Exemple #1
0
def test_model_class_par_init():
    x = Parameter("x", 4, "cm")
    y = Parameter("y", 10)

    model = MyModel(x=x, y=y)

    assert x is model.x
    assert y is model.y
Exemple #2
0
class CoModel(Model):
    """Compound model example"""
    norm = Parameter("norm", 42, "cm")

    def __init__(self, m1, m2, norm=norm.quantity):
        self.m1 = m1
        self.m2 = m2
        super().__init__(norm=norm)

    @property
    def parameters(self):
        return Parameters([self.norm]) + self.m1.parameters + self.m2.parameters
Exemple #3
0
class MyModel(Model):
    """Simple model example"""

    x = Parameter("x", 1, "cm")
    y = Parameter("y", 2)
Exemple #4
0
 def __init__(self, m1, a=1, y=99):
     self.m1 = m1
     a = Parameter("a", a)
     y = Parameter("y", y)
     self.default_parameters = Parameters([a, y])
     super().__init__(a=a, y=y)
Exemple #5
0
class SkyDiffuseCascadeCube(SpatialModel):
    """Cube sky map model for electromagnetic cascades.

    Parameters
    ----------
    cascmap : `~simCRpropa.cascmaps.CascMap`
        Cascade Map template

    spectral_model : `SpectralModel`
        Spectral model of the injected particles.

    rotation: float
        Rotation angle of the cascade template

    tmax: float
        Maximum delay time in years allowed for the cascade.

    interp_kwargs : dict
        Interpolation keyword arguments passed to `gammapy.maps.Map.interp_by_coord`.
        Default arguments are {'interp': 'linear', 'fill_value': 0}.
    """

    tag = "SkyDiffuseCascadeCube"
    rotation = Parameter("rotation", 0., unit="deg", frozen=True)
    tmax = Parameter("tmax", 1e7, unit="yr", frozen=True)

    _apply_irf_default = {"exposure": True, "psf": True, "edisp": True}

    def __init__(
        self,
        cascmap,
        spectral_model,
        rotation=rotation.quantity,
        tmax=tmax.quantity,
        interp_kwargs=None,
        apply_irf=None,
        name=None,
    ):

        self.cascmap = cascmap
        self._spectral_model = spectral_model
        self._energy_unit_spectral_model = energy_unit_spectral_model
        self._name = name

        interp_kwargs = {} if interp_kwargs is None else interp_kwargs
        interp_kwargs.setdefault("interp", "linear")
        interp_kwargs.setdefault("fill_value", 0)
        self._interp_kwargs = interp_kwargs

        self._cached_value = None
        self._cached_weights = None
        self._cached_coordinates = (None, None, None)

        if apply_irf is None:
            apply_irf = self._apply_irf_default.copy()

        self.apply_irf = apply_irf
        super().__init__(tmax=tmax, rotation=rotation)

    @property
    def name(self):
        return self._name

    def _interpolate(self, lon, lat, energy):
        coord = {
            "lon": lon.to_value("deg"),
            "lat": lat.to_value("deg"),
            "energy": energy,
        }
        return self.cascmap.add_primary_to_casc().interp_by_coord(
            coord, **self._interp_kwargs)

    def evaluate(self, lon, lat, energy, **kwargs):
        """Evaluate model at given coordinates"""

        rotation = kwargs.pop("rotation")
        tmax = kwargs.pop("tmax")

        # change max delay time
        if not tmax == self.cascmap.tmax:
            self.cascmap.tmax = tmax

        # change rotation angle
        # and apply rotation
        if not rotation == self.cascmap.angle:
            self.cascmap.angle = rotation

        # change spectral weights
        self.cascmap.apply_spectral_weights(self._inj_spec,
                                            smooth=True,
                                            **kwargs)

        is_cached_coord = [
            _ is coord
            for _, coord in zip((lon, lat, energy), self._cached_coordinates)
        ]

        # reset cache
        if not np.all(is_cached_coord):
            self._cached_value = None

        if self._cached_weights is not None and \
                not np.all(np.equal(self.cascmap.weights, self._cached_weights)):
            self._cached_weights = None

        if self._cached_value is None or self._cached_weights is None:
            self._cached_coordinates = (lon, lat, energy)
            self._cached_value = self._interpolate(lon, lat, energy)
            self._cached_weights = self.cascmap.weights

        return u.Quantity(self._cached_value,
                          self.cascmap.casc_obs.unit,
                          copy=False)

    def copy(self):
        """A shallow copy"""
        new = copy.copy(self)
        return new

    @property
    def position(self):
        """`~astropy.coordinates.SkyCoord`"""
        return self.cascmap.casc_obs.geom.center_skydir

    @property
    def evaluation_radius(self):
        """`~astropy.coordinates.Angle`"""
        return np.max(self.cascmap.casc_obs.geom.width) / 2.0

    @property
    def parameters(self):
        return (Parameters([self.rotation, self.tmax]) +
                self.spectral_model.parameters)

    def to_dict(self):
        data = super().to_dict()
        data["name"] = self.name
        data["type"] = data.pop("type")
        data["spectral_model"] = self.spectral_model.to_dict()
        data["parameters"] = Parameters([self.rotation, self.tmax]).to_dict()

        if self.apply_irf != self._apply_irf_default:
            data["apply_irf"] = self.apply_irf

        return data

    def __str__(self):
        str_ = self.__class__.__name__ + "\n\n"
        str_ += "\tParameters:\n"
        info = _get_parameters_str(self.parameters)
        lines = info.split("\n")
        str_ += "\t" + "\n\t".join(lines[:-1])

        str_ += "\n\n"
        return str_.expandtabs(tabsize=2)
