Skip to content

Commit b884513

Browse files
emolterbsipocz
authored andcommitted
made all changes suggested by @eerovaher
1 parent eb6a179 commit b884513

File tree

5 files changed

+67
-74
lines changed

5 files changed

+67
-74
lines changed

astroquery/solarsystem/pds/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class Conf(_config.ConfigNamespace):
1515

1616
# server settings
1717
pds_server = _config.ConfigItem(
18-
["https://pds-rings.seti.org/cgi-bin/tools/viewer3_xxx.pl?"], "Ring Node"
18+
"https://pds-rings.seti.org/cgi-bin/tools/viewer3_xxx.pl?", "Ring Node"
1919
)
2020

2121
# implement later: other pds tools

astroquery/solarsystem/pds/core.py

Lines changed: 17 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# 1. standard library imports
22

3-
from collections import OrderedDict
43
import re
54
import warnings
65

@@ -11,7 +10,6 @@
1110
import astropy.units as u
1211
from astropy.coordinates import EarthLocation, Angle
1312
from bs4 import BeautifulSoup
14-
from astroquery import log
1513

1614
# 3. local imports - use relative imports
1715
# all Query classes should inherit from BaseQuery.
@@ -29,27 +27,17 @@ class RingNodeClass(BaseQuery):
2927
<https://pds-rings.seti.org/tools/>
3028
"""
3129

32-
TIMEOUT = conf.timeout
33-
34-
def __init__(self):
30+
def __init__(self, timeout=None):
3531
'''
3632
Instantiate Planetary Ring Node query
3733
'''
3834
super().__init__()
39-
self.URL = conf.pds_server
35+
self.url = conf.pds_server
36+
self.timeout = conf.timeout
4037
self.planet_defaults = conf.planet_defaults
4138

4239
def __str__(self):
43-
"""
44-
String representation of `~RingNodeClass` object instance
4540

46-
Examples
47-
--------
48-
>>> from astroquery.solarsystem.pds import RingNode
49-
>>> nodeobj = RingNode
50-
>>> print(nodeobj) # doctest: +SKIP
51-
PDSRingNode instance
52-
"""
5341
return "PDSRingNode instance"
5442

5543
def ephemeris_async(self, planet, *, epoch=None, location=None, neptune_arcmodel=3,
@@ -89,7 +77,7 @@ def ephemeris_async(self, planet, *, epoch=None, location=None, neptune_arcmodel
8977
--------
9078
>>> from astroquery.solarsystem.pds import RingNode
9179
>>> import astropy.units as u
92-
>>> systemtable, bodytable, ringtable = RingNode.ephemeris(planet='Uranus',
80+
>>> bodytable, ringtable = RingNode.ephemeris(planet='Uranus',
9381
... epoch='2024-05-08 22:39',
9482
... location = (-23.029 * u.deg, -67.755 * u.deg, 5000 * u.m)) # doctest: +REMOTE_DATA
9583
>>> print(ringtable) # doctest: +REMOTE_DATA
@@ -120,12 +108,10 @@ def ephemeris_async(self, planet, *, epoch=None, location=None, neptune_arcmodel
120108
epoch = Time(epoch, format='iso')
121109
elif epoch is None:
122110
epoch = Time.now()
123-
log.warning("Observation time not set. Using current time.")
124111

125112
if location is None:
126113
viewpoint = "observatory"
127114
latitude, longitude, altitude = "", "", ""
128-
log.warning("Observatory coordinates not set. Using center of Earth.")
129115
else:
130116
viewpoint = "latlon"
131117
if isinstance(location, EarthLocation):
@@ -134,8 +120,8 @@ def ephemeris_async(self, planet, *, epoch=None, location=None, neptune_arcmodel
134120
latitude = loc[1].deg
135121
altitude = loc[2].to(u.m).value
136122
elif hasattr(location, "__iter__"):
137-
latitude = Angle(location[0]).deg
138-
longitude = Angle(location[1]).deg
123+
longitude = Angle(location[0]).deg
124+
latitude = Angle(location[1]).deg
139125
altitude = u.Quantity(location[2]).to("m").value
140126

141127
if int(neptune_arcmodel) not in [1, 2, 3]:
@@ -145,11 +131,11 @@ def ephemeris_async(self, planet, *, epoch=None, location=None, neptune_arcmodel
145131

146132
# configure request_payload for ephemeris query
147133
# thankfully, adding extra planet-specific keywords here does not break query for other planets
148-
request_payload = OrderedDict(
134+
request_payload = dict(
149135
[
150136
("abbrev", planet[:3]),
151137
("ephem", self.planet_defaults[planet]["ephem"]),
152-
("time", epoch.utc.to_value("iso", subfmt="date_hm")), # UTC. this should be enforced when checking inputs
138+
("time", epoch.utc.iso[:16]),
153139
("fov", 10), # next few are figure options, can be hardcoded and ignored
154140
("fov_unit", planet.capitalize() + " radii"),
155141
("center", "body"),
@@ -192,7 +178,7 @@ def ephemeris_async(self, planet, *, epoch=None, location=None, neptune_arcmodel
192178

193179
# query and parse
194180
response = self._request(
195-
"GET", self.URL, params=request_payload, timeout=self.TIMEOUT, cache=cache
181+
"GET", self.url, params=request_payload, timeout=self.timeout, cache=cache
196182
)
197183

198184
return response
@@ -210,21 +196,19 @@ def _parse_result(self, response, verbose=None):
210196
211197
Returns
212198
-------
213-
systemtable : dict
214-
bodytable : `astropy.Table`
215-
ringtable : `astropy.Table`
199+
bodytable : `astropy.QTable`
200+
ringtable : `astropy.QTable`
216201
"""
217202
self.last_response = response
218203
try:
219204
self._last_query.remove_cache_file(self.cache_location)
220-
except OSError:
205+
except FileNotFoundError:
221206
# this is allowed: if `cache` was set to False, this
222207
# won't be needed
223208
pass
224209

