示例#1
0
class TIOReader:
    """
    Reader for the R0 and R1 tio files
    """
    def __init__(self, path, max_events=None):
        try:
            from target_io import WaveformArrayReader
            from target_calib import CameraConfiguration
        except ModuleNotFoundError:
            msg = ("Cannot find TARGET libraries, please follow installation "
                   "instructions from https://forge.in2p3.fr/projects/gct/"
                   "wiki/Installing_CHEC_Software")
            raise ModuleNotFoundError(msg)

        if not os.path.exists(path):
            raise FileNotFoundError("File does not exist: {}".format(path))
        self.path = path

        self._reader = WaveformArrayReader(self.path, 2, 1)

        self.is_r1 = self._reader.fR1
        self.n_events = self._reader.fNEvents
        self.run_id = self._reader.fRunID
        self.n_pixels = self._reader.fNPixels
        self.n_modules = self._reader.fNModules
        self.n_tmpix = self.n_pixels // self.n_modules
        self.n_samples = self._reader.fNSamples

        self._camera_config = CameraConfiguration(self._reader.fCameraVersion)
        self.tc_mapping = self._camera_config.GetMapping(self.n_modules == 1)

        self._pixel = self._PixelWaveforms(self)

        self.n_cells = self._camera_config.GetNCells()
        self.camera_version = self._camera_config.GetVersion()
        self.reference_pulse_path = self._camera_config.GetReferencePulsePath()

        self.current_tack = None
        self.current_cpu_ns = None
        self.current_cpu_s = None

        self.first_cell_ids = np.zeros(self.n_pixels, dtype=np.uint16)

        if self.is_r1:
            self.samples = np.zeros((self.n_pixels, self.n_samples),
                                    dtype=np.float32)
            self.get_tio_event = self._reader.GetR1Event
        else:
            self.samples = np.zeros((self.n_pixels, self.n_samples),
                                    dtype=np.uint16)
            self.get_tio_event = self._reader.GetR0Event

        if max_events and max_events < self.n_events:
            self.n_events = max_events

    def _get_event(self, iev):
        self.index = iev
        self.get_tio_event(iev, self.samples, self.first_cell_ids)
        self.current_tack = self._reader.fCurrentTimeTack
        self.current_cpu_ns = self._reader.fCurrentTimeNs
        self.current_cpu_s = self._reader.fCurrentTimeSec
        return self.samples

    def __iter__(self):
        for iev in range(self.n_events):
            yield self._get_event(iev)

    def __getitem__(self, iev):
        return np.copy(self._get_event(iev))

    class _PixelWaveforms:
        def __init__(self, tio_reader):
            self.reader = tio_reader

        def __getitem__(self, p):
            if not isinstance(p, list) and not isinstance(p, np.ndarray):
                p = [p]

            n_events = self.reader.n_events
            n_pixels = len(p)
            n_samples = self.reader.n_samples
            waveforms = np.zeros((n_events, n_pixels, n_samples))

            for iev, wf in enumerate(self.reader):
                waveforms[iev] = wf[p]

            return waveforms

    @property
    def pixel(self):
        return self._pixel

    @property
    def mapping(self):
        return get_clp_mapping_from_tc_mapping(self.tc_mapping)

    def get_sn(self, tm):
        if tm >= self.n_modules:
            raise IndexError("Requested TM out of range: {}".format(tm))
        return self._reader.GetSN(tm)

    @staticmethod
    def is_compatible(filepath):
        try:
            h = fits.getheader(filepath, 0)
            if 'EVENT_HEADER_VERSION' not in h:
                return False
        except IOError:
            return False
        return True
