Exemplo n.º 1
0
    def __init__(
        self,
        energy_lo,
        energy_hi,
        fov_lon_lo,
        fov_lon_hi,
        fov_lat_lo,
        fov_lat_hi,
        data,
        meta=None,
        interp_kwargs=None,
    ):
        if interp_kwargs is None:
            interp_kwargs = self.default_interp_kwargs

        e_edges = edges_from_lo_hi(energy_lo, energy_hi)
        energy_axis = MapAxis.from_edges(e_edges, interp="log", name="energy")

        fov_lon_edges = edges_from_lo_hi(fov_lon_lo, fov_lon_hi)
        fov_lon_axis = MapAxis.from_edges(fov_lon_edges,
                                          interp="lin",
                                          name="fov_lon")

        fov_lat_edges = edges_from_lo_hi(fov_lat_lo, fov_lat_hi)
        fov_lat_axis = MapAxis.from_edges(fov_lat_edges,
                                          interp="lin",
                                          name="fov_lat")

        self.data = NDDataArray(
            axes=[energy_axis, fov_lon_axis, fov_lat_axis],
            data=data,
            interp_kwargs=interp_kwargs,
        )
        self.meta = meta or {}
Exemplo n.º 2
0
    def __init__(
        self,
        e_true_lo,
        e_true_hi,
        e_reco_lo,
        e_reco_hi,
        data,
        interp_kwargs=None,
        meta=None,
    ):
        if interp_kwargs is None:
            interp_kwargs = self.default_interp_kwargs

        e_true_edges = edges_from_lo_hi(e_true_lo, e_true_hi)
        e_true_axis = MapAxis.from_edges(e_true_edges,
                                         interp="log",
                                         name="e_true")

        e_reco_edges = edges_from_lo_hi(e_reco_lo, e_reco_hi)
        e_reco_axis = MapAxis.from_edges(e_reco_edges,
                                         interp="log",
                                         name="e_reco")

        self.data = NDDataArray(axes=[e_true_axis, e_reco_axis],
                                data=data,
                                interp_kwargs=interp_kwargs)
        self.meta = meta or {}
Exemplo n.º 3
0
    def __init__(
        self,
        energy_lo,
        energy_hi,
        offset_lo,
        offset_hi,
        data,
        meta=None,
        interp_kwargs=None,
    ):
        if interp_kwargs is None:
            interp_kwargs = self.default_interp_kwargs

        e_edges = edges_from_lo_hi(energy_lo, energy_hi)
        energy_axis = MapAxis.from_edges(e_edges, interp="log", name="energy")

        offset_edges = edges_from_lo_hi(offset_lo, offset_hi)
        offset_axis = MapAxis.from_edges(offset_edges,
                                         interp="lin",
                                         name="offset")

        self.data = NDDataArray(axes=[energy_axis, offset_axis],
                                data=data,
                                interp_kwargs=interp_kwargs)
        self.meta = meta or {}
Exemplo n.º 4
0
    def __init__(
        self,
        energy_lo,
        energy_hi,
        offset_lo,
        offset_hi,
        data,
        meta=None,
        interp_kwargs=None,
    ):

        if interp_kwargs is None:
            interp_kwargs = self.default_interp_kwargs

        e_edges = edges_from_lo_hi(energy_lo, energy_hi)
        energy_axis = MapAxis.from_edges(e_edges,
                                         interp="log",
                                         name="energy_true")

        # TODO: for some reason the H.E.S.S. DL3 files contain the same values for offset_hi and offset_lo
        if np.allclose(offset_lo.to_value("deg"), offset_hi.to_value("deg")):
            offset_axis = MapAxis.from_nodes(offset_lo,
                                             interp="lin",
                                             name="offset")
        else:
            offset_edges = edges_from_lo_hi(offset_lo, offset_hi)
            offset_axis = MapAxis.from_edges(offset_edges,
                                             interp="lin",
                                             name="offset")

        self.data = NDDataArray(axes=[energy_axis, offset_axis],
                                data=data,
                                interp_kwargs=interp_kwargs)
        self.meta = meta or {}
Exemplo n.º 5
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

    edges = edges_from_lo_hi(psf.energy_lo, psf.energy_hi)
    energy_axis = MapAxis.from_edges(edges, interp="log", name="energy_true")

    edges = edges_from_lo_hi(psf.rad_lo, psf.rad_hi)
    rad_axis = MapAxis.from_edges(edges, name="theta")

    geom = WcsGeom.create(
        skydir=position, npix=(3, 3), axes=[rad_axis, energy_axis], 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.psf_value.value).any()
    assert_allclose(psf.psf_value.value[22, 22], 12206.1665, rtol=1e-3)
Exemplo n.º 6
0
    def __init__(
        self,
        e_true_lo,
        e_true_hi,
        migra_lo,
        migra_hi,
        offset_lo,
        offset_hi,
        data,
        interp_kwargs=None,
        meta=None,
    ):
        if interp_kwargs is None:
            interp_kwargs = self.default_interp_kwargs

        e_true_edges = edges_from_lo_hi(e_true_lo, e_true_hi)
        e_true_axis = MapAxis.from_edges(e_true_edges, interp="log", name="e_true")

        migra_edges = edges_from_lo_hi(migra_lo, migra_hi)
        migra_axis = MapAxis.from_edges(
            migra_edges, interp="log", name="migra", unit=""
        )

        # TODO: for some reason the H.E.S.S. DL3 files contain the same values for offset_hi and offset_lo
        if np.allclose(offset_lo.to_value("deg"), offset_hi.to_value("deg")):
            offset_axis = MapAxis.from_nodes(offset_lo, interp="lin", name="offset")
        else:
            offset_edges = edges_from_lo_hi(offset_lo, offset_hi)
            offset_axis = MapAxis.from_edges(offset_edges, interp="lin", name="offset")

        axes = [e_true_axis, migra_axis, offset_axis]

        self.data = NDDataArray(axes=axes, data=data, interp_kwargs=interp_kwargs)
        self.meta = OrderedDict(meta) if meta else OrderedDict()
