From 755e8d1c18b948a6efee262419feae77054ea3ad Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Thu, 16 Nov 2023 17:11:10 +0100 Subject: [PATCH] fix: inefficient iterative reloading of reference and moving images The list comprehension had ``nb.loads`` and other method calls continously happening when converting the affine array into RAS. --- nitransforms/io/afni.py | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/nitransforms/io/afni.py b/nitransforms/io/afni.py index b7fc657b..75476e77 100644 --- a/nitransforms/io/afni.py +++ b/nitransforms/io/afni.py @@ -108,17 +108,24 @@ def from_string(cls, string): sa["parameters"] = parameters return tf - def to_ras(self, moving=None, reference=None): + def to_ras(self, moving=None, reference=None, pre_rotation=None, post_rotation=None): """Return a nitransforms internal RAS+ matrix.""" # swapaxes is necessary, as axis 0 encodes series of transforms retval = LPS @ np.swapaxes(self.structarr["parameters"].T, 0, 1) @ LPS - reference = _ensure_image(reference) - if reference is not None and _is_oblique(reference.affine): - retval = retval @ _cardinal_rotation(reference.affine, True) - moving = _ensure_image(moving) - if moving is not None and _is_oblique(moving.affine): - retval = _cardinal_rotation(moving.affine, False) @ retval + if pre_rotation is None and reference is not None: + ref_aff = _ensure_image(reference).affine + pre_rotation = _cardinal_rotation(ref_aff, True) if _is_oblique(ref_aff) else None + + if pre_rotation is not None: + retval = retval @ pre_rotation + + if post_rotation is None and reference is not None: + mov_aff = _ensure_image(moving).affine + post_rotation = _cardinal_rotation(mov_aff, True) if _is_oblique(mov_aff) else None + + if post_rotation is not None: + retval = post_rotation @ retval return retval @@ -130,9 +137,21 @@ class AFNILinearTransformArray(BaseLinearTransformList): def to_ras(self, moving=None, reference=None): """Return a nitransforms' internal RAS matrix.""" - return np.stack( - [xfm.to_ras(moving=moving, reference=reference) for xfm in self.xforms] - ) + + pre_rotation = None + if reference is not None: + ref_aff = _ensure_image(reference).affine + pre_rotation = _cardinal_rotation(ref_aff, True) if _is_oblique(ref_aff) else None + + post_rotation = None + if moving is not None: + mov_aff = _ensure_image(moving).affine + post_rotation = _cardinal_rotation(mov_aff, True) if _is_oblique(mov_aff) else None + + return np.stack([ + xfm.to_ras(pre_rotation=pre_rotation, post_rotation=post_rotation) + for xfm in self.xforms + ]) def to_string(self): """Convert to a string directly writeable to file."""