示例#1
0
def test_FitGammaHillas():
    '''
    a test of the complete fit procedure on one event including:
    • tailcut cleaning
    • hillas parametrisation
    • GreatCircle creation
    • direction fit
    • position fit

    in the end, proper units in the output are asserted '''

    filename = get_dataset("gamma_test.simtel.gz")

    fit = HillasReconstructor()

    cam_geom = {}
    tel_phi = {}
    tel_theta = {}

    source = hessio_event_source(filename)

    for event in source:

        hillas_dict = {}
        for tel_id in event.dl0.tels_with_data:

            if tel_id not in cam_geom:
                cam_geom[tel_id] = CameraGeometry.guess(
                                        event.inst.pixel_pos[tel_id][0],
                                        event.inst.pixel_pos[tel_id][1],
                                        event.inst.optical_foclen[tel_id])

                tel_phi[tel_id] = event.mc.tel[tel_id].azimuth_raw * u.rad
                tel_theta[tel_id] = (np.pi/2-event.mc.tel[tel_id].altitude_raw)*u.rad

            pmt_signal = event.r0.tel[tel_id].adc_sums[0]

            mask = tailcuts_clean(cam_geom[tel_id], pmt_signal,
                                  picture_thresh=10., boundary_thresh=5.)
            pmt_signal[mask == 0] = 0

            try:
                moments = hillas_parameters(event.inst.pixel_pos[tel_id][0],
                                            event.inst.pixel_pos[tel_id][1],
                                            pmt_signal)
                hillas_dict[tel_id] = moments
            except HillasParameterizationError as e:
                print(e)
                continue

        if len(hillas_dict) < 2: continue

        fit_result = fit.predict(hillas_dict, event.inst, tel_phi, tel_theta)

        print(fit_result)
        fit_result.alt.to(u.deg)
        fit_result.az.to(u.deg)
        fit_result.core_x.to(u.m)
        assert fit_result.is_valid
        return
示例#2
0
def display_event(event):
    """an extremely inefficient display. It creates new instances of
    CameraDisplay for every event and every camera, and also new axes
    for each event. It's hacked, but it works
    """
    print("Displaying... please wait (this is an inefficient implementation)")
    global fig
    ntels = len(event.r0.tels_with_data)
    fig.clear()

    plt.suptitle("EVENT {}".format(event.r0.event_id))

    disps = []

    for ii, tel_id in enumerate(event.r0.tels_with_data):
        print("\t draw cam {}...".format(tel_id))
        nn = int(ceil(sqrt(ntels)))
        ax = plt.subplot(nn, nn, ii + 1)

        x, y = event.inst.pixel_pos[tel_id]
        geom = CameraGeometry.guess(x, y, event.inst.optical_foclen[tel_id])
        disp = CameraDisplay(geom, ax=ax, title="CT{0}".format(tel_id))
        disp.pixels.set_antialiaseds(False)
        disp.autoupdate = False
        disp.cmap = random.choice(cmaps)
        chan = 0
        signals = event.r0.tel[tel_id].adc_sums[chan].astype(float)
        signals -= signals.mean()
        disp.image = signals
        disp.set_limits_percent(95)
        disp.add_colorbar()
        disps.append(disp)

    return disps
示例#3
0
def display_event(event):
    """an extremely inefficient display. It creates new instances of
    CameraDisplay for every event and every camera, and also new axes
    for each event. It's hacked, but it works
    """
    print("Displaying... please wait (this is an inefficient implementation)")
    global fig
    ntels = len(event.r0.tels_with_data)
    fig.clear()

    plt.suptitle("EVENT {}".format(event.r0.event_id))

    disps = []

    for ii, tel_id in enumerate(event.r0.tels_with_data):
        print("\t draw cam {}...".format(tel_id))
        nn = int(ceil(sqrt(ntels)))
        ax = plt.subplot(nn, nn, ii + 1)

        x, y = event.inst.pixel_pos[tel_id]
        geom = CameraGeometry.guess(x, y, event.inst.optical_foclen[tel_id])
        disp = CameraDisplay(geom, ax=ax, title="CT{0}".format(tel_id))
        disp.pixels.set_antialiaseds(False)
        disp.autoupdate = False
        disp.cmap = random.choice(cmaps)
        chan = 0
        signals = event.r0.tel[tel_id].adc_sums[chan].astype(float)
        signals -= signals.mean()
        disp.image = signals
        disp.set_limits_percent(95)
        disp.add_colorbar()
        disps.append(disp)

    return disps
示例#4
0
    def setup(self):
        self.log_format = "%(levelname)s: %(message)s [%(name)s.%(funcName)s]"
        kwargs = dict(config=self.config, tool=self)

        arrays = np.load(self.input_path)
        self.charge = self.dead.mask2d(arrays['charge'])
        self.charge_error = self.dead.mask2d(arrays['charge_error'])
        self.rundesc = arrays['rundesc']

        self.n_run, self.n_pixels = self.charge.shape
        assert (self.n_run == self.rundesc.size)

        geom = CameraGeometry.guess(*checm_pixel_pos * u.m,
                                    optical_foclen * u.m)
        self.modules = np.arange(self.n_pixels) // self.n_tmpix
        self.tmpix = np.arange(self.n_pixels) % self.n_tmpix
        self.n_tm = np.unique(self.modules).size

        # Init Plots
        self.p_c_pix = Camera(self, "", geom)
        self.p_c_tm = Camera(self, "", geom)
        self.p_c_tmpixspread = Camera(self, "", geom)
        self.p_p_pix = Plotter(**kwargs)
        self.p_p_tm = Plotter(**kwargs)
        self.p_b_tmpixspread = BoxPlotter(**kwargs)
        self.p_b_tmspread = BoxPlotter(**kwargs)
        self.p_b_pixspread = BoxPlotter(**kwargs)
示例#5
0
 def get_camera(self, tel_id):
     if not tel_id in self.camera_geom_dict:
         pos = self.inst.pixel_pos[tel_id]
         foclen = self.inst.optical_foclen[tel_id]
         geom = CameraGeometry.guess(*pos, foclen, apply_derotation=False)
         self.camera_geom_dict[tel_id] = geom
     return self.camera_geom_dict[tel_id]
示例#6
0
    def setup(self):
        self.log_format = "%(levelname)s: %(message)s [%(name)s.%(funcName)s]"
        kwargs = dict(config=self.config, tool=self)

        arrays = np.load(self.input_path)
        self.charge = self.dead.mask2d(arrays['charge'])
        self.charge = np.ma.masked_where(self.charge <= 0, self.charge)
        self.charge_error = np.ma.array(arrays['charge_error'],
                                        mask=self.charge.mask)
        self.hv = arrays['rundesc']

        self.n_hv, self.n_pixels = self.charge.shape
        assert (self.n_hv == self.hv.size)

        geom = CameraGeometry.guess(*checm_pixel_pos * u.m,
                                    optical_foclen * u.m)
        self.modules = np.arange(self.n_pixels) // self.n_tmpix
        self.tmpix = np.arange(self.n_pixels) % self.n_tmpix
        self.n_tm = np.unique(self.modules).size

        # Init Plots
        self.p_camera_pix = Camera(self, "Gain Matching Pixels", geom)
        self.p_camera_tm = Camera(self, "Gain Matching TMs", geom)
        self.p_plotter_pix = Plotter(**kwargs)
        self.p_plotter_tm = Plotter(**kwargs)
示例#7
0
    def setup(self):
        self.log_format = "%(levelname)s: %(message)s [%(name)s.%(funcName)s]"
        kwargs = dict(config=self.config, tool=self)

        reader_factory = EventFileReaderFactory(**kwargs)
        reader_class = reader_factory.get_class()
        self.reader = reader_class(**kwargs)

        r1_factory = CameraR1CalibratorFactory(origin=self.reader.origin,
                                               **kwargs)
        r1_class = r1_factory.get_class()
        self.r1 = r1_class(**kwargs)

        self.dl0 = CameraDL0Reducer(**kwargs)

        self.cleaner = CHECMWaveformCleanerAverage(**kwargs)
        self.extractor = AverageWfPeakIntegrator(**kwargs)
        self.extractor_height = SimpleIntegrator(window_shift=0,
                                                 window_width=1,
                                                 **kwargs)

        self.dl1 = CameraDL1Calibrator(extractor=self.extractor,
                                       cleaner=self.cleaner,
                                       **kwargs)
        self.dl1_height = CameraDL1Calibrator(extractor=self.extractor_height,
                                              cleaner=self.cleaner,
                                              **kwargs)

        self.dead = Dead()

        fitter_factory = ChargeFitterFactory(**kwargs)
        fitter_class = fitter_factory.get_class()
        self.fitter = fitter_class(**kwargs)

        self.n_events = self.reader.num_events
        first_event = self.reader.get_event(0)
        self.n_pixels = first_event.inst.num_pixels[0]
        self.n_samples = first_event.r0.tel[0].num_samples

        geom = CameraGeometry.guess(*first_event.inst.pixel_pos[0],
                                    first_event.inst.optical_foclen[0])
        self.neighbours2d = get_neighbours_2d(geom.pix_x, geom.pix_y)

        # Get stage names
        self.stage_names = [
            '0: raw', '1: baseline_sub', '2: no_pulse', '3: smooth_baseline',
            '4: smooth_wf', '5: cleaned'
        ]

        # Init Plots
        self.p_camera_area = Camera(self, self.neighbours2d, "Area", geom)
        self.p_camera_fit_gain = Camera(self, self.neighbours2d, "Gain", geom)
        self.p_camera_fit_brightness = Camera(self, self.neighbours2d,
                                              "Brightness", geom)
        self.p_fitter = FitterWidget(fitter=self.fitter, **kwargs)
        self.p_stage_viewer = StageViewer(**kwargs)
        self.p_fit_viewer = FitViewer(**kwargs)
        self.p_fit_table = FitTable(**kwargs)
def display_telescope(calibrated_data,cam,tel_id,pdffilename):
    logger.info("Tel_ID %d\n"%tel_id)
    pp = PdfPages("%s"%pdffilename)
    global fig
    for event in calibrated_data:
        tels = list(event.r0.tels_with_data)
        logger.debug(tels)
        # Select telescope
        if tel_id not in tels:
            continue

        fig.clear()

        # geom = cam['CameraTable_VersionFeb2016_TelID%s'%tel_id]
        geom = CameraGeometry.guess(*event.inst.pixel_pos[tel_id],
                                       event.inst.optical_foclen[tel_id])
        # Select number of pads to display. It depends on the numberr of gains:
        nchan = event.inst.num_channels[tel_id]

        plt.suptitle("EVENT {} {:.1e} TeV @({:.1f},{:.1f})deg @{:.1f} m".format(
            event.r0.event_id, event.mc.energy,
            event.mc.alt, event.mc.az,
            np.sqrt(pow(event.mc.core_x, 2) +
                    pow(event.mc.core_y, 2))))
        print("\t draw cam {} (gains={})...".format(tel_id,nchan))
        ax=[]
        disp=[]
        signals=[]
        npads=0
        for i in range(nchan):
            npads += 1
            # Display the camera charge (HG/LG)
            ax.append(plt.subplot(nchan, 2, npads))
            disp.append(visualization.CameraDisplay(geom, ax=ax[-1],
                                                    title="CT{} [{} ADC cts]".format(tel_id,gain_label[i])))
            disp[-1].pixels.set_antialiaseds(False)
            signals.append(event.r0.tel[tel_id].adc_sums[i])
            disp[-1].image = signals[-1]
            disp[-1].pixels.set_cmap(get_cmap(disp[-1].image))
            disp[-1].add_colorbar(label=" [{} ADC cts]".format(gain_label[i]))

            # Display the camera charge for significant pixels (HG/LG)
            npads += 1
            ax.append(plt.subplot(nchan, 2, npads))
            disp.append(visualization.CameraDisplay(geom, ax=ax[-1],
                                                    title="CT{} [{} ADC cts]".format(tel_id,gain_label[i])))
            disp[-1].pixels.set_antialiaseds(False)
            signals.append(event.r0.tel[tel_id].adc_sums[i])
            m = (get_zero_sup_mode(tel_id) & 0x001) or (get_significant(tel_id) & 0x020)
            disp[-1].image = signals[-1]*(m/m.max())
            disp[-1].pixels.set_cmap(get_cmap(disp[-1].image))
            disp[-1].add_colorbar(label=" [{} ADC cts]".format(gain_label[i]))

            
        plt.pause(0.1)
        pp.savefig(fig)

    pp.close()
示例#9
0
    def get_geometry(self, tel):
        npix = len(self.event.r0.tel[tel].adc_sums[0])
        cam_dimensions = (npix, self.event.inst.optical_foclen[tel])

        if tel not in self.geom_dict:
            self.geom_dict[tel] = \
                CameraGeometry.guess(*self.event.inst.pixel_pos[tel],
                                     self.event.inst.optical_foclen[tel])
        return self.geom_dict[tel]
示例#10
0
def plot_quick_camera(image, ax=None):
    ax = ax if ax is not None else plt.gca()

    cameraconfig = Config()
    pos = cameraconfig.pixel_pos * u.m
    foclen = cameraconfig.optical_foclen * u.m
    geom = CameraGeometry.guess(*pos, foclen)
    camera = CameraDisplay(geom, ax=ax, image=image, cmap='viridis')
    return camera
示例#11
0
    def get_geometry(self, tel):
        npix = len(self.event.r0.tel[tel].adc_sums[0])
        cam_dimensions = (npix, self.event.inst.optical_foclen[tel])

        if tel not in self.geom_dict:
            self.geom_dict[tel] = \
                CameraGeometry.guess(*self.event.inst.pixel_pos[tel],
                                     self.event.inst.optical_foclen[tel])
        return self.geom_dict[tel]
示例#12
0
 def write_camera_geometries(self):
     cam_types = get_camera_types(self.inst)
     print_camera_types(self.inst, printer=self.log.info)
     for cam_name in cam_types:
         ext, args = self._get_file_format_info(self.format, 'CAMGEOM',
                                                cam_name)
         self.log.debug("writing {}".format(cam_name))
         tel_id = cam_types[cam_name].pop()
         pix = self.inst.pixel_pos[tel_id]
         flen = self.inst.optical_foclen[tel_id]
         geom = CameraGeometry.guess(*pix, flen)
         table = geom.to_table()
         table.meta['SOURCE'] = self.infile
         table.write("{}.camgeom.{}".format(cam_name, ext), **args)
示例#13
0
    def start(self):
        event = self.reader.get_event(self.req_event)
        telid = list(event.r0.tels_with_data)[0]
        geom = CameraGeometry.guess(*event.inst.pixel_pos[0],
                                    event.inst.optical_foclen[0])

        self.r1.calibrate(event)
        self.dl0.reduce(event)
        self.dl1.calibrate(event)

        cleaned = event.dl1.tel[telid].cleaned[0]

        output_dir = self.reader.output_directory
        self.animator.plot(cleaned, geom, self.req_event, output_dir)
示例#14
0
    def setup_arrays(self, file_reader):
        global TELID
        global CHAN
        global N_PIXELS
        global N_SAMPLES
        global PIXEL_POS

        first_event = file_reader.get_event(0)
        TELID = list(first_event.r0.tels_with_data)[0]
        CHAN = 0
        N_PIXELS, N_SAMPLES = first_event.r0.tel[TELID].adc_samples[CHAN].shape
        PIXEL_POS = first_event.inst.pixel_pos[TELID]
        pos = first_event.inst.pixel_pos[TELID]
        foclen = first_event.inst.optical_foclen[TELID]
        self.geom = CameraGeometry.guess(*pos, foclen)
示例#15
0
 def write_camera_geometries(self):
     cam_types = get_camera_types(self.inst)
     print_camera_types(self.inst, printer=self.log.info)
     for cam_name in cam_types:
         ext, args = self._get_file_format_info(self.format,
                                                'CAMGEOM',
                                                cam_name)
         self.log.debug("writing {}".format(cam_name))
         tel_id = cam_types[cam_name].pop()
         pix = self.inst.pixel_pos[tel_id]
         flen = self.inst.optical_foclen[tel_id]
         geom = CameraGeometry.guess(*pix, flen)
         table = geom.to_table()
         table.meta['SOURCE'] = self.infile
         table.write("{}.camgeom.{}".format(cam_name, ext), **args)
示例#16
0
文件: dl1.py 项目: epuesche/ctapipe
    def get_geometry(event, telid):
        """
        Obtain the geometry for this telescope.

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

        Returns
        -------
        `CameraGeometry`
        """
        return CameraGeometry.guess(*event.inst.pixel_pos[telid],
                                    event.inst.optical_foclen[telid])
示例#17
0
文件: dl1.py 项目: renlliang3/ctapipe
    def get_geometry(event, telid):
        """
        Obtain the geometry for this telescope.

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

        Returns
        -------
        `CameraGeometry`
        """
        return CameraGeometry.guess(*event.inst.pixel_pos[telid],
                                    event.inst.optical_foclen[telid])
