Skip to main content

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.

pyOutfit
CI PyPI version Documentation Python 3.12 Build (maturin) License: CeCILL-C

Upstream Outfit (Rust core)
crates.io docs.rs MSRV

✨ 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.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

🧪 Minimal End‑to‑End Example

Below: create an environment, register an observer, ingest synthetic observations, configure Gauss IOD, and estimate orbits.

https://github.com/FusRoman/pyOutfit/blob/f58071657e896f4dc2cf9ee3f7b894b81593c311/docs/tutorials/tutorial_snippets/quickstart_snippet.py#L1-L102

🔧 Working with IODParams

https://github.com/FusRoman/pyOutfit/blob/f58071657e896f4dc2cf9ee3f7b894b81593c311/docs/tutorials/tutorial_snippets/iod_params_parallel.py#L1-L10

📊 Accessing Observations

https://github.com/FusRoman/pyOutfit/blob/f58071657e896f4dc2cf9ee3f7b894b81593c311/docs/tutorials/tutorial_snippets/trajectories_estimate_single.py#L108-L111

🗂 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 seed to TrajectorySet.estimate_all_orbits.
  • Error propagation: all OutfitError variants surface as Python RuntimeError with 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:

  1. Fork & create a feature branch.
  2. Add tests (Python or Rust) for new behavior.
  3. Keep public Python API backwards compatible when possible.
  4. Run pytest before 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)

Source distribution for py-outfit 1.0.0
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)

Table of built distributions (wheels) for py-outfit 1.0.0
File Interpreter ABI Platform Actions
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.

Release history Release notifications | RSS feed

This release

1.0.0 This release

4 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page