示例#2
0
class SimtelReader(WaveformReader):
    def __init__(self, path, max_events=None):
        """
        Reads simtelarray files utilising the SimTelEventSource from ctapipe

        Parameters
        ----------
        path : str
            Path to the simtel file
        max_events : int
            Maximum number of events to read from the file
        """
        super().__init__(path, max_events)

        try:
            from ctapipe.io import SimTelEventSource, EventSeeker
        except ModuleNotFoundError:
            msg = "Cannot find ctapipe installation"
            raise ModuleNotFoundError(msg)

        try:
            from target_calib import CameraConfiguration
        except ModuleNotFoundError:
            msg = ("Cannot find TARGET libraries, please follow installation "
                   "instructions from https://forge.in2p3.fr/projects/gct/"
                   "wiki/Installing_CHEC_Software")
            raise ModuleNotFoundError(msg)

        self.path = path
        reader = SimTelEventSource(input_url=path,
                                   max_events=max_events,
                                   back_seekable=True)
        self.seeker = EventSeeker(reader)

        first_event = self.seeker[0]
        tels = list(first_event.r0.tels_with_data)
        self.tel = tels[0]
        shape = first_event.r0.tel[self.tel].waveform.shape
        _, self.n_pixels, self.n_samples = shape
        self.n_modules = self.n_pixels // 64
        self.index = 0

        n_modules = 32
        camera_version = "1.1.0"
        self._camera_config = CameraConfiguration(camera_version)
        tc_mapping = self._camera_config.GetMapping(n_modules == 1)
        self.mapping = get_clp_mapping_from_tc_mapping(tc_mapping)
        pix_x = first_event.inst.subarray.tel[tels[0]].camera.pix_x.value
        pix_y = first_event.inst.subarray.tel[tels[0]].camera.pix_y.value
        self.mapping['xpix'] = pix_x
        self.mapping['ypix'] = pix_y
        self.reference_pulse_path = self._camera_config.GetReferencePulsePath()
        self.camera_version = self._camera_config.GetVersion()

        self.gps_time = None
        self.mc_true = None
        self.mc = None
        self.pointing = None
        self.mcheader = None

    def _get_event(self, iev):
        event = self.seeker[iev]
        self._fill_event_containers(event)
        return event.r1.tel[self.tel].waveform[0]

    @staticmethod
    def is_compatible(path):
        # read the first 4 bytes
        with open(path, 'rb') as f:
            marker_bytes = f.read(4)

        # if file is gzip, read the first 4 bytes with gzip again
        if marker_bytes[0] == 0x1f and marker_bytes[1] == 0x8b:
            with gzip.open(path, 'rb') as f:
                marker_bytes = f.read(4)

        # check for the simtel magic marker
        int_marker, = struct.unpack('I', marker_bytes)
        return int_marker == 3558836791 or int_marker == 931798996

    def __iter__(self):
        for event in self.seeker:
            self._fill_event_containers(event)
            yield event.r1.tel[self.tel].waveform[0]

    def _fill_event_containers(self, event):
        self.index = event.count
        self.run_id = event.r0.obs_id
        self.gps_time = event.trig.gps_time

        self.mc_true = event.mc.tel[self.tel].photo_electron_image

        self.mc = dict(iev=self.index,
                       t_cpu=self.t_cpu,
                       energy=event.mc.energy.value,
                       alt=event.mc.alt.value,
                       az=event.mc.az.value,
                       core_x=event.mc.core_x.value,
                       core_y=event.mc.core_y.value,
                       h_first_int=event.mc.h_first_int.value,
                       x_max=event.mc.x_max.value,
                       shower_primary_id=event.mc.shower_primary_id)

        self.pointing = dict(
            iev=self.index,
            t_cpu=self.t_cpu,
            azimuth_raw=event.mc.tel[self.tel].azimuth_raw,
            altitude_raw=event.mc.tel[self.tel].altitude_raw,
            azimuth_cor=event.mc.tel[self.tel].azimuth_cor,
            altitude_cor=event.mc.tel[self.tel].altitude_cor,
        )

        if self.mcheader is None:
            mch = event.mcheader
            self.mcheader = dict(
                corsika_version=mch.corsika_version,
                simtel_version=mch.simtel_version,
                energy_range_min=mch.energy_range_min.value,
                energy_range_max=mch.energy_range_max.value,
                prod_site_B_total=mch.prod_site_B_total.value,
                prod_site_B_declination=mch.prod_site_B_declination.value,
                prod_site_B_inclination=mch.prod_site_B_inclination.value,
                prod_site_alt=mch.prod_site_alt.value,
                spectral_index=mch.spectral_index,
                shower_prog_start=mch.shower_prog_start,
                shower_prog_id=mch.shower_prog_id,
                detector_prog_start=mch.detector_prog_start,
                detector_prog_id=mch.detector_prog_id,
                num_showers=mch.num_showers,
                shower_reuse=mch.shower_reuse,
                max_alt=mch.max_alt.value,
                min_alt=mch.min_alt.value,
                max_az=mch.max_az.value,
                min_az=mch.min_az.value,
                diffuse=mch.diffuse,
                max_viewcone_radius=mch.max_viewcone_radius.value,
                min_viewcone_radius=mch.min_viewcone_radius.value,
                max_scatter_range=mch.max_scatter_range.value,
                min_scatter_range=mch.min_scatter_range.value,
                core_pos_mode=mch.core_pos_mode,
                injection_height=mch.injection_height.value,
                atmosphere=mch.atmosphere,
                corsika_iact_options=mch.corsika_iact_options,
                corsika_low_E_model=mch.corsika_low_E_model,
                corsika_high_E_model=mch.corsika_high_E_model,
                corsika_bunchsize=mch.corsika_bunchsize,
                corsika_wlen_min=mch.corsika_wlen_min.value,
                corsika_wlen_max=mch.corsika_wlen_max.value,
                corsika_low_E_detail=mch.corsika_low_E_detail,
                corsika_high_E_detail=mch.corsika_high_E_detail,
            )

    @property
    def n_events(self):
        return len(self.seeker)

    @property
    def t_cpu(self):
        return pd.to_datetime(self.gps_time.value, unit='s')
