Commit 6ede4739 authored by Daniel Brown's avatar Daniel Brown
Browse files

range of refactor fixes for signal stuff, mostly electronic and beamsplitter

parent 6d0e7dec
......@@ -46,25 +46,26 @@ class MicroResonator(Connector):
self.mech.F_z.frequencies = self.frequencies
def _get_workspace(self, sim):
if sim.is_audio:
if sim.carrier.any_frequencies_changing:
# ddb - This case probably needs some more thought on what beatings change
raise NotImplementedError(
"Changing carrier frequencies whilst using a MicroResonant not supported yet."
)
if sim.signal:
refill = (
sim.model.fsig.f.is_changing
or self.mass.is_changing
or self.f.is_changing
or self.Q.is_changing
)
ws = MicroResonatorWorkspace(self, sim, refill)
ws.set_fill_function(self.fill)
ws.Fz_frequencies = sim.mechanical_frequencies[self.mech.F_z]
ws.z_frequencies = sim.mechanical_frequencies[self.mech.z]
ws = MicroResonatorWorkspace(self, sim, refill, refill)
ws.signal.set_fill_function(self.fill)
ws.Fz_frequencies = sim.signal.mechanical_frequencies[self.mech.F_z]
ws.z_frequencies = sim.signal.mechanical_frequencies[self.mech.z]
return ws
else:
if sim.any_frequencies_changing:
# ddb - This case probably needs some more thought on what beatings change
raise NotImplementedError(
"Changing carrier frequencies whilst using a MicroResonant not supported yet."
)
return None
return None
def _couples_frequency(self, ws, connection, frequency_in, frequency_out):
return True
......
......@@ -586,16 +586,17 @@ class Beamsplitter(Surface):
def _get_workspace(self, sim):
from finesse.components.modal.beamsplitter import (
beamsplitter_fill,
beamsplitter_carrier_fill,
beamsplitter_signal_fill,
BeamsplitterWorkspace,
)
_, is_changing = self._eval_parameters()
refill = (
(sim.is_audio and sim.model.fsig.f.is_changing)
(sim.signal and sim.model.fsig.f.is_changing)
or self in sim.trace_forest.changing_components
or sim.any_frequencies_changing
or sim.carrier.any_frequencies_changing
or (len(is_changing) and is_changing.issubset(self.__changing_check))
)
......@@ -604,7 +605,8 @@ class Beamsplitter(Surface):
ws.nr1 = refractive_index(self.p1) or refractive_index(self.p2) or 1
ws.nr2 = refractive_index(self.p3) or refractive_index(self.p4) or 1
ws.set_fill_function(beamsplitter_fill)
ws.carrier.set_fill_function(beamsplitter_carrier_fill)
ws.signal.set_fill_function(beamsplitter_signal_fill)
# Initialise the ABCD matrix memory-views
if sim.is_modal:
......
......@@ -72,7 +72,7 @@ class DegreeOfFreedom(Connector):
return self.__amplitudes
def _get_workspace(self, sim):
if sim.is_audio:
if sim.signal:
ws = DOFWorkspace(self, sim, False)
ws.set_fill_function(self.__fill)
ws.drives = self.drives
......
......@@ -34,12 +34,12 @@ class ZPKNodeActuator(Connector):
self._register_node_coupling("P1_ACT", self.p1.i, mechanical_node)
def _get_workspace(self, sim):
if sim.is_audio:
if sim.signal:
refill = sim.model.fsig.f.is_changing or any(
p.is_changing for p in self.parameters
)
ws = FilterWorkspace(self, sim, refill)
ws.set_fill_function(self.fill)
ws = FilterWorkspace(self, sim, refill, refill)
ws.signal.set_fill_function(self.fill)
ws.frequencies = sim.electrical_frequencies[self.p1.i].frequencies
return ws
else:
......@@ -48,7 +48,7 @@ class ZPKNodeActuator(Connector):
def fill(self, ws):
for _ in ws.frequencies:
# Assumes only couples to first mech frequency
with ws.sim.component_edge_fill3(
with ws.sim.signal.component_edge_fill3(
ws.owner_id, ws.connections.P1_ACT_idx, _.index, 0,
) as mat:
mat[:] = ws.values.gain
......@@ -69,12 +69,12 @@ class Amplifier(Connector):
self._register_node_coupling("P1_P2", self.p1.i, self.p2.o)
def _get_workspace(self, sim):
if sim.is_audio:
if sim.signal:
refill = sim.model.fsig.f.is_changing or any(
p.is_changing for p in self.parameters
)
ws = FilterWorkspace(self, sim, refill)
ws.set_fill_function(self.fill)
ws = FilterWorkspace(self, sim, refill, refill)
ws.signal.set_fill_function(self.fill)
ws.frequencies = sim.electrical_frequencies[self.p1.i].frequencies
return ws
else:
......@@ -82,7 +82,7 @@ class Amplifier(Connector):
def fill(self, ws):
for _ in ws.frequencies:
with ws.sim.component_edge_fill3(
with ws.sim.signal.component_edge_fill3(
ws.owner_id, ws.connections.P1_P2_idx, 0, 0,
) as mat:
mat[:] = ws.values.gain
......@@ -106,13 +106,13 @@ class Filter(Connector):
self._register_node_coupling("P1_P2", self.p1.i, self.p2.o)
def _get_workspace(self, sim):
if sim.is_audio:
if sim.signal:
refill = sim.model.fsig.f.is_changing or any(
p.is_changing for p in self.parameters
)
ws = FilterWorkspace(self, sim, refill)
ws.set_fill_function(self.fill)
ws.frequencies = sim.electrical_frequencies[self.p1.i].frequencies
ws = FilterWorkspace(self, sim, refill, refill)
ws.signal.set_fill_function(self.fill)
ws.frequencies = sim.signal.electrical_frequencies[self.p1.i].frequencies
return ws
else:
return None
......@@ -121,7 +121,7 @@ class Filter(Connector):
Hz = self.eval(ws.sim.model_data.fsig)
for _ in ws.frequencies:
with ws.sim.component_edge_fill3(
with ws.sim.signal.component_edge_fill3(
ws.owner_id, ws.connections.P1_P2_idx, 0, 0,
) as mat:
mat[:] = Hz
......
......@@ -109,11 +109,11 @@ class LIGOTripleSuspension(Connector):
)
def _get_workspace(self, sim):
if sim.is_audio:
if sim.signal:
refill = sim.model.fsig.f.is_changing # Need to recompute H(f)
N = len(self._registered_connections)
ws = MIMOTFWorkspace(self, sim, refill, N)
ws.set_fill_function(mimo_fill)
ws.signal.set_fill_function(mimo_fill)
ws.set_denominator(self.tfs.den[0][0])
name_map = {n.port.name: "tst" for n in self.tst.nodes}
......
......@@ -239,11 +239,10 @@ class Joint(Connector):
self.__I = np.eye(sim.model_data.num_HOMs, dtype=np.complex128)
def _fill_matrix(self, sim):
if not sim.is_audio:
return
for c in list(self._registered_connections):
with sim.component_edge_fill(self, c, None, None) as mat:
mat[:] = self.__I
if sim.signal:
for c in list(self._registered_connections):
with sim.signal.component_edge_fill(self, c, None, None) as mat:
mat[:] = self.__I
class FreeMassWorkspace(ConnectorWorkspace):
......@@ -282,10 +281,10 @@ class FreeMass(Connector):
self._register_node_coupling("F_to_PITCH", self.mech.F_pitch, self.mech.pitch)
def _get_workspace(self, sim):
if sim.is_audio:
if sim.signal:
refill = sim.model.fsig.f.is_changing or any(p.is_changing for p in self.parameters)
ws = FreeMassWorkspace(self, sim, refill)
ws.set_fill_function(self.fill)
ws = FreeMassWorkspace(self, sim, refill, refill)
ws.signal.set_fill_function(self.fill)
return ws
else:
return None
......@@ -293,7 +292,7 @@ class FreeMass(Connector):
def fill(self, ws):
f = ws.sim.model_data.fsig
Hz = -1 / (self.mass.value * (2*PI*f)**2)
with ws.sim.component_edge_fill3(
ws.owner_id, ws.connections.F_to_Z_idx, 0, 0,
with ws.sim.signal.component_edge_fill3(
ws.owner_id, ws.signal.connections.F_to_Z_idx, 0, 0,
) as mat:
mat[:] = Hz
......@@ -71,11 +71,7 @@ cdef class BeamsplitterOpticalConnections:
cdef class BeamsplitterSignalConnections(BeamsplitterOpticalConnections):
def __cinit__(self, MatrixSystemSolver mtx):
super().__cinit__(mtx)
# Only 1D arrays of views as spaces don't
# couple frequencies together.
Nf = mtx.optical_frequencies.size
self.P1i_Z = SubCCSView2DArray(Nf, 1)
self.P1o_Z = SubCCSView2DArray(Nf, 1)
self.P2i_Z = SubCCSView2DArray(Nf, 1)
......@@ -120,12 +116,15 @@ cdef class BeamsplitterWorkspace(KnmConnectorWorkspace):
refill,
refill,
BeamsplitterOpticalConnections(sim.carrier),
BeamsplitterSignalConnections(sim.signal),
BeamsplitterSignalConnections(sim.signal) if sim.signal else None,
BeamsplitterValues()
)
# Store direct type cast for C access
self.boc = self.carrier.connections
self.bsc = self.signal.connections
if sim.signal:
self.bsc = self.signal.connections
else:
self.bsc = None
self.bv = self.values
# tracing node information
......@@ -847,13 +846,14 @@ cdef object c_beamsplitter_carrier_fill(ConnectorWorkspace cws):
double alpha = DEG2RAD * ws.bv.alpha
double phase_shift_scaling
Py_ssize_t _i
Py_ssize_t _i, size
frequency_info_t *frequencies
bs_optical_connections *conn = &ws.boc.opt_conn_ptrs
size = ws.sim.carrier.optical_frequencies.size
frequencies = ws.sim.carrier.optical_frequencies.frequency_info
for i in range(ws.sim.num_frequencies):
for i in range(size):
beamsplitter_fill_optical_2_optical(
conn, ws, &frequencies[i], r, t, phi, alpha
)
......@@ -876,110 +876,16 @@ cdef object c_beamsplitter_signal_fill(ConnectorWorkspace cws):
double f_car # current value of the frequency object's carrier
double x_scale = ws.sim.model_data.x_scale # scaling for optical signals to motion
# # scaling factors for longitudinal motion
# # TODO (phil): should this k be carrier-specific?
# complex_t long_to_field = 1j * k0 * _r * x_scale
# complex_t field_to_long
Py_ssize_t _i
const complex_t *c_p1_i
const complex_t *c_p2_i
const complex_t *c_p3_i
const complex_t *c_p4_i
const complex_t *c_p1_o
const complex_t *c_p2_o
const complex_t *c_p3_o
const complex_t *c_p4_o
bint is_lower_sb
Py_ssize_t _i, size
frequency_info_t *frequencies
bs_optical_connections *conn = &ws.boc.opt_conn_ptrs
bs_optical_connections *conn = &ws.bsc.opt_conn_ptrs
bs_signal_connections *sconn = &ws.bsc.sig_conn_ptrs
size = ws.sim.signal.optical_frequencies.size
frequencies = ws.sim.signal.optical_frequencies.frequency_info
for i in range(ws.sim.signal.optical_frequencies.size):
for i in range(size):
beamsplitter_fill_optical_2_optical(
conn, ws, &frequencies[i], r, t, phi, alpha
)
# TODO ddb copy over mirror code to BS
# # -----------------------------------------------------------------
# # Mechanical to optical connections
# # -----------------------------------------------------------------
# # - Longitudinal
# # -----------------------------------------------------------------
# # As the output has a mixture of both refl and transmitted we only
# # modulate the incoming and refl'd field so we have to propagate
# # the input
# # Detuning phase is the phase the carrier picks up from reference point
# # to the mirror surface, then scattered into a different frequency and
# # propagated back to the reference point from the mirror surface.
# #
# # phase_shift = phi * (1 + car.f / f0) + phi * (1 + freq.f/f0)
# # = phi * (2 + (order*fsig + freq.f) / f0)
# phase_shift = phi * (2 + (freq.f + freq.f_car[0])/f0)
# _tuning = cexp(1.0j * phase_shift * ws.cos_alpha)
# # -----------------------------------------------------------------
# # Signal generation z->p1.o
# # Get incoming carrier field amplitudes
# c_p2_i = &ws.sim.carrier.out_view[ws.sim.carrier.field_fast_2(
# ws.car_p2i_rhs_idx,
# ws.car_p_num_hom,
# freq.audio_carrier_index,
# 0
# )]
# (<SubCCSView>ws.bc.Z_P1o[0, freq.index]).fill_za_zmv (
# long_to_field*_tuning,
# ws.K21.ptr, ws.K21.stride1, ws.K21.stride2,
# c_p2_i, 1 # 1D contiguous array from outview
# )
# # -----------------------------------------------------------------
# # Signal generation z->p2.o
# # Get incoming carrier field amplitudes
# c_p1_i = &ws.sim.carrier.out_view[ws.sim.carrier.field_fast_2(
# ws.car_p1i_rhs_idx,
# ws.car_p_num_hom,
# freq.audio_carrier_index,
# 0
# )]
# (<SubCCSView>ws.bc.Z_P2o[0, freq.index]).fill_za_zmv (
# long_to_field*_tuning,
# ws.K12.ptr, ws.K12.stride1, ws.K12.stride2,
# c_p1_i, 1 # 1D contiguous array from outview
# )
# # Tuning has different cos_alpha_2 because of nr/alpha difference
# _ctuning = conj(cexp(1.0j * phase_shift * ws.cos_alpha_2))
# # -----------------------------------------------------------------
# # Signal generation z->p3.o
# # extra 180 phase here as we're doing the opposite
# # modulation when looked at from the other side of the mirror
# c_p4_i = &ws.sim.carrier.out_view[ws.sim.carrier.field_fast_2(
# ws.car_p4i_rhs_idx,
# ws.car_p_num_hom,
# freq.audio_carrier_index,
# 0
# )]
# (<SubCCSView>ws.bc.Z_P3o[0, freq.index]).fill_za_zmv (
# -long_to_field*_ctuning,
# ws.K43.ptr, ws.K43.stride1, ws.K43.stride2,
# c_p4_i, 1 # 1D contiguous array from outview
# )
# # -----------------------------------------------------------------
# # Signal generation z->p4.o
# # extra 180 phase here as we're doing the opposite
# # modulation when looked at from the other side of the mirror
# c_p3_i = &ws.sim.carrier.out_view[ws.sim.carrier.field_fast_2(
# ws.car_p3i_rhs_idx,
# ws.car_p_num_hom,
# freq.audio_carrier_index,
# 0
# )]
# (<SubCCSView>ws.bc.Z_P4o[0, freq.index]).fill_za_zmv (
# -long_to_field*_ctuning,
# ws.K34.ptr, ws.K34.stride1, ws.K34.stride2,
# c_p3_i, 1 # 1D contiguous array from outview
# )
......@@ -79,7 +79,6 @@ cdef class MirrorSignalConnections(MirrorOpticalConnections):
def __cinit__(self, object mirror, MatrixSystemSolver mtx):
cdef:
int Nfo = mtx.optical_frequencies.size
super().__cinit__(mirror, mtx)
Nmz = mirror.mech.z.num_frequencies # num of mechanic frequencies
self.P1i_Fz = SubCCSView2DArray(Nfo, Nmz)
......@@ -129,11 +128,11 @@ cdef class MirrorWorkspace(KnmConnectorWorkspace):
if sim.signal:
# If we have a signal simulation then we need to cache some indicies
# for grabbing data when filling
self.car_p1o_rhs_idx = sim.carrier_index.get_node_info(owner.p1.o)['rhs_index']
self.car_p2o_rhs_idx = sim.carrier_index.get_node_info(owner.p2.o)['rhs_index']
self.car_p1i_rhs_idx = sim.carrier_index.get_node_info(owner.p1.i)['rhs_index']
self.car_p2i_rhs_idx = sim.carrier_index.get_node_info(owner.p2.i)['rhs_index']
self.car_p_num_hom = sim.carrier_index.get_node_info(owner.p1.o)['nhoms']
self.car_p1o_rhs_idx = sim.carrier.get_node_info(owner.p1.o)['rhs_index']
self.car_p2o_rhs_idx = sim.carrier.get_node_info(owner.p2.o)['rhs_index']
self.car_p1i_rhs_idx = sim.carrier.get_node_info(owner.p1.i)['rhs_index']
self.car_p2i_rhs_idx = sim.carrier.get_node_info(owner.p2.i)['rhs_index']
self.car_p_num_hom = sim.carrier.get_node_info(owner.p1.o)['nhoms']
# Get a reference to the mechanical node frequencies
fcnt = sim.signal.mechanical_frequencies[owner.mech.z]
self.z_mech_freqs = fcnt.frequency_info
......
......@@ -45,11 +45,11 @@ class Photodiode(Connector):
return self.p1.i
def _get_workspace(self, sim):
if sim.is_audio:
ws = PhotodiodeWorkspace(self, sim, True)
if sim.signal:
ws = PhotodiodeWorkspace(self, sim, True, True)
ws.I = np.eye(sim.model_data.num_HOMs, dtype=np.complex128)
ws.set_fill_function(self._fill_matrix)
ws.frequencies = sim.electrical_frequencies[self.DC.o].frequencies
ws.signal.set_fill_function(self._fill_matrix)
ws.frequencies = sim.signal.electrical_frequencies[self.DC.o].frequencies
return ws
else:
return None
......@@ -58,13 +58,13 @@ class Photodiode(Connector):
"""
Computing E.conj() * upper + E * lower.conj()
"""
for freq in ws.sim.frequencies:
for freq in ws.sim.signal.optical_frequencies.frequencies:
# Get the carrier HOMs for this frequency
E = ws.sim.DC.get_DC_out(self.p1.i, freq.audio_carrier_index)
E = ws.sim.carrier.get_out(self.p1.i, freq.audio_carrier_index)
# is_lower_sb = freq.audio_order < 0
for efreq in ws.frequencies:
with ws.sim.component_edge_fill3(
ws.owner_id, ws.connections.P1i_DC_idx, freq.index, efreq.index,
with ws.sim.signal.component_edge_fill3(
ws.owner_id, ws.signal.connections.P1i_DC_idx, freq.index, efreq.index,
) as mat:
mat[:] = E.conjugate() * ws.values.qeff
......@@ -95,11 +95,11 @@ class Photodiode1Demod(Connector):
self._register_node_coupling("P1i_Q", self.p1.i, self.Q.o)
def _get_workspace(self, sim):
if sim.is_audio:
if sim.signal:
ws = PhotodiodeWorkspace(self, sim, True)
ws.set_fill_function(self._fill_matrix)
ws.frequencies = sim.electrical_frequencies[self.I.o].frequencies
ws.dc_node_id = sim.DC.node_id(self.p1.i)
ws.signal.set_fill_function(self._fill_matrix)
ws.frequencies = sim.signal.electrical_frequencies[self.I.o].frequencies
ws.dc_node_id = sim.carrier.node_id(self.p1.i)
return ws
else:
return None
......@@ -119,131 +119,131 @@ class Photodiode1Demod(Connector):
# factorQ = 1j * factorI
# cfactorQ = factorQ.conjugate()
for f1 in ws.sim.DC.frequencies:
for f2 in ws.sim.DC.frequencies:
for f1 in ws.sim.carrier.optical_frequencies.frequencies:
for f2 in ws.sim.carrier.optical_frequencies.frequencies:
df = f1.f - f2.f
if df == ws.values.f or df == -ws.values.f:
with ws.sim.component_edge_fill3(
with ws.sim.signal.component_edge_fill3(
ws.owner_id,
ws.connections.P1i_I_idx,
ws.sim.DC.frequency_info[f2.index]["audio_lower_index"],
ws.signal.connections.P1i_I_idx,
ws.sim.carrier.optical_frequency.frequency_info[f2.index]["audio_lower_index"],
0,
) as mat:
mat[:] = 0
with ws.sim.component_edge_fill3(
with ws.sim.signal.component_edge_fill3(
ws.owner_id,
ws.connections.P1i_I_idx,
ws.sim.DC.frequency_info[f1.index]["audio_upper_index"],
ws.signal.connections.P1i_I_idx,
ws.sim.carrier.optical_frequency.frequency_info[f1.index]["audio_upper_index"],
0,
) as mat:
mat[:] = 0
with ws.sim.component_edge_fill3(
with ws.sim.signal.component_edge_fill3(
ws.owner_id,
ws.connections.P1i_Q_idx,
ws.sim.DC.frequency_info[f2.index]["audio_lower_index"],
ws.signal.connections.P1i_Q_idx,
ws.sim.carrier.optical_frequency.frequency_info[f2.index]["audio_lower_index"],
0,
) as mat:
mat[:] = 0
with ws.sim.component_edge_fill3(
with ws.sim.signal.component_edge_fill3(
ws.owner_id,
ws.connections.P1i_Q_idx,
ws.sim.DC.frequency_info[f1.index]["audio_upper_index"],
ws.signal.connections.P1i_Q_idx,
ws.sim.carrier.optical_frequency.frequency_info[f1.index]["audio_upper_index"],
0,
) as mat:
mat[:] = 0
for f1 in ws.sim.DC.frequencies:
for f2 in ws.sim.DC.frequencies:
for f1 in ws.sim.carrier.optical_frequencies.frequencies:
for f2 in ws.sim.carrier.optical_frequencies.frequencies:
df = f1.f - f2.f
if df == -ws.values.f:
with ws.sim.component_edge_fill3(
with ws.sim.signal.component_edge_fill3(
ws.owner_id,
ws.connections.P1i_I_idx,
ws.sim.DC.frequency_info[f2.index]["audio_lower_index"],
ws.signal.connections.P1i_I_idx,
ws.sim.carrier.optical_frequency.frequency_info[f2.index]["audio_lower_index"],
0,
) as mat:
for k in range(ws.sim.DC.model_data.num_HOMs):
car = ws.sim.DC.get_DC_out(self.p1.i, f1.index, k)
for k in range(ws.sim.model_data.num_HOMs):
car = ws.sim.carrier.get_out(self.p1.i, f1.index, k)
# This will apply a conjugation internally as it's
# a lower SB connection
mat[:][k] += factorI.conjugate() * car
with ws.sim.component_edge_fill3(
with ws.sim.signal.component_edge_fill3(
ws.owner_id,
ws.connections.P1i_I_idx,
ws.sim.DC.frequency_info[f1.index]["audio_upper_index"],
ws.signal.connections.P1i_I_idx,
ws.sim.carrier.optical_frequency.frequency_info[f1.index]["audio_upper_index"],
0,
) as mat:
for k in range(ws.sim.DC.model_data.num_HOMs):
car = ws.sim.DC.get_DC_out(self.p1.i, f2.index, k)
for k in range(ws.sim.model_data.num_HOMs):
car = ws.sim.carrier.get_out(self.p1.i, f2.index, k)
mat[:][k] += factorI.conjugate() * car.conjugate()
with ws.sim.component_edge_fill3(
with ws.sim.signal.component_edge_fill3(
ws.owner_id,
ws.connections.P1i_Q_idx,
ws.sim.DC.frequency_info[f2.index]["audio_lower_index"],
ws.signal.connections.P1i_Q_idx,
ws.sim.carrier.optical_frequency.frequency_info[f2.index]["audio_lower_index"],
0,
) as mat:
for k in range(ws.sim.DC.model_data.num_HOMs):
car = ws.sim.DC.get_DC_out(self.p1.i, f1.index, k)
for k in range(ws.sim.model_data.num_HOMs):
car = ws.sim.carrier.get_out(self.p1.i, f1.index, k)
# This will apply a conjugation internally as it's
# a lower SB connection
mat[:][k] += (factorQ.conjugate() * car)
with ws.sim.component_edge_fill3(
with ws.sim.signal.component_edge_fill3(
ws.owner_id,
ws.connections.P1i_Q_idx,
ws.sim.DC.frequency_info[f1.index]["audio_upper_index"],
ws.signal.connections.P1i_Q_idx,
ws.sim.carrier.optical_frequency.frequency_info[f1.index]["audio_upper_index"],
0,
) as mat:
for k in range(ws.sim.DC.model_data.num_HOMs):
car = ws.sim.DC.get_DC_out(self.p1.i, f2.index, k)
for k in range(ws.sim.model_data.num_HOMs):
car = ws.sim.carrier.get_out(self.p1.i, f2.index, k)
mat[:][k] += factorQ.conjugate() * car.conjugate()
if df == ws.values.f:
with ws.sim.component_edge_fill3(
with ws.sim.signal.component_edge_fill3(
ws.owner_id,
ws.connections.P1i_I_idx,
ws.sim.DC.frequency_info[f2.index]["audio_lower_index"],
ws.signal.connections.P1i_I_idx,
ws.sim.carrier.optical_frequency.frequency_info[f2.index]["audio_lower_index"],
0,