示例#18
0
def test_nb_peak_integration():
    telid = 11
    event = get_test_event()
    data = event.r0.tel[telid].adc_samples
    nsamples = data.shape[2]
    ped = event.mc.tel[telid].pedestal
    data_ped = data - np.atleast_3d(ped/nsamples)
    data_ped = np.array([data_ped[0], data_ped[0]])  # Test LG functionality
    geom = CameraGeometry.guess(*event.inst.pixel_pos[telid],
                                event.inst.optical_foclen[telid])
    nei = geom.neighbors

    integrator = NeighbourPeakIntegrator(None, None)
    integrator.neighbours = nei
    integration, peakpos, window = integrator.extract_charge(data_ped)

    assert_almost_equal(integration[0][0], -64, 0)
    assert_almost_equal(integration[1][0], -64, 0)
    assert peakpos[0][0] == 20
    assert peakpos[1][0] == 20
示例#19
0
    def start(self):
        geom = None
        imsum = None
        disp = None

        for data in hessio_event_source(self.infile,
                                        allowed_tels=self._selected_tels,
                                        max_events=self.max_events):

            self.calibrator.calibrate(data)

            if geom is None:
                x, y = data.inst.pixel_pos[self._base_tel]
                flen = data.inst.optical_foclen[self._base_tel]
                geom = CameraGeometry.guess(x, y, flen)
                imsum = np.zeros(shape=x.shape, dtype=np.float)
                disp = CameraDisplay(geom, title=geom.cam_id)
                disp.add_colorbar()
                disp.cmap = 'viridis'

            if len(data.dl0.tels_with_data) <= 2:
                continue

            imsum[:] = 0
            for telid in data.dl0.tels_with_data:
                imsum += data.dl1.tel[telid].image[0]

            self.log.info("event={} ntels={} energy={}" \
                          .format(data.r0.event_id,
                                  len(data.dl0.tels_with_data),
                                  data.mc.energy))
            disp.image = imsum
            plt.pause(0.1)

            if self.output_suffix is not "":
                filename = "{:020d}{}".format(data.r0.event_id,
                                              self.output_suffix)
                self.log.info("saving: '{}'".format(filename))
                plt.savefig(filename)
示例#20
0
    def start(self):
        geom = None
        imsum = None
        disp = None

        for data in hessio_event_source(self.infile,
                                        allowed_tels=self._selected_tels,
                                        max_events=self.max_events):

            self.calibrator.calibrate(data)

            if geom is None:
                x, y = data.inst.pixel_pos[self._base_tel]
                flen = data.inst.optical_foclen[self._base_tel]
                geom = CameraGeometry.guess(x, y, flen)
                imsum = np.zeros(shape=x.shape, dtype=np.float)
                disp = CameraDisplay(geom, title=geom.cam_id)
                disp.add_colorbar()
                disp.cmap = 'viridis'

            if len(data.dl0.tels_with_data) <= 2:
                continue

            imsum[:] = 0
            for telid in data.dl0.tels_with_data:
                imsum += data.dl1.tel[telid].image[0]

            self.log.info("event={} ntels={} energy={}" \
                          .format(data.r0.event_id,
                                  len(data.dl0.tels_with_data),
                                  data.mc.energy))
            disp.image = imsum
            plt.pause(0.1)

            if self.output_suffix is not "":
                filename = "{:020d}{}".format(data.r0.event_id,
                                              self.output_suffix)
                self.log.info("saving: '{}'".format(filename))
                plt.savefig(filename)
示例#21
0
    def create(self, residual, pixel_pos, foclen):
        self.log.info("Creating {}".format(self.name))
        mean = np.mean(residual, axis=(0, 2))
        stddev = np.std(residual, axis=(0, 2))
        min_ = np.min(residual, axis=(0, 2))
        max_ = np.max(residual, axis=(0, 2))
        x = np.arange(residual.shape[1])

        cdsource_d = dict(x=x, mean=mean, stddev=stddev, min=min_, max=max_)
        cdsource = ColumnDataSource(data=cdsource_d)

        title = "Residual Spread Vs Pixel ID"

        geom = CameraGeometry.guess(*pixel_pos, foclen)
        camera_mean = CameraDisplay(geometry=geom, image=mean)
        camera_mean.add_colorbar()
        camera_mean_fig = camera_mean.fig
        camera_mean_fig.title.text = "Residual Means"
        camera_stddev = CameraDisplay(geometry=geom, image=stddev)
        camera_stddev.add_colorbar()
        camera_stddev_fig = camera_stddev.fig
        camera_stddev_fig.title.text = "Residual Standard Deviations"

        self.layout = layout([[camera_mean_fig, camera_stddev_fig]])
示例#22
0
    disp = None

    print('SELECTING EVENTS FROM TELESCOPE {}'.format(args.tel))
    print('=' * 70)

    for event in source:

        print('Scanning input file... count = {}'.format(event.count))
        print(event.trig)
        print(event.mc)
        print(event.dl0)

        if disp is None:
            x, y = event.inst.pixel_pos[args.tel]
            focal_len = event.inst.optical_foclen[args.tel]
            geom = CameraGeometry.guess(x, y, focal_len)
            print(geom.pix_x)
            disp = CameraDisplay(geom, title='CT%d' % args.tel)
            #disp.enable_pixel_picker()
            disp.add_colorbar()
            plt.show(block=False)

        # display the event
        disp.axes.set_title('CT{:03d}, event {:010d}'.format(
            args.tel, event.r0.event_id))
        if args.show_samples:
            # display time-varying event
            data = event.r0.tel[args.tel].adc_samples[args.channel]
            if args.calibrate:
                peds, gains = get_mc_calibration_coeffs(event, args.tel)
                data = apply_mc_calibration(data, peds, gains, args.tel)
示例#23
0
def get_geometry():
    cameraconfig = Config()
    pixel_pos = cameraconfig.pixel_pos
    optical_foclen = cameraconfig.optical_foclen
    return CameraGeometry.guess(*pixel_pos * u.m, optical_foclen * u.m)
示例#24
0
def analyze_muon_event(event, params=None, geom_dict=None):
    """
    Generic muon event analyzer. 

    Parameters
    ----------
    event : ctapipe dl1 event container


    Returns
    -------
    muonringparam, muonintensityparam : MuonRingParameter and MuonIntensityParameter container event

    """
    # Declare a dict to define the muon cuts (ASTRI and SCT missing)
    muon_cuts = {}

    names = [
        'LST:LSTCam', 'MST:NectarCam', 'MST:FlashCam', 'MST-SCT:SCTCam',
        'SST-1M:DigiCam', 'SST-GCT:CHEC', 'SST-ASTRI:ASTRICam'
    ]
    TailCuts = [(5, 7), (5, 7), (10, 12), (5, 7), (5, 7), (5, 7),
                (5, 7)]  #10,12?
    impact = [(0.2, 0.9), (0.1, 0.95), (0.2, 0.9), (0.2, 0.9), (0.1, 0.95),
              (0.1, 0.95), (0.1, 0.95)]
    ringwidth = [(0.04, 0.08), (0.02, 0.1), (0.01, 0.1), (0.02, 0.1),
                 (0.01, 0.5), (0.02, 0.2), (0.02, 0.2)]
    TotalPix = [1855., 1855., 1764., 11328., 1296., 2048.,
                2368.]  #8% (or 6%) as limit
    MinPix = [148., 148., 141., 680., 104., 164., 142.]
    #Need to either convert from the pixel area in m^2 or check the camera specs
    AngPixelWidth = [0.1, 0.2, 0.18, 0.067, 0.24, 0.2,
                     0.17]  #Found from TDRs (or the pixel area)
    hole_rad = []  #Need to check and implement
    cam_rad = [2.26, 3.96, 3.87, 4., 4.45, 2.86,
               5.25]  #Found from the field of view calculation
    sec_rad = [
        0. * u.m, 0. * u.m, 0. * u.m, 2.7 * u.m, 0. * u.m, 1. * u.m, 1.8 * u.m
    ]
    sct = [False, False, False, True, False, True, True]

    muon_cuts = {
        'Name': names,
        'TailCuts': TailCuts,
        'Impact': impact,
        'RingWidth': ringwidth,
        'TotalPix': TotalPix,
        'MinPix': MinPix,
        'CamRad': cam_rad,
        'SecRad': sec_rad,
        'SCT': sct,
        'AngPixW': AngPixelWidth
    }
    #print(muon_cuts)

    muonringlist = []  #[None] * len(event.dl0.tels_with_data)
    muonintensitylist = []  #[None] * len(event.dl0.tels_with_data)
    tellist = []
    #for tid in event.dl0.tels_with_data:
    #    tellist.append(tid)
    muon_event_param = {
        'TelIds': tellist,
        'MuonRingParams': muonringlist,
        'MuonIntensityParams': muonintensitylist
    }
    #muonringparam = None
    #muonintensityparam = None

    for telid in event.dl0.tels_with_data:

        #print("Analysing muon event for tel",telid)
        muonringparam = None
        muonintensityparam = None
        #idx = muon_event_param['TelIds'].index(telid)

        x, y = event.inst.pixel_pos[telid]

        #image = event.dl1.tel[telid].calibrated_image
        image = event.dl1.tel[telid].image[0]

        # Get geometry
        geom = None
        if geom_dict is not None and telid in geom_dict:
            geom = geom_dict[telid]
        else:
            log.debug("[calib] Guessing camera geometry")
            geom = CameraGeometry.guess(*event.inst.pixel_pos[telid],
                                        event.inst.optical_foclen[telid])
            log.debug("[calib] Camera geometry found")
            if geom_dict is not None:
                geom_dict[telid] = geom

        teldes = event.inst.subarray.tel[telid]
        dict_index = muon_cuts['Name'].index(str(teldes))
        #print('found an index of',dict_index,'for camera',geom.cam_id)

        #tailcuts = (5.,7.)
        tailcuts = muon_cuts['TailCuts'][dict_index]

        #print("Tailcuts are",tailcuts[0],tailcuts[1])

        #rot_angle = 0.*u.deg
        #if event.inst.optical_foclen[telid] > 10.*u.m and event.dl0.tel[telid].num_pixels != 1764:
        #rot_angle = -100.14*u.deg

        clean_mask = tailcuts_clean(geom,
                                    image,
                                    picture_thresh=tailcuts[0],
                                    boundary_thresh=tailcuts[1])
        camera_coord = CameraFrame(
            x=x,
            y=y,
            z=np.zeros(x.shape) * u.m,
            focal_length=event.inst.optical_foclen[telid],
            rotation=geom.pix_rotation)

        #print("Camera",geom.cam_id,"focal length",event.inst.optical_foclen[telid],"rotation",geom.pix_rotation)
        #TODO: correct this hack for values over 90
        altval = event.mcheader.run_array_direction[1]
        if (altval > np.pi / 2.):
            altval = np.pi / 2.

        altaz = HorizonFrame(alt=altval * u.rad,
                             az=event.mcheader.run_array_direction[0] * u.rad)
        nom_coord = camera_coord.transform_to(
            NominalFrame(array_direction=altaz, pointing_direction=altaz))

        x = nom_coord.x.to(u.deg)
        y = nom_coord.y.to(u.deg)

        img = image * clean_mask
        noise = 5.
        weight = img / (img + noise)

        muonring = ChaudhuriKunduRingFitter(None)

        #print("img:",np.sum(image),"mask:",np.sum(clean_mask), "x=",x,"y=",y)
        if not sum(img):  #Nothing left after tail cuts
            continue
        muonringparam = muonring.fit(x, y, image * clean_mask)
        #muonringparam = muonring.fit(x,y,weight)
        dist = np.sqrt(
            np.power(x - muonringparam.ring_center_x, 2) +
            np.power(y - muonringparam.ring_center_y, 2))
        ring_dist = np.abs(dist - muonringparam.ring_radius)
        muonringparam = muonring.fit(
            x, y, img * (ring_dist < muonringparam.ring_radius * 0.4))

        dist = np.sqrt(
            np.power(x - muonringparam.ring_center_x, 2) +
            np.power(y - muonringparam.ring_center_y, 2))
        ring_dist = np.abs(dist - muonringparam.ring_radius)

        #print("1: x",muonringparam.ring_center_x,"y",muonringparam.ring_center_y,"radius",muonringparam.ring_radius)
        muonringparam = muonring.fit(
            x, y, img * (ring_dist < muonringparam.ring_radius * 0.4))
        #print("2: x",muonringparam.ring_center_x,"y",muonringparam.ring_center_y,"radius",muonringparam.ring_radius)
        muonringparam.tel_id = telid
        muonringparam.run_id = event.dl0.run_id
        muonringparam.event_id = event.dl0.event_id
        dist_mask = np.abs(
            dist - muonringparam.ring_radius) < muonringparam.ring_radius * 0.4

        rad = list()
        cx = list()
        cy = list()

        mc_x = event.mc.core_x
        mc_y = event.mc.core_y
        pix_im = image * dist_mask
        nom_dist = np.sqrt(
            np.power(muonringparam.ring_center_x, 2) +
            np.power(muonringparam.ring_center_y, 2))
        #numpix = event.dl0.tel[telid].num_pixels

        minpix = muon_cuts['MinPix'][dict_index]  #0.06*numpix #or 8%

        mir_rad = np.sqrt(
            event.inst.mirror_dish_area[telid] / (np.pi)
        )  #need to consider units? (what about hole? Area is then less...)

        #Camera containment radius -  better than nothing - guess pixel diameter of 0.11, all cameras are perfectly circular   cam_rad = np.sqrt(numpix*0.11/(2.*np.pi))

        if (np.sum(pix_im > tailcuts[0]) > 0.1 * minpix
                and np.sum(pix_im) > minpix
                and nom_dist < muon_cuts['CamRad'][dict_index] * u.deg
                and muonringparam.ring_radius < 1.5 * u.deg
                and muonringparam.ring_radius > 1. * u.deg):

            #Guess HESS is 0.16
            #sec_rad = 0.*u.m
            #sct = False
            #if numpix == 2048 and mir_rad > 2.*u.m and mir_rad < 2.1*u.m:
            #    sec_rad = 1.*u.m
            #    sct = True

            #Store muon ring parameters (passing cuts stage 1)
            #muonringlist[idx] = muonringparam
            tellist.append(telid)
            muonringlist.append(muonringparam)
            muonintensitylist.append(None)
            #embed()

            ctel = MuonLineIntegrate(
                mir_rad,
                0.2 * u.m,
                pixel_width=muon_cuts['AngPixW'][dict_index] * u.deg,
                sct_flag=muon_cuts['SCT'][dict_index],
                secondary_radius=muon_cuts['SecRad'][dict_index])

            if (image.shape[0] == muon_cuts['TotalPix'][dict_index]):
                muonintensityoutput = ctel.fit_muon(
                    muonringparam.ring_center_x, muonringparam.ring_center_y,
                    muonringparam.ring_radius, x[dist_mask], y[dist_mask],
                    image[dist_mask])

                muonintensityoutput.tel_id = telid
                muonintensityoutput.run_id = event.dl0.run_id
                muonintensityoutput.event_id = event.dl0.event_id
                muonintensityoutput.mask = dist_mask

                print("Tel", telid, "Impact parameter = ",
                      muonintensityoutput.impact_parameter, "mir_rad", mir_rad,
                      "ring_width=", muonintensityoutput.ring_width)

                #if(muonintensityoutput.impact_parameter > muon_cuts['Impact'][dict_index][1]*mir_rad or muonintensityoutput.impact_parameter < muon_cuts['Impact'][dict_index][0]*mir_rad):
                #    print("Failed on impact parameter low cut",muon_cuts['Impact'][dict_index][0]*mir_rad,"high cut",muon_cuts['Impact'][dict_index][1]*mir_rad,"for",geom.cam_id)
                #if(muonintensityoutput.ring_width > muon_cuts['RingWidth'][dict_index][1]*u.deg or muonintensityoutput.ring_width < muon_cuts['RingWidth'][dict_index][0]*u.deg):
                #    print("Failed on ring width low cut",muon_cuts['RingWidth'][dict_index][0]*u.deg,"high cut",muon_cuts['RingWidth'][dict_index][1]*u.deg,"for ",geom.cam_id)

                #print("Cuts <",muon_cuts["Impact"][dict_index][1]*mir_rad,"cuts >",muon_cuts['Impact'][dict_index][0]*u.m,'ring_width < ',muon_cuts['RingWidth'][dict_index][1]*u.deg,'ring_width >',muon_cuts['RingWidth'][dict_index][0]*u.deg)
                if (muonintensityoutput.impact_parameter <
                        muon_cuts['Impact'][dict_index][1] * mir_rad
                        and muonintensityoutput.impact_parameter >
                        muon_cuts['Impact'][dict_index][0] * u.m
                        and muonintensityoutput.ring_width <
                        muon_cuts['RingWidth'][dict_index][1] * u.deg
                        and muonintensityoutput.ring_width >
                        muon_cuts['RingWidth'][dict_index][0] * u.deg):
                    muonintensityparam = muonintensityoutput
                    idx = tellist.index(telid)
                    muonintensitylist[idx] = muonintensityparam
                    print("Muon in tel", telid, "# tels in event=",
                          len(event.dl0.tels_with_data))
                else:
                    continue

        #print("Fitted ring centre (2):",muonringparam.ring_center_x,muonringparam.ring_center_y)

    #return muonringparam, muonintensityparam
    return muon_event_param
示例#25
0
def test_guess_camera():
    px = np.linspace(-10, 10, 11328) * u.m
    py = np.linspace(-10, 10, 11328) * u.m
    geom = CameraGeometry.guess(px, py,0 * u.m)
    assert geom.pix_type.startswith('rect')
