test_spiceInterfaceReconstruction

Unit tests for the opt-in SPICE query reconstruction feature of C++ Module: spiceInterface.

These cover the invariants that the feature promises:

  • Bit-for-bit default preservation – with nothing configured, the planet-state output is byte-identical to the exact per-call SPICE path.

  • Reconstruction accuracy – a Hermite-interpolated planet tracks the exact SPICE position to a small tolerance while querying SPICE far fewer times.

  • Query-count savingsgetPlanetSpiceQueryCount reflects ~horizon/knotStep queries, not once per task step.

  • Single-knot orientation extrapolation is exact for a constant spinner (Earth’s IAU frame).

  • Channels are independent and toggle-off-able – a disabled channel emits the trivial default (zero position/velocity or identity orientation) without querying SPICE.

  • Derivative self-consistency – the emitted VelocityVector matches a finite difference of the reconstructed position.

test_spiceInterfaceReconstruction.test_defaultsAreBitIdentical()[source]

With nothing configured, every planet field must be byte-identical to the exact path. (Configuring one planet must not perturb the others, nor the default output of any field.)

test_spiceInterfaceReconstruction.test_disabledChannelsEmitTrivialDefault()[source]

A disabled position channel emits zero pos/vel; a disabled orientation channel emits the identity DCM and zero rate – and neither queries SPICE.

test_spiceInterfaceReconstruction.test_enablingReconstructionAfterResetAnchorsAtEpoch()[source]

Enabling reconstruction for the FIRST time between two ExecuteSimulation() segments (so the reconstruction object is created after Reset already set the epoch) must anchor knots at the init epoch, not J2000 ET 0. Otherwise the knot grid would query the wrong epoch and the state would be wildly wrong. Regression for the deferred-creation et0 anchoring.

test_spiceInterfaceReconstruction.test_exactSpiceResetRestoresDefault()[source]

setPlanetExactSpice reverts both channels; output returns to the exact path bit-for-bit.

test_spiceInterfaceReconstruction.test_integratorAgnosticQueryCountOnDynamicsTask()[source]

On an MJScene dynamics task the module’s UpdateState is called once per integrator STAGE, so the exact path would query SPICE (stages x steps) times. With reconstruction the knot cache collapses those onto ~horizon/knotStep queries, and that count is the SAME for a fixed RK4 and an adaptive RKF45 integrator – the integrator-agnostic property the feature exists to deliver.

test_spiceInterfaceReconstruction.test_misconfiguredPlanetWarnsNotThrows()[source]

A reconstruction config for a planet that was never added (or has no orientation frame) must WARN and keep running, not throw BasiliskError and abort the sim. The stale entry is pruned, so its query count reports unconfigured afterwards.

test_spiceInterfaceReconstruction.test_oddKnotStencilIsCentered()[source]

A 3-knot interpolation stencil is centred on the current interval ([k-1, k, k+1]); a forward-biased [k, k+1, k+2] stencil would be less accurate. Guards buildStencil’s centering: 3-knot reconstruction must be at least as accurate as 2-knot on the same coarse grid.

test_spiceInterfaceReconstruction.test_positionReconstructionAccurateAndCheaper()[source]

Hermite position reconstruction on a coarse grid tracks exact SPICE to well under a metre over a short horizon, at far fewer SPICE queries than one-per-step.

test_spiceInterfaceReconstruction.test_queryCountTracksExactPathWithNoReconstruction()[source]

getPlanetSpiceQueryCount reports SPICE calls even when NO reconstruction is configured: a plain exact-path planet queries both channels once per update, so the counts equal the number of updates. An added-but-never-queried name reads {0, 0}; a name never added reads {-1, -1}.

test_spiceInterfaceReconstruction.test_reconfiguringKnotStepClearsStaleCache()[source]

Reconfiguring a channel’s knotStep must drop the cached knots: they are keyed by integer index on the OLD grid, so reusing them would map indices to the wrong epochs. Reconfigure the grid mid-life (after one run has populated knots) and confirm a second run still tracks exact SPICE, i.e. it re-queried on the new grid rather than reusing the old samples.

test_spiceInterfaceReconstruction.test_singleKnotDefaultsAreExactRegardlessOfInterpolateFlag()[source]

A single-knot stencil (nKnots=1) is the enclosing knot for BOTH interpolate settings, so orientation reconstruction of a constant spinner is exact even with the enabled default interpolate=True (regression: a naive 1-knot formula would pick the future knot k+1).

test_spiceInterfaceReconstruction.test_singleKnotOrientationExtrapolationExactForConstantSpinner()[source]

Earth’s IAU frame is a constant-rate spinner, so extrapolating orientation from a SINGLE knot (nKnots=1, interpolate=False) reproduces the exact per-call sxform orientation, using only one sxform query for the whole run.

test_spiceInterfaceReconstruction.test_velocityIsDerivativeOfReconstructedPosition()[source]

The emitted VelocityVector must equal the time derivative of the reconstructed position, so a downstream Euler step stays self-consistent. Sampled from a single run’s recorder (a fine task cadence) and finite-differenced with the actual logging step.