def simulate_spectrum_dataset(model, random_state=0):
    energy_edges = np.logspace(-0.5, 1.5, 21) * u.TeV
    energy_axis = MapAxis.from_edges(energy_edges, interp="log", name="energy")

    aeff = EffectiveAreaTable.from_parametrization(
        energy=energy_edges).to_region_map()
    bkg_model = SkyModel(
        spectral_model=PowerLawSpectralModel(index=2.5,
                                             amplitude="1e-12 cm-2 s-1 TeV-1"),
        name="background",
    )
    bkg_model.spectral_model.amplitude.frozen = True
    bkg_model.spectral_model.index.frozen = True

    geom = RegionGeom(region=None, axes=[energy_axis])
    acceptance = RegionNDMap.from_geom(geom=geom, data=1)
    edisp = EDispKernelMap.from_diagonal_response(
        energy_axis=energy_axis,
        energy_axis_true=energy_axis.copy(name="energy_true"),
        geom=geom,
    )

    livetime = 100 * u.h
    exposure = aeff * livetime

    mask_safe = RegionNDMap.from_geom(geom=geom, dtype=bool)
    mask_safe.data += True

    dataset = SpectrumDatasetOnOff(name="test_onoff",
                                   exposure=exposure,
                                   acceptance=acceptance,
                                   acceptance_off=5,
                                   edisp=edisp,
                                   mask_safe=mask_safe)
    dataset.models = bkg_model
    bkg_npred = dataset.npred_signal()

    dataset.models = model
    dataset.fake(
        random_state=random_state,
        npred_background=bkg_npred,
    )
    return dataset
Example #2
0
def get_map_dataset(sky_model,
                    geom,
                    geom_etrue,
                    edisp="edispmap",
                    name="test",
                    **kwargs):
    """Returns a MapDatasets"""
    # define background model
    m = Map.from_geom(geom)
    m.quantity = 0.2 * np.ones(m.data.shape)
    background_model = BackgroundModel(m, datasets_names=[name])

    psf = get_psf()
    exposure = get_exposure(geom_etrue)

    e_reco = geom.get_axis_by_name("energy")
    e_true = geom_etrue.get_axis_by_name("energy_true")

    if edisp == "edispmap":
        edisp = EDispMap.from_diagonal_response(energy_axis_true=e_true)
    elif edisp == "edispkernelmap":
        edisp = EDispKernelMap.from_diagonal_response(energy_axis=e_reco,
                                                      energy_axis_true=e_true)
    elif edisp == "edispkernel":
        edisp = EDispKernel.from_diagonal_response(e_true=e_true.edges,
                                                   e_reco=e_reco.edges)
    else:
        edisp = None

    # define fit mask
    center = sky_model.spatial_model.position
    circle = CircleSkyRegion(center=center, radius=1 * u.deg)
    mask_fit = background_model.map.geom.region_mask([circle])
    mask_fit = Map.from_geom(geom, data=mask_fit)

    return MapDataset(models=[sky_model, background_model],
                      exposure=exposure,
                      psf=psf,
                      edisp=edisp,
                      mask_fit=mask_fit,
                      name=name,
                      **kwargs)
Example #3
0
def test_edispkernel_from_diagonal_response():
    energy_axis_true = MapAxis.from_energy_bounds("0.3 TeV",
                                                  "10 TeV",
                                                  nbin=11,
                                                  name="energy_true")
    energy_axis = MapAxis.from_energy_bounds("0.3 TeV",
                                             "10 TeV",
                                             nbin=11,
                                             name="energy")

    region = make_region("fk5;circle(0.,0., 10.")
    geom = RegionGeom(region)
    region_edisp = EDispKernelMap.from_diagonal_response(energy_axis,
                                                         energy_axis_true,
                                                         geom=geom)
    sum_kernel = np.sum(region_edisp.edisp_map.data[..., 0, 0], axis=1)

    # We exclude the first and last bin, where there is no
    # e_reco to contribute to
    assert_allclose(sum_kernel[1:-1], 1)
