Source code for gammapy.estimators.points.sensitivity
# Licensed under a 3-clause BSD style license - see LICENSE.rstimportnumpyasnpfromastropy.tableimportColumn,Tablefromgammapy.mapsimportMapfromgammapy.modeling.modelsimportPowerLawSpectralModel,SkyModelfromgammapy.statsimportWStatCountsStatisticfrom..coreimportEstimator__all__=["SensitivityEstimator"]
[docs]classSensitivityEstimator(Estimator):"""Estimate differential sensitivity. This class allows to determine for each reconstructed energy bin the flux associated to the number of gamma-ray events for which the significance is ``n_sigma``, and being larger than ``gamma_min`` and ``bkg_sys`` percent larger than the number of background events in the ON region. Parameters ---------- spectrum : `SpectralModel` Spectral model assumption n_sigma : float, optional Minimum significance. Default is 5. gamma_min : float, optional Minimum number of gamma-rays. Default is 10. bkg_syst_fraction : float, optional Fraction of background counts above which the number of gamma-rays is. Default is 0.05 Examples -------- For a usage example see :doc:`/tutorials/analysis-1d/cta_sensitivity` tutorial. """tag="SensitivityEstimator"def__init__(self,spectrum=None,n_sigma=5.0,gamma_min=10,bkg_syst_fraction=0.05):ifspectrumisNone:spectrum=PowerLawSpectralModel(index=2,amplitude="1 cm-2 s-1 TeV-1")self.spectrum=spectrumself.n_sigma=n_sigmaself.gamma_min=gamma_minself.bkg_syst_fraction=bkg_syst_fraction
[docs]defestimate_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.datastat=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_minexcess_counts[is_gamma_limited]=self.gamma_minbkg_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)returnexcess
[docs]defestimate_min_e2dnde(self,excess,dataset):"""Estimate dnde from given min. excess Parameters ---------- excess : `RegionNDMap` Minimal excess dataset : `SpectrumDataset` Spectrum dataset Returns ------- e2dnde : `~astropy.units.Quantity` Minimal differential flux. """energy=dataset._geom.axes["energy"].centerdataset.models=SkyModel(spectral_model=self.spectrum)npred=dataset.npred_signal()phi_0=excess/npreddnde_model=self.spectrum(energy=energy)dnde=phi_0.data[:,0,0]*dnde_model*energy**2returndnde.to("erg / (cm2 s)")
[docs]defrun(self,dataset):"""Run the sensitivity estimation Parameters ---------- dataset : `SpectrumDatasetOnOff` Dataset to compute sensitivity for. Returns ------- sensitivity : `~astropy.table.Table` Sensitivity table """energy=dataset._geom.axes["energy"].centerexcess=self.estimate_min_excess(dataset)e2dnde=self.estimate_min_e2dnde(excess,dataset)criterion=self._get_criterion(excess.data.squeeze(),dataset.background.data.squeeze())returnTable([Column(data=energy,name="energy",format="5g",description="Reconstructed Energy",),Column(data=e2dnde,name="e2dnde",format="5g",description="Energy squared times differential flux",),Column(data=excess.data.squeeze(),name="excess",format="5g",description="Number of excess counts in the bin",),Column(data=dataset.background.data.squeeze(),name="background",format="5g",description="Number of background counts in the bin",),Column(data=criterion,name="criterion",description="Sensitivity-limiting criterion",),])