225210
soup = BeautifulSoup(response.text, "html.parser")
226211
text = soup.get_text()
227-
# print(repr(text))
228212
textgroups = re.split("\n\n|\n \n", text)
229213
ringtable = None
230214
for group in textgroups:
@@ -354,15 +338,17 @@ def _parse_result(self, response, verbose=None):
354338
pass
355339

356340
# do some cleanup from the parsing job
341+
# and make system-wide parameters metadata of bodytable and ringtable
342+
systemtable["epoch"] = Time(epoch, format="iso", scale="utc") # add obs time to systemtable
357343
if ringtable is not None:
358344
ringtable.add_index("ring")
345+
ringtable.meta = systemtable
359346

360347
bodytable = table.join(bodytable, bodytable2) # concatenate minor body table
361348
bodytable.add_index("Body")
349+
bodytable.meta = systemtable
362350

363-
systemtable["epoch"] = Time(epoch, format="iso", scale="utc") # add obs time to systemtable
364-
365-
return systemtable, bodytable, ringtable
351+
return bodytable, ringtable
366352

367353

368354
RingNode = RingNodeClass()

astroquery/solarsystem/pds/tests/test_ringnode.py

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import os
33
import numpy as np
44

5-
from astropy.tests.helper import assert_quantity_allclose
65
import astropy.units as u
76

87
from astroquery.utils.mocks import MockResponse
@@ -45,13 +44,14 @@ def patch_request(request):
4544

4645
def test_ephemeris_query_Uranus(patch_request):
4746