Exemplo n.º 7
0
    def from_energy_lo_hi(cls, e_true_lo, e_true_hi, e_reco_lo, e_reco_hi, data, **kwargs):
        e_true_edges = edges_from_lo_hi(e_true_lo, e_true_hi)
        e_true_axis = MapAxis.from_edges(e_true_edges, interp="log", name="energy_true")

        e_reco_edges = edges_from_lo_hi(e_reco_lo, e_reco_hi)
        e_reco_axis = MapAxis.from_edges(e_reco_edges, interp="log", name="energy")

        return cls(e_true_axis, e_reco_axis, data, **kwargs)
Exemplo n.º 8
0
def plot_theta_squared_table(table):
    """Plot the theta2 distribution of ON, OFF counts, excess and signifiance in each theta2bin.

    Take the table containing the ON counts, the OFF counts, the acceptance, the off acceptance and the alpha
    (normalisation between ON and OFF) for each theta2 bin

    Parameters
    ----------
    table : `~astropy.table.Table`
        Required columns: theta2_min, theta2_max, counts, counts_off and alpha
    """
    import matplotlib.pyplot as plt

    theta2_edges = edges_from_lo_hi(table["theta2_min"].quantity,
                                    table["theta2_max"].quantity)
    theta2_axis = MapAxis.from_edges(theta2_edges,
                                     interp="lin",
                                     name="theta_squared")

    ax0 = plt.subplot(2, 1, 1)

    x = theta2_axis.center.value
    x_edges = theta2_axis.edges.value
    xerr = (x - x_edges[:-1], x_edges[1:] - x)

    ax0.errorbar(x,
                 table["counts"],
                 xerr=xerr,
                 yerr=np.sqrt(table["counts"]),
                 linestyle='None',
                 label="Counts")

    ax0.errorbar(x,
                 table["counts_off"],
                 xerr=xerr,
                 yerr=np.sqrt(table["counts_off"]),
                 linestyle='None',
                 label="Counts Off")

    ax0.errorbar(x,
                 table["excess"],
                 xerr=xerr,
                 yerr=(-table["excess_errn"], table["excess_errp"]),
                 fmt="+",
                 linestyle='None',
                 label="Excess")

    ax0.set_ylabel("Counts")
    ax0.set_xticks([])
    ax0.set_xlabel('')
    ax0.legend()

    ax1 = plt.subplot(2, 1, 2)
    ax1.errorbar(x, table["sqrt_ts"], xerr=xerr, linestyle='None')
    ax1.set_xlabel(f"Theta  [{theta2_axis.unit}]")
    ax1.set_ylabel("Significance")
Exemplo n.º 9
0
    def __init__(self, energy_lo, energy_hi, data, meta=None):

        e_edges = edges_from_lo_hi(energy_lo, energy_hi)
        energy_axis = MapAxis.from_edges(e_edges, interp="log", name="energy")

        interp_kwargs = {"extrapolate": False, "bounds_error": False}
        self.data = NDDataArray(axes=[energy_axis],
                                data=data,
                                interp_kwargs=interp_kwargs)
        self.meta = meta or {}
Exemplo n.º 10
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)
Exemplo n.º 11
0
    def __init__(self, energy_lo, energy_hi, data=None, unit=""):
        e_edges = edges_from_lo_hi(energy_lo, energy_hi)
        self.energy = MapAxis.from_edges(e_edges, interp="log", name="energy")

        if data is None:
            data = np.zeros(self.energy.nbin)

        self.data = np.array(data)
        if not self.energy.nbin == self.data.size:
            raise ValueError("Incompatible data and energy axis size.")

        self.unit = u.Unit(unit)
Exemplo n.º 12
0
def integrate_spectrum(func, emin, emax, ndecade=100, intervals=False):
    """Integrate 1d function using the log-log trapezoidal rule.

    If scalar values for xmin and xmax are passed an oversampled grid is generated using the
    ``ndecade`` keyword argument. If xmin and xmax arrays are passed, no
    oversampling is performed and the integral is computed in the provided
    grid.

    Parameters
    ----------
    func : callable
        Function to integrate.
    emin : `~astropy.units.Quantity`
        Integration range minimum
    emax : `~astropy.units.Quantity`
        Integration range minimum
    ndecade : int, optional
        Number of grid points per decade used for the integration.
        Default : 100.
    intervals : bool, optional
        Return integrals in the grid not the sum, default: False
    """
    if emin.isscalar and emax.isscalar:
        energies = MapAxis.from_energy_bounds(emin=emin,
                                              emax=emax,
                                              nbin=ndecade,
                                              per_decade=True).edges
    else:
        energies = edges_from_lo_hi(emin, emax)

    values = func(energies)

    integral = trapz_loglog(values, energies)

    if intervals:
        return integral

    return integral.sum()
Exemplo n.º 13
0
 def rad_axis(self):
     edges = edges_from_lo_hi(self.rad_lo, self.rad_hi)
     return MapAxis.from_edges(edges, name="theta", interp="lin")
Exemplo n.º 14
0
 def energy_axis(self):
     edges = edges_from_lo_hi(self.energy_lo, self.energy_hi)
     return MapAxis.from_edges(edges, name="energy_true", interp="log")