Tutorial

[1]:
from latticeadaptor.core import LatticeAdaptor

Properties

[2]:
la = LatticeAdaptor()
la.__dict__
[2]:
{'history': <queue.LifoQueue at 0x7f8317468b50>,
 'name': None,
 'len': 0.0,
 '_table': None,
 'filename': None,
 'inputstr': None,
 'builder': <latticeconstructor.core.LatticeBuilderLine at 0x7f8317468940>}

Methods

[3]:
from types import FunctionType
[x for x, y in LatticeAdaptor.__dict__.items() if (type(y) == FunctionType) and not x.startswith('_')]
[3]:
['load_from_file',
 'load_from_string',
 'parse_table_to_madx_sequence_string',
 'parse_table_to_madx_sequence_file',
 'parse_table_to_elegant_string',
 'parse_table_to_elegant_file',
 'parse_table_to_tracy_string',
 'parse_table_to_tracy_file',
 'madx_sequence_add_start_end_marker_string',
 'parse_table_to_madx_install_str',
 'parse_table_to_madx_remove_str',
 'madx_sequence_save_string',
 'add_drifts',
 'parse_table_to_madx_line_string',
 'parse_table_to_madx_line_file',
 'get_quad_strengths',
 'get_sext_strengths',
 'load_strengths_to_table',
 'compare_seq_center_positions',
 'update_table',
 'undo']

Load lattice from string

Lattices can be loaded from string or from file. Currently two lattice formats are implemented: - lte - madx (both sequence and line def)

[4]:
 latticestring = """
QF : QUADRUPOLE, L := 0.50 , K1 :=  1.00;
QD : QUADRUPOLE, L := 1.00 , K1 := -1.00;
D1 : DRIFT, L := 1.00;
D2 : DRIFT, L := 1.00;

FODO: SEQUENCE, L=4.00;
QF, at = 0.25;
D1, at = 1.00;
QD, at = 2.00;
D2, at = 3.00;
QF, at = 3.75;
ENDSEQUENCE;
"""
la1 = LatticeAdaptor()
la1.load_from_string(latticestring, ftype='madx')
Length has been autoset - check if value is ok - otherwise update it.
[5]:
la1.name, la1.len
[5]:
('FODO', 4.0)
[6]:
la1.table
[6]:
family L K1 name at
0 QUADRUPOLE 0.5 1.0 QF 0.25
1 DRIFT 1.0 NaN D1 1.00
2 QUADRUPOLE 1.0 -1.0 QD 2.00
3 DRIFT 1.0 NaN D2 3.00
4 QUADRUPOLE 0.5 1.0 QF 3.75

Load lattice from file

[7]:
# first write it to file
la1.parse_table_to_madx_sequence_file('lattice.seq')

# check if written ok
with open('lattice.seq','r') as f:
    dat = f.read()

print(dat)
QF              : QUADRUPOLE  , L:=0.5, K1:=1.0;
D1              : DRIFT       , L:=1.0;
QD              : QUADRUPOLE  , L:=1.0, K1:=-1.0;
D2              : DRIFT       , L:=1.0;
FODO: SEQUENCE, L=4.0;
QF         , at =     0.250000;
D1         , at =     1.000000;
QD         , at =     2.000000;
D2         , at =     3.000000;
QF         , at =     3.750000;
ENDSEQUENCE;
[8]:
la3 = LatticeAdaptor()
la3.load_from_file('lattice.seq',ftype='madx')
la3.table
Length has been autoset - check if value is ok - otherwise update it.
[8]:
family L K1 name at
0 QUADRUPOLE 0.5 1.0 QF 0.25
1 DRIFT 1.0 NaN D1 1.00
2 QUADRUPOLE 1.0 -1.0 QD 2.00
3 DRIFT 1.0 NaN D2 3.00
4 QUADRUPOLE 0.5 1.0 QF 3.75

Create lattice manually

Lattice can also be created manually by defining: - lattice name - lattice length - lattice table as data frame

[9]:
import pandas as pd

# create manually
latticename = 'FODO'
latticelen  = 4.00
latticetable = pd.DataFrame([
    {'name': 'QF','pos': 0.25,'family': 'QUADRUPOLE','L': 0.5,'K1': 1.0,'ANGLE': 0.0,'at': 0.25},
    {'name': 'D1','pos': 1.0,'family': 'DRIFT','L': 1.0,'at': 1.0},
    {'name': 'QD','pos': 2.0,'family': 'QUADRUPOLE','L': 1.0,'K1': -1.0,'at': 2.0},
    {'name': 'D2','pos': 3.0,'family': 'DRIFT','L': 1.0,'at': 3.0},
    {'name': 'QF','pos': 3.75,'family': 'QUADRUPOLE','L': 0.5,'K1': 1.0,'ANGLE': 0.0,'at': 3.75}
    ])

# uplaod it to the latticeadaptor object
la2 = LatticeAdaptor()
la2.name  = latticename
la2.len   = latticelen
la2.table = latticetable

la2.table
[9]:
name pos family L K1 ANGLE at
0 QF 0.25 QUADRUPOLE 0.5 1.0 0.0 0.25
1 D1 1.00 DRIFT 1.0 NaN NaN 1.00
2 QD 2.00 QUADRUPOLE 1.0 -1.0 NaN 2.00
3 D2 3.00 DRIFT 1.0 NaN NaN 3.00
4 QF 3.75 QUADRUPOLE 0.5 1.0 0.0 3.75

Convert table to lattice format

MADX Sequence

[10]:
print(la1.parse_table_to_madx_sequence_string())
QF              : QUADRUPOLE  , L:=0.5, K1:=1.0;
D1              : DRIFT       , L:=1.0;
QD              : QUADRUPOLE  , L:=1.0, K1:=-1.0;
D2              : DRIFT       , L:=1.0;
FODO: SEQUENCE, L=4.0;
QF         , at =     0.250000;
D1         , at =     1.000000;
QD         , at =     2.000000;
D2         , at =     3.000000;
QF         , at =     3.750000;
ENDSEQUENCE;
[11]:
print(la2.parse_table_to_madx_sequence_string())
QF              : QUADRUPOLE  , L:=0.5, K1:=1.0, ;
D1              : DRIFT       , L:=1.0;
QD              : QUADRUPOLE  , L:=1.0, K1:=-1.0;
D2              : DRIFT       , L:=1.0;
FODO: SEQUENCE, L=4.0;
QF         , at =     0.250000;
D1         , at =     1.000000;
QD         , at =     2.000000;
D2         , at =     3.000000;
QF         , at =     3.750000;
ENDSEQUENCE;
[12]:
#save to file
la1.parse_table_to_madx_sequence_file('lattice.seq')

