siderust 0.5.1

High-precision astronomy and satellite mechanics in Rust.
docs.rs failed to build siderust-0.5.1
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Visit the last successful build: siderust-0.4.0

Siderust

Crates.io Docs.rs

Precision astronomy & satellite mechanics in safe, fast Rust.

Siderust aims to be a reference ephemeris and orbit‑analysis library for research‐grade pipelines and ground‑segment tooling. Every algorithm ships with validation tests against authoritative data (JPL Horizons, IMCCE, SOFA). No unsafe blocks, no hidden allocations.


Table of Contents

  1. Supported Feature Flags
  2. Features
  3. Installation
  4. Coordinate Systems
  5. Units & Physical Quantities
  6. Quick Start
  7. Examples
  8. Crate Layout
  9. Roadmap
  10. Contributing
  11. License
  12. Acknowledgments

Supported Feature Flags

Feature Default What it enables
(none) VSOP87 + ELP2000-82B analytical ephemerides, full coordinate/altitude API
de440 JPL DE440 Chebyshev ephemeris backend (1550–2650 CE)
de441 JPL DE441 Chebyshev ephemeris backend (extended coverage)
serde Serialize / Deserialize on public types

Note: no_std and f128 quad‑precision are not supported today. The crate depends on std‑only libraries (chrono, nalgebra). Sub‑crates qtty and qtty-core do offer no_std support independently.


Features

Category What you get
Coordinate Systems Position and spherical Direction types parameterised by ReferenceCenter, ReferenceFrame, and Unit. Compile‑time guarantees prevent mixing frames by accident.
Target Tracking Target<T> couples any coordinate with an observation epoch and optional ProperMotion, enabling extrapolation & filtering.
Physical Units Strongly typed Mass, Length, Angle, Velocity, Duration & more via the qtty crate — dimensional correctness at compile time.
Celestial Mechanics Kepler solvers, VSOP87 & ELP2000 theories, Pluto (Meeus/Williams), light‑time & aberration, nutation & precession, apparent Sun & Moon, culmination searches.
Ephemeris Backends Pluggable Ephemeris trait with three backends — Vsop87Ephemeris (always available), De440Ephemeris, and De441Ephemeris (feature-gated JPL DE4xx).
Altitude API Unified AltitudePeriodsProvider trait for Sun, Moon, stars, and arbitrary ICRS directions — find crossings, culminations, altitude ranges, and above/below‑threshold periods.
Catalogs & Bodies Built‑in Sun→Neptune, asteroids (Ceres, Bennu, Apophis), comets (Halley, Encke, Hale-Bopp), a starter star catalog, + helpers for custom datasets.
Observatories Predefined sites (Roque de los Muchachos, El Paranal, Mauna Kea, La Silla) with ObserverSite for topocentric transforms.

Astrometry Compliance Note

  • Stellar aberration uses the full special-relativistic (Lorentz) formula per IERS Conventions (2020, §7.2); annual uses VSOP87E barycentric Earth velocity and topocentric adds a diurnal ω×r term (GMST-based Earth rotation).
  • This is not yet a full IAU 2000/2006 "apparent place" pipeline (missing CIO/CIP, polar motion, and gravitational light deflection).

Installation

Add to your Cargo.toml:

[dependencies]
siderust = "0.5"

Build-time datasets (VSOP87/ELP2000/IERS and optional JPL kernels) are downloaded on demand; see doc/datasets.md.

Ephemeris Backends (Enable / Disable / Combine)

Siderust always includes Vsop87Ephemeris (VSOP87 + ELP2000-82B). Optional features add JPL backends:

  • de440De440Ephemeris (1550–2650 CE)
  • de441De441Ephemeris (extended coverage from NAIF de441_part-2.bsp)

DefaultEphemeris selects the best available:

  • De441Ephemeris when de441 is enabled
  • otherwise De440Ephemeris when de440 is enabled
  • otherwise Vsop87Ephemeris
  1. VSOP87-only (explicit)
[dependencies]
siderust = { version = "0.5", default-features = false }
  1. Enable DE440
[dependencies]
siderust = { version = "0.5", features = ["de440"] }
  1. Enable DE441
[dependencies]
siderust = { version = "0.5", features = ["de441"] }
  1. Combine backends in one binary
use siderust::calculus::ephemeris::{Ephemeris, Vsop87Ephemeris};
use siderust::time::JulianDate;

let jd = JulianDate::J2000;

// Analytical series (always available)
let earth_vsop = Vsop87Ephemeris::earth_heliocentric(jd);
// With `de441` feature enabled:
use siderust::calculus::ephemeris::De441Ephemeris;

let earth_jpl = De441Ephemeris::earth_heliocentric(jd);

You can combine ephemeris features with others (for example serde):

[dependencies]
siderust = { version = "0.5", features = ["de441", "serde"] }

JPL Build Modes: Real vs Stubbed

When JPL features are enabled, build scripts may download:

  • de440.bsp (~120 MB)
  • de441_part-2.bsp (~1.65 GB)

Default checked-in behavior is real JPL builds (no global stubbing).

Real JPL mode (recommended for representative DE440/DE441 behavior):

unset SIDERUST_JPL_STUB
cargo test --features de440
cargo test --features de441

Offline/stub mode (explicit opt-in for fast local loops):

SIDERUST_JPL_STUB=all cargo check --all-features

Supported stub values:

  • de441: stubs DE441 only (De441Ephemeris is mocked to Vsop87Ephemeris).
  • de440: stubs DE440 only.
  • de440,de441 or all (also 1, true, yes, on): stubs both.

Optional local override file (keep untracked):

# .cargo/config.local.toml
[env]
SIDERUST_JPL_STUB = "all"

Use it explicitly:

cargo --config .cargo/config.local.toml check --all-features

