Twiss

Xtrack provides a twiss method associated to the line that can be used to obtain the lattice functions and other quantities like tunes, chromaticities, slip factor, etc. This is illustrated in the following examples. For a complete description of all available options and output quantities, please refer to the xtrack.Line.twiss() method documentation.

Basic usage (ring)

The following example shows how to use the twiss method to obtain the lattice functions and other quantities for a ring.

import numpy as np
import xtrack as xt

# Load a line
line = xt.load('../../test_data/hllhc15_thick/lhc_thick_with_knobs.json')
line.set_particle_ref('proton', energy0=7e12)
line['vrf400'] = 16 # set rf voltage

# Twiss
tw = line.twiss()

# Inspect tunes and chromaticities
tw.qx # Horizontal tune
tw.qy # Vertical tune
tw.dqx # Horizontal chromaticity
tw.dqy # Vertical chromaticity

# Plot closed orbit and lattice functions
import matplotlib.pyplot as plt
plt.close('all')

fig1 = plt.figure(1, figsize=(6.4, 4.8*1.5))
spbet = plt.subplot(3,1,1)
spco = plt.subplot(3,1,2, sharex=spbet)
spdisp = plt.subplot(3,1,3, sharex=spbet)

spbet.plot(tw.s, tw.betx)
spbet.plot(tw.s, tw.bety)
spbet.set_ylabel(r'$\beta_{x,y}$ [m]')

spco.plot(tw.s, tw.x)
spco.plot(tw.s, tw.y)
spco.set_ylabel(r'(Closed orbit)$_{x,y}$ [m]')

spdisp.plot(tw.s, tw.dx)
spdisp.plot(tw.s, tw.dy)
spdisp.set_ylabel(r'$D_{x,y}$ [m]')
spdisp.set_xlabel('s [m]')

fig1.suptitle(
    r'$q_x$ = ' f'{tw.qx:.5f}' r' $q_y$ = ' f'{tw.qy:.5f}' '\n'
    r"$Q'_x$ = " f'{tw.dqx:.2f}' r" $Q'_y$ = " f'{tw.dqy:.2f}'
    r' $\gamma_{tr}$ = '  f'{1/np.sqrt(tw.momentum_compaction_factor):.2f}'
)

fig1.subplots_adjust(left=.15, right=.92, hspace=.27)
plt.show()

# Complete source: xtrack/examples/twiss/000_twiss.py
_images/twiss.png

Lattice functions and accelerator parameters as obtained by Xtrack twiss.

Inspecting twiss output

The twiss table has several access options as illustrated in the following example.

import numpy as np

import xtrack as xt

# Load a line
line = xt.load('../../test_data/hllhc15_thick/lhc_thick_with_knobs.json')
line.set_particle_ref('proton', p0c=7e12)

# Twiss
tw = line.twiss(method='4d')

# Print table
tw.show()
# prints:
#
# TwissTable: 13401 rows, 70 cols
# name                     s             x            px             y ...
# ip7                      0             0             0             0
# drift_0                  0             0             0             0
# tcsg.a4r7.b1           0.5             0             0             0
# drift_1                1.5             0             0             0
# mcbwv.4r7.b1        53.341             0             0             0
# drift_2             55.041             0             0             0
# bpmw.4r7.b1        57.9855             0             0             0
# drift_3            57.9855             0             0             0
# mqwa.a4r7.b1        58.622             0             0             0
# drift_4              61.73             0             0             0
# ...
# bpmw.4l7.b1        26600.8  -4.24811e-16   3.18642e-18  -5.00664e-33
# drift_6658         26600.8  -4.24811e-16   3.18642e-18  -5.00664e-33
# mcbwh.4l7.b1       26601.5  -4.22611e-16   3.18642e-18  -5.01626e-33
# drift_6659         26603.2  -4.17194e-16   3.18642e-18  -5.03996e-33
# tcsg.b4l7.b1       26651.4  -2.63701e-16   3.18642e-18  -5.71147e-33
# drift_6660         26652.4  -2.60515e-16   3.18642e-18  -5.72541e-33
# tcsg.a4l7.b1       26655.4  -2.50955e-16   3.18642e-18  -5.76723e-33
# drift_6661         26656.4  -2.47769e-16   3.18642e-18  -5.78118e-33
# lhcb1ip7_p_        26658.9  -2.39803e-16   3.18642e-18  -5.81603e-33
# _end_point         26658.9  -2.39803e-16   3.18642e-18  -5.81603e-33