示例#26
0
def extract_images(simtel_file_path,
                   tel_id_filter_list=None,
                   event_id_filter_list=None,
                   output_directory=None):

    # EXTRACT IMAGES ##########################################################

    # hessio_event_source returns a Python generator that streams data from an
    # EventIO/HESSIO MC data file (e.g. a standard CTA data file).
    # This generator contains ctapipe.core.Container instances ("event").
    #
    # Parameters:
    # - max_events: maximum number of events to read
    # - allowed_tels: select only a subset of telescope, if None, all are read.
    source = hessio_event_source(simtel_file_path,
                                 allowed_tels=tel_id_filter_list)

    # ITERATE OVER EVENTS #####################################################

    calib = CameraCalibrator(None, None)

    for event in source:

        calib.calibrate(event)  # calibrate the event

        event_id = int(event.dl0.event_id)

        if (event_id_filter_list is None) or (event_id
                                              in event_id_filter_list):

            #print("event", event_id)

            # ITERATE OVER IMAGES #############################################

            for tel_id in event.trig.tels_with_trigger:

                tel_id = int(tel_id)

                if tel_id in tel_id_filter_list:

                    #print("telescope", tel_id)

                    # CHECK THE IMAGE GEOMETRY ################################

                    #print("checking geometry")

                    x, y = event.inst.subarray.tel[
                        tel_id].camera.pix_x, event.inst.subarray.tel[
                            tel_id].camera.pix_y
                    foclen = event.inst.subarray.tel[
                        tel_id].optics.equivalent_focal_length
                    geom = CameraGeometry.guess(x, y, foclen)

                    if (geom.pix_type != "hexagonal") or (geom.cam_id !=
                                                          "DigiCam"):
                        raise ValueError(
                            "Telescope {}: error (the input image is not a valide DigiCam telescope image) -> {} ({})"
                            .format(tel_id, geom.pix_type, geom.cam_id))

                    # GET IMAGES ##############################################

                    pe_image = event.mc.tel[
                        tel_id].photo_electron_image  # 1D np array

                    #uncalibrated_image = event.dl0.tel[tel_id].adc_sums  # ctapipe 0.3.0
                    uncalibrated_image = event.r0.tel[
                        tel_id].adc_sums  # ctapipe 0.4.0
                    pedestal = event.mc.tel[tel_id].pedestal
                    gain = event.mc.tel[tel_id].dc_to_pe
                    pixel_pos = (event.inst.subarray.tel[tel_id].camera.pix_x,
                                 event.inst.subarray.tel[tel_id].camera.pix_y)

                    calibrated_image = event.dl1.tel[tel_id].image

                    #print(pe_image.shape)
                    #print(calibrated_image.shape)
                    #print(uncalibrated_image.shape)
                    #print(pedestal.shape)
                    #print(gain.shape)
                    #print(pixel_pos.shape)
                    #print(pixel_pos[0])
                    #print(pixel_pos[1])

                    # CONVERTING GEOMETRY (1D TO 2D) ##########################

                    buffer_id_str = geom.cam_id + "0"

                    geom2d, pe_image_2d = ctapipe_geom_converter.convert_geometry_1d_to_2d(
                        geom, pe_image, buffer_id_str, add_rot=0)
                    geom2d, calibrated_image_2d = ctapipe_geom_converter.convert_geometry_1d_to_2d(
                        geom, calibrated_image[0], buffer_id_str, add_rot=0)

                    geom2d, uncalibrated_image_2d = ctapipe_geom_converter.convert_geometry_1d_to_2d(
                        geom, uncalibrated_image[0], buffer_id_str, add_rot=0)
                    geom2d, pedestal_2d = ctapipe_geom_converter.convert_geometry_1d_to_2d(
                        geom, pedestal[0], buffer_id_str, add_rot=0)
                    geom2d, gains_2d = ctapipe_geom_converter.convert_geometry_1d_to_2d(
                        geom, gain[0], buffer_id_str, add_rot=0)

                    # Make a mock pixel position array...
                    pixel_pos_2d = np.array(
                        np.meshgrid(
                            np.linspace(pixel_pos[0].min(), pixel_pos[0].max(),
                                        pe_image_2d.shape[0]),
                            np.linspace(pixel_pos[1].min(), pixel_pos[1].max(),
                                        pe_image_2d.shape[1])))

                    # PUT NAN IN BLANK PIXELS #################################

                    calibrated_image_2d[np.logical_not(geom2d.mask)] = np.nan
                    pe_image_2d[np.logical_not(geom2d.mask)] = np.nan

                    uncalibrated_image_2d[np.logical_not(geom2d.mask)] = np.nan
                    pedestal_2d[np.logical_not(geom2d.mask)] = np.nan
                    gains_2d[np.logical_not(geom2d.mask)] = np.nan

                    pixel_pos_2d[0, np.logical_not(geom2d.mask)] = np.nan
                    pixel_pos_2d[1, np.logical_not(geom2d.mask)] = np.nan

                    ###########################################################

                    # The ctapipe geometry converter operate on one channel
                    # only and then takes and return a 2D array but pywicta
                    # fits files keep all channels and thus takes 3D arrays...

                    uncalibrated_image_2d = np.array([uncalibrated_image_2d])
                    pedestal_2d = np.array([pedestal_2d])
                    gains_2d = np.array([gains_2d])

                    ###########################################################

                    #print(pe_image_2d.shape)
                    #print(calibrated_image_2d.shape)
                    #print(uncalibrated_image_2d.shape)
                    #print(pedestal_2d.shape)
                    #print(gains_2d.shape)

                    #img = pixel_pos_2d
                    #print(img[1])

                    #import matplotlib.pyplot as plt
                    #im = plt.imshow(img[1])
                    #plt.colorbar(im)
                    #plt.show()
                    #sys.exit(0)

                    # GET PIXEL MASK ##########################################

                    pixel_mask = geom2d.mask.astype(
                        int
                    )  # 1 for pixels with actual data, 0 for virtual (blank) pixels

                    # MAKE METADATA ###########################################

                    metadata = {}

                    metadata[
                        'version'] = 1  # Version of the pywicta fits format

                    metadata['cam_id'] = "DigiCam"

                    metadata['tel_id'] = tel_id
                    metadata['event_id'] = event_id
                    metadata['simtel'] = simtel_file_path

                    metadata['tel_trig'] = len(event.trig.tels_with_trigger)

                    metadata['energy'] = quantity_to_tuple(
                        event.mc.energy, 'TeV')
                    metadata['mc_az'] = quantity_to_tuple(event.mc.az, 'rad')
                    metadata['mc_alt'] = quantity_to_tuple(event.mc.alt, 'rad')
                    metadata['mc_corex'] = quantity_to_tuple(
                        event.mc.core_x, 'm')
                    metadata['mc_corey'] = quantity_to_tuple(
                        event.mc.core_y, 'm')
                    metadata['mc_hfi'] = quantity_to_tuple(
                        event.mc.h_first_int, 'm')

                    metadata['count'] = int(event.count)

                    metadata['run_id'] = int(event.dl0.obs_id)
                    metadata['tel_data'] = len(event.dl0.tels_with_data)

                    metadata['foclen'] = quantity_to_tuple(
                        event.inst.subarray.tel[tel_id].optics.
                        equivalent_focal_length, 'm')
                    metadata['tel_posx'] = quantity_to_tuple(
                        event.inst.subarray.tel_coords[tel_id].x, 'm')
                    metadata['tel_posy'] = quantity_to_tuple(
                        event.inst.subarray.tel_coords[tel_id].y, 'm')
                    metadata['tel_posz'] = quantity_to_tuple(
                        event.inst.subarray.tel_coords[tel_id].z, 'm')

                    # TODO: Astropy fails to store the following data in FITS files
                    #metadata['uid'] = os.getuid()
                    #metadata['datetime'] = str(datetime.datetime.now())
                    #metadata['version'] = VERSION
                    #metadata['argv'] = " ".join(sys.argv).encode('ascii', errors='ignore').decode('ascii')
                    #metadata['python'] = " ".join(sys.version.splitlines()).encode('ascii', errors='ignore').decode('ascii')
                    #metadata['system'] = " ".join(os.uname())

                    # SAVE THE IMAGE ##########################################

                    output_file_path_template = "{}_TEL{:03d}_EV{:05d}.fits"

                    if output_directory is not None:
                        simtel_basename = os.path.basename(simtel_file_path)
                        prefix = os.path.join(output_directory,
                                              simtel_basename)
                    else:
                        prefix = simtel_file_path

                    output_file_path = output_file_path_template.format(
                        prefix, tel_id, event_id)

                    print("saving", output_file_path)

                    images.save_benchmark_images(
                        img=calibrated_image_2d,
                        pe_img=pe_image_2d,
                        adc_sums_img=uncalibrated_image_2d,
                        pedestal_img=pedestal_2d,
                        gains_img=gains_2d,
                        pixel_pos=pixel_pos_2d,
                        pixel_mask=pixel_mask,
                        metadata=metadata,
                        output_file_path=output_file_path)
示例#27
0
    def draw_event(self, event, hillas_parameters=None):
        """
        Draw display for a given event

        Parameters
        ----------
        event: ctapipe event object
        hillas_parameters: dict
            Dictionary of Hillas parameters (in nominal system)

        Returns
        -------
            None
        """
        tel_list = event.r0.tels_with_data
        images = event.dl1

        # First close any plots that already exist
        plt.close()
        ntels = len(tel_list)

        fig = plt.figure(figsize=(20, 20 * 0.66))

        # If we want to draw the Hillas parameters in different planes we need to split our figure
        if self.draw_hillas_planes:
            y_axis_split = 2
        else:
            y_axis_split = 1

        outer_grid = gridspec.GridSpec(1, y_axis_split, width_ratios=[y_axis_split, 1])
        # Create a square grid for camera images
        nn = int(ceil(sqrt(ntels)))
        nx = nn
        ny = nn

        while nx * ny >= ntels:
            ny-=1
        ny+=1
        while nx * ny >= ntels:
            nx -= 1
        nx += 1

        camera_grid = gridspec.GridSpecFromSubplotSpec(ny, nx, subplot_spec=outer_grid[0])

        # Loop over camera images of all telescopes and create plots
        for ii, tel_id in zip(range(ntels), tel_list):

            # Cache of camera geometries, this may go away soon
            if tel_id not in self.geom:
                self.geom[tel_id] = CameraGeometry.guess(
                    event.inst.pixel_pos[tel_id][0],
                    event.inst.pixel_pos[tel_id][1],
                    event.inst.optical_foclen[tel_id])

            ax = plt.subplot(camera_grid[ii])
            self.get_camera_view(tel_id, images.tel[tel_id].image[0], ax)

        # If we want to draw the Hillas parameters in different planes we need to make a couple more viewers
        if self.draw_hillas_planes:
            # Split the second sub figure into two further figures
            reco_grid = gridspec.GridSpecFromSubplotSpec(2, 1, subplot_spec=outer_grid[1])
            # Create plot of telescope positions at ground level
            array = ArrayPlotter(telescopes=tel_list, instrument=event.inst,# system=tilted_system,
                                ax=plt.subplot(reco_grid[0]))
            # Draw MC position (this should change later)
            array.draw_position(event.mc.core_x, event.mc.core_y, use_centre=True)
            array.draw_array(((-300,300),(-300,300)))

            # If we have valid Hillas parameters we should draw them in the Nominal system
            if hillas_parameters is not None:
                array.overlay_hillas(hillas_parameters, draw_axes=True)

                nominal =  NominalPlotter(hillas_parameters=hillas_parameters, draw_axes=True, ax=plt.subplot(reco_grid[1]))
                nominal.draw_array()

        plt.show()

        return
def extract_images(simtel_file_path,
                   tel_id_filter_list=None,
                   event_id_filter_list=None,
                   output_directory=None,
                   crop=True):

    # EXTRACT IMAGES ##########################################################

    # hessio_event_source returns a Python generator that streams data from an
    # EventIO/HESSIO MC data file (e.g. a standard CTA data file).
    # This generator contains ctapipe.core.Container instances ("event").
    #
    # Parameters:
    # - max_events: maximum number of events to read
    # - allowed_tels: select only a subset of telescope, if None, all are read.
    source = hessio_event_source(simtel_file_path,
                                 allowed_tels=tel_id_filter_list)

    # ITERATE OVER EVENTS #####################################################

    calib = CameraCalibrator(None, None)

    for event in source:

        calib.calibrate(event)  # calibrate the event

        event_id = int(event.dl0.event_id)

        if (event_id_filter_list is None) or (event_id
                                              in event_id_filter_list):

            #print("event", event_id)

            # ITERATE OVER IMAGES #############################################

            for tel_id in event.trig.tels_with_trigger:

                tel_id = int(tel_id)

                if tel_id in tel_id_filter_list:

                    #print("telescope", tel_id)

                    # CHECK THE IMAGE GEOMETRY (ASTRI ONLY) ###################

                    # TODO

                    #print("checking geometry")

                    x, y = event.inst.subarray.tel[
                        tel_id].camera.pix_x, event.inst.subarray.tel[
                            tel_id].camera.pix_y
                    foclen = event.inst.subarray.tel[
                        tel_id].optics.equivalent_focal_length
                    geom = CameraGeometry.guess(x, y, foclen)

                    if (geom.pix_type != "rectangular") or (geom.cam_id
                                                            not in ("ASTRICam",
                                                                    "ASTRI")):
                        raise ValueError(
                            "Telescope {}: error (the input image is not a valide ASTRI telescope image) -> {} ({})"
                            .format(tel_id, geom.pix_type, geom.cam_id))

                    # GET IMAGES ##############################################

                    pe_image = event.mc.tel[
                        tel_id].photo_electron_image  # 1D np array

                    #uncalibrated_image = event.dl0.tel[tel_id].adc_sums  # ctapipe 0.3.0
                    uncalibrated_image = event.r0.tel[
                        tel_id].adc_sums  # ctapipe 0.4.0
                    pedestal = event.mc.tel[tel_id].pedestal
                    gain = event.mc.tel[tel_id].dc_to_pe
                    pixel_pos = (event.inst.subarray.tel[tel_id].camera.pix_x,
                                 event.inst.subarray.tel[tel_id].camera.pix_y)

                    calibrated_image = event.dl1.tel[tel_id].image

                    calibrated_image[1, calibrated_image[
                        0, :] <= ASTRI_CAM_CHANNEL_THRESHOLD] = 0
                    calibrated_image[0, calibrated_image[
                        0, :] > ASTRI_CAM_CHANNEL_THRESHOLD] = 0
                    calibrated_image = calibrated_image.sum(axis=0)

                    #print(pe_image.shape)
                    #print(calibrated_image.shape)
                    #print(uncalibrated_image.shape)
                    #print(pedestal.shape)
                    #print(gain.shape)
                    #print(pixel_pos.shape)
                    #print(pixel_pos[0])
                    #print(pixel_pos[1])

                    # CONVERTING GEOMETRY (1D TO 2D) ##########################

                    pe_image_2d = geometry_converter.astri_to_2d_array(
                        pe_image, crop=crop)
                    calibrated_image_2d = geometry_converter.astri_to_2d_array(
                        calibrated_image, crop=crop)
                    uncalibrated_image_2d = geometry_converter.astri_to_3d_array(
                        uncalibrated_image, crop=crop)
                    pedestal_2d = geometry_converter.astri_to_3d_array(
                        pedestal, crop=crop)
                    gains_2d = geometry_converter.astri_to_3d_array(gain,
                                                                    crop=crop)
                    pixel_pos_2d = geometry_converter.astri_to_3d_array(
                        pixel_pos, crop=crop)

                    #print(pe_image_2d.shape)
                    #print(calibrated_image_2d.shape)
                    #print(uncalibrated_image_2d.shape)
                    #print(pedestal_2d.shape)
                    #print(gains_2d.shape)
                    #print(pixel_pos_2d.shape)
                    #sys.exit(0)

                    # GET PIXEL MASK ##########################################

                    pixel_mask = geometry_converter.astri_pixel_mask(
                        crop
                    )  # 1 for pixels with actual data, 0 for virtual (blank) pixels

                    # MAKE METADATA ###########################################

                    metadata = {}

                    metadata[
                        'version'] = 1  # Version of the pywicta fits format

                    if crop:
                        metadata['cam_id'] = "ASTRI_CROPPED"
                    else:
                        metadata['cam_id'] = "ASTRI"

                    metadata['tel_id'] = tel_id
                    metadata['event_id'] = event_id
                    metadata['simtel'] = simtel_file_path

                    metadata['tel_trig'] = len(event.trig.tels_with_trigger)

                    metadata['energy'] = quantity_to_tuple(
                        event.mc.energy, 'TeV')
                    metadata['mc_az'] = quantity_to_tuple(event.mc.az, 'rad')
                    metadata['mc_alt'] = quantity_to_tuple(event.mc.alt, 'rad')
                    metadata['mc_corex'] = quantity_to_tuple(
                        event.mc.core_x, 'm')
                    metadata['mc_corey'] = quantity_to_tuple(
                        event.mc.core_y, 'm')
                    metadata['mc_hfi'] = quantity_to_tuple(
                        event.mc.h_first_int, 'm')

                    metadata['count'] = int(event.count)

                    metadata['run_id'] = int(event.dl0.obs_id)
                    metadata['tel_data'] = len(event.dl0.tels_with_data)

                    metadata['foclen'] = quantity_to_tuple(
                        event.inst.subarray.tel[tel_id].optics.
                        equivalent_focal_length, 'm')
                    metadata['tel_posx'] = quantity_to_tuple(
                        event.inst.subarray.tel_coords[tel_id].x, 'm')
                    metadata['tel_posy'] = quantity_to_tuple(
                        event.inst.subarray.tel_coords[tel_id].y, 'm')
                    metadata['tel_posz'] = quantity_to_tuple(
                        event.inst.subarray.tel_coords[tel_id].z, 'm')

                    # TODO: Astropy fails to store the following data in FITS files
                    #metadata['uid'] = os.getuid()
                    #metadata['datetime'] = str(datetime.datetime.now())
                    #metadata['version'] = VERSION
                    #metadata['argv'] = " ".join(sys.argv).encode('ascii', errors='ignore').decode('ascii')
                    #metadata['python'] = " ".join(sys.version.splitlines()).encode('ascii', errors='ignore').decode('ascii')
                    #metadata['system'] = " ".join(os.uname())

                    # SAVE THE IMAGE ##########################################

                    output_file_path_template = "{}_TEL{:03d}_EV{:05d}.fits"

                    if output_directory is not None:
                        simtel_basename = os.path.basename(simtel_file_path)
                        prefix = os.path.join(output_directory,
                                              simtel_basename)
                    else:
                        prefix = simtel_file_path

                    output_file_path = output_file_path_template.format(
                        prefix, tel_id, event_id)

                    print("saving", output_file_path)

                    images.save_benchmark_images(
                        img=calibrated_image_2d,
                        pe_img=pe_image_2d,
                        adc_sums_img=uncalibrated_image_2d,
                        pedestal_img=pedestal_2d,
                        gains_img=gains_2d,
                        pixel_pos=pixel_pos_2d,
                        pixel_mask=pixel_mask,
                        metadata=metadata,
                        output_file_path=output_file_path)