Example #4
0
def spectrum_dataset():
    e_true = MapAxis.from_energy_bounds("1 TeV",
                                        "10 TeV",
                                        nbin=20,
                                        name="energy_true")
    e_reco = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=4)
    aeff = EffectiveAreaTable.from_constant(value=1e6 * u.m**2,
                                            energy=e_true.edges)

    background = RegionNDMap.create(region="icrs;circle(0, 0, 0.1)",
                                    axes=[e_reco])
    background.data += 3600
    background.data[-1] *= 1e-3
    edisp = EDispKernelMap.from_diagonal_response(energy_axis_true=e_true,
                                                  energy_axis=e_reco,
                                                  geom=background.geom)
    return SpectrumDataset(aeff=aeff,
                           livetime="1h",
                           edisp=edisp,
                           background=background)
Example #5
0
def spectrum_dataset():
    e_true = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=20, name="energy_true")
    e_reco = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=4)

    background = RegionNDMap.create(region="icrs;circle(0, 0, 0.1)", axes=[e_reco])
    background.data += 3600
    background.data[0] *= 1e3
    background.data[-1] *= 1e-3
    edisp = EDispKernelMap.from_diagonal_response(
        energy_axis_true=e_true, energy_axis=e_reco, geom=background.geom
    )
    aeff = RegionNDMap.create(region="icrs;circle(0, 0, 0.1)", axes=[e_true], unit="m2")
    aeff.data += 1e6

    livetime = 1 * u.h
    exposure = aeff * livetime

    return SpectrumDataset(
        name="test", exposure=exposure, edisp=edisp, background=background
    )
Example #6
0
def get_map_dataset(geom, geom_etrue, edisp="edispmap", name="test", **kwargs):
    """Returns a MapDatasets"""
    # define background model
    background = Map.from_geom(geom)
    background.data += 0.2

    psf = get_psf()
    exposure = get_exposure(geom_etrue)

    e_reco = geom.axes["energy"]
    e_true = geom_etrue.axes["energy_true"]

    if edisp == "edispmap":
        edisp = EDispMap.from_diagonal_response(energy_axis_true=e_true)
    elif edisp == "edispkernelmap":
        edisp = EDispKernelMap.from_diagonal_response(energy_axis=e_reco,
                                                      energy_axis_true=e_true)
    elif edisp == "edispkernel":
        edisp = EDispKernel.from_diagonal_response(energy_true=e_true.edges,
                                                   energy=e_reco.edges)
    else:
        edisp = None

    # define fit mask
    center = SkyCoord("0.2 deg", "0.1 deg", frame="galactic")
    circle = CircleSkyRegion(center=center, radius=1 * u.deg)
    mask_fit = geom.region_mask([circle])
    mask_fit = Map.from_geom(geom, data=mask_fit)

    models = FoVBackgroundModel(dataset_name=name)

    return MapDataset(
        models=models,
        exposure=exposure,
        background=background,
        psf=psf,
        edisp=edisp,
        mask_fit=mask_fit,
        name=name,
        **kwargs,
    )
