@@ -11,24 +11,232 @@ This package provides functions to calculate various optics parameters from **MA
1111## Getting Started
1212
1313The package depends heavily on another one of our packages, ` tfs-pandas ` .
14- Installation is easily done via ` pip ` . The package is then used as ` optics_functions ` .
14+ Installation is easily done via ` pip ` .
15+ The package is then used as ` optics_functions ` .
1516
1617```
1718pip install optics_functions
1819```
1920
20- Example:
21+ ## Documentation
22+
23+ - Autogenerated docs via ` Sphinx ` can be found at < https://pylhc.github.io/optics_functions/ > .
24+ - General documentation of the OMC-Team is located at < https://pylhc.github.io/ >
25+
26+ ## Description
27+
28+ This package serves as a library of functions to calculate various optics parameters such as RDTs and coupling from a MAD-X twiss output.
29+ The functionality mainly manipulates and returns TFS files or ` TfsDataFrame ` objects from the ` tfs-pandas ` package.
30+
31+ ### Modules
32+
33+ - ` coupling ` - Functions to estimate coupling from twiss dataframes and
34+ different methods to calculate the closest tune approach from
35+ the calculated coupling RDTs.
36+ ([ ** coupling.py** ] ( optics_functions/coupling.py ) , [ ** doc** ] ( https://pylhc.github.io/optics_functions/modules/coupling.html ) )
37+ - ` rdt ` - Functions for the calculations of Resonance Driving Terms, as well as
38+ getting lists of valid driving term indices for certain orders.
39+ ([ ** rdt.py** ] ( optics_functions/rdt.py ) , [ ** doc** ] ( https://pylhc.github.io/optics_functions/modules/rdt.html ) )
40+ - ` utils ` - Helper functions to prepare the twiss dataframes for use with the optics
41+ functions as well as reusable utilities,
42+ that are needed within multiple optics calculations.
43+ ([ ** utils.py** ] ( optics_functions/utils.py ) , [ ** doc** ] ( https://pylhc.github.io/optics_functions/modules/utils.html ) )
44+
45+ ### Usage Examples
46+
47+ > :warning : In certain scenarios, e.g. in case of non-zero closed orbit, the RDT
48+ > calculations can be unreliable for ** thick** lattices.
49+ > Convert to a _ thin_ lattice by slicing the lattice reduce the error of the
50+ > analytical approximation.
51+
52+
53+ #### Coupling Example:
2154
2255``` python
23- import optics_functions
56+ import logging
57+ import sys
58+
59+ import tfs # tfs-pandas
60+
61+ from optics_functions.coupling import coupling_via_cmatrix, closest_tune_approach
62+ from optics_functions.utils import split_complex_columns
2463
25- # TODO : Include example once functionality is implemented
64+ logging.basicConfig(stream = sys.stdout, level = logging.INFO , format = " %(message)s " )
65+
66+ # read MAD-X twiss output
67+ df_twiss = tfs.read(" twiss.tfs" , index = " NAME" )
68+
69+ # calculate coupling from the cmatrix
70+ df_coupling = coupling_via_cmatrix(df_twiss)
71+
72+ # Example:
73+ # print(df_coupling)
74+ #
75+ # F1001 F1010 ... C22 GAMMA
76+ # NAME ...
77+ # IP3 -0.000000+0.000004j -0.004026+0.003574j ... -0.007140 1.000058
78+ # MCBWV.4R3.B1 0.000001+0.000004j -0.002429+0.004805j ... -0.009601 1.000058
79+ # BPMW.4R3.B1 0.000001+0.000004j -0.002351+0.004843j ... -0.009678 1.000058
80+ # MQWA.A4R3.B1 0.000001+0.000004j -0.001852+0.005055j ... -0.010102 1.000058
81+ # MQWA.B4R3.B1 0.000001+0.000004j -0.001231+0.005241j ... -0.010474 1.000058
82+ # ... ... ... ... ... ...
83+ # MQWB.4L3.B1 -0.000000+0.000004j -0.005059+0.001842j ... -0.003675 1.000058
84+ # MQWA.B4L3.B1 -0.000000+0.000004j -0.004958+0.002098j ... -0.004187 1.000058
85+ # MQWA.A4L3.B1 -0.000000+0.000004j -0.004850+0.002337j ... -0.004666 1.000058
86+ # BPMW.4L3.B1 -0.000000+0.000004j -0.004831+0.002376j ... -0.004743 1.000058
87+ # MCBWH.4L3.B1 -0.000000+0.000004j -0.004691+0.002641j ... -0.005274 1.000058
88+
89+
90+ # calculate the closest tune approach from the complex rdts
91+ df_dqmin = closest_tune_approach(df_coupling,
92+ qx = df_twiss.Q1, qy = df_twiss.Q2,
93+ method = ' calaga'
94+ )
95+
96+ # Example:
97+ # print(df_dqmin)
98+ #
99+ # DELTAQMIN
100+ # NAME
101+ # IP3 1.760865e-07
102+ # MCBWV.4R3.B1 1.760865e-07
103+ # BPMW.4R3.B1 1.760866e-07
104+ # MQWA.A4R3.B1 1.760865e-07
105+ # MQWA.B4R3.B1 1.760865e-07
106+ # ... ...
107+ # MQWB.4L3.B1 1.760865e-07
108+ # MQWA.B4L3.B1 1.760865e-07
109+ # MQWA.A4L3.B1 1.760866e-07
110+ # BPMW.4L3.B1 1.760865e-07
111+ # MCBWH.4L3.B1 1.760865e-0
112+
113+ # do something with the data.
114+ # (...)
115+
116+ # write out
117+ # as the writer can only handle real data,
118+ # you need to split the rdts into real and imaginary parts before writing
119+ tfs.write(" coupling.tfs" ,
120+ split_complex_columns(df_coupling, columns = [" F1001" , " F1010" ]),
121+ save_index = " NAME"
122+ )
26123```
27124
28- ## Description
125+ #### RDT Example:
29126
30- This package serves as a library of functions to calculate various optics parameters such as RDTs from a MAD-X twiss output.
31- The functionality mainly manipulates and returns TFS files or ` TfsDataFrame ` objects from the ` tfs-pandas ` package.
127+ ``` python
128+ import logging
129+ import sys
130+
131+ import tfs # tfs-pandas
132+
133+ from optics_functions.rdt import calculate_rdts, generator, jklm2str
134+ from optics_functions.utils import prepare_twiss_dataframe, split_complex_columns
135+
136+ logging.basicConfig(stream = sys.stdout, level = logging.INFO , format = " %(message)s " )
137+
138+ # read MAD-X twiss output
139+ df_twiss = tfs.read(" twiss.tfs" , index = " NAME" )
140+
141+ # generate all valid RDT names, here for RDTs of order 2
142+ rdts = [jklm2str(* jklm) for jklm in generator(orders = [2 ])[2 ]]
143+
144+ # check correct signs (i.e if beam==4), merge twiss and errors,
145+ # add empty K(S)L columns if needed
146+ df_twiss = prepare_twiss_dataframe(df_twiss = df_twiss, df_errors = None , max_order = 5 )
147+
148+ # do the actual rdt calculation
149+ df_rdts = calculate_rdts(df_twiss, rdts = rdts,
150+ loop_phases = True , # loop over phase-advance calculation, slower but saves memory
151+ feeddown = 2 , # include feed-down up to this order
152+ complex_columns = True , # complex output
153+ )
154+
155+ # Example:
156+ # print(df_rdts)
157+ # F0002 ... F2000
158+ # NAME ...
159+ # IP3 2.673376-1.045712j ... -2.863617-0.789910j
160+ # MCBWV.4R3.B1 2.475684-1.453081j ... -1.927365-2.260426j
161+ # BPMW.4R3.B1 2.470411-1.462027j ... -1.862287-2.314336j
162+ # MQWA.A4R3.B1 2.440763-1.511004j ... -1.413706-2.612603j
163+ # MQWA.B4R3.B1 2.228282-1.555324j ... -0.788608-2.855177j
164+ # ... ... ... ...
165+ # MQWB.4L3.B1 2.733194+0.167312j ... -2.632290+0.135418j
166+ # MQWA.B4L3.B1 2.763986-0.041253j ... -2.713212+0.063256j
167+ # MQWA.A4L3.B1 2.804960-0.235493j ... -2.847616-0.017922j
168+ # BPMW.4L3.B1 2.858218-0.266543j ... -2.970384-0.032890j
169+ # MCBWH.4L3.B1 2.831426-0.472735j ... -2.966818-0.149180j
170+
171+ # do something with the rdts.
172+ # (...)
173+
174+ # write out
175+ # as the writer can only handle real data, either set real = True above
176+ # or split the rdts into real and imaginary parts before writing
177+ tfs.write(" rdts.tfs" ,
178+ split_complex_columns(df_rdts, columns = rdts),
179+ save_index = " NAME"
180+ )
181+ ```
182+
183+ #### Appending Example:
184+
185+ ``` python
186+ import logging
187+ import sys
188+
189+ import tfs # tfs-pandas
190+
191+ from optics_functions.coupling import coupling_via_cmatrix, closest_tune_approach
192+ from optics_functions.utils import split_complex_columns
193+
194+ logging.basicConfig(stream = sys.stdout, level = logging.INFO , format = " %(message)s " )
195+
196+ # read MAD-X twiss output
197+ df_twiss = tfs.read(" twiss.tfs" , index = " NAME" )
198+
199+ # calculate coupling from the cmatrix and append to original dataframe
200+ # output=['rdts'] is used to avoid the output of the gamma and C## columns.
201+ df_twiss[[" F1001" , " F1010" ]] = coupling_via_cmatrix(df_twiss, output = [' rdts' ])
202+
203+ # Example:
204+ # print(df_twiss)
205+ #
206+ # Headers:
207+ # NAME: TWISS
208+ # TYPE: TWISS
209+ # SEQUENCE: LHCB1
210+ # ...
211+ # ORIGIN: 5.05.02 Linux 64
212+ # DATE: 01/02/21
213+ # TIME: 19.58.08
214+ #
215+ # KEYWORD S ... F1001 F1010
216+ # NAME ...
217+ # IP3 MARKER 0.0000 ... -0.000000+0.000004j -0.004026+0.003574j
218+ # MCBWV.4R3.B1 VKICKER 21.8800 ... 0.000001+0.000004j -0.002429+0.004805j
219+ # BPMW.4R3.B1 MONITOR 22.5205 ... 0.000001+0.000004j -0.002351+0.004843j
220+ # MQWA.A4R3.B1 QUADRUPOLE 26.1890 ... 0.000001+0.000004j -0.001852+0.005055j
221+ # MQWA.B4R3.B1 QUADRUPOLE 29.9890 ... 0.000001+0.000004j -0.001231+0.005241j
222+ # ... ... ... ... ... ...
223+ # MQWB.4L3.B1 QUADRUPOLE 26628.2022 ... -0.000000+0.000004j -0.005059+0.001842j
224+ # MQWA.B4L3.B1 QUADRUPOLE 26632.0022 ... -0.000000+0.000004j -0.004958+0.002098j
225+ # MQWA.A4L3.B1 QUADRUPOLE 26635.8022 ... -0.000000+0.000004j -0.004850+0.002337j
226+ # BPMW.4L3.B1 MONITOR 26636.4387 ... -0.000000+0.000004j -0.004831+0.002376j
227+ # MCBWH.4L3.B1 HKICKER 26641.0332 ... -0.000000+0.000004j -0.004691+0.002641j
228+ ```
229+
230+
231+ ## Quality checks
232+
233+ - Unit and accuracy tests are run automatically through CI [ Github Actions] ( https://github.com/pylhc/optics_functions/actions ) . See our workflows in this [ readme] ( .github/workflows/README.md ) .
234+ - Additional checks for code-complexity, design-rules, test-coverage and duplication are made through [ CodeClimate] ( https://codeclimate.com/github/pylhc/optics_functions ) .
235+ - Pull requests implementing functionality or fixes are merged into the master branch after passing CI, and getting a reviewer's approval.
236+
237+ ### Changelog
238+
239+ See the [ CHANGELOG] ( CHANGELOG.md ) file.
32240
33241## Authors
34242
0 commit comments