Fix nibabel.orientations.io_orientation#1461
Conversation
This Commit fixes the behavior of orientations.io_orientation, which extracts the `ornt`-array from an affine. Thus far, it always prioritizes the primary direction of the first column vector over other more aligned column vectors of the affine. Now, it ranks how well the axes align with the coordinate axes and iteratively selects the most aligned axis, eliminating that axis from further consideration. Currently, there are cases where the order of the column vectors impact results, now, changing the order of column vectors is a stable operation. E.g. previously, an affine might have returned ASL, but after "singular" as_closest_canonical alignment does not return RAS (because of this instability).
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1461 +/- ##
==========================================
- Coverage 95.42% 95.42% -0.01%
==========================================
Files 209 209
Lines 29822 29818 -4
Branches 4483 4482 -1
==========================================
- Hits 28457 28453 -4
Misses 930 930
Partials 435 435 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Unfortunately, I copied the code from the wrong file and only had the untested version... Here is my test @pytest.mark.parametrize(
argnames=["affine", "axcode"],
argvalues=[
[np.diag([2, 3, 4, 1]), "RAS"],
[np.diag([-2, 3, -4, 1])[:, [1, 0, 2, 3]], "ALI"],
[np.diag([2, -3, 4, 1])[:, [0, 2, 1, 3]], "RSP"],
[np.diag([-2, -3, -4, 1])[:, [2, 0, 1, 3]], "ILP"],
],
)
def test_aff2axcodes(affine: AffineMatrix4x4, axcode: StrictOrientationType):
"""Test whether aff2axcodes works as expected."""
actual = "".join(aff2axcodes(affine, ("lr", "pa", "is")))
expected = axcode.lower()
assert actual == expected, "aff2axcodes did not return the expected axcode!"My second test is a bit more complex and involves other function that are part of FastSurfer and not nibabel... |
|
Would you please add the test to the PR? Note that I will have limited internet access this week. Please ping again next Tuesday if I haven't gotten back to this. Also, I'd like @leoyala's input on this approach. And @matthew-brett if you have the time. |
|
I can confirm this same issue has been fixed in #1450 |
This PR fixes the behavior of orientations.io_orientation, which extracts the
ornt-array from an affine. Thus far, it always prioritizes the primary direction of the first column vector over other more aligned column vectors of the affine. Now, it ranks how well the axes align with the coordinate axes and iteratively selects the most aligned axis, eliminating that axis from further consideration. Currently, there are cases where the order of the column vectors impact results, now, changing the order of column vectors is a stable operation.E.g. previously, an affine might have returned ASL, but after "singular" as_closest_canonical alignment does not return RAS (because of this instability).
This solution fixes several problems in my code, and would impact other functions using
io_orientationsuch asas_closest_canonicaland others (many indirectly).I described the issue in #1460 as well.