示例#29
0
def test_FitGammaHillas():
    '''
    a test of the complete fit procedure on one event including:
    • tailcut cleaning
    • hillas parametrisation
    • GreatCircle creation
    • direction fit
    • position fit

    in the end, proper units in the output are asserted '''

    filename = get_dataset("gamma_test.simtel.gz")

    fit = HillasReconstructor()

    cam_geom = {}
    tel_phi = {}
    tel_theta = {}

    source = hessio_event_source(filename)

    for event in source:

        hillas_dict = {}
        for tel_id in event.dl0.tels_with_data:

            if tel_id not in cam_geom:
                cam_geom[tel_id] = CameraGeometry.guess(
                    event.inst.pixel_pos[tel_id][0],
                    event.inst.pixel_pos[tel_id][1],
                    event.inst.optical_foclen[tel_id])

                tel_phi[tel_id] = event.mc.tel[tel_id].azimuth_raw * u.rad
                tel_theta[tel_id] = (np.pi / 2 -
                                     event.mc.tel[tel_id].altitude_raw) * u.rad

            pmt_signal = event.r0.tel[tel_id].adc_sums[0]

            mask = tailcuts_clean(cam_geom[tel_id],
                                  pmt_signal,
                                  picture_thresh=10.,
                                  boundary_thresh=5.)
            pmt_signal[mask == 0] = 0

            try:
                moments = hillas_parameters(event.inst.pixel_pos[tel_id][0],
                                            event.inst.pixel_pos[tel_id][1],
                                            pmt_signal)
                hillas_dict[tel_id] = moments
            except HillasParameterizationError as e:
                print(e)
                continue

        if len(hillas_dict) < 2: continue

        fit_result = fit.predict(hillas_dict, event.inst, tel_phi, tel_theta)

        print(fit_result)
        fit_result.alt.to(u.deg)
        fit_result.az.to(u.deg)
        fit_result.core_x.to(u.m)
        assert fit_result.is_valid
        return
def extract_images(simtel_file_path,
                   tel_id_filter_list=None,
                   event_id_filter_list=None,
                   output_directory=None):

    # EXTRACT IMAGES ##########################################################

    # hessio_event_source returns a Python generator that streams data from an
    # EventIO/HESSIO MC data file (e.g. a standard CTA data file).
    # This generator contains ctapipe.core.Container instances ("event").
    # 
    # Parameters:
    # - max_events: maximum number of events to read
    # - allowed_tels: select only a subset of telescope, if None, all are read.
    source = hessio_event_source(simtel_file_path, allowed_tels=tel_id_filter_list)

    # ITERATE OVER EVENTS #####################################################

    calib = CameraCalibrator(None, None)

    for event in source:

        calib.calibrate(event)  # calibrate the event

        event_id = int(event.dl0.event_id)

        if (event_id_filter_list is None) or (event_id in event_id_filter_list):

            #print("event", event_id)

            # ITERATE OVER IMAGES #############################################

            for tel_id in event.trig.tels_with_trigger:

                tel_id = int(tel_id)

                if tel_id in tel_id_filter_list:

                    #print("telescope", tel_id)

                    # CHECK THE IMAGE GEOMETRY ################################

                    #print("checking geometry")

                    x, y = event.inst.pixel_pos[tel_id]
                    foclen = event.inst.optical_foclen[tel_id]
                    geom = CameraGeometry.guess(x, y, foclen)

                    if (geom.pix_type != "hexagonal") or (geom.cam_id != "LSTCam"):
                        raise ValueError("Telescope {}: error (the input image is not a valide LSTCam telescope image) -> {} ({})".format(tel_id, geom.pix_type, geom.cam_id))

                    # GET IMAGES ##############################################

                    pe_image = event.mc.tel[tel_id].photo_electron_image   # 1D np array

                    #uncalibrated_image = event.dl0.tel[tel_id].adc_sums  # ctapipe 0.3.0
                    uncalibrated_image = event.r0.tel[tel_id].adc_sums    # ctapipe 0.4.0
                    pedestal = event.mc.tel[tel_id].pedestal
                    gain = event.mc.tel[tel_id].dc_to_pe
                    pixel_pos = event.inst.pixel_pos[tel_id]

                    calibrated_image = event.dl1.tel[tel_id].image

                    calibrated_image[1, calibrated_image[0,:] <= LST_CAM_CHANNEL_THRESHOLD] = 0
                    calibrated_image[0, calibrated_image[0,:] >  LST_CAM_CHANNEL_THRESHOLD] = 0
                    calibrated_image = calibrated_image.sum(axis=0)

                    #print(pe_image.shape)
                    #print(calibrated_image.shape)
                    #print(uncalibrated_image.shape)
                    #print(pedestal.shape)
                    #print(gain.shape)
                    #print(pixel_pos.shape)
                    #print(pixel_pos[0])
                    #print(pixel_pos[1])

                    # CONVERTING GEOMETRY (1D TO 2D) ##########################

                    buffer_id_str = geom.cam_id + "0"

                    geom2d, pe_image_2d =           ctapipe_geom_converter.convert_geometry_1d_to_2d(geom, pe_image,           buffer_id_str, add_rot=0)
                    geom2d, calibrated_image_2d =   ctapipe_geom_converter.convert_geometry_1d_to_2d(geom, calibrated_image,   buffer_id_str, add_rot=0)

                    geom2d, uncalibrated_image_2d_ch0 = ctapipe_geom_converter.convert_geometry_1d_to_2d(geom, uncalibrated_image[0], buffer_id_str, add_rot=0)
                    geom2d, uncalibrated_image_2d_ch1 = ctapipe_geom_converter.convert_geometry_1d_to_2d(geom, uncalibrated_image[1], buffer_id_str, add_rot=0)
                    geom2d, pedestal_2d_ch0 =           ctapipe_geom_converter.convert_geometry_1d_to_2d(geom, pedestal[0],           buffer_id_str, add_rot=0)
                    geom2d, pedestal_2d_ch1 =           ctapipe_geom_converter.convert_geometry_1d_to_2d(geom, pedestal[1],           buffer_id_str, add_rot=0)
                    geom2d, gains_2d_ch0 =              ctapipe_geom_converter.convert_geometry_1d_to_2d(geom, gain[0],               buffer_id_str, add_rot=0)
                    geom2d, gains_2d_ch1 =              ctapipe_geom_converter.convert_geometry_1d_to_2d(geom, gain[1],               buffer_id_str, add_rot=0)

                    # Make a mock pixel position array...
                    pixel_pos_2d = np.array(np.meshgrid(np.linspace(pixel_pos[0].min(), pixel_pos[0].max(), pe_image_2d.shape[0]),
                                                        np.linspace(pixel_pos[1].min(), pixel_pos[1].max(), pe_image_2d.shape[1])))

                    ###########################################################

                    # The ctapipe geometry converter operate on one channel
                    # only and then takes and return a 2D array but datapipe
                    # fits files keep all channels and thus takes 3D arrays...

                    uncalibrated_image_2d = np.array([uncalibrated_image_2d_ch0, uncalibrated_image_2d_ch1])
                    pedestal_2d = np.array([pedestal_2d_ch0, pedestal_2d_ch1 ])
                    gains_2d = np.array([gains_2d_ch0, gains_2d_ch1])

                    # PUT NAN IN BLANK PIXELS #################################

                    calibrated_image_2d[np.logical_not(geom2d.mask)] = np.nan
                    pe_image_2d[np.logical_not(geom2d.mask)] = np.nan

                    uncalibrated_image_2d[0, np.logical_not(geom2d.mask)] = np.nan
                    uncalibrated_image_2d[1, np.logical_not(geom2d.mask)] = np.nan
                    pedestal_2d[0, np.logical_not(geom2d.mask)] = np.nan
                    pedestal_2d[1, np.logical_not(geom2d.mask)] = np.nan
                    gains_2d[0, np.logical_not(geom2d.mask)] = np.nan
                    gains_2d[1, np.logical_not(geom2d.mask)] = np.nan

                    pixel_pos_2d[0, np.logical_not(geom2d.mask)] = np.nan
                    pixel_pos_2d[1, np.logical_not(geom2d.mask)] = np.nan

                    ###########################################################

                    #print(pe_image_2d.shape)
                    #print(calibrated_image_2d.shape)
                    #print(uncalibrated_image_2d.shape)
                    #print(pedestal_2d.shape)
                    #print(gains_2d.shape)

                    #img = pixel_pos_2d
                    #print(img[1])

                    #import matplotlib.pyplot as plt
                    #im = plt.imshow(img[1])
                    #plt.colorbar(im)
                    #plt.show()
                    #sys.exit(0)

                    # GET PIXEL MASK ##########################################

                    pixel_mask = geom2d.mask.astype(int)  # 1 for pixels with actual data, 0 for virtual (blank) pixels

                    # MAKE METADATA ###########################################

                    metadata = {}

                    metadata['version'] = 1    # Version of the datapipe fits format

                    metadata['cam_id'] = "LSTCam"

                    metadata['tel_id'] = tel_id
                    metadata['event_id'] = event_id
                    metadata['simtel'] = simtel_file_path

                    metadata['tel_trig'] = len(event.trig.tels_with_trigger)

                    metadata['energy'] =  quantity_to_tuple(event.mc.energy, 'TeV')
                    metadata['mc_az'] = quantity_to_tuple(event.mc.az, 'rad')
                    metadata['mc_alt'] = quantity_to_tuple(event.mc.alt, 'rad')
                    metadata['mc_corex'] = quantity_to_tuple(event.mc.core_x, 'm')
                    metadata['mc_corey'] = quantity_to_tuple(event.mc.core_y, 'm')
                    metadata['mc_hfi'] = quantity_to_tuple(event.mc.h_first_int, 'm')

                    metadata['count'] = int(event.count)
                    
                    metadata['run_id'] = int(event.dl0.run_id)
                    metadata['tel_data'] = len(event.dl0.tels_with_data)

                    metadata['foclen'] = quantity_to_tuple(event.inst.optical_foclen[tel_id], 'm')
                    metadata['tel_posx'] = quantity_to_tuple(event.inst.tel_pos[tel_id][0], 'm')
                    metadata['tel_posy'] = quantity_to_tuple(event.inst.tel_pos[tel_id][1], 'm')
                    metadata['tel_posz'] = quantity_to_tuple(event.inst.tel_pos[tel_id][2], 'm')

                    # TODO: Astropy fails to store the following data in FITS files
                    #metadata['uid'] = os.getuid()
                    #metadata['datetime'] = str(datetime.datetime.now())
                    #metadata['version'] = VERSION
                    #metadata['argv'] = " ".join(sys.argv).encode('ascii', errors='ignore').decode('ascii')
                    #metadata['python'] = " ".join(sys.version.splitlines()).encode('ascii', errors='ignore').decode('ascii')
                    #metadata['system'] = " ".join(os.uname())

                    # SAVE THE IMAGE ##########################################

                    output_file_path_template = "{}_TEL{:03d}_EV{:05d}.fits"

                    if output_directory is not None:
                        simtel_basename = os.path.basename(simtel_file_path)
                        prefix = os.path.join(output_directory, simtel_basename)
                    else:
                        prefix = simtel_file_path

                    output_file_path = output_file_path_template.format(prefix,
                                                                        tel_id,
                                                                        event_id)

                    print("saving", output_file_path)

                    images.save_benchmark_images(img = calibrated_image_2d,
                                                 pe_img = pe_image_2d,
                                                 adc_sums_img = uncalibrated_image_2d,
                                                 pedestal_img = pedestal_2d,
                                                 gains_img = gains_2d,
                                                 pixel_pos = pixel_pos_2d,
                                                 pixel_mask = pixel_mask,
                                                 metadata = metadata,
                                                 output_file_path = output_file_path)
示例#31
0
    def reconstruct_event(self, event):
        """
        Perform full event reconstruction, including Hillas and ImPACT analysis.

        Parameters
        ----------
        event: ctapipe event container

        Returns
        -------
            None
        """
        # store MC pointing direction for the array
        array_pointing = HorizonFrame(
            alt=event.mcheader.run_array_direction[1] * u.rad,
            az=event.mcheader.run_array_direction[0] * u.rad)
        tilted_system = TiltedGroundFrame(pointing_direction=array_pointing)

        image = {}
        pixel_x = {}
        pixel_y = {}
        pixel_area = {}
        tel_type = {}
        tel_x = {}
        tel_y = {}

        hillas = {}
        hillas_nom = {}
        image_pred = {}
        mask_dict = {}
        print("Event energy", event.mc.energy)

        for tel_id in event.dl0.tels_with_data:

            # Get calibrated image (low gain channel only)
            pmt_signal = event.dl1.tel[tel_id].image[0]
            if len(event.dl1.tel[tel_id].image) > 1:
                print(event.dl1.tel[tel_id].image[1][pmt_signal > 100])
                pmt_signal[pmt_signal > 100] = \
                    event.dl1.tel[tel_id].image[1][pmt_signal > 100]
            # Create nominal system for the telescope (this should later used telescope
            # pointing)
            nom_system = NominalFrame(array_direction=array_pointing,
                                      pointing_direction=array_pointing)

            # Create camera system of all pixels
            pix_x, pix_y = event.inst.pixel_pos[tel_id]
            fl = event.inst.optical_foclen[tel_id]
            if tel_id not in self.geoms:
                self.geoms[tel_id] = CameraGeometry.guess(
                    pix_x,
                    pix_y,
                    event.inst.optical_foclen[tel_id],
                    apply_derotation=False)
            # Transform the pixels positions into nominal coordinates
            camera_coord = CameraFrame(x=pix_x,
                                       y=pix_y,
                                       z=np.zeros(pix_x.shape) * u.m,
                                       focal_length=fl,
                                       rotation=-1 *
                                       self.geoms[tel_id].cam_rotation)

            nom_coord = camera_coord.transform_to(nom_system)
            tx, ty, tz = event.inst.tel_pos[tel_id]

            # ImPACT reconstruction is performed in the tilted system,
            # so we need to transform tel positions
            grd_tel = GroundFrame(x=tx, y=ty, z=tz)
            tilt_tel = grd_tel.transform_to(tilted_system)

            # Clean image using split level cleaning
            mask = tailcuts_clean(
                self.geoms[tel_id],
                pmt_signal,
                picture_thresh=self.tail_cut[self.geoms[tel_id].cam_id][1],
                boundary_thresh=self.tail_cut[self.geoms[tel_id].cam_id][0])

            # Perform Hillas parameterisation
            moments = None
            try:
                moments_cam = hillas_parameters(
                    event.inst.pixel_pos[tel_id][0],
                    event.inst.pixel_pos[tel_id][1], pmt_signal * mask)

                moments = hillas_parameters(nom_coord.x, nom_coord.y,
                                            pmt_signal * mask)

            except HillasParameterizationError as e:
                print(e)
                continue

            # Make cut based on Hillas parameters
            if self.preselect(moments, np.sum(mask), tel_id):

                # Dialte around edges of image
                for i in range(4):
                    mask = dilate(self.geoms[tel_id], mask)

                # Save everything in dicts for reconstruction later
                pixel_area[tel_id] = self.geoms[tel_id].pix_area / (fl * fl)
                pixel_area[tel_id] *= u.rad * u.rad
                pixel_x[tel_id] = nom_coord.x
                pixel_y[tel_id] = nom_coord.y

                tel_x[tel_id] = tilt_tel.x
                tel_y[tel_id] = tilt_tel.y

                tel_type[tel_id] = self.geoms[tel_id].cam_id
                image[tel_id] = pmt_signal
                image_pred[tel_id] = np.zeros(pmt_signal.shape)

                hillas[tel_id] = moments_cam
                hillas_nom[tel_id] = moments
                mask_dict[tel_id] = mask

        # Cut on number of telescopes remaining
        if len(image) > 1:
            fit_result = self.fit.predict(hillas_nom, tel_x, tel_y,
                                          array_pointing)

            for tel_id in hillas_nom:

                core_grd = GroundFrame(x=fit_result.core_x,
                                       y=fit_result.core_y,
                                       z=0. * u.m)
                core_tilt = core_grd.transform_to(tilted_system)
                impact = np.sqrt(
                    np.power(tel_x[tel_id] - core_tilt.x, 2) +
                    np.power(tel_y[tel_id] - core_tilt.y, 2))

                pix = np.array([
                    pixel_x[tel_id].to(u.deg).value,
                    pixel_y[tel_id].to(u.deg).value
                ])
                img = image[tel_id]
                #img[img < 0.0] = 0.0
                #img /= np.max(img)

                lin = LinearNDInterpolator(pix.T, img, fill_value=0.0)
                x_img = np.arange(-4, 4, 0.05) * u.deg
                y_img = np.arange(-4, 4, 0.05) * u.deg
                xv, yv = np.meshgrid(x_img, y_img)
                pos = np.array([xv.ravel(), yv.ravel()])
                npix = xv.shape[0]
                img_int = np.reshape(lin(pos.T), xv.shape)
                print(img_int)

                hdu = fits.ImageHDU(img_int.astype(np.float32))
                hdu.header["IMPACT"] = impact.to(u.m).value
                hdu.header["TELTYPE"] = tel_type[tel_id]
                hdu.header["TELNUM"] = tel_id

                hdu.header["MCENERGY"] = event.mc.energy.to(u.TeV).value
                hdu.header["RECENERGY"] = 0
                hdu.header["AMP"] = hillas_nom[tel_id].size
                hdu.header["WIDTH"] = hillas_nom[tel_id].width.to(u.deg).value
                hdu.header["LENGTH"] = hillas_nom[tel_id].length.to(
                    u.deg).value
                self.output.append(hdu)
