Exemplo n.º 1
0
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)
Exemplo n.º 3
0
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
Exemplo n.º 4
0
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()
Exemplo n.º 5
0
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
Exemplo n.º 6
0
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()
Exemplo n.º 7
0
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
Exemplo n.º 8
0
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()
Exemplo n.º 9
0
def test_enum_trait_default_is_right():
    # function under test
    from ctapipe.utils.tools import enum_trait

    with pytest.raises(ValueError):
        enum_trait(ImageExtractor, default='name_of_default_choice')
Exemplo n.º 10
0
def test_enum_trait():
    # function under test
    from ctapipe.utils.tools import enum_trait

    trait = enum_trait(ImageExtractor, default='NeighborPeakWindowSum')
    assert isinstance(trait, traitlets.traitlets.CaselessStrEnum)
Exemplo n.º 11
0
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()
Exemplo n.º 12
0
def test_enum_trait():
    # function under test
    from ctapipe.utils.tools import enum_trait

    trait = enum_trait(ChargeExtractor, default='NeighbourPeakIntegrator')
    assert isinstance(trait, traitlets.traitlets.CaselessStrEnum)