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),

  • ηx: 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):

  • βy: the shape of the value is (2,). The target (shape ()) broadcasts to both points,

  • αy: the shape of the value is (2,). The target (shape (2,)) specifies the value at each refpoint,

  • ηx: 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 numpy diff() 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