Example #1
0
    def from_table_hdu(cls, hdu):
        """Create `EnergyDependentMultiGaussPSF` from HDU list.

        Parameters
        ----------
        hdu : `~astropy.io.fits.BinTableHDU`
            HDU
        """
        table = Table.read(hdu)

        energy_axis_true = MapAxis.from_table(table,
                                              column_prefix="ENERG",
                                              format="gadf-dl3")
        offset_axis = MapAxis.from_table(table,
                                         column_prefix="THETA",
                                         format="gadf-dl3")

        # Get sigmas
        shape = (offset_axis.nbin, energy_axis_true.nbin)
        sigmas = []
        for key in ["SIGMA_1", "SIGMA_2", "SIGMA_3"]:
            sigma = hdu.data[key].reshape(shape).copy()
            sigmas.append(sigma)

        # Get amplitudes
        norms = []
        for key in ["SCALE", "AMPL_2", "AMPL_3"]:
            norm = hdu.data[key].reshape(shape).copy()
            norms.append(norm)

        return cls(energy_axis_true=energy_axis_true,
                   offset_axis=offset_axis,
                   sigmas=sigmas,
                   norms=norms,
                   meta=dict(hdu.header))
Example #2
0
    def from_table(cls, table):
        """Create `PSF3D` from `~astropy.table.Table`.

        Parameters
        ----------
        table : `~astropy.table.Table`
            Table Table-PSF info.
        """
        psf_value = table["RPSF"].quantity[0]

        opts = {}
        try:
            opts["energy_thresh_lo"] = u.Quantity(table.meta["LO_THRES"],
                                                  "TeV")
            opts["energy_thresh_hi"] = u.Quantity(table.meta["HI_THRES"],
                                                  "TeV")
        except KeyError:
            pass

        energy_axis_true = MapAxis.from_table(table,
                                              column_prefix="ENERG",
                                              format="gadf-dl3")
        offset_axis = MapAxis.from_table(table,
                                         column_prefix="THETA",
                                         format="gadf-dl3")
        rad_axis = MapAxis.from_table(table,
                                      column_prefix="RAD",
                                      format="gadf-dl3")

        return cls(energy_axis_true=energy_axis_true,
                   offset_axis=offset_axis,
                   rad_axis=rad_axis,
                   psf_value=psf_value,
                   **opts)
Example #3
0
    def from_table(cls, table):
        """Create `PSFKing` from `~astropy.table.Table`.

        Parameters
        ----------
        table : `~astropy.table.Table`
            Table King PSF info.
        """
        energy_axis_true = MapAxis.from_table(table,
                                              column_prefix="ENERG",
                                              format="gadf-dl3")
        offset_axis = MapAxis.from_table(table,
                                         column_prefix="THETA",
                                         format="gadf-dl3")

        gamma = table["GAMMA"].quantity[0]
        sigma = table["SIGMA"].quantity[0]

        opts = {}
        try:
            opts["energy_thresh_lo"] = Quantity(table.meta["LO_THRES"], "TeV")
            opts["energy_thresh_hi"] = Quantity(table.meta["HI_THRES"], "TeV")
        except KeyError:
            pass

        return cls(energy_axis_true=energy_axis_true,
                   offset_axis=offset_axis,
                   gamma=gamma,
                   sigma=sigma,
                   **opts)
    def from_table(cls, table):
        """Create from `~astropy.table.Table`."""
        # TODO: move this to MapAxis.from_table()

        if "ENERG_LO" in table.colnames:
            energy_axis_true = MapAxis.from_table(table,
                                                  column_prefix="ENERG",
                                                  format="gadf-dl3")
        elif "ETRUE_LO" in table.colnames:
            energy_axis_true = MapAxis.from_table(table,
                                                  column_prefix="ETRUE",
                                                  format="gadf-dl3")
        else:
            raise ValueError(
                'Invalid column names. Need "ENERG_LO/ENERG_HI" or "ETRUE_LO/ETRUE_HI"'
            )

        offset_axis = MapAxis.from_table(table,
                                         column_prefix="THETA",
                                         format="gadf-dl3")
        migra_axis = MapAxis.from_table(table,
                                        column_prefix="MIGRA",
                                        format="gadf-dl3")

        matrix = table["MATRIX"].quantity[0].transpose()

        return cls(
            energy_axis_true=energy_axis_true,
            offset_axis=offset_axis,
            migra_axis=migra_axis,
            data=matrix,
        )
