AFAIK the problem is coming from the thing that the bending magnet of the storage ring (and the same thing with each family of sextupoles) are powered from the same power converter. There is one power converter in sector 1 for all the (32) storage ring bending magnets. Each magnet is a solenoid, but the cable to distribute the power to all of them can be saw globally like on big solenoid with one turn.
In the storage ring, there are also 9 families of sextupoles, each of them powered by converters also placed in sector 1, with the same situation than the bendings. This means that, globally, we have 10 solenoids of one turn of 268.8 meters.
(There are also 14 families of quadrupoles, but in that case there is one power converter per sector and is not contributing to this problem.)
How to compensate this? The problem is not when the storage ring magnets are cycling, the issue is when this magnets have set different currents due to many different purposes forces to reconfigure the linac. The easy and smarter solution perhaps is to install another turn to compensate the effect.
Then when the setting of the storage changes, the current of one extra power converter changes to cancel the effect on the linac. But calculate and apply new current values it's a boring thing for a human. Often I say the repetitive and boring task are good for computers, and gives free time to humans.
One detail more, some of the magnet turns goes clockwise direction in the storage ring, and some others goes in counter-clockwise direction. That means that they already cancels some of their effects but 0 effect is not grant. That the goal of this compensation turn.
A device server class with the name "RingMagnetCompensarion" is the responsible in the control system to calculate the current to set in the power converter for the compensation turn. This device has some properties:
- [Counter]ClockWise: two lists of magnet device server names
- MagnetAttr: name of the attribute to read/subscribe on the magnets of the lists
- CompensationMagnet: name of the device server where the calculated compensation current will be written
- AttrThreadSleep: Expert property to fine adjust of the refresh on the threaded option of the magnets current refresh
This Magnet class, checks if the attribute to read in the power converter device server have events or not. In case of event, it subscribes to it, but if not, if does a polling to read if the current have changed.
When a magnet object receives from its attrManager the notification of a readback change, this is propagated to the magnetGroup parent object. Why? Because this with update the cw/ccw list of currents and update the summatory. With this summatory updated, it's time to notify the RingMagnetCompensation device to calculate the formula:
Then only rest the event propagation and to write in the compensation power converter device if it's necessary.
Issues: One detected issue that has been already fix is when the magnets are cycling. The compensation power converter range is between 50A to -50A, and during cycling procedure this can be out of this range. Then each magnet object checks if the subdevice have received a command Cycle() to cut the propagation of readback change.
Another issues is the SlewRate of all the power converters involved. This has not tested yet, but it's possible that the speed changing the current in the compensation power converter would be not faster enough to a live response against the current changes on all the magnets in the lists.