From a4f06be4ffc63d79af7d342516503231fd2a67d8 Mon Sep 17 00:00:00 2001 From: Paul McCarthy <pauldmccarthy@gmail.com> Date: Mon, 22 Jul 2019 14:05:51 +0100 Subject: [PATCH] BF: Call existent parseVersionString function, as opposed to non-existent variant. applyDeformation/convertDeformationType/Space were assuming voxel alignment between deformation field and reference image. --- fsl/transform/nonlinear.py | 36 +++++++++++++++++++++++++----------- fsl/transform/x5.py | 4 ++-- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/fsl/transform/nonlinear.py b/fsl/transform/nonlinear.py index 520c5b7a5..82776bfe6 100644 --- a/fsl/transform/nonlinear.py +++ b/fsl/transform/nonlinear.py @@ -584,7 +584,8 @@ def convertDeformationType(field, defType=None): # we need the coordinates of every voxel # in the reference coordinate system. dx, dy, dz = field.shape[:3] - xform = field.getAffine('voxel', field.refSpace) + xform = affine.concat(field.ref.getAffine('world', field.refSpace), + field .getAffine('voxel', 'world')) coords = np.meshgrid(np.arange(dx), np.arange(dy), @@ -659,9 +660,12 @@ def convertDeformationSpace(field, from_, to): refcoords = np.array(refcoords) refcoords = refcoords.transpose((1, 2, 3, 0)).reshape((-1, 3)) - if from_ != 'voxel': - refmat = field.ref.getAffine('voxel', from_) - refcoords = affine.transform(refcoords, refmat) + xform = affine.concat( + field.ref.getAffine('world', from_), + field .getAffine('voxel', 'world')) + + if not np.all(np.isclose(xform, np.eye(4))): + refcoords = affine.transform(refcoords, xform) fieldcoords = srccoords - refcoords @@ -711,6 +715,7 @@ def applyDeformation(image, field, ref=None, order=1, mode=None, cval=None): if order is None: order = 1 if mode is None: mode = 'nearest' if cval is None: cval = 0 + if ref is None: ref = field.ref # We need the field to contain # absolute source image voxel @@ -725,13 +730,22 @@ def applyDeformation(image, field, ref=None, order=1, mode=None, cval=None): refSpace='voxel', defType='absolute') - # Resample to alternate reference image - # space if provided - regions of the - # field outside of the reference image - # space will contain -1s, so will be - # detected as out of bounds by - # map_coordinates - if ref is not None: + # If the field is not voxel-aligned + # to the reference, we need to + # resample the field itself into the + # reference image space (assumed to + # be world-aligned). If field and ref + # are not not world aligned, regions + # of the field outside of the + # reference image space will contain + # -1s, so will be detected as out of + # bounds by map_coordinates below. + # + # This will potentially result in + # truncation at the field boundaries, + # but there's nothing we can do about + # that. + if not field.sameSpace(ref): field = resample.resampleToReference(field, ref, order=1, diff --git a/fsl/transform/x5.py b/fsl/transform/x5.py index 4f14413ed..1ffe03282 100644 --- a/fsl/transform/x5.py +++ b/fsl/transform/x5.py @@ -458,8 +458,8 @@ def _readMetadata(group): version = group.attrs.get('Version') meta = group.attrs.get('Metadata') - parserver = fslversion.parseVersion(X5_VERSION) - filever = fslversion.parseVersion(version) + parserver = fslversion.parseVersionString(X5_VERSION) + filever = fslversion.parseVersionString(version) if (format != X5_FORMAT) or (filever[0] != parserver[0]): raise X5Error('Incompatible format/version (required: {}/{}, ' -- GitLab