Exemple #6
0
class CascadeSpectralModel(SpectralModel):
    """Spectral model for electromagnetic cascades.

    Parameters
    ----------
    cascmap : `~simCRpropa.cascmaps.CascMap`
        Cascade Map template

    spectral_model : `SpectralModel`
        Spectral model of the injected particles.

    ebl: `EBLAbsorptionNormSpectralModel`
        EBL model to be used

    region: region object
        region in which cascade is summed up

    rotation: float
        Rotation angle of the cascade template

    tmax: float
        Maximum delay time in years allowed for the cascade.

    bias: float
        energy bias for the TeV energy spectrum

    interp_kwargs : dict
        Interpolation keyword arguments passed to `gammapy.maps.Map.interp_by_coord`.
        Default arguments are {'interp': 'linear', 'fill_value': 0}.

    add_primary: bool
        if true, add the observed flux from the point source in evaluate function
    """

    tag = "CascadeSpectralModel"
    rotation = Parameter("rotation", 0., unit="deg", frozen=True)
    tmax = Parameter("tmax", 1e7, unit="yr", frozen=True)
    bias = Parameter("bias",
                     0.,
                     unit=u.dimensionless_unscaled,
                     frozen=True,
                     min=-0.2,
                     max=0.2)

    _apply_irf_default = {"exposure": True, "psf": True, "edisp": True}

    def __init__(self,
                 cascmap,
                 spectral_model,
                 ebl,
                 region,
                 rotation=rotation.quantity,
                 tmax=tmax.quantity,
                 bias=bias.quantity,
                 interp_kwargs=None,
                 apply_irf=None,
                 name=None,
                 add_primary=True,
                 energy_unit_spectral_model="TeV",
                 use_gammapy_interp=False):

        self.cascmap = cascmap
        self._intrinsic_spectral_model = spectral_model
        self._ebl = ebl
        self._name = name
        self._inj_spec = None
        self._energy_unit_spectral_model = energy_unit_spectral_model
        self._set_injection_spectrum()
        self.region = region
        self.add_primary = add_primary

        # get central sky coordinates
        self._lon, self._lat = cascmap.casc_obs.geom.center_coord[:-1]

        interp_kwargs = {} if interp_kwargs is None else interp_kwargs
        #interp_kwargs.setdefault("interp", "linear")
        #interp_kwargs.setdefault("fill_value", 0)
        interp_kwargs.setdefault("interp", 1)
        self._interp_kwargs = interp_kwargs

        self._cached_value = None
        self._cached_weights = None
        self._cached_coordinates = (None, None, None)

        self.use_gammapy_interp = use_gammapy_interp

        if apply_irf is None:
            apply_irf = self._apply_irf_default.copy()

        self.apply_irf = apply_irf
        super().__init__(tmax=tmax, rotation=rotation, bias=bias)

    @property
    def name(self):
        return self._name

    @property
    def ebl(self):
        return self._ebl

    @property
    def intrinsic_spectral_model(self):
        return self._intrinsic_spectral_model

    def _set_injection_spectrum(self):
        def inj_spec(energy, **kwargs):
            if isinstance(energy, u.Quantity):
                x = energy.to(self._energy_unit_spectral_model)
            else:
                x = energy * u.Unit(self._energy_unit_spectral_model)
            return self._intrinsic_spectral_model.evaluate(x, **kwargs)

        self._inj_spec = inj_spec

    def _interpolate(self, energy):

        spec = self.cascmap.get_obs_spectrum(self.region)

        if self.use_gammapy_interp:
            coord = {
                "lon": self._lon,
                "lat": self._lat,
                "energy_true": energy,
            }
            result = spec.interp_by_coord(coord, **
                                          self._interp_kwargs) * spec.unit

        else:
            data = spec.data[:, 0, 0]
            data[data <= 0] = 1e-40
            x = spec.geom.axes['energy_true'].center
            interp = interp1d(np.log(x.value),
                              np.log(data),
                              fill_value='extrapolate',
                              kind='linear')
            result = np.exp(interp(np.log(energy.to(
                x.unit).value))) * spec.unit

        return result

    def evaluate(self, energy, **kwargs):
        """Evaluate model at given coordinates"""

        rotation = kwargs.pop("rotation")
        tmax = kwargs.pop("tmax")
        smooth = kwargs.pop("smooth", True)
        bias = kwargs.pop("bias")

        # change max delay time
        if not tmax == self.cascmap.tmax:
            self.cascmap.tmax = tmax

        # change rotation angle
        # and apply rotation
        if not rotation == self.cascmap.angle:
            self.cascmap.angle = rotation

        # calculate flux from observed point source specturm
        # first the ebl contribution
        # and remove parameters from kwargs that belong to the EBL model
        kwargs_ebl = {}
        for k in self._ebl.parameters.names:
            kwargs_ebl[k] = kwargs.pop(k)

        result = self._ebl.evaluate(energy * (1. + bias), **kwargs_ebl)
        result *= self._intrinsic_spectral_model.evaluate(
            energy * (1. + bias), **kwargs)

        # change spectral weights
        self.cascmap.apply_spectral_weights(injspec=self._inj_spec,
                                            smooth=smooth,
                                            force_recompute=True,
                                            **kwargs)

        is_cached_coord = [
            _ is coord for _, coord in zip(energy, self._cached_coordinates)
        ]

        # reset cache
        if not np.all(is_cached_coord):
            self._cached_value = None

        if self._cached_weights is not None and \
                not np.all(np.equal(self.cascmap.weights, self._cached_weights)):
            self._cached_weights = None

        if self._cached_value is None or self._cached_weights is None:
            self._cached_coordinates = energy
            self._cached_value = self._interpolate(energy * (1. + bias))
            self._cached_weights = self.cascmap.weights

        if self.add_primary:
            result += self._cached_value.to(result.unit)
        else:
            result = self._cached_value.to(result.unit)

        return result

    def copy(self):
        """A shallow copy"""
        new = copy.copy(self)
        return new

    @property
    def parameters(self):
        return (Parameters([self.rotation, self.tmax, self.bias]) +
                self._intrinsic_spectral_model.parameters +
                self._ebl.parameters)

    def to_dict(self):
        data = super().to_dict()
        data["name"] = self.name
        data["type"] = data.pop("type")
        data["spectral_model"] = self.spectral_model.to_dict()
        data["parameters"] = Parameters([self.rotation, self.tmax]).to_dict()

        if self.apply_irf != self._apply_irf_default:
            data["apply_irf"] = self.apply_irf

        return data

    def __str__(self):
        str_ = self.__class__.__name__ + "\n\n"
        str_ += "\tParameters:\n"
        info = _get_parameters_str(self.parameters)
        lines = info.split("\n")
        str_ += "\t" + "\n\t".join(lines[:-1])

        str_ += "\n\n"
        return str_.expandtabs(tabsize=2)
Exemple #7
0
 def __init__(self, m1, a=1, y=99):
     self.m1 = m1
     parameters = [Parameter("a", a), Parameter("y", y)]
     super()._init_from_parameters(parameters)