Caveat:

  • Stubbed DE datasets compile successfully, but low-level DE calls are unavailable at runtime.
  • de441 has a high-level mock backend (De441Ephemeris -> Vsop87Ephemeris).
  • de440 is compile-only when stubbed; direct runtime calls to De440Ephemeris will panic.

Coordinate Systems

Siderust encodes both the origin and the orientation of every coordinate at the type level:

use siderust::coordinates::{cartesian, centers::*, frames::*};
use qtty::Au;

// Position of Mars in the Heliocentric Ecliptic frame
let mars_helio = cartesian::Position::<Heliocentric, EclipticMeanJ2000, Au>::new(1.5, 0.0, 0.0);

Impossible states (e.g. adding heliocentric and geocentric positions) simply do not compile.

Compile-Time vs Runtime Safety

For most centers (Barycentric, Heliocentric, Geocentric) all invariants are enforced at compile time with zero runtime cost (Params = ()).

Parameterized centers (Topocentric, Bodycentric) carry runtime data (e.g., ObserverSite). The center type is still checked at compile time, but parameter equality (e.g., "are these two positions at the same site?") is checked at runtime:

API Behaviour on mismatch
pos_a - pos_b / distance_to assert! (panics in all builds)
checked_sub / try_distance_to Returns Err(CenterParamsMismatchError)
ObserverSite::try_new Validates lat/lon ranges, returns Result

Units & Physical Quantities

Siderust uses the qtty crate for dimensionally typed quantities. The compiler prevents mixing incompatible units:

use qtty::*;

let distance = AstronomicalUnits::new(1.523); // Mars semi-major axis
let period   = Days::new(686.97);

// distance + period → compile error (length + time)

Common unit types: AstronomicalUnit (Au), Kilometer (Km), Meter, Degree, Radian, Day, Second, AuPerDay, and many more.


Quick Start

use siderust::{
    bodies::Mars,
    time::JulianDate,
};
use chrono::prelude::*;

// 1. Select an epoch (UTC now → JD)
let jd = JulianDate::from_utc(Utc::now());

// 2. Compute barycentric ecliptic coordinates via VSOP87
let mars = Mars::vsop87e(jd);

// 3. Print Mars's barycentric ecliptic position
println!("{}", mars.position);

Examples

The examples/ directory is a curated tour of the crate’s major building blocks (coordinates, transforms, altitude periods, ephemeris backends, serialization).

  • Browse: examples/README.md
  • Run one: cargo run --example basic_coordinates

Feature-gated examples:

# JPL DE4xx (may download large BSP datasets unless you explicitly stub)
cargo run --example jpl_precise_ephemeris --features de440
cargo run --example jpl_precise_ephemeris --features de441

# Fast/offline loop: compile JPL features but skip runtime DE calls
SIDERUST_JPL_STUB=all cargo run --example jpl_precise_ephemeris --features de440,de441

# Serde
cargo run --example serde_serialization --features serde

Crate Layout

├─ astro/         # Aberration, nutation, precession, sidereal time
├─ bodies/        # Planet, Star, Satellite, Asteroid, Comet + built-in catalogs
├─ calculus/
│   ├─ altitude/     # Unified altitude API (AltitudePeriodsProvider trait)
│   ├─ ephemeris/    # Ephemeris trait + VSOP87/DE440/DE441 backends
│   ├─ jpl/          # Shared JPL DE4xx infrastructure (Chebyshev evaluation)
│   ├─ math_core/    # Root-finding (Brent/bisection), extrema, interval assembly
│   ├─ solar/        # Sun altitude, night/day/twilight periods
│   ├─ lunar/        # Moon altitude with topocentric parallax
│   ├─ stellar/      # Analytical star altitude engine
│   ├─ vsop87/       # VSOP87 planetary theory
│   ├─ elp2000/      # ELP2000-82B lunar theory
│   ├─ kepler_equations/  # Kepler equation solvers
│   └─ pluto         # Meeus/Williams Pluto ephemeris
├─ coordinates/   # Cartesian/Spherical types, frames, centers, transforms
├─ observatories/ # Predefined observatory locations (Roque, Paranal, Mauna Kea, La Silla)
├─ targets/       # Target<T> with time & ProperMotion
└─ time           # Re-export of tempoch: JulianDate, MJD, Period<S>, time scales

Roadmap

  • Custom dynamic reference centers (topocentric, bodycentric)
  • DE440/DE441 JPL ephemerides
  • Unified altitude API (AltitudePeriodsProvider trait)
  • Serde serialization support
  • Gaia DR3 star ingestion & cone search
  • Relativistic light‑time & gravitational deflection
  • Batch orbit determination helpers (LSQ & EKF)
  • GPU acceleration via wgpu (experiment)

Contributing

Contributions of algorithms, bug fixes or docs are welcome! Please:

  1. Fork & clone (git clone)
  2. Create a feature branch
  3. Run all tests & clippy (cargo test && cargo clippy -- -D warnings)
  4. Open a PR with a clear description

By participating you agree to follow the Rust Code of Conduct.


License

Copyright (C) 2026 Vallés Puig, Ramon

This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). The AGPL-3.0 ensures that:

  • Any modifications and redistributions of the code (including as a network service) remain free and open.
  • End users have access to the full source code, including any improvements or extensions made.

Note for commercial or proprietary use: If you wish to incorporate this code into a closed-source or otherwise differently licensed project, a dual-licensing arrangement can be negotiated. Please contact the authors to discuss terms and conditions for a commercial or proprietary license that suits your needs.


Acknowledgments

Big thanks to Màrius Montón (@mariusmm) for inviting me to his three-week Rust intro course at the Universitat Autònoma de Barcelona (UAB) in 2024 that nudge set this project in motion.