def test_psf_kernel_to_image(): sigma1 = 0.5 * u.deg sigma2 = 0.2 * u.deg binsz = 0.1 * u.deg axis = MapAxis.from_energy_bounds(1, 10, 2, unit="TeV", name="energy_true") geom = WcsGeom.create(binsz=binsz, npix=50, axes=[axis]) disk_1 = DiskSpatialModel(r_0=sigma1) disk_2 = DiskSpatialModel(r_0=sigma2) rad_max = 2.5 * u.deg kernel1 = PSFKernel.from_spatial_model(disk_1, geom, max_radius=rad_max, factor=4) kernel2 = PSFKernel.from_spatial_model(disk_2, geom, max_radius=rad_max, factor=4) kernel1.psf_kernel_map.data[1, :, :] = kernel2.psf_kernel_map.data[1, :, :] kernel_image_1 = kernel1.to_image() kernel_image_2 = kernel1.to_image(exposure=[1, 2]) assert_allclose(kernel_image_1.psf_kernel_map.data.sum(), 1.0, atol=1e-5) assert_allclose(kernel_image_1.psf_kernel_map.data[0, 25, 25], 0.02844, atol=1e-5) assert_allclose(kernel_image_1.psf_kernel_map.data[0, 22, 22], 0.009636, atol=1e-5) assert_allclose(kernel_image_1.psf_kernel_map.data[0, 20, 20], 0.0, atol=1e-5) assert_allclose(kernel_image_2.psf_kernel_map.data.sum(), 1.0, atol=1e-5) assert_allclose( kernel_image_2.psf_kernel_map.data[0, 25, 25], 0.038091, atol=1e-5 ) assert_allclose(kernel_image_2.psf_kernel_map.data[0, 22, 22], 0.00777, atol=1e-5) assert_allclose(kernel_image_2.psf_kernel_map.data[0, 20, 20], 0.0, atol=1e-5)
def test_sky_disk(): # Test the disk case (e=0) r_0 = 2 * u.deg model = DiskSpatialModel(lon_0="1 deg", lat_0="45 deg", r_0=r_0) lon = [1, 5, 359] * u.deg lat = 46 * u.deg val = model(lon, lat) assert val.unit == "sr-1" desired = [261.263956, 0, 261.263956] assert_allclose(val.value, desired) radius = model.evaluation_radius assert radius.unit == "deg" assert_allclose(radius.value, r_0.value) # test the normalization for an elongated ellipse near the Galactic Plane m_geom_1 = WcsGeom.create(binsz=0.015, width=(20, 20), skydir=(2, 2), coordsys="GAL", proj="AIT") coords = m_geom_1.get_coord() solid_angle = m_geom_1.solid_angle() lon = coords.lon lat = coords.lat r_0 = 10 * u.deg model_1 = DiskSpatialModel(2 * u.deg, 2 * u.deg, r_0, 0.4, 30 * u.deg) vals_1 = model_1(lon, lat) assert vals_1.unit == "sr-1" assert_allclose(np.sum(vals_1 * solid_angle), 1, rtol=1.0e-3) radius = model_1.evaluation_radius assert radius.unit == "deg" assert_allclose(radius.value, r_0.value) # test rotation r_0 = 2 * u.deg semi_minor = 1 * u.deg eccentricity = np.sqrt(1 - (semi_minor / r_0)**2) model_rot_test = DiskSpatialModel(0 * u.deg, 0 * u.deg, r_0, eccentricity, 90 * u.deg) assert_allclose(model_rot_test(0 * u.deg, 1.5 * u.deg).value, 0) # test the normalization for a disk (ellipse with e=0) at the Galactic Pole m_geom_2 = WcsGeom.create(binsz=0.1, width=(6, 6), skydir=(0, 90), coordsys="GAL", proj="AIT") coords = m_geom_2.get_coord() lon = coords.lon lat = coords.lat r_0 = 5 * u.deg disk = DiskSpatialModel(0 * u.deg, 90 * u.deg, r_0) vals_disk = disk(lon, lat) solid_angle = 2 * np.pi * (1 - np.cos(5 * u.deg)) assert_allclose(np.max(vals_disk).value * solid_angle, 1)
def spatial_model(self): """Spatial model (`~gammapy.modeling.models.SpatialModel`).""" d = self.data ra = d["RAJ2000"] dec = d["DEJ2000"] if self.is_pointlike: model = PointSpatialModel(lon_0=ra, lat_0=dec, frame="icrs") else: de = self.data_extended morph_type = de["Model_Form"].strip() e = (1 - (de["Model_SemiMinor"] / de["Model_SemiMajor"]) ** 2.0) ** 0.5 sigma = de["Model_SemiMajor"] phi = de["Model_PosAng"] if morph_type in ["Disk", "Elliptical Disk"]: r_0 = de["Model_SemiMajor"] model = DiskSpatialModel( lon_0=ra, lat_0=dec, r_0=r_0, e=e, phi=phi, frame="icrs" ) elif morph_type in ["Map", "Ring", "2D Gaussian x2"]: filename = de["Spatial_Filename"].strip() path = make_path( "$GAMMAPY_DATA/catalogs/fermi/Extended_archive_v15/Templates/" ) return TemplateSpatialModel.read(path / filename) elif morph_type in ["2D Gaussian", "Elliptical 2D Gaussian"]: model = GaussianSpatialModel( lon_0=ra, lat_0=dec, sigma=sigma, e=e, phi=phi, frame="icrs" ) else: raise ValueError(f"Invalid spatial model: {morph_type!r}") self._set_spatial_errors(model) return model
def spatial_model(self): """Spatial model (`~gammapy.modeling.models.SpatialModel`).""" d = self.data ra = d["RAJ2000"] dec = d["DEJ2000"] if self.is_pointlike: model = PointSpatialModel(lon_0=ra, lat_0=dec, frame="icrs") else: de = self.data_extended morph_type = de["Model_Form"].strip() e = (1 - (de["Model_SemiMinor"] / de["Model_SemiMajor"]) ** 2.0) ** 0.5 sigma = de["Model_SemiMajor"] phi = de["Model_PosAng"] if morph_type == "Disk": r_0 = de["Model_SemiMajor"] model = DiskSpatialModel( lon_0=ra, lat_0=dec, r_0=r_0, e=e, phi=phi, frame="icrs" ) elif morph_type in ["Map", "Ring", "2D Gaussian x2"]: filename = de["Spatial_Filename"].strip() path = make_path( "$GAMMAPY_DATA/catalogs/fermi/LAT_extended_sources_8years/Templates/" ) with warnings.catch_warnings(): # ignore FITS units warnings warnings.simplefilter("ignore", FITSFixedWarning) model = TemplateSpatialModel.read(path / filename) elif morph_type == "2D Gaussian": model = GaussianSpatialModel( lon_0=ra, lat_0=dec, sigma=sigma, e=e, phi=phi, frame="icrs" ) else: raise ValueError(f"Invalid spatial model: {morph_type!r}") self._set_spatial_errors(model) return model
def spatial_model(self, which="point"): """Spatial model (`~gammapy.modeling.models.SpatialModel`). * ``which="point"`` - `~gammapy.modeling.models.PointSpatialModel` * ``which="extended"`` - `~gammapy.modeling.models.DiskSpatialModel`. Only available for some sources. Raise ValueError if not available. """ idx = self._get_idx(which) if idx == 0: model = PointSpatialModel( lon_0=self.data["glon"], lat_0=self.data["glat"], frame="galactic" ) else: model = DiskSpatialModel( lon_0=self.data["glon"], lat_0=self.data["glat"], r_0=self.data[f"spec{idx}_radius"], frame="galactic", ) lat_err = self.data["pos_err"].to("deg") lon_err = self.data["pos_err"].to("deg") / np.cos(self.data["glat"].to("rad")) model.parameters.set_error(lon_0=lon_err, lat_0=lat_err) return model
def test_sky_disk_edge(): r_0 = 2 * u.deg model = DiskSpatialModel(lon_0="0 deg", lat_0="0 deg", r_0=r_0, e=0.5, phi="0 deg") value_center = model(0 * u.deg, 0 * u.deg) value_edge = model(0 * u.deg, r_0) assert_allclose((value_edge / value_center).to_value(""), 0.5) edge = model.edge.quantity value_edge_pwidth = model(0 * u.deg, r_0 + edge / 2) assert_allclose((value_edge_pwidth / value_center).to_value(""), 0.05) value_edge_nwidth = model(0 * u.deg, r_0 - edge / 2) assert_allclose((value_edge_nwidth / value_center).to_value(""), 0.95)
def test_source_outside_geom(sky_model, geom, geom_etrue): dataset = get_map_dataset(geom, geom_etrue) dataset.edisp = get_edisp(geom, geom_etrue) models = dataset.models model = SkyModel( PowerLawSpectralModel(), DiskSpatialModel(lon_0=276.4 * u.deg, lat_0=-28.9 * u.deg, r_0=10 * u.deg), ) assert not geom.to_image().contains(model.position)[0] dataset.models = models + [model] dataset.npred() model_npred = dataset.evaluators[model.name].compute_npred().data assert np.sum(np.isnan(model_npred)) == 0 assert np.sum(~np.isfinite(model_npred)) == 0 assert np.sum(model_npred) > 0
def spatial_model(self): """ Source spatial model (`~gammapy.modeling.models.SpatialModel`). """ d = self.data pars = {} glon = d["GLON"] glat = d["GLAT"] if self.is_pointlike: pars["lon_0"] = glon pars["lat_0"] = glat return PointSpatialModel(lon_0=glon, lat_0=glat, frame="galactic") else: de = self.data_extended morph_type = de["Model_Form"].strip() if morph_type == "Disk": r_0 = de["Model_SemiMajor"].to("deg") return DiskSpatialModel(lon_0=glon, lat_0=glat, r_0=r_0, frame="galactic") elif morph_type in ["Map", "Ring", "2D Gaussian x2"]: filename = de["Spatial_Filename"].strip() path = make_path( "$GAMMAPY_DATA/catalogs/fermi/Extended_archive_v15/Templates/" ) return TemplateSpatialModel.read(path / filename) elif morph_type == "2D Gaussian": # TODO: fill elongation info as soon as model supports it sigma = de["Model_SemiMajor"].to("deg") return GaussianSpatialModel(lon_0=glon, lat_0=glat, sigma=sigma, frame="galactic") else: raise ValueError(f"Invalid spatial model: {morph_type!r}")
enlarger = 1.2 r_0 = rad_interpolate(energy_axis.center) * u.deg * enlarger r_0 = np.where(r_0>=0, r_0, 0) * u.deg ### Fill the index and normalization at the positions of the pixels binsize=0.02 eccentricity = 0.69 ang = 45. width = 3. m_wcs = WcsGeom.create(binsz=binsize, coordsys="CEL", skydir=position_psr, width=width*u.deg, axes=[energy_axis]) model = DiskSpatialModel(lon_0=ra_0_psr*u.deg, lat_0=dec_0_psr*u.deg, r_0="1.1 deg", e=eccentricity, phi=ang * u.deg, frame="icrs") coords = m_wcs.get_coord() coord_map = SkyCoord(coords.lon, coords.lat, frame='icrs') separation = position_psr.separation(coord_map) new_indexes = indexes(separation.value) N0 = (fluxes(separation.value) * (1-new_indexes) / ((emax/E_ref)**(1-new_indexes) - (emin/E_ref)**(1-new_indexes))) / (0.26 * np.pi / 180.)**2 ### Create the map skymap = Map.create(width=width*u.deg, axes=[energy_axis], binsz=binsize, coordsys="CEL", skydir=position_psr)
# Here is an example plot of the model: import numpy as np from astropy.coordinates import Angle from gammapy.modeling.models import ( DiskSpatialModel, Models, PowerLawSpectralModel, SkyModel, ) phi = Angle("30 deg") model = DiskSpatialModel( lon_0="2 deg", lat_0="2 deg", r_0="1 deg", e=0.8, phi="30 deg", frame="galactic", ) ax = model.plot(add_cbar=True) # illustrate size parameter region = model.to_region().to_pixel(ax.wcs) artist = region.as_artist(facecolor="none", edgecolor="red") ax.add_artist(artist) transform = ax.get_transform("galactic") ax.scatter(2, 2, transform=transform, s=20, edgecolor="red", facecolor="red") ax.text(1.7, 1.85, r"$(l_0, b_0)$", transform=transform, ha="center") ax.plot([2, 2 + np.sin(phi)], [2, 2 + np.cos(phi)],
import numpy as np import matplotlib.pyplot as plt from gammapy.maps import Map, WcsGeom from gammapy.modeling.models import DiskSpatialModel model = DiskSpatialModel("2 deg", "2 deg", "1 deg", 0.8, "30 deg", frame="galactic") m_geom = WcsGeom.create( binsz=0.01, width=(3, 3), skydir=(2, 2), coordsys="GAL", proj="AIT" ) coords = m_geom.get_coord() vals = model(coords.lon, coords.lat) skymap = Map.from_geom(m_geom, data=vals.value) _, ax, _ = skymap.smooth("0.05 deg").plot() transform = ax.get_transform("galactic") ax.scatter(2, 2, transform=transform, s=20, edgecolor="red", facecolor="red") ax.text(1.7, 1.85, r"$(l_0, b_0)$", transform=transform, ha="center") ax.plot( [2, 2 + np.sin(np.pi / 6)], [2, 2 + np.cos(np.pi / 6)], color="r", transform=transform, ) ax.vlines(x=2, color="r", linestyle="--", transform=transform, ymin=0, ymax=5) ax.text(2.15, 2.3, r"$\phi$", transform=transform) plt.show()