def dataset(): energy_axis = MapAxis.from_bounds(1, 10, nbin=3, unit="TeV", name="energy", interp="log") geom = WcsGeom.create(skydir=(0, 0), binsz=1, width="5 deg", frame="galactic", axes=[energy_axis]) geom_true = geom.copy() geom_true.axes[0].name = "energy_true" dataset = get_map_dataset(geom=geom, geom_etrue=geom_true, edisp="edispmap") dataset.gti = GTI.create(start=0 * u.s, stop=1000 * u.s, reference_time="2000-01-01") bkg_model = FoVBackgroundModel(dataset_name=dataset.name) dataset.models = [get_model(), bkg_model] return dataset
def test_hpxmap_read_write_fgst(tmp_path): path = tmp_path / "tmp.fits" axis = MapAxis.from_bounds(100.0, 1000.0, 4, name="energy", unit="MeV") # Test Counts Cube m = create_map(8, False, "galactic", None, [axis]) m.write(path, conv="fgst-ccube", overwrite=True) with fits.open(path, memmap=False) as hdulist: assert "SKYMAP" in hdulist assert "EBOUNDS" in hdulist assert hdulist["SKYMAP"].header["HPX_CONV"] == "FGST-CCUBE" assert hdulist["SKYMAP"].header["TTYPE1"] == "CHANNEL1" m2 = Map.read(path) # Test Model Cube m.write(path, conv="fgst-template", overwrite=True) with fits.open(path, memmap=False) as hdulist: assert "SKYMAP" in hdulist assert "ENERGIES" in hdulist assert hdulist["SKYMAP"].header["HPX_CONV"] == "FGST-TEMPLATE" assert hdulist["SKYMAP"].header["TTYPE1"] == "ENERGY1" m2 = Map.read(path)
def get_npred_map(): position = SkyCoord(0.0, 0.0, frame="galactic", unit="deg") energy_axis = MapAxis.from_bounds(1, 100, nbin=30, unit="TeV", name="energy_true", interp="log") exposure = Map.create( binsz=0.02, map_type="wcs", skydir=position, width="2 deg", axes=[energy_axis], frame="galactic", unit="cm2 s", ) spatial_model = GaussianSpatialModel(lon_0="0 deg", lat_0="0 deg", sigma="0.2 deg", frame="galactic") spectral_model = PowerLawSpectralModel(amplitude="1e-11 cm-2 s-1 TeV-1") skymodel = SkyModel(spatial_model=spatial_model, spectral_model=spectral_model) exposure.data = 1e14 * np.ones(exposure.data.shape) evaluator = MapEvaluator(model=skymodel, exposure=exposure) npred = evaluator.compute_npred() return evaluator, npred
def test_map_dataset_on_off_to_spectrum_dataset(images): e_reco = MapAxis.from_bounds(0.1, 10.0, 1, name="energy", unit=u.TeV, interp="log") new_images = dict() for key, image in images.items(): new_images[key] = Map.from_geom(image.geom.to_cube([e_reco]), data=image.data[np.newaxis, :, :]) dataset = get_map_dataset_onoff(new_images) gti = GTI.create([0 * u.s], [1 * u.h], reference_time="2010-01-01T00:00:00") dataset.gti = gti on_region = CircleSkyRegion(center=dataset.counts.geom.center_skydir, radius=0.1 * u.deg) spectrum_dataset = dataset.to_spectrum_dataset(on_region) assert spectrum_dataset.counts.data[0] == 8 assert spectrum_dataset.data_shape == (1, 1, 1) assert spectrum_dataset.counts_off.data[0] == 33914 assert_allclose(spectrum_dataset.alpha.data[0], 0.0002143, atol=1e-7) excess_map = new_images["counts"] - new_images["background"] excess_true = excess_map.get_spectrum(on_region, np.sum).data[0] excess = spectrum_dataset.excess.data[0] assert_allclose(excess, excess_true, atol=1e-6) assert spectrum_dataset.name != dataset.name
def test_get_spectrum_type(): axis = MapAxis.from_bounds(1, 10, nbin=3, unit="TeV", name="energy") geom = WcsGeom.create(skydir=(0, 0), width=(2.5, 2.5), binsz=0.5, axes=[axis], frame="galactic") m_int = Map.from_geom(geom, dtype="int") m_int.data += 1 m_bool = Map.from_geom(geom, dtype="bool") m_bool.data += True center = SkyCoord(0, 0, frame="galactic", unit="deg") region = CircleSkyRegion(center=center, radius=1 * u.deg) spec_int = m_int.get_spectrum(region=region) assert spec_int.data.dtype == np.dtype("int") assert_allclose(spec_int.data.squeeze(), [13, 13, 13]) spec_bool = m_bool.get_spectrum(region=region, func=np.any) assert spec_bool.data.dtype == np.dtype("bool") assert_allclose(spec_bool.data.squeeze(), [1, 1, 1])
def test_get_spectrum_weights(): axis = MapAxis.from_bounds(1, 10, nbin=3, unit="TeV", name="energy") geom = WcsGeom.create(skydir=(0, 0), width=(2.5, 2.5), binsz=0.5, axes=[axis], frame="galactic") m_int = Map.from_geom(geom, dtype="int") m_int.data += 1 weights = Map.from_geom(geom, dtype="bool") weights.data[:, 2, 2] = True bad_weights = Map.from_geom(geom.to_image(), dtype="bool") center = SkyCoord(0, 0, frame="galactic", unit="deg") region = CircleSkyRegion(center=center, radius=1 * u.deg) spec_int = m_int.get_spectrum(region=region, weights=weights) assert spec_int.data.dtype == np.dtype("int") assert_allclose(spec_int.data.squeeze(), [1, 1, 1]) with pytest.raises(ValueError): m_int.get_spectrum(region=region, weights=bad_weights)
def test_wcsndmap_reproject(): skydir = SkyCoord(110.0, 75.0, unit="deg", frame="icrs") geom = WcsGeom.create(npix=10, binsz=1.0, coordsys="GAL", proj="AIT", skydir=skydir) geom_new = geom.downsample(2) data = np.arange(np.prod(geom.data_shape)).reshape(geom.data_shape) m = WcsNDMap(data=data, geom=geom, unit="m2") m_reprojected = m.reproject(geom_new, order=1) assert m.unit == m_reprojected.unit assert_allclose(m_reprojected.data[0, 0], 5.5) assert_allclose(m_reprojected.data[4, 4], 93.5) energy_axis = MapAxis.from_bounds(0.1, 10, 2, name="energy", interp="log") geom_3d = geom.to_cube([energy_axis]) data = np.arange(np.prod(geom_3d.data_shape)).reshape(geom_3d.data_shape) m = WcsNDMap(data=data, geom=geom_3d, unit="m2") m_reprojected = m.reproject(geom_new, order=1) assert m.unit == m_reprojected.unit assert_allclose(m_reprojected.data[0, 0, 0], 5.5) assert_allclose(m_reprojected.data[1, 4, 4], 193.5) assert m_reprojected.geom.axes[0].name == "energy"
def test_rad_max_roundtrip(tmp_path): n_energy = 10 energy_axis = MapAxis.from_energy_bounds(50 * u.GeV, 100 * u.TeV, n_energy, name="energy") n_offset = 5 offset_axis = MapAxis.from_bounds(0, 2, n_offset, unit=u.deg, name="offset") shape = (n_energy, n_offset) rad_max = np.linspace(0.1, 0.5, n_energy * n_offset).reshape(shape) rad_max_2d = RadMax2D( axes=[ energy_axis, offset_axis, ], data=rad_max, unit=u.deg, ) rad_max_2d.write(tmp_path / "rad_max.fits") rad_max_read = RadMax2D.read(tmp_path / "rad_max.fits") assert np.all(rad_max_read.data == rad_max) assert np.all(rad_max_read.data == rad_max_read.data)
def dataset(): energy_axis = MapAxis.from_bounds(1, 10, nbin=3, unit="TeV", name="energy", interp="log") geom = WcsGeom.create(skydir=(0, 0), binsz=0.05, width="5 deg", frame="galactic", axes=[energy_axis]) etrue_axis = energy_axis.copy(name="energy_true") geom_true = geom.to_image().to_cube(axes=[etrue_axis]) dataset = get_map_dataset(geom=geom, geom_etrue=geom_true, edisp="edispmap", name="test") dataset.background /= 400 dataset.gti = GTI.create(start=0 * u.s, stop=1000 * u.s, reference_time="2000-01-01") return dataset
def test_convolve_full(region): energy = MapAxis.from_bounds(1, 100, unit='TeV', nbin=2, name='energy_true') nside = 256 all_sky_geom = HpxGeom(nside=nside, axes=[energy], region=region, nest=False, frame='icrs') all_sky_map = Map.from_geom(all_sky_geom) all_sky_map.set_by_coord((0, 0, [2, 90]), 1) all_sky_map.set_by_coord((10, 10, [2, 90]), 1) all_sky_map.set_by_coord((30, 30, [2, 90]), 1) all_sky_map.set_by_coord((-40, -40, [2, 90]), 1) all_sky_map.set_by_coord((60, 0, [2, 90]), 1) all_sky_map.set_by_coord((-45, 30, [2, 90]), 1) all_sky_map.set_by_coord((30, -45, [2, 90]), 1) wcs_geom = WcsGeom.create(width=5, binsz=0.05, axes=[energy]) psf = PSFMap.from_gauss(energy_axis_true=energy, sigma=[0.5, 0.6] * u.deg) kernel = psf.get_psf_kernel(geom=wcs_geom, max_radius=1 * u.deg) convolved_map = all_sky_map.convolve_full(kernel) assert_allclose(convolved_map.data.sum(), 14, rtol=1e-5)
def from_diagonal_response(cls, energy_axis_true, migra_axis=None): """Create an allsky EDisp map with diagonal response. Parameters ---------- energy_axis_true : `~gammapy.maps.MapAxis` True energy axis migra_axis : `~gammapy.maps.MapAxis` Migra axis Returns ------- edisp_map : `~gammapy.maps.EDispMap` Energy dispersion map. """ migra_res = 1e-5 migra_axis_default = MapAxis.from_bounds( 1 - migra_res, 1 + migra_res, nbin=3, name="migra", node_type="edges" ) migra_axis = migra_axis or migra_axis_default geom = WcsGeom.create( npix=(2, 1), proj="CAR", binsz=180, axes=[migra_axis, energy_axis_true] ) return cls.from_geom(geom)
def test_get_spectrum(): axis = MapAxis.from_bounds(1, 10, nbin=3, unit="TeV", name="energy") geom = WcsGeom.create(skydir=(0, 0), width=(2.5, 2.5), binsz=0.5, axes=[axis], frame="galactic") m = Map.from_geom(geom) m.data += 1 center = SkyCoord(0, 0, frame="galactic", unit="deg") region = CircleSkyRegion(center=center, radius=1 * u.deg) spec = m.get_spectrum(region=region) assert_allclose(spec.data.squeeze(), [13.0, 13.0, 13.0]) spec = m.get_spectrum(region=region, func=np.mean) assert_allclose(spec.data.squeeze(), [1.0, 1.0, 1.0]) spec = m.get_spectrum() assert isinstance(spec.geom.region, RectangleSkyRegion) region = PointSkyRegion(center) spec = m.get_spectrum(region=region) assert_allclose(spec.data.squeeze(), [1.0, 1.0, 1.0])
def test_safe_mask_maker(observations, caplog): obs = observations[0] axis = MapAxis.from_bounds(0.1, 10, nbin=16, unit="TeV", name="energy", interp="log") axis_true = MapAxis.from_bounds(0.1, 50, nbin=30, unit="TeV", name="energy_true", interp="log") geom = WcsGeom.create(npix=(11, 11), axes=[axis], skydir=obs.pointing_radec) empty_dataset = MapDataset.create(geom=geom, energy_axis_true=axis_true) dataset_maker = MapDatasetMaker() safe_mask_maker = SafeMaskMaker(offset_max="3 deg", bias_percent=0.02, position=obs.pointing_radec) dataset = dataset_maker.run(empty_dataset, obs) mask_offset = safe_mask_maker.make_mask_offset_max(dataset=dataset, observation=obs) assert_allclose(mask_offset.sum(), 109) mask_energy_aeff_default = safe_mask_maker.make_mask_energy_aeff_default( dataset=dataset, observation=obs) assert_allclose(mask_energy_aeff_default.data.sum(), 1936) mask_aeff_max = safe_mask_maker.make_mask_energy_aeff_max(dataset) assert_allclose(mask_aeff_max.data.sum(), 1210) mask_edisp_bias = safe_mask_maker.make_mask_energy_edisp_bias(dataset) assert_allclose(mask_edisp_bias.data.sum(), 1815) mask_bkg_peak = safe_mask_maker.make_mask_energy_bkg_peak(dataset) assert_allclose(mask_bkg_peak.data.sum(), 1815) assert caplog.records[-1].levelname == "WARNING" assert caplog.records[ -1].message == "No default thresholds defined for obs 110380"
def axis_energy(): return MapAxis.from_bounds(0.1, 1000, 2, unit=u.TeV, name="energy", interp="log", node_type="edges")
def test_irregular_geom_equality(): axis = MapAxis.from_bounds(1, 3, 10, name="axis", unit="") geom0 = WcsGeom.create(skydir=(0, 0), npix=10, binsz=0.1, axes=[axis]) binsizes = np.ones((10)) * 0.1 geom1 = WcsGeom.create(skydir=(0, 0), npix=10, binsz=binsizes, axes=[axis]) with pytest.raises(NotImplementedError): geom0 == geom1
def test_make_theta_squared_table(self): # pointing position: (0,0.5) degree in ra/dec # On theta2 distribution compute from (0,0) in ra/dec. # OFF theta2 distribution from the mirror position at (0,1) in ra/dec. position = SkyCoord(ra=0, dec=0, unit="deg", frame="icrs") axis = MapAxis.from_bounds(0, 0.2, nbin=4, interp="lin", unit="deg2") theta2_table = make_theta_squared_table( observations=[self.observations[0]], position=position, theta_squared_axis=axis, ) theta2_lo = [0, 0.05, 0.1, 0.15] theta2_hi = [0.05, 0.1, 0.15, 0.2] on_counts = [2, 0, 0, 0] off_counts = [1, 0, 0, 0] acceptance = [1, 1, 1, 1] acceptance_off = [1, 1, 1, 1] alpha = [1, 1, 1, 1] assert len(theta2_table) == 4 assert theta2_table["theta2_min"].unit == "deg2" assert_allclose(theta2_table["theta2_min"], theta2_lo) assert_allclose(theta2_table["theta2_max"], theta2_hi) assert_allclose(theta2_table["counts"], on_counts) assert_allclose(theta2_table["counts_off"], off_counts) assert_allclose(theta2_table["acceptance"], acceptance) assert_allclose(theta2_table["acceptance_off"], acceptance_off) assert_allclose(theta2_table["alpha"], alpha) assert_allclose(theta2_table.meta["ON_RA"], 0 * u.deg) assert_allclose(theta2_table.meta["ON_DEC"], 0 * u.deg) # Taking the off position as the on one off_position = position theta2_table2 = make_theta_squared_table( observations=[self.observations[0]], position=position, theta_squared_axis=axis, position_off=off_position, ) assert_allclose(theta2_table2["counts_off"], theta2_table["counts"]) # Test for two observations, here identical theta2_table_two_obs = make_theta_squared_table( observations=self.observations, position=position, theta_squared_axis=axis, ) on_counts_two_obs = [4, 0, 0, 0] off_counts_two_obs = [2, 0, 0, 0] acceptance_two_obs = [2, 2, 2, 2] acceptance_off_two_obs = [2, 2, 2, 2] alpha_two_obs = [1, 1, 1, 1] assert_allclose(theta2_table_two_obs["counts"], on_counts_two_obs) assert_allclose(theta2_table_two_obs["counts_off"], off_counts_two_obs) assert_allclose(theta2_table_two_obs["acceptance"], acceptance_two_obs) assert_allclose(theta2_table_two_obs["acceptance_off"], acceptance_off_two_obs) assert_allclose(theta2_table["alpha"], alpha_two_obs)
def test_energy_dispersion_2d_to_gadf(): from gammapy.irf import EnergyDispersion2D from gammapy.maps import MapAxis energy_axis = MapAxis.from_energy_bounds(1 * u.TeV, 10 * u.TeV, nbin=3, name='energy_true') offset_axis = MapAxis.from_bounds(0 * u.deg, 2 * u.deg, nbin=2, name='offset') migra_axis = MapAxis.from_bounds(0.2, 5, nbin=5, interp='log', name='migra') data = np.zeros((energy_axis.nbin, migra_axis.nbin, offset_axis.nbin)) edisp = EnergyDispersion2D(data=data, axes=[energy_axis, migra_axis, offset_axis]) hdu = edisp.to_table_hdu(format='gadf-dl3') mandatory_columns = { 'ENERG_LO', 'ENERG_HI', 'MIGRA_LO', 'MIGRA_HI', 'THETA_LO', 'THETA_HI', 'MATRIX', } columns = {column.name for column in hdu.columns} missing = mandatory_columns.difference(columns) assert len(missing) == 0, f'GADF HDU missing required column(s) {missing}' header = hdu.header assert header['HDUCLASS'] == 'GADF' assert header[ 'HDUDOC'] == 'https://github.com/open-gamma-ray-astro/gamma-astro-data-formats' assert header['HDUVERS'] == '0.2' assert header['HDUCLAS1'] == 'RESPONSE' assert header['HDUCLAS2'] == 'EDISP' assert header['HDUCLAS3'] == 'FULL-ENCLOSURE' assert header['HDUCLAS4'] == 'EDISP_2D'
def test_map_axes_pad(): axis_1 = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=1) axis_2 = MapAxis.from_bounds(0, 1, nbin=2, unit="deg", name="rad") axes = MapAxes([axis_1, axis_2]) axes = axes.pad(axis_name="energy", pad_width=1) assert_allclose(axes["energy"].edges, [0.1, 1, 10, 100] * u.TeV)
def bkg_2d(): offset_axis = MapAxis.from_bounds(0, 4, nbin=10, name="offset", unit="deg") energy_axis = MapAxis.from_energy_bounds("0.1 TeV", "10 TeV", nbin=20) bkg_2d = Background2D(axes=[energy_axis, offset_axis], unit="s-1 TeV-1 sr-1") coords = bkg_2d.axes.get_coord() value = np.exp(-0.5 * (coords["offset"] / (2 * u.deg))**2) bkg_2d.data = (value * (coords["energy"] / (1 * u.TeV))**-2).to_value("") return bkg_2d
def _spectrum_extraction(self): """Run all steps for the spectrum extraction.""" region = self.settings["datasets"]["geom"]["region"] log.info("Reducing spectrum datasets.") on_lon = Angle(region["center"][0]) on_lat = Angle(region["center"][1]) on_center = SkyCoord(on_lon, on_lat, frame=region["frame"]) on_region = CircleSkyRegion(on_center, Angle(region["radius"])) maker_config = {} if "containment_correction" in self.settings["datasets"]: maker_config["containment_correction"] = self.settings["datasets"][ "containment_correction" ] params = self.settings["datasets"]["geom"]["axes"][0] e_reco = MapAxis.from_bounds(**params).edges maker_config["e_reco"] = e_reco # TODO: remove hard-coded e_true and make it configurable maker_config["e_true"] = np.logspace(-2, 2.5, 109) * u.TeV maker_config["region"] = on_region dataset_maker = SpectrumDatasetMaker(**maker_config) bkg_maker_config = {} background = self.settings["datasets"]["background"] if "exclusion_mask" in background: map_hdu = {} filename = background["exclusion_mask"]["filename"] if "hdu" in background["exclusion_mask"]: map_hdu = {"hdu": background["exclusion_mask"]["hdu"]} exclusion_region = Map.read(filename, **map_hdu) bkg_maker_config["exclusion_mask"] = exclusion_region if background["background_estimator"] == "reflected": reflected_bkg_maker = ReflectedRegionsBackgroundMaker(**bkg_maker_config) else: # TODO: raise error? log.info("Background estimation only for reflected regions method.") safe_mask_maker = SafeMaskMaker(methods=["aeff-default", "aeff-max"]) datasets = [] for obs in self.observations: log.info(f"Processing observation {obs.obs_id}") selection = ["counts", "aeff", "edisp"] dataset = dataset_maker.run(obs, selection=selection) dataset = reflected_bkg_maker.run(dataset, obs) dataset = safe_mask_maker.run(dataset, obs) log.debug(dataset) datasets.append(dataset) self.datasets = Datasets(datasets) if self.settings["datasets"]["stack-datasets"]: stacked = self.datasets.stack_reduce() stacked.name = "stacked" self.datasets = Datasets([stacked])
def _make_energy_axis(axis, name="energy"): return MapAxis.from_bounds( name=name, lo_bnd=axis.min.value, hi_bnd=axis.max.to_value(axis.min.unit), nbin=axis.nbins, unit=axis.min.unit, interp="log", node_type="edges", )
def test_to_table_is_pointlike(): energy_axis = MapAxis.from_energy_bounds('1 TeV', '10 TeV', nbin=3, name='energy_true') offset_axis = MapAxis.from_bounds(0 * u.deg, 2 * u.deg, nbin=2, name='offset') aeff = EffectiveAreaTable2D(data=np.ones((3, 2)) * u.m**2, axes=[energy_axis, offset_axis]) hdu = aeff.to_table_hdu() assert "is_pointlike" not in hdu.header
def setup(self): self.energy_lo = np.logspace(0, 1, 10)[:-1] * u.TeV self.energy_hi = np.logspace(0, 1, 10)[1:] * u.TeV self.energy_axis_true = MapAxis.from_energy_bounds( "1 TeV", "10 TeV", nbin=9, name="energy_true" ) self.offset_lo = np.linspace(0, 1, 4)[:-1] * u.deg self.offset_hi = np.linspace(0, 1, 4)[1:] * u.deg self.offset_axis = MapAxis.from_bounds( 0, 1, nbin=3, unit="deg", name="offset", node_type="edges" ) self.migra_lo = np.linspace(0, 3, 4)[:-1] self.migra_hi = np.linspace(0, 3, 4)[1:] self.migra_axis = MapAxis.from_bounds( 0, 3, nbin=3, name="migra", node_type="edges" ) self.fov_lon_lo = np.linspace(-6, 6, 11)[:-1] * u.deg self.fov_lon_hi = np.linspace(-6, 6, 11)[1:] * u.deg self.fov_lon_axis = MapAxis.from_bounds(-6, 6, nbin=10, name="fov_lon") self.fov_lat_lo = np.linspace(-6, 6, 11)[:-1] * u.deg self.fov_lat_hi = np.linspace(-6, 6, 11)[1:] * u.deg self.fov_lat_axis = MapAxis.from_bounds(-6, 6, nbin=10, name="fov_lat") self.aeff_data = np.random.rand(9, 3) * u.cm * u.cm self.edisp_data = np.random.rand(9, 3, 3) self.bkg_data = np.random.rand(9, 10, 10) / u.MeV / u.s / u.sr self.aeff = EffectiveAreaTable2D( axes=[self.energy_axis_true, self.offset_axis], data=self.aeff_data.value, unit=self.aeff_data.unit ) self.edisp = EnergyDispersion2D(axes=[ self.energy_axis_true, self.migra_axis, self.offset_axis, ], data=self.edisp_data, ) axes = [self.energy_axis_true.copy(name="energy"), self.fov_lon_axis, self.fov_lat_axis] self.bkg = Background3D(axes=axes, data=self.bkg_data.value, unit=self.bkg_data.unit)
def _create_geometry(params): """Create the geometry.""" geom_params = copy.deepcopy(params) axes = [] for axis_params in params.get("axes", []): ax = MapAxis.from_bounds(**axis_params) axes.append(ax) geom_params["axes"] = axes if "skydir" in geom_params: geom_params["skydir"] = tuple(geom_params["skydir"]) return WcsGeom.create(**geom_params)
def dataset(): position = SkyCoord(0.0, 0.0, frame="galactic", unit="deg") energy_axis = MapAxis.from_bounds(1, 10, nbin=3, unit="TeV", name="energy", interp="log") spatial_model = GaussianSpatialModel(lon_0="0 deg", lat_0="0 deg", sigma="0.2 deg", frame="galactic") spectral_model = PowerLawSpectralModel(amplitude="1e-11 cm-2 s-1 TeV-1") t_min = 0 * u.s t_max = 1000 * u.s time = np.arange(t_max.value) * u.s tau = u.Quantity("2e2 s") norm = np.exp(-time / tau) table = Table() table["TIME"] = time table["NORM"] = norm / norm.max() t_ref = Time("2000-01-01") table.meta = dict(MJDREFI=t_ref.mjd, MJDREFF=0, TIMEUNIT="s") temporal_model = LightCurveTemplateTemporalModel(table) skymodel = SkyModel( spatial_model=spatial_model, spectral_model=spectral_model, temporal_model=temporal_model, ) geom = WcsGeom.create(skydir=position, binsz=1, width="5 deg", frame="galactic", axes=[energy_axis]) gti = GTI.create(start=t_min, stop=t_max, reference_time=t_ref) geom_true = geom.copy() geom_true.axes[0].name = "energy_true" dataset = get_map_dataset(sky_model=skymodel, geom=geom, geom_etrue=geom_true, edisp="edispmap") dataset.gti = gti return dataset
def test_write(self): energy_axis_true = MapAxis.from_energy_bounds( "1 TeV", "10 TeV", nbin=10, name="energy_true" ) offset_axis = MapAxis.from_bounds( 0, 1, nbin=3, unit="deg", name="offset", node_type="edges" ) migra_axis = MapAxis.from_bounds(0, 3, nbin=3, name="migra", node_type="edges") axes = MapAxes([energy_axis_true, migra_axis, offset_axis]) data = np.ones(shape=axes.shape) edisp = EnergyDispersion2D(axes=axes, data=data) hdu = edisp.to_table_hdu() energy = edisp.axes["energy_true"].edges assert_equal(hdu.data["ENERG_LO"][0], energy[:-1].value) assert hdu.header["TUNIT1"] == edisp.axes["energy_true"].unit
def test_psf_3d_to_gadf(): from gammapy.irf import PSF3D from gammapy.maps import MapAxis energy_axis = MapAxis.from_energy_bounds(1 * u.TeV, 10 * u.TeV, nbin=3, name='energy_true') offset_axis = MapAxis.from_bounds(0 * u.deg, 2 * u.deg, nbin=2, name='offset') rad_axis = MapAxis.from_bounds(0.0 * u.deg, 1 * u.deg, nbin=10, name='rad') data = np.zeros((energy_axis.nbin, offset_axis.nbin, rad_axis.nbin)) / u.sr psf = PSF3D(data=data, axes=[energy_axis, offset_axis, rad_axis]) hdu = psf.to_table_hdu(format='gadf-dl3') mandatory_columns = { 'ENERG_LO', 'ENERG_HI', 'THETA_LO', 'THETA_HI', 'RAD_LO', 'RAD_HI', 'RPSF', } columns = {column.name for column in hdu.columns} missing = mandatory_columns.difference(columns) assert len(missing) == 0, f'GADF HDU missing required column(s) {missing}' header = hdu.header assert header['HDUCLASS'] == 'GADF' assert header[ 'HDUDOC'] == 'https://github.com/open-gamma-ray-astro/gamma-astro-data-formats' assert header['HDUVERS'] == '0.2' assert header['HDUCLAS1'] == 'RESPONSE' assert header['HDUCLAS2'] == 'RPSF' assert header['HDUCLAS3'] == 'FULL-ENCLOSURE' assert header['HDUCLAS4'] == 'PSF_TABLE'
def _create_geometry(params): """Create the geometry.""" # TODO: handled in jsonschema validation class geom_params = copy.deepcopy(params) axes = [] for axis_params in geom_params.get("axes", []): ax = MapAxis.from_bounds(**axis_params) axes.append(ax) geom_params["axes"] = axes geom_params["skydir"] = tuple(geom_params["skydir"]) return WcsGeom.create(**geom_params)
def test_arithmetics_after_serialization(tmp_path, interp): axis = MapAxis.from_bounds( 1.0, 10.0, 3, interp=interp, name="energy", node_type="center", unit="TeV" ) m_wcs = Map.create(binsz=0.1, width=1.0, map_type="wcs", skydir=(0, 0), axes=[axis]) m_wcs += 1 m_wcs.write(tmp_path / "tmp.fits") m_wcs_serialized = Map.read(tmp_path / "tmp.fits") m_wcs += m_wcs_serialized assert_allclose(m_wcs.data, 2.0)
def test_to_table(): energy_axis_true = MapAxis.from_energy_bounds( "1 TeV", "10 TeV", nbin=10, name="energy_true" ) offset_axis = MapAxis.from_bounds(0, 1, nbin=4, name="offset", unit="deg") aeff = EffectiveAreaTable2D( axes=[energy_axis_true, offset_axis], data=1, unit="cm2" ) hdu = aeff.to_table_hdu() assert_equal(hdu.data["ENERG_LO"][0], aeff.axes["energy_true"].edges[:-1].value) assert hdu.header["TUNIT1"] == aeff.axes["energy_true"].unit