List of Examples
FODO Cell Example
1import os
2from pathlib import Path
3
4import matplotlib.pyplot as plt
5
6from pymadng import MAD
7
8original_dir = Path.cwd()
9os.chdir(Path(__file__).resolve().parent)
10
11# The typical way to communicate with MAD-NG is to use the send and recv methods.
12with MAD() as mad:
13 mad.send("""
14 MADX:load("fodo.seq", "fodo.mad")
15 local seq in MADX
16 seq.beam = beam -- use default beam
17 mtbl, mflw = twiss {sequence=seq, implicit=true, nslice=10, save="atbody"}
18 py:send(mtbl)
19 """)
20 mtbl = mad.recv("mtbl")
21 plt.plot(mtbl.s, mtbl.beta11, "r-", label="Method 1")
22
23 mad.send("""py:send(mtbl.s) ; py:send(mtbl.beta11)""")
24 plt.plot(
25 mad.recv(),
26 mad.recv(),
27 "g--",
28 label="Method 2",
29 )
30
31 plt.plot(mad.mtbl.s, mad.mtbl.beta11, "b:", label="Method 3")
32
33 plt.legend()
34 plt.show()
35
36# If you prefer to use pythonic syntax, the following code is equivalent to the above (- some plotting)(+ writing to a file)
37with MAD() as mad:
38 mad.MADX.load("'fodo.seq'", "'fodo.mad'")
39 mad.load("MADX", "seq")
40 mad.seq.beam = mad.beam()
41 mad["mtbl", "mflw"] = mad.twiss(sequence=mad.seq, implicit=True, nslice=10, save="'atbody'")
42 cols = mad.quote_strings(["name", "s", "beta11", "beta22", "mu1", "mu2", "alfa11", "alfa22"])
43 mad.mtbl.write("'twiss_py.tfs'", cols)
44
45 for x in mad.seq: # If an object is iterable, it is possible to loop over it
46 print(x.name, x.kind)
47
48 plt.plot(mad.mtbl.s, mad.mtbl.beta11)
49 plt.show()
50
51os.chdir(original_dir)
PS Twiss Example
1import os
2from pathlib import Path
3
4from pymadng import MAD
5
6original_dir = Path.cwd()
7os.chdir(Path(__file__).parent)
8
9with MAD(debug=False) as mad:
10 mad["psbeam"] = mad.beam(particle="'proton'", pc=2.794987)
11 mad.MADX.BEAM = mad.psbeam
12 mad.MADX.BRHO = mad.psbeam.brho
13 mad.MADX.load("'ps_unset_vars.mad'")
14 mad.MADX.load("'ps_mu.seq'")
15 mad.MADX.load("'ps_ss.seq'")
16 mad.MADX.load("'ps_fb_lhc.str'")
17
18 mad.load("MADX", "ps")
19 mad.ps.beam = mad.psbeam
20 mad["srv", "mflw"] = mad.survey(sequence=mad.ps)
21
22 mad.srv.write(
23 "'PS_survey_py.tfs'",
24 mad.quote_strings(["name", "kind", "s", "l", "angle", "x", "y", "z", "theta"]),
25 )
26
27 mad["mtbl", "mflw"] = mad.twiss(sequence=mad.ps, method=6, nslice=3)
28
29 mad.load("MAD.gphys", "melmcol")
30 # Add element properties as columns
31 # fmt: off
32 mad.melmcol(mad.mtbl,
33 mad.quote_strings(
34 ["angle", "tilt", "k0l", "k1l", "k2l", "k3l", "k4l", "k5l", "k6l", "k0sl",
35 "k1sl", "k2sl", "k3sl", "k4sl", "k5sl", "k6sl", "ksl", "hkick", "vkick" ]),
36 )
37
38 mad.mtbl.write("'PS_twiss_py.tfs'",
39 mad.quote_strings(
40 ["name", "kind", "s", "x", "px", "beta11", "alfa11", "beta22", "alfa22","dx",
41 "dpx", "mu1", "mu2", "l", "angle", "k0l", "k1l", "k2l", "k3l", "hkick", "vkick"]
42 )
43 )
44 # fmt: on
45 df = mad.mtbl.to_df()
46 try:
47 import tfs
48
49 assert type(df) is tfs.TfsDataFrame
50 print("tfs-pandas installed, so the header is stored in headers")
51 print(df.headers)
52 except ImportError:
53 print("tfs-pandas not installed, so the header is stored in attrs instead of headers")
54 print(df.attrs)
55
56 print(df)
57 print(mad.srv.to_df())
58
59os.chdir(original_dir)
LHC Example
1"""
2This script demonstrates the usage of the MAD class to perform a local coupling correction in the LHC.
3
4The aim of this script is demonstrate a combination of pythonic and MAD-NG syntax.
5Also, it demonstrates how you can retrieve data from MAD-NG and plot it in real-time, as it is being calculated, preventing the need to store it in memory.
6"""
7
8import os
9import time
10from pathlib import Path
11
12import matplotlib.pyplot as plt
13
14from pymadng import MAD
15
16original_dir = Path.cwd()
17os.chdir(Path(__file__).parent)
18
19
20with MAD() as mad:
21 mad.load("MAD.utility", "assertf")
22
23 mad.MADX.load("'lhc_as-built.seq'", "'lhc_as-built.mad'")
24 mad.MADX.load("'opticsfile.21'", "'opticsfile.21.mad'")
25 mad.MADX.load("'lhc_unset_vars.mad'") # Load a list of unset variables to prevent warnings
26
27 mad.load("MADX", "lhcb1", "nrj")
28
29 mad.assertf(
30 "#lhcb1 == 6694",
31 "'invalid number of elements %d in LHCB1 (6694 expected)'",
32 "#lhcb1",
33 )
34
35 mad.lhcb1.beam = mad.beam(particle="'proton'", energy=mad.nrj)
36 mad.evaluate_in_madx_environment("""
37 ktqx1_r2 = -ktqx1_l2 ! remove the link between these 2 vars
38 kqsx3_l2 = -0.0015
39 kqsx3_r2 = +0.0015
40 """)
41 t0 = time.time()
42 mad["tbl", "flw"] = mad.twiss(sequence=mad.lhcb1)
43 mad["srv"] = mad.survey(sequence=mad.lhcb1)
44 print(mad.srv)
45 print(mad.srv[0].to_df())
46 mad.tbl.write("'before_tune_correction_n'")
47
48 print("Values before matching")
49 print("dQx.b1=", mad.MADX.dqx_b1)
50 print("dQy.b1=", mad.MADX.dqy_b1)
51
52 mad.send("""
53 expr1 = \\t, s -> t.q1 - 62.30980
54 expr2 = \\t, s -> t.q2 - 60.32154
55 function twiss_and_send()
56 local mtbl, mflow = twiss {sequence=lhcb1}
57 py:send({mtbl.s, mtbl.beta11}, true) -- True means that the data table is sent as a shallow copy
58 return mtbl, mflow
59 end
60 """)
61 match_rtrn = mad.match(
62 command=mad.twiss_and_send,
63 variables=[
64 {"var": "'MADX.dqx_b1'", "name": "'dQx.b1'", "'rtol'": 1e-6},
65 {"var": "'MADX.dqy_b1'", "name": "'dQy.b1'", "'rtol'": 1e-6},
66 ],
67 equalities=[
68 {"expr": mad.expr1, "name": "'q1'", "tol": 1e-3},
69 {"expr": mad.expr2, "name": "'q2'", "tol": 1e-3},
70 ],
71 objective={"fmin": 1e-3},
72 maxcall=100,
73 info=2,
74 )
75 mad.send("py:send(nil)")
76 tws_result = mad.recv()
77 x = tws_result[0]
78 y = tws_result[1]
79
80 plt.ion()
81 fig = plt.figure()
82 ax = fig.add_subplot(111)
83 (line1,) = ax.plot(x, y, "b-")
84 while tws_result:
85 line1.set_xdata(tws_result[0])
86 line1.set_ydata(tws_result[1])
87 fig.canvas.draw()
88 fig.canvas.flush_events()
89 tws_result = mad.recv()
90
91 mad["status", "fmin", "ncall"] = match_rtrn
92 del match_rtrn
93
94 print("Values after matching")
95 print("dQx.b1=", mad.MADX.dqx_b1)
96 print("dQy.b1=", mad.MADX.dqy_b1)
97
98 mad.twiss("tbl", sequence=mad.lhcb1)
99 mad.tbl.write("'after_tune_correction_n'")
100 t1 = time.time()
101 print("Matching time: " + str(t1 - t0) + "s")
102
103os.chdir(original_dir)
Managing References Example
1# Code that does not necessarily work as expected
2import os
3from pathlib import Path
4
5import numpy as np
6
7from pymadng import MAD
8
9original_dir = Path.cwd()
10os.chdir(Path(__file__).parent)
11
12mad = MAD() # Not being in context manager makes not difference.
13
14# Just boring setup (in lots of other examples)
15mad.MADX.load("'fodo.seq'", "'fodo.mad'")
16mad["seq"] = mad.MADX.seq
17mad.seq.beam = mad.beam()
18
19
20# Only one thing is returned from the twiss, a reference (Nothing in python is ever received from MAD after telling MAD-NG to execute)
21twissrtrn = mad.twiss(sequence=mad.seq)
22
23# Any high level MAD-NG function will create a reference
24mad.MAD.gmath.reim(1.42 + 0.62j)
25
26# Try to receive from twiss
27mad["mtbl", "mflw"] = twissrtrn
28
29# mtbl and mflow correctly stored!
30print(mad.mtbl)
31print(mad.mflw[0])
32mad.send(
33 "print(mtbl, mflw[1])"
34) # This will print the table and the particle stored in mflw[1] (lua table)
35
36a_matrix = mad.MAD.matrix(4).seq() # Create 4x4 matrix
37
38print(type(a_matrix)) # Not a 4x4 matrix!
39print(type(a_matrix.eval())) # A 4x4 matrix!
40
41a_matrix = a_matrix.eval() # Store the matrix permanantly
42
43mad["myMatrix"] = mad.MAD.matrix(4).seq()
44print(mad.myMatrix, np.all(a_matrix == mad.myMatrix))
45
46os.chdir(original_dir)
Receiving Data from the LHC Example
1import time
2from pathlib import Path
3
4from pymadng import MAD
5
6current_dir = str(Path(__file__).parent) + "/"
7
8mad = MAD()
9
10mad.send(f"""
11function LHC_load () --Not local!
12 local beam in MAD
13 local assertf in MAD.utility
14
15 MADX:load('{current_dir}lhc_as-built.seq', '{current_dir}lhc_as-built.mad') -- convert and save on need
16 MADX:load('{current_dir}opt_400_10000_400_3000.madx', '{current_dir}opt_400_10000_400_3000.mad') -- ditto
17 MADX:load('{current_dir}lhc_unset_vars.mad') -- handmade, cleaner than disabling warnings...
18
19 local lhcb1, lhcb2 in MADX
20
21 -- sanity checks
22 local n1, n2 = #lhcb1, #lhcb2
23 assertf(n1 == 6677, "invalid number of elements %d in LHCB1 (6677 expected)", n1)
24 assertf(n2 == 6676, "invalid number of elements %d in LHCB2 (6676 expected)", n2)
25 py:send("done")
26end
27""")
28
29mad.send("""
30local is_number, is_string, is_function, is_table in MAD.typeid
31
32expr = {} -- list of deferred expressions
33
34function reg_expr(k,v) -- collect deferred expressions
35 if is_number(v) or is_string(v) then
36 ;
37 elseif is_function(v) then -- deferred expressions are functions
38 expr[#expr+1] = v
39 elseif is_table(v) then
40 for kk, vv in pairs(v) do reg_expr(kk,vv) end -- recursive call
41 else
42 print(k, v, type(v)) -- unexpected for MAD-X, just for debug
43 end
44end
45""")
46
47t0 = time.time()
48mad.LHC_load()
49mad.recv() # done
50t1 = time.time()
51print("Load time:", t1 - t0, " sec\n")
52
53t0 = time.time()
54mad.reg_expr("MADX", mad.MADX)
55mad.send("py:send('done')").recv() # reg_expr is recursive
56t1 = time.time()
57print("reg_expr time:", t1 - t0, " sec\n")
58
59mad.send(
60 "for i=1,#expr do expr[i]() end"
61) # So that warnings are performed here and do no affect timing
62
63
64# Methods of evaluation:
65t0 = time.time()
66mad.send("py:send(#expr)")
67for i in range(mad.recv()):
68 mad.send(f"py:send(expr[{i + 1}]())").recv(f"expr[{i + 1}]()")
69t1 = time.time()
70print("eval time method 1:", t1 - t0, " sec")
71
72t0 = time.time()
73mad.send("len = #expr py:send(len) for i=1,len do py:send(expr[i]()) end")
74for i in range(mad.recv()):
75 mad.recv(f"expr[{i + 1}]()")
76t1 = time.time()
77print("eval time method 2:", t1 - t0, " sec")
78
79t0 = time.time()
80mad.send("py:send(#expr)")
81expr_lst1 = [
82 mad.send(f"py:send(expr[{i + 1}]())").recv(f"expr[{i + 1}]()") for i in range(mad.recv())
83]
84t1 = time.time()
85print("eval time method 3:", t1 - t0, " sec")
86
87t0 = time.time()
88mad.send("len = #expr py:send(len) for i=1,len do py:send(expr[i]()) end")
89expr_lst2 = [mad.recv(f"expr[{i + 1}]()") for i in range(mad.recv())]
90t1 = time.time()
91print("eval time method 4:", t1 - t0, " sec\n")
92
93
94print("sanity check", expr_lst1 == expr_lst2, len(expr_lst1))
95
96t0 = time.time()
97mad["lhcb1"] = mad.MADX.lhcb1
98
99mad.send("""
100py:send(#lhcb1)
101for i, elm, spos, len in lhcb1:iter() do
102 py:send(elm.name)
103end
104""")
105list_of_names = [mad.recv() for _ in range(mad.recv())]
106t1 = time.time()
107print("time to retrieve every element name in lhcb1 sequence", t1 - t0, "sec")
108print(len(list_of_names))
109
110
111t0 = time.time()
112mad["lhcb2"] = mad.MADX.lhcb2
113mad.send("""
114lhcb2_tbl = {}
115for i, elm, spos, len in lhcb2:iter() do
116 lhcb2_tbl[i] = elm.name
117end
118py:send(lhcb2_tbl)
119""")
120list_of_names = mad.recv("lhcb2_tbl")
121t1 = time.time()
122print("time to retrieve every element name in lhcb2 sequence", t1 - t0, "sec")
123print(len(list_of_names))