Ejemplo n.º 1
0
    def make_mask_energy_aeff_max(self, dataset):
        """Make safe energy mask from effective area maximum value.

        Parameters
        ----------
        dataset : `~gammapy.datasets.MapDataset` or `~gammapy.datasets.SpectrumDataset`
            Dataset to compute mask for.

        Returns
        -------
        mask_safe : `~numpy.ndarray`
            Safe data range mask.
        """
        geom = dataset._geom

        if self.position is None:
            position = PointSkyRegion(dataset.counts.geom.center_skydir)
        else:
            position = PointSkyRegion(self.position)

        exposure = dataset.exposure.get_spectrum(position)

        energy = exposure.geom.axes["energy_true"]
        aeff = EffectiveAreaTable(
            energy_axis_true=energy,
            data=(exposure.quantity / dataset.gti.time_sum).squeeze(),
        )
        aeff_thres = (self.aeff_percent / 100) * aeff.max_area
        e_min = aeff.find_energy(aeff_thres)
        return geom.energy_mask(emin=e_min)
Ejemplo n.º 2
0
    def make_mask_energy_aeff_max(self, dataset):
        """Make safe energy mask from effective area maximum value.

        Parameters
        ----------
        dataset : `~gammapy.datasets.MapDataset` or `~gammapy.datasets.SpectrumDataset`
            Dataset to compute mask for.

        Returns
        -------
        mask_safe : `~numpy.ndarray`
            Safe data range mask.
        """
        geom = dataset._geom

        if isinstance(dataset, MapDataset):
            position = self.position
            if position is None:
                position = dataset.counts.geom.center_skydir
            exposure = dataset.exposure
            energy = exposure.geom.get_axis_by_name("energy_true")
            coord = MapCoord.create({"skycoord": position, "energy_true": energy.center})
            exposure_1d = exposure.interp_by_coord(coord)
            aeff = EffectiveAreaTable(
                energy_lo=energy.edges[:-1],
                energy_hi=energy.edges[1:],
                data=exposure_1d,
            )
        else:
            aeff = dataset.aeff

        aeff_thres = (self.aeff_percent / 100) * aeff.max_area
        e_min = aeff.find_energy(aeff_thres)
        return geom.energy_mask(emin=e_min)
Ejemplo n.º 3
0
    def test_spectrum_dataset_stack_nondiagonal_no_bkg(self):
        aeff = EffectiveAreaTable.from_parametrization(self.src.energy.edges,
                                                       "HESS")
        edisp1 = EDispKernel.from_gauss(self.src.energy.edges,
                                        self.src.energy.edges, 0.1, 0.0)
        livetime = self.livetime
        dataset1 = SpectrumDataset(counts=None,
                                   livetime=livetime,
                                   aeff=aeff,
                                   edisp=edisp1,
                                   background=None)

        livetime2 = livetime
        aeff2 = EffectiveAreaTable(self.src.energy.edges[:-1],
                                   self.src.energy.edges[1:], aeff.data.data)
        edisp2 = EDispKernel.from_gauss(self.src.energy.edges,
                                        self.src.energy.edges, 0.2, 0.0)
        dataset2 = SpectrumDataset(
            counts=self.src.copy(),
            livetime=livetime2,
            aeff=aeff2,
            edisp=edisp2,
            background=None,
        )
        dataset1.stack(dataset2)

        assert dataset1.counts is None
        assert dataset1.background is None
        assert dataset1.livetime == 2 * self.livetime
        assert_allclose(dataset1.aeff.data.data.to_value("m2"),
                        aeff.data.data.to_value("m2"))
        assert_allclose(dataset1.edisp.get_bias(1 * u.TeV), 0.0, atol=1.2e-3)
        assert_allclose(dataset1.edisp.get_resolution(1 * u.TeV),
                        0.1581,
                        atol=1e-2)
Ejemplo n.º 4
0
def test_spectrum_dataset_stack_nondiagonal_no_bkg(spectrum_dataset):
    energy = spectrum_dataset.counts.geom.axes[0].edges

    aeff = EffectiveAreaTable.from_parametrization(energy, "HESS")
    edisp1 = EDispKernel.from_gauss(energy, energy, 0.1, 0)
    livetime = 100 * u.s
    spectrum_dataset1 = SpectrumDataset(
        counts=spectrum_dataset.counts.copy(),
        livetime=livetime, aeff=aeff, edisp=edisp1,
    )

    livetime2 = livetime
    aeff2 = EffectiveAreaTable(
        energy[:-1], energy[1:], aeff.data.data
    )
    edisp2 = EDispKernel.from_gauss(energy, energy, 0.2, 0.0)
    spectrum_dataset2 = SpectrumDataset(
        counts=spectrum_dataset.counts.copy(),
        livetime=livetime2,
        aeff=aeff2,
        edisp=edisp2,
    )
    spectrum_dataset1.stack(spectrum_dataset2)

    assert spectrum_dataset1.background is None
    assert spectrum_dataset1.livetime == 2 * livetime
    assert_allclose(
        spectrum_dataset1.aeff.data.data.to_value("m2"), aeff.data.data.to_value("m2")
    )
    assert_allclose(spectrum_dataset1.edisp.get_bias(1 * u.TeV), 0.0, atol=1.2e-3)
    assert_allclose(spectrum_dataset1.edisp.get_resolution(1 * u.TeV), 0.1581, atol=1e-2)