Example #7
0
def fermi_dataset():
    size = Angle("3 deg", "3.5 deg")
    counts = Map.read("$GAMMAPY_DATA/fermi-3fhl-gc/fermi-3fhl-gc-counts-cube.fits.gz")
    counts = counts.cutout(counts.geom.center_skydir, size)

    background = Map.read(
        "$GAMMAPY_DATA/fermi-3fhl-gc/fermi-3fhl-gc-background-cube.fits.gz"
    )
    background = background.cutout(background.geom.center_skydir, size)
    background = BackgroundModel(background, datasets_names=["fermi-3fhl-gc"])

    exposure = Map.read(
        "$GAMMAPY_DATA/fermi-3fhl-gc/fermi-3fhl-gc-exposure-cube.fits.gz"
    )
    exposure = exposure.cutout(exposure.geom.center_skydir, size)
    exposure.unit = "cm2 s"
    mask_safe = counts.copy(data=np.ones_like(counts.data).astype("bool"))

    psf = EnergyDependentTablePSF.read(
        "$GAMMAPY_DATA/fermi-3fhl-gc/fermi-3fhl-gc-psf-cube.fits.gz"
    )
    psfmap = PSFMap.from_energy_dependent_table_psf(psf)
    edisp = EDispKernelMap.from_diagonal_response(
        energy_axis=counts.geom.get_axis_by_name("energy"),
        energy_axis_true=exposure.geom.get_axis_by_name("energy_true"),
    )

    dataset = MapDataset(
        counts=counts,
        models=[background],
        exposure=exposure,
        mask_safe=mask_safe,
        psf=psfmap,
        name="fermi-3fhl-gc",
        edisp=edisp
    )

    return dataset.to_image()
Example #8
0
    def setup(self):
        etrue = np.logspace(-1, 1, 10) * u.TeV
        self.e_true = MapAxis.from_energy_edges(etrue, name="energy_true")
        ereco = np.logspace(-1, 1, 5) * u.TeV
        elo = ereco[:-1]
        ehi = ereco[1:]
        self.e_reco = MapAxis.from_energy_edges(ereco, name="energy")

        start = u.Quantity([0], "s")
        stop = u.Quantity([1000], "s")
        time_ref = Time("2010-01-01 00:00:00.0")
        self.gti = GTI.create(start, stop, time_ref)
        self.livetime = self.gti.time_sum

        self.on_region = make_region("icrs;circle(0.,1.,0.1)")
        off_region = make_region("icrs;box(0.,1.,0.1, 0.2,30)")
        self.off_region = off_region.union(
            make_region("icrs;box(-1.,-1.,0.1, 0.2,150)"))
        self.wcs = WcsGeom.create(npix=300, binsz=0.01, frame="icrs").wcs

        self.aeff = RegionNDMap.create(region=self.on_region,
                                       wcs=self.wcs,
                                       axes=[self.e_true],
                                       unit="cm2")
        self.aeff.data += 1

        data = np.ones(elo.shape)
        data[-1] = 0  # to test stats calculation with empty bins

        axis = MapAxis.from_edges(ereco, name="energy", interp="log")
        self.on_counts = RegionNDMap.create(
            region=self.on_region,
            wcs=self.wcs,
            axes=[axis],
            meta={"EXPOSURE": self.livetime.to_value("s")},
        )
        self.on_counts.data += 1
        self.on_counts.data[-1] = 0

        self.off_counts = RegionNDMap.create(region=self.off_region,
                                             wcs=self.wcs,
                                             axes=[axis])
        self.off_counts.data += 10

        acceptance = RegionNDMap.from_geom(self.on_counts.geom)
        acceptance.data += 1

        data = np.ones(elo.shape)
        data[-1] = 0

        acceptance_off = RegionNDMap.from_geom(self.off_counts.geom)
        acceptance_off.data += 10

        self.edisp = EDispKernelMap.from_diagonal_response(
            self.e_reco, self.e_true, self.on_counts.geom.to_image())

        exposure = self.aeff * self.livetime
        exposure.meta["livetime"] = self.livetime

        mask_safe = RegionNDMap.from_geom(self.on_counts.geom, dtype=bool)
        mask_safe.data += True

        self.dataset = SpectrumDatasetOnOff(
            counts=self.on_counts,
            counts_off=self.off_counts,
            exposure=exposure,
            edisp=self.edisp,
            acceptance=acceptance,
            acceptance_off=acceptance_off,
            name="test",
            gti=self.gti,
            mask_safe=mask_safe,
        )