MADX Line

[13]:
print(la1.parse_table_to_madx_sequence_string())
QF              : QUADRUPOLE  , L:=0.5, K1:=1.0;
D1              : DRIFT       , L:=1.0;
QD              : QUADRUPOLE  , L:=1.0, K1:=-1.0;
D2              : DRIFT       , L:=1.0;
FODO: SEQUENCE, L=4.0;
QF         , at =     0.250000;
D1         , at =     1.000000;
QD         , at =     2.000000;
D2         , at =     3.000000;
QF         , at =     3.750000;
ENDSEQUENCE;
[14]:
la1.parse_table_to_madx_line_file('lattice.madx')
with open('lattice.madx','r') as f:
    dat = f.read()
print(dat)
QF              : QUADRUPOLE  , L:=0.5, K1:=1.0;
D1              : DRIFT       , L:=1.0;
QD              : QUADRUPOLE  , L:=1.0, K1:=-1.0;
D2              : DRIFT       , L:=1.0;


FODO: LINE=(QF,D1,QD,D2,QF);
[15]:
 latticestring = """
QF : QUADRUPOLE, L := 0.50 , K1 :=  1.00;
QD : QUADRUPOLE, L := 1.00 , K1 := -1.00;
D1 : DRIFT, L := 1.00;
D2 : DRIFT, L := 1.00;

FODO: SEQUENCE, L=4.00;
QF, at = 0.25;
QD, at = 2.00;
QF, at = 3.75;
ENDSEQUENCE;
"""
la4 = LatticeAdaptor()
la4.load_from_string(latticestring, ftype='madx')
la4.table
Length has been autoset - check if value is ok - otherwise update it.
[15]:
family L K1 name at
0 QUADRUPOLE 0.5 1.0 QF 0.25
1 QUADRUPOLE 1.0 -1.0 QD 2.00
2 QUADRUPOLE 0.5 1.0 QF 3.75
[16]:
la4.parse_table_to_madx_line_file('lattice.madx')
with open('lattice.madx','r') as f:
    dat = f.read()
print(dat)
QF              : QUADRUPOLE  , L:=0.5, K1:=1.0;
D1              : DRIFT       , L:=1.0;
QD              : QUADRUPOLE  , L:=1.0, K1:=-1.0;
D2              : DRIFT       , L:=1.0;


FODO: LINE=(QF,D1,QD,D2,QF);
[17]:
# generate madx inputstring to save sequence file
la1.madx_sequence_save_string('test.seq')
[17]:
"SAVE, SEQUENCE=FODO, file='test.seq';"

Elegant

[18]:
latticestring = """
QF : QUADRUPOLE, L := 0.50 , K1 :=  1.00;
QD : QUADRUPOLE, L := 1.00 , K1 := -1.00;


FODO: SEQUENCE, L=4.00;
QF, at = 0.25;
QD, at = 2.00;
QF, at = 3.75;
ENDSEQUENCE;
"""
la = LatticeAdaptor()
la.load_from_string(latticestring,ftype='madx')
Length has been autoset - check if value is ok - otherwise update it.
[19]:
la.table
[19]:
family L K1 name at
0 QUADRUPOLE 0.5 1.0 QF 0.25
1 QUADRUPOLE 1.0 -1.0 QD 2.00
2 QUADRUPOLE 0.5 1.0 QF 3.75
[20]:
print(la.parse_table_to_elegant_string())
QF              : KQUAD       , L=  0.500000000000, K1=  1.000000000000
D1              : DRIF        , L=  1.000000000000
QD              : KQUAD       , L=  1.000000000000, K1= -1.000000000000
D2              : DRIF        , L=  1.000000000000


FODO: LINE=(QF, D1, QD, D2, QF)
[21]:
la.parse_table_to_elegant_file('lattice.lte')
with open('lattice.lte','r') as f:
    dat = f.read()
print(dat)
QF              : KQUAD       , L=  0.500000000000, K1=  1.000000000000
D1              : DRIF        , L=  1.000000000000
QD              : KQUAD       , L=  1.000000000000, K1= -1.000000000000
D2              : DRIF        , L=  1.000000000000


FODO: LINE=(QF, D1, QD, D2, QF)

Tracy

[22]:
print(la1.parse_table_to_tracy_string())
QF: Quadrupole, L = 0.500000, K = 1.000000, N = Nquad, Method = 4;
D1: Drift, L = 1.0;
QD: Quadrupole, L = 1.000000, K = -1.000000, N = Nquad, Method = 4;
D2: Drift, L = 1.0;


FODO: QF, D1, QD, D2, QF;

ring: FODO;

cell: ring, symmetry = 1;

end;
[23]:
la1.parse_table_to_tracy_file('lattice.lat')
with open('lattice.lat','r') as f:
    dat = f.read()

print(dat)
QF: Quadrupole, L = 0.500000, K = 1.000000, N = Nquad, Method = 4;
D1: Drift, L = 1.0;
QD: Quadrupole, L = 1.000000, K = -1.000000, N = Nquad, Method = 4;
D2: Drift, L = 1.0;


FODO: QF, D1, QD, D2, QF;

ring: FODO;

cell: ring, symmetry = 1;

end;

Lattice operations

Install string for markers at start and end of lattice

[24]:
la1.table
[24]:
family L K1 name at pos
0 QUADRUPOLE 0.5 1.0 QF 0.25 0.25
1 DRIFT 1.0 NaN D1 1.0 1.0
2 QUADRUPOLE 1.0 -1.0 QD 2.0 2.0
3 DRIFT 1.0 NaN D2 3.0 3.0
4 QUADRUPOLE 0.5 1.0 QF 3.75 3.75
[25]:
print(la1.madx_sequence_add_start_end_marker_string())
MSTART      : MARKER      ;
MEND        : MARKER      ;

USE, SEQUENCE=FODO;
SEQEDIT, SEQUENCE = FODO;
FLATTEN;
INSTALL, ELEMENT = MSTART          , AT =     0.000000;
INSTALL, ELEMENT = MEND            , AT =     4.000000;
FLATTEN;
ENDEDIT;

Add drifts back to sequence