Example #5
0
    def from_table(cls, table):
        """Read from `~astropy.table.Table`."""
        # Spec says key should be "BKG", but there are files around
        # (e.g. CTA 1DC) that use "BGD". For now we support both
        if "BKG" in table.colnames:
            bkg_name = "BKG"
        elif "BGD" in table.colnames:
            bkg_name = "BGD"
        else:
            raise ValueError('Invalid column names. Need "BKG" or "BGD".')

        data_unit = u.Unit(table[bkg_name].unit, parse_strict="silent")
        if isinstance(data_unit, u.UnrecognizedUnit):
            data_unit = u.Unit("s-1 MeV-1 sr-1")
            log.warning(
                "Invalid unit found in background table! Assuming (s-1 MeV-1 sr-1)"
            )

        energy_axis = MapAxis.from_table(table,
                                         column_prefix="ENERG",
                                         format="gadf-dl3")
        fov_lon_axis = MapAxis.from_table(table,
                                          column_prefix="DETX",
                                          format="gadf-dl3")
        fov_lat_axis = MapAxis.from_table(table,
                                          column_prefix="DETY",
                                          format="gadf-dl3")

        return cls(
            energy_axis=energy_axis,
            fov_lon_axis=fov_lon_axis,
            fov_lat_axis=fov_lat_axis,
            data=table[bkg_name].data[0] * data_unit,
            meta=table.meta,
        )
Example #6
0
    def from_table(cls, table):
        """Read from `~astropy.table.Table`."""
        # Spec says key should be "BKG", but there are files around
        # (e.g. CTA 1DC) that use "BGD". For now we support both
        if "BKG" in table.colnames:
            bkg_name = "BKG"
        elif "BGD" in table.colnames:
            bkg_name = "BGD"
        else:
            raise ValueError('Invalid column names. Need "BKG" or "BGD".')

        data_unit = table[bkg_name].unit
        if data_unit is not None:
            data_unit = u.Unit(table[bkg_name].unit, parse_strict="silent")
        if isinstance(data_unit, u.UnrecognizedUnit) or (data_unit is None):
            data_unit = u.Unit("s-1 MeV-1 sr-1")
            log.warning(
                "Invalid unit found in background table! Assuming (s-1 MeV-1 sr-1)"
            )

        energy_axis = MapAxis.from_table(
            table, column_prefix="ENERG", format="gadf-dl3"
        )
        fov_lon_axis = MapAxis.from_table(
            table, column_prefix="DETX", format="gadf-dl3"
        )
        fov_lat_axis = MapAxis.from_table(
            table, column_prefix="DETY", format="gadf-dl3"
        )

        # TODO: The present HESS and CTA backgroundfits files
        #  have a reverse order (lon, lat, E) than recommened in GADF(E, lat, lon)
        #  For now, we suport both.

        data = table[bkg_name].data[0].T * data_unit
        shape = (energy_axis.nbin, fov_lon_axis.nbin, fov_lat_axis.nbin)

        if shape == shape[::-1]:
            log.error("Ambiguous axes order in Background fits files!")

        if np.shape(data) != shape:
            log.debug("Transposing background table on read")
            data = data.transpose()

        return cls(
            energy_axis=energy_axis,
            fov_lon_axis=fov_lon_axis,
            fov_lat_axis=fov_lat_axis,
            data=data,
            meta=table.meta,
        )
Example #7
0
    def from_table(cls, table):
        """Read from `~astropy.table.Table`."""
        energy_axis_true = MapAxis.from_table(table,
                                              column_prefix="ENERG",
                                              format="gadf-dl3")
        offset_axis = MapAxis.from_table(table,
                                         column_prefix="THETA",
                                         format="gadf-dl3")

        return cls(
            energy_axis_true=energy_axis_true,
            offset_axis=offset_axis,
            data=table["EFFAREA"].quantity[0].transpose(),
            meta=table.meta,
        )
Example #8
0
    def from_table(cls, table):
        """Create from `~astropy.table.Table` in ARF format.

        Data format specification: :ref:`gadf:ogip-arf`
        """
        energy_axis_true = MapAxis.from_table(table, format="ogip-arf")
        data = table["SPECRESP"].quantity
        return cls(energy_axis_true=energy_axis_true, data=data)
