Python API
This page documents the main Python API exported by the rust_ephem extension
module. The native extension is built with maturin and exposed under the
module name rust_ephem.
Module Reference
API Overview
The module exposes the following primary classes and helper functions. If the compiled extension is not available at documentation build time these names may be mocked (see docs/README.md).
Classes
- Ephemeris (Abstract Base Class)
Common interface for all ephemeris types. All concrete ephemeris classes (TLEEphemeris, SPICEEphemeris, GroundEphemeris, OEMEphemeris, FileEphemeris, ParquetEphemeris) implement this interface and can be used interchangeably where an
Ephemerisis expected.Use
isinstance(obj, Ephemeris)to check if an object is any ephemeris type.- Common Properties:
timestamp— Array of UTC timestampsgcrs_pv— Position/velocity in GCRS frameitrs_pv— Position/velocity in ITRS framegcrs— GCRS coordinates as astropy SkyCoorditrs— ITRS coordinates as astropy SkyCoordsun,moon,earth— Celestial body SkyCoord objectssun_pv,moon_pv— Celestial body position/velocity dataobsgeoloc,obsgeovel— Observer location/velocity in GCRSlatitude_deg,longitude_deg,height_m— Geodetic coordinatessun_radius_deg,moon_radius_deg,earth_radius_deg— Angular radiisun_ra_dec_deg,moon_ra_dec_deg,earth_ra_dec_deg— RA/Dec as Nx2 arrays (cached)sun_ra_deg,sun_dec_deg, etc. — Individual RA or Dec as 1D arraysbegin,end,step_size,polar_motion— Time range properties
- Common Methods:
index(time)— Find closest timestamp indexget_body(body, spice_kernel=None, use_horizons=False)— Get SkyCoord for a celestial body. Ifuse_horizons=True, falls back to JPL Horizons when the body is not found in SPICE kernels.get_body_pv(body, spice_kernel=None, use_horizons=False)— Get position/velocity for a celestial body. Ifuse_horizons=True, falls back to JPL Horizons when the body is not found in SPICE kernels.moon_illumination(time_indices=None)— Calculate Moon illumination fraction (0.0-1.0) as seen from observerradec_to_altaz(ra_deg, dec_deg, time_indices=None)— Convert RA/Dec to Alt/Az coordinatescalculate_airmass(ra_deg, dec_deg, time_indices=None)— Calculate astronomical airmass for target
- Type Alias:
EphemerisType = TLEEphemeris | SPICEEphemeris | OEMEphemeris | GroundEphemeris | FileEphemeris | ParquetEphemeris
- TLEEphemeris
Propagate Two-Line Element (TLE) sets with SGP4 and convert to coordinate frames.
- Constructor:
TLEEphemeris(tle1=None, tle2=None, begin=None, end=None, step_size=60, *, polar_motion=False, tle=None, norad_id=None, norad_name=None, spacetrack_username=None, spacetrack_password=None, epoch_tolerance_days=None, enforce_source=None)- Parameters:
tle1(str, optional) — First line of TLE (legacy method)tle2(str, optional) — Second line of TLE (legacy method)tle(str | TLERecord, optional) — Path to TLE file, URL to download TLE from, or aTLERecordobjectnorad_id(int, optional) — NORAD catalog ID to fetch TLE. If Space-Track credentials are available, Space-Track is tried first with failover to Celestrak.norad_name(str, optional) — Satellite name to fetch TLE from Celestrakbegin(datetime) — Start time for ephemeris (required)end(datetime) — End time for ephemeris (required)step_size(int) — Time step in seconds (default: 60)polar_motion(bool) — Apply polar motion corrections (default: False)spacetrack_username(str, optional) — Space-Track.org username (or useSPACETRACK_USERNAMEenv var)spacetrack_password(str, optional) — Space-Track.org password (or useSPACETRACK_PASSWORDenv var)epoch_tolerance_days(float, optional) — For Space-Track cache: how many days TLE epoch can differ from target epoch (default: 4.0 days)enforce_source(str, optional) — Enforce use of specific source without failover. Must be"celestrak","spacetrack", orNone
- Notes:
Must provide exactly one of: (
tle1,tle2),tle,norad_id, ornorad_namebeginandendparameters are requiredFile paths and URLs are cached locally for performance
Space-Track.org credentials can also be provided via
.envfile
- Attributes (read-only):
tle_epoch— TLE epoch as Python datetime (extracted from line 1)teme_pv— Position/velocity in TEME frame (PositionVelocityData)itrs_pv— Position/velocity in ITRS frame (PositionVelocityData)gcrs_pv— Position/velocity in GCRS frame (PositionVelocityData)sun_pv— Sun position/velocity in GCRS frame (PositionVelocityData)moon_pv— Moon position/velocity in GCRS frame (PositionVelocityData)timestamp— List of Python datetime objectsitrs— ITRS coordinates as astropy SkyCoordgcrs— GCRS coordinates as astropy SkyCoordlatitude— Observatory latitude as an astropy Quantity array (degrees), one per timestamplatitude_deg— Observatory latitude as NumPy array (degrees), one per timestamplatitude_rad— Observatory latitude as NumPy array (radians), one per timestamplongitude— Observatory longitude as an astropy Quantity array (degrees), one per timestamplongitude_deg— Observatory longitude as NumPy array (degrees), one per timestamplongitude_rad— Observatory longitude as NumPy array (radians), one per timestampheight— Observatory height as an astropy Quantity array (meters), one per timestampheight_m— Observatory height as raw NumPy array (meters), one per timestampheight_km— Observatory height as raw NumPy array (kilometers), one per timestampearth— Earth position as astropy SkyCoordsun— Sun position as astropy SkyCoordmoon— Moon position as astropy SkyCoordobsgeoloc— Observer geocentric location (alias for GCRS position)obsgeovel— Observer geocentric velocity (alias for GCRS velocity)sun_radius— Sun angular radius as astropy Quantity (degrees)sun_radius_deg— Sun angular radius as NumPy array (degrees)sun_radius_rad— Sun angular radius as NumPy array (radians)moon_radius— Moon angular radius as astropy Quantity (degrees)moon_radius_deg— Moon angular radius as NumPy array (degrees)moon_radius_rad— Moon angular radius as NumPy array (radians)earth_radius— Earth angular radius as astropy Quantity (degrees)earth_radius_deg— Earth angular radius as NumPy array (degrees)earth_radius_rad— Earth angular radius as NumPy array (radians)sun_ra_dec_deg— Sun RA/Dec as Nx2 NumPy array (degrees), cachedsun_ra_dec_rad— Sun RA/Dec as Nx2 NumPy array (radians), cachedmoon_ra_dec_deg— Moon RA/Dec as Nx2 NumPy array (degrees), cachedmoon_ra_dec_rad— Moon RA/Dec as Nx2 NumPy array (radians), cachedearth_ra_dec_deg— Earth RA/Dec as Nx2 NumPy array (degrees), cachedearth_ra_dec_rad— Earth RA/Dec as Nx2 NumPy array (radians), cachedsun_ra_deg,sun_dec_deg— Sun RA and Dec as separate 1D arrays (degrees)sun_ra_rad,sun_dec_rad— Sun RA and Dec as separate 1D arrays (radians)moon_ra_deg,moon_dec_deg— Moon RA and Dec as separate 1D arrays (degrees)moon_ra_rad,moon_dec_rad— Moon RA and Dec as separate 1D arrays (radians)earth_ra_deg,earth_dec_deg— Earth RA and Dec as separate 1D arrays (degrees)earth_ra_rad,earth_dec_rad— Earth RA and Dec as separate 1D arrays (radians)
- Methods:
index(time)— Find the index of the closest timestamp to the given datetimetime— Python datetime objectReturns:
intindex that can be used to access ephemeris arraysExample:
idx = eph.index(datetime(2024, 1, 1, 12, 0, 0))thenposition = eph.gcrs_pv.position[idx]
get_body_pv(body)— Get position/velocity of a solar system body relative to observerbody— Body name (e.g., “Sun”, “Moon”, “Mars”) or NAIF ID as string (e.g., “10”, “301”)Returns:
PositionVelocityDatawith position/velocity in GCRS frameRequires:
ensure_planetary_ephemeris()called first
get_body(body)— Get SkyCoord for a solar system body with observer location setbody— Body name or NAIF ID as stringReturns:
astropy.coordinates.SkyCoordin GCRS frame with obsgeoloc/obsgeovel setRequires:
ensure_planetary_ephemeris()called first
- SPICEEphemeris
Spacecraft ephemeris from SPICE SPK (Spacecraft and Planet Kernel) files. Use this for missions that provide trajectory data in SPICE format.
- Constructor:
SPICEEphemeris(spk_path, naif_id, begin, end, step_size=60, center_id=399, *, polar_motion=False)spk_path— Path to the SPICE SPK file containing spacecraft trajectorynaif_id— NAIF ID of the spacecraft (typically negative, e.g., -82 for Cassini)center_id— NAIF ID of the observer center (default: 399 = Earth)
- Attributes (read-only):
gcrs_pv— Position/velocity in GCRS frame (PositionVelocityData)itrs_pv— Position/velocity in ITRS frame (PositionVelocityData)sun_pv— Sun position/velocity in GCRS frame (PositionVelocityData)moon_pv— Moon position/velocity in GCRS frame (PositionVelocityData)timestamp— List of Python datetime objectsitrs— ITRS coordinates as astropy SkyCoordgcrs— GCRS coordinates as astropy SkyCoordearth— Earth position as astropy SkyCoordsun— Sun position as astropy SkyCoordmoon— Moon position as astropy SkyCoordlatitude— Geodetic latitude as an astropy Quantity array (degrees), one per timestamplatitude_deg— Geodetic latitude as NumPy array (degrees), one per timestamplatitude_rad— Geodetic latitude as NumPy array (radians), one per timestamplongitude— Geodetic longitude as an astropy Quantity array (degrees), one per timestamplongitude_deg— Geodetic longitude as NumPy array (degrees), one per timestamplongitude_rad— Geodetic longitude as NumPy array (radians), one per timestampheight— Height as an astropy Quantity array (meters), one per timestampheight_m— Height as raw NumPy array (meters), one per timestampheight_km— Height as raw NumPy array (kilometers), one per timestampobsgeoloc— Observer geocentric location (alias for GCRS position)obsgeovel— Observer geocentric velocity (alias for GCRS velocity)sun_radius— Sun angular radius as astropy Quantity (degrees)sun_radius_deg— Sun angular radius as NumPy array (degrees)sun_radius_rad— Sun angular radius as NumPy array (radians)moon_radius— Moon angular radius as astropy Quantity (degrees)moon_radius_deg— Moon angular radius as NumPy array (degrees)moon_radius_rad— Moon angular radius as NumPy array (radians)earth_radius— Earth angular radius as astropy Quantity (degrees)earth_radius_deg— Earth angular radius as NumPy array (degrees)earth_radius_rad— Earth angular radius as NumPy array (radians)sun_ra_dec_deg— Sun RA/Dec as Nx2 NumPy array (degrees), cachedsun_ra_dec_rad— Sun RA/Dec as Nx2 NumPy array (radians), cachedmoon_ra_dec_deg— Moon RA/Dec as Nx2 NumPy array (degrees), cachedmoon_ra_dec_rad— Moon RA/Dec as Nx2 NumPy array (radians), cachedearth_ra_dec_deg— Earth RA/Dec as Nx2 NumPy array (degrees), cachedearth_ra_dec_rad— Earth RA/Dec as Nx2 NumPy array (radians), cachedsun_ra_deg,sun_dec_deg— Sun RA and Dec as separate 1D arrays (degrees)sun_ra_rad,sun_dec_rad— Sun RA and Dec as separate 1D arrays (radians)moon_ra_deg,moon_dec_deg— Moon RA and Dec as separate 1D arrays (degrees)moon_ra_rad,moon_dec_rad— Moon RA and Dec as separate 1D arrays (radians)earth_ra_deg,earth_dec_deg— Earth RA and Dec as separate 1D arrays (degrees)earth_ra_rad,earth_dec_rad— Earth RA and Dec as separate 1D arrays (radians)
- Methods:
index(time)— Find the index of the closest timestamp to the given datetimetime— Python datetime objectReturns:
intindex that can be used to access ephemeris arraysExample:
idx = eph.index(datetime(2024, 1, 1, 12, 0, 0))thenposition = eph.gcrs_pv.position[idx]
get_body_pv(body)— Get position/velocity of a solar system body relative to observerbody— Body name (e.g., “Sun”, “Moon”, “Mars”) or NAIF ID as stringReturns:
PositionVelocityDatawith position/velocity in GCRS frame
get_body(body)— Get SkyCoord for a solar system body with observer location setbody— Body name or NAIF ID as stringReturns:
astropy.coordinates.SkyCoordin GCRS frame
- GroundEphemeris
Ground-based observatory ephemeris for a fixed point on Earth’s surface.
- Constructor:
GroundEphemeris(latitude, longitude, height, begin, end, step_size=60, *, polar_motion=False)latitude— Geodetic latitude in degrees (-90 to 90)longitude— Geodetic longitude in degrees (-180 to 180)height— Altitude in meters above WGS84 ellipsoid
- Attributes (read-only):
latitude— Observatory latitude as an astropy Quantity array (degrees), one per timestamplongitude— Observatory longitude as an astropy Quantity array (degrees), one per timestampheight— Observatory height as an astropy Quantity array (meters), one per timestampheight_m— Observatory height raw numpy array (meters), one per timestampgcrs_pv— Position/velocity in GCRS frame (PositionVelocityData)itrs_pv— Position/velocity in ITRS frame (PositionVelocityData)sun_pv— Sun position/velocity in GCRS frame (PositionVelocityData)moon_pv— Moon position/velocity in GCRS frame (PositionVelocityData)timestamp— List of Python datetime objectsitrs— ITRS coordinates as astropy SkyCoordgcrs— GCRS coordinates as astropy SkyCoordearth— Earth position as astropy SkyCoordsun— Sun position as astropy SkyCoordmoon— Moon position as astropy SkyCoordlatitude— Geodetic latitude as an astropy Quantity array (degrees), one per timestamplatitude_deg— Geodetic latitude as NumPy array (degrees), one per timestamplatitude_rad— Geodetic latitude as NumPy array (radians), one per timestamplongitude— Geodetic longitude as an astropy Quantity array (degrees), one per timestamplongitude_deg— Geodetic longitude as NumPy array (degrees), one per timestamplongitude_rad— Geodetic longitude as NumPy array (radians), one per timestampheight— Height as an astropy Quantity array (meters), one per timestampheight_m— Height as raw NumPy array (meters), one per timestampheight_km— Height as raw NumPy array (kilometers), one per timestampobsgeoloc— Observer geocentric location (alias for GCRS position)obsgeovel— Observer geocentric velocity (alias for GCRS velocity)sun_radius— Sun angular radius as astropy Quantity (degrees)sun_radius_deg— Sun angular radius as NumPy array (degrees)sun_radius_rad— Sun angular radius as NumPy array (radians)moon_radius— Moon angular radius as astropy Quantity (degrees)moon_radius_deg— Moon angular radius as NumPy array (degrees)moon_radius_rad— Moon angular radius as NumPy array (radians)earth_radius— Earth angular radius as astropy Quantity (degrees)earth_radius_deg— Earth angular radius as NumPy array (degrees)earth_radius_rad— Earth angular radius as NumPy array (radians)sun_ra_dec_deg— Sun RA/Dec as Nx2 NumPy array (degrees), cachedsun_ra_dec_rad— Sun RA/Dec as Nx2 NumPy array (radians), cachedmoon_ra_dec_deg— Moon RA/Dec as Nx2 NumPy array (degrees), cachedmoon_ra_dec_rad— Moon RA/Dec as Nx2 NumPy array (radians), cachedearth_ra_dec_deg— Earth RA/Dec as Nx2 NumPy array (degrees), cachedearth_ra_dec_rad— Earth RA/Dec as Nx2 NumPy array (radians), cachedsun_ra_deg,sun_dec_deg— Sun RA and Dec as separate 1D arrays (degrees)sun_ra_rad,sun_dec_rad— Sun RA and Dec as separate 1D arrays (radians)moon_ra_deg,moon_dec_deg— Moon RA and Dec as separate 1D arrays (degrees)moon_ra_rad,moon_dec_rad— Moon RA and Dec as separate 1D arrays (radians)earth_ra_deg,earth_dec_deg— Earth RA and Dec as separate 1D arrays (degrees)earth_ra_rad,earth_dec_rad— Earth RA and Dec as separate 1D arrays (radians)
- Methods:
index(time)— Find the index of the closest timestamp to the given datetimetime— Python datetime objectReturns:
intindex that can be used to access ephemeris arraysExample:
idx = eph.index(datetime(2024, 1, 1, 12, 0, 0))thensun_position = eph.sun_pv.position[idx]
get_body_pv(body)— Get position/velocity of a solar system body relative to observerbody— Body name (e.g., “Sun”, “Moon”, “Mars”) or NAIF ID as stringReturns:
PositionVelocityDatawith position/velocity in GCRS frameRequires:
ensure_planetary_ephemeris()called first
get_body(body)— Get SkyCoord for a solar system body with observer location setbody— Body name or NAIF ID as stringReturns:
astropy.coordinates.SkyCoordin GCRS frame
- OEMEphemeris
Load and interpolate CCSDS Orbit Ephemeris Message (OEM) files for spacecraft ephemeris.
The OEM file must use a GCRS-compatible reference frame such as J2000, EME2000, GCRF, or ICRF. Earth-fixed frames (e.g., ITRF) are not supported and will raise a ValueError.
- Constructor:
OEMEphemeris(oem_file_path, begin, end, step_size=60, *, polar_motion=False)oem_file_path— Path to CCSDS OEM file (.oem)begin— Start time for ephemeris (Python datetime)end— End time for ephemeris (Python datetime)step_size— Time step in seconds for interpolated ephemeris (default: 60)polar_motion— Enable polar motion corrections (default: False)
- Raises:
ValueError— If reference frame is missing or incompatible with GCRS
- Attributes (read-only):
oem_pv— Original OEM state vectors (PositionVelocityData) without interpolationoem_timestamp— Original OEM timestamps (list of datetime) without interpolationgcrs_pv— Interpolated position/velocity in GCRS frame (PositionVelocityData)itrs_pv— Position/velocity in ITRS frame (PositionVelocityData)sun_pv— Sun position/velocity in GCRS frame (PositionVelocityData)moon_pv— Moon position/velocity in GCRS frame (PositionVelocityData)timestamp— List of Python datetime objects for interpolated ephemerisitrs— ITRS coordinates as astropy SkyCoordgcrs— GCRS coordinates as astropy SkyCoordearth— Earth position as astropy SkyCoordsun— Sun position as astropy SkyCoordmoon— Moon position as astropy SkyCoordlatitude— Geodetic latitude as an astropy Quantity array (degrees), one per timestamplatitude_deg— Geodetic latitude as NumPy array (degrees), one per timestamplatitude_rad— Geodetic latitude as NumPy array (radians), one per timestamplongitude— Geodetic longitude as an astropy Quantity array (degrees), one per timestamplongitude_deg— Geodetic longitude as NumPy array (degrees), one per timestamplongitude_rad— Geodetic longitude as NumPy array (radians), one per timestampheight— Height as an astropy Quantity array (meters), one per timestampheight_m— Height as raw NumPy array (meters), one per timestampheight_km— Height as raw NumPy array (kilometers), one per timestampobsgeoloc— Observer geocentric location (alias for GCRS position)obsgeovel— Observer geocentric velocity (alias for GCRS velocity)sun_radius— Sun angular radius as astropy Quantity (degrees)sun_radius_deg— Sun angular radius as NumPy array (degrees)sun_radius_rad— Sun angular radius as NumPy array (radians)moon_radius— Moon angular radius as astropy Quantity (degrees)moon_radius_deg— Moon angular radius as NumPy array (degrees)moon_radius_rad— Moon angular radius as NumPy array (radians)earth_radius— Earth angular radius as astropy Quantity (degrees)earth_radius_deg— Earth angular radius as NumPy array (degrees)earth_radius_rad— Earth angular radius as NumPy array (radians)sun_ra_dec_deg— Sun RA/Dec as Nx2 NumPy array (degrees), cachedsun_ra_dec_rad— Sun RA/Dec as Nx2 NumPy array (radians), cachedmoon_ra_dec_deg— Moon RA/Dec as Nx2 NumPy array (degrees), cachedmoon_ra_dec_rad— Moon RA/Dec as Nx2 NumPy array (radians), cachedearth_ra_dec_deg— Earth RA/Dec as Nx2 NumPy array (degrees), cachedearth_ra_dec_rad— Earth RA/Dec as Nx2 NumPy array (radians), cachedsun_ra_deg,sun_dec_deg— Sun RA and Dec as separate 1D arrays (degrees)sun_ra_rad,sun_dec_rad— Sun RA and Dec as separate 1D arrays (radians)moon_ra_deg,moon_dec_deg— Moon RA and Dec as separate 1D arrays (degrees)moon_ra_rad,moon_dec_rad— Moon RA and Dec as separate 1D arrays (radians)earth_ra_deg,earth_dec_deg— Earth RA and Dec as separate 1D arrays (degrees)earth_ra_rad,earth_dec_rad— Earth RA and Dec as separate 1D arrays (radians)
- Methods:
index(time)— Find the index of the closest timestamp to the given datetimetime— Python datetime objectReturns:
intindex that can be used to access ephemeris arraysExample:
idx = eph.index(datetime(2032, 7, 1, 12, 0, 0))thenposition = eph.gcrs_pv.position[idx]
get_body_pv(body)— Get position/velocity of a solar system body relative to observerbody— Body name (e.g., “Sun”, “Moon”, “Mars”) or NAIF ID as stringReturns:
PositionVelocityDatawith position/velocity in GCRS frameRequires:
ensure_planetary_ephemeris()called first
get_body(body)— Get SkyCoord for a solar system body with observer location setbody— Body name or NAIF ID as stringReturns:
astropy.coordinates.SkyCoordin GCRS frame
- FileEphemeris
Load pre-computed state vectors from a simulator output file and resample to a uniform output grid via Hermite interpolation. Supports offset-based simulator output, simple CSV/TSV layouts, and any file where data rows contain seven whitespace-separated values:
<time> <x> <y> <z> <vx> <vy> <vz>.The coordinate frame, reference epoch, and units are auto-detected from header key-value pairs and may be overridden via constructor parameters.
- Constructor:
FileEphemeris(file_path, begin, end, step_size=60, *, polar_motion=False, position_unit=None, velocity_unit=None, frame=None, epoch=None, time_format=None)file_path— Path to the ephemeris filebegin— Start time for the output grid (Python datetime, UTC)end— End time for the output grid (Python datetime, UTC)step_size— Output time step in seconds (default: 60)polar_motion— Apply polar motion correction (default: False)position_unit— Override detected position unit:"km"(default),"m","cm"velocity_unit— Override detected velocity unit:"km/s"(default),"m/s","cm/s"frame— Override detected coordinate frame. GCRS-compatible:"J2000","EME2000","GCRF","GCRS","ICRF". Earth-fixed:"ITRS","ECEF","ECF","FIXED","TERRESTRIAL"epoch— Reference epoch (T0) for numeric time offsets; overrides any epoch found in the file headertime_format— How to interpret the time column:"auto"(default),"seconds","days","iso8601"
- Raises:
IOError— If the file cannot be opened or readValueError— If no state vectors are found, the requested time range exceeds the file data range, units are unrecognised, or the frame is unsupported
- Attributes (read-only):
file_path— Path to the source filesource_frame— Coordinate frame as detected/specifiedsource_position_unit— Position unit as detected/specified (before km conversion)source_velocity_unit— Velocity unit as detected/specified (before km/s conversion)file_pv— Raw state vectors from the file (km, km/s) before resampling (PositionVelocityData)file_timestamp— Raw timestamps from the file before resampling (list of datetime)gcrs_pv— Interpolated position/velocity in GCRS frame (PositionVelocityData)itrs_pv— Position/velocity in ITRS frame (PositionVelocityData)sun_pv,moon_pv— Sun/Moon position/velocity in GCRS frame (PositionVelocityData)timestamp— Output grid timestamps (NumPy datetime64 array)gcrs,itrs,earth,sun,moon— astropy SkyCoord objectslatitude_deg,longitude_deg,height_m— Geodetic coordinatesAll other standard
Ephemerisproperties (angular radii, RA/Dec arrays, etc.)
- Methods:
index(time)— Find the index of the closest output-grid timestamp to the given datetimeget_body_pv(body),get_body(body)— Solar system body position/velocity and SkyCoordmoon_illumination(time_indices=None)— Moon illumination fraction (0–1) as seen from spacecraftradec_to_altaz(ra_deg, dec_deg, time_indices=None)— Convert RA/Dec to Alt/Azcalculate_airmass(ra_deg, dec_deg, time_indices=None)— Astronomical airmass
See Using FileEphemeris for worked examples.
- ParquetEphemeris
Load pre-computed state vectors from a Parquet file via DuckDB and resample to a uniform output grid via Hermite interpolation. Supports local files, globs, and cloud object stores (S3, DigitalOcean Spaces, GCS, R2, HTTPS).
Requires the optional
duckdbPython package (pip install rust-ephem[parquet]orpip install duckdb).- Constructor:
ParquetEphemeris(source, begin, end, step_size=60, *, polar_motion=False, time_col=None, pos_cols=None, vel_cols=None, position_unit=None, velocity_unit=None, frame=None, s3_endpoint=None, s3_region=None, where_clause=None)source— Path or URI to the Parquet file. Supports local paths and globs,s3://,gcs://,r2://,http(s)://begin— Start time for the output grid (Python datetime, UTC)end— End time for the output grid (Python datetime, UTC)step_size— Output time step in seconds (default: 60)polar_motion— Apply polar motion correction (default: False)time_col— Name of the timestamp column (default:"time")pos_cols— Names of the three position columns (default:("x", "y", "z"))vel_cols— Names of the three velocity columns (default:("vx", "vy", "vz"))position_unit— Position unit in the source:"km"(default),"m","cm"velocity_unit— Velocity unit in the source:"km/s"(default),"m/s","cm/s"frame— Coordinate frame of the source. Default"GCRS". GCRS-compatible:"J2000","EME2000","GCRF","GCRS","ICRF". Earth-fixed:"ITRS","ECEF","ECF","FIXED","TERRESTRIAL"s3_endpoint— Custom S3 endpoint host for S3-compatible services (e.g."nyc3.digitaloceanspaces.com"for DigitalOcean Spaces)s3_region— Override S3 region. Falls back toAWS_REGIONenv var.where_clause— Extra SQLWHEREpredicate to apply to the Parquet (e.g."sat_id = 42"). Combined viaANDwith the time-range filter.
- Authentication:
Cloud access uses DuckDB’s
credential_chainSECRET, which transparently picks up the standard AWS environment variables:AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,AWS_REGION,AWS_SESSION_TOKEN.- Raises:
ImportError— If theduckdbpackage is not installedValueError— If column names are not safe identifiers, the requested time range exceeds the Parquet’s data range (with a 1 hour margin), units are unrecognised, or the frame is unsupported
- Attributes (read-only):
source— Path or URI for the Parquet datafile_path— Alias forsource(matchesFileEphemerisfor consistency)source_frame— Coordinate frame as specifiedsource_position_unit— Position unit as specified (before km conversion)source_velocity_unit— Velocity unit as specified (before km/s conversion)file_pv— Raw state vectors loaded from the Parquet (km, km/s) before resampling (PositionVelocityData)file_timestamp— Raw timestamps from the Parquet before resampling (list of datetime)gcrs_pv— Interpolated position/velocity in GCRS frame (PositionVelocityData)itrs_pv— Position/velocity in ITRS frame (PositionVelocityData)sun_pv,moon_pv— Sun/Moon position/velocity in GCRS frame (PositionVelocityData)timestamp— Output grid timestamps (NumPy datetime64 array)gcrs,itrs,earth,sun,moon— astropy SkyCoord objectslatitude_deg,longitude_deg,height_m— Geodetic coordinatesAll other standard
Ephemerisproperties (angular radii, RA/Dec arrays, etc.)
- Methods:
index(time)— Find the index of the closest output-grid timestamp to the given datetimeget_body_pv(body),get_body(body)— Solar system body position/velocity and SkyCoordmoon_illumination(time_indices=None)— Moon illumination fraction (0–1) as seen from spacecraftradec_to_altaz(ra_deg, dec_deg, time_indices=None)— Convert RA/Dec to Alt/Azcalculate_airmass(ra_deg, dec_deg, time_indices=None)— Astronomical airmass
See Using ParquetEphemeris for worked examples.
- Constraint
Evaluate astronomical observation constraints against ephemeris data.
- Static Methods:
Constraint.sun_proximity(min_angle, max_angle=None)— Create Sun proximity constraintConstraint.moon_proximity(min_angle, max_angle=None)— Create Moon proximity constraintConstraint.earth_limb(min_angle, max_angle=None)— Create Earth limb avoidance constraint *Constraint.earth_limb(min_angle, max_angle=None, include_refraction=False, horizon_dip=False)— Create Earth limb avoidance constraintConstraint.body_proximity(body, min_angle, max_angle=None)— Create solar system body proximity constraintConstraint.eclipse(umbra_only=True)— Create eclipse constraintConstraint.and_(*constraints)— Combine constraints with logical ANDConstraint.or_(*constraints)— Combine constraints with logical ORConstraint.xor_(*constraints)— Combine constraints with logical XOR (violation when exactly one sub-constraint is violated)Constraint.at_least(min_violated, constraints)— Threshold combinator (violation when at leastmin_violatedsub-constraints are violated)Constraint.not_(constraint)— Negate a constraint with logical NOTConstraint.boresight_offset(constraint, roll_deg=0.0, roll_clockwise=False, roll_reference="north", pitch_deg=0.0, yaw_deg=0.0)— Wrap a constraint with fixed boresight Euler-angle offsets -roll_deg— Fixed instrument roll offset (degrees) relative to the spacecraft frame. Default0.0. Spacecraft roll at observation time is a separate concept applied viatarget_rollon evaluation methods. -roll_reference— Roll-zero reference axis. Default is"north"(celestial-north-projected +Z zero-roll). Use"sun"for Sun-projected +Z zero-roll when needed.Constraint.from_json(json_str)— Create constraint from JSON configuration
- Methods:
evaluate(ephemeris, target_ra, target_dec, times=None, indices=None)— Evaluate constraint against ephemeris dataephemeris— AnyEphemerisobject (TLEEphemeris, SPICEEphemeris, GroundEphemeris, OEMEphemeris, FileEphemeris, or ParquetEphemeris)target_ra— Target right ascension in degrees (ICRS/J2000)target_dec— Target declination in degrees (ICRS/J2000)times— Optional: specific datetime(s) to evaluate (must exist in ephemeris)indices— Optional: specific time index/indices to evaluateReturns:
ConstraintResultobject
evaluate_batch(ephemeris, target_ras, target_decs, times=None, indices=None, target_rolls=None)— Convenience batch API returning oneConstraintResultper targetephemeris— AnyEphemerisobject (TLEEphemeris, SPICEEphemeris, GroundEphemeris, OEMEphemeris, FileEphemeris, or ParquetEphemeris)target_ras— List of target right ascensions in degrees (ICRS/J2000)target_decs— List of target declinations in degrees (ICRS/J2000)times— Optional: specific datetime(s) to evaluate (must exist in ephemeris)indices— Optional: specific time index/indices to evaluatetarget_rolls— Optional: per-target spacecraft roll angles in degrees, one value per target. Each entry may beNoneto evaluate that target without a fixed spacecraft roll (default:Nonefor all targets)Returns: list of
ConstraintResultobjects, one per targetBest when you want the same per-target summary shape as
evaluate()without writing the loop yourself
in_constraint_batch(ephemeris, target_ras, target_decs, times=None, indices=None, target_rolls=None)— [Recommended] Vectorized batch evaluation for multiple targetsephemeris— AnyEphemerisobject (TLEEphemeris, SPICEEphemeris, GroundEphemeris, OEMEphemeris, FileEphemeris, or ParquetEphemeris)target_ras— List/array of target right ascensions in degrees (ICRS/J2000)target_decs— List/array of target declinations in degrees (ICRS/J2000)times— Optional: specific datetime(s) to evaluate (must exist in ephemeris)indices— Optional: specific time index/indices to evaluatetarget_rolls— Optional: per-target spacecraft roll angles in degrees, one value per target. Each entry may beNoneto evaluate that target without a fixed spacecraft roll. When an entry isNoneand the constraint has boresight offsets with non-zero pitch/yaw, evaluates the target as violated only if it violates at every possible roll angle (default:Nonefor all targets)Returns: 2D NumPy boolean array of shape (n_targets, n_times) where True indicates constraint violation
Performance: 3-50x faster than calling
evaluate()in a loopOptimized: Uses vectorized operations for batch RA/Dec conversion and constraint evaluation
All constraint types supported: Sun/Moon proximity, Earth limb, Eclipse, Body proximity, boresight offsets, and logical combinators (AND, OR, XOR, AT_LEAST, NOT)
in_constraint(time, ephemeris, target_ra, target_dec)— Check if target is in-constraint at a single timetime— Python datetime object (must exist in ephemeris timestamps)Returns:
bool(True if constraint is violated / target is blocked, False if satisfied)
instantaneous_field_of_regard(ephemeris, time=None, index=None, n_points=DEFAULT_N_POINTS, n_roll_samples=DEFAULT_N_ROLL_SAMPLES, target_roll=None)— Compute instantaneous visible sky solid angle. Whentarget_rollis not specified, sweepsn_roll_samplesspacecraft roll angles for boresight-offset constraints with non-zero pitch/yaw, giving the total accessible sky over all roll states.ephemeris— AnyEphemerisobject (TLEEphemeris, SPICEEphemeris, GroundEphemeris, OEMEphemeris, FileEphemeris, or ParquetEphemeris)time— Optional datetime to evaluate (must exist in ephemeris)index— Optional ephemeris index to evaluaten_points— Number of sky samples (Fibonacci sphere integration, defaultDEFAULT_N_POINTS)target_roll— Spacecraft roll angle (degrees) to evaluate at. WhenNone(default), sweeps all roll angles for boresight-offset FoR.n_roll_samples— Spacecraft roll angles to sweep whentarget_rollisNoneand pitch/yaw offsets are present (defaultDEFAULT_N_ROLL_SAMPLES= 360, i.e. 1° resolution). Can be reduced (e.g., 72 for 5° resolution) for faster evaluation. Ignored otherwise.Returns:
floatsteradians in[0, 4π]Requirement: exactly one of
timeorindexmust be providedSemantics: constraints are violated when
True; this method integrates visible sky where constraint isFalse
to_json()— Get constraint configuration as JSON stringto_dict()— Get constraint configuration as Python dictionary
- ConstraintResult
Result of constraint evaluation containing violation information.
- Attributes (read-only):
violations— List ofConstraintViolationobjectsall_satisfied— Boolean indicating if constraint was satisfied for entire time rangeconstraint_name— String name/description of the constrainttimestamp— NumPy array of Python datetime objects (optimized with caching)constraint_array— NumPy boolean array where True means constraint violated / target blocked (optimized with caching)visibility— List ofVisibilityWindowobjects for contiguous satisfied periods
- Methods:
total_violation_duration()— Get total duration of violations in secondsin_constraint(time)— Check if constraint is violated at a given timetime— Python datetime object (must exist in result timestamps)Returns:
bool(True if violated / target blocked, False if satisfied)
- ConstraintViolation
Information about a specific constraint violation time window.
- Attributes (read-only):
start_time— Start time of violation window (ISO 8601 string)end_time— End time of violation window (ISO 8601 string)max_severity— Maximum severity of violation (0.0 = just violated, 1.0+ = severe)description— Human-readable description of the violation
- VisibilityWindow
Time window when observation target is not constrained (visible).
- Attributes (read-only):
start_time— Start time of visibility window (Python datetime)end_time— End time of visibility window (Python datetime)duration_seconds— Duration of the window in seconds (computed property)
- PositionVelocityData
Container for position and velocity data returned by ephemeris calculations.
- Attributes (read-only):
position— NumPy array of positions (N × 3), in kmvelocity— NumPy array of velocities (N × 3), in km/sposition_unit— String “km”velocity_unit— String “km/s”
Functions
Planetary Ephemeris Management
init_planetary_ephemeris(py_path)— Initialize an already-downloaded planetary SPK file.download_planetary_ephemeris(url, dest)— Download a planetary SPK file from a URL.ensure_planetary_ephemeris(py_path=None, download_if_missing=True, spk_url=None)— Download (if missing) and initialize planetary SPK lazily. Uses default de440s.bsp if no path provided.is_planetary_ephemeris_initialized()— Check if planetary ephemeris is initialized. Returnsbool.
Time System Conversions
get_tai_utc_offset(py_datetime)— Get TAI-UTC offset (leap seconds) for a given datetime. ReturnsOptional[float](seconds).get_ut1_utc_offset(py_datetime)— Get UT1-UTC offset for a given datetime. Returnsfloat(seconds).is_ut1_available()— Check if UT1 data is available. Returnsbool.init_ut1_provider()— Initialize UT1 provider. Returnsboolindicating success.
Earth Orientation Parameters (EOP)
get_polar_motion(py_datetime)— Get polar motion parameters (x_p, y_p) for a given datetime. ReturnsTuple[float, float](arcseconds).is_eop_available()— Check if EOP data is available. Returnsbool.init_eop_provider()— Initialize EOP provider. Returnsboolindicating success.
Cache Management
get_cache_dir()— Get the path to the cache directory used by rust_ephem. Returnsstr.
TLE Fetching
fetch_tle(*, tle=None, norad_id=None, norad_name=None, epoch=None, spacetrack_username=None, spacetrack_password=None, epoch_tolerance_days=None, enforce_source=None)— Fetch a TLE from various sources.This function provides a unified interface for retrieving TLE data from local files, URLs, Celestrak, or Space-Track.org. Returns a
TLERecordobject containing the TLE data and metadata.- Parameters:
tle(str, optional) — Path to TLE file or URL to download TLE fromnorad_id(int, optional) — NORAD catalog ID to fetch TLE. If Space-Track credentials are available, Space-Track is tried first with failover to Celestrak.norad_name(str, optional) — Satellite name to fetch TLE from Celestrakepoch(datetime, optional) — Target epoch for Space-Track queries. If not specified, current time is used. Space-Track will fetch the TLE with epoch closest to this time.spacetrack_username(str, optional) — Space-Track.org username (or useSPACETRACK_USERNAMEenv var)spacetrack_password(str, optional) — Space-Track.org password (or useSPACETRACK_PASSWORDenv var)epoch_tolerance_days(float, optional) — For Space-Track cache: how many days TLE epoch can differ from target epoch (default: 4.0 days)enforce_source(str, optional) — Enforce use of specific source without failover. Must be"celestrak","spacetrack", orNone(default behavior with failover)
- Returns:
TLERecord— A Pydantic model containing the TLE data and metadata- Raises:
ValueError— If no valid TLE source is specified or fetching fails
Examples:
import rust_ephem # Fetch from Celestrak by NORAD ID tle = rust_ephem.fetch_tle(norad_id=25544) # ISS print(tle.name) print(tle.line1) print(tle.line2) # Fetch from file tle = rust_ephem.fetch_tle(tle="path/to/satellite.tle") # Fetch from URL tle = rust_ephem.fetch_tle(tle="https://celestrak.org/NORAD/elements/gp.php?CATNR=25544") # Fetch from Space-Track with explicit credentials from datetime import datetime, timezone tle = rust_ephem.fetch_tle( norad_id=25544, spacetrack_username="your_username", spacetrack_password="your_password", epoch=datetime(2020, 1, 1, tzinfo=timezone.utc) ) # Use TLERecord with TLEEphemeris ephem = rust_ephem.TLEEphemeris( tle=tle, # Pass TLERecord directly begin=datetime(2024, 1, 1, tzinfo=timezone.utc), end=datetime(2024, 1, 2, tzinfo=timezone.utc), step_size=60 )
- Notes:
Must provide exactly one of:
tle,norad_id, ornorad_nameFile paths and URLs are cached locally for improved performance
Space-Track.org requires free account registration at https://www.space-track.org
Credentials can be provided via:
Explicit parameters:
spacetrack_usernameandspacetrack_passwordEnvironment variables:
SPACETRACK_USERNAMEandSPACETRACK_PASSWORD.envfile in the current directory or home directory (~/.env) containing the same environment variables
Data Models
- TLERecord
A Pydantic model representing a Two-Line Element (TLE) record with metadata. Can be passed directly to
TLEEphemerisvia thetleparameter. Supports JSON serialization for storage and transmission.- Attributes:
line1(str) — First line of the TLE (starts with ‘1’)line2(str) — Second line of the TLE (starts with ‘2’)name(str | None) — Optional satellite name (from 3-line TLE format)epoch(datetime) — TLE epoch timestamp (extracted from line1)source(str | None) — Source of the TLE data (e.g., ‘celestrak’, ‘spacetrack’, ‘file’, ‘url’)
- Derived Fields:
norad_id(int) — NORAD catalog ID extracted from line1classification(str) — Classification from line1 (U=unclassified, C=classified, S=secret)international_designator(str) — International designator extracted from line1mean_motion_dot_rev_per_day2(float) — First derivative of mean motion from line1mean_motion_ddot_rev_per_day3(float) — Second derivative of mean motion from line1bstar_drag(float) — BSTAR drag term from line1ephemeris_type(int) — Ephemeris type from line1element_set_number(int) — Element set number from line1revolution_number_at_epoch(int) — Revolution number at epoch from line2inclination_deg(float) — Inclination extracted from line2right_ascension_deg(float) — RAAN extracted from line2eccentricity(float) — Eccentricity extracted from line2arg_periapsis_deg(float) — Argument of periapsis extracted from line2mean_anomaly_deg(float) — Mean anomaly extracted from line2mean_motion_rev_per_day(float) — Mean motion extracted from line2mean_motion_rad_s(float) — Mean motion in radians/secondtrue_anomaly_deg(float) — True anomaly derived from mean anomaly and eccentricitysemimajor_axis_m(float) — Semimajor axis derived using WGS72 gravitational parameter
- Methods:
to_tle_string()— Convert to a 2-line or 3-line TLE string formatclassical_elements(mu_m3_s2=WGS72_EARTH_MU_M3_S2)— Return a dictionary of mean classical elements with keysSemimajorAxis_m,Eccentricity,Inclination_deg,RightAscension_deg,ArgPeriapsis_deg,TrueAnomaly_deg,MeanAnomaly_deg,MeanMotion_rev_per_day, andGravitationalParameter_m3_s2. Ifmu_m3_s2is overridden,SemimajorAxis_mis recomputed with the supplied value.model_dump()— Convert to dictionary (Pydantic)model_dump_json()— Convert to JSON string (Pydantic)
Example:
import rust_ephem tle = rust_ephem.fetch_tle(norad_id=25544) # Access TLE data print(f"Satellite: {tle.name}") print(f"NORAD ID: {tle.norad_id}") print(f"Epoch: {tle.epoch}") print(f"Source: {tle.source}") # Get TLE as string print(tle.to_tle_string()) # Serialize to JSON json_str = tle.model_dump_json() # Pass directly to TLEEphemeris ephem = rust_ephem.TLEEphemeris( tle=tle, begin=datetime(2024, 1, 1, tzinfo=timezone.utc), end=datetime(2024, 1, 2, tzinfo=timezone.utc) )
Constraint Configuration Classes
The following Pydantic models are used to configure constraints. These can be serialized to/from JSON and support logical combinations using Python operators.
- SunConstraint
Sun proximity constraint.
- Constructor:
SunConstraint(min_angle=45.0)- Attributes:
type— Always “sun”min_angle— Minimum angular separation from Sun in degrees (0-180)max_angle— Maximum angular separation from Sun in degrees (0-180), optional
- MoonConstraint
Moon proximity constraint.
- Constructor:
MoonConstraint(min_angle=30.0)- Attributes:
type— Always “moon”min_angle— Minimum angular separation from Moon in degrees (0-180)max_angle— Maximum angular separation from Moon in degrees (0-180), optional
- EarthLimbConstraint
Earth limb avoidance constraint.
- Constructor:
EarthLimbConstraint(min_angle=10.0, include_refraction=False, horizon_dip=False)- Attributes:
type— Always “earth_limb”min_angle— Minimum angular separation from Earth’s limb in degrees (0-180)max_angle— Maximum angular separation from Earth’s limb in degrees (0-180), optional *include_refraction— Include atmospheric refraction correction (~0.57°) for ground observers (default: False) *horizon_dip— Include geometric horizon dip correction for ground observers (default: False)
- BodyConstraint
Solar system body proximity constraint.
- Constructor:
BodyConstraint(body="Mars", min_angle=15.0)- Attributes:
type— Always “body”body— Name of the solar system body (e.g., “Mars”, “Jupiter”)min_angle— Minimum angular separation from body in degrees (0-180)max_angle— Maximum angular separation from body in degrees (0-180), optional
- EclipseConstraint
Eclipse constraint (Earth shadow). Assumes an Earth-centered ephemeris (Earth at origin).
- Constructor:
EclipseConstraint(umbra_only=True)- Attributes:
type— Always “eclipse”umbra_only— If True, only umbra counts. If False, includes penumbra.
- AndConstraint
Logical AND combination of constraints.
- Constructor:
AndConstraint(constraints=[constraint1, constraint2])- Attributes:
type— Always “and”constraints— List of constraints to combine with AND
- OrConstraint
Logical OR combination of constraints.
- Constructor:
OrConstraint(constraints=[constraint1, constraint2])- Attributes:
type— Always “or”constraints— List of constraints to combine with OR
- XorConstraint
Logical XOR combination of constraints.
Violation semantics: The XOR constraint is violated when exactly one sub-constraint is violated; it is satisfied otherwise (i.e., when either none or more than one sub-constraints are violated). This mirrors boolean XOR over “violation” states.
- Constructor:
XorConstraint(constraints=[constraint1, constraint2, ...])- Attributes:
type— Always “xor”constraints— List of constraints (minimum 2) evaluated with XOR violation semantics
- AtLeastConstraint
Threshold (k-of-n) combination of constraints.
Violation semantics: The AT_LEAST constraint is violated when the number of violated sub-constraints is greater than or equal to
min_violated.- Constructor:
AtLeastConstraint(min_violated=2, constraints=[constraint1, constraint2, ...])- Attributes:
type— Always “at_least”min_violated— Minimum number of violated sub-constraints required (>=1)constraints— List of constraints (minimum 1)
- NotConstraint
Logical NOT (negation) of a constraint.
- Constructor:
NotConstraint(constraint=some_constraint)- Attributes:
type— Always “not”constraint— Constraint to negate
Common Constraint Methods
All constraint configuration classes (SunConstraint, MoonConstraint, etc.) inherit these methods from RustConstraintMixin:
evaluate(ephemeris, target_ra, target_dec, times=None, indices=None)— Evaluate constraint for a single targetReturns:
ConstraintResultobjectSee
Constraint.evaluate()above for parameter details
in_constraint(time, ephemeris, target_ra, target_dec)— Check if target satisfies constraint at a single timeReturns:
bool
at_least(min_violated, *others)— Build anAtLeastConstraintfrom this constraint plus additional constraintsReturns:
AtLeastConstraint
Constraint Operators
Constraint configurations support Python bitwise operators for convenient combination:
constraint1 & constraint2— Logical AND (equivalent toAndConstraint)constraint1 | constraint2— Logical OR (equivalent toOrConstraint)constraint1 ^ constraint2— Logical XOR (equivalent toXorConstraint)~constraint— Logical NOT (equivalent toNotConstraint)
Usage examples are provided in the examples section of the docs.
Type Aliases
ConstraintConfigUnion type for all constraint configuration classes:
ConstraintConfig = ( SunConstraint | MoonConstraint | EclipseConstraint | EarthLimbConstraint | BodyConstraint | AndConstraint | OrConstraint | XorConstraint | AtLeastConstraint | NotConstraint )
CombinedConstraintConfigPydantic TypeAdapter for parsing constraint configurations from JSON.
Performance Notes
Constraint Evaluation Optimizations
The constraint system includes several performance optimizations for efficient evaluation:
Property Caching: The
timestampandconstraint_arrayproperties on ephemeris and constraint result objects are cached for repeated access (90x+ speedup on subsequent accesses)Subset Evaluation: Use
timesorindicesparameters inevaluate()to compute constraints for specific times only, avoiding full ephemeris evaluationSingle Time Checks: For checking a single time, use
Constraint.in_constraint()which is optimized for single-point evaluationVectorized Batch Evaluation: For checking multiple targets, use
in_constraint_batch()which evaluates all targets in a single call, eliminating Python call overheadOptimal Usage Patterns:
FASTEST (Multiple Targets): Use batch evaluation for multiple targets:
target_ras = [0.0, 90.0, 180.0, 270.0] target_decs = [0.0, 30.0, -30.0, 60.0] violations = constraint.in_constraint_batch(eph, target_ras, target_decs) # violations is (n_targets, n_times) array # violations[i, j] = True if target i violates constraint at time j
FAST (Single Target): Evaluate once, then use
constraint_arrayproperty:result = constraint.evaluate(eph, ra, dec) for i in range(len(result.timestamp)): if result.constraint_array[i]: # ~1000x faster than alternatives # Target is visible at this time pass
OK: Evaluate once, then loop over result:
result = constraint.evaluate(eph, ra, dec) for i, time in enumerate(result.timestamp): if result.in_constraint(time): # ~100x faster than evaluating each time # Target is visible pass
SLOW (avoid): Calling
in_constraint()in a loop:# Don't do this - evaluates ephemeris 1000s of times! for time in eph.timestamp: if constraint.in_constraint(time, eph, ra, dec): pass
Timestamp Access
All ephemeris and constraint result objects return NumPy arrays for the timestamp property, which is significantly faster than Python lists for indexing operations.