Exemple #1
0
 def tc_mapping(self):
     """
     Obtain the TargetCalib mapping class
     """
     from target_calib import CameraConfiguration
     version = self.mapping.metadata.version
     camera_config = CameraConfiguration(version)
     return camera_config.GetMapping(self.n_modules == 1)
Exemple #2
0
    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
Exemple #3
0
    def __init__(self, config=None, parent=None, **kwargs):
        super().__init__(config=config, parent=parent, **kwargs)

        self._data = None
        self._event_index = None
        self._event_id = 0
        self._time_tack = None
        self._time_sec = None
        self._time_ns = None

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

        self._n_events = self._reader.fNEvents
        self._first_event_id = self._reader.fFirstEventID
        self._last_event_id = self._reader.fLastEventID
        self._obs_id = self._reader.fRunID
        n_modules = self._reader.fNModules
        n_pix = self._reader.fNPixels
        n_samples = self._reader.fNSamples
        self.camera_config = CameraConfiguration(self._reader.fCameraVersion)
        self._n_cells = self.camera_config.GetNCells()
        m = self.camera_config.GetMapping(n_modules == 1)

        self._optical_foclen = u.Quantity(2.15, u.m)
        self._mirror_area = u.Quantity(14.126, u.m ** 2)
        self._n_pixels = m.GetNPixels()
        self._xpix = np.array(m.GetXPixVector()) * u.m
        self._ypix = np.array(m.GetYPixVector()) * u.m
        self._refshape = np.zeros(10)  # TODO: Get correct values for CHEC-S
        self._refstep = 0  # TODO: Get correct values for CHEC-S
        self._time_slice = 0  # TODO: Get correct values for CHEC-S
        self._chec_tel = 0

        # Init fields
        self._r0_samples = None
        self._r1_samples = None
        self._first_cell_ids = np.zeros(n_pix, dtype=np.uint16)

        # Check if file is already r1 (Information obtained from a flag
        # in the file's header)
        is_r1 = self._reader.fR1
        if is_r1:
            self._r1_samples = np.zeros(
                (1, n_pix, n_samples),
                dtype=np.float32
            )
            self._get_tio_event = self._reader.GetR1Event
            self._samples = self._r1_samples[0]
        else:
            self._r0_samples = np.zeros(
                (1, n_pix, n_samples),
                dtype=np.uint16
            )
            self._get_tio_event = self._reader.GetR0Event
            self._samples = self._r0_samples[0]

        self._init_container()
def plot_from_tc_mapping():
    """
    Plot using the TargetCalib Mapping class
    """
    from target_calib import CameraConfiguration
    c = CameraConfiguration("1.1.0")
    m = c.GetMapping()
    camera = CameraImage.from_tc_mapping(m)
    image = np.zeros(m.GetNPixels())
    image[::2] = 1
    camera.image = image
    plt.show()
Exemple #5
0
    def configure(self, config={}):
        # should be read from the file in the future
        from target_calib import CameraConfiguration

        self.cam_config = CameraConfiguration("1.1.0")
        self._mapping = self.cam_config.GetMapping()
        config[self.cout_camconfig] = self.cam_config
        self.pixsize = self._mapping.GetSize()
        self.pix_posx = np.array(self._mapping.GetXPixVector())
        self.pix_posy = np.array(self._mapping.GetYPixVector())
        self.pix_pos = np.array(list(zip(self.pix_posx, self.pix_posy)))
        # for the time being we load all data at once
        config["n_frames"] = 1
def plot_tm():
    """
    Make a camera image plot for values that are per superpixel
    """
    from target_calib import CameraConfiguration
    c = CameraConfiguration("1.1.0")
    m = c.GetMapping()
    df = get_tm_mapping(get_clp_mapping_from_tc_mapping(m))
    camera = CameraImage.from_mapping(df)
    image = np.zeros(m.GetNModules())
    image[::2] = 1
    camera.image = image
    plt.show()
Exemple #7
0
    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 plot_from_coordinates():
    """
    Plot directly with coordinates
    """
    from target_calib import CameraConfiguration
    c = CameraConfiguration("1.1.0")
    m = c.GetMapping()
    xpix = np.array(m.GetXPixVector())
    ypix = np.array(m.GetYPixVector())
    size = m.GetSize()
    camera = CameraImage(xpix, ypix, size)
    image = np.zeros(xpix.size)
    image[::2] = 1
    camera.image = image
    plt.show()
Exemple #9
0
def obtain_pixel_list(superpixels):
    mapping = CameraConfiguration("1.1.0").GetMapping()
    mappingsp = MappingSP(mapping)
    pix_dict = dict()
    for sp in superpixels.keys():
        pix_dict[sp] = list(mappingsp.GetContainedPixels(sp))
    return pix_dict
    def configure(self, config):
        # should be read from the file in the future
        from target_calib import CameraConfiguration

        config[self.cout_camconfig] = CameraConfiguration("1.1.0")
        # for the time being we load all data at once
        config["n_frames"] = 1
Exemple #11
0
class Reader(ProcessingModule):
    def __init__(
        self,
        filename,
        focal_length=2.15,
        mirror_area=6.5,
        location=EarthLocation.from_geodetic(lon=14.974609, lat=37.693267, height=1730),
    ):
        super().__init__("DataReader")

        self.reader = DataReader(filename)
        print(self.reader)

        print("Simulation config:", self.reader.sim_attr_dict)
        self.cout_camconfig = "CameraConfiguration"
        self.out_raw_resp = "raw_resp"
        self._loaded_data = False
        self.location = location
        self.focal_length = focal_length
        self.mirror_area = mirror_area

    def configure(self, config={}):
        # should be read from the file in the future
        from target_calib import CameraConfiguration

        self.cam_config = CameraConfiguration("1.1.0")
        self._mapping = self.cam_config.GetMapping()
        config[self.cout_camconfig] = self.cam_config
        self.pixsize = self._mapping.GetSize()
        self.pix_posx = np.array(self._mapping.GetXPixVector())
        self.pix_posy = np.array(self._mapping.GetYPixVector())
        self.pix_pos = np.array(list(zip(self.pix_posx, self.pix_posy)))
        # for the time being we load all data at once
        config["n_frames"] = 1

    def run(self, frame={}):
        # Only read the data once

        if not self._loaded_data:
            self.res = []
            self.times = []
            for r in self.reader.read():
                self.res.append(r.flatten())
                self.times.append(self.reader.cpu_t)
            self._loaded_data = True
            self.res = np.array(self.res)
            self.times = np.array(self.times)
        frame[self.out_raw_resp] = SlowSignalData(
            copy.copy(self.res),
            copy.copy(self.times),
            {"xpix": self.pix_posx, "ypix": self.pix_posy, "size": self.pixsize},
            focal_length=self.focal_length,
            mirror_area=self.mirror_area,
            location=self.location,
        )

        return frame
