FODO Examples
The file ex-fodo/ex-fodos.py has several methods of loading the same FODO cell and then plotting \(s\) and \(\beta_{xx}\) (known as beta11 in MAD-NG).
For the simplest low level example, see here
Simple (higher level) example
The first example (below) shows how to load a MADX sequence, perform a twiss on it in MAD-NG and then plot \(s\) and \(\beta_{xx}\).
Important points from this examples includes the mad[*args]
notation and the use of double quotations in the function call mad.MADX.load(...)
. The notation mad[*args]
is a method of creating variables within the MAD-NG environment from python variables. The double quotes in the load function are required because strings are interpreted by MAD-NG as scripts, allowing the use of variables in the string.
So going through the example line by line;
Start MAD-NG and name the communication object
mad
Load the MADX sequence in the file fodo.seq and store the translation into fodo.mad.
Grab the variable
seq
from the MADX environment and give it the nameseq
in the MAD-NG environment.Create the default beam object and attach this to the sequence
seq
.Run a twiss (the last three arguments are equivalent to the MADX
plot "interpolate"
) and name the return valuesmtbl
andmflw
in the MAD-NG environment.Create the plot of \(s\) and \(\beta_{xx}\).
Display the plot.
1with MAD() as mad:
2 mad.MADX.load(f"'fodo.seq'", f"'fodo.mad'")
3 mad["seq"] = mad.MADX.seq
4 mad.seq.beam = mad.beam()
5 mad["mtbl", "mflw"] = mad.twiss(sequence=mad.seq, method=4, implicit=True, nslice=10, save="'atbody'")
6 plt.plot(mad.mtbl.s, mad.mtbl.beta11)
7 plt.show()
Different (higher level) example
Going through the example line by line (ignoring lines that have been explained above);
Essentially the same as line 3 in the example above, yet this time you don’t control the naming in the MAD-NG environment, equivalent to
seq = MADX.seq
in MAD-NG.
Create a variable cols, for use in the next line. The use of
py_strs_to_mad_strs
adds quotes around every string in the list, so that they are interpreted as strings in MAD-NG.Write the columns above to the file twiss_py.tfs
Loop through the elements of the sequence
Print the name and kind of element in the sequence
1with MAD() as mad:
2 mad.MADX.load(f"'fodo.seq'", f"'fodo.mad'")
3 mad.load("MADX", "seq")
4 mad.seq.beam = mad.beam()
5 mad["mtbl", "mflw"] = mad.twiss(sequence=mad.seq, method=4, implicit=True, nslice=10, save="'atbody'")
6 cols = mad.py_strs_to_mad_strs(["name", "s", "beta11", "beta22", "mu1", "mu2", "alfa11", "alfa22"])
7 mad.mtbl.write("'twiss_py.tfs'", cols)
8 for x in mad.seq:
9 print(x.name, x.kind)
10 plt.plot(mad.mtbl.s, mad.mtbl.beta11)
11 plt.show()
Lines 8 - 9 are equivalent to
for i in range(len(mad.seq)):
x = mad.seq[i]
print(x.name, x.kind)
Creating a sequence from Python
In this example, we demonstrate creating a sequence from scratch in MAD-NG from python.
Going through the example line by line;
Load the element
quadrupole
from the moduleelement
in MAD-NG, making it available directly, equivalent to the python syntaxfrom element import quadrupole
.Create two variables in the MAD-NG environment,
circum = 60
,lcell = 20
.Create two variables in the MAD-NG environment,
sin = math.sin
,pi = math.pi
(in Python this is equivalent tofrom math import sin, pi
).Create a deferred expression equivalent to
v := 1/(lcell/sin(pi/4)/4)
in MAD-X.Create a quadrupole named
qf
withk1 = v.k
and length of 1.Create a quadrupole named
qd
withk1 = -v.k
and length of 1.Create a sequence using
qf
andqd
, specifying the positions and a length of 60.Attach a default beam to the sequence.
Run a twiss and name the return values
mtbl
andmflw
in the MAD-NG environment.Write the columns
col
to the file twiss_py.tfs.Plot the result (
mad.mtbl["beta11"]
is equivalent tomad.mtbl.beta11
).
1with MAD() as mad:
2 mad.load("element", "quadrupole")
3 mad["circum", "lcell"] = 60, 20
4
5 mad.load("math", "sin", "pi")
6 mad["v"] = mad.deferred(k="1/(lcell/sin(pi/4)/4)")
7
8 mad["qf"] = mad.quadrupole("knl:={0, v.k}", l=1)
9 mad["qd"] = mad.quadrupole("knl:={0, -v.k}", l=1)
10 mad["seq"] = mad.sequence("""
11 qf { at = 0 },
12 qd { at = 0.5 * lcell },
13 qf { at = 1.0 * lcell },
14 qd { at = 1.5 * lcell },
15 qf { at = 2.0 * lcell },
16 qd { at = 2.5 * lcell },
17 """, refer="'entry'", l=mad.circum,)
18 mad.seq.beam = mad.beam()
19 mad["mtbl", "mflw"] = mad.twiss(sequence=mad.seq, method=4, implicit=True, nslice=10, save="'atbody'")
20 cols = mad.py_strs_to_mad_strs(["name", "s", "beta11", "beta22", "mu1", "mu2", "alfa11", "alfa22"])
21 mad.mtbl.write("'twiss_py.tfs'", cols)
22
23 plt.plot(mad.mtbl.s, mad.mtbl["beta11"])
24 plt.title("FODO Cell")
25 plt.xlabel("s")
26 plt.ylabel("beta11")
27 plt.show()
Pure low level example
This is the simplest way to communicate with MAD-NG, but it requires the user to actively, deal with references and sending and receiving of specific data. In this example, three methods of receiving data are shown.
Going through the example line by line;
Send a string with the instructions (from the above examples) to load a sequence, attach the default beam and perform a twiss, then send to Python
mtbl
.
Recieve the object
mtbl
from MAD-NG. As this is an object that cannot be replicated in Python, you receive a reference. This reference must be named the name of the variable in the MAD-NG environment (done within the call of therecv
function), so that you can use the reference to communicate with MAD-NG.Using the reference, grab the attributes
s
andbeta11
and plot them
Ask MAD-NG to send the attributes
s
andbeta11
. (Instead of dealing with the reference, we send the attributes that can be received in Python directly, see this table for more information on these types)Receive and plot the attributes
s
andbeta11
.
Using the MAD-NG object, grab the variable
mtbl
and then the attributess
andbeta11
to plot them (as above)
1with MAD() as mad:
2 mad.send(f"""
3 MADX:load("fodo.seq", "fodo.mad")
4 local seq in MADX
5 seq.beam = beam -- use default beam
6 mtbl, mflw = twiss {{sequence=seq, method=4, implicit=true, nslice=10, save="atbody"}}
7 py:send(mtbl)
8 """)
9 mtbl = mad.recv("mtbl")
10 plt.plot(mtbl.s, mtbl.beta11, "r-", label="Method 1")
11
12 mad.send("""py:send(mtbl.s) ; py:send(mtbl.beta11)""")
13 plt.plot(mad.recv(), mad.recv(), "g--", label="Method 2", )
14
15 plt.plot(mad.mtbl.s, mad.mtbl.beta11, "b:", label="Method 3")
16
17 plt.legend()
18 plt.show()