def estimate_min_excess(self, dataset): """Estimate minimum excess to reach the given significance. Parameters ---------- dataset : `SpectrumDataset` Spectrum dataset Returns ------- excess : `RegionNDMap` Minimal excess """ n_off = dataset.counts_off.data stat = WStatCountsStatistic( n_on=dataset.alpha.data * n_off, n_off=n_off, alpha=dataset.alpha.data ) excess_counts = stat.n_sig_matching_significance(self.n_sigma) is_gamma_limited = excess_counts < self.gamma_min excess_counts[is_gamma_limited] = self.gamma_min bkg_syst_limited = ( excess_counts < self.bkg_syst_fraction * dataset.background.data ) excess_counts[bkg_syst_limited] = ( self.bkg_syst_fraction * dataset.background.data[bkg_syst_limited] ) excess = Map.from_geom(geom=dataset._geom, data=excess_counts) return excess
def calculate_sensitivity_lima_ebin(n_on_events, n_background, alpha, n_bins_energy): """ Sensitivity calculation using the Li & Ma formula eq. 17 of Li & Ma (1983). https://ui.adsabs.harvard.edu/abs/1983ApJ...272..317L/abstract Parameters --------- n_on_events: `numpy.ndarray` number of ON events in the signal region n_background: `numpy.ndarray` number of events in the background region alpha: `float` inverse of the number of off positions n_bins_energy:`int` number of bins in energy Returns --------- sensitivity: `numpy.ndarray` sensitivity in percentage of Crab units n_excesses_5sigma: `numpy.ndarray` number of excesses corresponding to a 5 sigma significance """ stat = WStatCountsStatistic(n_on=n_on_events, n_off=n_background, alpha=alpha) n_excesses_5sigma = stat.n_sig_matching_significance(5) for i in range(0, n_bins_energy): # If the excess needed to get 5 sigma is less than 10, # we force it to be at least 10 if n_excesses_5sigma[i] < 10: n_excesses_5sigma[i] = 10 # If the excess needed to get 5 sigma is less than 5% # of the background, we force it to be at least 5% of # the background if n_excesses_5sigma[i] < 0.05 * n_background[i] * alpha[i]: n_excesses_5sigma[i] = 0.05 * n_background[i] * alpha[i] sensitivity = n_excesses_5sigma / n_on_events * 100 # percentage of Crab return n_excesses_5sigma, sensitivity
def calculate_sensitivity_lima(n_signal, n_background, alpha): """ Sensitivity calculation using the Li & Ma formula eq. 17 of Li & Ma (1983). https://ui.adsabs.harvard.edu/abs/1983ApJ...272..317L/abstract We calculate the sensitivity in bins of energy and theta2 Parameters ---------- n_on_events: `numpy.ndarray` number of ON events in the signal region n_background: `numpy.ndarray` number of events in the background region alpha: `float` inverse of the number of off positions n_bins_energy: `int` number of bins in energy n_bins_theta2: `int` number of bins in theta2 Returns ------- sensitivity: `numpy.ndarray` sensitivity in percentage of Crab units n_excesses_5sigma: `numpy.ndarray` number of excesses corresponding to a 5 sigma significance """ stat = WStatCountsStatistic(n_on=n_signal + alpha * n_background, n_off=n_background, alpha=alpha) n_excesses_5sigma = stat.n_sig_matching_significance(5) n_excesses_5sigma[n_excesses_5sigma < 10] = 10 bkg_5percent = 0.05 * n_background * alpha n_excesses_5sigma[n_excesses_5sigma < bkg_5percent] = bkg_5percent[ n_excesses_5sigma < bkg_5percent] sensitivity = n_excesses_5sigma / (n_signal) * 100 # percentage of Crab return n_excesses_5sigma, sensitivity
def test_wstat_excess_matching_significance(n_off, alpha, significance, result): stat = WStatCountsStatistic(1, n_off, alpha) excess = stat.n_sig_matching_significance(significance) assert_allclose(excess, result, rtol=1e-2)