Twiss

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

Basic usage

import numpy as np

import xtrack as xt
import xpart as xp

#################################
# Load a line and build tracker #
#################################

line = xt.Line.from_json(
    '../../test_data/hllhc15_noerrors_nobb/line_and_particle.json')
line.particle_ref = xp.Particles(
                    mass0=xp.PROTON_MASS_EV, q0=1, energy0=7e12)
line.build_tracker()

#########
# Twiss #
#########

tw = line.twiss()
_images/twiss.png

Twiss functions and accelerator parameters as obtained by Xtrack twiss. See the full code generating the image.

Access option of twiss table

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

import numpy as np

import xtrack as xt
import xpart as xp

# Load a line and build tracker
line = xt.Line.from_json(
    '../../test_data/hllhc15_noerrors_nobb/line_and_particle.json')
line.particle_ref = xp.Particles(
                    mass0=xp.PROTON_MASS_EV, q0=1, energy0=7e12)
line.build_tracker()

# Twiss
tw = line.twiss()

# Examples of access modes to the twiss table

tw['qx']
# gives : 62.3100009

tw.qx
# gives : 62.3100009

tw['betx']
# gives a numpy array with the beta horizontal beta function along the line

tw.betx
# give the same as above

tw[:, 'ip1']
# gives a table with all the columns at the element `ip1`

tw[:, ['ip1', 'ip2']]
# gives a table with all the columns at the elements `ip1` and `ip2`

tw['betx', 0]
# gives the beta horizontal beta function at the first element

tw['betx', 'ip1']
# gives the beta horizontal beta function at the element `ip1`

tw[:, 'ip.*']
# gives a table with all the columns at all elements whose name matches the

tw['betx', 0:10]
# gives the horizontal beta function at the first 10 elements

tw['betx', 'ip1': 'ip2']
# gives the horizontal beta function at all elements between `ip1` and
# `ip2`

tw[['s', 'betx', 'bety'], 'ip.*']
# returns a table with the horizontal and vertical beta function at all
# elements whose name matches the regular expression `ip.*`

tw[['s', 'betx', 'bety'], 200:300:'s']
# returns the selected columns all the elements between s=200 and s=300

tw[:, 'ip1%%-5': 'ip1%%+5']
# returns a table with all the columns at elements located between 5 elements
# before and 5 elements after the element `ip1

tw[['betx','sqrt(betx)/2/bety'], 'ip1': 'ip2']
# returns a table including the required columns

tw.cols['betx']
# returns a table with the horizontal beta function along the line

tw.cols['betx', 'sqrt(betx)/2/bety']
# returns a table with the horizontal beta function and specified computation

tw.rows['ip1':'ip2', 'mcb.*']
# returns a table with the columns matching the regular expression `mcb.*`
# at all elements between `ip1` and `ip2`

tw.rows['ip1':'ip2', 'mcb.*'].cols['betx', 'sqrt(betx)/2/bety']
# returns a table with the horizontal beta function and specified computation
# at all elements between `ip1` and `ip2` matching the regular expression

4d method for twiss and build_particles

When the RF cavities are disabled or not included in the lattice or when the longitudinal motion is artificially frozen, the one-turn matrix of the line is singular, and it is no possible to use the standard method for the twiss calculation and to generate particles distributions matched to the lattice. In these cases, the “4d” method can be used, as illustrated in the following examples:

import json
import numpy as np

import xobjects as xo
import xtrack as xt
import xpart as xp

#####################################
# Load a line and build the tracker #
#####################################

fname_line_particles = '../../test_data/hllhc15_noerrors_nobb/line_and_particle.json'

with open(fname_line_particles, 'r') as fid:
    input_data = json.load(fid)
line = xt.Line.from_dict(input_data['line'])
line.particle_ref = xp.Particles.from_dict(input_data['particle'])

line.build_tracker()

# We consider a case in which all RF cavities are off
for ee in line.elements:
    if isinstance(ee, xt.Cavity):
        ee.voltage = 0

##################
# Twiss(4d mode) #
##################

# For this configuration, `line.twiss()` gives an exception 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')

###########################################
# Match a particle distribution (4d mode) #
###########################################

# The '4d' method can also be used to match a particle distribution:

particles = line.build_particles(method='4d',
                    x_norm=[1,2,3,4], # sigmas
                    nemitt_x=2.5e-6, nemitt_y=2.5e-6)

Non linear momentum detuning

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

import numpy as np
from cpymad.madx import Madx

import xtrack as xt
import xpart as xp

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

line = xt.Line.from_madx_sequence(mad.sequence.lhcb1)
line.particle_ref = xp.Particles(p0c=7000e9, mass0=xp.PROTON_MASS_EV)

line.build_tracker()

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
_images/twiss_vs_delta.png