示例#32
0
    def plot(self, input_file, event, telid, chan, extractor_name):
        # Extract required images
        dl0 = event.dl0.tel[telid].pe_samples[chan]

        t_pe = event.mc.tel[telid].photo_electron_image
        dl1 = event.dl1.tel[telid].image[chan]
        max_time = np.unravel_index(np.argmax(dl0), dl0.shape)[1]
        max_charges = np.max(dl0, axis=1)
        max_pix = int(np.argmax(max_charges))
        min_pix = int(np.argmin(max_charges))

        geom = CameraGeometry.guess(*event.inst.pixel_pos[telid],
                                    event.inst.optical_foclen[telid])

        nei = geom.neighbors

        # Get Neighbours
        max_pixel_nei = nei[max_pix]
        min_pixel_nei = nei[min_pix]

        # Get Windows
        windows = event.dl1.tel[telid].extracted_samples[chan]
        length = np.sum(windows, axis=1)
        start = np.argmax(windows, axis=1)
        end = start + length - 1

        # Draw figures
        ax_max_nei = {}
        ax_min_nei = {}
        fig_waveforms = plt.figure(figsize=(18, 9))
        fig_waveforms.subplots_adjust(hspace=.5)
        fig_camera = plt.figure(figsize=(15, 12))

        ax_max_pix = fig_waveforms.add_subplot(4, 2, 1)
        ax_min_pix = fig_waveforms.add_subplot(4, 2, 2)
        ax_max_nei[0] = fig_waveforms.add_subplot(4, 2, 3)
        ax_min_nei[0] = fig_waveforms.add_subplot(4, 2, 4)
        ax_max_nei[1] = fig_waveforms.add_subplot(4, 2, 5)
        ax_min_nei[1] = fig_waveforms.add_subplot(4, 2, 6)
        ax_max_nei[2] = fig_waveforms.add_subplot(4, 2, 7)
        ax_min_nei[2] = fig_waveforms.add_subplot(4, 2, 8)

        ax_img_nei = fig_camera.add_subplot(2, 2, 1)
        ax_img_max = fig_camera.add_subplot(2, 2, 2)
        ax_img_true = fig_camera.add_subplot(2, 2, 3)
        ax_img_cal = fig_camera.add_subplot(2, 2, 4)

        # Draw max pixel traces
        ax_max_pix.plot(dl0[max_pix])
        ax_max_pix.set_xlabel("Time (ns)")
        ax_max_pix.set_ylabel("DL0 Samples (ADC)")
        ax_max_pix.set_title(
            "(Max) Pixel: {}, True: {}, Measured = {:.3f}".format(
                max_pix, t_pe[max_pix], dl1[max_pix]))
        max_ylim = ax_max_pix.get_ylim()
        ax_max_pix.plot([start[max_pix], start[max_pix]],
                        ax_max_pix.get_ylim(),
                        color='r',
                        alpha=1)
        ax_max_pix.plot([end[max_pix], end[max_pix]],
                        ax_max_pix.get_ylim(),
                        color='r',
                        alpha=1)
        for i, ax in ax_max_nei.items():
            if len(max_pixel_nei) > i:
                pix = max_pixel_nei[i]
                ax.plot(dl0[pix])
                ax.set_xlabel("Time (ns)")
                ax.set_ylabel("DL0 Samples (ADC)")
                ax.set_title(
                    "(Max Nei) Pixel: {}, True: {}, Measured = {:.3f}".format(
                        pix, t_pe[pix], dl1[pix]))
                ax.set_ylim(max_ylim)
                ax.plot([start[pix], start[pix]],
                        ax.get_ylim(),
                        color='r',
                        alpha=1)
                ax.plot([end[pix], end[pix]],
                        ax.get_ylim(),
                        color='r',
                        alpha=1)

        # Draw min pixel traces
        ax_min_pix.plot(dl0[min_pix])
        ax_min_pix.set_xlabel("Time (ns)")
        ax_min_pix.set_ylabel("DL0 Samples (ADC)")
        ax_min_pix.set_title(
            "(Min) Pixel: {}, True: {}, Measured = {:.3f}".format(
                min_pix, t_pe[min_pix], dl1[min_pix]))
        ax_min_pix.set_ylim(max_ylim)
        ax_min_pix.plot([start[min_pix], start[min_pix]],
                        ax_min_pix.get_ylim(),
                        color='r',
                        alpha=1)
        ax_min_pix.plot([end[min_pix], end[min_pix]],
                        ax_min_pix.get_ylim(),
                        color='r',
                        alpha=1)
        for i, ax in ax_min_nei.items():
            if len(min_pixel_nei) > i:
                pix = min_pixel_nei[i]
                ax.plot(dl0[pix])
                ax.set_xlabel("Time (ns)")
                ax.set_ylabel("DL0 Samples (ADC)")
                ax.set_title(
                    "(Min Nei) Pixel: {}, True: {}, Measured = {:.3f}".format(
                        pix, t_pe[pix], dl1[pix]))
                ax.set_ylim(max_ylim)
                ax.plot([start[pix], start[pix]],
                        ax.get_ylim(),
                        color='r',
                        alpha=1)
                ax.plot([end[pix], end[pix]],
                        ax.get_ylim(),
                        color='r',
                        alpha=1)

        # Draw cameras
        nei_camera = np.zeros_like(max_charges, dtype=np.int)
        nei_camera[min_pixel_nei] = 2
        nei_camera[min_pix] = 1
        nei_camera[max_pixel_nei] = 3
        nei_camera[max_pix] = 4
        camera = CameraDisplay(geom, ax=ax_img_nei)
        camera.image = nei_camera
        camera.cmap = plt.cm.viridis
        ax_img_nei.set_title("Neighbour Map")
        ax_img_nei.annotate("Pixel: {}".format(max_pix),
                            xy=(geom.pix_x.value[max_pix],
                                geom.pix_y.value[max_pix]),
                            xycoords='data',
                            xytext=(0.05, 0.98),
                            textcoords='axes fraction',
                            arrowprops=dict(facecolor='red',
                                            width=2,
                                            alpha=0.4),
                            horizontalalignment='left',
                            verticalalignment='top')
        ax_img_nei.annotate("Pixel: {}".format(min_pix),
                            xy=(geom.pix_x.value[min_pix],
                                geom.pix_y.value[min_pix]),
                            xycoords='data',
                            xytext=(0.05, 0.94),
                            textcoords='axes fraction',
                            arrowprops=dict(facecolor='orange',
                                            width=2,
                                            alpha=0.4),
                            horizontalalignment='left',
                            verticalalignment='top')
        camera = CameraDisplay(geom, ax=ax_img_max)
        camera.image = dl0[:, max_time]
        camera.cmap = plt.cm.viridis
        camera.add_colorbar(ax=ax_img_max, label="DL0 Samples (ADC)")
        ax_img_max.set_title("Max Timeslice (T = {})".format(max_time))
        ax_img_max.annotate("Pixel: {}".format(max_pix),
                            xy=(geom.pix_x.value[max_pix],
                                geom.pix_y.value[max_pix]),
                            xycoords='data',
                            xytext=(0.05, 0.98),
                            textcoords='axes fraction',
                            arrowprops=dict(facecolor='red',
                                            width=2,
                                            alpha=0.4),
                            horizontalalignment='left',
                            verticalalignment='top')
        ax_img_max.annotate("Pixel: {}".format(min_pix),
                            xy=(geom.pix_x.value[min_pix],
                                geom.pix_y.value[min_pix]),
                            xycoords='data',
                            xytext=(0.05, 0.94),
                            textcoords='axes fraction',
                            arrowprops=dict(facecolor='orange',
                                            width=2,
                                            alpha=0.4),
                            horizontalalignment='left',
                            verticalalignment='top')

        camera = CameraDisplay(geom, ax=ax_img_true)
        camera.image = t_pe
        camera.cmap = plt.cm.viridis
        camera.add_colorbar(ax=ax_img_true, label="True Charge (p.e.)")
        ax_img_true.set_title("True Charge")
        ax_img_true.annotate("Pixel: {}".format(max_pix),
                             xy=(geom.pix_x.value[max_pix],
                                 geom.pix_y.value[max_pix]),
                             xycoords='data',
                             xytext=(0.05, 0.98),
                             textcoords='axes fraction',
                             arrowprops=dict(facecolor='red',
                                             width=2,
                                             alpha=0.4),
                             horizontalalignment='left',
                             verticalalignment='top')
        ax_img_true.annotate("Pixel: {}".format(min_pix),
                             xy=(geom.pix_x.value[min_pix],
                                 geom.pix_y.value[min_pix]),
                             xycoords='data',
                             xytext=(0.05, 0.94),
                             textcoords='axes fraction',
                             arrowprops=dict(facecolor='orange',
                                             width=2,
                                             alpha=0.4),
                             horizontalalignment='left',
                             verticalalignment='top')

        camera = CameraDisplay(geom, ax=ax_img_cal)
        camera.image = dl1
        camera.cmap = plt.cm.viridis
        camera.add_colorbar(ax=ax_img_cal,
                            label="Calib Charge (Photo-electrons)")
        ax_img_cal.set_title("Charge (integrator={})".format(extractor_name))
        ax_img_cal.annotate("Pixel: {}".format(max_pix),
                            xy=(geom.pix_x.value[max_pix],
                                geom.pix_y.value[max_pix]),
                            xycoords='data',
                            xytext=(0.05, 0.98),
                            textcoords='axes fraction',
                            arrowprops=dict(facecolor='red',
                                            width=2,
                                            alpha=0.4),
                            horizontalalignment='left',
                            verticalalignment='top')
        ax_img_cal.annotate("Pixel: {}".format(min_pix),
                            xy=(geom.pix_x.value[min_pix],
                                geom.pix_y.value[min_pix]),
                            xycoords='data',
                            xytext=(0.05, 0.94),
                            textcoords='axes fraction',
                            arrowprops=dict(facecolor='orange',
                                            width=2,
                                            alpha=0.4),
                            horizontalalignment='left',
                            verticalalignment='top')

        fig_waveforms.suptitle("Integrator = {}".format(extractor_name))
        fig_camera.suptitle("Camera = {}".format(geom.cam_id))

        waveform_output_name = "e{}_t{}_c{}_extractor{}_waveform.pdf"\
            .format(event.count, telid, chan, extractor_name)
        camera_output_name = "e{}_t{}_c{}_extractor{}_camera.pdf"\
            .format(event.count, telid, chan, extractor_name)

        output_dir = self.output_dir
        if output_dir is None:
            output_dir = input_file.output_directory
        output_dir = os.path.join(output_dir, self.name)
        if not os.path.exists(output_dir):
            self.log.info("Creating directory: {}".format(output_dir))
            os.makedirs(output_dir)

        waveform_output_path = os.path.join(output_dir, waveform_output_name)
        self.log.info("Saving: {}".format(waveform_output_path))
        fig_waveforms.savefig(waveform_output_path,
                              format='pdf',
                              bbox_inches='tight')

        camera_output_path = os.path.join(output_dir, camera_output_name)
        self.log.info("Saving: {}".format(camera_output_path))
        fig_camera.savefig(camera_output_path,
                           format='pdf',
                           bbox_inches='tight')
        return geom
示例#33
0
 def get_geometry(self, event, telid):
     if telid not in self._geom_dict:
         geom = CameraGeometry.guess(*event.inst.pixel_pos[telid],
                                     event.inst.optical_foclen[telid])
         self._geom_dict[telid] = geom
     return self._geom_dict[telid]
示例#34
0
    def start(self):
        df_list = []
        n_frames = 0

        first_event = self.reader.get_event(0)
        n_samples = first_event.r0.tel[0].num_samples
        pos = first_event.inst.pixel_pos[0]
        foclen = first_event.inst.optical_foclen[0]
        geom = CameraGeometry.guess(*pos, foclen)

        desc = "Extracting image slices from file"
        n_events = self.reader.num_events
        source = self.reader.read()
        for event in tqdm(source, total=n_events, desc=desc):
            event_id = event.r0.event_id

            self.r1.calibrate(event)
            self.dl0.reduce(event)
            self.dl1.calibrate(event)

            image = event.dl1.tel[0].image[0]
            cleaned = event.dl1.tel[0].cleaned[0]

            # Cleaning
            tc = tailcuts_clean(geom, image, 7, 3)
            empty = np.zeros(cleaned.shape, dtype=bool)
            cleaned_tc_mask = np.ma.mask_or(empty, ~tc[:, None])
            cleaned_dl1 = np.ma.masked_array(cleaned, mask=cleaned_tc_mask)

            # Find start and end of movie for event
            sum_wf = np.sum(cleaned_dl1, axis=0)
            sum_wf_t = np.arange(sum_wf.size)
            max_ = np.max(sum_wf)
            tmax = np.argmax(sum_wf)
            before = sum_wf[:tmax + 1][::-1]
            before_t = sum_wf_t[:tmax + 1][::-1]
            after = sum_wf[tmax:]
            after_t = sum_wf_t[tmax:]
            limit = 0.1 * max_
            # if limit < 2:
            #     limit = 2
            try:
                start = before_t[before <= limit][0] - 2
                end = after_t[after <= limit][0] + 5
            except IndexError:
                self.log.warning("No image for event id {}".format(event_id))
                continue
            if start < 0:
                start = 0
            if end >= n_samples:
                end = n_samples - 1

            s = []
            for t in range(start, end):
                s.append(cleaned[:, t])
                n_frames += 1
            df_list.append(dict(event_id=event_id, images=np.array(s), tc=tc))

        df = pd.DataFrame(df_list)

        output_dir = self.reader.output_directory
        title = self.reader.filename
        title = title[:title.find("_")]
        # Prepare Output
        if not exists(output_dir):
            self.log.info("Creating directory: {}".format(output_dir))
            makedirs(output_dir)
        output_path = join(output_dir, title + "_animation.mp4")

        self.animator.plot(df, n_frames, geom, output_path, title)
