LHC Example

The file ex-lhc-couplingLocal/ex-lhc-couplingLocal.py contains an example of loading the required files to use and run the LHC, while including a method to receive and plot intermediate results of a match.

Loading the LHC

The following lines loads the required variables and files for the example. assertf is not required, but it is used to check if the loading of the LHC is successful. The two string inputs to mad.MADX.load is also not required, but it is used to specify the final destination of the translated files from MAD-X to MAD-NG. Also, line 5 is not required as this is just to prevent MAD-NG from reporting warnings of unset variables from loading the LHC. Once again, in this extract, the important point to note is that to input strings into functions in MAD-NG, they must be enclosed in quotes. This is because any string input from the side of python is evaluated by MAD-NG, therefore the input can be a variable or expressions.

To grab variables from the MAD-X environment, we use mad.load("MADX", ...).

1with MAD() as mad:
2    mad.load("MAD.utility", "assertf")
3
4    mad.MADX.load("'lhc_as-built.seq'", "'lhc_as-built.mad'")
5    mad.MADX.load("'opticsfile.21'", "'opticsfile.21.mad'")
6    mad.MADX.load("'lhc_unset_vars.mad'")  # Load a list of unset variables to prevent warnings
7
8    mad.load("MADX", "lhcb1", "nrj")
9

Receiving intermediate results

The most complicated part of the example includes the following set of lines.

From lines 4 - 8 below, we define a function that will be invoked during the optimisation process at each iteration. Within this function, we perform a twiss for the match function to use, while also sending some information on the twiss to python, on line 6.

From lines 10 - 23, we run a match, with a reference to the match result returned to the variable match_rtrn. Line 24 is a very important line, as this is something you place in the pipe to MAD-NG for MAD-NG to execute once the match is done. Lines 23-25 receive the first result returned during the match, so that we can start plotting the results.

The plotting occurs between lines 29 - 38, wtih the while loop continuing until twiss result is None, which occurs when the match is done, as requested on line 24.

Finally, on lines 40 and 41, we retrieve the results of the match from the variable match_rtrn. Since match_rtrn is a temporary variable, there is a limit to how many of these that can be stored (see Advanced Features in PyMAD-NG for more information on these), we delete the reference in python to clear the temporary variable so that is is available for future use.

Important

As MAD-NG is running in the background, the variable match_rtrn contains no information and instead must be queried for the results. During the query, python will then have to wait for MAD-NG to finish the match, and then return the results. On the other hand, if we do not query for the results, the match will continue to run in the background, we can do other things in python, and then query for the results later.

 1    print("dQy.b1=", mad.MADX.dqy_b1)
 2
 3    mad.send("""
 4    expr1 = \\t, s -> t.q1 - 62.30980
 5    expr2 = \\t, s -> t.q2 - 60.32154
 6    function twiss_and_send()
 7        local mtbl, mflow = twiss {sequence=lhcb1}
 8        py:send({mtbl.s, mtbl.beta11}, true) -- True means that the data table is sent as a shallow copy
 9        return mtbl, mflow
10    end
11    """)
12    match_rtrn = mad.match(
13        command=mad.twiss_and_send,
14        variables=[
15            {"var": "'MADX.dqx_b1'", "name": "'dQx.b1'", "'rtol'": 1e-6},
16            {"var": "'MADX.dqy_b1'", "name": "'dQy.b1'", "'rtol'": 1e-6},
17        ],
18        equalities=[
19            {"expr": mad.expr1, "name": "'q1'", "tol": 1e-3},
20            {"expr": mad.expr2, "name": "'q2'", "tol": 1e-3},
21        ],
22        objective={"fmin": 1e-3},
23        maxcall=100,
24        info=2,
25    )
26    mad.send("py:send(nil)")
27    tws_result = mad.recv()
28    x = tws_result[0]
29    y = tws_result[1]
30
31    plt.ion()
32    fig = plt.figure()
33    ax = fig.add_subplot(111)
34    (line1,) = ax.plot(x, y, "b-")
35    while tws_result:
36        line1.set_xdata(tws_result[0])
37        line1.set_ydata(tws_result[1])
38        fig.canvas.draw()
39        fig.canvas.flush_events()
40        tws_result = mad.recv()
41