Fix live reduction when Mantid default facility is not SNS - #685
Fix live reduction when Mantid default facility is not SNS#685darshdinger wants to merge 4 commits into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## next #685 +/- ##
=======================================
Coverage 96.51% 96.51%
=======================================
Files 79 79
Lines 7279 7279
=======================================
Hits 7025 7025
Misses 254 254
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
"""Naming the listener explicitly doesn't help. Setting Listener/Address with Instrument |
|
""" One side effect worth noting for review: algorithm creation moved from before the mutex to inside |
|
I'm very skeptical about these changes! Arguably you've selected an optimal path, but I think we're adding lots of complexity, and future potential defects to work around Mantid flaws. We should probably just fix the latter. (And any users of SNAPwrap, in the mean time [i.e. waiting for the new Mantid version] can just set their facility!) Here are what I think are the key points:
|
Description of work
Live reduction fails outright for any user whose Mantid default facility is not SNS. The reported
failure came through SNAPWrap on an analysis node:
Mantid's live-data algorithms (
LoadLiveData,StartLiveData,MonitorLiveData) build theallowed-values list for their
Instrumentproperty from the default facility, restricted toinstruments that have a live-data listener. Under a non-SNS default that list comes back empty, so
Instrument="SNAP"is rejected before anything else happens. SNAPRed has no argument it can pass toavoid this.
This is a Mantid defect, and after review the agreed direction is to fix it upstream rather than work
around it in SNAPRed. So this PR does not itself make live reduction work under a non-SNS default —
see "What this PR does not do" at the bottom. What it does is remove SNAPRed's own dependence on
Mantid's process-wide defaults, and record the defect and its workaround so the next person doesn't
have to rediscover any of it.
Explanation of work
Two rules came out of review, and they now apply to all SNAPRed code:
getFacility(<name>)andgetInstrument(<name>)search all facilities and are unaffected by theuser's defaults; the no-argument forms are not.
name is only meaningful with respect to a facility. Either may be optional, but both must be
overridable.
Changes follow from those:
LoadLiveDataIntervalnow declares aFacilityproperty alongsideInstrument, and itsvalidateInputsresolves against a named facility instead of the default one. An emptyFacilitymeans
<liveData.facility.name>— deliberately not Mantid's default facility:Worth flagging one trap found while writing this: the two lookups report different sentinels. An
unknown facility raises
Facilities search object, while an unknown instrument within a facilityraises
FacilityInfo search object. My first version guarded on the wrong one and re-raised instead ofreturning a clean validation error; a test caught it.
Facilitycannot yet be forwarded to the childLoadLiveData— Mantid has no such property — sothere's a
TODOat that call site pointing at the upstream fix.CheckIPTShad two problems. The"DAS"exclusion compared anInstrumentInfoagainst a string,so it silently did nothing;
"DAS"matters precisely because it is whatConfigService.setFacility("SNS")selects as the default instrument. Separately, it logged
"Using default instrument: X"while actuallypassing the empty instrument to
FileFinder— a misleading message about a default-instrumentdependence. Both fixed.
SNAPRedGUInow saves and restoresdefault.instrumentalongsidedefault.facility. Setting thefacility alone never yields the right instrument:
setStringleaves the previous one in place, whileConfigService.setFacilityresets it to the facility's first instrument. This is also, in effect,the workaround applied automatically for GUI users.
Approach considered and withdrawn
An earlier revision of this branch scoped a temporary override of the default facility/instrument
around each live-data call, applied centrally in
MantidSnapper.executeAlgorithm. It worked, but itwas withdrawn in review as too much complexity to carry for a defect in code we don't own — and it
required mutating a process-wide singleton the workbench reads concurrently, which brings its own
hazards. That mechanism, and the
MantidSnapperchanges it needed, have been reverted in full;MantidSnapper.pyis byte-identical tonextapart from one added comment. It remains in thisbranch's history at
e0e4ef5eif it is ever wanted.That approach also needed the configuration correct at construction time, so it moved algorithm
construction inside the live-data mutex — justified in review comments by an appeal to listener
safety, which was wrong: constructing the algorithm creates no listener. The mutex guards execution
deliberately, because
LoadLiveDatahas been used as a stay-resident algorithm whose instance is keptalive across
executecalls so its listener can preload and keep working against the same stream.That rationale wasn't recorded anywhere and was nearly lost, so it is now captured both as a comment
at the mutex declaration and in the implementation note. The comment is the only change to
MantidSnapper.py; drop it if you'd rather this PR left that file completely alone.Three facts about the Mantid validator are recorded in the new implementation note, because they rule
out the obvious upstream shortcuts:
initialize()and never re-evaluated.AlgorithmManager.createinitializes; a second
initialize()is a no-op.Facilityproperty upstream is not sufficient on its own — property valuesare only set after initialization. The validation must also be made dynamic, e.g. by moving the
check into
validateInputs.Listener/Addressexplicitly does not avoid the lookup. WithInstrumentempty, thealgorithm resolves from the default instrument regardless — verified for
Listeneralone,Addressalone, both, and neither, all identical.To test
Dev testing
tests/unit/backend/recipe/algorithm/test_LoadLiveDataInterval.py— 52 tests, of which 4 are new(
TestLoadLiveDataIntervalFacility): SNAP validates while the default facility is ILL; an explicitFacilityis honoured; an instrument outside the named facility is rejected; an unknown facility isrejected. Existing tests updated for the new property and the changed error text.
tests/unit/backend/data/test_liveDataFacilityConfig.py— 9 tests characterizing the Mantidbehaviour: the rejection itself, that facility+instrument together fix it, that
amend_configrestores cleanly, that allowed-values are frozen at
initialize(), and thatgetInstrument(name)searches all facilities. These assert nothing about SNAPRed, so they stay valid before and after the
upstream fix — when it lands, the "rejected" expectations should start failing, which is the signal
this workaround can be retired.
tests/unit/backend/recipe/algorithm/test_CheckIPTS.py— 5 tests:DASexcluded, SNAP present,empty string still allowed.
tests/unit/ui/test_mainLiveDataConfig.py— 4 tests for the GUI save/override/restore, runagainst a stub so no Qt widgets are constructed.
Things reviewers should look at closely:
tests/unit/ui/test_mainLiveDataConfig.pyisimportorskip-guarded, becausesnapred.ui.mainrequires the pinned Mantid version and my local env is behind. It skips locally and runs in CI. I
verified the logic separately by shimming the one missing symbol, so I expect it to pass rather than
merely skip — but CI is the first place it actually executes.
.pixi/envs/devis on Mantid 6.15 against the>=6.16pin, becausepixicannot readlockfile v7 without an upgrade. All of
tests/unit/uitherefore fails to collect locally, so thesuite was run as
pytest tests/unit --ignore=tests/unit/ui: 1517 passed, 31 skipped, 1 failed.The one failure (
test_RunMetadata::test_defaults_log_warning_fromNeXusLogs) is pre-existing —confirmed by stashing on a clean tree.
CIS testing
Run from workbench. This checks that SNAPRed's own validation no longer depends on your default
facility, and that the documented workaround does what the note says.
Success looks like:
PASS:on steps 1, 3 and 4, andEXPECTED-FAILURE confirmedon step 2. Step 2failing is the point — it is the upstream defect this PR documents rather than fixes.
GUI check. Set a non-SNAP default instrument in File → Settings → General, restart workbench,
open SNAPRed, then confirm in settings afterwards that your default instrument is unchanged — SNAPRed
must save and restore it, not leave its own behind.
Link to EWM item
EWM#15513
Verification
Acceptance Criteria
This list is for ease of reference, and does not replace reading the EWM story as part of the review.
Verify this list matches the EWM story before reviewing.
What this PR does not do
must still set their facility — via workbench settings,
Mantid.user.properties, orConfigService.setFacility("SNS"). The implementation note gives the instructions.Instrumentvalidation dynamic andadd an optional
Facilityproperty. A prototype validates correctly under a non-SNS default with noconfiguration mutation at all, and gives far better diagnostics. Note it must not change
LoadLiveDataitself in ways that disturb the listener lifecycle.code into the live-data fallback to begin with. Malcolm has since confirmed the file exists at
/SNS/SNAP/IPTS-36879/nexus/SNAP_69405.nxs.h5with all PVs present, which sharpens rather thananswers the question: it is worth checking on analysis whether the IPTS lookup is also
facility-dependent, since
CheckIPTS/FileFindersits on that path.