def extract_images(simtel_file_path,
                   tel_id_filter_list=None,
                   event_id_filter_list=None,
                   output_directory=None,
                   crop=True):

    # EXTRACT IMAGES ##########################################################

    # hessio_event_source returns a Python generator that streams data from an
    # EventIO/HESSIO MC data file (e.g. a standard CTA data file).
    # This generator contains ctapipe.core.Container instances ("event").
    # 
    # Parameters:
    # - max_events: maximum number of events to read
    # - allowed_tels: select only a subset of telescope, if None, all are read.
    source = hessio_event_source(simtel_file_path, allowed_tels=tel_id_filter_list)

    # ITERATE OVER EVENTS #####################################################

    calib = CameraCalibrator(None, None)

    for event in source:

        calib.calibrate(event)  # calibrate the event

        event_id = int(event.dl0.event_id)

        if (event_id_filter_list is None) or (event_id in event_id_filter_list):

            #print("event", event_id)

            # ITERATE OVER IMAGES #############################################

            for tel_id in event.trig.tels_with_trigger:

                tel_id = int(tel_id)

                if tel_id in tel_id_filter_list:

                    #print("telescope", tel_id)

                    # CHECK THE IMAGE GEOMETRY (ASTRI ONLY) ###################

                    # TODO

                    #print("checking geometry")

                    x, y = event.inst.pixel_pos[tel_id]
                    foclen = event.inst.optical_foclen[tel_id]
                    geom = CameraGeometry.guess(x, y, foclen)

                    if (geom.pix_type != "rectangular") or (geom.cam_id not in ("ASTRICam", "ASTRI")):
                        raise ValueError("Telescope {}: error (the input image is not a valide ASTRI telescope image) -> {} ({})".format(tel_id, geom.pix_type, geom.cam_id))

                    # GET IMAGES ##############################################

                    pe_image = event.mc.tel[tel_id].photo_electron_image   # 1D np array

                    #uncalibrated_image = event.dl0.tel[tel_id].adc_sums  # ctapipe 0.3.0
                    uncalibrated_image = event.r0.tel[tel_id].adc_sums    # ctapipe 0.4.0
                    pedestal = event.mc.tel[tel_id].pedestal
                    gain = event.mc.tel[tel_id].dc_to_pe
                    pixel_pos = event.inst.pixel_pos[tel_id]

                    calibrated_image = event.dl1.tel[tel_id].image

                    calibrated_image[1, calibrated_image[0,:] <= ASTRI_CAM_CHANNEL_THRESHOLD] = 0
                    calibrated_image[0, calibrated_image[0,:] >  ASTRI_CAM_CHANNEL_THRESHOLD] = 0
                    calibrated_image = calibrated_image.sum(axis=0)

                    #print(pe_image.shape)
                    #print(calibrated_image.shape)
                    #print(uncalibrated_image.shape)
                    #print(pedestal.shape)
                    #print(gain.shape)
                    #print(pixel_pos.shape)
                    #print(pixel_pos[0])
                    #print(pixel_pos[1])

                    # CONVERTING GEOMETRY (1D TO 2D) ##########################

                    pe_image_2d = geometry_converter.astri_to_2d_array(pe_image, crop=crop)
                    calibrated_image_2d = geometry_converter.astri_to_2d_array(calibrated_image, crop=crop)
                    uncalibrated_image_2d = geometry_converter.astri_to_3d_array(uncalibrated_image, crop=crop)
                    pedestal_2d = geometry_converter.astri_to_3d_array(pedestal, crop=crop)
                    gains_2d = geometry_converter.astri_to_3d_array(gain, crop=crop)
                    pixel_pos_2d = geometry_converter.astri_to_3d_array(pixel_pos, crop=crop)

                    #print(pe_image_2d.shape)
                    #print(calibrated_image_2d.shape)
                    #print(uncalibrated_image_2d.shape)
                    #print(pedestal_2d.shape)
                    #print(gains_2d.shape)
                    #print(pixel_pos_2d.shape)
                    #sys.exit(0)

                    # GET PIXEL MASK ##########################################

                    pixel_mask = geometry_converter.astri_pixel_mask(crop)  # 1 for pixels with actual data, 0 for virtual (blank) pixels

                    # MAKE METADATA ###########################################

                    metadata = {}

                    metadata['version'] = 1    # Version of the datapipe fits format

                    if crop:
                        metadata['cam_id'] = "ASTRI_CROPPED"
                    else:
                        metadata['cam_id'] = "ASTRI"

                    metadata['tel_id'] = tel_id
                    metadata['event_id'] = event_id
                    metadata['simtel'] = simtel_file_path

                    metadata['tel_trig'] = len(event.trig.tels_with_trigger)

                    metadata['energy'] =  quantity_to_tuple(event.mc.energy, 'TeV')
                    metadata['mc_az'] = quantity_to_tuple(event.mc.az, 'rad')
                    metadata['mc_alt'] = quantity_to_tuple(event.mc.alt, 'rad')
                    metadata['mc_corex'] = quantity_to_tuple(event.mc.core_x, 'm')
                    metadata['mc_corey'] = quantity_to_tuple(event.mc.core_y, 'm')
                    metadata['mc_hfi'] = quantity_to_tuple(event.mc.h_first_int, 'm')

                    metadata['count'] = int(event.count)
                    
                    metadata['run_id'] = int(event.dl0.run_id)
                    metadata['tel_data'] = len(event.dl0.tels_with_data)

                    metadata['foclen'] = quantity_to_tuple(event.inst.optical_foclen[tel_id], 'm')
                    metadata['tel_posx'] = quantity_to_tuple(event.inst.tel_pos[tel_id][0], 'm')
                    metadata['tel_posy'] = quantity_to_tuple(event.inst.tel_pos[tel_id][1], 'm')
                    metadata['tel_posz'] = quantity_to_tuple(event.inst.tel_pos[tel_id][2], 'm')

                    # TODO: Astropy fails to store the following data in FITS files
                    #metadata['uid'] = os.getuid()
                    #metadata['datetime'] = str(datetime.datetime.now())
                    #metadata['version'] = VERSION
                    #metadata['argv'] = " ".join(sys.argv).encode('ascii', errors='ignore').decode('ascii')
                    #metadata['python'] = " ".join(sys.version.splitlines()).encode('ascii', errors='ignore').decode('ascii')
                    #metadata['system'] = " ".join(os.uname())

                    # SAVE THE IMAGE ##########################################

                    output_file_path_template = "{}_TEL{:03d}_EV{:05d}.fits"

                    if output_directory is not None:
                        simtel_basename = os.path.basename(simtel_file_path)
                        prefix = os.path.join(output_directory, simtel_basename)
                    else:
                        prefix = simtel_file_path

                    output_file_path = output_file_path_template.format(prefix,
                                                                        tel_id,
                                                                        event_id)

                    print("saving", output_file_path)

                    images.save_benchmark_images(img = calibrated_image_2d,
                                                 pe_img = pe_image_2d,
                                                 adc_sums_img = uncalibrated_image_2d,
                                                 pedestal_img = pedestal_2d,
                                                 gains_img = gains_2d,
                                                 pixel_pos = pixel_pos_2d,
                                                 pixel_mask = pixel_mask,
                                                 metadata = metadata,
                                                 output_file_path = output_file_path)
示例#36
0
    def plot(self, input_file, event, telid, chan, extractor_name):
        # Extract required images
        dl0 = event.dl0.tel[telid].pe_samples[chan]

        t_pe = event.mc.tel[telid].photo_electron_image
        dl1 = event.dl1.tel[telid].image[chan]
        max_time = np.unravel_index(np.argmax(dl0), dl0.shape)[1]
        max_charges = np.max(dl0, axis=1)
        max_pix = int(np.argmax(max_charges))
        min_pix = int(np.argmin(max_charges))

        geom = CameraGeometry.guess(*event.inst.pixel_pos[telid],
                                    event.inst.optical_foclen[telid])

        nei = geom.neighbors

        # Get Neighbours
        max_pixel_nei = nei[max_pix]
        min_pixel_nei = nei[min_pix]

        # Get Windows
        windows = event.dl1.tel[telid].extracted_samples[chan]
        length = np.sum(windows, axis=1)
        start = np.argmax(windows, axis=1)
        end = start + length - 1

        # Draw figures
        ax_max_nei = {}
        ax_min_nei = {}
        fig_waveforms = plt.figure(figsize=(18, 9))
        fig_waveforms.subplots_adjust(hspace=.5)
        fig_camera = plt.figure(figsize=(15, 12))

        ax_max_pix = fig_waveforms.add_subplot(4, 2, 1)
        ax_min_pix = fig_waveforms.add_subplot(4, 2, 2)
        ax_max_nei[0] = fig_waveforms.add_subplot(4, 2, 3)
        ax_min_nei[0] = fig_waveforms.add_subplot(4, 2, 4)
        ax_max_nei[1] = fig_waveforms.add_subplot(4, 2, 5)
        ax_min_nei[1] = fig_waveforms.add_subplot(4, 2, 6)
        ax_max_nei[2] = fig_waveforms.add_subplot(4, 2, 7)
        ax_min_nei[2] = fig_waveforms.add_subplot(4, 2, 8)

        ax_img_nei = fig_camera.add_subplot(2, 2, 1)
        ax_img_max = fig_camera.add_subplot(2, 2, 2)
        ax_img_true = fig_camera.add_subplot(2, 2, 3)
        ax_img_cal = fig_camera.add_subplot(2, 2, 4)

        # Draw max pixel traces
        ax_max_pix.plot(dl0[max_pix])
        ax_max_pix.set_xlabel("Time (ns)")
        ax_max_pix.set_ylabel("DL0 Samples (ADC)")
        ax_max_pix.set_title("(Max) Pixel: {}, True: {}, Measured = {:.3f}"
                             .format(max_pix, t_pe[max_pix], dl1[max_pix]))
        max_ylim = ax_max_pix.get_ylim()
        ax_max_pix.plot([start[max_pix], start[max_pix]],
                        ax_max_pix.get_ylim(), color='r', alpha=1)
        ax_max_pix.plot([end[max_pix], end[max_pix]],
                        ax_max_pix.get_ylim(), color='r', alpha=1)
        for i, ax in ax_max_nei.items():
            if len(max_pixel_nei) > i:
                pix = max_pixel_nei[i]
                ax.plot(dl0[pix])
                ax.set_xlabel("Time (ns)")
                ax.set_ylabel("DL0 Samples (ADC)")
                ax.set_title("(Max Nei) Pixel: {}, True: {}, Measured = {:.3f}"
                             .format(pix, t_pe[pix], dl1[pix]))
                ax.set_ylim(max_ylim)
                ax.plot([start[pix], start[pix]],
                        ax.get_ylim(), color='r', alpha=1)
                ax.plot([end[pix], end[pix]],
                        ax.get_ylim(), color='r', alpha=1)

        # Draw min pixel traces
        ax_min_pix.plot(dl0[min_pix])
        ax_min_pix.set_xlabel("Time (ns)")
        ax_min_pix.set_ylabel("DL0 Samples (ADC)")
        ax_min_pix.set_title("(Min) Pixel: {}, True: {}, Measured = {:.3f}"
                             .format(min_pix, t_pe[min_pix], dl1[min_pix]))
        ax_min_pix.set_ylim(max_ylim)
        ax_min_pix.plot([start[min_pix], start[min_pix]],
                        ax_min_pix.get_ylim(), color='r', alpha=1)
        ax_min_pix.plot([end[min_pix], end[min_pix]],
                        ax_min_pix.get_ylim(), color='r', alpha=1)
        for i, ax in ax_min_nei.items():
            if len(min_pixel_nei) > i:
                pix = min_pixel_nei[i]
                ax.plot(dl0[pix])
                ax.set_xlabel("Time (ns)")
                ax.set_ylabel("DL0 Samples (ADC)")
                ax.set_title("(Min Nei) Pixel: {}, True: {}, Measured = {:.3f}"
                             .format(pix, t_pe[pix], dl1[pix]))
                ax.set_ylim(max_ylim)
                ax.plot([start[pix], start[pix]],
                        ax.get_ylim(), color='r', alpha=1)
                ax.plot([end[pix], end[pix]],
                        ax.get_ylim(), color='r', alpha=1)

        # Draw cameras
        nei_camera = np.zeros_like(max_charges, dtype=np.int)
        nei_camera[min_pixel_nei] = 2
        nei_camera[min_pix] = 1
        nei_camera[max_pixel_nei] = 3
        nei_camera[max_pix] = 4
        camera = CameraDisplay(geom, ax=ax_img_nei)
        camera.image = nei_camera
        camera.cmap = plt.cm.viridis
        ax_img_nei.set_title("Neighbour Map")
        ax_img_nei.annotate("Pixel: {}".format(max_pix),
                            xy=(geom.pix_x.value[max_pix],
                                geom.pix_y.value[max_pix]),
                            xycoords='data', xytext=(0.05, 0.98),
                            textcoords='axes fraction',
                            arrowprops=dict(facecolor='red', width=2,
                                            alpha=0.4),
                            horizontalalignment='left',
                            verticalalignment='top')
        ax_img_nei.annotate("Pixel: {}".format(min_pix),
                            xy=(geom.pix_x.value[min_pix],
                                geom.pix_y.value[min_pix]),
                            xycoords='data', xytext=(0.05, 0.94),
                            textcoords='axes fraction',
                            arrowprops=dict(facecolor='orange', width=2,
                                            alpha=0.4),
                            horizontalalignment='left',
                            verticalalignment='top')
        camera = CameraDisplay(geom, ax=ax_img_max)
        camera.image = dl0[:, max_time]
        camera.cmap = plt.cm.viridis
        camera.add_colorbar(ax=ax_img_max, label="DL0 Samples (ADC)")
        ax_img_max.set_title("Max Timeslice (T = {})".format(max_time))
        ax_img_max.annotate("Pixel: {}".format(max_pix),
                            xy=(geom.pix_x.value[max_pix],
                                geom.pix_y.value[max_pix]),
                            xycoords='data', xytext=(0.05, 0.98),
                            textcoords='axes fraction',
                            arrowprops=dict(facecolor='red', width=2,
                                            alpha=0.4),
                            horizontalalignment='left',
                            verticalalignment='top')
        ax_img_max.annotate("Pixel: {}".format(min_pix),
                            xy=(geom.pix_x.value[min_pix],
                                geom.pix_y.value[min_pix]),
                            xycoords='data', xytext=(0.05, 0.94),
                            textcoords='axes fraction',
                            arrowprops=dict(facecolor='orange', width=2,
                                            alpha=0.4),
                            horizontalalignment='left',
                            verticalalignment='top')

        camera = CameraDisplay(geom, ax=ax_img_true)
        camera.image = t_pe
        camera.cmap = plt.cm.viridis
        camera.add_colorbar(ax=ax_img_true, label="True Charge (p.e.)")
        ax_img_true.set_title("True Charge")
        ax_img_true.annotate("Pixel: {}".format(max_pix),
                             xy=(geom.pix_x.value[max_pix],
                                 geom.pix_y.value[max_pix]),
                             xycoords='data', xytext=(0.05, 0.98),
                             textcoords='axes fraction',
                             arrowprops=dict(facecolor='red', width=2,
                                             alpha=0.4),
                             horizontalalignment='left',
                             verticalalignment='top')
        ax_img_true.annotate("Pixel: {}".format(min_pix),
                             xy=(geom.pix_x.value[min_pix],
                                 geom.pix_y.value[min_pix]),
                             xycoords='data', xytext=(0.05, 0.94),
                             textcoords='axes fraction',
                             arrowprops=dict(facecolor='orange', width=2,
                                             alpha=0.4),
                             horizontalalignment='left',
                             verticalalignment='top')

        camera = CameraDisplay(geom, ax=ax_img_cal)
        camera.image = dl1
        camera.cmap = plt.cm.viridis
        camera.add_colorbar(ax=ax_img_cal,
                            label="Calib Charge (Photo-electrons)")
        ax_img_cal.set_title("Charge (integrator={})".format(extractor_name))
        ax_img_cal.annotate("Pixel: {}".format(max_pix),
                            xy=(geom.pix_x.value[max_pix],
                                geom.pix_y.value[max_pix]),
                            xycoords='data', xytext=(0.05, 0.98),
                            textcoords='axes fraction',
                            arrowprops=dict(facecolor='red', width=2,
                                            alpha=0.4),
                            horizontalalignment='left',
                            verticalalignment='top')
        ax_img_cal.annotate("Pixel: {}".format(min_pix),
                            xy=(geom.pix_x.value[min_pix],
                                geom.pix_y.value[min_pix]),
                            xycoords='data', xytext=(0.05, 0.94),
                            textcoords='axes fraction',
                            arrowprops=dict(facecolor='orange', width=2,
                                            alpha=0.4),
                            horizontalalignment='left',
                            verticalalignment='top')

        fig_waveforms.suptitle("Integrator = {}".format(extractor_name))
        fig_camera.suptitle("Camera = {}".format(geom.cam_id))

        waveform_output_name = "e{}_t{}_c{}_extractor{}_waveform.pdf"\
            .format(event.count, telid, chan, extractor_name)
        camera_output_name = "e{}_t{}_c{}_extractor{}_camera.pdf"\
            .format(event.count, telid, chan, extractor_name)

        output_dir = self.output_dir
        if output_dir is None:
            output_dir = input_file.output_directory
        output_dir = os.path.join(output_dir, self.name)
        if not os.path.exists(output_dir):
            self.log.info("Creating directory: {}".format(output_dir))
            os.makedirs(output_dir)

        waveform_output_path = os.path.join(output_dir, waveform_output_name)
        self.log.info("Saving: {}".format(waveform_output_path))
        fig_waveforms.savefig(waveform_output_path, format='pdf',
                              bbox_inches='tight')

        camera_output_path = os.path.join(output_dir, camera_output_name)
        self.log.info("Saving: {}".format(camera_output_path))
        fig_camera.savefig(camera_output_path, format='pdf',
                           bbox_inches='tight')
        return geom
