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)
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']
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'}