class DisplayDL1Calib(Tool): name = "ctapipe-display-dl1" description = __doc__ telescope = Int(None, allow_none=True, help='Telescope to view. Set to None to display all ' 'telescopes.').tag(config=True) extractor_product = tool_utils.enum_trait(ImageExtractor, default='NeighborPeakWindowSum') aliases = Dict( dict(max_events='EventSource.max_events', extractor='DisplayDL1Calib.extractor_product', T='DisplayDL1Calib.telescope', O='ImagePlotter.output_path')) flags = Dict( dict(D=({ 'ImagePlotter': { 'display': True } }, "Display the photoelectron images on-screen as they " "are produced."))) classes = List([EventSource, CameraDL1Calibrator, ImagePlotter] + tool_utils.classes_with_traits(ImageExtractor)) def __init__(self, **kwargs): super().__init__(**kwargs) self.eventsource = None self.calibrator = None self.plotter = None def setup(self): self.eventsource = EventSource.from_url( get_dataset_path("gamma_test_large.simtel.gz"), parent=self, ) self.calibrator = CameraCalibrator(parent=self) self.plotter = ImagePlotter(parent=self) def start(self): for event in self.eventsource: self.calibrator.calibrate(event) tel_list = event.r0.tels_with_data if self.telescope: if self.telescope not in tel_list: continue tel_list = [self.telescope] for telid in tel_list: self.plotter.plot(event, telid) def finish(self): self.plotter.finish()
class ChargeResolutionGenerator(Tool): name = "ChargeResolutionGenerator" description = ("Calculate the Charge Resolution from a sim_telarray " "simulation and store within a HDF5 file.") telescopes = List(Int, None, allow_none=True, help='Telescopes to include from the event file. ' 'Default = All telescopes').tag(config=True) output_path = Unicode( 'charge_resolution.h5', help='Path to store the output HDF5 file').tag(config=True) extractor_product = tool_utils.enum_trait( ChargeExtractor, default='NeighbourPeakIntegrator') aliases = Dict( dict( f='SimTelEventSource.input_url', max_events='SimTelEventSource.max_events', T='SimTelEventSource.allowed_tels', extractor='ChargeResolutionGenerator.extractor_product', window_width='WindowIntegrator.window_width', window_shift='WindowIntegrator.window_shift', t0='SimpleIntegrator.t0', lwt='NeighbourPeakIntegrator.lwt', clip_amplitude='CameraDL1Calibrator.clip_amplitude', radius='CameraDL1Calibrator.radius', O='ChargeResolutionGenerator.output_path', )) classes = List([ SimTelEventSource, CameraDL1Calibrator, ] + tool_utils.classes_with_traits(ChargeExtractor)) def __init__(self, **kwargs): super().__init__(**kwargs) self.eventsource = None self.r1 = None self.dl0 = None self.dl1 = None self.calculator = None def setup(self): self.log_format = "%(levelname)s: %(message)s [%(name)s.%(funcName)s]" self.eventsource = SimTelEventSource(parent=self) extractor = ChargeExtractor.from_name(self.extractor_product, parent=self) self.r1 = HESSIOR1Calibrator(parent=self) self.dl0 = CameraDL0Reducer(parent=self) self.dl1 = CameraDL1Calibrator(extractor=extractor, parent=self) self.calculator = ChargeResolutionCalculator() def start(self): desc = "Extracting Charge Resolution" for event in tqdm(self.eventsource, desc=desc): self.r1.calibrate(event) self.dl0.reduce(event) self.dl1.calibrate(event) # Check events have true charge included if event.count == 0: try: pe = list(event.mc.tel.values())[0].photo_electron_image if np.all(pe == 0): raise KeyError except KeyError: self.log.exception('Source does not contain true charge!') raise for mc, dl1 in zip(event.mc.tel.values(), event.dl1.tel.values()): true_charge = mc.photo_electron_image measured_charge = dl1.image[0] pixels = np.arange(measured_charge.size) self.calculator.add(pixels, true_charge, measured_charge) def finish(self): df_p, df_c = self.calculator.finish() output_directory = os.path.dirname(self.output_path) if not os.path.exists(output_directory): self.log.info(f"Creating directory: {output_directory}") os.makedirs(output_directory) with pd.HDFStore(self.output_path, 'w') as store: store['charge_resolution_pixel'] = df_p store['charge_resolution_camera'] = df_c self.log.info("Created charge resolution file: {}".format( self.output_path)) Provenance().add_output_file(self.output_path)
class BokehFileViewer(Tool): name = "BokehFileViewer" description = ("Interactively explore an event file using the bokeh " "visualisation package") port = Int(5006, help="Port to open bokeh server onto").tag(config=True) disable_server = Bool(False, help="Do not start the bokeh server " "(useful for testing)").tag(config=True) default_url = get_dataset_path("gamma_test_large.simtel.gz") EventSource.input_url.default_value = default_url extractor_product = tool_utils.enum_trait(ImageExtractor, default='NeighborPeakWindowSum') aliases = Dict( dict( port='BokehFileViewer.port', disable_server='BokehFileViewer.disable_server', f='EventSource.input_url', max_events='EventSource.max_events', extractor='BokehFileViewer.extractor_product', )) classes = List([ EventSource, ] + tool_utils.classes_with_traits(ImageExtractor)) def __init__(self, **kwargs): super().__init__(**kwargs) self._event = None self._event_index = None self._event_id = None self._telid = None self._channel = None self.w_next_event = None self.w_previous_event = None self.w_event_index = None self.w_event_id = None self.w_goto_event_index = None self.w_goto_event_id = None self.w_telid = None self.w_channel = None self.w_dl1_dict = None self.wb_extractor = None self.layout = None self.reader = None self.seeker = None self.extractor = None self.calibrator = None self.viewer = None self._updating_dl1 = False # make sure, gzip files are seekable self.config.SimTelEventSource.back_seekable = True def setup(self): self.log_format = "%(levelname)s: %(message)s [%(name)s.%(funcName)s]" self.reader = EventSource.from_config(parent=self) self.seeker = EventSeeker(self.reader, parent=self) self.extractor = ImageExtractor.from_name(self.extractor_product, parent=self) self.calibrator = CameraCalibrator( parent=self, image_extractor=self.extractor, ) self.viewer = BokehEventViewer(parent=self) # Setup widgets self.viewer.create() self.viewer.enable_automatic_index_increment() self.create_previous_event_widget() self.create_next_event_widget() self.create_event_index_widget() self.create_goto_event_index_widget() self.create_event_id_widget() self.create_goto_event_id_widget() self.create_telid_widget() self.create_channel_widget() self.create_dl1_widgets() self.update_dl1_widget_values() # Setup layout self.layout = layout([[self.viewer.layout], [ self.w_previous_event, self.w_next_event, self.w_goto_event_index, self.w_goto_event_id ], [self.w_event_index, self.w_event_id], [self.w_telid, self.w_channel], [self.wb_extractor]]) def start(self): self.event_index = 0 def finish(self): if not self.disable_server: def modify_doc(doc): doc.add_root(self.layout) doc.title = self.name directory = os.path.abspath(os.path.dirname(__file__)) theme_path = os.path.join(directory, "theme.yaml") template_path = os.path.join(directory, "templates") doc.theme = Theme(filename=theme_path) env = jinja2.Environment( loader=jinja2.FileSystemLoader(template_path)) doc.template = env.get_template('index.html') self.log.info('Opening Bokeh application on ' 'http://localhost:{}/'.format(self.port)) server = Server({'/': modify_doc}, num_procs=1, port=self.port) server.start() server.io_loop.add_callback(server.show, "/") server.io_loop.start() @property def event_index(self): return self._event_index @event_index.setter def event_index(self, val): try: self.event = self.seeker[val] except IndexError: self.log.warning(f"Event Index {val} does not exist") @property def event_id(self): return self._event_id @event_id.setter def event_id(self, val): try: self.event = self.seeker[str(val)] except IndexError: self.log.warning(f"Event ID {val} does not exist") @property def telid(self): return self._telid @telid.setter def telid(self, val): self.channel = 0 tels = list(self.event.r0.tels_with_data) if val not in tels: val = tels[0] self._telid = val self.viewer.telid = val self.update_telid_widget() @property def channel(self): return self._channel @channel.setter def channel(self, val): self._channel = val self.viewer.channel = val self.update_channel_widget() @property def event(self): return self._event @event.setter def event(self, val): self.calibrator(val) self._event = val self.viewer.event = val self._event_index = val.count self._event_id = val.r0.event_id self.update_event_index_widget() self.update_event_id_widget() self._telid = self.viewer.telid self.update_telid_widget() self._channel = self.viewer.channel self.update_channel_widget() def update_dl1_calibrator(self, extractor=None): """ Recreate the dl1 calibrator with the specified extractor and cleaner Parameters ---------- extractor : ctapipe.image.extractor.ImageExtractor """ if extractor is None: extractor = self.calibrator.image_extractor self.extractor = extractor self.calibrator = CameraCalibrator( parent=self, image_extractor=self.extractor, ) self.viewer.refresh() def create_next_event_widget(self): self.w_next_event = Button(label=">", button_type="default", width=50) self.w_next_event.on_click(self.on_next_event_widget_click) def on_next_event_widget_click(self): self.event_index += 1 def create_previous_event_widget(self): self.w_previous_event = Button(label="<", button_type="default", width=50) self.w_previous_event.on_click(self.on_previous_event_widget_click) def on_previous_event_widget_click(self): self.event_index -= 1 def create_event_index_widget(self): self.w_event_index = TextInput(title="Event Index:", value='') def update_event_index_widget(self): if self.w_event_index: self.w_event_index.value = str(self.event_index) def create_event_id_widget(self): self.w_event_id = TextInput(title="Event ID:", value='') def update_event_id_widget(self): if self.w_event_id: self.w_event_id.value = str(self.event_id) def create_goto_event_index_widget(self): self.w_goto_event_index = Button(label="GOTO Index", button_type="default", width=100) self.w_goto_event_index.on_click(self.on_goto_event_index_widget_click) def on_goto_event_index_widget_click(self): self.event_index = int(self.w_event_index.value) def create_goto_event_id_widget(self): self.w_goto_event_id = Button(label="GOTO ID", button_type="default", width=70) self.w_goto_event_id.on_click(self.on_goto_event_id_widget_click) def on_goto_event_id_widget_click(self): self.event_id = int(self.w_event_id.value) def create_telid_widget(self): self.w_telid = Select(title="Telescope:", value="", options=[]) self.w_telid.on_change('value', self.on_telid_widget_change) def update_telid_widget(self): if self.w_telid: tels = [str(t) for t in self.event.r0.tels_with_data] self.w_telid.options = tels self.w_telid.value = str(self.telid) def on_telid_widget_change(self, _, __, ___): if self.telid != int(self.w_telid.value): self.telid = int(self.w_telid.value) def create_channel_widget(self): self.w_channel = Select(title="Channel:", value="", options=[]) self.w_channel.on_change('value', self.on_channel_widget_change) def update_channel_widget(self): if self.w_channel: try: n_chan = self.event.r0.tel[self.telid].waveform.shape[0] except AttributeError: n_chan = 1 channels = [str(c) for c in range(n_chan)] self.w_channel.options = channels self.w_channel.value = str(self.channel) def on_channel_widget_change(self, _, __, ___): if self.channel != int(self.w_channel.value): self.channel = int(self.w_channel.value) def create_dl1_widgets(self): self.w_dl1_dict = dict( extractor=Select(title="Extractor:", value='', width=5, options=BokehFileViewer.extractor_product.values), extractor_window_start=TextInput(title="Window Start:", value=''), extractor_window_width=TextInput(title="Window Width:", value=''), extractor_window_shift=TextInput(title="Window Shift:", value=''), extractor_lwt=TextInput(title="Local Pixel Weight:", value='')) for val in self.w_dl1_dict.values(): val.on_change('value', self.on_dl1_widget_change) self.wb_extractor = widgetbox( PreText(text="Charge Extractor Configuration"), self.w_dl1_dict['extractor'], self.w_dl1_dict['extractor_window_start'], self.w_dl1_dict['extractor_window_width'], self.w_dl1_dict['extractor_window_shift'], self.w_dl1_dict['extractor_lwt']) def update_dl1_widget_values(self): if self.w_dl1_dict: for key, val in self.w_dl1_dict.items(): if 'extractor' in key: if key == 'extractor': val.value = self.extractor.__class__.__name__ else: key = key.replace("extractor_", "") try: val.value = str(getattr(self.extractor, key)) except AttributeError: val.value = '' def on_dl1_widget_change(self, _, __, ___): if self.event: if not self._updating_dl1: self._updating_dl1 = True cmdline = [] for key, val in self.w_dl1_dict.items(): k = key.replace("extractor_", "ImageExtractor.") if val.value: cmdline.append(f'--{k}={val.value}') self.parse_command_line(cmdline) extractor = ImageExtractor.from_name(self.extractor_product, parent=self) self.update_dl1_calibrator(extractor) self.update_dl1_widget_values() self._updating_dl1 = False
class CalibrationHDF5Writer(Tool): """ Tool that generates a HDF5 file with camera calibration coefficients. This is just an example on how the monitoring containers can be filled using the calibration Components in calib/camera. This example is based on an input file with interleaved pedestal and flat-field events For getting help run: python calc_camera_calibration.py --help """ name = "CalibrationHDF5Writer" description = "Generate a HDF5 file with camera calibration coefficients" output_file = Unicode( 'calibration.hdf5', help='Name of the output file' ).tag(config=True) pedestal_product = tool_utils.enum_trait( PedestalCalculator, default='PedestalIntegrator' ) flatfield_product = tool_utils.enum_trait( FlatFieldCalculator, default='FlasherFlatFieldCalculator' ) r0calibrator_product = tool_utils.enum_trait( CameraR0Calibrator, default='NullR0Calibrator' ) aliases = Dict(dict( input_file='EventSource.input_url', max_events='EventSource.max_events', pedestal_file= 'LSTR0Corrections.pedestal_path', flatfield_product='CalibrationHDF5Writer.flatfield_product', pedestal_product='CalibrationHDF5Writer.pedestal_product', r0calibrator_product='CalibrationHDF5Writer.r0calibrator_product' )) classes = List([EventSource, FlatFieldCalculator, FlatFieldContainer, PedestalCalculator, PedestalContainer, WaveformCalibrationContainer ] + tool_utils.classes_with_traits(CameraR0Calibrator) + tool_utils.classes_with_traits(ImageExtractor) + tool_utils.classes_with_traits(FlatFieldCalculator) + tool_utils.classes_with_traits(PedestalCalculator) ) def __init__(self, **kwargs): super().__init__(**kwargs) """ Tool that generates a HDF5 file with camera calibration coefficients. Input file must contain interleaved pedestal and flat-field events For getting help run: python calc_camera_calibration.py --help """ self.eventsource = None self.flatfield = None self.pedestal = None self.container = None self.writer = None self.r0calibrator = None self.tel_id = None def setup(self): kwargs = dict(parent=self) self.eventsource = EventSource.from_config(**kwargs) self.flatfield = FlatFieldCalculator.from_name( self.flatfield_product, **kwargs ) self.pedestal = PedestalCalculator.from_name( self.pedestal_product, **kwargs ) if self.r0calibrator_product: self.r0calibrator = CameraR0Calibrator.from_name( self.r0calibrator_product, **kwargs ) msg = "tel_id not the same for all calibration components" assert self.r0calibrator.tel_id == self.pedestal.tel_id == self.flatfield.tel_id, msg self.tel_id = self.flatfield.tel_id group_name = 'tel_' + str(self.tel_id) self.writer = HDF5TableWriter( filename=self.output_file, group_name=group_name, overwrite=True ) def start(self): '''Calibration coefficient calculator''' ped_initialized = False ff_initialized = False for count, event in enumerate(self.eventsource): # if count == 0: ped_data = event.mon.tel[self.tel_id].pedestal ff_data = event.mon.tel[self.tel_id].flatfield status_data = event.mon.tel[self.tel_id].pixel_status calib_data = event.mon.tel[self.tel_id].calibration # correct for low level calibration self.r0calibrator.calibrate(event) # if pedestal if event.r0.tel[self.tel_id].trigger_type == 32: if self.pedestal.calculate_pedestals(event): self.log.debug(f"new pedestal at event n. {count+1}, id {event.r0.event_id}") # update pedestal mask status_data.pedestal_mask = np.logical_or(ped_data.charge_median_outliers, ped_data.charge_std_outliers) if not ped_initialized: # save the config, to be retrieved as data.meta['config'] ped_data.meta['config'] = self.config ped_initialized = True else: self.log.debug(f"write pedestal data") # write only after a first event (used to initialize the mask) self.writer.write('pedestal', ped_data) # consider flat field events only after first pedestal event elif event.r0.tel[self.tel_id].trigger_type == 1 and ped_initialized: if self.flatfield.calculate_relative_gain(event): self.log.debug(f"new flatfield at event n. {count+1}, id {event.r0.event_id}") # update the flatfield mask status_data.flatfield_mask = np.logical_or(ff_data.charge_median_outliers, ff_data.time_median_outliers) calib_data.pixel_status_mask = np.logical_or(status_data.pedestal_mask,status_data.flatfield_mask) masked_charge = np.ma.array(ff_data.charge_median - ped_data.charge_median, mask=calib_data.pixel_status_mask) masked_std_square = np.ma.array(ff_data.charge_std ** 2 - ped_data.charge_std ** 2, mask=calib_data.pixel_status_mask) masked_time = np.ma.array(ff_data.relative_time_median, mask=calib_data.pixel_status_mask) masked_n_phe = 1.2 * masked_charge ** 2 / masked_std_square masked_n_phe_median = np.ma.median(masked_n_phe) # calculate the calibration data calib_data.n_phe = np.ma.getdata(masked_n_phe) calib_data.dc_to_phe = np.ma.getdata(masked_n_phe_median/masked_charge) calib_data.time_correction = - np.ma.getdata(masked_time) # save the config, to be retrieved as data.meta['config'] if not ff_initialized: ff_data.meta['config']=self.config calib_data.meta['config'] = self.config ff_initialized = True else: # write only after a first event (used to initialize the mask) self.log.debug(f"write flatfield data") self.writer.write('flatfield', ff_data) self.log.debug(f"write pixel_status data") self.writer.write('pixel_status',status_data) self.log.debug(f"write calibration data") self.writer.write('calibration', calib_data) def finish(self): Provenance().add_output_file( self.output_file, role='mon.tel.calibration' ) self.writer.close()
class DisplayIntegrator(Tool): name = "ctapipe-display-integration" description = __doc__ event_index = Int(0, help='Event index to view.').tag(config=True) use_event_id = Bool( False, help='event_index will obtain an event using event_id instead of ' 'index.').tag(config=True) telescope = Int(None, allow_none=True, help='Telescope to view. Set to None to display the first' 'telescope with data.').tag(config=True) channel = Enum([0, 1], 0, help='Channel to view').tag(config=True) extractor_product = tool_utils.enum_trait( ChargeExtractor, default='NeighbourPeakIntegrator') aliases = Dict( dict( f='EventSource.input_url', max_events='EventSource.max_events', extractor='DisplayIntegrator.extractor_product', E='DisplayIntegrator.event_index', T='DisplayIntegrator.telescope', C='DisplayIntegrator.channel', )) flags = Dict( dict(id=({ 'DisplayDL1Calib': { 'use_event_index': True } }, 'event_index will obtain an event using ' 'event_id instead of index.'))) classes = List([ EventSource, CameraDL1Calibrator, ] + tool_utils.classes_with_traits(ChargeExtractor)) def __init__(self, **kwargs): super().__init__(**kwargs) self.eventseeker = None self.r1 = None self.dl0 = None self.extractor = None self.dl1 = None def setup(self): self.log_format = "%(levelname)s: %(message)s [%(name)s.%(funcName)s]" event_source = EventSource.from_config(parent=self) self.eventseeker = EventSeeker(event_source, parent=self) self.extractor = ChargeExtractor.from_name( self.extractor_product, parent=self, ) self.r1 = CameraR1Calibrator.from_eventsource( eventsource=event_source, parent=self, ) self.dl0 = CameraDL0Reducer(parent=self) self.dl1 = CameraDL1Calibrator(extractor=self.extractor, parent=self) def start(self): event_num = self.event_index if self.use_event_id: event_num = str(event_num) event = self.eventseeker[event_num] # Calibrate self.r1.calibrate(event) self.dl0.reduce(event) self.dl1.calibrate(event) # Select telescope tels = list(event.r0.tels_with_data) telid = self.telescope if telid is None: telid = tels[0] if telid not in tels: self.log.error("[event] please specify one of the following " "telescopes for this event: {}".format(tels)) exit() extractor_name = self.extractor.__class__.__name__ plot(event, telid, self.channel, extractor_name) def finish(self): pass
class DisplayIntegrator(Tool): name = "DisplayIntegrator" description = "Calibrate dl0 data to dl1, and plot the various camera " \ "images that characterise the event and calibration. Also " \ "plot some examples of waveforms with the " \ "integration window." event_index = Int(0, help='Event index to view.').tag(config=True) use_event_id = Bool(False, help='event_index will obtain an event using' 'event_id instead of ' 'index.').tag(config=True) telescope = Int(None, allow_none=True, help='Telescope to view. Set to None to display the first' 'telescope with data.').tag(config=True) channel = Enum([0, 1], 0, help='Channel to view').tag(config=True) extractor_product = tool_utils.enum_trait( ChargeExtractor, default='NeighbourPeakIntegrator') aliases = Dict( dict( f='EventSource.input_url', max_events='EventSource.max_events', extractor='DisplayIntegrator.extractor_product', t0='SimpleIntegrator.t0', window_width='WindowIntegrator.window_width', window_shift='WindowIntegrator.window_shift', sig_amp_cut_HG='PeakFindingIntegrator.sig_amp_cut_HG', sig_amp_cut_LG='PeakFindingIntegrator.sig_amp_cut_LG', lwt='NeighbourPeakIntegrator.lwt', clip_amplitude='CameraDL1Calibrator.clip_amplitude', radius='CameraDL1Calibrator.radius', E='DisplayIntegrator.event_index', T='DisplayIntegrator.telescope', C='DisplayIntegrator.channel', )) flags = Dict( dict(id=({ 'DisplayDL1Calib': { 'use_event_index': True } }, 'event_index will obtain an event using ' 'event_id instead of index.'))) classes = List([ EventSource, CameraDL1Calibrator, ] + tool_utils.classes_with_traits(ChargeExtractor)) def __init__(self, **kwargs): super().__init__(**kwargs) self.eventseeker = None self.r1 = None self.dl0 = None self.extractor = None self.dl1 = None def setup(self): self.log_format = "%(levelname)s: %(message)s [%(name)s.%(funcName)s]" kwargs = dict(config=self.config, tool=self) event_source = EventSource.from_config(**kwargs) self.eventseeker = EventSeeker(event_source, **kwargs) self.extractor = ChargeExtractor.from_name(self.extractor_product, **kwargs) self.r1 = CameraR1Calibrator.from_eventsource(eventsource=event_source, **kwargs) self.dl0 = CameraDL0Reducer(**kwargs) self.dl1 = CameraDL1Calibrator(extractor=self.extractor, **kwargs) def start(self): event_num = self.event_index if self.use_event_id: event_num = str(event_num) event = self.eventseeker[event_num] # Calibrate self.r1.calibrate(event) self.dl0.reduce(event) self.dl1.calibrate(event) # Select telescope tels = list(event.r0.tels_with_data) telid = self.telescope if telid is None: telid = tels[0] if telid not in tels: self.log.error("[event] please specify one of the following " "telescopes for this event: {}".format(tels)) exit() extractor_name = self.extractor.__class__.__name__ plot(event, telid, self.channel, extractor_name) def finish(self): pass
class FlatFieldHDF5Writer(Tool): name = "FlatFieldHDF5Writer" description = "Generate a HDF5 file with flat field coefficients" output_file = Unicode( 'flatfield.hdf5', help='Name of the output flat field file file').tag(config=True) cleaner_product = tool_utils.enum_trait(WaveformCleaner, default='NullWaveformCleaner') calculator_product = tool_utils.enum_trait( FlatFieldCalculator, default='FlasherFlatFieldCalculator') aliases = Dict( dict(input_file='EventSource.input_url', max_events='EventSource.max_events', flatfield_calculator='FlatFieldHDF5Writer.calculator_product', tel_id='FlatFieldCalculator.tel_id', sample_duration='FlatFieldCalculator.sample_duration', sample_size='FlatFieldCalculator.sample_size', n_channels='FlatFieldCalculator.n_channels', charge_product='FlatFieldCalculator.charge_product', cleaner='FlatFieldHDF5Writer.cleaner_product', baseline_start='BaselineWaveformCleaner.baseline_start', baseline_end='BaselineWaveformCleaner.baseline_end')) classes = List([ EventSource, WaveformCleaner, FlatFieldCalculator, FlatFieldContainer, HDF5TableWriter ] + tool_utils.classes_with_traits(WaveformCleaner) + tool_utils.classes_with_traits(ChargeExtractor) + tool_utils.classes_with_traits(FlatFieldCalculator)) def __init__(self, **kwargs): super().__init__(**kwargs) self.eventsource = None self.flatfield = None self.container = None self.writer = None self.cleaner = None def setup(self): kwargs = dict(parent=self) self.eventsource = EventSource.from_config(**kwargs) self.flatfield = FlatFieldCalculator.from_name(self.calculator_product, **kwargs) self.cleaner = WaveformCleaner.from_name(self.cleaner_product, **kwargs) self.writer = HDF5TableWriter(filename=self.output_file, group_name='flatfield', overwrite=True) def start(self): '''Flat field coefficient calculator''' table_name = 'tel_' + str(self.flatfield.tel_id) self.log.info("write events in table: /flatfield/%s", table_name) write_config = False for count, event in enumerate(self.eventsource): # one should add hier the pedestal subtraction and/or cleaner ff_data = self.flatfield.calculate_relative_gain(event) if ff_data: # save the config, to be retrieved as data.meta['config'] if not write_config: ff_data.meta['config'] = self.config write_config = True self.writer.write(table_name, ff_data) def finish(self): Provenance().add_output_file(self.output_file, role='mon.tel.flatfield') self.writer.close()
class PedestalHDF5Writer(Tool): name = "PedestalHDF5Writer" description = "Generate a HDF5 file with pedestal values" output_file = Unicode( 'pedestal.hdf5', help='Name of the output file' ).tag(config=True) calculator_product = tool_utils.enum_trait( PedestalCalculator, default='PedestalIntegrator' ) aliases = Dict(dict( pedestal_calculator='PedestalHDF5Writer.calculator_product', input_file='EventSource.input_url', max_events='EventSource.max_events', tel_id='PedestalCalculator.tel_id', sample_duration='PedestalCalculator.sample_duration', sample_size='PedestalCalculator.sample_size', n_channels='PedestalCalculator.n_channels', charge_product = 'PedestalCalculator.charge_product' )) classes = List([EventSource, PedestalCalculator, PedestalContainer, HDF5TableWriter ] + tool_utils.classes_with_traits(PedestalCalculator)) def __init__(self, **kwargs): super().__init__(**kwargs) self.eventsource = None self.pedestal = None self.container = None self.writer = None def setup(self): kwargs = dict(parent=self) self.eventsource = EventSource.from_config(**kwargs) self.pedestal = PedestalCalculator.from_name( self.calculator_product, **kwargs ) self.writer = HDF5TableWriter( filename=self.output_file, group_name='pedestals', overwrite=True ) def start(self): '''Pedestal calculator''' for count, event in enumerate(self.eventsource): if __name__ == '__main__': ped_data = self.pedestal.calculate_pedestals(event) if ped_data: # save the config, to be retrieved as data.meta['config'] write_config = False if not write_config: ped_data.meta['config']=self.config write_config = True table_name = 'tel_' + str(self.pedestal.tel_id) self.log.info("write event in table: /pedestal/%s", table_name) self.writer.write(table_name, ped_data) def finish(self): Provenance().add_output_file( self.output_file, role='mon.tel.pedestal' ) self.writer.close()
def test_enum_classes_with_traits(): # function under test from ctapipe.utils.tools import classes_with_traits list_of_classes = classes_with_traits(ImageExtractor) assert list_of_classes # should not be empty
class DisplayDL1Calib(Tool): name = "DisplayDL1Calib" description = "Calibrate dl0 data to dl1, and plot the photoelectron " \ "images." telescope = Int( None, allow_none=True, help='Telescope to view. Set to None to display all ' 'telescopes.' ).tag(config=True) extractor_product = tool_utils.enum_trait( ChargeExtractor, default='NeighbourPeakIntegrator' ) aliases = Dict( dict( max_events='EventSource.max_events', extractor='DisplayDL1Calib.extractor_product', t0='SimpleIntegrator.t0', window_width='WindowIntegrator.window_width', window_shift='WindowIntegrator.window_shift', sig_amp_cut_HG='PeakFindingIntegrator.sig_amp_cut_HG', sig_amp_cut_LG='PeakFindingIntegrator.sig_amp_cut_LG', lwt='NeighbourPeakIntegrator.lwt', clip_amplitude='CameraDL1Calibrator.clip_amplitude', T='DisplayDL1Calib.telescope', O='ImagePlotter.output_path' ) ) flags = Dict( dict( D=({ 'ImagePlotter': { 'display': True } }, "Display the photoelectron images on-screen as they " "are produced.") ) ) classes = List( [ EventSource, CameraDL1Calibrator, ImagePlotter ] + tool_utils.classes_with_traits(ChargeExtractor) ) def __init__(self, **kwargs): super().__init__(**kwargs) self.eventsource = None self.calibrator = None self.plotter = None def setup(self): kwargs = dict(config=self.config, tool=self) self.eventsource = event_source( get_dataset_path("gamma_test.simtel.gz"), **kwargs ) self.calibrator = CameraCalibrator( eventsource=self.eventsource, **kwargs ) self.plotter = ImagePlotter(**kwargs) def start(self): for event in self.eventsource: self.calibrator.calibrate(event) tel_list = event.r0.tels_with_data if self.telescope: if self.telescope not in tel_list: continue tel_list = [self.telescope] for telid in tel_list: self.plotter.plot(event, telid) def finish(self): self.plotter.finish()