def display_telescope(event, tel_id, display, geom_dict, pp, fig): fig.clear() cam_dimensions = (event.dl0.tel[tel_id].num_pixels, event.meta.optical_foclen[tel_id]) fig.suptitle("EVENT {} {:.1e} @({:.1f},{:.1f}) @{:.1f}".format( event.dl1.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)))) # Select number of pads to display (will depend on the integrator): # charge and/or time of maximum. # This last one is displayed only if the integrator calculates it npads = 1 if not event.dl1.tel[tel_id].peakpos[0] is None: npads = 2 # Only create two pads if there is timing information extracted # from the calibration ax1 = fig.add_subplot(1, npads, 1) # If the geometery has not already been added to geom_dict, it will # be added in CameraPlotter plotter = CameraPlotter(event, geom_dict) signals = event.dl1.tel[tel_id].pe_charge camera1 = plotter.draw_camera(tel_id, signals, ax1) cmaxmin = (max(signals) - min(signals)) 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) camera1.add_colorbar(ax=ax1, label=" [photo-electrons]") ax1.set_title("CT {} ({}) - Mean pixel charge".format( tel_id, geom_dict[cam_dimensions].cam_id)) if not event.dl1.tel[tel_id].peakpos[0] is None: ax2 = fig.add_subplot(1, npads, npads) times = event.dl1.tel[tel_id].peakpos camera2 = plotter.draw_camera(tel_id, times, ax2) tmaxmin = event.dl0.tel[tel_id].num_samples t_chargemax = times[signals.argmax()] if t_chargemax > 15: t_chargemax = 7 cmap_time = colors.LinearSegmentedColormap.from_list( 'cmap_t', [(0 / tmaxmin, 'darkgreen'), (0.6 * t_chargemax / tmaxmin, 'green'), (t_chargemax / tmaxmin, 'yellow'), (1.4 * t_chargemax / tmaxmin, 'blue'), (1, 'darkblue')]) camera2.pixels.set_cmap(cmap_time) camera2.add_colorbar(ax=ax2, label="[time slice]") ax2.set_title("CT {} ({}) - Pixel peak position".format( tel_id, geom_dict[cam_dimensions].cam_id)) if display: plt.pause(0.1) if pp is not None: pp.savefig(fig)
def test_eventplotter(): dataset = get_dataset("gamma_test.simtel.gz") source = hessio_event_source(dataset, max_events=1) event = next(source) data = event.r0.tel[38].adc_samples[0] plotter = CameraPlotter(event) camera = plotter.draw_camera(38, data[:, 0]) assert camera is not None np.testing.assert_array_equal(camera.image, data[:, 0]) plotter.draw_camera_pixel_ids(38, [0, 1, 2]) waveform = plotter.draw_waveform(data[0, :]) assert waveform is not None np.testing.assert_array_equal(waveform.get_ydata(), data[0, :]) line = plotter.draw_waveform_positionline(0) assert line is not None np.testing.assert_array_equal(line.get_xdata(), [0, 0])
def test_eventplotter(): dataset = get_dataset_path("gamma_test_large.simtel.gz") with event_source(dataset, max_events=1) as source: event = next(iter(source)) telid = list(event.r0.tels_with_data)[0] data = event.r0.tel[telid].waveform[0] plotter = CameraPlotter(event) camera = plotter.draw_camera(telid, data[:, 0]) assert camera is not None np.testing.assert_array_equal(camera.image, data[:, 0]) plotter.draw_camera_pixel_ids(telid, [0, 1, 2]) waveform = plotter.draw_waveform(data[0, :]) assert waveform is not None np.testing.assert_array_equal(waveform.get_ydata(), data[0, :]) line = plotter.draw_waveform_positionline(0) assert line is not None np.testing.assert_array_equal(line.get_xdata(), [0, 0])
def plot_muon_event(event, muonparams, args=None): if muonparams['MuonRingParams'] is not None: # Plot the muon event and overlay muon parameters fig = plt.figure(figsize=(16, 7)) colorbar = None colorbar2 = None #for tel_id in event.dl0.tels_with_data: for tel_id in muonparams['TelIds']: idx = muonparams['TelIds'].index(tel_id) if not muonparams['MuonRingParams'][idx]: continue #otherwise... 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) image = event.dl1.tel[tel_id].image[0] geom = event.inst.subarray.tel[tel_id].camera tailcuts = (5., 7.) # Try a higher threshold for if geom.cam_id == 'FlashCam': tailcuts = (10., 12.) 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['MuonRingParams'][idx].ring_center_x**2. + muonparams['MuonRingParams'][idx].ring_center_y**2.) muon_phi = np.arctan( muonparams['MuonRingParams'][idx].ring_center_y / muonparams['MuonRingParams'][idx].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['MuonRingParams'][idx].ring_center_x, y=muonparams['MuonRingParams'][idx].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['MuonRingParams'][idx].ring_radius.to(u.rad) \ * event.inst.optical_foclen[tel_id] * 2. # But not FC? px, py = event.inst.pixel_pos[tel_id] flen = event.inst.optical_foclen[tel_id] camera_coord = CameraFrame(x=px, y=py, focal_length=flen, rotation=geom.pix_rotation) nom_coord = camera_coord.transform_to( NominalFrame(array_direction=altaz, pointing_direction=altaz)) px = nom_coord.x.to(u.deg) py = nom_coord.y.to(u.deg) dist = np.sqrt( np.power(px - muonparams['MuonRingParams'][idx].ring_center_x, 2) + np.power(py - muonparams['MuonRingParams'][idx].ring_center_y, 2)) ring_dist = np.abs(dist - muonparams['MuonRingParams'][idx].ring_radius) pixRmask = ring_dist < muonparams['MuonRingParams'][ idx].ring_radius * 0.4 #if muonparams[1] is not None: if muonparams['MuonIntensityParams'][idx] is not None: signals *= muonparams['MuonIntensityParams'][idx].mask camera1 = plotter.draw_camera(tel_id, signals, ax1) cmaxmin = (max(signals) - min(signals)) cmin = min(signals) if not cmin: cmin = 1. if not cmaxmin: cmaxmin = 1. cmap_charge = colors.LinearSegmentedColormap.from_list( 'cmap_c', [(0 / cmaxmin, 'darkblue'), (np.abs(cmin) / cmaxmin, 'black'), (2.0 * np.abs(cmin) / cmaxmin, 'blue'), (2.5 * np.abs(cmin) / 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") if muonparams['MuonIntensityParams'][idx] is not None: # continue #Comment this...(should ringwidthfrac also be *0.5?) ringwidthfrac = muonparams['MuonIntensityParams'][ idx].ring_width / muonparams['MuonRingParams'][ idx].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['MuonIntensityParams'][idx].prediction if len(pred) != np.sum( muonparams['MuonIntensityParams'][idx].mask): print("Warning! Lengths do not match...len(pred)=", len(pred), "len(mask)=", np.sum(muonparams['MuonIntensityParams'][idx].mask)) # Numpy broadcasting - fill in the shape plotpred = np.zeros(image.shape) plotpred[muonparams['MuonIntensityParams'][idx].mask == True] = pred camera2 = plotter.draw_camera(tel_id, plotpred, ax2) if np.isnan(max(plotpred)) or np.isnan(min(plotpred)): print("nan prediction, skipping...") continue 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()
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()
def run(self, inputs): self.log.debug("--- PrepareDisplayStep RUN ---") calibrated_event, geom_dict = inputs for tel_id in calibrated_event.dl0.tels_with_data: self.fig.clear() cam_dimensions = (calibrated_event.inst.num_pixels[tel_id], calibrated_event.inst.optical_foclen[tel_id]) self.fig.suptitle( "EVENT {} {:.1e} @({:.1f},{:.1f}) @{:.1f}".format( calibrated_event.dl1.event_id, calibrated_event.mc.energy, calibrated_event.mc.alt, calibrated_event.mc.az, np.sqrt( pow(calibrated_event.mc.core_x, 2) + pow(calibrated_event.mc.core_y, 2)))) # Select number of pads to display (will depend on the integrator): # charge and/or time of maximum. # This last one is displayed only if the integrator calculates it npads = 1 if not calibrated_event.dl1.tel[tel_id].peakpos[0] is None: npads = 2 # Only create two pads if there is timing information extracted # from the calibration ax1 = self.fig.add_subplot(1, npads, 1) # If the geometery has not already been added to geom_dict, it will # be added in CameraPlotter plotter = CameraPlotter(calibrated_event, geom_dict) signals = calibrated_event.dl1.tel[tel_id].calibrated_image camera1 = plotter.draw_camera(tel_id, signals, ax1) cmaxmin = (max(signals) - min(signals)) color_list = [(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')] try: cmap_charge = colors.LinearSegmentedColormap.from_list( 'cmap_c', color_list) camera1.pixels.set_cmap(cmap_charge) camera1.add_colorbar(ax=ax1, label=" [photo-electrons]") except: camera1.pixels.set_cmap('jet') ax1.set_title("CT {} ({}) - Mean pixel charge".format( tel_id, geom_dict[tel_id].cam_id)) if not calibrated_event.dl1.tel[tel_id].peakpos[0] is None: ax2 = self.fig.add_subplot(1, npads, npads) times = calibrated_event.dl1.tel[tel_id].peakpos camera2 = plotter.draw_camera(tel_id, times, ax2) tmaxmin = calibrated_event.dl0.tel[tel_id].num_samples t_chargemax = times[signals.argmax()] if t_chargemax > 15: t_chargemax = 7 cmap_time = colors.LinearSegmentedColormap.from_list( 'cmap_t', [(0 / tmaxmin, 'darkgreen'), (0.6 * t_chargemax / tmaxmin, 'green'), (t_chargemax / tmaxmin, 'yellow'), (1.4 * t_chargemax / tmaxmin, 'blue'), (1, 'darkblue')]) try: camera2.pixels.set_cmap(cmap_time) camera2.add_colorbar(ax=ax2, label="[time slice]") except: camera2.pixels.set_cmap('jet') ax2.set_title("CT {} ({}) - Pixel peak position".format( tel_id, geom_dict[tel_id].cam_id)) yield self.fig self.log.debug("--- PrepareDisplayStep END ---")
def plot_muon_event(event, muonparams): if muonparams['MuonRingParams'] is not None: # Plot the muon event and overlay muon parameters fig = plt.figure(figsize=(16, 7)) colorbar = None colorbar2 = None subarray = event.inst.subarray # for tel_id in event.dl0.tels_with_data: for tel_id in muonparams['TelIds']: idx = muonparams['TelIds'].index(tel_id) if not muonparams['MuonRingParams'][idx]: continue # otherwise... 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) image = event.dl1.tel[tel_id].image[0] geom = event.inst.subarray.tel[tel_id].camera tailcuts = (5., 7.) # Try a higher threshold for if geom.cam_id == 'FlashCam': tailcuts = (10., 12.) clean_mask = tailcuts_clean(geom, image, picture_thresh=tailcuts[0], boundary_thresh=tailcuts[1]) signals = image * clean_mask rotr_angle = geom.pix_rotation # The following two lines have been commented out to avoid a rotation error. # if geom.cam_id == 'LSTCam' or geom.cam_id == 'NectarCam': # rotr_angle = 0. * u.deg # Convert to camera frame (centre & radius) altaz = HorizonFrame(alt=event.mc.alt, az=event.mc.az) ring_nominal = SkyCoord( delta_az=muonparams['MuonRingParams'][idx].ring_center_x, delta_alt=muonparams['MuonRingParams'][idx].ring_center_y, frame=NominalFrame(origin=altaz) ) flen = subarray.tel[tel_id].optics.equivalent_focal_length ring_camcoord = ring_nominal.transform_to(CameraFrame( pointing_direction=altaz, focal_length=flen, rotation=rotr_angle)) centroid = (ring_camcoord.x.value, ring_camcoord.y.value) radius = muonparams['MuonRingParams'][idx].ring_radius ringrad_camcoord = 2 * radius.to(u.rad) * flen # But not FC? px = subarray.tel[tel_id].camera.pix_x py = subarray.tel[tel_id].camera.pix_y camera_coord = SkyCoord( x=px, y=py, frame=CameraFrame( focal_length=flen, rotation=geom.pix_rotation, ) ) nom_coord = camera_coord.transform_to( NominalFrame(origin=altaz) ) px = nom_coord.delta_az.to(u.deg) py = nom_coord.delta_alt.to(u.deg) dist = np.sqrt(np.power(px - muonparams['MuonRingParams'][idx].ring_center_x, 2) + np.power(py - muonparams['MuonRingParams'][idx]. ring_center_y, 2)) ring_dist = np.abs(dist - muonparams['MuonRingParams'][idx].ring_radius) pix_rmask = ring_dist < muonparams['MuonRingParams'][idx].ring_radius * 0.4 if muonparams['MuonIntensityParams'][idx] is not None: signals *= muonparams['MuonIntensityParams'][idx].mask elif muonparams['MuonIntensityParams'][idx] is None: signals *= pix_rmask camera1 = plotter.draw_camera(tel_id, signals, ax1) cmaxmin = (max(signals) - min(signals)) cmin = min(signals) if not cmin: cmin = 1. if not cmaxmin: cmaxmin = 1. cmap_charge = colors.LinearSegmentedColormap.from_list( 'cmap_c', [(0 / cmaxmin, 'darkblue'), (np.abs(cmin) / cmaxmin, 'black'), (2.0 * np.abs(cmin) / cmaxmin, 'blue'), (2.5 * np.abs(cmin) / 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") if muonparams['MuonIntensityParams'][idx] is not None: ringwidthfrac = muonparams['MuonIntensityParams'][idx].ring_width / \ muonparams['MuonRingParams'][idx].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['MuonIntensityParams'][idx].prediction if len(pred) != np.sum( muonparams['MuonIntensityParams'][idx].mask): logger.warning("Lengths do not match...len(pred)=%s len(" "mask)=", len(pred), np.sum(muonparams['MuonIntensityParams'][idx].mask)) # Numpy broadcasting - fill in the shape plotpred = np.zeros(image.shape) truelocs = np.where(muonparams['MuonIntensityParams'][idx].mask == True) plotpred[truelocs] = pred camera2 = plotter.draw_camera(tel_id, plotpred, ax2) if np.isnan(max(plotpred)) or np.isnan(min(plotpred)): logger.debug("nan prediction, skipping...") continue 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()
def plot_muon_event(event, muonparams): if muonparams['MuonRingParams'] is not None: # Plot the muon event and overlay muon parameters fig = plt.figure(figsize=(16, 7)) colorbar = None colorbar2 = None subarray = event.inst.subarray # for tel_id in event.dl0.tels_with_data: for tel_id in muonparams['TelIds']: idx = muonparams['TelIds'].index(tel_id) if not muonparams['MuonRingParams'][idx]: continue # otherwise... 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) image = event.dl1.tel[tel_id].image geom = event.inst.subarray.tel[tel_id].camera tailcuts = (5., 7.) # Try a higher threshold for if geom.cam_id == 'FlashCam': tailcuts = (10., 12.) clean_mask = tailcuts_clean(geom, image, picture_thresh=tailcuts[0], boundary_thresh=tailcuts[1]) signals = image * clean_mask rotr_angle = geom.pix_rotation # The following two lines have been commented out to avoid a rotation error. # if geom.cam_id == 'LSTCam' or geom.cam_id == 'NectarCam': # rotr_angle = 0. * u.deg # Convert to camera frame (centre & radius) altaz = AltAz(alt=event.mc.alt, az=event.mc.az) ring_nominal = SkyCoord( delta_az=muonparams['MuonRingParams'][idx].ring_center_x, delta_alt=muonparams['MuonRingParams'][idx].ring_center_y, frame=NominalFrame(origin=altaz)) flen = subarray.tel[tel_id].optics.equivalent_focal_length ring_camcoord = ring_nominal.transform_to( CameraFrame(pointing_direction=altaz, focal_length=flen, rotation=rotr_angle)) centroid = (ring_camcoord.x.value, ring_camcoord.y.value) radius = muonparams['MuonRingParams'][idx].ring_radius ringrad_camcoord = 2 * radius.to(u.rad) * flen # But not FC? px = subarray.tel[tel_id].camera.pix_x py = subarray.tel[tel_id].camera.pix_y camera_coord = SkyCoord(x=px, y=py, frame=CameraFrame( focal_length=flen, rotation=geom.pix_rotation, )) nom_coord = camera_coord.transform_to(NominalFrame(origin=altaz)) px = nom_coord.delta_az.to(u.deg) py = nom_coord.delta_alt.to(u.deg) dist = np.sqrt( np.power(px - muonparams['MuonRingParams'][idx].ring_center_x, 2) + np.power(py - muonparams['MuonRingParams'][idx].ring_center_y, 2)) ring_dist = np.abs(dist - muonparams['MuonRingParams'][idx].ring_radius) pix_rmask = ring_dist < muonparams['MuonRingParams'][ idx].ring_radius * 0.4 if muonparams['MuonIntensityParams'][idx] is not None: signals *= muonparams['MuonIntensityParams'][idx].mask elif muonparams['MuonIntensityParams'][idx] is None: signals *= pix_rmask camera1 = plotter.draw_camera(tel_id, signals, ax1) cmaxmin = (max(signals) - min(signals)) cmin = min(signals) if not cmin: cmin = 1. if not cmaxmin: cmaxmin = 1. cmap_charge = colors.LinearSegmentedColormap.from_list( 'cmap_c', [(0 / cmaxmin, 'darkblue'), (np.abs(cmin) / cmaxmin, 'black'), (2.0 * np.abs(cmin) / cmaxmin, 'blue'), (2.5 * np.abs(cmin) / 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") if muonparams['MuonIntensityParams'][idx] is not None: ringwidthfrac = muonparams['MuonIntensityParams'][idx].ring_width / \ muonparams['MuonRingParams'][idx].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['MuonIntensityParams'][idx].prediction if len(pred) != np.sum( muonparams['MuonIntensityParams'][idx].mask): logger.warning( "Lengths do not match...len(pred)=%s len(" "mask)=", len(pred), np.sum(muonparams['MuonIntensityParams'][idx].mask)) # Numpy broadcasting - fill in the shape plotpred = np.zeros(image.shape) truelocs = np.where( muonparams['MuonIntensityParams'][idx].mask == True) plotpred[truelocs] = pred camera2 = plotter.draw_camera(tel_id, plotpred, ax2) if np.isnan(max(plotpred)) or np.isnan(min(plotpred)): logger.debug("nan prediction, skipping...") continue 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()
def run(self,inputs): self.log.debug("--- PrepareDisplayStep RUN ---") calibrated_event, geom_dict = inputs for tel_id in calibrated_event.dl0.tels_with_data: self.fig.clear() cam_dimensions = (calibrated_event.inst.num_pixels[tel_id], calibrated_event.inst.optical_foclen[tel_id]) self.fig.suptitle("EVENT {} {:.1e} @({:.1f},{:.1f}) @{:.1f}" .format(calibrated_event.dl1.event_id, calibrated_event.mc.energy, calibrated_event.mc.alt, calibrated_event.mc.az, np.sqrt(pow(calibrated_event.mc.core_x, 2) + pow(calibrated_event.mc.core_y, 2)))) # Select number of pads to display (will depend on the integrator): # charge and/or time of maximum. # This last one is displayed only if the integrator calculates it npads = 1 if not calibrated_event.dl1.tel[tel_id].peakpos[0] is None: npads = 2 # Only create two pads if there is timing information extracted # from the calibration ax1 = self.fig.add_subplot(1, npads, 1) # If the geometery has not already been added to geom_dict, it will # be added in CameraPlotter plotter = CameraPlotter(calibrated_event, geom_dict) signals = calibrated_event.dl1.tel[tel_id].calibrated_image camera1 = plotter.draw_camera(tel_id, signals, ax1) cmaxmin = (max(signals) - min(signals)) color_list = [(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')] try: cmap_charge = colors.LinearSegmentedColormap.from_list('cmap_c', color_list) camera1.pixels.set_cmap(cmap_charge) camera1.add_colorbar(ax=ax1, label=" [photo-electrons]") except: camera1.pixels.set_cmap('jet') ax1.set_title("CT {} ({}) - Mean pixel charge" .format(tel_id, geom_dict[tel_id].cam_id)) if not calibrated_event.dl1.tel[tel_id].peakpos[0] is None: ax2 = self.fig.add_subplot(1, npads, npads) times = calibrated_event.dl1.tel[tel_id].peakpos camera2 = plotter.draw_camera(tel_id, times, ax2) tmaxmin = calibrated_event.dl0.tel[tel_id].num_samples t_chargemax = times[signals.argmax()] if t_chargemax > 15: t_chargemax = 7 cmap_time = colors.LinearSegmentedColormap.from_list( 'cmap_t', [(0 / tmaxmin, 'darkgreen'), (0.6 * t_chargemax / tmaxmin, 'green'), (t_chargemax / tmaxmin, 'yellow'), (1.4 * t_chargemax / tmaxmin, 'blue'), (1, 'darkblue')]) try: camera2.pixels.set_cmap(cmap_time) camera2.add_colorbar(ax=ax2, label="[time slice]") except: camera2.pixels.set_cmap('jet') ax2.set_title("CT {} ({}) - Pixel peak position" .format(tel_id, geom_dict[tel_id].cam_id)) yield self.fig self.log.debug("--- PrepareDisplayStep END ---")
def main(): script = os.path.splitext(os.path.basename(__file__))[0] log.info("[SCRIPT] {}".format(script)) parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('-f', '--file', dest='input_path', action='store', default=get_path('gamma_test.simtel.gz'), help='path to the input file') parser.add_argument('-O', '--origin', dest='origin', action='store', choices=InputFile.origin_list(), default='hessio', help='origin of the file') parser.add_argument('-o', '--output', dest='output_dir', action='store', default=None, help='path of the output directory to store the ' 'images (default = input file directory)') parser.add_argument('-e', '--event', dest='event_req', action='store', default=0, type=int, help='event index to plot (not id!)') parser.add_argument('--id', dest='event_id_f', action='store_true', default=False, help='-e will specify event_id instead ' 'of index') parser.add_argument('-t', '--telescope', dest='tel', action='store', type=int, default=None, help='telecope to view') parser.add_argument('-c', '--channel', dest='chan', action='store', type=int, default=0, help='channel to view (default = 0 (HG))') parser.add_argument('--calib-help', dest='calib_help', action='store_true', default=False, help='display the arguments used for the camera ' 'calibration') logger_detail = parser.add_mutually_exclusive_group() logger_detail.add_argument('-q', '--quiet', dest='quiet', action='store_true', default=False, help='Quiet mode') logger_detail.add_argument('-v', '--verbose', dest='verbose', action='store_true', default=False, help='Verbose mode') logger_detail.add_argument('-d', '--debug', dest='debug', action='store_true', default=False, help='Debug mode') args, excess_args = parser.parse_known_args() if args.quiet: log.setLevel(40) if args.verbose: log.setLevel(20) if args.debug: log.setLevel(10) telid = args.tel chan = args.chan log.debug("[file] Reading file") input_file = InputFile(args.input_path, args.origin) event = input_file.get_event(args.event_req, args.event_id_f) # Print event/args values log.info("[event_index] {}".format(event.count)) log.info("[event_id] {}".format(event.dl0.event_id)) log.info("[telescope] {}".format(telid)) log.info("[channel] {}".format(chan)) params, unknown_args = calibration_parameters(excess_args, args.origin, args.calib_help) if unknown_args: parser.print_help() calibration_parameters(unknown_args, args.origin, True) msg = 'unrecognized arguments: %s' parser.error(msg % ' '.join(unknown_args)) # Create a dictionary to store any geoms in geom = CameraGeometry.guess(*event.meta.pixel_pos[telid], event.meta.optical_foclen[telid]) geom_dict = {telid: geom} calibrated_event = calibrate_event(event, params, geom_dict) # Select telescope tels = list(calibrated_event.dl0.tels_with_data) if telid is None or telid not in tels: log.error("[event] please specify one of the following telescopes " "for this event: {}".format(tels)) exit() # Extract required images data_ped = calibrated_event.dl1.tel[telid].pedestal_subtracted_adc[chan] true_pe = calibrated_event.mc.tel[telid].photo_electrons measured_pe = calibrated_event.dl1.tel[telid].pe_charge max_time = np.unravel_index(np.argmax(data_ped), data_ped.shape)[1] max_charges = np.max(data_ped, axis=1) max_pixel = int(np.argmax(max_charges)) min_pixel = int(np.argmin(max_charges)) # Get Neighbours max_pixel_nei = geom.neighbors[max_pixel] min_pixel_nei = geom.neighbors[min_pixel] # Get Windows windows = calibrated_event.dl1.tel[telid].integration_window[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) plotter = CameraPlotter(event, geom_dict) # Draw max pixel traces plotter.draw_waveform(data_ped[max_pixel], ax_max_pix) ax_max_pix.set_title("(Max) Pixel: {}, " "True: {}, " "Measured = {:.3f}".format(max_pixel, true_pe[max_pixel], measured_pe[max_pixel])) ax_max_pix.set_ylabel("Amplitude-Ped (ADC)") max_ylim = ax_max_pix.get_ylim() plotter.draw_waveform_positionline(start[max_pixel], ax_max_pix) plotter.draw_waveform_positionline(end[max_pixel], ax_max_pix) for i, ax in ax_max_nei.items(): if len(max_pixel_nei) > i: pix = max_pixel_nei[i] plotter.draw_waveform(data_ped[pix], ax) ax.set_title("(Max Nei) Pixel: {}, " "True: {}, " "Measured = {:.3f}".format(pix, true_pe[pix], measured_pe[pix])) ax.set_ylabel("Amplitude-Ped (ADC)") ax.set_ylim(max_ylim) plotter.draw_waveform_positionline(start[pix], ax) plotter.draw_waveform_positionline(end[pix], ax) # Draw min pixel traces plotter.draw_waveform(data_ped[min_pixel], ax_min_pix) ax_min_pix.set_title("(Min) Pixel: {}, " "True: {}, " "Measured = {:.3f}".format(min_pixel, true_pe[min_pixel], measured_pe[min_pixel])) ax_min_pix.set_ylabel("Amplitude-Ped (ADC)") ax_min_pix.set_ylim(max_ylim) plotter.draw_waveform_positionline(start[min_pixel], ax_min_pix) plotter.draw_waveform_positionline(end[min_pixel], ax_min_pix) for i, ax in ax_min_nei.items(): if len(min_pixel_nei) > i: pix = min_pixel_nei[i] plotter.draw_waveform(data_ped[pix], ax) ax.set_title("(Min Nei) Pixel: {}, " "True: {}, " "Measured = {:.3f}".format(pix, true_pe[pix], measured_pe[pix])) ax.set_ylabel("Amplitude-Ped (ADC)") ax.set_ylim(max_ylim) plotter.draw_waveform_positionline(start[pix], ax) plotter.draw_waveform_positionline(end[pix], ax) # Draw cameras nei_camera = np.zeros_like(max_charges, dtype=np.int) nei_camera[min_pixel_nei] = 2 nei_camera[min_pixel] = 1 nei_camera[max_pixel_nei] = 3 nei_camera[max_pixel] = 4 camera = plotter.draw_camera(telid, nei_camera, ax_img_nei) camera.cmap = plt.cm.viridis ax_img_nei.set_title("Neighbour Map") plotter.draw_camera_pixel_annotation(telid, max_pixel, min_pixel, ax_img_nei) camera = plotter.draw_camera(telid, data_ped[:, max_time], ax_img_max) camera.add_colorbar(ax=ax_img_max, label="Amplitude-Ped (ADC)") ax_img_max.set_title("Max Timeslice (T = {})".format(max_time)) plotter.draw_camera_pixel_annotation(telid, max_pixel, min_pixel, ax_img_max) camera = plotter.draw_camera(telid, true_pe, ax_img_true) camera.add_colorbar(ax=ax_img_true, label="True Charge (Photo-electrons)") ax_img_true.set_title("True Charge") plotter.draw_camera_pixel_annotation(telid, max_pixel, min_pixel, ax_img_true) int_dict, inverted = integrator_dict() integrator_name = '' if 'integrator' not in params else \ params['integrator'] camera = plotter.draw_camera(telid, measured_pe, ax_img_cal) camera.add_colorbar(ax=ax_img_cal, label="Calib Charge (Photo-electrons)") ax_img_cal.set_title("Charge (integrator={})".format(integrator_name)) plotter.draw_camera_pixel_annotation(telid, max_pixel, min_pixel, ax_img_cal) fig_waveforms.suptitle("Integrator = {}".format(integrator_name)) fig_camera.suptitle("Camera = {}".format(geom.cam_id)) waveform_output_name = "{}_e{}_t{}_c{}_integrator{}_waveform.pdf"\ .format(input_file.filename, event.count, telid, chan, inverted[params['integrator']]) camera_output_name = "{}_e{}_t{}_c{}_integrator{}_camera.pdf"\ .format(input_file.filename, event.count, telid, chan, inverted[params['integrator']]) output_dir = args.output_dir if args.output_dir is not None else \ input_file.output_directory output_dir = os.path.join(output_dir, script) if not os.path.exists(output_dir): log.info("[output] Creating directory: {}".format(output_dir)) os.makedirs(output_dir) waveform_output_path = os.path.join(output_dir, waveform_output_name) log.info("[output] {}".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) log.info("[output] {}".format(camera_output_path)) fig_camera.savefig(camera_output_path, format='pdf', bbox_inches='tight') log.info("[COMPLETE]")
def plot_muon_event(event, muonparams, args=None): if muonparams['MuonRingParams'] is not None: # Plot the muon event and overlay muon parameters fig = plt.figure(figsize=(16, 7)) colorbar = None colorbar2 = None #for tel_id in event.dl0.tels_with_data: for tel_id in muonparams['TelIds']: idx = muonparams['TelIds'].index(tel_id) if not muonparams['MuonRingParams'][idx]: continue #otherwise... 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) image = event.dl1.tel[tel_id].image[0] geom = event.inst.subarray.tel[tel_id].camera tailcuts = (5., 7.) # Try a higher threshold for if geom.cam_id == 'FlashCam': tailcuts = (10., 12.) 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['MuonRingParams'][idx].ring_center_x**2. + muonparams['MuonRingParams'][idx].ring_center_y**2.) muon_phi = np.arctan(muonparams['MuonRingParams'][idx].ring_center_y / muonparams['MuonRingParams'][idx].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['MuonRingParams'][idx].ring_center_x, y=muonparams['MuonRingParams'][idx].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['MuonRingParams'][idx].ring_radius.to(u.rad) \ * event.inst.optical_foclen[tel_id] * 2. # But not FC? 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) ) px = nom_coord.x.to(u.deg) py = nom_coord.y.to(u.deg) dist = np.sqrt(np.power( px - muonparams['MuonRingParams'][idx].ring_center_x, 2) + np.power(py - muonparams['MuonRingParams'][idx].ring_center_y, 2)) ring_dist = np.abs(dist - muonparams['MuonRingParams'][idx].ring_radius) pixRmask = ring_dist < muonparams['MuonRingParams'][idx].ring_radius * 0.4 #if muonparams[1] is not None: if muonparams['MuonIntensityParams'][idx] is not None: signals *= muonparams['MuonIntensityParams'][idx].mask camera1 = plotter.draw_camera(tel_id, signals, ax1) cmaxmin = (max(signals) - min(signals)) cmin = min(signals) if not cmin: cmin = 1. if not cmaxmin: cmaxmin = 1. cmap_charge = colors.LinearSegmentedColormap.from_list( 'cmap_c', [(0 / cmaxmin, 'darkblue'), (np.abs(cmin) / cmaxmin, 'black'), (2.0 * np.abs(cmin) / cmaxmin, 'blue'), (2.5 * np.abs(cmin) / 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") if muonparams['MuonIntensityParams'][idx] is not None: # continue #Comment this...(should ringwidthfrac also be *0.5?) ringwidthfrac = muonparams['MuonIntensityParams'][idx].ring_width / muonparams['MuonRingParams'][idx].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['MuonIntensityParams'][idx].prediction if len(pred) != np.sum(muonparams['MuonIntensityParams'][idx].mask): print("Warning! Lengths do not match...len(pred)=", len(pred), "len(mask)=", np.sum(muonparams['MuonIntensityParams'][idx].mask)) # Numpy broadcasting - fill in the shape plotpred = np.zeros(image.shape) plotpred[muonparams['MuonIntensityParams'][idx].mask == True] = pred camera2 = plotter.draw_camera(tel_id, plotpred, ax2) if np.isnan(max(plotpred)) or np.isnan(min(plotpred)): print("nan prediction, skipping...") continue 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()
def display_telescope(event, tel_id, display, geom_dict, pp, fig): fig.clear() cam_dimensions = (event.dl0.tel[tel_id].num_pixels, event.meta.optical_foclen[tel_id]) fig.suptitle("EVENT {} {:.1e} @({:.1f},{:.1f}) @{:.1f}" .format(event.dl1.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)))) # Select number of pads to display (will depend on the integrator): # charge and/or time of maximum. # This last one is displayed only if the integrator calculates it npads = 1 if not event.dl1.tel[tel_id].peakpos[0] is None: npads = 2 # Only create two pads if there is timing information extracted # from the calibration ax1 = fig.add_subplot(1, npads, 1) # If the geometery has not already been added to geom_dict, it will # be added in CameraPlotter plotter = CameraPlotter(event, geom_dict) signals = event.dl1.tel[tel_id].pe_charge camera1 = plotter.draw_camera(tel_id, signals, ax1) cmaxmin = (max(signals) - min(signals)) 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) camera1.add_colorbar(ax=ax1, label=" [photo-electrons]") ax1.set_title("CT {} ({}) - Mean pixel charge" .format(tel_id, geom_dict[cam_dimensions].cam_id)) if not event.dl1.tel[tel_id].peakpos[0] is None: ax2 = fig.add_subplot(1, npads, npads) times = event.dl1.tel[tel_id].peakpos camera2 = plotter.draw_camera(tel_id, times, ax2) tmaxmin = event.dl0.tel[tel_id].num_samples t_chargemax = times[signals.argmax()] if t_chargemax > 15: t_chargemax = 7 cmap_time = colors.LinearSegmentedColormap.from_list( 'cmap_t', [(0 / tmaxmin, 'darkgreen'), (0.6 * t_chargemax / tmaxmin, 'green'), (t_chargemax / tmaxmin, 'yellow'), (1.4 * t_chargemax / tmaxmin, 'blue'), (1, 'darkblue')]) camera2.pixels.set_cmap(cmap_time) camera2.add_colorbar(ax=ax2, label="[time slice]") ax2.set_title("CT {} ({}) - Pixel peak position" .format(tel_id, geom_dict[cam_dimensions].cam_id)) if display: plt.pause(0.1) if pp is not None: pp.savefig(fig)
def main(): script = os.path.splitext(os.path.basename(__file__))[0] log.info("[SCRIPT] {}".format(script)) parser = argparse.ArgumentParser(description='Create a gif of an event') parser.add_argument('-f', '--file', dest='input_path', action='store', required=True, help='path to the input file') parser.add_argument('-O', '--origin', dest='origin', action='store', required=True, help='origin of the file: {}' .format(origin_list())) parser.add_argument('-o', '--output', dest='output_dir', action='store', default=None, help='path of the output directory to store the ' 'images (default = input file directory)') parser.add_argument('-e', '--event', dest='event_req', action='store', required=True, type=int, help='event index to plot (not id!)') parser.add_argument('--id', dest='event_id_f', action='store_true', default=False, help='-e will specify event_id instead ' 'of index') parser.add_argument('-t', '--telescope', dest='tel', action='store', type=int, default=None, help='telecope to view') parser.add_argument('-c', '--channel', dest='chan', action='store', type=int, default=0, help='channel to view (default = 0 (HG))') calibration_arguments(parser) logger_detail = parser.add_mutually_exclusive_group() logger_detail.add_argument('-q', '--quiet', dest='quiet', action='store_true', default=False, help='Quiet mode') logger_detail.add_argument('-v', '--verbose', dest='verbose', action='store_true', default=False, help='Verbose mode') logger_detail.add_argument('-d', '--debug', dest='debug', action='store_true', default=False, help='Debug mode') args = parser.parse_args() if args.quiet: log.setLevel(40) if args.verbose: log.setLevel(20) if args.debug: log.setLevel(10) telid = args.tel chan = args.chan log.debug("[file] Reading file") input_file = InputFile(args.input_path, args.origin) event = input_file.get_event(args.event_req, args.event_id_f) # Print event/args values log.info("[event_index] {}".format(event.count)) log.info("[event_id] {}".format(event.dl0.event_id)) log.info("[telescope] {}".format(telid)) log.info("[channel] {}".format(chan)) params = calibration_parameters(args) # Create a dictionary to store any geoms in geom = CameraGeometry.guess(*event.meta.pixel_pos[telid], event.meta.optical_foclen[telid]) geom_dict = {telid: geom} calibrated_event = calibrate_event(event, params, geom_dict) # Select telescope tels = list(calibrated_event.dl0.tels_with_data) if telid is None or telid not in tels: log.error("[event] please specify one of the following telescopes " "for this event: {}".format(tels)) exit() # Extract required images data_ped = calibrated_event.dl1.tel[telid].pedestal_subtracted_adc[chan] true_pe = calibrated_event.mc.tel[telid].photo_electrons measured_pe = calibrated_event.dl1.tel[telid].pe_charge max_time = np.unravel_index(np.argmax(data_ped), data_ped.shape)[1] max_charges = np.max(data_ped, axis=1) max_pixel = int(np.argmax(max_charges)) min_pixel = int(np.argmin(max_charges)) # Get Neighbours max_pixel_nei = geom.neighbors[max_pixel] min_pixel_nei = geom.neighbors[min_pixel] # Get Windows windows = calibrated_event.dl1.tel[telid].integration_window[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=(24, 10)) fig_waveforms.subplots_adjust(hspace=.5) fig_camera = plt.figure(figsize=(30, 24)) 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) plotter = CameraPlotter(event, geom_dict) # Draw max pixel traces plotter.draw_waveform(data_ped[max_pixel], ax_max_pix) ax_max_pix.set_title("(Max) Pixel: {}, " "True: {}, " "Measured = {}".format(max_pixel, true_pe[max_pixel], measured_pe[max_pixel])) ax_max_pix.set_ylabel("Amplitude-Ped (ADC)") max_ylim = ax_max_pix.get_ylim() plotter.draw_waveform_positionline(start[max_pixel], ax_max_pix) plotter.draw_waveform_positionline(end[max_pixel], ax_max_pix) for i, ax in ax_max_nei.items(): if len(max_pixel_nei) > i: pix = max_pixel_nei[i] plotter.draw_waveform(data_ped[pix], ax) ax.set_title("(Max Nei) Pixel: {}, " "True: {}, " "Measured = {}".format(pix, true_pe[pix], measured_pe[pix])) ax.set_ylabel("Amplitude-Ped (ADC)") ax.set_ylim(max_ylim) plotter.draw_waveform_positionline(start[pix], ax) plotter.draw_waveform_positionline(end[pix], ax) # Draw min pixel traces plotter.draw_waveform(data_ped[min_pixel], ax_min_pix) ax_min_pix.set_title("(Min) Pixel: {}, " "True: {}, " "Measured = {}".format(min_pixel, true_pe[min_pixel], measured_pe[min_pixel])) ax_min_pix.set_ylabel("Amplitude-Ped (ADC)") ax_min_pix.set_ylim(max_ylim) plotter.draw_waveform_positionline(start[min_pixel], ax_min_pix) plotter.draw_waveform_positionline(end[min_pixel], ax_min_pix) for i, ax in ax_min_nei.items(): if len(min_pixel_nei) > i: pix = min_pixel_nei[i] plotter.draw_waveform(data_ped[pix], ax) ax.set_title("(Min Nei) Pixel: {}, " "True: {}, " "Measured = {}".format(pix, true_pe[pix], measured_pe[pix])) ax.set_ylabel("Amplitude-Ped (ADC)") ax.set_ylim(max_ylim) plotter.draw_waveform_positionline(start[pix], ax) plotter.draw_waveform_positionline(end[pix], ax) # Draw cameras nei_camera = np.zeros_like(max_charges, dtype=np.int) nei_camera[min_pixel_nei] = 2 nei_camera[min_pixel] = 1 nei_camera[max_pixel_nei] = 3 nei_camera[max_pixel] = 4 camera = plotter.draw_camera(telid, nei_camera, ax_img_nei) camera.cmap = plt.cm.viridis ax_img_nei.set_title("Neighbour Map") plotter.draw_camera_pixel_annotation(telid, max_pixel, min_pixel, ax_img_nei) camera = plotter.draw_camera(telid, data_ped[:, max_time], ax_img_max) camera.add_colorbar(ax=ax_img_max, label="Amplitude-Ped (ADC)") ax_img_max.set_title("Max Timeslice (T = {})".format(max_time)) plotter.draw_camera_pixel_annotation(telid, max_pixel, min_pixel, ax_img_max) camera = plotter.draw_camera(telid, true_pe, ax_img_true) camera.add_colorbar(ax=ax_img_true, label="True Charge (Photo-electrons)") ax_img_true.set_title("True Charge") plotter.draw_camera_pixel_annotation(telid, max_pixel, min_pixel, ax_img_true) camera = plotter.draw_camera(telid, measured_pe, ax_img_cal) camera.add_colorbar(ax=ax_img_cal, label="Calib Charge (Photo-electrons)") ax_img_cal.set_title("Charge (integrator={})".format(params['integrator'])) plotter.draw_camera_pixel_annotation(telid, max_pixel, min_pixel, ax_img_cal) fig_waveforms.suptitle("Integrator = {}".format(params['integrator'])) fig_camera.suptitle("Camera = {}".format(geom.cam_id)) # TODO: another figure of all waveforms that have non-zero true charge waveform_output_name = "{}_e{}_t{}_c{}_integrator{}_waveform.pdf"\ .format(input_file.filename, event.count, telid, chan, args.integrator) camera_output_name = "{}_e{}_t{}_c{}_integrator{}_camera.pdf"\ .format(input_file.filename, event.count, telid, chan, args.integrator) output_dir = args.output_dir if args.output_dir is not None else \ input_file.output_directory output_dir = os.path.join(output_dir, script) if not os.path.exists(output_dir): log.info("[output] Creating directory: {}".format(output_dir)) os.makedirs(output_dir) waveform_output_path = os.path.join(output_dir, waveform_output_name) log.info("[output] {}".format(waveform_output_path)) fig_waveforms.savefig(waveform_output_path, format='pdf') camera_output_path = os.path.join(output_dir, camera_output_name) log.info("[output] {}".format(camera_output_path)) fig_camera.savefig(camera_output_path, format='pdf') log.info("[COMPLETE]")
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()