OptimiseRFReadoutPhaseDC() modifies the status of the simulated layout
Summary
The use of OptimizeRFReadoutPhaseDC() for optimization of split RF photodetectors somewhat ends up changing the state of the finesse model. In my particular case, after running it, the powers in the cavity became extremely low, I tried to check all DOFs DC values but they seem all unchanged with respect to the initial case.
Steps to reproduce
- Create a matched and tuned finesse model (I tried a coupled PR and arm-cavity model) and add a quadrant photodetector.
- Check the powers in the cavities and the DOF tunings
- Use OptimizeRFReadoutPhaseDC() on an angular DOF and on the quadrant PD
- Check the powers and the tunings of the model after the use of OptimizeRFReadoutPhaseDC().
Bug behavior
Power circulating in the cavities drops significantly, while tunings seem to remain the same
What is the expected correct behavior?
The only part of the finesse model affected by the OptimizeRFReadoutPhaseDC() function should be the demodulation phase of the split detector. Power circulating in the cavities should remain the same.
Relevant logs and/or screenshots
Example code to reproduce the bug:
import numpy as np
import finesse
from finesse.analysis import actions as fac
#Helper function to check the resonance conditions and fix the modulation frequencies to WIP
def print_tunings(ifo):
# not sure if RM1 RM2 and RM3 should be just summed or what
print(f"""
┌──────────────────┐
│ Optic Tuning │
├──────────────────┤
│ PR : {ifo.RM1.phi.eval() + ifo.RM2.phi.eval() + ifo.RM3.phi.eval() + ifo.PRCL.DC:9.4g} │
│ NI : {ifo.NITM.phi.eval():9.4g} │
│ NE : {ifo.NETM.phi.eval() + ifo.NETM_z.DC:9.4g} │
└──────────────────┘""")
def print_powers(ifo):
act = fac.Series(
fac.Temporary(fac.Change({"eom1.midx": 0, "eom2.midx": 0}),
fac.Noxaxis()
)
)
out=ifo.run(act)
#out = actions.temporary(noxaxis(ifo)
print("""┌────────────────────────────────────────┐
│ Detector Power [W] Pow. ratio │
├────────────────────────────────────────┤""")
for detector in ifo.detectors:
power = np.abs(out[detector])**2
if "CAR_AMP" in detector.name:
print(f"│ {detector.name:12s} : {power:9.4g} {power/ifo.laser1.P:9.4g} │")
for detector in ifo.readouts:
if '_f' not in detector.name:
power = out[detector.name + '_DC']
print(f"│ {detector.name:12s} : {power:9.4g} {power/ifo.laser1.P:9.4g} │")
print("└────────────────────────────────────────┘")
base = finesse.Model()
base.parse(
"""
l laser1 P=25 # laser with P = 25W at the default frequency
# modulations
mod eom1 f=6270777 midx=0.15 order=1
mod eom2 f=56436993 midx=0.15 order=1
link(laser1, 0.1, eom1, 0.1,eom2, B2_pickoff.p1)
dbs B2_pickoff
m RM1 L=30e-6 T=0.04835 Rc=2.758 phi=225
s L0 B2_pickoff.p3 RM1.p1 L=0
bs RM2 R=1 T=0 alpha=1.7 Rc=163
s L1 RM1.p2 RM2.p1 L=83.7374
bs RM3 L=0 T=1e-4 alpha=45
s L2 RM2.p2 RM3.p1 L=83.59
#Narm
m NITM L=27e-6 T=0.01377 Rc=-1420 phi=-45
s L3 RM3.p2 NITM.p1 L=11.952 # 6.051855+ (6.015178+5.785112)/2
m NETM L=27e-6 T=3.39e-6 Rc=1683 phi=-45
s sNarm NITM.p2 NETM.p1 L=2999.8
#Cavities
cav cavPRN RM1.p2.o NITM.p1.i
cav Narm NITM.p2.o NETM.p1.i
var lPRC (L1.L + L2.L + L3.L)
dof PRCL RM1.dofs.z +1
dof NARM NITM.dofs.z +1 NETM.dofs.z -1
dof NITM_z NITM.dofs.z +1
dof NETM_z NETM.dofs.z +1
dof NARMp NITM.dofs.yaw.DC +1 NETM.dofs.yaw.DC +1
dof NARMm NITM.dofs.yaw.DC +1 NETM.dofs.yaw.DC -1 # Need to check the signs
var fsrN (0.5 * c0 / sNarm.L)
var fsrPRC (0.5 * c0 / lPRC)
# B4 quadrant
readout_rf B4_f1_NF RM3.p3.o f=eom1.f pdtype=xsplit phase=0 output_detectors=True
readout_dc B2 B2_pickoff.p4.o output_detectors=True
readout_dc Intra_CAV RM2.p1.o output_detectors=True
readout_dc Intra_arm NETM.p1.o output_detectors=True
readout_dc B4 RM3.p3.o output_detectors=True
readout_dc B7 NETM.p2.o output_detectors=True
ad CAR_AMP_PRin RM1.p1.i f=0
ad CAR_AMP_N NETM.p1.o f=0
ad CAR_AMP_PRC RM2.p1.o f=0
""")
# Set maxtem to 1 to detect misalignment modes
base.modes(maxtem=1)
# Run the phase optimization
_kat = base.deepcopy() # Doing a deepcopy because this function fucks something up it seems
print_tunings(_kat)
print_powers(_kat)
out = _kat.run(fac.OptimiseRFReadoutPhaseDC('NARMp.DC','B4_f1_NF', d_dof=1e-6))
print_tunings(_kat)
print_powers(_kat)
(Finesse version used: '3.0a21')
Labels
Please assign labels to the issue by uncommenting approiate lines:
Reproducing the bug
If cannot reproduce the bug comment out the first line and uncomment the second.
Area of the bug
If possible label the area the bug is occuring in: - Packaging (you can only use one) - Build system - Documentation - Parser (of the KatScript) Use Parser::legacy if you are parsing legacy files - Plotting - Testing (for issues with the automated tests) - User interface
Operating system
Add a label for the operating system you are using Finesse on. ~label /"OS::Linux
Urgency
If the bug is preventing Finesse from being used, for example if it produces seemingly valid but incorrect results, add this label.