astra.covariance module

ASTRA Core Covariance and Uncertainty Modeling. Calculates Mahalanobis distance and Probability of Collision (Pc) by projecting 3D positional covariances onto the 2D encounter plane. Includes: - Analytical Foster/Chan Pc (rectilinear short-duration encounters) - Monte Carlo Pc (co-orbital, slow encounters, curvilinear geometry) - STM-based covariance propagation (linearized J2 dynamics) - Empirical covariance estimation (TLE degradation model)

astra.covariance.rotate_covariance_rtn_to_eci(cov_rtn, r_eci_km, v_eci_km_s)[source]

Map a 3×3 covariance from RTN (diagonal or full) into ECI at the given state. RTN: R radial (position), T along-track, N cross-track (angular momentum).

astra.covariance.compute_collision_probability(miss_vector_km, rel_vel_km_s, cov_a, cov_b, radius_a_km=0.005, radius_b_km=0.005)[source]

Computes Probability of Collision (Pc) via 2D projection on the encounter plane. Uses standard Foster/Chan methodology for projecting combined 3D Cartesian covariance onto the B-plane (perpendicular to relative velocity vector). Args: :param miss_vector_km: (3,) relative position vector at exact TCA (km). :param rel_vel_km_s: (3,) relative velocity vector at TCA (km/s). :param cov_a: (3, 3) or (6, 6) positional/state covariance matrix for Object A. :param cov_b: (3, 3) or (6, 6) positional/state covariance matrix for Object B. :param radius_a_km: Hard-body radius for Object A (km). :param radius_b_km: Hard-body radius for Object B (km).

Returns:

Probability of collision (float) bounded [0.0, 1.0], or None if covariance is singular.

astra.covariance.estimate_covariance(time_since_epoch_days, f107_flux=150.0)[source]

Generates an estimated positional covariance matrix (3x3) in RTN frame. Models realistic anisotropic TLE degradation based on Vallado & Alfano (2014): - Radial (R): grows quadratically with time (gravity model uncertainty) - In-track (T): grows cubically with time (drag uncertainty dominates) - Cross-track (N): grows linearly with time (inclination uncertainty) The returned matrix is diagonal in RTN. For full accuracy, this should be rotated to the ECI/TEME frame using the satellite’s orbital state, but for encounter-plane projection this diagonal approximation produces physically meaningful Pc values. .. warning:

In ``ASTRA_STRICT_MODE=True`` this function raises ``ValueError``.
Collision probability pipelines require real Orbit Determination
covariances, not heuristic estimates.
Parameters:
  • time_since_epoch_days – Days elapsed since TLE epoch.

  • f107_flux – Solar F10.7 index for drag scaling.

Returns:

(3, 3) diagonal covariance matrix in km^2.

Return type:

np.ndarray

Raises:

ValueError – In STRICT_MODE — real OD covariance data must be supplied.

astra.covariance.compute_collision_probability_mc(miss_vector_km, rel_vel_km_s, cov_a, cov_b, radius_a_km=0.005, radius_b_km=0.005, n_samples=100000, seed=None, mean_motion_rad_s=None)[source]

Monte Carlo Collision Probability for long-duration and co-orbital encounters. Trajectory model selection (HIGH-04): For encounters with relative speed >= 0.1 km/s (crossing or chase geometry), a linear relative path is used per sample – accurate and fast for these cases. For encounters with relative speed < 0.1 km/s (co-orbital / formation flying), the Hill-Clohessy-Wiltshire (HCW) equations propagate each sampled state along the correct curved orbit-relative trajectory. The prior linear model systematically under-estimates Pc in this regime because it ignores the orbital curvature that brings co-planar objects back toward each other on timescales of minutes to hours (critical for Starlink/OneWeb same-plane conjunctions). The HCW evaluation is fully vectorised over all samples via numpy broadcasting (n_samples x n_time_steps) – no per-sample Python loop. :param miss_vector_km: (3,) relative position at TCA (km). :param rel_vel_km_s: (3,) relative velocity at TCA (km/s). :param cov_a: (6,6) Object A full covariance (km^2, km^2/s^2 etc). :param cov_b: (6,6) Object B full covariance (km^2, km^2/s^2 etc). :param radius_a_km: Object A hard-body radius (km). Default 5 m. :param radius_b_km: Object B hard-body radius (km). Default 5 m. :param n_samples: Number of Monte Carlo samples (default 100,000). :param seed: Optional RNG seed for reproducibility. :param mean_motion_rad_s: Mean orbital motion (rad/s) for HCW propagation.

