Example #1
0
        def update(frame):

            self.log.debug("Frame=", frame)
            centroid = np.random.uniform(-fov, fov, size=2) * scale
            width = np.random.uniform(0, maxwid) * scale
            length = np.random.uniform(0, maxlen) * scale + width
            angle = np.random.uniform(0, 360)
            intens = np.random.exponential(2) * 50
            model = toymodel.generate_2d_shower_model(centroid=centroid,
                                                      width=width,
                                                      length=length,
                                                      psi=angle * u.deg)
            image, sig, bg = toymodel.make_toymodel_shower_image(
                geom, model.pdf, intensity=intens, nsb_level_pe=5000)

            # alternate between cleaned and raw images
            if self._counter == self.cleanframes:
                plt.suptitle("Image Cleaning ON")
                self.imclean = True
            if self._counter == self.cleanframes * 2:
                plt.suptitle("Image Cleaning OFF")
                self.imclean = False
                self._counter = 0

            if self.imclean:
                cleanmask = tailcuts_clean(geom, image / 80.0)
                for ii in range(3):
                    dilate(geom, cleanmask)
                image[cleanmask == 0] = 0  # zero noise pixels

            self.log.debug("count = {}, image sum={} max={}".format(
                self._counter, image.sum(), image.max()))
            disp.image = image

            if self.autoscale:
                disp.set_limits_percent(95)
            else:
                disp.set_limits_minmax(-100, 4000)

            disp.axes.figure.canvas.draw()
            self._counter += 1
            return [
                ax,
            ]
Example #2
0
        def update(frame):

            centroid = np.random.uniform(-0.5, 0.5, size=2)
            width = np.random.uniform(0, 0.01)
            length = np.random.uniform(0, 0.03) + width
            angle = np.random.uniform(0, 360)
            intens = np.random.exponential(2) * 50
            model = toymodel.generate_2d_shower_model(centroid=centroid,
                                                      width=width,
                                                      length=length,
                                                      psi=angle * u.deg)
            image, sig, bg = toymodel.make_toymodel_shower_image(geom, model.pdf,
                                                                 intensity=intens,
                                                                 nsb_level_pe=5000)

            # alternate between cleaned and raw images
            if self._counter == self.cleanframes:
                plt.suptitle("Image Cleaning ON")
                self.imclean = True
            if self._counter == self.cleanframes*2:
                plt.suptitle("Image Cleaning OFF")
                self.imclean = False
                self._counter = 0

            if self.imclean:
                cleanmask = tailcuts_clean(geom, image/80.0)
                for ii in range(3):
                    dilate(geom, cleanmask)
                image[cleanmask == 0] = 0  # zero noise pixels

            self.log.debug("count = {}, image sum={} max={}"
                .format(self._counter, image.sum(), image.max()))
            disp.image = image

            if self.autoscale:
                disp.set_limits_percent(95)
            else:
                disp.set_limits_minmax(-100, 4000)

            disp.axes.figure.canvas.draw()
            self._counter += 1
            return [ax,]
Example #3
0
 def __call__(self, cameras):
     if not isinstance(cameras, list):
         cameras = [cameras]
     results = []
     for (charge, peak) in cameras:
         if self.tailcuts_clean_params is not None:
             cleanmask = tailcuts_clean(self.geometry, charge, **self.tailcuts_clean_params)
             charge[~cleanmask] = 0.0
             for _ in range(3):
                 cleanmask = dilate(self.geometry, cleanmask)
             peak[~cleanmask] = 0.0
         charge /= self.charge_scaler_value
         if self.peak_scaler is not None:
             peak  = self.peak_scaler.transform(peak.reshape((-1, 1))).flatten()
         results.append((charge, peak))
     return results
