Skip to content

Feature: Chromaticity correction #55

@gubaidulinvadim

Description

@gubaidulinvadim

Description, motivation and use case
The chromaticity correction and measurement / estimation from sextupole setting can now be implemented in pyAML as all prerequisites are fulfilled. The below idea largely follows the User interface Specification document.

Proposed solution
This use case is supposed to give access (get and set) to the storage ring chromaticity or to the booster chromaticity at a given time along the ramp.
The user would like to get the value of the chromaticity and set it to a desired value (not necessarily the model one).
This measurement requires implementing a betatron tune monitor (for chromaticity measurement) and at least two families of sextupole magnets (for changing chromaticity in both transverse planes) with a corresponding response matrix, and having a measured of estimated value of momentum compaction factor and beam energy (usually simulator values are good enough).
Depending on the way to measure chromaticity, we may need access to the RF master clock (varying the main RF frequency around the nominal value), analysis of the bunch spectrum of betatron oscillations, or calculation of chromaticity based on the lattice.
Here, only the method using the RF master clock is described.

The measurement of chromaticity is done in the following way.
The user sets the value of the step in RF frequency ($\Delta f$, a small value of a few \unit{\Hz}) and the number of such steps.
Then the RF frequency is changed between $f_0$, $f_0 - n_\text{steps}\Delta f$ to $f_0 + n_\text{steps}\Delta f$ and back to $f_0$ (we do this path to avoid any large change in the RF frequency).
At each value of RF frequency, a betatron tune value (horizontal and vertical) is recorded and stored.
A betatron tune in each plane $Q_{x, y}$ as a function of RF frequency is fitted to a polynomial of a user-specified order (typically $<=4$).
The polynomial coefficients, normalised with a coefficient depending on momentum compaction factor and beam energy, are the values of chromaticity.
Typically, only the linear coefficient is of interest in the horizontal and vertical planes.

To set the chromaticity, one requires a response matrix of chromaticity to sextupole magnet strength/currents.
Such a matrix can be measured or estimated from a simulator model of the accelerator and stored in a file.
Knowing the desired chromaticity values, we can find the required sextupole families' settings by using the inverse of this response matrix.
Then the required strength/currents are applied to the magnets.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered. An argument for why this solution is not the preferred one.

Example

import pyaml
import pyaml.tuning.chromaticity 

sr = pyaml('sr.yaml')
# sr = pyaml('sr_low_alpha.yaml')
# sr = pyaml('sr_low_emittance.yaml')
# sr = pyaml('sr_ss_mb_mode.yaml')

sr.live.chromaticity.get()
[6.1585, 7.3401]
sr.live.chromaticity.steps=5
sr.live.chromaticity.delta_rf=10 # Hz
sr.live.chromaticity.measure()
'-20Hz tunes = [76.255, 27.438]'
'-10Hz tunes = [76.252, 27.439]'
'  0Hz tunes = [76.250, 27.440]'
' 10Hz tunes = [76.248, 27.441]'
' 20Hz tunes = [76.246, 27.442]'
sr.live.chromaticity.get()
[6.2585, 7.2401]
sr.live.chromaticity.measurement_error.get()
[0.52, 0.42]
# request chromaticity variation
sr.live.chromaticity.sextupoles = sr.live.SF1SD2 # array of all SF1* and SD2* sextupoles
sr.live.chromaticity.update_optics() # computes tune response and saves file. 
sr.live.chromaticity.iterations = 3
chrom0 = sr.design.chromaticy.get()  # value from measurement in digital twin model 
[7, 8]
chrom = sr.design.optics.chromaticity.get() # value from optics computed by digital twin
[7,8]
sr.live.chromaticity.set(chrom0)
'sextupoles arrays SF1 and SD2 have been changed by 0.023 and -0.52 to go from [6.2585, 7.2401] to [7, 8]'
sr.live.chromaticity.status()
'running'
sr.live.chromaticity.status()
'ready'
sr.live.chromaticity.measure(verbose=False)
sr.live.measurement_data.file
'folder/to/store/data/Measurement/2025/01_31/Chrom_13_56.yaml'
sr.live.measurement_data.get()
{freq:[...],tune_h:[...],tune_v:[...]}
sr.live.chromaticity.get()
{hor:[7.0232, 123.2323], ver:[7.9876,232.22]}  # Q', Q'', fit orders from data in file
sr.live.chromaticity.set([26.25, 77.44])
'warning. The requested chromaticity variation is too large. nothing done'
sr.live.chromaticity.set([15, 15])
'warning at least one SF1 quadrupole would end up above the current limit. nothing done'
sr.live.chromaticity.response.file
'folder/to/store/data/Operation/Chromaticity/Chrom.yaml'
sr.live.chromaticity.response.get()
{SF1A02:[...,...], SD1B02:[...], SF1A03:[...,...], SD1B05:[...], ...}

@simoneliuzzo @kparasch @Amoutardier @gubaidulinvadim This issue might interest you!

Checklist

  • I've assigned this issue to a project
  • I've @-mentioned relevant people

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions