The ‘frequency_response’ action for modelling transfer functions¶
As seen in the previous section we can manually compute single input to multiple output (SIMO) transfer functions with a few lines of KatScript. If we wanted to inject multiple signals separately from one another to compute a full multiple input multiple output (MIMO) it can get awkward with the manual method. This would require adding and removing signal generators in some for-loop then concatenating all the results together.
In Finesse 3 we have introduced the
Readout component. This is a mix of a detector
and a component. it has one optical port for light to be incident on, then it can have
one or several output electrical ports. This means instead of taking transfer functions
from some signal generator to a detector, we can simple take specify electrical or
mechanical nodes to inject a signal at, then simply read the result out at another node.
Consider a similar example to what we discussed in the previous section: a laser beam
reflected from a mirror far away then back on to a photodiode. Instead of specifying a
pd1 we now use a
readout_dc component which we’ll call
This models a photodiode which measures signal fluctuations and converts it into an
electrical output at the port
REFL.DC. You’ll notice in this we do not need to
specify the signal frequency like we did previously with
import finesse finesse.init_plotting() model = finesse.Model() model.parse(""" l l1 P=1 s s1 l1.p1 m1.p1 L=10k m m1 R=1 T=0 readout_dc REFL l1.p1.i butter current_drive 1 lowpass 5k link(current_drive, l1.amp) fsig(1) """)
Now we introduce a new analysis that can be performed on a model, the
frequency_response action. This single action allows you to inject multiple signals
and read them out at multiple outputs over a generic frequency vector. Above we use the
geomspace(start, stop, steps) (:seealso:
numpy.geomspace) to create a
logarithmic vector (
linspace is also available as well as specify arbitrary ones,
[1, 10, 11.5, 18]). Next we provide an array of inputs nodes, followed by an
array (or singular in this case) output node.
model.parse(""" frequency_response( geomspace(100, 100k, 100), # frequency vector [current_drive.p1.i, l1.amp.i], # injection nodes REFL.DC.o # output nodes ) """) sol = model.run() sol.plot();
<Figure size 576x355.968 with 0 Axes>
sol.plot_readouts(); # alternate plot method
In cases where a port only has a single node you can just write the port for
REFL.DC.o is equivalent to
REFL.DC when some element or command
expects a node.