Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

ENH: Add get/set_zooms(units='norm') to manipulate zooms in mm/s units#567

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
effigies wants to merge24 commits intonipy:master
base:master
Choose a base branch
Loading
fromeffigies:enh/norm_units

Conversation

@effigies
Copy link
Member

@effigieseffigies commentedOct 24, 2017
edited
Loading

Because most NIfTI files are in mm+s units, it's pretty easy to write code that breaks on nonstandard units. This PR adds aget_norm_zooms method to spatial image headers that always returns zooms scaled to mm+s, based on metadata when available.

The basic API is:

img.header.get_norm_zooms()# Zooms in mm+s, assuming already in mm+s if missingimg.header.get_norm_zooms(raise_unknown=True)# Raise error if units not explicitly encoded

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.

defget_zooms(self):
''' Get zooms from header
Returns the spacing of voxels in the x, y, and z dimensions.
For four-dimensional files, a fourth zoom is included, equal to the
repetition time (TR) in ms (see `The MGH/MGZ Volume Format
<mghformat>`_).

I've also added aset_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.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.1%) to 96.149% when pulling2bfc8d7 on effigies:enh/norm_units intob2c0f81 on nipy:master.

@codecov-io
Copy link

codecov-io commentedOct 24, 2017
edited by codecovbot
Loading

Codecov Report

Base:92.40% // Head:92.18% // Decreases project coverage by-0.21%⚠️

Coverage data is based on head(98e43a0) compared to base(943e5e8).
Patch coverage: 65.59% of modified lines in pull request are covered.

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
Impacted FilesCoverage Δ
nibabel/spatialimages.py94.30% <37.50%> (-2.00%)⬇️
nibabel/analyze.py97.48% <42.85%> (-1.11%)⬇️
nibabel/freesurfer/mghformat.py92.94% <62.50%> (-2.13%)⬇️
nibabel/nifti1.py90.97% <69.64%> (-1.66%)⬇️
nibabel/ecat.py88.25% <100.00%> (+0.06%)⬆️
nibabel/minc1.py90.36% <100.00%> (+0.11%)⬆️
nibabel/viewers.py95.49% <0.00%> (-0.65%)⬇️

Help us with your feedback. Take ten seconds to tell ushow you rate us. Have a feature suggestion?Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment?Let us know in this issue.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.1%) to 96.149% when pulling468397b on effigies:enh/norm_units intob2c0f81 on nipy:master.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.1%) to 96.149% when pullingc112e26 on effigies:enh/norm_units intob1bf5e7 on nipy:master.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.1%) to 96.212% when pulling925d5f9 on effigies:enh/norm_units intob646d5f on nipy:master.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.1%) to 96.212% when pulling976eace on effigies:enh/norm_units intob646d5f on nipy:master.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.02%) to 96.349% when pulling1da0097 on effigies:enh/norm_units intob8545ef on nipy:master.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.02%) to 96.349% when pullingdcc71f1 on effigies:enh/norm_units intob8545ef on nipy:master.

@effigies
Copy link
MemberAuthor

This is ready for review. All behavior tested.

@effigies
Copy link
MemberAuthor

Just a bump on this, now the holidays are over.

@coveralls
Copy link

coveralls commentedJan 11, 2018
edited
Loading

Coverage Status

Coverage increased (+0.05%) to 93.407% when pullinge56e6d7 on effigies:enh/norm_units into636d5d2 on nipy:master.

@matthew-brett
Copy link
Member

I hate to say it - but would you mind putting a test intotest_image_api.py?

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 aboutget_canonical_zooms?

@matthew-brett
Copy link
Member

Or a flag toget_zooms ?

@effigies
Copy link
MemberAuthor

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.

@matthew-brett
Copy link
Member

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://github.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)?

@effigies
Copy link
MemberAuthor

Okay. So no property. I'd be okay with doing the option toget_zooms, if that seems cleaner. We'd presumably want a deprecation schedule to move from a default of raw to default of canonical.

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=notnp.allclose(zooms,target_zooms,atol=atol)

(Adapted fromhttps://github.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 butget_xyzt_units still says they're in meters, then we'll be doing the wrong thing.

@matthew-brett
Copy link
Member

Right - but I guess the snippet leaves open whether anyone actually has micron etc nifti images ...

A flag seems like the right way to go. I think we should also default Freesurfer to using seconds - what do you think?

@effigies
Copy link
MemberAuthor

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 aunits parameter toget_zooms. I'd be inclined to make the options'raw' and'canonical', given this discussion, but open to alternatives. We can default tocanonical on any image type known to only allowmm/s, and FreeSurfer, which we'll coerce.

For nifti and any others where we are not guaranteed thatraw == canonical, we should default toNone, which will provide raw results but warn that the default will switch to canonical (version 4)?

Do you know MINC units off the top of your head? I think I had a look but couldn't find them.

@effigies
Copy link
MemberAuthor

Does bring up a question ofset_zooms. What's the appropriate analog of theunits flag there?

@effigies
Copy link
MemberAuthor

A thing I just thought about: If the zooms are in microns, then the affine is presumably from VOX -> RAS (um), right? Do we need to account for that at all?

@effigies
Copy link
MemberAuthor

@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.

* Moving toget_zooms(units='raw'|'canonical'); holdup is in trying to prevent a huge number ofFutureWarnings littering the test outputs, and even more so building up a will to dig intowarnings context managers.

- Switch 'canonical' to 'norm' for brevity
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@yarikopticyarikopticyarikoptic requested changes

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

6 participants

@effigies@coveralls@codecov-io@matthew-brett@nibotmi@yarikoptic

[8]ページ先頭

©2009-2025 Movatter.jp