def main():
    input_path = "/Volumes/gct-jason/data_checs/dynamicrange_180514/tf_pchip/spe_three.h5"
    file_dir = os.path.dirname(os.path.abspath(__file__))
    output_dir = os.path.join(file_dir, "outputs")

    dead = [677, 293, 27, 1925]

    store = pd.HDFStore(input_path)
    df = store['coeff_pixel']
    df_array = store['array_camera']
    df = df.loc[~df['pixel'].isin(dead)]
    df_mean = df.mean().to_dict()

    norm = (df_mean['norm0'] + df_mean['norm1'] + df_mean['norm2']) / 3
    spe = df_mean['spe']

    config = CameraConfiguration("1.1.0")
    ref_path = config.GetReferencePulsePath()
    cc = CrossCorrelation(1, 96, reference_pulse_path=ref_path)

    d = dict(norm=1,
             eped=cc.get_pulse_height(df_mean['eped']),
             eped_sigma=cc.get_pulse_height(df_mean['eped_sigma']),
             spe=cc.get_pulse_height(df_mean['spe']),
             spe_sigma=cc.get_pulse_height(df_mean['spe_sigma']),
             lambda_=1,
             opct=df_mean['opct'],
             pap=df_mean['pap'],
             dap=df_mean['dap'])

    hist = df_array.loc[0, 'hist'] / (norm * 800)
    edges = cc.get_pulse_height(df_array.loc[0, 'edges'])
    between = cc.get_pulse_height(df_array.loc[0, 'between'])

    x = np.linspace(-5, 15, 1000)
    y = pe_signal(1, x, **d)

    p_hist = SPEHist()
    label = "fadc_amplitude = spe = {:.3f}".format(d['spe'])
    p_hist.plot(hist, edges, between, x, y, label)
    output_path = os.path.join(output_dir, "checs_fadc_amplitude.pdf")
    p_hist.save(output_path)
Exemple #13
0
    def from_camera_version(cls, camera_version, single=False, **kwargs):
        """
        Generate the class using the camera version (required TargetCalib)

        Parameters
        ----------
        camera_version : str
            Version of the camera (e.g. "1.0.1" corresponds to CHEC-S)
        single : bool
            Designate if it is just a single module you wish to plot
        kwargs
            Arguments passed to `CHECLabPy.plottong.setup.Plotter`

        Returns
        -------
        `CameraImage`

        """
        from target_calib import CameraConfiguration
        config = CameraConfiguration(camera_version)
        tc_mapping = config.GetMapping(single)
        return cls.from_tc_mapping(tc_mapping, **kwargs)
Exemple #14
0
def main():
    input_path = "/Volumes/gct-jason/thesis_data/checs/lab/dynrange/tf/tf_poly/spe.h5"
    file_dir = os.path.dirname(os.path.abspath(__file__))
    output_dir = os.path.join(file_dir, "outputs")

    dead = [677, 293, 27, 1925]

    store = pd.HDFStore(input_path)
    df = store['coeff_pixel']
    df_array = store['array_camera']
    df = df.loc[~df['pixel'].isin(dead)]
    df_mean = df.mean().to_dict()

    norm = (df_mean['norm0'] + df_mean['norm1'] + df_mean['norm2']) / 3

    config = CameraConfiguration("1.1.0")
    ref_path = config.GetReferencePulsePath()
    cc = CrossCorrelation(1, 96, reference_pulse_path=ref_path)

    d = dict(norm=1,
             eped=cc.get_pulse_height(df_mean['eped']),
             eped_sigma=cc.get_pulse_height(df_mean['eped_sigma']),
             lambda_=1)

    hist = df_array.loc[0, 'hist'] / (norm * 1000)
    edges = cc.get_pulse_height(df_array.loc[0, 'edges'])
    between = cc.get_pulse_height(df_array.loc[0, 'between'])

    x = np.linspace(-5, 15, 1000)
    y = pedestal_signal(x, **d)

    p_hist = SPEHist()
    label = "fadc_noise = eped_sigma = {:.3f}".format(d['eped_sigma'])
    p_hist.plot(hist, edges, between, x, y, label)
    output_path = os.path.join(output_dir, "checs_fadc_noise.pdf")
    p_hist.save(output_path)
Exemple #15
0
def main():
    pm = PixelMasks()
    dead = np.where(np.logical_or(pm.dead, np.repeat(pm.bad_hv, 4)))[0]

    ref_path = CameraConfiguration("1.1.0").GetReferencePulsePath()
    cc = CrossCorrelation(1, 96, reference_pulse_path=ref_path)

    spe_path = get_astri_2019('d2019-04-23_nudges/spe_+0.h5')
    with pd.HDFStore(spe_path) as store:
        coeff = store['coeff_pixel']
        coeff = coeff.loc[~coeff['pixel'].isin(dead)]

    spe = cc.get_pulse_height(np.median(coeff['spe']))
    spe_sigma = cc.get_pulse_height(np.median(coeff['spe_sigma']))
    opct = np.median(coeff['opct'])

    output_dir = get_plot("d190716_simtel_cfg")
    generate_spectrum.call(output_dir, spe, spe_sigma, opct, 0, 0)
Exemple #16
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')
Exemple #17
0
def get_clp_mapping_from_version(version, single_module=False):
    from target_calib import CameraConfiguration
    tc_mapping = CameraConfiguration(version).GetMapping(
        singleModule=single_module
    )
    return get_clp_mapping_from_tc_mapping(tc_mapping)
