Skip to content

Commit 840edf1

Browse files
authored
Merge pull request #2161 from mkelley/jplhorizons-fix-id_type-behavior
Revise id_type behavior in jplhorizons.
2 parents f32a0d5 + 3116180 commit 840edf1

File tree

5 files changed

+348
-334
lines changed

5 files changed

+348
-334
lines changed

CHANGES.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ jplhorizons
3434
Included in this update, the default reference system is changed from
3535
J2000 to ICRF, following API documentation. [#2154]
3636

37+
- Query ``id_type`` behavior has changed:
38+
- ``'majorbody'`` and ``'id'`` have been removed and the equivalent functionality
39+
replaced with ``None``. ``None`` implements the Horizons default, which is
40+
to search for major bodies first, then fall back to a small body search when
41+
no matches are found. Horizons does not have a major body only search.
42+
- The default value was ``'smallbody'`` but it is now ``None``, which
43+
follows Horizons's default behavior.
44+
3745
Infrastructure, Utility and Other Changes and Additions
3846
-------------------------------------------------------
3947

astroquery/jplhorizons/core.py

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from astropy.table import Table, Column
1313
from astropy.io import ascii
1414
from astropy.time import Time
15+
from astropy.utils.exceptions import AstropyDeprecationWarning
1516

1617
# 3. local imports - use relative imports
1718
# commonly required local imports shown below as example
@@ -29,13 +30,13 @@
2930
class HorizonsClass(BaseQuery):
3031
"""
3132
A class for querying the
32-
`JPL Horizons <https://ssd.jpl.nasa.gov/horizons.cgi>`_ service.
33+
`JPL Horizons <https://ssd.jpl.nasa.gov/horizons/>`_ service.
3334
"""
3435

3536
TIMEOUT = conf.timeout
3637

3738
def __init__(self, id=None, location=None, epochs=None,
38-
id_type='smallbody'):
39+
id_type=None):
3940
"""Instantiate JPL query.
4041
4142
Parameters
@@ -47,7 +48,7 @@ def __init__(self, id=None, location=None, epochs=None,
4748
orbital element or vector queries. Uses the same codes as JPL
4849
Horizons. If no location is provided, Earth's center is used for
4950
ephemerides queries and the Sun's center for elements and vectors
50-
queries. Arbitrary topocentic coordinates for ephemerides queries
51+
queries. Arbitrary topocentric coordinates for ephemerides queries
5152
can be provided in the format of a dictionary. The dictionary has to
5253
be of the form {``'lon'``: longitude in deg (East positive, West
5354
negative), ``'lat'``: latitude in deg (North positive, South
@@ -64,11 +65,18 @@ def __init__(self, id=None, location=None, epochs=None,
6465
element and vector queries. If no epochs are provided, the current
6566
time is used.
6667
id_type : str, optional
67-
Identifier type, options: ``'smallbody'``, ``'majorbody'`` (planets
68-
but also anything that is not a small body), ``'designation'``,
69-
``'name'``, ``'asteroid_name'``, ``'comet_name'``, ``'id'``
70-
(Horizons id number), or ``'smallbody'`` (find the closest match
71-
under any id_type), default: ``'smallbody'``
68+
Controls Horizons's object selection for ``id``
69+
[HORIZONSDOC_SELECTION]_ . Options: ``'designation'`` (small body
70+
designation), ``'name'`` (asteroid or comet name),
71+
``'asteroid_name'``, ``'comet_name'``, ``'smallbody'`` (asteroid
72+
and comet search), or ``None`` (first search search planets,
73+
natural satellites, spacecraft, and special cases, and if no
74+
matches, then search small bodies).
75+
76+
References
77+
----------
78+
79+
.. [HORIZONSDOC_SELECTION] https://ssd.jpl.nasa.gov/horizons/manual.html#select (retrieved 2021 Sep 23).
7280
7381
7482
Examples
@@ -79,7 +87,7 @@ def __init__(self, id=None, location=None, epochs=None,
7987
... 'stop':'2017-02-01',
8088
... 'step':'1d'})
8189
>>> print(eros) # doctest: +SKIP
82-
JPLHorizons instance "433"; location=568, epochs={'start': '2017-01-01', 'step': '1d', 'stop': '2017-02-01'}, id_type=smallbody
90+
JPLHorizons instance "433"; location=568, epochs={'start': '2017-01-01', 'step': '1d', 'stop': '2017-02-01'}, id_type=None
8391
"""
8492
super(HorizonsClass, self).__init__()
8593
self.id = id
@@ -101,9 +109,13 @@ def __init__(self, id=None, location=None, epochs=None,
101109
self.epochs = epochs
102110

103111
# check for id_type
104-
if id_type not in ['smallbody', 'majorbody',
105-
'designation', 'name',
106-
'asteroid_name', 'comet_name', 'id']:
112+
if id_type in ['majorbody', 'id']:
113+
warnings.warn("``id_type``s 'majorbody' and 'id' are deprecated "
114+
"and replaced with ``None``, which has the same "
115+
"functionality.", AstropyDeprecationWarning)
116+
id_type = None
117+
if id_type not in [None, 'smallbody', 'designation', 'name',
118+
'asteroid_name', 'comet_name']:
107119
raise ValueError('id_type ({:s}) not allowed'.format(id_type))
108120
self.id_type = id_type
109121

@@ -128,7 +140,7 @@ def __str__(self):
128140
... 'stop':'2017-02-01',
129141
... 'step':'1d'})
130142
>>> print(eros) # doctest: +SKIP
131-
JPLHorizons instance "433"; location=568, epochs={'start': '2017-01-01', 'step': '1d', 'stop': '2017-02-01'}, id_type=smallbody
143+
JPLHorizons instance "433"; location=568, epochs={'start': '2017-01-01', 'step': '1d', 'stop': '2017-02-01'}, id_type=None
132144
"""
133145
return ('JPLHorizons instance \"{:s}\"; location={:s}, '
134146
'epochs={:s}, id_type={:s}').format(

astroquery/jplhorizons/tests/test_jplhorizons.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,17 @@
66
from collections import OrderedDict
77

88
from numpy.ma import is_masked
9-
from ...utils.testing_tools import MockResponse
109
from astropy.tests.helper import assert_quantity_allclose
10+
from astropy.utils.exceptions import AstropyDeprecationWarning
1111

12+
from ...utils.testing_tools import MockResponse
1213
from ... import jplhorizons
1314

1415
# files in data/ for different query types
1516
DATA_FILES = {'ephemerides': 'ceres_ephemerides.txt',
1617
'elements': 'ceres_elements.txt',
1718
'vectors': 'ceres_vectors.txt',
18-
'"1935 UZ;"': 'no_H.txt'}
19+
'"1935 UZ"': 'no_H.txt'}
1920

2021

2122
def data_path(filename):
@@ -26,7 +27,7 @@ def data_path(filename):
2627
# monkeypatch replacement request function
2728
def nonremote_request(self, request_type, url, **kwargs):
2829

29-
if kwargs['params']['COMMAND'] == '"Ceres;"':
30+
if kwargs['params']['COMMAND'] == '"Ceres"':
3031
# pick DATA_FILE based on query type
3132
query_type = {'OBSERVER': 'ephemerides',
3233
'ELEMENTS': 'elements',
@@ -181,7 +182,7 @@ def test_elements_query_payload():
181182
('EPHEM_TYPE', 'ELEMENTS'),
182183
('MAKE_EPHEM', 'YES'),
183184
('OUT_UNITS', 'AU-D'),
184-
('COMMAND', '"Ceres;"'),
185+
('COMMAND', '"Ceres"'),
185186
('CENTER', "'500@10'"),
186187
('CSV_FORMAT', 'YES'),
187188
('ELEM_LABELS', 'YES'),
@@ -201,7 +202,7 @@ def test_vectors_query_payload():
201202
('format', 'text'),
202203
('EPHEM_TYPE', 'VECTORS'),
203204
('OUT_UNITS', 'AU-D'),
204-
('COMMAND', '"Ceres;"'),
205+
('COMMAND', '"Ceres"'),
205206
('CENTER', "'500@10'"),
206207
('CSV_FORMAT', '"YES"'),
207208
('REF_PLANE', 'ECLIPTIC'),
@@ -218,3 +219,17 @@ def test_no_H(patch_request):
218219
"""testing missing H value (also applies for G, M1, k1, M2, k2)"""
219220
res = jplhorizons.Horizons(id='1935 UZ').ephemerides()[0]
220221
assert 'H' not in res
222+
223+
224+
def test_id_type_deprecation():
225+
"""Test deprecation warnings based on issue 1742.
226+
227+
 https://github.com/astropy/astroquery/pull/2161
