def setup(self): etrue = np.logspace(-1, 1, 10) * u.TeV self.e_true = etrue ereco = np.logspace(-1, 1, 5) * u.TeV elo = ereco[:-1] ehi = ereco[1:] self.aeff = EffectiveAreaTable(etrue[:-1], etrue[1:], np.ones(9) * u.cm**2) self.edisp = EnergyDispersion.from_diagonal_response(etrue, ereco) data = np.ones(elo.shape) data[-1] = 0 # to test stats calculation with empty bins self.on_counts = CountsSpectrum(elo, ehi, data) self.off_counts = CountsSpectrum(elo, ehi, np.ones(elo.shape) * 10) self.livetime = 1000 * u.s self.dataset = SpectrumDatasetOnOff( counts=self.on_counts, counts_off=self.off_counts, aeff=self.aeff, edisp=self.edisp, livetime=self.livetime, acceptance=np.ones(elo.shape), acceptance_off=np.ones(elo.shape) * 10, obs_id="test", )
def make_observation_list(): """obs with dummy IRF""" nbin = 3 energy = np.logspace(-1, 1, nbin + 1) * u.TeV livetime = 2 * u.h data_on = np.arange(nbin) dataoff_1 = np.ones(3) dataoff_2 = np.ones(3) * 3 dataoff_1[1] = 0 dataoff_2[1] = 0 on_vector = CountsSpectrum(energy_lo=energy[:-1], energy_hi=energy[1:], data=data_on) off_vector1 = CountsSpectrum(energy_lo=energy[:-1], energy_hi=energy[1:], data=dataoff_1) off_vector2 = CountsSpectrum(energy_lo=energy[:-1], energy_hi=energy[1:], data=dataoff_2) aeff = EffectiveAreaTable.from_constant(energy, "1 cm2") edisp = EDispKernel.from_gauss(e_true=energy, e_reco=energy, sigma=0.2, bias=0) time_ref = Time("2010-01-01") gti1 = make_gti({ "START": [5, 6, 1, 2], "STOP": [8, 7, 3, 4] }, time_ref=time_ref) gti2 = make_gti({"START": [14], "STOP": [15]}, time_ref=time_ref) obs1 = SpectrumDatasetOnOff( counts=on_vector, counts_off=off_vector1, aeff=aeff, edisp=edisp, livetime=livetime, mask_safe=np.ones(on_vector.energy.nbin, dtype=bool), acceptance=1, acceptance_off=2, name="1", gti=gti1, ) obs2 = SpectrumDatasetOnOff( counts=on_vector, counts_off=off_vector2, aeff=aeff, edisp=edisp, livetime=livetime, mask_safe=np.ones(on_vector.energy.nbin, dtype=bool), acceptance=1, acceptance_off=4, name="2", gti=gti2, ) obs_list = [obs1, obs2] return obs_list
def setup(self): etrue = np.logspace(-1, 1, 10) * u.TeV self.e_true = etrue ereco = np.logspace(-1, 1, 5) * u.TeV elo = ereco[:-1] ehi = ereco[1:] self.e_reco = ereco self.aeff = EffectiveAreaTable(etrue[:-1], etrue[1:], np.ones(9) * u.cm**2) self.edisp = EDispKernel.from_diagonal_response(etrue, ereco) data = np.ones(elo.shape) data[-1] = 0 # to test stats calculation with empty bins self.on_counts = CountsSpectrum(elo, ehi, data) self.off_counts = CountsSpectrum(elo, ehi, np.ones(elo.shape) * 10) start = u.Quantity([0], "s") stop = u.Quantity([1000], "s") time_ref = Time("2010-01-01 00:00:00.0") self.gti = GTI.create(start, stop, time_ref) self.livetime = self.gti.time_sum self.dataset = SpectrumDatasetOnOff( counts=self.on_counts, counts_off=self.off_counts, aeff=self.aeff, edisp=self.edisp, livetime=self.livetime, acceptance=np.ones(elo.shape), acceptance_off=np.ones(elo.shape) * 10, name="test", gti=self.gti, )
def setup(self): self.nbins = 30 binning = np.logspace(-1, 1, self.nbins + 1) * u.TeV self.source_model = PowerLawSpectralModel(index=2, amplitude=1e5 / u.TeV, reference=0.1 * u.TeV) self.bkg_model = PowerLawSpectralModel(index=3, amplitude=1e4 / u.TeV, reference=0.1 * u.TeV) self.alpha = 0.1 random_state = get_random_state(23) npred = self.source_model.integral(binning[:-1], binning[1:]) source_counts = random_state.poisson(npred) self.src = CountsSpectrum(energy_lo=binning[:-1], energy_hi=binning[1:], data=source_counts) # Currently it's necessary to specify a lifetime self.src.livetime = 1 * u.s npred_bkg = self.bkg_model.integral(binning[:-1], binning[1:]) bkg_counts = random_state.poisson(npred_bkg) off_counts = random_state.poisson(npred_bkg * 1.0 / self.alpha) self.bkg = CountsSpectrum(energy_lo=binning[:-1], energy_hi=binning[1:], data=bkg_counts) self.off = CountsSpectrum(energy_lo=binning[:-1], energy_hi=binning[1:], data=off_counts)
def setup(self): self.nbins = 30 binning = np.logspace(-1, 1, self.nbins + 1) * u.TeV self.source_model = PowerLawSpectralModel(index=2.1, amplitude=1e5 / u.TeV / u.s, reference=0.1 * u.TeV) self.livetime = 100 * u.s bkg_rate = np.ones(self.nbins) / u.s bkg_expected = bkg_rate * self.livetime self.bkg = CountsSpectrum(energy_lo=binning[:-1], energy_hi=binning[1:], data=bkg_expected) random_state = get_random_state(23) self.npred = (self.source_model.integral(binning[:-1], binning[1:]) * self.livetime) self.npred += bkg_expected source_counts = random_state.poisson(self.npred) self.src = CountsSpectrum(energy_lo=binning[:-1], energy_hi=binning[1:], data=source_counts) self.dataset = SpectrumDataset( model=self.source_model, counts=self.src, livetime=self.livetime, background=self.bkg, )
def setup(self): self.nbins = 30 binning = np.logspace(-1, 1, self.nbins + 1) * u.TeV self.source_model = PowerLawSpectralModel(index=2.1, amplitude=1e5 * u.Unit("cm-2 s-1 TeV-1"), reference=0.1 * u.TeV) self.livetime = 100 * u.s aeff = EffectiveAreaTable.from_constant(binning, "1 cm2") bkg_rate = np.ones(self.nbins) / u.s bkg_expected = (bkg_rate * self.livetime).to_value("") self.bkg = CountsSpectrum(energy_lo=binning[:-1], energy_hi=binning[1:], data=bkg_expected) random_state = get_random_state(23) flux = self.source_model.integral(binning[:-1], binning[1:]) self.npred = (flux * aeff.data.data[0] * self.livetime).to_value("") self.npred += bkg_expected source_counts = random_state.poisson(self.npred) self.src = CountsSpectrum(energy_lo=binning[:-1], energy_hi=binning[1:], data=source_counts) self.dataset = SpectrumDataset( model=self.source_model, counts=self.src, aeff=aeff, livetime=self.livetime, background=self.bkg, )
def setup(self): self.nbins = 30 binning = np.logspace(-1, 1, self.nbins + 1) * u.TeV self.source_model = PowerLawSpectralModel(index=2, amplitude=1e5 * u.Unit("cm-2 s-1 TeV-1"), reference=0.1 * u.TeV) bkg_model = PowerLawSpectralModel(index=3, amplitude=1e4 * u.Unit("cm-2 s-1 TeV-1"), reference=0.1 * u.TeV) self.alpha = 0.1 random_state = get_random_state(23) npred = self.source_model.integral(binning[:-1], binning[1:]).value source_counts = random_state.poisson(npred) self.src = CountsSpectrum(energy_lo=binning[:-1], energy_hi=binning[1:], data=source_counts) self.src.livetime = 1 * u.s self.aeff = EffectiveAreaTable.from_constant(binning, "1 cm2") npred_bkg = bkg_model.integral(binning[:-1], binning[1:]).value bkg_counts = random_state.poisson(npred_bkg) off_counts = random_state.poisson(npred_bkg * 1.0 / self.alpha) self.bkg = CountsSpectrum(energy_lo=binning[:-1], energy_hi=binning[1:], data=bkg_counts) self.off = CountsSpectrum(energy_lo=binning[:-1], energy_hi=binning[1:], data=off_counts)
def get_spectrum(self, region=None, func=np.nansum): """Extract spectrum in a given region. The spectrum can be computed by summing (or, more generally, applying ``func``) along the spatial axes in each energy bin. This occurs only inside the ``region``, which by default is assumed to be the whole spatial extension of the map. Parameters ---------- region: `~regions.Region` Region (pixel or sky regions accepted). func : numpy.ufunc Function to reduce the data. Returns ------- spectrum : `~gammapy.spectrum.CountsSpectrum` Spectrum in the given region. """ from gammapy.spectrum import CountsSpectrum energy_axis = self.geom.get_axis_by_name("energy") if region: mask = self.geom.region_mask([region]) data = self.data[mask].reshape(energy_axis.nbin, -1) data = func(data, axis=1) else: data = func(self.data, axis=(1, 2)) edges = energy_axis.edges return CountsSpectrum(data=data, energy_lo=edges[:-1], energy_hi=edges[1:], unit=self.unit)
def sens(): etrue = np.logspace(0, 1, 21) * u.TeV elo = etrue[:-1] ehi = etrue[1:] area = np.zeros(20) + 1e6 * u.m**2 arf = EffectiveAreaTable(energy_lo=elo, energy_hi=ehi, data=area) ereco = np.logspace(0, 1, 5) * u.TeV rmf = EnergyDispersion.from_diagonal_response(etrue, ereco) bkg_array = np.ones(4) bkg_array[-1] = 1e-3 bkg = CountsSpectrum(energy_lo=ereco[:-1], energy_hi=ereco[1:], data=bkg_array, unit="s-1") sens = SensitivityEstimator(arf=arf, rmf=rmf, bkg=bkg, livetime=1 * u.h, index=2, gamma_min=20, alpha=0.2) sens.run() return sens
def test_fake(self): """Test the fake dataset""" source_model = SkyModel(spectral_model=PowerLawSpectralModel()) dataset = SpectrumDatasetOnOff( counts=self.on_counts, counts_off=self.off_counts, models=source_model, aeff=self.aeff, livetime=self.livetime, edisp=self.edisp, acceptance=1, acceptance_off=10, ) real_dataset = dataset.copy() # Define background model counts elo = self.on_counts.energy.edges[:-1] ehi = self.on_counts.energy.edges[1:] data = np.ones(self.on_counts.data.shape) background_model = CountsSpectrum(elo, ehi, data) dataset.fake(background_model=background_model, random_state=314, name="fake") assert real_dataset.counts.data.shape == dataset.counts.data.shape assert real_dataset.counts_off.data.shape == dataset.counts_off.data.shape assert (real_dataset.counts.energy.center.mean() == dataset.counts.energy.center.mean()) assert real_dataset.acceptance.mean() == dataset.acceptance.mean() assert real_dataset.acceptance_off.mean( ) == dataset.acceptance_off.mean() assert dataset.counts_off.data.sum() == 39 assert dataset.counts.data.sum() == 5 assert dataset.name == "fake"
def _counts_spectrum(self, ebounds): from gammapy.spectrum import CountsSpectrum if not ebounds: ebounds = self._default_plot_ebounds() spec = CountsSpectrum(energy_lo=ebounds[:-1], energy_hi=ebounds[1:]) spec.fill_energy(self.energy) return spec
def spectrum_dataset(): e_true = np.logspace(0, 1, 21) * u.TeV e_reco = np.logspace(0, 1, 5) * u.TeV aeff = EffectiveAreaTable.from_constant(value=1e6 * u.m**2, energy=e_true) edisp = EDispKernel.from_diagonal_response(e_true, e_reco) data = 3600 * np.ones(4) data[-1] *= 1e-3 background = CountsSpectrum(energy_lo=e_reco[:-1], energy_hi=e_reco[1:], data=data) return SpectrumDataset(aeff=aeff, livetime="1h", edisp=edisp, background=background)
def test_spectrum_dataset_stack_diagonal_safe_mask(self): aeff = EffectiveAreaTable.from_parametrization(self.src.energy.edges, "HESS") edisp = EDispKernel.from_diagonal_response(self.src.energy.edges, self.src.energy.edges) livetime = self.livetime dataset1 = SpectrumDataset( counts=self.src.copy(), livetime=livetime, aeff=aeff, edisp=edisp, background=self.bkg.copy(), ) livetime2 = 0.5 * livetime aeff2 = EffectiveAreaTable(self.src.energy.edges[:-1], self.src.energy.edges[1:], 2 * aeff.data.data) bkg2 = CountsSpectrum( self.src.energy.edges[:-1], self.src.energy.edges[1:], data=2 * self.bkg.data, ) safe_mask2 = np.ones_like(self.src.data, bool) safe_mask2[0] = False dataset2 = SpectrumDataset( counts=self.src.copy(), livetime=livetime2, aeff=aeff2, edisp=edisp, background=bkg2, mask_safe=safe_mask2, ) dataset1.stack(dataset2) assert_allclose(dataset1.counts.data[1:], self.src.data[1:] * 2) assert_allclose(dataset1.counts.data[0], self.src.data[0]) assert dataset1.livetime == 1.5 * self.livetime assert_allclose(dataset1.background.data[1:], 3 * self.bkg.data[1:]) assert_allclose(dataset1.background.data[0], self.bkg.data[0]) assert_allclose( dataset1.aeff.data.data.to_value("m2"), 4.0 / 3 * aeff.data.data.to_value("m2"), ) assert_allclose(dataset1.edisp.pdf_matrix[1:], edisp.pdf_matrix[1:]) assert_allclose(dataset1.edisp.pdf_matrix[0], 0.5 * edisp.pdf_matrix[0])
def test_wrong_init(self): bins = energy_logspace(1, 10, 8, "TeV") with pytest.raises(ValueError): CountsSpectrum(data=self.counts, energy_lo=bins[:-1], energy_hi=bins[1:])
def setup(self): self.counts = [0, 0, 2, 5, 17, 3] self.bins = energy_logspace(1, 10, 7, "TeV") self.spec = CountsSpectrum( data=self.counts, energy_lo=self.bins[:-1], energy_hi=self.bins[1:] )
# In[ ]: arf.data.data *= containment # ## Estimate background # # We now provide a workaround to estimate the background from the tabulated IRF in the energy bins we consider. # In[ ]: bkg_data = irfs["bkg"].evaluate_integrate(fov_lon=0 * u.deg, fov_lat=offset, energy_reco=energy_reco) bkg = CountsSpectrum( energy_reco[:-1], energy_reco[1:], data=(bkg_data * solid_angles).to_value("s-1"), unit="s-1", ) # ## Compute sensitivity # # We impose a minimal number of expected signal counts of 5 per bin and a minimal significance of 3 per bin. We assume an alpha of 0.2 (ratio between ON and OFF area). # We then run the sensitivity estimator. # In[ ]: sensitivity_estimator = SensitivityEstimator(arf=arf, rmf=rmf, bkg=bkg, livetime="5h", gamma_min=5,
def test_wrong_init(self): bins = MapAxis.from_energy_bounds(1, 10, 8, "TeV").edges with pytest.raises(ValueError): CountsSpectrum(data=self.counts, energy_lo=bins[:-1], energy_hi=bins[1:])
def setup(self): self.counts = [0, 0, 2, 5, 17, 3] self.bins = MapAxis.from_energy_bounds(1, 10, 6, "TeV").edges self.spec = CountsSpectrum(data=self.counts, energy_lo=self.bins[:-1], energy_hi=self.bins[1:])
# In[ ]: arf.data.data *= containment # ## Estimate background # # We now provide a workaround to estimate the background from the tabulated IRF in the energy bins we consider. # In[ ]: bkg_data = irfs["bkg"].evaluate_integrate(fov_lon=0 * u.deg, fov_lat=offset, energy_reco=energy_reco) bkg = CountsSpectrum(energy_reco[:-1], energy_reco[1:], data=(bkg_data * solid_angles)) # ## Compute sensitivity # # We impose a minimal number of expected signal counts of 5 per bin and a minimal significance of 3 per bin. We assume an alpha of 0.2 (ratio between ON and OFF area). # We then run the sensitivity estimator. # In[ ]: sensitivity_estimator = SensitivityEstimator(arf=arf, rmf=rmf, bkg=bkg, livetime="5h", gamma_min=5, sigma=3,
# # In this section we will include a background component extracted from the IRF. Furthermore, we will also simulate more than one observation and fit each one individually in order to get average fit results. # In[ ]: # We assume a PowerLawSpectralModel shape of the background as well bkg_data = ( cta_irf["bkg"].evaluate_integrate( fov_lon=0 * u.deg, fov_lat=offset, energy_reco=energy ) * solid_angle * livetime ) bkg = CountsSpectrum( energy[:-1], energy[1:], data=bkg_data.to_value(""), unit="" ) # In[ ]: dataset = SpectrumDatasetOnOff( aeff=aeff, edisp=edisp, model=model_ref, livetime=livetime, acceptance=1, acceptance_off=5, )