Exemple #18
0
class DynamicPlotter:
    def __init__(self,
                 ip,
                 port,
                 sampleinterval=0.1,
                 timewindow=10.0,
                 size=(600, 350)):
        # PyQtGraph stuff
        self._interval = int(sampleinterval * 1000)
        self.app = QtGui.QApplication([])
        self.win = pg.GraphicsWindow()
        self.win.setWindowTitle("Slow signal viewer")
        # data
        self.data = defaultdict(
            list)  # {'hv_current':list(),'hv_voltage':list()}
        self.time = list()
        self.plts = {}
        self.curve_names = list()
        self.plot_time_window = 10
        self.lastframeindicator = pg.LabelItem(text="")
        self.lastframe = datetime.now()
        self.win.addItem(self.lastframeindicator)
        self.gotdataindicator = pg.LabelItem(
            text='<font color="{}">{}</font>'.format("green", "connected"))
        self.win.addItem(self.gotdataindicator)
        self.counter = 0
        self.win.nextRow()
        # self.win.addItem(pg.TextItem(text='HEJHEJHEJ', color=(200, 200, 200), html=None, anchor=(0, 0), border=None, fill=None, angle=0, rotateAxis=None),row=1 )
        self._add_plot(
            "TMs per readout",
            ("Number of TMs", ""),
            ("Time", "min"),
            ["current nTMs", "av nTMs"],
        )
        self._add_plot(
            "Slow signal amplitude",
            ("Amplitude", "mV"),
            ("Time", "min"),
            ["total amplitude", "max amplitude X 10"],
        )
        self.win.nextRow()
        # self._add_plot('DAC HV Voltage (Super pixels 0-8)',('Voltage','V'),('Time','min'),['dac_suppix_%d'%i for i in range(9)])

        # self._add_plot('DAC HV Voltage (Super pixels 9-15)',('Voltage','V'),('Time','min'),['dac_suppix_%d'%i for i in range(9,16)])

        # self._add_plot('Temperature',('Temperature',u"\u00B0"+'C'),('Time','min'),['temp_powb','temp_auxb','temp_primb'])#,'temp_sipm'
        self.badpixs = np.array([
            25,
            58,
            101,
            304,
            449,
            570,
            653,
            1049,
            1094,
            1158,
            1177,
            1381,
            1427,
            1434,
            1439,
            1765,
            1829,
            1869,
            1945,
            1957,
            2009,
            2043,
        ])
        self.img = pg.ImageItem(levels=(0, 400))
        self.p = self.win.addPlot()
        self.p.addItem(self.img)
        self.c = CameraConfiguration("1.1.0")
        self.m = self.c.GetMapping()

        self.xpix = np.array(self.m.GetXPixVector())
        self.ypix = np.array(self.m.GetYPixVector())
        self.xmap = np.array(self.m.GetRowVector())
        self.ymap = np.array(self.m.GetColumnVector())
        self.map = np.zeros((48, 48), dtype=np.uint64)
        for i in range(2048):
            self.map[self.xmap[i], self.ymap[i]] = i

        self.map = self.map.flatten()
        # label = pg.LabelItem()
        # label2 = pg.TextItem("BLAH")
        # # label2.setText()
        # label.setText("test",color='CCFF00')
        # self.win.addItem(label)
        # self.win.addItem(label2)
        # Add a color scale
        # self.gl = pg.GradientLegend((20, 150), (-10, -10))
        # self.gl.setParentItem(self.img)
        # self.gl.scale(1,-1)
        # self.gl
        # self.colorScale.setLabels('Label')
        # self.p.scene().addItem(self.colorScale)
        # QTimer

        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.updateplots)
        self.timer.start(self._interval)

        self.ss_listener = subscribers.SSReadoutSubscriber(port=port, ip=ip)
        self.ss_listener.start()

        # if(isinstance(ss_calib, np.array)):
        # else:
        # self.ss_calib = np.zeros(64)

    def _add_plot(self, title, labely, labelx, curves):
        self.curve_names += curves
        self.plts[title] = (self.win.addPlot(title=title), curves, list())
        self.plts[title][0].setLabel("left", labely[0], labely[1])
        self.plts[title][0].setLabel("bottom", labelx[0], labelx[1])
        self.plts[title][0].addLegend()
        self.plts[title][0].showGrid(x=True, y=True)
        for i, curve in enumerate(curves):
            t = sum((color_set1[i], (20, )), ())
            self.plts[title][2].append(self.plts[title][0].plot(
                np.linspace(0, 10, 10),
                np.linspace(0, 10, 10),
                pen=color_set1[i],
                fillLevel=0,
                fillBrush=t,
                name=curve,
            ))
        self.plts[title][0].setXRange(-self.plot_time_window, 0)
        # self.plts[title][2][i].setClickable()

    def get_data(self):
        evs = []
        ntries = 0
        self.counter += 1
        while ntries < 10:
            try:
                ev = self.ss_listener.get_data(timeout=0.1)
                evs.append(ev._get_asic_mapped())
            except:
                ntries += 1
                break
        if len(evs) == 0:
            return
        else:
            data = evs[-1]
        self.gotdata = True
        self.lastframe = datetime.now()
        imgdata = np.zeros((48, 48))
        m = ~np.isnan(data)
        parttms = set(np.where(m)[0])
        nparttms = len(parttms)
        data = data.flatten()
        data[data <= 0] = np.nan

        # data = np.log10(data)
        data[self.badpixs] = np.nan

        # print(data[data>0])
        imgdata[self.xmap, self.ymap] = data

        imgdata[np.isnan(imgdata)] = 0
        self.img.setImage(imgdata.T, levels=(0, 400))

        self.data["total amplitude"].append(np.nansum(data))
        self.data["max amplitude X 10"].append(np.nanmax(data) * 10)
        self.data["current nTMs"].append(nparttms)
        n = np.min([10, len(self.data["current nTMs"])])
        self.data["av nTMs"].append(np.mean(self.data["current nTMs"][-n:]))

        self.time.append(datetime.now())

    def run(self):
        self.app.exec_()

    def _update_plot(self, time, plot):
        for i in range(len(plot[2])):
            plot[2][i].setData(time,
                               self.data[plot[1][i]][::-1],
                               fillLevel=0.5)

    def updateplots(self):
        self.gotdata = False
        self.get_data()

        if self.gotdata:
            stat = ("green", "connected")
        else:
            stat = ("red", "disconnected")
        self.gotdataindicator.setText(
            '<font color="{}">{}</font>'.format(*stat))
        self.lastframeindicator.setText(
            "time since last received frame: {} ".format(datetime.now() -
                                                         self.lastframe))

        time = list()
        now = datetime.now()
        for t in self.time:
            time.append((t - now).total_seconds() / 60)
        t = np.array(time)
        if len(t) > 0:
            trange = t[t > t[-1] - self.plot_time_window]
            for k, v in self.plts.items():
                # v[0].setXRange(trange[0], trange[-1])
                self._update_plot(time, v)
        self.app.processEvents()
