def _add_random_energies(self, data, n_events): """Draw n_events random energies from the energy spectrum and add them to the data dict. """ es, rs = self._single_spectrum() energies = Hist1d.from_histogram(rs[:-1], es).get_random(n_events) data['energy'] = energies return data
def peak_matching_histogram(results, histogram_key, bin_edges): """ Make 1D histogram of peak matching results (=peaks with extra fields) added by histogram_key """ if histogram_key not in results.dtype.names: raise ValueError( 'Histogram key %s should be one of the columns in results: %s' % (histogram_key, results.dtype.names)) # How many true peaks do we have in each bin in total? n_peaks_hist = Hist1d(results[histogram_key], bin_edges) hists = {'_total': n_peaks_hist} for outcome in np.unique(results['outcome']): # Histogram the # of peaks that have this outcome hist = Hist1d(results[results['outcome'] == outcome][histogram_key], bins=n_peaks_hist.bin_edges) hists[outcome] = hist return hists
def bestfit(): """Second example in osg_tutorial""" # this is setting up LowER likelihood # there is no partitioning here -- just a single SR1 likelihood print("Setting up the likelihood...") sr1 = SR1() # axion signal model. this is ABC-only A = SolarAxion(1e-3, gae=3.5e-12) # initialize the likelihood lf = lstat.sciencerun_likelihood(sr1, A) print("Simulating dataset") # simulate a fake dataset data = lf.base_model.simulate() # feed the data to the likelihood lf.set_data(data) # now do a fit. # we use a convenience function that get best-fit, null-fit, and likelihood ratio b/t the two llr, bestfit, nullfit = lstat.ll_ratio(lf, 'solar_axion') # get significance of this sim using Wilk's theorem print("Background model rejected at %0.2f sigma" % (llr**0.5)) # create histogram objects from best/null fit results bestfit_hist = lstat.get_fit(lf, bestfit) nullfit_hist = lstat.get_fit(lf, nullfit) # plot the data, best-fit, and null-fit h = Hist1d(data['ces'], bins=np.linspace(0, 30, 31)) f = plt.figure() h.plot(errors=True, label='sim data') bestfit_hist.plot(label='best-fit') nullfit_hist.plot(label='null-fit') plt.xlim(0, 30) plt.ylim(0, max(h.histogram) + 20) plt.xlabel("Energy [keV]") plt.ylabel('events/keV') plt.legend() plt.title("Simulating axions on OSG") plt.savefig('my_axion_fit.png', dpi=300)
def plot_energy_spectrum(events, color='b', label=None, error_alpha=0.5, errors='fc', n_bins=100, min_energy=1, max_energy=100, geomspace=True): """Plot an energy spectrum histogram, with 1 sigma Poisson confidence intervals around it. :param min_energy: Minimum energy of the histogram :param max_energy: Maximum energy of the histogram :param geomspace: If True, will use a logarithmic energy binning. Otherwise will use a linear scale. :param n_bins: Number of energy bins to use :param color: Color to plot in :param label: Label for the line :param error_alpha: Alpha value for the statistical error band :param errors: Type of errors to draw, passed to 'errors' argument of Hist1d.plot. """ h = Hist1d(events['e_ces'], bins=(np.geomspace if geomspace else np.linspace)(min_energy, max_energy, n_bins)) h.plot(errors=errors, error_style='band', color=color, label=label, linewidth=1, error_alpha=error_alpha) plt.yscale('log') if geomspace: straxen.log_x(min_energy, max_energy, scalar_ticks=True) else: plt.xlim(min_energy, max_energy) plt.ylabel("Events / (keV_ee * day)") plt.xlabel("Energy [keV_ee], CES")
def plot_energy_spectrum( events, color='b', label=None, unit=None, exposure_kg_sec=None, error_alpha=0.5, errors='fc', n_bins=100, min_energy=1, max_energy=100, geomspace=True): """Plot an energy spectrum histogram, with 1 sigma Poisson confidence intervals around it. :param exposure_kg_sec: Exposure in kg * sec :param unit: Unit to plot spectrum in. Can be either: - events (events per bin) - kg_day_kev (events per kg day keV) - tonne_day_kev (events per tonne day keV) - tonne_year_kev (events per tonne year keV) Defaults to kg_day_kev if exposure_kg_sec is provided, otherwise events. :param min_energy: Minimum energy of the histogram :param max_energy: Maximum energy of the histogram :param geomspace: If True, will use a logarithmic energy binning. Otherwise will use a linear scale. :param n_bins: Number of energy bins to use :param color: Color to plot in :param label: Label for the line :param error_alpha: Alpha value for the statistical error band :param errors: Type of errors to draw, passed to 'errors' argument of Hist1d.plot. """ if unit is None: if exposure_kg_sec is not None: unit = 'kg_day_kev' else: unit = 'events' h = Hist1d(events['e_ces'], bins=(np.geomspace if geomspace else np.linspace)( min_energy, max_energy, n_bins)) if unit == 'events': scale, ylabel = 1, 'Events per bin' else: exposure_kg_day = exposure_kg_sec / (3600 * 24) if unit == 'kg_day_kev': scale = exposure_kg_day ylabel = 'Events / (kg day keV)' elif unit == 'tonne_day_kev': scale = exposure_kg_day / 1000 ylabel = 'Events / (tonne day keV)' elif unit == 'tonne_year_kev': scale = exposure_kg_day / 1000 ylabel = 'Events / (tonne year keV)' else: raise ValueError(f"Invalid unit {unit}") scale *= h.bin_volumes() h.plot(errors=errors, error_style='band', color=color, label=label, linewidth=1, scale_histogram_by=1/scale, error_alpha=error_alpha) plt.yscale('log') if geomspace: straxen.log_x(min_energy, max_energy, scalar_ticks=True) else: plt.xlim(min_energy, max_energy) plt.ylabel(ylabel) plt.xlabel("Energy [keV_ee], CES")
def test_init_from_histogram(self): m = Hist1d.from_histogram([0, 1, 0], [0, 1, 2, 3]) self.assertEqual(m.histogram.tolist(), [0, 1, 0]) self.assertEqual(m.bin_centers.tolist(), [0.5, 1.5, 2.5])
def test_init_from_data(self): ex_data = list(range(11)) m = Hist1d(ex_data, bins=len(ex_data) - 1) self.assertEqual(m.bin_edges.tolist(), ex_data) self.assertTrue(m.histogram.tolist(), [1] * n_bins)
def setUp(self): self.m = Hist1d(bins=n_bins, range=test_range)
def wilks_hist(result, bins=None, show_percentiles=None, show_theory=('wilks', )): if show_percentiles is None: show_percentiles = default_percentiles if not show_percentiles: show_percentiles = tuple() if isinstance(show_theory, str): show_theory = (show_theory, ) if bins is None: bins = default_bins h = Hist1d(result, bins=bins) x = h.bin_centers y = h.histogram plt.fill_between(x, y - y**0.5, y + y**0.5, color='b', label='Simulation', alpha=0.4, step='mid', linewidth=0) plt.plot(x, y, linestyle='steps-mid', color='b', linewidth=0.5) wilks_dist = stats.chi2(1) wilks_y = np.diff(wilks_dist.cdf(bins)) * h.n chernoff_y0 = (lookup(0, x, wilks_y) + h.n) / 2 if 'wilks' in show_theory: plt.plot(x, wilks_y, color=theory_colors['wilks'], label='Wilks') if 'chernoff' in show_theory: plt.plot(x, wilks_y / 2, color=theory_colors['chernoff'], label='Chernoff') plt.scatter(0, chernoff_y0, marker='.', color=theory_colors['chernoff']) plt.yscale('log') plt.ylabel("Toys / bin") plt.ylim(0.8, None) plt.gca().yaxis.set_major_formatter( matplotlib.ticker.FormatStrFormatter('%g')) plt.xlabel("-2 $\log ( L({\mu_s}^{*}) / L(\hat{\mu_s}) )$") plt.xlim(h.bin_edges[0], h.bin_edges[-1]) plt.legend(loc='upper right') ax = plt.gca() t1 = ax.transData t2 = ax.transAxes.inverted() def data_to_axes(x, y): return t2.transform(t1.transform((x, y))) def pc_line(x, y, label=None, color='b', alpha=0.8): plt.axvline(x, ymax=data_to_axes(x, y)[1], color=color, alpha=alpha, linewidth=0.5) if label: plt.text(x + 0.15, .9, label, rotation=90, horizontalalignment='left', verticalalignment='bottom') for pc, label in show_percentiles: x = np.percentile(result, pc) y = h.lookup(x) pc_line(x, y, label=label, color='k', alpha=1) if 'wilks' in show_theory: x = wilks_dist.ppf(pc / 100) y = lookup(x, h.bin_centers, wilks_y) pc_line(x, y, color=theory_colors['wilks']) if 'chernoff' in show_theory: if pc <= 50: x = 0 y = chernoff_y0 else: x = wilks_dist.ppf(1 - 2 * (1 - pc / 100)) y = lookup(x, h.bin_centers, wilks_y) / 2 pc_line(x, y, color=theory_colors['chernoff'])