Exemplo n.º 1
0
def test_waveform_extractor_factory_args():
    """
    Config is supposed to be created by a `Tool`
    """
    from traitlets.config.loader import Config
    config = Config(
        {
            'ImageExtractor': {
                'window_width': 20,
                'window_shift': 3,
            }
        }
    )

    extractor = ImageExtractor.from_name(
        'LocalPeakWindowSum',
        config=config,
    )
    assert extractor.window_width == 20
    assert extractor.window_shift == 3

    with pytest.warns(UserWarning):
        ImageExtractor.from_name(
            'FullWaveformSum',
            config=config,
        )
Exemplo n.º 2
0
def test_extractor_tel_param(camera_waveforms):
    waveforms, subarray = camera_waveforms
    _, n_samples = waveforms.shape

    config = Config({
        'ImageExtractor': {
            'window_width': [("type", "*", n_samples),
                             ("id", "2", n_samples // 2)],
            'window_start': 0,
        }
    })

    waveforms, subarray = camera_waveforms
    n_pixels, n_samples = waveforms.shape
    extractor = ImageExtractor.from_name("FixedWindowSum", config=config)

    with pytest.raises(KeyError):
        assert extractor.window_width[1] == n_samples

    with pytest.raises(KeyError):
        assert extractor.window_width[2] == n_samples // 2

    assert extractor.window_start[None] == 0
    assert extractor.window_width[None] == n_samples

    extractor = ImageExtractor.from_name("FixedWindowSum",
                                         config=config,
                                         subarray=subarray)

    assert extractor.window_start[1] == 0
    assert extractor.window_start[2] == 0
    assert extractor.window_width[None] == n_samples
    assert extractor.window_width[1] == n_samples
    assert extractor.window_width[2] == n_samples // 2
Exemplo n.º 3
0
def test_waveform_extractor_factory_args(subarray):
    """
    Config is supposed to be created by a `Tool`
    """
    config = Config({"ImageExtractor": {"window_width": 20, "window_shift": 3}})

    extractor = ImageExtractor.from_name(
        "LocalPeakWindowSum", subarray=subarray, config=config
    )
    assert extractor.window_width.tel[None] == 20
    assert extractor.window_shift.tel[None] == 3

    with pytest.warns(UserWarning):
        ImageExtractor.from_name("FullWaveformSum", config=config, subarray=subarray)
Exemplo n.º 4
0
    def __init__(
        self,
        subarray,
        config=None,
        parent=None,
        cleaner=None,
        image_extractor=None,
        **kwargs,
    ):
        """
        Parameters
        ----------
        subarray: ctapipe.instrument.SubarrayDescription
            Description of the subarray
        config: traitlets.loader.Config
            Configuration specified by config file or cmdline arguments.
            Used to set traitlet values.
            Set to None if no configuration to pass.
        kwargs
        """
        super().__init__(config=config, parent=parent, subarray=subarray, **kwargs)

        if cleaner is None:
            self.cleaner = TailcutsImageCleaner(parent=self, subarray=self.subarray)
        else:
            self.cleaner = cleaner

        if image_extractor is None:
            self.image_extractor = ImageExtractor.from_name(
                self.image_extractor_type, subarray=self.subarray, parent=self
            )
        else:
            self.image_extractor = image_extractor
Exemplo n.º 5
0
    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.dl0 = CameraDL0Reducer(parent=self)
        self.dl1 = CameraDL1Calibrator(extractor=self.extractor, parent=self)

        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]])
Exemplo n.º 6
0
def test_waveform_extractor_factory(toymodel):
    waveforms, subarray, telid, selected_gain_channel, true_charge, true_time = toymodel
    extractor = ImageExtractor.from_name("LocalPeakWindowSum",
                                         subarray=subarray)
    charge, pulse_time = extractor(waveforms, telid, selected_gain_channel)
    assert_allclose(charge, true_charge, rtol=0.1)
    assert_allclose(pulse_time, true_time, rtol=0.1)
    def __init__(self, subarray, **kwargs):
        """
        The TimeCorrectionCalculate class to create h5py
        file with coefficients for time correction curve of chip DRS4.
        Description of this method: "Analysis techniques and performance
        of the Domino Ring Sampler version 4 based readout
        for the MAGIC telescopes [arxiv:1305.1007]

        Parameters
        ----------
        subarray: ctapipe.instrument.SubarrayDescription
            Description of the subarray. Provides information about the
            camera which are useful in charge extraction, such as reference
            pulse shape, sampling rate, neighboring pixels. Also required for
            configuring the TelescopeParameter traitlets.
        kwargs
        """
        super().__init__(**kwargs)

        self.n_bins = int(self.n_capacitors / self.n_combine)

        self.mean_values_per_bin = np.zeros((n_gain, n_pixels, self.n_bins))
        self.entries_per_bin = np.zeros((n_gain, n_pixels, self.n_bins))

        self.first_cap_array = np.zeros((n_modules, n_gain, n_channel))

        # load the waveform charge extractor
        self.extractor = ImageExtractor.from_name(self.charge_product,
                                                  config=self.config,
                                                  subarray=subarray)

        self.log.info(f"extractor {self.extractor}")
        self.sum_events = 0
