Source code for vane.plugins

# SPDX-License-Identifier: Apache-2.0
# Copyright (c) 2026 Jae Hoon Seo, SMI Lab, Inha University
"""Extension protocols for VANE's pluggable analysis stages.

VANE's two model-dependent stages, cross-operating-point **tracking** and physical
**labelling**, are each defined here as a :class:`typing.Protocol`, so an alternative
implementation can be used wherever the built-in is used, without subclassing
anything. These are *static* (type-checker) contracts; the consumers accept the
protocol type, so a static type checker verifies that a custom implementation fits.

``Tracker`` and ``Labeler`` are callable-only protocols and are deliberately **not**
``runtime_checkable``: an ``isinstance`` check against a callable Protocol only confirms
that the object is callable (not its signature or return type), so it would accept a
non-tracker and fail later. Use static typing, or simply the injection points, for
them.

The built-ins satisfy these contracts structurally:

* :func:`vane.modal.identify_modes` is a :class:`Tracker`;
* :func:`vane.modal.label_solution` is a :class:`Labeler`.

The consumers accept the protocol type, not the concrete class:
:class:`vane.ModalPipeline` takes an optional ``tracker``. An LTP/Floquet tracker or
an alternative rule-based labeller can therefore be used without changing the
pipeline.
"""

from __future__ import annotations

from typing import TYPE_CHECKING, Protocol

if TYPE_CHECKING:
    from collections.abc import Sequence

    from vane.modal.eigensolver import ModalSolution
    from vane.modal.identifier import IdentificationResult
    from vane.modal.labeler import ModeLabel

__all__ = ["Labeler", "Tracker"]


[docs] class Labeler(Protocol): """Assign a physical label to every mode of a solution. Any callable taking a :class:`~vane.modal.ModalSolution` and returning one :class:`~vane.modal.ModeLabel` per mode (in mode order) is a labeler. :func:`vane.modal.label_solution` is the built-in. A static (callable) contract: not ``runtime_checkable`` (see the module docstring). """ def __call__(self, solution: ModalSolution) -> list[ModeLabel]: """Return one label per mode of ``solution``, in mode order.""" ...
[docs] class Tracker(Protocol): """Link modes across operating points into labeled tracks. Any callable taking the per-operating-point solutions (with the optional sweep axis) and returning an :class:`~vane.modal.IdentificationResult` is a tracker. :func:`vane.modal.identify_modes` is the built-in; a Floquet/LTP tracker conforms by presenting the same call. A static (callable) contract: not ``runtime_checkable`` (see the module docstring). """ def __call__( self, solutions: Sequence[ModalSolution], *, parameter_values: Sequence[float] | None = None, ) -> IdentificationResult: """Return the cross-operating-point tracks for ``solutions``.""" ...