# Access to scalar quantities
tw.qx    # is : 62.31000
tw['qx'] # is : 62.31000

# Access to a single column of the table
tw['betx'] # is an array with the horizontal beta function at all elements

# Access to a single element of the table of a vector quantity
tw['betx', 'ip1'] # is 0.150000

# Regular expressions can be used to select elements by name
tw.rows['ip.*']
# returns:
#
# TwissTable: 9 rows, 41 cols
# name                           s x px y py zeta delta ptau    betx    bety ...
# ip7                            0 0  0 0  0    0     0    0 120.813 149.431
# ip8                      3321.22 0  0 0  0    0     0    0     1.5     1.5
# ip1.l1                   6664.72 0  0 0  0    0     0    0    0.15    0.15
# ip1                      6664.72 0  0 0  0    0     0    0    0.15    0.15
# ip2                      9997.16 0  0 0  0    0     0    0      10      10
# ip3                      13329.4 0  0 0  0    0     0    0 121.567 218.584
# ip4                      16661.7 0  0 0  0    0     0    0  236.18 306.197
# ip5                        19994 0  0 0  0    0     0    0    0.15    0.15
# ip6                      23326.4 0  0 0  0    0     0    0 273.434  183.74

# A section of the ring can be selected using names
tw.rows['ip5':'mqxfa.a1r5/lhcb1']
# returns:
#
# TwissTable: 8 rows, 70 cols
# name                        s             x            px ...
# ip5                     19994   5.14781e-18  -8.47233e-17
# mbcs2.1r5               19994   5.14781e-18  -8.47233e-17
# drift_5020            20000.5  -5.45553e-16  -8.47233e-17
# taxs.1r5              20013.1  -1.60883e-15  -8.47233e-17
# drift_5021            20014.9  -1.76133e-15  -8.47233e-17
# bpmqstza.1r5.b1       20015.9  -1.84783e-15  -8.47233e-17
# drift_5022            20015.9  -1.84783e-15  -8.47233e-17
# mqxfa.a1r5            20016.9   -1.9373e-15  -8.47233e-17

# A section of the ring can be selected using the s coordinate
tw.rows[300:305:'s']
# returns:
#
# TwissTable: 5 rows, 70 cols
# name                     s             x            px             y ...
# bpm.8r7.b1         300.698  -1.46744e-16  -9.41823e-18             0
# drift_52           300.698  -1.46744e-16  -9.41823e-18             0
# mq.8r7.b1          301.695  -1.56134e-16  -9.41823e-18             0
# drift_53           304.795  -1.92329e-16  -1.40959e-17             0
# mqtli.8r7.b1       304.964  -1.94711e-16  -1.40959e-17             0

# A section of the ring can be selected using indexes relative one element
# (e.g. to get from three elements upstream of 'ip5' to two elements
# downstream of 'ip5')
tw.rows['ip5<<3':'ip5>>2']
# returns:
#
# TwissTable: 6 rows, 70 cols
# name                   s             x            px             y ...
# taxs.1l5         19973.2   1.77163e-15  -8.47233e-17   5.46514e-33
# drift_5019         19975   1.61913e-15  -8.47233e-17    5.0159e-33
# mbcs2.1l5        19987.5   5.55849e-16  -8.47233e-17   1.88372e-33
# ip5                19994   5.14781e-18  -8.47233e-17   2.61468e-34
# mbcs2.1r5          19994   5.14781e-18  -8.47233e-17   2.61468e-34
# drift_5020       20000.5  -5.45553e-16  -8.47233e-17  -1.36078e-33

# Columns can be selected as well (and defined on the fly with simple mathematical
# expressions)
tw.cols['betx dx/sqrt(betx)']
# returns:
#
# TwissTable: 13401 rows, 3 cols
# name                  betx dx/sqrt(betx)
# ip7                120.813    -0.0185459
# drift_0            120.813    -0.0185459
# tcsg.a4r7.b1       119.542    -0.0186442
# drift_1            117.031    -0.0188431
# mcbwv.4r7.b1       46.5375    -0.0298815
# ...

# Each of the selection methods above returns a valid table, hence selections
# can be chained. For example we can get the beta functions at all the skew
# quadrupoles between ip1 and ip2:

