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.time import Time |
||
7 | from astropy.utils.data import get_pkg_data_filename |
||
8 | from gammapy.catalog import ( |
||
9 | SourceCatalog2FHL, |
||
10 | SourceCatalog3FGL, |
||
11 | SourceCatalog3FHL, |
||
12 | SourceCatalog4FGL, |
||
13 | ) |
||
14 | from gammapy.modeling.models import ( |
||
15 | ExpCutoffPowerLaw3FGLSpectralModel, |
||
16 | LogParabolaSpectralModel, |
||
17 | PowerLaw2SpectralModel, |
||
18 | PowerLawSpectralModel, |
||
19 | SuperExpCutoffPowerLaw3FGLSpectralModel, |
||
20 | SuperExpCutoffPowerLaw4FGLSpectralModel, |
||
21 | ) |
||
22 | from gammapy.utils.gauss import Gauss2DPDF |
||
23 | from gammapy.utils.testing import ( |
||
24 | assert_quantity_allclose, |
||
25 | assert_time_allclose, |
||
26 | requires_data, |
||
27 | ) |
||
28 | |||
29 | SOURCES_4FGL = [ |
||
30 | dict( |
||
31 | idx=0, |
||
32 | name="4FGL J0000.3-7355", |
||
33 | str_ref_file="data/4fgl_J0000.3-7355.txt", |
||
34 | spec_type=PowerLawSpectralModel, |
||
35 | dnde=u.Quantity(2.9476e-11, "cm-2 s-1 GeV-1"), |
||
36 | dnde_err=u.Quantity(5.3318e-12, "cm-2 s-1 GeV-1"), |
||
37 | ), |
||
38 | dict( |
||
39 | idx=3, |
||
40 | name="4FGL J0001.5+2113", |
||
41 | str_ref_file="data/4fgl_J0001.5+2113.txt", |
||
42 | spec_type=LogParabolaSpectralModel, |
||
43 | dnde=u.Quantity(2.8545e-8, "cm-2 s-1 GeV-1"), |
||
44 | dnde_err=u.Quantity(1.3324e-9, "cm-2 s-1 GeV-1"), |
||
45 | ), |
||
46 | dict( |
||
47 | idx=7, |
||
48 | name="4FGL J0002.8+6217", |
||
49 | str_ref_file="data/4fgl_J0002.8+6217.txt", |
||
50 | spec_type=SuperExpCutoffPowerLaw4FGLSpectralModel, |
||
51 | dnde=u.Quantity(2.084e-09, "cm-2 s-1 GeV-1"), |
||
52 | dnde_err=u.Quantity(1.0885e-10, "cm-2 s-1 GeV-1"), |
||
53 | ), |
||
54 | dict( |
||
55 | idx=2718, |
||
56 | name="4FGL J1409.1-6121e", |
||
57 | str_ref_file="data/4fgl_J1409.1-6121e.txt", |
||
58 | spec_type=LogParabolaSpectralModel, |
||
59 | dnde=u.Quantity(1.3237202133031811e-12, "cm-2 s-1 MeV-1"), |
||
60 | dnde_err=u.Quantity(4.513233455580648e-14, "cm-2 s-1 MeV-1"), |
||
61 | ), |
||
62 | ] |
||
63 | |||
64 | SOURCES_3FGL = [ |
||
65 | dict( |
||
66 | idx=0, |
||
67 | name="3FGL J0000.1+6545", |
||
68 | str_ref_file="data/3fgl_J0000.1+6545.txt", |
||
69 | spec_type=PowerLawSpectralModel, |
||
70 | dnde=u.Quantity(1.4351261e-9, "cm-2 s-1 GeV-1"), |
||
71 | dnde_err=u.Quantity(2.1356270e-10, "cm-2 s-1 GeV-1"), |
||
72 | ), |
||
73 | dict( |
||
74 | idx=4, |
||
75 | name="3FGL J0001.4+2120", |
||
76 | str_ref_file="data/3fgl_J0001.4+2120.txt", |
||
77 | spec_type=LogParabolaSpectralModel, |
||
78 | dnde=u.Quantity(8.3828599e-10, "cm-2 s-1 GeV-1"), |
||
79 | dnde_err=u.Quantity(2.6713238e-10, "cm-2 s-1 GeV-1"), |
||
80 | ), |
||
81 | dict( |
||
82 | idx=55, |
||
83 | name="3FGL J0023.4+0923", |
||
84 | str_ref_file="data/3fgl_J0023.4+0923.txt", |
||
85 | spec_type=ExpCutoffPowerLaw3FGLSpectralModel, |
||
86 | dnde=u.Quantity(1.8666925e-09, "cm-2 s-1 GeV-1"), |
||
87 | dnde_err=u.Quantity(2.2068837e-10, "cm-2 s-1 GeV-1"), |
||
88 | ), |
||
89 | dict( |
||
90 | idx=960, |
||
91 | name="3FGL J0835.3-4510", |
||
92 | str_ref_file="data/3fgl_J0835.3-4510.txt", |
||
93 | spec_type=SuperExpCutoffPowerLaw3FGLSpectralModel, |
||
94 | dnde=u.Quantity(1.6547128794756733e-06, "cm-2 s-1 GeV-1"), |
||
95 | dnde_err=u.Quantity(1.6621504e-11, "cm-2 s-1 MeV-1"), |
||
96 | ), |
||
97 | ] |
||
98 | |||
99 | SOURCES_2FHL = [ |
||
100 | dict( |
||
101 | idx=221, |
||
102 | name="2FHL J1445.1-0329", |
||
103 | str_ref_file="data/2fhl_j1445.1-0329.txt", |
||
104 | spec_type=PowerLaw2SpectralModel, |
||
105 | dnde=u.Quantity(1.065463448091757e-10, "cm-2 s-1 TeV-1"), |
||
106 | dnde_err=u.Quantity(4.9691205387540815e-11, "cm-2 s-1 TeV-1"), |
||
107 | ), |
||
108 | dict( |
||
109 | idx=134, |
||
110 | name="2FHL J0822.6-4250e", |
||
111 | str_ref_file="data/2fhl_j0822.6-4250e.txt", |
||
112 | spec_type=LogParabolaSpectralModel, |
||
113 | dnde=u.Quantity(2.46548351696472e-10, "cm-2 s-1 TeV-1"), |
||
114 | dnde_err=u.Quantity(9.771755529198772e-11, "cm-2 s-1 TeV-1"), |
||
115 | ), |
||
116 | ] |
||
117 | |||
118 | SOURCES_3FHL = [ |
||
119 | dict( |
||
120 | idx=352, |
||
121 | name="3FHL J0534.5+2201", |
||
122 | spec_type=PowerLawSpectralModel, |
||
123 | dnde=u.Quantity(6.3848912826152664e-12, "cm-2 s-1 GeV-1"), |
||
124 | dnde_err=u.Quantity(2.679593524691324e-13, "cm-2 s-1 GeV-1"), |
||
125 | ), |
||
126 | dict( |
||
127 | idx=1442, |
||
128 | name="3FHL J2158.8-3013", |
||
129 | spec_type=LogParabolaSpectralModel, |
||
130 | dnde=u.Quantity(2.056998292908196e-12, "cm-2 s-1 GeV-1"), |
||
131 | dnde_err=u.Quantity(4.219030630302381e-13, "cm-2 s-1 GeV-1"), |
||
132 | ), |
||
133 | ] |
||
134 | |||
135 | |||
136 | @requires_data() |
||
137 | def test_4FGL_DR3(): |
||
138 | cat = SourceCatalog4FGL("$GAMMAPY_DATA/catalogs/fermi/gll_psc_v28.fit.gz") |
||
139 | source = cat["4FGL J0534.5+2200"] |
||
140 | model = source.spectral_model() |
||
141 | fp = source.flux_points |
||
142 | not_ul = ~fp.is_ul.data.squeeze() |
||
143 | fp_dnde = fp.dnde.quantity.squeeze()[not_ul] |
||
144 | model_dnde = model(fp.energy_ref[not_ul]) |
||
145 | assert_quantity_allclose(model_dnde, fp_dnde, rtol=0.07) |
||
146 | |||
147 | |||
148 | @requires_data() |
||
149 | class TestFermi4FGLObject: |
||
150 | @classmethod |
||
151 | def setup_class(cls): |
||
152 | cls.cat = SourceCatalog4FGL("$GAMMAPY_DATA/catalogs/fermi/gll_psc_v20.fit.gz") |
||
153 | cls.source_name = "4FGL J0534.5+2200" |
||
154 | cls.source = cls.cat[cls.source_name] |
||
155 | |||
156 | def test_name(self): |
||
157 | assert self.source.name == self.source_name |
||
158 | |||
159 | def test_row_index(self): |
||
160 | assert self.source.row_index == 995 |
||
161 | |||
162 | @pytest.mark.parametrize("ref", SOURCES_4FGL, ids=lambda _: _["name"]) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Loading history...
|
|||
163 | def test_str(self, ref): |
||
164 | actual = str(self.cat[ref["idx"]]) |
||
165 | expected = open(get_pkg_data_filename(ref["str_ref_file"])).read() |
||
166 | assert actual == expected |
||
167 | |||
168 | @pytest.mark.parametrize("ref", SOURCES_4FGL, ids=lambda _: _["name"]) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
169 | def test_spectral_model(self, ref): |
||
170 | model = self.cat[ref["idx"]].spectral_model() |
||
171 | |||
172 | e_ref = model.reference.quantity |
||
173 | dnde, dnde_err = model.evaluate_error(e_ref) |
||
174 | assert isinstance(model, ref["spec_type"]) |
||
175 | assert_quantity_allclose(dnde, ref["dnde"], rtol=1e-4) |
||
176 | assert_quantity_allclose(dnde_err, ref["dnde_err"], rtol=1e-4) |
||
177 | |||
178 | View Code Duplication | def test_spatial_model(self): |
|
0 ignored issues
–
show
|
|||
179 | model = self.cat["4FGL J0000.3-7355"].spatial_model() |
||
180 | assert "PointSpatialModel" in model.tag |
||
181 | assert model.frame == "icrs" |
||
182 | p = model.parameters |
||
183 | assert_allclose(p["lon_0"].value, 0.0983) |
||
184 | assert_allclose(p["lat_0"].value, -73.921997) |
||
185 | pos_err = model.position_error |
||
186 | assert_allclose(pos_err.angle.value, -62.7) |
||
187 | assert_allclose(0.5 * pos_err.height.value, 0.0525, rtol=1e-4) |
||
188 | assert_allclose(0.5 * pos_err.width.value, 0.051, rtol=1e-4) |
||
189 | assert_allclose(model.position.ra.value, pos_err.center.ra.value) |
||
190 | assert_allclose(model.position.dec.value, pos_err.center.dec.value) |
||
191 | |||
192 | model = self.cat["4FGL J1409.1-6121e"].spatial_model() |
||
193 | assert "DiskSpatialModel" in model.tag |
||
194 | assert model.frame == "icrs" |
||
195 | p = model.parameters |
||
196 | assert_allclose(p["lon_0"].value, 212.294006) |
||
197 | assert_allclose(p["lat_0"].value, -61.353001) |
||
198 | assert_allclose(p["r_0"].value, 0.7331369519233704) |
||
199 | |||
200 | model = self.cat["4FGL J0617.2+2234e"].spatial_model() |
||
201 | assert "GaussianSpatialModel" in model.tag |
||
202 | assert model.frame == "icrs" |
||
203 | p = model.parameters |
||
204 | assert_allclose(p["lon_0"].value, 94.309998) |
||
205 | assert_allclose(p["lat_0"].value, 22.58) |
||
206 | assert_allclose(p["sigma"].value, 0.27) |
||
207 | |||
208 | model = self.cat["4FGL J1443.0-6227e"].spatial_model() |
||
209 | assert "TemplateSpatialModel" in model.tag |
||
210 | assert model.frame == "fk5" |
||
211 | assert model.normalize |
||
212 | |||
213 | @pytest.mark.parametrize("ref", SOURCES_4FGL, ids=lambda _: _["name"]) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
214 | def test_sky_model(self, ref): |
||
215 | self.cat[ref["idx"]].sky_model |
||
216 | |||
217 | def test_flux_points(self): |
||
218 | flux_points = self.source.flux_points |
||
219 | |||
220 | assert flux_points.norm.geom.axes["energy"].nbin == 7 |
||
221 | assert flux_points.norm_ul |
||
222 | |||
223 | desired = [ |
||
224 | 2.2378458e-06, |
||
225 | 1.4318283e-06, |
||
226 | 5.4776939e-07, |
||
227 | 1.2769708e-07, |
||
228 | 2.5820052e-08, |
||
229 | 2.3897000e-09, |
||
230 | 7.1766204e-11, |
||
231 | ] |
||
232 | assert_allclose(flux_points.flux.data.flat, desired, rtol=1e-5) |
||
233 | |||
234 | def test_flux_points_meta(self): |
||
235 | source = self.cat["4FGL J0000.3-7355"] |
||
236 | fp = source.flux_points |
||
237 | |||
238 | assert_allclose(fp.sqrt_ts_threshold_ul, 1) |
||
239 | assert_allclose(fp.n_sigma, 1) |
||
240 | assert_allclose(fp.n_sigma_ul, 2) |
||
241 | |||
242 | def test_flux_points_ul(self): |
||
243 | source = self.cat["4FGL J0000.3-7355"] |
||
244 | flux_points = source.flux_points |
||
245 | |||
246 | desired = [ |
||
247 | 4.13504750e-08, |
||
248 | 3.80519616e-09, |
||
249 | np.nan, |
||
250 | np.nan, |
||
251 | np.nan, |
||
252 | np.nan, |
||
253 | 7.99699456e-12, |
||
254 | ] |
||
255 | assert_allclose(flux_points.flux_ul.data.flat, desired, rtol=1e-5) |
||
256 | |||
257 | def test_lightcurve_dr1(self): |
||
258 | lc = self.source.lightcurve(interval="1-year") |
||
259 | table = lc.to_table(format="lightcurve", sed_type="flux") |
||
260 | |||
261 | assert len(table) == 8 |
||
262 | assert table.colnames == [ |
||
263 | "time_min", |
||
264 | "time_max", |
||
265 | "e_ref", |
||
266 | "e_min", |
||
267 | "e_max", |
||
268 | "flux", |
||
269 | "flux_errp", |
||
270 | "flux_errn", |
||
271 | "flux_ul", |
||
272 | "ts", |
||
273 | "sqrt_ts", |
||
274 | "is_ul", |
||
275 | ] |
||
276 | axis = lc.geom.axes["time"] |
||
277 | expected = Time(54682.6552835, format="mjd", scale="utc") |
||
278 | assert_time_allclose(axis.time_min[0].utc, expected) |
||
279 | |||
280 | expected = Time(55045.30090278, format="mjd", scale="utc") |
||
281 | assert_time_allclose(axis.time_max[0].utc, expected) |
||
282 | |||
283 | assert table["flux"].unit == "cm-2 s-1" |
||
284 | assert_allclose(table["flux"][0], 2.2122326e-06, rtol=1e-3) |
||
285 | |||
286 | assert table["flux_errp"].unit == "cm-2 s-1" |
||
287 | assert_allclose(table["flux_errp"][0], 2.3099371e-08, rtol=1e-3) |
||
288 | |||
289 | assert table["flux_errn"].unit == "cm-2 s-1" |
||
290 | assert_allclose(table["flux_errn"][0], 2.3099371e-08, rtol=1e-3) |
||
291 | |||
292 | table = self.source.lightcurve(interval="2-month").to_table( |
||
293 | format="lightcurve", sed_type="flux" |
||
294 | ) |
||
295 | assert len(table) == 48 # (12 month/year / 2month) * 8 years |
||
296 | |||
297 | assert table["flux"].unit == "cm-2 s-1" |
||
298 | assert_allclose(table["flux"][0], 2.238483e-6, rtol=1e-3) |
||
299 | |||
300 | assert table["flux_errp"].unit == "cm-2 s-1" |
||
301 | assert_allclose(table["flux_errp"][0], 4.437058e-8, rtol=1e-3) |
||
302 | |||
303 | assert table["flux_errn"].unit == "cm-2 s-1" |
||
304 | assert_allclose(table["flux_errn"][0], 4.437058e-8, rtol=1e-3) |
||
305 | |||
306 | def test_lightcurve_dr2(self): |
||
307 | dr2 = SourceCatalog4FGL("$GAMMAPY_DATA/catalogs/fermi/gll_psc_v27.fit.gz") |
||
308 | source_dr2 = dr2[self.source_name] |
||
309 | table = source_dr2.lightcurve(interval="1-year").to_table( |
||
310 | format="lightcurve", sed_type="flux" |
||
311 | ) |
||
312 | |||
313 | assert table["flux"].unit == "cm-2 s-1" |
||
314 | assert_allclose(table["flux"][0], 2.196788e-6, rtol=1e-3) |
||
315 | |||
316 | assert table["flux_errp"].unit == "cm-2 s-1" |
||
317 | assert_allclose(table["flux_errp"][0], 2.312938e-8, rtol=1e-3) |
||
318 | |||
319 | assert table["flux_errn"].unit == "cm-2 s-1" |
||
320 | assert_allclose(table["flux_errn"][0], 2.312938e-8, rtol=1e-3) |
||
321 | |||
322 | with pytest.raises(ValueError): |
||
323 | source_dr2.lightcurve(interval="2-month") |
||
324 | |||
325 | |||
326 | @requires_data() |
||
327 | class TestFermi3FGLObject: |
||
328 | @classmethod |
||
329 | def setup_class(cls): |
||
330 | cls.cat = SourceCatalog3FGL() |
||
331 | # Use 3FGL J0534.5+2201 (Crab) as a test source |
||
332 | cls.source_name = "3FGL J0534.5+2201" |
||
333 | cls.source = cls.cat[cls.source_name] |
||
334 | |||
335 | def test_name(self): |
||
336 | assert self.source.name == self.source_name |
||
337 | |||
338 | def test_row_index(self): |
||
339 | assert self.source.row_index == 621 |
||
340 | |||
341 | def test_data(self): |
||
342 | assert_allclose(self.source.data["Signif_Avg"], 30.669872283935547) |
||
343 | |||
344 | def test_position(self): |
||
345 | position = self.source.position |
||
346 | assert_allclose(position.ra.deg, 83.637199, atol=1e-3) |
||
347 | assert_allclose(position.dec.deg, 22.024099, atol=1e-3) |
||
348 | |||
349 | @pytest.mark.parametrize("ref", SOURCES_3FGL, ids=lambda _: _["name"]) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
350 | def test_str(self, ref): |
||
351 | actual = str(self.cat[ref["idx"]]) |
||
352 | expected = open(get_pkg_data_filename(ref["str_ref_file"])).read() |
||
353 | assert actual == expected |
||
354 | |||
355 | @pytest.mark.parametrize("ref", SOURCES_3FGL, ids=lambda _: _["name"]) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
356 | def test_spectral_model(self, ref): |
||
357 | model = self.cat[ref["idx"]].spectral_model() |
||
358 | |||
359 | dnde, dnde_err = model.evaluate_error(1 * u.GeV) |
||
360 | |||
361 | assert isinstance(model, ref["spec_type"]) |
||
362 | assert_quantity_allclose(dnde, ref["dnde"]) |
||
363 | assert_quantity_allclose(dnde_err, ref["dnde_err"], rtol=1e-3) |
||
364 | |||
365 | View Code Duplication | def test_spatial_model(self): |
|
0 ignored issues
–
show
|
|||
366 | model = self.cat[0].spatial_model() |
||
367 | assert "PointSpatialModel" in model.tag |
||
368 | assert model.frame == "icrs" |
||
369 | p = model.parameters |
||
370 | assert_allclose(p["lon_0"].value, 0.0377) |
||
371 | assert_allclose(p["lat_0"].value, 65.751701) |
||
372 | |||
373 | model = self.cat[122].spatial_model() |
||
374 | assert "GaussianSpatialModel" in model.tag |
||
375 | assert model.frame == "icrs" |
||
376 | p = model.parameters |
||
377 | assert_allclose(p["lon_0"].value, 14.75) |
||
378 | assert_allclose(p["lat_0"].value, -72.699997) |
||
379 | assert_allclose(p["sigma"].value, 1.35) |
||
380 | |||
381 | model = self.cat[955].spatial_model() |
||
382 | assert "DiskSpatialModel" in model.tag |
||
383 | assert model.frame == "icrs" |
||
384 | p = model.parameters |
||
385 | assert_allclose(p["lon_0"].value, 128.287201) |
||
386 | assert_allclose(p["lat_0"].value, -45.190102) |
||
387 | assert_allclose(p["r_0"].value, 0.91) |
||
388 | |||
389 | model = self.cat[602].spatial_model() |
||
390 | assert "TemplateSpatialModel" in model.tag |
||
391 | assert model.frame == "fk5" |
||
392 | assert model.normalize |
||
393 | |||
394 | model = self.cat["3FGL J0000.2-3738"].spatial_model() |
||
395 | pos_err = model.position_error |
||
396 | assert_allclose(pos_err.angle.value, -88.55) |
||
397 | assert_allclose(0.5 * pos_err.height.value, 0.0731, rtol=1e-4) |
||
398 | assert_allclose(0.5 * pos_err.width.value, 0.0676, rtol=1e-4) |
||
399 | assert_allclose(model.position.ra.value, pos_err.center.ra.value) |
||
400 | assert_allclose(model.position.dec.value, pos_err.center.dec.value) |
||
401 | |||
402 | @pytest.mark.parametrize("ref", SOURCES_3FGL, ids=lambda _: _["name"]) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
403 | def test_sky_model(self, ref): |
||
404 | self.cat[ref["idx"]].sky_model() |
||
405 | |||
406 | def test_flux_points(self): |
||
407 | flux_points = self.source.flux_points |
||
408 | |||
409 | assert flux_points.energy_axis.nbin == 5 |
||
410 | assert flux_points.norm_ul |
||
411 | |||
412 | desired = [1.645888e-06, 5.445407e-07, 1.255338e-07, 2.545524e-08, 2.263189e-09] |
||
413 | assert_allclose(flux_points.flux.data.flat, desired, rtol=1e-5) |
||
414 | |||
415 | def test_flux_points_ul(self): |
||
416 | source = self.cat["3FGL J0000.2-3738"] |
||
417 | flux_points = source.flux_points |
||
418 | |||
419 | desired = [4.096391e-09, 6.680059e-10, np.nan, np.nan, np.nan] |
||
420 | assert_allclose(flux_points.flux_ul.data.flat, desired, rtol=1e-5) |
||
421 | |||
422 | def test_lightcurve(self): |
||
423 | lc = self.source.lightcurve() |
||
424 | table = lc.to_table(format="lightcurve", sed_type="flux") |
||
425 | |||
426 | assert len(table) == 48 |
||
427 | assert table.colnames == [ |
||
428 | "time_min", |
||
429 | "time_max", |
||
430 | "e_ref", |
||
431 | "e_min", |
||
432 | "e_max", |
||
433 | "flux", |
||
434 | "flux_errp", |
||
435 | "flux_errn", |
||
436 | "flux_ul", |
||
437 | "is_ul", |
||
438 | ] |
||
439 | |||
440 | expected = Time(54680.02313657408, format="mjd", scale="utc") |
||
441 | axis = lc.geom.axes["time"] |
||
442 | assert_time_allclose(axis.time_min[0].utc, expected) |
||
443 | |||
444 | expected = Time(54710.46295139, format="mjd", scale="utc") |
||
445 | assert_time_allclose(axis.time_max[0].utc, expected) |
||
446 | |||
447 | assert table["flux"].unit == "cm-2 s-1" |
||
448 | assert_allclose(table["flux"][0], 2.384e-06, rtol=1e-3) |
||
449 | |||
450 | assert table["flux_errp"].unit == "cm-2 s-1" |
||
451 | assert_allclose(table["flux_errp"][0], 8.071e-08, rtol=1e-3) |
||
452 | |||
453 | assert table["flux_errn"].unit == "cm-2 s-1" |
||
454 | assert_allclose(table["flux_errn"][0], 8.071e-08, rtol=1e-3) |
||
455 | |||
456 | def test_crab_alias(self): |
||
457 | for name in [ |
||
458 | "Crab", |
||
459 | "3FGL J0534.5+2201", |
||
460 | "1FHL J0534.5+2201", |
||
461 | "PSR J0534+2200", |
||
462 | ]: |
||
463 | assert self.cat[name].row_index == 621 |
||
464 | |||
465 | |||
466 | @requires_data() |
||
467 | class TestFermi2FHLObject: |
||
468 | @classmethod |
||
469 | def setup_class(cls): |
||
470 | cls.cat = SourceCatalog2FHL() |
||
471 | # Use 2FHL J0534.5+2201 (Crab) as a test source |
||
472 | cls.source_name = "2FHL J0534.5+2201" |
||
473 | cls.source = cls.cat[cls.source_name] |
||
474 | |||
475 | def test_name(self): |
||
476 | assert self.source.name == self.source_name |
||
477 | |||
478 | def test_position(self): |
||
479 | position = self.source.position |
||
480 | assert_allclose(position.ra.deg, 83.634102, atol=1e-3) |
||
481 | assert_allclose(position.dec.deg, 22.0215, atol=1e-3) |
||
482 | |||
483 | @pytest.mark.parametrize("ref", SOURCES_2FHL, ids=lambda _: _["name"]) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
484 | def test_str(self, ref): |
||
485 | actual = str(self.cat[ref["idx"]]) |
||
486 | expected = open(get_pkg_data_filename(ref["str_ref_file"])).read() |
||
487 | assert actual == expected |
||
488 | |||
489 | def test_spectral_model(self): |
||
490 | model = self.source.spectral_model() |
||
491 | energy = u.Quantity(100, "GeV") |
||
492 | desired = u.Quantity(6.8700477298e-12, "cm-2 GeV-1 s-1") |
||
493 | assert_quantity_allclose(model(energy), desired) |
||
494 | |||
495 | def test_flux_points(self): |
||
496 | # test flux point on PKS 2155-304 |
||
497 | src = self.cat["PKS 2155-304"] |
||
498 | flux_points = src.flux_points |
||
499 | actual = flux_points.flux.quantity[:, 0, 0] |
||
500 | desired = [2.866363e-10, 6.118736e-11, 3.257970e-16] * u.Unit("cm-2 s-1") |
||
501 | assert_quantity_allclose(actual, desired) |
||
502 | |||
503 | actual = flux_points.flux_ul.quantity[:, 0, 0] |
||
504 | desired = [np.nan, np.nan, 1.294092e-11] * u.Unit("cm-2 s-1") |
||
505 | assert_quantity_allclose(actual, desired, rtol=1e-3) |
||
506 | |||
507 | def test_spatial_model(self): |
||
508 | model = self.cat[221].spatial_model() |
||
509 | assert "PointSpatialModel" in model.tag |
||
510 | assert model.frame == "icrs" |
||
511 | p = model.parameters |
||
512 | assert_allclose(p["lon_0"].value, 221.281998, rtol=1e-5) |
||
513 | assert_allclose(p["lat_0"].value, -3.4943, rtol=1e-5) |
||
514 | |||
515 | model = self.cat["2FHL J1304.5-4353"].spatial_model() |
||
516 | pos_err = model.position_error |
||
517 | scale = Gauss2DPDF().containment_radius(0.95) / Gauss2DPDF().containment_radius( |
||
518 | 0.68 |
||
519 | ) |
||
520 | assert_allclose(pos_err.height.value, 2 * 0.041987 * scale, rtol=1e-4) |
||
521 | assert_allclose(pos_err.width.value, 2 * 0.041987 * scale, rtol=1e-4) |
||
522 | assert_allclose(model.position.ra.value, pos_err.center.ra.value) |
||
523 | assert_allclose(model.position.dec.value, pos_err.center.dec.value) |
||
524 | |||
525 | model = self.cat[97].spatial_model() |
||
526 | assert "GaussianSpatialModel" in model.tag |
||
527 | assert model.frame == "icrs" |
||
528 | p = model.parameters |
||
529 | assert_allclose(p["lon_0"].value, 94.309998, rtol=1e-5) |
||
530 | assert_allclose(p["lat_0"].value, 22.58, rtol=1e-5) |
||
531 | assert_allclose(p["sigma"].value, 0.27) |
||
532 | |||
533 | model = self.cat[134].spatial_model() |
||
534 | assert "DiskSpatialModel" in model.tag |
||
535 | assert model.frame == "icrs" |
||
536 | p = model.parameters |
||
537 | assert_allclose(p["lon_0"].value, 125.660004, rtol=1e-5) |
||
538 | assert_allclose(p["lat_0"].value, -42.84, rtol=1e-5) |
||
539 | assert_allclose(p["r_0"].value, 0.37) |
||
540 | |||
541 | model = self.cat[256].spatial_model() |
||
542 | assert "TemplateSpatialModel" in model.tag |
||
543 | assert model.frame == "fk5" |
||
544 | assert model.normalize |
||
545 | # TODO: have to check the extended template used for RX J1713, |
||
546 | # for now I guess it's the same than for 3FGL |
||
547 | # and added a copy with the name given by 2FHL in gammapy-extra |
||
548 | |||
549 | |||
550 | @requires_data() |
||
551 | class TestFermi3FHLObject: |
||
552 | @classmethod |
||
553 | def setup_class(cls): |
||
554 | cls.cat = SourceCatalog3FHL() |
||
555 | # Use 3FHL J0534.5+2201 (Crab) as a test source |
||
556 | cls.source_name = "3FHL J0534.5+2201" |
||
557 | cls.source = cls.cat[cls.source_name] |
||
558 | |||
559 | def test_name(self): |
||
560 | assert self.source.name == self.source_name |
||
561 | |||
562 | def test_row_index(self): |
||
563 | assert self.source.row_index == 352 |
||
564 | |||
565 | def test_data(self): |
||
566 | assert_allclose(self.source.data["Signif_Avg"], 168.64082) |
||
567 | |||
568 | def test_str(self): |
||
569 | actual = str(self.cat["3FHL J2301.9+5855e"]) # an extended source |
||
570 | expected = open(get_pkg_data_filename("data/3fhl_j2301.9+5855e.txt")).read() |
||
571 | assert actual == expected |
||
572 | |||
573 | def test_position(self): |
||
574 | position = self.source.position |
||
575 | assert_allclose(position.ra.deg, 83.634834, atol=1e-3) |
||
576 | assert_allclose(position.dec.deg, 22.019203, atol=1e-3) |
||
577 | |||
578 | @pytest.mark.parametrize("ref", SOURCES_3FHL, ids=lambda _: _["name"]) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
579 | def test_spectral_model(self, ref): |
||
580 | model = self.cat[ref["idx"]].spectral_model() |
||
581 | |||
582 | dnde, dnde_err = model.evaluate_error(100 * u.GeV) |
||
583 | |||
584 | assert isinstance(model, ref["spec_type"]) |
||
585 | assert_quantity_allclose(dnde, ref["dnde"]) |
||
586 | assert_quantity_allclose(dnde_err, ref["dnde_err"], rtol=1e-3) |
||
587 | |||
588 | @pytest.mark.parametrize("ref", SOURCES_3FHL, ids=lambda _: _["name"]) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
589 | def test_spatial_model(self, ref): |
||
590 | model = self.cat[ref["idx"]].spatial_model() |
||
591 | assert model.frame == "icrs" |
||
592 | |||
593 | model = self.cat["3FHL J0002.1-6728"].spatial_model() |
||
594 | pos_err = model.position_error |
||
595 | assert_allclose(0.5 * pos_err.height.value, 0.035713, rtol=1e-4) |
||
596 | assert_allclose(0.5 * pos_err.width.value, 0.035713, rtol=1e-4) |
||
597 | assert_allclose(model.position.ra.value, pos_err.center.ra.value) |
||
598 | assert_allclose(model.position.dec.value, pos_err.center.dec.value) |
||
599 | |||
600 | @pytest.mark.parametrize("ref", SOURCES_3FHL, ids=lambda _: _["name"]) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
601 | def test_sky_model(self, ref): |
||
602 | self.cat[ref["idx"]].sky_model() |
||
603 | |||
604 | def test_flux_points(self): |
||
605 | flux_points = self.source.flux_points |
||
606 | |||
607 | assert flux_points.energy_axis.nbin == 5 |
||
608 | assert flux_points.norm_ul |
||
609 | |||
610 | desired = [5.169889e-09, 2.245024e-09, 9.243175e-10, 2.758956e-10, 6.684021e-11] |
||
611 | assert_allclose(flux_points.flux.data[:, 0, 0], desired, rtol=1e-3) |
||
612 | |||
613 | def test_crab_alias(self): |
||
614 | for name in ["Crab Nebula", "3FHL J0534.5+2201", "3FGL J0534.5+2201i"]: |
||
615 | assert self.cat[name].row_index == 352 |
||
616 | |||
617 | |||
618 | @requires_data() |
||
619 | class TestSourceCatalog3FGL: |
||
620 | @classmethod |
||
621 | def setup_class(cls): |
||
622 | cls.cat = SourceCatalog3FGL() |
||
623 | |||
624 | def test_main_table(self): |
||
625 | assert len(self.cat.table) == 3034 |
||
626 | |||
627 | def test_extended_sources(self): |
||
628 | table = self.cat.extended_sources_table |
||
629 | assert len(table) == 25 |
||
630 | |||
631 | |||
632 | @requires_data() |
||
633 | class TestSourceCatalog2FHL: |
||
634 | @classmethod |
||
635 | def setup_class(cls): |
||
636 | cls.cat = SourceCatalog2FHL() |
||
637 | |||
638 | def test_main_table(self): |
||
639 | assert len(self.cat.table) == 360 |
||
640 | |||
641 | def test_extended_sources(self): |
||
642 | table = self.cat.extended_sources_table |
||
643 | assert len(table) == 25 |
||
644 | |||
645 | def test_crab_alias(self): |
||
646 | for name in ["Crab", "3FGL J0534.5+2201i", "1FHL J0534.5+2201"]: |
||
647 | assert self.cat[name].row_index == 85 |
||
648 | |||
649 | |||
650 | @requires_data() |
||
651 | class TestSourceCatalog3FHL: |
||
652 | @classmethod |
||
653 | def setup_class(cls): |
||
654 | cls.cat = SourceCatalog3FHL() |
||
655 | |||
656 | def test_main_table(self): |
||
657 | assert len(self.cat.table) == 1556 |
||
658 | |||
659 | def test_extended_sources(self): |
||
660 | table = self.cat.extended_sources_table |
||
661 | assert len(table) == 55 |
||
662 | |||
663 | def test_to_models(self): |
||
664 | mask = self.cat.table["GLAT"].quantity > 80 * u.deg |
||
665 | subcat = self.cat[mask] |
||
666 | models = subcat.to_models() |
||
667 | assert len(models) == 17 |
||
668 |