You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A dipole is mandatory for ramped machine and/or dipole equipped with an additional correction coil.
Basically a dipole magnet has a model that depends only on $B\rho$.
So the main coil current should change only according to $B\rho$.
This require #90
A correction coil will have a model that will depend on the HCorrector strength and $B\rho$.
Such a Dipole can be configured as:
i.e.
- type: pyaml.magnet.dipolename: DIP # All dipoles are named DIP is the latticemodel:
type: pyaml.magnet.dipole_linear_model # this model depend only on Brho# calibration stuff....powerconverter:
- type: tango.pyaml.attributeattribute: srmag/ps-main/dip/currentunit: A
- type: pyaml.magnet.hcorrectorname: DIP-C01-Hlattice_names: DIP@0 # Main current is serialized, we access the good dipole in the latticemodel:
type: pyaml.magnet.linear_model # this model depend only on Brho and H strength# calibration stuff....powerconverter:
- type: tango.pyaml.attributeattribute: srmag/ps-corr-dip/c01/currentunit: A
- type: pyaml.magnet.hcorrectorname: DIP-C02-Hlattice_names: DIP@1 # Main current is serialized, we access the good dipole in the latticemodel:
type: pyaml.magnet.linear_model # this model depend on Brho and H strength# calibration stuff....powerconverter:
- type: tango.pyaml.attributeattribute: srmag/ps-corr-dip/c02/currentunit: A
I noticed when testing the orbit correction that the correctors set the dipole component in PolynomB and PolynomA and not KickAngle. Is there a specific reason for that or otherwise maybe when adding the dipole it's worth changing that mapping? I usually use the KickAngle field in pyAT for correctors to be able to easily separate that contribution to potential other things like errors that could also go into the PolynomB and PolynomA.
Problem of KickAngle is that it is integrated and slightly wrong So in fact it is better to just load PolynomA,B[0] so it stays coherent with other non integrated PolynomA,B coefficients.
PyAML performs the correction with the length to be in agreement with KL convention.
However PALS like integrated polynoms has been added in AT recently an can be used.
In PyAML, if you use corr.angle.set() instead of corr.strength.set() it will perform the tan().
Mhm, I understand. Now I'm wondering what that means for the implementation in pyAML.
Say that I'm doing simulated commissioning, add some dipole errors and then run orbit correction. When I read the correctors, how does it know how much of the polynom that is corrector strength and how much is from the errors?
I think if I did that in MML the code wouldn't know and would interpret the whole dipole component as corrector strength because it just reads directly from the lattice object. Does pyAML need some extra layer to keep track of the different contributions? Or perhaps this is something that @kparasch already has a solution for in pySC since I guess the problem is also there?
IMHO,
Concerning strength, the best would be to switch to PALS like polynomials.
Concerning errors, the plan was rather to add something to do something like: @simoneliuzzo, tips are welcome ;)
# The random number generator will use seed[0] to produce reproductible error set# Add some coupling, cutoff 2 sigmasr.error[0].get_magnets("skews").strengths.add_error( 1e-3 , cutoff=2 )
# Misalignmentsr.error[0].get_magnets("quads").position.add_error( [10e-6,10e-6] , cutoff=2 )
# Multipolar errorssr.error[0].get_magnets("quads").strengths.add_multipolar_error( [[1e-10,1e-10],[1e-2,1e-6],[1e-7,1e-7],[1e-7,1e-7], cutoff=2 )
etc...
# All the above can also be added to the config to produce rings with error out of the box# Retrieve errorerr=sr.error[0].get_magnets("skews").strengths.get() -sr.design.get_magnets("skews").strengths.get()
@JeanLucPons
I like your use example. It seems rather intuitive to me. @kparasch should confirm, but I think also pySC deals internally with the various contributions to corrections.
also in my commissioning simulations software and in the simulator device server, I only use PolynomA/B.
The availability in pyAML of various lattices to do actions like: err = sr.error[0].get_magnets("skews").strengths.get() - sr.design.get_magnets("skews").strengths.get()
is the most user friendly and intuitive way to work in my opinon.
Indeed pySC is an extra layer between strengths you control and strengths in the simulation.
It on purpose hides the errors internally so that if you would do something equivalent to:
You would end up with the same errors as initially generated. This was also the behavior of original SC which makes the simulation feel more close to handling a real accelerator.
On the point of KickAngle, I also would prefer just using PolynomB (ideally with PALS convention). For me, having to handle two variables that do the same thing confuses me.
Reacted by simone liuzzo, Jean-Luc PONS and Vadim Gubaidulin
I think sr.error is another part than what I was thinking about. As I understand it that's just the initial lattice model that you load which will have some errors inside but could potentially have zero corrector strength if you haven't already corrected the orbit for that model.
Then inside pyAML you run the orbit correction and that will set your correctors. Then it sounds like the layer @kparasch says pySC has inside will be needed to know how much is the corrector strength and how much is the error. Otherwise I don't understand how the code would not just read the full value of the polynom, think it's all corrector strength and when you convert into current give a different number than your power supply will actually have.
Activity
TeresiaOlsson commentedon Jan 29, 2026
I noticed when testing the orbit correction that the correctors set the dipole component in
PolynomBandPolynomAand notKickAngle. Is there a specific reason for that or otherwise maybe when adding the dipole it's worth changing that mapping? I usually use theKickAnglefield in pyAT for correctors to be able to easily separate that contribution to potential other things like errors that could also go into thePolynomBandPolynomA.JeanLucPons commentedon Jan 29, 2026
Problem of
KickAngleis that it is integrated and slightly wrong So in fact it is better to just load PolynomA,B[0] so it stays coherent with other non integrated PolynomA,B coefficients.PyAML performs the correction with the length to be in agreement with KL convention.
However PALS like integrated polynoms has been added in AT recently an can be used.
In PyAML, if you use corr.angle.set() instead of corr.strength.set() it will perform the
tan().TeresiaOlsson commentedon Jan 29, 2026
Mhm, I understand. Now I'm wondering what that means for the implementation in pyAML.
Say that I'm doing simulated commissioning, add some dipole errors and then run orbit correction. When I read the correctors, how does it know how much of the polynom that is corrector strength and how much is from the errors?
I think if I did that in MML the code wouldn't know and would interpret the whole dipole component as corrector strength because it just reads directly from the lattice object. Does pyAML need some extra layer to keep track of the different contributions? Or perhaps this is something that @kparasch already has a solution for in pySC since I guess the problem is also there?
JeanLucPons commentedon Jan 30, 2026
IMHO,
Concerning strength, the best would be to switch to PALS like polynomials.
Concerning errors, the plan was rather to add something to do something like:
@simoneliuzzo, tips are welcome ;)
This is just some ideas...
simoneliuzzo commentedon Jan 30, 2026
@JeanLucPons
I like your use example. It seems rather intuitive to me.
@kparasch should confirm, but I think also pySC deals internally with the various contributions to corrections.
also in my commissioning simulations software and in the simulator device server, I only use PolynomA/B.
The availability in pyAML of various lattices to do actions like:
err = sr.error[0].get_magnets("skews").strengths.get() - sr.design.get_magnets("skews").strengths.get()is the most user friendly and intuitive way to work in my opinon.
kparasch commentedon Jan 30, 2026
Indeed pySC is an extra layer between strengths you control and strengths in the simulation.
It on purpose hides the errors internally so that if you would do something equivalent to:
You would end up with the same errors as initially generated. This was also the behavior of original SC which makes the simulation feel more close to handling a real accelerator.
On the point of KickAngle, I also would prefer just using PolynomB (ideally with PALS convention). For me, having to handle two variables that do the same thing confuses me.
TeresiaOlsson commentedon Jan 30, 2026
I think
sr.erroris another part than what I was thinking about. As I understand it that's just the initial lattice model that you load which will have some errors inside but could potentially have zero corrector strength if you haven't already corrected the orbit for that model.Then inside pyAML you run the orbit correction and that will set your correctors. Then it sounds like the layer @kparasch says pySC has inside will be needed to know how much is the corrector strength and how much is the error. Otherwise I don't understand how the code would not just read the full value of the polynom, think it's all corrector strength and when you convert into current give a different number than your power supply will actually have.
[-]Feature: Add dipole magnet[/-][+]Add dipole magnet[/+]