Freeze longitudinal coordinates

In certain studies, it is convenient to track particles updating only the transverse coordinates, while keeping the longitudinal coordinates fixed (frozen). Xsuite offers the possibility to freeze the longitudinal coordinates within a single method or changin the state of the tracker, as illustrated in the following sections.

Freezing longitudinal when calling methods

The Tracker.twiss and Tracker.track can work with frozen longitudinal coordinates. This is done by setting the freeze_longitudinal argument to True, as shown in the following example:

import json

import xtrack as xt
import xpart as xp

fname_line = '../../test_data/lhc_no_bb/line_and_particle.json'

# import a line and add reference particle
with open(fname_line) as fid:
    line_dict = json.load(fid)
line = xt.Line.from_dict(line_dict['line'])
line.particle_ref = xp.Particles.from_dict(line_dict['particle'])

# Build the tracker
tracker = line.build_tracker()

# Track some particles with frozen longitudinal coordinates
particles = tracker.build_particles(delta=1e-3, x=[-1e-3, 0, 1e-3])
tracker.track(particles, num_turns=10, freeze_longitudinal=True)
print(particles.delta) # gives [0.001 0.001 0.001], same as initial value

# Twiss with frozen longitudinal coordinates (needs to be 4d)
twiss = tracker.twiss(method='4d', freeze_longitudinal=True)
print(twiss.slip_factor) # gives 0 (no longitudinal motion)

# Track some particles with unfrozen longitudinal coordinates
particles = tracker.build_particles(delta=1e-3, x=[-1e-3, 0, 1e-3])
tracker.track(particles, num_turns=10)
print(particles.delta) # gives [0.00099218, ...], different from initial value

# Twiss with unfrozen longitudinal coordinates (can be 6d)
twiss = tracker.twiss(method='6d')
print(twiss.slip_factor) # gives 0.00032151, from longitudinal motion

Freezing longitudinal coordinates a with block

A context manager is also available to freeze the longitudinal coordinates within a with block. The normal tracking mode, updating the longitudinal coordinates, is automatically restored when exiting the with block, as it is illustrated in the following example:

import json

import xtrack as xt
import xpart as xp

fname_line = '../../test_data/lhc_no_bb/line_and_particle.json'

# import a line and add reference particle
with open(fname_line) as fid:
    line_dict = json.load(fid)
line = xt.Line.from_dict(line_dict['line'])
line.particle_ref = xp.Particles.from_dict(line_dict['particle'])

# Build the tracker
tracker = line.build_tracker()

# Perform a set of operations with frozen longitudinal coordinates
with xt.freeze_longitudinal(tracker):
    # Track some particles with frozen longitudinal coordinates
    particles = tracker.build_particles(delta=1e-3, x=[-1e-3, 0, 1e-3])
    tracker.track(particles, num_turns=10)
    print(particles.delta) # gives [0.001 0.001 0.001], same as initial value

    # Twiss with frozen longitudinal coordinates (needs to be 4d)
    twiss = tracker.twiss(method='4d')
    print(twiss.slip_factor) # gives 0 (no longitudinal motion)

# 6d tracking is automatically restored when the with block is exited

# Track some particles with unfrozen longitudinal coordinates
particles = tracker.build_particles(delta=1e-3, x=[-1e-3, 0, 1e-3])
tracker.track(particles, num_turns=10)
print(particles.delta) # gives [0.00099218, ...], different from initial value

# Twiss with unfrozen longitudinal coordinates (can be 6d)
twiss = tracker.twiss(method='6d')
print(twiss.slip_factor) # gives 0.00032151, from longitudinal motion

Freezing longitudinal coordinates with tracker method

The xtrack.Tracker class provides a method called freeze_longitudinal() to explicitly freeze the longitudinal coordinates. The normal tracking mode, updating the longitudinal coordinates, can be restored by calling freeze_longitudinal(False). This is illustrated in the following example:

import json

import xtrack as xt
import xpart as xp

fname_line = '../../test_data/lhc_no_bb/line_and_particle.json'

# import a line and add reference particle
with open(fname_line) as fid:
    line_dict = json.load(fid)
line = xt.Line.from_dict(line_dict['line'])
line.particle_ref = xp.Particles.from_dict(line_dict['particle'])

# Build the tracker
tracker = line.build_tracker()

# Freeze longitudinal coordinates
tracker.freeze_longitudinal()

# Track some particles with frozen longitudinal coordinates
particles = tracker.build_particles(delta=1e-3, x=[-1e-3, 0, 1e-3])
tracker.track(particles, num_turns=10)
print(particles.delta) # gives [0.001 0.001 0.001], same as initial value

# Twiss with frozen longitudinal coordinates (needs to be 4d)
twiss = tracker.twiss(method='4d')
print(twiss.slip_factor) # gives 0 (no longitudinal motion)

# Unfreeze longitudinal coordinates
tracker.freeze_longitudinal(False)

# Track some particles with unfrozen longitudinal coordinates
particles = tracker.build_particles(delta=1e-3, x=[-1e-3, 0, 1e-3])
tracker.track(particles, num_turns=10)
print(particles.delta) # gives [0.00099218, ...], different from initial value

# Twiss with unfrozen longitudinal coordinates (can be 6d)
twiss = tracker.twiss(method='6d')
print(twiss.slip_factor) # gives 0.00032151, from longitudinal motion