From 47ea032b541fccb512ecb44f9ddb9420cfacdd0a Mon Sep 17 00:00:00 2001 From: Guillaume Becq Date: Thu, 25 Apr 2024 16:33:18 +0200 Subject: [PATCH 1/3] Update OrthoSlicer3D._set_position in viewers.py wrong indices to original data leading to weird selection of voxels for weird affine transforms and weird volumes this bug is also related to strange behavior with special acquisition, for example with small animal settings such as rodents leading to wrong location of origin (0,0,0) with image.orthoview() --- nibabel/viewers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nibabel/viewers.py b/nibabel/viewers.py index 1e927544b..e66a34149 100644 --- a/nibabel/viewers.py +++ b/nibabel/viewers.py @@ -399,7 +399,8 @@ def _set_position(self, x, y, z, notify=True): # deal with slicing appropriately self._position[:3] = [x, y, z] idxs = np.dot(self._inv_affine, self._position)[:3] - for ii, (size, idx) in enumerate(zip(self._sizes, idxs)): + idxs_new_order = idxs[self._order] + for ii, (size, idx) in enumerate(zip(self._sizes, idxs_new_order)): self._data_idx[ii] = max(min(int(round(idx)), size - 1), 0) for ii in range(3): # sagittal: get to S/A From 5203368461dbd720be6e776d52803a5ac81fe434 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Thu, 5 Sep 2024 14:07:31 -0400 Subject: [PATCH 2/3] fix: Update order of indices on mouseclick --- nibabel/viewers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nibabel/viewers.py b/nibabel/viewers.py index e66a34149..0dc2f0daf 100644 --- a/nibabel/viewers.py +++ b/nibabel/viewers.py @@ -492,10 +492,11 @@ def _on_mouse(self, event): x, y = event.xdata, event.ydata x = self._sizes[xax] - x if self._flips[xax] else x y = self._sizes[yax] - y if self._flips[yax] else y - idxs = [None, None, None, 1.0] + idxs = np.ones(4) idxs[xax] = x idxs[yax] = y idxs[ii] = self._data_idx[ii] + idxs[:3] = idxs[self._order] self._set_position(*np.dot(self._affine, idxs)[:3]) self._draw() From 4f36bc7a5591a4ac5ac416a9586a4ad8ec53148c Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Thu, 5 Sep 2024 14:20:26 -0400 Subject: [PATCH 3/3] test: Add regression test for rotated data --- nibabel/tests/test_viewers.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/nibabel/tests/test_viewers.py b/nibabel/tests/test_viewers.py index 53f4a32bd..72d839c92 100644 --- a/nibabel/tests/test_viewers.py +++ b/nibabel/tests/test_viewers.py @@ -102,3 +102,35 @@ def test_viewer(): v2.link_to(v1) # shouldn't do anything v1.close() v2.close() + + +@needs_mpl +def test_viewer_nonRAS(): + data1 = np.random.rand(10, 20, 40) + data1[5, 10, :] = 0 + data1[5, :, 30] = 0 + data1[:, 10, 30] = 0 + # RSA affine + aff1 = np.array([[1, 0, 0, -5], [0, 0, 1, -30], [0, 1, 0, -10], [0, 0, 0, 1]]) + o1 = OrthoSlicer3D(data1, aff1) + sag = o1._ims[0].get_array() + cor = o1._ims[1].get_array() + axi = o1._ims[2].get_array() + + # Sagittal view: [0, I->S, P->A], so data is transposed, matching plot array + assert_array_equal(sag, data1[5, :, :]) + # Coronal view: [L->R, I->S, 0]. Data is not transposed, transpose to match plot array + assert_array_equal(cor, data1[:, :, 30].T) + # Axial view: [L->R, 0, P->A]. Data is not transposed, transpose to match plot array + assert_array_equal(axi, data1[:, 10, :].T) + + o1.set_position(1, 2, 3) # R, A, S coordinates + + sag = o1._ims[0].get_array() + cor = o1._ims[1].get_array() + axi = o1._ims[2].get_array() + + # Shift 1 right, 2 anterior, 3 superior + assert_array_equal(sag, data1[6, :, :]) + assert_array_equal(cor, data1[:, :, 32].T) + assert_array_equal(axi, data1[:, 13, :].T)