Example #9
0
    def from_table_hdu(cls, hdu):
        """Create `EnergyDependentMultiGaussPSF` from HDU list.

        Parameters
        ----------
        hdu : `~astropy.io.fits.BinTableHDU`
            HDU
        """
        table = Table.read(hdu)

        energy_axis_true = MapAxis.from_table(table,
                                              column_prefix="ENERG",
                                              format="gadf-dl3")
        offset_axis = MapAxis.from_table(table,
                                         column_prefix="THETA",
                                         format="gadf-dl3")

        # Get sigmas
        shape = (offset_axis.nbin, energy_axis_true.nbin)
        sigmas = []
        for key in ["SIGMA_1", "SIGMA_2", "SIGMA_3"]:
            sigma = hdu.data[key].reshape(shape).copy()
            sigmas.append(sigma)

        # Get amplitudes
        norms = []
        for key in ["SCALE", "AMPL_2", "AMPL_3"]:
            norm = hdu.data[key].reshape(shape).copy()
            norms.append(norm)

        opts = {}
        try:
            opts["energy_thresh_lo"] = u.Quantity(hdu.header["LO_THRES"],
                                                  "TeV")
            opts["energy_thresh_hi"] = u.Quantity(hdu.header["HI_THRES"],
                                                  "TeV")
        except KeyError:
            pass

        return cls(
            energy_axis_true=energy_axis_true,
            offset_axis=offset_axis,
            sigmas=sigmas,
            norms=norms,
            **opts,
        )
Example #10
0
    def from_hdulist(cls, hdulist, hdu1="MATRIX", hdu2="EBOUNDS"):
        """Create `EnergyDispersion` object from `~astropy.io.fits.HDUList`.

        Parameters
        ----------
        hdulist : `~astropy.io.fits.HDUList`
            HDU list with ``MATRIX`` and ``EBOUNDS`` extensions.
        hdu1 : str, optional
            HDU containing the energy dispersion matrix, default: MATRIX
        hdu2 : str, optional
            HDU containing the energy axis information, default, EBOUNDS
        """
        matrix_hdu = hdulist[hdu1]
        ebounds_hdu = hdulist[hdu2]

        data = matrix_hdu.data
        header = matrix_hdu.header

        pdf_matrix = np.zeros([len(data), header["DETCHANS"]],
                              dtype=np.float64)

        for i, l in enumerate(data):
            if l.field("N_GRP"):
                m_start = 0
                for k in range(l.field("N_GRP")):
                    pdf_matrix[i,
                               l.field("F_CHAN")[k]:l.field("F_CHAN")[k] +
                               l.field("N_CHAN")[k], ] = l.field(
                                   "MATRIX")[m_start:m_start +
                                             l.field("N_CHAN")[k]]
                    m_start += l.field("N_CHAN")[k]

        table = Table.read(ebounds_hdu)
        energy_axis = MapAxis.from_table(table, format="ogip")

        table = Table.read(matrix_hdu)
        energy_axis_true = MapAxis.from_table(table, format="ogip-arf")

        return cls(
            energy_axis=energy_axis,
            energy_axis_true=energy_axis_true,
            data=pdf_matrix,
        )
Example #11
0
    def from_table(cls, table):
        """Create `PSFKing` from `~astropy.table.Table`.

        Parameters
        ----------
        table : `~astropy.table.Table`
            Table King PSF info.
        """
        energy_axis_true = MapAxis.from_table(table,
                                              column_prefix="ENERG",
                                              format="gadf-dl3")
        offset_axis = MapAxis.from_table(table,
                                         column_prefix="THETA",
                                         format="gadf-dl3")

        gamma = table["GAMMA"].quantity[0]
        sigma = table["SIGMA"].quantity[0]

        return cls(energy_axis_true=energy_axis_true,
                   offset_axis=offset_axis,
                   gamma=gamma,
                   sigma=sigma,
                   meta=table.meta)
