empyrean.propagate¶
- propagate(orbits, epochs, config=None, *, force_model=None, uncertainty_method=None, num_threads=None, events=None, tagged_covariance=False, thrust_arcs=None, _builtsystem=None)[source]¶
Propagate orbits to target epochs.
- Parameters:
orbits (
CartesianOrbits|KeplerianOrbits|CometaryOrbits|SphericalOrbits) – Input orbits with optional covariance and non-gravitational parameters.epochs (
Epochs) – Target epochs as anEpochstable, converted to TDB internally. Build one withEpochs.from_mjd(values, scale="tdb")(orscale="utc"); a bare array is refused, as it carries no time scale.config (
PropagationConfig|None) – Full propagation configuration. Construct withPropagationConfig(force_model=..., uncertainty_method=...)etc. If omitted, one is built from the sugar kwargs below (or defaults).force_model (
ForceModelTier|str|None) – Quick override forconfig.force_model. Ignored ifconfigis given.uncertainty_method (
UncertaintyMethod|SigmaPoint|MonteCarlo|GaussianMixture|Auto|str|None) –Optional quick override for
config.uncertainty_method. Accepts either an enum / string (default parameters) or a parameterized dataclass (SigmaPoint,MonteCarlo,GaussianMixture,Auto). Ignored ifconfigis given. PassAuto(rather than the bareAUTOenum) to tune the per-close-approach κ band edges and AGM knobs.All six methods run in
propagate():FIRST_ORDER/SECOND_ORDER/AUTOattach the STM-based state covariance (AUTOescalating to a second-order ellipsoid over close-approach windows).SIGMA_POINTreconstructs a genuine sample-based state covariance (the second moment of the propagated canonical 2N+1 sigma-point set), read back taggedsigma_point.MONTE_CARLOdrawsn_samplesfrom the input covariance (reproducibly, for a fixedseed) and reports the Monte-Carlo impact probability on theip_mccolumn of any possible-impact event. It does not reconstruct a per-epoch state covariance — the propagated states carry no state covariance underMONTE_CARLO(useSIGMA_POINTfor a sampled state covariance, orcompute_impact_probabilities()for the full Monte-Carlo impact-probability workflow).GAUSSIAN_MIXTUREsplits the input Gaussian into an adaptive mixture at close approaches; its distinctive product is the mixture-corrected impact probability. Away from encounters the output-state covariance is the linearΦ·Σ·Φᵀmapping (likeSECOND_ORDER), so for a well-determined object it reads back very close toFIRST_ORDER(taggedlinear) — that is expected, not a bug.The mixture components themselves come back on
PropagationResult.mixtures(aMixtureChainstable), so a consumer can evaluatesum_k w_k * N(x | mu_k, Sigma_k)directly at a retained close-approach epoch. Four limits apply to what is retained, each a real property of the engine’s retention rather than a marshaling shortfall:Depth-0 only. Only the initial split is retained; recursive AGM calls (depth > 0) are not captured.
Only CA epochs where AGM fired. An orbit that never triggered a split contributes no rows, not a one-component chain.
Component covariance is the linear map. Each component’s covariance is
Phi Sigma_k Phi^T; the second-order mean correction is intentionally omitted.Retained weights may sum to less than 1. A sub-Gaussian whose own sub-propagation missed the close approach (or failed to integrate) contributes no component, and the deficit is not recorded anywhere. Do not assume
sum_k w_k == 1; sumweightand check.
num_threads (
int|None) – Threads for multi-orbit propagation.None(default) and0both use all available cores;n> 0 pins exactlynthreads. Each orbit is integrated on a single thread; parallelism is across orbits, not within a single trajectory.events (
EventConfig|None) – Event-detection toggles + body filter + dense-output cadence. Override individual flags here without rebuilding a fullPropagationConfig. SeeEventConfig.tagged_covariance (
bool) – WhenTrue, also read back the provenance-tagged, resolved-kind covariance at every output epoch (the honest covariance that distinguishes a second-order close-approach ellipsoid from the bare linearΦ Σ₀ Φᵀmapping on the states). The result’stagged_covariancetable is populated andtagged_covariance_series()becomes usable. Off by default — the readback recomputes the resolved kind per orbit, so it isn’t free.thrust_arcs (
Sequence[ThrustParams|None] |None) – Structured continuous-thrust / finite-burn input, one entry per orbit and positionally aligned withorbits(passNonefor the gravity / non-grav-only orbits, or the whole argumentNonefor a fully ballistic batch). Build each entry fromThrustParams/ThrustArc/ aSteeringLawvariant. A non-emptycorrection_covariancestriggers the burn-sensitivity propagation whose solved segments surface in the tagged-covariancethrust_segments(requirestagged_covariance=True). Length or arc/correction mismatches raise, never silently degrade._builtsystem (Any)
- Return type:
PropagationResult- Returns:
PropagationResult – Propagated states, detected events, and per-orbit state sensitivity chains.
Notes
Within each orbit, states come back in ascending epoch order, always, regardless of the order the epochs were requested in. Positional pairing against an ascending, duplicate-free request grid is therefore exact; for any other request shape, join on the result’s
epoch_mjd_tdbcolumn.The joint covariance travels in both directions. An input orbit carrying cross terms — on
non_grav.non_grav_cross(the 6x3 state-Marsden border) andwide_cross(everything else) — is propagated against them rather than against its6x6alone, and every output row carries the propagated cross terms in the same two columns. This is what makes a chained propagation agree with the single-leg answer: the state-parameter columns are non-zero even when the input was block-diagonal, because propagation itself generates that correlation, so a second leg handed only the6x6reports a tighter uncertainty than the first leg supports.Cross terms are refused without the parameter blocks they are conditioned on (the non-grav
3x3, the DT and AMRAT prior variances). Propagation passes those through unchanged rather than restating them on every output row, so when chaining legs by hand take them from the orbit that started the chain. A row with no cross terms is null, never zero — an absent correlation and a measured zero correlation are different claims.- Raises:
TypeError –
epochsis not anEpochstable.- Parameters:
orbits (CartesianOrbits | KeplerianOrbits | CometaryOrbits | SphericalOrbits)
epochs (Epochs)
config (PropagationConfig | None)
force_model (ForceModelTier | str | None)
uncertainty_method (UncertaintyMethod | SigmaPoint | MonteCarlo | GaussianMixture | Auto | str | None)
num_threads (int | None)
events (EventConfig | None)
tagged_covariance (bool)
thrust_arcs (Sequence[ThrustParams | None] | None)
_builtsystem (Any)
- Return type:
PropagationResult
Examples
Defaults (Standard force model, FirstOrder uncertainty):
>>> times = Epochs.from_mjd([60500.0, 60501.0], scale="tdb") >>> result = empyrean.propagate(orbits, times)
With a config object:
>>> cfg = PropagationConfig( ... force_model=ForceModelTier.STANDARD, ... uncertainty_method=SigmaPoint(), ... num_threads=8, ... ) >>> result = empyrean.propagate(orbits, times, cfg)
With inline kwargs (sugar):
>>> result = empyrean.propagate(orbits, times, force_model="standard")