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