Skip to content

Conversation

@oesteban
Copy link
Contributor

@oesteban oesteban commented Mar 7, 2017

This interface is intended to be placed in the beginning of workflows, with the idea of checking and overwritting image orientation (to RAS), the data type, and the affine matrix.

It'd be great to hear from @matthew-brett about this PR:

  • It'd be nice if we could set the desired output orientation using string codes ('RAS', 'LPS' etc.) but my ignorance about nibabel limits me to implement this, sorry about that.
  • I'd really appreciate some feedback on the affine handling (comments below).

Regarding the affines:
We are seeing how the sform and qform matrices are not homogeneously interpreted by software, and they are a potential source of errors. The idea of this node is that, when images enter the pipeline and since most of the software will not care much about these matrices (for instance, if you use ANTs and initialize aligning centers of masses you are defeating their purpose, right?), it is probably more stable to use the base affine, with the center at the center of the volume.

When the workflow ends, one can always re-set these matrices to the appropriate values depending on the coordinate system the images are referred to (there is an output to get the original headers backed-up).

This interface is intended to be placed in the beginning of workflows, with the idea of checking and overwritting image orientation (to RAS), the data type, and the affine matrix.
@codecov-io
Copy link

codecov-io commented Mar 7, 2017

Codecov Report

Merging #1868 into master will decrease coverage by 0.03%.
The diff coverage is 48.75%.

Impacted file tree graph

@@ Coverage Diff @@ ## master #1868 +/- ## ========================================== - Coverage 73.13% 73.09% -0.04%  ========================================== Files 1065 1067 +2 Lines 53429 53509 +80 ========================================== + Hits 39075 39114 +39  - Misses 14354 14395 +41
Flag Coverage Δ
#unittests 73.09% <48.75%> (-0.04%) ⬇️
Impacted Files Coverage Δ
nipype/interfaces/utility/nifti.py 39.39% <39.39%> (ø)
...interfaces/utility/tests/test_auto_ConformImage.py 92.85% <92.85%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0424b65...9a2ff5a. Read the comment docs.

@matthew-brett
Copy link
Member

Do I understand right - that you're intending to get the images to RAS+ orientation (more or less) by using as_closest_canonical and then you want to throw away the affine? This would surely be a bad idea for things like functional / anatomical registration and so on? Is there a lot of software that ignores the affine? Maybe AFNI?

@oesteban
Copy link
Contributor Author

oesteban commented Mar 9, 2017

Thanks very much @matthew-brett, that is the idea.

I'd say a fair amount of software will dismiss these headers by default (e.g. when using ANTs to register two images nobody prevents you to manually set an initialization matrix you computed from the headers of the images, but normally it will align the centers of mass/volume of the two). This interface could be handy when you want to ignore these matrices. But practically speaking, yes, simplifying the metadata of the images is sometimes beneficial to simplify the whole workflow. This new interface would write the headers out, so that you can set them back if necessary.

I will add a big warning on the documentation for this interface, to clearly state the concern you raised.

With all that in mind, if your intention is to get rid of the sform and qform, this code (https://github.com/oesteban/nipype/blob/9a2ff5a8879a2dbda568d12fced23356cfd56d18/nipype/interfaces/utility/nifti.py#L151-L166) is correct?

Does nibabel.as_closest_canonical() effectively flip and sort out axes on the underlying numpy data grid or it only operates on the affine matrix?

data = nb.as_closest_canonical(nii).get_data()
aff = nb.as_closest_canonical(nii).header.get_base_affine()
hdr['qform_code'] = 0
hdr['sform_code'] = 0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my worry is with this setting. this brings us back to analyze days. if i'm given this file without any context, then i have no way of knowing what's left or right in the brain.

wouldn't it be better to use an sform code that aligns with a standard?

https://nifti.nimh.nih.gov/nifti-1/documentation/faq#Q18

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is why I asked @matthew-brett to look at this. If I'm not wrong, by using as_closest_canonical we are basically addressing this problem. That function makes sure the image is in RAS, and the rationale was as follows: if you are sure your image has no axis flipped, then you can project the axes (making the affine a diagonal matrix scaled by the pixel spacings).

There is some code, for the situation where you want LAS that intends to do the same. We could also implement other options when the axes are in canonical order.

@matthew-brett
Copy link
Member

Hmm. So SPM, for example, will assume that a file without an affine is in LAS+ voxel order, but I believe you can change that interpretation with an SPM defaults setting.

So, I can see that it might be safer to pull the images into some standard voxel orientation before starting the processing (if you can afford the cost of that operation), but I'm not sure I see the logic of discarding the remaining affine. Even if some software does not use it, other software (such as SPM) will.

@oesteban
Copy link
Contributor Author

I see. I'll add all these details in the documentation, particularly the SPM detail.

Also, I'll add a big runtime warning when the option of trashing the original affine is enabled (it should be disabled by default).

@oesteban
Copy link
Contributor Author

I have posted this: nipy/nibabel#518

The idea for this interface is that you would specify the desired output orientation and rewrite the affine so that it is closest to that orientation. With a boolean option (false default), the removal of the s/q form matrices would be done (with a big warning showing up)

@satra
Copy link
Member

satra commented Mar 20, 2017

@oesteban - the days of the analyze format were so fraught with danger that i'm quite susceptible to seeing this through an emotional lens. would it be possible to do the canonical reorientation but still leave a specific qform or sform in place?

@oesteban
Copy link
Contributor Author

@satra - sure, that would be the default behavior of the interface

@oesteban
Copy link
Contributor Author

We could save the original sform/qform in the Nifti description field of the header.

@satra
Copy link
Member

satra commented Oct 8, 2017

@oesteban - is this still relevant, or can you simplify and directly use nibabel's as_closest_canonical?

@oesteban
Copy link
Contributor Author

@satra I'll have a look soon

@oesteban
Copy link
Contributor Author

I think this is not a problem for now. Will open a new PR if something changes.

@oesteban oesteban closed this Oct 11, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

4 participants