Source code for spindoctor.nav_model.nav_model_titan

"""Titan NavModel -- records a no-result for Titan's opaque haze.

Titan needs a different algorithm than ellipsoid-limb fitting: its visible
"limb" is the haze top, varies with wavelength, and the surface inside is
invisible.  At high phase Titan is not even a circle, so disc / limb /
terminator navigation is systematically wrong rather than merely noisy.

Titan is handled as a deliberate special case: its atmosphere is unique
(transparent at some wavelengths), so its handling does not generalize to
other thick-atmosphere bodies such as Venus.  This model is built and active
whenever Titan is in the field of view (the shape-based ``NavModelBody``
skips Titan).  It emits no features, so no technique navigates it; instead
it records, per image, *why* a Titan scene cannot be navigated.  The
orchestrator reads the marker it exposes and fails such a frame with
:attr:`~spindoctor.support.status_reason.NavStatusReason.TITAN_UNSUPPORTED`
rather than a silent empty failure.
"""

from __future__ import annotations

from typing import TYPE_CHECKING

from oops import Observation

from spindoctor.annotation import Annotations
from spindoctor.config import DEFAULT_CONFIG, Config
from spindoctor.feature.feature import NavFeature
from spindoctor.nav_model.nav_model import NavModel
from spindoctor.nav_model.nav_model_body import TITAN_BODY_NAME, bodies_in_extfov

if TYPE_CHECKING:  # pragma: no cover - typing-only import
    from spindoctor.nav_orchestrator.nav_context import NavContext

__all__ = ['NavModelTitan']