Native Python port of Orekit 13.1.6's Draper Semi-analytical Satellite Theory
(DSST) package, centered on DSSTPropagator.
This project is intended to run independently of Orekit Java at application runtime. The Java Orekit checkout is only used by the regression tooling that generates comparison fixtures.
- Scalar and field-style DSST propagator shells.
- Native equinoctial orbit and spacecraft-state data adapters.
- DSST force models for Newtonian attraction, J2-squared, zonal, tesseral, third body, solar radiation pressure, and atmospheric drag.
- DSST utilities, Hansen helpers, short-period terms, interpolation grids, mapper conversion, STM/Jacobian helpers, and selected-coefficient plumbing.
- Pytest coverage plus optional Orekit Java fixture comparison tests.
The port uses lightweight Python data records instead of Orekit's Java
Orbit, SpacecraftState, AbsoluteDate, Frame, body, atmosphere, and
shape classes. That keeps runtime use standalone, but it also means this is
not a drop-in replacement for every surrounding Orekit API.
- Python 3.10 or newer
pytestfor tests
SciPy is not required by the current implementation.
From this directory:
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install -e ".[test]"On Linux/macOS the activation step is:
source .venv/bin/activateThe propagator works with native equinoctial data. Use SI units: meters,
seconds, radians, kilograms, and m^3/s^2.
import math
from dsst.dsst_propagator import DSSTPropagator
from dsst.utilities.auxiliary_elements import EquinoctialOrbitData
mu = 398600.4418e9
a = 7_000_000.0
n = math.sqrt(mu / a) / a
orbit = EquinoctialOrbitData(
date=0.0,
frame="GCRF",
e=0.02,
keplerian_mean_motion=n,
keplerian_period=2.0 * math.pi / n,
a=a,
equinoctial_ex=0.01,
equinoctial_ey=-0.017,
hx=0.001,
hy=-0.002,
lm=0.25,
lv=0.25,
le=0.25,
mu=mu,
)
state = {"date": 0.0, "orbit": orbit, "mass": 900.0}
propagator = DSSTPropagator()
propagator.setMu(mu)
propagator.setInitialState(state, "MEAN")
propagated = propagator.propagate(600.0, step=60.0)
print(propagated["date"])
print(propagated["orbit"].lm)setMu(mu) adds the central Newtonian attraction model. You can also add it
explicitly with DSSTNewtonianAttraction(mu).
Force models are added with addForceModel. Most force calculations use
AuxiliaryElements, which wrap an equinoctial orbit and the retrograde factor
(1 for normal prograde DSST use).
from dsst.dsst_propagator import DSSTPropagator
from dsst.forces.dsst_atmospheric_drag import DSSTAtmosphericDrag
from dsst.forces.dsst_solar_radiation_pressure import CentralBodyData, DSSTSolarRadiationPressure
from dsst.forces.dsst_third_body import DSSTThirdBody
from dsst.forces.dsst_third_body_dynamic_context import CelestialBodyData
from dsst.utilities.auxiliary_elements import AuxiliaryElements
auxiliary = AuxiliaryElements(orbit, 1)
moon = CelestialBodyData(
position=(384_400_000.0, 1_000_000.0, -2_000_000.0),
name="Moon",
gm=4.9048695e12,
)
drag = DSSTAtmosphericDrag({"density": 2.0e-12}, 2.2, 12.5, mu)
srp = DSSTSolarRadiationPressure(
1.2,
10.0,
(149_597_870_700.0, 0.0, 0.0),
CentralBodyData(6_378_137.0),
mu,
)
propagator = DSSTPropagator()
propagator.setMu(mu)
propagator.addForceModel(DSSTThirdBody(moon, mu))
propagator.addForceModel(drag)
propagator.addForceModel(srp)
rates = propagator.computeDerivatives(state, auxiliary)For gravity harmonics, use SphericalHarmonicsProviderData with DSSTZonal,
DSSTTesseral, or DSSTJ2SquaredClosedForm.
Create the propagator with propagationType="OSCULATING" when you want
short-period terms applied to propagated output.
propagator = DSSTPropagator(propagationType="OSCULATING")
propagator.setMu(mu)
propagator.setInitialState(state, "MEAN")
osculating = propagator.propagate(600.0, step=60.0)Useful methods:
computeOsculatingState(mean_state)computeMeanState(osculating_state)setInterpolationGridToFixedNumberOfPoints(points)setInterpolationGridToMaxTimeGap(max_gap)setSelectedCoefficients({"DSST-SRP-c[12]"})
The Python port accepts several lightweight shapes:
dict:{"date": ..., "orbit": ..., "mass": ..., "additionalData": ...}SimpleSpacecraftStateEquinoctialOrbitData- Orbit-like objects with Orekit-style getters such as
getA()andgetLM() - Date adapters with
toAbsoluteDate()ordurationFrom(...)
Map-state mass values may be numeric strings such as "900.0"; they are
normalized to floats when propagated.
Run the native and fixture-backed suite:
python -m pytest -qCurrent verification baseline:
261 passed- No Java runtime is required for normal package use.
- Java, Maven, and the Orekit checkout are only needed when regenerating
Orekit comparison fixtures under
regression/.
src/dsst/ Python package
src/dsst/forces/ DSST force models and force contexts
src/dsst/utilities/ DSST utility and coefficient helpers
src/dsst/utilities/hansen/ Hansen recurrence helpers
tests/ Pytest unit, functionality, and Orekit fixture tests
regression/ Optional Orekit Java reference fixture generation
PORTING_MANIFEST.json Java source to Python source map
PROGRESS.md Porting ledger and verification history
Applications importing dsst-python do not call Java, JPype, Maven, or Orekit.
The native code contains the implemented DSST formulas and lightweight adapter
types directly. Keep the Orekit source tree only if you want to audit
provenance or regenerate reference fixtures.
- This is a DSST-focused native port, not the full Orekit ecosystem.
- High-fidelity production use should validate inputs, force configuration, and propagation horizons against mission-specific truth data.
- External frames, time scales, celestial ephemerides, body shapes, atmosphere models, and spacecraft models should be supplied through the lightweight data adapters or through application-specific wrapper objects.
The package metadata declares Apache-2.0. Source provenance for every ported
Orekit DSST class is recorded in PORTING_MANIFEST.json and in class-level
status() metadata.