Ejemplo n.º 5
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")
    edisp = EDispKernelMap.from_diagonal_response(energy,
                                                  energy_true,
                                                  geom=geom.to_image())
    livetime = 100 * u.s
    background = spectrum_dataset.background
    spectrum_dataset1 = SpectrumDataset(
        counts=spectrum_dataset.counts.copy(),
        livetime=livetime,
        aeff=aeff,
        edisp=edisp.copy(),
        background=background.copy(),
    )

    livetime2 = 0.5 * livetime
    aeff2 = EffectiveAreaTable(energy.edges[:-1], energy.edges[1:],
                               2 * aeff.data.data)
    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)

    spectrum_dataset2 = SpectrumDataset(
        counts=spectrum_dataset.counts.copy(),
        livetime=livetime2,
        aeff=aeff2,
        edisp=edisp,
        background=bkg2,
        mask_safe=safe_mask2,
    )
    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 spectrum_dataset1.livetime == 1.5 * livetime
    assert_allclose(spectrum_dataset1.background.data[1:],
                    3 * background.data[1:])
    assert_allclose(spectrum_dataset1.background.data[0], background.data[0])
    assert_allclose(
        spectrum_dataset1.aeff.data.data.to_value("m2"),
        4.0 / 3 * aeff.data.data.to_value("m2"),
    )
    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])
Ejemplo n.º 6
0
def test_spectrum_dataset_stack_diagonal_safe_mask(spectrum_dataset):
    geom = spectrum_dataset.counts.geom

    energy = np.logspace(-1, 1, 31) * u.TeV
    aeff = EffectiveAreaTable.from_parametrization(energy, "HESS")
    edisp = EDispKernel.from_diagonal_response(energy, energy)
    livetime = 100 * u.s
    background = spectrum_dataset.background
    spectrum_dataset1 = SpectrumDataset(
        counts=spectrum_dataset.counts.copy(),
        livetime=livetime,
        aeff=aeff,
        edisp=edisp,
        background=background.copy(),
    )

    livetime2 = 0.5 * livetime
    aeff2 = EffectiveAreaTable(energy[:-1], energy[1:], 2 * aeff.data.data)
    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)

    spectrum_dataset2 = SpectrumDataset(
        counts=spectrum_dataset.counts.copy(),
        livetime=livetime2,
        aeff=aeff2,
        edisp=edisp,
        background=bkg2,
        mask_safe=safe_mask2,
    )
    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 spectrum_dataset1.livetime == 1.5 * livetime
    assert_allclose(spectrum_dataset1.background.data[1:],
                    3 * background.data[1:])
    assert_allclose(spectrum_dataset1.background.data[0], background.data[0])
    assert_allclose(
        spectrum_dataset1.aeff.data.data.to_value("m2"),
        4.0 / 3 * aeff.data.data.to_value("m2"),
    )
    assert_allclose(spectrum_dataset1.edisp.pdf_matrix[1:],
                    edisp.pdf_matrix[1:])
    assert_allclose(spectrum_dataset1.edisp.pdf_matrix[0],
                    0.5 * edisp.pdf_matrix[0])
Ejemplo n.º 7
0
def spectrum_dataset():
    energy = np.logspace(-1, 1, 31) * u.TeV
    livetime = 100 * u.s

    pwl = PowerLawSpectralModel(
        index=2.1, amplitude="1e5 cm-2 s-1 TeV-1", reference="0.1 TeV",
    )

    temp_mod = ConstantTemporalModel()

    model = SkyModel(spectral_model=pwl, temporal_model=temp_mod, name="test-source")
    aeff = EffectiveAreaTable.from_constant(energy, "1 cm2")

    axis = MapAxis.from_edges(energy, interp="log", name="energy")
    background = RegionNDMap.create(region="icrs;circle(0, 0, 0.1)", axes=[axis])

    bkg_rate = np.ones(30) / u.s
    background.quantity = bkg_rate * livetime

    start = [1, 3, 5] * u.day
    stop = [2, 3.5, 6] * u.day
    t_ref = Time(55555, format="mjd")
    gti = GTI.create(start, stop, reference_time=t_ref)

    dataset = SpectrumDataset(
        models=model,
        aeff=aeff,
        livetime=livetime,
        background=background,
        name="test",
        gti=gti,
    )
    dataset.fake(random_state=23)
    return dataset
Ejemplo n.º 8
0
    def setup(self):
        self.nbins = 30
        binning = np.logspace(-1, 1, self.nbins + 1) * u.TeV

        self.source_model = PowerLawSpectralModel(index=2.1,
                                                  amplitude=1e5 *
                                                  u.Unit("cm-2 s-1 TeV-1"),
                                                  reference=0.1 * u.TeV)

        self.livetime = 100 * u.s
        aeff = EffectiveAreaTable.from_constant(binning, "1 cm2")

        bkg_rate = np.ones(self.nbins) / u.s
        bkg_expected = (bkg_rate * self.livetime).to_value("")

        self.bkg = CountsSpectrum(energy_lo=binning[:-1],
                                  energy_hi=binning[1:],
                                  data=bkg_expected)

        random_state = get_random_state(23)
        flux = self.source_model.integral(binning[:-1], binning[1:])
        self.npred = (flux * aeff.data.data[0] * self.livetime).to_value("")
        self.npred += bkg_expected
        source_counts = random_state.poisson(self.npred)

        self.src = CountsSpectrum(energy_lo=binning[:-1],
                                  energy_hi=binning[1:],
                                  data=source_counts)
        self.dataset = SpectrumDataset(
            model=self.source_model,
            counts=self.src,
            aeff=aeff,
            livetime=self.livetime,
            background=self.bkg,
        )
