Per-Instrument Settings (InstrumentSettings)

Overview

InstrumentSettings is the frozen dataclass that carries per-instrument runtime parameters the orchestrator needs to navigate an observation. The companion function instrument_settings_from_obs() reads the per-camera inst_config mapping that an ObsInst populates from config_4N0_inst_*.yaml and returns a populated dataclass. Every per-instrument behavioural branch in NavOrchestrator ultimately reads off this dataclass.

Theory

Per-instrument configuration is split into two layers:

  • The static per-instrument YAML (config_400_inst_coiss.yaml, config_410_inst_gossi.yaml, config_420_inst_nhlorri.yaml, config_430_inst_vgiss.yaml) carries the slow-moving parameters: data unit convention, saturation DN, classifier thresholds, and camera rotation flags.

  • The per-image observation snapshot (ObsSnapshotInst) carries the fast-moving parameters: PSF sigma, midtime, extfov margin. These come from the per-image instrument spec rather than the YAML.

instrument_settings_from_obs() reads the slow-moving keys off the per-camera YAML block and returns a populated InstrumentSettings. The orchestrator calls it once per observation in _make_context and the result is consumed by:

  • NavImageClassifier (via the thresholds field).

  • The orchestrator’s saturation-mask construction (via saturation_dn / data_units).

  • The orchestrator’s pre-filter selection (per-instrument source_image_filter block).

  • The NavContext rotation flags (fit_camera_rotation, max_rotation_deg).

Restrictions and assumptions

  • The per-instrument YAML must declare the data_units field; missing values raise ValueError at config-load time so the failure surfaces during process startup.

  • Required numeric fields are coerced through a _required_float helper that rejects non-numeric, non-finite, or boolean values.

  • The marker-value field accepts the literal string "NaN" for calibrated-IF instruments where the missing-data sentinel is float NaN; numeric values are coerced through float.

  • The dataclass is frozen; new instances are returned per observation rather than mutated.

Sources of uncertainty

The dataclass carries no uncertainty.

Configuration

The per-instrument YAML schema consumed by instrument_settings_from_obs():

  • data_units — str, one of 'raw_dn' or 'calibrated_if'. raw_dn exposes pixels in raw counts; calibrated_if exposes pixels in calibrated I/F reflectance.

  • noise.saturation_dn — float, optional. Per-instrument full-well DN. Required for raw_dn instruments; None for calibrated_if (where saturation cannot be identified post-CALIB).

  • noise.marker_value — int / float / str. Missing-data sentinel value. For raw instruments typically 0; for calibrated-IF the literal "NaN" (or null) becomes float NaN.

  • image_quality_thresholds — block consumed by ImageQualityThresholds. See Image Classifier (NavImageClassifier) for the field-by-field schema.

  • camera_rotation.fit_camera_rotation — bool, default False. When True every technique adds in-plane camera rotation as a third parameter. Cassini ISS / NHLORRI default to False; VGISS / GOSSI default to True.

  • camera_rotation.max_rotation_deg — float, default 5.0 deg. Maximum allowed rotation magnitude when fit_camera_rotation is True.

Implementation

Source file: src/nav/nav_orchestrator/instrument_config.pyInstrumentSettings, instrument_settings_from_obs(), and the DataUnits Literal alias.

Public surface (autodocumented at nav.nav_orchestrator):

The module’s private helpers _coerce_marker_value and _required_float validate the YAML values; the public function is the only entry point external callers use.

Examples

Cassini ISS NAC. config_400_inst_coiss.yaml declares data_units: raw_dn, noise.saturation_dn: 4095.0, noise.marker_value: 0, camera_rotation.fit_camera_rotation: false, and camera_rotation.max_rotation_deg: 5.0. instrument_settings_from_obs() returns:

InstrumentSettings(
    data_units='raw_dn',
    saturation_dn=4095.0,
    marker_value=0.0,
    thresholds=ImageQualityThresholds(...),
    fit_camera_rotation=False,
    max_rotation_deg=5.0,
)

Voyager ISS. config_430_inst_vgiss.yaml declares camera_rotation.fit_camera_rotation: true and camera_rotation.max_rotation_deg: 10.0. The orchestrator’s per-image NavContext inherits fit_camera_rotation=True and every technique runs the 3-DoF path, so BodyLimbNav reports a 3x3 covariance on Voyager imagery.

Cassini ISS CALIB pipeline. When the operator runs the calibrated-IF pipeline, data_units: calibrated_if, noise.saturation_dn: null, and noise.marker_value: NaN. The orchestrator’s saturation-mask helper returns an empty mask (saturation cannot be identified post-CALIB), and the star navigation model gates catalog stars purely by magnitude against obs.star_max_usable_vmag(), so the calibrated-IF units carry no effect on the star detectability decision.