Exemple #19
0
    def __init__(self,
                 ip,
                 port,
                 sampleinterval=0.1,
                 timewindow=10.0,
                 size=(600, 350)):
        # PyQtGraph stuff
        self._interval = int(sampleinterval * 1000)
        self.app = QtGui.QApplication([])
        self.win = pg.GraphicsWindow()
        self.win.setWindowTitle("Slow signal viewer")
        # data
        self.data = defaultdict(
            list)  # {'hv_current':list(),'hv_voltage':list()}
        self.time = list()
        self.plts = {}
        self.curve_names = list()
        self.plot_time_window = 10
        self.lastframeindicator = pg.LabelItem(text="")
        self.lastframe = datetime.now()
        self.win.addItem(self.lastframeindicator)
        self.gotdataindicator = pg.LabelItem(
            text='<font color="{}">{}</font>'.format("green", "connected"))
        self.win.addItem(self.gotdataindicator)
        self.counter = 0
        self.win.nextRow()
        # self.win.addItem(pg.TextItem(text='HEJHEJHEJ', color=(200, 200, 200), html=None, anchor=(0, 0), border=None, fill=None, angle=0, rotateAxis=None),row=1 )
        self._add_plot(
            "TMs per readout",
            ("Number of TMs", ""),
            ("Time", "min"),
            ["current nTMs", "av nTMs"],
        )
        self._add_plot(
            "Slow signal amplitude",
            ("Amplitude", "mV"),
            ("Time", "min"),
            ["total amplitude", "max amplitude X 10"],
        )
        self.win.nextRow()
        # self._add_plot('DAC HV Voltage (Super pixels 0-8)',('Voltage','V'),('Time','min'),['dac_suppix_%d'%i for i in range(9)])

        # self._add_plot('DAC HV Voltage (Super pixels 9-15)',('Voltage','V'),('Time','min'),['dac_suppix_%d'%i for i in range(9,16)])

        # self._add_plot('Temperature',('Temperature',u"\u00B0"+'C'),('Time','min'),['temp_powb','temp_auxb','temp_primb'])#,'temp_sipm'
        self.badpixs = np.array([
            25,
            58,
            101,
            304,
            449,
            570,
            653,
            1049,
            1094,
            1158,
            1177,
            1381,
            1427,
            1434,
            1439,
            1765,
            1829,
            1869,
            1945,
            1957,
            2009,
            2043,
        ])
        self.img = pg.ImageItem(levels=(0, 400))
        self.p = self.win.addPlot()
        self.p.addItem(self.img)
        self.c = CameraConfiguration("1.1.0")
        self.m = self.c.GetMapping()

        self.xpix = np.array(self.m.GetXPixVector())
        self.ypix = np.array(self.m.GetYPixVector())
        self.xmap = np.array(self.m.GetRowVector())
        self.ymap = np.array(self.m.GetColumnVector())
        self.map = np.zeros((48, 48), dtype=np.uint64)
        for i in range(2048):
            self.map[self.xmap[i], self.ymap[i]] = i

        self.map = self.map.flatten()
        # label = pg.LabelItem()
        # label2 = pg.TextItem("BLAH")
        # # label2.setText()
        # label.setText("test",color='CCFF00')
        # self.win.addItem(label)
        # self.win.addItem(label2)
        # Add a color scale
        # self.gl = pg.GradientLegend((20, 150), (-10, -10))
        # self.gl.setParentItem(self.img)
        # self.gl.scale(1,-1)
        # self.gl
        # self.colorScale.setLabels('Label')
        # self.p.scene().addItem(self.colorScale)
        # QTimer

        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.updateplots)
        self.timer.start(self._interval)

        self.ss_listener = subscribers.SSReadoutSubscriber(port=port, ip=ip)
        self.ss_listener.start()
Exemple #20
0
class DynamicTRPlotter:
    def __init__(self,
                 ip,
                 port,
                 sampleinterval=0.1,
                 timewindow=10.0,
                 size=(600, 350)):
        # PyQtGraph stuff
        self._interval = int(sampleinterval * 1000)
        self.app = QtGui.QApplication([])
        self.win = pg.GraphicsWindow()
        self.win.setWindowTitle("Triggerpattern viewer")
        # data
        self.data = defaultdict(
            list)  # {'hv_current':list(),'hv_voltage':list()}
        self.time = list()
        self.plts = {}
        self.curve_names = list()
        self.plot_time_window = 10
        # self.win.addItem(pg.TextItem(text='HEJHEJHEJ', color=(200, 200, 200), html=None, anchor=(0, 0), border=None, fill=None, angle=0, rotateAxis=None),row=1 )
        self.lastframeindicator = pg.LabelItem(text="")
        self.lastframe = datetime.now()
        self.win.addItem(self.lastframeindicator)
        self.gotdataindicator = pg.LabelItem(
            text='<font color="{}">{}</font>'.format("green", "connected"))
        self.win.addItem(self.gotdataindicator)
        self.win.nextRow()
        self.countersindicator = pg.LabelItem(text="")
        self.win.addItem(self.countersindicator)
        self.win.nextRow()
        self.last_uc_ev = 0
        self.missed_counter = 0
        self.readout_counter = 0

        self._add_plot(
            "Trigger rate",
            ("Rate Hz", ""),
            ("Time", "min"),
            ["Nominal triggers"],  # , "Busy triggers"],
        )
        # self._add_plot(
        #     "Slow signal amplitude",
        #     ("Amplitude", "mV"),
        #     ("Time", "min"),
        #     ["total amplitude", "max amplitude X 10"],
        # )
        self.win.nextRow()
        self.img = pg.ImageItem(levels=(0, 400))
        self.p = self.win.addPlot()
        self.p.addItem(self.img)
        self.c = CameraConfiguration("1.1.0")
        self.m = self.c.GetMapping()
        from CHECLabPy.plotting.camera import CameraImage, CameraImageImshow
        from CHECLabPy.utils.mapping import (
            get_clp_mapping_from_tc_mapping,
            get_superpixel_mapping,
            get_tm_mapping,
        )

        self.sp_mapping = get_superpixel_mapping(
            get_clp_mapping_from_tc_mapping(self.m))

        self.xpix = np.array(self.sp_mapping.xpix)
        self.ypix = np.array(self.sp_mapping.ypix)
        self.xmap = np.array(self.sp_mapping.row)
        self.ymap = np.array(self.sp_mapping.col)
        print(self.xmap.shape, self.ymap.shape)
        self.map = np.zeros((24, 24), dtype=np.uint64)
        for i in range(512):
            self.map[self.xmap[i], self.ymap[i]] = i

        self.map = self.map.flatten()
        from ssdaq.data._dataimpl.trigger_format import (
            get_SP2bptrigg_mapping,
            get_bptrigg2SP_mapping,
        )

        self.bptmap = get_bptrigg2SP_mapping()
        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.updateplots)
        self.timer.start(self._interval)

        self.tr_listener = subscribers.BasicTriggerSubscriber(port=port, ip=ip)
        self.tr_listener.start()

        # if(isinstance(ss_calib, np.array)):
        # else:
        # self.ss_calib = np.zeros(64)

    def _add_plot(self, title, labely, labelx, curves):
        self.curve_names += curves
        self.plts[title] = (self.win.addPlot(title=title), curves, list())
        self.plts[title][0].setLabel("left", labely[0], labely[1])
        self.plts[title][0].setLabel("bottom", labelx[0], labelx[1])
        self.plts[title][0].addLegend()
        self.plts[title][0].showGrid(x=True, y=True)
        for i, curve in enumerate(curves):
            t = sum((color_set1[i], (20, )), ())
            self.plts[title][2].append(self.plts[title][0].plot(
                np.linspace(0, 10, 10),
                np.linspace(0, 10, 10),
                pen=color_set1[i],
                fillLevel=0,
                fillBrush=t,
                name=curve,
            ))
        self.plts[title][0].setXRange(-self.plot_time_window, 0)
        # self.plts[title][2][i].setClickable()

    def get_data(self):
        trs = []
        ntries = 0
        while ntries < 10:
            try:
                t = self.tr_listener.get_data(timeout=0.1)
                trs.append(t)
                if t.uc_ev == 0 or t.uc_ev < self.last_uc_ev:
                    self.missed_counter = 0
                    self.readout_counter = 0
                    self.last_uc_ev = 0
                if self.last_uc_ev != 0 and self.last_uc_ev + 1 != t.uc_ev:
                    self.missed_counter += t.uc_ev - self.last_uc_ev - 1
                self.readout_counter += 1
                self.last_uc_ev = t.uc_ev

            except:
                ntries += 1
                break
        if len(trs) == 0:
            return
        else:
            trigg = trs[-1]

        self.lastframe = datetime.now()
        imgdata = np.zeros((24, 24))

        imgdata[self.xmap, self.ymap] = trigg.trigg_union[self.bptmap]

        imgdata[np.isnan(imgdata)] = 0
        self.img.setImage(imgdata.T, levels=(0, 1))
        trig0 = evs[0]
        self.data["Nominal triggers"].append(
            len(evs) / ((trigg.TACK - trig0.TACK) * 1e-9))
        # self.data["max amplitude X 10"].append(np.nanmax(data) * 10)
        # self.data["current nTMs"].append(nparttms)
        # n = np.min([10, len(self.data["current nTMs"])])
        # self.data["av nTMs"].append(np.mean(self.data["current nTMs"][-n:]))

        self.time.append(datetime.now())

    def run(self):
        self.app.exec_()

    def _update_plot(self, time, plot):
        for i in range(len(plot[2])):
            plot[2][i].setData(time,
                               self.data[plot[1][i]][::-1],
                               fillLevel=0.5)

    def updateplots(self):
        self.gotdata = False
        self.get_data()
        self.countersindicator.setText(
            "Readout Triggers: {}, Lost packets: {}".format(
                self.readout_counter, self.missed_counter))

        if self.gotdata:
            stat = ("green", "connected")
        else:
            stat = ("red", "disconnected")
        self.gotdataindicator.setText(
            '<font color="{}">{}</font>'.format(*stat))
        self.lastframeindicator.setText(
            "time since last received frame: {} ".format(datetime.now() -
                                                         self.lastframe))
        time = list()
        now = datetime.now()
        for t in self.time:
            time.append((t - now).total_seconds() / 60)
        t = np.array(time)
        if len(t) > 0:
            trange = t[t > t[-1] - self.plot_time_window]
            for k, v in self.plts.items():
                # v[0].setXRange(trange[0], trange[-1])
                self._update_plot(time, v)
        self.app.processEvents()
