Match twiss parameters
The Xtrack Line class provides a match method that allows to match the twiss parameters of a to adjust knobs attached to the line in order to obtain desired values in the twiss results. This feature is illustrated in the following examples.
Match tunes and chromaticities
See also xtrack.Line.match()
import json
import time
import xtrack as xt
import xpart as xp
###################################
# Load a line and build a tracker #
####################################
with open('../../test_data/hllhc15_noerrors_nobb/line_w_knobs_and_particle.json') as f:
dct = json.load(f)
line = xt.Line.from_dict(dct['line'])
line.particle_ref = xp.Particles.from_dict(dct['particle'])
line.build_tracker()
#########
# Twiss #
#########
tw_before = line.twiss()
####################################################
# Tunes, chromaticities, and knobs before matching #
####################################################
# Initial tune and chromaticity values
print(f"Qx = {tw_before['qx']:.5f} Qy = {tw_before['qy']:.5f} "
f"Q'x = {tw_before['dqx']:.5f} Q'y = {tw_before['dqy']:.5f}")
# Initial value of the knobs correcting tunes an chromaticities
print(f"kqtf.b1 = {line.vars['kqtf.b1']._value}")
print(f"kqtd.b1 = {line.vars['kqtd.b1']._value}")
print(f"ksf.b1 = {line.vars['ksf.b1']._value}")
print(f"ksd.b1 = {line.vars['ksd.b1']._value}")
#####################################################
# Match tunes and chromaticities to assigned values #
#####################################################
line.match(
vary=[
xt.Vary('kqtf.b1', step=1e-8),
xt.Vary('kqtd.b1', step=1e-8),
xt.Vary('ksf.b1', step=1e-8),
xt.Vary('ksd.b1', step=1e-8),
],
targets = [
xt.Target('qx', 62.315, tol=1e-4),
xt.Target('qy', 60.325, tol=1e-4),
xt.Target('dqx', 10.0, tol=0.05),
xt.Target('dqy', 12.0, tol=0.05)])
###################################################
# Tunes, chromaticities, and knobs after matching #
###################################################
tw_final = line.twiss()
print(f"Qx = {tw_final['qx']:.5f} Qy = {tw_final['qy']:.5f} "
f"Q'x = {tw_final['dqx']:.5f} Q'y = {tw_final['dqy']:.5f}")
print(f"kqtf.b1 = {line.vars['kqtf.b1']._value}")
print(f"kqtd.b1 = {line.vars['kqtd.b1']._value}")
print(f"ksf.b1 = {line.vars['ksf.b1']._value}")
print(f"ksd.b1 = {line.vars['ksd.b1']._value}")
#####################################
# Match with specific twiss options #
#####################################
# Any argument accepted by the twiss method can be passed to the match method
# For example, to match the tunes and chromaticities using the '4d' method:
line.match(method='4d', # <-- 4d matching
vary=[
xt.Vary('kqtf.b1', step=1e-8),
xt.Vary('kqtd.b1', step=1e-8),
xt.Vary('ksf.b1', step=1e-6),
xt.Vary('ksd.b1', step=1e-6),
],
targets = [
xt.Target('qx', 62.29, tol=1e-4),
xt.Target('qy', 60.31, tol=1e-4),
xt.Target('dqx', 6.0, tol=0.05),
xt.Target('dqy', 4.0, tol=0.05)],
)
##############################################
# Match custom function of the twiss results #
##############################################
# The match method can also be used to match any user-defined function of
# the twiss results. For example, to match the difference between the tunes,
# instead of the vertical tune:
line.match(
vary=[
xt.Vary('kqtf.b1', step=1e-10),
xt.Vary('kqtd.b1', step=1e-10),
xt.Vary('ksf.b1', step=1e-10),
xt.Vary('ksd.b1', step=1e-10),
],
targets = [
xt.Target('qx', 62.27, tol=1e-4),
xt.Target(lambda tw: tw['qx'] - tw['qy'], 1.98, tol=1e-4), # equivalent to ('qy', 60.325)
xt.Target('dqx', 6.0, tol=0.05),
xt.Target('dqy', 4.0, tol=0.05),])
Match an orbit bump
See also xtrack.Line.match()
The match method can also be used with targets at specific locations in the line.
import json
import numpy as np
import xtrack as xt
import xobjects as xo
with open('../../test_data/hllhc14_no_errors_with_coupling_knobs/line_b1.json',
'r') as fid:
dct = json.load(fid)
line = xt.Line.from_dict(dct)
line.build_tracker()
tw_before = line.twiss()
line.match(
# Portion of the beam line to be modified and initial conditions
ele_start='mq.33l8.b1',
ele_stop='mq.23l8.b1',
twiss_init=tw_before.get_twiss_init(at_element='mq.33l8.b1'),
# Dipole corrector strengths to be varied
vary=[
xt.Vary(name='acbv30.l8b1', step=1e-10),
xt.Vary(name='acbv28.l8b1', step=1e-10),
xt.Vary(name='acbv26.l8b1', step=1e-10),
xt.Vary(name='acbv24.l8b1', step=1e-10),
],
targets=[
# I want the vertical orbit to be at 3 mm at mq.28l8.b1 with zero angle
xt.Target('y', at='mb.b28l8.b1', value=3e-3, tol=1e-4, scale=1),
xt.Target('py', at='mb.b28l8.b1', value=0, tol=1e-6, scale=1000),
# I want the bump to be closed
xt.Target('y', at='mq.23l8.b1', value=tw_before['y', 'mq.23l8.b1'],
tol=1e-6, scale=1),
xt.Target('py', at='mq.23l8.b1', value=tw_before['py', 'mq.23l8.b1'],
tol=1e-7, scale=1000),
]
)
The matched orbit bump. The green vertical lines mark the range used For the matching. The red line is the point where the position and angle are imposed. The grey lines mark the location of the used orbit correctors. See the full code generating the image.