def _make_wcsgeom_from_config(config): """Build a `WCS.Geom` object from a fermipy coniguration file""" binning = config['binning'] binsz = binning['binsz'] coordsys = binning.get('coordsys', 'GAL') roiwidth = binning['roiwidth'] proj = binning.get('proj', 'AIT') ra = config['selection']['ra'] dec = config['selection']['dec'] npix = int(np.round(roiwidth / binsz)) skydir = SkyCoord(ra * u.deg, dec * u.deg) wcsgeom = WcsGeom.create(npix=npix, binsz=binsz, proj=proj, coordsys=coordsys, skydir=skydir) return wcsgeom
def test_psfmap_to_psf_kernel(): psfmap = make_test_psfmap(0.15 * u.deg) energy_axis = psfmap.psf_map.geom.axes[1] # create PSFKernel kern_geom = WcsGeom.create(binsz=0.02, width=5.0, axes=[energy_axis]) psfkernel = psfmap.get_psf_kernel(position=SkyCoord(1, 1, unit="deg"), geom=kern_geom, max_radius=1 * u.deg) assert_allclose(psfkernel.psf_kernel_map.geom.width, 2.02 * u.deg) assert_allclose(psfkernel.psf_kernel_map.data.sum(axis=(1, 2)), 1.0, atol=1e-7) psfkernel = psfmap.get_psf_kernel( position=SkyCoord(1, 1, unit="deg"), geom=kern_geom, ) assert_allclose(psfkernel.psf_kernel_map.geom.width, 1.14 * u.deg) assert_allclose(psfkernel.psf_kernel_map.data.sum(axis=(1, 2)), 1.0, atol=1e-7)
def test_safe_mask_maker_bkg_invalid(observations_hess_dl3): obs = observations_hess_dl3[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_nonan = SafeMaskMaker([]) dataset = dataset_maker.run(empty_dataset, obs) bkg = dataset.background.data bkg[0, 0, 0] = np.nan mask_nonan = safe_mask_maker_nonan.make_mask_bkg_invalid(dataset) assert mask_nonan[0, 0, 0] == False assert_allclose(bkg[mask_nonan].max(), 3.615932e+28) #TODO: change after disable IRF extrapolation: #assert_allclose(bkg[mask_nonan].max(), 20.656366) dataset = safe_mask_maker_nonan.run(dataset, obs) assert_allclose(dataset.mask_safe, mask_nonan)
def from_dict(cls, data): if "filename" in data: bkg_map = Map.read(data["filename"]) elif "map" in data: bkg_map = data["map"] else: # TODO: for now create a fake map for serialization, # uptdated in MapDataset.from_dict() axis = MapAxis.from_edges(np.logspace(-1, 1, 2), unit=u.TeV, name="energy") geom = WcsGeom.create( skydir=(0, 0), npix=(1, 1), frame="galactic", axes=[axis] ) bkg_map = Map.from_geom(geom) model = cls( map=bkg_map, name=data["name"], datasets_names=data.get("datasets_names"), filename=data.get("filename"), ) model._update_from_dict(data) return model
def test_make_psf(pars, data_store): obs = data_store.obs(23523) psf = obs.psf if pars["energy"] is None: edges = edges_from_lo_hi(psf.energy_lo, psf.energy_hi) energy_axis = MapAxis.from_edges(edges, interp="log", name="energy_true") else: energy_axis = pars["energy"] if pars["rad"] is None: edges = edges_from_lo_hi(psf.rad_lo, psf.rad_hi) rad_axis = MapAxis.from_edges(edges, name="theta") else: rad_axis = pars["rad"] position = SkyCoord(83.63, 22.01, unit="deg") geom = WcsGeom.create( skydir=position, npix=(3, 3), axes=[rad_axis, energy_axis], binsz=0.2 ) psf_map = make_psf_map_obs(geom, obs) psf = psf_map.get_energy_dependent_table_psf(position) assert psf.energy.unit == "GeV" assert psf.energy.shape == pars["energy_shape"] assert_allclose(psf.energy.value[15], pars["psf_energy"], rtol=1e-3) assert psf.rad.unit == "rad" assert psf.rad.shape == pars["rad_shape"] assert_allclose(psf.rad.value[15], pars["psf_rad"], rtol=1e-3) assert psf.exposure.unit == "cm2 s" assert psf.exposure.shape == pars["energy_shape"] assert_allclose(psf.exposure.value[15], pars["psf_exposure"], rtol=1e-3) assert psf.psf_value.unit == "sr-1" assert psf.psf_value.shape == pars["psf_value_shape"] assert_allclose(psf.psf_value.value[15, 50], pars["psf_value"], rtol=1e-3)
def data_prep(): data_store = DataStore.from_dir("$GAMMAPY_DATA/cta-1dc/index/gps/") OBS_ID = 110380 obs_ids = OBS_ID * np.ones(N_OBS) observations = data_store.get_observations(obs_ids) energy_axis = MapAxis.from_bounds(0.1, 10, nbin=10, unit="TeV", name="energy", interp="log") geom = WcsGeom.create( skydir=(0, 0), binsz=0.02, width=(10, 8), coordsys="GAL", proj="CAR", axes=[energy_axis], ) src_pos = SkyCoord(0, 0, unit="deg", frame="galactic") offset_max = 4 * u.deg maker = MapDatasetMaker(offset_max=offset_max) safe_mask_maker = SafeMaskMaker(methods=["offset-max"], offset_max="4 deg") stacked = MapDataset.create(geom=geom) datasets = [] for obs in observations: dataset = maker.run(stacked, obs) dataset = safe_mask_maker.run(dataset, obs) dataset.edisp = dataset.edisp.get_energy_dispersion( position=src_pos, e_reco=energy_axis.edges) dataset.psf = dataset.psf.get_psf_kernel(position=src_pos, geom=geom, max_radius="0.3 deg") datasets.append(dataset) return datasets
def test_make_psf_map(): psf = fake_psf3d(0.3 * u.deg) pointing = SkyCoord(0, 0, unit="deg") energy_axis = MapAxis(nodes=[0.2, 0.7, 1.5, 2.0, 10.0], unit="TeV", name="energy") rad_axis = MapAxis(nodes=np.linspace(0.0, 1.0, 51), unit="deg", name="theta") geom = WcsGeom.create(skydir=pointing, binsz=0.2, width=5, axes=[rad_axis, energy_axis]) psfmap = make_psf_map(psf, pointing, geom, 3 * u.deg) assert psfmap.psf_map.geom.axes[0] == rad_axis assert psfmap.psf_map.geom.axes[1] == energy_axis assert psfmap.psf_map.unit == Unit("sr-1") assert psfmap.psf_map.data.shape == (4, 50, 25, 25)
def from_energy_dependent_table_psf(cls, table_psf): """Create PSF map from table PSF object. Helper function to create an allsky PSF map from table PSF, which does not depend on position. Parameters ---------- table_psf : `EnergyDependentTablePSF` Table PSF Returns ------- psf_map : `PSFMap` Point spread function map. """ energy_axis = MapAxis.from_nodes(table_psf.energy, name="energy_true", interp="log") rad_axis = MapAxis.from_nodes(table_psf.rad, name="theta") geom = WcsGeom.create(npix=(2, 1), proj="CAR", binsz=180, axes=[rad_axis, energy_axis]) coords = geom.get_coord() # TODO: support broadcasting in .evaluate() data = table_psf._interpolate( (coords["energy_true"], coords["theta"])).to_value("sr-1") psf_map = Map.from_geom(geom, data=data, unit="sr-1") geom_exposure = geom.squash(axis="theta") data = table_psf.exposure.reshape((-1, 1, 1, 1)) exposure_map = Map.from_geom(geom_exposure, unit="cm2 s") exposure_map.quantity += data return cls(psf_map=psf_map, exposure_map=exposure_map)
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") skymodel = SkyModel(spatial_model=spatial_model, spectral_model=spectral_model) geom = WcsGeom.create(skydir=position, binsz=1, width="5 deg", frame="galactic", axes=[energy_axis]) t_min = 0 * u.s t_max = 30000 * u.s gti = GTI.create(start=t_min, stop=t_max) 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=True) dataset.gti = gti return dataset
def test_make_edisp_kernel_map(): migra = MapAxis.from_edges(np.linspace(0.5, 1.5, 50), unit="", name="migra") etrue = MapAxis.from_energy_bounds(0.5, 2, 6, unit="TeV", name="energy_true") offset = MapAxis.from_edges(np.linspace(0.0, 2.0, 3), unit="deg", name="offset") ereco = MapAxis.from_energy_bounds(0.5, 2, 3, unit="TeV", name="energy") edisp = EnergyDispersion2D.from_gauss( energy_axis_true=etrue, migra_axis=migra, bias=0, sigma=0.01, offset_axis=offset ) geom = WcsGeom.create(10, binsz=0.5, axes=[ereco, etrue]) pointing = SkyCoord(0, 0, frame="icrs", unit="deg") edispmap = make_edisp_kernel_map(edisp, pointing, geom) kernel = edispmap.get_edisp_kernel(pointing) assert_allclose(kernel.pdf_matrix[:, 0], (1.0, 1.0, 0.0, 0.0, 0.0, 0.0)) assert_allclose(kernel.pdf_matrix[:, 1], (0.0, 0.0, 1.0, 1.0, 0.0, 0.0)) assert_allclose(kernel.pdf_matrix[:, 2], (0.0, 0.0, 0.0, 0.0, 1.0, 1.0))
def test_compute_npred_sign(): center = SkyCoord("0 deg", "0 deg", frame="galactic") energy_axis_true = MapAxis.from_energy_bounds(".1 TeV", "10 TeV", nbin=2, name="energy_true") geom = WcsGeom.create(skydir=center, width=1 * u.deg, axes=[energy_axis_true], frame='galactic', binsz=0.2 * u.deg) spectral_model_pos = PowerLawSpectralModel(index=2, amplitude="1e-11 TeV-1 s-1 m-2") spectral_model_neg = PowerLawSpectralModel( index=2, amplitude="-1e-11 TeV-1 s-1 m-2") spatial_model = PointSpatialModel(lon_0=0 * u.deg, lat_0=0 * u.deg, frame="galactic") model_pos = SkyModel(spectral_model=spectral_model_pos, spatial_model=spatial_model) model_neg = SkyModel(spectral_model=spectral_model_neg, spatial_model=spatial_model) exposure = Map.from_geom(geom, unit="m2 s") exposure.data += 1.0 psf = PSFKernel.from_gauss(geom, sigma="0.1 deg") evaluator_pos = MapEvaluator(model=model_pos, exposure=exposure, psf=psf) evaluator_neg = MapEvaluator(model=model_neg, exposure=exposure, psf=psf) npred_pos = evaluator_pos.compute_npred() npred_neg = evaluator_neg.compute_npred() assert (npred_pos.data == -npred_neg.data).all() assert np.all(npred_pos.data >= 0) assert np.all(npred_neg.data <= 0)
def test_large_oversampling(): nbin = 2 energy_axis_true = MapAxis.from_energy_bounds(".1 TeV", "10 TeV", nbin=nbin, name="energy_true") geom = WcsGeom.create(width=1, binsz=0.02, axes=[energy_axis_true]) spectral_model = ConstantSpectralModel() spatial_model = GaussianSpatialModel(lon_0=0 * u.deg, lat_0=0 * u.deg, sigma=1e-4 * u.deg, frame="icrs") models = SkyModel(spectral_model=spectral_model, spatial_model=spatial_model) model = Models(models) exposure = Map.from_geom(geom, unit="m2 s") exposure.data += 1.0 psf = PSFKernel.from_gauss(geom, sigma="0.1 deg") evaluator = MapEvaluator(model=model[0], exposure=exposure, psf=psf) flux_1 = evaluator.compute_flux_spatial() spatial_model.sigma.value = 0.001 flux_2 = evaluator.compute_flux_spatial() spatial_model.sigma.value = 0.01 flux_3 = evaluator.compute_flux_spatial() spatial_model.sigma.value = 0.03 flux_4 = evaluator.compute_flux_spatial() assert_allclose(flux_1.data.sum(), nbin, rtol=1e-4) assert_allclose(flux_2.data.sum(), nbin, rtol=1e-4) assert_allclose(flux_3.data.sum(), nbin, rtol=1e-4) assert_allclose(flux_4.data.sum(), nbin, rtol=1e-4)
def test_slice_by_idx(): axis = MapAxis.from_energy_bounds("0.1 TeV", "10 TeV", nbin=17) axis_etrue = MapAxis.from_energy_bounds( "0.1 TeV", "10 TeV", nbin=31, name="energy_true" ) geom = WcsGeom.create( skydir=(0, 0), binsz=0.5, width=(2, 2), frame="icrs", axes=[axis], ) dataset = MapDataset.create(geom=geom, energy_axis_true=axis_etrue, binsz_irf=0.5) slices = {"energy": slice(5, 10)} sub_dataset = dataset.slice_by_idx(slices) assert sub_dataset.counts.geom.data_shape == (5, 4, 4) assert sub_dataset.mask_safe.geom.data_shape == (5, 4, 4) assert sub_dataset.npred_background().geom.data_shape == (5, 4, 4) assert sub_dataset.exposure.geom.data_shape == (31, 4, 4) assert sub_dataset.edisp.edisp_map.geom.data_shape == (31, 5, 4, 4) assert sub_dataset.psf.psf_map.geom.data_shape == (31, 66, 4, 4) axis = sub_dataset.counts.geom.axes["energy"] assert_allclose(axis.edges[0].value, 0.387468, rtol=1e-5) slices = {"energy_true": slice(5, 10)} sub_dataset = dataset.slice_by_idx(slices) assert sub_dataset.counts.geom.data_shape == (17, 4, 4) assert sub_dataset.mask_safe.geom.data_shape == (17, 4, 4) assert sub_dataset.npred_background().geom.data_shape == (17, 4, 4) assert sub_dataset.exposure.geom.data_shape == (5, 4, 4) assert sub_dataset.edisp.edisp_map.geom.data_shape == (5, 17, 4, 4) assert sub_dataset.psf.psf_map.geom.data_shape == (5, 66, 4, 4) axis = sub_dataset.counts.geom.axes["energy"] assert_allclose(axis.edges[0].value, 0.1, rtol=1e-5) axis = sub_dataset.exposure.geom.axes["energy_true"] assert_allclose(axis.edges[0].value, 0.210175, rtol=1e-5)
def test_convolve_nd(): energy_axis = MapAxis.from_edges(np.logspace(-1.0, 1.0, 4), unit="TeV", name="energy_true") geom = WcsGeom.create(binsz=0.02 * u.deg, width=4.0 * u.deg, axes=[energy_axis]) m = Map.from_geom(geom) m.fill_by_coord([[0.2, 0.4], [-0.1, 0.6], [0.5, 3.6]]) psf = PSFMap.from_gauss(energy_axis, sigma=[0.1, 0.2, 0.3] * u.deg) psf_kernel = psf.get_psf_kernel(geom=geom, max_radius=1 * u.deg) assert psf_kernel.psf_kernel_map.data.shape == (3, 101, 101) mc = m.convolve(psf_kernel) assert_allclose(mc.data.sum(axis=(1, 2)), [0, 1, 1], atol=1e-5) kernel_2d = Box2DKernel(3, mode="center") kernel_2d.normalize("peak") mc = m.convolve(kernel_2d.array) assert_allclose(mc.data[0, :, :].sum(), 0, atol=1e-5) assert_allclose(mc.data[1, :, :].sum(), 9, atol=1e-5) kernel_2d = Gaussian2DKernel(15, mode="center") kernel_2d.normalize("peak") mc_full = m.convolve(kernel_2d.array, mode="full") mc_same = m.convolve(kernel_2d.array, mode="same") coords = [ [0.2, 0.1, 0.4, 0.44, -1.3], [-0.1, -0.13, 0.6, 0.57, 0.91], [0.5, 0.5, 3.6, 3.6, 0.5], ] values_full = mc_full.get_by_coord(coords) values_same = mc_same.get_by_coord(coords) assert mc_same.data.shape == (3, 200, 200) assert mc_full.data.shape == (3, 320, 320) assert_allclose(values_full, values_same, rtol=1e-5)
def extract_spectrum_fermi(on_region, off_region, energy, containment_correction): """Perform the spectral extraction at target_position for a circular region.""" geom = WcsGeom.create(skydir=on_region.center, width="5 deg", binsz=0.01, axes=[energy]) ds = FermiDatasetMaker().run(geom) spec_dataset = ds.to_spectrum_dataset( on_region, containment_correction=containment_correction, name="fermi") on_mask = ds.counts.geom.region_mask([on_region]) on_solid_angle = np.sum(ds.counts.geom.solid_angle() * on_mask.data) off_dataset = ds.to_spectrum_dataset(off_region, containment_correction=False) off_mask = ds.counts.geom.region_mask([off_region]) off_solid_angle = np.sum(ds.counts.geom.solid_angle() * off_mask.data) # To be stored as OGIP, we need to define a livetime in the exposure meta spec_dataset.exposure.meta['livetime'] = np.max( spec_dataset.exposure.quantity) / (1e4 * u.cm**2) acceptance = Map.from_geom(spec_dataset.counts.geom, unit='') acceptance += 1 acceptance_off = Map.from_geom(spec_dataset.counts.geom, unit='') acceptance_off += (off_solid_angle / on_solid_angle).to_value("") return SpectrumDatasetOnOff(counts=spec_dataset.counts, counts_off=off_dataset.counts, gti=spec_dataset.gti, exposure=spec_dataset.exposure, edisp=spec_dataset.edisp, acceptance=acceptance, acceptance_off=acceptance_off, name="fermi-3fhl")
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_wcsndmap_read_write_fgst(tmpdir): filename = str(tmpdir / "map.fits") axis = MapAxis.from_bounds(100.0, 1000.0, 4, name="energy", unit="MeV") geom = WcsGeom.create(npix=10, binsz=1.0, proj="AIT", coordsys="GAL", axes=[axis]) # Test Counts Cube m = WcsNDMap(geom) m.write(filename, conv="fgst-ccube", overwrite=True) with fits.open(filename) as h: assert "EBOUNDS" in h m2 = Map.read(filename) assert m2.geom.axes[0].name == "energy" # Test Model Cube m.write(filename, conv="fgst-template", overwrite=True) with fits.open(filename) as h: assert "ENERGIES" in h
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)
def _check_unit(self): from astropy.time import Time from gammapy.data.gti import GTI # evaluate over a test geom to check output unit # TODO simpler way to test this ? axis = MapAxis.from_edges(np.logspace(-1, 1, 3), unit=u.TeV, name="energy_true") geom = WcsGeom.create(skydir=(0, 0), npix=(2, 2), frame="galactic", axes=[axis]) t_ref = Time(55555, format="mjd") gti = GTI.create([1, 5] * u.day, [2, 6] * u.day, reference_time=t_ref) value = self.evaluate_geom(geom, gti) if self.spatial_model is not None: ref_unit = "cm-2 s-1 MeV-1 sr-1" else: ref_unit = "cm-2 s-1 MeV-1" if not value.unit.is_equivalent(ref_unit): raise ValueError( f"SkyModel unit {value.unit} is not equivalent to {ref_unit}")
def test_downsample_onoff(): axis = MapAxis.from_energy_bounds(1, 10, 4, unit="TeV") geom = WcsGeom.create(npix=(10, 10), binsz=0.05, axes=[axis]) counts = Map.from_geom(geom, data=np.ones((4, 10, 10))) counts_off = Map.from_geom(geom, data=np.ones((4, 10, 10))) acceptance = Map.from_geom(geom, data=np.ones((4, 10, 10))) acceptance_off = Map.from_geom(geom, data=np.ones((4, 10, 10))) acceptance_off *= 2 dataset_onoff = MapDatasetOnOff( counts=counts, counts_off=counts_off, acceptance=acceptance, acceptance_off=acceptance_off, ) downsampled = dataset_onoff.downsample(2, axis_name="energy") assert downsampled.counts.data.shape == (2, 10, 10) assert downsampled.counts.data.sum() == dataset_onoff.counts.data.sum() assert downsampled.counts_off.data.sum() == dataset_onoff.counts_off.data.sum() assert_allclose(downsampled.alpha.data, 0.5)
def test_wcsndmap_fill_by_coord(npix, binsz, frame, proj, skydir, axes): geom = WcsGeom.create( npix=npix, binsz=binsz, skydir=skydir, proj=proj, frame=frame, axes=axes ) m = WcsNDMap(geom) coords = m.geom.get_coord() fill_coords = tuple([qconcatenate(t, t) for t in coords]) fill_vals = fill_coords[1] m.fill_by_coord(fill_coords, fill_vals.value) assert_allclose(m.get_by_coord(coords), 2.0 * coords[1].value) # Test with SkyCoords m = WcsNDMap(geom) coords = m.geom.get_coord() skydir = coords.skycoord skydir_cel = skydir.transform_to("icrs") skydir_gal = skydir.transform_to("galactic") fill_coords_cel = (skydir_cel,) + tuple(coords[2:]) fill_coords_gal = (skydir_gal,) + tuple(coords[2:]) m.fill_by_coord(fill_coords_cel, coords[1].value) m.fill_by_coord(fill_coords_gal, coords[1].value) assert_allclose(m.get_by_coord(coords), 2.0 * coords[1].value)
def test_make_mean_psf(data_store): observations = data_store.get_observations([23523, 23526]) position = SkyCoord(83.63, 22.01, unit="deg") psf = observations[0].psf geom = WcsGeom.create( skydir=position, npix=(3, 3), axes=[psf.rad_axis, psf.energy_axis_true], binsz=0.2, ) psf_map_1 = make_psf_map_obs(geom, observations[0]) psf_map_2 = make_psf_map_obs(geom, observations[1]) stacked_psf = psf_map_1.copy() stacked_psf.stack(psf_map_2) psf = stacked_psf.get_energy_dependent_table_psf(position) assert not np.isnan(psf.data.data).any() assert_allclose(psf.data.data[22, 22], 12206.1665 / u.sr, rtol=1e-3)
def test_to_map_dataset(): axis = MapAxis.from_energy_bounds(1, 10, 2, unit="TeV") geom = WcsGeom.create(npix=(10, 10), binsz=0.05, axes=[axis]) counts = Map.from_geom(geom, data=np.ones((2, 10, 10))) counts_off = Map.from_geom(geom, data=np.ones((2, 10, 10))) acceptance = Map.from_geom(geom, data=np.ones((2, 10, 10))) acceptance_off = Map.from_geom(geom, data=np.ones((2, 10, 10))) acceptance_off *= 2 dataset_onoff = MapDatasetOnOff( counts=counts, counts_off=counts_off, acceptance=acceptance, acceptance_off=acceptance_off, ) dataset = dataset_onoff.to_map_dataset(name="ds") assert dataset.name == "ds" assert_allclose(dataset.npred_background().data.sum(), 100) assert isinstance(dataset, MapDataset) assert dataset.counts == dataset_onoff.counts
def make_test_psfmap(size, shape="gauss"): psf = fake_psf3d(size, shape) aeff2d = fake_aeff2d() pointing = SkyCoord(0, 0, unit="deg") energy_axis = MapAxis(nodes=[0.2, 0.7, 1.5, 2.0, 10.0], unit="TeV", name="energy_true") rad_axis = MapAxis.from_edges(edges=np.linspace(0.0, 1, 101), unit="deg", name="rad") geom = WcsGeom.create(skydir=pointing, binsz=0.2, width=5, axes=[rad_axis, energy_axis]) exposure_geom = geom.squash(axis_name="rad") exposure_map = make_map_exposure_true_energy(pointing, "1 h", aeff2d, exposure_geom) return make_psf_map(psf, pointing, geom, exposure_map)
def test_wcsndmap_read_write_fgst(tmp_path): path = tmp_path / "tmp.fits" axis = MapAxis.from_bounds(100.0, 1000.0, 4, name="energy", unit="MeV") geom = WcsGeom.create(npix=10, binsz=1.0, proj="AIT", frame="galactic", axes=[axis]) # Test Counts Cube m = WcsNDMap(geom) m.write(path, format="fgst-ccube", overwrite=True) with fits.open(path, memmap=False) as hdulist: assert "EBOUNDS" in hdulist m2 = Map.read(path) assert m2.geom.axes[0].name == "energy" # Test Model Cube m.write(path, format="fgst-template", overwrite=True) with fits.open(path, memmap=False) as hdulist: assert "ENERGIES" in hdulist
def test_minimal_datastore(): """"Check that a standard analysis runs on a minimal datastore""" energy_axis = MapAxis.from_energy_bounds( 1, 10, nbin=3, per_decade=False, unit="TeV", name="energy" ) geom = WcsGeom.create( skydir=(83.633, 22.014), binsz=0.5, width=(2, 2), frame="icrs", proj="CAR", axes=[energy_axis], ) data_store = DataStore.from_dir("$GAMMAPY_DATA/tests/minimal_datastore") observations = data_store.get_observations() maker = MapDatasetMaker() offset_max = 2.3 * u.deg maker_safe_mask = SafeMaskMaker(methods=["offset-max"], offset_max=offset_max) circle = CircleSkyRegion( center=SkyCoord("83.63 deg", "22.14 deg"), radius=0.2 * u.deg ) exclusion_mask = ~geom.region_mask(regions=[circle]) maker_fov = FoVBackgroundMaker(method="fit", exclusion_mask=exclusion_mask) stacked = MapDataset.create(geom=geom, name="crab-stacked") for obs in observations: dataset = maker.run(stacked, obs) dataset = maker_safe_mask.run(dataset, obs) dataset = maker_fov.run(dataset) stacked.stack(dataset) assert_allclose(stacked.exposure.data.sum(), 6.01909e10) assert_allclose(stacked.counts.data.sum(), 1446) assert_allclose(stacked.background.data.sum(), 1445.9841)
def _create_wcs_geometry(wcs_geom_settings, axes): """Create the WCS geometry.""" geom_params = {} skydir_settings = wcs_geom_settings.skydir if skydir_settings.lon is not None: skydir = SkyCoord(skydir_settings.lon, skydir_settings.lat, frame=skydir_settings.frame) geom_params["skydir"] = skydir if skydir_settings.frame in ["icrs", "galactic"]: geom_params["frame"] = skydir_settings.frame else: raise ValueError( f"Incorrect skydir frame: expect 'icrs' or 'galactic'. Got {skydir_settings.frame}" ) geom_params["axes"] = axes geom_params["binsz"] = wcs_geom_settings.binsize width = wcs_geom_settings.width.width.to("deg").value height = wcs_geom_settings.width.height.to("deg").value geom_params["width"] = (width, height) return WcsGeom.create(**geom_params)
def test_wcsgeom_solid_angle(): # Test using a CAR projection map with an extra axis binsz = 1.0 * u.deg npix = 10 geom = WcsGeom.create( skydir=(0, 0), npix=(npix, npix), binsz=binsz, coordsys="GAL", proj="CAR", axes=[MapAxis.from_edges([0, 2, 3])], ) solid_angle = geom.solid_angle() # Check array size assert solid_angle.shape == (2, npix, npix) # Test at b = 0 deg assert solid_angle.unit == "sr" assert_allclose(solid_angle.value[0, 5, 5], 0.0003046, rtol=1e-3) # Test at b = 5 deg assert_allclose(solid_angle.value[0, 9, 5], 0.0003038, rtol=1e-3)
def test_wcsndmap_set_get_by_coord(npix, binsz, frame, proj, skydir, axes): geom = WcsGeom.create(npix=npix, binsz=binsz, skydir=skydir, proj=proj, frame=frame, axes=axes) m = WcsNDMap(geom) coords = m.geom.get_coord() m.set_by_coord(coords, coords[0]) assert_allclose(coords[0].value, m.get_by_coord(coords)) # Test with SkyCoords m = WcsNDMap(geom) coords = m.geom.get_coord() skydir = coords.skycoord skydir_cel = skydir.transform_to("icrs") skydir_gal = skydir.transform_to("galactic") m.set_by_coord((skydir_gal, ) + tuple(coords[2:]), coords[0]) assert_allclose(coords[0].value, m.get_by_coord(coords)) assert_allclose( m.get_by_coord((skydir_cel, ) + tuple(coords[2:])), m.get_by_coord((skydir_gal, ) + tuple(coords[2:])), ) # Test with MapCoord m = WcsNDMap(geom) coords = m.geom.get_coord() coords_dict = dict(lon=coords[0], lat=coords[1]) if axes: for i, ax in enumerate(axes): coords_dict[ax.name] = coords[i + 2] map_coords = MapCoord.create(coords_dict, frame=frame) m.set_by_coord(map_coords, coords[0]) assert_allclose(coords[0].value, m.get_by_coord(map_coords))
def fake_dataset(): axis = MapAxis.from_energy_bounds(0.1, 10, 5, unit="TeV", name="energy") axis_true = MapAxis.from_energy_bounds(0.05, 20, 10, unit="TeV", name="energy_true") geom = WcsGeom.create(npix=50, binsz=0.02, axes=[axis]) dataset = MapDataset.create(geom) dataset.psf = PSFMap.from_gauss(axis_true, sigma="0.05 deg") dataset.mask_safe += np.ones(dataset.data_shape, dtype=bool) dataset.background += 1 dataset.exposure += 1e12 * u.cm**2 * u.s spatial_model = PointSpatialModel() spectral_model = PowerLawSpectralModel(amplitude="1e-10 cm-2s-1TeV-1", index=2) model = SkyModel(spatial_model=spatial_model, spectral_model=spectral_model, name="source") dataset.models = [model] dataset.fake(random_state=42) return dataset
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)
npix_irreg = np.vstack((np.arange(2,10,2),np.arange(2,10,2))).T cdelt_irreg = cdelt*np.vstack((np.linspace(4.,1.,4),np.linspace(4.,1.,4))).T crpix_irreg = (npix_irreg+1)/2. tab_bands = create_bands_table(emin, emax, npix_irreg, cdelt_irreg, crpix_irreg) hdulist = [hdu, fits.table_to_hdu(tab_bands)] update_header(hdulist[1].header, **{}) fits.HDUList(hdulist).writeto('wcs_ccube_irregular.fits', overwrite=True) ################################# # WCS Cube Sparse from gammapy.maps import WcsMapND, WcsGeom geom = WcsGeom.create(npix=npix, axes=[egy]) m = WcsMapND(geom, data) m.write('test_sparse.fits',sparse=True) data_flat = np.ravel(data).reshape(data.shape[:-2] + (data.shape[-1] * data.shape[-2],)) nonzero = np.where(data_flat > 0) channel = np.ravel_multi_index(nonzero[:-1], data.shape[:-2]) cols = [Column(name='PIX', data=nonzero[1], dtype='i4'), Column(name='CHANNEL', data=nonzero[0], dtype='i2'), Column(name='VALUE', data=data_flat[nonzero], dtype='f8')] tab_sparse = Table(cols, meta={'EXTNAME' : 'SKYMAP'}) # Write File tab_bands = create_bands_table(emin, emax)
) spectral_model_2 = PowerLaw( index=3, amplitude="1e-11 cm-2 s-1 TeV-1", reference="1 TeV" ) sky_model_1 = SkyModel(spatial_model=spatial_model_1, spectral_model=spectral_model_1) sky_model_2 = SkyModel(spatial_model=spatial_model_2, spectral_model=spectral_model_2) models = sky_model_1 + sky_model_2 # Define map geometry axis = MapAxis.from_edges(np.logspace(-1.0, 1.0, 10), unit="TeV") geom = WcsGeom.create( skydir=(0, 0), binsz=0.02, width=(2, 2), coordsys="GAL", axes=[axis] ) # Define some observation parameters # we are not simulating many pointings / observations pointing = SkyCoord(0.2, 0.5, unit="deg", frame="galactic") livetime = 20 * u.hour exposure_map = make_map_exposure_true_energy( pointing=pointing, livetime=livetime, aeff=aeff, geom=geom ) evaluator = MapEvaluator(model=models, exposure=exposure_map)
"""Plot Fermi PSF.""" import matplotlib.pyplot as plt from gammapy.irf import EnergyDependentTablePSF from gammapy.maps import WcsGeom from gammapy.cube import PSFKernel filename = "$GAMMAPY_DATA/tests/unbundled/fermi/psf.fits" fermi_psf = EnergyDependentTablePSF.read(filename) psf = fermi_psf.table_psf_at_energy(energy="1 GeV") geom = WcsGeom.create(npix=100, binsz=0.01) kernel = PSFKernel.from_table_psf(psf, geom) plt.imshow(kernel.data) plt.colorbar() plt.show()