class CameraDemo(Tool): name = u"ctapipe-camdemo" description = "Display fake events in a demo camera" delay = traits.Int(50, help="Frame delay in ms", min=20).tag(config=True) cleanframes = traits.Int(100, help="Number of frames between turning on " "cleaning", min=0).tag(config=True) autoscale = traits.Bool(False, help='scale each frame to max if ' 'True').tag(config=True) blit = traits.Bool(False, help='use blit operation to draw on screen (' 'much faster but may cause some draw ' 'artifacts)').tag(config=True) camera = traits.CaselessStrEnum( CameraGeometry.get_known_camera_names(), default_value='NectarCam', help='Name of camera to display').tag(config=True) optics = traits.CaselessStrEnum( OpticsDescription.get_known_optics_names(), default_value='MST', help='Telescope optics description name').tag(config=True) aliases = traits.Dict({ 'delay': 'CameraDemo.delay', 'cleanframes': 'CameraDemo.cleanframes', 'autoscale': 'CameraDemo.autoscale', 'blit': 'CameraDemo.blit', 'camera': 'CameraDemo.camera', 'optics': 'CameraDemo.optics', }) def __init__(self): super().__init__() self._counter = 0 self.imclean = False def start(self): self.log.info("Starting CameraDisplay for {}".format(self.camera)) self._display_camera_animation() def _display_camera_animation(self): # plt.style.use("ggplot") fig = plt.figure(num="ctapipe Camera Demo", figsize=(7, 7)) ax = plt.subplot(111) # load the camera tel = TelescopeDescription.from_name(optics_name=self.optics, camera_name=self.camera) geom = tel.camera # poor-man's coordinate transform from telscope to camera frame (it's # better to use ctapipe.coordiantes when they are stable) scale = tel.optics.effective_focal_length.to(geom.pix_x.unit).value fov = np.deg2rad(4.0) maxwid = np.deg2rad(0.01) maxlen = np.deg2rad(0.03) disp = CameraDisplay(geom, ax=ax, autoupdate=True, title="{}, f={}".format( tel, tel.optics.effective_focal_length)) disp.cmap = plt.cm.terrain def update(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, ] self.anim = FuncAnimation(fig, update, interval=self.delay, blit=self.blit) plt.show()
class CameraDemo(Tool): name = u"ctapipe-camdemo" description = "Display fake events in a demo camera" delay = traits.Int(20, help="Frame delay in ms").tag(config=True) cleanframes = traits.Int(100, help="Number of frames between turning on " "cleaning").tag(config=True) autoscale = traits.Bool(False, help='scale each frame to max if ' 'True').tag(config=True) blit = traits.Bool(False, help='use blit operation to draw on screen (' 'much faster but may cause some draw ' 'artifacts)').tag(config=True) aliases = traits.Dict({'delay': 'CameraDemo.delay', 'cleanframes': 'CameraDemo.cleanframes', 'autoscale' : 'CameraDemo.autoscale', 'blit': 'CameraDemo.blit'}) def __init__(self): super().__init__() self._counter = 0 self.imclean = False def start(self): self.log.info("Starting Camera Display") self._display_camera_animation() def _display_camera_animation(self): #plt.style.use("ggplot") fig = plt.figure(num="ctapipe Camera Demo", figsize=(7, 7)) ax = plt.subplot(111) # load the camera geom = io.CameraGeometry.from_name("hess", 1) disp = visualization.CameraDisplay(geom, ax=ax, autoupdate=True) disp.cmap = plt.cm.terrain 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 = cleaning.tailcuts_clean(geom, image, pedvars=80) for ii in range(3): cleaning.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,] self.anim = FuncAnimation(fig, update, interval=self.delay, blit=self.blit) plt.show()
class MuonDisplayerTool(Tool): name = 'ctapipe-display-muons' description = t.Unicode(__doc__) events = t.Unicode("", help="input event data file").tag(config=True) outfile = t.Unicode("muons.hdf5", help='HDF5 output file name').tag( config=True) display = t.Bool( help='display the camera events', default=False ).tag(config=True) classes = t.List([ CameraCalibrator, EventSource ]) aliases = t.Dict({ 'input': 'MuonDisplayerTool.events', 'outfile': 'MuonDisplayerTool.outfile', 'display': 'MuonDisplayerTool.display', 'max_events': 'EventSource.max_events', 'allowed_tels': 'EventSource.allowed_tels', }) def setup(self): if self.events == '': raise ToolConfigurationError("please specify --input <events file>") self.log.debug("input: %s", self.events) self.source = event_source(self.events) self.calib = CameraCalibrator( config=self.config, tool=self, eventsource=self.source ) self.writer = HDF5TableWriter(self.outfile, "muons") def start(self): numev = 0 self.num_muons_found = defaultdict(int) for event in tqdm(self.source, desc='detecting muons'): self.calib.calibrate(event) muon_evt = analyze_muon_event(event) if numev == 0: _exclude_some_columns(event.inst.subarray, self.writer) numev += 1 if not muon_evt['MuonIntensityParams']: # No telescopes contained a good muon continue else: if self.display: plot_muon_event(event, muon_evt) for tel_id in muon_evt['TelIds']: idx = muon_evt['TelIds'].index(tel_id) intens_params = muon_evt['MuonIntensityParams'][idx] if intens_params is not None: ring_params = muon_evt['MuonRingParams'][idx] cam_id = str(event.inst.subarray.tel[tel_id].camera) self.num_muons_found[cam_id] += 1 self.log.debug("INTENSITY: %s", intens_params) self.log.debug("RING: %s", ring_params) self.writer.write(table_name=cam_id, containers=[intens_params, ring_params]) self.log.info( "Event Number: %d, found %s muons", numev, dict(self.num_muons_found) ) def finish(self): Provenance().add_output_file(self.outfile, role='dl1.tel.evt.muon') self.writer.close()
class CameraDemo(Tool): name = "ctapipe-camdemo" description = "Display fake events in a demo camera" delay = traits.Int(50, help="Frame delay in ms", min=20).tag(config=True) cleanframes = traits.Int(20, help="Number of frames between turning on " "cleaning", min=0).tag(config=True) autoscale = traits.Bool(False, help='scale each frame to max if ' 'True').tag(config=True) blit = traits.Bool(False, help='use blit operation to draw on screen (' 'much faster but may cause some draw ' 'artifacts)').tag(config=True) camera = traits.CaselessStrEnum( CameraDescription.get_known_camera_names(), default_value='NectarCam', help='Name of camera to display').tag(config=True) optics = traits.CaselessStrEnum( OpticsDescription.get_known_optics_names(), default_value='MST', help='Telescope optics description name' ).tag(config=True) num_events = traits.Int(0, help='events to show before exiting (0 for ' 'unlimited)').tag(config=True) display = traits.Bool(True, "enable or disable display (for " "testing)").tag(config=True) aliases = traits.Dict({ 'delay': 'CameraDemo.delay', 'cleanframes': 'CameraDemo.cleanframes', 'autoscale': 'CameraDemo.autoscale', 'blit': 'CameraDemo.blit', 'camera': 'CameraDemo.camera', 'optics': 'CameraDemo.optics', 'num-events': 'CameraDemo.num_events' }) def __init__(self): super().__init__() self._counter = 0 self.imclean = False def start(self): self.log.info(f"Starting CameraDisplay for {self.camera}") self._display_camera_animation() def _display_camera_animation(self): # plt.style.use("ggplot") fig = plt.figure(num="ctapipe Camera Demo", figsize=(7, 7)) ax = plt.subplot(111) # load the camera tel = TelescopeDescription.from_name(optics_name=self.optics, camera_name=self.camera) geom = tel.camera.geometry # poor-man's coordinate transform from telscope to camera frame (it's # better to use ctapipe.coordiantes when they are stable) foclen = tel.optics.equivalent_focal_length.to(geom.pix_x.unit).value fov = np.deg2rad(4.0) scale = foclen minwid = np.deg2rad(0.1) maxwid = np.deg2rad(0.3) maxlen = np.deg2rad(0.5) self.log.debug(f"scale={scale} m, wid=({minwid}-{maxwid})") disp = CameraDisplay( geom, ax=ax, autoupdate=True, title=f"{tel}, f={tel.optics.equivalent_focal_length}" ) disp.cmap = plt.cm.terrain 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, ] frames = None if self.num_events == 0 else self.num_events repeat = True if self.num_events == 0 else False self.log.info(f"Running for {frames} frames") self.anim = FuncAnimation(fig, update, interval=self.delay, frames=frames, repeat=repeat, blit=self.blit) if self.display: plt.show()
class MuonDisplayerTool(Tool): name = 'ctapipe-display-muons' description = t.Unicode(__doc__) infile = t.Unicode( help='input file name', default=get_dataset('gamma_test_large.simtel.gz') ).tag(config=True) outfile = t.Unicode(help='output file name', default=None).tag(config=True) display = t.Bool( help='display the camera events', default=False ).tag(config=True) classes = t.List([CameraCalibrator,]) aliases = t.Dict({'infile': 'MuonDisplayerTool.infile', 'outfile': 'MuonDisplayerTool.outfile', 'display' : 'MuonDisplayerTool.display' }) def setup(self): self.calib = CameraCalibrator(config=self.config, tool=self) def start(self): output_parameters = {'MuonEff': [], 'ImpactP': [], 'RingWidth': []} numev = 0 num_muons_found = 0 for event in hessio_event_source(self.infile): self.log.info("Event Number: %d, found %d muons", numev, num_muons_found) self.calib.calibrate(event) muon_evt = analyze_muon_event(event) numev += 1 if not muon_evt['MuonIntensityParams']: # No telescopes contained a good muon continue else: if self.display: plot_muon_event(event, muon_evt) for tid in muon_evt['TelIds']: idx = muon_evt['TelIds'].index(tid) if not muon_evt['MuonIntensityParams'][idx]: continue self.log.info("** Muon params: %s", muon_evt[idx]) output_parameters['MuonEff'].append( muon_evt['MuonIntensityParams'][idx].optical_efficiency_muon ) output_parameters['ImpactP'].append( muon_evt['MuonIntensityParams'][idx].impact_parameter.value ) output_parameters['RingWidth'].append( muon_evt['MuonIntensityParams'][idx].ring_width.value ) print_muon(muon_evt, printer=self.log.info) num_muons_found += 1 t = Table(output_parameters) t['ImpactP'].unit = 'm' t['RingWidth'].unit = 'deg' if self.outfile: t.write(self.outfile)
class MuonDisplayerTool(Tool): name = 'ctapipe-display-muons' description = t.Unicode(__doc__) infile = t.Unicode( help='input file name', default=get_dataset('gamma_test_large.simtel.gz')).tag(config=True) outfile = t.Unicode(help='output file name', default=None).tag(config=True) display = t.Bool(help='display the camera events', default=False).tag(config=True) classes = t.List([ CameraCalibrator, ]) aliases = t.Dict({ 'infile': 'MuonDisplayerTool.infile', 'outfile': 'MuonDisplayerTool.outfile', 'display': 'MuonDisplayerTool.display' }) def setup(self): self.calib = CameraCalibrator() def start(self): output_parameters = { 'MuonEff': [], 'ImpactP': [], 'RingWidth': [], 'RingCont': [], 'RingComp': [], 'RingPixComp': [], 'Core_x': [], 'Core_y': [], 'Impact_x_arr': [], 'Impact_y_arr': [], 'MCImpactP': [], 'ImpactDiff': [], 'RingSize': [], 'RingRadius': [], 'NTels': [] } numev = 0 num_muons_found = 0 for event in event_source(self.infile): self.log.info("Event Number: %d, found %d muons", numev, num_muons_found) self.calib.calibrate(event) muon_evt = analyze_muon_event(event) numev += 1 if not muon_evt[ 'MuonIntensityParams']: # No telescopes contained a good muon continue else: if self.display: plot_muon_event(event, muon_evt) ntels = len(event.r0.tels_with_data) #if(len( event.r0.tels_with_data) <= 1): #continue #print("event.r0.tels_with_data", event.r0.tels_with_data) for tid in muon_evt['TelIds']: idx = muon_evt['TelIds'].index(tid) if muon_evt['MuonIntensityParams'][idx] is not None: print("pos, tid", event.inst.subarray.positions[tid], tid) tel_x = event.inst.subarray.positions[tid][0] tel_y = event.inst.subarray.positions[tid][1] core_x = event.mc.core_x # MC Core x core_y = event.mc.core_y # MC Core y rec_impact_x = muon_evt['MuonIntensityParams'][ idx].impact_parameter_pos_x rec_impact_y = muon_evt['MuonIntensityParams'][ idx].impact_parameter_pos_y print("rec_impact_x, rec_impact_y", rec_impact_x, rec_impact_y) print("event.mc.core_x, event.mc.core_y", event.mc.core_x, event.mc.core_y) impact_mc = np.sqrt( np.power(core_x - tel_x, 2) + np.power(core_y - tel_y, 2)) print("simulated impact", impact_mc) # Coordinate transformation to move the impact point to array coordinates rec_impact_x_arr = tel_x + rec_impact_x rec_impact_y_arr = tel_y + rec_impact_y print("impact_x_arr, impact_y_arr", rec_impact_x_arr, rec_impact_y_arr) # Distance between core of the showe and impact parameter impact_diff = np.sqrt( np.power(core_x - rec_impact_x_arr, 2) + np.power(core_y - rec_impact_y_arr, 2)) print("impact_diff ", impact_diff) self.log.info("** Muon params: %s", muon_evt['MuonIntensityParams'][idx]) output_parameters['MuonEff'].append( muon_evt['MuonIntensityParams'] [idx].optical_efficiency_muon) output_parameters['ImpactP'].append( muon_evt['MuonIntensityParams'] [idx].impact_parameter.value) output_parameters['RingWidth'].append( muon_evt['MuonIntensityParams'] [idx].ring_width.value) output_parameters['RingCont'].append( muon_evt['MuonRingParams'][idx].ring_containment) output_parameters['RingComp'].append( muon_evt['MuonIntensityParams'] [idx].ring_completeness) output_parameters['RingPixComp'].append( muon_evt['MuonIntensityParams'] [idx].ring_pix_completeness) output_parameters['Core_x'].append( event.mc.core_x.value) output_parameters['Core_y'].append( event.mc.core_y.value) output_parameters['Impact_x_arr'].append( rec_impact_x_arr.value) output_parameters['Impact_y_arr'].append( rec_impact_y_arr.value) output_parameters['MCImpactP'].append(impact_mc.value) output_parameters['ImpactDiff'].append( impact_diff.value) output_parameters['RingSize'].append( muon_evt['MuonIntensityParams'][idx].ring_size) output_parameters['RingRadius'].append( muon_evt['MuonRingParams'][idx].ring_radius.value) output_parameters['NTels'].append(ntels) print_muon(muon_evt, printer=self.log.info) num_muons_found += 1 t = Table(output_parameters) t['ImpactP'].unit = 'm' t['RingWidth'].unit = 'deg' #t['MCImpactP'].unit = 'm' if self.outfile: t.write(self.outfile)