Skip to content

Commit 06db9c5

Browse files
authored
Merge pull request #2095 from syed-gilani/missions_mast
Missions mast
2 parents f99e1ba + 200af24 commit 06db9c5

File tree

9 files changed

+815
-34
lines changed

9 files changed

+815
-34
lines changed

.mailmap

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ Pey Lian Lim <[email protected]> <[email protected]>
5959
6060
6161
Simon Liedtke <[email protected]>
62+
63+
64+
Syed Gilani <[email protected]>
6265
Tinuade Adeleke <[email protected]>
6366
Volodymyr Savchenko <[email protected]> <[email protected]>
6467
Volodymyr Savchenko <[email protected]> <[email protected]>

CHANGES.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,8 @@ mast
323323

324324
- Added Zcut functionality to astroquery [#1911]
325325

326+
- Added searching missions(HST) metadata functiona;ity to astroquery. [#2095]
327+
326328
svo_fps
327329
^^^^^^^
328330

astroquery/mast/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@ class Conf(_config.ConfigNamespace):
3333
from .cutouts import TesscutClass, Tesscut, ZcutClass, Zcut
3434
from .observations import Observations, ObservationsClass, MastClass, Mast
3535
from .collections import Catalogs, CatalogsClass
36+
from .missions import MastMissions, MastMissionsClass
3637
from .core import MastQueryWithLogin
3738
from . import utils
3839

3940
__all__ = ['Observations', 'ObservationsClass',
4041
'Catalogs', 'CatalogsClass',
42+
'MastMissions', 'MastMissionsClass',
4143
'Mast', 'MastClass',
4244
'Tesscut', 'TesscutClass',
4345
'Zcut', 'ZcutClass',

astroquery/mast/missions.py

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
# Licensed under a 3-clause BSD style license - see LICENSE.rst
2+
"""
3+
MAST Missions
4+
=================
5+
6+
This module contains methods for searching MAST missions.
7+
"""
8+
9+
import requests
10+
11+
import astropy.units as u
12+
import astropy.coordinates as coord
13+
14+
from astroquery.utils import commons, async_to_sync
15+
from astroquery.utils.class_or_instance import class_or_instance
16+
from astroquery.exceptions import InvalidQueryError
17+
18+
from astroquery.mast import utils
19+
from astroquery.mast.core import MastQueryWithLogin
20+
21+
from . import conf
22+
23+
__all__ = ['MastMissionsClass', 'MastMissions']
24+
25+
26+
@async_to_sync
27+
class MastMissionsClass(MastQueryWithLogin):
28+
"""
29+
MastMissions search class.
30+
31+
Class that allows direct programatic access to the MAST search API for a given mission.
32+
"""
33+
34+
def __init__(self, *, mission='hst', service='search'):
35+
super().__init__()
36+
37+
self._search_option_fields = ['limit', 'offset', 'sort_by', 'search_key', 'sort_desc', 'select_cols',
38+
'skip_count', 'user_fields']
39+
self.service = service
40+
self.mission = mission
41+
42+
service_dict = {self.service: {'path': self.service, 'args': {}}}
43+
self._service_api_connection.set_service_params(service_dict, f"{self.service}/{self.mission}")
44+
45+
def _parse_result(self, response, verbose=False): # Used by the async_to_sync decorator functionality
46+
"""
47+
Parse the results of a `~requests.Response` objects and return an `~astropy.table.Table` of results.
48+
49+
Parameters
50+
----------
51+
response : `~requests.Response`
52+
`~requests.Response` objects.
53+
verbose : bool
54+
(presently does nothing - there is no output with verbose set to
55+
True or False)
56+
Default False. Setting to True provides more extensive output.
57+
58+
Returns
59+
-------
60+
response : `~astropy.table.Table`
61+
"""
62+
63+
return self._service_api_connection._parse_result(response, verbose, data_key='results')
64+
65+
@class_or_instance
66+
def query_region_async(self, coordinates, radius=3*u.arcmin, **kwargs):
67+
"""
68+
Given a sky position and radius, returns a list of matching dataset IDs.
69+
70+
Parameters
71+
----------
72+
coordinates : str or `~astropy.coordinates` object
73+
The target around which to search. It may be specified as a
74+
string or as the appropriate `~astropy.coordinates` object.
75+
radius : str or `~astropy.units.Quantity` object, optional
76+
Default 3 degrees.
77+
The string must be parsable by `~astropy.coordinates.Angle`. The
78+
appropriate `~astropy.units.Quantity` object from
79+
`~astropy.units` may also be used. Defaults to 3 arcminutes.
80+
**kwargs
81+
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
84+
For example one can specify the output columns(select_cols) or use other filters(conditions)
85+
86+
Returns
87+
-------
88+
response : list of `~requests.Response`
89+
"""
90+
91+
# Put coordinates and radius into consistant format
92+
coordinates = commons.parse_coordinates(coordinates)
93+
94+
# if radius is just a number we assume degrees
95+
radius = coord.Angle(radius, u.arcmin)
96+
97+
# basic params
98+
params = {'target': [f"{coordinates.ra.deg} {coordinates.dec.deg}"],
99+
'radius': radius.arcmin,
100+
'radius_units': 'arcminutes'}
101+
102+
params['conditions'] = []
103+
# adding additional user specified parameters
104+
for prop, value in kwargs.items():
105+
if prop not in self._search_option_fields:
106+
params['conditions'].append({prop: value})
107+
else:
108+
params[prop] = value
109+
110+
return self._service_api_connection.service_request_async(self.service, params, use_json=True)
111+
112+
@class_or_instance
113+
def query_criteria_async(self, **criteria):
114+
"""
115+
Given a set of search criteria, returns a list of mission metadata.
116+
117+
Parameters
118+
----------
119+
**criteria
120+
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`),
122+
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.
126+
127+
Returns
128+
-------
129+
response : list of `~requests.Response`
130+
"""
131+
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)
136+
137+
if objectname or coordinates:
138+
coordinates = utils.parse_input_location(coordinates, objectname)
139+
140+
# if radius is just a number we assume degrees
141+
radius = coord.Angle(radius, u.arcmin)
142+
143+
# build query
144+
params = {}
145+
if coordinates:
146+
params["target"] = [f"{coordinates.ra.deg} {coordinates.dec.deg}"]
147+
params["radius"] = radius.arcmin
148+
params["radius_units"] = 'arcminutes'
149+
150+
if not self._service_api_connection.check_catalogs_criteria_params(criteria):
151+
raise InvalidQueryError("At least one non-positional criterion must be supplied.")
152+
153+
params['conditions'] = []
154+
for prop, value in criteria.items():
155+
if prop not in self._search_option_fields:
156+
params['conditions'].append({prop: value})
157+
else:
158+
params[prop] = value
159+
160+
return self._service_api_connection.service_request_async(self.service, params, use_json=True)
161+
162+
@class_or_instance
163+
def query_object_async(self, objectname, radius=3*u.arcmin, **kwargs):
164+
"""
165+
Given an object name, returns a list of matching rows.
166+
167+
Parameters
168+
----------
169+
objectname : str
170+
The name of the target around which to search.
171+
radius : str or `~astropy.units.Quantity` object, optional
172+
Default 3 arcmin.
173+
The string must be parsable by `~astropy.coordinates.Angle`.
174+
The appropriate `~astropy.units.Quantity` object from
175+
`~astropy.units` may also be used. Defaults to 3 arcminutes.
176+
**kwargs
177+
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.
180+
181+
Returns
182+
-------
183+
response : list of `~requests.Response`
184+
"""
185+
186+
coordinates = utils.resolve_object(objectname)
187+
188+
return self.query_region_async(coordinates, radius, **kwargs)
189+
190+
@class_or_instance
191+
def get_column_list(self):
192+
"""
193+
For a mission, return a list of all searchable columns and their descriptions
194+
195+
Returns
196+
-------
197+
json data that contains columns names and their descriptions
198+
"""
199+
200+
url = f"{conf.server}/search/util/api/v0.1/column_list?mission={self.mission}"
201+
202+
try:
203+
results = requests.get(url)
204+
results = results.json()
205+
for result in results:
206+
result.pop('field_name')
207+
result.pop('queryable')
208+
result.pop('indexed')
209+
result.pop('default_output')
210+
return results
211+
except Exception:
212+
raise Exception(f"Error occured while trying to get column list for mission {self.mission}")
213+
214+
215+
MastMissions = MastMissionsClass()

0 commit comments

Comments
 (0)