Ejemplo n.º 9
0
def simulate_spectrum_dataset(model, random_state=0):
    edges = np.logspace(-0.5, 1.5, 21) * u.TeV
    energy_axis = MapAxis.from_edges(edges, interp="log", name="energy")

    aeff = EffectiveAreaTable.from_parametrization(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
    )

    dataset = SpectrumDatasetOnOff(
        aeff=aeff, livetime=100 * u.h, acceptance=acceptance, acceptance_off=5, edisp=edisp
    )
    dataset.models = bkg_model
    bkg_npred = dataset.npred_sig()

    dataset.models = model
    dataset.fake(random_state=random_state, background_model=bkg_npred)
    return dataset
Ejemplo n.º 10
0
    def setup(self):
        self.nbins = 30
        energy = np.logspace(-1, 1, self.nbins + 1) * u.TeV
        self.source_model = SkyModel(
            spectral_model=PowerLawSpectralModel(
                index=2, amplitude=1e5 * u.Unit("cm-2 s-1 TeV-1"), reference=0.1 * u.TeV
            )
        )
        bkg_model = PowerLawSpectralModel(
            index=3, amplitude=1e4 * u.Unit("cm-2 s-1 TeV-1"), reference=0.1 * u.TeV
        )

        self.alpha = 0.1
        random_state = get_random_state(23)
        npred = self.source_model.spectral_model.integral(
            energy[:-1], energy[1:]
        ).value
        source_counts = random_state.poisson(npred)

        axis = MapAxis.from_edges(energy, name="energy", interp="log")
        geom = RegionGeom(region=None, axes=[axis])

        self.src = RegionNDMap.from_geom(geom=geom, data=source_counts)

        self.src.livetime = 1 * u.s
        self.aeff = EffectiveAreaTable.from_constant(energy, "1 cm2")

        npred_bkg = bkg_model.integral(energy[:-1], energy[1:]).value

        bkg_counts = random_state.poisson(npred_bkg)
        off_counts = random_state.poisson(npred_bkg * 1.0 / self.alpha)
        self.bkg = RegionNDMap.from_geom(geom=geom, data=bkg_counts)
        self.off = RegionNDMap.from_geom(geom=geom, data=off_counts)
Ejemplo n.º 11
0
    def test(aeff):
        assert aeff.data.axes["energy_true"].nbin == 96
        assert aeff.data.axes["offset"].nbin == 6
        assert aeff.data.data.shape == (96, 6)

        assert aeff.data.axes["energy_true"].unit == "TeV"
        assert aeff.data.axes["offset"].unit == "deg"
        assert aeff.data.data.unit == "m2"

        assert_quantity_allclose(aeff.high_threshold, 100 * u.TeV, rtol=1e-3)
        assert_quantity_allclose(aeff.low_threshold, 0.870964 * u.TeV, rtol=1e-3)

        test_val = aeff.data.evaluate(energy_true="14 TeV", offset="0.2 deg")
        assert_allclose(test_val.value, 683177.5, rtol=1e-3)

        # Test ARF export
        offset = 0.236 * u.deg
        e_axis = np.logspace(0, 1, 20) * u.TeV
        effareafrom2d = aeff.to_effective_area_table(offset, e_axis)

        energy = np.sqrt(e_axis[:-1] * e_axis[1:])
        area = aeff.data.evaluate(energy_true=energy, offset=offset)

        energy_axis_true = MapAxis.from_energy_edges(e_axis, name="energy_true")
        effarea1d = EffectiveAreaTable(energy_axis_true=energy_axis_true, data=area)

        actual = effareafrom2d.data.evaluate(energy_true="2.34 TeV")
        desired = effarea1d.data.evaluate(energy_true="2.34 TeV")
        assert_equal(actual, desired)

        # Test ARF export #2
        offset = 1.2 * u.deg
        actual = aeff.to_effective_area_table(offset=offset).data.data
        desired = aeff.data.evaluate(offset=offset)
        assert_allclose(actual.value, desired.value.squeeze(), rtol=1e-9)
Ejemplo n.º 12
0
def sens():
    etrue = np.logspace(0, 1, 21) * u.TeV
    elo = etrue[:-1]
    ehi = etrue[1:]
    area = np.zeros(20) + 1e6 * u.m**2

    arf = EffectiveAreaTable(energy_lo=elo, energy_hi=ehi, data=area)

    ereco = np.logspace(0, 1, 5) * u.TeV
    rmf = EnergyDispersion.from_diagonal_response(etrue, ereco)

    bkg_array = np.ones(4)
    bkg_array[-1] = 1e-3
    bkg = CountsSpectrum(energy_lo=ereco[:-1],
                         energy_hi=ereco[1:],
                         data=bkg_array,
                         unit="s-1")

    sens = SensitivityEstimator(arf=arf,
                                rmf=rmf,
                                bkg=bkg,
                                livetime=1 * u.h,
                                index=2,
                                gamma_min=20,
                                alpha=0.2)
    sens.run()
    return sens
