Skip to content

Outputs & Reporting

Each simulation run produces a suite of JSON, parquet, CSV, and PNG artefacts summarising the generated measurements, filter results, and diagnostics. The files live under the directory passed via --run-dir (e.g., outputs/lunar_static/), with one subdirectory per pipeline stage.

Simulation stage outputs (simulate/)

File Contents
measurements.json Full measurement catalogue (epoch, satellite ID, range/range-rate values, \(C/N_0\), noise sigmas, user/satellite clock realisations, SISE contributions/variances, visibility flag, azimuth/elevation, satellite & receiver state vectors).
measurement_summary.csv Measurement quality stats per observable and satellite (counts, value mean/std/min/max, noise std summaries, C/N₀, elevation span) computed after outlier rejection.
dop_timeseries.csv GDOP/PDOP/HDOP/VDOP and satellite counts per epoch, filtered with the same outlier mask.

Figures

src/reporting.py renders several diagnostic plots (all saved under simulate/plots/):

  • dop_vs_time.png – DOP metrics vs epoch.
  • signal_to_noise_vs_time.png – Received C/N₀ per satellite across the observation window.
  • cn0_vs_elevation.png – Scatter plot coloured by satellite ID (outliers removed).
  • measurement_counts.png – Grouped bar chart showing measurement counts per type and satellite.
  • satellite_polar.png – Sky plot of satellite azimuth/elevation coloured by satellite ID.
  • two_way_link_schedule.png – Timeline showing which satellite carries the two-way link at each epoch (coloured by \(C/N_0\) when available) with shaded windows marking periods when two-way contacts are authorised.
  • sise_position_three_sigma.png – 3σ SISE position per satellite.
  • sise_velocity_three_sigma.png – 3σ SISE velocity per satellite.
  • sat_clock_bias_error.png – Satellite clock bias residuals per navigation message.

In addition, ingest/plots/ contains 3D and XY orbit views, and estimate/plots/ contains residual and error plots described below.

Estimation stage outputs (estimate/)

By default, all estimation artefacts are written to <run-dir>/estimate/. Supplying --output-subdir <name> stores them in <run-dir>/estimate/<name>/ (or under the sibling estimate directory next to an overridden --measurements-path), which keeps multiple filter runs organised.

File Contents
ekf_states.parquet Full EKF state history (position, velocity, clock bias/drift).
ekf_states_downsampled.parquet / .csv Down-sampled state history for quick inspection.
ekf_residuals.parquet / .csv Measurement residual log (range and range-rate), written after MAD-based outlier rejection.
ekf_covariances.parquet Full covariance matrices for each processed epoch.
ekf_covariances_downsampled.csv Down-sampled covariance diagonals.
ekf_covariance_diag.csv Final covariance diagonal (single row snapshot).
state_errors.csv Truth-relative position/clock errors per epoch (outliers removed).
state_error_stats.csv RMS and percentile statistics computed from the cleaned error set.
residual_rms_vs_time.csv RMS of residuals per epoch, aligned with GDOP values.

Key plots (found in estimate/plots/) include residuals vs elevation, residual histograms, error CDFs, the position-error timeline (3D radial error vs. hours with 1σ/3σ envelopes and satellite count), 3D satellite paths, and the residual/GDOP timeline. Each plot is generated from the outlier-filtered datasets.

Log file

Each stage writes a structured log (<stage>.log) under its run directory. These logs capture inputs, applied outlier masks, warnings (e.g., low C/N₀), and paths to generated artefacts. Adjust verbosity with the CLI --log-level flag; selecting TRACE prints representative range and range-rate observations with every error contribution (geometry, user clock, SISE, calibration bias, and DLL/FLL noise) to aid debugging.

Processing assumption snapshot

Every CLI invocation now (re)generates <run-dir>/processing_assumptions.md (e.g., outputs/lunar_static/processing_assumptions.md) straight from the scenario YAML. The summary mirrors the config in prose/bullets so non-technical stakeholders can skim the time span, frames, SPICE kernels, receiver geometry, RF settings, and EKF tunings without reading raw YAML. After each stage finishes, the prompt prints the absolute path to this summary so downstream users immediately know where to look.

Extending the reports

Reporting utilities live in src/reporting.py. To add custom artefacts:

  1. Extend generate_simulation_outputs() or generate_estimation_outputs() with new exports/plots.
  2. Leverage the measurement/residual/state DataFrames returned by the pipeline stages.
  3. Consider whether the new diagnostic should apply the existing MAD-based outlier filter before rendering.

Refer to the source code for examples of writing CSV/JSON/parquet files and creating Matplotlib figures.