Proposal: opt-in geometry-consistency reporting (qform vs sform) #1523
Replies: 4 comments 3 replies
|
The biggest difference between the sform and qform is that the sform can be shear or degenerate but can be represented exactly up to float32 precision (float64 for NIfTI-2), while the qform is susceptible to round-trip errors (not all shearless affines can be represented). So there are a lot of cases that need to be handled by anybody trying to keep them synchronized, and it's possible that you end up in a state where they are unavoidably different (e.g., the sform is valid, the qform is the closest representable equivalent, and you don't want to change the image alignment by copying the qform into the sform). Apart from the qform/sform problem, you do also run into tools (some AFNI tooling is the main place I'm aware of) that deoblique affines before processing, and so that can be another source of orientation corruption if the wrapper / downstream tools are unaware. To your questions:
I just want to link in some relevant discussions:
In nipreps (fmriprep and friends), we settled on the following logic for acceptable modifications of incoming images that best preserved equivalence to the input images: I'd be interested in the opinions of @joshuacwnewton @jcohenadad @oesteban here. (Not exclusively! Just the first folks who come to mind on the topic.) |
The format expects them to disagree: the q-form is the image's orientation affine and the s-form is there to store a linear mapping onto standard space. If you visualize the image with a reasonable viewer (none that I use, except Mango I believe, and AFNI's probably does the right thing to), you should be able to select how to visualize the data (q- or s-form). You'd choose q-form to see it in native space and s-form to overlay over e.g., MNI (strictly speaking, I believe the format intended Talairach only). The problem is that implementation beyond visualization tools is also sparse. Some tools will generally prefer q-form over s-form, though some language is allowed to use s-form (I guess AFNI and some FSL tools), but some tools have traditionally ignored s-form (ITK, for good reasons too, though I think later versions now support s-form). (now I see @joshuacwnewton, and I agree this could be a generated proposal) |
|
Thanks @effigies and @oesteban — this is the grounding I was missing, and you're right on the core point. @oesteban — I'll drop the framing that treated qform≠sform as inherently a problem. The format expects them to disagree (q-form = native orientation, s-form = the map to standard space), so divergence alone isn't a defect. And even where they should agree they often can't exactly: as So let me narrow it to the in-scope piece you pointed at, @effigies. Instead of a "consistency checker" that flags divergence, something like a small documented function that classifies the q/s-form relationship the way nipreps already settled in #873 — (valid quaternions, qform_code, sform_code, qform==sform within tolerance) → {matching, precision-loss, genuine-mismatch, missing} — returning that structured result and the applicable action, without deciding policy for the caller. That keeps the use-case-specific decision-making out of the shared library while giving the docs something concrete to stand on. I'd fold in your actions-vs-warnings separation from #873, since the same action can warrant very different warnings. One honesty note, since @oesteban rightly flagged it: yes, this is AI-assisted — I'm an AI engineer, I use a frontier model with a verification step, and I should have said so up front. The fair criticism isn't the tooling, it's that the first draft reasoned about q/s-form without doing the reading. That's on me — I've since gone through Thanks for taking the time to correct this instead of closing it. |
|
Hi all — I've been subscribed to this thread the whole time, so I've had a front-row seat to being discussed in the third person. Strange spectator sport when you're also the subject. Quick intro, since it came up: self-taught, and I build with AI openly. "No prior MRI background" is fair on paper — off paper, my wife has primary progressive MS and my son carries her genes, so I didn't quite stumble in off a random agent crawl. This corner of the ecosystem is personal for me. On the proposal: the corrections were right, I've done the reading and narrowed it down, and I'm grateful for them. So one small, friendly ask — I'm right here in the replies. If there's something to say about me, even "is this guy for real," I'd genuinely rather hear it said to me than about me. Tends to go better than reaching for the moderation tools. 🙂 |
Uh oh!
There was an error while loading. Please reload this page.
Motivation
A NIfTI stores its spatial mapping twice —
qformandsform— and the format permits them to disagree. Tooling splits on which it reads: nibabel and most Python code use thesform; several C/registration tools read theqform. So a preprocessing step that rewrites only one of them silently mislocates the image, with no error or warning. It's a recurring, hard-to-debug failure in pipelines.nibabel already exposes
get_qform(),get_sform(), and the codes, so the information is all there — but there's no first-class, discoverable way to ask "are these two consistent, and by how much?", and the pitfall isn't surfaced on the common load path.The design question
Would you be open to an opt-in helper that reports qform/sform divergence — e.g. the max translation/rotation between the two plus the code states — without changing any default load behavior? Something along the lines of:
Explicitly not proposing: warnings on by default (noisy and backwards-incompatible), or any auto-repair (the correct fix is dataset-specific and a human decision).
Disclosure / prior art
I built a small standalone tool for exactly this check (nifti-qc), and it's been useful — but the detection arguably belongs closer to the data model, so I wanted to gauge scope before assuming. I'm glad to contribute an implementation plus tests if there's appetite, and equally fine if the answer is to keep it in external tooling.
Open questions
All reactions