Repository navigation
Serialized magnets: mixed-function families, strengths/hardwares arrays and completed partial requests - #485
Conversation
…d completed partial requests for serialized magnets (#461)
I think this drives a difference of behavior when changing the values directly using the array and if a tuning tool with the planned knob implementation in #461 :
|
Yes. An intermediate slution would be to use only the referenced magnet to compute the current (like if it was a sub-serie) but it might lead to errors for the others magnets of the serie. I don't see a good solution here, it's a matter of choice in my opinion. |
For me the second behavior is what we want. |
|
Ok, I'll do it tomorrow. |
Description
Follow-up to #474 on the serialized-magnet accessors. It adds three things on top of the agreed accessor convention:
functionaccepts one value per element.family.strengths/family.hardwaresread or write every magnet of the series in one call, likeCombinedFunctionMagnet.strengths/.hardwares.A series has a single degree of freedom, the power-supply current
I. Magnetihas the strengthk_i = f_i(I):get()set(x)family.hardwareII = xfamily.strengthsum(f_i(I)) / Nsum(f_i(I)) / N = x. Raises on a mixed familyfamily.hardwares[I, ..., I]I = mean(x)family.strengths[f_1(I), ..., f_N(I)]sum(f_i(I)) = sum(x_i)magnet[i].hardwareII = xmagnet[i].strengthf_i(I)I = f_i^-1(x), the others followf_j(I), then solvesum(f_i(I)) = sum(k_i)Known limitations
magnet[i].strength.set(x), which imposesf_i^-1(x)on the whole series.f_i^-1(x). This supersedes the "writing one member no longer moves the PS by 1/N" behaviour of Implement the agreed serialized-magnet accessor convention #474, on purpose: the magnetsoutside the request are not driven to a large uncontrolled change.
magnet[i].strength.set(x)is not affected.PyAMLExceptionand nothing is written. This matchesthe physical situation: following the request would change the magnets outside it with no control over them.
sum(f_i(I))is not monotonic inI, the request cannot be inverted andPyAMLExceptionis raised (existing behaviour ofcompute_hardware_from_mean_strength).unit/hardware_unitinLinearSerializedMagnetModel, sofamily.strengths.unit()reports the same strength unit for every magnet whatever its function.Related Issue
get/setare not consitent anddesign/livedisagree #461 (does not close it: one knob per power supply in the tuning tools is still open)Features/issues described there are:
functionaccepts a list with one function per element, so a series can mix magnet functions on one power supply.polynomsholds one polynom per element and the simulator uses each magnet's own polynom, otherwise the sextupole of a mixed family would write into the quadrupole slot.is_homogeneous()tells whether every magnet shares the same function.family.strengths/family.hardwares(ReadWriteSerializedStrengthArray/ReadWriteSerializedHardwareArray), to read or write every magnet of a series in one call, as forCombinedFunctionMagnet.strengths.set(k)solvessum(f_i(I)) = sum(k_i)through the newLinearSerializedMagnetModel.compute_hardware_from_strengths(), which reuses the exact piecewise-linear inversion ofcompute_hardware_from_mean_strength.hardwares.set(x)appliesmean(x).family.strengthraisesPyAMLExceptionon a family mixing functions, because a single value cannot be both a quadrupole and a sextupole strength.family.strengths,family.hardware(s)and per-magnet access keep working.functionraised aKeyError, the key was read before being checked. It now raisesPyAMLException.Changes to existing functionality
compute_hardware_values_partial(array writes covering part of a series): reimplemented to complete the magnets that are not requested with the strength given by the current hardware value, then delegate tocompute_hardware_from_strengths, because the previous rule, the mean of the currents implied by each requested strength (sum(f_i^-1(k_i)) / N), is only exact when everyf_iis the same, oraffine with the same slope. It now checks that it receives one hardware value per power supply and returns an array of the same shape. The inconsistency warning is shortened to the largest gap and the magnet concerned.
RWMagnetStrength.set()(design arrays, no aggregator): passes the current hardware value instead ofNone, needed for the completion. The single-member shortcut (magnet.strength.set()) is removed, so design and live arrays follow the same rule (live arrays already went through the aggregator).Testing
The following tests (compatible with pytest) were added:
tests/config/sr_serialized_magnets.yaml: newmixedFunctionSeriesfamily (quadrupoleQF6D-C01and sextupoleSD1A-C01on one power supply)tests/magnet/test_serialized_magnets.py: homogeneity,family.strengthrefused on the mixed family, hardware and per-magnet access kept, each magnet written in its own polynom, exact convergence of a consistentstrengths.set()request, warning on an inconsistent one, shape check ofcompute_hardware_values_partialtests/magnet/test_serialized_magnets_cs.py, in design and live:strengths/hardwaresread and write,set(get())leaves the machine unchanged, an array with two magnets of a series is completed with the current strength of the otherstest_array_with_inconsistent_magnets_of_a_seriesnow expects the exact solution of the average strength, and the single-member array test now expects the completed request and its warningVerify that your checklist complies with the project
-m "not integration";test_tuning_ormfails on Windows only, temporary file lock, unrelated)