48-
systemtable, bodytable, ringtable = pds.RingNode.ephemeris(
47+
bodytable, ringtable = pds.RingNode.ephemeris(
4948
planet="Uranus",
5049
epoch="2022-05-03 00:00",
51-
location=(10.0 * u.deg, -120.355 * u.deg, 1000 * u.m),
50+
location=(-120.355 * u.deg, 10.0 * u.deg, 1000 * u.m),
5251
)
5352
# check system table
54-
assert_quantity_allclose(
53+
systemtable = bodytable.meta
54+
assert np.allclose(
5555
[
5656
-56.12233,
5757
-56.13586,
@@ -83,7 +83,7 @@ def test_ephemeris_query_Uranus(patch_request):
8383
mab = bodytable[bodytable.loc_indices["Mab"]]
8484
assert mab["NAIF ID"] == 726
8585
assert mab["Body"] == "Mab"
86-
assert_quantity_allclose(
86+
assert np.allclose(
8787
[
8888
42.011201,
8989
15.801323,
@@ -119,14 +119,13 @@ def test_ephemeris_query_Uranus(patch_request):
119119

120120
def test_ephemeris_query_Pluto(patch_request):
121121

122-
systemtable, bodytable, ringtable = pds.RingNode.ephemeris(
122+
bodytable, ringtable = pds.RingNode.ephemeris(
123123
planet="Pluto",
124124
epoch="2021-10-07 07:25",
125125
)
126-
print(systemtable)
127-
print(bodytable[bodytable.loc_indices["Styx"]])
126+
systemtable = bodytable.meta
128127
# check system table
129-
assert_quantity_allclose(
128+
assert np.allclose(
130129
[
131130
57.57737,
132131
57.56961,
@@ -158,7 +157,7 @@ def test_ephemeris_query_Pluto(patch_request):
158157
styx = bodytable[bodytable.loc_indices["Styx"]]
159158
assert styx["NAIF ID"] == 905
160159
assert styx["Body"] == "Styx"
161-
assert_quantity_allclose(
160+
assert np.allclose(
162161
[
163162
296.212477,
164163
-22.93533,
@@ -193,15 +192,13 @@ def test_ephemeris_query_Pluto(patch_request):
193192
def test_ephemeris_query_Neptune(patch_request):
194193
'''Verify that the Neptune ring arcs are queried properly'''
195194

196-
systemtable, bodytable, ringtable = pds.RingNode.ephemeris(
195+
bodytable, ringtable = pds.RingNode.ephemeris(
197196
planet="Neptune",
198197
epoch="2021-10-07 07:25",
199198
neptune_arcmodel=2
200199
)
201200

202-
print(ringtable[ringtable.loc_indices["Courage"]])
203-
204-
assert_quantity_allclose(
201+
assert np.allclose(
205202
[63.81977,
206203
55.01978,
207204
44.21976,
@@ -227,13 +224,12 @@ def test_ephemeris_query_Neptune(patch_request):
227224

228225
def test_ephemeris_query_Saturn(patch_request):
229226
'''Check Saturn F ring is queried properly'''
230-
systemtable, bodytable, ringtable = pds.RingNode.ephemeris(
227+
bodytable, ringtable = pds.RingNode.ephemeris(
231228
planet="Saturn",
232229
epoch="2021-10-07 07:25",
233230
)
234-
print(ringtable)
235231

236-
assert_quantity_allclose(
232+
assert np.allclose(
237233
[249.23097,
238234
250.34081
239235
],
@@ -248,7 +244,7 @@ def test_ephemeris_query_payload():
248244
planet="Neptune",
249245
epoch="2022-05-03 00:00",
250246
neptune_arcmodel=1,
251-
location=(10.0 * u.deg, -120.355 * u.deg, 1000 * u.m),
247+
location=(-120.355 * u.deg, 10.0 * u.deg, 1000 * u.m),
252248
get_query_payload=True,
253249
)
254250

@@ -301,3 +297,12 @@ def test_ephemeris_query_payload():
301297
("output", "html"),
302298
]
303299
)
300+
301+
302+
def test_bad_query_raise():
303+
304+
with pytest.raises(ValueError):
305+
bodytable, ringtable = pds.RingNode.ephemeris(
306+
planet="Venus",
307+
epoch="2021-10-07 07:25",
308+
)

astroquery/solarsystem/pds/tests/test_ringnode_remote.py

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,22 @@
11
import pytest
2-
from astropy.tests.helper import assert_quantity_allclose
32
import numpy as np
43
import astropy.units as u
54

65
from ... import pds
76

87

9-
# Horizons has machinery here to mock request from a text file
10-
# is that necessary? why is that done?
11-
# wouldn't we want to know if the website we are querying changes something that makes code fail?
12-
13-
14-
# --------------------------------- actual test functions
15-
16-
178
@pytest.mark.remote_data
189
class TestRingNodeClass:
1910
def test_ephemeris_query(self):
2011

21-
systemtable, bodytable, ringtable = pds.RingNode.ephemeris(
12+
bodytable, ringtable = pds.RingNode.ephemeris(
2213
planet="Uranus",
2314
epoch="2022-05-03 00:00",
24-
location=(10.0 * u.deg, -120.355 * u.deg, 1000 * u.m),
15+
location=(-120.355 * u.deg, 10.0 * u.deg, 1000 * u.m),
2516
)
2617
# check system table
27-
assert_quantity_allclose(
18+
systemtable = bodytable.meta
19+
assert np.allclose(
2820
[
2921
-56.12233,
3022
-56.13586,
@@ -56,7 +48,7 @@ def test_ephemeris_query(self):
5648
mab = bodytable[bodytable.loc_indices["Mab"]]
5749
assert mab["NAIF ID"] == 726
5850
assert mab["Body"] == "Mab"
59-
assert_quantity_allclose(
51+
assert np.allclose(
6052
[
6153
42.011201,
6254
15.801323,

docs/solarsystem/pds/pds.rst

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ ephemerides of the rings and small moons around Uranus as viewed from ALMA:
2222
2323
>>> from astroquery.solarsystem.pds import RingNode
2424
>>> import astropy.units as u
25-
>>> systemtable, bodytable, ringtable = RingNode.ephemeris(planet='Uranus',
25+
>>> bodytable, ringtable = RingNode.ephemeris(planet='Uranus',
2626
... epoch='2024-05-08 22:39',
27-
... location = (-23.029 * u.deg, -67.755 * u.deg, 5000 * u.m)) # doctest: +REMOTE_DATA
27+
... location = (-67.755 * u.deg, -23.029 * u.deg, 5000 * u.m)) # doctest: +REMOTE_DATA
2828
>>> print(ringtable)
2929
ring pericenter ascending node
3030
deg deg
@@ -42,21 +42,23 @@ ephemerides of the rings and small moons around Uranus as viewed from ALMA:
4242
4343
``planet`` must be one of ['mars', 'jupiter', 'uranus', 'saturn', 'neptune', 'pluto'] (case-insensitive)
4444

45+
.. code-block:: python
46+
47+
>>> bodytable, ringtable = RingNode.ephemeris(planet='Venus',
48+
... epoch='2024-05-08 22:39',
49+
... location = (-67.755 * u.deg, -23.029 * u.deg, 5000 * u.m)) # doctest: +IGNORE_EXCEPTION_DETAIL
50+
Traceback (most recent call last):
51+
...
52+
ValueError: illegal value for 'planet' parameter (must be 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune', or 'Pluto')
53+
4554
``epoch`` is the datetime to query. Accepts a string in format 'YYYY-MM-DD HH:MM' (UTC assumed), or a `~astropy.time.Time` object. If no epoch is provided, the current time is used.
4655
47-
``location`` is the observer's location. Accepts an `~astropy.coordinates.EarthLocation`, or any 3-element array-like (e.g. list, tuple) of format (latitude, longitude, elevation). Longitude and latitude should be anything that initializes an `~astropy.coordinates.Angle` object, and altitude should initialize a `~astropy.units.Quantity` object (with units of length). If ``None``, then the geocenter is used.
56+
``location`` is the observer's location. Accepts an `~astropy.coordinates.EarthLocation`, or any 3-element array-like (e.g. list, tuple) of format (longitude, latitude, elevation). Longitude and latitude should be anything that initializes an `~astropy.coordinates.Angle` object, and altitude should initialize a `~astropy.units.Quantity` object (with units of length). If ``None``, then the geocenter is used.
4857

4958
``neptune_arcmodel`` is the choice of which ephemeris to assume for Neptune's ring arcs. accepts a float. must be one of 1, 2, or 3 (see https://pds-rings.seti.org/tools/viewer3_nep.shtml for details). default 3. has no effect if planet != 'Neptune'
5059

5160
Outputs
5261
---------
53-
``systemtable`` is a dict containing system-wide ephemeris data. Every value is a `~astropy.units.Quantity`. We can get a list of all the keys in this dictionary with:
54-
55-
.. code-block:: python
56-
57-
>>> print(systemtable.keys())
58-
dict_keys(['sub_sun_lat', 'sub_sun_lat_min', 'sub_sun_lat_max', 'opening_angle', 'phase_angle', 'sub_sun_lon', 'sub_obs_lon', 'd_sun', 'd_obs', 'light_time', 'epoch'])
59-
6062
``bodytable`` is a `~astropy.table.QTable` containing ephemeris information on the moons in the planetary system. Every column is assigned a unit from `~astropy.units`. We can get a list of all the columns in this table with:
6163

6264
.. code-block:: python
@@ -75,7 +77,7 @@ Note that the behavior of ``ringtable`` changes depending on the planet you quer
7577

7678
.. code-block:: python
7779
78-
>>> systemtable, bodytable, ringtable = RingNode.ephemeris(planet='Neptune', epoch='2022-05-24 00:00') # doctest: +REMOTE_DATA
80+
>>> bodytable, ringtable = RingNode.ephemeris(planet='Neptune', epoch='2022-05-24 00:00') # doctest: +REMOTE_DATA
7981
>>> print(ringtable)
8082
ring min_angle max_angle
8183
deg deg
@@ -85,6 +87,14 @@ Note that the behavior of ``ringtable`` changes depending on the planet you quer
8587
Egalite A 33.88179 34.88179
8688
Egalite B 30.0818 33.0818
8789
Fraternite 16.0818 25.68181
90+
91+
System-wide data are available as metadata in both ``bodytable`` and ``ringtable`` (if ``ringtable`` exists), e.g.:
92+
93+
.. code-block:: python
94+
95+
>>> systemtable = bodytable.meta
96+
>>> print(systemtable.keys())
97+
dict_keys(['sub_sun_lat', 'sub_sun_lat_min', 'sub_sun_lat_max', 'opening_angle', 'phase_angle', 'sub_sun_lon', 'sub_obs_lon', 'd_sun', 'd_obs', 'light_time', 'epoch'])
8898
8999
90100
Acknowledgements

0 commit comments

Comments
 (0)