228+
229+
"""
230+
231+
with pytest.warns(AstropyDeprecationWarning):
232+
res = jplhorizons.Horizons(id='Ceres', id_type='id')
233+
234+
with pytest.warns(AstropyDeprecationWarning):
235+
res = jplhorizons.Horizons(id='Ceres', id_type='majorbody')

astroquery/jplhorizons/tests/test_jplhorizons_remote.py

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ def test_ephemerides_query(self):
1515
# check values of Ceres for a given epoch
1616
# orbital uncertainty of Ceres is basically zero
1717
res = jplhorizons.Horizons(id='Ceres', location='500',
18+
id_type='smallbody',
1819
epochs=2451544.5).ephemerides()[0]
1920

2021
assert res['targetname'] == "1 Ceres (A801 AA)"
@@ -152,7 +153,7 @@ def test_ephemerides_query_five(self):
152153

153154
def test_ephemerides_query_six(self):
154155
# tests optional constrains for ephemerides queries
155-
obj = jplhorizons.Horizons(id='3552',
156+
obj = jplhorizons.Horizons(id='3552', id_type='smallbody',
156157
location='I33',
157158
epochs={'start': '2018-05-01',
158159
'stop': '2018-08-01',
@@ -169,13 +170,14 @@ def test_ephemerides_query_six(self):
169170

170171
def test_ephemerides_query_raw(self):
171172
res = (jplhorizons.Horizons(id='Ceres', location='500',
172-
epochs=2451544.5).
173+
id_type='smallbody', epochs=2451544.5).
173174
ephemerides(get_raw_response=True))
174175

175176
assert len(res) >= 15400
176177

177178
def test_elements_query(self):
178179
res = jplhorizons.Horizons(id='Ceres', location='500@10',
180+
id_type='smallbody',
179181
epochs=[2451544.5,
180182
2451545.5]).elements()[0]
181183

@@ -204,6 +206,7 @@ def test_elements_query(self):
204206

205207
def test_elements_query_two(self):
206208
obj = jplhorizons.Horizons(id='Ceres', location='500@10',
209+
id_type='smallbody',
207210
epochs=[2451544.5,
208211
2451545.5])
209212

@@ -219,6 +222,7 @@ def test_elements_query_two(self):
219222

220223
def test_elements_query_raw(self):
221224
res = jplhorizons.Horizons(id='Ceres', location='500@10',
225+
id_type='smallbody',
222226
epochs=2451544.5).elements(
223227
get_raw_response=True)
224228

@@ -228,6 +232,7 @@ def test_vectors_query(self):
228232
# check values of Ceres for a given epoch
229233
# orbital uncertainty of Ceres is basically zero
230234
res = jplhorizons.Horizons(id='Ceres', location='500@10',
235+
id_type='smallbody',
231236
epochs=2451544.5).vectors()[0]
232237

233238
assert res['targetname'] == "1 Ceres (A801 AA)"
@@ -251,28 +256,25 @@ def test_vectors_query(self):
251256

252257
def test_vectors_query_raw(self):
253258
res = jplhorizons.Horizons(id='Ceres', location='500@10',
259+
id_type='smallbody',
254260
epochs=2451544.5).vectors(
255261
get_raw_response=True)
256262

257263
assert len(res) >= 6412
258264

259265
def test_unknownobject(self):
260-
try:
266+
with pytest.raises(ValueError):
261267
jplhorizons.Horizons(id='spamspamspameggsspam', location='500',
262268
epochs=2451544.5).ephemerides()
263-
except ValueError:
264-
pass
265269

266270
def test_multipleobjects(self):
267-
try:
268-
jplhorizons.Horizons(id='73P', location='500',
271+
with pytest.raises(ValueError):
272+
jplhorizons.Horizons(id='73P', location='500', id_type='smallbody',
269273
epochs=2451544.5).ephemerides()
270-
except ValueError:
271-
pass
272274

273275
def test_uri(self):
274276
target = jplhorizons.Horizons(id='3552', location='500',
275-
epochs=2451544.5)
277+
id_type='smallbody', epochs=2451544.5)
276278
assert target.uri is None
277279

278280
target.ephemerides()
@@ -299,10 +301,12 @@ def test__userdefinedlocation_ephemerides_query(self):
299301

300302
am_res = jplhorizons.Horizons(id='Ceres',
301303
location='688',
304+
id_type='smallbody',
302305
epochs=2451544.5).ephemerides()[0]
303306

304307
user_res = jplhorizons.Horizons(id='Ceres',
305308
location=anderson_mesa,
309+
id_type='smallbody',
306310
epochs=2451544.5).ephemerides()[0]
307311

308312
assert_quantity_allclose([am_res['RA'], am_res['DEC']],
@@ -342,6 +346,7 @@ def test_airmass(self):
342346

343347
# verify data['a-mass'].filled(99) works:
344348
target = jplhorizons.Horizons('Ceres', location='I41',
349+
id_type='smallbody',
345350
epochs=[2458300.5])
346351
eph = target.ephemerides(quantities='1,8')
347352
assert len(eph) == 1
@@ -352,7 +357,8 @@ def test_airmass(self):
352357

353358
def test_vectors_aberrations(self):
354359
"""Check functionality of `aberrations` options"""
355-
obj = jplhorizons.Horizons(id='1', epochs=2458500, location='500@0')
360+
obj = jplhorizons.Horizons(id='1', epochs=2458500, location='500@0',
361+
id_type='smallbody')
356362

357363
vec = obj.vectors(aberrations='geometric')
358364
assert_quantity_allclose(vec['x'][0], -2.086487005013347)
@@ -364,7 +370,8 @@ def test_vectors_aberrations(self):
364370
assert_quantity_allclose(vec['x'][0], -2.086576286974797)
365371

366372
def test_vectors_delta_T(self):
367-
obj = jplhorizons.Horizons(id='1', epochs=2458500, location='500@0')
373+
obj = jplhorizons.Horizons(id='1', epochs=2458500, location='500@0',
374+
id_type='smallbody')
368375

369376
vec = obj.vectors(delta_T=False)
370377
assert 'delta_T' not in vec.columns
@@ -373,7 +380,8 @@ def test_vectors_delta_T(self):
373380
assert_quantity_allclose(vec['delta_T'][0], 69.184373)
374381

375382
def test_ephemerides_extraprecision(self):
376-
obj = jplhorizons.Horizons(id='1', epochs=2458500, location='G37')
383+
obj = jplhorizons.Horizons(id='1', epochs=2458500, location='G37',
384+
id_type='smallbody')
377385

378386
vec_simple = obj.ephemerides(extra_precision=False)
379387
vec_highprec = obj.ephemerides(extra_precision=True)

0 commit comments

Comments
 (0)