1 | # Licensed under a 3-clause BSD style license - see LICENSE.rst |
||
2 | """Utilities to compute J-factor maps.""" |
||
3 | from __future__ import absolute_import, division, print_function, unicode_literals |
||
4 | import numpy as np |
||
5 | import astropy.units as u |
||
6 | |||
7 | __all__ = ["JFactory", "compute_dm_flux"] |
||
8 | |||
9 | |||
10 | class JFactory(object): |
||
0 ignored issues
–
show
Unused Code
introduced
by
Loading history...
|
|||
11 | """Compute J-Factor maps. |
||
12 | |||
13 | All J-Factors are computed for annihilation. The assumed dark matter |
||
14 | profiles will be centered on the center of the map. |
||
15 | |||
16 | Parameters |
||
17 | ---------- |
||
18 | geom : `~gammapy.maps.WcsGeom` |
||
19 | Reference geometry |
||
20 | profile : `~gammapy.astro.darkmatter.profiles.DMProfile` |
||
21 | Dark matter profile |
||
22 | distance : `~astropy.units.Quantity` |
||
23 | Distance to convert angular scale of the map |
||
24 | """ |
||
25 | |||
26 | def __init__(self, geom, profile, distance): |
||
27 | self.geom = geom |
||
28 | self.profile = profile |
||
29 | self.distance = distance |
||
30 | |||
31 | def compute_differential_jfactor(self): |
||
32 | r"""Compute differential J-Factor. |
||
33 | |||
34 | .. math :: |
||
35 | \frac{\mathrm d J}{\mathrm d \Omega} = |
||
36 | \int_{\mathrm{LoS}} \mathrm d r \rho(r) |
||
37 | """ |
||
38 | # TODO: Needs to be implemented more efficiently |
||
0 ignored issues
–
show
|
|||
39 | separation = self.geom.separation(self.geom.center_skydir) |
||
40 | rmin = separation.rad * self.distance |
||
41 | rmax = self.distance |
||
42 | val = [self.profile.integral(_, rmax) for _ in rmin.flatten()] |
||
43 | jfact = u.Quantity(val).to("GeV2 cm-5").reshape(rmin.shape) |
||
44 | return jfact / u.steradian |
||
0 ignored issues
–
show
|
|||
45 | |||
46 | def compute_jfactor(self): |
||
47 | r"""Compute astrophysical J-Factor. |
||
48 | |||
49 | .. math :: |
||
50 | J(\Delta\Omega) = |
||
51 | \int_{\Delta\Omega} \mathrm d \Omega^{\prime} |
||
52 | \frac{\mathrm d J}{\mathrm d \Omega^{\prime}} |
||
53 | """ |
||
54 | diff_jfact = self.compute_differential_jfactor() |
||
55 | return diff_jfact * self.geom.to_image().solid_angle() |
||
56 | |||
57 | |||
58 | def compute_dm_flux(jfact, prim_flux, x_section, energy_range): |
||
59 | r"""Create dark matter flux maps. |
||
60 | |||
61 | The gamma-ray flux is computed as follows: |
||
62 | |||
63 | .. math:: |
||
64 | |||
65 | \frac{\mathrm d \phi}{\mathrm d E \mathrm d\Omega} = |
||
66 | \frac{\langle \sigma\nu \rangle}{8\pi m^2_{\mathrm{DM}}} |
||
67 | \frac{\mathrm d N}{\mathrm dE} \times J(\Delta\Omega) |
||
68 | |||
69 | Parameters |
||
70 | ---------- |
||
71 | jfact : `~astropy.units.Quantity` |
||
72 | J-Factor as computed by `~gammapy.astro.darkmatter.JFactory` |
||
73 | prim_flux : `~gammapy.astro.darkmatter.PrimaryFlux` |
||
74 | Primary gamma-ray flux |
||
75 | x_section : `~astropy.units.Quantity` |
||
76 | Velocity averaged annihilation cross section, :math:`\langle \sigma\nu\rangle` |
||
77 | energy_range : tuple of `~astropy.units.Quantity` |
||
78 | Energy range for the map |
||
79 | |||
80 | Returns |
||
81 | ------- |
||
82 | flux : `~astropy.units.Quantity` |
||
83 | DM Flux |
||
84 | |||
85 | References |
||
86 | ---------- |
||
87 | * `2011JCAP...03..051 <http://adsabs.harvard.edu/abs/2011JCAP...03..051>`_ |
||
88 | """ |
||
89 | prefactor = x_section / (8 * np.pi * prim_flux.mDM ** 2) |
||
90 | int_flux = prim_flux.table_model.integral( |
||
91 | emin=energy_range[0], emax=energy_range[1] |
||
92 | ) |
||
93 | return (jfact * prefactor * int_flux).to("cm-2 s-1") |
||
94 |