Repository navigation
Serialized magnets: mixed-function families, strengths/hardwares arrays and partial series writes - #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. |
… strength is clamped to the excitation curve
|
@GamelinAl, It's done |
… strength is clamped to the excitation curve
|
@gupichon-soleil There are several issues, finally I prefer to discuss it there so we agree on the changes to do. 1.a The solver fails with opposite polaritiesEach
Even a perfectly reachable request fails, or silently gives a wrong current. 1.b On a mixed series, the compromise is weighted by unit sizeWhen the requested strengths cannot all be reached with one current, the result is a compromise. Summing raw strengths means the magnet with the largest numbers wins. Example with a "quadrupole" (calibration 1) and a "sextupole" (calibration 60) on the same curve, with an inconsistent request:
The sextupole almost gets what it asked for and the quadrupole takes nearly all the error. The existing Proposal for 1a and 1b: normalized residualWe keep the idea of the PR (a single equation in
Properties:
2.
|
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 followsum(f_i(I)) = sum(k_i)over the requested magnets, the others followKnown limitations
magnet[i].strength.set(x), which imposesf_i^-1(x)on the whole series.PyAMLExceptionbefore anything is written, for every write path (array,family.strength(s),family.hardware,magnet[i].strength). In design there is no power-supply range.I, 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 or all of a series): reimplemented to solvesum(f_i(I)) = sum(k_i)over the requested magnets only, with the same exact piecewise-linear inversion, 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, or affine with the same slope. With a single requested magnet it givesf_i^-1(k_i), asmagnet[i].strength.set(). It now checks thatcurrent_hardwareholds one 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 ofNonetocompute_hardware_values_partial, and the single-member shortcut (magnet.strength.set()) is removed, so design and live arrays go through the same code.Testing
The following tests (compatible with pytest) were added:
tests/config/sr_serialized_magnets.yaml: newmixedFunctionSeriesfamily (quadrupoleQF6D-C01and sextupoleSD1A-C01on one power supply)tests/config/sr_serialized_magnets_range.yaml: QF1A on a power supply limited to [0, 90] A in a static Tango catalog, with an array holding two of its four magnetstests/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 one magnet of a series drives it with that magnet's submodel, an array with two magnets drives it from those two only while the others follow, a strength outside the curve is clamped with a warningtests/magnet/test_serialized_magnets_cs.py, live with a power-supply range: a write needing a current outside the range raisesPyAMLExceptionand leaves the series unchanged, through an array,family.strengths,family.strength,magnet.strengthandfamily.hardware, and an in-range array write on part of the series moves the whole seriestest_array_with_inconsistent_magnets_of_a_seriesnow expects the exact solution of the average strengthVerify that your checklist complies with the project
-m "not integration";test_tuning_ormfails on Windows only, temporary file lock, unrelated)