[26]:
 latticestring = """
QF : QUADRUPOLE, L := 0.50 , K1 :=  1.00;
QD : QUADRUPOLE, L := 1.00 , K1 := -1.00;
D1 : DRIFT, L := 1.00;
D2 : DRIFT, L := 1.00;

FODO: SEQUENCE, L=4.00;
QF, at = 0.25;
QD, at = 2.00;
QF, at = 3.75;
ENDSEQUENCE;
"""
la4 = LatticeAdaptor()
la4.load_from_string(latticestring, ftype='madx')
la4.table
Length has been autoset - check if value is ok - otherwise update it.
[26]:
family L K1 name at
0 QUADRUPOLE 0.5 1.0 QF 0.25
1 QUADRUPOLE 1.0 -1.0 QD 2.00
2 QUADRUPOLE 0.5 1.0 QF 3.75
[27]:
la4.add_drifts()
la4.table
[27]:
family L K1 name at pos
0 QUADRUPOLE 0.5 1.0 QF 0.25 0.25
1 DRIFT 1.0 NaN D1 NaN 1.0
2 QUADRUPOLE 1.0 -1.0 QD 2.0 2.0
3 DRIFT 1.0 NaN D2 NaN 3.0
4 QUADRUPOLE 0.5 1.0 QF 3.75 3.75

Extract settings

[28]:
la1.get_quad_strengths()
[28]:
{'QF': 1.0, 'QD': -1.0}
[29]:
la1.get_sext_strengths()
[29]:
{}

Load settings

[30]:
from latticeadaptor.utils import highlight_cells
[31]:
settings_dict = {'QF' : 1.53}
la1.load_strengths_to_table(settings_dict,'K1')
la1.table.style.apply(
    highlight_cells,_list=list(settings_dict.values()),color="lightgreen",axis=1
)
[31]:
family L K1 name at pos
0 QUADRUPOLE 0.500000 1.530000 QF 0.250000 0.250000
1 DRIFT 1.000000 nan D1 1.000000 1.000000
2 QUADRUPOLE 1.000000 -1.000000 QD 2.000000 2.000000
3 DRIFT 1.000000 nan D2 3.000000 3.000000
4 QUADRUPOLE 0.500000 1.530000 QF 3.750000 3.750000

Update table from builder

[32]:
la1.name, la1.len, la1.builder.lattice
[32]:
('FODO', 4.0, ['QF', 'D1', 'QD', 'D2', 'QF'])
[33]:
la1.builder.lattice.append("D1")
la1.builder.lattice
[33]:
['QF', 'D1', 'QD', 'D2', 'QF', 'D1']
[34]:
la1.table
[34]:
family L K1 name at pos
0 QUADRUPOLE 0.5 1.53 QF 0.25 0.25
1 DRIFT 1.0 NaN D1 1.0 1.0
2 QUADRUPOLE 1.0 -1.0 QD 2.0 2.0
3 DRIFT 1.0 NaN D2 3.0 3.0
4 QUADRUPOLE 0.5 1.53 QF 3.75 3.75
[35]:
la1.builder.positions
[35]:
name at
0 QF 0.25
1 D1 1.00
2 QD 2.00
3 D2 3.00
4 QF 3.75
[36]:
la1.update_table()
Length has been autoset - check if value is ok - otherwise update it.
[37]:
la1.builder.definitions
[37]:
{'QF': {'family': 'QUADRUPOLE', 'L': 0.5, 'K1': 1.0},
 'QD': {'family': 'QUADRUPOLE', 'L': 1.0, 'K1': -1.0},
 'D1': {'family': 'DRIFT', 'L': 1.0},
 'D2': {'family': 'DRIFT', 'L': 1.0}}
[38]:
la1.name, la1.len, la1.builder.lattice
[38]:
('FODO', 5.0, ['QF', 'D1', 'QD', 'D2', 'QF', 'D1'])
[39]:
la1.builder.positions
[40]:
la1.builder.table
[40]:
family L K1 name at
0 QUADRUPOLE 0.5 1.0 QF 0.25
1 DRIFT 1.0 NaN D1 1.00
2 QUADRUPOLE 1.0 -1.0 QD 2.00
3 DRIFT 1.0 NaN D2 3.00
4 QUADRUPOLE 0.5 1.0 QF 3.75
5 DRIFT 1.0 NaN D1 4.50

Compare settings

[41]:
from latticeadaptor.utils import compare_settings_dicts
from latticeadaptor.utils import Beamlinegraph_compare_from_seq_files
[42]:
la2.compare_seq_center_positions('lattice.seq')
[42]:
(  name_x   pos name_y
 0     QF  0.25     QF
 1     D1  1.00     D1
 2     QD  2.00     QD
 3     D2  3.00     D2
 4     QF  3.75     QF,
 Empty DataFrame
 Columns: [name, pos]
 Index: [])
[43]:
quad_set1 = la1.get_quad_strengths()
quad_set2 = la2.get_quad_strengths()
compare_settings_dicts(quad_set1, quad_set2, threshold=1)
QF           1.000000000000   1.000000000000
QD          -1.000000000000  -1.000000000000
[44]:
quad_set1 = la1.get_quad_strengths()
quad_set2 = la2.get_quad_strengths()
compare_settings_dicts(quad_set1, quad_set2, threshold=.1)
QF           1.000000000000   1.000000000000
QD          -1.000000000000  -1.000000000000
[45]:
latticestring = """
QF : QUADRUPOLE, L := 0.50 , K1 :=  1.00;
QD : QUADRUPOLE, L := 0.75 , K1 := -1.00;

FODO: SEQUENCE, L=4.00;
QF, at = 0.25;
QD, at = 2.00;
QF, at = 3.75;
ENDSEQUENCE;
"""
la4 = LatticeAdaptor()
la4.load_from_string(latticestring, ftype='madx')
la4.parse_table_to_madx_sequence_file('lattice2.seq')
Length has been autoset - check if value is ok - otherwise update it.
[46]:
Beamlinegraph_compare_from_seq_files('lattice.seq','lattice2.seq')
[46]:
(<module 'matplotlib.pyplot' from '/home/mti/anaconda3/envs/lae/lib/python3.9/site-packages/matplotlib/pyplot.py'>,
 <AxesSubplot:xlabel='S[m]'>)
../_images/notebook_Tutorial_65_1.png

Plotting

[47]:
from latticeadaptor.utils import Beamlinegraph_from_seq_file
[48]:
madxseqsymm = """
QF : QUADRUPOLE, L := 0.50 , K1 :=  1.00;
QD : QUADRUPOLE, L := 1.00 , K1 := -1.00;
D1 : DRIFT, L := 1.00;
D2 : DRIFT, L := 1.00;

FODO: SEQUENCE, L=4.00;
QF, at = 0.25;
D1, at = 1.00;
QD, at = 2.00;
D2, at = 3.00;
QF, at = 3.75;
ENDSEQUENCE;
"""
la = LatticeAdaptor()
la.load_from_string(madxseqsymm,ftype='madx')
la.parse_table_to_madx_sequence_file('fodo.seq')
Beamlinegraph_from_seq_file('fodo.seq')
Length has been autoset - check if value is ok - otherwise update it.
[48]:
(<module 'matplotlib.pyplot' from '/home/mti/anaconda3/envs/lae/lib/python3.9/site-packages/matplotlib/pyplot.py'>,
 <AxesSubplot:xlabel='S[m]'>)
