7
7
"""
8
8
9
9
import requests
10
+ import warnings
10
11
12
+ from astropy .table import Table
11
13
import astropy .units as u
12
14
import astropy .coordinates as coord
13
15
14
16
from astroquery .utils import commons , async_to_sync
15
17
from astroquery .utils .class_or_instance import class_or_instance
16
- from astroquery .exceptions import InvalidQueryError
18
+ from astroquery .exceptions import InvalidQueryError , MaxResultsWarning
17
19
18
20
from astroquery .mast import utils
19
21
from astroquery .mast .core import MastQueryWithLogin
27
29
class MastMissionsClass (MastQueryWithLogin ):
28
30
"""
29
31
MastMissions search class.
30
-
31
- Class that allows direct programatic access to the MAST search API for a given mission.
32
+ Class that allows direct programatic access to retrieve metadata via the MAST search API for a given mission.
32
33
"""
33
34
34
35
def __init__ (self , * , mission = 'hst' , service = 'search' ):
@@ -38,11 +39,12 @@ def __init__(self, *, mission='hst', service='search'):
38
39
'skip_count' , 'user_fields' ]
39
40
self .service = service
40
41
self .mission = mission
42
+ self .limit = 5000
41
43
42
44
service_dict = {self .service : {'path' : self .service , 'args' : {}}}
43
45
self ._service_api_connection .set_service_params (service_dict , f"{ self .service } /{ self .mission } " )
44
46
45
- def _parse_result (self , response , verbose = False ): # Used by the async_to_sync decorator functionality
47
+ def _parse_result (self , response , * , verbose = False ): # Used by the async_to_sync decorator functionality
46
48
"""
47
49
Parse the results of a `~requests.Response` objects and return an `~astropy.table.Table` of results.
48
50
@@ -53,17 +55,22 @@ def _parse_result(self, response, verbose=False): # Used by the async_to_sync d
53
55
verbose : bool
54
56
(presently does nothing - there is no output with verbose set to
55
57
True or False)
56
- Default False. Setting to True provides more extensive output.
58
+ Default False. Setting to True provides more extensive output.
57
59
58
60
Returns
59
61
-------
60
62
response : `~astropy.table.Table`
61
63
"""
62
64
63
- return self ._service_api_connection ._parse_result (response , verbose , data_key = 'results' )
65
+ results = self ._service_api_connection ._parse_result (response , verbose , data_key = 'results' )
66
+ if len (results ) >= self .limit :
67
+ warnings .warn ("Maximum results returned, may not include all sources within radius." ,
68
+ MaxResultsWarning )
69
+
70
+ return results
64
71
65
72
@class_or_instance
66
- def query_region_async (self , coordinates , radius = 3 * u .arcmin , ** kwargs ):
73
+ def query_region_async (self , coordinates , * , radius = 3 * u .arcmin , limit = 5000 , offset = 0 , ** kwargs ):
67
74
"""
68
75
Given a sky position and radius, returns a list of matching dataset IDs.
69
76
@@ -77,17 +84,26 @@ def query_region_async(self, coordinates, radius=3*u.arcmin, **kwargs):
77
84
The string must be parsable by `~astropy.coordinates.Angle`. The
78
85
appropriate `~astropy.units.Quantity` object from
79
86
`~astropy.units` may also be used. Defaults to 3 arcminutes.
87
+ limit : int
88
+ Optional and default is 5000.
89
+ the maximun number of dataset IDs in the results.
90
+ offset : int
91
+ Optional and default is 0
92
+ the number of records you wish to skip before selecting records.
80
93
**kwargs
81
94
Other mission-specific keyword args.
82
- These can be found at the following link
83
- https://mast.stsci.edu/search/docs/#/Hubble%20Search/post_search_hst_api_v0_1_search_post
95
+ Any invalid keys are ignored by the API.
96
+ All valid key names can be found using `~astroquery.mast.missions.MastMissionsClass.get_column_list`
97
+ function.
84
98
For example one can specify the output columns(select_cols) or use other filters(conditions)
85
99
86
100
Returns
87
101
-------
88
102
response : list of `~requests.Response`
89
103
"""
90
104
105
+ self .limit = limit
106
+
91
107
# Put coordinates and radius into consistant format
92
108
coordinates = commons .parse_coordinates (coordinates )
93
109
@@ -97,7 +113,9 @@ def query_region_async(self, coordinates, radius=3*u.arcmin, **kwargs):
97
113
# basic params
98
114
params = {'target' : [f"{ coordinates .ra .deg } { coordinates .dec .deg } " ],
99
115
'radius' : radius .arcmin ,
100
- 'radius_units' : 'arcminutes' }
116
+ 'radius_units' : 'arcminutes' ,
117
+ 'limit' : limit ,
118
+ 'offset' : offset }
101
119
102
120
params ['conditions' ] = []
103
121
# adding additional user specified parameters
@@ -110,29 +128,47 @@ def query_region_async(self, coordinates, radius=3*u.arcmin, **kwargs):
110
128
return self ._service_api_connection .service_request_async (self .service , params , use_json = True )
111
129
112
130
@class_or_instance
113
- def query_criteria_async (self , ** criteria ):
131
+ def query_criteria_async (self , * , coordinates = None , objectname = None , radius = 3 * u .arcmin ,
132
+ limit = 5000 , offset = 0 , select_cols = [], ** criteria ):
114
133
"""
115
134
Given a set of search criteria, returns a list of mission metadata.
116
135
117
136
Parameters
118
137
----------
138
+ coordinates : str or `~astropy.coordinates` object
139
+ The target around which to search. It may be specified as a
140
+ string or as the appropriate `~astropy.coordinates` object.
141
+ objectname : str
142
+ The name of the target around which to search.
143
+ radius : str or `~astropy.units.Quantity` object, optional
144
+ Default 3 degrees.
145
+ The string must be parsable by `~astropy.coordinates.Angle`. The
146
+ appropriate `~astropy.units.Quantity` object from
147
+ `~astropy.units` may also be used. Defaults to 3 arcminutes.
148
+ limit : int
149
+ Optional and default is 5000.
150
+ the maximun number of dataset IDs in the results.
151
+ offset : int
152
+ Optional and default is 0.
153
+ the number of records you wish to skip before selecting records.
154
+ select_cols: list
155
+ names of columns that will be included in the astropy table
119
156
**criteria
120
157
Criteria to apply. At least one non-positional criteria must be supplied.
121
- Valid criteria are coordinates, objectname, radius (as in `query_region` and `query_object`),
158
+ Valid criteria are coordinates, objectname, radius (as in
159
+ `~astroquery.mast.missions.MastMissionsClass.query_region` and
160
+ `~astroquery.mast.missions.MastMissionsClass.query_object` functions),
122
161
and all fields listed in the column documentation for the mission being queried.
123
- Fields that can be used to match results on criteria. See the TAP schema link below for all field names .
124
- https://vao.stsci.edu/missionmast/tapservice.aspx/tables
125
- some common fields for criteria are sci_pep_id, sci_spec_1234 and sci_actual_duration .
162
+ Any invalid keys passed in criteria are ignored by the API .
163
+ List of all valid fields that can be used to match results on criteria can be retrieved by calling
164
+ `~astroquery.mast.missions.MastMissionsClass.get_column_list` function .
126
165
127
166
Returns
128
167
-------
129
168
response : list of `~requests.Response`
130
169
"""
131
170
132
- # Seperating any position info from the rest of the filters
133
- coordinates = criteria .pop ('coordinates' , None )
134
- objectname = criteria .pop ('objectname' , None )
135
- radius = criteria .pop ('radius' , 0.2 * u .deg )
171
+ self .limit = limit
136
172
137
173
if objectname or coordinates :
138
174
coordinates = utils .parse_input_location (coordinates , objectname )
@@ -141,7 +177,7 @@ def query_criteria_async(self, **criteria):
141
177
radius = coord .Angle (radius , u .arcmin )
142
178
143
179
# build query
144
- params = {}
180
+ params = {"limit" : self . limit , "offset" : offset , 'select_cols' : select_cols }
145
181
if coordinates :
146
182
params ["target" ] = [f"{ coordinates .ra .deg } { coordinates .dec .deg } " ]
147
183
params ["radius" ] = radius .arcmin
@@ -160,7 +196,7 @@ def query_criteria_async(self, **criteria):
160
196
return self ._service_api_connection .service_request_async (self .service , params , use_json = True )
161
197
162
198
@class_or_instance
163
- def query_object_async (self , objectname , radius = 3 * u .arcmin , ** kwargs ):
199
+ def query_object_async (self , objectname , * , radius = 3 * u .arcmin , limit = 5000 , offset = 0 , ** kwargs ):
164
200
"""
165
201
Given an object name, returns a list of matching rows.
166
202
@@ -173,10 +209,17 @@ def query_object_async(self, objectname, radius=3*u.arcmin, **kwargs):
173
209
The string must be parsable by `~astropy.coordinates.Angle`.
174
210
The appropriate `~astropy.units.Quantity` object from
175
211
`~astropy.units` may also be used. Defaults to 3 arcminutes.
212
+ limit : int
213
+ Optional and default is 5000.
214
+ the maximun number of dataset IDs in the results.
215
+ offset : int
216
+ Optional and default is 0.
217
+ the number of records you wish to skip before selecting records.
176
218
**kwargs
177
219
Mission-specific keyword args.
178
- These can be found in the `service documentation <https://mast.stsci.edu/api/v0/_services.html>`__.
179
- for specific catalogs. For example one can specify the magtype for an HSC search.
220
+ Any invalid keys are ignored by the API.
221
+ All valid keys can be found by calling `~astroquery.mast.missions.MastMissionsClass.get_column_list`
222
+ function.
180
223
181
224
Returns
182
225
-------
@@ -185,7 +228,7 @@ def query_object_async(self, objectname, radius=3*u.arcmin, **kwargs):
185
228
186
229
coordinates = utils .resolve_object (objectname )
187
230
188
- return self .query_region_async (coordinates , radius , ** kwargs )
231
+ return self .query_region_async (coordinates , radius = radius , limit = limit , offset = offset , ** kwargs )
189
232
190
233
@class_or_instance
191
234
def get_column_list (self ):
@@ -194,20 +237,23 @@ def get_column_list(self):
194
237
195
238
Returns
196
239
-------
197
- json data that contains columns names and their descriptions
240
+ response : `~astropy.table.Table` that contains columns names, types and their descriptions
198
241
"""
199
242
200
243
url = f"{ conf .server } /search/util/api/v0.1/column_list?mission={ self .mission } "
201
244
202
245
try :
203
246
results = requests .get (url )
204
247
results = results .json ()
248
+ rows = []
205
249
for result in results :
206
250
result .pop ('field_name' )
207
251
result .pop ('queryable' )
208
252
result .pop ('indexed' )
209
253
result .pop ('default_output' )
210
- return results
254
+ rows .append ((result ['column_name' ], result ['qual_type' ], result ['description' ]))
255
+ data_table = Table (rows = rows , names = ('name' , 'data_type' , 'description' ))
256
+ return data_table
211
257
except Exception :
212
258
raise Exception (f"Error occured while trying to get column list for mission { self .mission } " )
213
259
0 commit comments