Ejemplo n.º 13
0
    def setup(self):
        self.nbins = 30
        binning = np.logspace(-1, 1, self.nbins + 1) * u.TeV
        self.source_model = PowerLawSpectralModel(index=2,
                                                  amplitude=1e5 *
                                                  u.Unit("cm-2 s-1 TeV-1"),
                                                  reference=0.1 * u.TeV)
        bkg_model = PowerLawSpectralModel(index=3,
                                          amplitude=1e4 *
                                          u.Unit("cm-2 s-1 TeV-1"),
                                          reference=0.1 * u.TeV)

        self.alpha = 0.1
        random_state = get_random_state(23)
        npred = self.source_model.integral(binning[:-1], binning[1:]).value
        source_counts = random_state.poisson(npred)
        self.src = CountsSpectrum(energy_lo=binning[:-1],
                                  energy_hi=binning[1:],
                                  data=source_counts)

        self.src.livetime = 1 * u.s
        self.aeff = EffectiveAreaTable.from_constant(binning, "1 cm2")

        npred_bkg = bkg_model.integral(binning[:-1], binning[1:]).value

        bkg_counts = random_state.poisson(npred_bkg)
        off_counts = random_state.poisson(npred_bkg * 1.0 / self.alpha)
        self.bkg = CountsSpectrum(energy_lo=binning[:-1],
                                  energy_hi=binning[1:],
                                  data=bkg_counts)
        self.off = CountsSpectrum(energy_lo=binning[:-1],
                                  energy_hi=binning[1:],
                                  data=off_counts)
Ejemplo n.º 14
0
    def setup(self):
        etrue = np.logspace(-1, 1, 10) * u.TeV
        self.e_true = etrue
        ereco = np.logspace(-1, 1, 5) * u.TeV
        elo = ereco[:-1]
        ehi = ereco[1:]
        self.e_reco = ereco
        self.aeff = EffectiveAreaTable(etrue[:-1], etrue[1:],
                                       np.ones(9) * u.cm**2)
        self.edisp = EDispKernel.from_diagonal_response(etrue, ereco)

        data = np.ones(elo.shape)
        data[-1] = 0  # to test stats calculation with empty bins
        self.on_counts = CountsSpectrum(elo, ehi, data)
        self.off_counts = CountsSpectrum(elo, ehi, np.ones(elo.shape) * 10)

        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.dataset = SpectrumDatasetOnOff(
            counts=self.on_counts,
            counts_off=self.off_counts,
            aeff=self.aeff,
            edisp=self.edisp,
            livetime=self.livetime,
            acceptance=np.ones(elo.shape),
            acceptance_off=np.ones(elo.shape) * 10,
            name="test",
            gti=self.gti,
        )
Ejemplo n.º 15
0
def extract_aeff(exposure, target_position, energy):
    energy_log_ctr = np.sqrt(energy[1:] * energy[:-1])
    lon = target_position.galactic.l
    lat = target_position.galactic.b
    expo_values = exposure.get_by_coord((lon.value, lat.value, energy_log_ctr.value))

    table = Table(
        [energy[:-1], energy[1:], expo_values],
        names=("ENERG_LO", "ENERG_HI", "SPECRESP"),
        dtype=("float64", "float64", "float64"),
        meta={"name": "Fermi-LAT exposure"},
    )

    table["ENERG_LO"].unit = str(energy.unit)
    table["ENERG_HI"].unit = str(energy.unit)
    table["SPECRESP"].unit = "cm2"

    table.meta["EXTNAME"] = "SPECRESP"
    table.meta["TELESCOP"] = "Fermi"
    table.meta["INSTRUME"] = "LAT"
    table.meta["EXPOSURE"] = "1"
    table.meta["FILTER"] = ""
    table.meta["HDUCLASS"] = "OGIP"
    table.meta["HDUCLAS1"] = "RESPONSE"
    table.meta["HDUCLAS2"] = "SPECRESP"
    table.meta["HDUVERS"] = "1.1.0"

    return EffectiveAreaTable.from_table(table)
Ejemplo n.º 16
0
    def setup(self):
        etrue = np.logspace(-1, 1, 10) * u.TeV
        self.e_true = etrue
        ereco = np.logspace(-1, 1, 5) * u.TeV
        elo = ereco[:-1]
        ehi = ereco[1:]

        self.aeff = EffectiveAreaTable(etrue[:-1], etrue[1:],
                                       np.ones(9) * u.cm**2)
        self.edisp = EnergyDispersion.from_diagonal_response(etrue, ereco)

        data = np.ones(elo.shape)
        data[-1] = 0  # to test stats calculation with empty bins
        self.on_counts = CountsSpectrum(elo, ehi, data)
        self.off_counts = CountsSpectrum(elo, ehi, np.ones(elo.shape) * 10)

        self.livetime = 1000 * u.s

        self.dataset = SpectrumDatasetOnOff(
            counts=self.on_counts,
            counts_off=self.off_counts,
            aeff=self.aeff,
            edisp=self.edisp,
            livetime=self.livetime,
            acceptance=np.ones(elo.shape),
            acceptance_off=np.ones(elo.shape) * 10,
            obs_id="test",
        )
Ejemplo n.º 17
0
def test_compute_thresholds_from_parametrization():
    energy = np.logspace(-2, 2.0, 100) * u.TeV
    aeff = EffectiveAreaTable.from_parametrization(energy=energy)
    edisp = EnergyDispersion.from_gauss(e_true=energy,
                                        e_reco=energy,
                                        sigma=0.2,
                                        bias=0)

    thresh_lo, thresh_hi = compute_energy_thresholds(
        aeff=aeff,
        edisp=edisp,
        method_lo="area_max",
        method_hi="area_max",
        area_percent_lo=10,
        area_percent_hi=90,
    )

    assert_allclose(thresh_lo.to("TeV").value, 0.18557, rtol=1e-4)
    assert_allclose(thresh_hi.to("TeV").value, 43.818, rtol=1e-4)

    thresh_lo, thresh_hi = compute_energy_thresholds(aeff=aeff,
                                                     edisp=edisp,
                                                     method_hi="area_max",
                                                     area_percent_hi=70)

    assert_allclose(thresh_hi.to("TeV").value, 100.0, rtol=1e-4)
