-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcore.py
273 lines (204 loc) · 9.34 KB
/
core.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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
#!/usr/bin/env python
# Licensed under a 3-clause BSD style license - see LICENSE
"""
Query from the HyperLEDA web data access service.
=================================================
"""
__author__ = "Iskren Y. Georgiev"
# Based on: https://astroquery.readthedocs.io/en/latest/template.html
# Imports organized as shown below
# 1. local imports relative imports
# all Query classes should inherit from BaseQuery.
from astroquery.query import BaseQuery
# has common functions required by most modules
from astroquery.utils import commons
# prepend_docstr is a way to copy docstrings between methods
from astroquery.utils import prepend_docstr_nosections
# async_to_sync generates the relevant query tools from _async methods
from astroquery.utils import async_to_sync
from astroquery.utils.class_or_instance import class_or_instance
# import configurable items declared in __init__.py
from . import conf
# 2. standard library imports
# 3. third party imports
import astropy.units as u
import astropy.coordinates as coord
import astropy.io.votable as votable
from astropy.table import Table, vstack
from astropy.io import fits
# export all the public classes and methods
__all__ = ['hyperleda', 'HyperLEDAClass']
# declare global variables and constants if any
# Begin main class
# Should be decorated with the async_to_sync imported previously
@async_to_sync
class HyperLEDAClass(BaseQuery):
"""
Base class for querying data from the HyperLEDA database.
http://leda.univ-lyon1.fr
"""
URL = conf.server
TIMEOUT = conf.timeout
# The URL with the table of the main object properties
URL_PROPERTIES = URL + '/leda/meandata.html'
URL_HTTP_REQUEST = URL + '/fG.cgi'
@class_or_instance
def get_properties(self):
"""
Get the available object properties in the HyperLEDA database.
(See http://leda.univ-lyon1.fr/leda/meandata.html)
Returns an `~astropy.table.Table` object.
Returns
-------
prop_tbl : An `~astropy.table.Table` object with the available object
properties in HyperLEDA
Example
--------
>>> from query.hyperleda import hyperleda
>>>
>>> properties_tbl = hyperleda.get_properties()
>>> properties_tbl.pprint_all()
"""
url_prop = self.URL_PROPERTIES
response = self._request("GET", url_prop)
prop_tbl = self._parse_result(response)
return prop_tbl
def _perp_param_lst(self, param_lst):
# Prepare the parameter's list
#print('Full list of parameters number:',len(str(param_lst).split(',')))
# These params are no longer in the leda tables
for param in ['numtype','hptr','logavmm','e_logavmm']:
if param in param_lst:
param_lst.remove(param)
param_str = str(param_lst)
param_str = param_str[2:param_str.rfind('\'')]
param_str = param_str.replace('\', \'', ',')
return param_str
@class_or_instance
def query_object(self, obj_name, properties = 'all'):
"""
Query an object from the HyperLEDA database.
Returns the object properties in an `~astropy.table.Table` object.
Example
--------
>>> from query.hyperleda import hyperleda
>>> result_table = hyperleda.query_object(obj_name = 'UGC12591',
properties = 'objname,type,logr25,
btc,v,modbest,al2000,de2000,
celposJ(pgc)')
>>> result_table.pprint()
Parameters
----------
obj_name : str
Object ID recognizable by HyperLEDA or SIMBAD
properties : str, or comma separated strings. Default: 'all'
The full list of properties in HyperLEDA is available at
http://leda.univ-lyon1.fr/leda/meandata.html
or via
hyperleda.get_properties().pprint_all()
Returns
-------
Table : An `~astropy.table.Table` object with the object properties
from HyperLEDA
"""
if properties == 'all':
prop_tbl = self.get_properties()
param_lst = prop_tbl['field'].data.tolist()
param_str = self._perp_param_lst(param_lst)
else:
param_str = properties
url_http_request = self.URL_HTTP_REQUEST
ls_SQL_search = "objname = objname('{:}')".format(obj_name)
request_payload = dict(n = 'meandata', c = 'o', of = '1,leda,simbad',
nra = 'l', nakd = '1',
d = '{:}'.format(param_str),
sql = '{:}'.format(ls_SQL_search), ob = '',
a = 'csv[|]')
response = self._request("GET", url_http_request,
params=request_payload)
sql_result_tbl = Table.read(response.url, format='ascii', delimiter='|')
return sql_result_tbl
@class_or_instance
def query_sql(self, search, properties = 'all'):
"""
Perform SQL search in the HyperLEDA database.
(See http://leda.univ-lyon1.fr/fullsql.html)
Returns an `~astropy.table.Table` object with the results from the
search containing the object properties.
Parameters
----------
search : str
A string containing a valid SQL WHERE clause.
properties : str, or comma separated strings. Default: 'all'
The full list of properties in HyperLEDA is available at
http://leda.univ-lyon1.fr/leda/meandata.html
or via
hyperleda.get_properties().pprint_all()
Returns
-------
Table : An `~astropy.table.Table` object with the object properties from
HyperLEDA
Example
--------
>>> from query.hyperleda import hyperleda
>>> hl = hyperleda()
>>> sql_tbl = hl.query_sql(search = "(mod0<=27 and t>=-3 and t<=0 and
type='S0') or (mod0<=27 and t>=-3
and t<=0 and type='S0-a')",
properties = 'objname,type,logr25,btc,v,
modbest,al2000,de2000,hl_names(pgc),
celposJ(pgc)')
>>> result_table.pprint()
"""
if properties == 'all':
prop_tbl = self.get_properties()
param_lst = prop_tbl['field'].data.tolist()
param_str = self._perp_param_lst(param_lst)
else:
param_str = properties
url_http_request = self.URL_HTTP_REQUEST
ls_SQL_search = search
request_payload = dict(n = 'meandata', c = 'o', of = '1,leda,simbad',
nra = 'l', nakd = '1',
d = '{:}'.format(param_str),
sql = '{:}'.format(ls_SQL_search), ob = '',
a = 'csv[|]')
response = self._request("GET", url_http_request,
params=request_payload)
sql_result_tbl = Table.read(response.url, format='ascii', delimiter='|')
return sql_result_tbl
def _parse_result(self, response, verbose=False):
# if verbose is False then suppress any VOTable related warnings
if not verbose:
commons.suppress_vo_warnings()
# try to parse the result into an astropy.Table, else
# return the raw result with an informative error message.
try:
# do something with regex to get the result into
# astropy.Table form. return the Table.
lind = response.text.find('/fG.cgi')
rind = lind + response.text[lind:].find('"')
ls_url_props_src = response.text[lind:rind]
ls_url_props = self.URL + ls_url_props_src
# Get the main table
prop_tbl = Table.read(ls_url_props, format = 'ascii.html')
prop_tbl.rename_columns(prop_tbl.colnames,
['field', 'type', 'units', 'description'])
# Get the table with the available SQL functions
sql_func_tbl = Table.read(response.url, format='ascii.html',
htmldict={'table_id' : 2})
sql_func_tbl.add_column(col='--', name='units', index=2)
sql_func_tbl.rename_columns(sql_func_tbl.colnames,
['field', 'type', 'units', 'description'])
prop_tbl = vstack([prop_tbl, sql_func_tbl])
except ValueError:
# catch common errors here, but never use bare excepts
# return raw result/ handle in some way
pass
return prop_tbl
# the default tool for users to interact with is an instance of the Class
hyperleda = HyperLEDAClass()
# once your class is done, tests should be written
# See ./tests for examples on this
# Next you should write the docs in astroquery/docs/module_name
# using Sphinx.