/
crab.py
141 lines (111 loc) · 4.55 KB
/
crab.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# Licensed under a 3-clause BSD style license - see LICENSE.rst
import numpy as np
from astropy import units as u
from ..utils.fitting import Parameters
from .models import PowerLaw, LogParabola, ExponentialCutoffPowerLaw, SpectralModel
__all__ = ["CrabSpectrum"]
# HESS publication: 2006A&A...457..899A
hess_pl = {
"amplitude": 3.45e-11 * u.Unit("1 / (cm2 s TeV)"),
"index": 2.63,
"reference": 1 * u.TeV,
}
hess_ecpl = {
"amplitude": 3.76e-11 * u.Unit("1 / (cm2 s TeV)"),
"index": 2.39,
"lambda_": 1 / (14.3 * u.TeV),
"reference": 1 * u.TeV,
}
# HEGRA publication : 2004ApJ...614..897A
hegra = {
"amplitude": 2.83e-11 * u.Unit("1 / (cm2 s TeV)"),
"index": 2.62,
"reference": 1 * u.TeV,
}
# MAGIC publication: 2015JHEAp...5...30A
# note that in the paper the beta of the LogParabola is given as negative in
# Table 1 (pag. 33), but should be positive to match gammapy LogParabola expression
# Also MAGIC uses log10 in the LogParabola expression, gammapy uses ln, hence
# the conversion factor
magic_lp = {
"amplitude": 3.23e-11 * u.Unit("1 / (cm2 s TeV)"),
"alpha": 2.47,
"beta": 0.24 / np.log(10),
"reference": 1 * u.TeV,
}
magic_ecpl = {
"amplitude": 3.80e-11 * u.Unit("1 / (cm2 s TeV)"),
"index": 2.21,
"lambda_": 1 / (6.0 * u.TeV),
"reference": 1 * u.TeV,
}
class MeyerCrabModel(SpectralModel):
"""Meyer 2010 log polynomial Crab spectral model.
See 2010A%26A...523A...2M, Appendix D.
"""
coefficients = np.array([-0.00449161, 0, 0.0473174, -0.179475, -0.53616, -10.2708])
def __init__(self):
self._parameters = Parameters()
@staticmethod
def evaluate(energy):
polynomial = np.poly1d(MeyerCrabModel.coefficients)
log_energy = np.log10(energy.to_value("TeV"))
log_flux = polynomial(log_energy)
flux = u.Quantity(np.power(10, log_flux), "erg / (cm2 s)", copy=False)
return flux / energy ** 2
class CrabSpectrum:
"""Crab nebula spectral model.
The Crab nebula is often used as a standard candle in gamma-ray astronomy.
Fluxes and sensitivities are often quoted relative to the Crab spectrum.
The following references are available:
* 'meyer', http://adsabs.harvard.edu/abs/2010A%26A...523A...2M, Appendix D
* 'hegra', http://adsabs.harvard.edu/abs/2000ApJ...539..317A
* 'hess_pl' and 'hess_ecpl': http://adsabs.harvard.edu/abs/2006A%26A...457..899A
* 'magic_lp' and 'magic_ecpl': http://adsabs.harvard.edu/abs/2015JHEAp...5...30A
Parameters
----------
reference : {'meyer', 'hegra', 'hess_pl', 'hess_ecpl', 'magic_lp', 'magic_ecpl'}
Which reference to use for the spectral model.
Examples
--------
Let's first import what we need::
import astropy.units as u
from gammapy.spectrum import CrabSpectrum
from gammapy.spectrum.models import PowerLaw
Plot the 'hess_ecpl' reference Crab spectrum between 1 TeV and 100 TeV::
crab_hess_ecpl = CrabSpectrum('hess_ecpl')
crab_hess_ecpl.model.plot([1, 100] * u.TeV)
Use a reference crab spectrum as unit to measure a differential flux (at 10 TeV)::
>>> pwl = PowerLaw(index=2.3, amplitude=1e-12 * u.Unit('1 / (cm2 s TeV)'), reference=1 * u.TeV)
>>> crab = CrabSpectrum('hess_pl').model
>>> energy = 10 * u.TeV
>>> dnde_cu = (pwl(energy) / crab(energy)).to('%')
>>> print(dnde_cu)
6.19699156377 %
And the same for integral fluxes (between 1 and 10 TeV)::
>>> # compute integral flux in crab units
>>> emin, emax = [1, 10] * u.TeV
>>> flux_int_cu = (pwl.integral(emin, emax) / crab.integral(emin, emax)).to('%')
>>> print(flux_int_cu)
3.5350582166 %
"""
references = ["meyer", "hegra", "hess_pl", "hess_ecpl", "magic_lp", "magic_ecpl"]
"""Available references (see class docstring)."""
def __init__(self, reference="meyer"):
if reference == "meyer":
model = MeyerCrabModel()
elif reference == "hegra":
model = PowerLaw(**hegra)
elif reference == "hess_pl":
model = PowerLaw(**hess_pl)
elif reference == "hess_ecpl":
model = ExponentialCutoffPowerLaw(**hess_ecpl)
elif reference == "magic_lp":
model = LogParabola(**magic_lp)
elif reference == "magic_ecpl":
model = ExponentialCutoffPowerLaw(**magic_ecpl)
else:
fmt = "Invalid reference: {!r}. Choices: {!r}"
raise ValueError(fmt.format(reference, self.references))
self.model = model
self.reference = reference