../_images/notebook_Tutorial_68_2.png
[49]:
madxseqsymm = """
QF: QUADRUPOLE, L=0.5,K1=0.2;
QD: QUADRUPOLE, L=1.0,K1=-0.2;
B: SBEND, L=1.0, ANGLE=15.0, E1 =7.5, E2=7.5;
FODO: SEQUENCE, L=12.0;
QF, at = 0.25;
B,  at = 3.00;
QD, at = 6.00;
B,  at = 9.00;
QF, at = 11.75;
ENDSEQUENCE;
"""
la = LatticeAdaptor()
la.load_from_string(madxseqsymm,ftype='madx')
la.parse_table_to_madx_sequence_file('fodob.seq')
Beamlinegraph_from_seq_file('fodob.seq')
Length has been autoset - check if value is ok - otherwise update it.
[49]:
(<module 'matplotlib.pyplot' from '/home/mti/anaconda3/envs/lae/lib/python3.9/site-packages/matplotlib/pyplot.py'>,
 <AxesSubplot:xlabel='S[m]'>)
../_images/notebook_Tutorial_69_2.png
[50]:
from latticeadaptor.utils import twissplot
import numpy as np

from cpymad.madx import Madx
madx = Madx(stdout=False)
madx.command.beam(particle='electron',energy=1.7)
madx.call(file='fodo.seq')
madx.use(sequence='FODO')
twiss = madx.twiss()
twissplot(
    twiss, cols=["betx", "bety", "dx"],
    beamlinegraph=True,
    sequence='fodo.seq',
    offset_array = np.array([0.0,7.0]),
    anno=True
)
[50]:
(<module 'matplotlib.pyplot' from '/home/mti/anaconda3/envs/lae/lib/python3.9/site-packages/matplotlib/pyplot.py'>,
 <AxesSubplot:xlabel='S[m]'>)
../_images/notebook_Tutorial_70_1.png

Advanced editing

[51]:
from latticeadaptor.utils import dipole_split_angles_to_dict

dipolename = 'B'
dipolelen  = 6.00
dipoleanglerad = 0.098
anglelistdeg = [1.4,2.5,6.4]
split_dict = dipole_split_angles_to_dict(dipolename,dipolelen,dipoleanglerad,anglelistdeg,verbose=True)
Dipole length [m]       :     6.000000
Dipole Bend Angle [rad] :     0.098000
Dipole Bend Angle [deg] :     5.614986
Dipole Bend Radius [m]  :    61.224490


BM splitting angles               [deg] :     1.400000    2.500000    2.807493    5.614986    6.400000
BM splitting angles  - cumulative [rad] :     0.024435    0.043633    0.049000    0.098000    0.111701
BM splitting angles  - individual [rad] :     0.024435    0.019199    0.005367    0.049000    0.013701
BM splitting lengths - cumulative [m]   :     1.495997    2.671422    3.000000    6.000000    6.838841
BM splitting lengths - individual [m]   :     1.495997    1.175426    0.328578    3.000000    0.838841

[52]:
split_dict
[52]:
{'B': {'lengths': array([1.4959965 , 1.17542582, 0.32857768, 3.        , 0.83884115]),
  'angles': array([0.02443461, 0.01919862, 0.00536677, 0.049     , 0.01370107])}}
[53]:
from latticeadaptor.utils import split_dipoles, filter_family

dfdip  = filter_family(la.table, 'SBEND')
newdip = split_dipoles(dfdip, split_dict ,dipoleanglerad/2)
newdip
[53]:
L at family name pos ANGLE E1 E2 K1
0 0.000000 3.995997 MARKER MBEAMPORT_2A1 3.995997 NaN NaN NaN NaN
1 1.495997 3.247998 SBEND B1_1p40_deg NaN 0.024435 7.5 0.0 NaN
2 0.000000 5.171422 MARKER MBEAMPORT_2A2 5.171422 NaN NaN NaN NaN
3 1.175426 4.583709 SBEND B1_2p50_deg NaN 0.019199 0.0 0.0 NaN
4 0.000000 5.500000 MARKER MB_MIDDLE 5.500000 NaN NaN NaN NaN
5 0.328578 5.335711 SBEND B1_2p81_deg NaN 0.005367 0.0 0.0 NaN
6 3.000000 7.000000 SBEND B2_5p61_deg NaN 0.049000 0.0 0.0 NaN
7 0.000000 9.338841 MARKER MBEAMPORT_2B2 9.338841 NaN NaN NaN NaN
8 0.838841 8.919421 SBEND B2_6p40_deg NaN 0.013701 0.0 7.5 NaN
9 0.000000 9.995997 MARKER MBEAMPORT_2A1 9.995997 NaN NaN NaN NaN
10 1.495997 9.247998 SBEND B1_1p40_deg NaN 0.024435 7.5 0.0 NaN
11 0.000000 11.171422 MARKER MBEAMPORT_2A2 11.171422 NaN NaN NaN NaN
12 1.175426 10.583709 SBEND B1_2p50_deg NaN 0.019199 0.0 0.0 NaN
13 0.000000 11.500000 MARKER MB_MIDDLE 11.500000 NaN NaN NaN NaN
14 0.328578 11.335711 SBEND B1_2p81_deg NaN 0.005367 0.0 0.0 NaN
15 3.000000 13.000000 SBEND B2_5p61_deg NaN 0.049000 0.0 0.0 NaN
16 0.000000 15.338841 MARKER MBEAMPORT_2B2 15.338841 NaN NaN NaN NaN
17 0.838841 14.919421 SBEND B2_6p40_deg NaN 0.013701 0.0 7.5 NaN
[54]:
latticestring = """
QF : QUADRUPOLE, L := 0.50 , K1 :=  1.00;
QD : QUADRUPOLE, L := 0.75 , K1 := -1.00;

FODO: SEQUENCE, L=4.00;
QF, at = 0.25;
QD, at = 2.00;
QF, at = 3.75;
ENDSEQUENCE;
"""
la = LatticeAdaptor()
la.load_from_string(latticestring, ftype='madx')
la.add_drifts()
la.table
Length has been autoset - check if value is ok - otherwise update it.
[54]:
family L K1 name at pos
0 QUADRUPOLE 0.5 1.0 QF 0.25 0.25
1 DRIFT 1.125 NaN D1 NaN 1.0625
2 QUADRUPOLE 0.75 -1.0 QD 2.0 2.0
3 DRIFT 1.125 NaN D2 NaN 2.9375
4 QUADRUPOLE 0.5 1.0 QF 3.75 3.75
[55]:
la.undo()
la.table
[55]:
family L K1 name at
0 QUADRUPOLE 0.50 1.0 QF 0.25
1 QUADRUPOLE 0.75 -1.0 QD 2.00
2 QUADRUPOLE 0.50 1.0 QF 3.75
[56]:
print(la.parse_table_to_madx_install_str())
USE, SEQUENCE=FODO;
SEQEDIT, SEQUENCE = FODO;
FLATTEN;
INSTALL, ELEMENT = QF              , AT =     0.250000;
INSTALL, ELEMENT = QD              , AT =     2.000000;
INSTALL, ELEMENT = QF              , AT =     3.750000;
FLATTEN;
ENDEDIT;
[57]:
print(la.parse_table_to_madx_remove_str())
USE, SEQUENCE=FODO;
SEQEDIT, SEQUENCE = FODO;
FLATTEN;
REMOVE, ELEMENT = QF              ;
REMOVE, ELEMENT = QD              ;
REMOVE, ELEMENT = QF              ;
FLATTEN;
ENDEDIT;

