Skip to content

Commit 01cfcbc

Browse files
committed
fix: bug in oblique adjusting matrices computation
1 parent 0a02bcf commit 01cfcbc

File tree

5 files changed

+16
-8
lines changed

5 files changed

+16
-8
lines changed

nitransforms/io/afni.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,10 @@ def to_ras(self, moving=None, reference=None):
135135
if reference is not None and _is_oblique(ref_aff := _ensure_image(reference).affine):
136136
pre_rotation = _cardinal_rotation(ref_aff, True)
137137
if moving is not None and _is_oblique(mov_aff := _ensure_image(moving).affine):
138-
post_rotation = _cardinal_rotation(mov_aff, True)
138+
post_rotation = _cardinal_rotation(mov_aff, False)
139139

140140
return np.stack([
141-
post_rotation @ xfm.to_ras() @ pre_rotation
141+
post_rotation @ (xfm.to_ras() @ pre_rotation)
142142
for xfm in self.xforms
143143
])
144144

@@ -152,14 +152,22 @@ def to_string(self):
152152
if line.strip()
153153
]
154154
strings += lines
155-
return "\n".join(strings)
155+
return "\n".join(strings + [""])
156156

157157
@classmethod
158158
def from_ras(cls, ras, moving=None, reference=None):
159159
"""Create an ITK affine from a nitransform's RAS+ matrix."""
160160
_self = cls()
161+
162+
pre_rotation = post_rotation = np.eye(4)
163+
164+
if reference is not None and _is_oblique(ref_aff := _ensure_image(reference).affine):
165+
pre_rotation = _cardinal_rotation(ref_aff, False)
166+
if moving is not None and _is_oblique(mov_aff := _ensure_image(moving).affine):
167+
post_rotation = _cardinal_rotation(mov_aff, True)
168+
161169
_self.xforms = [
162-
cls._inner_type.from_ras(ras[i, ...], moving=moving, reference=reference)
170+
cls._inner_type.from_ras(post_rotation @ ras[i, ...] @ pre_rotation)
163171
for i in range(ras.shape[0])
164172
]
165173
return _self
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
affine-RAS.afni-array
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
affine-RAS.afni-array
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
affine-RAS.afni-array

nitransforms/tests/test_io.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,6 @@ def test_Linear_common(tmpdir, data_path, sw, image_orientation, get_testdata):
208208

209209
fname = f"affine-{image_orientation}.{sw}{ext}"
210210

211-
if sw == "afni-array":
212-
fname.replace(image_orientation, "RAS")
213-
214211
# Test the transform loaders are implemented
215212
xfm = factory.from_filename(data_path / fname)
216213

@@ -228,7 +225,7 @@ def test_Linear_common(tmpdir, data_path, sw, image_orientation, get_testdata):
228225
# Test from_ras
229226
RAS = from_matvec(euler2mat(x=0.9, y=0.001, z=0.001), [4.0, 2.0, -1.0])
230227
if sw == "afni-array":
231-
RAS = [RAS, RAS]
228+
RAS = np.array([RAS, RAS])
232229

233230
xfm = factory.from_ras(RAS, reference=reference, moving=moving)
234231
assert np.allclose(xfm.to_ras(reference=reference, moving=moving), RAS)

0 commit comments

Comments
 (0)