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;

  1. Start MAD-NG and name the communication object mad

  2. Load the MADX sequence in the file fodo.seq and store the translation into fodo.mad.

  3. Grab the variable seq from the MADX environment and give it the name seq in the MAD-NG environment.

  4. Create the default beam object and attach this to the sequence seq.

  5. Run a twiss (the last three arguments are equivalent to the MADX plot "interpolate") and name the return values mtbl and mflw in the MAD-NG environment.

  6. Create the plot of \(s\) and \(\beta_{xx}\).

  7. 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);

  1. 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.

  1. 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.

  2. Write the columns above to the file twiss_py.tfs

  3. Loop through the elements of the sequence

  4. 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;

  1. Load the element quadrupole from the module element in MAD-NG, making it available directly, equivalent to the python syntax from element import quadrupole.

  2. Create two variables in the MAD-NG environment, circum = 60, lcell = 20.

  3. Create two variables in the MAD-NG environment, sin = math.sin, pi = math.pi (in Python this is equivalent to from math import sin, pi).

  4. Create a deferred expression equivalent to v := 1/(lcell/sin(pi/4)/4) in MAD-X.

  5. Create a quadrupole named qf with k1 = v.k and length of 1.

  6. Create a quadrupole named qd with k1 = -v.k and length of 1.

  7. Create a sequence using qf and qd, specifying the positions and a length of 60.

  8. Attach a default beam to the sequence.

  9. Run a twiss and name the return values mtbl and mflw in the MAD-NG environment.

  10. Write the columns col to the file twiss_py.tfs.

  11. Plot the result (mad.mtbl["beta11"] is equivalent to mad.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;

  1. 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.

  1. 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 the recv function), so that you can use the reference to communicate with MAD-NG.

  2. Using the reference, grab the attributes s and beta11 and plot them

  1. Ask MAD-NG to send the attributes s and beta11. (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)

  2. Receive and plot the attributes s and beta11.

  1. Using the MAD-NG object, grab the variable mtbl and then the attributes s and beta11 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()