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.
Metadata
Release files for py-outfit 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| py_outfit-1.0.0.tar.gz | 142.4 kB | Without provenance | Details for py_outfit-1.0.0.tar.gz |
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| py_outfit-1.0.0-cp312-cp312-manylinux_2_28_x86_64.whl | CPython 3.12 | CPython 3.12 | Linux glibc 2.28+ x86-64 | Details for py_outfit-1.0.0-cp312-cp312-manylinux_2_28_x86_64.whl |
| py_outfit-1.0.0-cp311-cp311-manylinux_2_28_x86_64.whl | CPython 3.11 | CPython 3.11 | Linux glibc 2.28+ x86-64 | Details for py_outfit-1.0.0-cp311-cp311-manylinux_2_28_x86_64.whl |
| py_outfit-1.0.0-cp310-cp310-manylinux_2_28_x86_64.whl | CPython 3.10 | CPython 3.10 | Linux glibc 2.28+ x86-64 | Details for py_outfit-1.0.0-cp310-cp310-manylinux_2_28_x86_64.whl |
Total release size: 7.0 MB
Release files / py_outfit-1.0.0.tar.gz
| Download URL | py_outfit-1.0.0.tar.gz |
|---|---|
| Size | 142.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
dd6de75fd10c027a209a690e1aa0a69f3e2ed33a212497d11811e1494c1294eb
|
|
BLAKE2b-256 checksum How to use checksums |
ed165f40e3d87e39661795cabbcbf0bc4cbc197961ea1d34cad707e3f5f85315
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|
Release files / py_outfit-1.0.0-cp312-cp312-manylinux_2_28_x86_64.whl
| Download URL | py_outfit-1.0.0-cp312-cp312-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | CPython 3.12 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
e57497fb701adc04ec926a7a6167eb924a3419b83ca7f602399c2bc82de5ae19
|
|
BLAKE2b-256 checksum How to use checksums |
7e67116f2a50b39721cc0eb2d0f860e090129b5253aab94597d15f1901f8553f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.9.4
|
Release files / py_outfit-1.0.0-cp311-cp311-manylinux_2_28_x86_64.whl
| Download URL | py_outfit-1.0.0-cp311-cp311-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | CPython 3.11 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
2cb184d7d8792ee7ff876563059976fac3f554566bd962b9f1c78b95f78aea16
|
|
BLAKE2b-256 checksum How to use checksums |
5a4be10488b7133336132841ea36ff24d6415221590ff0f2acd9d43389312c37
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.9.4
|
Release files / py_outfit-1.0.0-cp310-cp310-manylinux_2_28_x86_64.whl
| Download URL | py_outfit-1.0.0-cp310-cp310-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | CPython 3.10 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
9458dfa0e8f82c451b0205904b9d1f0e7b37ff9ceee75c0b43c9bd4fe3ad2e06
|
|
BLAKE2b-256 checksum How to use checksums |
057f3f0e456498808adff6aa38ef0319dffa0e4beb99756ff9f3cea36729d046
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.9.4
|
Security for py-outfit 1.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.