Welcome to latticeadaptor’s documentation!

latticeadaptor

Documentation Status https://mybinder.org/badge_logo.svg

This package is used to convert a table of accelerator lattice elements and their arguments to various accelerator lattice formats. Currently covered are:

  • MadX (Sequence and Line format)

  • Elegant

  • Tracy

Features

  • Fast lattice comparison by plotting element locations against eachother.

  • Fast settings compare by comparing magnet settings.

  • Quick twiss plotting.

  • Quick lattice element plotting.

  • Conversion from table to standard formats.

Installation

Stable release

To install latticeadaptor, run this command in your terminal:

$ pip install latticeadaptor

This is the preferred method to install latticeadaptor, as it will always install the most recent stable release.

If you don’t have pip installed, this Python installation guide can guide you through the process.

From sources

The sources for latticeadaptor can be downloaded from the Github repo.

You can either clone the public repository:

$ git clone git://github.com/tomerten/latticeadaptor

Or download the tarball:

$ curl  -OL https://github.com/tomerten/latticeadaptor/tarball/master

Once you have a copy of the source, you can install it with:

$ python setup.py install

API

Package latticeadaptor

Top-level package for latticeadaptor.

latticeadaptor.hello(who='world')

‘Hello world’ method.

Parameters

who (str) – whom to say hello to

Returns

a string

Module latticeadaptor.lark

A module containing the madx lark file.

Module latticeadaptor.mappings

A module containing mappings between elements and attributes for the different lattice formats used: * MadX * Elegant * Tracy

Development

  • Tom Mertens

History

v0.0.0 (2021-05-05)

v0.3.7 (2021-07-06) : correction to calculate lattice lengths when using madx sequence files.

v0.3.8 (2021-07-07) : update dependency version numbers

v0.3.9 (2021-07-07) : update dependency version numbers latticejson and latticeconstructor (updated elegant mapping)

This package was created with package et-micc,

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

Indices and tables