Commit 05e5aa77 authored by Sean Leavey's avatar Sean Leavey

Merge branch 'master' into reoptimise

parents f6ee0877 7e3dcfbf
......@@ -7,7 +7,7 @@ import logging
import numpy as np
from finesse.components import Cavity
from finesse.components import Cavity, Space
from finesse.components.general import Connector
from finesse.components.node import Port, OpticalNode
from finesse.element import evaluate, Symbol
......@@ -184,6 +184,11 @@ class PropagationSolution(BaseSolution):
)
return list(space_entries.keys())
@property
def components(self):
"""A list of all components traversed, in order."""
return list(filter(lambda x: not isinstance(x, Space), self.comp_info.keys()))
@property
def path_length(self):
"""The optical path length of the traversed path."""
......@@ -356,6 +361,92 @@ class PropagationSolution(BaseSolution):
raise TypeError(f"Invalid type for key: {key}")
def compute_distances_matrix(self, subs=None):
"""Compute the distances between each optic, relative to each other.
Returns a dict of dicts for each "delta z".
Use :meth:`PropagationSolution.print_distances_matrix` to print a tabulated
string representation of this dict.
Parameters
----------
subs : dict, optional
A dictionary of model parameter to value substitutions
to pass to the ``eval`` methods of symbolic expressions.
If this solution object is not symbolic then this argument
is ignored.
Returns
-------
deltas : dict
Dict of dicts for each dz between components.
"""
if not self.symbolic and subs is not None:
LOGGER.warning(
"Ignoring subs=%s kwarg as PropagationSolution is non-symbolic.", subs,
)
deltas = {}
outer_done = set()
for node1, info1 in self.node_info.items():
comp1 = node1.component
if comp1 in outer_done:
continue
inner_done = set()
deltas[comp1] = {}
for node2, info2 in self.node_info.items():
comp2 = node2.component
if comp2 in inner_done:
continue
z2 = self.__eval_z_for_display(info2, subs=subs)
z1 = self.__eval_z_for_display(info1, subs=subs)
deltas[comp1][comp2] = z2 - z1
inner_done.add(comp2)
outer_done.add(comp1)
return deltas
def print_distances_matrix(self, scale=1, tablefmt="fancy_grid", subs=None):
"""Print the distances between each optic, relative to each other, in a table.
Note that all distances are in metres by default. You can apply a scaling factor,
via the `scale` argument, to all values to change the units accordingly.
Parameters
----------
scale : float, optional
Scaling factor to apply to distances. Defaults to unity such
that all distances are in metres.
tablefmt : str, optional; default: "fancy_grid"
The plain-text table format to pass to tabulate.
subs : dict, optional
A dictionary of model parameter to value substitutions
to pass to the ``eval`` methods of symbolic expressions.
If this solution object is not symbolic then this argument
is ignored.
"""
from tabulate import tabulate
deltas = self.compute_distances_matrix(subs=subs)
table = []
headers = [comp.name for comp in self.components]
for comp1 in deltas:
entry = [comp1.name]
for dz in deltas[comp1].values():
entry.append(scale * dz)
table.append(entry)
print(tabulate(table, headers, tablefmt=tablefmt))
def make_table(self, tablefmt="fancy_grid", subs=None):
"""Construct a table showing the beam properties at each node.
......
......@@ -405,7 +405,7 @@ cdef tuple propagate_beam_numeric(
info_at_space["acc_gouy"] = degrees(gouy(q2) - gouy(q1))
distance += space.L.value / space.nr.value
distance += space.L.value
info_at_space["q_out"] = q
else:
......@@ -465,7 +465,7 @@ cdef tuple propagate_beam_symbolic(
info_at_space["acc_gouy"] = np.degrees(q2.gouy() - q1.gouy())
distance += space.L.ref / space.nr.ref
distance += space.L.ref
info_at_space["q_out"] = q
else:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment