def get_map_dataset(sky_model, geom, geom_etrue, edisp=True, 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) if edisp: # define energy dispersion e_true = geom_etrue.get_axis_by_name("energy_true") edisp = EDispMap.from_diagonal_response(energy_axis_true=e_true) 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 test_edisp_map_read_write(tmp_path): edisp_map = make_edisp_map_test() edisp_map.write(tmp_path / "tmp.fits") new_edmap = EDispMap.read(tmp_path / "tmp.fits") assert_allclose(edisp_map.edisp_map.quantity, new_edmap.edisp_map.quantity)
def make_edisp_map(edisp, pointing, geom, exposure_map=None, use_region_center=True): """Make a edisp map for a single observation Expected axes : migra and true energy in this specific order The name of the migra MapAxis is expected to be 'migra' Parameters ---------- edisp : `~gammapy.irf.EnergyDispersion2D` the 2D Energy Dispersion IRF pointing : `~astropy.coordinates.SkyCoord` the pointing direction geom : `~gammapy.maps.Geom` the map geom to be used. It provides the target geometry. migra and true energy axes should be given in this specific order. exposure_map : `~gammapy.maps.Map`, optional the associated exposure map. default is None use_region_center: Bool If geom is a RegionGeom, whether to just consider the values at the region center or the instead the average over the whole region Returns ------- edispmap : `~gammapy.irf.EDispMap` the resulting EDisp map """ # Compute separations with pointing position if not use_region_center: coords, weights = geom.get_wcs_coord_and_weights() else: coords, weights = geom.get_coord(sparse=True), None offset = coords.skycoord.separation(pointing) # Compute EDisp values data = edisp.evaluate( offset=offset, energy_true=coords["energy_true"], migra=coords["migra"], ) if not use_region_center: data = np.average(data, axis=2, weights=weights) # Create Map and fill relevant entries edisp_map = Map.from_geom(geom, data=data.to_value(""), unit="") edisp_map.normalize(axis_name="migra") return EDispMap(edisp_map, exposure_map)
def test_edisp_map_to_from_hdulist(): edmap = make_edisp_map_test() hdulist = edmap.to_hdulist() assert "EDISP" in hdulist assert "EDISP_BANDS" in hdulist assert "EDISP_EXPOSURE" in hdulist assert "EDISP_EXPOSURE_BANDS" in hdulist new_edmap = EDispMap.from_hdulist(hdulist) assert_allclose(edmap.edisp_map.data, new_edmap.edisp_map.data) assert new_edmap.edisp_map.geom == edmap.edisp_map.geom assert new_edmap.exposure_map.geom == edmap.exposure_map.geom
def test_edisp_map_to_from_hdulist(): edmap = make_edisp_map_test() hdulist = edmap.to_hdulist(edisp_hdu="EDISP", edisp_hdubands="BANDSEDISP") assert "EDISP" in hdulist assert "BANDSEDISP" in hdulist assert "EXPMAP" in hdulist assert "BANDSEXP" in hdulist new_edmap = EDispMap.from_hdulist(hdulist, edisp_hdu="EDISP", edisp_hdubands="BANDSEDISP") assert_allclose(edmap.edisp_map.data, new_edmap.edisp_map.data) assert new_edmap.edisp_map.geom == edmap.edisp_map.geom assert new_edmap.exposure_map.geom == edmap.exposure_map.geom
def test_edisp_from_diagonal_response(position): position = SkyCoord(position) energy_axis_true = MapAxis.from_energy_bounds("0.3 TeV", "10 TeV", nbin=31, name="energy_true") edisp_map = EDispMap.from_diagonal_response(energy_axis_true) edisp_kernel = edisp_map.get_edisp_kernel(position, energy_axis=energy_axis_true) sum_kernel = np.sum(edisp_kernel.data.data, axis=1).data # We exclude the first and last bin, where there is no # e_reco to contribute to assert_allclose(sum_kernel[1:-1], 1)
def test_edisp_map_to_edisp_kernel_map(): energy_axis = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=5) energy_axis_true = MapAxis.from_energy_bounds( "0.3 TeV", "30 TeV", nbin=10, per_decade=True, name="energy_true" ) migra_axis = MapAxis(nodes=np.linspace(0.0, 3.0, 51), unit="", name="migra") edisp_map = EDispMap.from_diagonal_response(energy_axis_true, migra_axis) edisp_kernel_map = edisp_map.to_edisp_kernel_map(energy_axis) position = SkyCoord(0, 0, unit="deg") kernel = edisp_kernel_map.get_edisp_kernel(position) assert edisp_kernel_map.exposure_map.geom.axes[0].name == "energy" actual = kernel.pdf_matrix.sum(axis=0) assert_allclose(actual, 2.0)
def make_edisp_map(edisp, pointing, geom, exposure_map=None): """Make a edisp map for a single observation Expected axes : migra and true energy in this specific order The name of the migra MapAxis is expected to be 'migra' Parameters ---------- edisp : `~gammapy.irf.EnergyDispersion2D` the 2D Energy Dispersion IRF pointing : `~astropy.coordinates.SkyCoord` the pointing direction geom : `~gammapy.maps.Geom` the map geom to be used. It provides the target geometry. migra and true energy axes should be given in this specific order. exposure_map : `~gammapy.maps.Map`, optional the associated exposure map. default is None Returns ------- edispmap : `~gammapy.cube.EDispMap` the resulting EDisp map """ energy_axis = geom.get_axis_by_name("energy_true") energy = energy_axis.center migra_axis = geom.get_axis_by_name("migra") migra = migra_axis.center # Compute separations with pointing position offset = geom.separation(pointing) # Compute EDisp values edisp_values = edisp.data.evaluate( offset=offset, energy_true=energy[:, np.newaxis, np.newaxis, np.newaxis], migra=migra[:, np.newaxis, np.newaxis], ) # Create Map and fill relevant entries data = edisp_values.to_value("") edispmap = Map.from_geom(geom, data=data, unit="") return EDispMap(edispmap, exposure_map)
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, )