Skip to content

Interface to MAD-X (cpymad)

The interface between the python code and MAD-X is obtained using the cpymad library. For details about the library please see the related documentation.

In the following we will list some of its capabilities.

Mad-X is started by instantiating a python object:

from cpymad.madx import Madx
mad = Madx()

Independent mad instancies can be handled within the same python session:

mad_1 = Madx()
mad_2 = Madx()

The MAD-X syntax can be used through the input command:

mad.input('a = 10;')
mad.input('b := 2*a;')
mad.input('call, file="optics.madx";')

# Here some values are passed through python f-strings
qp = 15
qx = 62.31
qy = 60.32
mad.input(f'''
    match,chrom;
    global, dq1={qp}, dq2={qp};
    global, q1={qx}, q2={qy};
    vary,   name=ksf;
    vary,   name=ksd;
    vary,   name=kqtf, step=1.0E-7 ;
    vary,   name=kqtd, step=1.0E-7 ;
    lmdif,  calls=500, tolerance=1.0E-21;
    endmatch;
''')

MAD-X variables are accessible in python:

b = mad.globals.a

Pythonic access to MAD-X tables is available:

mad.use('lhcb1')
twiss_table = mad.twiss()
twiss_dataframe = twiss_table.dframe()
plt.plot(twiss_dataframe.s, twiss_dataframe.betx)
Pythonic access to MAD-X element properties is available as well:
print(mad.elements['mqml.6l1.b2..4'].knl) # read
mad.elements['mqml.6l1.b2..4'].knl = [0, 2e-3] #write

Variables inspection

One of the difficulties for the MAD-X users is to understand what are the constant and variables (dependent or independent) of MAD-X. For example, one could wonder what are the knobs that are controlling a given MAD-X sequence.

With cpymad and pymask this can be easily done. Here you are a simple example (you need to have installed pymask):

import pymask as pm
Madx = pm.Madxp
mad = Madx(command_log="my_log.log")
mad.input('''
! variables definition
a=1;
b:=c+3*a+sqrt(d)+pi;
c:=a+2+e; 
d:=2+f;
f=g;
h:=3;
const i=2;
! element definition
my_quad: quadrupole, l=1, k1:=(h+b)/1000;
! sequence definition
my_sequence: sequence,l=10, refer=exit;
q1: my_quad, at=3;
endsequence;
! beam definition
beam, sequence=my_sequence;
! use sequence
use, sequence=my_sequence;
''');

Info

Note that if you want you can always run the "my_log.log" as a raw MAD-X input (without python).

To list the constant and variables of your MAD-X instance you can type:

my_df=mad.get_variables_dataframes()
my_df['constants']
Then you will obtain the following table of the MAD-X constant. Please note that the i constant is user-defined.

value
amu0 1.25664e-06
clight 2.99792e+08
degrad 57.2958
e 2.71828
emass 0.000510999
erad 2.81794e-15
hbar 6.58212e-25
i 2
mumass 0.105658
nmass 0.939565
pi 3.14159
pmass 0.938272
prad 1.5347e-18
qelect 1.60218e-19
raddeg 0.0174533
twopi 6.28319
version 50601

Similarly you can obtain the independent and dependent variables.

my_df['independent_variables']
value
a 1
f 0
g 0
h 3
none 0
twiss_tol 1e-06
my_df['dependent_variables']
value expression parameters knobs
b 13.2741 c+3*a+sqrt(d)+pi ['a', 'c', 'd', 'pi'] ['a', 'f']
c 5.71828 a+2+e ['a', 'e'] ['a']
d 2 2+f ['f'] ['f']

For the dependent variables (the one assigned by deferred expressions) you have the name of the knobs that are controlling them.

You can also retrieve the knobs attached to the elements of your sequence by

result=mad.get_sequence_df('my_sequence')[['position','parent','parameters','knobs']]
result

position parent parameters knobs
my_sequence$start 0 marker ['none'] ['none']
q1 2 my_quad ['b' 'h' 'none'] ['a', 'f', 'h', 'none']
my_sequence$end 10 marker ['none'] ['none']

Finally the knobs of your sequence can be retrieved by

set([knobs for element_knobs in result['knobs'] for knobs in element_knobs])

that is

{'a', 'f', 'h', 'none'}