Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion nibabel/orientations.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,10 @@ def io_orientation(affine, tol=None):
# axis N changes. In case there are ties, we choose the axes
# iteratively, removing used axes from consideration as we go
ornt = np.ones((p, 2), dtype=np.int8) * np.nan
for in_ax in range(p):
# Process input axes from strongest to weakest (stable on ties) so a given
# dimension is labeled consistently regardless of the original order.
in_axes = np.argsort(np.min(-(R**2), axis=0), kind='stable')
for in_ax in in_axes:
col = R[:, in_ax]
if not np.allclose(col, 0):
out_ax = np.argmax(np.abs(col))
Expand Down
36 changes: 36 additions & 0 deletions nibabel/tests/test_orientations.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from numpy.testing import assert_array_equal

from ..affines import from_matvec, to_matvec
from ..nifti1 import Nifti1Image
from ..orientations import (
OrientationError,
aff2axcodes,
Expand Down Expand Up @@ -291,6 +292,41 @@ def test_io_orientation():
)


def test_io_orientation_column_strength_regression():
# Build a small image using the real-world affine that motivated the
# stronger column ordering.
affine = np.array(
[
[2.08759499e00, 7.70245194e-02, 1.12271041e-01, -1.67531357e01],
[-1.04219818e00, 1.58019245e-01, -5.34135476e-02, 1.22405062e01],
[-2.33361936e00, -1.66752085e-03, 1.24289364e-01, -1.09963446e01],
[0.00000000e00, 0.00000000e00, 0.00000000e00, 1.00000000e00],
]
)

# create image from afffine and reorient
img = Nifti1Image(np.zeros((2, 3, 4), dtype=np.float32), affine)
print(aff2axcodes(img.affine))

# check that orientation is as expected
img_ornt = io_orientation(affine)
assert_array_equal(img_ornt, axcodes2ornt('IAR'))

# reorient image to RAS
img_ras = img.as_reoriented(img_ornt)
img_ras_ornt = io_orientation(img_ras.affine)

# Verify reorientation swaps first and third axes and the labels follow the axes
assert_array_equal(io_orientation(img.affine), [[2, -1], [1, 1], [0, 1]])

# Test idempotence
img_ras_reornt = img_ras.as_reoriented(img_ras_ornt)
img_ras_reornt_ornt = io_orientation(img_ras_reornt.affine)

assert img_ras_reornt.shape == (4, 3, 2)
assert_array_equal(img_ras_reornt_ornt, [[0, 1], [1, 1], [2, 1]])


def test_ornt_transform():
assert_array_equal(
ornt_transform(
Expand Down