optica
Fast, typed participating-media and optics foundations for Rust.
optica provides the core building blocks for radiative-transfer and
optical-depth workloads: typed rays, optical coefficients, phase functions,
sampled spectra, interpolation tables, and Beer–Lambert integration.
It is intentionally domain-agnostic — no astronomy policies, planetary
constants, ephemerides, or observatory presets.
Pre-1.0 API: Breaking changes may occur in minor releases. Each breaking change is documented in CHANGELOG.md.
Scope
- Typed rays and ray segments (affn geometry, phantom length unit)
- Optical coefficients: absorption
σ_a, scatteringσ_s, extinctionσ_t, SSAω₀ - Scattering phase functions: Rayleigh, Henyey–Greenstein, double-HG, tabulated
- Rayleigh and Ångström (Mie) optical-depth formulas (caller-supplied parameters)
- Sampled spectra: 1-D tables with linear, nearest, step, and cubic-spline interpolation
- Two-column ASCII spectrum loader (whitespace or CSV, unit-scale factors, provenance)
- 1-D, 2-D, and 3-D typed interpolation grids (ascending and descending axes)
- Optical-depth integration over a ray segment: midpoint, trapezoidal, Simpson, and Gauss-Legendre rules
- Beer–Lambert transmittance and van Rhijn path-length factor
- Provenance metadata for tabulated inputs and generated products
Non-goals
- Astronomical bodies, ephemerides, or site-specific observatory constants
- Atmospheric profiles or specific planetary atmospheric models
- Radiometric source models (solar spectra, thermal emission)
- GPU or SIMD acceleration (the crate prioritises correctness and
no_stdsupport)
Installation
[]
= "0.1"
Default features include std. Opt out for no_std + alloc:
[]
= { = "0.1", = false, = ["alloc"] }
Enable Serde serialization:
[]
= { = "0.1", = ["serde"] }
Feature flags
| Feature | Default | Description |
|---|---|---|
std |
✓ | Enables std-dependent helpers (ASCII/string parsing) and implies alloc. |
alloc |
Enables heap-backed types (Vec/Box/String) for no_std targets. With this off, only medium, ray, scatter, and transport are compiled. |
|
serde |
Derives Serialize/Deserialize on the public data, error, and policy types. TableSource derives only Serialize because it borrows static slices. |
|
astro |
Reserved for future astronomy-specific adapters; currently a no-op. |
Serde support
When the serde feature is enabled, the following types derive Serialize and Deserialize:
AxisDirection, OutOfRange, Provenance, TableSource (Serialize only),
Interpolation, SpectrumError, OpticalCoefficientError, PhaseError,
ScatterError, TransportError, IntegrationMethod, IntegrationOpts,
MieParams.
The following types do not derive serde:
SampledSpectrum, Grid1D, Grid2D, Grid3D, HomogeneousMedium,
HenyeyGreensteinPhaseFunction, DoubleHenyeyGreensteinPhaseFunction,
RayleighPhaseFunction, PhaseModel, PhaseTable.
These containers hold variable-length data or opaque function pointers; their
serialization format is left to the caller.
Examples
Load a two-column ASCII spectrum
use ;
use OutOfRange;
use ;
let data = "# wavelength(nm) transmittance\n400.0 0.0\n550.0 0.85\n700.0 0.92\n";
let spectrum = .unwrap;
use Quantity;
let t = spectrum.interp_at;
assert!;
Interpolate a 2-D table
use ;
use ;
// Row-major: row 0 (y=0°): V(400nm)=0.1, V(700nm)=0.4
// row 1 (y=1°): V(400nm)=0.5, V(700nm)=0.9
let grid = from_raw_row_major.unwrap;
let v = grid.interp_at;
assert!;
Integrate optical depth along a ray
use ;
use HomogeneousMedium;
use ;
use ;
use ;
use Kilometer;
;
;
// σ_a = 0.1 km⁻¹, σ_s = 0.2 km⁻¹ → σ_t = 0.3 km⁻¹
let medium = try_new.unwrap;
let ray = new;
let tau = integrate_optical_depth;
// τ = σ_t × distance = 0.3 × 10 = 3.0
assert!;
Relationship with siderust
siderust builds domain-specific
astronomy and atmospheric science on top of optica. It adds:
- Concrete atmospheric profiles (ozone, Rayleigh, aerosol models)
- Observatory and site-specific presets
- Ephemerides and body constants
- Astronomical epoch and coordinate types
optica is the generic foundation; siderust is the astronomy adapter.
Users who only need participating-media primitives can depend on optica
directly without pulling in siderust.
License
AGPL-3.0-only — see LICENSE.