tw.rows['ip1':'ip2'].rows['mqs.*b1'].cols['betx bety']
# returns:
#
# TwissTable: 4 rows, 3 cols
# name                        betx    bety
# mqs.23r1.b1              574.134 57.4386
# mqs.27r1.b1              574.134 57.4386
# mqs.27l2.b1              59.8967 62.0111
# mqs.23l2.b1              59.8968  62.011

# Complete source: xtrack/examples/twiss/017_table_slicing.py

4d method (RF off)

When the RF cavities are disabled or not included in the lattice (or when the longitudinal motion is artificially frozen) it is not possible to use the standard method for the twiss calculation. In these cases, the “4d” method can be used, as illustrated in the following examples:

import xtrack as xt

# Load a line
line = xt.load(
    '../../test_data/hllhc15_noerrors_nobb/line_and_particle.json')
line.set_particle_ref('proton', p0c=7e12)

# We consider a case in which all RF cavities are off
tab = line.get_table()
tab_cav = tab.rows[tab.element_type == 'Cavity']
for nn in tab_cav.name:
    line[nn].voltage = 0

# For this configuration, `line.twiss()` gives an error because the
# longitudinal motion is not stable.
# In this case, the '4d' method of `line.twiss()` can be used to compute the
# twiss parameters.

tw = line.twiss(method='4d')

# Complete source: xtrack/examples/twiss/008_4d_twiss_and_particle_match.py

Off-momentum twiss

The 4d mode of the twiss can be used providing in input the initial momentum. This feature can be used to measure the non-linear momentum detuning of a ring as shown in the following example:

import numpy as np
from cpymad.madx import Madx

import xtrack as xt

mad = Madx()
mad.call('../../test_data/hllhc15_noerrors_nobb/sequence.madx')
mad.use('lhcb1')

line = xt.Line.from_madx_sequence(mad.sequence.lhcb1)
line.set_particle_ref('proton', p0c=7000e9)

tw = line.twiss()

delta_values = np.linspace(-5e-3, 5e-3, 100)

qx_values = delta_values * 0
qy_values = delta_values * 0
for i, delta in enumerate(delta_values):
    print(f'Xsuite working on {i} of {len(delta_values)}  ', end='\r', flush=True)
    tt = line.twiss(method='4d', delta0=delta)

    qx_values[i] = tt.qx
    qy_values[i] = tt.qy

# Complete source: xtrack/examples/twiss/011_tune_vs_delta.py
_images/twiss_vs_delta.png

Twiss with “initial” conditions

The twiss calculation can be performed with initial conditions provided by the users or extracted from an existing twiss table, as illustrated in the following example:

import xtrack as xt

# Load a line
line = xt.load('../../test_data/hllhc15_noerrors_nobb/line_and_particle.json')
line.set_particle_ref('proton', energy0=7e12)

# Periodic twiss
tw_p = line.twiss()

# Twiss over a range with user-defined initial conditions (at start)
tw1 = line.twiss(start='ip5', end='mb.c24r5.b1',
                betx=0.15, bety=0.15, py=1e-6)


# Twiss over a range with user-defined initial conditions at end
tw2 = line.twiss(start='ip5', end='mb.c24r5.b1', init_at=xt.END,
                alfx=3.50482, betx=131.189, alfy=-0.677173, bety=40.7318,
                dx=1.22515, dpx=-0.0169647)

# Twiss over a range with user-defined initial conditions at arbitrary location
tw3 = line.twiss(start='ip5', end='mb.c24r5.b1', init_at='mb.c14r5.b1',
                 alfx=-0.437695, betx=31.8512, alfy=-6.73282, bety=450.454,
                 dx=1.22606, dpx=-0.0169647)

# Initial conditions can also be taken from an existing twiss table
tw4 = line.twiss(start='ip5', end='mb.c24r5.b1', init_at='mb.c14r5.b1',
                 init=tw_p)

# More explicitly, a `TwissInit` object can be extracted from the twiss table
# and used as initial conditions
tw_init = tw_p.get_twiss_init('mb.c14r5.b1',)
tw5 = line.twiss(start='ip5', end='mb.c24r5.b1', init=tw_init)

# Complete source: xtrack/examples/twiss/000a_twiss_range.py
_images/twiss_range.png

Result of all twiss calculations with initial conditions shown in the example above.

Periodic twiss on a portion of a line

The twiss method can also be used to find the periodic solution for a portion of a beam line, as illustrated in the following example:

import xtrack as xt

# Load a line
line = xt.load('../../test_data/hllhc15_noerrors_nobb/line_and_particle.json')
line.set_particle_ref('proton', energy0=7e12)