Example #12
0
    def __init__(self, data, reference_spectral_model):
        # TODO: Check data
        self._data = data

        if hasattr(self._data["norm"], "geom"):
            self._energy_axis = self.data["norm"].geom.axes["energy"]
            self._expand_slice = (slice(None), np.newaxis, np.newaxis)
        else:
            # Here we assume there is only one row per energy
            self._energy_axis = MapAxis.from_table(table=data, format="gadf-sed")
            self._expand_slice = slice(None)

        # Note that here we could use the specification from dnde_ref to build piecewise PL
        # But does it work beyond min and max centers?

        self._reference_spectral_model = reference_spectral_model
Example #13
0
    def _convert_flux_columns(table, reference_model, sed_type):
        energy_axis = MapAxis.from_table(table, format="gadf-sed")

        with np.errstate(invalid="ignore", divide="ignore"):
            fluxes = reference_model.reference_fluxes(energy_axis=energy_axis)

        # TODO: handle reshaping in MapAxis
        col_ref = table[sed_type]
        factor = fluxes[f"ref_{sed_type}"].to(col_ref.unit)

        data = Table(fluxes)
        data["norm"] = col_ref / factor

        for key in OPTIONAL_QUANTITIES[sed_type]:
            if key in table.colnames:
                norm_type = key.replace(sed_type, "norm")
                data[norm_type] = table[key] / factor

        return data
Example #14
0
    def from_hdulist(cls, hdu_list):
        """Create `EnergyDependentTablePSF` from ``gtpsf`` format HDU list.

        Parameters
        ----------
        hdu_list : `~astropy.io.fits.HDUList`
            HDU list with ``THETA`` and ``PSF`` extensions.
        """
        rad_axis = MapAxis.from_table_hdu(hdu_list["THETA"], format="gtpsf")

        table = Table.read(hdu_list["PSF"])
        energy_axis_true = MapAxis.from_table(table, format="gtpsf")
        exposure = table["Exposure"].data * u.Unit("cm2 s")

        data = table["Psf"].data
        return cls(axes=[energy_axis_true, rad_axis],
                   exposure=exposure,
                   data=data,
                   unit="sr-1")
Example #15
0
    def from_hdulist(
        cls,
        hdulist,
        hdu=None,
        hdu_bands=None,
        exposure_hdu=None,
        exposure_hdu_bands=None,
        format="gadf",
    ):
        """Create from `~astropy.io.fits.HDUList`.

        Parameters
        ----------
        hdulist : `~astropy.fits.HDUList`
            HDU list.
        hdu : str
            Name or index of the HDU with the IRF map.
        hdu_bands : str
            Name or index of the HDU with the IRF map BANDS table.
        exposure_hdu : str
            Name or index of the HDU with the exposure map data.
        exposure_hdu_bands : str
            Name or index of the HDU with the exposure map BANDS table.
        format : {"gadf", "gtpsf"}
            File format

        Returns
        -------
        irf_map : `IRFMap`
            IRF map.
        """
        if format == "gadf":
            if hdu is None:
                hdu = IRF_MAP_HDU_SPECIFICATION[cls.tag]

            irf_map = Map.from_hdulist(hdulist,
                                       hdu=hdu,
                                       hdu_bands=hdu_bands,
                                       format=format)

            if exposure_hdu is None:
                exposure_hdu = IRF_MAP_HDU_SPECIFICATION[cls.tag] + "_exposure"

            if exposure_hdu in hdulist:
                exposure_map = Map.from_hdulist(hdulist,
                                                hdu=exposure_hdu,
                                                hdu_bands=exposure_hdu_bands,
                                                format=format)
            else:
                exposure_map = None
        elif format == "gtpsf":
            rad_axis = MapAxis.from_table_hdu(hdulist["THETA"], format=format)

            table = Table.read(hdulist["PSF"])
            energy_axis_true = MapAxis.from_table(table, format=format)

            geom_psf = RegionGeom.create(region=None,
                                         axes=[rad_axis, energy_axis_true])

            psf_map = Map.from_geom(geom=geom_psf,
                                    data=table["Psf"].data,
                                    unit="sr-1")

            geom_exposure = geom_psf.squash("rad")
            exposure_map = Map.from_geom(geom=geom_exposure,
                                         data=table["Exposure"].data,
                                         unit="cm2 s")
            return cls(psf_map=psf_map, exposure_map=exposure_map)
        else:
            raise ValueError(f"Format {format} not supported")

        return cls(irf_map, exposure_map)