Source code for across.tools.ephemeris.jpl_ephem

from datetime import datetime, timedelta

import astropy.units as u  # type: ignore[import-untyped]
import astroquery.jplhorizons as jpl  # type: ignore[import-untyped]
from astropy.coordinates import (  # type: ignore[import-untyped]
    GCRS,
    ITRS,
    CartesianDifferential,
    CartesianRepresentation,
    SkyCoord,
)
from astropy.time import Time, TimeDelta  # type: ignore[import-untyped]

from .base import Ephemeris


[docs] class JPLEphemeris(Ephemeris): """ JPL Horizons-based ephemeris calculation. This class provides functionality to calculate ephemeris data using JPL Horizons system. It requires a Navigation and Ancillary Information Facility (NAIF) ID to identify the celestial object of interest. Parameters ---------- begin : datetime or Time Start time of the ephemeris calculation end : datetime or Time End time of the ephemeris calculation step_size : int or TimeDelta or timedelta, default=60 Time step between ephemeris points in seconds naif_id : int, optional NAIF ID of the celestial object for JPL Horizons query Attributes ---------- naif_id : int NAIF ID of object for JPL Horizons or Spice Kernel gcrs : SkyCoord Geocentric celestial reference system coordinates earth_location : EarthLocation Earth-fixed coordinates of the object Methods ------- prepare_data() Calculate ephemeris based on JPL Horizons data Notes ----- The class uses the JPL Horizons API to fetch vector data for the specified celestial object and converts it to both GCRS and ITRS coordinate frames. Raises ------ ValueError If no NAIF ID is provided when preparing the data """ # NAIF ID of object for JPL Horizons or Spice Kernel
[docs] naif_id: int | None = None
def __init__( self, begin: datetime | Time, end: datetime | Time, step_size: int | TimeDelta | timedelta = 60, naif_id: int | None = None, ) -> None: super().__init__(begin, end, step_size) self.naif_id = naif_id
[docs] def prepare_data(self) -> None: """Calculate ephemeris based on JPL Horizons data.""" # Check that parameters needed for JPL Horizons are set if self.naif_id is None: raise ValueError("No NAIF ID provided") # Calculate the number of steps between start and stop num_steps = len(self.timestamp) - 1 # Create a time range dictionary for Horizons horizons_range = { "start": str(self.begin.tdb.datetime), "stop": str(self.end.tdb.datetime), "step": str(num_steps), # Fetch the ephemeris vector data from Horizons horizons_ephemeris = jpl.Horizons( id=self.naif_id, location="500@399", epochs=horizons_range, id_type=None, ) horizons_vectors = horizons_ephemeris.vectors(refplane="earth") # Create a GCRS SkyCoord object from the ephemeris data self.gcrs = SkyCoord( CartesianRepresentation( horizons_vectors["x"].to(u.km), horizons_vectors["y"].to(u.km), horizons_vectors["z"].to(u.km), ).with_differentials( CartesianDifferential( horizons_vectors["vx"], horizons_vectors["vy"], horizons_vectors["vz"], ) ), frame=GCRS(obstime=self.timestamp), ) # Calculate the ITRS coordinates and Earth Location itrs = self.gcrs.transform_to(ITRS(obstime=self.timestamp)) self.earth_location = itrs.earth_location
[docs] def compute_jpl_ephemeris( begin: datetime | Time, end: datetime | Time, step_size: int | timedelta | TimeDelta, naif_id: int, ) -> Ephemeris: """ Compute space ephemeris data using JPL Horizons system. Parameters ---------- begin : Union[datetime, Time] Start date and time for ephemeris computation end : Union[datetime, Time] End date and time for ephemeris computation step_size : Union[int, timedelta, TimeDelta] Time step size between ephemeris points, in seconds if int naif_id : int Navigation and Ancillary Information Facility (NAIF) object identifier (e.g., 301 for Moon. -48 for HST) Returns ------- Ephemeris An Ephemeris object containing the computed ephemeris data Notes ----- This function uses the JPL Horizons system to compute high-precision ephemeris data for celestial bodies in space-based reference frame. Examples -------- >>> from datetime import datetime >>> begin = datetime(2023, 1, 1) >>> end = datetime(2023, 1, 2) >>> moon_ephemeris = compute_jpl_ephemeris(begin, end, 60, 301) """ # Compute the ephemeris using the JPLEphemeris class ephemeris = JPLEphemeris(naif_id=naif_id, begin=begin, end=end, step_size=step_size) ephemeris.compute() return ephemeris