示例#37
0
def analyze_muon_event(event, params=None, geom_dict=None):
    """
    Generic muon event analyzer. 

    Parameters
    ----------
    event : ctapipe dl1 event container


    Returns
    -------
    muonringparam, muonintensityparam : MuonRingParameter and MuonIntensityParameter container event

    """
    # Declare a dict to define the muon cuts (ASTRI and SCT missing)
    muon_cuts = {}

    names = ['LST:LSTCam','MST:NectarCam','MST:FlashCam','MST-SCT:SCTCam','SST-1M:DigiCam','SST-GCT:CHEC','SST-ASTRI:ASTRICam']
    TailCuts = [(5,7),(5,7),(10,12),(5,7),(5,7),(5,7),(5,7)] #10,12?
    impact = [(0.2,0.9),(0.1,0.95),(0.2,0.9),(0.2,0.9),(0.1,0.95),(0.1,0.95),(0.1,0.95)]
    ringwidth = [(0.04,0.08),(0.02,0.1),(0.01,0.1),(0.02,0.1),(0.01,0.5),(0.02,0.2),(0.02,0.2)]
    TotalPix = [1855.,1855.,1764.,11328.,1296.,2048.,2368.]#8% (or 6%) as limit
    MinPix = [148.,148.,141.,680.,104.,164.,142.]
    #Need to either convert from the pixel area in m^2 or check the camera specs
    AngPixelWidth = [0.1,0.2,0.18,0.067,0.24,0.2,0.17] #Found from TDRs (or the pixel area)
    hole_rad = []#Need to check and implement
    cam_rad = [2.26,3.96,3.87,4.,4.45,2.86,5.25]#Found from the field of view calculation
    sec_rad = [0.*u.m,0.*u.m,0.*u.m,2.7*u.m,0.*u.m,1.*u.m,1.8*u.m]
    sct = [False,False,False,True,False,True,True]


    muon_cuts = {'Name':names,'TailCuts':TailCuts,'Impact':impact,'RingWidth':ringwidth,'TotalPix':TotalPix,'MinPix':MinPix,'CamRad':cam_rad,'SecRad':sec_rad,'SCT':sct,'AngPixW':AngPixelWidth}
    #print(muon_cuts)

    muonringlist = []#[None] * len(event.dl0.tels_with_data)
    muonintensitylist = []#[None] * len(event.dl0.tels_with_data)
    tellist = []
    #for tid in event.dl0.tels_with_data:
    #    tellist.append(tid)
    muon_event_param = {'TelIds':tellist,'MuonRingParams':muonringlist,'MuonIntensityParams':muonintensitylist}
    #muonringparam = None
    #muonintensityparam = None

    for telid in event.dl0.tels_with_data:

        #print("Analysing muon event for tel",telid)
        muonringparam = None
        muonintensityparam = None
        #idx = muon_event_param['TelIds'].index(telid)

        x, y = event.inst.pixel_pos[telid]

        #image = event.dl1.tel[telid].calibrated_image
        image = event.dl1.tel[telid].image[0]

        # Get geometry
        geom = None
        if geom_dict is not None and telid in geom_dict:
            geom = geom_dict[telid]
        else:
            log.debug("[calib] Guessing camera geometry")
            geom = CameraGeometry.guess(*event.inst.pixel_pos[telid],
                                        event.inst.optical_foclen[telid])
            log.debug("[calib] Camera geometry found")
            if geom_dict is not None:
                geom_dict[telid] = geom


        teldes = event.inst.subarray.tel[telid]
        dict_index = muon_cuts['Name'].index(str(teldes))
        #print('found an index of',dict_index,'for camera',geom.cam_id)

        #tailcuts = (5.,7.)
        tailcuts = muon_cuts['TailCuts'][dict_index]

        #print("Tailcuts are",tailcuts[0],tailcuts[1])

        #rot_angle = 0.*u.deg
        #if event.inst.optical_foclen[telid] > 10.*u.m and event.dl0.tel[telid].num_pixels != 1764:
            #rot_angle = -100.14*u.deg

        clean_mask = tailcuts_clean(geom,image,picture_thresh=tailcuts[0],boundary_thresh=tailcuts[1])
        camera_coord = CameraFrame(x=x,y=y,z=np.zeros(x.shape)*u.m, focal_length = event.inst.optical_foclen[telid], rotation=geom.pix_rotation)

        #print("Camera",geom.cam_id,"focal length",event.inst.optical_foclen[telid],"rotation",geom.pix_rotation)
        #TODO: correct this hack for values over 90
        altval = event.mcheader.run_array_direction[1]
        if (altval > np.pi/2.):
            altval = np.pi/2.

        altaz = HorizonFrame(alt=altval*u.rad,az=event.mcheader.run_array_direction[0]*u.rad)
        nom_coord = camera_coord.transform_to(NominalFrame(array_direction=altaz,pointing_direction=altaz))

        
        x = nom_coord.x.to(u.deg)
        y = nom_coord.y.to(u.deg)

        img = image*clean_mask
        noise = 5.
        weight = img / (img+noise)

        muonring = ChaudhuriKunduRingFitter(None)

        #print("img:",np.sum(image),"mask:",np.sum(clean_mask), "x=",x,"y=",y)
        if not sum(img):#Nothing left after tail cuts
            continue
        muonringparam = muonring.fit(x,y,image*clean_mask)
        #muonringparam = muonring.fit(x,y,weight)
        dist = np.sqrt(np.power(x-muonringparam.ring_center_x,2) + np.power(y-muonringparam.ring_center_y,2))
        ring_dist = np.abs(dist-muonringparam.ring_radius)
        muonringparam = muonring.fit(x,y,img*(ring_dist<muonringparam.ring_radius*0.4))

        dist = np.sqrt(np.power(x-muonringparam.ring_center_x,2) + np.power(y-muonringparam.ring_center_y,2))
        ring_dist = np.abs(dist-muonringparam.ring_radius)

        #print("1: x",muonringparam.ring_center_x,"y",muonringparam.ring_center_y,"radius",muonringparam.ring_radius)
        muonringparam = muonring.fit(x,y,img*(ring_dist<muonringparam.ring_radius*0.4))
        #print("2: x",muonringparam.ring_center_x,"y",muonringparam.ring_center_y,"radius",muonringparam.ring_radius)
        muonringparam.tel_id = telid
        muonringparam.run_id = event.dl0.run_id
        muonringparam.event_id = event.dl0.event_id
        dist_mask = np.abs(dist-muonringparam.ring_radius)<muonringparam.ring_radius*0.4

        rad = list()
        cx = list()
        cy = list()
        
        mc_x = event.mc.core_x
        mc_y = event.mc.core_y
        pix_im = image*dist_mask
        nom_dist = np.sqrt(np.power(muonringparam.ring_center_x,2)+np.power(muonringparam.ring_center_y,2))
        #numpix = event.dl0.tel[telid].num_pixels

        minpix = muon_cuts['MinPix'][dict_index]#0.06*numpix #or 8%

        mir_rad = np.sqrt(event.inst.mirror_dish_area[telid]/(np.pi))#need to consider units? (what about hole? Area is then less...)


        #Camera containment radius -  better than nothing - guess pixel diameter of 0.11, all cameras are perfectly circular   cam_rad = np.sqrt(numpix*0.11/(2.*np.pi))

        if(np.sum(pix_im>tailcuts[0])>0.1*minpix and np.sum(pix_im)>minpix and nom_dist < muon_cuts['CamRad'][dict_index]*u.deg and muonringparam.ring_radius<1.5*u.deg and muonringparam.ring_radius>1.*u.deg):

            #Guess HESS is 0.16 
            #sec_rad = 0.*u.m
            #sct = False
            #if numpix == 2048 and mir_rad > 2.*u.m and mir_rad < 2.1*u.m:
            #    sec_rad = 1.*u.m
            #    sct = True

            #Store muon ring parameters (passing cuts stage 1)
            #muonringlist[idx] = muonringparam
            tellist.append(telid)
            muonringlist.append(muonringparam)
            muonintensitylist.append(None)
            #embed()

            ctel = MuonLineIntegrate(mir_rad,0.2*u.m,pixel_width=muon_cuts['AngPixW'][dict_index]*u.deg,sct_flag=muon_cuts['SCT'][dict_index], secondary_radius=muon_cuts['SecRad'][dict_index])
          
            if (image.shape[0] == muon_cuts['TotalPix'][dict_index]):
                muonintensityoutput = ctel.fit_muon(muonringparam.ring_center_x,muonringparam.ring_center_y,muonringparam.ring_radius,x[dist_mask],y[dist_mask],image[dist_mask])

                muonintensityoutput.tel_id = telid
                muonintensityoutput.run_id = event.dl0.run_id
                muonintensityoutput.event_id = event.dl0.event_id
                muonintensityoutput.mask = dist_mask

                print("Tel",telid,"Impact parameter = ",muonintensityoutput.impact_parameter,"mir_rad",mir_rad,"ring_width=",muonintensityoutput.ring_width)

                #if(muonintensityoutput.impact_parameter > muon_cuts['Impact'][dict_index][1]*mir_rad or muonintensityoutput.impact_parameter < muon_cuts['Impact'][dict_index][0]*mir_rad):
                #    print("Failed on impact parameter low cut",muon_cuts['Impact'][dict_index][0]*mir_rad,"high cut",muon_cuts['Impact'][dict_index][1]*mir_rad,"for",geom.cam_id)
                #if(muonintensityoutput.ring_width > muon_cuts['RingWidth'][dict_index][1]*u.deg or muonintensityoutput.ring_width < muon_cuts['RingWidth'][dict_index][0]*u.deg):
                #    print("Failed on ring width low cut",muon_cuts['RingWidth'][dict_index][0]*u.deg,"high cut",muon_cuts['RingWidth'][dict_index][1]*u.deg,"for ",geom.cam_id)

                #print("Cuts <",muon_cuts["Impact"][dict_index][1]*mir_rad,"cuts >",muon_cuts['Impact'][dict_index][0]*u.m,'ring_width < ',muon_cuts['RingWidth'][dict_index][1]*u.deg,'ring_width >',muon_cuts['RingWidth'][dict_index][0]*u.deg)
                if( muonintensityoutput.impact_parameter < muon_cuts['Impact'][dict_index][1]*mir_rad and muonintensityoutput.impact_parameter > muon_cuts['Impact'][dict_index][0]*u.m and muonintensityoutput.ring_width < muon_cuts['RingWidth'][dict_index][1]*u.deg and muonintensityoutput.ring_width > muon_cuts['RingWidth'][dict_index][0]*u.deg ):
                    muonintensityparam = muonintensityoutput
                    idx = tellist.index(telid)
                    muonintensitylist[idx] = muonintensityparam
                    print("Muon in tel",telid,"# tels in event=",len(event.dl0.tels_with_data))
                else:
                    continue

        #print("Fitted ring centre (2):",muonringparam.ring_center_x,muonringparam.ring_center_y)

    #return muonringparam, muonintensityparam
    return muon_event_param
示例#38
0
 def get_geometry(self, event, telid):
     if telid not in self._geom_dict:
         geom = CameraGeometry.guess(*event.inst.pixel_pos[telid],
                                     event.inst.optical_foclen[telid])
         self._geom_dict[telid] = geom
     return self._geom_dict[telid]
示例#39
0
    def setup(self):
        self.log_format = "%(levelname)s: %(message)s [%(name)s.%(funcName)s]"

        data_config = self.config.copy()
        data_config['WaveformCleanerFactory'] = Config(cleaner='CHECMWaveformCleanerLocal')
        mc_config = self.config.copy()

        data_kwargs = dict(config=data_config, tool=self)
        mc_kwargs = dict(config=mc_config, tool=self)

        filepath = '/Volumes/gct-jason/data/170330/onsky-mrk501/Run05477_r1.tio'
        reader = TargetioFileReader(input_path=filepath, **data_kwargs)
        filepath = '/Users/Jason/Software/outputs/sim_telarray/meudon_cr/simtel_proton_nsb50_thrs30_1petal_rndm015_heide.gz'
        # filepath = '/Users/Jason/Software/outputs/sim_telarray/meudon_cr/simtel_proton_nsb50_thrs30.gz'
        reader_mc = HessioFileReader(input_path=filepath, **mc_kwargs)

        calibrator = CameraCalibrator(origin=reader.origin,
                                      **data_kwargs)
        calibrator_mc = CameraCalibrator(origin=reader_mc.origin,
                                         **mc_kwargs)

        first_event = reader.get_event(0)
        telid = list(first_event.r0.tels_with_data)[0]
        pos = first_event.inst.pixel_pos[telid]
        foclen = first_event.inst.optical_foclen[telid]
        geom = CameraGeometry.guess(*pos, foclen)

        first_event = reader_mc.get_event(0)
        telid = list(first_event.r0.tels_with_data)[0]
        pos_mc = first_event.inst.pixel_pos[telid]
        foclen = first_event.inst.optical_foclen[telid]
        geom_mc = CameraGeometry.guess(*pos_mc, foclen)

        d1 = dict(type='Data', reader=reader, calibrator=calibrator,
                  pos=pos, geom=geom, t1=20, t2=10)
        d2 = dict(type='MC', reader=reader_mc, calibrator=calibrator_mc,
                  pos=pos_mc, geom=geom_mc, t1=20, t2=10)
        self.reader_df = pd.DataFrame([d1, d2])

        p_kwargs = data_kwargs
        p_kwargs['script'] = "checm_paper_hillas"
        p_kwargs['figure_name'] = "all_images"
        self.p_allimage = AllImagePlotter(**p_kwargs)
        p_kwargs['figure_name'] = "all_peak_time_images"
        self.p_alltimeimage = PeakTimePlotter(**p_kwargs)
        p_kwargs['figure_name'] = "all_mc_images"
        self.p_allmcimage = AllImagePlotter(**p_kwargs)
        p_kwargs['figure_name'] = "zero_width_images"
        self.p_zwimage = ZeroWidthImagePlotter(**p_kwargs)
        p_kwargs['figure_name'] = "zero_width_mc_images"
        self.p_zwmcimage = ZeroWidthImagePlotter(**p_kwargs)
        p_kwargs['figure_name'] = "muon_images"
        self.p_muonimage = MuonImagePlotter(**p_kwargs)
        p_kwargs['figure_name'] = "bright_images"
        self.p_brightimage = BrightImagePlotter(**p_kwargs)
        p_kwargs['figure_name'] = "count_image"
        self.p_countimage = CountPlotter(**p_kwargs)
        p_kwargs['figure_name'] = "whole_distribution"
        self.p_whole_dist = WholeDist(**p_kwargs, shape='wide')
        p_kwargs['figure_name'] = "width_vs_length"
        self.p_widthvslength = WidthVsLength(**p_kwargs, shape='wide')
        p_kwargs['figure_name'] = "size_vs_length"
        self.p_sizevslength = SizeVsLength(**p_kwargs, shape='wide')
        p_kwargs['figure_name'] = "width_div_length"
        self.p_widthdivlength = WidthDivLength(**p_kwargs, shape='wide')
        p_kwargs['figure_name'] = "length_div_size"
        self.p_lengthdivsize = LengthDivSize(**p_kwargs, shape='wide')
        p_kwargs['figure_name'] = "pair_plot"
        self.p_pair = PairPlotter(**p_kwargs, shape='wide')
        p_kwargs['figure_name'] = "pair_mc_plot"
        self.p_mc_pair = PairPlotter(**p_kwargs, shape='wide')
        p_kwargs['figure_name'] = "length"
        self.p_length = LengthPlotter(**p_kwargs, shape='wide')
        p_kwargs['figure_name'] = "width"
        self.p_width = WidthPlotter(**p_kwargs, shape='wide')