示例#3
0
文件: tio.py 项目: pillera/CHECLabPy
class TIOReader(WaveformReader):
    def __init__(self, path, max_events=None,
                 skip_events=2, skip_end_events=1):
        """
        Utilies TargetIO to read R0 and R1 tio files. Enables easy access to
        the waveforms for anaylsis.

        Waveforms can be read from the file by either indexing this reader or
        iterating over it:

        >>> path = "/path/to/file_r0.tio"
        >>> reader = TIOReader(path)
        >>> wf = reader[3]  # Obtain the waveforms for the third event

        >>> path = "/path/to/file_r0.tio"
        >>> reader = TIOReader(path)
        >>> wfs = reader[:10]  # Obtain the waveforms for the first 10 events

        >>> path = "/path/to/file_r0.tio"
        >>> reader = TIOReader(path)
        >>> for wf in reader:  # Iterate over all events in the file
        >>>    print(wf)

        Parameters
        ----------
        path : str
            Path to the _r0.tio or _r1.tio file
        max_events : int
            Maximum number of events to read from the file
        """
        super().__init__(path, max_events)

        try:
            from target_io import WaveformArrayReader
            from target_calib import CameraConfiguration
        except ModuleNotFoundError:
            msg = ("Cannot find TARGET libraries, please follow installation "
                   "instructions from https://forge.in2p3.fr/projects/gct/"
                   "wiki/Installing_CHEC_Software")
            raise ModuleNotFoundError(msg)

        self._reader = WaveformArrayReader(
            self.path, skip_events, skip_end_events
        )

        self.is_r1 = self._reader.fR1
        self._n_events = self._reader.fNEvents
        self.run_id = self._reader.fRunID
        self.n_pixels = self._reader.fNPixels
        self.n_superpixels_per_module = self._reader.fNSuperpixelsPerModule
        self.n_modules = self._reader.fNModules
        self.n_tmpix = self.n_pixels // self.n_modules
        self.n_samples = self._reader.fNSamples

        self._camera_config = CameraConfiguration(self._reader.fCameraVersion)
        self.tc_mapping = self._camera_config.GetMapping(self.n_modules == 1)

        self.n_cells = self._camera_config.GetNCells()
        self.camera_version = self._camera_config.GetVersion()
        self.reference_pulse_path = self._camera_config.GetReferencePulsePath()

        self.current_tack = None
        self.current_cpu_ns = None
        self.current_cpu_s = None

        self.first_cell_ids = np.zeros(self.n_pixels, dtype=np.uint16)
        self.stale = np.zeros(self.n_pixels, dtype=np.uint8)

        if self.is_r1:
            self.samples = np.zeros((self.n_pixels, self.n_samples),
                                    dtype=np.float32)
            self.get_tio_event = self._reader.GetR1Event
        else:
            self.samples = np.zeros((self.n_pixels, self.n_samples),
                                    dtype=np.uint16)
            self.get_tio_event = self._reader.GetR0Event

        if max_events and max_events < self._n_events:
            self._n_events = max_events

    def _get_event(self, iev):
        self.index = iev
        try:  # TODO: Remove try in future version
            self.get_tio_event(iev, self.samples, self.first_cell_ids,
                               self.stale)
        except TypeError:
            warnings.warn(
                "This call to WaveformArrayReader has been deprecated. "
                "Please update TargetIO",
                SyntaxWarning
            )
            self.get_tio_event(iev, self.samples, self.first_cell_ids)
        self.current_tack = self._reader.fCurrentTimeTack
        self.current_cpu_ns = self._reader.fCurrentTimeNs
        self.current_cpu_s = self._reader.fCurrentTimeSec
        return self.samples

    @staticmethod
    def is_compatible(path):
        with open(path, 'rb') as f:
            marker_bytes = f.read(1024)

        # if file is gzip, read the first 4 bytes with gzip again
        if marker_bytes[0] == 0x1f and marker_bytes[1] == 0x8b:
            with gzip.open(path, 'rb') as f:
                marker_bytes = f.read(1024)

        if b'FITS' not in marker_bytes:
            return False

        try:
            h = fits.getheader(path, 0)
            if 'EVENT_HEADER_VERSION' not in h:
                return False
        except IOError:
            return False
        return True

    @property
    def n_events(self):
        return self._n_events

    @property
    def t_cpu(self):
        return pd.to_datetime(
            np.int64(self.current_cpu_s * 1E9) + np.int64(self.current_cpu_ns),
            unit='ns'
        )

    @property
    def mapping(self):
        return get_clp_mapping_from_tc_mapping(self.tc_mapping)

    def get_sn(self, tm):
        """
        Get the SN of the TARGET module in a slot

        Parameters
        ----------
        tm : int
            Slot number for the TARGET module

        Returns
        -------
        int
            Serial number of the TM
        """
        if tm >= self.n_modules:
            raise IndexError("Requested TM out of range: {}".format(tm))
        return self._reader.GetSN(tm)

    def get_sipm_temp(self, tm):
        if tm >= self.n_modules:
            raise IndexError("Requested TM out of range: {}".format(tm))
        return self._reader.GetSiPMTemp(tm)

    def get_primary_temp(self, tm):
        if tm >= self.n_modules:
            raise IndexError("Requested TM out of range: {}".format(tm))
        return self._reader.GetPrimaryTemp(tm)

    def get_sp_dac(self, tm, sp):
        if tm >= self.n_modules:
            raise IndexError("Requested TM out of range: {}".format(tm))
        if sp >= self.n_superpixels_per_module:
            raise IndexError("Requested SP out of range: {}".format(sp))
        return self._reader.GetSPDAC(tm, sp)

    def get_sp_hvon(self, tm, sp):
        if tm >= self.n_modules:
            raise IndexError("Requested TM out of range: {}".format(tm))
        if sp >= self.n_superpixels_per_module:
            raise IndexError("Requested SP out of range: {}".format(sp))
        return self._reader.GetSPHVON(tm, sp)