Class Hierarchy
The autonomous-navigation pipeline is built around four cooperating groups of classes — observation snapshots, predicted-scene models, per-feature techniques, and the orchestrator that runs them. The following Mermaid diagram captures the principal relationships; the narrative below the diagram describes each group in turn.
classDiagram
direction RL
class NavBase {
+__init__(*, config=None, **kwargs)
+config: Config
+logger: PdsLogger
}
class DataSet {
<<abstract>>
+_img_name_valid(name)*
+yield_image_files_from_arguments(args)*
+yield_image_files_index(**kwargs)*
}
class Obs {
<<abstract>>
}
class ObsSnapshot {
+backplane(...)
+ra_dec_limits_ext()
+extfov_data_sensor_mask()
}
class ObsSnapshotInst {
<<abstract>>
+from_file(path, *, config=None, extfov_margin_vu=None)*
}
class NavModel {
<<abstract>>
+__init__(name, obs, *, config=None)
+name
+obs
+metadata
+create_model()*
+to_features(context)* list[NavFeature]
+to_annotations(context)* Annotations
+instances_for_obs(obs)$ list[NavModel]
}
class NavModelStars {
+create_model()
+to_features(context)
+to_annotations(context)
}
class NavModelBodyBase {
<<abstract>>
+_render_silhouette(...)
+_create_edge_annotations(...)
}
class NavModelBody {
+create_model()
+to_features(context)
+to_annotations(context)
}
class NavModelBodySimulated {
+create_model()
+to_features(context)
+to_annotations(context)
}
class NavModelRingsBase {
<<abstract>>
+_create_edge_annotations(...)
}
class NavModelRings {
+create_model()
+to_features(context)
+to_annotations(context)
}
class NavModelRingsSimulated {
+create_model()
+to_features(context)
+to_annotations(context)
}
class NavModelTitan {
+create_model()
+to_features(context)
+to_annotations(context)
}
class NavTechnique {
<<abstract>>
+name
+accepts_feature_types
+requires_prior
+is_feasible(features)* NavFeasibilityReport
+navigate(features, context)* NavTechniqueResult
}
class StarUniqueMatchNav
class StarFieldFromCatalogNav
class StarRefineNav
class BodyLimbNav
class BodyTerminatorNav
class BodyDiscCorrelateNav
class BodyBlobNav
class RingEdgeNav
class RingAnnulusNav
class NavTechniqueManual
class NavOrchestrator {
+__init__(models, *, config=None, only_models='*', only_techniques='*')
+navigate(obs) NavResult
}
class NavFeature {
<<frozen dataclass>>
+feature_id: str
+feature_type: NavFeatureType
+geometry: NavFeatureGeometry
+position_cov_px
+preferred_filter: NavFilterSpec
+reliability: float
+flags: NavFeatureFlags
}
class NavTechniqueResult {
<<frozen dataclass>>
+technique_name
+feature_ids
+offset_px
+covariance_px2
+confidence
+spurious / at_edge
+diagnostics: NavTechniqueDiagnostics
}
class NavResult {
<<frozen dataclass>>
+status
+status_reason
+offset_px / sigma_px
+covariance_px2
+confidence / confidence_rank
+rotation_rad / sigma_rotation_rad
+per_technique
+feature_inventory
+image_classifier
+model_metadata
+annotations
+provenance
}
class NavContext {
<<frozen dataclass>>
+obs
+image_ext
+sensor_mask_ext
+image_noise_sigma
+saturation_mask_ext
+cosmic_ray_mask_ext
+image_classifier
+image_gradient_ext
+image_gradient_vu_ext
+image_edge_dt_ext
+prior_offset_px
+prior_covariance_px2
+fit_camera_rotation
+provenance
}
class FeatureReliabilityGate {
+thresholds: dict[NavFeatureType, float]
+apply(features) tuple[list, list]
}
class InstrumentSettings {
<<frozen dataclass>>
+data_units
+saturation_dn
+marker_value
+thresholds: ImageQualityThresholds
+fit_camera_rotation
+max_rotation_deg
}
class NavImageClassifier {
+classify(image, *, settings) NavImageClassifierResult
}
class Annotations {
+add_annotations(other)
+combine(offset_px) NDArray
}
class Annotation {
<<abstract>>
+color
+avoid_mask
+draw(image)*
}
NavBase <|-- DataSet
NavBase <|-- Obs
NavBase <|-- NavModel
NavBase <|-- NavTechnique
NavBase <|-- NavOrchestrator
Obs <|-- ObsSnapshot
ObsSnapshot <|-- ObsSnapshotInst
NavModel <|-- NavModelStars
NavModel <|-- NavModelBodyBase
NavModel <|-- NavModelRingsBase
NavModel <|-- NavModelTitan
NavModelBodyBase <|-- NavModelBody
NavModelBodyBase <|-- NavModelBodySimulated
NavModelRingsBase <|-- NavModelRings
NavModelRingsBase <|-- NavModelRingsSimulated
NavTechnique <|-- StarUniqueMatchNav
NavTechnique <|-- StarFieldFromCatalogNav
NavTechnique <|-- StarRefineNav
NavTechnique <|-- BodyLimbNav
NavTechnique <|-- BodyTerminatorNav
NavTechnique <|-- BodyDiscCorrelateNav
NavTechnique <|-- BodyBlobNav
NavTechnique <|-- RingEdgeNav
NavTechnique <|-- RingAnnulusNav
NavTechnique <|-- NavTechniqueManual
NavOrchestrator --> NavModel : iterates
NavOrchestrator --> NavTechnique : iterates registry
NavOrchestrator --> NavContext : builds
NavOrchestrator --> NavResult : produces
NavOrchestrator o-- FeatureReliabilityGate : owns
NavOrchestrator o-- InstrumentSettings : reads
NavOrchestrator o-- NavImageClassifier : runs
NavOrchestrator o-- Annotations : merges
NavModel ..> NavFeature : emits
NavModel ..> Annotations : emits
NavTechnique ..> NavFeature : consumes
NavTechnique ..> NavTechniqueResult : produces
NavResult --> NavTechniqueResult : per_technique
NavResult --> Annotations : annotations
Annotations o-- Annotation : aggregates
Top-level driver
NavOrchestrator is the
top-level driver. Given a list of pre-built
NavModel instances and an
ObsSnapshot, the orchestrator runs the
full two-pass navigation pipeline: it builds a
NavContext, calls each
model’s create_model, gathers
NavFeature instances via to_features,
gates them by reliability, runs every feasible
NavTechnique, and reconciles
the per-technique results through
ensemble(). The output is a single
NavResult.
Glob-pattern filters at construction time
(only_models='body:MIMAS',
only_techniques='!StarFieldFromCatalogNav') restrict which models or
techniques run, supporting debugging and per-image study without
modifying registry contents. See
Selecting models and techniques in the user guide for the full
pattern syntax (globs, ! exclusion, prefix-only shorthand) and the
list of shipping model and technique names.
FeatureReliabilityGate
FeatureReliabilityGate is the gate the
orchestrator runs between feature extraction and technique invocation.
It carries a per-NavFeatureType
threshold mapping (defaulted from
DEFAULT_RELIABILITY_THRESHOLDS) and
exposes a single
apply() method that
splits an extracted feature list into (kept, gated): features whose
self-assessed
reliability falls below the
per-type threshold are emitted as
GatedFeatureRecord instances carrying a
stable reason string; everything else passes through unmodified.
Per-instance threshold overrides come from the configuration loader (the
features block in config_510_techniques.yaml and any per-instrument
override under config_4N0_inst_*.yaml). Threshold values are validated
on construction: they must be finite floats in \([0, 1]\) and keyed
by NavFeatureType enum members. The
gate is stateless — the same instance can be reused across images — and
deterministic given its thresholds.
Dataset, Obs, and ObsSnapshot
DataSet handles access to image files and
metadata; per-mission subclasses
(DataSetPDS3CassiniISS, DataSetPDS3VoyagerISS,
DataSetPDS3GalileoSSI, DataSetPDS3NewHorizonsLORRI,
DataSetSim) implement archive-specific iteration and PDS4 bundle
hooks.
Obs is the abstract observation base.
ObsSnapshot adds backplane handling and
extended-FOV accessors; per-instrument subclasses derive from
ObsSnapshotInst and implement the
from_file(path, ...) constructor. See
Observations for the per-mission subclass list, the
public API surface, and the new-instrument checklist.
Annotation
The nav.annotation subsystem composes labels and graphical
elements into an overlay used by the summary PNG.
Annotations aggregates
model-provided annotations and renders them with appropriate coloring
and contrast stretching. Each
to_annotations() returns a fresh
Annotations collection; the
orchestrator merges them into
annotations via
add_annotations(). See
Annotations for the per-class API, the per-NavModel
contributions, and the source-of-configuration map.