Migrating from Pykat + Finesse 2¶
Many of the features from Pykat have been integrated directly into Finesse 3 and in some cases, expanded. This leads to some important difference in the usual recipes to produce an interferometer and start modelling, which are summarized below.
Creating a model¶
pykat.finesse.Kat class has been replaced with the
Finesse 2 style KatScript is not the primary way to build new models now, you also
have to call
parse_legacy to parse Finesse 2 style scripts. For example:
from finesse import Model # Create the empty model. ifo = Model() # Parse some components into the model. ifo.parse_legacy( """ l laser 2.5 0.0 0.0 input s s1 1 input n1 m ITM 0.8 0.2 0.0 n1 n2 s s2 70 n2 n3 m ETM 0.999 1e-05 0.0 n3 n4 xaxis ETM phi lin -95 95 1000 """ )
There are two available functions for parsing Finesse 2 style KatScript:
Model.parse_legacy_file(). There are also two
similar functions for parsing the newer Finesse 3 style script
Not all functions are supported by this legacy parser! See Finesse 2 support for more details.
Major syntax changes¶
There have been a number of syntax changes and improvements in Finesse 3. Instead of
an object’s optional attributes being defined via the
attr command, it is now
possible to define all attributes on the object definition line. This also means the
numbered component types like
bs2, etc. are no longer needed. These changes
mean the following code:
m1 ETM 5e-06 5e-05 0.0 nETM1 nETM2 attr EMAx Rcx 25 attr EMAx Rcy 20
can be replaced with:
m ETM T=1e-5 L=1e-6 Rc=10
Another new feature of Finesse 3 syntax is that it allows the use of arbitrary
symbolic expressions with references to other parameters. This removes the need for the
put commands. An example of this syntax in the
Finesse 2 (Section 3.5 of :cite:finesse2_manual) is shown in Finesse 3 form in
See KatScript for more details.
Expand documentation to include free_mass
The kat3 convert command line program bundled with Finesse provides the ability to convert Finesse 2 style KatScript to Finesse 3 style. Note however that this is an experimental feature and does not support all forms of syntax yet. See the documentation for more information.
The port and node system¶
In Finesse 2, each node needs to be uniquely and explicitly named. This requirement has been overcome in Finesse 3. Components now have one or more ports. For example, a mirror has two optical ports, corresponding to each surface. Each port then has multiple nodes. In the case of a mirror, each optical port has two nodes, corresponding to the input and output field at each side of the mirror.
ifo = Model() # Create a laser and mirror. ifo.parse( """ l L0 P=1 s s1 L0.p1 ETM.p1 m ETM T=1e-5 L=1e-6 Rc=10 """ ) # Grab the ETM nodes. ifo.ETM.nodes
OrderedDict([('ETM.p1.i', <OpticalNode ETM.p1.i @ 0x7f3562853580>), ('ETM.p1.o', <OpticalNode ETM.p1.o @ 0x7f3562853490>), ('ETM.p2.i', <OpticalNode ETM.p2.i @ 0x7f3562853940>), ('ETM.p2.o', <OpticalNode ETM.p2.o @ 0x7f3562853340>), ('ETM.mech.z', <MechanicalNode ETM.mech.z @ 0x7f3562853130>), ('ETM.mech.yaw', <MechanicalNode ETM.mech.yaw @ 0x7f3562853640>), ('ETM.mech.pitch', <MechanicalNode ETM.mech.pitch @ 0x7f3562853700>), ('ETM.mech.F_z', <MechanicalNode ETM.mech.F_z @ 0x7f3562853a30>), ('ETM.mech.F_yaw', <MechanicalNode ETM.mech.F_yaw @ 0x7f3562853970>), ('ETM.mech.F_pitch', <MechanicalNode ETM.mech.F_pitch @ 0x7f3562853850>)])
See The port and node system for more details.
In Finesse 3, expressions and functions can be specified inside parameter definitions.
This removes the need for the
m m2 R=&m1.R*0.5 T=1-&m1.R*0.5 phi=cos(&l1.P/10)
Variables, constants and references¶
In Finesse 2, in order to make a parameter of one component track another, a combination of set and put commands would have to be used:
m m1 0.99 0.01 0 n1 n2 m m2 0.5 0.5 0 n3 n4 set refl m1 R set trans m1 T put m2 R $refl put m2 T $trans
In Finesse 3, we can take references to a parameter by prefixing it with an ampersand (&), transforming the above into
m m1 0.99 0.01 m m2 R=&m1.R T=&m1.T
Running a model¶
Similar to Pykat, models can be run by calling the
run() method on the
model object. As before, this produces an output object, which can be plotted.
out = ifo.run()