Matching#
import numpy as np
from importlib.resources import files, as_file
from at import (
Lattice,
LocalOpticsObservable,
GlobalOpticsObservable,
ObservableList,
End,
)
Special import to use the new matching:
from at.future import RefptsVariable, VariableList, match
Import a sample lattice:
fname = "hmba.mat"
with as_file(files("machine_data") / fname) as path:
ring = Lattice.load(path)
Split the sextupoles in halves to set constraints in their middle:
sf = ring.get_uint32_index("SF*")
sf1 = ring[sf[0]].divide([0.5, 0.5])
sf2 = ring[sf[1]].divide([0.5, 0.5])
ring.pop(sf[1])
ring.insert(sf[1], sf2[1])
ring.insert(sf[1], sf2[0])
ring.pop(sf[0])
ring.insert(sf[0], sf1[1])
ring.insert(sf[0], sf1[0])
ring.periodicity = 1
Define the location of constraints#
sf = ring.get_uint32_index("SF*")[1::2]
center = ring.get_uint32_index("CellCenter")
Define the variables#
We take the strengths of 7 quadrupole families
names = ["QF1*", "QD2*", "QD3*", "QF4*", "QD5*", "QF6*", "QF8*"]
bounds = [[0, 5], [-5, 0], [-5, 0], [0, 5], [-5, 0], [0, 5], [0, 5]]
variables = VariableList(
RefptsVariable(nm, "PolynomB", index=1, bounds=bnd, name=nm, ring=ring)
for nm, bnd in zip(names, bounds)
)
print(variables)
Name Initial Final Variation
QF1* 2.539460e+00 2.539460e+00 0.000000e+00
QD2* -2.672025e+00 -2.672025e+00 0.000000e+00
QD3* -2.404266e+00 -2.404266e+00 0.000000e+00
QF4* 2.429986e+00 2.429986e+00 0.000000e+00
QD5* -2.704501e+00 -2.704501e+00 0.000000e+00
QF6* 4.464541e+00 4.464541e+00 0.000000e+00
QF8* 4.425467e+00 4.425467e+00 0.000000e+00
Define the constraints#
Tunes:
obs = ObservableList()
# Tunes
obs.append(GlobalOpticsObservable("tune", target=[0.38, 0.85]))
Optics at the entrance of the lattice (1 reference point):
(both planes): the shape of the value is (1, 2). The shape of target (2,) is automatically broadcasted to (1, 2), : the shape of the value is (1,). The shape of target () is automatically broadcasted to (1,).
obs.append(LocalOpticsObservable(0, "alpha", target=[0.0, 0.0]))
obs.append(LocalOpticsObservable(0, "dispersion", plane="px", target=0.0))
Optics at the centre of the cell:
obs.append(LocalOpticsObservable(center, "beta", plane="y", target=4.69999257))
obs.append(LocalOpticsObservable(center, "alpha", target=[0.0, 0.0]))
obs.append(LocalOpticsObservable(center, "dispersion", plane="px", target=0.0))
Optics in the middle of sextupoles (2 reference points):
: the shape of the value is (2,). The target (shape ()) broadcasts to both points, : the shape of the value is (2,). The target (shape (2,)) specifies the value at each refpoint, : the shape of the value is (2,). The target (shape ()) broadcasts to both points.
obs.append(LocalOpticsObservable(sf, "beta", plane="y", target=5.4))
obs.append(LocalOpticsObservable(sf, "alpha", plane="y", target=[0.68, -0.68]))
obs.append(LocalOpticsObservable(sf, "dispersion", plane="x", target=0.0882))
Phase advance between the sextupoles (2 reference points):
(both planes): the numpydiff()
function reduces the 1st dimension by 1, so the shape of value is (1, 2). The shape of target (2,) is broadcasted to (1, 2).
obs.append(
LocalOpticsObservable(
sf, "mu2pif", target=[0.49721338, 0.48228011], statfun=np.diff
)
)
Perform the matching:#
newring = match(ring, variables, obs, copy=True)
17 constraints, 7 variables, using method trf
Iteration Total nfev Cost Cost reduction Step norm Optimality
0 1 1.0793e-05 6.22e-03
1 3 5.4660e-06 5.33e-06 3.56e-03 2.33e-02
2 4 1.9157e-06 3.55e-06 7.17e-03 8.80e-02
3 5 9.4304e-08 1.82e-06 2.23e-03 4.16e-03
4 6 3.5989e-08 5.83e-08 7.08e-03 1.41e-03
5 7 2.8207e-09 3.32e-08 1.02e-02 3.01e-03
6 8 2.2899e-10 2.59e-09 1.20e-03 4.15e-05
7 9 1.8505e-10 4.39e-11 4.11e-04 5.02e-06
8 10 1.8504e-10 6.42e-15 1.88e-06 3.54e-10
`gtol` termination condition is satisfied.
Function evaluations 10, initial cost 1.0793e-05, final cost 1.8504e-10, first-order optimality 3.54e-10.
Constraints:
location Initial Actual Low bound High bound deviation
tune
[ 0.3816 ...] [ 0.38 ...] [ 0.38 ...] [ 0.38 ...] [ 5.152e-08 ...]
alpha
RFC [ 1.009e-07 ...] [ 9.976e-08 ...] [ 0.0 ...] [ 0.0 ...] [ 9.976e-08 ...]
dispersion[px]
RFC 4.04369e-09 4.04779e-09 0.0 0.0 4.04779e-09
beta[y]
CellCenter 4.69999 4.69999 4.69999 4.69999 2.52854e-08
alpha
CellCenter [-4.653e-07 ...] [-4.601e-07 ...] [ 0.0 ...] [ 0.0 ...] [-4.601e-07 ...]
dispersion[px]
CellCenter 6.50009e-09 6.50726e-09 0.0 0.0 6.50726e-09
beta[y]
SF2A 5.40001 5.40001 5.4 5.4 1.21184e-05
SF2E 5.39998 5.39999 5.4 5.4 -1.16331e-05
alpha[y]
SF2A 0.680004 0.680003 0.68 0.68 3.45064e-06
SF2E -0.679997 -0.679996 -0.68 -0.68 3.55375e-06
dispersion[x]
SF2A 0.0882 0.0881956 0.0882 0.0882 -4.40557e-06
SF2E 0.0882 0.0881956 0.0882 0.0882 -4.43116e-06
diff(mu2pif)
[ 0.4972 ...] [ 0.4972 ...] [ 0.4972 ...] [ 0.4972 ...] [-2.134e-06 ...]
Variables:
Name Initial Final Variation
QF1* 2.539460e+00 2.532112e+00 -7.347814e-03
QD2* -2.672025e+00 -2.651372e+00 2.065282e-02
QD3* -2.404266e+00 -2.415254e+00 -1.098898e-02
QF4* 2.429986e+00 2.430280e+00 2.937205e-04
QD5* -2.704501e+00 -2.704692e+00 -1.911423e-04
QF6* 4.464541e+00 4.464754e+00 2.133294e-04
QF8* 4.425467e+00 4.425392e+00 -7.464186e-05