Ejemplo n.º 1
0
    def spatial_model(self):
        """Source spatial model (`~gammapy.image.models.SkySpatialModel`)."""
        d = self.data

        pars = {}
        glon = d["GLON"]
        glat = d["GLAT"]

        if self.is_pointlike:
            pars["lon_0"] = glon
            pars["lat_0"] = glat
            return SkyPointSource(lon_0=glon, lat_0=glat)
        else:
            de = self.data_extended
            morph_type = de["Spatial_Function"].strip()

            if morph_type == "RadialDisk":
                r_0 = de["Model_SemiMajor"].to("deg")
                return SkyDisk(lon_0=glon, lat_0=glat, r_0=r_0)
            elif morph_type in ["SpatialMap"]:
                filename = de["Spatial_Filename"].strip()
                path = make_path(
                    "$GAMMAPY_DATA/catalogs/fermi/Extended_archive_v18/Templates/"
                )
                return SkyDiffuseMap.read(path / filename)
            elif morph_type == "RadialGauss":
                # TODO: fill elongation info as soon as model supports it
                sigma = de["Model_SemiMajor"].to("deg")
                return SkyGaussian(lon_0=glon, lat_0=glat, sigma=sigma)
            else:
                raise ValueError("Invalid morph_type: {!r}".format(morph_type))
Ejemplo n.º 2
0
def test_sky_point_source():
    model = SkyPointSource(lon_0="2.5 deg", lat_0="2.5 deg")
    lat, lon = np.mgrid[0:6, 0:6] * u.deg
    val = model(lon, lat)
    assert val.unit == "deg-2"
    assert_allclose(val.sum().value, 1)
    radius = model.evaluation_radius
    assert radius.unit == "deg"
    assert_allclose(radius.value, 0)
    assert model.frame == "galactic"

    assert_allclose(model.position.l.deg, 2.5)
    assert_allclose(model.position.b.deg, 2.5)
Ejemplo n.º 3
0
table_psf = observations.make_mean_psf(pos_crab)

# In[ ]:

psf_kernel = PSFKernel.from_table_psf(table_psf, geom, max_radius="0.3 deg")
psf_kernel_array = psf_kernel.psf_kernel_map.sum_over_axes().data
# psf_kernel.psf_kernel_map.slice_by_idx({'energy': 0}).plot()
# plt.imshow(psf_kernel_array)

# ## Map fit
#
# Let's fit this source assuming a Gaussian spatial shape and a power-law spectral shape

# In[ ]:

spatial_model = SkyPointSource(lon_0="83.6 deg", lat_0="22.0 deg")
spectral_model = PowerLaw(index=2.6,
                          amplitude="5e-11 cm-2 s-1 TeV-1",
                          reference="1 TeV")
model = SkyModel(spatial_model=spatial_model, spectral_model=spectral_model)

# In[ ]:

get_ipython().run_cell_magic(
    'time', '',
    'fit = MapFit(\n    model=model,\n    counts=maps["counts"],\n    exposure=maps["exposure"],\n    background=maps["background"],\n    psf=psf_kernel,\n)\nresult = fit.run()\nprint(result)\nprint(result.model.parameters.to_table())'
)

# ## Residual image
#
# We compute a residual image as `residual = counts - model`. Note that this is counts per pixel and our pixel size is 0.02 deg. Smoothing is counts-preserving. The residual image shows that currently both the source and the background modeling isn't very good. The background model is underestimated (so residual is positive), and the source model is overestimated.
Ejemplo n.º 4
0
for obs_id in obs_ids:
    path = Path("analysis_3d_joint") / "obs_{}".format(obs_id)
    path.mkdir(parents=True, exist_ok=True)

    for key in ["counts", "exposure", "background", "edisp", "psf"]:
        filename = "{}.fits.gz".format(key)
        observations_data[obs_id][key].write(path / filename, overwrite=True)

# ## Likelihood fit
#
# ### Reading maps and IRFs
# As first step we define a source model:

# In[ ]:

spatial_model = SkyPointSource(lon_0="-0.05 deg", lat_0="-0.05 deg")
spectral_model = PowerLaw(index=2.4,
                          amplitude="2.7e-12 cm-2 s-1 TeV-1",
                          reference="1 TeV")
model = SkyModel(spatial_model=spatial_model, spectral_model=spectral_model)

# Now we read the maps and IRFs and create the dataset for each observation:

# In[ ]:

datasets = []

for obs_id in obs_ids:
    path = Path("analysis_3d_joint") / "obs_{}".format(obs_id)

    # read counts map and IRFs
Ejemplo n.º 5
0
flux = excess.copy()
flux.data /= exposure.data
flux.unit = excess.unit / exposure.unit
flux.sum_over_axes().smooth(2).plot(stretch="sqrt", add_cbar=True);


# ## Fit
# 
# Finally, the big finale: let's do a 3D map fit for the source at the Galactic center, to measure it's position and spectrum.

# In[ ]:


model = SkyModel(
    SkyPointSource("0 deg", "0 deg"),
    PowerLaw(index=2.5, amplitude="1e-11 cm-2 s-1 TeV-1", reference="100 GeV"),
)
fit = MapFit(
    model=model,
    counts=counts,
    exposure=exposure,
    background=background,
    psf=psf_kernel,
)
result = fit.run()


# In[ ]:

Ejemplo n.º 6
0
# In[ ]:

psf_kernel = PSFKernel.from_table_psf(table_psf, geom, max_radius="0.3 deg")
psf_kernel_array = psf_kernel.psf_kernel_map.sum_over_axes().data
# psf_kernel.psf_kernel_map.slice_by_idx({'energy': 0}).plot()
# plt.imshow(psf_kernel_array)

# ## Map fit
#
# Let's fit this source assuming a Gaussian spatial shape and a power-law spectral shape, and a background with a flexible normalisation

# In[ ]:

spatial_model = SkyPointSource(lon_0="83.6 deg",
                               lat_0="22.0 deg",
                               frame="icrs")
spectral_model = PowerLaw(index=2.6,
                          amplitude="5e-11 cm-2 s-1 TeV-1",
                          reference="1 TeV")
model = SkyModel(spatial_model=spatial_model, spectral_model=spectral_model)
background_model = BackgroundModel(maps["background"], norm=1.0)
background_model.parameters["tilt"].frozen = False

# In[ ]:

get_ipython().run_cell_magic(
    'time', '',
    'dataset = MapDataset(\n    model=model,\n    counts=maps["counts"],\n    exposure=maps["exposure"],\n    background_model=background_model,\n    psf=psf_kernel,\n)\nfit = Fit(dataset)\nresult = fit.run()\nprint(result)'
)
Ejemplo n.º 7
0
mask.get_image_by_idx((0, )).plot()

# In addition we also exclude the range below 0.3 TeV for the fit:

# In[ ]:

coords = mask.geom.get_coord()
mask.data &= coords["energy"] > 0.3

# ### Model fit
#
# No we are ready for the actual likelihood fit. We first define the model as a combination of a point source with a powerlaw:

# In[ ]:

spatial_model = SkyPointSource(lon_0="0.01 deg", lat_0="0.01 deg")
spectral_model = PowerLaw(index=2.2,
                          amplitude="3e-12 cm-2 s-1 TeV-1",
                          reference="1 TeV")
model = SkyModel(spatial_model=spatial_model, spectral_model=spectral_model)

# Now we set up the `MapFit` object by passing the prepared maps, IRFs as well as the model:

# In[ ]:

fit = MapFit(
    model=model,
    counts=cmaps["counts"],
    exposure=cmaps["exposure"],
    background=cmaps["background"],
    mask=mask,