Exemplo n.º 8
0
def test_extractor_tel_param(toymodel):
    waveforms, subarray, _, _, _, _ = toymodel
    _, n_samples = waveforms.shape

    config = Config({
        "ImageExtractor": {
            "window_width": [("type", "*", n_samples),
                             ("id", "2", n_samples // 2)],
            "window_start": 0,
        }
    })

    waveforms, subarray, _, _, _, _ = toymodel
    n_pixels, n_samples = waveforms.shape
    extractor = ImageExtractor.from_name(
        "FixedWindowSum",
        subarray=subarray,
        config=config,
    )

    assert extractor.window_start.tel[None] == 0
    assert extractor.window_start.tel[1] == 0
    assert extractor.window_start.tel[2] == 0
    assert extractor.window_width.tel[None] == n_samples
    assert extractor.window_width.tel[1] == n_samples
    assert extractor.window_width.tel[2] == n_samples // 2
Exemplo n.º 9
0
    def __init__(
        self,
        subarray,
        config=None,
        parent=None,
        image_extractor=None,
        data_volume_reducer=None,
        **kwargs,
    ):
        """
        Parameters
        ----------
        subarray: ctapipe.instrument.SubarrayDescription
            Description of the subarray. Provides information about the
            camera which are useful in calibration. Also required for
            configuring the TelescopeParameter traitlets.
        config: traitlets.loader.Config
            Configuration specified by config file or cmdline arguments.
            Used to set traitlet values.
            This is mutually exclusive with passing a ``parent``.
        parent: ctapipe.core.Component or ctapipe.core.Tool
            Parent of this component in the configuration hierarchy,
            this is mutually exclusive with passing ``config``
        data_volume_reducer: ctapipe.image.reducer.DataVolumeReducer
            The DataVolumeReducer to use.
            This is used to override the options from the config system
            and to enable passing a preconfigured reducer.
        image_extractor: ctapipe.image.extractor.ImageExtractor
            The ImageExtractor to use. If None, the default via the
            configuration system will be constructed.
        """
        super().__init__(subarray=subarray,
                         config=config,
                         parent=parent,
                         **kwargs)
        self.subarray = subarray

        self._r1_empty_warn = False
        self._dl0_empty_warn = False

        self.image_extractors = {}

        if image_extractor is None:
            for (_, _, name) in self.image_extractor_type:
                self.image_extractors[name] = ImageExtractor.from_name(
                    name, subarray=self.subarray, parent=self)
        else:
            name = image_extractor.__class__.__name__
            self.image_extractor_type = [("type", "*", name)]
            self.image_extractors[name] = image_extractor

        if data_volume_reducer is None:
            self.data_volume_reducer = DataVolumeReducer.from_name(
                self.data_volume_reducer_type,
                subarray=self.subarray,
                parent=self)
        else:
            self.data_volume_reducer = data_volume_reducer
Exemplo n.º 10
0
    def setup(self):
        self.log_format = "%(levelname)s: %(message)s [%(name)s.%(funcName)s]"

        event_source = self.add_component(EventSource.from_config(parent=self))
        self.eventseeker = self.add_component(
            EventSeeker(event_source, parent=self))
        self.extractor = self.add_component(
            ImageExtractor.from_name(self.extractor_product, parent=self))
        self.calibrate = self.add_component(
            CameraCalibrator(parent=self, image_extractor=self.extractor))
Exemplo n.º 11
0
    def setup(self):
        self.log_format = "%(levelname)s: %(message)s [%(name)s.%(funcName)s]"

        self.eventsource = self.add_component(SimTelEventSource(parent=self))

        extractor = self.add_component(
            ImageExtractor.from_name(self.extractor_product, parent=self))

        self.calibrator = self.add_component(
            CameraCalibrator(parent=self, image_extractor=extractor))
        self.calculator = ChargeResolutionCalculator()
Exemplo n.º 12
0
    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 = ImageExtractor.from_name(
            self.extractor_product,
            parent=self,
        )
        self.dl0 = CameraDL0Reducer(parent=self)
        self.dl1 = CameraDL1Calibrator(extractor=self.extractor, parent=self)
Exemplo n.º 13
0
    def __init__(self, subarray, **kwargs):
        """
        Parameters
        ----------

        reducer_product : ctapipe.image.reducer.DataVolumeReducer
            The DataVolumeReducer to use. If None, then
            NullDataVolumeReducer will be used by default, and waveforms
            will not be reduced.
        extractor_product : ctapipe.image.extractor.ImageExtractor
            The ImageExtractor to use. If None, then LocalPeakWindowSum
            will be used by default.
        calibration_path :
            Path to LST calibration file to get the pedestal and flat-field corrections


        kwargs
        """
        super().__init__(subarray, **kwargs)

        # load the waveform charge extractor
        self.image_extractor = ImageExtractor.from_name(self.extractor_product,
                                                        subarray=self.subarray,
                                                        config=self.config)
        self.log.info(f"extractor {self.extractor_product}")

        print("EXTRACTOR", self.image_extractor)

        self.data_volume_reducer = DataVolumeReducer.from_name(
            self.reducer_product, subarray=self.subarray, config=self.config)
        self.log.info(f" {self.reducer_product}")

        # declare gain selector if the threshold is defined
        if self.gain_threshold:
            self.gain_selector = gainselection.ThresholdGainSelector(
                threshold=self.gain_threshold)

        # declare time calibrator if correction file exist
        if os.path.exists(self.time_calibration_path):
            self.time_corrector = PulseTimeCorrection(
                calib_file_path=self.time_calibration_path)
        else:
            raise IOError(
                f"Time calibration file {self.time_calibration_path} not found!"
            )

        # calibration data container
        self.mon_data = MonitoringContainer()

        # initialize the MonitoringContainer() for the moment it reads it from a hdf5 file
        self._initialize_correction()

        self.log.info(f"Global charge scale {self.charge_scale}")
Exemplo n.º 14
0
def test_waveform_extractor_factory_args():
    """
    Config is supposed to be created by a `Tool`
    """
    config = Config(
        {'ImageExtractor': {
            'window_width': 20,
            'window_shift': 3,
        }})

    extractor = ImageExtractor.from_name(
        'LocalPeakWindowSum',
        config=config,
    )
    assert extractor.window_width[None] == 20
    assert extractor.window_shift[None] == 3

    with pytest.warns(UserWarning):
        ImageExtractor.from_name(
            'FullWaveformSum',
            config=config,
        )
Exemplo n.º 15
0
    def setup(self):
        self.log_format = "%(levelname)s: %(message)s [%(name)s.%(funcName)s]"

        self.eventsource = SimTelEventSource(parent=self)

        extractor = ImageExtractor.from_name(self.extractor_product,
                                             parent=self)

        self.dl0 = CameraDL0Reducer(parent=self)

        self.dl1 = CameraDL1Calibrator(extractor=extractor, parent=self)

        self.calculator = ChargeResolutionCalculator()
Exemplo n.º 16
0
def test_waveform_extractor_factory_args(subarray):
    """
    Config is supposed to be created by a `Tool`
    """
    config = Config(
        {"ImageExtractor": {
            "window_width": 20,
            "window_shift": 3
        }})

    extractor = ImageExtractor.from_name("LocalPeakWindowSum",
                                         subarray=subarray,
                                         config=config)
    assert extractor.window_width.tel[None] == 20
    assert extractor.window_shift.tel[None] == 3

    # this basically tests that traitlets do not accept unknown traits,
    # which is tested for all traitlets in the core tests already
    with pytest.raises(TraitError):
        ImageExtractor.from_name("FullWaveformSum",
                                 config=config,
                                 subarray=subarray)
Exemplo n.º 17
0
    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.r1 = CameraR1Calibrator.from_eventsource(
            eventsource=self.reader,
            parent=self
        )
        self.dl0 = CameraDL0Reducer(parent=self)
        self.dl1 = CameraDL1Calibrator(
            extractor=self.extractor,
            parent=self
        )

        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]
        ])
