def test_write(tmpdir, diffuse_model): filename = tmpdir / diffuse_model.spatial_model.filename diffuse_model.spatial_model.filename = None with pytest.raises(IOError): diffuse_model.spatial_model.write() with pytest.raises(IOError): Models(diffuse_model).to_dict() diffuse_model.spatial_model.filename = filename diffuse_model.spatial_model.write(overwrite=False) TemplateSpatialModel.read(filename)
def test_flux_estimator_norm_range_template(): energy = MapAxis.from_energy_bounds(0.1, 10, 3.0, unit="TeV", name="energy_true") template = WcsNDMap.create(npix=10, axes=[energy], unit="cm-2 s-1 sr-1 TeV-1") spatial = TemplateSpatialModel(template, normalize=False) spectral = PowerLawNormSpectralModel() model = SkyModel(spectral_model=spectral, spatial_model=spatial, name="test") model.spectral_model.norm.max = 10 model.spectral_model.norm.min = 0 estimator = FluxEstimator(source="test", selection_optional=[], reoptimize=True) scale_model = estimator.get_scale_model(Models([model])) assert_allclose(scale_model.norm.min, 0) assert_allclose(scale_model.norm.max, 10) assert scale_model.norm.interp == "log"
def test_sky_diffuse_map(caplog): filename = "$GAMMAPY_DATA/catalogs/fermi/Extended_archive_v18/Templates/RXJ1713_2016_250GeV.fits" model = TemplateSpatialModel.read(filename, normalize=False) lon = [258.5, 0] * u.deg lat = -39.8 * u.deg val = model(lon, lat) assert "WARNING" in [_.levelname for _ in caplog.records] assert "Missing spatial template unit, assuming sr^-1" in [ _.message for _ in caplog.records ] assert val.unit == "sr-1" desired = [3269.178107, 0] assert_allclose(val.value, desired) res = model.evaluate_geom(model.map.geom) assert_allclose(np.sum(res.value), 32826159.74707) radius = model.evaluation_radius assert radius.unit == "deg" assert_allclose(radius.value, 0.64, rtol=1.0e-2) assert model.frame == "fk5" assert isinstance(model.to_region(), RectangleSkyRegion) with pytest.raises(TypeError): model.plot_interative() with pytest.raises(TypeError): model.plot_grid()
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): """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 test_sky_diffuse_map(): filename = "$GAMMAPY_DATA/catalogs/fermi/Extended_archive_v18/Templates/RXJ1713_2016_250GeV.fits" model = TemplateSpatialModel.read(filename, normalize=False) lon = [258.5, 0] * u.deg lat = -39.8 * u.deg val = model(lon, lat) assert val.unit == "sr-1" desired = [3269.178107, 0] assert_allclose(val.value, desired) res = model.evaluate_geom(model.map.geom) assert_allclose(np.sum(res.value), 32816514.42078349) radius = model.evaluation_radius assert radius.unit == "deg" assert_allclose(radius.value, 0.64, rtol=1.0e-2) assert model.frame == "fk5" assert isinstance(model.to_region(), PolygonSkyRegion) with pytest.raises(TypeError): model.plot_interative() with pytest.raises(TypeError): model.plot_grid()
def diffuse_model(): axis = MapAxis.from_nodes([0.1, 100], name="energy_true", unit="TeV", interp="log") m = Map.create( npix=(4, 3), binsz=2, axes=[axis], unit="cm-2 s-1 MeV-1 sr-1", frame="galactic" ) m.data += 42 spatial_model = TemplateSpatialModel(m, normalize=False) return SkyModel(PowerLawNormSpectralModel(), spatial_model)
def test_read(): model = TemplateSpatialModel.read( "$GAMMAPY_DATA/tests/unbundled/fermi/gll_iem_v02_cutout.fits", normalize=False, ) assert model.map.unit == "cm-2 s-1 MeV-1 sr-1" # Check pixel inside map val = model.evaluate(0 * u.deg, 0 * u.deg, 100 * u.GeV) assert val.unit == "cm-2 s-1 MeV-1 sr-1" assert val.shape == (1,) assert_allclose(val.value, 1.396424e-12, rtol=1e-5)
def test_sky_diffuse_map(): filename = "$GAMMAPY_DATA/catalogs/fermi/Extended_archive_v18/Templates/RXJ1713_2016_250GeV.fits" model = TemplateSpatialModel.read(filename, normalize=False) lon = [258.5, 0] * u.deg lat = -39.8 * u.deg val = model(lon, lat) assert val.unit == "sr-1" desired = [3269.178107, 0] assert_allclose(val.value, desired) radius = model.evaluation_radius assert radius.unit == "deg" assert_allclose(radius.value, 0.64, rtol=1.0e-2) assert model.frame == "fk5"
def test_sky_diffuse_map_normalize(): # define model map with a constant value of 1 model_map = Map.create(map_type="wcs", width=(10, 5), binsz=0.5) model_map.data += 1.0 model = TemplateSpatialModel(model_map) # define data map with a different spatial binning data_map = Map.create(map_type="wcs", width=(10, 5), binsz=1) coords = data_map.geom.get_coord() solid_angle = data_map.geom.solid_angle() vals = model(coords.lon, coords.lat) * solid_angle assert vals.unit == "" integral = vals.sum() assert_allclose(integral.value, 1, rtol=1e-4)
def test_sky_diffuse_map_3d(): filename = "$GAMMAPY_DATA/fermi-3fhl-gc/gll_iem_v06_gc.fits.gz" model = TemplateSpatialModel.read(filename, normalize=False) lon = [258.5, 0] * u.deg lat = -39.8 * u.deg energy = 1 * u.GeV val = model(lon, lat, energy) with pytest.raises(ValueError): model(lon, lat) assert model.map.unit == "cm-2 s-1 MeV-1 sr-1" val = model(lon, lat, energy) assert val.unit == "cm-2 s-1 MeV-1 sr-1" res = model.evaluate_geom(model.map.geom) assert_allclose(np.sum(res.value), 0.11803847221522712) with pytest.raises(TypeError): model.plot()
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}")
JFAC = 3.27e19 * u.Unit("GeV2 cm-5") # <--- Reticulum II Extended #JFAC = 1.26e20 * u.Unit("GeV2 cm-5") # <--- Draco I Extended mDM = 40000 * u.Unit("GeV") channel = "b" xsection = 1e-26 * u.Unit("cm3 s-1") redshift = 0 RATIO = 2.71 # **Define 3D Sky Model** DarkMatterAnnihilationSpectralModel.THERMAL_RELIC_CROSS_SECTION = xsection flux_model = DarkMatterAnnihilationSpectralModel(mass=mDM, channel=channel, jfactor=JFAC) spatial_model = TemplateSpatialModel.read(jfactor_filename) sky_model = SkyModel(spatial_model=spatial_model, spectral_model=flux_model, name="model-simu") bkg_model = FoVBackgroundModel(dataset_name="dataset-simu") models = Models([sky_model, bkg_model]) # ## Declare observation values pointing = src_pos livetime = 100 * u.hour offset = 2.0 * u.deg #offset = 0.5 * u.deg
def run_region(self, kr, lon, lat, radius): # TODO: for now we have to read/create the allsky maps each in each job # because we can't pickle <functools._lru_cache_wrapper object # send this back to init when fixed log.info(f"ROI {kr}: loading data") # exposure exposure_hpx = Map.read( "$GAMMAPY_DATA/fermi_3fhl/fermi_3fhl_exposure_cube_hpx.fits.gz") exposure_hpx.unit = "cm2 s" # iem iem_filepath = BASE_PATH / "data" / "gll_iem_v06_extrapolated.fits" iem_fermi_extra = Map.read(iem_filepath) # norm=1.1, tilt=0.03 see paper appendix A model_iem = SkyModel( PowerLawNormSpectralModel(norm=1.1, tilt=0.03), TemplateSpatialModel(iem_fermi_extra, normalize=False), name="iem_extrapolated", ) # ROI roi_time = time() ROI_pos = SkyCoord(lon, lat, frame="galactic", unit="deg") width = 2 * (radius + self.psf_margin) # Counts counts = Map.create( skydir=ROI_pos, width=width, proj="CAR", frame="galactic", binsz=1 / 8.0, axes=[self.energy_axis], dtype=float, ) counts.fill_by_coord({ "skycoord": self.events.radec, "energy": self.events.energy }) axis = MapAxis.from_nodes(counts.geom.axes[0].center, name="energy_true", unit="GeV", interp="log") wcs = counts.geom.wcs geom = WcsGeom(wcs=wcs, npix=counts.geom.npix, axes=[axis]) coords = geom.get_coord() # expo data = exposure_hpx.interp_by_coord(coords) exposure = WcsNDMap(geom, data, unit=exposure_hpx.unit, dtype=float) # read PSF psf_kernel = PSFKernel.from_table_psf(self.psf, geom, max_radius=self.psf_margin * u.deg) # Energy Dispersion e_true = exposure.geom.axes[0].edges e_reco = counts.geom.axes[0].edges edisp = EDispKernel.from_diagonal_response(e_true=e_true, e_reco=e_reco) # fit mask if coords["lon"].min() < 90 * u.deg and coords["lon"].max( ) > 270 * u.deg: coords["lon"][coords["lon"].value > 180] -= 360 * u.deg mask = ( (coords["lon"] >= coords["lon"].min() + self.psf_margin * u.deg) & (coords["lon"] <= coords["lon"].max() - self.psf_margin * u.deg) & (coords["lat"] >= coords["lat"].min() + self.psf_margin * u.deg) & (coords["lat"] <= coords["lat"].max() - self.psf_margin * u.deg)) mask_fermi = WcsNDMap(counts.geom, mask) log.info(f"ROI {kr}: pre-computing diffuse") # IEM eval_iem = MapEvaluator(model=model_iem, exposure=exposure, psf=psf_kernel, edisp=edisp) bkg_iem = eval_iem.compute_npred() # ISO eval_iso = MapEvaluator(model=self.model_iso, exposure=exposure, edisp=edisp) bkg_iso = eval_iso.compute_npred() # merge iem and iso, only one local normalization is fitted dataset_name = "3FHL_ROI_num" + str(kr) background_total = bkg_iem + bkg_iso background_model = BackgroundModel(background_total, name="bkg_iem+iso", datasets_names=[dataset_name]) background_model.parameters["norm"].min = 0.0 # Sources model in_roi = self.FHL3.positions.galactic.contained_by(wcs) FHL3_roi = [] for ks in range(len(self.FHL3.table)): if in_roi[ks] == True: model = self.FHL3[ks].sky_model() model.spatial_model.parameters.freeze_all() # freeze spatial model.spectral_model.parameters["amplitude"].min = 0.0 if isinstance(model.spectral_model, PowerLawSpectralModel): model.spectral_model.parameters["index"].min = 0.1 model.spectral_model.parameters["index"].max = 10.0 else: model.spectral_model.parameters["alpha"].min = 0.1 model.spectral_model.parameters["alpha"].max = 10.0 FHL3_roi.append(model) model_total = Models([background_model] + FHL3_roi) # Dataset dataset = MapDataset( models=model_total, counts=counts, exposure=exposure, psf=psf_kernel, edisp=edisp, mask_fit=mask_fermi, name=dataset_name, ) cat_stat = dataset.stat_sum() datasets = Datasets([dataset]) log.info(f"ROI {kr}: running fit") fit = Fit(datasets) results = fit.run(**self.optimize_opts) print("ROI_num", str(kr), "\n", results) fit_stat = datasets.stat_sum() if results.message != "Optimization failed.": datasets.write(path=Path(self.resdir), prefix=dataset.name, overwrite=True) np.savez( self.resdir / f"3FHL_ROI_num{kr}_fit_infos.npz", message=results.message, stat=[cat_stat, fit_stat], ) exec_time = time() - roi_time print("ROI", kr, " time (s): ", exec_time) log.info(f"ROI {kr}: running flux points") for model in FHL3_roi: if (self.FHL3[model.name].data["ROI_num"] == kr and self.FHL3[model.name].data["Signif_Avg"] >= self.sig_cut): flux_points = FluxPointsEstimator( e_edges=self.El_flux, source=model.name, n_sigma_ul=2, ).run(datasets=datasets) filename = self.resdir / f"{model.name}_flux_points.fits" flux_points.write(filename, overwrite=True) exec_time = time() - roi_time - exec_time print("ROI", kr, " Flux points time (s): ", exec_time)
# ------------ # Here is an example plot of the model: from gammapy.maps import Map from gammapy.modeling.models import ( Models, PowerLawSpectralModel, SkyModel, TemplateSpatialModel, ) filename = "$GAMMAPY_DATA/catalogs/fermi/Extended_archive_v18/Templates/RXJ1713_2016_250GeV.fits" m = Map.read(filename) m.unit = "sr^-1" model = TemplateSpatialModel(m, filename=filename) model.plot(add_cbar=True) # %% # YAML representation # ------------------- # Here is an example YAML file using the model: pwl = PowerLawSpectralModel() template = TemplateSpatialModel(m, filename=filename) model = SkyModel(spectral_model=pwl, spatial_model=template, name="pwl-template-model") models = Models([model])
def make_datasets_example(): # Define which data to use and print some information energy_axis = MapAxis.from_edges(np.logspace(-1.0, 1.0, 4), unit="TeV", name="energy", interp="log") geom0 = WcsGeom.create( skydir=(0, 0), binsz=0.1, width=(2, 2), frame="galactic", proj="CAR", axes=[energy_axis], ) geom1 = WcsGeom.create( skydir=(1, 0), binsz=0.1, width=(2, 2), frame="galactic", proj="CAR", axes=[energy_axis], ) geoms = [geom0, geom1] sources_coords = [(0, 0), (0.9, 0.1)] names = ["gc", "g09"] models = Models() for idx, (lon, lat) in enumerate(sources_coords): spatial_model = PointSpatialModel(lon_0=lon * u.deg, lat_0=lat * u.deg, frame="galactic") spectral_model = ExpCutoffPowerLawSpectralModel( index=2 * u.Unit(""), amplitude=3e-12 * u.Unit("cm-2 s-1 TeV-1"), reference=1.0 * u.TeV, lambda_=0.1 / u.TeV, ) model_ecpl = SkyModel(spatial_model=spatial_model, spectral_model=spectral_model, name=names[idx]) models.append(model_ecpl) models["gc"].spectral_model.reference = models[ "g09"].spectral_model.reference obs_ids = [110380, 111140, 111159] data_store = DataStore.from_dir("$GAMMAPY_DATA/cta-1dc/index/gps/") diffuse_spatial = TemplateSpatialModel.read( "$GAMMAPY_DATA/fermi-3fhl-gc/gll_iem_v06_gc.fits.gz") diffuse_model = SkyModel(PowerLawSpectralModel(), diffuse_spatial) maker = MapDatasetMaker() datasets = Datasets() observations = data_store.get_observations(obs_ids) for idx, geom in enumerate(geoms): stacked = MapDataset.create(geom=geom, name=names[idx]) for obs in observations: dataset = maker.run(stacked, obs) stacked.stack(dataset) bkg = stacked.models.pop(0) stacked.models = [models[idx], diffuse_model, bkg] datasets.append(stacked) datasets.write( "$GAMMAPY_DATA/tests/models", prefix="gc_example", overwrite=True, write_covariance=False, )
# ------------ # Here is an example plot of the model: from gammapy.maps import Map from gammapy.modeling.models import ( Models, PowerLawSpectralModel, SkyModel, TemplateSpatialModel, ) filename = "$GAMMAPY_DATA/catalogs/fermi/Extended_archive_v18/Templates/RXJ1713_2016_250GeV.fits" m = Map.read(filename) m.unit = "sr^-1" model = TemplateSpatialModel(m) model.plot(add_cbar=True) # %% # YAML representation # ------------------- # Here is an example YAML file using the model: pwl = PowerLawSpectralModel() template = TemplateSpatialModel(m) model = SkyModel(spectral_model=pwl, spatial_model=template, name="pwl-template-model") models = Models([model])