Handle steps that run nothing, and stop the driver degrading a protocol - #8
Merged
Conversation
Three archives arrived from clinical studies rather than pure imaging protocols, and the reader raised on all of them. A step in the running order need not run anything: EdfPauseStep is an instruction an operator put between scans -- "Count down with RA to start of scan", "Pause for saliva collection", "Do NOT add Raw Filter to 3D MPR" -- carrying an EdfMeasurementStepContent with injector fields and no protocol child. Eleven of CHR-MDD's thirty-four steps are pauses. Nothing about the existing corpus could have surfaced that. It came from protocols written for studies with behavioural tasks, where the operator needs telling what to do between acquisitions. They are named, they are in the chain, and the PDF does not print them as scans, so anything walking scans skips them. Step.is_pause reads the instance kind and runs_a_protocol reads the content; a test asserts the two always agree, because either alone could be wrong. Reader, validator, patcher and driver all handle them, and the validator's independent step count now includes both kinds or it disagrees with the chain it checks. Driving an archive from its own PDF must write nothing, and on these it wrote one value and refused another. Both were real. Unit stripping matched a unit anywhere, and "MS" is one, so a case-insensitive match turned "RMS" into "R" -- which then failed to resolve as an Averaging choice. A unit only counts after whitespace. And a printout carries fewer digits than the protocol: one scan prints "TE 1 = 54 ms" for a stored 54.16, so writing the printed value back drops 0.16 ms. agrees_at_printed_precision treats a printed value as matching when the stored one rounds to it at the precision actually printed. Without it the driver quietly degraded every protocol it touched. Matching also pairs repeated names positionally. A protocol may run four scans called Localizer; when both sides agree on how many, running order settles which is which, and when they disagree it stays a guess and is reported. ZMK23 went from 18 matched and 5 unmatched to 23 and 0. Two of the three pairs do not match each other: CHR-MDD's archive holds 23 acquisitions against its printout's 24, and the 31P archive holds 24 against its printout's 13. All three printed counts are confirmed by their own contents pages, so these are different versions of those protocols rather than parse errors, and the expectation table says so. ZMK23's pair agrees at 23 each. Corpus is 54 snapshots and 1031 scans; the new protocols add no unaccounted sequences. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three archives arrived from clinical studies rather than pure imaging
protocols, and the reader raised on all three.
A step in the running order need not run anything
EdfPauseStepis an instruction an operator put between scans -- "Count downwith RA to start of scan", "Pause for saliva collection", "Do NOT add Raw
Filter to 3D MPR" -- carrying an
EdfMeasurementStepContentwith injectorfields and no protocol child. Eleven of
CHR-MDD's thirty-four steps arepauses.
Nothing about the existing corpus could have surfaced this. Every archive
until now came from imaging protocols; these come from studies with
behavioural tasks, where the operator needs telling what to do between
acquisitions.
Pause steps are named, they are in the chain, and the PDF does not print them
as scans, so anything walking scans skips them.
Step.is_pausereads theinstance kind and
runs_a_protocolreads the content, and a test asserts thetwo always agree, because either alone could be wrong. Reader, validator,
patcher and driver all handle them, and the validator's independent step count
now includes both kinds -- otherwise it disagrees with the chain it is
checking.
Two driver bugs, both caught by the same invariant
Driving an archive from its own PDF must write nothing. On these it wrote
one value and refused another, and both were real.
RMSbecameR. Unit stripping matched a unit anywhere in the string,and
MSis a unit, so a case-insensitive match ate the tail ofRMS-- whichthen failed to resolve as an
Averagingchoice. A unit only counts afterwhitespace.
A printout carries fewer digits than the protocol. One scan prints
TE 1 = 54 msfor a stored54.16, so writing the printed value back drops0.16 ms.
agrees_at_printed_precisiontreats a printed value as matching whenthe stored one rounds to it at the precision actually printed. Without it the
driver quietly degraded every protocol it touched -- which is the failure mode
a PDF-driven generator has to be most careful about, since the loss is
invisible in the printout it came from.
Matching
Repeated scan names now pair positionally. A protocol may run four scans
called
Localizer; when both sides agree on how many, running order settleswhich is which, and when they disagree it stays a guess and is reported.
ZMK23went from 18 matched and 5 unmatched to 23 and 0.Two pairs in the corpus do not match each other
All three printed counts are confirmed against their own contents pages, so
these are different versions of those protocols rather than parse errors. The
expectation table says so rather than quietly picking a number.
Verification
Corpus is 54 snapshots and 1031 scans; the new protocols add no unaccounted
sequences.
Still open
No archive built end to end by
exarhas been through a loader. Every pieceis validated separately -- patched values on five archives, created scans on
one -- and the combination is not. Coverage is about a tenth of what a
protocol prints, dominated by console UI settings rather than acquisition
parameters, which is worth confirming before collecting more option scans.
🤖 Generated with Claude Code