Exemple #21
0
    def __init__(self,
                 ip,
                 port,
                 sampleinterval=0.1,
                 timewindow=10.0,
                 size=(600, 350)):
        # PyQtGraph stuff
        self._interval = int(sampleinterval * 1000)
        self.app = QtGui.QApplication([])
        self.win = pg.GraphicsWindow()
        self.win.setWindowTitle("Triggerpattern viewer")
        # data
        self.data = defaultdict(
            list)  # {'hv_current':list(),'hv_voltage':list()}
        self.time = list()
        self.plts = {}
        self.curve_names = list()
        self.plot_time_window = 10
        # self.win.addItem(pg.TextItem(text='HEJHEJHEJ', color=(200, 200, 200), html=None, anchor=(0, 0), border=None, fill=None, angle=0, rotateAxis=None),row=1 )
        self.lastframeindicator = pg.LabelItem(text="")
        self.lastframe = datetime.now()
        self.win.addItem(self.lastframeindicator)
        self.gotdataindicator = pg.LabelItem(
            text='<font color="{}">{}</font>'.format("green", "connected"))
        self.win.addItem(self.gotdataindicator)
        self.win.nextRow()
        self.countersindicator = pg.LabelItem(text="")
        self.win.addItem(self.countersindicator)
        self.win.nextRow()
        self.last_uc_ev = 0
        self.missed_counter = 0
        self.readout_counter = 0

        self._add_plot(
            "Trigger rate",
            ("Rate Hz", ""),
            ("Time", "min"),
            ["Nominal triggers"],  # , "Busy triggers"],
        )
        # self._add_plot(
        #     "Slow signal amplitude",
        #     ("Amplitude", "mV"),
        #     ("Time", "min"),
        #     ["total amplitude", "max amplitude X 10"],
        # )
        self.win.nextRow()
        self.img = pg.ImageItem(levels=(0, 400))
        self.p = self.win.addPlot()
        self.p.addItem(self.img)
        self.c = CameraConfiguration("1.1.0")
        self.m = self.c.GetMapping()
        from CHECLabPy.plotting.camera import CameraImage, CameraImageImshow
        from CHECLabPy.utils.mapping import (
            get_clp_mapping_from_tc_mapping,
            get_superpixel_mapping,
            get_tm_mapping,
        )

        self.sp_mapping = get_superpixel_mapping(
            get_clp_mapping_from_tc_mapping(self.m))

        self.xpix = np.array(self.sp_mapping.xpix)
        self.ypix = np.array(self.sp_mapping.ypix)
        self.xmap = np.array(self.sp_mapping.row)
        self.ymap = np.array(self.sp_mapping.col)
        print(self.xmap.shape, self.ymap.shape)
        self.map = np.zeros((24, 24), dtype=np.uint64)
        for i in range(512):
            self.map[self.xmap[i], self.ymap[i]] = i

        self.map = self.map.flatten()
        from ssdaq.data._dataimpl.trigger_format import (
            get_SP2bptrigg_mapping,
            get_bptrigg2SP_mapping,
        )

        self.bptmap = get_bptrigg2SP_mapping()
        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.updateplots)
        self.timer.start(self._interval)

        self.tr_listener = subscribers.BasicTriggerSubscriber(port=port, ip=ip)
        self.tr_listener.start()