Example #9
0
def test_spectrum_dataset_stack_diagonal_safe_mask(spectrum_dataset):
    geom = spectrum_dataset.counts.geom

    energy = MapAxis.from_energy_bounds("0.1 TeV", "10 TeV", nbin=30)
    energy_true = MapAxis.from_energy_bounds("0.1 TeV",
                                             "10 TeV",
                                             nbin=30,
                                             name="energy_true")

    aeff = EffectiveAreaTable2D.from_parametrization(
        energy_axis_true=energy_true, instrument="HESS")

    livetime = 100 * u.s
    gti = GTI.create(start=0 * u.s, stop=livetime)

    geom_true = geom.as_energy_true
    exposure = make_map_exposure_true_energy(geom=geom_true,
                                             livetime=livetime,
                                             pointing=geom_true.center_skydir,
                                             aeff=aeff)

    edisp = EDispKernelMap.from_diagonal_response(energy,
                                                  energy_true,
                                                  geom=geom.to_image())
    edisp.exposure_map.data = exposure.data[:, :, np.newaxis, :]

    background = spectrum_dataset.background

    mask_safe = RegionNDMap.from_geom(geom=geom, dtype=bool)
    mask_safe.data += True

    spectrum_dataset1 = SpectrumDataset(
        name="ds1",
        counts=spectrum_dataset.counts.copy(),
        exposure=exposure.copy(),
        edisp=edisp.copy(),
        background=background.copy(),
        gti=gti.copy(),
        mask_safe=mask_safe,
    )

    livetime2 = 0.5 * livetime
    gti2 = GTI.create(start=200 * u.s, stop=200 * u.s + livetime2)
    bkg2 = RegionNDMap.from_geom(geom=geom, data=2 * background.data)

    geom = spectrum_dataset.counts.geom
    data = np.ones(spectrum_dataset.data_shape, dtype="bool")
    data[0] = False
    safe_mask2 = RegionNDMap.from_geom(geom=geom, data=data)
    exposure2 = exposure.copy()

    edisp = edisp.copy()
    edisp.exposure_map.data = exposure2.data[:, :, np.newaxis, :]
    spectrum_dataset2 = SpectrumDataset(
        name="ds2",
        counts=spectrum_dataset.counts.copy(),
        exposure=exposure2,
        edisp=edisp,
        background=bkg2,
        mask_safe=safe_mask2,
        gti=gti2,
    )

    spectrum_dataset1.stack(spectrum_dataset2)

    reference = spectrum_dataset.counts.data
    assert_allclose(spectrum_dataset1.counts.data[1:], reference[1:] * 2)
    assert_allclose(spectrum_dataset1.counts.data[0], 141363)
    assert_allclose(spectrum_dataset1.exposure.quantity[0],
                    4.755644e09 * u.Unit("cm2 s"))
    assert_allclose(spectrum_dataset1.background.data[1:],
                    3 * background.data[1:])
    assert_allclose(spectrum_dataset1.background.data[0], background.data[0])

    kernel = edisp.get_edisp_kernel()
    kernel_stacked = spectrum_dataset1.edisp.get_edisp_kernel()

    assert_allclose(kernel_stacked.pdf_matrix[1:], kernel.pdf_matrix[1:])
    assert_allclose(kernel_stacked.pdf_matrix[0], 0.5 * kernel.pdf_matrix[0])
