Skip to content

Commit 7b31bba

Browse files
committed
Update to_ephem
* Move to_ephem to StateBase * compute coordinates if an observer is given * put frame in Ephem metadata
1 parent 26ed63b commit 7b31bba

1 file changed

Lines changed: 97 additions & 24 deletions

File tree

sbpy/dynamics/state.py

Lines changed: 97 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,103 @@ def to_skycoord(self) -> SkyCoord:
294294
else:
295295
return SkyCoord(self._data, obstime=self.t, representation_type="cartesian")
296296

297+
def to_ephem(self, observer: StateType | None = None) -> Ephem:
298+
r"""Convert to an sbpy ephemeris object.
299+
300+
301+
Parameters
302+
----------
303+
observer : `State`, optional
304+
Calculate RA/longitude, Dec/latitude, distance, etc for this
305+
observer.
306+
307+
308+
Returns
309+
-------
310+
eph : Ephem
311+
312+
313+
Notes
314+
-----
315+
316+
Observer state is stored in the `Ephem.meta` attribute. ``coords`` is
317+
calculated for the given observer.
318+
319+
========================= ====================
320+
Attribute or quantity ``Ephem`` field name
321+
========================= ====================
322+
t, as `Time` date
323+
t, as `Quantity` t_relative
324+
:math:`|r|` r
325+
:math:`|v \cdot \hat{r}|` rdot
326+
coords.ra ra
327+
coords.dec dec
328+
coords.pm_ra_cosdec ra*cos(dec)_rate
329+
coords.pm_dec dec_rate
330+
coords.lon lon
331+
coords.lat lat
332+
coords.pm_lon_coslat lon*cos(lat)_rate
333+
coords.pm_lat lat_rate
334+
coords.distance delta
335+
coords.radial_velocity deltadot
336+
x x
337+
y y
338+
z z
339+
v_x vx
340+
v_y vy
341+
v_z vz
342+
========================= ====================
343+
344+
"""
345+
346+
data: dict = {}
347+
348+
if isinstance(self.t, Time):
349+
data["date"] = self.t
350+
else:
351+
data["t_relative"] = self.t
352+
353+
data["r"] = abs(self)[0]
354+
data["rdot"] = np.sum(self.r * self.v, 1) / np.sqrt(np.sum(self.r * self.r, 1))
355+
356+
data["x"] = self.x
357+
data["y"] = self.y
358+
data["z"] = self.z
359+
data["vx"] = self.v_x
360+
data["vy"] = self.v_y
361+
data["vz"] = self.v_z
362+
363+
meta = {"frame": self.frame}
364+
365+
if observer is not None:
366+
meta["observer"] = {
367+
"r": self.observer.r,
368+
"v": self.observer.v,
369+
"t": self.observer.t,
370+
"frame": self.observer.frame,
371+
}
372+
373+
coords = observer.observe(self)
374+
375+
# use SkyCoords's to_table() method, which will account for when
376+
# RA/Dec vs lon/lat are used.
377+
tab = coords.to_table()
378+
379+
# convert SkyCoords's column names to Ephem's field names
380+
skycoords_to_ephem = {
381+
"pm_ra_cosdec": "ra*cos(dec)_rate",
382+
"pm_lon_coslat": "lon*cos(lat)_rate",
383+
"pm_dec": "dec_rate",
384+
"pm_lat": "lat_rate",
385+
"distance": "delta",
386+
"radial_velocity": "deltadot",
387+
}
388+
for col in tab.colnames:
389+
field = skycoords_to_ephem.get(col, col)
390+
data[field] = tab[col]
391+
392+
return Ephem.from_dict(data, meta=meta)
393+
297394
def transform_to(self, frame: FrameInputTypes) -> StateBaseType:
298395
"""Transform state into another reference frame.
299396
@@ -435,30 +532,6 @@ def from_ephem(
435532
" velocity fields."
436533
)
437534

438-
def to_ephem(self) -> Ephem:
439-
"""Convert to an ephemeris object.
440-
441-
442-
Returns
443-
-------
444-
eph : `~sbpy.data.ephem.Ephem`
445-
446-
"""
447-
448-
time_field = "dt" if self.arbitrary_time else "date"
449-
450-
eph = {
451-
time_field: self.t,
452-
"x": self.x,
453-
"y": self.y,
454-
"z": self.z,
455-
"vx": self.v_x,
456-
"vy": self.v_y,
457-
"vz": self.v_z,
458-
}
459-
460-
return Ephem.from_dict(eph, meta={"frame": self.frame})
461-
462535
def observe(self, target: StateType) -> SkyCoord:
463536
"""Project a target's position onto the sky.
464537

0 commit comments

Comments
 (0)