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=np.ones_like(n_off), n_off=n_off, alpha=dataset.alpha.data) excess_counts =stat.excess_matching_significance(self.sigma) is_gamma_limited = excess_counts < self.gamma_min excess_counts[is_gamma_limited] = self.gamma_min excess = dataset.background.copy() excess.data = excess_counts return excess
def calculate_sensitivity_lima(n_on_events, n_background, alpha, n_bins_energy, n_bins_gammaness, n_bins_theta2): """ 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, gammaness 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_gammaness: `int` number of bins in gammaness 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_on_events, n_off=n_background, alpha=alpha) n_excesses_5sigma = stat.excess_matching_significance(5) for i in range(0, n_bins_energy): for j in range(0, n_bins_gammaness): for k in range(0, n_bins_theta2): if n_excesses_5sigma[i][j][k] < 10: n_excesses_5sigma[i][j][k] = 10 if n_excesses_5sigma[i, j, k] < 0.05 * n_background[i][j][k] / 5: n_excesses_5sigma[i, j, k] = 0.05 * n_background[i][j][k] / 5 sensitivity = n_excesses_5sigma / n_on_events * 100 # percentage of Crab return n_excesses_5sigma, sensitivity
def calculate_sensitivity_lima_ebin(n_excesses, 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_excesses: `numpy.ndarray` number of excess 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 """ if any(len(a) != n_bins_energy for a in (n_excesses, n_background, alpha)): raise ValueError( 'Excess, background and alpha arrays must have the same length') stat = WStatCountsStatistic( n_on=np.ones_like(n_background), n_off=n_background, alpha=alpha) n_excesses_5sigma = stat.excess_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_excesses * 100 # percentage of Crab return n_excesses_5sigma, sensitivity
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.excess_matching_significance(self.n_sigma) is_gamma_limited = excess_counts < self.gamma_min excess_counts[is_gamma_limited] = self.gamma_min excess = Map.from_geom(geom=dataset._geom, data=excess_counts) return excess
def test_wstat_excess_matching_significance(n_off, alpha, significance, result): stat = WStatCountsStatistic(1, n_off, alpha) excess = stat.excess_matching_significance(significance) assert_allclose(excess, result, atol=1e-3)