Summary
Two related problems in the magnetism plumbing:
1. Partial magnetic update crashes. src/easyreflectometry/calculators/refl1d/wrapper.py:65-69: the guard fires when either magnetism_rhoM or magnetism_thetaM is in kwargs, but the body unconditionally reads both:
if any(item.startswith('magnetism') for item in kwargs.keys()):
magnetism = names.Magnetism(rhoM=kwargs['magnetism_rhoM'], thetaM=kwargs['magnetism_thetaM'])
EasyScience pushes parameter updates one at a time through ItemContainer, so update_layer(name, magnetism_rhoM=5) raises KeyError: 'magnetism_thetaM'. It also discards the existing value of the other component instead of reading it from self.storage['layer'][name].magnetism. Tests only ever pass both keys together (tests/calculators/refl1d/test_refl1d_wrapper.py:84, 99), so the gap is uncovered.
2. The refnx guard never fires through the public API. RefnxWrapper.include_magnetism raises NotImplementedError on set (refnx/wrapper.py:16-30), but CalculatorBase.include_magnetism's setter writes self._wrapper.magnetism (calculator_base.py:237) — the base attribute — so enabling magnetism on a refnx calculator silently "succeeds".
Suggested fix
(1) Read missing components from current storage: rhoM = kwargs.get('magnetism_rhoM', current.rhoM) etc. (2) Route CalculatorBase.include_magnetism through the wrapper property so engine-specific guards apply. Add a single-key update test.
Found during deep code review (DEEP_ANALYSIS.md §5.4, §3.2).
Summary
Two related problems in the magnetism plumbing:
1. Partial magnetic update crashes.
src/easyreflectometry/calculators/refl1d/wrapper.py:65-69: the guard fires when eithermagnetism_rhoMormagnetism_thetaMis in kwargs, but the body unconditionally reads both:EasyScience pushes parameter updates one at a time through
ItemContainer, soupdate_layer(name, magnetism_rhoM=5)raisesKeyError: 'magnetism_thetaM'. It also discards the existing value of the other component instead of reading it fromself.storage['layer'][name].magnetism. Tests only ever pass both keys together (tests/calculators/refl1d/test_refl1d_wrapper.py:84, 99), so the gap is uncovered.2. The refnx guard never fires through the public API.
RefnxWrapper.include_magnetismraisesNotImplementedErroron set (refnx/wrapper.py:16-30), butCalculatorBase.include_magnetism's setter writesself._wrapper.magnetism(calculator_base.py:237) — the base attribute — so enabling magnetism on a refnx calculator silently "succeeds".Suggested fix
(1) Read missing components from current storage:
rhoM = kwargs.get('magnetism_rhoM', current.rhoM)etc. (2) RouteCalculatorBase.include_magnetismthrough the wrapper property so engine-specific guards apply. Add a single-key update test.Found during deep code review (DEEP_ANALYSIS.md §5.4, §3.2).