Example #4
0
        def update(frame):


            centroid = np.random.uniform(-fov, fov, size=2) * scale
            width = np.random.uniform(0, maxwid-minwid) * scale + minwid
            length = np.random.uniform(0, maxlen) * scale + width
            angle = np.random.uniform(0, 360)
            intens = np.random.exponential(2) * 500
            model = toymodel.generate_2d_shower_model(centroid=centroid,
                                                      width=width,
                                                      length=length,
                                                      psi=angle * u.deg)
            self.log.debug(
                "Frame=%d width=%03f length=%03f intens=%03d",
                frame, width, length, intens
            )

            image, sig, bg = toymodel.make_toymodel_shower_image(
                geom,
                model.pdf,
                intensity=intens,
                nsb_level_pe=3,
            )

            # alternate between cleaned and raw images
            if self._counter == self.cleanframes:
                plt.suptitle("Image Cleaning ON")
                self.imclean = True
            if self._counter == self.cleanframes * 2:
                plt.suptitle("Image Cleaning OFF")
                self.imclean = False
                self._counter = 0
                disp.clear_overlays()

            if self.imclean:
                cleanmask = tailcuts_clean(geom, image,
                                           picture_thresh=10.0,
                                           boundary_thresh=5.0)
                for ii in range(2):
                    dilate(geom, cleanmask)
                image[cleanmask == 0] = 0  # zero noise pixels
                try:
                    hillas = hillas_parameters(geom, image)
                    disp.overlay_moments(hillas, with_label=False,
                                         color='red', alpha=0.7,
                                         linewidth=2, linestyle='dashed')
                except HillasParameterizationError:
                    disp.clear_overlays()
                    pass

            self.log.debug("Frame=%d  image_sum=%.3f max=%.3f",
                           self._counter, image.sum(), image.max())
            disp.image = image

            if self.autoscale:
                disp.set_limits_percent(95)
            else:
                disp.set_limits_minmax(-5, 200)

            disp.axes.figure.canvas.draw()
            self._counter += 1
            return [ax, ]
Example #5
0
        def update(frame):
            x, y = np.random.uniform(-fov, fov, size=2) * scale
            width = np.random.uniform(0, maxwid - minwid) * scale + minwid
            length = np.random.uniform(0, maxlen) * scale + width
            angle = np.random.uniform(0, 360)
            intens = np.random.exponential(2) * 500
            model = toymodel.Gaussian(
                x=x * u.m,
                y=y * u.m,
                width=width * u.m,
                length=length * u.m,
                psi=angle * u.deg,
            )
            self.log.debug(
                "Frame=%d width=%03f length=%03f intens=%03d",
                frame, width, length, intens
            )

            image, _, _ = model.generate_image(
                geom,
                intensity=intens,
                nsb_level_pe=3,
            )

            # alternate between cleaned and raw images
            if self._counter == self.cleanframes:
                plt.suptitle("Image Cleaning ON")
                self.imclean = True
            if self._counter == self.cleanframes * 2:
                plt.suptitle("Image Cleaning OFF")
                self.imclean = False
                self._counter = 0
                disp.clear_overlays()

            if self.imclean:
                cleanmask = tailcuts_clean(geom, image,
                                           picture_thresh=10.0,
                                           boundary_thresh=5.0)
                for ii in range(2):
                    dilate(geom, cleanmask)
                image[cleanmask == 0] = 0  # zero noise pixels
                try:
                    hillas = hillas_parameters(geom, image)
                    disp.overlay_moments(hillas, with_label=False,
                                         color='red', alpha=0.7,
                                         linewidth=2, linestyle='dashed')
                except HillasParameterizationError:
                    disp.clear_overlays()
                    pass

            self.log.debug("Frame=%d  image_sum=%.3f max=%.3f",
                           self._counter, image.sum(), image.max())
            disp.image = image

            if self.autoscale:
                disp.set_limits_percent(95)
            else:
                disp.set_limits_minmax(-5, 200)

            disp.axes.figure.canvas.draw()
            self._counter += 1
            return [ax, ]
Example #6
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)
Example #7
0
                              length=0.15 * u.m,
                              psi='35d')

    image, sig, bg = model.generate_image(geom, intensity=1500, nsb_level_pe=5)

    disp = CameraDisplay(geom, image=image)
    plt.show(disp)

    cleanmask = tailcuts_clean(geom,
                               image,
                               picture_thresh=10,
                               boundary_thresh=5)
    clean = image.copy()
    clean[~cleanmask] = 0.0

    disp = CameraDisplay(geom, image=clean)
    plt.show(disp)

    cleanmask_dilated = dilate(geom, cleanmask)
    clean_dilated = image.copy()
    clean_dilated[~cleanmask_dilated] = 0.0

    disp = CameraDisplay(geom, image=clean_dilated)
    plt.show(disp)

    cleanmasks_visualized = cleanmask.astype(int) + cleanmask_dilated.astype(
        int)

    disp = CameraDisplay(geom, image=cleanmasks_visualized)
    plt.show(disp)
