def calibration_popout(self): if self.calib_popout: self.calib_popout.destroy() self.calib_popout = tk.Toplevel() self.calib_popout.title("About this application...") if not self.calib_params: return entry_dict = {} i = 0 d, inv = integrator_dict() for key, val in self.calib_params.items(): tk.Label(self.calib_popout, text=key).grid(row=i) entry_dict[key] = tk.Entry(self.calib_popout) entry_dict[key].grid(row=i, column=1) if val: entry_dict[key].delete(0, "end") if key == 'integrator': val = inv[val] entry_dict[key].insert(0, val) i += 1 def callback(): cmdline = [] for param, entry in entry_dict.items(): value = entry.get() if value: cmdkey = '--'+param.replace('integration_', 'integration-') cmdline.append(cmdkey) cmdline.extend(value.split()) self.set_calibration_params(cmdline) self.event = self.event self.calib_popout.destroy() b = tk.Button(self.calib_popout, text="Calibrate", command=callback) b.grid(row=i, column=0, columnspan=2)
def calibrate_event(event, params, geom_dict=None): """ Generic calibrator for events. Calls the calibrator corresponding to the source of the event, and stores the dl1 (calibrated_image) information into a new event container. Parameters ---------- event : container A `ctapipe` event container params : dict REQUIRED: params['integrator'] - Integration scheme params['integration_window'] - Integration window size and shift of integration window centre (adapted such that window fits into readout). OPTIONAL: params['integration_clip_amp'] - Amplitude in p.e. above which the signal is clipped. params['integration_calib_scale'] : Identical to global variable CALIB_SCALE in reconstruct.c in hessioxxx software package. 0.92 is the default value (corresponds to HESS). The required value changes between cameras (GCT = 1.05). params['integration_sigamp'] - Amplitude in ADC counts above pedestal at which a signal is considered as significant (separate for high gain/low gain). geom_dict : dict Dict of pixel geometry for each telescope. Leave as None for automatic calculation when it is required. dict[(num_pixels, focal_length)] = `ctapipe.io.CameraGeometry` Returns ------- calibrated : container A new `ctapipe` event container containing the dl1 information, and a reference to all other information contained in the original event container. """ # Obtain relevent calibrator switch = {'hessio': partial(mc.calibrate_mc, event=event, params=params)} try: calibrator = switch[event.meta['source']] except KeyError: log.exception("no calibration created for data origin: '{}'".format( event.meta['source'])) raise # KPK: should not copy the event here! there is no reason to # Copying is # up to the user if they want to do it, not in the algorithms. # calibrated = copy(event) # params stored in metadata event.dl1.meta.update(params) # Fill dl1 event.dl1.reset() for telid in event.dl0.tels_with_data: nchan = event.inst.num_channels[telid] npix = event.inst.num_pixels[telid] event.dl1.tel[telid] = CalibratedCameraContainer() # Get geometry int_dict, inverted = integrator_dict() geom = None # Check if geom is even needed for integrator if inverted[params['integrator']] in integrators_requiring_geom(): if geom_dict is not None and telid in geom_dict: geom = geom_dict[telid] else: log.debug("[calib] Guessing camera geometry") geom = CameraGeometry.guess(*event.inst.pixel_pos[telid], event.inst.optical_foclen[telid]) log.debug("[calib] Camera geometry found") if geom_dict is not None: geom_dict[telid] = geom pe, window, data_ped, peakpos = calibrator(telid=telid, geom=geom) tel = event.dl1.tel[telid] tel.calibrated_image = pe tel.peakpos = peakpos for chan in range(nchan): tel.integration_window[chan] = window[chan] tel.pedestal_subtracted_adc[chan] = data_ped[chan] return event
def calibrate_event(event, params, geom_dict=None): """ Generic calibrator for events. Calls the calibrator corresponding to the source of the event, and stores the dl1 (pe_charge) information into a new event container. Parameters ---------- event : container A `ctapipe` event container params : dict REQUIRED: params['integrator'] - Integration scheme params['integration_window'] - Integration window size and shift of integration window centre (adapted such that window fits into readout). OPTIONAL: params['integration_clip_amp'] - Amplitude in p.e. above which the signal is clipped. params['integration_calib_scale'] : Identical to global variable CALIB_SCALE in reconstruct.c in hessioxxx software package. 0.92 is the default value (corresponds to HESS). The required value changes between cameras (GCT = 1.05). params['integration_sigamp'] - Amplitude in ADC counts above pedestal at which a signal is considered as significant (separate for high gain/low gain). geom_dict : dict Dict of pixel geometry for each telescope. Leave as None for automatic calculation when it is required. dict[(num_pixels, focal_length)] = `ctapipe.io.CameraGeometry` Returns ------- calibrated : container A new `ctapipe` event container containing the dl1 information, and a reference to all other information contained in the original event container. """ # Obtain relevent calibrator switch = {'hessio': partial(mc.calibrate_mc, event=event, params=params)} try: calibrator = switch[event.meta.source] except KeyError: log.exception("no calibration created for data origin: '{}'".format( event.meta.source)) raise calibrated = copy(event) # Add dl1 to the event container (if it hasn't already been added) try: calibrated.add_item("dl1", RawData()) calibrated.dl1.run_id = event.dl0.run_id calibrated.dl1.event_id = event.dl0.event_id calibrated.dl1.tels_with_data = event.dl0.tels_with_data calibrated.dl1.calibration_parameters = params except AttributeError: pass # Fill dl1 calibrated.dl1.tel = dict() # clear the previous telescopes for telid in event.dl0.tels_with_data: nchan = event.dl0.tel[telid].num_channels npix = event.dl0.tel[telid].num_pixels calibrated.dl1.tel[telid] = CalibratedCameraData(telid) calibrated.dl1.tel[telid].num_channels = nchan calibrated.dl1.tel[telid].num_pixels = npix # Get geometry int_dict, inverted = integrator_dict() geom = None cam_dimensions = (event.dl0.tel[telid].num_pixels, event.meta.optical_foclen[telid]) # Check if geom is even needed for integrator if inverted[params['integrator']] in integrators_requiring_geom(): if geom_dict is not None and telid in geom_dict: geom = geom_dict[telid] else: log.debug("[calib] Guessing camera geometry") geom = CameraGeometry.guess(*event.meta.pixel_pos[telid], event.meta.optical_foclen[telid]) log.debug("[calib] Camera geometry found") if geom_dict is not None: geom_dict[telid] = geom pe, window, data_ped, peakpos = calibrator(telid=telid, geom=geom) calibrated.dl1.tel[telid].pe_charge = pe calibrated.dl1.tel[telid].peakpos = peakpos for chan in range(nchan): calibrated.dl1.tel[telid].integration_window[chan] = window[chan] calibrated.dl1.tel[telid].pedestal_subtracted_adc[chan] = \ data_ped[chan] return calibrated
def main(): script = os.path.splitext(os.path.basename(__file__))[0] log.info("[SCRIPT] {}".format(script)) parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('-f', '--file', dest='input_path', action='store', default=get_path('gamma_test.simtel.gz'), help='path to the input file') parser.add_argument('-O', '--origin', dest='origin', action='store', choices=InputFile.origin_list(), default='hessio', help='origin of the file') parser.add_argument('-o', '--output', dest='output_dir', action='store', default=None, help='path of the output directory to store the ' 'images (default = input file directory)') parser.add_argument('-e', '--event', dest='event_req', action='store', default=0, type=int, help='event index to plot (not id!)') parser.add_argument('--id', dest='event_id_f', action='store_true', default=False, help='-e will specify event_id instead ' 'of index') parser.add_argument('-t', '--telescope', dest='tel', action='store', type=int, default=None, help='telecope to view') parser.add_argument('-c', '--channel', dest='chan', action='store', type=int, default=0, help='channel to view (default = 0 (HG))') parser.add_argument('--calib-help', dest='calib_help', action='store_true', default=False, help='display the arguments used for the camera ' 'calibration') logger_detail = parser.add_mutually_exclusive_group() logger_detail.add_argument('-q', '--quiet', dest='quiet', action='store_true', default=False, help='Quiet mode') logger_detail.add_argument('-v', '--verbose', dest='verbose', action='store_true', default=False, help='Verbose mode') logger_detail.add_argument('-d', '--debug', dest='debug', action='store_true', default=False, help='Debug mode') args, excess_args = parser.parse_known_args() if args.quiet: log.setLevel(40) if args.verbose: log.setLevel(20) if args.debug: log.setLevel(10) telid = args.tel chan = args.chan log.debug("[file] Reading file") input_file = InputFile(args.input_path, args.origin) event = input_file.get_event(args.event_req, args.event_id_f) # Print event/args values log.info("[event_index] {}".format(event.count)) log.info("[event_id] {}".format(event.dl0.event_id)) log.info("[telescope] {}".format(telid)) log.info("[channel] {}".format(chan)) params, unknown_args = calibration_parameters(excess_args, args.origin, args.calib_help) if unknown_args: parser.print_help() calibration_parameters(unknown_args, args.origin, True) msg = 'unrecognized arguments: %s' parser.error(msg % ' '.join(unknown_args)) # Create a dictionary to store any geoms in geom = CameraGeometry.guess(*event.meta.pixel_pos[telid], event.meta.optical_foclen[telid]) geom_dict = {telid: geom} calibrated_event = calibrate_event(event, params, geom_dict) # Select telescope tels = list(calibrated_event.dl0.tels_with_data) if telid is None or telid not in tels: log.error("[event] please specify one of the following telescopes " "for this event: {}".format(tels)) exit() # Extract required images data_ped = calibrated_event.dl1.tel[telid].pedestal_subtracted_adc[chan] true_pe = calibrated_event.mc.tel[telid].photo_electrons measured_pe = calibrated_event.dl1.tel[telid].pe_charge max_time = np.unravel_index(np.argmax(data_ped), data_ped.shape)[1] max_charges = np.max(data_ped, axis=1) max_pixel = int(np.argmax(max_charges)) min_pixel = int(np.argmin(max_charges)) # Get Neighbours max_pixel_nei = geom.neighbors[max_pixel] min_pixel_nei = geom.neighbors[min_pixel] # Get Windows windows = calibrated_event.dl1.tel[telid].integration_window[chan] length = np.sum(windows, axis=1) start = np.argmax(windows, axis=1) end = start + length - 1 # Draw figures ax_max_nei = {} ax_min_nei = {} fig_waveforms = plt.figure(figsize=(18, 9)) fig_waveforms.subplots_adjust(hspace=.5) fig_camera = plt.figure(figsize=(15, 12)) ax_max_pix = fig_waveforms.add_subplot(4, 2, 1) ax_min_pix = fig_waveforms.add_subplot(4, 2, 2) ax_max_nei[0] = fig_waveforms.add_subplot(4, 2, 3) ax_min_nei[0] = fig_waveforms.add_subplot(4, 2, 4) ax_max_nei[1] = fig_waveforms.add_subplot(4, 2, 5) ax_min_nei[1] = fig_waveforms.add_subplot(4, 2, 6) ax_max_nei[2] = fig_waveforms.add_subplot(4, 2, 7) ax_min_nei[2] = fig_waveforms.add_subplot(4, 2, 8) ax_img_nei = fig_camera.add_subplot(2, 2, 1) ax_img_max = fig_camera.add_subplot(2, 2, 2) ax_img_true = fig_camera.add_subplot(2, 2, 3) ax_img_cal = fig_camera.add_subplot(2, 2, 4) plotter = CameraPlotter(event, geom_dict) # Draw max pixel traces plotter.draw_waveform(data_ped[max_pixel], ax_max_pix) ax_max_pix.set_title("(Max) Pixel: {}, " "True: {}, " "Measured = {:.3f}".format(max_pixel, true_pe[max_pixel], measured_pe[max_pixel])) ax_max_pix.set_ylabel("Amplitude-Ped (ADC)") max_ylim = ax_max_pix.get_ylim() plotter.draw_waveform_positionline(start[max_pixel], ax_max_pix) plotter.draw_waveform_positionline(end[max_pixel], ax_max_pix) for i, ax in ax_max_nei.items(): if len(max_pixel_nei) > i: pix = max_pixel_nei[i] plotter.draw_waveform(data_ped[pix], ax) ax.set_title("(Max Nei) Pixel: {}, " "True: {}, " "Measured = {:.3f}".format(pix, true_pe[pix], measured_pe[pix])) ax.set_ylabel("Amplitude-Ped (ADC)") ax.set_ylim(max_ylim) plotter.draw_waveform_positionline(start[pix], ax) plotter.draw_waveform_positionline(end[pix], ax) # Draw min pixel traces plotter.draw_waveform(data_ped[min_pixel], ax_min_pix) ax_min_pix.set_title("(Min) Pixel: {}, " "True: {}, " "Measured = {:.3f}".format(min_pixel, true_pe[min_pixel], measured_pe[min_pixel])) ax_min_pix.set_ylabel("Amplitude-Ped (ADC)") ax_min_pix.set_ylim(max_ylim) plotter.draw_waveform_positionline(start[min_pixel], ax_min_pix) plotter.draw_waveform_positionline(end[min_pixel], ax_min_pix) for i, ax in ax_min_nei.items(): if len(min_pixel_nei) > i: pix = min_pixel_nei[i] plotter.draw_waveform(data_ped[pix], ax) ax.set_title("(Min Nei) Pixel: {}, " "True: {}, " "Measured = {:.3f}".format(pix, true_pe[pix], measured_pe[pix])) ax.set_ylabel("Amplitude-Ped (ADC)") ax.set_ylim(max_ylim) plotter.draw_waveform_positionline(start[pix], ax) plotter.draw_waveform_positionline(end[pix], ax) # Draw cameras nei_camera = np.zeros_like(max_charges, dtype=np.int) nei_camera[min_pixel_nei] = 2 nei_camera[min_pixel] = 1 nei_camera[max_pixel_nei] = 3 nei_camera[max_pixel] = 4 camera = plotter.draw_camera(telid, nei_camera, ax_img_nei) camera.cmap = plt.cm.viridis ax_img_nei.set_title("Neighbour Map") plotter.draw_camera_pixel_annotation(telid, max_pixel, min_pixel, ax_img_nei) camera = plotter.draw_camera(telid, data_ped[:, max_time], ax_img_max) camera.add_colorbar(ax=ax_img_max, label="Amplitude-Ped (ADC)") ax_img_max.set_title("Max Timeslice (T = {})".format(max_time)) plotter.draw_camera_pixel_annotation(telid, max_pixel, min_pixel, ax_img_max) camera = plotter.draw_camera(telid, true_pe, ax_img_true) camera.add_colorbar(ax=ax_img_true, label="True Charge (Photo-electrons)") ax_img_true.set_title("True Charge") plotter.draw_camera_pixel_annotation(telid, max_pixel, min_pixel, ax_img_true) int_dict, inverted = integrator_dict() integrator_name = '' if 'integrator' not in params else \ params['integrator'] camera = plotter.draw_camera(telid, measured_pe, ax_img_cal) camera.add_colorbar(ax=ax_img_cal, label="Calib Charge (Photo-electrons)") ax_img_cal.set_title("Charge (integrator={})".format(integrator_name)) plotter.draw_camera_pixel_annotation(telid, max_pixel, min_pixel, ax_img_cal) fig_waveforms.suptitle("Integrator = {}".format(integrator_name)) fig_camera.suptitle("Camera = {}".format(geom.cam_id)) waveform_output_name = "{}_e{}_t{}_c{}_integrator{}_waveform.pdf"\ .format(input_file.filename, event.count, telid, chan, inverted[params['integrator']]) camera_output_name = "{}_e{}_t{}_c{}_integrator{}_camera.pdf"\ .format(input_file.filename, event.count, telid, chan, inverted[params['integrator']]) output_dir = args.output_dir if args.output_dir is not None else \ input_file.output_directory output_dir = os.path.join(output_dir, script) if not os.path.exists(output_dir): log.info("[output] Creating directory: {}".format(output_dir)) os.makedirs(output_dir) waveform_output_path = os.path.join(output_dir, waveform_output_name) log.info("[output] {}".format(waveform_output_path)) fig_waveforms.savefig(waveform_output_path, format='pdf', bbox_inches='tight') camera_output_path = os.path.join(output_dir, camera_output_name) log.info("[output] {}".format(camera_output_path)) fig_camera.savefig(camera_output_path, format='pdf', bbox_inches='tight') log.info("[COMPLETE]")
def calibrate_event(event, params, geom_dict=None): """ Generic calibrator for events. Calls the calibrator corresponding to the source of the event, and stores the dl1 (pe_charge) information into a new event container. Parameters ---------- event : container A `ctapipe` event container params : dict REQUIRED: params['integrator'] - Integration scheme params['integration_window'] - Integration window size and shift of integration window centre (adapted such that window fits into readout). OPTIONAL: params['integration_clip_amp'] - Amplitude in p.e. above which the signal is clipped. params['integration_calib_scale'] : Identical to global variable CALIB_SCALE in reconstruct.c in hessioxxx software package. 0.92 is the default value (corresponds to HESS). The required value changes between cameras (GCT = 1.05). params['integration_sigamp'] - Amplitude in ADC counts above pedestal at which a signal is considered as significant (separate for high gain/low gain). geom_dict : dict Dict of pixel geometry for each telescope. Leave as None for automatic calculation when it is required. dict[(num_pixels, focal_length)] = `ctapipe.io.CameraGeometry` Returns ------- calibrated : container A new `ctapipe` event container containing the dl1 information, and a reference to all other information contained in the original event container. """ # Obtain relevent calibrator switch = { 'hessio': partial(mc.calibrate_mc, event=event, params=params) } try: calibrator = switch[event.meta.source] except KeyError: log.exception("no calibration created for data origin: '{}'" .format(event.meta.source)) raise calibrated = copy(event) # Add dl1 to the event container (if it hasn't already been added) try: calibrated.add_item("dl1", RawData()) calibrated.dl1.run_id = event.dl0.run_id calibrated.dl1.event_id = event.dl0.event_id calibrated.dl1.tels_with_data = event.dl0.tels_with_data calibrated.dl1.calibration_parameters = params except AttributeError: pass # Fill dl1 calibrated.dl1.tel = dict() # clear the previous telescopes for telid in event.dl0.tels_with_data: nchan = event.dl0.tel[telid].num_channels npix = event.dl0.tel[telid].num_pixels calibrated.dl1.tel[telid] = CalibratedCameraData(telid) calibrated.dl1.tel[telid].num_channels = nchan calibrated.dl1.tel[telid].num_pixels = npix # Get geometry int_dict, inverted = integrator_dict() geom = None cam_dimensions = (event.dl0.tel[telid].num_pixels, event.meta.optical_foclen[telid]) # Check if geom is even needed for integrator if inverted[params['integrator']] in integrators_requiring_geom(): if geom_dict is not None and telid in geom_dict: geom = geom_dict[telid] else: log.debug("[calib] Guessing camera geometry") geom = CameraGeometry.guess(*event.meta.pixel_pos[telid], event.meta.optical_foclen[telid]) log.debug("[calib] Camera geometry found") if geom_dict is not None: geom_dict[telid] = geom pe, window, data_ped, peakpos = calibrator(telid=telid, geom=geom) calibrated.dl1.tel[telid].pe_charge = pe calibrated.dl1.tel[telid].peakpos = peakpos for chan in range(nchan): calibrated.dl1.tel[telid].integration_window[chan] = window[chan] calibrated.dl1.tel[telid].pedestal_subtracted_adc[chan] = \ data_ped[chan] return calibrated
def calibrate_event(event, params, geom_dict=None): """ Generic calibrator for events. Calls the calibrator corresponding to the source of the event, and stores the dl1 (calibrated_image) information into a new event container. Parameters ---------- event : container A `ctapipe` event container params : dict REQUIRED: params['integrator'] - Integration scheme params['integration_window'] - Integration window size and shift of integration window centre (adapted such that window fits into readout). OPTIONAL: params['integration_clip_amp'] - Amplitude in p.e. above which the signal is clipped. params['integration_calib_scale'] : Identical to global variable CALIB_SCALE in reconstruct.c in hessioxxx software package. 0.92 is the default value (corresponds to HESS). The required value changes between cameras (GCT = 1.05). params['integration_sigamp'] - Amplitude in ADC counts above pedestal at which a signal is considered as significant (separate for high gain/low gain). geom_dict : dict Dict of pixel geometry for each telescope. Leave as None for automatic calculation when it is required. dict[(num_pixels, focal_length)] = `ctapipe.io.CameraGeometry` Returns ------- calibrated : container A new `ctapipe` event container containing the dl1 information, and a reference to all other information contained in the original event container. """ # Obtain relevent calibrator switch = { 'hessio': partial(mc.calibrate_mc, event=event, params=params) } try: calibrator = switch[event.meta['source']] except KeyError: log.exception("no calibration created for data origin: '{}'" .format(event.meta['source'])) raise # KPK: should not copy the event here! there is no reason to # Copying is # up to the user if they want to do it, not in the algorithms. # calibrated = copy(event) # params stored in metadata event.dl1.meta.update(params) # Fill dl1 event.dl1.reset() for telid in event.dl0.tels_with_data: nchan = event.inst.num_channels[telid] npix = event.inst.num_pixels[telid] event.dl1.tel[telid] = CalibratedCameraContainer() # Get geometry int_dict, inverted = integrator_dict() geom = None # Check if geom is even needed for integrator if inverted[params['integrator']] in integrators_requiring_geom(): if geom_dict is not None and telid in geom_dict: geom = geom_dict[telid] else: log.debug("[calib] Guessing camera geometry") geom = CameraGeometry.guess(*event.inst.pixel_pos[telid], event.inst.optical_foclen[telid]) log.debug("[calib] Camera geometry found") if geom_dict is not None: geom_dict[telid] = geom pe, window, data_ped, peakpos = calibrator(telid=telid, geom=geom) tel = event.dl1.tel[telid] tel.calibrated_image = pe tel.peakpos = peakpos for chan in range(nchan): tel.integration_window[chan] = window[chan] tel.pedestal_subtracted_adc[chan] = data_ped[chan] return event