def simulate_spectrum_dataset(model, random_state=0): edges = np.logspace(-0.5, 1.5, 21) * u.TeV energy_axis = MapAxis.from_edges(edges, interp="log", name="energy") aeff = EffectiveAreaTable.from_parametrization(energy=edges).to_region_map() bkg_model = SkyModel( spectral_model=PowerLawSpectralModel( index=2.5, amplitude="1e-12 cm-2 s-1 TeV-1" ), name="background", ) bkg_model.spectral_model.amplitude.frozen = True bkg_model.spectral_model.index.frozen = True geom = RegionGeom(region=None, axes=[energy_axis]) acceptance = RegionNDMap.from_geom(geom=geom, data=1) edisp = EDispKernelMap.from_diagonal_response( energy_axis=energy_axis, energy_axis_true=energy_axis.copy(name="energy_true"), geom=geom ) dataset = SpectrumDatasetOnOff( aeff=aeff, livetime=100 * u.h, acceptance=acceptance, acceptance_off=5, edisp=edisp ) dataset.models = bkg_model bkg_npred = dataset.npred_sig() dataset.models = model dataset.fake(random_state=random_state, background_model=bkg_npred) return dataset
def test_spectrum_dataset_stack_nondiagonal_no_bkg(self): aeff = EffectiveAreaTable.from_parametrization(self.src.energy.edges, "HESS") edisp1 = EDispKernel.from_gauss(self.src.energy.edges, self.src.energy.edges, 0.1, 0.0) livetime = self.livetime dataset1 = SpectrumDataset(counts=None, livetime=livetime, aeff=aeff, edisp=edisp1, background=None) livetime2 = livetime aeff2 = EffectiveAreaTable(self.src.energy.edges[:-1], self.src.energy.edges[1:], aeff.data.data) edisp2 = EDispKernel.from_gauss(self.src.energy.edges, self.src.energy.edges, 0.2, 0.0) dataset2 = SpectrumDataset( counts=self.src.copy(), livetime=livetime2, aeff=aeff2, edisp=edisp2, background=None, ) dataset1.stack(dataset2) assert dataset1.counts is None assert dataset1.background is None assert dataset1.livetime == 2 * self.livetime assert_allclose(dataset1.aeff.data.data.to_value("m2"), aeff.data.data.to_value("m2")) assert_allclose(dataset1.edisp.get_bias(1 * u.TeV), 0.0, atol=1.2e-3) assert_allclose(dataset1.edisp.get_resolution(1 * u.TeV), 0.1581, atol=1e-2)
def test_compute_thresholds_from_parametrization(): energy = np.logspace(-2, 2.0, 100) * u.TeV aeff = EffectiveAreaTable.from_parametrization(energy=energy) edisp = EnergyDispersion.from_gauss(e_true=energy, e_reco=energy, sigma=0.2, bias=0) thresh_lo, thresh_hi = compute_energy_thresholds( aeff=aeff, edisp=edisp, method_lo="area_max", method_hi="area_max", area_percent_lo=10, area_percent_hi=90, ) assert_allclose(thresh_lo.to("TeV").value, 0.18557, rtol=1e-4) assert_allclose(thresh_hi.to("TeV").value, 43.818, rtol=1e-4) thresh_lo, thresh_hi = compute_energy_thresholds(aeff=aeff, edisp=edisp, method_hi="area_max", area_percent_hi=70) assert_allclose(thresh_hi.to("TeV").value, 100.0, rtol=1e-4)
def test_spectrum_dataset_stack_nondiagonal_no_bkg(spectrum_dataset): energy = spectrum_dataset.counts.geom.axes[0].edges aeff = EffectiveAreaTable.from_parametrization(energy, "HESS") edisp1 = EDispKernel.from_gauss(energy, energy, 0.1, 0) livetime = 100 * u.s spectrum_dataset1 = SpectrumDataset( counts=spectrum_dataset.counts.copy(), livetime=livetime, aeff=aeff, edisp=edisp1, ) livetime2 = livetime aeff2 = EffectiveAreaTable( energy[:-1], energy[1:], aeff.data.data ) edisp2 = EDispKernel.from_gauss(energy, energy, 0.2, 0.0) spectrum_dataset2 = SpectrumDataset( counts=spectrum_dataset.counts.copy(), livetime=livetime2, aeff=aeff2, edisp=edisp2, ) spectrum_dataset1.stack(spectrum_dataset2) assert spectrum_dataset1.background is None assert spectrum_dataset1.livetime == 2 * livetime assert_allclose( spectrum_dataset1.aeff.data.data.to_value("m2"), aeff.data.data.to_value("m2") ) assert_allclose(spectrum_dataset1.edisp.get_bias(1 * u.TeV), 0.0, atol=1.2e-3) assert_allclose(spectrum_dataset1.edisp.get_resolution(1 * u.TeV), 0.1581, atol=1e-2)
def test_spectrum_dataset_stack_diagonal_safe_mask(spectrum_dataset): geom = spectrum_dataset.counts.geom energy = MapAxis.from_energy_bounds("0.1 TeV", "10 TeV", nbin=30) energy_true = MapAxis.from_energy_bounds("0.1 TeV", "10 TeV", nbin=30, name="energy_true") aeff = EffectiveAreaTable.from_parametrization(energy.edges, "HESS") edisp = EDispKernelMap.from_diagonal_response(energy, energy_true, geom=geom.to_image()) livetime = 100 * u.s background = spectrum_dataset.background spectrum_dataset1 = SpectrumDataset( counts=spectrum_dataset.counts.copy(), livetime=livetime, aeff=aeff, edisp=edisp.copy(), background=background.copy(), ) livetime2 = 0.5 * livetime aeff2 = EffectiveAreaTable(energy.edges[:-1], energy.edges[1:], 2 * aeff.data.data) bkg2 = RegionNDMap.from_geom(geom=geom, data=2 * background.data) geom = spectrum_dataset.counts.geom data = np.ones(spectrum_dataset.data_shape, dtype="bool") data[0] = False safe_mask2 = RegionNDMap.from_geom(geom=geom, data=data) spectrum_dataset2 = SpectrumDataset( counts=spectrum_dataset.counts.copy(), livetime=livetime2, aeff=aeff2, edisp=edisp, background=bkg2, mask_safe=safe_mask2, ) spectrum_dataset1.stack(spectrum_dataset2) reference = spectrum_dataset.counts.data assert_allclose(spectrum_dataset1.counts.data[1:], reference[1:] * 2) assert_allclose(spectrum_dataset1.counts.data[0], 141363) assert spectrum_dataset1.livetime == 1.5 * livetime assert_allclose(spectrum_dataset1.background.data[1:], 3 * background.data[1:]) assert_allclose(spectrum_dataset1.background.data[0], background.data[0]) assert_allclose( spectrum_dataset1.aeff.data.data.to_value("m2"), 4.0 / 3 * aeff.data.data.to_value("m2"), ) kernel = edisp.get_edisp_kernel() kernel_stacked = spectrum_dataset1.edisp.get_edisp_kernel() assert_allclose(kernel_stacked.pdf_matrix[1:], kernel.pdf_matrix[1:]) assert_allclose(kernel_stacked.pdf_matrix[0], 0.5 * kernel.pdf_matrix[0])
def test_from_parametrization(): # Log center of this is 100 GeV energy = [80, 125] * u.GeV area_ref = 1.65469579e07 * u.cm ** 2 area = EffectiveAreaTable.from_parametrization(energy, "HESS") assert_allclose(area.data.data, area_ref) assert area.data.data.unit == area_ref.unit # Log center of this is 0.1, 2 TeV energy = [0.08, 0.125, 32] * u.TeV area_ref = [1.65469579e07, 1.46451957e09] * u.cm * u.cm area = EffectiveAreaTable.from_parametrization(energy, "HESS") assert_allclose(area.data.data, area_ref) assert area.data.data.unit == area_ref.unit
def get_test_cases(): e_true = Quantity(np.logspace(-1, 2, 120), "TeV") e_reco = Quantity(np.logspace(-1, 2, 100), "TeV") return [ dict(model=PowerLawSpectralModel(amplitude="1e2 TeV-1"), e_true=e_true, npred=999), dict( model=PowerLaw2SpectralModel(amplitude="1", emin="0.1 TeV", emax="100 TeV"), e_true=e_true, npred=1, ), dict( model=PowerLawSpectralModel(amplitude="1e-11 TeV-1 cm-2 s-1"), aeff=EffectiveAreaTable.from_parametrization(e_true), livetime="10 h", npred=1448.05960, ), dict( model=PowerLawSpectralModel(reference="1 GeV", amplitude="1e-11 GeV-1 cm-2 s-1"), aeff=EffectiveAreaTable.from_parametrization(e_true), livetime="30 h", npred=4.34417881, ), dict( model=PowerLawSpectralModel(amplitude="1e-11 TeV-1 cm-2 s-1"), aeff=EffectiveAreaTable.from_parametrization(e_true), edisp=EnergyDispersion.from_gauss(e_reco=e_reco, e_true=e_true, bias=0, sigma=0.2), livetime="10 h", npred=1437.450076, ), dict( model=TemplateSpectralModel( energy=[0.1, 0.2, 0.3, 0.4] * u.TeV, values=[4.0, 3.0, 1.0, 0.1] * u.Unit("TeV-1"), ), e_true=[0.1, 0.2, 0.3, 0.4] * u.TeV, npred=0.554513062, ), ]
def test_spectrum_dataset_stack_nondiagonal_no_bkg(spectrum_dataset): energy = spectrum_dataset.counts.geom.axes["energy"] geom = spectrum_dataset.counts.geom.to_image() edisp1 = EDispKernelMap.from_gauss( energy_axis=energy, energy_axis_true=energy.copy(name="energy_true"), sigma=0.1, bias=0, geom=geom) edisp1.exposure_map.data += 1 aeff = EffectiveAreaTable.from_parametrization( energy.edges, "HESS").to_region_map(geom.region) geom = spectrum_dataset.counts.geom counts = RegionNDMap.from_geom(geom=geom) gti = GTI.create(start=0 * u.s, stop=100 * u.s) spectrum_dataset1 = SpectrumDataset( counts=counts, exposure=aeff * gti.time_sum, edisp=edisp1, meta_table=Table({"OBS_ID": [0]}), gti=gti.copy(), ) edisp2 = EDispKernelMap.from_gauss( energy_axis=energy, energy_axis_true=energy.copy(name="energy_true"), sigma=0.2, bias=0.0, geom=geom) edisp2.exposure_map.data += 1 gti2 = GTI.create(start=100 * u.s, stop=200 * u.s) spectrum_dataset2 = SpectrumDataset( counts=counts, exposure=aeff * gti2.time_sum, edisp=edisp2, meta_table=Table({"OBS_ID": [1]}), gti=gti2, ) spectrum_dataset1.stack(spectrum_dataset2) assert_allclose(spectrum_dataset1.meta_table["OBS_ID"][0], [0, 1]) assert spectrum_dataset1.background_model is None assert_allclose(spectrum_dataset1.gti.time_sum.to_value("s"), 200) assert_allclose(spectrum_dataset1.exposure.quantity[2].to_value("m2 s"), 1573851.079861) kernel = edisp1.get_edisp_kernel() assert_allclose(kernel.get_bias(1 * u.TeV), 0.0, atol=1.2e-3) assert_allclose(kernel.get_resolution(1 * u.TeV), 0.1581, atol=1e-2)
def test_set_model(self): aeff = EffectiveAreaTable.from_parametrization(self.src.energy.edges, "HESS") edisp = EnergyDispersion.from_diagonal_response( self.src.energy.edges, self.src.energy.edges) dataset = SpectrumDataset(None, self.src, self.livetime, None, aeff, edisp, self.bkg) with pytest.raises(AttributeError): dataset.parameters dataset.model = self.source_model assert dataset.parameters[0] == self.source_model.parameters[0]
def test_compute_thresholds_from_parametrization(): energy = np.logspace(-2, 2.0, 100) * u.TeV aeff = EffectiveAreaTable.from_parametrization(energy=energy) thresh_lo = aeff.find_energy(aeff=0.1 * aeff.max_area) e_max = aeff.energy.edges[-1] thresh_hi = aeff.find_energy( aeff=0.9 * aeff.max_area, energy_min=0.1 * e_max, energy_max=e_max ) assert_allclose(thresh_lo.to("TeV").value, 0.18557, rtol=1e-4) assert_allclose(thresh_hi.to("TeV").value, 43.818, rtol=1e-4)
def test_spectrum_dataset_stack_diagonal_safe_mask(spectrum_dataset): geom = spectrum_dataset.counts.geom energy = np.logspace(-1, 1, 31) * u.TeV aeff = EffectiveAreaTable.from_parametrization(energy, "HESS") edisp = EDispKernel.from_diagonal_response(energy, energy) livetime = 100 * u.s background = spectrum_dataset.background spectrum_dataset1 = SpectrumDataset( counts=spectrum_dataset.counts.copy(), livetime=livetime, aeff=aeff, edisp=edisp, background=background.copy(), ) livetime2 = 0.5 * livetime aeff2 = EffectiveAreaTable(energy[:-1], energy[1:], 2 * aeff.data.data) bkg2 = RegionNDMap.from_geom(geom=geom, data=2 * background.data) geom = spectrum_dataset.counts.geom data = np.ones(spectrum_dataset.data_shape, dtype="bool") data[0] = False safe_mask2 = RegionNDMap.from_geom(geom=geom, data=data) spectrum_dataset2 = SpectrumDataset( counts=spectrum_dataset.counts.copy(), livetime=livetime2, aeff=aeff2, edisp=edisp, background=bkg2, mask_safe=safe_mask2, ) spectrum_dataset1.stack(spectrum_dataset2) reference = spectrum_dataset.counts.data assert_allclose(spectrum_dataset1.counts.data[1:], reference[1:] * 2) assert_allclose(spectrum_dataset1.counts.data[0], 141363) assert spectrum_dataset1.livetime == 1.5 * livetime assert_allclose(spectrum_dataset1.background.data[1:], 3 * background.data[1:]) assert_allclose(spectrum_dataset1.background.data[0], background.data[0]) assert_allclose( spectrum_dataset1.aeff.data.data.to_value("m2"), 4.0 / 3 * aeff.data.data.to_value("m2"), ) assert_allclose(spectrum_dataset1.edisp.pdf_matrix[1:], edisp.pdf_matrix[1:]) assert_allclose(spectrum_dataset1.edisp.pdf_matrix[0], 0.5 * edisp.pdf_matrix[0])
def simulate_spectrum_dataset(model, random_state=0): energy = np.logspace(-0.5, 1.5, 21) * u.TeV aeff = EffectiveAreaTable.from_parametrization(energy=energy) bkg_model = PowerLawSpectralModel(index=2.5, amplitude="1e-12 cm-2 s-1 TeV-1") dataset = SpectrumDatasetOnOff( aeff=aeff, model=model, livetime=100 * u.h, acceptance=1, acceptance_off=5 ) eval = SpectrumEvaluator(model=bkg_model, aeff=aeff, livetime=100 * u.h) bkg_model = eval.compute_npred() dataset.fake(random_state=random_state, background_model=bkg_model) return dataset
def test_set_model(self): aeff = EffectiveAreaTable.from_parametrization(self.src.energy.edges, "HESS") edisp = EDispKernel.from_diagonal_response(self.src.energy.edges, self.src.energy.edges) dataset = SpectrumDataset(None, self.src, self.livetime, None, aeff, edisp, self.bkg) spectral_model = PowerLawSpectralModel() model = SkyModel(spectral_model=spectral_model, name="test") dataset.models = model assert dataset.models["test"] is model models = Models([model]) dataset.models = models assert dataset.models["test"] is model
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_spectrum_dataset_stack_nondiagonal_no_bkg(spectrum_dataset): energy = spectrum_dataset.counts.geom.axes[0] geom = spectrum_dataset.counts.geom.to_image() edisp1 = EDispKernelMap.from_gauss(energy, energy, 0.1, 0, geom=geom) edisp1.exposure_map.data += 1 aeff = EffectiveAreaTable.from_parametrization( energy.edges, "HESS").to_region_map(geom.region) livetime = 100 * u.s spectrum_dataset1 = SpectrumDataset(counts=spectrum_dataset.counts.copy(), livetime=livetime, aeff=aeff, edisp=edisp1, meta_table=Table({"OBS_ID": [0]})) livetime2 = livetime aeff2 = aeff.copy() edisp2 = EDispKernelMap.from_gauss(energy, energy, 0.2, 0.0, geom=geom) edisp2.exposure_map.data += 1 spectrum_dataset2 = SpectrumDataset(counts=spectrum_dataset.counts.copy(), livetime=livetime2, aeff=aeff2, edisp=edisp2, meta_table=Table({"OBS_ID": [1]})) spectrum_dataset1.stack(spectrum_dataset2) assert_allclose(spectrum_dataset1.meta_table["OBS_ID"][0], [0, 1]) assert spectrum_dataset1.background is None assert spectrum_dataset1.livetime == 2 * livetime assert_allclose(spectrum_dataset1.aeff.quantity.to_value("m2"), aeff.quantity.to_value("m2")) kernel = edisp1.get_edisp_kernel() assert_allclose(kernel.get_bias(1 * u.TeV), 0.0, atol=1.2e-3) assert_allclose(kernel.get_resolution(1 * u.TeV), 0.1581, atol=1e-2)
def test_spectrum_dataset_stack_diagonal_safe_mask(spectrum_dataset): geom = spectrum_dataset.counts.geom energy = MapAxis.from_energy_bounds("0.1 TeV", "10 TeV", nbin=30) energy_true = MapAxis.from_energy_bounds("0.1 TeV", "10 TeV", nbin=30, name="energy_true") aeff = EffectiveAreaTable.from_parametrization( energy.edges, "HESS").to_region_map(geom.region) livetime = 100 * u.s gti = GTI.create(start=0 * u.s, stop=livetime) exposure = aeff * livetime edisp = EDispKernelMap.from_diagonal_response(energy, energy_true, geom=geom.to_image()) edisp.exposure_map.data = exposure.data[:, :, np.newaxis, :] background = spectrum_dataset.background_model.map.copy() spectrum_dataset1 = SpectrumDataset(name="ds1", counts=spectrum_dataset.counts.copy(), exposure=exposure.copy(), edisp=edisp.copy(), models=BackgroundModel( background, name="ds1-bkg", datasets_names=["ds1"]), gti=gti.copy()) livetime2 = 0.5 * livetime gti2 = GTI.create(start=200 * u.s, stop=200 * u.s + livetime2) aeff2 = aeff * 2 bkg2 = RegionNDMap.from_geom(geom=geom, data=2 * background.data) geom = spectrum_dataset.counts.geom data = np.ones(spectrum_dataset.data_shape, dtype="bool") data[0] = False safe_mask2 = RegionNDMap.from_geom(geom=geom, data=data) exposure2 = aeff2 * livetime2 edisp = edisp.copy() edisp.exposure_map.data = exposure2.data[:, :, np.newaxis, :] spectrum_dataset2 = SpectrumDataset(name="ds2", counts=spectrum_dataset.counts.copy(), exposure=exposure2, edisp=edisp, models=BackgroundModel( bkg2, name="ds2-bkg", datasets_names=["ds2"]), mask_safe=safe_mask2, gti=gti2) spectrum_dataset1.stack(spectrum_dataset2) reference = spectrum_dataset.counts.data assert_allclose(spectrum_dataset1.counts.data[1:], reference[1:] * 2) assert_allclose(spectrum_dataset1.counts.data[0], 141363) assert_allclose(spectrum_dataset1.exposure.data[0], 4.755644e+09) assert_allclose(spectrum_dataset1.background_model.map.data[1:], 3 * background.data[1:]) assert_allclose(spectrum_dataset1.background_model.map.data[0], background.data[0]) assert_allclose( spectrum_dataset1.exposure.quantity.to_value("m2s"), 2 * (aeff * livetime).quantity.to_value("m2s"), ) kernel = edisp.get_edisp_kernel() kernel_stacked = spectrum_dataset1.edisp.get_edisp_kernel() assert_allclose(kernel_stacked.pdf_matrix[1:], kernel.pdf_matrix[1:]) assert_allclose(kernel_stacked.pdf_matrix[0], 0.5 * kernel.pdf_matrix[0])
import numpy as np import matplotlib.pyplot as plt import astropy.units as u from gammapy.irf import EffectiveAreaTable energy = np.logspace(-3, 3, 100) * u.TeV for instrument in ['HESS', 'HESS2', 'CTA']: aeff = EffectiveAreaTable.from_parametrization(energy, instrument) ax = aeff.plot(label=instrument) ax.set_yscale('log') ax.set_xlim([1e-3, 1e3]) ax.set_ylim([1e3, 1e12]) plt.legend(loc='best') plt.show()
from gammapy.spectrum.models import PowerLaw # ## Create detector # # For the sake of self consistency of this tutorial, we will simulate a simple detector. For a real application you would want to replace this part of the code with loading the IRFs or your detector. # In[ ]: e_true = np.logspace(-2, 2.5, 109) * u.TeV e_reco = np.logspace(-2, 2, 79) * u.TeV edisp = EnergyDispersion.from_gauss(e_true=e_true, e_reco=e_reco, sigma=0.2, bias=0) aeff = EffectiveAreaTable.from_parametrization(energy=e_true) fig, axes = plt.subplots(1, 2, figsize=(12, 6)) edisp.plot_matrix(ax=axes[0]) aeff.plot(ax=axes[1]) # ## Power law # # In this section we will simulate one observation using a power law model. # In[ ]: pwl = PowerLaw(index=2.3, amplitude=1e-11 * u.Unit("cm-2 s-1 TeV-1"), reference=1 * u.TeV) print(pwl)