Example #8
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 = {}
        

        Gate_dict = {}
        Nectar_dict = {}
        LST_dict ={}
        dict_list=[]

        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]

            # 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(3):
                    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[mask]
                pixel_y[tel_id] = nom_coord.y[mask]

                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[mask]
                image_pred[tel_id] = np.zeros(pmt_signal.shape)

                hillas[tel_id] = moments_cam
                hillas_nom[tel_id] = moments
                mask_dict[tel_id] = mask
                
            
                cam_id = self.geoms[tel_id].cam_id
                print (cam_id)

                mom=[moments.size, tilt_tel, moments.width/u.rad,
                     moments.length/u.rad]
                
                if (cam_id == 'LSTCam'):
                    try:
                        LST_dict[cam_id].append(mom)
                    except:
                        LST_dict.update({'LSTCam':[mom]})
                elif (cam_id =='NectarCam'):
                    try:
                        Nectar_dict['NectarCam'].append(mom)
                    except:
                        Nectar_dict.update({'NectarCam':[mom]})
                elif (cam_id =='CHEC'):
                    try:
                        Gate_dict[cam_id].append(mom)
                    except:
                        Gate_dict.update({'CHEC':[mom]})
                else:
                    print (cam_id +': Type not known')

        #################################################
        # Cut on number of telescopes remaining
        if len(image)>1:
            fit_result = self.fit.predict(hillas_nom, tel_x, 
                                          tel_y, array_pointing)
            
            core_pos_grd = GroundFrame(x=fit_result.core_x,y=fit_result.core_y,
                                       z=0*u.m)
            core_pos_tilt = core_pos_grd.transform_to(tilted_system)

            coredist=np.sqrt(core_pos_grd.x**2+core_pos_grd.y**2)
            
            dict_list=np.array([])
            if len(LST_dict) != 0:
                for i in range (0,len(LST_dict['LSTCam'])):
                    LST_dict['LSTCam'][i][1]= LST_dict['LSTCam'][i][1].separation_3d(core_pos_tilt).to(u.m)/u.m
                dict_list=np.append(dict_list,LST_dict)
            if len(Nectar_dict) != 0:
                for i in range(0,len(Nectar_dict['NectarCam'])):
                    Nectar_dict['NectarCam'][i][1]= Nectar_dict['NectarCam'][i][1].separation_3d(core_pos_tilt).to(u.m) /u.m
                dict_list=np.append(dict_list,Nectar_dict)
            if len(Gate_dict) !=0:
                for i in range(0, len(Gate_dict['CHEC'])):
                    Gate_dict['CHEC'][i][1]= Gate_dict['CHEC'][i][1].separation_3d(core_pos_tilt).to(u.m) /u.m
                dict_list=np.append(dict_list,Gate_dict)

            energy_result = self.energy_reco.predict_by_event(dict_list)

            print('Fit results and Energy results')
            print(energy_result)
            print ('__________________________')

            # Perform ImPACT reconstruction
            self.ImPACT.set_event_properties(image, pixel_x, pixel_y, 
                                             pixel_area, tel_type, tel_x, 
                                             tel_y, array_pointing, hillas_nom)

            energy_seed=ReconstructedEnergyContainer()
            
            energy_seed.energy=np.mean(np.power(10,energy_result['mean'].value)) * u.TeV
            energy_seed.energy_uncert=np.mean(energy_result['std'])
            energy_seed.is_valid = True
            energy_seed.tel_ids= event.dl0.tels_with_data



            ImPACT_shower, ImPACT_energy = self.ImPACT.predict(fit_result, energy_seed)

            print(ImPACT_energy)
            # insert the row into the table
            self.output.add_row((event.dl0.event_id, ImPACT_shower.alt,
                                 ImPACT_shower.az, ImPACT_energy.energy, 
                                 fit_result.alt, fit_result.az, 
                                 np.mean(np.power(10,energy_result['mean'].value)),  
                                 ImPACT_shower.goodness_of_fit,
                                 event.mc.alt, event.mc.az, event.mc.energy, 
                                 len(image),coredist))