-
Notifications
You must be signed in to change notification settings - Fork 0
/
api.py
138 lines (112 loc) · 3.93 KB
/
api.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
# -*- coding: utf-8 -*-
"""
API for querying the XMM-Newton Upper Limit Database using the XSA interface
@author: ruizca
"""
import requests
from astropy.coordinates import ICRS
from astropy.table import Table
from astropy_healpix import HEALPix
from pandas import DataFrame as df
def _check_kwargs(obstype, instrum):
if obstype not in ["slew", "pointed", None]:
raise ValueError(f"Unknown obstype: {obstype}")
if instrum not in ["PN", "M1", "M2", None]:
raise ValueError(f"Unknown instrum: {instrum}")
def _filter_uls(uls, obstype, instrum):
if obstype:
mask = uls["obstype"] == obstype
uls = uls[mask]
if instrum:
mask = uls["instrum"] == instrum
uls = uls[mask]
return uls
def _get_level(obstype):
if obstype == "pointed":
return 16
else:
return 15
def _npixels_to_coords(npixels, level):
hp = HEALPix(nside=2 ** level, order="nested", frame=ICRS())
return hp.healpix_to_skycoord(npixels)
def _query_xsa_uls(payload, obstype=None, instrum=None):
_check_kwargs(obstype, instrum)
r = requests.get(
"http://nxsa.esac.esa.int/nxsa-sl/servlet/get-uls", params=payload
)
r.raise_for_status()
uls = Table.from_pandas(df.from_records(r.json()))
if uls:
uls = _filter_uls(uls, obstype, instrum)
return uls
def query_radec(ra, dec, **kwargs):
"""
Search for upper limits at the coordinates defined by ra, dec.
Parameters
----------
ra : List
List-like of Right Ascension values, in degrees.
dec : List
List-like of Declination values, in degrees.
obstype : str, optional
Filter the results by observation type ("pointed" or "slew").
instrum : str, optional
Filter the results by instrument ("PN, "M1" or"M2"). The default is None.
Returns
-------
Astropy Table
An Astropy Table with the upper limit data for each observation
containing the positions for the list of npixels.
"""
if len(ra) != len(dec):
raise ValueError("ra and dec lengths don't match!")
payload = {
"ra": ";".join(str(round(c, 10)) for c in ra),
"dec": ";".join(str(round(c, 10)) for c in dec),
}
return _query_xsa_uls(payload, **kwargs)
def query_coords(coords, **kwargs):
"""
Search for upper limits at the coordinates defined by "coords"
Parameters
----------
coords : Astropy SkyCoord
obstype : str, optional
Filter the results by observation type ("pointed" or "slew").
instrum : str, optional
Filter the results by instrument ("PN, "M1" or"M2"). The default is None.
Returns
-------
Astropy Table
An Astropy Table with the upper limit data for each observation
containing the positions for the list of npixels.
"""
payload = {
"ra": ";".join(str(round(c.ra.deg, 10)) for c in coords),
"dec": ";".join(str(round(c.dec.deg, 10)) for c in coords),
}
return _query_xsa_uls(payload, **kwargs)
def query_npixels(npixels, obstype="pointed", instrum=None):
"""
Search for upper limits at the coordinates corresponding to "npixels", a
list-like of integers corresponding to npixel values in the nested ordering
scheme.
Parameters
----------
npixels : TYPE
DESCRIPTION.
obstype : str, optional
The observation type ("pointed" or "slew"). For pointed observations
npixels are assumed to use order=16, and order=15 for slew observations.
The default is "pointed".
instrum : str, optional
Filter the results by instrument ("PN, "M1" or"M2"). The default is None.
Returns
-------
Astropy Table
An Astropy Table with the upper limit data for each observation
containing the positions for the list of npixels.
"""
level = _get_level(obstype)
coords = _npixels_to_coords(npixels, level)
return query_coords(coords, obstype=obstype, instrum=instrum)