Source code for gammapy.data.utils

# Licensed under a 3-clause BSD style license - see LICENSE.rst
import numpy as np
import astropy.units as u
from astropy.table import Table
from gammapy.utils.cluster import standard_scaler

__all__ = ["get_irfs_features"]


[docs] def get_irfs_features( observations, energy_true, position=None, fixed_offset=None, names=None, containment_fraction=0.68, apply_standard_scaler=False, ): """Get features from IRFs properties at a given position. Used for observations clustering. Parameters ---------- observations : `~gammapy.data.Observations` Container holding a list of `~gammapy.data.Observation`. energy_true : `~astropy.units.Quantity` Energy true at which to compute the containment radius. position : `~astropy.coordinates.SkyCoord`, optional Sky position. Default is None. fixed_offset : `~astropy.coordinates.Angle`, optional Offset calculated from the pointing position. Default is None. If neither the `position` nor the `fixed_offset` is specified, it uses the position of the center of the map by default. names : {"edisp-bias", "edisp-res", "psf-radius"} IRFs properties to be considered. Default is None. If None, all the features are computed. containment_fraction : float, optional Containment_fraction to compute the `psf-radius`. Default is 68%. apply_standard_scaler : bool, optional Compute standardize features by removing the mean and scaling to unit variance. Default is False. Returns ------- features : `~astropy.table.Table` Features table. Examples -------- Compute the IRF features for "edisp-bias", "edisp-res" and "psf-radius" at 1 TeV:: >>> from gammapy.data.utils import get_irfs_features >>> from gammapy.data import DataStore >>> from gammapy.utils.cluster import standard_scaler >>> from astropy.coordinates import SkyCoord >>> import astropy.units as u >>> selection = dict( ... type="sky_circle", ... frame="icrs", ... lon="329.716 deg", ... lat="-30.225 deg", ... radius="2 deg", ... ) >>> data_store = DataStore.from_dir("$GAMMAPY_DATA/hess-dl3-dr1/") >>> obs_table = data_store.obs_table.select_observations(selection) >>> obs = data_store.get_observations(obs_table["OBS_ID"][:3]) >>> position = SkyCoord(329.716 * u.deg, -30.225 * u.deg, frame="icrs") >>> names = ["edisp-bias", "edisp-res", "psf-radius"] >>> features_irfs = get_irfs_features( ... obs, ... energy_true="1 TeV", ... position=position, ... names=names, ... ) >>> print(features_irfs) edisp-bias obs_id edisp-res psf-radius deg ------------------- ------ ------------------- ------------------- 0.11587179071752986 33787 0.368346217294295 0.14149953611195087 0.04897634344908595 33788 0.33983991887701287 0.11553325504064559 0.033176650892097 33789 0.32377509405904137 0.10262943822890519 """ from gammapy.irf import EDispKernelMap, PSFMap if names is None: names = ["edisp-bias", "edisp-res", "psf-radius"] if position and fixed_offset: raise ValueError( "`position` and `fixed_offset` arguments are mutually exclusive" ) rows = [] for obs in observations: psf_kwargs = dict(fraction=containment_fraction, energy_true=energy_true) if isinstance(obs.psf, PSFMap) and isinstance(obs.edisp, EDispKernelMap): if position is None: position = obs.psf.psf_map.geom.center_skydir edisp_kernel = obs.edisp.get_edisp_kernel(position=position) psf_kwargs["position"] = position else: if fixed_offset is None: if position is None: offset = 0 * u.deg else: offset_max = np.minimum( obs.psf.axes["offset"].center[-1], obs.edisp.axes["offset"].center[-1], ) offset = np.minimum( position.separation(obs.get_pointing_icrs(obs.tmid)), offset_max ) else: offset = fixed_offset edisp_kernel = obs.edisp.to_edisp_kernel(offset) psf_kwargs["offset"] = offset data = {} for name in names: if name == "edisp-bias": data[name] = edisp_kernel.get_bias(energy_true)[0] if name == "edisp-res": data[name] = edisp_kernel.get_resolution(energy_true)[0] if name == "psf-radius": data[name] = obs.psf.containment_radius(**psf_kwargs).to("deg") data["obs_id"] = obs.obs_id rows.append(data) features = Table(rows) if apply_standard_scaler: features = standard_scaler(features) features.meta = dict( energy_true=energy_true, fixed_offset=fixed_offset, containment_fraction=containment_fraction, apply_standard_scaler=apply_standard_scaler, ) if position: features.meta["lon"] = position.galactic.l features.meta["lat"] = position.galactic.b features.meta["frame"] = "galactic" return features