def cal_report(cal):
    hist_a = dashi.histogram.hist1d(
        np.linspace(np.nanmin(cal.a), np.nanmax(cal.a), 100))
    hist_a.fill(cal.a)
    hist_b = dashi.histogram.hist1d(
        np.linspace(np.nanmin(cal.b), np.nanmax(cal.b), 100))
    hist_b.fill(cal.b)
    hist_c = dashi.histogram.hist1d(
        np.linspace(np.nanmin(cal.c), np.nanmax(cal.c), 100))
    hist_c.fill(cal.c)
    thresh = (-cal.b + np.sqrt(cal.b**2 - 4 * cal.a * cal.c)) / (2 * cal.a)
    hist_thresh = dashi.histogram.hist1d(
        np.linspace(np.nanmin(thresh), np.nanmax(thresh), 100))
    hist_thresh.fill(thresh)

    plt.figure(figsize=(10, 8))
    hist_a.line()
    hist_a.statbox()
    plt.title("a parameter")
    plt.savefig("plots/cal_report_a_par_hist.png")
    plt.figure(figsize=(10, 8))
    hist_b.line()
    hist_b.statbox()
    plt.title("b parameter")
    plt.savefig("plots/cal_report_b_par_hist.png")
    plt.figure(figsize=(10, 8))
    hist_c.line()
    hist_c.statbox()
    plt.title("c parameter")
    plt.savefig("plots/cal_report_c_par_hist.png")

    plt.figure(figsize=(10, 8))
    hist_thresh.line()
    hist_thresh.statbox()
    plt.title("Threshold")
    plt.savefig("plots/cal_report_threshold_hist.png")

    from target_calib import CameraConfiguration

    cam_config = CameraConfiguration("1.1.0")
    mapping = cam_config.GetMapping()
    pixsize = mapping.GetSize()
    pix_posx = np.array(mapping.GetXPixVector())
    pix_posy = np.array(mapping.GetYPixVector())
    from CHECLabPy.plotting.camera import CameraImage

    f, a = plt.subplots(figsize=(13, 8))
    camera = CameraImage(pix_posx, pix_posy, pixsize, ax=a)
    camera.image = cal.a
    camera.add_colorbar("")
    camera.ax.set_title("a parameter")
    camera.highlight_pixels(list(cal.badpixs["unphysical_cal"]),
                            color="r",
                            linewidth=2)
    # camera.highlight_pixels(np.where(unphysical_rate)[0],color='b',linewidth=1.4)
    camera.highlight_pixels(list(cal.badpixs["no_cal"]), color="k")
    camera.highlight_pixels(list(cal.badpixs["bad_fit"]),
                            color="b",
                            linewidth=1.4)
    camera.set_limits_minmax(np.nanmin(cal.a), 0)
    plt.savefig("plots/cal_report_a_par.png")

    f, a = plt.subplots(figsize=(13, 8))
    camera = CameraImage(pix_posx, pix_posy, pixsize, ax=a)
    camera.image = cal.b
    camera.add_colorbar("")
    camera.ax.set_title("b parameter")
    camera.highlight_pixels(list(cal.badpixs["unphysical_cal"]),
                            color="r",
                            linewidth=2)
    # camera.highlight_pixels(np.where(unphysical_rate)[0],color='b',linewidth=1.4)
    camera.highlight_pixels(list(cal.badpixs["no_cal"]), color="k")
    camera.highlight_pixels(list(cal.badpixs["bad_fit"]),
                            color="b",
                            linewidth=1.4)
    camera.set_limits_minmax(0, np.nanmax(cal.b))
    plt.savefig("plots/cal_report_b_par.png")

    f, a = plt.subplots(figsize=(13, 8))
    camera = CameraImage(pix_posx, pix_posy, pixsize, ax=a)
    camera.image = cal.c
    camera.add_colorbar("")
    camera.ax.set_title("c parameter")
    camera.highlight_pixels(list(cal.badpixs["unphysical_cal"]),
                            color="r",
                            linewidth=2)
    # camera.highlight_pixels(np.where(unphysical_rate)[0],color='b',linewidth=1.4)
    camera.highlight_pixels(list(cal.badpixs["no_cal"]), color="k")
    camera.highlight_pixels(list(cal.badpixs["bad_fit"]),
                            color="b",
                            linewidth=1.4)
    camera.set_limits_minmax(np.nanmin(cal.c), 0)
    plt.savefig("plots/cal_report_c_par.png")

    f, a = plt.subplots(figsize=(13, 8))
    camera = CameraImage(pix_posx, pix_posy, pixsize, ax=a)
    camera.image = thresh
    camera.add_colorbar("photon rate (MHz)")
    camera.ax.set_title("NSB threshold")
    camera.highlight_pixels(list(cal.badpixs["unphysical_cal"]),
                            color="r",
                            linewidth=2)
    # camera.highlight_pixels(np.where(unphysical_rate)[0],color='b',linewidth=1.4)
    camera.highlight_pixels(list(cal.badpixs["no_cal"]), color="k")
    camera.highlight_pixels(list(cal.badpixs["bad_fit"]),
                            color="b",
                            linewidth=1.4)
    # camera.set_limits_minmax(np.nanmin(cal.c),0)
    plt.savefig("plots/cal_report_nsb_thres.png")
def main():
    description = ('Reduce a *_r1.tio file into a *_dl1.hdf5 file containing '
                   'various parameters extracted from the waveforms')
    parser = argparse.ArgumentParser(description=description,
                                     formatter_class=Formatter)
    parser.add_argument('-f',
                        '--files',
                        dest='input_paths',
                        nargs='+',
                        help='path to the TIO r1 run files')
    parser.add_argument('-m',
                        '--monitor',
                        dest='monitor',
                        action='store',
                        help='path to the monitor file (OPTIONAL)')
    parser.add_argument('-o',
                        '--output',
                        dest='output_path',
                        action='store',
                        help='path to store the output HDF5 dl1 file '
                        '(OPTIONAL, will be automatically set if '
                        'not specified)')
    parser.add_argument('-n',
                        '--maxevents',
                        dest='max_events',
                        action='store',
                        help='Number of events to process',
                        type=int)
    parser.add_argument('-r',
                        '--reducer',
                        dest='reducer',
                        action='store',
                        default='AverageWF',
                        choices=WaveformReducerFactory.subclass_names,
                        help='WaveformReducer to use')
    parser.add_argument('-c',
                        '--config',
                        dest='configuration',
                        help="""Configuration to pass to the waveform reducer
                        (Usage: '{"window_shift":6, "window_size":6}') """)
    parser.add_argument('-p',
                        '--plot',
                        dest='plot',
                        action='store_true',
                        help="Plot stages for waveform reducers")
    args = parser.parse_args()
    if args.configuration:
        config = json.loads(args.configuration)
        config_string = args.configuration
    else:
        config = {}
        config_string = ""

    input_paths = args.input_paths
    n_files = len(input_paths)
    for i_path, input_path in enumerate(input_paths):
        print("PROGRESS: Reducing file {}/{}".format(i_path + 1, n_files))

        kwargs = dict(input_url=input_path, max_events=args.max_events)
        reader = HESSIOEventSource(**kwargs)
        seeker = EventSeeker(reader)

        n_events = len(seeker)

        first_event = seeker[0]
        tels = list(first_event.r0.tels_with_data)
        _, n_pixels, n_samples = first_event.r0.tel[tels[0]].waveform.shape
        n_modules = 32
        n_cells = 1
        pixel_array = np.arange(n_pixels)
        camera_version = "1.1.0"
        camera_config = CameraConfiguration(camera_version)
        tc_mapping = camera_config.GetMapping(n_modules == 1)
        mapping = get_clp_mapping_from_tc_mapping(tc_mapping)
        if 'reference_pulse_path' not in config:
            reference_pulse_path = camera_config.GetReferencePulsePath()
            config['reference_pulse_path'] = reference_pulse_path

        kwargs = dict(n_pixels=n_pixels,
                      n_samples=n_samples,
                      plot=args.plot,
                      mapping=mapping,
                      **config)
        reducer = WaveformReducerFactory.produce(args.reducer, **kwargs)
        baseline_subtractor = BaselineSubtractor(seeker)

        input_path = reader.input_url
        output_path = args.output_path
        if not output_path:
            output_path = input_path.replace(".simtel.gz", "_dl1.h5")
            output_path = output_path.replace("run", "Run")

        r1 = HESSIOR1Calibrator()

        with DL1Writer(output_path, n_events * n_pixels,
                       args.monitor) as writer:
            t_cpu = 0
            start_time = 0
            desc = "Processing events"
            for event in tqdm(seeker, total=n_events, desc=desc):
                iev = event.count

                r1.calibrate(event)
                waveforms = event.r1.tel[tels[0]].waveform[0]
                mc_true = event.mc.tel[tels[0]].photo_electron_image

                t_cpu = pd.to_datetime(event.trig.gps_time.value, unit='s')

                if not start_time:
                    start_time = t_cpu

                waveforms_bs = baseline_subtractor.subtract(waveforms)
                bs = baseline_subtractor.baseline

                params = reducer.process(waveforms_bs)

                df_ev = pd.DataFrame(
                    dict(iev=iev,
                         pixel=pixel_array,
                         first_cell_id=0,
                         t_cpu=t_cpu,
                         t_tack=0,
                         baseline_subtracted=bs,
                         **params,
                         mc_true=mc_true))
                writer.append_event(df_ev)

            sn_dict = {}
            for tm in range(n_modules):
                sn_dict['TM{:02d}_SN'.format(tm)] = "NaN"

            metadata = dict(source="CHECLabPy",
                            date_generated=pd.datetime.now(),
                            input_path=input_path,
                            n_events=n_events,
                            n_modules=n_modules,
                            n_pixels=n_pixels,
                            n_samples=n_samples,
                            n_cells=n_cells,
                            start_time=start_time,
                            end_time=t_cpu,
                            camera_version=camera_version,
                            reducer=reducer.__class__.__name__,
                            configuration=config_string,
                            **sn_dict)

            writer.add_metadata(**metadata)
            writer.add_mapping(mapping)