# Periodic twiss of the full ring
tw_p = line.twiss()

# Periodic twiss of an arc cell
tw = line.twiss(method='4d', start='mq.14r6.b1', end='mq.16r6.b1', init='periodic')

# Complete source: xtrack/examples/twiss/000b_twiss_range_periodic.py
_images/twiss_periodic.png

Result of the twiss with periodic boundary conditions.

Beam sizes from twiss table

The transverse and longitudinal beam sizes can be computed from the twiss table, as illustrated in the following example:

import numpy as np
import xtrack as xt

# Load a line
line = xt.load('../../test_data/hllhc15_noerrors_nobb/line_and_particle.json')
line.set_particle_ref('proton', p0c=7e12)

# Twiss
tw = line.twiss()

# Transverse normalized emittances
nemitt_x = 2.5e-6
nemitt_y = 2.5e-6

# Longitudinal emittance from energy spread
sigma_pzeta = 2e-4
gemitt_zeta = sigma_pzeta**2 * tw.bets0
# similarly, if the bunch length is known, the emittance can be computed as
# gemitt_zeta = sigma_zeta**2 / tw.bets0

# Compute beam sizes
beam_sizes = tw.get_beam_covariance(nemitt_x=nemitt_x, nemitt_y=nemitt_y,
                                    gemitt_zeta=gemitt_zeta)

# Inspect beam sizes (table can be accessed similarly to twiss tables)
beam_sizes.rows['ip.?'].show()
# prints
#
# name                       s     sigma_x     sigma_y sigma_zeta    sigma_px ...
# ip3                        0 0.000226516 0.000270642    0.19694 4.35287e-06
# ip4                  3332.28 0.000281326 0.000320321   0.196941 1.30435e-06
# ip5                  6664.57  7.0898e-06 7.08975e-06    0.19694  4.7265e-05
# ip6                  9997.01 0.000314392 0.000248136   0.196939 1.61401e-06
# ip7                  13329.4 0.000205156 0.000223772   0.196939 2.70123e-06
# ip8                  16650.7 2.24199e-05 2.24198e-05   0.196939 1.49465e-05
# ip1                  19994.2 7.08975e-06 7.08979e-06   0.196939 4.72651e-05
# ip2                  23326.6 5.78877e-05 5.78878e-05   0.196939 5.78879e-06

# All covariances are computed including those from linear coupling
beam_sizes.keys()
# is:
#
# ['s', 'name', 'sigma_x', 'sigma_y', 'sigma_zeta', 'sigma_px', 'sigma_py',
# 'sigma_pzeta', 'Sigma', 'Sigma11', 'Sigma12', 'Sigma13', 'Sigma14', 'Sigma15',
# 'Sigma16', 'Sigma21', 'Sigma22', 'Sigma23', 'Sigma24', 'Sigma25', 'Sigma26',
# 'Sigma31', 'Sigma32', 'Sigma33', 'Sigma34', 'Sigma41', 'Sigma42', 'Sigma43',
# 'Sigma44', 'Sigma51', 'Sigma52'])

# Plot
import matplotlib.pyplot as plt
plt.close('all')

fig1 = plt.figure(1, figsize=(6.4, 4.8*1.5))
spbet = plt.subplot(3,1,1)
spdisp = plt.subplot(3,1,2, sharex=spbet)
spbsz = plt.subplot(3,1,3, sharex=spbet)

spbet.plot(tw.s, tw.betx)
spbet.plot(tw.s, tw.bety)
spbet.set_ylabel(r'$\beta_{x,y}$ [m]')

spdisp.plot(tw.s, tw.dx)
spdisp.plot(tw.s, tw.dy)
spdisp.set_ylabel(r'$D_{x,y}$ [m]')

spbsz.plot(beam_sizes.s, beam_sizes.sigma_x)
spbsz.plot(beam_sizes.s, beam_sizes.sigma_y)
spbsz.set_ylabel(r'$\sigma_{x,y}$ [m]')
spbsz.set_xlabel('s [m]')

spbet.set_xlim(tw['s', 'ip5'] - 2000, tw['s', 'ip5'] + 2000)

fig1.subplots_adjust(left=.15, right=.92, hspace=.27)
plt.show()

# Complete source: xtrack/examples/twiss/018_compute_beam_sizes.py
_images/twiss_beam_sizes.png

Beam sizes as obtained from twiss.

Particles normalized coordinates

