Source code for finesse.paths

"""Containers for paths traversed through a configuration."""

from .utilities.tables import Table
from .symbols import simplification
from finesse.utilities.misc import deprecation_warning


[docs]class OpticalPath: """Represents a path traversing through optical connections of a :class:`.Model` instance. The underlying data stored by instances of this class are lists of two-element tuples containing optical nodes and the components that they connect into. This list is formatted as `[(from_node, to_comp)]` where `from_node` is an :class:`.OpticalNode` instance and `to_comp` can be any sub-class instance of :class:`.Connector`; `from_node` is then an input node to `to_comp`. A handle to the underlying list can be obtained through accessing the property :attr:`OpticalPath.data`. This is not required for iterating through the path entries however, as this class provides iterator access itself. Parameters ---------- path : list A list of 2-tuples containing the path data; first element stores the :class:`.OpticalNode`, second element stores the component this node feeds into. symbolic : bool, optional Whether to compute symbolic lengths """
[docs] def __init__(self, path, symbolic=False): self.__path = path self.symbolic = symbolic
def __str__(self): return str(self.table())
[docs] def table(self): """Show the components of the path in a table.""" return Table( [("From optical node", "Into component")] + [(node.full_name, comp.name) for node, comp in self.__path], headerrow=True, headercolumn=False, )
def __iter__(self): return iter(self.__path) def __next__(self): return next(self.__path) @property def data(self): """A handle to the underlying path data. :getter: Returns the list of 2-tuples containing the path data. """ return self.__path @property def nodes(self): """The path data with only the :class:`.OpticalNode` sequence. :getter: Returns a list of the sequence of traversed optical nodes. """ return [pair[0] for pair in self.__path] @property def nodes_only(self): """The path data with only the :class:`.OpticalNode` sequence. :getter: Returns a list of the sequence of traversed optical nodes. """ deprecation_warning("Use .nodes instead of .nodes_only", "3.0") return self.nodes @property def components(self): """The path data with only the component sequence. :getter: Returns a list of the sequence of traversed components. """ return [pair[1] for pair in self.__path if pair[1] is not None] @property def components_only(self): """The path data with only the component sequence. :getter: Returns a list of the sequence of traversed components. """ deprecation_warning("Use .components instead of .components_only", "3.0") return self.components @property def spaces(self): """The spaces in the optical path. :getter: Yields the spaces in the optical path. """ from finesse.components import Space for _, to_comp in self.__path: if isinstance(to_comp, Space): yield to_comp @property def optical_length(self): """This returns the optical path length, i.e. the geometric length of each space scaled by its refractive index. :getter: Returns the total traversed length of the optical path (in metres). """ if self.symbolic: with simplification(allow_flagged=True): return sum([space.L.ref * space.nr.ref for space in self.spaces]) else: return sum([space.L * space.nr for space in self.spaces]) @property def physical_length(self): """This returns the physical path length. :getter: Returns the total length (in metres). """ if self.symbolic: with simplification(allow_flagged=True): return sum([space.L.ref for space in self.spaces]) else: return sum([space.L for space in self.spaces])