Ejemplo n.º 18
0
def spectrum_dataset():
    energy = np.logspace(-1, 1, 31) * u.TeV
    livetime = 100 * u.s

    pwl = PowerLawSpectralModel(
            index=2.1,
            amplitude="1e5 cm-2 s-1 TeV-1",
            reference="0.1 TeV",
        )

    model = SkyModel(spectral_model=pwl, name="test-source")
    aeff = EffectiveAreaTable.from_constant(energy, "1 cm2")

    axis = MapAxis.from_edges(energy, interp="log", name="energy")
    background = RegionNDMap.create(region="icrs;circle(0, 0, 0.1)", axes=[axis])

    bkg_rate = np.ones(30) / u.s
    background.quantity = bkg_rate * livetime

    dataset = SpectrumDataset(
        models=model,
        aeff=aeff,
        livetime=livetime,
        background=background,
        name="test",
    )
    dataset.fake(random_state=23)
    return dataset
Ejemplo n.º 19
0
def make_observation_list():
    """obs with dummy IRF"""
    nbin = 3
    energy = np.logspace(-1, 1, nbin + 1) * u.TeV
    livetime = 2 * u.h
    data_on = np.arange(nbin)
    dataoff_1 = np.ones(3)
    dataoff_2 = np.ones(3) * 3
    dataoff_1[1] = 0
    dataoff_2[1] = 0
    on_vector = CountsSpectrum(energy_lo=energy[:-1],
                               energy_hi=energy[1:],
                               data=data_on)
    off_vector1 = CountsSpectrum(energy_lo=energy[:-1],
                                 energy_hi=energy[1:],
                                 data=dataoff_1)
    off_vector2 = CountsSpectrum(energy_lo=energy[:-1],
                                 energy_hi=energy[1:],
                                 data=dataoff_2)
    aeff = EffectiveAreaTable.from_constant(energy, "1 cm2")
    edisp = EDispKernel.from_gauss(e_true=energy,
                                   e_reco=energy,
                                   sigma=0.2,
                                   bias=0)

    time_ref = Time("2010-01-01")
    gti1 = make_gti({
        "START": [5, 6, 1, 2],
        "STOP": [8, 7, 3, 4]
    },
                    time_ref=time_ref)
    gti2 = make_gti({"START": [14], "STOP": [15]}, time_ref=time_ref)

    obs1 = SpectrumDatasetOnOff(
        counts=on_vector,
        counts_off=off_vector1,
        aeff=aeff,
        edisp=edisp,
        livetime=livetime,
        mask_safe=np.ones(on_vector.energy.nbin, dtype=bool),
        acceptance=1,
        acceptance_off=2,
        name="1",
        gti=gti1,
    )
    obs2 = SpectrumDatasetOnOff(
        counts=on_vector,
        counts_off=off_vector2,
        aeff=aeff,
        edisp=edisp,
        livetime=livetime,
        mask_safe=np.ones(on_vector.energy.nbin, dtype=bool),
        acceptance=1,
        acceptance_off=4,
        name="2",
        gti=gti2,
    )

    obs_list = [obs1, obs2]
    return obs_list
Ejemplo n.º 20
0
    def test_spectrum_dataset_stack_diagonal_safe_mask(self):
        aeff = EffectiveAreaTable.from_parametrization(self.src.energy.edges,
                                                       "HESS")
        edisp = EDispKernel.from_diagonal_response(self.src.energy.edges,
                                                   self.src.energy.edges)
        livetime = self.livetime
        dataset1 = SpectrumDataset(
            counts=self.src.copy(),
            livetime=livetime,
            aeff=aeff,
            edisp=edisp,
            background=self.bkg.copy(),
        )

        livetime2 = 0.5 * livetime
        aeff2 = EffectiveAreaTable(self.src.energy.edges[:-1],
                                   self.src.energy.edges[1:],
                                   2 * aeff.data.data)
        bkg2 = CountsSpectrum(
            self.src.energy.edges[:-1],
            self.src.energy.edges[1:],
            data=2 * self.bkg.data,
        )
        safe_mask2 = np.ones_like(self.src.data, bool)
        safe_mask2[0] = False
        dataset2 = SpectrumDataset(
            counts=self.src.copy(),
            livetime=livetime2,
            aeff=aeff2,
            edisp=edisp,
            background=bkg2,
            mask_safe=safe_mask2,
        )
        dataset1.stack(dataset2)

        assert_allclose(dataset1.counts.data[1:], self.src.data[1:] * 2)
        assert_allclose(dataset1.counts.data[0], self.src.data[0])
        assert dataset1.livetime == 1.5 * self.livetime
        assert_allclose(dataset1.background.data[1:], 3 * self.bkg.data[1:])
        assert_allclose(dataset1.background.data[0], self.bkg.data[0])
        assert_allclose(
            dataset1.aeff.data.data.to_value("m2"),
            4.0 / 3 * aeff.data.data.to_value("m2"),
        )
        assert_allclose(dataset1.edisp.pdf_matrix[1:], edisp.pdf_matrix[1:])
        assert_allclose(dataset1.edisp.pdf_matrix[0],
                        0.5 * edisp.pdf_matrix[0])