The twiss table holds the information to convert particle physical coordinates into normalized coordinates. This can be done with the method get_normalized_coordinates as illustrated in the following example:

import numpy as np
import xtrack as xt

# Load a line
line = xt.load(
    '../../test_data/hllhc15_noerrors_nobb/line_and_particle.json')
line.set_particle_ref('proton', p0c=7e12)

# Generate some particles with known normalized coordinates
particles = line.build_particles(
    nemitt_x=2.5e-6, nemitt_y=1e-6,
    x_norm=[-1, 0, 0.5], y_norm=[0.3, -0.2, 0.2],
    px_norm=[0.1, 0.2, 0.3], py_norm=[0.5, 0.6, 0.8],
    zeta=[0, 0.1, -0.1], delta=[1e-4, 0., -1e-4])

# Inspect physical coordinates
tab = particles.get_table()
tab.show()
# prints
#
# Table: 3 rows, 17 cols
# particle_id s            x           px            y          py zeta   delta chi ...
#           0 0 -0.000253245  3.33271e-06  5.10063e-05 1.00661e-06    0  0.0001   1
#           1 0 -2.06127e-09  3.32087e-07 -3.42343e-05 5.59114e-08  0.1       0   1
#           2 0  0.000152331 -7.62878e-07  3.45785e-05  1.0462e-06 -0.1 -0.0001   1


# Compute twiss
tw = line.twiss()

# Use twiss to compute normalized coordinates
norm_coord = tw.get_normalized_coordinates(particles, nemitt_x=2.5e-6,
                                           nemitt_y=1e-6)

# Inspect normalized coordinates
norm_coord.show()
#
# Table: 3 rows, 8 cols
# particle_id at_element       x_norm px_norm y_norm py_norm   zeta_norm  pzeta_norm
#           0          0           -1     0.1    0.3     0.5 1.06651e-07  0.00313799
#           1          0 -1.59607e-20     0.2   -0.2     0.6  0.00318676 1.12046e-05
#           2          0          0.5     0.3    0.2     0.8  -0.0031868  -0.0031492

# Complete source: xtrack/examples/twiss/012_compute_norm_coordinates.py

Reverse reference frame

The reverse` flag, allows getting the output of the twiss in the counter-rotating reference system. When reverse is True, the ordering of the elements is reversed, the zero of the s` coordinate and of the phase advances is set at the new start, the sign of the coordinates s` and x` is inverted, while the sign of the coordinate y is unchanged. This is illustrated in the following example:

import xtrack as xt

# Load collider with two lines
collider = xt.load('../../test_data/hllhc15_thick/hllhc15_collider_thick.json')
collider.lhcb1.twiss_default.clear() # clear twiss default settings
collider.lhcb2.twiss_default.clear() # clear twiss default settings
collider['on_disp'] = 0 # disable dispersion correction

# Set a horizontal crossing angle between the two beams  in the interaction
# point ip1 and a vertical crossing angle in ip5
collider['on_x1hl'] = 10 # [urad]
collider['on_x5vl'] = 10 # [urad]
# Set a vertical separation between the two beams in the interaction point ip5
# and a horizontal separation in ip5
collider['on_sep1v'] = 0.5 # [mm]
collider['on_sep5h'] = 0.5 # [mm]

# Twiss the two lines (4d method since cavities are off)
tw1 = collider.lhcb1.twiss(method='4d')
tw2 = collider.lhcb2.twiss(method='4d')

tw1.reference_frame # is `proper`
tw2.reference_frame # is `proper`

# tw1 has a clokwise frame while tw2 has a counter-clockwise frame.
#
# name         s   mux   muy         x          y         px         py
# ip1          0     0     0 4.313e-09     0.0005  1.002e-05 -4.133e-09
# ip3       6665 15.95 15.45 2.392e-08 -2.209e-07  3.695e-10 -3.005e-09
# ip5  1.333e+04 30.93 29.99    0.0005  4.332e-09  1.918e-08      1e-05
# ip7  1.999e+04 46.35 44.59 2.138e-07 -1.785e-08 -2.132e-09 -3.078e-11

tw2.rows['ip[1,3,5,7]'].cols['s mux muy x y px py'].show(digits=4)
# prints:
#
# name         s   mux   muy          x          y         px         py
# ip7       6665 16.19 15.45 -5.941e-09   2.69e-07 -1.098e-10  2.428e-09
# ip5  1.333e+04 31.28 30.37     0.0005  5.997e-09 -4.562e-09  1.003e-05
# ip3  1.999e+04 46.46 44.81  -9.85e-08 -2.447e-08  3.218e-09 -9.711e-10
# ip1  2.666e+04 62.31 60.32 -2.278e-09    -0.0005     -1e-05   2.57e-08

