High-performance Python bindings for the Outfit orbit-determination engine (Initial Orbit Determination, observation ingestion, orbital element conversions & batch processing) powered by Rust + PyO3.
pyOutfit
exposes the Rust Outfit crate to Python with a thin, typed interface. It enables:
- Gauss-based Initial Orbit Determination (IOD) with configurable numerical & physical filters.
- Manipulation of multiple orbital element representations (Keplerian, Equinoctial, Cometary).
- Efficient ingest of astrometric observations (single trajectories or large batches) with zero-copy / single-conversion paths.
- Parallel batch processing for thousands of trajectories (opt-in).
- Access & registration of observatories (MPC code lookup & custom definitions).
Rust performs all heavy numerical work; Python orchestrates workflows with minimal overhead.
Area | Highlights |
---|---|
IOD | Gauss method with configurable solver tolerances & physical filters |
Elements | Keplerian / Equinoctial / Cometary conversions & wrappers |
Observations | NumPy ingestion in radians or degrees (with automatic conversion) |
Performance | Optional parallel batches, detached GIL region for compute-heavy steps |
Safety | Rust error types mapped to Python RuntimeError (idiomatic try/except) |
Extensibility | Builder pattern for IODParams & ergonomic container types |
# (Recommended) Create & activate a virtual environment first
python3.12 -m venv .venv
source .venv/bin/activate
# Install build backend (only needed for local builds)
pip install --upgrade pip maturin
# Build and install the extension in development mode
maturin develop
Verify the module loads:
python -c "import py_outfit; print('Classes:', [c for c in dir(py_outfit) if c[0].isupper()])"
Until wheels are published on PyPI, build from source:
git clone <this-repo-url>
cd pyOutfit
pip install maturin
maturin develop # or: maturin build --release && pip install target/wheels/py_outfit-*.whl
System requirements:
- Python 3.12 (matching the
pyproject.toml
requirement) - Rust toolchain (≥ 1.82)
- C toolchain (e.g.
build-essential
on Debian/Ubuntu)
Example (Debian/Ubuntu):
sudo apt update
sudo apt install -y build-essential python3.12-dev pkg-config libssl-dev
Install Rust if needed: https://rustup.rs
Below: create an environment, register an observer, ingest synthetic observations, configure Gauss IOD, and estimate orbits.
pyOutfit/docs/tutorials/tutorial_snippets/quickstart_snippet.py
Lines 1 to 102 in f580716
pyOutfit/docs/tutorials/tutorial_snippets/iod_params_parallel.py
Lines 1 to 10 in f580716
pyOutfit/docs/tutorials/tutorial_snippets/trajectories_estimate_single.py
Lines 108 to 111 in f580716
Class / Function | Purpose |
---|---|
PyOutfit |
Global environment (ephemerides, error model, observatory catalog) |
Observer |
Observatory definition / MPC lookup handle |
IODParams / IODParams.builder() |
IOD configuration (physical filters, solver tolerances, parallelism) |
TrajectorySet |
Mapping-like container of trajectories (IDs → Observations ) |
Observations |
Read-only per-trajectory access + NumPy export |
GaussResult |
Result wrapper (preliminary / corrected orbit + element extraction) |
KeplerianElements , EquinoctialElements , CometaryElements |
Different orbital element families |
- Core numerical routines run in Rust without the Python GIL (
py.detach
). - Batch ingestion uses zero-copy (radian path) or a single conversion (degree path).
- Parallel processing is opt-in via
IODParams.builder().do_parallel()
to avoid contention when working with small data. - Deterministic runs are achievable by passing a
seed
toTrajectorySet.estimate_all_orbits
. - Error propagation: all
OutfitError
variants surface as PythonRuntimeError
with descriptive messages.
try:
env = PyOutfit("horizon:DE440", "VFCC17")
except RuntimeError as e:
print("Failed to init environment:", e)
# 1. (one time) Setup
pip install maturin pytest
# 2. Rebuild after Rust changes
maturin develop
# 3. Run Python tests
pytest -q
# 4. Optional: run Rust unit tests (if added)
cargo test
src/ # Rust sources (PyO3 classes & bindings)
py_outfit/ # Generated Python package (stub .pyi + compiled extension)
tests/ # Python tests (pytest)
Cargo.toml # Rust crate metadata
pyproject.toml # Python build config (maturin backend)
Contributions are welcome:
- Fork & create a feature branch.
- Add tests (Python or Rust) for new behavior.
- Keep public Python API backwards compatible when possible.
- Run
pytest
before opening a PR.
Feel free to open an issue for design discussions first.
Distributed under the CeCILL-C license. See LICENSE
for the full text.
Built on top of the Rust Outfit crate and the PyO3 + maturin ecosystem.
Questions, ideas, or issues? Open an issue or start a discussion – happy to help.