Example #10
0
def test_spectrum_dataset_stack_diagonal_safe_mask(spectrum_dataset):
    geom = spectrum_dataset.counts.geom

    energy = MapAxis.from_energy_bounds("0.1 TeV", "10 TeV", nbin=30)
    energy_true = MapAxis.from_energy_bounds("0.1 TeV",
                                             "10 TeV",
                                             nbin=30,
                                             name="energy_true")

    aeff = EffectiveAreaTable.from_parametrization(
        energy.edges, "HESS").to_region_map(geom.region)

    livetime = 100 * u.s
    gti = GTI.create(start=0 * u.s, stop=livetime)

    exposure = aeff * livetime

    edisp = EDispKernelMap.from_diagonal_response(energy,
                                                  energy_true,
                                                  geom=geom.to_image())
    edisp.exposure_map.data = exposure.data[:, :, np.newaxis, :]

    background = spectrum_dataset.background_model.map.copy()

    spectrum_dataset1 = SpectrumDataset(name="ds1",
                                        counts=spectrum_dataset.counts.copy(),
                                        exposure=exposure.copy(),
                                        edisp=edisp.copy(),
                                        models=BackgroundModel(
                                            background,
                                            name="ds1-bkg",
                                            datasets_names=["ds1"]),
                                        gti=gti.copy())

    livetime2 = 0.5 * livetime
    gti2 = GTI.create(start=200 * u.s, stop=200 * u.s + livetime2)
    aeff2 = aeff * 2
    bkg2 = RegionNDMap.from_geom(geom=geom, data=2 * background.data)

    geom = spectrum_dataset.counts.geom
    data = np.ones(spectrum_dataset.data_shape, dtype="bool")
    data[0] = False
    safe_mask2 = RegionNDMap.from_geom(geom=geom, data=data)
    exposure2 = aeff2 * livetime2

    edisp = edisp.copy()
    edisp.exposure_map.data = exposure2.data[:, :, np.newaxis, :]
    spectrum_dataset2 = SpectrumDataset(name="ds2",
                                        counts=spectrum_dataset.counts.copy(),
                                        exposure=exposure2,
                                        edisp=edisp,
                                        models=BackgroundModel(
                                            bkg2,
                                            name="ds2-bkg",
                                            datasets_names=["ds2"]),
                                        mask_safe=safe_mask2,
                                        gti=gti2)

    spectrum_dataset1.stack(spectrum_dataset2)

    reference = spectrum_dataset.counts.data
    assert_allclose(spectrum_dataset1.counts.data[1:], reference[1:] * 2)
    assert_allclose(spectrum_dataset1.counts.data[0], 141363)
    assert_allclose(spectrum_dataset1.exposure.data[0], 4.755644e+09)
    assert_allclose(spectrum_dataset1.background_model.map.data[1:],
                    3 * background.data[1:])
    assert_allclose(spectrum_dataset1.background_model.map.data[0],
                    background.data[0])

    assert_allclose(
        spectrum_dataset1.exposure.quantity.to_value("m2s"),
        2 * (aeff * livetime).quantity.to_value("m2s"),
    )
    kernel = edisp.get_edisp_kernel()
    kernel_stacked = spectrum_dataset1.edisp.get_edisp_kernel()

    assert_allclose(kernel_stacked.pdf_matrix[1:], kernel.pdf_matrix[1:])
    assert_allclose(kernel_stacked.pdf_matrix[0], 0.5 * kernel.pdf_matrix[0])
