Source code for optiland.nonsequential.components.registry
"""ComponentRegistry for Non-Sequential Raytracing.
Maps compound component names to CompoundComponent objects and exposes a
flat surface list for the tracer.
Kramer Harrison, 2026
"""
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from optiland.nonsequential.components.base import BaseComponent
from optiland.nonsequential.components.compound import CompoundComponent
[docs]
class ComponentRegistry:
"""Named registry of compound components.
Stores :class:`~optiland.nonsequential.components.compound.CompoundComponent`
objects keyed by name and provides the tracer with a flat list of
:class:`~optiland.nonsequential.components.base.BaseComponent` surfaces.
Attributes:
_registry: Ordered dict mapping name -> CompoundComponent.
"""
def __init__(self) -> None:
"""Initialize an empty ComponentRegistry."""
self._registry: dict[str, CompoundComponent] = {}
[docs]
def add(self, name: str, component: CompoundComponent) -> None:
"""Add a compound component under the given name.
Args:
name: Unique identifier for the component.
component: The compound component to register.
Raises:
KeyError: If a component with ``name`` already exists.
"""
if name in self._registry:
raise KeyError(f"Component '{name}' is already registered.")
self._registry[name] = component
[docs]
def remove(self, name: str) -> None:
"""Remove a component by name.
Args:
name: Name of the component to remove.
Raises:
KeyError: If no component with ``name`` exists.
"""
if name not in self._registry:
raise KeyError(f"Component '{name}' not found.")
del self._registry[name]
[docs]
def get(self, name: str) -> CompoundComponent:
"""Retrieve a compound component by name.
Args:
name: Name of the component.
Returns:
The registered compound component.
Raises:
KeyError: If no component with ``name`` exists.
"""
if name not in self._registry:
raise KeyError(f"Component '{name}' not found.")
return self._registry[name]
def __contains__(self, name: str) -> bool:
"""Check whether a component name is registered."""
return name in self._registry
@property
def surfaces(self) -> list[BaseComponent]:
"""Flat list of all sub-surfaces in registration order.
Returns:
Concatenated list of sub-surfaces from all compound components.
"""
return [s for c in self._registry.values() for s in c.surfaces]
@property
def compounds(self) -> list[CompoundComponent]:
"""Ordered list of all registered compound components.
Returns:
List of compound components in registration order.
"""
return list(self._registry.values())