"n_trials": 50, "n_steps": 10, } analyse(mh_dict, cluster=True, n_jobs=100) analyses.append(mh_dict) wait_cluster() sens = [] sens_err = [] disc_pots = [] for rh_dict in analyses: rh = ResultsHandler(rh_dict) sens.append(rh.sensitivity) sens_err.append(rh.sensitivity_err) disc_pots.append(rh.disc_potential) sens_err = np.array(sens_err).T plot_range = np.linspace(-0.99, 0.99, 1000) plt.figure() ax1 = plt.subplot2grid((4, 1), (0, 0), colspan=3, rowspan=3) ax1.plot( sindecs, reference_sensitivity(sindecs), color="blue", label=r"7-year Point Source analysis",
res_dict[i] = mh_dict rd.wait_for_cluster() sens = [] disc = [] for i in n_range: mh_dict = res_dict[i] # Creates a Results Handler to analyse the results, and calculate the # sensitivity. This is the flux that needs to arrive at Earth, in order for # IceCube to see an overfluctuation 90% of the time. Prints this information. rh = ResultsHandler(mh_dict) sens.append(rh.sensitivity) disc.append(rh.disc_potential) for i, vals in enumerate([sens, disc]): label = ["Sensitivity", "Discovery Potential"][i] plt.figure() plt.plot(n_range, vals) plt.ylabel("Ratio to Model") plt.xlabel("Model Number") plt.title(label + " during TXS Neutrino Flare") savepath = plot_output_dir(base_dir) + label + ".pdf"
disc_e = [[] for _ in src_res] labels = [] cat_path = tde_catalogue_name(cat) + "_catalogue.npy" catalogue = np.load(cat_path) src_1_frac = old_div(min(catalogue["Distance (Mpc)"])**-2,np.sum( catalogue["Distance (Mpc)"] ** -2 )) for i, (f_type, res) in enumerate(sorted(src_res.items())): for (length, rh_dict) in sorted(res.items()): try: rh = ResultsHandler(rh_dict) # Convert flux to fluence and source energy inj_time = length * 60 * 60 * 24 astro_sens, astro_disc = rh.astro_values( rh_dict["inj kwargs"]["Injection Energy PDF"]) key = "Total Fluence (GeV cm^{-2} s^{-1})" e_key = "Mean Luminosity (erg/s)" sens[i].append(astro_sens[key] * inj_time) disc_pots[i].append(astro_disc[key] * inj_time)
for (e_min, rh_dict) in sorted(rh_dict_srcs.items()): cat = load_catalogue(rh_dict["catalogue"]) print("e_min in loop: ", e_min) print(" ") print(" ") int_xray = np.sum(cat["base_weight"] / 1e13 * 624.151) int_xray_flux.append(int_xray) # GeV cm-2 s-1 int_xray_flux_erg.append(np.sum(cat["base_weight"]) / 1e13) # erg # cm-2 s-1 fracs.append(np.sum(cat["base_weight"]) / full_flux) try: rh = ResultsHandler(rh_dict) print("Sens", rh.sensitivity) print( "Sens_err", rh.sensitivity_err, rh.sensitivity_err[0], rh.sensitivity_err[1], ) print("Disc", rh.disc_potential) print("Disc_TS_threshold", rh.disc_ts_threshold) # print("Guess", rh_dict["scale"]) print("Sens (n)", rh.sensitivity * rh.flux_to_ns) print("DP (n)", rh.disc_potential * rh.flux_to_ns) # # guess.append(k_to_flux(rh_dict["scale"])* 2./3.) # guess.append(k_to_flux(rh_dict["scale"])/3.) print(
print( "Reference distance from paper: z={0} ({1:.2f})".format(ref_redshift, ref_distance) ) area = 4 * np.pi * (ref_distance.to("cm") ** 2) print("Area at this distance is {0}".format(area)) energy_PDF = EnergyPDF.create(injection_energy) e_integral = energy_PDF.fluence_integral() * u.GeV**2 print("Integral over energy is {0}".format(e_integral)) rh = ResultsHandler( rh_dict["name"], rh_dict["llh kwargs"], rh_dict["catalogue"], show_inj=True ) inj_time = injection_length * 60 * 60 * 24 * u.s astro_sens, astro_disc = rh.astro_values(rh_dict["inj kwargs"]["Injection Energy PDF"]) key = "Total Fluence (GeV cm^{-2} s^{-1})" e_key = "Mean Luminosity (erg/s)" sens_livetime = astro_sens[key] * inj_time * u.GeV / u.cm**2 / u.s disc_livetime = astro_disc[key] * inj_time * u.GeV / u.cm**2 / u.s sens_e = astro_sens[e_key] * inj_time * u.erg / u.s disc_e = astro_disc[e_key] * inj_time * u.erg / u.s
mh_dict["scale"] = scale # Creates a Minimisation Handler using the dictionary, and runs the trials analyse(mh_dict, n_cpu=2, n_jobs=1, cluster=False) # wait_cluster() # mh.iterate_run(scale, n_steps=mh_dict["n_steps"], # n_trials=mh_dict["n_trials"]) # Creates a Results Handler to analyse the results, and calculate the # sensitivity. This is the flux that needs to arrive at Earth, in order for # IceCube to see an overfluctuation 90% of the time. Prints this information. rh = ResultsHandler(mh_dict) sens = rh.sensitivity # Converts the flux at Earth to a required luminosity from the source, # by scaling with distance and accounting for redshift astro_sens, astro_disc = rh.astro_values( mh_dict["inj_dict"]["injection_energy_pdf"]) # Print output # Load the source print("\n \n \n") print("The source to be analysed is:") print(txs_catalogue["source_name"][0])
def calculate_upper_limits(self): try: ul_dir = os.path.join(self.plot_dir, "upper_limits/") try: os.makedirs(ul_dir) except OSError: pass flux_uls = [] fluence_uls = [] e_per_source_uls = [] energy_flux = [] x_axis = [] for subdir in sorted(os.listdir(self.pickle_dir)): root = os.path.join(self.unblind_dict["background_ts"], subdir) new_path = analysis_pickle_path(name=root) logger.info(f'Opening file {new_path}') with open(new_path, "rb") as f: mh_dict = pickle.load(f) e_pdf_dict = mh_dict["inj_dict"][ "injection_energy_pdf"] self.unblind_dict['name'] = mh_dict['name'] rh = ResultsHandler(self.unblind_dict) logger.debug( f"In calculate_upper_limits, ResultsHandler is {rh}") savepath = ul_dir + subdir + ".pdf" if self.ts < rh.bkg_median: logging.warning( f"Specified TS ({self.ts}) less than the background median ({rh.bkg_median}). " f"There was thus a background n underfluctuation. " f"Using the sensitivity for an upper limit.") ul, extrapolated, err = rh.find_overfluctuations( max(self.ts, rh.bkg_median), savepath) flux_uls.append(ul) # Calculate mean injection time per source n_sources = float(len(self.sources)) inj_time = 0. seasons = mh_dict["dataset"] for (name, season) in seasons.items(): t_pdf = TimePDF.create( mh_dict["inj_dict"]["injection_sig_time_pdf"], season.get_time_pdf()) for src in self.sources: inj_time += t_pdf.raw_injection_time(src) / \ n_sources astro_dict = rh.nu_astronomy(ul, e_pdf_dict) key = "Energy Flux (GeV cm^{-2} s^{-1})" fluence_uls.append(astro_dict[key] * inj_time) e_per_source_uls.append( astro_dict["Mean Luminosity (erg/s)"] * inj_time) energy_flux.append(astro_dict[key]) x_axis.append(float(subdir)) plt.figure() ax = plt.subplot(111) plt.plot(x_axis, flux_uls, marker='o', label="upper limit") if self.mock_unblind: ax.text(0.2, 0.5, "MOCK DATA", color="grey", alpha=0.5, transform=ax.transAxes) ax.set_xlabel('Gamma') ax.set_ylabel('Flux') plt.yscale("log") plt.savefig(self.plot_dir + "upper_limit_flux.pdf") plt.close() plt.figure() ax1 = plt.subplot(111) ax2 = ax1.twinx() ax1.plot(x_axis, fluence_uls, marker='o') ax2.plot(x_axis, e_per_source_uls, marker='o') if self.mock_unblind: ax1.text(0.2, 0.5, "MOCK DATA", color="grey", alpha=0.5, transform=ax1.transAxes) ax2.grid(True, which='both') ax1.set_xlabel('Gamma') ax2.set_xlabel('Gamma') ax1.set_ylabel(r"Total Fluence [GeV cm$^{-2}$ s$^{-1}$]") ax2.set_ylabel( r"Isotropic-Equivalent Luminosity $L_{\nu}$ (erg/s)") ax1.set_yscale("log") ax2.set_yscale("log") for k, ax in enumerate([ax1, ax2]): y = [fluence_uls, e_per_source_uls][k] ax.set_ylim(0.95 * min(y), 1.1 * max(y)) plt.tight_layout() plt.savefig(self.plot_dir + "upper_limit_fluence.pdf") plt.close() try: os.makedirs(os.path.dirname(self.limit_path)) except OSError: pass logger.info("Saving limits to {0}".format(self.limit_path)) res_dict = { "gamma": x_axis, "flux": flux_uls, "energy_flux": energy_flux, "fluence": fluence_uls, "energy": e_per_source_uls } with open(self.limit_path, "wb") as f: pickle.dump(res_dict, f) except AttributeError as e: logger.warning( "Unable to set limits. No TS distributions found.") except ValueError as e: raise OverfluctuationError( "Insufficent pseudotrial values above and below threshold")
# load the background trials if (pdf_type == "decay") and (gamma == 2.0): gamma_str = "2" else: gamma_str = str(gamma) sens_name = ( f"{base_raw}/{pdf_type}/{cat}/{time_key}/{gamma_str}" ) sens_mh_dict = dict(mh_dict) sens_mh_dict["name"] = sens_name logging.info( "----- loading sensitivity results -------") sens_rh = ResultsHandler(sens_mh_dict, do_disc=False, do_sens=False) # sens_rh = ExperimentalResultHandler(sens_mh_dict, do_sens=False, do_disc=False) bkg_res = sens_rh.results[scale_shortener(0.0)] # load the signal trials # rh = ResultsHandler(mh_dict, do_disc=False, do_sens=False) try: logging.info( "----------- loading energy range calculations ------------" ) # rh = ExperimentalResultHandler(mh_dict, do_sens=False, do_disc=False) rh = ResultsHandler(mh_dict, do_sens=False, do_disc=False)
def run_quick_injections_to_estimate_sensitivity_scale(self): """ Roughly estimates the injection scale in order to find a better scale range. The quick injection trials are run locally. Note that a scale still has to be given in the mh_dict as a first estimate. """ logger.info(f"doing quick trials to estimate scale") if self.mh_dict["mh_name"] == "fit_weights": raise NotImplementedError( "This method does not work with the fit_weights MinimizationHandler " "because it assumes a background TS distribution median of zero! " "Be the hero to think of something!") # The given scale will serve as an initial guess guess = self.mh_dict[ "scale"] if not self.disc_guess else self.disc_guess # make sure self._clean_injection_values_and_pickled_results( self._quick_injections_name) # repeat the guessing until success: while not self.successful_guess_by_quick_injections: quick_injections_mh_dict = dict(self.mh_dict) quick_injections_mh_dict["name"] = self._quick_injections_name quick_injections_mh_dict["background_ntrials_factor"] = 1 quick_injections_mh_dict["n_trials"] = 10 quick_injections_mh_dict["scale"] = guess self.submit_local(quick_injections_mh_dict) # collect the quick injections quick_injections_rh = ResultsHandler(quick_injections_mh_dict, do_sens=False, do_disc=False) # guess the disc and sens scale ( self.disc_guess, self.sens_guess, ) = quick_injections_rh.estimate_sens_disc_scale() if any((g < 0) or (g > guess) for g in [self.disc_guess, self.sens_guess]): logger.info(f"Could not perform scale guess because " f"at least one guess outside [0, {guess}]! " f"Adjusting accordingly.") guess = abs(max((self.sens_guess, self.disc_guess)) * 1.5) elif guess > 5 * self.disc_guess: logger.info( f"Could not perform scale guess beause " f"initial scale guess {guess} much larger than " f"disc scale guess {self.disc_guess}. " f"Adjusting initial guess to {4 * self.disc_guess} and retry." ) guess = 4 * abs(self.disc_guess) else: logger.info( "Scale guess successful. Adjusting injection scale.") self.successful_guess_by_quick_injections = True self._clean_injection_values_and_pickled_results( quick_injections_rh.name)