Exemplo n.º 18
0
 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.º 19
0
    def setup(self):
        self.log_format = "%(levelname)s: %(message)s [%(name)s.%(funcName)s]"

        self.eventsource = SimTelEventSource(parent=self)

        extractor = ImageExtractor.from_name(
            self.extractor_product,
            parent=self
        )

        self.dl0 = CameraDL0Reducer(parent=self)

        self.dl1 = CameraDL1Calibrator(extractor=extractor, parent=self)

        self.calculator = ChargeResolutionCalculator()
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        self.n_bins = int(self.n_capacitors / self.n_combine)

        self.mean_values_per_bin = np.zeros((n_gain, n_pixels, self.n_bins))
        self.entries_per_bin = np.zeros((n_gain, n_pixels, self.n_bins))

        self.first_cap_array = np.zeros((n_modules, n_gain, n_channel))

        # load the waveform charge extractor
        self.extractor = ImageExtractor.from_name(self.charge_product,
                                                  config=self.config)

        self.log.info(f"extractor {self.extractor}")
        self.sum_events = 0
Exemplo n.º 21
0
 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.º 22
0
def test_sw_pulse_lst():
    """
    Test function of sliding window extractor for LST camera pulse shape with
    the correction for the integration window completeness
    """

    # prepare array with 1 LST
    subarray = SubarrayDescription(
        "LST1",
        tel_positions={1: np.zeros(3) * u.m},
        tel_descriptions={
            1:
            TelescopeDescription.from_name(optics_name="LST",
                                           camera_name="LSTCam")
        },
    )

    telid = list(subarray.tel.keys())[0]

    n_pixels = subarray.tel[telid].camera.geometry.n_pixels
    n_samples = 40
    readout = subarray.tel[telid].camera.readout

    random = np.random.RandomState(1)
    min_charge = 100
    max_charge = 1000
    charge_true = random.uniform(min_charge, max_charge, n_pixels)
    time_true = random.uniform(n_samples // 2 - 1, n_samples // 2 + 1,
                               n_pixels) / readout.sampling_rate.to_value(
                                   u.GHz)

    waveform_model = WaveformModel.from_camera_readout(readout)
    waveform = waveform_model.get_waveform(charge_true, time_true, n_samples)
    selected_gain_channel = np.zeros(charge_true.size, dtype=np.int8)

    # define extractor
    config = Config({"SlidingWindowMaxSum": {"window_width": 8}})
    extractor = SlidingWindowMaxSum(subarray=subarray)
    extractor = ImageExtractor.from_name("SlidingWindowMaxSum",
                                         subarray=subarray,
                                         config=config)

    dl1: DL1CameraContainer = extractor(waveform, telid, selected_gain_channel)
    print(dl1.image / charge_true)
    assert_allclose(dl1.image, charge_true, rtol=0.02)
    assert dl1.is_valid
