Conversation
f5435f5
to 2bfc8d7
Compare Codecov ReportBase: 92.40% // Head: 92.18% // Decreases project coverage by
Additional details and impacted files@@ Coverage Diff @@
## master #567 +/- ##
==========================================
- Coverage 92.40% 92.18% -0.22%
==========================================
Files 98 98
Lines 12248 12326 +78
Branches 2516 2546 +30
==========================================
+ Hits 11318 11363 +45
- Misses 611 630 +19
- Partials 319 333 +14
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
468397b
to c112e26
Compare c112e26
to 925d5f9
Compare 925d5f9
to 976eace
Compare 976eace
to bddf15c
Compare 1da0097
to dcc71f1
Compare dcc71f1
to ad9fc49
Compare I hate to say it - but would you mind putting a test into I'm suffering slightly about this one, because we otherwhere make our outputs canonical - for example, we make our affines point to RAS+ space, for DICOM. So it seems kindve odd to let the formats do whatever with the zooms, and fix it with this function. I guess it's too late to switch nifti / freesurfer to (mm, mm, mm, seconds) ? How about |
Not too late for MGHHeader, since we haven't released with TR as zooms[3], but yeah, NIFTI uses raw zooms without correcting for units. Unless we want to treat that as a bug, but I think people will be depending on it. We could deprecate get_zooms, or switch to a keyword argument to specify raw or canonical. Finally, I'm okay with get_canonical_zooms, but it is getting long. Does it make sense to move to a canonical zooms property? Or even header.zooms that behaves canonically, combined with a get/set_zooms deprecation that warns of new semantics. And sure, I'll add tests. |
I believe I avoided using a property on the basis that the setter would also modify the header (at least, it does now). So, it would break the property manifesto : https://.com/nipy/nibabel/wiki/property_manifesto I could imagine another model, where we left the header unmodified from its load state, and stored things like zooms etc inside the image, but that would be an API break. Could you say more about what people are depending on? Do you think that some people currently have meters set in their header, but are using the units as mm (for example)? |
Okay. So no property. I'd be okay with doing the option to And an example of depending on current behavior: zooms = np.array(reoriented.header.get_zooms()[:3])
xyz_unit = img.header.get_xyzt_units()[0]
atol = {'meter': 1e-5, 'mm': 0.01, 'micron': 10}[xyz_unit]
rescale = not np.allclose(zooms, target_zooms, atol=atol) (Adapted from https://.com/poldracklab/fmriprep/blob/682b507c141254a51316b2367f9834708eb4409e/fmriprep/interfaces/images.py#L236-L256) Here we took into account the fact that the zooms may not be in mm. If the zooms start being mm but |
Yes, that's true. I've seen someone say they have ms TR images (they ran into issues with an FSL tool that assumed sec), but I don't know if I've ever heard of a meter image in the wild. So how about a For nifti and any others where we are not guaranteed that Do you know MINC units off the top of your head? I think I had a look but couldn't find them. |
@matthew-brett I have some unpushed changes in the pipeline*, but if you have a minute to give your thoughts on the API issues I brought up in the last three comments, I'd appreciate it.
|
4b53011
to 3cd8618
Compare - Switch 'canonical' to 'norm' for brevity
3cd8618
to 98e43a0
Compare
Because most NIfTI files are in mm+s units, it's pretty easy to write code that breaks on nonstandard units. This PR adds a
get_norm_zooms
method to spatial image headers that always returns zooms scaled to mm+s, based on metadata when available.The basic API is:
Edit:
With MGHHeader encoding TR in milliseconds (see snippet), being able to access zooms in standard units across image types seems even more like a good idea.
I've also added a
set_norm_zooms()
that takes zooms in mm/s and applies any necessary transformations to set the headers correctly to ensure a lossless round-trip withget_norm_zooms
.