Advanced diplole splitting example

[58]:
# load more complicated lattice
lad = LatticeAdaptor()
lad.load_from_file("bessy_base.seq",ftype='madx')

# filter the dipoles out
dfdip = filter_family(lad.table,"SBEND")
dfdip.head()
Length has been autoset - check if value is ok - otherwise update it.
[58]:
family name L K2 K1 ANGLE E1 E2 at
0 SBEND BM2D1R 0.855 NaN NaN 0.19635 0.098175 0.098175 5.1825
1 SBEND BM1T1R 0.855 NaN NaN 0.19635 0.098175 0.098175 9.8175
2 SBEND BM2T1R 0.855 NaN NaN 0.19635 0.098175 0.098175 20.1825
3 SBEND BM1D2R 0.855 NaN NaN 0.19635 0.098175 0.098175 24.8175
4 SBEND BM2D2R 0.855 NaN NaN 0.19635 0.098175 0.098175 35.1825
[59]:
# dipole values
dipole_length         = 0.855
dipole_bend_angle_rad = np.pi / 16
dipole_bend_angle_deg = np.rad2deg(dipole_bend_angle_rad)
dipole_bend_radius    = dipole_length / dipole_bend_angle_rad

# general splitting
split_angles_BM2_deg  = [4.0, 6.7, dipole_bend_angle_deg -2.0]
split_angles_BM1_deg  = [2.0, dipole_bend_angle_deg - 6.7, dipole_bend_angle_deg - 4.0]

# special splitting - minus signs due to BM2 magnets
split_angles_special = {
    "BM2D2R" : sorted(
    [
        3.7,
        4.0,
        4.1,
        4.3,
        6.7,
        dipole_bend_angle_deg - 2.0,
    ]
),
    "BM2D5R" : sorted(
    [
        3.6580,
        4.0,
        4.129,
        4.299,
        6.7,
        dipole_bend_angle_deg - 2.0,
    ]
)
}

# add all the splitings to a single dict
splitting_dict  = {}