Exemplo n.º 23
0
    def __init__(self, subarray, **kwargs):

        """Calculates flat-field parameters from flasher data
           based on the best algorithm described by S. Fegan in MST-CAM-TN-0060 (eq. 19)
           Pixels are defined as outliers on the base of a cut on the pixel charge median
           over the full sample distribution and the pixel signal time inside the
           waveform time


         Parameters:
         ----------
         charge_cut_outliers : List[2]
             Interval of accepted charge values (fraction with respect to camera median value)
         time_cut_outliers : List[2]
             Interval (in waveform samples) of accepted time values

        """
        super().__init__(subarray, **kwargs)

        self.log.info("Used events statistics : %d", self.sample_size)

        # members to keep state in calculate_relative_gain()
        self.num_events_seen = 0
        self.time_start = None  # trigger time of first event in sample
        self.trigger_time = None  # trigger time of present event

        self.charge_medians = None  # med. charge in camera per event in sample
        self.charges = None  # charge per event in sample
        self.arrival_times = None  # arrival time per event in sample
        self.sample_masked_pixels = None  # masked pixels per event in sample

        # declare the charge sampling corrector
        if self.time_sampling_correction_path is not None:
            self.time_sampling_corrector = TimeSamplingCorrection(
                    time_sampling_correction_path=self.time_sampling_correction_path
            )
        else:
            self.time_sampling_corrector = None

        # fix for broken extractor setup in ctapipe baseclass
        self.extractor = ImageExtractor.from_name(
            self.charge_product, parent=self, subarray=subarray
        )