Ejemplo n.º 21
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 = EDispKernel.from_diagonal_response(e_true.edges, e_reco.edges)
        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,
        )
Ejemplo n.º 22
0
    def test_from_parametrization():
        # Log center of this is 100 GeV
        energy = [80, 125] * u.GeV
        area_ref = 1.65469579e07 * u.cm ** 2

        area = EffectiveAreaTable.from_parametrization(energy, "HESS")

        assert_allclose(area.data.data, area_ref)
        assert area.data.data.unit == area_ref.unit

        # Log center of this is 0.1, 2 TeV
        energy = [0.08, 0.125, 32] * u.TeV
        area_ref = [1.65469579e07, 1.46451957e09] * u.cm * u.cm

        area = EffectiveAreaTable.from_parametrization(energy, "HESS")
        assert_allclose(area.data.data, area_ref)
        assert area.data.data.unit == area_ref.unit
Ejemplo n.º 23
0
def get_test_cases():
    e_true = Quantity(np.logspace(-1, 2, 120), "TeV")
    e_reco = Quantity(np.logspace(-1, 2, 100), "TeV")
    return [
        dict(model=PowerLawSpectralModel(amplitude="1e2 TeV-1"),
             e_true=e_true,
             npred=999),
        dict(
            model=PowerLaw2SpectralModel(amplitude="1",
                                         emin="0.1 TeV",
                                         emax="100 TeV"),
            e_true=e_true,
            npred=1,
        ),
        dict(
            model=PowerLawSpectralModel(amplitude="1e-11 TeV-1 cm-2 s-1"),
            aeff=EffectiveAreaTable.from_parametrization(e_true),
            livetime="10 h",
            npred=1448.05960,
        ),
        dict(
            model=PowerLawSpectralModel(reference="1 GeV",
                                        amplitude="1e-11 GeV-1 cm-2 s-1"),
            aeff=EffectiveAreaTable.from_parametrization(e_true),
            livetime="30 h",
            npred=4.34417881,
        ),
        dict(
            model=PowerLawSpectralModel(amplitude="1e-11 TeV-1 cm-2 s-1"),
            aeff=EffectiveAreaTable.from_parametrization(e_true),
            edisp=EnergyDispersion.from_gauss(e_reco=e_reco,
                                              e_true=e_true,
                                              bias=0,
                                              sigma=0.2),
            livetime="10 h",
            npred=1437.450076,
        ),
        dict(
            model=TemplateSpectralModel(
                energy=[0.1, 0.2, 0.3, 0.4] * u.TeV,
                values=[4.0, 3.0, 1.0, 0.1] * u.Unit("TeV-1"),
            ),
            e_true=[0.1, 0.2, 0.3, 0.4] * u.TeV,
            npred=0.554513062,
        ),
    ]
Ejemplo n.º 24
0
    def setup(self):
        etrue = np.logspace(-1, 1, 10) * u.TeV
        self.e_true = etrue
        ereco = np.logspace(-1, 1, 5) * u.TeV
        elo = ereco[:-1]
        ehi = ereco[1:]
        self.e_reco = ereco
        self.aeff = EffectiveAreaTable(etrue[:-1], etrue[1:], np.ones(9) * u.cm ** 2)
        self.edisp = EDispKernel.from_diagonal_response(etrue, ereco)

        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.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,
        )
Ejemplo n.º 25
0
def spectrum_dataset():
    e_true = np.logspace(0, 1, 21) * u.TeV
    e_reco = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=4)
    aeff = EffectiveAreaTable.from_constant(value=1e6 * u.m ** 2, energy=e_true)
    edisp = EDispKernel.from_diagonal_response(e_true, e_reco.edges)

    background = RegionNDMap.create(region="icrs;circle(0, 0, 0.1)", axes=[e_reco])
    background.data += 3600
    background.data[-1] *= 1e-3
    return SpectrumDataset(aeff=aeff, livetime="1h", edisp=edisp, background=background)
Ejemplo n.º 26
0
def test_spectrum_dataset_stack_nondiagonal_no_bkg(spectrum_dataset):
    energy = spectrum_dataset.counts.geom.axes["energy"]
    geom = spectrum_dataset.counts.geom.to_image()

    edisp1 = EDispKernelMap.from_gauss(
        energy_axis=energy,
        energy_axis_true=energy.copy(name="energy_true"),
        sigma=0.1,
        bias=0,
        geom=geom)
    edisp1.exposure_map.data += 1

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

    geom = spectrum_dataset.counts.geom
    counts = RegionNDMap.from_geom(geom=geom)

    gti = GTI.create(start=0 * u.s, stop=100 * u.s)
    spectrum_dataset1 = SpectrumDataset(
        counts=counts,
        exposure=aeff * gti.time_sum,
        edisp=edisp1,
        meta_table=Table({"OBS_ID": [0]}),
        gti=gti.copy(),
    )

    edisp2 = EDispKernelMap.from_gauss(
        energy_axis=energy,
        energy_axis_true=energy.copy(name="energy_true"),
        sigma=0.2,
        bias=0.0,
        geom=geom)
    edisp2.exposure_map.data += 1

    gti2 = GTI.create(start=100 * u.s, stop=200 * u.s)

    spectrum_dataset2 = SpectrumDataset(
        counts=counts,
        exposure=aeff * gti2.time_sum,
        edisp=edisp2,
        meta_table=Table({"OBS_ID": [1]}),
        gti=gti2,
    )
    spectrum_dataset1.stack(spectrum_dataset2)

    assert_allclose(spectrum_dataset1.meta_table["OBS_ID"][0], [0, 1])

    assert spectrum_dataset1.background_model is None
    assert_allclose(spectrum_dataset1.gti.time_sum.to_value("s"), 200)
    assert_allclose(spectrum_dataset1.exposure.quantity[2].to_value("m2 s"),
                    1573851.079861)
    kernel = edisp1.get_edisp_kernel()
    assert_allclose(kernel.get_bias(1 * u.TeV), 0.0, atol=1.2e-3)
    assert_allclose(kernel.get_resolution(1 * u.TeV), 0.1581, atol=1e-2)