# -- Reverse b2 twiss --
# The `reverse`` flag, allows getting the output of the twiss in the counter-rotating
# reference system. When `reverse` is True, the ordering of the elements is reversed,
# the zero of the s coordinate and fo the phase advances is set at  the new start,
# the sign of the coordinates s and x is inverted, while the sign of the coordinate
# y is unchanged. In symbols:
#
# s   -> L - s
# mux -> mux(L) - mux
# muy -> muy(L) - muy
# x   -> -x
# y   -> y
# px  -> px
# py  -> -py

tw2_r = collider.lhcb2.twiss(method='4d', reverse=True)
tw2_r.reference_frame # is `reverse`

tw2_r.rows['ip[1,3,5,7]'].cols['s mux muy x y px py'].show(digits=4)
# prints:
#
# name         s   mux   muy         x          y         px         py
# ip1  2.183e-11     0     0 2.278e-09    -0.0005     -1e-05  -2.57e-08
# ip3       6665 15.85 15.51  9.85e-08 -2.447e-08  3.218e-09  9.711e-10
# ip5  1.333e+04 31.03 29.95   -0.0005  5.997e-09 -4.562e-09 -1.003e-05
# ip7  1.999e+04 46.12 44.87 5.941e-09   2.69e-07 -1.098e-10 -2.428e-09

# In this way, for a collider, it is possible to plot the closed orbit and the
# twiss functions of the two beams in the same graph. For example:

import matplotlib.pyplot as plt
plt.close('all')
fig = plt.figure(1)

ax1 = fig.add_subplot(211)
ax1.plot(tw1.s, tw1.x * 1000, color='b', label='b1')
ax1.plot(tw2_r.s, tw2_r.x * 1000, color='r', label='b2')
ax1.set_ylabel('x [m]')
ax1.legend(loc='best')

ax2 = fig.add_subplot(212, sharex=ax1)
ax2.plot(tw1.s, tw1.y * 1000, color='b', label='b1')
ax2.plot(tw2_r.s, tw2_r.y * 1000, color='r', label='b1')
ax2.set_ylabel('y [mm]')
ax2.set_xlabel('s [mm]')

ax1.set_xlim(tw1['s', 'ip5'] - 300, tw1['s', 'ip5'] + 300)

ax1.axvline(x=tw1['s', 'ip5'], color='k', linestyle='--', alpha=0.5)
ax2.axvline(x=tw1['s', 'ip5'], color='k', linestyle='--', alpha=0.5)
plt.text(tw1['s', 'ip5'], -0.6, 'ip5', rotation=90, alpha=0.5,
         horizontalalignment='left', verticalalignment='top')

plt.show()

# Complete source: xtrack/examples/twiss/000e_twiss_reverse.py
_images/twiss_reverse.png

Closed Orbit of the two LHC beams in the same reference frame. This is obtained setting reverse=True on the twiss of beam 2.

Twiss defaults

It is possible to change the default behavior of the twiss method for a given line using line.twiss_defaults, which is a dictionary with the desired default twiss arguments. This is illustrated in the following example:

import xtrack as xt

# Load a line
line = xt.load('../../test_data/hllhc15_noerrors_nobb/line_and_particle.json')
line.set_particle_ref('proton', energy0=7e12)

# Twiss (built-in defaults)
tw_a = line.twiss()
tw_a.method # is '6d'
tw_a.reference_frame # is 'proper'

# Inspect twiss defaults
line.twiss_default # is {}

# Set some twiss defaults
line.twiss_default['method'] = '4d'
line.twiss_default['reverse'] = True

# Twiss (defaults redefined)
tw_b = line.twiss()
tw_b.method # is '4d'
tw_b.reference_frame # is 'reverse'

# Inspect twiss defaults
line.twiss_default # is {'method': '4d', 'reverse': True}

# Reset twiss defaults
line.twiss_default.clear()

# Twiss (defaults reset)
tw_c = line.twiss()
tw_c.method # is '6d'
tw_c.reference_frame # is 'proper'

# Complete source: xtrack/examples/twiss/000f_twiss_default.py

Twiss with synchrotron radiation

See Synchrotron radiation.