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_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 run(self, geom): """Create and fill the map dataset""" dataset = MapDataset.create(geom, binsz_irf=1.0) dataset.counts.fill_events(self.events) dataset.gti = self._make_gti() self._fill_psfmap(self.psf, dataset) # recompute exposure on geom coords = geom.get_coord() # this is to change the axis name. Can we avoid this? coords = MapCoord.create( dict(skycoord=coords.skycoord, energy_true=coords['energy'])) values = self.exposure.interp_by_coord(coords) dataset.exposure = Map.from_geom(geom, data=values, unit=self.exposure.unit) # Not the real Fermi-LAT EDISP: Use 5% energy resolution as approximation energy = geom.axes[0] edisp = EDispKernel.from_gauss(e_true=energy.edges, e_reco=energy.edges, sigma=0.05, bias=0) dataset.edisp = edisp return dataset
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 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 test_io(self, tmp_path): indices = np.array([[1, 3, 6], [3, 3, 2]]) desired = self.edisp.pdf_matrix[indices] self.edisp.write(tmp_path / "tmp.fits") edisp2 = EDispKernel.read(tmp_path / "tmp.fits") actual = edisp2.pdf_matrix[indices] assert_allclose(actual, desired)
def create(cls, e_reco, e_true=None, region=None, reference_time="2000-01-01", name=None, meta_table=None): """Creates empty spectrum dataset. Empty containers are created with the correct geometry. counts, background and aeff are zero and edisp is diagonal. The safe_mask is set to False in every bin. Parameters ---------- e_reco : `~gammapy.maps.MapAxis` counts energy axis. Its name must be "energy". e_true : `~gammapy.maps.MapAxis` effective area table energy axis. Its name must be "energy-true". If not set use reco energy values. Default : None region : `~regions.SkyRegion` Region to define the dataset for. reference_time : `~astropy.time.Time` reference time of the dataset, Default is "2000-01-01" meta_table : `~astropy.table.Table` Table listing informations on observations used to create the dataset. One line per observation for stacked datasets. """ if e_true is None: e_true = e_reco.copy(name="energy_true") if region is None: region = "icrs;circle(0, 0, 1)" counts = RegionNDMap.create(region=region, axes=[e_reco]) background = RegionNDMap.create(region=region, axes=[e_reco]) aeff = EffectiveAreaTable( e_true.edges[:-1], e_true.edges[1:], np.zeros(e_true.edges[:-1].shape) * u.m**2, ) edisp = EDispKernel.from_diagonal_response(e_true.edges, e_reco.edges) mask_safe = RegionNDMap.from_geom(counts.geom, dtype="bool") gti = GTI.create(u.Quantity([], "s"), u.Quantity([], "s"), reference_time) livetime = gti.time_sum return SpectrumDataset( counts=counts, aeff=aeff, edisp=edisp, mask_safe=mask_safe, background=background, livetime=livetime, gti=gti, name=name, )
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) 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.on_region = make_region("icrs;circle(0.,1.,0.1)") off_region = make_region("icrs;box(0.,1.,0.1, 0.2,30)") self.off_region = off_region.union( make_region("icrs;box(-1.,-1.,0.1, 0.2,150)") ) self.wcs = WcsGeom.create(npix=300, binsz=0.01, frame="icrs").wcs data = np.ones(elo.shape) data[-1] = 0 # to test stats calculation with empty bins axis = MapAxis.from_edges(ereco, name="energy", interp="log") self.on_counts = RegionNDMap.create( region=self.on_region, wcs=self.wcs, axes=[axis] ) self.on_counts.data += 1 self.on_counts.data[-1] = 0 self.off_counts = RegionNDMap.create( region=self.off_region, wcs=self.wcs, axes=[axis] ) self.off_counts.data += 10 acceptance = RegionNDMap.from_geom(self.on_counts.geom) acceptance.data += 1 data = np.ones(elo.shape) data[-1] = 0 acceptance_off = RegionNDMap.from_geom(self.off_counts.geom) acceptance_off.data += 10 self.dataset = SpectrumDatasetOnOff( counts=self.on_counts, counts_off=self.off_counts, aeff=self.aeff, edisp=self.edisp, livetime=self.livetime, acceptance=acceptance, acceptance_off=acceptance_off, name="test", gti=self.gti, )
def test_from_diagonal_response(self): energy_axis_true = MapAxis.from_energy_edges([0.5, 1, 2, 4, 6] * u.TeV, name="energy_true") energy_axis = MapAxis.from_energy_edges([2, 4, 6] * u.TeV) edisp = EDispKernel.from_diagonal_response(energy_axis_true, energy_axis) assert edisp.pdf_matrix.shape == (4, 2) expected = [[0, 0], [0, 0], [1, 0], [0, 1]] assert_equal(edisp.pdf_matrix, expected) # Test square matrix edisp = EDispKernel.from_diagonal_response(energy_axis_true) assert_allclose(edisp.axes["energy"].edges, edisp.axes["energy_true"].edges) assert edisp.axes["energy"].unit == "TeV" assert_equal(edisp.pdf_matrix[0][0], 1) assert_equal(edisp.pdf_matrix[2][0], 0) assert edisp.pdf_matrix.sum() == 4
def test_from_diagonal_response(self): e_true = [0.5, 1, 2, 4, 6] * u.TeV e_reco = [2, 4, 6] * u.TeV edisp = EDispKernel.from_diagonal_response(e_true, e_reco) assert edisp.pdf_matrix.shape == (4, 2) expected = [[0, 0], [0, 0], [1, 0], [0, 1]] assert_equal(edisp.pdf_matrix, expected) # Test square matrix edisp = EDispKernel.from_diagonal_response(e_true) assert_allclose(edisp.e_reco.edges.value, e_true.value) assert edisp.e_reco.unit == "TeV" assert_equal(edisp.pdf_matrix[0][0], 1) assert_equal(edisp.pdf_matrix[2][0], 0) assert edisp.pdf_matrix.sum() == 4
def spectrum_dataset(): e_true = np.logspace(0, 1, 21) * u.TeV e_reco = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=4) aeff = EffectiveAreaTable.from_constant(value=1e6 * u.m ** 2, energy=e_true) edisp = EDispKernel.from_diagonal_response(e_true, e_reco.edges) background = RegionNDMap.create(region="icrs;circle(0, 0, 0.1)", axes=[e_reco]) background.data += 3600 background.data[-1] *= 1e-3 return SpectrumDataset(aeff=aeff, livetime="1h", edisp=edisp, background=background)
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 axis = MapAxis.from_edges(energy, name="energy", interp="log") geom = RegionGeom(region=None, axes=[axis]) on_vector = RegionNDMap.from_geom(geom=geom, data=data_on) off_vector1 = RegionNDMap.from_geom(geom=geom, data=dataoff_1) off_vector2 = RegionNDMap.from_geom(geom=geom, data=dataoff_2) mask_safe = RegionNDMap.from_geom(geom, dtype=bool) mask_safe.data += True 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=mask_safe, 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=mask_safe, acceptance=1, acceptance_off=4, name="2", gti=gti2, ) obs_list = [obs1, obs2] return obs_list
def setup(self): self.e_true = np.logspace(0, 1, 101) * u.TeV self.e_reco = self.e_true self.resolution = 0.1 self.bias = 0 self.edisp = EDispKernel.from_gauss( e_true=self.e_true, e_reco=self.e_reco, pdf_threshold=1e-7, sigma=self.resolution, bias=self.bias, )
def create(cls, e_reco, e_true=None, region=None, reference_time="2000-01-01", name=None): """Creates empty spectrum dataset. Empty containers are created with the correct geometry. counts, background and aeff are zero and edisp is diagonal. The safe_mask is set to False in every bin. Parameters ---------- e_reco : `~astropy.units.Quantity` edges of counts vector e_true : `~astropy.units.Quantity` edges of effective area table. If not set use reco energy values. Default : None region : `~regions.SkyRegion` Region to define the dataset for. reference_time : `~astropy.time.Time` reference time of the dataset, Default is "2000-01-01" """ if e_true is None: e_true = e_reco if region is None: region = "icrs;circle(0, 0, 1)" # TODO: change .create() API energy = MapAxis.from_edges(e_reco, interp="log", name="energy") counts = RegionNDMap.create(region=region, axes=[energy]) background = RegionNDMap.create(region=region, axes=[energy]) aeff = EffectiveAreaTable(e_true[:-1], e_true[1:], np.zeros(e_true[:-1].shape) * u.m**2) edisp = EDispKernel.from_diagonal_response(e_true, e_reco) mask_safe = RegionNDMap.from_geom(counts.geom, dtype="bool") gti = GTI.create(u.Quantity([], "s"), u.Quantity([], "s"), reference_time) livetime = gti.time_sum return SpectrumDataset( counts=counts, aeff=aeff, edisp=edisp, mask_safe=mask_safe, background=background, livetime=livetime, gti=gti, name=name, )
def setup(self): energy_axis = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=100) energy_axis_true = energy_axis.copy(name="energy_true") self.resolution = 0.1 self.bias = 0 self.edisp = EDispKernel.from_gauss( energy_axis_true=energy_axis_true, energy_axis=energy_axis, pdf_threshold=1e-7, sigma=self.resolution, bias=self.bias, )
def test_apply_edisp(region_map_true): e_true = region_map_true.geom.axes[0].edges e_reco = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=3).edges edisp = EDispKernel.from_diagonal_response(e_true=e_true, e_reco=e_reco) m = region_map_true.apply_edisp(edisp) assert m.geom.data_shape == (3, 1, 1) e_reco = m.geom.axes[0].edges assert e_reco.unit == "TeV" assert m.geom.axes[0].name == "energy" assert_allclose(e_reco[[0, -1]].value, [1, 10])
def create(cls, e_reco, e_true=None, region=None, reference_time="2000-01-01", name=None): """Create empty SpectrumDatasetOnOff. Empty containers are created with the correct geometry. counts, counts_off and aeff are zero and edisp is diagonal. The safe_mask is set to False in every bin. Parameters ---------- e_reco : `~astropy.units.Quantity` edges of counts vector e_true : `~astropy.units.Quantity` edges of effective area table. If not set use reco energy values. Default : None region : `~regions.SkyRegion` Region to define the dataset for. reference_time : `~astropy.time.Time` reference time of the dataset, Default is "2000-01-01" """ if e_true is None: e_true = e_reco counts = CountsSpectrum(e_reco[:-1], e_reco[1:], region=region) counts_off = CountsSpectrum(e_reco[:-1], e_reco[1:], region=region) aeff = EffectiveAreaTable(e_true[:-1], e_true[1:], np.zeros(e_true[:-1].shape) * u.m**2) edisp = EDispKernel.from_diagonal_response(e_true, e_reco) mask_safe = np.zeros_like(counts.data, "bool") gti = GTI.create(u.Quantity([], "s"), u.Quantity([], "s"), reference_time) livetime = gti.time_sum acceptance = np.ones_like(counts.data, int) acceptance_off = np.ones_like(counts.data, int) return SpectrumDatasetOnOff( counts=counts, counts_off=counts_off, aeff=aeff, edisp=edisp, mask_safe=mask_safe, acceptance=acceptance, acceptance_off=acceptance_off, livetime=livetime, gti=gti, name=name, )
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 test_to_image(self): e_reco = MapAxis.from_energy_bounds("0.1 TeV", "10 TeV", nbin=3) e_true = MapAxis.from_energy_bounds( "0.08 TeV", "20 TeV", nbin=5, name="energy_true" ) edisp = EDispKernel.from_gauss( energy=e_reco.edges, energy_true=e_true.edges, sigma=0.2, bias=0.1 ) im = edisp.to_image() assert im.pdf_matrix.shape == (5, 1) assert_allclose( im.pdf_matrix, [[0.97142], [1.0], [1.0], [1.0], [0.12349]], rtol=1e-3 ) assert_allclose(im.energy_axis.edges, [0.1, 10] * u.TeV)
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_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_edispkernel_from_1D(): energy_axis_true = MapAxis.from_energy_bounds( "0.5 TeV", "5 TeV", nbin=31, name="energy_true" ) energy_axis = MapAxis.from_energy_bounds( "0.1 TeV", "10 TeV", nbin=11, name="energy" ) edisp = EDispKernel.from_gauss(energy_axis_true.edges, energy_axis.edges, 0.1, 0.0) region = make_region("fk5;circle(0.,0., 10.") geom = RegionGeom(region) region_edisp = EDispKernelMap.from_edisp_kernel(edisp, geom=geom) sum_kernel = np.sum(region_edisp.edisp_map.data[..., 0, 0], axis=1) assert_allclose(sum_kernel, 1, rtol=1e-5) allsky_edisp = EDispKernelMap.from_edisp_kernel(edisp) sum_kernel = np.sum(allsky_edisp.edisp_map.data[..., 0, 0], axis=1) assert allsky_edisp.edisp_map.data.shape == (31, 11, 1, 2) assert_allclose(sum_kernel, 1, rtol=1e-5)
def get_map_dataset(geom, geom_etrue, edisp="edispmap", name="test", **kwargs): """Returns a MapDatasets""" # define background model background = Map.from_geom(geom) background.data += 0.2 psf = get_psf() exposure = get_exposure(geom_etrue) e_reco = geom.axes["energy"] e_true = geom_etrue.axes["energy_true"] if edisp == "edispmap": edisp = EDispMap.from_diagonal_response(energy_axis_true=e_true) elif edisp == "edispkernelmap": edisp = EDispKernelMap.from_diagonal_response( energy_axis=e_reco, energy_axis_true=e_true ) elif edisp == "edispkernel": edisp = EDispKernel.from_diagonal_response( energy_true=e_true.edges, energy=e_reco.edges ) else: edisp = None # define fit mask center = SkyCoord("0.2 deg", "0.1 deg", frame="galactic") circle = CircleSkyRegion(center=center, radius=1 * u.deg) mask_fit = geom.region_mask([circle]) mask_fit = Map.from_geom(geom, data=mask_fit) models = FoVBackgroundModel(dataset_name=name) return MapDataset( models=models, exposure=exposure, background=background, psf=psf, edisp=edisp, mask_fit=mask_fit, name=name, **kwargs, )
def get_map_dataset(sky_model, geom, geom_etrue, edisp="edispmap", name="test", **kwargs): """Returns a MapDatasets""" # define background model m = Map.from_geom(geom) m.quantity = 0.2 * np.ones(m.data.shape) background_model = BackgroundModel(m, datasets_names=[name]) psf = get_psf() exposure = get_exposure(geom_etrue) e_reco = geom.get_axis_by_name("energy") e_true = geom_etrue.get_axis_by_name("energy_true") if edisp == "edispmap": edisp = EDispMap.from_diagonal_response(energy_axis_true=e_true) elif edisp == "edispkernelmap": edisp = EDispKernelMap.from_diagonal_response(energy_axis=e_reco, energy_axis_true=e_true) elif edisp == "edispkernel": edisp = EDispKernel.from_diagonal_response(e_true=e_true.edges, e_reco=e_reco.edges) else: edisp = None # define fit mask center = sky_model.spatial_model.position circle = CircleSkyRegion(center=center, radius=1 * u.deg) mask_fit = background_model.map.geom.region_mask([circle]) mask_fit = Map.from_geom(geom, data=mask_fit) return MapDataset(models=[sky_model, background_model], exposure=exposure, psf=psf, edisp=edisp, mask_fit=mask_fit, name=name, **kwargs)
def read_rmf(filename, exposure): """Read RMF file Parameters ---------- filename : str or `Path` PHA file name exposure : `RegionNDMap` Exposure map Returns ------- data : `EDispKernelMap` Dict with edisp """ kernel = EDispKernel.read(filename) edisp = EDispKernelMap.from_edisp_kernel(kernel, geom=exposure.geom) # TODO: resolve this separate handling of exposure for edisp edisp.exposure_map.data = exposure.data[:, :, np.newaxis, :] return edisp
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=SkyModel(spectral_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=SkyModel(spectral_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=SkyModel(spectral_model=PowerLawSpectralModel( amplitude="1e-11 TeV-1 cm-2 s-1")), aeff=EffectiveAreaTable.from_parametrization(e_true), edisp=EDispKernel.from_gauss(e_reco=e_reco, e_true=e_true, bias=0, sigma=0.2), livetime="10 h", npred=1437.494815, ), dict( model=SkyModel(spectral_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"), )), aeff=EffectiveAreaTable.from_constant([0.1, 0.2, 0.3, 0.4] * u.TeV, 1), npred=0.554513062, ), ]
def from_ogip_files(cls, filename): """Read `~gammapy.spectrum.SpectrumDatasetOnOff` from OGIP files. BKG file, ARF, and RMF must be set in the PHA header and be present in the same folder. The naming scheme is fixed to the following scheme: * PHA file is named ``pha_obs{name}.fits`` * BKG file is named ``bkg_obs{name}.fits`` * ARF file is named ``arf_obs{name}.fits`` * RMF file is named ``rmf_obs{name}.fits`` with ``{name}`` the dataset name. Parameters ---------- filename : str OGIP PHA file to read """ filename = make_path(filename) dirname = filename.parent with fits.open(str(filename), memmap=False) as hdulist: counts = RegionNDMap.from_hdulist(hdulist, format="ogip") acceptance = RegionNDMap.from_hdulist( hdulist, format="ogip", ogip_column="BACKSCAL" ) if "GTI" in hdulist: gti = GTI(Table.read(hdulist["GTI"])) else: gti = None mask_safe = RegionNDMap.from_hdulist( hdulist, format="ogip", ogip_column="QUALITY" ) mask_safe.data = np.logical_not(mask_safe.data) phafile = filename.name try: rmffile = phafile.replace("pha", "rmf") kernel = EDispKernel.read(dirname / rmffile) edisp = EDispKernelMap.from_edisp_kernel(kernel, geom=counts.geom) except OSError: # TODO : Add logger and echo warning edisp = None try: bkgfile = phafile.replace("pha", "bkg") with fits.open(str(dirname / bkgfile), memmap=False) as hdulist: counts_off = RegionNDMap.from_hdulist(hdulist, format="ogip") acceptance_off = RegionNDMap.from_hdulist( hdulist, ogip_column="BACKSCAL" ) except OSError: # TODO : Add logger and echo warning counts_off, acceptance_off = None, None arffile = phafile.replace("pha", "arf") aeff = RegionNDMap.read(dirname / arffile, format="ogip-arf") return cls( counts=counts, aeff=aeff, counts_off=counts_off, edisp=edisp, livetime=counts.meta["EXPOSURE"] * u.s, mask_safe=mask_safe, acceptance=acceptance, acceptance_off=acceptance_off, name=str(counts.meta["OBS_ID"]), gti=gti, )
def test_get_bias_energy(): """Obs read from file""" rmffile = "$GAMMAPY_DATA/joint-crab/spectra/hess/rmf_obs23523.fits" edisp = EDispKernel.read(rmffile) thresh_lo = edisp.get_bias_energy(0.1) assert_allclose(thresh_lo.to("TeV").value, 0.9174, rtol=1e-4)
def edisp(geom, geom_true): e_reco = geom.get_axis_by_name("energy").edges e_true = geom_true.get_axis_by_name("energy_true").edges return EDispKernel.from_diagonal_response(e_true=e_true, e_reco=e_reco)