=============== Class Hierarchy =============== The following Mermaid diagram shows the complete class hierarchy of the RMS-NAV system: .. mermaid:: classDiagram direction RL class NavBase { +__init__(*, config=None, **kwargs) +logger +config } class DataSet { <> +__init__(*, config=None) +_img_name_valid(name)* +add_selection_arguments(parser, group)* +yield_image_files_from_arguments(args)* +yield_image_files_index(**kwargs)* +supported_grouping() +pds4_bundle_template_dir() +pds4_bundle_name() +pds4_bundle_path_for_image(name) +pds4_path_stub(image_file) +pds4_template_variables(...) +pds4_image_name_to_data_lid(name) +pds4_image_name_to_data_lidvid(name) +pds4_image_name_to_browse_lid(name) +pds4_image_name_to_browse_lidvid(name) } class DataSetPDS3 { +__init__(pds3_holdings_root=None, *, index_filecache=None, pds3_holdings_filecache=None, config=None) +_img_name_valid(name) +yield_image_files_index(**kwargs) } class DataSetPDS3CassiniISS { +__init__(*, config=None) +_img_name_valid(name) +pds4_bundle_template_dir() +pds4_bundle_name() +pds4_bundle_path_for_image(name) +pds4_path_stub(image_file) +pds4_template_variables(...) +pds4_image_name_to_data_lid(name) +pds4_image_name_to_data_lidvid(name) +pds4_image_name_to_browse_lid(name) +pds4_image_name_to_browse_lidvid(name) } class DataSetPDS3CassiniISSCruise { +__init__(*, config=None) +_img_name_valid(name) } class DataSetPDS3CassiniISSSaturn { +__init__(*, config=None) +_img_name_valid(name) } class DataSetPDS3VoyagerISS { +__init__(*, config=None) +_img_name_valid(name) } class DataSetPDS3GalileoSSI { +__init__(*, config=None) +_img_name_valid(name) } class DataSetPDS3NewHorizonsLORRI { +__init__(*, config=None) +_img_name_valid(name) } class DataSetSim { +__init__(*, config=None) +_img_name_valid(name) } class DataSetPDS4 { +__init__(*, config=None) +_img_name_valid(name) } class Obs { <> +__init__(*, config=None, **kwargs) } class ObsSnapshot { +__init__(snapshot, *, extfov_margin_vu=None, config=None, **kwargs) +inventory_body_in_fov(inv) +inventory_body_in_extfov(inv) +clip_rect_fov(u_min, u_max, v_min, v_max) +clip_rect_extfov(u_min, u_max, v_min, v_max) +bp +ext_bp +corner_bp +center_bp } class ObsInst { <> +from_file(path, *, config=None, extfov_margin_vu=None, **kwargs)* +star_min_usable_vmag()* +star_max_usable_vmag()* +get_public_metadata()* } class ObsSnapshotInst { <> +from_file(path, *, config=None, extfov_margin_vu=None, **kwargs)* } class ObsCassiniISS { +from_file(path, *, config=None, extfov_margin_vu=None) } class ObsVoyagerISS { +from_file(path, *, config=None, extfov_margin_vu=None) } class ObsGalileoSSI { +from_file(path, *, config=None, extfov_margin_vu=None) } class ObsNewHorizonsLORRI { +from_file(path, *, config=None, extfov_margin_vu=None) } class ObsSim { +from_file(path, *, config=None, extfov_margin_vu=None) } class NavMaster { +__init__(obs, *, nav_models=None, nav_techniques=None, config=None) +obs +models +compute_all_models() +navigate() +metadata_serializable() } class NavModel { <> +__init__(name, obs, *, config=None) +name +obs +models +metadata +create_model(always_create_model=False, never_create_model=False, create_annotations=True)* } class NavModelStars { +__init__(name, obs, *, config=None) +create_model(always_create_model=False, never_create_model=False, create_annotations=True) +star_list } class NavModelBodyBase { <> +__init__(name, obs, *, config=None) +create_model(always_create_model=False, never_create_model=False, create_annotations=True)* } class NavModelBody { +__init__(name, obs, *, config=None) +create_model(always_create_model=False, never_create_model=False, create_annotations=True) } class NavModelBodySimulated { +__init__(name, obs, *, config=None) +create_model(always_create_model=False, never_create_model=False, create_annotations=True) } class NavModelRingsBase { <> +__init__(name, obs, *, config=None) +create_model(always_create_model=False, never_create_model=False, create_annotations=True)* } class NavModelRings { +__init__(name, obs, *, config=None) +create_model(always_create_model=False, never_create_model=False, create_annotations=True) } class NavModelRingsSimulated { +__init__(name, obs, ring_name, sim_params, *, config=None) +create_model(always_create_model=False, never_create_model=False, create_annotations=True) } class RingFeatureType { <> GAP RINGLET } class RingBaseOrbitMode { <> +a: float +ae: float +long_peri: float +rate_peri: float +rms: float } class RingPerturbationMode { <> +mode_num: int +amplitude: float +phase: float +pattern_speed: float } class RingFeature { <> +key: str +name: str | None +feature_type: RingFeatureType +inner_edge: RingEdgeData | None +outer_edge: RingEdgeData | None +is_visible_at(obs_time_et) bool +is_in_radius_range(min_r, max_r) bool +uncertainty: float +all_base_radii() Sequence +from_config(key, data)$ RingFeature +render(context) list[RingRenderResult] } class RingEdgeData { <> +base_orbit: RingBaseOrbitMode +perturbations: tuple[RingPerturbationMode, ...] +base_radius: float +rms: float +radial_perturbations() tuple +parsed_modes_for_backplane() list } class RingFeatureFilter { +__init__(obs_time_et, min_radius, max_radius, ..., logger) +filter(features) list[RingFeature] } class RingsRenderContext { <> +obs +ring_target: str +epoch: float +resolutions: ndarray +fade_width_pix: float +all_edge_radii: tuple +logger } class RingRenderResult { +model_img: ndarray +model_mask: ndarray +uncertainty: float +edge_info_list: list } class NavModelTitan { +__init__(name, obs, *, config=None) +create_model(always_create_model=False, never_create_model=False, create_annotations=True) } class NavModelCombined { +__init__(name, obs, models, *, config=None) +create_model(always_create_model=False, never_create_model=False, create_annotations=True) } class NavTechnique { <> +__init__(nav_master, *, config=None) +nav_master +navigate()* +offset +uncertainty +confidence } class NavTechniqueCorrelateAll { +__init__(nav_master, *, config=None) +navigate() +combined_model() } class NavTechniqueManual { +__init__(nav_master, *, config=None) +navigate() +combined_model() } class NavTechniqueTitan { +__init__(nav_master, *, config=None) +navigate() } class Annotation { <> +__init__(*, config=None) +draw(image)* } class Annotations { +__init__(*, config=None) +annotations: List[Annotation] +add(annotation) +draw_all(image) } class AnnotationTextInfo { +__init__(text, position, *, config=None) +draw(image) } class Config { +__init__() +read_config(config_path=None, reread=False) +update_config(config_path, read_default=True) +category(name) } NavBase <|-- DataSet NavBase <|-- Obs NavBase <|-- NavMaster NavBase <|-- NavModel NavBase <|-- NavTechnique NavBase <|-- Annotation DataSet <|-- DataSetPDS3 DataSet <|-- DataSetSim DataSet <|-- DataSetPDS4 DataSetPDS3 <|-- DataSetPDS3CassiniISS DataSetPDS3 <|-- DataSetPDS3VoyagerISS DataSetPDS3 <|-- DataSetPDS3GalileoSSI DataSetPDS3 <|-- DataSetPDS3NewHorizonsLORRI DataSetPDS3CassiniISS <|-- DataSetPDS3CassiniISSCruise DataSetPDS3CassiniISS <|-- DataSetPDS3CassiniISSSaturn Obs <|-- ObsSnapshot ObsInst <|-- ObsSnapshotInst ObsSnapshot <|-- ObsSnapshotInst ObsSnapshotInst <|-- ObsCassiniISS ObsSnapshotInst <|-- ObsVoyagerISS ObsSnapshotInst <|-- ObsGalileoSSI ObsSnapshotInst <|-- ObsNewHorizonsLORRI ObsSnapshotInst <|-- ObsSim NavModel <|-- NavModelStars NavModel <|-- NavModelBodyBase NavModel <|-- NavModelRingsBase NavModel <|-- NavModelTitan NavModel <|-- NavModelCombined NavModelBodyBase <|-- NavModelBody NavModelBodyBase <|-- NavModelBodySimulated NavModelRingsBase <|-- NavModelRings NavModelRingsBase <|-- NavModelRingsSimulated RingFeature --> RingFeatureType : feature_type RingEdgeData *-- RingBaseOrbitMode : base_orbit RingEdgeData "1" o-- "0..*" RingPerturbationMode : perturbations NavModelRings --> RingFeature : retrieves & renders RingFeature --> RingEdgeData : inner_edge / outer_edge NavModelRings --> RingFeatureFilter : constructs RingFeature ..> RingFeatureFilter : filter pipeline RingFeature --> RingsRenderContext : render(context) RingFeature --> RingRenderResult : render() returns NavTechnique <|-- NavTechniqueCorrelateAll NavTechnique <|-- NavTechniqueManual NavTechnique <|-- NavTechniqueTitan Annotation <|-- AnnotationTextInfo Annotations --> Annotation Key Components ============== NavBase ------- :class:`~nav.support.nav_base.NavBase` is the base class for most components in the system. It provides access to configuration settings and a logger via the ``config`` and ``logger`` properties. All subclasses call ``super().__init__(config=...)`` to ensure the shared state is initialized. NavMaster --------- :class:`~nav.nav_master.nav_master.NavMaster` coordinates the navigation process. It initializes with a :class:`~oops.observation.snapshot.Snapshot`-backed observation and optional lists of navigation models and techniques (``nav_models`` and ``nav_techniques``). It computes models, applies techniques (for example, ``correlate_all`` and ``manual``), determines the prevailing offset based on confidence, and produces both a summary PNG image and JSON-serializable metadata via ``metadata_serializable()``. NavModel -------- :class:`~nav.nav_model.nav_model.NavModel` is the abstract base for synthetic model generators. Subclasses implement ``create_model(...)`` to populate arrays and annotations. Public properties include the model name and snapshot (``name``, ``obs``), arrays (``model_img``, ``model_mask``, ``range``), optional quality measures (``uncertainty``, ``blur_amount``, ``confidence``), optional packed ``stretch_regions`` for per-region contrast, and ``annotations``. Implementations include complete classes for stars, bodies (including a simulated variant), rings (including a base class with shared functionality and subclasses for real and simulated rings), and Titan, plus a combined model used to merge the nearest visible model at each pixel. :doc:`developer_guide_navigation_models` covers each navigation model family. NavTechnique ------------ :class:`~nav.nav_technique.nav_technique.NavTechnique` is the abstract base for navigation algorithms that estimate offsets from models and the observation. Techniques are selected by name and record technique-specific metadata. Current implementations include ``correlate_all`` (automated correlation), ``manual`` (interactive GUI), and ``titan`` (not yet implemented). Dataset ------- :class:`~nav.dataset.dataset.DataSet` handles access to image files and metadata. It defines ``_img_name_valid(...)``, ``add_selection_arguments(...)``, ``yield_image_files_from_arguments(...)``, and ``yield_image_files_index(...)`` for dataset-specific selection and iteration. For PDS4 bundle generation, it defines non-abstract stubs (each raising ``NotImplementedError``) that subclasses may override: ``pds4_bundle_template_dir()``, ``pds4_bundle_name()``, ``pds4_bundle_path_for_image()``, ``pds4_path_stub()``, ``pds4_template_variables()``, and the four LID/LIDVID converters (``pds4_image_name_to_{data,browse}_{lid,lidvid}()``). Datasets that do not yet support PDS4 bundle generation leave these as the default stubs. :class:`~nav.dataset.dataset_pds3.DataSetPDS3` provides volume and index-based iteration for archives, while instrument-specific subclasses tailor parsing and volume sets. Instrument-specific dataset classes include :class:`~nav.dataset.dataset_pds3_cassini_iss.DataSetPDS3CassiniISS` (base class for all Cassini ISS volumes), :class:`~nav.dataset.dataset_pds3_cassini_iss.DataSetPDS3CassiniISSCruise` (volumes 1001-1009), :class:`~nav.dataset.dataset_pds3_cassini_iss.DataSetPDS3CassiniISSSaturn` (volumes 2001-2116), :class:`~nav.dataset.dataset_pds3_voyager_iss.DataSetPDS3VoyagerISS`, :class:`~nav.dataset.dataset_pds3_galileo_ssi.DataSetPDS3GalileoSSI`, :class:`~nav.dataset.dataset_pds3_newhorizons_lorri.DataSetPDS3NewHorizonsLORRI`, and :class:`~nav.dataset.dataset_sim.DataSetSim` (for simulated images). Dataset name mapping is defined in ``nav.dataset.__init__`` (``coiss``, ``coiss_cruise``, ``coiss_saturn``, ``gossi``, ``nhlorri``, ``vgiss``, their ``*_pds3`` aliases, and ``sim``). Cassini ISS adds ``--camera`` (NAC or WAC) and supports a ``botsim`` grouping that pairs NAC/WAC images when available. Obs and ObsSnapshot ------------------- :class:`~nav.obs.obs.Obs` is the abstract base class for observations. :class:`~nav.obs.obs_snapshot.ObsSnapshot` extends it with backplane handling and accessors, while :class:`~nav.obs.obs_inst.ObsInst` defines the instrument-specific contract with a ``from_file(...)`` constructor and metadata helpers. Instrument snapshots extend :class:`~nav.obs.obs_snapshot_inst.ObsSnapshotInst` and must accept ``config`` and ``extfov_margin_vu`` keyword arguments. Instrument classes include :class:`~nav.obs.obs_inst_cassini_iss.ObsCassiniISS`, :class:`~nav.obs.obs_inst_voyager_iss.ObsVoyagerISS`, :class:`~nav.obs.obs_inst_galileo_ssi.ObsGalileoSSI`, :class:`~nav.obs.obs_inst_newhorizons_lorri.ObsNewHorizonsLORRI`, and :class:`~nav.obs.obs_inst_sim.ObsSim` (for simulated images). Annotation ---------- The annotation subsystem composes labels and graphical elements into an overlay used by the final PNG. :class:`~nav.annotation.annotations.Annotations` aggregates model-provided annotations and renders them with appropriate coloring and contrast stretching, optionally using per-region stretching via ``stretch_regions``.