Package: optics-functions
optics_functionsThis package provides functions to calculate various optics parameters fromMAD-X TWISSoutputs, such as RDTs and coupling.
The functionality mainly manipulates and returnsTFSfiles orTfsDataFrameobjects from ourtfs-pandaspackage.See theAPI documentationfor details.InstallingInstallation is easily done viapip:python-mpipinstalloptics_functionsOne can also install in acondaenvironment via theconda-forgechannel with:condainstall-cconda-forgeoptics_functionsExample UsageWarning:In certain scenarios, e.g. in case of non-zero closed orbit, theRDTcalculations can be unreliable forthicklattices.
Convert to athinlattice by slicing the lattice to reduce the error of the analytical approximation.Coupling Example:importloggingimportsysimporttfs# tfs-pandasfromoptics_functions.couplingimportcoupling_via_cmatrix,closest_tune_approachfromoptics_functions.utilsimportsplit_complex_columnslogging.basicConfig(stream=sys.stdout,level=logging.INFO,format="%(message)s")# read MAD-X twiss outputdf_twiss=tfs.read("twiss.tfs",index="NAME")# calculate coupling from the cmatrixdf_coupling=coupling_via_cmatrix(df_twiss)# Example:# print(df_coupling)##                            F1001               F1010  ...       C22     GAMMA# NAME                                                  ...# IP3          -0.000000+0.000004j -0.004026+0.003574j  ... -0.007140  1.000058# MCBWV.4R3.B1  0.000001+0.000004j -0.002429+0.004805j  ... -0.009601  1.000058# BPMW.4R3.B1   0.000001+0.000004j -0.002351+0.004843j  ... -0.009678  1.000058# MQWA.A4R3.B1  0.000001+0.000004j -0.001852+0.005055j  ... -0.010102  1.000058# MQWA.B4R3.B1  0.000001+0.000004j -0.001231+0.005241j  ... -0.010474  1.000058# ...                          ...                 ...  ...       ...       ...# MQWB.4L3.B1  -0.000000+0.000004j -0.005059+0.001842j  ... -0.003675  1.000058# MQWA.B4L3.B1 -0.000000+0.000004j -0.004958+0.002098j  ... -0.004187  1.000058# MQWA.A4L3.B1 -0.000000+0.000004j -0.004850+0.002337j  ... -0.004666  1.000058# BPMW.4L3.B1  -0.000000+0.000004j -0.004831+0.002376j  ... -0.004743  1.000058# MCBWH.4L3.B1 -0.000000+0.000004j -0.004691+0.002641j  ... -0.005274  1.000058# calculate the closest tune approach from the complex rdtsdf_dqmin=closest_tune_approach(df_coupling,qx=df_twiss.Q1,qy=df_twiss.Q2,method='calaga')# Example:# print(df_dqmin)##                  DELTAQMIN# NAME# IP3           1.760865e-07# MCBWV.4R3.B1  1.760865e-07# BPMW.4R3.B1   1.760866e-07# MQWA.A4R3.B1  1.760865e-07# MQWA.B4R3.B1  1.760865e-07# ...                    ...# MQWB.4L3.B1   1.760865e-07# MQWA.B4L3.B1  1.760865e-07# MQWA.A4L3.B1  1.760866e-07# BPMW.4L3.B1   1.760865e-07# MCBWH.4L3.B1  1.760865e-07# do something with the data.# (...)# write out# as the writer can only handle real data,# you need to split the rdts into real and imaginary parts before writingtfs.write("coupling.tfs",split_complex_columns(df_coupling,columns=["F1001","F1010"]),save_index="NAME",)RDT Example:importloggingimportsysimporttfs# tfs-pandasfromoptics_functions.rdtimportcalculate_rdts,generator,jklm2strfromoptics_functions.utilsimportprepare_twiss_dataframe,split_complex_columnslogging.basicConfig(stream=sys.stdout,level=logging.INFO,format="%(message)s")# read MAD-X twiss outputdf_twiss=tfs.read("twiss.tfs",index="NAME")# generate all valid RDT names, here for RDTs of order 2rdts=[jklm2str(*jklm)forjklmingenerator(orders=[2])[2]]# check correct signs (i.e if beam==4), merge twiss and errors,# add empty K(S)L columns if neededdf_twiss=prepare_twiss_dataframe(df_twiss=df_twiss,df_errors=None,max_order=5)# do the actual rdt calculationdf_rdts=calculate_rdts(df_twiss,rdts=rdts,loop_phases=True,# loop over phase-advance calculation, slower but saves memoryfeeddown=2,# include feed-down up to this ordercomplex_columns=True,# complex output)# Example:# print(df_rdts)#                            F0002  ...               F2000# NAME                              ...# IP3           2.673376-1.045712j  ... -2.863617-0.789910j# MCBWV.4R3.B1  2.475684-1.453081j  ... -1.927365-2.260426j# BPMW.4R3.B1   2.470411-1.462027j  ... -1.862287-2.314336j# MQWA.A4R3.B1  2.440763-1.511004j  ... -1.413706-2.612603j# MQWA.B4R3.B1  2.228282-1.555324j  ... -0.788608-2.855177j# ...                          ...  ...                 ...# MQWB.4L3.B1   2.733194+0.167312j  ... -2.632290+0.135418j# MQWA.B4L3.B1  2.763986-0.041253j  ... -2.713212+0.063256j# MQWA.A4L3.B1  2.804960-0.235493j  ... -2.847616-0.017922j# BPMW.4L3.B1   2.858218-0.266543j  ... -2.970384-0.032890j# MCBWH.4L3.B1  2.831426-0.472735j  ... -2.966818-0.149180j# do something with the rdts.# (...)# write out# as the writer can only handle real data, either set real = True above# or split the rdts into real and imaginary parts before writingtfs.write("rdts.tfs",split_complex_columns(df_rdts,columns=rdts),save_index="NAME")Appending Example:importloggingimportsysimporttfs# tfs-pandasfromoptics_functions.couplingimportcoupling_via_cmatrix,closest_tune_approachfromoptics_functions.utilsimportsplit_complex_columnslogging.basicConfig(stream=sys.stdout,level=logging.INFO,format="%(message)s")# read MAD-X twiss outputdf_twiss=tfs.read("twiss.tfs",index="NAME")# calculate coupling from the cmatrix and append to original dataframe# output=['rdts'] is used to avoid the output of the gamma and C## columns.df_twiss[["F1001","F1010"]]=coupling_via_cmatrix(df_twiss,output=['rdts'])# Example:# print(df_twiss)## Headers:# NAME: TWISS# TYPE: TWISS# SEQUENCE: LHCB1# ...# ORIGIN: 5.05.02 Linux 64# DATE: 01/02/21# TIME: 19.58.08##                  KEYWORD           S  ...               F1001               F1010# NAME                                  ...# IP3               MARKER      0.0000  ... -0.000000+0.000004j -0.004026+0.003574j# MCBWV.4R3.B1     VKICKER     21.8800  ...  0.000001+0.000004j -0.002429+0.004805j# BPMW.4R3.B1      MONITOR     22.5205  ...  0.000001+0.000004j -0.002351+0.004843j# MQWA.A4R3.B1  QUADRUPOLE     26.1890  ...  0.000001+0.000004j -0.001852+0.005055j# MQWA.B4R3.B1  QUADRUPOLE     29.9890  ...  0.000001+0.000004j -0.001231+0.005241j# ...                  ...         ...  ...                 ...                 ...# MQWB.4L3.B1   QUADRUPOLE  26628.2022  ... -0.000000+0.000004j -0.005059+0.001842j# MQWA.B4L3.B1  QUADRUPOLE  26632.0022  ... -0.000000+0.000004j -0.004958+0.002098j# MQWA.A4L3.B1  QUADRUPOLE  26635.8022  ... -0.000000+0.000004j -0.004850+0.002337j# BPMW.4L3.B1      MONITOR  26636.4387  ... -0.000000+0.000004j -0.004831+0.002376j# MCBWH.4L3.B1     HKICKER  26641.0332  ... -0.000000+0.000004j -0.004691+0.002641jModulescoupling- Functions to estimate coupling from twiss dataframes and
different methods to calculate the closest tune approach from
the calculated coupling RDTs.
(coupling.py,doc)rdt- Functions for the calculations of Resonance Driving Terms, as well as
getting lists of valid driving term indices for certain orders.
(rdt.py,doc)utils- Helper functions to prepare the twiss dataframes for use with the optics
functions as well as reusable utilities,
that are needed within multiple optics calculations.
(utils.py,doc)LicenseThis project is licensed under the MIT License - see theLICENSEfile for details.