13
13
from astropy .table import Table , Column
14
14
from astropy .io import ascii
15
15
from astropy .time import Time
16
+ from astropy import units as u
16
17
from astropy .utils .exceptions import AstropyDeprecationWarning
17
18
from astropy .utils .decorators import deprecated_renamed_argument , deprecated_attribute
18
19
@@ -53,14 +54,14 @@ def __init__(self, id=None, *, location=None, epochs=None,
53
54
54
55
id : str or dict, required
55
56
Name, number, or designation of target object. Uses the same codes
56
- as JPL Horizons. Arbitrary topocentric coordinates can be added
57
- in a dict. The dict has to be of the form
58
- { ``'lon '``: longitude in deg (East positive, West
59
- negative), ``'lat '``: latitude in deg (North positive, South
60
- negative), ``'elevation '``: elevation in km above the reference
61
- ellipsoid, [``' body'``: Horizons body ID of the central body;
62
- optional; if this value is not provided it is assumed that this
63
- location is on Earth]} .
57
+ as JPL Horizons. Arbitrary topocentric coordinates can be added in a
58
+ dict. The dict has to be of the form {``'lon'``: longitude in deg
59
+ (East positive, West negative), ``'lat '``: latitude in deg (North
60
+ positive, South negative), ``'elevation '``: elevation in km above
61
+ the reference ellipsoid, [ ``'body '``: Horizons body ID of the
62
+ central body; optional; if this value is not provided it is assumed
63
+ that this location is on Earth]}. Float values are assumed to have
64
+ units of degrees and kilometers .
64
65
65
66
location : str or dict, optional
66
67
Observer's location for ephemerides queries or center body name for
@@ -69,12 +70,13 @@ def __init__(self, id=None, *, location=None, epochs=None,
69
70
ephemerides queries and the Sun's center for elements and vectors
70
71
queries. Arbitrary topocentric coordinates for ephemerides queries
71
72
can be provided in the format of a dictionary. The dictionary has to
72
- be of the form {``'lon'``: longitude in deg (East positive, West
73
- negative), ``'lat'``: latitude in deg (North positive, South
74
- negative), ``'elevation'``: elevation in km above the reference
75
- ellipsoid, [``'body'``: Horizons body ID of the central body;
76
- optional; if this value is not provided it is assumed that this
77
- location is on Earth]}.
73
+ be of the form {``'lon'``: longitude (East positive, West negative),
74
+ ``'lat'``: latitude (North positive, South negative),
75
+ ``'elevation'``: elevation above the reference ellipsoid,
76
+ [``'body'``: Horizons body ID of the central body; optional; if this
77
+ value is not provided it is assumed that this location is on
78
+ Earth]}. Float values are assumed to have units of degrees and
79
+ kilometers.
78
80
79
81
epochs : scalar, list-like, or dictionary, optional
80
82
Either a list of epochs in JD or MJD format or a dictionary defining
@@ -117,16 +119,10 @@ def __init__(self, id=None, *, location=None, epochs=None,
117
119
"""
118
120
119
121
super ().__init__ ()
120
- # check & format coordinate dictionaries for id and location; simply
121
- # treat other values as given
122
- if isinstance (id , Mapping ):
123
- self .id = self ._prep_loc_dict (dict (id ), "id" )
124
- else :
125
- self .id = id
126
- if isinstance (location , Mapping ):
127
- self .location = self ._prep_loc_dict (dict (location ), "location" )
128
- else :
129
- self .location = location
122
+
123
+ self .id = id
124
+ self .location = location
125
+
130
126
# check for epochs to be dict or list-like; else: make it a list
131
127
if epochs is not None :
132
128
if isinstance (epochs , (list , tuple , ndarray )):
@@ -185,6 +181,32 @@ def __str__(self):
185
181
str (self .epochs ),
186
182
str (self .id_type ))
187
183
184
+ @property
185
+ def id (self ):
186
+ return self ._id
187
+
188
+ @id .setter
189
+ def id (self , _id ):
190
+ # check & format coordinate dictionaries for id; simply treat other
191
+ # values as given
192
+ if isinstance (_id , Mapping ):
193
+ self ._id = self ._prep_loc_dict (dict (_id ), "id" )
194
+ else :
195
+ self ._id = _id
196
+
197
+ @property
198
+ def location (self ):
199
+ return self ._location
200
+
201
+ @location .setter
202
+ def location (self , _location ):
203
+ # check & format coordinate dictionaries for location; simply treat
204
+ # other values as given
205
+ if isinstance (_location , Mapping ):
206
+ self ._location = self ._prep_loc_dict (dict (_location ), "location" )
207
+ else :
208
+ self ._location = _location
209
+
188
210
# ---------------------------------- query functions
189
211
190
212
@deprecated_renamed_argument ("get_raw_response" , None , since = "0.4.7" ,
@@ -593,10 +615,7 @@ def ephemerides_async(self, *, airmass_lessthan=99,
593
615
if self .id is None :
594
616
raise ValueError ("'id' parameter not set. Query aborted." )
595
617
elif isinstance (self .id , dict ):
596
- commandline = (
597
- f"g:{ self .id ['lon' ]} ,{ self .id ['lat' ]} ,"
598
- f"{ self .id ['elevation' ]} @{ self .id ['body' ]} "
599
- )
618
+ commandline = "g:" + self ._format_site_coords (self .id )
600
619
else :
601
620
commandline = str (self .id )
602
621
if self .location is None :
@@ -1080,7 +1099,7 @@ def vectors_async(self, *, get_query_payload=False,
1080
1099
if self .id is None :
1081
1100
raise ValueError ("'id' parameter not set. Query aborted." )
1082
1101
elif isinstance (self .id , dict ):
1083
- commandline = "g:{lon},{lat},{elevation}@{body}" . format ( ** self .id )
1102
+ commandline = "g:" + self . _format_site_coords ( self .id )
1084
1103
else :
1085
1104
commandline = str (self .id )
1086
1105
if self .location is None :
@@ -1183,6 +1202,10 @@ def _prep_loc_dict(loc_dict, attr_name):
1183
1202
)
1184
1203
if 'body' not in loc_dict :
1185
1204
loc_dict ['body' ] = 399
1205
+ # assumed units are degrees and km
1206
+ loc_dict ["lat" ] = u .Quantity (loc_dict ["lat" ], u .deg )
1207
+ loc_dict ["lon" ] = u .Quantity (loc_dict ["lon" ], u .deg )
1208
+ loc_dict ["elevation" ] = u .Quantity (loc_dict ["elevation" ], u .km )
1186
1209
return loc_dict
1187
1210
1188
1211
@staticmethod
@@ -1191,12 +1214,19 @@ def _location_to_params(loc_dict):
1191
1214
loc_dict = {
1192
1215
"CENTER" : f"coord@{ loc_dict ['body' ]} " ,
1193
1216
"COORD_TYPE" : "GEODETIC" ,
1194
- "SITE_COORD" : "," .join (
1195
- str (float (loc_dict [k ])) for k in ['lon' , 'lat' , 'elevation' ]
1196
- )
1217
+ "SITE_COORD" : HorizonsClass ._format_site_coords (loc_dict )
1197
1218
}
1198
1219
loc_dict ["SITE_COORD" ] = f"'{ loc_dict ['SITE_COORD' ]} '"
1199
1220
return loc_dict
1221
+
1222
+ @staticmethod
1223
+ def _format_site_coords (coords ):
1224
+ # formats lon/lat/elevation/body (e.g., id and location dictionaries) for the Horizons API
1225
+ "," .join (
1226
+ str (coords [k ].to_value ()) for k in ['lon' , 'lat' , 'elevation' ]
1227
+ )
1228
+ return (f"{ coords ['lon' ].to_value ('deg' )} ,{ coords ['lat' ].to_value ('deg' )} ,"
1229
+ f"{ coords ['elevation' ].to_value ('km' )} @{ coords ['body' ]} " )
1200
1230
1201
1231
def _parse_result (self , response , verbose = None ):
1202
1232
"""
0 commit comments