Skip to main content

siderust/
lib.rs

1// SPDX-License-Identifier: AGPL-3.0-only
2// Copyright (C) 2026 Vallés Puig, Ramon
3
4//! # Siderust
5//!
6//! **Precision positional astrometry, atmospheric optics, ephemerides,
7//! sky-brightness and satellite mechanics in Rust.**
8//!
9//! `siderust` is a research-grade astronomy toolkit built on two explicit pillars:
10//!
11//! 1. **Typed quantities everywhere** — every physical quantity at a public API
12//!    boundary is a [`qtty`] newtype (e.g. `Meters`, `Radians`, `JulianDate`,
13//!    `Airmass`, `OpticalDepth`, `Albedo`, `IlluminationFraction`, `Refractivity`,
14//!    `CipCoordinate`, …).  Bare `f64` is confined to internal math kernels.
15//!
16//! 2. **Compile-time model selection** — when a function can use one of several
17//!    algorithms or conventions (nutation theory, airmass formula, extinction
18//!    parameterisation, …) the choice is expressed as a zero-sized phantom-type
19//!    parameter, not a runtime enum.  For example:
20//!    ```rust,ignore
21//!    // picks Iau2006A nutation at compile time — no runtime dispatch
22//!    let equatorial = ecliptic.to_frame_as::<Equatorial, Iau2006A>(ctx);
23//!    ```
24//!
25//! Together these two properties make type errors in physical calculations into
26//! compile-time errors and eliminate whole classes of unit-confusion bugs.
27//!
28//! See [`doc/conventions.md`](../doc/conventions.md) for the mandatory
29//! authoring rules: the academic-style module-doc template
30//! (*Scientific scope / Technical scope / References*), typed-quantity
31//! guidelines, and the phantom-type model-selection pattern.
32//!
33//! ## Scientific scope
34//!
35//! - Strongly-typed coordinates (center + frame + unit encoded in the type system)
36//! - Ephemerides (VSOP87/ELP2000 always available; optional JPL DE4xx backends)
37//! - Observation planning (altitude periods, crossings, culminations, azimuth windows)
38//! - Atmospheric refraction and extinction (airmass, optical depth, scattering)
39//! - Sky brightness and lunar photometry (phase geometry, albedo, spectral radiance)
40//! - Time handling (via the `tempoch` crate, re-exported as [`time`])
41//! - Keplerian / conic orbits and satellite mechanics
42//! - Photometric passbands and throughput (optional `photometry` feature)
43//!
44//! ## API pillars
45//!
46//! - **Coordinates**: `cartesian::{Position, Direction, Velocity, ...}` and
47//!   `spherical::{Position, Direction}` parameterized by `Center`, `Frame`, and `Unit`.
48//! - **Transforms**: frame rotations + center shifts with compile-time guarantees.
49//! - **Altitude API**: `AltitudeProvider` plus `above_threshold`, `below_threshold`,
50//!   and `altitude_ranges` for crossings, culminations, and altitude periods.
51//! - **Ephemeris backends**: `Ephemeris` trait with VSOP87/ELP2000 and optional DE440/DE441.
52//! - **Serde**: optional `serde` feature for public types.
53//!
54//! ## Crate composition
55//!
56//! `siderust` is an orchestration crate that composes the specialized
57//! Siderust sub-crates. Each sub-crate owns a distinct concern:
58//!
59//! | Crate | Owns |
60//! |-------|------|
61//! | `siderust` | Astronomy API, coordinate transforms, observation planning, ephemeris front-end, satellite workflows, POD |
62//! | [`siderust_archive`] | Scientific datasets, manifests, checksums, provenance, generated coefficient snapshots |
63//! | `tempoch` | Time scales (TT/TAI/UTC/UT1/TDB/TCG/TCB), ΔT, EOP, active time-data status |
64//! | `qtty` | Physical units and typed quantity arithmetic |
65//! | `cheby` | Chebyshev / polynomial interpolation |
66//! | `keplerian` | Keplerian orbital primitives |
67//! | `principia` | Dynamics and physical force-model primitives |
68//! | `optica` | Photometry and optics primitives |
69//!
70//! ## Crate Modules
71//!
72//! - [`coordinates`]             : Cartesian & Spherical coordinate types and transformations; includes [`SkyGrid`] sampling utility
73//! - [`healpix`]                 : Typed HEALPix full-sky grid, index, and map primitives
74//! - [`starlight`]               : Stellar surface-brightness HEALPix map builder and validators
75//! - [`targets`]                 : `CoordinateWithPM<T>` + `Trackable` trait for observation targets
76//! - [`time`]                    : Thin re-export facade over `tempoch`; adds TT-default [`JulianDate`] / [`J2000`] aliases
77//! - [`astro`]                   : Aberration, nutation, precession, sidereal time, conic helpers, event support, orbits, orbital mechanics
78//! - [`ephemeris`]               : Ephemeris traits and backends (VSOP87, ELP2000, DE4xx, Pluto); coefficient tables from [`siderust_archive`]
79//! - [`event`]                   : Altitude/azimuth/lunar/solar/stellar event-search APIs
80//! - [`bodies`]                  : Planets, stars, satellites, asteroids, comets, and built-in catalogs
81//! - [`mission`]                 : Mission geometry, runtime context, and site metadata (FoV, terrain mask, AzElRange, eclipse, orbit-relative)
82//! - [`catalogs`]`::observatories` : Predefined observatory locations (Roque, Paranal, Mauna Kea, La Silla)
83//! - [`qtty`]                    : Re-exports of typed quantity newtypes from the `qtty` crate
84//! - [`formats`]                 : Low-level binary file-format parsers (e.g. SPICE DAF/SPK)
85//! - `atmosphere` *(optional)* : Atmospheric refraction, extinction, airmass, and optical-depth models (`atmosphere` feature)
86//! - `photometry` *(optional)* : Astronomical photometric passbands and throughput unit (`photometry` feature)
87//! - Dataset catalog, manifests, and runtime ephemeris download: [`siderust_archive`] crate
88//!
89//! ## Public dependencies
90//!
91//! Crates whose types form part of Siderust's public API are re-exported so
92//! applications do not need to add matching direct dependencies merely to name
93//! those types: [`affn`], [`chrono`], [`optica`], [`principia`], and [`tempoch`].
94//! Typed quantities are available through Siderust's compatibility-enhanced
95//! [`qtty`] facade.
96//!
97//! ## Error-handling conventions
98//!
99//! `siderust` deliberately uses three distinct error-reporting patterns;
100//! they are not interchangeable.  The choice tells you something about the
101//! contract of the function:
102//!
103//! | Pattern                        | Meaning                                                        |
104//! |--------------------------------|----------------------------------------------------------------|
105//! | `-> Result<T, ConcreteError>`  | A *recoverable, domain-specific* failure (bad input, no convergence, dataset out of range). The error type is module-local and documented. |
106//! | `-> Option<T>`                 | A *lookup* that may legitimately have no answer (e.g. no event in the requested window, parameter outside the table's interpolation range). The `None` semantics are documented in the `# Returns` section of every public `Option`-returning function. |
107//! | `panic!` / `unwrap` / `expect` | A **bug or contract violation**: a non-finite Julian Date, an inverse of a singular rotation, an inconsistent type-system state, or a corrupt build-time table. Public functions that may panic carry a `# Panics` section. |
108//!
109//! When extending the public API, prefer `Result` over `Option` whenever the
110//! caller might want to know *why* there is no answer (e.g. "out of EOP
111//! range" vs "no event").  Reserve panics for true invariant violations,
112//! and document the trigger in the `# Panics` section.
113//!
114//! ## Minimal Example
115//!
116//! ```rust
117//! use siderust::{bodies::Mars, time::{JulianDate, JD, TT, Time, UTC}};
118//! use chrono::prelude::*;
119//!
120//! // 1. Select an epoch (UTC now to JD)
121//! let jd: JulianDate = Time::<UTC>::from_chrono(Utc::now()).to::<TT>().to::<JD>();
122//!
123//! // 2. Compute barycentric ecliptic coordinates via VSOP87
124//! let mars = Mars::vsop87e(jd);
125//!
126//! // 3. Print Mars's barycentric ecliptic position (AstronomicalUnits)
127//! println!("{:?}", mars);
128//! ```
129//!
130//! For a runnable tour of the library, see the `examples/` directory.
131//!
132//! ## `std` / `no_std`
133//!
134//! By default the crate enables the `std` and `serde` features. For
135//! `no_std` + `alloc` builds:
136//!
137//! ```toml
138//! siderust = { version = "0.12", default-features = false }
139//! ```
140//!
141//! Filesystem, OS I/O, and `Utc::now` require `std`. Features such as
142//! `runtime-data`, `spice`, and `pod` imply `std`.
143
144#![cfg_attr(not(feature = "std"), no_std)]
145#![cfg_attr(not(feature = "std"), allow(unused_imports))]
146
147extern crate alloc;
148
149pub(crate) use ::qtty as ext_qtty;
150
151// Keep public dependency types reachable through the exact crate instances
152// used to compile Siderust. This follows the same pattern as `affn::qtty` and
153// avoids making consumers declare these crates solely to name API types.
154pub use affn;
155pub use chrono;
156pub use optica;
157pub use principia;
158pub use tempoch;
159
160pub mod astro;
161#[cfg(feature = "atmosphere")]
162pub mod atmosphere;
163pub mod bodies;
164pub mod catalogs;
165pub mod checksum;
166pub mod coordinates;
167pub mod ephemeris;
168pub mod event;
169pub mod formats;
170pub mod healpix;
171pub mod mission;
172#[cfg(feature = "photometry")]
173pub mod photometry;
174#[cfg(feature = "pod")]
175pub mod pod;
176pub mod qtty;
177#[cfg(feature = "spice")]
178pub mod spice;
179pub mod starlight;
180pub mod targets;
181pub mod time;
182
183pub(crate) use siderust_archive as archive;
184
185// Ergonomic re-exports of common time markers / epoch (`siderust::J2000` in rustdoc examples).
186pub use time::{JulianDate, ModifiedJulianDate, J2000, JD, MJD};
187
188// Convenience re-export: sky sampling utilities.
189pub use coordinates::{SkyGrid, SkyGridCell};
190
191pub(crate) mod macros;
192
193// ---------------------------------------------------------------------------
194// Convenience re‑exports: unified azimuth API
195// ---------------------------------------------------------------------------
196pub use event::azimuth::{
197    azimuth_crossings, azimuth_extrema, azimuth_periods as compute_azimuth_periods, azimuth_ranges,
198    in_azimuth_range, outside_azimuth_range, AzimuthCrossingDirection, AzimuthCrossingEvent,
199    AzimuthExtremum, AzimuthExtremumKind, AzimuthProvider, AzimuthQuery,
200};
201pub use event::solar::{twilight, Twilight};
202pub use event::solar::{twilight_classification, TwilightPhase};
203
204// ---------------------------------------------------------------------------
205// Convenience re‑exports: unified altitude API
206// ---------------------------------------------------------------------------
207pub use affn::conic::ConicKind;
208pub use astro::conic::{ConicError, ConicOrbit, MeanMotionOrbit};
209pub use astro::orbit::{KeplerianOrbit, PreparedOrbit};
210pub use event::altitude::{
211    above_threshold, altitude_ranges, below_threshold, crossings, culminations, AltitudeEventsExt,
212    AltitudeProvider, CrossingDirection, CrossingEvent, CulminationEvent, CulminationKind,
213    SearchOpts,
214};
215
216// ---------------------------------------------------------------------------
217// Convenience re‑exports: lunar phase API
218// ---------------------------------------------------------------------------
219pub use event::lunar::phase::{
220    find_phase_events, illumination_above, illumination_below, illumination_range,
221    moon_phase_geocentric, moon_phase_topocentric, MoonPhaseGeometry, MoonPhaseLabel,
222    MoonPhaseSeries, PhaseEvent, PhaseKind, PhaseSearchOpts, PhaseThresholds,
223};
224pub use event::lunar::photometry::{
225    lunar_albedo_jones2013, lunar_full_moon_albedo_jones2013, lunar_phase_attenuation_jones2013,
226    reflected_lunar_spectral_irradiance_jones2013, reflected_lunar_spectral_radiance_jones2013,
227};
228pub use event::lunar::position_angle::{moon_bright_limb_position_angle, LunarObservationCenter};
229
230// ---------------------------------------------------------------------------
231// Convenience re‑exports: planetary physical orientation
232// ---------------------------------------------------------------------------
233pub use event::planetary::{
234    body_orientation, mars_orientation, saturn_ring_orientation, saturn_rings, BodyOrientation,
235    MarsOrientation, ObservationGeometry, PlanetaryObservationCenter, SaturnRingOrientation,
236    SkyOrientationFrame, ORIENTATION_CORRECTIONS,
237};
238
239// ---------------------------------------------------------------------------
240// Convenience re‑exports: target abstractions
241// ---------------------------------------------------------------------------
242pub use targets::{CoordinateWithPM, Trackable};
243
244#[cfg(feature = "bench-internals")]
245#[doc(hidden)]
246#[path = "../benches/support/internals.rs"]
247pub mod bench_internals;