Commit 7f9cc1d5 authored by Daniel Brown's avatar Daniel Brown Committed by Sean Leavey
Browse files

adding in readout Q node couplings, adding test

parent 2db208ab
......@@ -338,7 +338,11 @@ class ReadoutRF(_Readout):
* ws.sim.model_data.EPSILON0_C
* np.exp(-1j * ws.values.phase * finesse.constants.DEG2RAD)
)
# factorQ = 1j * factorI
factorQ = (
0.5
* ws.sim.model_data.EPSILON0_C
* np.exp(-1j * (ws.values.phase + 90) * finesse.constants.DEG2RAD)
)
terms = defaultdict(list)
for f1 in ws.sim.carrier.optical_frequencies.frequencies:
......@@ -376,6 +380,25 @@ class ReadoutRF(_Readout):
)
terms[key].append(factorI.conjugate() * E2c)
if ws.signal.connections.P1i_Q_idx >= 0:
key = (
ws.owner_id,
ws.signal.connections.P1i_Q_idx,
ws.sim.carrier.optical_frequencies.get_info(f2.index)[
"audio_lower_index"
],
)
terms[key].append(factorQ * E1c)
key = (
ws.owner_id,
ws.signal.connections.P1i_Q_idx,
ws.sim.carrier.optical_frequencies.get_info(f1.index)[
"audio_upper_index"
],
)
terms[key].append(factorQ.conjugate() * E2c)
if df == ws.values.f:
if ws.signal.connections.P1i_I_idx >= 0:
key = (
......@@ -397,6 +420,26 @@ class ReadoutRF(_Readout):
terms[key].append(factorI * E2c)
if ws.signal.connections.P1i_Q_idx >= 0:
key = (
ws.owner_id,
ws.signal.connections.P1i_Q_idx,
ws.sim.carrier.optical_frequencies.get_info(f2.index)[
"audio_lower_index"
],
)
terms[key].append(factorQ.conjugate() * E1c)
key = (
ws.owner_id,
ws.signal.connections.P1i_Q_idx,
ws.sim.carrier.optical_frequencies.get_info(f1.index)[
"audio_upper_index"
],
)
terms[key].append(factorQ * E2c)
for key, values in terms.items():
total = sum(values)
if ws.is_segmented:
......
......@@ -123,7 +123,8 @@ def fp_cavity_model(model):
readout_rf REFL9 ITMXAR.p1.o f=&f1 phase=90 output_detectors=true
sgen sig DARM.AC
pd2 TF REFL9.p1.i f1=&REFL9.f phase1=&REFL9.phase f2=&fsig.f
pd2 TF_I REFL9.p1.i f1=&REFL9.f phase1=&REFL9.phase f2=&fsig.f
pd2 TF_Q REFL9.p1.i f1=&REFL9.f phase1=&REFL9.phase+90 f2=&fsig.f
"""
)
......@@ -131,47 +132,71 @@ def fp_cavity_model(model):
@pytest.fixture
def compute_fp_cavity_readout_pd1_slope(fp_cavity_model):
def freq_resp_noxaxis_fp_cavity(fp_cavity_model):
base = fp_cavity_model
base.fsig.f = 1e-3
sol = Series(
FrequencyResponse((base.fsig.f,), "DARM", "REFL9.I", name="tf"),
FrequencyResponse((base.fsig.f,), "DARM", ["REFL9.I", "REFL9.Q"], name="tf"),
Xaxis("DARM.DC", "lin", -1e-8, 1e-8, 1, relative=True),
Noxaxis(),
).run(base)
return sol, base
@pytest.fixture
def compute_fp_cavity_readout_pd1_slope_I(freq_resp_noxaxis_fp_cavity):
sol, base = freq_resp_noxaxis_fp_cavity
k = 2 * np.pi / base.lambda0
TF_gain1 = sol["noxaxis"]["TF"]
TF_gain = sol["tf"].out.squeeze()
TF_gain1 = sol["noxaxis"]["TF_I"]
TF_gain = sol["tf"]["REFL9.I"].squeeze()
error = sol["xaxis"]["REFL9_I"]
x = sol["xaxis"].x1
# convert degree sweep into meters
slope = np.gradient(error, x[1] - x[0]).mean() * (k * np.rad2deg(1)) # W/m
print("pd1: ", TF_gain1.real) # units W/m
print("readout: ", TF_gain.real) # units W/m
print("dif errsig:", slope.real)
# print("pd1: ", TF_gain1.real) # units W/m
# print("readout: ", TF_gain.real) # units W/m
# print("dif errsig:", slope.real)
return TF_gain1.real, TF_gain.real, slope.real
def test_error_signal_slope(compute_fp_cavity_readout_pd1_slope):
pd1, readout, slope = compute_fp_cavity_readout_pd1_slope
assert abs(slope - reference) / abs(reference) < 1e-6
@pytest.fixture
def compute_fp_cavity_readout_pd1_slope_Q(freq_resp_noxaxis_fp_cavity):
sol, base = freq_resp_noxaxis_fp_cavity
k = 2 * np.pi / base.lambda0
TF_gain1 = sol["noxaxis"]["TF_Q"]
TF_gain = sol["tf"]["REFL9.Q"].squeeze()
error = sol["xaxis"]["REFL9_Q"]
x = sol["xaxis"].x1
# convert degree sweep into meters
slope = np.gradient(error, x[1] - x[0]).mean() * (k * np.rad2deg(1)) # W/m
# print("pd1: ", TF_gain1.real) # units W/m
# print("readout: ", TF_gain.real) # units W/m
# print("dif errsig:", slope.real)
def test_error_pd1(compute_fp_cavity_readout_pd1_slope):
pd1, readout, slope = compute_fp_cavity_readout_pd1_slope
assert abs(pd1 - reference) / abs(reference) < 1e-6
return TF_gain1.real, TF_gain.real, slope.real
@pytest.mark.xfail(reason="Weird 0.1% error in readout method, unsure why")
def test_error_readout(compute_fp_cavity_readout_pd1_slope):
pd1, readout, slope = compute_fp_cavity_readout_pd1_slope
def test_I_signal_slope(compute_fp_cavity_readout_pd1_slope_I):
pd1, readout, slope = compute_fp_cavity_readout_pd1_slope_I
assert abs(slope - reference) / abs(reference) < 1e-6
assert abs(pd1 - reference) / abs(reference) < 1e-6
assert abs(readout - reference) / abs(reference) < 1e-6
def test_Q_signal_slope(compute_fp_cavity_readout_pd1_slope_Q):
pd1, readout, slope = compute_fp_cavity_readout_pd1_slope_Q
# No reference in the detuned case for Q
assert abs(readout - slope) / abs(slope) < 1e-6
assert abs(pd1 - slope) / abs(slope) < 1e-6
assert (
abs(pd1 - readout) / abs(readout) < 1e-14
) # Readout and pd1 should agree exactly
@pytest.fixture
def compute_detuned_fp_cavity_readout_pd1_slope(fp_cavity_model):
base = fp_cavity_model
......@@ -185,7 +210,7 @@ def compute_detuned_fp_cavity_readout_pd1_slope(fp_cavity_model):
).run(base)
k = 2 * np.pi / base.lambda0
TF_gain1 = sol["noxaxis"]["TF"]
TF_gain1 = sol["noxaxis"]["TF_I"]
TF_gain = sol["tf"].out.squeeze()
error = sol["xaxis"]["REFL9_I"]
x = sol["xaxis"].x1
......
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