for i, row in dfdip.iterrows():
    if row["name"] not in list(split_angles_special.keys()):
        if "BM1" in row["name"]:
            angle_list = split_angles_BM1_deg

        elif "BM2" in row["name"]:
            angle_list = split_angles_BM2_deg

        else:
            print("NOK")
            break

    else:
        angle_list = split_angles_special[row["name"]]


    splitting_dict = {**splitting_dict,**dipole_split_angles_to_dict(row["name"], row.L, row.ANGLE, angle_list, verbose=True)}
Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     4.000000    5.625000    6.700000    9.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.069813    0.098175    0.116937    0.161443    0.196350
BM splitting angles  - individual [rad] :     0.069813    0.028362    0.018762    0.044506    0.034907
BM splitting lengths - cumulative [m]   :     0.304000    0.427500    0.509200    0.703000    0.855000
BM splitting lengths - individual [m]   :     0.304000    0.123500    0.081700    0.193800    0.152000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     2.000000    4.550000    5.625000    7.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.034907    0.079412    0.098175    0.126536    0.196350
BM splitting angles  - individual [rad] :     0.034907    0.044506    0.018762    0.028362    0.069813
BM splitting lengths - cumulative [m]   :     0.152000    0.345800    0.427500    0.551000    0.855000
BM splitting lengths - individual [m]   :     0.152000    0.193800    0.081700    0.123500    0.304000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     4.000000    5.625000    6.700000    9.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.069813    0.098175    0.116937    0.161443    0.196350
BM splitting angles  - individual [rad] :     0.069813    0.028362    0.018762    0.044506    0.034907
BM splitting lengths - cumulative [m]   :     0.304000    0.427500    0.509200    0.703000    0.855000
BM splitting lengths - individual [m]   :     0.304000    0.123500    0.081700    0.193800    0.152000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     2.000000    4.550000    5.625000    7.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.034907    0.079412    0.098175    0.126536    0.196350
BM splitting angles  - individual [rad] :     0.034907    0.044506    0.018762    0.028362    0.069813
BM splitting lengths - cumulative [m]   :     0.152000    0.345800    0.427500    0.551000    0.855000
BM splitting lengths - individual [m]   :     0.152000    0.193800    0.081700    0.123500    0.304000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     3.700000    4.000000    4.100000    4.300000    5.625000    6.700000    9.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.064577    0.069813    0.071558    0.075049    0.098175    0.116937    0.161443    0.196350
BM splitting angles  - individual [rad] :     0.064577    0.005236    0.001745    0.003491    0.023126    0.018762    0.044506    0.034907
BM splitting lengths - cumulative [m]   :     0.281200    0.304000    0.311600    0.326800    0.427500    0.509200    0.703000    0.855000
BM splitting lengths - individual [m]   :     0.281200    0.022800    0.007600    0.015200    0.100700    0.081700    0.193800    0.152000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     2.000000    4.550000    5.625000    7.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.034907    0.079412    0.098175    0.126536    0.196350
BM splitting angles  - individual [rad] :     0.034907    0.044506    0.018762    0.028362    0.069813
BM splitting lengths - cumulative [m]   :     0.152000    0.345800    0.427500    0.551000    0.855000
BM splitting lengths - individual [m]   :     0.152000    0.193800    0.081700    0.123500    0.304000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     4.000000    5.625000    6.700000    9.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.069813    0.098175    0.116937    0.161443    0.196350
BM splitting angles  - individual [rad] :     0.069813    0.028362    0.018762    0.044506    0.034907
BM splitting lengths - cumulative [m]   :     0.304000    0.427500    0.509200    0.703000    0.855000
BM splitting lengths - individual [m]   :     0.304000    0.123500    0.081700    0.193800    0.152000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     2.000000    4.550000    5.625000    7.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.034907    0.079412    0.098175    0.126536    0.196350
BM splitting angles  - individual [rad] :     0.034907    0.044506    0.018762    0.028362    0.069813
BM splitting lengths - cumulative [m]   :     0.152000    0.345800    0.427500    0.551000    0.855000
BM splitting lengths - individual [m]   :     0.152000    0.193800    0.081700    0.123500    0.304000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     4.000000    5.625000    6.700000    9.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.069813    0.098175    0.116937    0.161443    0.196350
BM splitting angles  - individual [rad] :     0.069813    0.028362    0.018762    0.044506    0.034907
BM splitting lengths - cumulative [m]   :     0.304000    0.427500    0.509200    0.703000    0.855000
BM splitting lengths - individual [m]   :     0.304000    0.123500    0.081700    0.193800    0.152000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     2.000000    4.550000    5.625000    7.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.034907    0.079412    0.098175    0.126536    0.196350
BM splitting angles  - individual [rad] :     0.034907    0.044506    0.018762    0.028362    0.069813
BM splitting lengths - cumulative [m]   :     0.152000    0.345800    0.427500    0.551000    0.855000
BM splitting lengths - individual [m]   :     0.152000    0.193800    0.081700    0.123500    0.304000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     4.000000    5.625000    6.700000    9.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.069813    0.098175    0.116937    0.161443    0.196350
BM splitting angles  - individual [rad] :     0.069813    0.028362    0.018762    0.044506    0.034907
BM splitting lengths - cumulative [m]   :     0.304000    0.427500    0.509200    0.703000    0.855000
BM splitting lengths - individual [m]   :     0.304000    0.123500    0.081700    0.193800    0.152000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     2.000000    4.550000    5.625000    7.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.034907    0.079412    0.098175    0.126536    0.196350
BM splitting angles  - individual [rad] :     0.034907    0.044506    0.018762    0.028362    0.069813
BM splitting lengths - cumulative [m]   :     0.152000    0.345800    0.427500    0.551000    0.855000
BM splitting lengths - individual [m]   :     0.152000    0.193800    0.081700    0.123500    0.304000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     4.000000    5.625000    6.700000    9.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.069813    0.098175    0.116937    0.161443    0.196350
BM splitting angles  - individual [rad] :     0.069813    0.028362    0.018762    0.044506    0.034907
BM splitting lengths - cumulative [m]   :     0.304000    0.427500    0.509200    0.703000    0.855000
BM splitting lengths - individual [m]   :     0.304000    0.123500    0.081700    0.193800    0.152000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     2.000000    4.550000    5.625000    7.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.034907    0.079412    0.098175    0.126536    0.196350
BM splitting angles  - individual [rad] :     0.034907    0.044506    0.018762    0.028362    0.069813
BM splitting lengths - cumulative [m]   :     0.152000    0.345800    0.427500    0.551000    0.855000
BM splitting lengths - individual [m]   :     0.152000    0.193800    0.081700    0.123500    0.304000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     4.000000    5.625000    6.700000    9.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.069813    0.098175    0.116937    0.161443    0.196350
BM splitting angles  - individual [rad] :     0.069813    0.028362    0.018762    0.044506    0.034907
BM splitting lengths - cumulative [m]   :     0.304000    0.427500    0.509200    0.703000    0.855000
BM splitting lengths - individual [m]   :     0.304000    0.123500    0.081700    0.193800    0.152000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     2.000000    4.550000    5.625000    7.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.034907    0.079412    0.098175    0.126536    0.196350
BM splitting angles  - individual [rad] :     0.034907    0.044506    0.018762    0.028362    0.069813
BM splitting lengths - cumulative [m]   :     0.152000    0.345800    0.427500    0.551000    0.855000
BM splitting lengths - individual [m]   :     0.152000    0.193800    0.081700    0.123500    0.304000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     3.658000    4.000000    4.129000    4.299000    5.625000    6.700000    9.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.063844    0.069813    0.072065    0.075032    0.098175    0.116937    0.161443    0.196350
BM splitting angles  - individual [rad] :     0.063844    0.005969    0.002251    0.002967    0.023143    0.018762    0.044506    0.034907
BM splitting lengths - cumulative [m]   :     0.278008    0.304000    0.313804    0.326724    0.427500    0.509200    0.703000    0.855000
BM splitting lengths - individual [m]   :     0.278008    0.025992    0.009804    0.012920    0.100776    0.081700    0.193800    0.152000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     2.000000    4.550000    5.625000    7.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.034907    0.079412    0.098175    0.126536    0.196350
BM splitting angles  - individual [rad] :     0.034907    0.044506    0.018762    0.028362    0.069813
BM splitting lengths - cumulative [m]   :     0.152000    0.345800    0.427500    0.551000    0.855000
BM splitting lengths - individual [m]   :     0.152000    0.193800    0.081700    0.123500    0.304000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     4.000000    5.625000    6.700000    9.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.069813    0.098175    0.116937    0.161443    0.196350
BM splitting angles  - individual [rad] :     0.069813    0.028362    0.018762    0.044506    0.034907
BM splitting lengths - cumulative [m]   :     0.304000    0.427500    0.509200    0.703000    0.855000
BM splitting lengths - individual [m]   :     0.304000    0.123500    0.081700    0.193800    0.152000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     2.000000    4.550000    5.625000    7.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.034907    0.079412    0.098175    0.126536    0.196350
BM splitting angles  - individual [rad] :     0.034907    0.044506    0.018762    0.028362    0.069813
BM splitting lengths - cumulative [m]   :     0.152000    0.345800    0.427500    0.551000    0.855000
BM splitting lengths - individual [m]   :     0.152000    0.193800    0.081700    0.123500    0.304000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     4.000000    5.625000    6.700000    9.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.069813    0.098175    0.116937    0.161443    0.196350
BM splitting angles  - individual [rad] :     0.069813    0.028362    0.018762    0.044506    0.034907
BM splitting lengths - cumulative [m]   :     0.304000    0.427500    0.509200    0.703000    0.855000
BM splitting lengths - individual [m]   :     0.304000    0.123500    0.081700    0.193800    0.152000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     2.000000    4.550000    5.625000    7.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.034907    0.079412    0.098175    0.126536    0.196350
BM splitting angles  - individual [rad] :     0.034907    0.044506    0.018762    0.028362    0.069813
BM splitting lengths - cumulative [m]   :     0.152000    0.345800    0.427500    0.551000    0.855000
BM splitting lengths - individual [m]   :     0.152000    0.193800    0.081700    0.123500    0.304000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     4.000000    5.625000    6.700000    9.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.069813    0.098175    0.116937    0.161443    0.196350
BM splitting angles  - individual [rad] :     0.069813    0.028362    0.018762    0.044506    0.034907
BM splitting lengths - cumulative [m]   :     0.304000    0.427500    0.509200    0.703000    0.855000
BM splitting lengths - individual [m]   :     0.304000    0.123500    0.081700    0.193800    0.152000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     2.000000    4.550000    5.625000    7.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.034907    0.079412    0.098175    0.126536    0.196350
BM splitting angles  - individual [rad] :     0.034907    0.044506    0.018762    0.028362    0.069813
BM splitting lengths - cumulative [m]   :     0.152000    0.345800    0.427500    0.551000    0.855000
BM splitting lengths - individual [m]   :     0.152000    0.193800    0.081700    0.123500    0.304000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     4.000000    5.625000    6.700000    9.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.069813    0.098175    0.116937    0.161443    0.196350
BM splitting angles  - individual [rad] :     0.069813    0.028362    0.018762    0.044506    0.034907
BM splitting lengths - cumulative [m]   :     0.304000    0.427500    0.509200    0.703000    0.855000
BM splitting lengths - individual [m]   :     0.304000    0.123500    0.081700    0.193800    0.152000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     2.000000    4.550000    5.625000    7.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.034907    0.079412    0.098175    0.126536    0.196350
BM splitting angles  - individual [rad] :     0.034907    0.044506    0.018762    0.028362    0.069813
BM splitting lengths - cumulative [m]   :     0.152000    0.345800    0.427500    0.551000    0.855000
BM splitting lengths - individual [m]   :     0.152000    0.193800    0.081700    0.123500    0.304000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     4.000000    5.625000    6.700000    9.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.069813    0.098175    0.116937    0.161443    0.196350
BM splitting angles  - individual [rad] :     0.069813    0.028362    0.018762    0.044506    0.034907
BM splitting lengths - cumulative [m]   :     0.304000    0.427500    0.509200    0.703000    0.855000
BM splitting lengths - individual [m]   :     0.304000    0.123500    0.081700    0.193800    0.152000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     2.000000    4.550000    5.625000    7.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.034907    0.079412    0.098175    0.126536    0.196350
BM splitting angles  - individual [rad] :     0.034907    0.044506    0.018762    0.028362    0.069813
BM splitting lengths - cumulative [m]   :     0.152000    0.345800    0.427500    0.551000    0.855000
BM splitting lengths - individual [m]   :     0.152000    0.193800    0.081700    0.123500    0.304000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     4.000000    5.625000    6.700000    9.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.069813    0.098175    0.116937    0.161443    0.196350
BM splitting angles  - individual [rad] :     0.069813    0.028362    0.018762    0.044506    0.034907
BM splitting lengths - cumulative [m]   :     0.304000    0.427500    0.509200    0.703000    0.855000
BM splitting lengths - individual [m]   :     0.304000    0.123500    0.081700    0.193800    0.152000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     2.000000    4.550000    5.625000    7.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.034907    0.079412    0.098175    0.126536    0.196350
BM splitting angles  - individual [rad] :     0.034907    0.044506    0.018762    0.028362    0.069813
BM splitting lengths - cumulative [m]   :     0.152000    0.345800    0.427500    0.551000    0.855000
BM splitting lengths - individual [m]   :     0.152000    0.193800    0.081700    0.123500    0.304000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     4.000000    5.625000    6.700000    9.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.069813    0.098175    0.116937    0.161443    0.196350
BM splitting angles  - individual [rad] :     0.069813    0.028362    0.018762    0.044506    0.034907
BM splitting lengths - cumulative [m]   :     0.304000    0.427500    0.509200    0.703000    0.855000
BM splitting lengths - individual [m]   :     0.304000    0.123500    0.081700    0.193800    0.152000