Exemplo n.º 24
0
    def __init__(self, subarray, **kwargs):

        """
        Parent class for the flat-field calculators.
        Fills the MonitoringCameraContainer.FlatfieldContainer on the base of a given
        flat-field event sample.
        The sample is defined by a maximal interval of time (sample_duration) or a
        minimal number of events (sample_duration).
        The calculator is supposed to be called in an event loop, extract and collect the
        event charge and fill the PedestalContainer

        Parameters
        ----------
        subarray: ctapipe.instrument.SubarrayDescription
            Description of the subarray
        tel_id : int
              id of the telescope (default 0)
        sample_duration : int
             interval of time (s) used to gather the pedestal statistics
        sample_size : int
             number of pedestal events requested for the statistics
        n_channels : int
             number of waveform channel to be considered
        charge_product : str
            Name of the charge extractor to be used
        config : traitlets.loader.Config
            Configuration specified by config file or cmdline arguments.
            Used to set traitlet values.
            Set to None if no configuration to pass.

        kwargs

        """

        super().__init__(**kwargs)
        # load the waveform charge extractor
        self.extractor = ImageExtractor.from_name(
            self.charge_product,
            config=self.config,
            subarray=subarray,
        )

        self.log.info(f"extractor {self.extractor}")
Exemplo n.º 25
0
    def __init__(self, subarray, **kwargs):
        """Calculates pedestal parameters integrating the charge of pedestal events:
           the pedestal value corresponds to the charge estimated with the selected
           charge extractor
           The pixels are set as outliers on the base of a cut on the pixel charge median
           over the pedestal sample and the pixel charge standard deviation over
           the pedestal sample with respect to the camera median values


         Parameters:
         ----------
         charge_median_cut_outliers : List[2]
             Interval (number of std) of accepted charge values around camera median value
         charge_std_cut_outliers : List[2]
             Interval (number of std) of accepted charge standard deviation around camera median value
        """

        super().__init__(subarray, **kwargs)

        self.log.info("Used events statistics : %d", self.sample_size)

        # members to keep state in calculate_relative_gain()
        self.num_events_seen = 0
        self.time_start = None  # trigger time of first event in sample
        self.trigger_time = None  # trigger time of present event

        self.charge_medians = None  # med. charge in camera per event in sample
        self.charges = None  # charge per event in sample
        self.sample_masked_pixels = None  # pixels tp be masked per event in sample

        # declare the charge sampling corrector
        if self.time_sampling_correction_path is not None:
            self.time_sampling_corrector = TimeSamplingCorrection(
                time_sampling_correction_path=self.
                time_sampling_correction_path)
        else:
            self.time_sampling_corrector = None

        # fix for broken extractor setup in ctapipe baseclass
        self.extractor = ImageExtractor.from_name(self.charge_product,
                                                  parent=self,
                                                  subarray=subarray)
Exemplo n.º 26
0
    def __init__(self, **kwargs):
        """
        Parent class for the flat field calculators.
        Fills the flatfield container.

        Parameters
        ----------
        config : traitlets.loader.Config
            Configuration specified by config file or cmdline arguments.
            Used to set traitlet values.
            Set to None if no configuration to pass.
        tool : ctapipe.core.Tool
            Tool executable that is calling this component.
            Passes the correct logger to the component.
            Set to None if no Tool to pass.
        kwargs

        """
        super().__init__(**kwargs)
        # load the waveform charge extractor
        self.extractor = ImageExtractor.from_name(self.charge_product,
                                                  config=self.config)

        self.log.info(f"extractor {self.extractor}")
Exemplo n.º 27
0
def test_waveform_extractor_factory(camera_waveforms):
    waveforms, _ = camera_waveforms
    extractor = ImageExtractor.from_name('LocalPeakWindowSum')
    extractor(waveforms)
Exemplo n.º 28
0
def test_waveform_extractor_factory(camera_waveforms):
    waveforms, _ = camera_waveforms
    extractor = ImageExtractor.from_name('LocalPeakWindowSum')
    extractor(waveforms)