empyrean
Safe Rust wrapper over libempyrean — uncertainty-first orbit propagation, ephemeris, orbit determination, and event detection for asteroids and comets, powered by automatic differentiation
The idiomatic Rust API over the libempyrean C ABI. Every C function
exposed in the cdylib has a typed, Result<_, Error>-returning wrapper
here. RAII handles the underlying allocations so callers never juggle
raw FFI pointers.
[]
= "0.7"
What it does
- Propagation — N-body (Sun, planets, Moon, Pluto) with EIH general relativity, Sun J2 and Earth J2–J4 zonal harmonics, 16 asteroid perturbers, and the Marsden non-gravitational model — selectable across Approximate / Basic / Standard force-model tiers (Standard is the default). GR15 and DOP853 integrators.
- Uncertainty — First-order (Jet1) state transition matrices; second-order (Jet2) state transition tensors.
- Ephemeris — RA/Dec, rates, photometry (H–G, H–G₁G₂, H–G₁₂), light time, phase angle, solar elongation, local horizon.
- Orbit determination — Gauss, Herget, and systematic-ranging (admissible region + Manifold of Variations) IOD → N-body differential correction with STM caching and outlier rejection. Validated against
find_orband JPL SBDB. - Events — Close approach (start/end), periapsis, gravitational capture (start/end), shadow entry/exit, atmospheric entry/exit, impact, and possible impact.
Quick start
use ;
let ctx = from_data_dir?;
// Query SBDB for Apophis and propagate through its 2029 Earth flyby.
let orbits = query_sbdb?.orbits;
let epochs = vec!;
let result = ctx.propagate?;
println!;
# Ok::
Orbit determination
determine runs a full IOD (Gauss / Herget / systematic ranging) → N-body differential correction. The
fitted result.orbit is a re-feedable [Orbit] carrying state, covariance,
and any fitted non-gravitational parameters — pass it straight back into
propagate, generate_ephemeris, or compute_impact_probabilities.
# use ;
# let ctx = from_data_dir?;
let obs = ctx.read_ades?; // optical + radar
let result = ctx.determine?;
println!;
# Ok::
Ephemeris
# use ;
# let ctx = from_data_dir?;
# let orbits = query_sbdb?.orbits;
let epochs = vec!;
let observers = ctx.get_observers?;
let eph = ctx.generate_ephemeris?;
for entry in &eph.entries
# Ok::
Uncertainty
First-order (the default) propagates the covariance with the state-transition matrix — accurate when the orbit is approximately linear over the uncertainty region. Second-order adds the state-transition tensor for the curvature that linear covariance misses near a close approach.
# use ;
# let ctx = from_data_dir?;
# let orbits = query_sbdb?.orbits;
# let epochs = vec!;
let config = PropagationConfig ;
let result = ctx.propagate?;
# Ok::
Impact probability and B-plane geometry
For each detected close approach you can ask for an impact-probability assessment or a full B-plane breakdown, and run several uncertainty methods side-by-side on the same encounter. Each returns one record per (method × orbit × body), tagged with its method and closest-approach epoch.
# use ;
# let ctx = from_data_dir?;
# let orbits = query_sbdb?.orbits;
let end = from_mjd_tdb;
let ips = ctx.compute_impact_probabilities?;
for ip in &ips
let bps = ctx.compute_b_planes?;
for bp in &bps
# Ok::
Runtime requirement
This crate (via empyrean-sys) loads libempyrean.{dylib,so,dll} at
run time, which is distributed separately as a binary release on
GitHub and
inside the published Python wheel. The library is opened from a path
resolved at build/run time — a local ../target/release build, an
EMPYREAN_LIB_DIR override, or a checksum-pinned prebuilt downloaded
from the GitHub release; no system library path setup is required.
The full distribution surface (Python wheel, CLI binary, C SDK, this Rust crate) lives at the main repository — see its README for installation paths and the cross-channel quickstart.
Accuracy
Validated against JPL Horizons, ASSIST (reboundx), and find_orb on
43 objects across 13 dynamical populations (NEOs, MBAs, Trojans, TNOs,
comets, and more). Sub-meter propagation accuracy on bounded timescales.
No guarantee of accuracy
empyrean performs numerical computations used in planetary-science and mission-planning contexts. Outputs should not be used as the sole basis for any decision — including but not limited to impact monitoring, mission planning, collision avoidance, or navigation — without independent verification. See the LICENSE file for the full terms.
License
Source code in this crate is licensed under the
BSD 3-Clause License. The closed-source libempyrean
runtime it loads at runtime is governed by a separate proprietary
binary license; see the main repository for the dual-license breakdown.
Copyright © 2024–2026 Joachim Moeyens. All rights reserved.