Example #11
0
def test_stack(sky_model):
    axis = MapAxis.from_energy_bounds("0.1 TeV", "10 TeV", nbin=3)
    geom = WcsGeom.create(
        skydir=(266.40498829, -28.93617776),
        binsz=0.05,
        width=(2, 2),
        frame="icrs",
        axes=[axis],
    )
    axis_etrue = MapAxis.from_energy_bounds(
        "0.1 TeV", "10 TeV", nbin=5, name="energy_true"
    )
    geom_etrue = WcsGeom.create(
        skydir=(266.40498829, -28.93617776),
        binsz=0.05,
        width=(2, 2),
        frame="icrs",
        axes=[axis_etrue],
    )

    edisp = EDispKernelMap.from_diagonal_response(
        energy_axis=axis, energy_axis_true=axis_etrue, geom=geom
    )
    edisp.exposure_map.quantity = (
        1e0 * u.m ** 2 * u.s * np.ones(edisp.exposure_map.data.shape)
    )

    bkg1 = Map.from_geom(geom)
    bkg1.data += 0.2

    cnt1 = Map.from_geom(geom)
    cnt1.data = 1.0 * np.ones(cnt1.data.shape)

    exp1 = Map.from_geom(geom_etrue)
    exp1.quantity = 1e7 * u.m ** 2 * u.s * np.ones(exp1.data.shape)

    mask1 = Map.from_geom(geom)
    mask1.data = np.ones(mask1.data.shape, dtype=bool)
    mask1.data[0][:][5:10] = False
    dataset1 = MapDataset(
        counts=cnt1,
        background=bkg1,
        exposure=exp1,
        mask_safe=mask1,
        name="dataset-1",
        edisp=edisp,
        meta_table=Table({"OBS_ID": [0]}),
    )

    bkg2 = Map.from_geom(geom)
    bkg2.data = 0.1 * np.ones(bkg2.data.shape)

    cnt2 = Map.from_geom(geom)
    cnt2.data = 1.0 * np.ones(cnt2.data.shape)

    exp2 = Map.from_geom(geom_etrue)
    exp2.quantity = 1e7 * u.m ** 2 * u.s * np.ones(exp2.data.shape)

    mask2 = Map.from_geom(geom)
    mask2.data = np.ones(mask2.data.shape, dtype=bool)
    mask2.data[0][:][5:10] = False
    mask2.data[1][:][10:15] = False

    dataset2 = MapDataset(
        counts=cnt2,
        background=bkg2,
        exposure=exp2,
        mask_safe=mask2,
        name="dataset-2",
        edisp=edisp,
        meta_table=Table({"OBS_ID": [1]}),
    )

    background_model2 = FoVBackgroundModel(dataset_name="dataset-2")
    background_model1 = FoVBackgroundModel(dataset_name="dataset-1")

    dataset1.models = [background_model1, sky_model]
    dataset2.models = [background_model2, sky_model]
    dataset1.stack(dataset2)

    dataset1.models = [sky_model]
    npred_b = dataset1.npred()

    assert_allclose(npred_b.data.sum(), 1459.985035, 1e-5)
    assert_allclose(dataset1.npred_background().data.sum(), 1360.00, 1e-5)
    assert_allclose(dataset1.counts.data.sum(), 9000, 1e-5)
    assert_allclose(dataset1.mask_safe.data.sum(), 4600)
    assert_allclose(dataset1.exposure.data.sum(), 1.6e11)

    assert_allclose(dataset1.meta_table["OBS_ID"][0], [0, 1])
Example #12
0
    def create(
        cls,
        e_reco,
        e_true=None,
        region=None,
        reference_time="2000-01-01",
        name=None,
        meta_table=None,
    ):
        """Creates empty spectrum dataset.

        Empty containers are created with the correct geometry.
        counts, background and aeff are zero and edisp is diagonal.

        The safe_mask is set to False in every bin.

        Parameters
        ----------
        e_reco : `~gammapy.maps.MapAxis`
            counts energy axis. Its name must be "energy".
        e_true : `~gammapy.maps.MapAxis`
            effective area table energy axis. Its name must be "energy-true".
            If not set use reco energy values. Default : None
        region : `~regions.SkyRegion`
            Region to define the dataset for.
        reference_time : `~astropy.time.Time`
            reference time of the dataset, Default is "2000-01-01"
        meta_table : `~astropy.table.Table`
            Table listing informations on observations used to create the dataset.
            One line per observation for stacked datasets.
        """
        if e_true is None:
            e_true = e_reco.copy(name="energy_true")

        if region is None:
            region = "icrs;circle(0, 0, 1)"

        name = make_name(name)
        counts = RegionNDMap.create(region=region, axes=[e_reco])
        background = RegionNDMap.create(region=region, axes=[e_reco])
        models = Models([
            BackgroundModel(background,
                            name=name + "-bkg",
                            datasets_names=[name])
        ])
        exposure = RegionNDMap.create(region=region,
                                      axes=[e_true],
                                      unit="cm2 s")
        edisp = EDispKernelMap.from_diagonal_response(e_reco,
                                                      e_true,
                                                      geom=counts.geom)
        mask_safe = RegionNDMap.from_geom(counts.geom, dtype="bool")
        gti = GTI.create(u.Quantity([], "s"), u.Quantity([], "s"),
                         reference_time)

        return SpectrumDataset(
            counts=counts,
            exposure=exposure,
            edisp=edisp,
            mask_safe=mask_safe,
            gti=gti,
            models=models,
            name=name,
        )