Ejemplo n.º 27
0
    def test_EffectiveAreaTable(tmpdir, aeff):
        arf = aeff.to_effective_area_table(offset=0.3 * u.deg)

        assert_quantity_allclose(arf.data.evaluate(), arf.data.data)

        with mpl_plot_check():
            arf.plot()

        filename = str(tmpdir / "effarea_test.fits")
        arf.write(filename)
        arf2 = EffectiveAreaTable.read(filename)

        assert_quantity_allclose(arf.data.evaluate(), arf2.data.evaluate())

        test_aeff = 0.6 * arf.max_area
        node_above = np.where(arf.data.data > test_aeff)[0][0]
        energy = arf.data.axis("energy")
        ener_above = energy.center[node_above]
        ener_below = energy.center[node_above - 1]
        test_ener = arf.find_energy(test_aeff)

        assert ener_below < test_ener and test_ener < ener_above

        elo_threshold = arf.find_energy(0.1 * arf.max_area)
        assert elo_threshold.unit == "TeV"
        assert_allclose(elo_threshold.value, 0.554086, rtol=1e-3)

        ehi_threshold = arf.find_energy(0.9 * arf.max_area,
                                        emin=30 * u.TeV,
                                        emax=100 * u.TeV)
        assert ehi_threshold.unit == "TeV"
        assert_allclose(ehi_threshold.value, 53.347217, rtol=1e-3)

        # Test evaluation outside safe range
        data = [np.nan, np.nan, 0, 0, 1, 2, 3, np.nan, np.nan]
        energy = np.logspace(0, 10, 10) * u.TeV
        aeff = EffectiveAreaTable(data=data,
                                  energy_lo=energy[:-1],
                                  energy_hi=energy[1:])
        vals = aeff.evaluate_fill_nan()
        assert vals[1] == 0
        assert vals[-1] == 3
Ejemplo n.º 28
0
    def test_EffectiveAreaTable(tmp_path, aeff):
        arf = aeff.to_effective_area_table(offset=0.3 * u.deg)

        assert_quantity_allclose(arf.data.evaluate(), arf.data.data)

        with mpl_plot_check():
            arf.plot()

        arf.write(tmp_path / "tmp.fits")
        arf2 = EffectiveAreaTable.read(tmp_path / "tmp.fits")

        assert_quantity_allclose(arf.data.evaluate(), arf2.data.evaluate())

        test_aeff = 0.6 * arf.max_area
        node_above = np.where(arf.data.data > test_aeff)[0][0]
        energy = arf.data.axes["energy_true"]
        ener_above = energy.center[node_above]
        ener_below = energy.center[node_above - 1]
        test_ener = arf.find_energy(test_aeff)

        assert ener_below < test_ener and test_ener < ener_above

        elo_threshold = arf.find_energy(0.1 * arf.max_area)
        assert elo_threshold.unit == "TeV"
        assert_allclose(elo_threshold.value, 0.554086, rtol=1e-3)

        ehi_threshold = arf.find_energy(0.9 * arf.max_area,
                                        emin=30 * u.TeV,
                                        emax=100 * u.TeV)
        assert ehi_threshold.unit == "TeV"
        assert_allclose(ehi_threshold.value, 53.347217, rtol=1e-3)

        # Test evaluation outside safe range
        data = [np.nan, np.nan, 0, 0, 1, 2, 3, np.nan, np.nan]
        energy_axis_true = MapAxis.from_energy_bounds("1 TeV",
                                                      "10 TeV",
                                                      nbin=9,
                                                      name="energy_true")
        aeff = EffectiveAreaTable(data=data, energy_axis_true=energy_axis_true)
        vals = aeff.evaluate_fill_nan()
        assert vals[1] == 0
        assert vals[-1] == 3