Exemple #24
0
def main():
    file_dir = os.path.dirname(os.path.abspath(__file__))
    output_dir = os.path.join(file_dir, "outputs")
    output_path = os.path.join(output_dir, "checs_pixel_mapping.txt")

    config = CameraConfiguration("1.1.0")
    mapping = config.GetMapping()
    mappingsp = mapping.GetMappingSP()

    with open(output_path, 'w') as f:
        pixtype = """# PixType format:
# Par.  1: pixel type (here always 1)
#       2: PMT type (must be 0)
#       3: cathode shape type
#       4: visible cathode diameter [cm]
#       5: funnel shape type (see above)
#       6: funnel diameter (flat-to-flat for hex.) [cm]
#       7: depth of funnel [cm]
#       8: a) funnel efficiency "filename",   b) funnel plate transparency
#       9: a) optional wavelength "filename", b) funnel wall reflectivity
# In case a) in column 8, columns 3+7 are not used. If in case a) the
# optional file name for the wavelength dependence is provided, the
# overall scale in the file provided as parameter 8 is ignored because
# it is rescaled such that the average over all mirrors is equal to
# the given wavelength dependent value.
#
# Shape types: 0: circ., 1: hex(flat x), 2: sq., 3: hex(flat y)
#
#Angular Dep currently all set to one for checks

# Note that pixel size is scale from the actual 6.125 mm at the focal length
# planned with GATE telescopes (228.3 cm) to the focal length of ASTRI (215 cm).
# Similarly scaled are the pixel positions.
PixType    1 0 2 0.623   2 0.623 0.0   "transmission_pmma_vs_theta_20150422.dat" "transmission_pmma_vs_lambda_meas0deg_coat_82raws.dat"

# Pixel format:
# Par.  1: pixel number (starting at 0)
#       2: pixel type (must be 1)
#       3: x position [cm]
#       4: y position [cm]
#       5: drawer/module number
#       6: board number in module
#       7: channel number n board
#       8: board Id number ('0x....')
#       9: pixel on (is on if parameter is missing)

"""

        f.write(pixtype)

        for i in range(mapping.GetNPixels()):
            ipix = mapping.GetPixel(i)
            xpix = mapping.GetXPix(i) * 10**2
            ypix = mapping.GetYPix(i) * 10**2
            imod = mapping.GetSlot(i)
            ichan = mapping.GetTMPixel(i)
            l = "Pixel\t{}\t1\t{:.2f}\t{:.2f}\t{}\t0\t{}\t0x00\t1\n"
            lf = l.format(ipix, xpix, ypix, imod, ichan)
            f.write(lf)

        f.write('\n')

        for i in range(mappingsp.GetNSuperPixels()):
            nei = mappingsp.GetNeighbours(i, True)
            f.write("MajorityTrigger * of ")
            for isp in [i, *nei]:
                con = list(mappingsp.GetContainedPixels(isp))
                f.write(str(isp))
                f.write("[{}] ".format(','.join(str(x) for x in con)))
            f.write('\n')
Exemple #25
0
    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
            from ctapipe.coordinates import EngineeringCameraFrame
        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

        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)
        n_rows = self.mapping.metadata['n_rows']
        n_columns = self.mapping.metadata['n_columns']
        camera_geom = first_event.inst.subarray.tel[tels[0]].camera
        engineering_frame = EngineeringCameraFrame(n_mirrors=2)
        engineering_geom = camera_geom.transform_to(engineering_frame)
        pix_x = engineering_geom.pix_x.value
        pix_y = engineering_geom.pix_y.value
        row, col = get_row_column(pix_x, pix_y)
        camera_2d = np.zeros((n_rows, n_columns), dtype=np.int)
        camera_2d[row, col] = np.arange(self.n_pixels, dtype=np.int)
        self.pixel_order = camera_2d[self.mapping['row'], self.mapping['col']]

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

        self._iev = None
        self._t_cpu = None
        self.mc = None
        self.pointing = None
        self.mcheader = None
