Passed
Pull Request — master (#2033)
by
unknown
02:19
created

fixed_pointing_info_aligned()   A

Complexity

Conditions 1

Size

Total Lines 21
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 18
nop 1
dl 0
loc 21
rs 9.5
c 0
b 0
f 0
1
# Licensed under a 3-clause BSD style license - see LICENSE.rst
2
import pytest
3
import numpy as np
4
from numpy.testing import assert_allclose
5
from astropy import units as u
6
from astropy.coordinates import SkyCoord, EarthLocation
7
from astropy.time import Time
8
from ...utils.testing import requires_data
9
from ...maps import WcsGeom, HpxGeom, MapAxis
10
from ...irf import Background3D
11
from ..background import make_map_background_irf
12
from ...data.pointing import FixedPointingInfo
13
14
pytest.importorskip("healpy")
15
16
17
@pytest.fixture(scope="session")
18
def fixed_pointing_info():
19
    filename = (
20
        "$GAMMAPY_DATA/cta-1dc/data/baseline/gps/gps_baseline_110380.fits"
21
    )
22
    return FixedPointingInfo.read(filename)
23
24
25
@pytest.fixture(scope="session")
26
def fixed_pointing_info_aligned(fixed_pointing_info):
27
    # Create Fixed Pointing Info aligined between sky and horizon coordinates
28
    # (removes rotation in FoV and results in predictable solid angles)
29
    origin = SkyCoord(
30
        0, 0,
31
        unit='deg', frame='icrs',
32
        location=EarthLocation(lat=90*u.deg, lon=0*u.deg),
33
        obstime=Time('2000-9-21 12:00:00')
34
    )
35
    fpi = fixed_pointing_info
36
    meta = fpi.meta.copy()
37
    meta['RA_PNT'] = origin.icrs.ra
38
    meta['DEC_PNT'] = origin.icrs.dec
39
    meta['GEOLON'] = origin.location.lon
40
    meta['GEOLAT'] = origin.location.lat
41
    meta['ALTITUDE'] = origin.location.height
42
    time_start = origin.obstime.datetime - fpi.time_ref.datetime
43
    meta['TSTART'] = time_start.total_seconds()
44
    meta['TSTOP'] = meta['TSTART'] + 60
45
    return FixedPointingInfo(meta)
46
47
48
@pytest.fixture(scope="session")
49
def bkg_3d():
50
    filename = (
51
        "$GAMMAPY_DATA/cta-1dc/caldb/data/cta/1dc/bcf/South_z20_50h/irf_file.fits"
52
    )
53
    return Background3D.read(filename, hdu="BACKGROUND")
54
55
56
def bkg_3d_custom(symmetry='constant'):
57
    if symmetry == 'constant':
58
        data = np.ones((2, 3, 3)) * u.Unit("s-1 MeV-1 sr-1")
59
    elif symmetry == 'symmetric':
60
        data = np.ones((2, 3, 3)) * u.Unit("s-1 MeV-1 sr-1")
61
        data[:, 1, 1] *= 2
62
    elif symmetry == 'asymmetric':
63
        data = np.indices((3, 3))[1] + 1
64
        data = np.stack(2 * [data]) * u.Unit("s-1 MeV-1 sr-1")
65
    else:
66
        raise ValueError("Unkown value for symmetry: {}".format(symmetry))
67
68
    energy = [0.1, 10, 1000] * u.TeV
69
    fov_lon = [-3, -1, 1, 3] * u.deg
70
    fov_lat = [-3, -1, 1, 3] * u.deg
71
    return Background3D(
72
        energy_lo=energy[:-1],
73
        energy_hi=energy[1:],
74
        fov_lon_lo=fov_lon[:-1],
75
        fov_lon_hi=fov_lon[1:],
76
        fov_lat_lo=fov_lat[:-1],
77
        fov_lat_hi=fov_lat[1:],
78
        data=data,
79
    )
80
81
82
def make_map_background_irf_with_symmetry(fpi, symmetry='constant'):
83
    axis = MapAxis.from_edges(
84
        [0.1, 1, 10], name="energy", unit="TeV", interp="log"
85
    )
86
    return make_map_background_irf(
87
        pointing=fpi,
88
        ontime="42 s",
89
        bkg=bkg_3d_custom(symmetry),
90
        geom=WcsGeom.create(
91
            npix=(3, 3),
92
            binsz=4,
93
            axes=[axis],
94
            skydir=fpi.radec
95
        ),
96
    )
97
98
99
def geom(map_type, ebounds, skydir):
100
    axis = MapAxis.from_edges(ebounds, name="energy", unit="TeV", interp="log")
101
    if map_type == "wcs":
102
        return WcsGeom.create(npix=(4, 3), binsz=2, axes=[axis], skydir=skydir)
103
    elif map_type == "hpx":
104
        return HpxGeom(256, axes=[axis])
105
    else:
106
        raise ValueError()
107
108
109
@requires_data("gammapy-data")
110
@pytest.mark.parametrize(
111
    "pars",
112
    [
113
        {
114
            "map_type": "wcs",
115
            "ebounds": [0.1, 1, 10],
116
            "shape": (2, 3, 4),
117
            "sum": 940.167672,
118
        },
119
        {
120
            "map_type": "wcs",
121
            "ebounds": [0.1, 10],
122
            "shape": (1, 3, 4),
123
            "sum": 1019.495516,
124
        },
125
        # TODO: make this work for HPX
126
        # 'HpxGeom' object has no attribute 'separation'
127
        # {
128
        #     'geom': geom(map_type='hpx', ebounds=[0.1, 1, 10]),
129
        #     'shape': '???',
130
        #     'sum': '???',
131
        # },
132
    ],
133
)
134
135
def test_make_map_background_irf(bkg_3d, pars, fixed_pointing_info):
136
    m = make_map_background_irf(
137
        pointing=fixed_pointing_info,
138
        ontime="42 s",
139
        bkg=bkg_3d,
140
        geom=geom(
141
            map_type=pars['map_type'],
142
            ebounds=pars['ebounds'],
143
            skydir=fixed_pointing_info.radec
144
        ),
145
    )
146
147
    assert m.data.shape == pars["shape"]
148
    assert m.unit == ""
149
    assert_allclose(m.data.sum(), pars["sum"], rtol=1e-5)
150
151
152
def test_make_map_background_irf_constant(fixed_pointing_info_aligned):
153
    m = make_map_background_irf_with_symmetry(
154
        fpi=fixed_pointing_info_aligned, symmetry='constant'
155
    )
156
    for d in m.data:
157
        assert_allclose(d[1, :], d[1, 0])  # Constant along lon
158
        assert_allclose(d[0, 1], d[2, 1])  # Symmetric along lat
159
        with pytest.raises(AssertionError):
160
            # Not constant along lat due to changes in
161
            # solid angle (great circle)
162
            assert_allclose(d[:, 1], d[0, 1])
163
164
165
def test_make_map_background_irf_sym(fixed_pointing_info_aligned):
166
    m = make_map_background_irf_with_symmetry(
167
        fpi=fixed_pointing_info_aligned, symmetry='symmetric'
168
    )
169
    for d in m.data:
170
        assert_allclose(d[1, 0], d[1, 2], rtol=1e-4)  # Symmetric along lon
171
        assert_allclose(d[0, 1], d[2, 1], rtol=1e-4)  # Symmetric along lat
172
173
174
def test_make_map_background_irf_asym(fixed_pointing_info_aligned):
175
    m = make_map_background_irf_with_symmetry(
176
        fpi=fixed_pointing_info_aligned, symmetry='asymmetric'
177
    )
178
    for d in m.data:
179
        # TODO:
180
        #  Dimensions of skymap data are [energy, lat, lon] (and is
181
        #  representated as [lon, lat, energy] in the api, but the bkg irf
182
        #  dimensions are currently [energy, lon, lat] - Will be changed in
183
        #  the future (perhaps when IRFs use the skymaps class)
184
        assert_allclose(d[1, 0], d[1, 2], rtol=1e-4)  # Symmetric along lon
185
        with pytest.raises(AssertionError):
186
            assert_allclose(d[0, 1], d[2, 1], rtol=1e-4)  # Symmetric along lat
187
        assert_allclose(d[0, 1]*9, d[2, 1], rtol=1e-4)  # Asymmetric along lat
188