def test_prod4_B_TEL_1170_pde(): prod4_cam_eff = CameraEfficiency.from_prod4() prod4_cam_eff._cherenkov_scale = 1 # Konrad does not scale np.testing.assert_allclose(prod4_cam_eff._cherenkov_flux_300_550, 168.41, rtol=1e-4) f = prod4_cam_eff._cherenkov_flux_300_550_inside_pixel_bypass_telescope np.testing.assert_allclose(f, 69.58, rtol=1e-4) prod4_cam_eff = CameraEfficiency.from_prod4( ) # Scaling should not matter here np.testing.assert_allclose(prod4_cam_eff.B_TEL_1170_pde, 0.388, rtol=1e-4) prod4_cam_eff._cherenkov_scale = 1000 np.testing.assert_allclose(prod4_cam_eff.B_TEL_1170_pde, 0.388, rtol=1e-4)
def plot(self, alpha=1): d = { "0deg": 'PDE at 0 deg', "20deg": 'PDE at 20 deg', "40deg": 'PDE at 40 deg', "60deg": 'PDE at 60 deg', "70deg": 'PDE at 70 deg', "80deg": 'PDE at 80 deg', "-20deg": 'PDE at -20 deg', "-40deg": 'PDE at -40 deg', "-60deg": 'PDE at -60 deg', "-70deg": 'PDE at -70 deg', "-80deg": 'PDE at -80 deg', } fig, ax = plt.subplots() for label, col in d.items(): color = ax._get_lines.get_next_color() ax.plot(self.df.index, self.df[col], "-", alpha=alpha, color=color, label=label) from sstcam_simulation.utils.efficiency import CameraEfficiency c = CameraEfficiency.from_prod4() ax.plot(c.wavelength, c.pde, alpha=alpha, color='black', label="prod4") ax.legend() ax.set_xlabel("Wavelength (nm)") ax.set_ylabel("PDE")
def plot_measured(self, alpha=1): df = self.df df_no_interp = self._df_no_interp d = { "0deg": '0_measured', "20deg": '20_measured', "45deg": '45_measured', "50deg": '50_measured', "60deg": '60_measured', } fig, ax = plt.subplots() for label, col in d.items(): color = ax._get_lines.get_next_color() ax.plot(df.index, df[col], ":", alpha=alpha, color=color) ax.plot(df_no_interp.index, df_no_interp[col], "-", alpha=alpha, color=color, label=label) from sstcam_simulation.utils.efficiency import CameraEfficiency c = CameraEfficiency.from_prod4() ax.plot(c.wavelength, c.window_transmissivity, alpha=alpha, color='black', label="prod4") ax.legend() ax.set_xlabel("Wavelength (nm)") ax.set_ylabel("Transmissivity")
def main(): overvoltages = np.linspace(3, 7.5, 10) fov_angles = np.linspace(0, 10, 11) d_list = [] sipm_candidates = dict( lct5_6mm_50um_epoxy=SiPMOvervoltage.lct5_6mm_50um_epoxy(), lct5_6mm_75um_epoxy=SiPMOvervoltage.lct5_6mm_75um_epoxy(), lvr3_6mm_50um_silicon=SiPMOvervoltage.lvr3_6mm_50um_silicon(), lvr3_6mm_50um_uncoated=SiPMOvervoltage.lvr3_6mm_50um_uncoated(), lvr3_6mm_75um_silicon=SiPMOvervoltage.lvr3_6mm_75um_silicon(), lvr3_6mm_75um_uncoated=SiPMOvervoltage.lvr3_6mm_75um_uncoated(), ) mia_gamma_interp = MinimumImageAmplitudeInterpolator.gamma() for sipm_candidate, sipm_tool in tqdm(sipm_candidates.items()): for overvoltage in overvoltages: sipm_tool.overvoltage = overvoltage pde_at_450nm = sipm_tool.pde for fov_angle in fov_angles: eff = CameraEfficiency.from_sstcam(fov_angle=fov_angle, pde_at_450nm=pde_at_450nm) opct = sipm_tool.opct gain = sipm_tool.gain camera_cherenkov_pde = eff.camera_cherenkov_pde mv_per_pe = 4 nominal_nsb_rate = eff.nominal_nsb_rate.to_value("MHz") mia_pe = mia_gamma_interp(opct, nominal_nsb_rate, mv_per_pe)[0] mia_photons = mia_pe / camera_cherenkov_pde d_list.append( dict( sipm_candidate=sipm_candidate, overvoltage=overvoltage, pde_at_450nm=pde_at_450nm, opct=opct, gain=gain, fov_angle=fov_angle, B_TEL_1170_pde=eff.B_TEL_1170_pde, camera_cherenkov_pde=camera_cherenkov_pde, telescope_cherenkov_pde=eff.telescope_cherenkov_pde, camera_nsb_pde=eff.camera_nsb_pde.to_value(), telescope_nsb_pde=eff.telescope_nsb_pde.to_value(), camera_signal_to_noise=eff.camera_signal_to_noise. to_value(), telescope_signal_to_noise=eff. telescope_signal_to_noise.to_value(), nominal_nsb_rate=nominal_nsb_rate, maximum_nsb_rate=eff.maximum_nsb_rate.to_value("MHz"), n_cherenkov_photoelectrons=eff. n_cherenkov_photoelectrons, minimum_image_amplitude=mia_photons, )) df = pd.DataFrame(d_list) with pd.HDFStore("sipm_candidate_performance.h5") as store: store['data'] = df
def test_prod4_integrate_nsb(): prod4_cam_eff = CameraEfficiency.from_prod4() nsb_diff_flux = prod4_cam_eff._nsb_diff_flux_on_ground nsb_flux = prod4_cam_eff._integrate_nsb(nsb_diff_flux, 300 * u.nm, 550 * u.nm) nsb_flux = nsb_flux.to_value("1/(cm² ns sr)") np.testing.assert_allclose(nsb_flux, 0.116, rtol=1e-2) nsb_flux = prod4_cam_eff._integrate_nsb(nsb_diff_flux, 300 * u.nm, 650 * u.nm) nsb_flux = nsb_flux.to_value("1/(cm² ns sr)") np.testing.assert_allclose(nsb_flux, 0.263, rtol=1e-2)
def test_scale_pde(): prod4_cam_eff = CameraEfficiency.from_prod4() original_pde = prod4_cam_eff.pde.copy() prod4_cam_eff.scale_pde(u.Quantity(410, u.nm), 0.5) pde_at_wavelength = prod4_cam_eff.pde[prod4_cam_eff.wavelength == 410] np.testing.assert_allclose(pde_at_wavelength, 0.5, rtol=1e-2) prod4_cam_eff.scale_pde(u.Quantity(410, u.nm), 0.25) pde_at_wavelength = prod4_cam_eff.pde[prod4_cam_eff.wavelength == 410] np.testing.assert_allclose(pde_at_wavelength, 0.25, rtol=1e-2) prod4_cam_eff.reset_pde_scale() np.testing.assert_allclose(prod4_cam_eff.pde, original_pde, rtol=1e-2)
def test_prod4_camera_cherenkov_pde(): prod4_cam_eff = CameraEfficiency.from_prod4() np.testing.assert_allclose(prod4_cam_eff.camera_cherenkov_pde, 0.441, rtol=1e-3) prod4_cam_eff.scale_pde(u.Quantity(410, u.nm), 0.5) np.testing.assert_allclose(prod4_cam_eff.camera_cherenkov_pde, 0.451, rtol=1e-3) prod4_cam_eff.scale_pde(u.Quantity(410, u.nm), 0.25) np.testing.assert_allclose(prod4_cam_eff.camera_cherenkov_pde, 0.2253, rtol=1e-3) prod4_cam_eff.reset_pde_scale()
def test_prod4_integrate_cherenkov(): prod4_cam_eff = CameraEfficiency.from_prod4() diff_flux = prod4_cam_eff._cherenkov_diff_flux_on_ground flux = prod4_cam_eff._integrate_cherenkov(diff_flux, 300 * u.nm, 600 * u.nm) np.testing.assert_allclose(flux, 100, rtol=1e-2) prod4_cam_eff._cherenkov_scale = 1 # Konrad does not scale diff_flux = prod4_cam_eff._cherenkov_diff_flux_inside_pixel flux = prod4_cam_eff._integrate_cherenkov(diff_flux, 300 * u.nm, 550 * u.nm) np.testing.assert_allclose(flux, 50.12, rtol=1e-2) flux = prod4_cam_eff._integrate_cherenkov(diff_flux, 200 * u.nm, 999 * u.nm) np.testing.assert_allclose(flux, 56.66, rtol=1e-2)
def test_prod4_telescope_cherenkov_pde(): prod4_cam_eff = CameraEfficiency.from_prod4() np.testing.assert_allclose(prod4_cam_eff.telescope_cherenkov_pde, 0.342, rtol=1e-3)
def test_prod4_maximum_nsb(): prod4_cam_eff = CameraEfficiency.from_prod4() nsb_rate = prod4_cam_eff.maximum_nsb_rate.to_value("1/ns") np.testing.assert_allclose(nsb_rate, 0.75, rtol=1e-2)
def test_prod4_nominal_nsb(): prod4_cam_eff = CameraEfficiency.from_prod4() nsb_rate = prod4_cam_eff.nominal_nsb_rate.to_value("1/ns") np.testing.assert_allclose(nsb_rate, 0.04, rtol=1e-2)
def obtain_prod4(): try: return CameraEfficiency.from_prod4() except FileNotFoundError: return None
def test_prod4_nsb_rate_inside_pixel(): prod4_cam_eff = CameraEfficiency.from_prod4() nsb_rate = prod4_cam_eff._nsb_rate_inside_pixel.to_value("1/ns") np.testing.assert_allclose(nsb_rate, 0.044, rtol=1e-2)
def test_prod4_pixel_fill_factor(): prod4_cam_eff = CameraEfficiency.from_prod4() fill_factor = prod4_cam_eff.pixel_fill_factor np.testing.assert_allclose(fill_factor, 0.939, rtol=1e-3)
def main(): path = "sipm_candidate_performance.h5" with pd.HDFStore(path) as store: df = store['data'] df = df.loc[df['fov_angle'] == 0] prod4_eff = CameraEfficiency.from_prod4() p_cherenkov_pde = Plotter() for candidate, group in df.groupby("sipm_candidate"): p_cherenkov_pde.ax.plot(group['overvoltage'], group['camera_cherenkov_pde'], 'x-', label=candidate) p_cherenkov_pde.ax.axhline(prod4_eff.camera_cherenkov_pde, ls='--', color='blue', label="Prod4") p_cherenkov_pde.ax.set_xlabel("Overvoltage (V)") p_cherenkov_pde.ax.set_ylabel("Camera Cherenkov PDE") p_cherenkov_pde.add_legend(loc="best") p_cherenkov_pde.save("camera_cherenkov_pde.pdf") p_B_TEL_1170_pde = Plotter() for candidate, group in df.groupby("sipm_candidate"): p_B_TEL_1170_pde.ax.plot(group['overvoltage'], group['B_TEL_1170_pde'], 'x-', label=candidate) p_B_TEL_1170_pde.ax.axhline(BTEL1170_PDE, ls='--', color='black', label="Requirement") p_B_TEL_1170_pde.ax.axhline(prod4_eff.B_TEL_1170_pde, ls='--', color='blue', label="Prod4") p_B_TEL_1170_pde.ax.set_xlabel("Overvoltage (V)") p_B_TEL_1170_pde.ax.set_ylabel("B-TEL-1170 PDE") p_B_TEL_1170_pde.add_legend(loc="best") p_B_TEL_1170_pde.save("B_TEL_1170_pde.pdf") p_sn = Plotter() for candidate, group in df.groupby("sipm_candidate"): p_sn.ax.plot(group['overvoltage'], group['telescope_signal_to_noise'], 'x-', label=candidate) p_sn.ax.axhline(BTEL0090_SNR, ls='--', color='black', label="Requirement") p_sn.ax.axhline(prod4_eff.telescope_signal_to_noise, ls='--', color='blue', label="Prod4") p_sn.ax.set_xlabel("Overvoltage (V)") p_sn.ax.set_ylabel("B-TEL-0090 SNR") p_sn.add_legend(loc="best") p_sn.save("B-TEL-0090_snr.pdf") p_opct = Plotter() for candidate, group in df.groupby("sipm_candidate"): p_opct.ax.plot(group['overvoltage'], group['opct'], 'x-', label=candidate) p_opct.ax.axhline(PROD4_OPCT, ls='--', color='blue', label="Prod4") p_opct.ax.set_xlabel("Overvoltage (V)") p_opct.ax.set_ylabel("Optical Crosstalk") p_opct.add_legend(loc="best") p_opct.save("opct.pdf") p_nominal_nsb = Plotter() for candidate, group in df.groupby("sipm_candidate"): p_nominal_nsb.ax.plot(group['overvoltage'], group['nominal_nsb_rate'], 'x-', label=candidate) p_nominal_nsb.ax.axhline(prod4_eff.nominal_nsb_rate.to_value("MHz"), ls='--', color='blue', label="Prod4") p_nominal_nsb.ax.set_xlabel("Overvoltage (V)") p_nominal_nsb.ax.set_ylabel("Nominal NSB Rate (MHz)") p_nominal_nsb.add_legend(loc="best") p_nominal_nsb.save("nominal_nsb.pdf") p_maximum_nsb = Plotter() for candidate, group in df.groupby("sipm_candidate"): p_maximum_nsb.ax.plot(group['overvoltage'], group['maximum_nsb_rate'], 'x-', label=candidate) p_maximum_nsb.ax.axhline(prod4_eff.maximum_nsb_rate.to_value("MHz"), ls='--', color='blue', label="Prod4") p_maximum_nsb.ax.set_xlabel("Overvoltage (V)") p_maximum_nsb.ax.set_ylabel("Maximum NSB Rate (MHz)") p_maximum_nsb.add_legend(loc="best") p_maximum_nsb.save("maximum_nsb.pdf") p_mia_g = Plotter() for candidate, group in df.groupby("sipm_candidate"): p_mia_g.ax.plot(group['overvoltage'], group['minimum_image_amplitude'], 'x-', label=candidate) p_mia_g.ax.axhline(MINIMGAMP_GAMMA, ls='--', color='black', label="Requirement") p_mia_g.ax.axhline(PROD4_MINIMGAMP_GAMMA, ls='--', color='blue', label="Prod4") p_mia_g.ax.set_xlabel("Overvoltage (V)") p_mia_g.ax.set_ylabel("Minimum Image Amplitude (ph.)") p_mia_g.add_legend(loc="best") p_mia_g.save("mia_gamma.pdf")
def test_prod4_pixel_active_solid_angle(): prod4_cam_eff = CameraEfficiency.from_prod4() pixel_active_solid_angle = prod4_cam_eff._pixel_active_solid_angle.to_value( "μsr") np.testing.assert_allclose(pixel_active_solid_angle, 8.3, rtol=1e-3)
def test_prod4_telescope_signal_to_noise(): prod4_cam_eff = CameraEfficiency.from_prod4() np.testing.assert_allclose(prod4_cam_eff.telescope_signal_to_noise, 0.446, rtol=1e-3)
def test_prod4_camera_signal_to_noise(): prod4_cam_eff = CameraEfficiency.from_prod4() np.testing.assert_allclose(prod4_cam_eff.camera_signal_to_noise, 0.510, rtol=1e-3)
def test_prod4_camera_nsb_pde(): prod4_cam_eff = CameraEfficiency.from_prod4() np.testing.assert_allclose(prod4_cam_eff.camera_nsb_pde, 0.749, rtol=1e-3)
def test_prod4_telescope_nsb_pde(): prod4_cam_eff = CameraEfficiency.from_prod4() np.testing.assert_allclose(prod4_cam_eff.telescope_nsb_pde, 0.5875, rtol=1e-3)