Exemple #26
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
Exemple #27
0
class TargetIOEventSource(EventSource):
    """
    EventSource for the targetio unofficial data format, the data
    format used by cameras containing TARGET modules, such as CHEC for
    the GCT SST.

    Extract waveform information from `target_io` to store them
    into `ctapipe.io.containers`.

    This Extractor can fill either the R0 or R1 event container, depending on
    the file being read (The header of the file is checked for a flag
    indicating that it has had R1 calibration applied to it).

    This reader requires the TARGET libraries. The instructions to install
    these libraries can be found here:
    https://forge.in2p3.fr/projects/gct/wiki/Installing_CHEC_Software

    Attributes
    ----------
    _tio_reader : target_io.TargetIOEventReader()
        C++ event reader for TargetIO files. Handles the event building into
        an array of (n_pixels, n_samples) in C++, avoiding loops in Python
    _n_events : int
        number of events in the fits file
    _n_samples : int
        number of samples in the waveform
    _r0_samples : ndarray
        three dimensional array to store the R0 level waveform for each pixel
        (n_channels, n_pixels, n_samples)
    _r1_samples : ndarray
        three dimensional array to store the R1 level waveform for each pixel
        (n_channels, n_pixels, n_samples)
    _samples : ndarray
        pointer to the first index of either r0_samples or r1_samples
        (depending if the file has been R1 calibrated) for passing to
        TargetIO to be filled
    """

    def __init__(self, config=None, parent=None, **kwargs):
        super().__init__(config=config, parent=parent, **kwargs)

        self._data = None
        self._event_index = None
        self._event_id = 0
        self._time_tack = None
        self._time_sec = None
        self._time_ns = None

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

        self._n_events = self._reader.fNEvents
        self._first_event_id = self._reader.fFirstEventID
        self._last_event_id = self._reader.fLastEventID
        self._obs_id = self._reader.fRunID
        n_modules = self._reader.fNModules
        n_pix = self._reader.fNPixels
        n_samples = self._reader.fNSamples
        self.camera_config = CameraConfiguration(self._reader.fCameraVersion)
        self._n_cells = self.camera_config.GetNCells()
        m = self.camera_config.GetMapping(n_modules == 1)

        self._optical_foclen = u.Quantity(2.15, u.m)
        self._mirror_area = u.Quantity(14.126, u.m ** 2)
        self._n_pixels = m.GetNPixels()
        self._xpix = np.array(m.GetXPixVector()) * u.m
        self._ypix = np.array(m.GetYPixVector()) * u.m
        self._refshape = np.zeros(10)  # TODO: Get correct values for CHEC-S
        self._refstep = 0  # TODO: Get correct values for CHEC-S
        self._time_slice = 0  # TODO: Get correct values for CHEC-S
        self._chec_tel = 0

        # Init fields
        self._r0_samples = None
        self._r1_samples = None
        self._first_cell_ids = np.zeros(n_pix, dtype=np.uint16)

        # Check if file is already r1 (Information obtained from a flag
        # in the file's header)
        is_r1 = self._reader.fR1
        if is_r1:
            self._r1_samples = np.zeros(
                (1, n_pix, n_samples),
                dtype=np.float32
            )
            self._get_tio_event = self._reader.GetR1Event
            self._samples = self._r1_samples[0]
        else:
            self._r0_samples = np.zeros(
                (1, n_pix, n_samples),
                dtype=np.uint16
            )
            self._get_tio_event = self._reader.GetR0Event
            self._samples = self._r0_samples[0]

        self._init_container()

    @staticmethod
    def is_compatible(file_path):
        return file_path.endswith('.tio')

    def _init_container(self):
        """
        Prepare the ctapipe event container, and fill it with the information
        that does not change with event, including the instrument information.
        """
        chec_tel = 0

        data = TargetIODataContainer()
        data.meta['origin'] = "targetio"

        data.meta['input'] = self.input_url
        data.meta['max_events'] = self.max_events

        # Instrument information

        camera = CameraGeometry(
            "CHEC",
            pix_id=np.arange(self._n_pixels),
            pix_x=self._xpix,
            pix_y=self._ypix,
            pix_area=None,
            pix_type='rectangular',
        )

        optics = OpticsDescription(
            name="ASTRI",
            num_mirrors=2,
            equivalent_focal_length=self._optical_foclen,
            mirror_area=self._mirror_area,
            num_mirror_tiles=2,
        )

        tel_descriptions = {
            chec_tel: TelescopeDescription(
                name="ASTRI",
                type="SST",
                camera=camera,
                optics=optics,
            )
        }
        tel_positions = {
            chec_tel: u.Quantity(0, u.m)
        }

        data.inst.subarray =SubarrayDescription(
            "CHECMonoArray",
            tel_positions=tel_positions,
            tel_descriptions=tel_descriptions,
        )

        self._data = data

    def _update_container(self):
        """
        Update the ctapipe event containers with the information from the
        current event being pointed to in TargetIO.
        """
        data = self._data
        chec_tel = 0

        obs_id = self._obs_id
        event_id = self._event_id
        tels = {self._chec_tel}

        data.r0.obs_id = obs_id
        data.r0.event_id = event_id
        data.r0.tels_with_data = tels
        data.r1.obs_id = obs_id
        data.r1.event_id = event_id
        data.r1.tels_with_data = tels
        data.dl0.obs_id = obs_id
        data.dl0.event_id = event_id
        data.dl0.tels_with_data = tels

        data.trig.tels_with_trigger = [chec_tel]

        data.meta['tack'] = self._time_tack
        data.meta['sec'] = self._time_sec
        data.meta['ns'] = self._time_ns
        data.trig.gps_time = Time(self._time_sec * u.s, self._time_ns * u.ns,
                                  format='unix', scale='utc', precision=9)

        data.count = self._event_index

        data.r0.tel.clear()
        data.r1.tel.clear()
        data.dl0.tel.clear()
        data.dl1.tel.clear()
        data.mc.tel.clear()
        data.targetio.tel.clear()

        # load the data per telescope/chan
        data.r0.tel[chec_tel].waveform = self._r0_samples
        data.r1.tel[chec_tel].waveform = self._r1_samples

        # Load the TargetIO specific data per telescope/chan
        data.targetio.tel[chec_tel].first_cell_ids = self._first_cell_ids
        data.r0.tel[chec_tel].num_samples = self._samples.shape[-1]

        # Some information that currently exists in the mc container, but is
        # useful for real data (essentially the reference pulse shape,
        # which may be used in charge extraction methods)
        data.mc.tel[chec_tel].reference_pulse_shape = self._refshape
        data.mc.tel[chec_tel].meta['refstep'] = self._refstep
        data.mc.tel[chec_tel].time_slice = self._time_slice

    @property
    def _current_event_index(self):
        return self._event_index

    @_current_event_index.setter
    def _current_event_index(self, val):
        """
        Setting the event index will cause the event to be saught from
        TargetIO, and the Containers to point to
        the correct event. The ctapipe event containers are then updated
        with this new event's information.
        """
        self._event_index = val
        self._get_tio_event(val, self._samples, self._first_cell_ids)
        self._event_id = self._reader.fCurrentEventID
        self._time_tack = self._reader.fCurrentTimeTack
        self._time_sec = self._reader.fCurrentTimeSec
        self._time_ns = self._reader.fCurrentTimeNs
        self._update_container()

    def _generator(self):
        for self._current_event_index in range(self._n_events):
            yield self._data
        return

    def __len__(self):
        num = self._n_events
        if self.max_events and self.max_events < num:
            num = self.max_events
        return num

    def _get_event_by_index(self, index):
        self._current_event_index = index
        return self._data

    def _get_event_by_id(self, event_id):
        if ((event_id < self._first_event_id) |
                (event_id > self._last_event_id)):
            raise IndexError(f"Event id {event_id} not found in file")
        index = self._reader.GetEventIndex(event_id)
        return self._get_event_by_index(index)
Exemple #28
0
    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
Exemple #29
0
def get_ref_path_from_version(version):
    from target_calib import CameraConfiguration
    ref_path = CameraConfiguration(version).GetReferencePulsePath()
    return ref_path
Exemple #30
0
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)