105 lines
3.1 KiB
Python
105 lines
3.1 KiB
Python
from typing import Any
|
|
|
|
from finesse.model import Model, Port, SeriesSolution, DegreeOfFreedom
|
|
from finesse.components import SignalGenerator
|
|
from finesse.detectors import PowerDetectorDemod1
|
|
from finesse.analysis.actions.axes import Xaxis, Noxaxis
|
|
|
|
from numpy.typing import NDArray
|
|
from numpy import float64
|
|
|
|
|
|
def typingfix_seriessolution(
|
|
solution: None | SeriesSolution | tuple[Any],
|
|
) -> SeriesSolution:
|
|
if solution is None:
|
|
raise ValueError("Result of the simulation is None")
|
|
if isinstance(solution, tuple):
|
|
raise ValueError("Result is not in the expected format")
|
|
return solution
|
|
|
|
|
|
def fix_dark_fringe(model: Model, power: float) -> tuple[int, float]:
|
|
solution: SeriesSolution = typingfix_seriessolution(
|
|
model.run(Noxaxis())
|
|
)
|
|
if "B1_DC" not in solution.outputs:
|
|
raise Exception("Model does not contain B1 readout")
|
|
|
|
if type(model.get("DARM")) is DegreeOfFreedom:
|
|
result = solution["B1_DC"]
|
|
start, stop, nb = 0, 1, 0
|
|
while (abs(result - power) > 1e-6) and (nb < 500):
|
|
nb += 1
|
|
temp = start + (stop - start) / 2
|
|
|
|
model.get("DARM").DC = temp
|
|
solution: SeriesSolution = typingfix_seriessolution(
|
|
model.run(Noxaxis())
|
|
)
|
|
if "B1_DC" not in solution.outputs:
|
|
raise Exception("Model do not contains B1 readout")
|
|
result = solution["B1_DC"]
|
|
if result > power:
|
|
stop = temp
|
|
else:
|
|
start = temp
|
|
return nb, solution["B1_DC"]
|
|
raise Exception("DARM is not a degree of freedom in the model")
|
|
|
|
|
|
def compute_TF(
|
|
model: Model,
|
|
frequencies: NDArray[float64],
|
|
inputs: list[Port | str],
|
|
) -> SeriesSolution:
|
|
model.fsig.f = 1 # pyright: ignore[reportAttributeAccessIssue]
|
|
|
|
for input in inputs:
|
|
model.add(SignalGenerator("sig1", model.get(input), 1, 0))
|
|
model.add(
|
|
PowerDetectorDemod1(
|
|
"TF", model.get("SDB1").p2.o, f=model.get("fsig").f
|
|
)
|
|
)
|
|
model.get("TF").select_mask(exclude=(0, 0))
|
|
return model.run(
|
|
Xaxis(
|
|
model.fsig.f, # pyright: ignore[reportAttributeAccessIssue]
|
|
"log",
|
|
min(frequencies),
|
|
max(frequencies),
|
|
frequencies.shape[0] - 1,
|
|
)
|
|
)
|
|
|
|
|
|
class TF:
|
|
def __init__(
|
|
self,
|
|
model: Model,
|
|
inputs: list[Port | str],
|
|
outputs: list[Port | str],
|
|
frequencies: NDArray[float64],
|
|
):
|
|
self.model = model.deepcopy()
|
|
self.inputs = inputs
|
|
self.outputs = outputs
|
|
self.frequencies = frequencies
|
|
self.result: SeriesSolution | None = None
|
|
self.compute()
|
|
|
|
# alias
|
|
self.f = self.frequencies
|
|
|
|
def compute(self):
|
|
solution = compute_TF(self.model, self.frequencies, self.inputs)
|
|
self.result = solution
|
|
return self
|
|
|
|
def get(self, output: Port | str):
|
|
if self.result is None:
|
|
raise Exception(
|
|
"TF need to be computed before getting result"
|
|
)
|
|
return self.result[output]
|