Exemple #1
0
    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
Exemple #2
0
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)
Exemple #3
0
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)
Exemple #4
0
    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
Exemple #5
0
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
Exemple #7
0
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)
Exemple #8
0
    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)
Exemple #9
0
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
Exemple #10
0
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))
Exemple #11
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)
Exemple #12
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)
Exemple #13
0
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)
Exemple #14
0
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)
Exemple #15
0
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")
Exemple #16
0
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])
Exemple #17
0
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
Exemple #18
0
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)
Exemple #19
0
    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}")
Exemple #20
0
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)
Exemple #21
0
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)
Exemple #22
0
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)
Exemple #23
0
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
Exemple #24
0
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)
Exemple #25
0
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
Exemple #26
0
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)
Exemple #27
0
    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)
Exemple #28
0
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)
Exemple #29
0
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))
Exemple #30
0
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
Exemple #31
0
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)
Exemple #33
0
)

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)

Exemple #34
0
"""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()