示例#1
0
文件: dl1.py 项目: renlliang3/ctapipe
 def __init__(self, config, tool, extractor=None, cleaner=None, **kwargs):
     super().__init__(config=config, parent=tool, **kwargs)
     self.extractor = extractor
     if self.extractor is None:
         self.extractor = NeighbourPeakIntegrator(config, tool)
     self.cleaner = cleaner
     if self.cleaner is None:
         self.cleaner = NullWaveformCleaner(config, tool)
     self._dl0_empty_warn = False
示例#2
0
文件: dl1.py 项目: epuesche/ctapipe
 def __init__(self, config, tool, extractor=None, cleaner=None, **kwargs):
     super().__init__(config=config, parent=tool, **kwargs)
     self.extractor = extractor
     if self.extractor is None:
         self.extractor = NeighbourPeakIntegrator(config, tool)
     self.cleaner = cleaner
     if self.cleaner is None:
         self.cleaner = NullWaveformCleaner(config, tool)
     self._dl0_empty_warn = False
示例#3
0
文件: dl1.py 项目: renlliang3/ctapipe
class CameraDL1Calibrator(Component):
    """
    The calibrator for DL1 charge extraction. Fills the dl1 container.

    It handles the integration correction and, if required, the list of
    neighbours.

    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 or None
        Tool executable that is calling this component.
        Passes the correct logger to the component.
        Set to None if no Tool to pass.
    extractor : ctapipe.calib.camera.charge_extractors.ChargeExtractor
        The extractor to use to extract the charge from the waveforms.
        By default the NeighbourPeakIntegrator with default configuration
        is used.
    cleaner : ctapipe.calib.camera.waveform_cleaners.Cleaner
        The waveform cleaner to use. By default no cleaning is
        applied to the waveforms.
    kwargs
    """

    name = 'CameraCalibrator'
    radius = Float(None,
                   allow_none=True,
                   help='Pixels within radius from a pixel are considered '
                   'neighbours to the pixel. Set to None for the default '
                   '(1.4 * min_pixel_seperation).').tag(config=True)
    clip_amplitude = Float(None,
                           allow_none=True,
                           help='Amplitude in p.e. above which the signal is '
                           'clipped. Set to None for no '
                           'clipping.').tag(config=True)

    def __init__(self, config, tool, extractor=None, cleaner=None, **kwargs):
        super().__init__(config=config, parent=tool, **kwargs)
        self.extractor = extractor
        if self.extractor is None:
            self.extractor = NeighbourPeakIntegrator(config, tool)
        self.cleaner = cleaner
        if self.cleaner is None:
            self.cleaner = NullWaveformCleaner(config, tool)
        self._dl0_empty_warn = False

    def check_dl0_exists(self, event, telid):
        """
        Check that dl0 data exists. If it does not, then do not change dl1.

        This ensures that if the containers were filled from a file containing
        dl1 data, it is not overwritten by non-existant data.

        Parameters
        ----------
        event : container
            A `ctapipe` event container
        telid : int
            The telescope id.

        Returns
        -------
        bool
            True if dl0.tel[telid].pe_samples is not None, else false.
        """
        dl0 = event.dl0.tel[telid].pe_samples
        if dl0 is not None:
            return True
        else:
            if not self._dl0_empty_warn:
                self.log.warning("Encountered an event with no DL0 data. "
                                 "DL1 is unchanged in this circumstance.")
                self._dl0_empty_warn = True
            return False

    @staticmethod
    def get_geometry(event, telid):
        """
        Obtain the geometry for this telescope.

        Parameters
        ----------
        event : container
            A `ctapipe` event container
        telid : int
            The telescope id.
            The neighbours are calculated once per telescope.

        Returns
        -------
        `CameraGeometry`
        """
        return CameraGeometry.guess(*event.inst.pixel_pos[telid],
                                    event.inst.optical_foclen[telid])

    def get_correction(self, event, telid):
        """
        Obtain the integration correction for this telescope.

        Parameters
        ----------
        event : container
            A `ctapipe` event container
        telid : int
            The telescope id.
            The integration correction is calculated once per telescope.

        Returns
        -------
        ndarray
        """
        try:
            shift = self.extractor.window_shift
            width = self.extractor.window_width
            n_chan = event.inst.num_channels[telid]
            shape = event.mc.tel[telid].reference_pulse_shape
            step = event.mc.tel[telid].meta['refstep']
            time_slice = event.mc.tel[telid].time_slice
            correction = integration_correction(n_chan, shape, step,
                                                time_slice, width, shift)
            return correction
        except (AttributeError, KeyError):
            # Don't apply correction when window_shift or window_width
            # does not exist in extractor, or when container does not have
            # a reference pulse shape
            return np.ones(event.inst.num_channels[telid])

    def calibrate(self, event):
        """
        Fill the dl1 container with the calibration data that results from the
        configuration of this calibrator.

        Parameters
        ----------
        event : container
            A `ctapipe` event container
        """
        for telid in event.dl0.tels_with_data:

            if self.check_dl0_exists(event, telid):
                waveforms = event.dl0.tel[telid].pe_samples
                n_samples = waveforms.shape[2]
                if n_samples == 1:
                    # To handle ASTRI and dst
                    corrected = waveforms[..., 0]
                    window = np.ones(waveforms.shape)
                    peakpos = np.zeros(waveforms.shape[0:2])
                    cleaned = waveforms
                else:
                    # Clean waveforms
                    cleaned = self.cleaner.apply(waveforms)

                    # Extract charge
                    if self.extractor.requires_neighbours():
                        e = self.extractor
                        g = self.get_geometry(event, telid)
                        e.neighbours = g.neighbor_matrix_where
                    extract = self.extractor.extract_charge
                    charge, peakpos, window = extract(cleaned)

                    # Apply integration correction
                    correction = self.get_correction(event, telid)[:, None]
                    corrected = charge * correction

                # Clip amplitude
                if self.clip_amplitude:
                    corrected[corrected > self.clip_amplitude] = \
                        self.clip_amplitude

                # Store into event container
                event.dl1.tel[telid].image = corrected
                event.dl1.tel[telid].extracted_samples = window
                event.dl1.tel[telid].peakpos = peakpos
                event.dl1.tel[telid].cleaned = cleaned
