def main(input_files, output, site, complementary, label): bins, bin_center, bin_widths = make_energy_bins(e_min=0.003 * u.TeV, e_max=330 * u.TeV, bins=10) for input, color, l in zip(input_files, color_cycle, label): df = fact.io.read_data( input, key='array_events', columns=['mc_energy', 'h_max_prediction', 'mc_x_max']).dropna() thickness, altitude = get_atmosphere_profile_functions(site) mc_h_max = altitude(df.mc_x_max.values * u.Unit('g/cm^2')).value y = mc_h_max - df.h_max_prediction x = df.mc_energy.values b_50, bin_edges, binnumber = binned_statistic(x, y, statistic='median', bins=bins) bin_centers = np.sqrt(bin_edges[1:] * bin_edges[:-1]) plt.step(bin_centers, b_50, lw=2, color=color, label=l, where='mid') plt.xscale('log') # plt.yscale('log') plt.ylabel('Distance to true H max / meter') plt.xlabel(r'True Energy / TeV ') plt.legend() plt.tight_layout() if output: plt.savefig(output) else: plt.show()
def main(input_files, output, threshold, multiplicity, reference, complementary): columns = [ 'mc_alt', 'mc_az', 'mc_energy', 'az_prediction', 'alt_prediction', 'num_triggered_telescopes' ] if threshold > 0: columns.append('gamma_prediction_mean') bins, bin_center, bin_widths = make_energy_bins(e_min=0.003 * u.TeV, e_max=330 * u.TeV, bins=15) for input_file in input_files: df = fact.io.read_data(input_file, key='array_events', columns=columns).dropna() if threshold > 0: df = df.query(f'gamma_prediction_mean > {threshold}').copy() if multiplicity > 2: df = df.query(f'num_triggered_telescopes >= {multiplicity}').copy() distance = calculate_distance_to_true_source_position(df) b_68, bin_edges, binnumber = binned_statistic( df.mc_energy.values, distance, statistic=lambda y: np.percentile(y, 68), bins=bins) plt.step(bin_center, b_68, lw=2, label=os.path.basename(input_file), where='mid') if reference: df = load_angular_resolution_requirement() plt.plot(df.energy, df.resolution, '--', color='#5b5b5b', label='Prod3B Reference') plt.xscale('log') plt.yscale('log') plt.ylabel('Distance to True Position / degree') plt.xlabel(r'True Energy / TeV ') plt.ylim([0.001, 100.8]) plt.legend() plt.tight_layout() if output: plt.savefig(output) else: plt.show()
def main(gammas, protons, output): t_obs = 50 * u.h gammas = fact.io.read_data(gammas, key='array_events') gammas = gammas.dropna() gamma_runs = fact.io.read_data(gammas, key='runs') mc_production_gamma = MCSpectrum.from_cta_runs(gamma_runs) protons = fact.io.read_data(protons, key='array_events') protons = protons.dropna() # print(f'Plotting {len(protons)} protons and {len(gammas)} gammas.') proton_runs = fact.io.read_data(protons, key='runs') mc_production_proton = MCSpectrum.from_cta_runs(proton_runs) crab = CrabSpectrum() cosmic = CosmicRaySpectrum() gammas['weight'] = mc_production_gamma.reweigh_to_other_spectrum( crab, gammas.mc_energy.values * u.TeV, t_assumed_obs=t_obs) protons['weight'] = mc_production_proton.reweigh_to_other_spectrum( cosmic, protons.mc_energy.values * u.TeV, t_assumed_obs=t_obs) # gammas_gammalike = gammas.query(f'gamma_prediction_mean > {cut}') # protons_gammalike = protons.query(f'gamma_prediction_mean > {cut}') bin_edges, _, _ = make_energy_bins(gammas.mc_energy.values * u.TeV, bins=20) on, off, alpha = coordinates.split_on_off(gammas, protons, on_region_radius=0.4 * u.deg) print(f'alpha:{alpha}') on['energy_bin'] = pd.cut(on.mc_energy, bin_edges) off['energy_bin'] = pd.cut(off.mc_energy, bin_edges) for ((_, g_on), (_, g_off)) in zip(on.groupby('energy_bin'), off.groupby('energy_bin')): n_on = g_on.weight.sum() n_off = g_off.weight.sum() print('----' * 20) print(n_on, n_off) print(g_on.size, g_off.size) print(li_ma_significance(n_on, n_off, alpha=1)) if output: plt.savefig(output) else: plt.show()
def main( gamma_input, proton_input, output, n_bins, n_jobs, optimize, iterations, ): ''' Calculates a sensitivity curve vs real energy. For each energy bin it performs a gridsearch to find the theta and gamma_prediction_mean cuts that produce the highest sensitivity. ''' t_obs = 50 * u.h e_min, e_max = 0.003 * u.TeV, 330 * u.TeV bin_edges, _, _ = make_energy_bins(e_min=e_min, e_max=e_max, bins=n_bins) columns = ['gamma_prediction_mean', 'az_prediction', 'alt_prediction', 'mc_alt', 'mc_az', 'mc_energy'] gammas = fact.io.read_data(gamma_input, key='array_events', columns=columns) gammas = gammas.dropna() gamma_runs = fact.io.read_data(gamma_input, key='runs') mc_production_gamma = MCSpectrum.from_cta_runs(gamma_runs) protons = fact.io.read_data(proton_input, key='array_events', columns=columns) protons = protons.dropna() proton_runs = fact.io.read_data(proton_input, key='runs') mc_production_proton = MCSpectrum.from_cta_runs(proton_runs) crab = CrabSpectrum() cosmic = CosmicRaySpectrum() gammas['weight'] = mc_production_gamma.reweigh_to_other_spectrum(crab, gammas.mc_energy.values * u.TeV, t_assumed_obs=t_obs) protons['weight'] = mc_production_proton.reweigh_to_other_spectrum(cosmic, protons.mc_energy.values * u.TeV, t_assumed_obs=t_obs) if optimize: result_table = optimize_differential_sensitivity(gammas, protons, bin_edges=bin_edges, num_threads=n_jobs) else: result_table = calculate_differential_sensitivity(gammas, protons, bin_edges=bin_edges) result_table.write(output, overwrite=True)
def main(input_files, output, threshold, complementary, label): bins, bin_center, bin_widths = make_energy_bins(e_min=0.003 * u.TeV, e_max=330 * u.TeV, bins=10) columns = [ 'mc_core_x', 'mc_core_y', 'core_x_prediction', 'core_y_prediction', 'mc_energy' ] for input_file, color, l in zip(input_files, color_cycle, label): df = fact.io.read_data(input_file, key='array_events', columns=columns).dropna() distance = np.sqrt((df.mc_core_x - df.core_x_prediction)**2 + (df.mc_core_y - df.core_y_prediction)**2) x = df.mc_energy.values y = distance b_50, bin_edges, binnumber = binned_statistic(x, y, statistic='median', bins=bins) bin_centers = np.sqrt(bin_edges[1:] * bin_edges[:-1]) plt.step(bin_centers, b_50, lw=2, color=color, label=l, where='mid') plt.xscale('log') plt.yscale('log') plt.ylabel('Distance to True Impact Position / meter') plt.xlabel(r'True Energy / TeV ') plt.legend() plt.tight_layout() if output: plt.savefig(output) else: plt.show()
def main(gammas_dl3, protons_dl3, output_pdf, bins, threshold): cols = ['az_prediction', 'alt_prediction', 'mc_energy'] gammas = fact.io.read_data(gammas_dl3, key='array_events') print(f'Reading {len(gammas)} gammas') # import IPython; IPython.embed() gammas = gammas.dropna(subset=cols) protons = fact.io.read_data(protons_dl3, key='array_events') print(f'Reading {len(protons)} protons') protons = protons.dropna(subset=cols) gamma_runs = fact.io.read_data(gammas_dl3, key='runs') mc_production_gamma = MCSpectrum.from_cta_runs(gamma_runs) proton_runs = fact.io.read_data(protons_dl3, key='runs') mc_production_proton = MCSpectrum.from_cta_runs(proton_runs) crab = CrabSpectrum() cosmic = CosmicRaySpectrum() t_obs = 60 * u.s gammas['weight'] = mc_production_gamma.reweigh_to_other_spectrum( crab, gammas.mc_energy.values * u.TeV, t_assumed_obs=t_obs) protons['weight'] = mc_production_proton.reweigh_to_other_spectrum( cosmic, protons.mc_energy.values * u.TeV, t_assumed_obs=t_obs) with PdfPages(output_pdf) as pdf: plt.figure() bin_edges, _, _ = make_energy_bins(gammas.mc_energy.values * u.TeV, bins=20) plt.hist(gammas.mc_energy, bins=bin_edges, histtype='step', lw=2, label='gammas true energy') plt.hist(protons.mc_energy, bins=bin_edges, histtype='step', lw=2, label='proton true energy') plt.legend() plt.xscale('log') plt.xlabel(r'$Energy / \mathrm{TeV}$') plt.ylabel('Counts') pdf.savefig() plt.close() plt.figure() gammas['theta'] = calculate_distance(gammas) protons['theta'] = calculate_distance(protons) bins = np.linspace(0, 25.2, 40) kwargs = {'histtype': 'step', 'lw': 2.0} plt.hist(gammas['theta'], bins=bins, label='gamma', density=True, **kwargs) plt.hist(protons['theta'], bins=bins, label='proton', density=True, **kwargs) plt.legend() plt.xlabel(r'$Distance / Degree$') plt.ylabel('Normalized Counts') pdf.savefig() plt.close() plt.figure() plt.hist(gammas['theta']**2, bins=bins, label='gamma', density=True, **kwargs) plt.hist(protons['theta']**2, bins=bins, label='proton', density=True, **kwargs) plt.legend() plt.xlabel(r'$Distance Squared / Degree^2$') plt.ylabel('Normalized Counts') pdf.savefig() plt.close() plt.figure() bins = np.linspace(0, 0.30, 40) plt.hist(gammas['theta']**2, bins=bins, label='gamma', density=True, **kwargs) plt.hist(protons['theta']**2, bins=bins, label='proton', density=True, **kwargs) plt.legend() plt.xlabel(r'$Distance Squared / Degree^2$') plt.ylabel('Normalized Counts') pdf.savefig() plt.close() plt.figure() bins = np.linspace(0, 0.30, 40) on = gammas.append(protons) plt.hist(gammas['theta']**2, bins=bins, label='gammas', weights=gammas.weight, **kwargs) plt.hist(protons['theta']**2, bins=bins, label='proton', weights=protons.weight, **kwargs) plt.legend() plt.xlabel(r'$Distance Squared / Degree^2$') plt.ylabel('weighted Counts') pdf.savefig() plt.close() plt.figure() bins = np.linspace(0, 0.30, 40) on = gammas.append(protons) plt.hist(on['theta']**2, bins=bins, label='on (gammas + protons)', weights=on.weight, **kwargs) plt.hist(protons['theta']**2, bins=bins, label='proton', weights=protons.weight, **kwargs) plt.legend() plt.xlabel(r'$Distance Squared / Degree^2$') plt.ylabel('weighted Counts') pdf.savefig() plt.close() fig, ax = plt.subplots() c = coordinates.skyccords_from_dl3_table(gammas).icrs ra = c.ra.deg dec = c.dec.deg ra_bins = np.linspace(11, 17, 50) dec_bins = np.linspace(41, 47, 50) _, _, _, im = ax.hist2d(ra, dec, bins=[ra_bins, dec_bins], cmap='magma') ax.set_aspect('equal', ) plt.colorbar(im, ax=ax) plt.title('gammas') plt.xlabel(r'$Right Ascension / Degree$') plt.ylabel(r'$Declination / Degree$') pdf.savefig() plt.close() fig, ax = plt.subplots() c = coordinates.skyccords_from_dl3_table(protons).icrs ra = c.ra.deg dec = c.dec.deg _, _, _, im = ax.hist2d(ra, dec, bins=[ra_bins, dec_bins], cmap='magma') ax.set_aspect('equal') plt.title('protons') plt.colorbar(im, ax=ax) plt.xlabel(r'$Right Ascension / Degree$') plt.ylabel(r'$Declination / Degree$') pdf.savefig() plt.close() fig, ax = plt.subplots() on, off, _ = coordinates.split_on_off(gammas, protons) c = coordinates.skyccords_from_dl3_table(on).icrs _, _, _, im = ax.hist2d(c.ra.deg, c.dec.deg, bins=[ra_bins, dec_bins], cmap='magma') ax.set_aspect('equal') plt.title('on region') plt.colorbar(im, ax=ax) pdf.savefig() plt.close() fig, ax = plt.subplots() c = coordinates.skyccords_from_dl3_table(off).icrs _, _, _, im = ax.hist2d(c.ra.deg, c.dec.deg, bins=[ra_bins, dec_bins], cmap='magma') ax.set_aspect('equal') plt.colorbar(im, ax=ax) plt.title('off region') pdf.savefig() plt.close() plt.figure() plt.hist(on.mc_energy, bins=bin_edges, histtype='step', lw=2, label='on region true energy', density=True) plt.hist(off.mc_energy, bins=bin_edges, histtype='step', lw=2, label='off region true energy', density=True) plt.hist(gammas.mc_energy, bins=bin_edges, histtype='step', lw=2, label='gammas true energy', color='gray', density=True) plt.hist(protons.mc_energy, bins=bin_edges, histtype='step', lw=2, label='proton true energy', color='lightgray', density=True) plt.legend() plt.xscale('log') plt.xlabel(r'$Energy / \mathrm{TeV}$') plt.ylabel(' Normalized Counts') pdf.savefig() plt.close() gammas = gammas.query(f'gamma_prediction_mean > {threshold}') protons = protons.query(f'gamma_prediction_mean > {threshold}') plt.figure() bins = np.linspace(0, 0.22, 40) plt.hist(gammas['theta']**2, bins=bins, label='gamma', density=True, **kwargs) plt.hist(protons['theta']**2, bins=bins, label='proton', density=True, **kwargs) plt.legend() plt.xlabel(r'$Distance Squared / Degree^2$') plt.ylabel(f'Normalized Counts t > {threshold}') pdf.savefig() plt.close() fig, ax = plt.subplots() on, off, _ = coordinates.split_on_off(gammas, protons) c = coordinates.skyccords_from_dl3_table(on).icrs _, _, _, im = ax.hist2d(c.ra.deg, c.dec.deg, bins=[ra_bins, dec_bins], cmap='magma') ax.set_aspect('equal') plt.colorbar(im, ax=ax) plt.title( f'{len(on)} gammalike events in on region threshold={threshold}') pdf.savefig() plt.close() fig, ax = plt.subplots() c = coordinates.skyccords_from_dl3_table(off).icrs _, _, _, im = ax.hist2d(c.ra.deg, c.dec.deg, bins=[ra_bins, dec_bins], cmap='magma') ax.set_aspect('equal') plt.colorbar(im, ax=ax) plt.title( f'{len(off)} gammalike events in off region threshold={threshold}') pdf.savefig() plt.close() plt.figure() plt.title('gammalike events') plt.hist(on.mc_energy, bins=bin_edges, histtype='step', lw=2, label='on region true energy', density=True) plt.hist(off.mc_energy, bins=bin_edges, histtype='step', lw=2, label='off region true energy', density=True) plt.hist(gammas.mc_energy, bins=bin_edges, histtype='step', lw=2, label='gammas true energy', color='gray', density=True) plt.hist(protons.mc_energy, bins=bin_edges, histtype='step', lw=2, label='proton true energy', color='lightgray', density=True) plt.legend() plt.xscale('log') plt.xlabel(r'$Energy / \mathrm{TeV}$') plt.ylabel('Normalized Counts') pdf.savefig() plt.close() plt.figure() plt.title('gammalike events') plt.hist( on.mc_energy, bins=bin_edges, histtype='step', lw=2, label='on region true energy', ) plt.hist( off.mc_energy, bins=bin_edges, histtype='step', lw=2, label='off region true energy', ) plt.hist( gammas.mc_energy, bins=bin_edges, histtype='step', lw=2, label='gammas true energy', color='gray', ) plt.hist( protons.mc_energy, bins=bin_edges, histtype='step', lw=2, label='proton true energy', color='lightgray', ) plt.legend() plt.xscale('log') plt.yscale('log') plt.xlabel(r'$Energy / \mathrm{TeV}$') plt.ylabel('Counts') pdf.savefig() plt.close()