示例#40
0
def plot_muon_event(event, muonparams, geom_dict=None, args=None):

    if muonparams[0] is not None:

        # Plot the muon event and overlay muon parameters
        fig = plt.figure(figsize=(16, 7))
        # if args.display:
        #    plt.show(block=False)
        #pp = PdfPages(args.output_path) if args.output_path is not None else None
        # pp = None #For now, need to correct this

        colorbar = None
        colorbar2 = None

        for tel_id in event.dl0.tels_with_data:
            npads = 2
            # Only create two pads if there is timing information extracted
            # from the calibration
            ax1 = fig.add_subplot(1, npads, 1)
            plotter = CameraPlotter(event, geom_dict)
            #image = event.dl1.tel[tel_id].calibrated_image
            image = event.dl1.tel[tel_id].image[0]
            # Get geometry
            geom = None
            if geom_dict is not None and tel_id in geom_dict:
                geom = geom_dict[tel_id]
            else:
                #log.debug("[calib] Guessing camera geometry")
                geom = CameraGeometry.guess(*event.inst.pixel_pos[tel_id],
                                            event.inst.optical_foclen[tel_id])
                #log.debug("[calib] Camera geometry found")
                if geom_dict is not None:
                    geom_dict[tel_id] = geom

            tailcuts = (5., 7.)
            # Try a higher threshold for
            if geom.cam_id == 'FlashCam':
                tailcuts = (10., 12.)

            #print("Using Tail Cuts:",tailcuts)
            clean_mask = tailcuts_clean(geom, image,
                                        picture_thresh=tailcuts[0],
                                        boundary_thresh=tailcuts[1])

            signals = image * clean_mask

            #print("Ring Centre in Nominal Coords:",muonparams[0].ring_center_x,muonparams[0].ring_center_y)
            muon_incl = np.sqrt(muonparams[0].ring_center_x**2. +
                                muonparams[0].ring_center_y**2.)

            muon_phi = np.arctan(muonparams[0].ring_center_y /
                                 muonparams[0].ring_center_x)

            rotr_angle = geom.pix_rotation
            # if event.inst.optical_foclen[tel_id] > 10.*u.m and
            # event.dl0.tel[tel_id].num_pixels != 1764:
            if geom.cam_id == 'LSTCam' or geom.cam_id == 'NectarCam':
                #print("Resetting the rotation angle")
                rotr_angle = 0. * u.deg

            # Convert to camera frame (centre & radius)
            altaz = HorizonFrame(alt=event.mc.alt, az=event.mc.az)

            ring_nominal = NominalFrame(x=muonparams[0].ring_center_x,
                                        y=muonparams[0].ring_center_y,
                                        array_direction=altaz,
                                        pointing_direction=altaz)

            # embed()
            ring_camcoord = ring_nominal.transform_to(CameraFrame(
                pointing_direction=altaz,
                focal_length=event.inst.optical_foclen[tel_id],
                rotation=rotr_angle))

            centroid_rad = np.sqrt(ring_camcoord.y**2 + ring_camcoord.x**2)
            centroid = (ring_camcoord.x.value, ring_camcoord.y.value)

            ringrad_camcoord = muonparams[0].ring_radius.to(u.rad) \
                               * event.inst.optical_foclen[tel_id] * 2.  # But not FC?

            #rot_angle = 0.*u.deg
            # if event.inst.optical_foclen[tel_id] > 10.*u.m and event.dl0.tel[tel_id].num_pixels != 1764:
            #rot_angle = -100.14*u.deg

            px, py = event.inst.pixel_pos[tel_id]
            flen = event.inst.optical_foclen[tel_id]
            camera_coord = CameraFrame(x=px, y=py,
                                       z=np.zeros(px.shape) * u.m,
                                       focal_length=flen,
                                       rotation=geom.pix_rotation)

            nom_coord = camera_coord.transform_to(
                NominalFrame(array_direction=altaz,
                             pointing_direction=altaz)
            )
            #,focal_length = event.inst.optical_foclen[tel_id])) # tel['TelescopeTable_VersionFeb2016'][tel['TelescopeTable_VersionFeb2016']['TelID']==telid]['FL'][0]*u.m))

            px = nom_coord.x.to(u.deg)
            py = nom_coord.y.to(u.deg)

            dist = np.sqrt(np.power( px - muonparams[0].ring_center_x, 2)
                           + np.power(py - muonparams[0].ring_center_y, 2))
            ring_dist = np.abs(dist - muonparams[0].ring_radius)
            pixRmask = ring_dist < muonparams[0].ring_radius * 0.4

            if muonparams[1] is not None:
                signals *= muonparams[1].mask

            camera1 = plotter.draw_camera(tel_id, signals, ax1)

            cmaxmin = (max(signals) - min(signals))
            if not cmaxmin:
                cmaxmin = 1.
            cmap_charge = colors.LinearSegmentedColormap.from_list(
                'cmap_c', [(0 / cmaxmin, 'darkblue'),
                           (np.abs(min(signals)) / cmaxmin, 'black'),
                           (2.0 * np.abs(min(signals)) / cmaxmin, 'blue'),
                           (2.5 * np.abs(min(signals)) / cmaxmin, 'green'),
                           (1, 'yellow')]
            )
            camera1.pixels.set_cmap(cmap_charge)
            if not colorbar:
                camera1.add_colorbar(ax=ax1, label=" [photo-electrons]")
                colorbar = camera1.colorbar
            else:
                camera1.colorbar = colorbar
            camera1.update(True)

            camera1.add_ellipse(centroid, ringrad_camcoord.value,
                                ringrad_camcoord.value, 0., 0., color="red")

#            ax1.set_title("CT {} ({}) - Mean pixel charge"
#                          .format(tel_id, geom_dict[tel_id].cam_id))

            if muonparams[1] is not None:
                # continue #Comment this...(should ringwidthfrac also be *0.5?)
                ringwidthfrac = muonparams[
                    1].ring_width / muonparams[0].ring_radius
                ringrad_inner = ringrad_camcoord * (1. - ringwidthfrac)
                ringrad_outer = ringrad_camcoord * (1. + ringwidthfrac)
                camera1.add_ellipse(centroid, ringrad_inner.value,
                                     ringrad_inner.value, 0., 0.,
                                     color="magenta")
                camera1.add_ellipse(centroid, ringrad_outer.value,
                                    ringrad_outer.value, 0., 0., color="magenta")
                npads = 2
                ax2 = fig.add_subplot(1, npads, npads)
                pred = muonparams[1].prediction

                if len(pred) != np.sum(muonparams[1].mask):
                    print("Warning! Lengths do not match...len(pred)=",
                          len(pred), "len(mask)=", np.sum(muonparams[1].mask))

                # Numpy broadcasting - fill in the shape
                plotpred = np.zeros(image.shape)
                plotpred[muonparams[1].mask == True] = pred

                camera2 = plotter.draw_camera(tel_id, plotpred, ax2)

                c2maxmin = (max(plotpred) - min(plotpred))
                if not c2maxmin:
                    c2maxmin = 1.
                c2map_charge = colors.LinearSegmentedColormap.from_list(
                    'c2map_c', [(0 / c2maxmin, 'darkblue'),
                                (np.abs(min(plotpred)) / c2maxmin, 'black'),
                                (2.0 * np.abs(min(plotpred)) / c2maxmin, 'blue'),
                                (2.5 * np.abs(min(plotpred)) / c2maxmin, 'green'),
                                (1, 'yellow')]
                )
                camera2.pixels.set_cmap(c2map_charge)
                if not colorbar2:
                    camera2.add_colorbar(ax=ax2, label=" [photo-electrons]")
                    colorbar2 = camera2.colorbar
                else:
                    camera2.colorbar = colorbar2
                camera2.update(True)
                plt.pause(1.)  # make shorter

            # plt.pause(0.1)
            # if pp is not None:
            #    pp.savefig(fig)
            fig.savefig(str(args.output_path) + "_" +
                        str(event.dl0.event_id) + '.png')

            plt.close()
示例#41
0
def test_guess_camera():
    px = np.linspace(-10, 10, 11328) * u.m
    py = np.linspace(-10, 10, 11328) * u.m
    geom = CameraGeometry.guess(px, py, 0 * u.m)
    assert geom.pix_type.startswith('rect')
示例#42
0
    def start(self):

        # Get first event information
        first_event = self.reader.get_event(0)
        n_pixels = first_event.inst.num_pixels[0]
        n_samples = first_event.r0.tel[0].num_samples
        pos = first_event.inst.pixel_pos[0]
        foclen = first_event.inst.optical_foclen[0]
        geom = CameraGeometry.guess(*pos, foclen)

        # Setup Output
        output_dir = self.reader.output_directory
        title = self.reader.filename
        title = title[:title.find("_")]
        # Prepare Output
        if not exists(output_dir):
            self.log.info("Creating directory: {}".format(output_dir))
            makedirs(output_dir)
        output_path = join(output_dir, title + "_events.pdf")

        # Setup plot
        fig = plt.figure(figsize=(10, 10))
        ax_camera = fig.add_subplot(1, 1, 1)
        fig.patch.set_visible(False)
        ax_camera.axis('off')
        camera = CameraDisplay(geom,
                               ax=ax_camera,
                               image=np.zeros(2048),
                               cmap='viridis')
        camera.add_colorbar()
        cb = camera.colorbar
        camera.colorbar.set_label("Amplitude (p.e.)")
        fig.suptitle(title)

        source = self.reader.read()
        desc = "Looping through file"
        with PdfPages(output_path) as pdf:
            for event in tqdm(source, desc=desc):
                ev = event.count
                event_id = event.r0.event_id
                self.r1.calibrate(event)
                self.dl0.reduce(event)
                self.dl1.calibrate(event)
                for t in event.r0.tels_with_data:
                    dl1 = event.dl1.tel[t].image[0]

                    # Cleaning
                    tc = tailcuts_clean(geom, dl1, 20, 10)
                    if not tc.any():
                        continue
                    cleaned_dl1 = np.ma.masked_array(dl1, mask=~tc)

                    try:
                        # hillas = hillas_parameters(*pos, cleaned_tc)
                        hillas = hillas_parameters_4(*pos, cleaned_dl1)
                    except HillasParameterizationError:
                        continue

                    ax_camera.cla()
                    camera = CameraDisplay(geom,
                                           ax=ax_camera,
                                           image=np.zeros(2048),
                                           cmap='viridis')
                    camera.colorbar = cb
                    camera.image = dl1
                    max_ = cleaned_dl1.max()  # np.percentile(dl1, 99.9)
                    min_ = np.percentile(dl1, 0.1)
                    camera.set_limits_minmax(min_, max_)
                    camera.highlight_pixels(tc, 'white')
                    camera.overlay_moments(hillas, color='red')
                    camera.update(True)
                    ax_camera.set_title("Event: {}".format(event_id))
                    ax_camera.axis('off')

                    pdf.savefig(fig)

        self.log.info("Created images: {}".format(output_path))
示例#43
0
    def draw_event(self, event, hillas_parameters=None):
        """
        Draw display for a given event

        Parameters
        ----------
        event: ctapipe event object
        hillas_parameters: dict
            Dictionary of Hillas parameters (in nominal system)

        Returns
        -------
            None
        """
        tel_list = event.r0.tels_with_data
        images = event.dl1

        # First close any plots that already exist
        plt.close()
        ntels = len(tel_list)

        fig = plt.figure(figsize=(20, 20 * 0.66))

        # If we want to draw the Hillas parameters in different planes we need to split our figure
        if self.draw_hillas_planes:
            y_axis_split = 2
        else:
            y_axis_split = 1

        outer_grid = gridspec.GridSpec(1,
                                       y_axis_split,
                                       width_ratios=[y_axis_split, 1])
        # Create a square grid for camera images
        nn = int(ceil(sqrt(ntels)))
        nx = nn
        ny = nn

        while nx * ny >= ntels:
            ny -= 1
        ny += 1
        while nx * ny >= ntels:
            nx -= 1
        nx += 1

        camera_grid = gridspec.GridSpecFromSubplotSpec(
            ny, nx, subplot_spec=outer_grid[0])

        # Loop over camera images of all telescopes and create plots
        for ii, tel_id in zip(range(ntels), tel_list):

            # Cache of camera geometries, this may go away soon
            if tel_id not in self.geom:
                self.geom[tel_id] = CameraGeometry.guess(
                    event.inst.pixel_pos[tel_id][0],
                    event.inst.pixel_pos[tel_id][1],
                    event.inst.optical_foclen[tel_id])

            ax = plt.subplot(camera_grid[ii])
            self.get_camera_view(tel_id, images.tel[tel_id].image[0], ax)

        # If we want to draw the Hillas parameters in different planes we need to make a couple more viewers
        if self.draw_hillas_planes:
            # Split the second sub figure into two further figures
            reco_grid = gridspec.GridSpecFromSubplotSpec(
                2, 1, subplot_spec=outer_grid[1])
            # Create plot of telescope positions at ground level
            array = ArrayPlotter(
                telescopes=tel_list,
                instrument=event.inst,  # system=tilted_system,
                ax=plt.subplot(reco_grid[0]))
            # Draw MC position (this should change later)
            array.draw_position(event.mc.core_x,
                                event.mc.core_y,
                                use_centre=True)
            array.draw_array(((-300, 300), (-300, 300)))

            # If we have valid Hillas parameters we should draw them in the Nominal system
            if hillas_parameters is not None:
                array.overlay_hillas(hillas_parameters, draw_axes=True)

                nominal = NominalPlotter(hillas_parameters=hillas_parameters,
                                         draw_axes=True,
                                         ax=plt.subplot(reco_grid[1]))
                nominal.draw_array()

        plt.show()

        return
示例#44
0
def test_array_draw():

    filename = get_dataset("gamma_test.simtel.gz")
    cam_geom = {}

    source = hessio_event_source(filename, max_events=2)
    r1 = HessioR1Calibrator(None, None)
    dl0 = CameraDL0Reducer(None, None)

    calibrator = CameraDL1Calibrator(None, None)

    for event in source:
        array_pointing = SkyCoord(
            event.mcheader.run_array_direction[1] * u.rad,
            event.mcheader.run_array_direction[0] * u.rad,
            frame=AltAz)
        #array_view = ArrayPlotter(instrument=event.inst,
        #                          system=TiltedGroundFrame(pointing_direction=array_pointing))

        hillas_dict = {}
        r1.calibrate(event)
        dl0.reduce(event)
        calibrator.calibrate(event)  # calibrate the events

        # store MC pointing direction for the array

        for tel_id in event.dl0.tels_with_data:

            pmt_signal = event.dl1.tel[tel_id].image[0]

            x, y = event.inst.pixel_pos[tel_id]
            fl = event.inst.optical_foclen[tel_id]

            if tel_id not in cam_geom:
                cam_geom[tel_id] = CameraGeometry.guess(
                    event.inst.pixel_pos[tel_id][0],
                    event.inst.pixel_pos[tel_id][1],
                    event.inst.optical_foclen[tel_id])

            # Transform the pixels positions into nominal coordinates
            camera_coord = CameraFrame(x=x,
                                       y=y,
                                       z=np.zeros(x.shape) * u.m,
                                       focal_length=fl,
                                       rotation=90 * u.deg -
                                       cam_geom[tel_id].cam_rotation)

            nom_coord = camera_coord.transform_to(
                NominalFrame(array_direction=array_pointing,
                             pointing_direction=array_pointing))

            mask = tailcuts_clean(cam_geom[tel_id],
                                  pmt_signal,
                                  picture_thresh=10.,
                                  boundary_thresh=5.)

            try:
                moments = hillas_parameters(nom_coord.x, nom_coord.y,
                                            pmt_signal * mask)
                hillas_dict[tel_id] = moments
                nom_coord = NominalPlotter(hillas_parameters=hillas_dict,
                                           draw_axes=True)
                nom_coord.draw_array()

            except HillasParameterizationError as e:
                print(e)
                continue
    def start(self):

        disp = None

        for event in tqdm(self.source,
                          desc='Tel{}'.format(self.tel),
                          total=self.reader.max_events,
                          disable=~self.progress):

            self.log.debug(event.trig)
            self.log.debug("Energy: {}".format(event.mc.energy))

            self.calibrator.calibrate(event)

            if disp is None:
                x, y = event.inst.pixel_pos[self.tel]
                focal_len = event.inst.optical_foclen[self.tel]
                geom = CameraGeometry.guess(x, y, focal_len)
                self.log.info(geom)
                disp = CameraDisplay(geom)
                # disp.enable_pixel_picker()
                disp.add_colorbar()
                if self.display:
                    plt.show(block=False)

            # display the event
            disp.axes.set_title('CT{:03d} ({}), event {:06d}'.format(
                self.tel, geom.cam_id, event.r0.event_id)
            )

            if self.samples:
                # display time-varying event
                data = event.dl0.tel[self.tel].pe_samples[self.channel]
                for ii in range(data.shape[1]):
                    disp.image = data[:, ii]
                    disp.set_limits_percent(70)
                    plt.suptitle("Sample {:03d}".format(ii))
                    if self.display:
                        plt.pause(self.delay)
                    if self.write:
                        plt.savefig('CT{:03d}_EV{:10d}_S{:02d}.png'
                                    .format(self.tel, event.r0.event_id, ii))
            else:
                # display integrated event:
                im = event.dl1.tel[self.tel].image[self.channel]

                if self.clean:
                    mask = tailcuts_clean(geom, im, picture_thresh=10,
                                          boundary_thresh=7)
                    im[~mask] = 0.0

                disp.image = im

                if self.hillas:
                    try:
                        ellipses = disp.axes.findobj(Ellipse)
                        if len(ellipses) > 0:
                            ellipses[0].remove()

                        params = hillas_parameters(pix_x=geom.pix_x,
                                                   pix_y=geom.pix_y, image=im)
                        disp.overlay_moments(params, color='pink', lw=3,
                                             with_label=False)
                    except HillasParameterizationError:
                        pass

                if self.display:
                    plt.pause(self.delay)
                if self.write:
                    plt.savefig('CT{:03d}_EV{:010d}.png'
                                .format(self.tel, event.r0.event_id))

        self.log.info("FINISHED READING DATA FILE")

        if disp is None:
            self.log.warning('No events for tel {} were found in {}. Try a '
                             'different EventIO file or another telescope'
                             .format(self.tel, self.infile),
                             )

        pass
示例#46
0
filepath = get_path("/Users/Jason/Software/outputs/sim_telarray/meudon_gamma/"
                    "simtel_runmeudon_gamma_30tel_30deg_19.gz")
# filepath = get_path(sys.argv[1])

source = hessio_event_source(filepath, max_events=1)
event = next(source)
tel = list(event.dl0.tels_with_data)[0]
pos_arr = np.array(event.inst.pixel_pos[tel])

n_pix = pos_arr.shape[1]

pos_arr = pos_arr[:, checm_pixel_id]
pos_arr[1] = -pos_arr[1]

fig = plt.figure(figsize=(13, 13))
ax = fig.add_subplot(111)
geom = CameraGeometry.guess(*event.inst.pixel_pos[tel],
                            event.inst.optical_foclen[tel])
camera = CameraDisplay(geom, ax=ax, image=np.zeros(2048))

for pix in range(n_pix):
    pos_x = pos_arr[0, pix]
    pos_y = pos_arr[1, pix]
    ax.text(pos_x, pos_y, pix, fontsize=3, color='w', ha='center')
    # print("[{0:.5g}, {1:.5g}],  # {2}".format(pos_x, pos_y, pix))

name = "checm_pixel_pos.npy"
path = join(realpath(dirname(__file__)), "../targetpipe/io", name)
np.save(path, pos_arr)
plt.show()