Dipole length [m]       :     0.855000
Dipole Bend Angle [rad] :     0.196350
Dipole Bend Angle [deg] :    11.250000
Dipole Bend Radius [m]  :     4.354479


BM splitting angles               [deg] :     2.000000    4.550000    5.625000    7.250000   11.250000
BM splitting angles  - cumulative [rad] :     0.034907    0.079412    0.098175    0.126536    0.196350
BM splitting angles  - individual [rad] :     0.034907    0.044506    0.018762    0.028362    0.069813
BM splitting lengths - cumulative [m]   :     0.152000    0.345800    0.427500    0.551000    0.855000
BM splitting lengths - individual [m]   :     0.152000    0.193800    0.081700    0.123500    0.304000

[60]:
# check one of the entries
splitting_dict['BM2D1R']
[60]:
{'lengths': array([0.304 , 0.1235, 0.0817, 0.1938, 0.152 ]),
 'angles': array([0.06981317, 0.0283616 , 0.01876229, 0.0445059 , 0.03490658])}
[61]:
# create a table containing the beamport markers

# split the dipoles and add the markers (auto-named)
dfbeamports = split_dipoles(dfdip, splitting_dict, dipole_bend_angle_rad/2.0)

# update the pos
dfbeamports['pos'] = dfbeamports['at']
dfbeamports = dfbeamports.sort_values(by="pos").reset_index(drop=True)
[62]:
dfbeamports.head(10)
[62]:
L at family name pos ANGLE E1 E2 K1 K2
0 0.3040 4.90700 SBEND BM2D1R1_4p00_deg 4.90700 0.069813 0.098175 0.000000 NaN NaN
1 0.0000 5.05900 MARKER MBEAMPORT_2A1 5.05900 NaN NaN NaN NaN NaN
2 0.1235 5.12075 SBEND BM2D1R1_5p62_deg 5.12075 0.028362 0.000000 0.000000 NaN NaN
3 0.0000 5.18250 MARKER MBM2D1R_MIDDLE 5.18250 NaN NaN NaN NaN NaN
4 0.0817 5.22335 SBEND BM2D1R2_6p70_deg 5.22335 0.018762 0.000000 0.000000 NaN NaN
5 0.0000 5.26420 MARKER MBEAMPORT_2B1 5.26420 NaN NaN NaN NaN NaN
6 0.1938 5.36110 SBEND BM2D1R2_9p25_deg 5.36110 0.044506 0.000000 0.000000 NaN NaN
7 0.0000 5.45800 MARKER MBEAMPORT_2B2 5.45800 NaN NaN NaN NaN NaN
8 0.1520 5.53400 SBEND BM2D1R2_11p25_deg 5.53400 0.034907 0.000000 0.098175 NaN NaN
9 0.1520 9.46600 SBEND BM1T1R1_2p00_deg 9.46600 0.034907 0.098175 0.000000 NaN NaN
[63]:
# sort, add sectors
dfbeamportssec = dfbeamports.copy().sort_values(by="pos").reset_index(drop=True)
dfbeamportssec['sector'] = dfbeamportssec["name"].apply(lambda x: x[3:5] if (not "PORT" in x) and not "MIDDLE" in x else np.nan)
dfbeamportssec["sector"] = dfbeamportssec["sector"].fillna(method="ffill")