Example #13
0
    def setup(self):
        etrue = np.logspace(-1, 1, 10) * u.TeV
        self.e_true = MapAxis.from_edges(etrue, name="energy_true")
        ereco = np.logspace(-1, 1, 5) * u.TeV
        elo = ereco[:-1]
        ehi = ereco[1:]
        self.e_reco = MapAxis.from_edges(ereco, name="energy")
        self.aeff = EffectiveAreaTable(etrue[:-1], etrue[1:],
                                       np.ones(9) * u.cm**2)

        start = u.Quantity([0], "s")
        stop = u.Quantity([1000], "s")
        time_ref = Time("2010-01-01 00:00:00.0")
        self.gti = GTI.create(start, stop, time_ref)
        self.livetime = self.gti.time_sum

        self.on_region = make_region("icrs;circle(0.,1.,0.1)")
        off_region = make_region("icrs;box(0.,1.,0.1, 0.2,30)")
        self.off_region = off_region.union(
            make_region("icrs;box(-1.,-1.,0.1, 0.2,150)"))
        self.wcs = WcsGeom.create(npix=300, binsz=0.01, frame="icrs").wcs

        data = np.ones(elo.shape)
        data[-1] = 0  # to test stats calculation with empty bins

        axis = MapAxis.from_edges(ereco, name="energy", interp="log")
        self.on_counts = RegionNDMap.create(region=self.on_region,
                                            wcs=self.wcs,
                                            axes=[axis])
        self.on_counts.data += 1
        self.on_counts.data[-1] = 0

        self.off_counts = RegionNDMap.create(region=self.off_region,
                                             wcs=self.wcs,
                                             axes=[axis])
        self.off_counts.data += 10

        acceptance = RegionNDMap.from_geom(self.on_counts.geom)
        acceptance.data += 1

        data = np.ones(elo.shape)
        data[-1] = 0

        acceptance_off = RegionNDMap.from_geom(self.off_counts.geom)
        acceptance_off.data += 10

        self.edisp = EDispKernelMap.from_diagonal_response(
            self.e_reco, self.aeff.data.axis("energy_true"),
            self.on_counts.geom)

        self.dataset = SpectrumDatasetOnOff(
            counts=self.on_counts,
            counts_off=self.off_counts,
            aeff=self.aeff,
            edisp=self.edisp,
            livetime=self.livetime,
            acceptance=acceptance,
            acceptance_off=acceptance_off,
            name="test",
            gti=self.gti,
        )
