def test_conversion(): """ Test conversion between CameraFrame and EngineeringCameraFrame """ from ctapipe.coordinates import CameraFrame, EngineeringCameraFrame coords = SkyCoord(x=[3, 1] * u.m, y=[2, 4] * u.m, frame=CameraFrame()) for coord in coords: eng_coord = coord.transform_to(EngineeringCameraFrame()) assert eng_coord.x == -coord.y assert eng_coord.y == -coord.x back = eng_coord.transform_to(CameraFrame()) assert back.x == coord.x assert back.y == coord.y eng_coord = coord.transform_to(EngineeringCameraFrame(n_mirrors=2)) assert eng_coord.x == coord.y assert eng_coord.y == -coord.x back = eng_coord.transform_to(CameraFrame()) assert back.x == coord.x assert back.y == coord.y
def camera_to_horizontal(x, y, az_pointing, alt_pointing, focal_length): hf = AltAz() pointing = SkyCoord( alt=alt_pointing.values * u.rad, az=az_pointing.values * u.rad, frame=hf, ) # cf = CameraFrame( # focal_length=focal_length.values*u.m, # telescope_pointing=pointing, # ) cf = EngineeringCameraFrame( n_mirrors=2, #location=LOCATION, #obstime=obstime, focal_length=focal_length.values * u.m, telescope_pointing=pointing, ) altaz_coord = SkyCoord(x=x.values * u.m, y=y.values * u.m, frame=cf) altaz_coord = altaz_coord.transform_to(hf) return altaz_coord.alt.to(u.rad).value, altaz_coord.az.to(u.rad).value
def horizontal_to_camera(az, alt, az_pointing, alt_pointing, focal_length): hf = AltAz() pointing = SkyCoord( alt=alt_pointing.values * u.rad, az=az_pointing.values * u.rad, frame=hf, ) # cf = CameraFrame( # focal_length=focal_length.values*u.m, # telescope_pointing=pointing, # ) cf = EngineeringCameraFrame( n_mirrors=2, #location=LOCATION, #obstime=obstime, focal_length=focal_length.values * u.m, telescope_pointing=pointing, ) xy_coord = SkyCoord(az=az.values * u.rad, alt=alt.values * u.rad, frame=hf) xy_coord = xy_coord.transform_to(cf) return xy_coord.x.to(u.m).value, xy_coord.y.to(u.m).value
def configure(self, config): config["pix_pos"] = self.pix_pos config["fov"] = self.fov td = config["time_step"] n_frames = config["n_frames"] # precomputing transformations # Will need to do this smarter (in chunks) when the number of frames reaches 10k-100k self.obstimes = np.array( [config["start_time"] + td * i for i in range(n_frames)]) self.precomp_hf = AltAz(location=self.location, obstime=self.obstimes) if isinstance(self.target, SkyCoord): self.precomp_point = self.target.transform_to(self.precomp_hf) else: alt, az = self.target n = len(self.obstimes) self.precomp_point = SkyCoord( alt=alt * np.ones(n), az=az * np.ones(n), frame=self.precomp_hf, ) self.precomp_camf = EngineeringCameraFrame( n_mirrors=2, telescope_pointing=self.precomp_point, focal_length=u.Quantity(self.focal_length, u.m), # 28 for LST obstime=self.obstimes, location=self.location, ) config["start_pointing"] = self.precomp_point[0]
def test_camera_coordinate_transform(camera_name): """test conversion of the coordinates stored in a camera frame""" from ctapipe.coordinates import EngineeringCameraFrame, CameraFrame, TelescopeFrame geom = CameraGeometry.from_name(camera_name) trans_geom = geom.transform_to(EngineeringCameraFrame()) unit = geom.pix_x.unit assert np.allclose(geom.pix_x.to_value(unit), -trans_geom.pix_y.to_value(unit)) assert np.allclose(geom.pix_y.to_value(unit), -trans_geom.pix_x.to_value(unit)) # also test converting into a spherical frame: focal_length = 1.2 * u.m geom.frame = CameraFrame(focal_length=focal_length) telescope_frame = TelescopeFrame() sky_geom = geom.transform_to(telescope_frame) x = sky_geom.pix_x.to_value(u.deg) assert len(x) == len(geom.pix_x) # and test going backward from spherical to cartesian: geom_cam = sky_geom.transform_to(CameraFrame(focal_length=focal_length)) assert np.allclose(geom_cam.pix_x.to_value(unit), geom.pix_x.to_value(unit))
def test_camera_coordinate_transform(camera_name): '''test conversion of the coordinates stored in a camera frame''' from ctapipe.coordinates import EngineeringCameraFrame geom = CameraGeometry.from_name(camera_name) trans_geom = geom.transform_to(EngineeringCameraFrame()) unit = geom.pix_x.unit assert np.allclose(geom.pix_x.to_value(unit), -trans_geom.pix_y.to_value(unit)) assert np.allclose(geom.pix_y.to_value(unit), -trans_geom.pix_x.to_value(unit))
def main(): fig, axs = plt.subplots(1, 2, constrained_layout=True, figsize=(6, 3)) model = Gaussian(0 * u.m, 0.1 * u.m, 0.3 * u.m, 0.05 * u.m, 25 * u.deg) cam = CameraGeometry.from_name('FlashCam') image, *_ = model.generate_image(cam, 2500) CameraDisplay(cam, ax=axs[0], image=image) CameraDisplay( cam.transform_to(EngineeringCameraFrame()), ax=axs[1], image=image, ) axs[0].set_title('CameraFrame') axs[1].set_title('EngineeringCameraFrame') plt.show()
def get_ctapipe_camera_geometry(mapping): """ Obtain a ctapipe CameraGeometry object from the CHECLabPy Mapping object. Pixel coordinates are converted into degrees using the plate scale. Parameters ---------- mapping : `pandas.DataFrame` The mapping for the pixels stored in a pandas DataFrame. Can be obtained from either of these options: CHECLabPy.io.TIOReader.mapping CHECLabPy.io.ReaderR0.mapping CHECLabPy.io.ReaderR1.mapping CHECLabPy.io.DL1Reader.mapping CHECLabPy.utils.mapping.get_clp_mapping_from_tc_mapping Returns ------- geom : `ctapipe.instrument.camera.CameraGeometry` """ from ctapipe.instrument import CameraGeometry from ctapipe.coordinates import EngineeringCameraFrame from astropy import units as u pix_x = mapping['xpix'].values pix_y = mapping['ypix'].values camera = CameraGeometry( "CHEC", pix_id=np.arange(mapping.metadata['n_pixels']), pix_x=pix_x * u.m, pix_y=pix_y * u.m, pix_area=None, pix_type='rectangular', frame=EngineeringCameraFrame(n_mirrors=2), sampling_rate=u.Quantity(1, u.GHz), ) return camera
def generate_hotspots( alt, az, altaz_frame, stars_pos, star_cat, pixsize, vmag_lim, pos ): telescope_pointing = SkyCoord(alt=alt, az=az, frame=altaz_frame) fov_mask = telescope_pointing.separation(stars_pos).deg < 5 sind = np.argsort(star_cat.vmag.values[fov_mask]) focal_length = u.Quantity(2.15191, u.m) engineering_frame = EngineeringCameraFrame( n_mirrors=2, location=telescope_pointing.location, obstime=telescope_pointing.obstime, focal_length=focal_length, telescope_pointing=telescope_pointing, ) hotspots = [] in_cat_stars = [] hips = [] for i, star in enumerate(stars_pos[fov_mask][sind]): star_en = star.transform_to(engineering_frame) p = np.array([star_en.x.value, star_en.y.value]) if np.any( np.linalg.norm((pos - np.outer(p, np.ones(2048))).T, axis=1) < pixsize * 1.1 ): for h in hotspots: if np.linalg.norm(np.array(h) - p) > pixsize * 4: continue hotspots.append((star_en.x.value, star_en.y.value)) hip = (i, star_cat.hip_number.values[fov_mask][sind][i]) hips.append(hip) # print(hip, i) if star_cat.vmag.values[fov_mask][sind][i] < vmag_lim: in_cat_stars.append(hip) if len(in_cat_stars) == 0: print("no star in catalog for fov") # print("number of stars in catalog for fov", len(in_cat_stars)) return hotspots, telescope_pointing, fov_mask, in_cat_stars, hips
def add_camera_position(df_pointing, source_skycoord): obstime = df_pointing.index.values alt = df_pointing['altitude_raw'].values az = df_pointing['azimuth_raw'].values altaz_frame = AltAz(location=LOCATION, obstime=obstime) telescope_pointing = SkyCoord( alt=alt, az=az, unit='rad', frame=altaz_frame, ) engineering_frame = EngineeringCameraFrame( n_mirrors=2, location=LOCATION, obstime=obstime, focal_length=FOCAL_LENGTH, telescope_pointing=telescope_pointing, ) source_cam = source_skycoord.transform_to(engineering_frame) x_src = source_cam.x.value y_src = source_cam.y.value df_pointing['x_src'] = x_src df_pointing['y_src'] = y_src
for pix, (p, noise) in zip((42, 314), pixels): ax.plot(x, p + 0.2 * noise, label=f'Pixel {pix}') ax.legend(loc=(0.5, 0.6), frameon=False) fig.savefig('build/calibrated.pdf') hillas = dict( x=80 * u.mm, y=20 * u.mm, width=15 * u.mm, length=50 * u.mm, psi=35 * u.deg, ) cam = CameraGeometry.from_name('FACT').transform_to(EngineeringCameraFrame()) longi, trans = camera_to_shower_coordinates(cam.pix_x, cam.pix_y, hillas['x'], hillas['y'], hillas['psi']) m = SkewedGaussian(**hillas, skewness=0.3) img, signal, noise = m.generate_image(cam, intensity=2500, nsb_level_pe=3) time_noise = np.random.uniform(0, 60, cam.n_pixels) time_image = 0.2 * longi.to_value(u.mm) + 25 time = np.average(np.column_stack([time_noise, time_image]), weights=np.column_stack([noise, signal]) + 1, axis=1) inferno = plt.get_cmap('inferno') inferno.set_bad('gray')
def plot_pedestals(data_file, pedestal_file, run=0, plot_file=None, tel_id=1, offset_value=400, sample_size=1000): """ plot pedestal quantities quantities Parameters ---------- data_file: pedestal run pedestal_file: file with drs4 corrections run: run number of data to be corrected plot_file: name of output pdf file tel_id: id of the telescope offset_value: baseline off_set """ config = { "LSTEventSource": { "allowed_tels": [1], "LSTR0Corrections": { "drs4_pedestal_path": pedestal_file, }, } } # event_reader reader = EventSource(data_file, config=Config(config), max_events=None) t = np.linspace(2, 37, 36) # configuration for the charge integrator charge_config = Config( { "FixedWindowSum": { "window_shift": 6, "window_width": 12, "peak_index": 18, } } ) # declare the pedestal component pedestal = PedestalIntegrator( tel_id=tel_id, time_sampling_correction_path=None, sample_size=sample_size, sample_duration=1000000, charge_median_cut_outliers=[-10, 10], charge_std_cut_outliers=[-10, 10], charge_product="FixedWindowSum", config=charge_config, subarray=reader.subarray, ) for i, event in enumerate(reader): if tel_id != event.trigger.tels_with_trigger[0]: raise Exception( f"Given wrong telescope id {tel_id}, files has id {event.trigger.tels_with_trigger[0]}" ) are_pedestals_calculated = pedestal.calculate_pedestals(event) if are_pedestals_calculated: ped_data = event.mon.tel[tel_id].pedestal break camera_geometry = reader.subarray.tels[tel_id].camera.geometry camera_geometry = camera_geometry.transform_to(EngineeringCameraFrame()) if are_pedestals_calculated and plot_file is not None: with PdfPages(plot_file) as pdf: plt.rc("font", size=15) # first figure fig = plt.figure(1, figsize=(12, 24)) plt.tight_layout() n_samples = charge_config["FixedWindowSum"]["window_width"] fig.suptitle(f"Run {run}, integration on {n_samples} samples", fontsize=25) pad = 420 image = ped_data.charge_median mask = ped_data.charge_median_outliers for chan in np.arange(2): pad += 1 plt.subplot(pad) plt.tight_layout() disp = CameraDisplay(camera_geometry) mymin = np.median(image[chan]) - 2 * np.std(image[chan]) mymax = np.median(image[chan]) + 2 * np.std(image[chan]) disp.set_limits_minmax(mymin, mymax) disp.highlight_pixels(mask[chan], linewidth=2) disp.image = image[chan] disp.cmap = plt.cm.coolwarm # disp.axes.text(lposx, 0, f'{channel[chan]} pedestal [ADC]', rotation=90) plt.title(f"{channel[chan]} pedestal [ADC]") disp.add_colorbar() image = ped_data.charge_std mask = ped_data.charge_std_outliers for chan in np.arange(2): pad += 1 plt.subplot(pad) plt.tight_layout() disp = CameraDisplay(camera_geometry) mymin = np.median(image[chan]) - 2 * np.std(image[chan]) mymax = np.median(image[chan]) + 2 * np.std(image[chan]) disp.set_limits_minmax(mymin, mymax) disp.highlight_pixels(mask[chan], linewidth=2) disp.image = image[chan] disp.cmap = plt.cm.coolwarm # disp.axes.text(lposx, 0, f'{channel[chan]} pedestal std [ADC]', rotation=90) plt.title(f"{channel[chan]} pedestal std [ADC]") disp.add_colorbar() # histograms for chan in np.arange(2): mean_ped = ped_data.charge_mean[chan] ped_std = ped_data.charge_std[chan] # select good pixels select = np.logical_not(mask[chan]) # fig.suptitle(f"Run {run} channel: {channel[chan]}", fontsize=25) pad += 1 # pedestal charge plt.subplot(pad) plt.tight_layout() plt.ylabel("pixels") plt.xlabel(f"{channel[chan]} pedestal") median = np.median(mean_ped[select]) rms = np.std(mean_ped[select]) label = f"{channel[chan]} Median {median:3.2f}, std {rms:3.2f}" plt.hist(mean_ped[select], bins=50, label=label) plt.legend() pad += 1 # pedestal std plt.subplot(pad) plt.ylabel("pixels") plt.xlabel(f"{channel[chan]} pedestal std") median = np.median(ped_std[select]) rms = np.std(ped_std[select]) label = f" Median {median:3.2f}, std {rms:3.2f}" plt.hist(ped_std[select], bins=50, label=label) plt.legend() plt.subplots_adjust(top=0.94, bottom=0.04, right=0.96) pdf.savefig() plt.close() # event_reader # reader = EventSource(data_file, config=Config(config), max_events=1000) pix = 0 pad = 420 offset_value = reader.r0_r1_calibrator.offset.tel[tel_id] # plot corrected waveforms of first 8 events for i, ev in enumerate(reader): for chan in np.arange(2): if pad == 420: # new figure fig = plt.figure(ev.index.event_id * 1000, figsize=(12, 24)) fig.suptitle(f"Run {run}, pixel {pix}", fontsize=25) plt.tight_layout() pad += 1 plt.subplot(pad) # remove samples at beginning / end of waveform start = reader.r0_r1_calibrator.r1_sample_start.tel[tel_id] end = reader.r0_r1_calibrator.r1_sample_end.tel[tel_id] plt.subplots_adjust(top=0.92) label = f"event {ev.index.event_id}, {channel[chan]}: R0" plt.step( t, ev.r0.tel[tel_id].waveform[chan, pix, start:end], color="blue", label=label, ) label = "baseline correction \n + dt corr + interp. spikes" plt.step( t, ev.r1.tel[tel_id].waveform[chan, pix] + offset_value, alpha=0.5, color="green", label=label, ) plt.plot([0, 40], [offset_value, offset_value], "k--", label="offset") plt.xlabel("time sample [ns]") plt.ylabel("counts [ADC]") plt.legend() plt.ylim(200, 600) if pad == 428: pad = 420 plt.subplots_adjust(top=0.92) pdf.savefig() plt.close() if i == 8: break elif not are_pedestals_calculated: log.error("Not able to calculate pedestals or output pdf file not especified.") elif plot_file is None: log.warning("Not PDF outputfile specified.")
def finish(self): """ write fit results in h5 file and the check-plots in pdf file """ gain = np.ma.array(self.fit_parameters.T[0], mask=self.fit_error.T) quadratic_term = np.ma.array(self.fit_parameters.T[1], mask=self.fit_error.T) # give to the badly fitted pixel a median value for the B term median_quadratic_term = np.ma.median(quadratic_term, axis=0) fill_array = np.ones((constants.N_PIXELS, constants.N_GAINS)) * median_quadratic_term quadratic_term_corrected = np.ma.filled(quadratic_term, fill_array) with h5py.File(self.output_path, 'w') as hf: hf.create_dataset('gain', data=gain.T) hf.create_dataset('B_term', data=quadratic_term_corrected.T) hf.create_dataset('covariance_matrix', data=self.fit_cov_matrix) hf.create_dataset('bad_fit_mask', data=self.fit_error) # remember the camera median and the variance per run channel = ["HG", "LG"] for chan in [0, 1]: if self.signal[chan] is not None: hf.create_dataset(f'median_signal_{channel[chan]}', data=np.median(self.signal[chan], axis=0)) hf.create_dataset(f'median_variance_{channel[chan]}', data=np.median(self.variance[chan], axis=0)) hf.create_dataset(f'runs_{channel[chan]}', data=self.selected_runs[chan]) hf.create_dataset('runs', data=self.run_list) hf.create_dataset('sub_run', data=self.sub_run) # plot open pdf with PdfPages(self.plot_path) as pdf: plt.rc("font", size=15) for chan in self.gain_channels: # plot the used runs and their median camera charge fig = plt.figure((chan + 1), figsize=(8, 20)) fig.suptitle(f"{channel[chan]} channel", fontsize=25) ax = plt.subplot(2, 1, 1) ax.grid(True) ax.yaxis.set_major_locator(MaxNLocator(integer=True)) ax.xaxis.set_major_locator(MaxNLocator(integer=True)) ax.yaxis.set_major_locator(plt.MultipleLocator(1)) plt.plot(np.median(self.signal[chan], axis=0), self.selected_runs[chan], "o") plt.xlabel(r'$\mathrm{\overline{Q}-\overline{ped}}$ [ADC]') plt.ylabel(r'Runs used in the fit') plt.subplot(2, 1, 2) camera = load_camera_geometry() camera = camera.transform_to(EngineeringCameraFrame()) disp = CameraDisplay(camera) image = self.fit_parameters.T[1].T * 100 mymin = np.median(image[chan]) - 3 * np.std(image[chan]) mymax = np.median(image[chan]) + 3 * np.std(image[chan]) disp.set_limits_minmax(mymin, mymax) mask = np.where(self.fit_error[chan] == 1)[0] disp.highlight_pixels(mask, linewidth=2.5, color="green") disp.image = image[chan] disp.cmap = plt.cm.coolwarm plt.title(f"{channel[chan]} Fitted B values [%]") disp.add_colorbar() plt.tight_layout() pdf.savefig() # plot the fit results and residuals for four arbitrary pixels fig = plt.figure((chan + 1) * 10, figsize=(11, 22)) fig.suptitle(f"{channel[chan]} channel", fontsize=25) pad = 0 for pix in [0, 600, 1200, 1800]: pad += 1 plt.subplot(4, 2, pad) plt.grid(which='minor') mask = self.unusable_pixels[chan][pix] sig = np.ma.array(self.signal[chan][pix], mask=mask).compressed() var = np.ma.array(self.variance[chan][pix], mask=mask).compressed() popt = self.fit_parameters[chan, pix] # plot points plt.plot(sig, var, 'o', color="C0") # plot fit min_x = min(1000, np.min(sig) * 0.9) max_x = max(10000, np.max(sig) * 1.1) x = np.arange(np.min(sig), np.max(sig)) plt.plot(x, quadratic_fit(x, *popt), '--', color="C1", label=f'Pixel {pix}:\ng={popt[0]:5.2f} [ADC/pe] , B={popt[1]:5.3f}') plt.xlim(min_x, max_x) plt.xlabel('Q-ped [ADC]') plt.ylabel(r'$\mathrm{\sigma_Q^2-\sigma_{ped}^2}$ [$ADC^2$]') plt.xscale('log') plt.yscale('log') plt.legend() # plot residuals pad += 1 plt.subplot(4, 2, pad) plt.grid(which='both', axis='both') popt = self.fit_parameters[chan, pix] plt.plot(sig, (quadratic_fit(sig, *popt) - var) / var * 100, 'o', color="C0") plt.xlim(min_x, max_x) plt.xscale('log') plt.ylabel('fit residuals %') plt.xlabel('Q-ped [ADC]') plt.hlines(0, 0, np.max(sig), linestyle='dashed', color="black") plt.tight_layout() pdf.savefig()
def plot_all(ped_data, ff_data, calib_data, run=0, plot_file="none"): """ plot camera calibration quantities Parameters ---------- ped_data: pedestal container PedestalContainer() ff_data: flat-field container FlatFieldContainer() calib_data: calibration container WaveformCalibrationContainer() """ # read geometry camera = load_camera_geometry() camera = camera.transform_to(EngineeringCameraFrame()) # plot open pdf if plot_file != "none": pp = PdfPages(plot_file) plt.rc('font', size=15) ### first figure fig = plt.figure(1, figsize=(12, 24)) plt.tight_layout() fig.suptitle(f"Run {run}", fontsize=25) pad = 420 image = ff_data.charge_median mask = ff_data.charge_median_outliers for chan in (np.arange(2)): pad += 1 plt.subplot(pad) plt.tight_layout() disp = CameraDisplay(camera) mymin = np.median(image[chan]) - 2 * np.std(image[chan]) mymax = np.median(image[chan]) + 2 * np.std(image[chan]) disp.set_limits_minmax(mymin, mymax) disp.highlight_pixels(mask[chan], linewidth=2) disp.image = image[chan] disp.cmap = plt.cm.coolwarm #disp.axes.text(lposx, 0, f'{channel[chan]} signal charge (ADC)', rotation=90) plt.title(f'{channel[chan]} signal charge [ADC]') disp.add_colorbar() image = ff_data.charge_std mask = ff_data.charge_std_outliers for chan in (np.arange(2)): pad += 1 plt.subplot(pad) plt.tight_layout() disp = CameraDisplay(camera) mymin = np.median(image[chan]) - 2 * np.std(image[chan]) mymax = np.median(image[chan]) + 2 * np.std(image[chan]) disp.set_limits_minmax(mymin, mymax) disp.highlight_pixels(mask[chan], linewidth=2) disp.image = image[chan] disp.cmap = plt.cm.coolwarm #disp.axes.text(lposx, 0, f'{channel[chan]} signal std [ADC]', rotation=90) plt.title(f'{channel[chan]} signal std [ADC]') disp.add_colorbar() image = ped_data.charge_median mask = ped_data.charge_median_outliers for chan in (np.arange(2)): pad += 1 plt.subplot(pad) plt.tight_layout() disp = CameraDisplay(camera) mymin = np.median(image[chan]) - 2 * np.std(image[chan]) mymax = np.median(image[chan]) + 2 * np.std(image[chan]) disp.set_limits_minmax(mymin, mymax) disp.highlight_pixels(mask[chan], linewidth=2) disp.image = image[chan] disp.cmap = plt.cm.coolwarm #disp.axes.text(lposx, 0, f'{channel[chan]} pedestal [ADC]', rotation=90) plt.title(f'{channel[chan]} pedestal [ADC]') disp.add_colorbar() image = ped_data.charge_std mask = ped_data.charge_std_outliers for chan in (np.arange(2)): pad += 1 plt.subplot(pad) plt.tight_layout() disp = CameraDisplay(camera) mymin = np.median(image[chan]) - 2 * np.std(image[chan]) mymax = np.median(image[chan]) + 2 * np.std(image[chan]) disp.set_limits_minmax(mymin, mymax) disp.highlight_pixels(mask[chan], linewidth=2) disp.image = image[chan] disp.cmap = plt.cm.coolwarm #disp.axes.text(lposx, 0, f'{channel[chan]} pedestal std [ADC]', rotation=90) plt.title(f'{channel[chan]} pedestal std [ADC]') disp.add_colorbar() plt.subplots_adjust(top=0.92) if plot_file != "none": pp.savefig() ### second figure fig = plt.figure(2, figsize=(12, 24)) plt.tight_layout() fig.suptitle(f"Run {run}", fontsize=25) pad=420 # time image = ff_data.time_median mask = ff_data.time_median_outliers for chan in (np.arange(2)): pad += 1 plt.subplot(pad) plt.tight_layout() disp = CameraDisplay(camera) disp.highlight_pixels(mask[chan], linewidth=2) disp.image = image[chan] disp.cmap = plt.cm.coolwarm #disp.axes.text(lposx, 0, f'{channel[chan]} time', rotation=90) plt.title(f'{channel[chan]} time') disp.add_colorbar() image = ff_data.relative_gain_median mask = calib_data.unusable_pixels for chan in (np.arange(2)): pad += 1 plt.subplot(pad) plt.tight_layout() disp = CameraDisplay(camera) disp.highlight_pixels(mask[chan], linewidth=2) mymin = np.median(image[chan]) - 2 * np.std(image[chan]) mymax = np.median(image[chan]) + 2 * np.std(image[chan]) disp.set_limits_minmax(mymin, mymax) disp.image = image[chan] disp.cmap = plt.cm.coolwarm disp.set_limits_minmax(0.7, 1.3) plt.title(f'{channel[chan]} relative signal') #disp.axes.text(lposx, 0, f'{channel[chan]} relative gain', rotation=90) disp.add_colorbar() # pe image = calib_data.n_pe mask = calib_data.unusable_pixels image = np.where(np.isnan(image), 0, image) for chan in (np.arange(2)): pad += 1 plt.subplot(pad) plt.tight_layout() disp = CameraDisplay(camera) disp.highlight_pixels(mask[chan], linewidth=2) disp.image = image[chan] mymin= np.median(image[chan])- 2*np.std(image[chan]) mymax= np.median(image[chan])+ 2*np.std(image[chan]) disp.set_limits_minmax(mymin, mymax) disp.cmap = plt.cm.coolwarm plt.title(f'{channel[chan]} photon-electrons') #disp.axes.text(lposx, 0, f'{channel[chan]} photon-electrons', rotation=90) disp.add_colorbar() # pe histogram pad += 1 plt.subplot(pad) plt.tight_layout() for chan in np.arange(2): n_pe = calib_data.n_pe[chan] # select good pixels select = np.logical_not(mask[chan]) median = int(np.median(n_pe[select])) rms = np.std(n_pe[select]) mymin= median - 4*rms mymax= median + 4*rms label = f"{channel[chan]} Median {median:3.2f}, std {rms:5.2f}" plt.hist(n_pe[select], label=label, histtype='step', range=(mymin, mymax), bins=50, stacked=True, alpha=0.5, fill=True) plt.legend() plt.xlabel(f'pe', fontsize=20) plt.ylabel('pixels', fontsize=20) # pe scatter plot pad += 1 plt.subplot(pad) plt.tight_layout() HG = calib_data.n_pe[0] LG = calib_data.n_pe[1] HG = np.where(np.isnan(HG), 0, HG) LG = np.where(np.isnan(LG), 0, LG) mymin = np.median(LG) - 2 * np.std(LG) mymax = np.median(LG) + 2 * np.std(LG) plt.hist2d(LG, HG, bins=[100, 100]) plt.xlabel("LG", fontsize=20) plt.ylabel("HG", fontsize=20) x = np.arange(mymin,mymax) plt.plot(x, x) plt.ylim(mymin, mymax) plt.xlim(mymin, mymax) plt.subplots_adjust(top=0.92) if plot_file != "none": pp.savefig() ### figures 3 and 4 : histograms for chan in np.arange(2): n_pe = calib_data.n_pe[chan] gain_median = ff_data.relative_gain_median[chan] #charge_median = ff_data.charge_median[chan] charge_mean = ff_data.charge_mean[chan] charge_std = ff_data.charge_std[chan] #median_ped = ped_data.charge_median[chan] mean_ped = ped_data.charge_mean[chan] ped_std = ped_data.charge_std[chan] # select good pixels select = np.logical_not(mask[chan]) fig = plt.figure(chan+10, figsize=(12, 18)) fig.tight_layout(rect=[0, 0.0, 1, 0.95]) fig.suptitle(f"Run {run} channel: {channel[chan]}", fontsize=25) # charge plt.subplot(321) plt.tight_layout() median = int(np.median(charge_mean[select])) rms = np.std(charge_mean[select]) label=f"Median {median:3.2f}, std {rms:5.0f}" plt.xlabel('charge (ADC)', fontsize=20) plt.ylabel('pixels', fontsize=20) plt.hist(charge_mean[select], bins=50,label=label) plt.legend() plt.subplot(322) plt.tight_layout() plt.ylabel('pixels', fontsize=20) plt.xlabel('charge std', fontsize=20) median = np.median(charge_std[select]) rms = np.std(charge_std[select]) label=f"Median {median:3.2f}, std {rms:3.2f}" plt.hist(charge_std[select], bins=50,label=label) plt.legend() # pedestal charge plt.subplot(323) plt.tight_layout() plt.ylabel('pixels', fontsize=20) plt.xlabel('pedestal', fontsize=20) median = np.median(mean_ped[select]) rms = np.std(mean_ped[select]) label=f"Median {median:3.2f}, std {rms:3.2f}" plt.hist(mean_ped[select], bins=50,label=label) plt.legend() # pedestal std plt.subplot(324) plt.ylabel('pixels', fontsize=20) plt.xlabel('pedestal std', fontsize=20) median = np.median(ped_std[select]) rms = np.std(ped_std[select]) label=f"Median {median:3.2f}, std {rms:3.2f}" plt.hist(ped_std[select], bins=50,label=label) plt.legend() # relative gain plt.subplot(325) plt.tight_layout() plt.ylabel('pixels', fontsize=20) plt.xlabel('relative signal', fontsize=20) median = np.median(gain_median[select]) rms = np.std(gain_median[select]) label=f"Relative gain {median:3.2f}, std {rms:5.2f}" plt.hist(gain_median[select], bins=50,label=label) plt.legend() # photon electrons plt.subplot(326) plt.tight_layout() plt.ylabel('pixels', fontsize=20) plt.xlabel('pe', fontsize=20) median = np.median(n_pe[select]) rms = np.std(n_pe[select]) label=f"Median {median:3.2f}, std {rms:3.2f}" plt.hist(n_pe[select], bins=50,label=label) plt.legend() plt.subplots_adjust(top=0.92) if plot_file != "none": pp.savefig(plt.gcf()) if plot_file != "none": pp.close()
def plot_all(ped_data, ff_data, calib_data, run=0, plot_file=None): """ plot camera calibration quantities Parameters ---------- ped_data: pedestal container PedestalContainer() ff_data: flat-field container FlatFieldContainer() calib_data: calibration container WaveformCalibrationContainer() run: run number plot_file: name of the output PDF file. No file is produced if name is not provided """ # read geometry camera = load_camera_geometry() camera = camera.transform_to(EngineeringCameraFrame()) # plot open pdf if plot_file is not None: with PdfPages(plot_file) as pdf: plt.rc("font", size=15) # first figure fig = plt.figure(1, figsize=(12, 24)) plt.tight_layout() fig.suptitle(f"Run {run}", fontsize=25) pad = 420 image = ff_data.charge_median mask = ff_data.charge_median_outliers for chan in np.arange(2): pad += 1 plt.subplot(pad) plt.tight_layout() disp = CameraDisplay(camera) mymin = np.median(image[chan]) - 2 * np.std(image[chan]) mymax = np.median(image[chan]) + 2 * np.std(image[chan]) disp.set_limits_minmax(mymin, mymax) disp.highlight_pixels(mask[chan], linewidth=2) disp.image = image[chan] disp.cmap = plt.cm.coolwarm # disp.axes.text(lposx, 0, f'{channel[chan]} signal charge (ADC)', rotation=90) plt.title(f"{channel[chan]} signal charge [ADC]") disp.add_colorbar() image = ff_data.charge_std mask = ff_data.charge_std_outliers for chan in np.arange(2): pad += 1 plt.subplot(pad) plt.tight_layout() disp = CameraDisplay(camera) mymin = np.median(image[chan]) - 2 * np.std(image[chan]) mymax = np.median(image[chan]) + 2 * np.std(image[chan]) disp.set_limits_minmax(mymin, mymax) disp.highlight_pixels(mask[chan], linewidth=2) disp.image = image[chan] disp.cmap = plt.cm.coolwarm # disp.axes.text(lposx, 0, f'{channel[chan]} signal std [ADC]', rotation=90) plt.title(f"{channel[chan]} signal std [ADC]") disp.add_colorbar() image = ped_data.charge_median mask = ped_data.charge_median_outliers for chan in np.arange(2): pad += 1 plt.subplot(pad) plt.tight_layout() disp = CameraDisplay(camera) mymin = np.median(image[chan]) - 2 * np.std(image[chan]) mymax = np.median(image[chan]) + 2 * np.std(image[chan]) disp.set_limits_minmax(mymin, mymax) disp.highlight_pixels(mask[chan], linewidth=2) disp.image = image[chan] disp.cmap = plt.cm.coolwarm # disp.axes.text(lposx, 0, f'{channel[chan]} pedestal [ADC]', rotation=90) plt.title(f"{channel[chan]} pedestal [ADC]") disp.add_colorbar() image = ped_data.charge_std mask = ped_data.charge_std_outliers for chan in np.arange(2): pad += 1 plt.subplot(pad) plt.tight_layout() disp = CameraDisplay(camera) mymin = np.median(image[chan]) - 2 * np.std(image[chan]) mymax = np.median(image[chan]) + 2 * np.std(image[chan]) disp.set_limits_minmax(mymin, mymax) disp.highlight_pixels(mask[chan], linewidth=2) disp.image = image[chan] disp.cmap = plt.cm.coolwarm # disp.axes.text(lposx, 0, f'{channel[chan]} pedestal std [ADC]', rotation=90) plt.title(f"{channel[chan]} pedestal std [ADC]") disp.add_colorbar() plt.subplots_adjust(top=0.92) pdf.savefig() plt.close() # second figure fig = plt.figure(2, figsize=(12, 24)) plt.tight_layout() fig.suptitle(f"Run {run}", fontsize=25) pad = 420 # time image = ff_data.time_median mask = ff_data.time_median_outliers for chan in np.arange(2): pad += 1 plt.subplot(pad) plt.tight_layout() disp = CameraDisplay(camera) disp.highlight_pixels(mask[chan], linewidth=2) disp.image = image[chan] disp.cmap = plt.cm.coolwarm # disp.axes.text(lposx, 0, f'{channel[chan]} time', rotation=90) plt.title(f"{channel[chan]} time") disp.add_colorbar() image = ff_data.relative_gain_median mask = calib_data.unusable_pixels for chan in np.arange(2): pad += 1 plt.subplot(pad) plt.tight_layout() disp = CameraDisplay(camera) disp.highlight_pixels(mask[chan], linewidth=2) mymin = np.median(image[chan]) - 2 * np.std(image[chan]) mymax = np.median(image[chan]) + 2 * np.std(image[chan]) disp.set_limits_minmax(mymin, mymax) disp.image = image[chan] disp.cmap = plt.cm.coolwarm disp.set_limits_minmax(0.7, 1.3) plt.title(f"{channel[chan]} relative signal") # disp.axes.text(lposx, 0, f'{channel[chan]} relative gain', rotation=90) disp.add_colorbar() # pe image = calib_data.n_pe mask = calib_data.unusable_pixels image = np.where(np.isnan(image), 0, image) for chan in np.arange(2): pad += 1 plt.subplot(pad) plt.tight_layout() disp = CameraDisplay(camera) disp.highlight_pixels(mask[chan], linewidth=2) disp.image = image[chan] mymin = np.median(image[chan]) - 2 * np.std(image[chan]) mymax = np.median(image[chan]) + 2 * np.std(image[chan]) disp.set_limits_minmax(mymin, mymax) disp.cmap = plt.cm.coolwarm plt.title(f"{channel[chan]} photon-electrons") # disp.axes.text(lposx, 0, f'{channel[chan]} photon-electrons', rotation=90) disp.add_colorbar() # pe histogram pad += 1 plt.subplot(pad) plt.tight_layout() for chan in np.arange(2): n_pe = calib_data.n_pe[chan] # select good pixels select = np.logical_not(mask[chan]) median = int(np.median(n_pe[select])) rms = np.std(n_pe[select]) mymin = median - 4 * rms mymax = median + 4 * rms label = f"{channel[chan]} Median {median:3.2f}, std {rms:5.2f}" plt.hist( n_pe[select], label=label, histtype="step", range=(mymin, mymax), bins=50, stacked=True, alpha=0.5, fill=True, ) plt.legend() plt.xlabel("pe", fontsize=20) plt.ylabel("pixels", fontsize=20) # pe scatter plot pad += 1 plt.subplot(pad) plt.tight_layout() HG = calib_data.n_pe[0] LG = calib_data.n_pe[1] HG = np.where(np.isnan(HG), 0, HG) LG = np.where(np.isnan(LG), 0, LG) mymin = np.median(LG) - 2 * np.std(LG) mymax = np.median(LG) + 2 * np.std(LG) plt.hist2d(LG, HG, bins=[100, 100]) plt.xlabel("LG", fontsize=20) plt.ylabel("HG", fontsize=20) x = np.arange(mymin, mymax) plt.plot(x, x) plt.ylim(mymin, mymax) plt.xlim(mymin, mymax) plt.subplots_adjust(top=0.92) pdf.savefig() plt.close() # figures 3 and 4: histograms for chan in np.arange(2): n_pe = calib_data.n_pe[chan] gain_median = ff_data.relative_gain_median[chan] charge_median = ff_data.charge_median[chan] #charge_mean = ff_data.charge_mean[chan] charge_std = ff_data.charge_std[chan] n_ff = ff_data.n_events median_ped = ped_data.charge_median[chan] #mean_ped = ped_data.charge_mean[chan] ped_std = ped_data.charge_std[chan] n_ped = ped_data.n_events dc_to_pe = calib_data.dc_to_pe[chan] time_correction = calib_data.time_correction[chan] # select good pixels select = np.logical_not(mask[chan]) fig = plt.figure(chan + 10, figsize=(12, 24)) fig.tight_layout(rect=[0, 0.0, 1, 0.95]) fig.suptitle(f"Run {run} channel: {channel[chan]}", fontsize=25) # charge plt.subplot(421) plt.title(f"FF sample of {n_ff} events") plt.tight_layout() median = int(np.median(charge_median[select])) rms = np.std(charge_median[select]) label = f"Median {median:3.2f}, std {rms:5.0f}" plt.xlabel("charge (ADC)", fontsize=20) plt.ylabel("pixels", fontsize=20) plt.hist(charge_median[select], bins=50, label=label) plt.legend() plt.subplot(422) plt.tight_layout() plt.ylabel("pixels", fontsize=20) plt.xlabel("charge std", fontsize=20) median = np.median(charge_std[select]) rms = np.std(charge_std[select]) label = f"Median {median:3.2f}, std {rms:3.2f}" plt.hist(charge_std[select], bins=50, label=label) plt.legend() # pedestal charge plt.subplot(423) plt.tight_layout() plt.title(f"pedestal sample of {n_ped} events") plt.ylabel("pixels", fontsize=20) plt.xlabel("pedestal", fontsize=20) median = np.median(median_ped[select]) rms = np.std(median_ped[select]) label = f"Median {median:3.2f}, std {rms:3.2f}" plt.hist(median_ped[select], bins=50, label=label) plt.legend() # pedestal std plt.subplot(424) plt.ylabel("pixels", fontsize=20) plt.xlabel("pedestal std", fontsize=20) median = np.median(ped_std[select]) rms = np.std(ped_std[select]) label = f"Median {median:3.2f}, std {rms:3.2f}" plt.hist(ped_std[select], bins=50, label=label) plt.legend() # relative gain plt.subplot(425) plt.tight_layout() plt.ylabel("pixels", fontsize=20) plt.xlabel("relative signal", fontsize=20) median = np.median(gain_median[select]) rms = np.std(gain_median[select]) label = f"Relative gain {median:3.2f}, std {rms:5.2f}" plt.hist(gain_median[select], bins=50, label=label) plt.legend() # photon electrons plt.subplot(426) plt.tight_layout() plt.ylabel("pixels", fontsize=20) plt.xlabel("time corrections [ns]", fontsize=20) median = np.median(time_correction[select]) rms = np.std(time_correction[select]) label = f"Median {median:3.2f}, std {rms:3.2f}" plt.hist(time_correction[select].value, bins=50, label=label) plt.legend() plt.subplots_adjust(top=0.92) # photon electrons plt.subplot(427) plt.tight_layout() plt.ylabel("pixels", fontsize=20) plt.xlabel("pe", fontsize=20) median = np.median(n_pe[select]) rms = np.std(n_pe[select]) label = f"Median {median:3.2f}, std {rms:3.2f}" plt.hist(n_pe[select], bins=50, label=label) plt.legend() plt.subplots_adjust(top=0.92) # gain plt.subplot(428) plt.tight_layout() plt.ylabel("pixels", fontsize=20) plt.xlabel("flat-fielded gain [ADC/pe]", fontsize=20) denominator = dc_to_pe[select] numerator = 1. gain = np.divide(numerator, denominator, out=np.zeros_like(denominator), where=denominator != 0) median = np.median(gain) rms = np.std(gain) label = f"Median {median:3.2f}, std {rms:3.2f}" plt.hist(gain, bins=50, label=label) plt.legend() plt.subplots_adjust(top=0.92) pdf.savefig(plt.gcf()) plt.close()
def __init__(self, path, max_events=None): """ Reads simtelarray files utilising the SimTelEventSource from ctapipe Parameters ---------- path : str Path to the simtel file max_events : int Maximum number of events to read from the file """ super().__init__(path, max_events) try: from ctapipe.io import SimTelEventSource, EventSeeker from ctapipe.coordinates import EngineeringCameraFrame except ModuleNotFoundError: msg = "Cannot find ctapipe installation" raise ModuleNotFoundError(msg) try: from target_calib import CameraConfiguration except ModuleNotFoundError: msg = ("Cannot find TARGET libraries, please follow installation " "instructions from https://forge.in2p3.fr/projects/gct/" "wiki/Installing_CHEC_Software") raise ModuleNotFoundError(msg) self.path = path reader = SimTelEventSource(input_url=path, max_events=max_events, back_seekable=True) self.seeker = EventSeeker(reader) first_event = self.seeker[0] tels = list(first_event.r0.tels_with_data) self.tel = tels[0] shape = first_event.r0.tel[self.tel].waveform.shape _, self.n_pixels, self.n_samples = shape self.n_modules = self.n_pixels // 64 n_modules = 32 camera_version = "1.1.0" self._camera_config = CameraConfiguration(camera_version) tc_mapping = self._camera_config.GetMapping(n_modules == 1) self.mapping = get_clp_mapping_from_tc_mapping(tc_mapping) n_rows = self.mapping.metadata['n_rows'] n_columns = self.mapping.metadata['n_columns'] camera_geom = first_event.inst.subarray.tel[tels[0]].camera engineering_frame = EngineeringCameraFrame(n_mirrors=2) engineering_geom = camera_geom.transform_to(engineering_frame) pix_x = engineering_geom.pix_x.value pix_y = engineering_geom.pix_y.value row, col = get_row_column(pix_x, pix_y) camera_2d = np.zeros((n_rows, n_columns), dtype=np.int) camera_2d[row, col] = np.arange(self.n_pixels, dtype=np.int) self.pixel_order = camera_2d[self.mapping['row'], self.mapping['col']] self.reference_pulse_path = self._camera_config.GetReferencePulsePath() self.camera_version = self._camera_config.GetVersion() self._iev = None self._t_cpu = None self.mc = None self.pointing = None self.mcheader = None
def plot(filename='longterm_dl1_check.h5'): # First read in the camera geometry: cam_description_table = \ Table.read(filename, path='instrument/telescope/camera/LSTCam') camgeom = CameraGeometry.from_table(cam_description_table) engineering_geom = camgeom.transform_to(EngineeringCameraFrame()) file = tables.open_file('longterm_dl1_check.h5') bokeh_output_file(Path(filename).with_suffix('.html'), title='LST1 long-term DL1 data check') run_titles = [] for i, run in enumerate(file.root.pixwise_runsummary.col('runnumber')): date = pd.to_datetime(file.root.pixwise_runsummary.col('time')[i], origin='unix', unit='s') run_titles.append('Run {0:05d}, {date}'.\ format(run, date = date.strftime("%b %d %Y %H:%M:%S"))) runsummary = pd.read_hdf(filename, 'runsummary') page0 = Panel() fig_ped_rates = show_graph( x=pd.to_datetime(runsummary['time'], origin='unix', unit='s'), y=runsummary['num_pedestals'] / runsummary['elapsed_time'], xlabel='date', ylabel='Interleaved pedestals rate', ey=np.sqrt(runsummary['num_pedestals']) / runsummary['elapsed_time'], xtype='datetime', ytype='linear', point_labels=run_titles) fig_ff_rates = show_graph( x=pd.to_datetime(runsummary['time'], origin='unix', unit='s'), y=runsummary['num_flatfield'] / runsummary['elapsed_time'], xlabel='date', ylabel='Interleaved flat field rate', ey=np.sqrt(runsummary['num_flatfield']) / runsummary['elapsed_time'], xtype='datetime', ytype='linear', point_labels=run_titles) fig_cosmic_rates = show_graph( x=pd.to_datetime(runsummary['time'], origin='unix', unit='s'), y=runsummary['num_cosmics'] / runsummary['elapsed_time'], xlabel='date', ylabel='Cosmics rate', ey=np.sqrt(runsummary['num_cosmics']) / runsummary['elapsed_time'], xtype='datetime', ytype='linear', point_labels=run_titles) fig_muring_rates = show_graph( x=pd.to_datetime(runsummary['time'], origin='unix', unit='s'), y=runsummary['num_contained_mu_rings'] / runsummary['elapsed_time'], xlabel='date', ylabel='Contained mu-rings rate', ey=np.sqrt(runsummary['num_contained_mu_rings']) / runsummary['elapsed_time'], xtype='datetime', ytype='linear', point_labels=run_titles) pad_width = 550 pad_height = 350 row1 = [fig_ped_rates, fig_ff_rates] row2 = [fig_cosmic_rates, fig_muring_rates] grid0 = gridplot([row1, row2], sizing_mode=None, plot_width=pad_width, plot_height=pad_height) page0.child = grid0 page0.title = 'Event rates' page0b = Panel() altmin = np.rad2deg(runsummary['min_altitude']) altmean = np.rad2deg(runsummary['mean_altitude']) altmax = np.rad2deg(runsummary['max_altitude']) fig_altitude = show_graph(x=pd.to_datetime(runsummary['time'], origin='unix', unit='s'), y=altmean, xlabel='date', ylabel='Telescope altitude (mean, min, max)', eylow=altmean - altmin, eyhigh=altmax - altmean, xtype='datetime', ytype='linear', point_labels=run_titles) fig_altitude.y_range = Range1d(altmin.min() * 0.95, altmax.max() * 1.05) row1 = [fig_altitude] grid0b = gridplot([row1], sizing_mode=None, plot_width=pad_width, plot_height=pad_height) page0b.child = grid0b page0b.title = 'Pointing' page1 = Panel() pad_width = 350 pad_height = 370 mean = [] stddev = [] for item in file.root.pixwise_runsummary.col('ped_pix_charge_mean'): mean.append(item) for item in file.root.pixwise_runsummary.col('ped_pix_charge_stddev'): stddev.append(item) row1 = show_camera(np.array(mean), engineering_geom, pad_width, pad_height, 'Pedestals mean charge', run_titles) row2 = show_camera(np.array(stddev), engineering_geom, pad_width, pad_height, 'Pedestals charge std dev', run_titles) grid1 = gridplot([row1, row2], sizing_mode=None, plot_width=pad_width, plot_height=pad_height) page1.child = grid1 page1.title = 'Interleaved pedestals' page2 = Panel() mean = [] stddev = [] for item in file.root.pixwise_runsummary.col('ff_pix_charge_mean'): mean.append(item) for item in file.root.pixwise_runsummary.col('ff_pix_charge_stddev'): stddev.append(item) row1 = show_camera(np.array(mean), engineering_geom, pad_width, pad_height, 'Flat-Field mean charge (pe)', run_titles) row2 = show_camera(np.array(stddev), engineering_geom, pad_width, pad_height, 'Flat-Field charge std dev (pe)', run_titles) grid2 = gridplot([row1, row2], sizing_mode=None, plot_width=pad_width, plot_height=pad_height) page2.child = grid2 page2.title = 'Interleaved flat field, charge' page3 = Panel() mean = [] stddev = [] for item in file.root.pixwise_runsummary.col('ff_pix_rel_time_mean'): mean.append(item) for item in file.root.pixwise_runsummary.col('ff_pix_rel_time_stddev'): stddev.append(item) row1 = show_camera(np.array(mean), engineering_geom, pad_width, pad_height, 'Flat-Field mean relative time (ns)', run_titles, showlog=False) row2 = show_camera(np.array(stddev), engineering_geom, pad_width, pad_height, 'Flat-Field rel. time std dev (ns)', run_titles, showlog=False) grid3 = gridplot([row1, row2], sizing_mode=None, plot_width=pad_width, plot_height=pad_height) page3.child = grid3 page3.title = 'Interleaved flat field, time' page4 = Panel() pulse_fraction_above_10 = [] pulse_fraction_above_30 = [] for item in file.root.pixwise_runsummary.col( 'cosmics_pix_fraction_pulses_above10'): pulse_fraction_above_10.append(item) for item in file.root.pixwise_runsummary.col( 'cosmics_pix_fraction_pulses_above30'): pulse_fraction_above_30.append(item) row1 = show_camera(np.array(pulse_fraction_above_10), engineering_geom, pad_width, pad_height, 'Cosmics, fraction of >10pe pulses', run_titles) row2 = show_camera(np.array(pulse_fraction_above_30), engineering_geom, pad_width, pad_height, 'Cosmics, fraction of >30pe pulses', run_titles) grid4 = gridplot([row1, row2], sizing_mode=None, plot_width=pad_width, plot_height=pad_height) page4.child = grid4 page4.title = 'Cosmics' file.close() page5 = Panel() pad_width = 550 pad_height = 280 fig_mu_effi = show_graph(x=pd.to_datetime(runsummary['time'], origin='unix', unit='s'), y=runsummary['mu_effi_mean'], xlabel='date', ylabel='telescope efficiency from mu-rings', ey=runsummary['mu_effi_stddev'] / np.sqrt(runsummary['num_contained_mu_rings']), xtype='datetime', ytype='linear', point_labels=run_titles) fig_mu_effi.y_range = Range1d(0., 1.1 * np.max(runsummary['mu_effi_mean'])) fig_mu_width = show_graph(x=pd.to_datetime(runsummary['time'], origin='unix', unit='s'), y=runsummary['mu_width_mean'], xlabel='date', ylabel='muon ring width (deg)', ey=runsummary['mu_width_stddev'] / np.sqrt(runsummary['num_contained_mu_rings']), xtype='datetime', ytype='linear', point_labels=run_titles) fig_mu_width.y_range = Range1d(0., 1.1 * np.max(runsummary['mu_width_mean'])) fig_mu_intensity = show_graph(x=pd.to_datetime(runsummary['time'], origin='unix', unit='s'), y=runsummary['mu_intensity_mean'], xlabel='date', ylabel='mean muon ring intensity (p.e.)', xtype='datetime', ytype='linear', point_labels=run_titles) fig_mu_intensity.y_range = \ Range1d(0., 1.1 * np.max(runsummary['mu_intensity_mean'])) fig_mu_hg_peak = show_graph(x=pd.to_datetime(runsummary['time'], origin='unix', unit='s'), y=runsummary['mu_hg_peak_sample_mean'], xlabel='date', ey=runsummary['mu_hg_peak_sample_stddev'], ylabel='HG global peak sample id (mean&RMS)', xtype='datetime', ytype='linear', point_labels=run_titles) fig_mu_hg_peak.y_range = Range1d(0., 38.) fig_mu_lg_peak = show_graph(x=pd.to_datetime(runsummary['time'], origin='unix', unit='s'), y=runsummary['mu_lg_peak_sample_mean'], xlabel='date', ey=runsummary['mu_lg_peak_sample_stddev'], ylabel='LG global peak sample id (mean&RMS)', xtype='datetime', ytype='linear', point_labels=run_titles) fig_mu_lg_peak.y_range = Range1d(0., 38.) row1 = [fig_mu_effi, fig_mu_width] row2 = [fig_mu_intensity] row3 = [fig_mu_hg_peak, fig_mu_lg_peak] grid5 = gridplot([row1, row2, row3], sizing_mode=None, plot_width=pad_width, plot_height=pad_height) page5.child = grid5 page5.title = "Muons" page6 = Panel() pad_width = 550 pad_height = 350 fig_ped = show_graph(x=pd.to_datetime(runsummary['time'], origin='unix', unit='s'), y=runsummary['ped_charge_mean'], xlabel='date', ylabel='Camera-averaged pedestal charge (pe/pixel)', ey=runsummary['ped_charge_mean_err'], xtype='datetime', ytype='linear', point_labels=run_titles) fig_ped.y_range = Range1d(0., 1.1 * np.max(runsummary['ped_charge_mean'])) fig_ped_stddev = show_graph(x=pd.to_datetime(runsummary['time'], origin='unix', unit='s'), y=runsummary['ped_charge_stddev'], xlabel='date', ylabel='Camera-averaged pedestal charge std ' 'dev (pe/pixel)', xtype='datetime', ytype='linear', point_labels=run_titles) fig_ped_stddev.y_range = \ Range1d(0.,1.1*np.max(runsummary['ped_charge_stddev'])) frac = runsummary['num_pedestals_after_cleaning'] / \ runsummary['num_pedestals'] err = np.sqrt(frac * (1 - frac) / runsummary['num_pedestals']) fig_ped_clean_fraction = show_graph( x=pd.to_datetime(runsummary['time'], origin='unix', unit='s'), y=frac, xlabel='date', ylabel='Fraction of pedestals surviving cleaning', ey=err, xtype='datetime', ytype='linear', point_labels=run_titles) row1 = [fig_ped, fig_ped_stddev] row2 = [fig_ped_clean_fraction] grid6 = gridplot([row1, row2], sizing_mode=None, plot_width=pad_width, plot_height=pad_height) page6.child = grid6 page6.title = "Interleaved pedestals, averages" page7 = Panel() pad_width = 550 pad_height = 280 fig_flatfield = show_graph(x=pd.to_datetime(runsummary['time'], origin='unix', unit='s'), y=runsummary['ff_charge_mean'], xlabel='date', ylabel='Cam-averaged FF Q (pe/pixel)', ey=runsummary['ff_charge_mean_err'], xtype='datetime', ytype='linear', point_labels=run_titles) fig_flatfield.y_range = Range1d(0., 1.1 * np.max(runsummary['ff_charge_mean'])) fig_ff_stddev = show_graph(x=pd.to_datetime(runsummary['time'], origin='unix', unit='s'), y=runsummary['ff_charge_stddev'], xlabel='date', ylabel='Cam-averaged FF Q std ' 'dev (pe/pixel)', xtype='datetime', ytype='linear', point_labels=run_titles) fig_ff_stddev.y_range = \ Range1d(0.,1.1*np.max(runsummary['ff_charge_stddev'])) fig_ff_time = show_graph(x=pd.to_datetime(runsummary['time'], origin='unix', unit='s'), y=runsummary['ff_time_mean'], xlabel='date', ylabel='Cam-averaged FF time (ns)', ey=runsummary['ff_time_mean_err'], xtype='datetime', ytype='linear', point_labels=run_titles) fig_ff_time_std = show_graph(x=pd.to_datetime(runsummary['time'], origin='unix', unit='s'), y=runsummary['ff_time_stddev'], xlabel='date', ylabel='Cam-averaged FF t std ' 'dev (ns)', xtype='datetime', ytype='linear', point_labels=run_titles) fig_ff_rel_time_std = show_graph(x=pd.to_datetime(runsummary['time'], origin='unix', unit='s'), y=runsummary['ff_rel_time_stddev'], xlabel='date', ylabel='Cam-averaged FF ' 'rel. pix t std dev (ns)', xtype='datetime', ytype='linear', point_labels=run_titles) fig_ff_rel_time_std.y_range = \ Range1d(0., np.max([1., runsummary['ff_rel_time_stddev'].max()])) row1 = [fig_flatfield, fig_ff_stddev] row2 = [fig_ff_time, fig_ff_time_std] row3 = [fig_ff_rel_time_std] grid7 = gridplot([row1, row2, row3], sizing_mode=None, plot_width=pad_width, plot_height=pad_height) page7.child = grid7 page7.title = "Interleaved FF, averages" tabs = Tabs( tabs=[page0, page0b, page1, page2, page3, page4, page5, page6, page7]) show(column(Div(text='<h1> Long-term DL1 data check </h1>'), tabs))
from ctapipe.visualization import CameraDisplay from ctapipe.instrument import CameraGeometry from ctapipe.coordinates import EngineeringCameraFrame from ctapipe.image.toymodel import SkewedGaussian import matplotlib.pyplot as plt import astropy.units as u import numpy as np np.random.seed(1337) geom = CameraGeometry.from_name('FACT') geom = geom.transform_to(EngineeringCameraFrame()) model = SkewedGaussian( width=0.01 * u.m, length=0.03 * u.m, x=0.14 * u.m, y=0.07 * u.m, skewness=0.05, psi=30 * u.deg, ) img, signal, noise = model.generate_image(geom, 1000, nsb_level_pe=2) fig = plt.figure(figsize=(5, 5)) ax = fig.add_axes([0, 0, 1, 1]) ax.set_xticks([]) ax.set_yticks([]) ax.set_xlabel('') ax.set_ylabel('') ax.set_axis_off() disp = CameraDisplay(geom, image=img, ax=ax, cmap='inferno')
def plot_pedestals(data_file, pedestal_file, run=0, plot_file="none", tel_id=1, offset_value=400): """ plot pedestal quantities quantities Parameters ---------- data_file: pedestal run pedestal_file: file with drs4 corrections run: run number of data to be corrected plot_file: name of output pdf file tel_id: id of the telescope offset_value: baseline off_set """ # plot open pdf if plot_file != "none": pp = PdfPages(plot_file) plt.rc('font', size=15) # r0 calibrator r0_calib = LSTR0Corrections(pedestal_path=pedestal_file, offset=offset_value, tel_id=tel_id) # event_reader reader = event_source(data_file, max_events=1000) t = np.linspace(2, 37, 36) # configuration for the charge integrator charge_config = Config( {"FixedWindowSum": { "window_start": 12, "window_width": 12, }}) # declare the pedestal component pedestal = PedestalIntegrator(tel_id=tel_id, sample_size=1000, sample_duration=1000000, charge_median_cut_outliers=[-10, 10], charge_std_cut_outliers=[-10, 10], charge_product="FixedWindowSum", config=charge_config, subarray=reader.subarray) for i, event in enumerate(reader): if tel_id != event.r0.tels_with_data[0]: raise Exception( f"Given wrong telescope id {tel_id}, files has id {event.r0.tels_with_data[0]}" ) # move from R0 to R1 r0_calib.calibrate(event) ok = pedestal.calculate_pedestals(event) if ok: ped_data = event.mon.tel[tel_id].pedestal break camera_geometry = reader.subarray.tels[tel_id].camera.geometry camera_geometry = camera_geometry.transform_to(EngineeringCameraFrame()) # plot open pdf if plot_file != "none": pp = PdfPages(plot_file) plt.rc('font', size=15) ### first figure fig = plt.figure(1, figsize=(12, 24)) plt.tight_layout() n_samples = charge_config["FixedWindowSum"]['window_width'] fig.suptitle(f"Run {run}, integration on {n_samples} samples", fontsize=25) pad = 420 image = ped_data.charge_median mask = ped_data.charge_median_outliers for chan in (np.arange(2)): pad += 1 plt.subplot(pad) plt.tight_layout() disp = CameraDisplay(camera_geometry) mymin = np.median(image[chan]) - 2 * np.std(image[chan]) mymax = np.median(image[chan]) + 2 * np.std(image[chan]) disp.set_limits_minmax(mymin, mymax) disp.highlight_pixels(mask[chan], linewidth=2) disp.image = image[chan] disp.cmap = plt.cm.coolwarm # disp.axes.text(lposx, 0, f'{channel[chan]} pedestal [ADC]', rotation=90) plt.title(f'{channel[chan]} pedestal [ADC]') disp.add_colorbar() image = ped_data.charge_std mask = ped_data.charge_std_outliers for chan in (np.arange(2)): pad += 1 plt.subplot(pad) plt.tight_layout() disp = CameraDisplay(camera_geometry) mymin = np.median(image[chan]) - 2 * np.std(image[chan]) mymax = np.median(image[chan]) + 2 * np.std(image[chan]) disp.set_limits_minmax(mymin, mymax) disp.highlight_pixels(mask[chan], linewidth=2) disp.image = image[chan] disp.cmap = plt.cm.coolwarm # disp.axes.text(lposx, 0, f'{channel[chan]} pedestal std [ADC]', rotation=90) plt.title(f'{channel[chan]} pedestal std [ADC]') disp.add_colorbar() ### histograms for chan in np.arange(2): mean_ped = ped_data.charge_mean[chan] ped_std = ped_data.charge_std[chan] # select good pixels select = np.logical_not(mask[chan]) #fig.suptitle(f"Run {run} channel: {channel[chan]}", fontsize=25) pad += 1 # pedestal charge plt.subplot(pad) plt.tight_layout() plt.ylabel('pixels') plt.xlabel(f'{channel[chan]} pedestal') median = np.median(mean_ped[select]) rms = np.std(mean_ped[select]) label = f"{channel[chan]} Median {median:3.2f}, std {rms:3.2f}" plt.hist(mean_ped[select], bins=50, label=label) plt.legend() pad += 1 # pedestal std plt.subplot(pad) plt.ylabel('pixels') plt.xlabel(f'{channel[chan]} pedestal std') median = np.median(ped_std[select]) rms = np.std(ped_std[select]) label = f" Median {median:3.2f}, std {rms:3.2f}" plt.hist(ped_std[select], bins=50, label=label) plt.legend() plt.subplots_adjust(top=0.94) if plot_file != "none": pp.savefig() pix = 0 pad = 420 # plot corrected waveforms of first 8 events for i, ev in enumerate(reader): for chan in np.arange(2): if pad == 420: # new figure fig = plt.figure(ev.index.event_id, figsize=(12, 24)) fig.suptitle(f"Run {run}, pixel {pix}", fontsize=25) plt.tight_layout() pad += 1 plt.subplot(pad) plt.subplots_adjust(top=0.92) label = f"event {ev.index.event_id}, {channel[chan]}: R0" plt.step(t, ev.r0.tel[tel_id].waveform[chan, pix, 2:38], color="blue", label=label) r0_calib.subtract_pedestal(ev, tel_id) label = "+ pedestal substraction" plt.step(t, ev.r1.tel[tel_id].waveform[chan, pix, 2:38], color="red", alpha=0.5, label=label) r0_calib.time_lapse_corr(ev, tel_id) r0_calib.interpolate_spikes(ev, tel_id) label = "+ dt corr + interp. spikes" plt.step(t, ev.r1.tel[tel_id].waveform[chan, pix, 2:38], alpha=0.5, color="green", label=label) plt.plot([0, 40], [offset_value, offset_value], 'k--', label="offset") plt.xlabel("time sample [ns]") plt.ylabel("counts [ADC]") plt.legend() plt.ylim([-50, 500]) if plot_file != "none" and pad == 428: pad = 420 plt.subplots_adjust(top=0.92) pp.savefig() if i == 8: break if plot_file != "none": pp.close()
def from_location( clc, altaz_frame, stars, sdt, fov, focal_length, min_alt, pixsize, vmag_lim, minpixdist=5, ): log = daiquiri.getLogger(__name__) mask = sdt.vmag < vmag_lim sdt = sdt[mask] stars = stars[mask] path = os.path.join( root_dir, "caldata", "starcat_pixsize{:.3g}_fov{}_minpixdist{}_vmag{}.pkl".format( pixsize, fov, minpixdist, vmag_lim ), ) if os.path.exists(path): with open(path, "rb") as f: try: args = pickle.load(f) except Exception as e: log.error( "Error occured while loading star patterns from file.", file=f, error=e, ) raise e return clc(**args) log.info( "No previously computed star pattern file found. Generating table now...." ) star_patterns = {} for k, star in tqdm(enumerate(stars), total=len(stars)): telescope_pointing = SkyCoord( ra=star.ra, dec=star.dec, frame="icrs" # ,altaz_frame, ) tm_alt_az = telescope_pointing.transform_to(altaz_frame) engineering_frame = EngineeringCameraFrame( n_mirrors=2, location=altaz_frame.location, obstime=altaz_frame.obstime, focal_length=focal_length, telescope_pointing=tm_alt_az, ) if tm_alt_az.alt.deg < min_alt: continue sep = telescope_pointing.separation(stars) ind = np.where(sep.deg < fov)[0] stars_eng = stars[ind].transform_to(engineering_frame) focus_star = stars_eng[np.where(ind == k)[0]] pf = np.array([focus_star.x.value[0], focus_star.y.value[0]]) hipf = sdt.hip_number.values[k] vmagf = sdt.vmag.values[k] pattern = [] for i, star1 in enumerate(stars_eng): if ind[i] == k: continue hip = sdt.hip_number.values[ind][i] vmag = sdt.vmag.values[ind][i] pc = np.array([star1.x.value, star1.y.value]) pattern.append((pf - pc, hip, vmag)) pattern = sorted(pattern, key=lambda t: t[2]) vmags = np.array([p[2] for p in pattern]) hips = np.array([p[1] for p in pattern], dtype=np.uint32) pcs = np.array([p[0] for p in pattern]) star_patterns[hipf] = StarPattern( hipf, vmagf, np.array([star.ra.rad, star.dec.rad]), pcs, vmags, hips, k ) with open(path, "wb") as f: log.info("Generated star pattern table saved.", file=f) pickle.dump( dict( star_coordinates=stars, star_table=sdt, patterns=star_patterns, pixsize=pixsize, minpixdist=minpixdist, engineering_frame=engineering_frame, ), f, ) return clc(stars, sdt, star_patterns, pixsize, minpixdist, engineering_frame)