# check out the D2 sector
dfbeamportssec.loc[dfbeamportssec.sector=="D2"].sort_values(by="pos").head()
[63]:
L at family name pos ANGLE E1 E2 K1 K2 sector
27 0.1520 24.46600 SBEND BM1D2R1_2p00_deg 24.46600 0.034907 0.098175 0.0 NaN NaN D2
28 0.0000 24.54200 MARKER MBEAMPORT_1A1 24.54200 NaN NaN NaN NaN NaN D2
29 0.1938 24.63890 SBEND BM1D2R1_4p55_deg 24.63890 0.044506 0.000000 0.0 NaN NaN D2
30 0.0000 24.73580 MARKER MBEAMPORT_1A2 24.73580 NaN NaN NaN NaN NaN D2
31 0.0817 24.77665 SBEND BM1D2R1_5p62_deg 24.77665 0.018762 0.000000 0.0 NaN NaN D2
[64]:
# highlighting some beamports - visual checking
from latticeadaptor.utils import highlight_cells, highlight_row

dfbeamportssec.loc[dfbeamportssec.sector=="D2"][-15:].style.apply(
    highlight_row,_list=["MBEAMPORT_2A1","MBEAMPORT_2A3","MBEAMPORT_2A4"], column=["name"],axis=1
).apply(highlight_row,_list=["BM2D2R1_3p70_deg","BM2D2R1_4p10_deg","BM2D2R1_4p30_deg"], column=["name"],color="orange",axis=1)
[64]:
L at family name pos ANGLE E1 E2 K1 K2 sector
36 0.281200 34.895600 SBEND BM2D2R1_3p70_deg 34.895600 0.064577 0.098175 0.000000 nan nan D2
37 0.000000 35.036200 MARKER MBEAMPORT_2A1 35.036200 nan nan nan nan nan D2
38 0.022800 35.047600 SBEND BM2D2R1_4p00_deg 35.047600 0.005236 0.000000 0.000000 nan nan D2
39 0.000000 35.059000 MARKER MBEAMPORT_2A2 35.059000 nan nan nan nan nan D2
40 0.007600 35.062800 SBEND BM2D2R1_4p10_deg 35.062800 0.001745 0.000000 0.000000 nan nan D2
41 0.000000 35.066600 MARKER MBEAMPORT_2A3 35.066600 nan nan nan nan nan D2
42 0.015200 35.074200 SBEND BM2D2R1_4p30_deg 35.074200 0.003491 0.000000 0.000000 nan nan D2
43 0.000000 35.081800 MARKER MBEAMPORT_2A4 35.081800 nan nan nan nan nan D2
44 0.100700 35.132150 SBEND BM2D2R1_5p62_deg 35.132150 0.023126 0.000000 0.000000 nan nan D2
45 0.000000 35.182500 MARKER MBM2D2R_MIDDLE 35.182500 nan nan nan nan nan D2
46 0.081700 35.223350 SBEND BM2D2R2_6p70_deg 35.223350 0.018762 0.000000 0.000000 nan nan D2
47 0.000000 35.264200 MARKER MBEAMPORT_2B1 35.264200 nan nan nan nan nan D2
48 0.193800 35.361100 SBEND BM2D2R2_9p25_deg 35.361100 0.044506 0.000000 0.000000 nan nan D2
49 0.000000 35.458000 MARKER MBEAMPORT_2B2 35.458000 nan nan nan nan nan D2
50 0.152000 35.534000 SBEND BM2D2R2_11p25_deg 35.534000 0.034907 0.000000 0.098175 nan nan D2
[65]:
# rename some of the auto-named markers
dfbeamports.loc[37, "name"] = "M_PINHOLE3"
dfbeamports.loc[41, "name"] = "M_OLD_STREAK_CAMERA"
dfbeamports.loc[43, "name"] = "M_ADP_FILL_PATTERN"

# check if updated in original seq table
dfbeamports[36:50].style.apply(
    highlight_cells,
    _list=["M_PINHOLE3","M_OLD_STREAK_CAMERA","M_ADP_FILL_PATTERN"],
    color="lightgreen")
[65]:
L at family name pos ANGLE E1 E2 K1 K2
36 0.281200 34.895600 SBEND BM2D2R1_3p70_deg 34.895600 0.064577 0.098175 0.000000 nan nan
37 0.000000 35.036200 MARKER M_PINHOLE3 35.036200 nan nan nan nan nan
38 0.022800 35.047600 SBEND BM2D2R1_4p00_deg 35.047600 0.005236 0.000000 0.000000 nan nan
39 0.000000 35.059000 MARKER MBEAMPORT_2A2 35.059000 nan nan nan nan nan
40 0.007600 35.062800 SBEND BM2D2R1_4p10_deg 35.062800 0.001745 0.000000 0.000000 nan nan
41 0.000000 35.066600 MARKER M_OLD_STREAK_CAMERA 35.066600 nan nan nan nan nan
42 0.015200 35.074200 SBEND BM2D2R1_4p30_deg 35.074200 0.003491 0.000000 0.000000 nan nan
43 0.000000 35.081800 MARKER M_ADP_FILL_PATTERN 35.081800 nan nan nan nan nan
44 0.100700 35.132150 SBEND BM2D2R1_5p62_deg 35.132150 0.023126 0.000000 0.000000 nan nan
45 0.000000 35.182500 MARKER MBM2D2R_MIDDLE 35.182500 nan nan nan nan nan
46 0.081700 35.223350 SBEND BM2D2R2_6p70_deg 35.223350 0.018762 0.000000 0.000000 nan nan
47 0.000000 35.264200 MARKER MBEAMPORT_2B1 35.264200 nan nan nan nan nan
48 0.193800 35.361100 SBEND BM2D2R2_9p25_deg 35.361100 0.044506 0.000000 0.000000 nan nan
49 0.000000 35.458000 MARKER MBEAMPORT_2B2 35.458000 nan nan nan nan nan