Skip to content

Commit 5f72e7e

Browse files
Simple PR review fixes.
1 parent a424464 commit 5f72e7e

File tree

5 files changed

+71
-70
lines changed

5 files changed

+71
-70
lines changed

CHANGES.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
New Tools and Services
55
----------------------
66

7+
ipac.irsa.most
8+
^^^^^^^^^^^^^^
9+
10+
- New module to access the Moving Object Search Tool (MOST) added. [#2660]
11+
712
gaia
813
^^^^
914

astroquery/ipac/irsa/most.py

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,9 @@ class MostClass(BaseQuery):
2222
URL = conf.most_server
2323
TIMEOUT = conf.timeout
2424

25-
def __init__(self):
26-
super().__init__()
27-
2825
def _validate_name_input_type(self, params):
2926
"""
30-
Validate required parameters when `input_type='name_input'`.
27+
Validate required parameters when ``input_type='name_input'``.
3128
3229
Parameters
3330
----------
@@ -45,7 +42,7 @@ def _validate_name_input_type(self, params):
4542

4643
def _validate_nafid_input_type(self, params):
4744
"""
48-
Validate required parameters when `input_type='naifid_input'`.
45+
Validate required parameters when ``input_type='naifid_input'``.
4946
5047
5148
Parameters
@@ -64,7 +61,7 @@ def _validate_nafid_input_type(self, params):
6461

6562
def _validate_mpc_input_type(self, params):
6663
"""
67-
Validate required parameters when `input_type='mpc_input'`.
64+
Validate required parameters when ``input_type='mpc_input'``.
6865
6966
Parameters
7067
----------
@@ -88,7 +85,7 @@ def _validate_mpc_input_type(self, params):
8885

8986
def _validate_manual_input_type(self, params):
9087
"""
91-
Validate required parameters when `input_type='manual_input'`.
88+
Validate required parameters when ``input_type='manual_input'``.
9289
9390
Parameters
9491
----------
@@ -103,9 +100,9 @@ def _validate_manual_input_type(self, params):
103100
"""
104101
obj_type = params.get("obj_type", False)
105102
if not obj_type:
106-
raise ValueError("When input type is 'mpc_input' key 'obj_type' is required.")
103+
raise ValueError("When input type is 'manual_input' key 'obj_type' is required.")
107104
if obj_type not in ("Asteroid", "Comet"):
108-
raise ValueError("Object type is case sensitive and must be one of: `Asteroid` or `Comet`")
105+
raise ValueError("Object type is case sensitive and must be one of: 'Asteroid' or 'Comet'")
109106

110107
# MOST will always require at least the distance and eccentricity
111108
# distance param is named differently in cases of asteroids and comets
@@ -128,8 +125,8 @@ def _validate_input(self, params):
128125
Validate the minimum required set of parameters, for a given input
129126
type, are at least truthy.
130127
131-
These include the keys `catalog`, `input_type`, `output_mode` and
132-
`ephem_step` in addition to keys required by the specified input type.
128+
These include the keys ``catalog``, ``input_type``, ``output_mode`` and
129+
``ephem_step`` in addition to keys required by the specified input type.
133130
134131
Parameters
135132
----------
@@ -159,13 +156,13 @@ def _validate_input(self, params):
159156
self._validate_manual_input_type(params)
160157
else:
161158
raise ValueError(
162-
"Unrecognized `input_type`. Expected `name_input`, `nafid_input` "
159+
"Unrecognized 'input_type'. Expected `name_input`, `nafid_input` "
163160
f"`mpc_input` or `manual_input`, got {input_type} instead."
164161
)
165162

166163
def _parse_full_regular_response(self, response, withTarballs=False):
167164
"""
168-
Parses the response when output type is set to `Regular` or `Full`.
165+
Parses the response when output type is set to ``"Regular"`` or ``"Full"``.
169166
170167
Parameters
171168
----------
@@ -178,14 +175,14 @@ def _parse_full_regular_response(self, response, withTarballs=False):
178175
Returns
179176
-------
180177
retdict : `dict`
181-
Dictionary containing the keys `results`, `metadata` and `region`.
182-
Optionally can contain keys `fits_tarball` and `region_tarball`.
183-
The `results` and `metadata` are an `astropy.table.Table` object
178+
Dictionary containing the keys ``results``, ``metadata`` and ``region``.
179+
Optionally can contain keys ``fits_tarball`` and ``region_tarball``.
180+
The ``results`` and ``metadata`` are an `astropy.table.Table` object
184181
containing the links to image and region files and minimum object
185-
metadata, while `metadata` contains the image metadata and object
186-
positions. The `region` key contains a link to the DS9 region file
182+
metadata, while ``metadata`` contains the image metadata and object
183+
positions. The ``region`` key contains a link to the DS9 region file
187184
representing the matched object trajectory and search boxes. When
188-
existing, `fits_tarball` and `region_tarball` are links to the
185+
existing, ``fits_tarball`` and ``region_tarball`` are links to the
189186
tarball archives of the fits and region images.
190187
"""
191188
retdict = {}
@@ -220,9 +217,9 @@ def list_catalogs(self):
220217
catalog_dropdown_options = html.find("select").find_all("option")
221218

222219
catalogs = [tag.string for tag in catalog_dropdown_options]
223-
# I think I saw somewhere that some password prompt will pop up for
224-
# catalogs listed as '--- Internal use only:' but there are seemingly
225-
# no limits to queries there.
220+
221+
# The Internal-Use-only datasets are free to search in MOST.
222+
# The way it is supposed to work is that the images will not be accessible.
226223
if "--- Internal use only:" in catalogs:
227224
catalogs.remove("--- Internal use only:")
228225
return catalogs
@@ -531,8 +528,7 @@ def query_object(self, catalog="wise_merge", input_mode="name_input", output_mod
531528
data=qparams, timeout=self.TIMEOUT)
532529

533530
# service unreachable or some other reason
534-
if not response.ok:
535-
raise response.raise_for_status()
531+
response.raise_for_status()
536532

537533
# MOST will not raise an bad response if the query is bad because they
538534
# are not a REST API
@@ -550,7 +546,7 @@ def query_object(self, catalog="wise_merge", input_mode="name_input", output_mod
550546
matches = votable.parse(io.BytesIO(response.content))
551547
if matches.get_table_by_index(0).nrows == 0:
552548
warnings.warn("Number of Matched Image Frames = 0", NoResultsWarning)
553-
return None
549+
return Table()
554550
return matches
555551
else:
556552
return self._parse_full_regular_response(response, qparams["fits_region_files"])

astroquery/ipac/irsa/tests/test_most.py

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,10 @@ def patch_requests(request):
8787

8888
def test_validation(patch_requests):
8989
"""Tests MOST parameter validation."""
90-
with pytest.raises(ValueError):
90+
with pytest.raises(ValueError, match="When input type is 'name_input' key 'obj_name' is required."):
9191
Most.query_object()
9292

93-
with pytest.raises(ValueError):
93+
with pytest.raises(ValueError, match="When input type is 'name_input' key 'obj_name' is required."):
9494
Most.query_object(catalog="wise_allsky_4band")
9595

9696
# make sure no funny business happens with
@@ -105,7 +105,7 @@ def test_validation(patch_requests):
105105
input_mode="name_input"
106106
)
107107

108-
with pytest.raises(ValueError):
108+
with pytest.raises(ValueError, match="When obj_type is 'Asteroid', 'semimajor_axis' is required."):
109109
# fails because insufficient orbital parameters specified
110110
Most.query_object(
111111
catalog="wise_allsky_4band",
@@ -125,7 +125,7 @@ def test_validation(patch_requests):
125125
eccentricity=0.33,
126126
)
127127

128-
with pytest.raises(ValueError):
128+
with pytest.raises(ValueError, match="When obj_type is 'Comet', 'perih_dist' is required."):
129129
# Comets require perihel_dist keyword
130130
# instead of smimajor_axis
131131
Most.query_object(
@@ -137,7 +137,7 @@ def test_validation(patch_requests):
137137
eccentricity=0.33
138138
)
139139

140-
with pytest.raises(ValueError):
140+
with pytest.raises(ValueError, match="Object type is case sensitive and must be one of: 'Asteroid' or 'Comet'"):
141141
# object type is case sensitive
142142
Most.query_object(
143143
catalog="wise_allsky_4band",
@@ -148,41 +148,42 @@ def test_validation(patch_requests):
148148
eccentricity=0.33
149149
)
150150

151-
with pytest.raises(ValueError):
151+
with pytest.raises(ValueError, match="When input type is 'mpc_input' key 'obj_type' is required."):
152152
# missing mpc_data and obj_type
153153
Most.query_object(
154154
catalog="wise_allsky_4band",
155155
output_mode="Brief",
156156
input_mode="mpc_input"
157157
)
158158

159-
Most.query_object(
159+
response = Most.query_object(
160160
catalog="wise_allsky_4band",
161161
output_mode="Brief",
162162
input_mode="mpc_input",
163163
obj_type="Asteroid",
164164
mpc_data="K10N010+2010+08+16.1477+1.494525+0.533798+153.4910+113.2118+12.8762+20100621+17.0+4.0+P/2010+N1+(WISE)+MPC+75712" # noqa: E501
165165
)
166+
assert len(response) > 0
166167

167168

168169
def test_regular(patch_requests):
169170
"""Tests the default MOST query returns expected results."""
170-
response = Most.query_object(obj_name="Victoria")
171+
results = Most.query_object(obj_name="Victoria")
171172

172-
assert "results" in response
173-
assert "metadata" in response
174-
assert "region" in response
175-
assert "fits_tarball" not in response
176-
assert "region_tarball" not in response
173+
assert "results" in results
174+
assert "metadata" in results
175+
assert "region" in results
176+
assert "fits_tarball" not in results
177+
assert "region_tarball" not in results
177178

178-
results = Table.read(data_path("most_regular_results.tbl"), format="ipac")
179-
metadata = Table.read(data_path("most_imgframes_matched_final_table.tbl"), format="ipac")
179+
expected_results = Table.read(data_path("most_regular_results.tbl"), format="ipac")
180+
expected_metadata = Table.read(data_path("most_imgframes_matched_final_table.tbl"), format="ipac")
180181
url = REGULAR_BASE_URL + "ds9region/ds9_orbit_path.reg"
181182

182183
silent_stream = io.StringIO()
183-
assert report_diff_values(results, response["results"], silent_stream)
184-
assert report_diff_values(metadata, response["metadata"], silent_stream)
185-
assert url == response["region"]
184+
assert report_diff_values(expected_results, results["results"], silent_stream)
185+
assert report_diff_values(expected_metadata, results["metadata"], silent_stream)
186+
assert url == results["region"]
186187

187188

188189
def test_get_full_with_tarballs(patch_requests):

astroquery/ipac/irsa/tests/test_most_remote.py

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
# Licensed under a 3-clause BSD style license - see LICENSE.rst
22
import os
33
import pytest
4-
import warnings
54

65
import numpy as np
76

87
import astropy.io.fits as fits
98
from astropy.table import Table
109
from astroquery.ipac.irsa import Most
11-
from astroquery.exceptions import InvalidQueryError
10+
from astroquery.exceptions import InvalidQueryError, NoResultsWarning
1211

1312
# each MOST query is given a PID and a temporary directory availible publicly
1413
# from this base URL. This URL is then used to create links on the returned
@@ -26,37 +25,38 @@ def data_path(filename):
2625
@pytest.mark.remote_data
2726
def test_query_object():
2827
"""Tests the default MOST query returns expected results."""
29-
response = Most.query_object(
28+
results = Most.query_object(
3029
obj_name="Victoria",
3130
obs_begin="2014-05-21",
3231
obs_end="2014-05-30"
3332
)
3433

3534
# check expected fields were returned
36-
assert "results" in response
37-
assert "metadata" in response
38-
assert "region" in response
39-
assert "fits_tarball" not in response
40-
assert "region_tarball" not in response
35+
assert "results" in results
36+
assert "metadata" in results
37+
assert "region" in results
38+
assert "fits_tarball" not in results
39+
assert "region_tarball" not in results
4140

4241
# check content is as expected for the columns we don't expect to change
43-
# This excludes URLS, they contain PIDs. The rest can be compared, but the
42+
# This excludes URLS; they contain PIDs. The rest can be compared, but the
4443
# problem is that report_diff_values doesn't sort the values and they are
4544
# not returned in same order nor header width. So we have to compare
4645
# manually
47-
results = Table.read(data_path("most_regular_results.tbl"), format="ipac")
46+
expected_results = Table.read(data_path("most_regular_results.tbl"), format="ipac")
4847

49-
columns = [col for col in results.columns if col not in ("image_url", "postcard_url", "region_file")]
48+
columns = [col for col in expected_results.columns if col not in ("image_url", "postcard_url", "region_file")]
5049
for col in columns:
51-
response_col = response["results"][col]
52-
results_col = results[col]
53-
response_col.sort()
50+
results_col = results["results"][col]
51+
expected_results_col = expected_results[col]
5452
results_col.sort()
55-
if 'float' in response_col.dtype.name:
56-
assert np.allclose(response_col, results_col, rtol=0.005)
53+
expected_results_col.sort()
54+
if 'float' in results_col.dtype.name:
55+
assert np.allclose(results_col, expected_results_col, rtol=0.005)
5756
else:
58-
# probably a string like Img_ID or datetime stamps
59-
assert all(response_col == results_col)
57+
# probably a string like Img_ID or datetime stamps so direct
58+
# comparison is ok
59+
assert all(results_col == expected_results_col)
6060

6161

6262
@pytest.mark.remote_data
@@ -91,8 +91,7 @@ def test_list_catalogs():
9191

9292
@pytest.mark.remote_data
9393
def test_no_results():
94-
with warnings.catch_warnings():
95-
warnings.simplefilter("ignore")
94+
with pytest.warns(NoResultsWarning, match="Number of Matched Image Frames = 0"):
9695
response = Most.query_object(
9796
obj_name="Victoria",
9897
obs_begin="2019-05-21",
@@ -101,8 +100,7 @@ def test_no_results():
101100

102101
assert response is None
103102

104-
with warnings.catch_warnings():
105-
warnings.simplefilter("ignore")
103+
with pytest.warns(NoResultsWarning, match="Number of Matched Image Frames = 0"):
106104
response = Most.get_images(
107105
obj_name="Victoria",
108106
obs_begin="2019-05-21",
@@ -114,14 +112,16 @@ def test_no_results():
114112

115113
@pytest.mark.remote_data
116114
def test_invalid_query():
117-
with pytest.raises(InvalidQueryError):
115+
err_msg = r".*observation time start time must be less than end time.*"
116+
117+
with pytest.raises(InvalidQueryError, match=err_msg):
118118
Most.query_object(
119119
obj_name="Victoria",
120120
obs_begin="2014-05-21",
121121
obs_end="2014-05-19"
122122
)
123123

124-
with pytest.raises(InvalidQueryError):
124+
with pytest.raises(InvalidQueryError, match=err_msg):
125125
Most.get_images(
126126
obj_name="Victoria",
127127
obs_begin="2014-05-21",

docs/ipac/irsa/most/most.rst

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ dist_ctr Projected distance from the center of the image (deg).
9797
phase Sun-Object-earth angle (deg).
9898
vmag Estimate of visual magnitude (from Horizons).
9999
image_url Links to download or view the data.
100-
postcard_url ??? usually ``null``
100+
postcard_url Currently ``null``. It is waiting for a future dataset that may have a png along with the image.
101101
region_file Markers for the moving object in DS9 "region" format.
102102
============ ===============================================================
103103

@@ -445,5 +445,4 @@ key:
445445
Reference/API
446446
=============
447447

448-
.. automodule:: astroquery.ipac.irsa.most
449-
:members:
448+
See `~astroquery.ipac.irsa.most.MostClass` and `~astroquery.ipac.irsa.Conf`.

0 commit comments

Comments
 (0)