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, ]
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,]
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
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, ]
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, ]
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)
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)
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))