Passed
Pull Request — master (#1918)
by Christoph
05:37
created

gammapy/astro/darkmatter/spectra.py (3 issues)

1
# Licensed under a 3-clause BSD style license - see LICENSE.rst
2
"""Dark matter spectra."""
3
from __future__ import absolute_import, division, print_function, unicode_literals
4
import numpy as np
5
from astropy.units import Quantity
6
from astropy.table import Table
7
from astropy.utils import lazyproperty
8
from ...utils.scripts import make_path
9
from ...spectrum.models import TableModel
10
11
__all__ = ["PrimaryFlux"]
12
13
14
class PrimaryFlux(object):
0 ignored issues
show
The variable __class__ seems to be unused.
Loading history...
15
    """DM-annihilation gamma-ray spectra.
16
17
    Based on the precomputed models by `Cirelli et al.
18
    <http://www.marcocirelli.net/PPPC4DMID.html>`_. All available
19
    annihilation channels can be found there. The dark matter mass will be set
20
    to the nearest available value. The spectra will be available as
21
    `~gammapy.spectrum.models.TableModel` for a chosen dark matter mass and
22
    annihilation channel.
23
24
    References
25
    ----------
26
    * `2011JCAP...03..051 <http://adsabs.harvard.edu/abs/2011JCAP...03..051>`_
27
    """
28
29
    channel_registry = {
30
        "eL": "eL",
31
        "eR": "eR",
32
        "e": "e",
33
        "muL": "\\[Mu]L",
34
        "muR": "\\[Mu]R",
35
        "mu": "\\[Mu]",
36
        "tauL": "\\[Tau]L",
37
        "tauR": "\\[Tau]R",
38
        "tau": "\\[Tau]",
39
        "q": "q",
40
        "c": "c",
41
        "b": "b",
42
        "t": "t",
43
        "WL": "WL",
44
        "WT": "WT",
45
        "W": "W",
46
        "ZL": "ZL",
47
        "ZT": "ZT",
48
        "Z": "Z",
49
        "g": "g",
50
        "gamma": "\\[Gamma]",
51
        "h": "h",
52
        "nu_e": "\\[Nu]e",
53
        "nu_mu": "\\[Nu]\\[Mu]",
54
        "nu_tau": "\\[Nu]\\[Tau]",
55
        "V->e": "V->e",
56
        "V->mu": "V->\\[Mu]",
57
        "V->tau": "V->\\[Tau]",
58
    }
59
60
    def __init__(self, mDM, channel):
61
        self.mDM = mDM
62
        self.channel = channel
63
64
    @lazyproperty
65
    def table(self):
66
        """Lookup table (`~astropy.table.Table`)."""
67
        filename = "$GAMMAPY_DATA/dark_matter_spectra/AtProduction_gammas.dat"
68
        return Table.read(
69
            str(make_path(filename)),
70
            format="ascii.fast_basic",
71
            guess=False,
72
            delimiter=" ",
73
        )
74
75
    @property
76
    def mDM(self):
77
        """Dark matter mass."""
78
        return self._mDM
79
80
    @mDM.setter
81
    def mDM(self, mDM):
82
        mDM_vals = self.table["mDM"].data
83
        mDM_ = Quantity(mDM).to_value("GeV")
84
        interp_idx = np.argmin(np.abs(mDM_vals - mDM_))
85
        self._mDM = Quantity(mDM_vals[interp_idx], "GeV")
0 ignored issues
show
The attribute _mDM was defined outside __init__.

It is generally a good practice to initialize all attributes to default values in the __init__ method:

class Foo:
    def __init__(self, x=None):
        self.x = x
Loading history...
86
87
    @property
88
    def allowed_channels(self):
89
        """List of allowed annihilation channels."""
90
        return list(self.channel_registry.keys())
91
92
    @property
93
    def channel(self):
94
        """Annihilation channel (str)."""
95
        return self._channel
96
97
    @channel.setter
98
    def channel(self, channel):
99
        if channel not in self.allowed_channels:
100
            msg = "Invalid channel {}\n"
101
            msg += "Available: {}\n"
102
            raise ValueError(msg.format(channel, self.allowed_channels))
103
        else:
104
            self._channel = channel
0 ignored issues
show
The attribute _channel was defined outside __init__.

It is generally a good practice to initialize all attributes to default values in the __init__ method:

class Foo:
    def __init__(self, x=None):
        self.x = x
Loading history...
105
106
    @property
107
    def table_model(self):
108
        """Spectrum as `~gammapy.spectrum.models.TableModel`."""
109
        subtable = self.table[self.table["mDM"] == self.mDM.value]
110
        energies = (10 ** subtable["Log[10,x]"]) * self.mDM
111
        channel_name = self.channel_registry[self.channel]
112
        dN_dlogx = subtable[channel_name]
113
        dN_dE = dN_dlogx / (energies * np.log(10))
114
115
        return TableModel(energy=energies, values=dN_dE, values_scale="lin")
116