Required for low-relative-speed HCW encounters in strict mode. In relaxed mode, a warning is emitted and a 90-minute LEO default is used only as a screening fallback.

Returns:

Probability of collision (float) bounded [0.0, 1.0].

astra.covariance.propagate_covariance_stm(t_jd0, r0_km, v0_km_s, cov0_6x6, duration_s, drag_config=None)[source]

Propagate a full 6x6 covariance matrix using the State Transition Matrix.

Warning

The STM Jacobian includes J2–J6 zonal harmonics and atmospheric drag. It does not include Sun/Moon third-body gravity or SRP. For GEO/HEO objects, omitting third-body perturbations causes significant secular nodal-rate errors. Use propagate_cowell(include_stm=True) for force-model-consistent covariance at those altitudes.

This function is appropriate for LEO conjunction screening where the dominant perturbations are J2–J6 and atmospheric drag.

Uses linearized J2–J6 + drag dynamics to compute the 6x6 STM via numerical integration, mapping the full 6x6 state uncertainty:

C(t) = Φ(t, t₀) · C₀ · Φ(t, t₀)ᵀ

The state-transition matrix Φ is computed by integrating the variational equations along the nominal trajectory. The Jacobian includes: - Point-mass gravity (μ/r³) - Zonal harmonics (J2, J3, J4, J5, J6) - Atmospheric Drag partials (∂a/∂v) for LEO satellites.

astra.covariance.compute_collision_probability_timeseries(miss_vectors_km, rel_velocities_km_s, covariances_a, covariances_b, times_jd, radius_a_km=0.01, radius_b_km=0.01)[source]

Compute collision probability Pc(t) at each time step in a screening window.

Evaluates the standard Foster-Chan 2D encounter-plane collision probability at each of N time steps. This produces a Pc time series required for CDM screening compliance, where operators need to monitor how Pc evolves over a 7-day look-ahead window, not just its value at TCA.

Uses compute_collision_probability() at each step. If any individual computation fails (singular covariance, zero relative velocity), the Pc for that step is set to NaN.

Parameters:
  • miss_vectors_km – (N, 3) array of relative position vectors at each time step (km).

  • rel_velocities_km_s – (N, 3) array of relative velocity vectors at each time step (km/s).

  • covariances_a – (N, 3, 3) or (N, 6, 6) positional/state covariance matrices for Object A at each time step.

  • covariances_b – (N, 3, 3) or (N, 6, 6) positional/state covariance matrices for Object B at each time step.

  • times_jd – (N,) array of Julian Dates for each time step. Used for output indexing; not directly consumed by the Pc formula.

  • radius_a_km – Hard-body radius for Object A (km). Default 0.01 (10 m).

  • radius_b_km – Hard-body radius for Object B (km). Default 0.01 (10 m).

Returns:

(N,) array of collision probabilities. Each element is in [0.0, 1.0] or NaN if the computation failed for that step.

Raises:

ValueError – If input array shapes are inconsistent (mismatched N dimensions or wrong axis sizes).

Example:

import numpy as np
import astra
N = 100
miss = np.random.randn(N, 3) * 0.5      # km
vrel = np.tile([7.0, 0.0, 0.0], (N, 1))  # km/s
cov_a = np.tile(np.eye(3) * 0.01, (N, 1, 1))  # km²
cov_b = np.tile(np.eye(3) * 0.01, (N, 1, 1))
times = np.linspace(2460000.5, 2460007.5, N)
pc_series = astra.compute_collision_probability_timeseries(
    miss, vrel, cov_a, cov_b, times
)
# pc_series is (100,) array of Pc values over 7 days