Source code for gammapy_plugin.models.spatial

import logging

import astropy.units as u
import numpy as np
from astromodels.core.parameter_transformation import LogarithmicTransformation
from astromodels.core.sky_direction import SkyDirection
from astromodels.functions.function import Function
from gammapy.modeling.models import (
    PointSpatialModel,
    SpatialModel,
)
from gammapy.modeling.parameter import Parameter, Parameters

log = logging.getLogger(__name__)


[docs] class SpatialModelConverted(SpatialModel): """Class for converting a spatial astromodels function into an gammapy SpatialModel.""" tag = ["SpatialModelConverted", "spat_conv"] def __init__( self, function: Function, frame: str = None, ) -> None: """ :param function: astromodel function describing the morphology :param frame: reference frame of the geometry, defaults to ICRS """ log.debug("type of spatial function: " + str(type(function))) assert issubclass( type(function), Function ), "function must be astromodels function" self._astromodel_function = function # self._source_name = self._astromodel_function.name if frame is None: log.info("No frame passed - will use ICRS!") frame = "icrs" self._frame = frame setattr(self, "frame", self._frame) self._setup_parameters() super().__init__() def _setup_parameters(self): """Setup the parameters by creating gammapy Parameters and setting them as attributes to this class.""" paras = [] # needed later for correctly evaluating the function self._mapping = {} self._mapping_free = {} for k, v in self._astromodel_function.parameters.items(): vmin = np.nan vmax = np.nan if v.min_value is not None: vmin = v.min_value if v.max_value is not None: vmax = v.max_value self._mapping[v.path] = v.name if v.free: self._mapping_free[v.path] = v.name interp = "linear" if isinstance(v.transformation, LogarithmicTransformation): interp = "log" paras.append( Parameter( name=v.name, value=v.value, unit=v.unit, min=vmin, max=vmax, frozen=not bool(v.free), interp=interp, ) ) setattr(self, v.name, paras[-1]) self.default_parameters = Parameters(paras) # todo check return type
[docs] def evaluate(self, *args, **kwargs): """Evaluates astromodels function instead of gammapy one.""" return self._astromodel_function.evaluate(*args, **kwargs)
@property def mapping(self): return self._mapping @property def mapping_free(self): return self._mapping_free
[docs] class PointSourceModelConverted(PointSpatialModel): tag = ["PointSourceModelConverted", "ps_conv"] def __init__(self, sky_position: SkyDirection, frame: str): assert isinstance( sky_position, SkyDirection ), "sky_position must be SkyDirection" self._sky_position = sky_position self._name = self._sky_position.name self._position = self._sky_position.sky_coord.transform_to(frame) self._frame = frame log.debug(f"PointSpatialMpdel got frame {self._frame}") setattr(self, "frame", self._frame) self._setup_parameters() super().__init__() def _setup_parameters(self): """Setup the parameters by creating gammapy Parameters and setting them as attributes to this class.""" self._mapping = {} self._mapping_free = {} if self._frame == "galactic": lon = self._position.l lat = self._position.b elif self._frame == "icrs": lon = self._position.ra lat = self._position.dec else: raise NotImplementedError("Only galactic and icrs currently available") if lon.value > 180: lon -= 360 * u.deg for k, v in self._sky_position.parameters.items(): if k == "ra" or k == "l": para_name = "lon_0" lon_free = v.free elif k == "dec" or k == "b": para_name = "lat_0" lat_free = v.free self._mapping[v.path] = para_name if v.free: self._mapping_free[v.path] = para_name lon_0 = Parameter( name="lon_0", value=lon.value, unit=lon.unit, frozen=not lon_free ) lat_0 = Parameter( name="lat_0", value=lat.value, unit=lat.unit, frozen=not lat_free ) setattr(self, "lon_0", lon_0) setattr(self, "lat_0", lat_0) self.default_parameters = Parameters([lon_0, lat_0]) log.debug(f"Set parameters to be {lon_0} and {lat_0}") @property def mapping(self): return self._mapping @property def mapping_free(self): return self._mapping_free