def test_SensitivityPointSource_sensitivity_MC(): np.random.seed(314159) alpha = 1. n_sig = 20 n_bgr = 10 # one bin with the bin-centre at 1 TeV energy_bin_edges = np.array([.1, 10]) * u.TeV energies_sig = np.ones(n_sig) energies_bgr = np.ones(n_bgr) sens = SensitivityPointSource(reco_energies={ 's': energies_sig * u.TeV, 'b': energies_bgr * u.TeV }) # sens.event_weights = {'s': energies_sig, 'b': energies_bgr} sensitivity = sens.get_sensitivity( alpha=alpha, signal_list=("s"), mode="MC", sensitivity_source_flux=crab_source_rate, sensitivity_energy_bin_edges=energy_bin_edges, min_n=0, max_background_ratio=1) # the ratio between sensitivity and reference flux (i.e. from the crab nebula) should # be the scaling factor that needs to be applied to n_sig to produce a 5 sigma result # in the lima formula ratio = sensitivity["Sensitivity"][0] / (crab_source_rate(1 * u.TeV)).value np.testing.assert_allclose( [sigma_lima(ratio * n_sig + alpha * n_bgr, n_bgr, alpha)], [5], atol=0.0066)
def test_SensitivityPointSource_sensitivity_MC(): np.random.seed(314159) alpha = 1. n_sig = 20 n_bgr = 10 # one bin with the bin-centre at 1 TeV energy_bin_edges = np.array([.1, 10]) * u.TeV energies_sig = np.ones(n_sig) energies_bgr = np.ones(n_bgr) sens = SensitivityPointSource(reco_energies={'s': energies_sig * u.TeV, 'b': energies_bgr * u.TeV}) # sens.event_weights = {'s': energies_sig, 'b': energies_bgr} sensitivity = sens.get_sensitivity(alpha=alpha, signal_list=("s"), mode="MC", sensitivity_source_flux=crab_source_rate, sensitivity_energy_bin_edges=energy_bin_edges, min_n=0, max_background_ratio=1) # the ratio between sensitivity and reference flux (i.e. from the crab nebula) should # be the scaling factor that needs to be applied to n_sig to produce a 5 sigma result # in the lima formula ratio = sensitivity["Sensitivity"][0] / (crab_source_rate(1 * u.TeV)).value np.testing.assert_allclose( [sigma_lima(ratio * n_sig + alpha * n_bgr, n_bgr, alpha)], [5], atol=0.0066)
def test_SensitivityPointSource_sensitivity_data(): alpha = 1. n_on = 30 n_off = 10 # one bin with the bin-centre at 1 TeV energy_bin_edges = np.array([.1, 10]) * u.TeV energies_sig = np.ones(n_on) energies_bgr = np.ones(n_off) sens = SensitivityPointSource(reco_energies={ 's': energies_sig * u.TeV, 'b': energies_bgr * u.TeV }) sensitivity = sens.get_sensitivity( alpha=alpha, signal_list=("s"), mode="data", sensitivity_source_flux=crab_source_rate, sensitivity_energy_bin_edges=energy_bin_edges, min_n=0, max_background_ratio=1) # the ratio between sensitivity and reference flux (i.e. from the crab nebula) should # be the scaling factor that needs to be applied to n_sig=n_on-n_off*alpha to produce # a 5 sigma result in the lima formula ratio = sensitivity["Sensitivity"][0] / (crab_source_rate(1 * u.TeV)).value np.testing.assert_allclose([ sigma_lima(ratio * (n_on - n_off * alpha) + n_off * alpha, n_off, alpha) ], [5])
def make_sensitivity_plots(SensCalc, sensitivities, SensCalc_t, sensitivities_t): bin_centres_g = (edges_gammas[1:] + edges_gammas[:-1]) / 2. bin_centres_p = (edges_proton[1:] + edges_proton[:-1]) / 2. bin_widths_g = np.diff(edges_gammas.value) bin_widths_p = np.diff(edges_proton.value) # the point-source sensitivity binned in energy plt.figure() # draw the crab flux as a reference crab_bins = np.logspace(-2, 2.5, 17) plt.loglog(crab_bins, (crab_source_rate(crab_bins * u.TeV) * (crab_bins * u.TeV)**2).to(sensitivity_unit).value, color="red", ls="dashed", label="Crab Nebula") plt.loglog(crab_bins, (crab_source_rate(crab_bins * u.TeV) * (crab_bins * u.TeV)**2).to(sensitivity_unit).value / 10, color="red", ls="dashed", alpha=.66, label="Crab Nebula / 10") plt.loglog(crab_bins, (crab_source_rate(crab_bins * u.TeV) * (crab_bins * u.TeV)**2).to(sensitivity_unit).value / 100, color="red", ls="dashed", alpha=.33, label="Crab Nebula / 100") # some semi-official line to compare ref_loge, ref_sens = *(np.array([ (-1.8, 6.87978e-11), (-1.6, 1.87765e-11), (-1.4, 7.00645e-12), (-1.2, 1.77677e-12), (-1.0, 8.19263e-13), (-0.8, 4.84879e-13), (-0.6, 3.00256e-13), (-0.4, 2.07787e-13), (-0.2, 1.4176e-13), (0.0, 1.06069e-13), (0.2, 8.58209e-14), (0.4, 6.94294e-14), (0.6, 6.69301e-14), (0.8, 7.61169e-14), (1.0, 7.13895e-14), (1.2, 9.49376e-14), (1.4, 1.25208e-13), (1.6, 1.91209e-13), (1.8, 3.11611e-13), (2.0, 4.80354e-13)]).T), plt.loglog(10**ref_loge, ((ref_sens) * (u.erg * u.cm**2 * u.s)**(-1)).to(flux_unit).value, marker="s", color="black", ms=3, linewidth=1, label="reference") sens_low, sens_up = ( (sensitivities["Sensitivity"] - sensitivities["Sensitivity_low"]).to(flux_unit) * sensitivities["Energy"].to(u.erg)**2, (sensitivities["Sensitivity_up"] - sensitivities["Sensitivity"]).to(flux_unit) * sensitivities["Energy"].to(u.erg)**2) # plt.errorbar( plt.loglog( sensitivities["Energy"] / energy_unit, (sensitivities["Sensitivity"].to(flux_unit) * sensitivities["Energy"].to(u.erg)**2).to(sensitivity_unit).value, # (sens_low.value, sens_up.value), color="darkred", marker="s", label="wavelets") # plt.loglog( # sensitivities["Energy"] / energy_unit, # (sensitivities["Sensitivity_base"].to(flux_unit) * # sensitivities["Energy"].to(u.erg)**2).to(sensitivity_unit).value, # color="darkgreen", # marker="^", # ls="", # label="wavelets (no upscale)") # tailcuts sens_low_t, sens_up_t = ( (sensitivities_t["Sensitivity"] - sensitivities_t["Sensitivity_low"]).to(flux_unit) * sensitivities_t["Energy"].to(u.erg)**2, (sensitivities_t["Sensitivity_up"] - sensitivities_t["Sensitivity"]).to(flux_unit) * sensitivities_t["Energy"].to(u.erg)**2) # plt.errorbar( plt.loglog( sensitivities_t["Energy"] / energy_unit, (sensitivities_t["Sensitivity"].to(flux_unit) * sensitivities_t["Energy"].to(u.erg)**2).to(sensitivity_unit).value, # (sens_low_t.value, sens_up_t.value), color="darkorange", marker="s", ls="--", label="tailcuts") # plt.loglog( # sensitivities_t["Energy"].to(energy_unit), # (sensitivities_t["Sensitivity_base"].to(flux_unit) * # sensitivities_t["Energy"].to(u.erg)**2), # color="darkblue", # marker="v", # ls="", # label="tailcuts (no upscale)") plt.legend(title="Obsetvation Time: {}".format(observation_time), loc=1) plt.xlabel(r'$E_\mathrm{reco}$' + ' / {:latex}'.format(energy_unit)) plt.ylabel(r'$E^2 \Phi /$ {:latex}'.format(sensitivity_unit)) plt.gca().set_xscale("log") plt.grid() plt.xlim([1e-2, 2e2]) plt.ylim([5e-15, 5e-10]) if args.write: save_fig(args.plots_dir + "sensitivity") # plot the sensitivity ratios try: plt.figure() plt.semilogx(sensitivities_t["Energy"].to(energy_unit)[1:-2].value, (sensitivities_t["Sensitivity"].to(flux_unit) * sensitivities_t["Energy"].to(u.erg)**2)[1:-2] / (sensitivities["Sensitivity"].to(flux_unit) * sensitivities["Energy"].to(u.erg)**2)[1:-2], label=r"Sens$_\mathrm{tail}$ / Sens$_\mathrm{wave}$" ) plt.legend() # plt.semilogx(sensitivities_t["Energy"].to(energy_unit)[[0, -1]], # [1, 1], ls="--", color="gray") # plt.xlim(sensitivities_t["Energy"].to(energy_unit)[[0, -1]].value) # plt.ylim([.25, 1.1]) plt.xlabel('E / {:latex}'.format(energy_unit)) plt.ylabel("ratio") if args.write: save_fig(args.plots_dir + "sensitivity_ratio") except: plt.close() # plot a sky image of the events # useless since too few MC background events left if False: fig2 = plt.figure() plt.hexbin( [(ph - 180) * np.sin(th * u.deg) for ph, th in zip(chain(gammas['phi'], proton['phi']), chain(gammas['theta'], proton['theta']))], [a for a in chain(gammas['theta'], proton['theta'])], gridsize=41, extent=[-2, 2, 18, 22], C=[a for a in chain(weights['g'], weights['p'])], bins='log' ) plt.colorbar().set_label("log(Number of Events)") plt.axes().set_aspect('equal') plt.xlabel(r"$\sin(\vartheta) \cdot (\varphi-180) / ${:latex}" .format(angle_unit)) plt.ylabel(r"$\vartheta$ / {:latex}".format(angle_unit)) if args.write: save_fig("plots/skymap")