Example #14
0
    def create(
        cls,
        e_reco,
        e_true=None,
        region=None,
        reference_time="2000-01-01",
        name=None,
        meta_table=None,
    ):
        """Creates empty spectrum dataset.

        Empty containers are created with the correct geometry.
        counts, background and aeff are zero and edisp is diagonal.

        The safe_mask is set to False in every bin.

        Parameters
        ----------
        e_reco : `~gammapy.maps.MapAxis`
            counts energy axis. Its name must be "energy".
        e_true : `~gammapy.maps.MapAxis`
            effective area table energy axis. Its name must be "energy-true".
            If not set use reco energy values. Default : None
        region : `~regions.SkyRegion`
            Region to define the dataset for.
        reference_time : `~astropy.time.Time`
            reference time of the dataset, Default is "2000-01-01"
        meta_table : `~astropy.table.Table`
            Table listing informations on observations used to create the dataset.
            One line per observation for stacked datasets.
        """
        if e_true is None:
            e_true = e_reco.copy(name="energy_true")

        if region is None:
            region = "icrs;circle(0, 0, 1)"

        counts = RegionNDMap.create(region=region, axes=[e_reco])
        background = RegionNDMap.create(region=region, axes=[e_reco])

        aeff = EffectiveAreaTable(
            e_true.edges[:-1],
            e_true.edges[1:],
            np.zeros(e_true.edges[:-1].shape) * u.m**2,
        )
        edisp = EDispKernelMap.from_diagonal_response(e_reco, e_true,
                                                      counts.geom)
        mask_safe = RegionNDMap.from_geom(counts.geom, dtype="bool")
        gti = GTI.create(u.Quantity([], "s"), u.Quantity([], "s"),
                         reference_time)
        livetime = gti.time_sum

        return SpectrumDataset(
            counts=counts,
            aeff=aeff,
            edisp=edisp,
            mask_safe=mask_safe,
            background=background,
            livetime=livetime,
            gti=gti,
            name=name,
        )
Example #15
0
    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"

        # psf
        psf_map = PSFMap.read(
            "$GAMMAPY_DATA/fermi_3fhl/fermi_3fhl_psf_gc.fits.gz",
            format="gtpsf")
        # reduce size of the PSF
        axis = psf_map.psf_map.geom.axes["rad"].center.to_value(u.deg)
        indmax = np.argmin(np.abs(self.psf_margin - axis))
        psf_map = psf_map.slice_by_idx(slices={"rad": slice(0, indmax)})

        # 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)

        # Energy Dispersion
        edisp = EDispKernelMap.from_diagonal_response(
            energy_axis_true=axis, energy_axis=self.energy_axis)

        # 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)
        mask_safe_fermi = WcsNDMap(counts.geom, np.ones(mask.shape,
                                                        dtype=bool))

        log.info(f"ROI {kr}: pre-computing diffuse")

        # IEM
        eval_iem = MapEvaluator(
            model=model_iem,
            exposure=exposure,
            psf=psf_map.get_psf_kernel(geom),
            edisp=edisp.get_edisp_kernel(),
        )
        bkg_iem = eval_iem.compute_npred()

        # ISO
        eval_iso = MapEvaluator(model=self.model_iso,
                                exposure=exposure,
                                edisp=edisp.get_edisp_kernel())
        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

        # Dataset
        dataset = MapDataset(
            counts=counts,
            exposure=exposure,
            background=background_total,
            psf=psf_map,
            edisp=edisp,
            mask_fit=mask_fermi,
            mask_safe=mask_safe_fermi,
            name=dataset_name,
        )

        background_model = FoVBackgroundModel(dataset_name=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(FHL3_roi + [background_model])
        dataset.models = model_total

        cat_stat = dataset.stat_sum()
        datasets = Datasets([dataset])

        log.info(f"ROI {kr}: running fit")
        fit = Fit(**self.fit_opts)
        results = fit.run(datasets=datasets)
        print("ROI_num", str(kr), "\n", results)
        fit_stat = datasets.stat_sum()

        if results.message != "Optimization failed.":
            filedata = Path(self.resdir) / f"3FHL_ROI_num{kr}_datasets.yaml"
            filemodel = Path(self.resdir) / f"3FHL_ROI_num{kr}_models.yaml"
            datasets.write(filedata, filemodel, 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):
                    print(model.name)
                    flux_points = FluxPointsEstimator(
                        energy_edges=self.El_flux,
                        source=model.name,
                        n_sigma_ul=2,
                        selection_optional=["ul"],
                    ).run(datasets=datasets)
                    flux_points.meta["sqrt_ts_threshold_ul"] = 1

                    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)