def spectrum_dataset(): name = "test" energy = np.logspace(-1, 1, 31) * u.TeV livetime = 100 * u.s pwl = PowerLawSpectralModel( index=2.1, amplitude="1e5 cm-2 s-1 TeV-1", reference="0.1 TeV", ) temp_mod = ConstantTemporalModel() model = SkyModel(spectral_model=pwl, temporal_model=temp_mod, name="test-source") axis = MapAxis.from_edges(energy, interp="log", name="energy") axis_true = MapAxis.from_edges(energy, interp="log", name="energy_true") background = RegionNDMap.create(region="icrs;circle(0, 0, 0.1)", axes=[axis]) models = Models([model]) exposure = RegionNDMap.create(region="icrs;circle(0, 0, 0.1)", axes=[axis_true]) exposure.quantity = u.Quantity("1 cm2") * livetime bkg_rate = np.ones(30) / u.s background.quantity = bkg_rate * livetime start = [1, 3, 5] * u.day stop = [2, 3.5, 6] * u.day t_ref = Time(55555, format="mjd") gti = GTI.create(start, stop, reference_time=t_ref) dataset = SpectrumDataset( models=models, exposure=exposure, background=background, name=name, gti=gti, ) dataset.fake(random_state=23) return dataset
def spectrum_dataset(): e_true = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=20, name="energy_true") e_reco = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=4) background = RegionNDMap.create(region="icrs;circle(0, 0, 0.1)", axes=[e_reco]) background.data += 3600 background.data[0] *= 1e3 background.data[-1] *= 1e-3 edisp = EDispKernelMap.from_diagonal_response(energy_axis_true=e_true, energy_axis=e_reco, geom=background.geom) exposure = RegionNDMap.create(region="icrs;circle(0, 0, 0.1)", axes=[e_true], unit="m2 h", data=1e6) return SpectrumDataset(name="test", exposure=exposure, edisp=edisp, background=background)
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)" name = make_name(name) counts = RegionNDMap.create(region=region, axes=[e_reco]) background = RegionNDMap.create(region=region, axes=[e_reco]) exposure = RegionNDMap.create(region=region, axes=[e_true], unit="cm2 s", meta={"livetime": 0 * u.s}) edisp = EDispKernelMap.from_diagonal_response(e_reco, e_true, geom=counts.geom) mask_safe = RegionNDMap.from_geom(counts.geom, dtype="bool") gti = GTI.create(u.Quantity([], "s"), u.Quantity([], "s"), reference_time) return SpectrumDataset( counts=counts, exposure=exposure, background=background, edisp=edisp, mask_safe=mask_safe, gti=gti, name=name, )
def spectrum_dataset(): e_true = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=20, name="energy_true") e_reco = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=4) background = RegionNDMap.create(region="icrs;circle(0, 0, 0.1)", axes=[e_reco]) background.data += 3600 background.data[0] *= 1e3 background.data[-1] *= 1e-3 edisp = EDispKernelMap.from_diagonal_response(energy_axis_true=e_true, energy_axis=e_reco, geom=background.geom) aeff = RegionNDMap.create(region="icrs;circle(0, 0, 0.1)", axes=[e_true], unit="m2") aeff.data += 1e6 livetime = 1 * u.h exposure = aeff * livetime return SpectrumDataset( name="test", exposure=exposure, edisp=edisp, models=BackgroundModel(background, name="test-bkg", datasets_names="test"), )
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_maps_region(): axis = MapAxis.from_edges([1, 2, 3, 4], name="axis", unit="cm") map1 = RegionNDMap.create(region=None, axes=[axis]) map1.data = 1 map2 = RegionNDMap.create(region=None, axes=[axis]) maps = Maps(map1=map1, map2=map2) assert len(maps) == 2 assert_allclose(maps["map1"], 1)
def test_stack_differen_unit(): region = "icrs;circle(0, 0, 1)" axis = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=3) region_map = RegionNDMap.create(axes=[axis], unit="m2 s", region=region) region_map.data += 1 region_map_other = RegionNDMap.create(axes=[axis], unit="cm2 s", region=region) region_map_other.data += 1 region_map.stack(region_map_other) assert_allclose(region_map.data, 1.0001)
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 test_compute_flux_spatial(): center = SkyCoord("0 deg", "0 deg", frame="galactic") region = CircleSkyRegion(center=center, radius=0.1 * u.deg) nbin = 2 energy_axis_true = MapAxis.from_energy_bounds(".1 TeV", "10 TeV", nbin=nbin, name="energy_true") spectral_model = ConstantSpectralModel() spatial_model = PointSpatialModel(lon_0=0 * u.deg, lat_0=0 * u.deg, frame="galactic") models = SkyModel(spectral_model=spectral_model, spatial_model=spatial_model) model = Models(models) exposure_region = RegionNDMap.create(region, axes=[energy_axis_true], binsz_wcs="0.01deg") exposure_region.data += 1.0 exposure_region.unit = "m2 s" geom = RegionGeom(region, axes=[energy_axis_true], binsz_wcs="0.01deg") psf = PSFKernel.from_gauss(geom.to_wcs_geom(), sigma="0.1 deg") evaluator = MapEvaluator(model=model[0], exposure=exposure_region, psf=psf) flux = evaluator.compute_flux_spatial() g = Gauss2DPDF(0.1) reference = g.containment_fraction(0.1) assert_allclose(flux.value, reference, rtol=0.003)
def plot(self, time_range, ax=None, **kwargs): """ Plot Temporal Model. Parameters ---------- time_range : `~astropy.time.Time` times to plot the model ax : `~matplotlib.axes.Axes`, optional Axis to plot on **kwargs : dict Keywords forwarded to `~matplotlib.pyplot.errorbar` Returns ------- ax : `~matplotlib.axes.Axes`, optional axis """ time_min, time_max = time_range time_axis = TimeMapAxis.from_time_bounds(time_min=time_min, time_max=time_max, nbin=100) time_axis.time_format = "mjd" m = RegionNDMap.create(region=None, axes=[time_axis]) kwargs.setdefault("marker", "None") kwargs.setdefault("ls", "-") kwargs.setdefault("xerr", None) m.quantity = self(time_axis.time_mid) ax = m.plot(ax=ax, **kwargs) ax.set_ylabel("Norm / A.U.") return ax
def test_compute_flux_spatial_no_psf(): # check that spatial integration is not performed in the absence of a psf center = SkyCoord("0 deg", "0 deg", frame="galactic") region = CircleSkyRegion(center=center, radius=0.1 * u.deg) nbin = 2 energy_axis_true = MapAxis.from_energy_bounds(".1 TeV", "10 TeV", nbin=nbin, name="energy_true") spectral_model = ConstantSpectralModel() spatial_model = GaussianSpatialModel(lon_0=0 * u.deg, lat_0=0 * u.deg, frame="galactic", sigma="0.1 deg") models = SkyModel(spectral_model=spectral_model, spatial_model=spatial_model) model = Models(models) exposure_region = RegionNDMap.create(region, axes=[energy_axis_true]) exposure_region.data += 1.0 exposure_region.unit = "m2 s" evaluator = MapEvaluator(model=model[0], exposure=exposure_region) flux = evaluator.compute_flux_spatial() assert_allclose(flux, 1.0)
def test_template_ND(tmpdir): energy_axis = MapAxis.from_bounds(1.0, 100, 10, interp="log", name="energy_true", unit="GeV") norm = MapAxis.from_bounds(0, 10, 10, interp="lin", name="norm", unit="") tilt = MapAxis.from_bounds(-1.0, 1, 5, interp="lin", name="tilt", unit="") region_map = RegionNDMap.create(region="icrs;point(83.63, 22.01)", axes=[energy_axis, norm, tilt]) region_map.data[:, :, :5, 0, 0] = 1 region_map.data[:, :, 5:, 0, 0] = 2 template = TemplateNDSpectralModel(region_map) assert len(template.parameters) == 2 assert template.parameters["norm"].value == 5 assert template.parameters["tilt"].value == 0 assert_allclose(template([1, 100, 1000] * u.GeV), [1.0, 2.0, 2.0]) template.parameters["norm"].value = 1 template.filename = str(tmpdir / "template_ND.fits") template.write() dict_ = template.to_dict() template_new = TemplateNDSpectralModel.from_dict(dict_) assert_allclose(template_new.map.data, region_map.data) assert len(template_new.parameters) == 2 assert template_new.parameters["norm"].value == 1 assert template_new.parameters["tilt"].value == 0
def spectrum_dataset(): energy = np.logspace(-1, 1, 31) * u.TeV livetime = 100 * u.s pwl = PowerLawSpectralModel( index=2.1, amplitude="1e5 cm-2 s-1 TeV-1", reference="0.1 TeV", ) model = SkyModel(spectral_model=pwl, name="test-source") aeff = EffectiveAreaTable.from_constant(energy, "1 cm2") axis = MapAxis.from_edges(energy, interp="log", name="energy") background = RegionNDMap.create(region="icrs;circle(0, 0, 0.1)", axes=[axis]) bkg_rate = np.ones(30) / u.s background.quantity = bkg_rate * livetime dataset = SpectrumDataset( models=model, aeff=aeff, livetime=livetime, background=background, name="test", ) dataset.fake(random_state=23) return dataset
def test_map_with_time_axis(time_intervals): time_axis = TimeMapAxis(time_intervals["t_min"], time_intervals["t_max"], time_intervals["t_ref"]) energy_axis = MapAxis.from_energy_bounds(0.1, 10, 2, unit="TeV") region_map = RegionNDMap.create(region="fk5; circle(0,0,0.1)", axes=[energy_axis, time_axis]) assert region_map.geom.data_shape == (20, 2, 1, 1)
def test_template_ND_EBL(tmpdir): #TODO: add RegionNDMap.read(format="xspec") # Create EBL data array filename = "$GAMMAPY_DATA/ebl/ebl_franceschini.fits.gz" filename = make_path(filename) table_param = Table.read(filename, hdu="PARAMETERS") npar = len(table_param) par_axes = [] idx_data = [] for k in range(npar): name = table_param["NAME"][k].lower().strip() param, idx = np.unique(table_param[0]["VALUE"], return_index=True) par_axes.append( MapAxis(param, node_type="center", interp="lin", name=name, unit="")) idx_data.append(idx) idx_data.append(Ellipsis) idx_data = tuple(idx_data) # Get energy values table_energy = Table.read(filename, hdu="ENERGIES") energy_lo = u.Quantity(table_energy["ENERG_LO"], "keV", copy=False) # unit not stored in file energy_hi = u.Quantity(table_energy["ENERG_HI"], "keV", copy=False) # unit not stored in file energy = np.sqrt(energy_lo * energy_hi) # Get spectrum values table_spectra = Table.read(filename, hdu="SPECTRA") energy_axis = MapAxis(energy, node_type="center", interp="log", name="energy_true") region_map = RegionNDMap.create(region="galactic;point(0, 0)", axes=[energy_axis] + par_axes) #TODO: here we use a fake position, is it possible to allow region=None ? data = table_spectra["INTPSPEC"].data[idx_data] region_map.data[:, :, 0, 0] = data template = TemplateNDSpectralModel(region_map) assert len(template.parameters) == 1 assert_allclose(template.parameters["redshift"].value, 1.001, rtol=1e-3) expected = [9.950501e-01, 4.953951e-01, 1.588062e-06] assert_allclose(template([1, 100, 1000] * u.GeV), expected, rtol=1e-3) template.parameters["redshift"].value = 0.1 template.filename = str(tmpdir / "template_ND_ebl_franceschini.fits") template.write() dict_ = template.to_dict() template_new = TemplateNDSpectralModel.from_dict(dict_) assert_allclose(template_new.map.data, region_map.data) assert len(template.parameters) == 1 assert_allclose(template.parameters["redshift"].value, 0.1)
def test_template_ND_no_energy(tmpdir): norm = MapAxis.from_bounds(0, 10, 10, interp="lin", name="norm", unit="") tilt = MapAxis.from_bounds(-1.0, 1, 5, interp="lin", name="tilt", unit="") region_map = RegionNDMap.create(region="icrs;point(83.63, 22.01)", axes=[norm, tilt]) region_map.data[:, :5, 0, 0] = 1 region_map.data[:, 5:, 0, 0] = 2 with pytest.raises(ValueError): TemplateNDSpectralModel(region_map)
def test_region_nd_hdulist(): energy_axis = MapAxis.from_edges([1, 3, 10] * u.TeV, name="energy") m = RegionNDMap.create(region="icrs;circle(83.63, 22.01, 0.5)", axes=[energy_axis]) hdulist = m.to_hdulist() assert hdulist[0].name == "PRIMARY" assert hdulist[1].name == "SKYMAP" assert hdulist[2].name == "SKYMAP_BANDS" assert hdulist[3].name == "SKYMAP_REGION"
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 test_region_nd_io_gadf_no_region(tmpdir): energy_axis = MapAxis.from_edges([1, 3, 10] * u.TeV, name="energy") m = RegionNDMap.create(region=None, axes=[energy_axis]) m.write(tmpdir / "test.fits", format="gadf", hdu="TEST") m_new = RegionNDMap.read(tmpdir / "test.fits", format="gadf", hdu="TEST") assert m_new.geom.region is None assert m_new.geom.axes[0].name == "energy" assert m_new.data.shape == (2, 1, 1) assert_allclose(m_new.geom.axes["energy"].edges, [1, 3, 10] * u.TeV)
def test_region_nd_io_ogip_arf(tmpdir): energy_axis = MapAxis.from_energy_bounds(0.1, 10, 12, unit="TeV", name="energy_true") m = RegionNDMap.create("icrs;circle(83.63, 22.01, 0.5)", axes=[energy_axis]) m.write(tmpdir / "test.fits", format="ogip-arf") m_new = RegionNDMap.read(tmpdir / "test.fits", format="ogip-arf") assert m_new.geom.region is None with pytest.raises(ValueError): m.write(tmpdir / "test.fits", format="ogip")
def test_region_nd_io_gadf(tmpdir): energy_axis = MapAxis.from_edges([1, 3, 10] * u.TeV, name="energy") m = RegionNDMap.create("icrs;circle(83.63, 22.01, 0.5)", axes=[energy_axis]) m.write(tmpdir / "test.fits", format="gadf") m_new = RegionNDMap.read(tmpdir / "test.fits", format="gadf") assert isinstance(m_new.geom.region, CircleSkyRegion) assert m_new.geom.axes[0].name == "energy" assert m_new.data.shape == (2, 1, 1) assert_allclose(m_new.geom.axes["energy"].edges, [1, 3, 10] * u.TeV)
def test_region_nd_map_plot_label_axis(): energy_axis = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=5) label_axis = LabelMapAxis(labels=["dataset-1", "dataset-2"], name="dataset") m = RegionNDMap.create(region=None, axes=[energy_axis, label_axis]) with mpl_plot_check(): m.plot(axis_name="energy") with mpl_plot_check(): m.plot(axis_name="dataset")
def test_region_nd_io_ogip(tmpdir): energy_axis = MapAxis.from_energy_bounds(0.1, 10, 12, unit="TeV") m = RegionNDMap.create("icrs;circle(83.63, 22.01, 0.5)", axes=[energy_axis], binsz_wcs="0.01deg") m.write(tmpdir / "test.fits", format="ogip") m_new = RegionNDMap.read(tmpdir / "test.fits", format="ogip") assert isinstance(m_new.geom.region, CircleSkyRegion) geom = m_new.geom.to_wcs_geom() assert geom.data_shape == (12, 102, 102) with pytest.raises(ValueError): m.write(tmpdir / "test.fits", format="ogip-arf")
def test_label_axis_io(tmpdir): energy_axis = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=5) label_axis = LabelMapAxis(labels=["dataset-1", "dataset-2"], name="dataset") m = RegionNDMap.create(region=None, axes=[energy_axis, label_axis]) m.data = np.arange(m.data.size) filename = tmpdir / "test.fits" m.write(filename, format="gadf") m_new = RegionNDMap.read(filename, format="gadf") assert m.geom.axes["dataset"] == m_new.geom.axes["dataset"] assert m.geom.axes["energy"] == m_new.geom.axes["energy"]
def test_region_nd_io_gadf_rad_axis(tmpdir): energy_axis = MapAxis.from_edges([1, 3, 10] * u.TeV, name="energy") rad_axis = MapAxis.from_nodes([0, 0.1, 0.2] * u.deg, name="rad") m = RegionNDMap.create("icrs;circle(83.63, 22.01, 0.5)", axes=[energy_axis, rad_axis], unit="sr-1") m.data = np.arange(np.prod(m.data.shape)).reshape(m.data.shape) m.write(tmpdir / "test.fits", format="gadf") m_new = RegionNDMap.read(tmpdir / "test.fits", format="gadf") assert isinstance(m_new.geom.region, CircleSkyRegion) assert m_new.geom.axes.names == ["energy", "rad"] assert m_new.unit == "sr-1" # check that the data is not re-shuffled assert_allclose(m_new.data, m.data) assert m_new.data.shape == (3, 2, 1, 1)
def spectrum_dataset(): e_true = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=20, name="energy_true") e_reco = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=4) aeff = EffectiveAreaTable.from_constant(value=1e6 * u.m**2, energy=e_true.edges) background = RegionNDMap.create(region="icrs;circle(0, 0, 0.1)", axes=[e_reco]) background.data += 3600 background.data[-1] *= 1e-3 edisp = EDispKernelMap.from_diagonal_response(energy_axis_true=e_true, energy_axis=e_reco, geom=background.geom) return SpectrumDataset(aeff=aeff, livetime="1h", edisp=edisp, background=background)
def test_npred_no_edisp(self): const = 1 * u.Unit("cm-2 s-1 TeV-1") model = SkyModel(spectral_model=ConstantSpectralModel(const=const)) livetime = 1 * u.s aeff = RegionNDMap.create(region=self.on_region, unit="cm2", axes=[self.e_reco.copy(name="energy_true")]) aeff.data += 1 dataset = SpectrumDatasetOnOff( counts=self.on_counts, counts_off=self.off_counts, aeff=aeff, models=model, livetime=livetime, ) energy = aeff.geom.axes[0].edges expected = aeff.data[0] * (energy[-1] - energy[0]) * const * livetime assert_allclose(dataset.npred_sig().data.sum(), expected.value)
def test_region_nd_map_plot_two_axes(): energy_axis = MapAxis.from_energy_edges([1, 3, 10] * u.TeV) time_ref = Time('1999-01-01T00:00:00.123456789') time_axis = TimeMapAxis(edges_min=[0, 1, 3] * u.d, edges_max=[0.8, 1.9, 5.4] * u.d, reference_time=time_ref) m = RegionNDMap.create("icrs;circle(0, 0, 1)", axes=[energy_axis, time_axis]) m.data = 10 + np.random.random(m.data.size) with mpl_plot_check(): m.plot(axis_name="energy") with mpl_plot_check(): m.plot(axis_name="time") with pytest.raises(ValueError): m.plot()
def setup(self): etrue = np.logspace(-1, 1, 10) * u.TeV self.e_true = MapAxis.from_energy_edges(etrue, name="energy_true") ereco = np.logspace(-1, 1, 5) * u.TeV elo = ereco[:-1] ehi = ereco[1:] self.e_reco = MapAxis.from_energy_edges(ereco, name="energy") 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 self.aeff = RegionNDMap.create(region=self.on_region, wcs=self.wcs, axes=[self.e_true], unit="cm2") self.aeff.data += 1 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], meta={"EXPOSURE": self.livetime.to_value("s")}, ) 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.edisp = EDispKernelMap.from_diagonal_response( self.e_reco, self.e_true, self.on_counts.geom.to_image()) exposure = self.aeff * self.livetime exposure.meta["livetime"] = self.livetime mask_safe = RegionNDMap.from_geom(self.on_counts.geom, dtype=bool) mask_safe.data += True self.dataset = SpectrumDatasetOnOff( counts=self.on_counts, counts_off=self.off_counts, exposure=exposure, edisp=self.edisp, acceptance=acceptance, acceptance_off=acceptance_off, name="test", gti=self.gti, mask_safe=mask_safe, )