Ejemplo n.º 29
0
def make_observation_list():
    """obs with dummy IRF"""
    nbin = 3
    energy = np.logspace(-1, 1, nbin + 1) * u.TeV
    livetime = 2 * u.h
    data_on = np.arange(nbin)
    dataoff_1 = np.ones(3)
    dataoff_2 = np.ones(3) * 3
    dataoff_1[1] = 0
    dataoff_2[1] = 0

    axis = MapAxis.from_edges(energy, name="energy", interp="log")
    geom = RegionGeom(region=None, axes=[axis])

    on_vector = RegionNDMap.from_geom(geom=geom, data=data_on)
    off_vector1 = RegionNDMap.from_geom(geom=geom, data=dataoff_1)
    off_vector2 = RegionNDMap.from_geom(geom=geom, data=dataoff_2)
    mask_safe = RegionNDMap.from_geom(geom, dtype=bool)
    mask_safe.data += True

    aeff = EffectiveAreaTable.from_constant(energy, "1 cm2")
    edisp = EDispKernel.from_gauss(e_true=energy, e_reco=energy, sigma=0.2, bias=0)

    time_ref = Time("2010-01-01")
    gti1 = make_gti({"START": [5, 6, 1, 2], "STOP": [8, 7, 3, 4]}, time_ref=time_ref)
    gti2 = make_gti({"START": [14], "STOP": [15]}, time_ref=time_ref)

    obs1 = SpectrumDatasetOnOff(
        counts=on_vector,
        counts_off=off_vector1,
        aeff=aeff,
        edisp=edisp,
        livetime=livetime,
        mask_safe=mask_safe,
        acceptance=1,
        acceptance_off=2,
        name="1",
        gti=gti1,
    )
    obs2 = SpectrumDatasetOnOff(
        counts=on_vector,
        counts_off=off_vector2,
        aeff=aeff,
        edisp=edisp,
        livetime=livetime,
        mask_safe=mask_safe,
        acceptance=1,
        acceptance_off=4,
        name="2",
        gti=gti2,
    )

    obs_list = [obs1, obs2]
    return obs_list
Ejemplo n.º 30
0
def test_compute_thresholds_from_parametrization():
    energy = np.logspace(-2, 2.0, 100) * u.TeV
    aeff = EffectiveAreaTable.from_parametrization(energy=energy)

    thresh_lo = aeff.find_energy(aeff=0.1 * aeff.max_area)
    e_max = aeff.energy.edges[-1]
    thresh_hi = aeff.find_energy(
        aeff=0.9 * aeff.max_area, energy_min=0.1 * e_max, energy_max=e_max
    )

    assert_allclose(thresh_lo.to("TeV").value, 0.18557, rtol=1e-4)
    assert_allclose(thresh_hi.to("TeV").value, 43.818, rtol=1e-4)
Ejemplo n.º 31
0
    def read(cls, filename, offset='0.5 deg'):
        """Read from a FITS file.

        Compute RMF at 0.5 deg offset on fly.

        Parameters
        ----------
        filename : `str`
            File containing the IRFs
        """
        filename = str(make_path(filename))

        with fits.open(filename, memmap=False) as hdulist:
            aeff = EffectiveAreaTable.from_hdulist(hdulist=hdulist)
            edisp = EnergyDispersion2D.read(filename, hdu='ENERGY DISPERSION')
            bkg = BgRateTable.from_hdulist(hdulist=hdulist)
            psf = Psf68Table.from_hdulist(hdulist=hdulist)
            sens = SensitivityTable.from_hdulist(hdulist=hdulist)

        # Create rmf with appropriate dimensions (e_reco->bkg, e_true->area)
        e_reco_min = bkg.energy.lo[0]
        e_reco_max = bkg.energy.hi[-1]
        e_reco_bin = bkg.energy.nbins
        e_reco_axis = EnergyBounds.equal_log_spacing(
            e_reco_min, e_reco_max, e_reco_bin, 'TeV',
        )

        e_true_min = aeff.energy.lo[0]
        e_true_max = aeff.energy.hi[-1]
        e_true_bin = aeff.energy.nbins
        e_true_axis = EnergyBounds.equal_log_spacing(
            e_true_min, e_true_max, e_true_bin, 'TeV',
        )

        rmf = edisp.to_energy_dispersion(
            offset=offset, e_reco=e_reco_axis, e_true=e_true_axis,
        )

        return cls(
            aeff=aeff,
            bkg=bkg,
            edisp=edisp,
            psf=psf,
            sens=sens,
            rmf=rmf
        )
Ejemplo n.º 32
0
def retrieve_arf_info(hdu_list, energies, plot=False):
    """
    Retrieve effective area information from arf fits file.

    Parameters
    ----------
    hdu_list : `~astropy.io.fits.HDUList`
            HDU list with ``SPECRESP``extension.
    plot : bool
        Make an effective area vs. energy plot.
    """
    from gammapy.irf import EffectiveAreaTable
    arf = EffectiveAreaTable.from_fits(hdu_list)
    energies = Quantity(energies, 'TeV')
    print(arf.info(energies=energies))

    if plot:
        arf.plot_area_vs_energy('effective_area.png')
Ejemplo n.º 33
0
from gammapy.spectrum import calculate_predicted_counts, SpectrumExtraction, PHACountsSpectrum, SpectrumObservation
from gammapy.utils.random import get_random_state
import numpy as np
import astropy.units as u
import matplotlib.pyplot as plt

e_true = SpectrumExtraction.DEFAULT_TRUE_ENERGY
e_reco = SpectrumExtraction.DEFAULT_RECO_ENERGY

# EDISP
edisp = EnergyDispersion.from_gauss(e_true=e_true, e_reco=e_true, sigma=0.2)

# AEFF
nodes = np.sqrt(e_true[:-1] * e_true[1:])
data = abramowski_effective_area(energy=nodes)
aeff = EffectiveAreaTable(data=data, energy=e_true)
lo_threshold = aeff.find_energy(0.1 * aeff.max_area)


# MODEL
model = PowerLaw(index=2.3 * u.Unit(""), amplitude=2.5 * 1e-12 * u.Unit("cm-2 s-1 TeV-1"), reference=1 * u.TeV)

# COUNTS
livetime = 2 * u.h
npred = calculate_predicted_counts(model=model, aeff=aeff, edisp=edisp, livetime=livetime)

bkg = 0.2 * npred.data
alpha = 0.1
counts_kwargs = dict(
    energy=npred.energy,
    exposure=livetime,