示例#4
0
文件: dl1.py 项目: epuesche/ctapipe
class CameraDL1Calibrator(Component):
    """
    The calibrator for DL1 charge extraction. Fills the dl1 container.

    It handles the integration correction and, if required, the list of
    neighbours.

    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 or None
        Tool executable that is calling this component.
        Passes the correct logger to the component.
        Set to None if no Tool to pass.
    extractor : ctapipe.calib.camera.charge_extractors.ChargeExtractor
        The extractor to use to extract the charge from the waveforms.
        By default the NeighbourPeakIntegrator with default configuration
        is used.
    cleaner : ctapipe.calib.camera.waveform_cleaners.Cleaner
        The waveform cleaner to use. By default no cleaning is
        applied to the waveforms.
    kwargs
    """

    name = 'CameraCalibrator'
    radius = Float(None, allow_none=True,
                   help='Pixels within radius from a pixel are considered '
                        'neighbours to the pixel. Set to None for the default '
                        '(1.4 * min_pixel_seperation).').tag(config=True)
    clip_amplitude = Float(None, allow_none=True,
                           help='Amplitude in p.e. above which the signal is '
                                'clipped. Set to None for no '
                                'clipping.').tag(config=True)

    def __init__(self, config, tool, extractor=None, cleaner=None, **kwargs):
        super().__init__(config=config, parent=tool, **kwargs)
        self.extractor = extractor
        if self.extractor is None:
            self.extractor = NeighbourPeakIntegrator(config, tool)
        self.cleaner = cleaner
        if self.cleaner is None:
            self.cleaner = NullWaveformCleaner(config, tool)
        self._dl0_empty_warn = False

    def check_dl0_exists(self, event, telid):
        """
        Check that dl0 data exists. If it does not, then do not change dl1.

        This ensures that if the containers were filled from a file containing
        dl1 data, it is not overwritten by non-existant data.

        Parameters
        ----------
        event : container
            A `ctapipe` event container
        telid : int
            The telescope id.

        Returns
        -------
        bool
            True if dl0.tel[telid].pe_samples is not None, else false.
        """
        dl0 = event.dl0.tel[telid].pe_samples
        if dl0 is not None:
            return True
        else:
            if not self._dl0_empty_warn:
                self.log.warning("Encountered an event with no DL0 data. "
                                 "DL1 is unchanged in this circumstance.")
                self._dl0_empty_warn = True
            return False

    @staticmethod
    def get_geometry(event, telid):
        """
        Obtain the geometry for this telescope.

        Parameters
        ----------
        event : container
            A `ctapipe` event container
        telid : int
            The telescope id.
            The neighbours are calculated once per telescope.

        Returns
        -------
        `CameraGeometry`
        """
        return CameraGeometry.guess(*event.inst.pixel_pos[telid],
                                    event.inst.optical_foclen[telid])

    def get_correction(self, event, telid):
        """
        Obtain the integration correction for this telescope.

        Parameters
        ----------
        event : container
            A `ctapipe` event container
        telid : int
            The telescope id.
            The integration correction is calculated once per telescope.

        Returns
        -------
        ndarray
        """
        try:
            shift = self.extractor.window_shift
            width = self.extractor.window_width
            n_chan = event.inst.num_channels[telid]
            shape = event.mc.tel[telid].reference_pulse_shape
            step = event.mc.tel[telid].meta['refstep']
            time_slice = event.mc.tel[telid].time_slice
            correction = integration_correction(n_chan, shape, step,
                                                time_slice, width, shift)
            return correction
        except (AttributeError, KeyError):
            # Don't apply correction when window_shift or window_width
            # does not exist in extractor, or when container does not have
            # a reference pulse shape
            return np.ones(event.inst.num_channels[telid])

    def calibrate(self, event):
        """
        Fill the dl1 container with the calibration data that results from the
        configuration of this calibrator.

        Parameters
        ----------
        event : container
            A `ctapipe` event container
        """
        for telid in event.dl0.tels_with_data:

            if self.check_dl0_exists(event, telid):
                waveforms = event.dl0.tel[telid].pe_samples
                n_samples = waveforms.shape[2]
                if n_samples == 1:
                    # To handle ASTRI and dst
                    corrected = waveforms
                    window = np.ones(waveforms.shape)
                    peakpos = np.zeros(waveforms.shape[0:2])
                    cleaned = waveforms
                else:
                    # Clean waveforms
                    cleaned = self.cleaner.apply(waveforms)

                    # Extract charge
                    if self.extractor.requires_neighbours():
                        e = self.extractor
                        g = self.get_geometry(event, telid)
                        e.neighbours = g.neighbor_matrix_where
                    extract = self.extractor.extract_charge
                    charge, peakpos, window = extract(cleaned)

                    # Apply integration correction
                    correction = self.get_correction(event, telid)[:, None]
                    corrected = charge * correction

                # Clip amplitude
                if self.clip_amplitude:
                    corrected[corrected > self.clip_amplitude] = \
                        self.clip_amplitude

                # Store into event container
                event.dl1.tel[telid].image = corrected
                event.dl1.tel[telid].extracted_samples = window
                event.dl1.tel[telid].peakpos = peakpos
                event.dl1.tel[telid].cleaned = cleaned