4
4
5
5
# 2. third party imports
6
6
from astropy .time import Time
7
- from astropy import table
7
+ from astropy . table import QTable , join
8
8
import astropy .units as u
9
9
from astropy .coordinates import EarthLocation , Angle
10
10
from bs4 import BeautifulSoup
@@ -93,7 +93,8 @@ def ephemeris_async(self, planet, *, epoch=None, location=None, neptune_arcmodel
93
93
94
94
Parameters
95
95
----------
96
- planet : str, required. one of Mars, Jupiter, Saturn, Uranus, Neptune, or Pluto
96
+ planet : str
97
+ One of "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", or "Pluto".
97
98
epoch : `~astropy.time.Time` object, or str in format YYYY-MM-DD hh:mm, optional.
98
99
If str is provided then UTC is assumed.
99
100
If no epoch is provided, the current time is used.
@@ -107,8 +108,9 @@ def ephemeris_async(self, planet, *, epoch=None, location=None, neptune_arcmodel
107
108
`~astropy.coordinates.Angle` object, and altitude should
108
109
initialize an `~astropy.units.Quantity` object (with units
109
110
of length). If ``None``, then the geofocus is used.
110
- neptune_arcmodel : float, optional. which ephemeris to assume for Neptune's ring arcs
111
- must be one of 1, 2, or 3 (see https://pds-rings.seti.org/tools/viewer3_nep.shtml for details)
111
+ neptune_arcmodel : int, optional.
112
+ which ephemeris to assume for Neptune's ring arcs
113
+ Must be one of 1, 2, or 3 (see https://pds-rings.seti.org/tools/viewer3_nep.shtml for details)
112
114
has no effect if planet != 'Neptune'
113
115
get_query_payload : boolean, optional
114
116
When set to `True` the method returns the HTTP request parameters as
@@ -147,10 +149,9 @@ def ephemeris_async(self, planet, *, epoch=None, location=None, neptune_arcmodel
147
149
"""
148
150
149
151
planet = planet .lower ()
150
- if planet not in ["mars" , "jupiter" , "saturn" , "uranus" , "neptune" , "pluto" , ]:
151
- raise ValueError (
152
- "illegal value for 'planet' parameter (must be 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune', or 'Pluto')"
153
- )
152
+ if planet not in planet_defaults :
153
+ raise ValueError ("illegal value for 'planet' parameter "
154
+ "(must be 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune', or 'Pluto')" )
154
155
155
156
if isinstance (epoch , (int , float )):
156
157
epoch = Time (epoch , format = 'jd' )
@@ -174,13 +175,13 @@ def ephemeris_async(self, planet, *, epoch=None, location=None, neptune_arcmodel
174
175
loc = location .geodetic
175
176
longitude = loc [0 ].deg
176
177
latitude = loc [1 ].deg
177
- altitude = loc [2 ].to (u .m ). value
178
+ altitude = loc [2 ].to_value (u .m )
178
179
elif hasattr (location , "__iter__" ):
179
180
longitude = Angle (location [0 ]).deg
180
181
latitude = Angle (location [1 ]).deg
181
- altitude = u .Quantity (location [2 ]).to ( "m" ). value
182
+ altitude = u .Quantity (location [2 ]).to_value ( u . m )
182
183
183
- if int ( neptune_arcmodel ) not in [1 , 2 , 3 ]:
184
+ if neptune_arcmodel not in [1 , 2 , 3 ]:
184
185
raise ValueError (
185
186
f"Illegal Neptune arc model { neptune_arcmodel } . must be one of 1, 2, or 3 (see https://pds-rings.seti.org/tools/viewer3_nep.shtml for details)"
186
187
)
@@ -209,7 +210,7 @@ def ephemeris_async(self, planet, *, epoch=None, location=None, neptune_arcmodel
209
210
("altitude" , altitude ),
210
211
("moons" , planet_defaults [planet ]["moons" ]),
211
212
("rings" , planet_defaults [planet ]["rings" ]),
212
- ("arcmodel" , neptune_arcmodels [int ( neptune_arcmodel ) ]),
213
+ ("arcmodel" , neptune_arcmodels [neptune_arcmodel ]),
213
214
("extra_ra" , "" ), # figure options below this line, can all be hardcoded and ignored
214
215
("extra_ra_type" , "hours" ),
215
216
("extra_dec" , "" ),
@@ -251,15 +252,9 @@ def _parse_result(self, response, verbose=None):
251
252
252
253
Returns
253
254
-------
254
- bodytable : `astropy.QTable`
255
- ringtable : `astropy.QTable`
255
+ bodytable : `~ astropy.table .QTable`
256
+ ringtable : `~ astropy.table .QTable`
256
257
"""
257
- try :
258
- self ._last_query .remove_cache_file (self .cache_location )
259
- except FileNotFoundError :
260
- # this is allowed: if `cache` was set to False, this
261
- # won't be needed
262
- pass
263
258
264
259
soup = BeautifulSoup (response .text , "html.parser" )
265
260
text = soup .get_text ()
@@ -278,138 +273,116 @@ def _parse_result(self, response, verbose=None):
278
273
group = "NAIF " + group # fixing lack of header for NAIF ID
279
274
bodytable_names = ("NAIF ID" , "Body" , "RA" , "Dec" , "RA (deg)" , "Dec (deg)" , "dRA" , "dDec" )
280
275
bodytable_units = [None , None , None , None , u .deg , u .deg , u .arcsec , u .arcsec ]
281
- bodytable = table . QTable .read (group , format = "ascii.fixed_width" ,
276
+ bodytable = QTable .read (group , format = "ascii.fixed_width" ,
282
277
col_starts = (0 , 4 , 18 , 35 , 54 , 68 , 80 , 91 ),
283
278
col_ends = (4 , 18 , 35 , 54 , 68 , 80 , 91 , 102 ),
284
- names = bodytable_names )
285
- # units=(bodytable_units)) # this much cleaner way of adding units is supported in later versions but not in 3.7
286
- for name , unit in zip (bodytable_names , bodytable_units ):
287
- bodytable [name ].unit = unit
279
+ names = bodytable_names ,
280
+ units = (bodytable_units ))
288
281
289
282
# minor body table part 2
290
283
elif group .startswith ("Sub-" ):
291
284
292
285
group = os .linesep .join (group .splitlines ()[2 :]) # removing two-row header entirely
293
286
bodytable2_names = ("NAIF ID" , "Body" , "sub_obs_lon" , "sub_obs_lat" , "sub_sun_lon" , "sub_sun_lat" , "phase" , "distance" )
294
287
bodytable2_units = [None , None , u .deg , u .deg , u .deg , u .deg , u .deg , u .km * 1e6 ]
295
- bodytable2 = table .QTable .read (group , format = "ascii.fixed_width" ,
296
- col_starts = (0 , 4 , 18 , 28 , 37 , 49 , 57 , 71 ),
297
- col_ends = (4 , 18 , 28 , 37 , 49 , 57 , 71 , 90 ),
298
- names = bodytable2_names ,
299
- data_start = 0 )
300
- # units=(bodytable_units)) # this much cleaner way of adding units is supported in later versions but not in 3.7
301
- for name , unit in zip (bodytable2_names , bodytable2_units ):
302
- bodytable2 [name ].unit = unit
288
+ bodytable2 = QTable .read (group , format = "ascii.fixed_width" ,
289
+ col_starts = (0 , 4 , 18 , 28 , 37 , 49 , 57 , 71 ),
290
+ col_ends = (4 , 18 , 28 , 37 , 49 , 57 , 71 , 90 ),
291
+ names = bodytable2_names ,
292
+ data_start = 0 ,
293
+ units = (bodytable2_units ))
303
294
304
295
# ring plane data
305
296
elif group .startswith ("Ring s" ):
306
- lines = group .splitlines ()
307
- for line in lines :
308
- l = line .split (":" )
309
- if "Ring sub-solar latitude" in l [0 ]:
310
- [sub_sun_lat , sub_sun_lat_min , sub_sun_lat_max ] = [
311
- float (s .strip ("()" )) for s in re .split (r"\(|to" , l [1 ])
297
+ for line in group .splitlines ():
298
+ lines = line .split (":" )
299
+ if "Ring sub-solar latitude" in lines [0 ]:
300
+ sub_sun_lat , sub_sun_lat_min , sub_sun_lat_max = [
301
+ float (s .strip ("()" )) for s in re .split (r"\(|to" , lines [1 ])
312
302
]
313
303
systemtable = {
314
304
"sub_sun_lat" : sub_sun_lat * u .deg ,
315
305
"sub_sun_lat_min" : sub_sun_lat_min * u .deg ,
316
306
"sub_sun_lat_max" : sub_sun_lat_min * u .deg ,
317
307
}
318
308
319
- elif "Ring plane opening angle" in l [0 ]:
309
+ elif "Ring plane opening angle" in lines [0 ]:
320
310
systemtable ["opening_angle" ] = (
321
- float (re .sub ("[a-zA-Z]+" , "" , l [1 ]).strip ("()" )) * u .deg
311
+ float (re .sub ("[a-zA-Z]+" , "" , lines [1 ]).strip ("()" )) * u .deg
322
312
)
323
- elif "Ring center phase angle" in l [0 ]:
324
- systemtable ["phase_angle" ] = float (l [1 ].strip ()) * u .deg
325
- elif "Sub-solar longitude" in l [0 ]:
313
+ elif "Ring center phase angle" in lines [0 ]:
314
+ systemtable ["phase_angle" ] = float (lines [1 ].strip ()) * u .deg
315
+ elif "Sub-solar longitude" in lines [0 ]:
326
316
systemtable ["sub_sun_lon" ] = (
327
- float (re .sub ("[a-zA-Z]+" , "" , l [1 ]).strip ("()" )) * u .deg
317
+ float (re .sub ("[a-zA-Z]+" , "" , lines [1 ]).strip ("()" )) * u .deg
328
318
)
329
- elif "Sub-observer longitude" in l [0 ]:
330
- systemtable ["sub_obs_lon" ] = float (l [1 ].strip ()) * u .deg
331
- else :
332
- pass
319
+ elif "Sub-observer longitude" in lines [0 ]:
320
+ systemtable ["sub_obs_lon" ] = float (lines [1 ].strip ()) * u .deg
333
321
334
322
# basic info about the planet
335
323
elif group .startswith ("Sun-planet" ):
336
- lines = group .splitlines ()
337
- for line in lines :
338
- l = line .split (":" )
339
- if "Sun-planet distance (AU)" in l [0 ]:
324
+ for line in group .splitlines ():
325
+ lines = line .split (":" )
326
+ if "Sun-planet distance (AU)" in lines [0 ]:
340
327
# this is redundant with sun distance in km
341
328
pass
342
- elif "Observer-planet distance (AU)" in l [0 ]:
329
+ elif "Observer-planet distance (AU)" in lines [0 ]:
343
330
# this is redundant with observer distance in km
344
331
pass
345
- elif "Sun-planet distance (km)" in l [0 ]:
332
+ elif "Sun-planet distance (km)" in lines [0 ]:
346
333
systemtable ["d_sun" ] = (
347
- float (l [1 ].split ("x" )[0 ].strip ()) * 1e6 * u .km
334
+ float (lines [1 ].split ("x" )[0 ].strip ()) * 1e6 * u .km
348
335
)
349
- elif "Observer-planet distance (km)" in l [0 ]:
336
+ elif "Observer-planet distance (km)" in lines [0 ]:
350
337
systemtable ["d_obs" ] = (
351
- float (l [1 ].split ("x" )[0 ].strip ()) * 1e6 * u .km
338
+ float (lines [1 ].split ("x" )[0 ].strip ()) * 1e6 * u .km
352
339
)
353
- elif "Light travel time" in l [0 ]:
354
- systemtable ["light_time" ] = float (l [1 ].strip ()) * u .second
355
- else :
356
- pass
340
+ elif "Light travel time" in lines [0 ]:
341
+ systemtable ["light_time" ] = float (lines [1 ].strip ()) * u .second
357
342
358
343
# --------- below this line, planet-specific info ------------
359
344
# Uranus individual rings data
360
345
elif group .startswith ("Ring " ):
361
346
ringtable_names = ("ring" , "pericenter" , "ascending node" )
362
347
ringtable_units = [None , u .deg , u .deg ]
363
- ringtable = table .QTable .read (" " + group , format = "ascii.fixed_width" ,
364
- col_starts = (5 , 18 , 29 ),
365
- col_ends = (18 , 29 , 36 ),
366
- names = ringtable_names )
367
- # units=(ringtable_units)) # this much cleaner way of adding units is supported in later versions but not in 3.7
368
- for name , unit in zip (ringtable_names , ringtable_units ):
369
- ringtable [name ].unit = unit
348
+ ringtable = QTable .read (" " + group , format = "ascii.fixed_width" ,
349
+ col_starts = (5 , 18 , 29 ),
350
+ col_ends = (18 , 29 , 36 ),
351
+ names = ringtable_names ,
352
+ units = (ringtable_units ))
370
353
371
354
# Saturn F-ring data
372
355
elif group .startswith ("F Ring" ):
373
- lines = group .splitlines ()
374
- for line in lines :
375
- l = line .split (":" )
376
- if "F Ring pericenter" in l [0 ]:
377
- peri = float (re .sub ("[a-zA-Z]+" , "" , l [1 ]).strip ("()" ))
378
- elif "F Ring ascending node" in l [0 ]:
379
- ascn = float (l [1 ].strip ())
356
+ for line in group .splitlines ():
357
+ lines = line .split (":" )
358
+ if "F Ring pericenter" in lines [0 ]:
359
+ peri = float (re .sub ("[a-zA-Z]+" , "" , lines [1 ]).strip ("()" ))
360
+ elif "F Ring ascending node" in lines [0 ]:
361
+ ascn = float (lines [1 ].strip ())
380
362
ringtable_names = ("ring" , "pericenter" , "ascending node" )
381
363
ringtable_units = [None , u .deg , u .deg ]
382
- ringtable = table .QTable (
383
- [["F" ], [peri ], [ascn ]],
384
- names = ringtable_names )
385
- # units=(ringtable_units) # this much cleaner way of adding units is supported in later versions but not in 3.7
386
- for name , unit in zip (ringtable_names , ringtable_units ):
387
- ringtable [name ].unit = unit
364
+ ringtable = QTable ([["F" ], [peri ], [ascn ]],
365
+ names = ringtable_names ,
366
+ units = (ringtable_units ))
388
367
389
368
# Neptune ring arcs data
390
369
elif group .startswith ("Courage" ):
391
- lines = group .splitlines ()
392
- for i in range (len (lines )):
393
- l = lines [i ].split (":" )
394
- ring = l [0 ].split ("longitude" )[0 ].strip ()
370
+ for i , line in enumerate (group .splitlines ()):
371
+ lines = line .split (":" )
372
+ ring = lines [0 ].split ("longitude" )[0 ].strip ()
395
373
[min_angle , max_angle ] = [
396
374
float (s .strip ())
397
- for s in re .sub ("[a-zA-Z]+" , "" , l [1 ]).strip ("()" ).split ()
375
+ for s in re .sub ("[a-zA-Z]+" , "" , lines [1 ]).strip ("()" ).split ()
398
376
]
399
377
if i == 0 :
400
378
ringtable_names = ("ring" , "min_angle" , "max_angle" )
401
379
ringtable_units = [None , u .deg , u .deg ]
402
- ringtable = table .QTable (
403
- [[ring ], [min_angle ], [max_angle ]],
404
- names = ringtable_names )
405
- for name , unit in zip (ringtable_names , ringtable_units ):
406
- ringtable [name ].unit = unit
407
- # units=(ringtable_units) # this much cleaner way of adding units is supported in later versions but not in 3.7
380
+ ringtable = QTable ([[ring ], [min_angle ], [max_angle ]],
381
+ names = ringtable_names ,
382
+ units = ringtable_units )
408
383
else :
409
384
ringtable .add_row ([ring , min_angle * u .deg , max_angle * u .deg ])
410
385
411
- else :
412
- pass
413
386
414
387
# do some cleanup from the parsing job
415
388
# and make system-wide parameters metadata of bodytable and ringtable
@@ -418,7 +391,7 @@ def _parse_result(self, response, verbose=None):
418
391
ringtable .add_index ("ring" )
419
392
ringtable .meta = systemtable
420
393
421
- bodytable = table . join (bodytable , bodytable2 ) # concatenate minor body table
394
+ bodytable = join (bodytable , bodytable2 ) # concatenate minor body table
422
395
bodytable .add_index ("Body" )
423
396
bodytable .meta = systemtable
424
397
0 commit comments