Python bindings for Outfit (Rust) — Gauss IOD, ephemerides, etc.
Project description
pyOutfit
High-performance Python bindings for the Outfit orbit-determination engine (Initial Orbit Determination, observation ingestion, orbital element conversions & batch processing) powered by Rust + PyO3.
✨ Overview
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.
🔍 Feature Highlights
| 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 |
🚀 Quick Start
# (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()])"
📦 Installation Options
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.tomlrequirement) - Rust toolchain (≥ 1.82)
- C toolchain (e.g.
build-essentialon 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
🧪 Minimal End‑to‑End Example
Below: create an environment, register an observer, ingest synthetic observations, configure Gauss IOD, and estimate orbits.
🔧 Working with IODParams
📊 Accessing Observations
🗂 API Surface (Python Names)
| 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 |
⚙️ Performance Notes
- 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
seedtoTrajectorySet.estimate_all_orbits. - Error propagation: all
OutfitErrorvariants surface as PythonRuntimeErrorwith descriptive messages.
🧭 Error Handling Pattern
try:
env = PyOutfit("horizon:DE440", "VFCC17")
except RuntimeError as e:
print("Failed to init environment:", e)
🧑💻 Development Workflow
# 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
Project Layout
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)
🤝 Contributing
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
pytestbefore opening a PR.
Feel free to open an issue for design discussions first.
📄 License
Distributed under the CeCILL-C license. See LICENSE for the full text.
🙌 Acknowledgements
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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file py_outfit-1.0.0.tar.gz.
File metadata
- Download URL: py_outfit-1.0.0.tar.gz
- Upload date:
- Size: 142.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dd6de75fd10c027a209a690e1aa0a69f3e2ed33a212497d11811e1494c1294eb
|
|
| MD5 |
2cb83e339722b2f485e3278b062a18a6
|
|
| BLAKE2b-256 |
ed165f40e3d87e39661795cabbcbf0bc4cbc197961ea1d34cad707e3f5f85315
|
File details
Details for the file py_outfit-1.0.0-cp312-cp312-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: py_outfit-1.0.0-cp312-cp312-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 2.3 MB
- Tags: CPython 3.12, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.9.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e57497fb701adc04ec926a7a6167eb924a3419b83ca7f602399c2bc82de5ae19
|
|
| MD5 |
c7038459e0059a512b64e7538b156f9b
|
|
| BLAKE2b-256 |
7e67116f2a50b39721cc0eb2d0f860e090129b5253aab94597d15f1901f8553f
|
File details
Details for the file py_outfit-1.0.0-cp311-cp311-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: py_outfit-1.0.0-cp311-cp311-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 2.3 MB
- Tags: CPython 3.11, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.9.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2cb184d7d8792ee7ff876563059976fac3f554566bd962b9f1c78b95f78aea16
|
|
| MD5 |
944cabe14ea57b3dd9a87297fc35e0ee
|
|
| BLAKE2b-256 |
5a4be10488b7133336132841ea36ff24d6415221590ff0f2acd9d43389312c37
|
File details
Details for the file py_outfit-1.0.0-cp310-cp310-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: py_outfit-1.0.0-cp310-cp310-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 2.3 MB
- Tags: CPython 3.10, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.9.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9458dfa0e8f82c451b0205904b9d1f0e7b37ff9ceee75c0b43c9bd4fe3ad2e06
|
|
| MD5 |
6b3da03bd5b5f98bdef38537f2832a00
|
|
| BLAKE2b-256 |
057f3f0e456498808adff6aa38ef0319dffa0e4beb99756ff9f3cea36729d046
|