Skip to content
Snippets Groups Projects
Commit ca204fed authored by Paul McCarthy's avatar Paul McCarthy :mountain_bicyclist:
Browse files

RF,BK: Change nomenclature in nonlinear module. More to come.

parent 94b5ade7
No related branches found
No related tags found
No related merge requests found
...@@ -8,17 +8,18 @@ ...@@ -8,17 +8,18 @@
FNIRT-style nonlinear transformations. FNIRT-style nonlinear transformations.
The :class:`DisplacementField` and :class:`CoefficientField` can be used to The :class:`DeformationField` and :class:`CoefficientField` can be used to
load and interact with FNIRT transformation images. The following utility load and interact with FNIRT transformation images. The following utility
functions are also available: functions are also available:
.. autosummary:: .. autosummary::
:nosignatures: :nosignatures:
detectDisplacementType detectDeformationType
convertDisplacementType convertDeformationType
convertDisplacementSpace convertDeformationSpace
coefficientFieldToDisplacementField coefficientFieldToDeformationField
""" """
...@@ -38,7 +39,7 @@ log = logging.getLogger(__name__) ...@@ -38,7 +39,7 @@ log = logging.getLogger(__name__)
class NonLinearTransform(fslimage.Image): class NonLinearTransform(fslimage.Image):
"""Class which represents a nonlinear transformation. This is just a base """Class which represents a nonlinear transformation. This is just a base
class for the :class:`DisplacementField` and :class:`CoefficientField` class for the :class:`DeformationField` and :class:`CoefficientField`
classes. classes.
...@@ -53,17 +54,6 @@ class NonLinearTransform(fslimage.Image): ...@@ -53,17 +54,6 @@ class NonLinearTransform(fslimage.Image):
the corresponding location in the source image space. Therefore, these the corresponding location in the source image space. Therefore, these
non-linear transformation effectively encode a transformation *from* the non-linear transformation effectively encode a transformation *from* the
reference image *to* the source image. reference image *to* the source image.
A FNIRT nonlinear transformation often contains a *premat*, a global
affine transformation from the source space to the reference space, which
was calculated with FLIRT, and used as the starting point for the
non-linear optimisation performed by FNIRT.
This affine may be provided when creating a ``NonLinearTransform`` as the
``srcToRefMat`` argument to :meth:`__init__`, and is subsequently accessed
via the :meth:`srcToRefMat` attribute.
""" """
...@@ -73,7 +63,7 @@ class NonLinearTransform(fslimage.Image): ...@@ -73,7 +63,7 @@ class NonLinearTransform(fslimage.Image):
ref, ref,
srcSpace=None, srcSpace=None,
refSpace=None, refSpace=None,
srcToRefMat=None,
**kwargs): **kwargs):
"""Create a ``NonLinearTransform``. """Create a ``NonLinearTransform``.
...@@ -93,20 +83,11 @@ class NonLinearTransform(fslimage.Image): ...@@ -93,20 +83,11 @@ class NonLinearTransform(fslimage.Image):
``NonLinearTransform`` maps from. Defaults to ``NonLinearTransform`` maps from. Defaults to
``'fsl'``. ``'fsl'``.
:arg srcToRefMat: Optional initial global affine transformation from
the source image to the reference image. This is
assumed to be a FLIRT-style matrix, i.e. it
transforms from source image ``srcSpace`` coordinates
into reference image ``refSpace`` coordinates
(typically ``'fsl'`` coordinates, i.e. scaled voxels
potentially with a left-right flip).
All other arguments are passed through to :meth:`.Image.__init__`. All other arguments are passed through to :meth:`.Image.__init__`.
""" """
if srcSpace is None: srcSpace = 'fsl' if srcSpace is None: srcSpace = 'fsl'
if refSpace is None: refSpace = 'fsl' if refSpace is None: refSpace = 'fsl'
if srcToRefMat is not None: srcToRefMat = np.copy(srcToRefMat)
if srcSpace not in ('fsl', 'voxel', 'world') or \ if srcSpace not in ('fsl', 'voxel', 'world') or \
refSpace not in ('fsl', 'voxel', 'world'): refSpace not in ('fsl', 'voxel', 'world'):
...@@ -119,11 +100,6 @@ class NonLinearTransform(fslimage.Image): ...@@ -119,11 +100,6 @@ class NonLinearTransform(fslimage.Image):
self.__ref = fslimage.Nifti(ref.header.copy()) self.__ref = fslimage.Nifti(ref.header.copy())
self.__srcSpace = srcSpace self.__srcSpace = srcSpace
self.__refSpace = refSpace self.__refSpace = refSpace
self.__srcToRefMat = srcToRefMat
self.__refToSrcMat = None
if srcToRefMat is not None:
self.__refToSrcMat = affine.invert(srcToRefMat)
@property @property
...@@ -158,23 +134,7 @@ class NonLinearTransform(fslimage.Image): ...@@ -158,23 +134,7 @@ class NonLinearTransform(fslimage.Image):
return self.__refSpace return self.__refSpace
@property def transform(self, coords, from_=None, to=None):
def srcToRefMat(self):
"""Return the initial source-to-reference affine, or ``None`` if
there isn't one.
"""
return self.__srcToRefMat
@property
def refToSrcMat(self):
"""Return the inverse of the initial source-to-reference affine, or
``None`` if there isn't one.
"""
return self.__refToSrcMat
def transform(self, coords, from_=None, to=None, premat=True):
"""Transform coordinates from the reference image space to the source """Transform coordinates from the reference image space to the source
image space. Implemented by sub-classes. image space. Implemented by sub-classes.
...@@ -186,31 +146,31 @@ class NonLinearTransform(fslimage.Image): ...@@ -186,31 +146,31 @@ class NonLinearTransform(fslimage.Image):
:arg to: Source image space to transform ``coords`` into :arg to: Source image space to transform ``coords`` into
:arg premat: If ``True``, the inverse :meth:`srcToRefMat` is applied
to the coordinates after they have been calculated.
:returns: ``coords``, transformed into the source image space :returns: ``coords``, transformed into the source image space
""" """
raise NotImplementedError() raise NotImplementedError()
class DisplacementField(NonLinearTransform): class DeformationField(NonLinearTransform):
"""Class which represents a displacement field which, at each voxel, """Class which represents a deformation (a.k.a. warp) field which, at each
contains an absolute or relative displacement between a source space and a voxel, contains either:
reference space.
- a relative displacement from the reference space to the source space,
or
- absolute coordinates in the source space
""" """
def __init__(self, image, src, ref=None, **kwargs): def __init__(self, image, src, ref=None, **kwargs):
"""Create a ``DisplacementField``. """Create a ``DisplacementField``.
:arg ref: Optional. If not provided, it is assumed that the :arg ref: Optional. If not provided, it is assumed that the
reference is defined in the same space as ``image``. reference is defined in the same space as ``image``.
:arg dispType: Either ``'absolute'`` or ``'relative'``, indicating :arg defType: Either ``'absolute'`` or ``'relative'``, indicating
the type of this displacement field. If not provided, the type of this displacement field. If not provided,
will be inferred via the :func:`detectDisplacementType` will be inferred via the :func:`detectDeformationType`
function. function.
All other arguments are passed through to All other arguments are passed through to
:meth:`NonLinearTransform.__init__`. :meth:`NonLinearTransform.__init__`.
...@@ -219,46 +179,46 @@ class DisplacementField(NonLinearTransform): ...@@ -219,46 +179,46 @@ class DisplacementField(NonLinearTransform):
if ref is None: if ref is None:
ref = self ref = self
dispType = kwargs.pop('dispType', None) defType = kwargs.pop('defType', None)
if dispType not in (None, 'relative', 'absolute'): if defType not in (None, 'relative', 'absolute'):
raise ValueError('Invalid value for dispType: {}'.format(dispType)) raise ValueError('Invalid value for defType: {}'.format(defType))
NonLinearTransform.__init__(self, image, src, ref, **kwargs) NonLinearTransform.__init__(self, image, src, ref, **kwargs)
if not self.sameSpace(self.ref): if not self.sameSpace(self.ref):
raise ValueError('Invalid reference image: {}'.format(self.ref)) raise ValueError('Invalid reference image: {}'.format(self.ref))
self.__dispType = dispType self.__defType = defType
@property @property
def displacementType(self): def deformationType(self):
"""The type of this ``DisplacementField`` - ``'absolute'`` or """The type of this ``DeformationField`` - ``'absolute'`` or
``'relative'``. ``'relative'``.
""" """
if self.__dispType is None: if self.__defType is None:
self.__dispType = detectDisplacementType(self) self.__defType = detectDeformationType(self)
return self.__dispType return self.__defType
@property @property
def absolute(self): def absolute(self):
"""``True`` if this ``DisplacementField`` contains absolute """``True`` if this ``DeformationField`` contains absolute
displacements. coordinates.
""" """
return self.displacementType == 'absolute' return self.deformationType == 'absolute'
@property @property
def relative(self): def relative(self):
"""``True`` if this ``DisplacementField`` contains relative """``True`` if this ``DeformationField`` contains relative
displacements. displacements.
""" """
return self.displacementType == 'relative' return self.deformationType == 'relative'
def transform(self, coords, from_=None, to=None, premat=True): def transform(self, coords, from_=None, to=None):
"""Transform the given XYZ coordinates from the reference image space """Transform the given XYZ coordinates from the reference image space
to the source image space. to the source image space.
...@@ -270,9 +230,6 @@ class DisplacementField(NonLinearTransform): ...@@ -270,9 +230,6 @@ class DisplacementField(NonLinearTransform):
:arg to: Source image space to transform ``coords`` into :arg to: Source image space to transform ``coords`` into
:arg premat: If ``True``, the inverse :meth:`srcToRefMat` is applied
to the coordinates after they have been calculated.
:returns: ``coords``, transformed into the source image space :returns: ``coords``, transformed into the source image space
""" """
...@@ -310,28 +267,14 @@ class DisplacementField(NonLinearTransform): ...@@ -310,28 +267,14 @@ class DisplacementField(NonLinearTransform):
if self.absolute: disps = self.data[xs, ys, zs, :] if self.absolute: disps = self.data[xs, ys, zs, :]
else: disps = self.data[xs, ys, zs, :] + coords[voxmask] else: disps = self.data[xs, ys, zs, :] + coords[voxmask]
# Make sure the coordinates are # Make sure the coordinates are in
# in the requested source image # the requested source image space
# space, and apply the initial
# inv(srcToRefMat) if it there
# is one
# And here the premat becomes
# a postmat; how confusing
if premat: postmat = self.refToSrcMat
else: postmat = None
if to != self.srcSpace: if to != self.srcSpace:
xform = self.src.getAffine(self.srcSpace, to) xform = self.src.getAffine(self.srcSpace, to)
if postmat is not None: postmat = affine.concat(xform, postmat) disps = affine.transform(disps, xform)
else: postmat = xform
if postmat is not None:
disps = affine.transform(disps, postmat)
# Nans for input coordinates # Nans for input coordinates which
# which were outside of the # were outside of the field
# field
outcoords = np.full(coords.shape, np.nan) outcoords = np.full(coords.shape, np.nan)
outcoords[voxmask] = disps outcoords[voxmask] = disps
...@@ -343,6 +286,17 @@ class CoefficientField(NonLinearTransform): ...@@ -343,6 +286,17 @@ class CoefficientField(NonLinearTransform):
The :meth:`displacements` method can be used to calculate relative The :meth:`displacements` method can be used to calculate relative
displacements for a set of reference space voxel coordinates. displacements for a set of reference space voxel coordinates.
A FNIRT nonlinear transformation often contains a *premat*, a global
affine transformation from the source space to the reference space, which
was calculated with FLIRT, and used as the starting point for the
non-linear optimisation performed by FNIRT.
This affine may be provided when creating a ``CoefficientField`` as the
``srcToRefMat`` argument to :meth:`__init__`, and is subsequently accessed
via the :meth:`srcToRefMat` attribute.
""" """
...@@ -355,6 +309,7 @@ class CoefficientField(NonLinearTransform): ...@@ -355,6 +309,7 @@ class CoefficientField(NonLinearTransform):
fieldType, fieldType,
knotSpacing, knotSpacing,
fieldToRefMat, fieldToRefMat,
srcToRefMat=None,
**kwargs): **kwargs):
"""Create a ``CoefficientField``. """Create a ``CoefficientField``.
...@@ -367,6 +322,14 @@ class CoefficientField(NonLinearTransform): ...@@ -367,6 +322,14 @@ class CoefficientField(NonLinearTransform):
image voxel coordinates into coefficient field image voxel coordinates into coefficient field
voxel coordinates. voxel coordinates.
:arg srcToRefMat: Optional initial global affine transformation from
the source image to the reference image. This is
assumed to be a FLIRT-style matrix, i.e. it
transforms from source image ``srcSpace``
coordinates into reference image ``refSpace``
coordinates (typically ``'fsl'`` coordinates, i.e.
scaled voxels potentially with a left-right flip).
See the :class:`NonLinearTransform` class for details on the other See the :class:`NonLinearTransform` class for details on the other
arguments. arguments.
""" """
...@@ -374,6 +337,9 @@ class CoefficientField(NonLinearTransform): ...@@ -374,6 +337,9 @@ class CoefficientField(NonLinearTransform):
if fieldType not in ('cubic',): if fieldType not in ('cubic',):
raise ValueError('Unsupported field type: {}'.format(fieldType)) raise ValueError('Unsupported field type: {}'.format(fieldType))
if srcToRefMat is not None:
srcToRefMat = np.copy(srcToRefMat)
NonLinearTransform.__init__(self, NonLinearTransform.__init__(self,
image, image,
src, src,
...@@ -384,9 +350,14 @@ class CoefficientField(NonLinearTransform): ...@@ -384,9 +350,14 @@ class CoefficientField(NonLinearTransform):
self.__fieldType = fieldType self.__fieldType = fieldType
self.__knotSpacing = tuple(knotSpacing) self.__knotSpacing = tuple(knotSpacing)
self.__refToSrcMat = None
self.__srcToRefMat = srcToRefMat
self.__fieldToRefMat = np.copy(fieldToRefMat) self.__fieldToRefMat = np.copy(fieldToRefMat)
self.__refToFieldMat = affine.invert(self.__fieldToRefMat) self.__refToFieldMat = affine.invert(self.__fieldToRefMat)
if srcToRefMat is not None:
self.__refToSrcMat = affine.invert(srcToRefMat)
@property @property
def fieldType(self): def fieldType(self):
...@@ -420,11 +391,27 @@ class CoefficientField(NonLinearTransform): ...@@ -420,11 +391,27 @@ class CoefficientField(NonLinearTransform):
return np.copy(self.__refToFieldMat) return np.copy(self.__refToFieldMat)
@property
def srcToRefMat(self):
"""Return the initial source-to-reference affine, or ``None`` if
there isn't one.
"""
return self.__srcToRefMat
@property
def refToSrcMat(self):
"""Return the inverse of the initial source-to-reference affine, or
``None`` if there isn't one.
"""
return self.__refToSrcMat
@memoize.Instanceify(memoize.memoize) @memoize.Instanceify(memoize.memoize)
def asDisplacementField(self, dispType='relative', premat=True): def asDeformationField(self, defType='relative', premat=True):
"""Convert this ``CoefficientField`` to a :class:`DisplacementField`. """Convert this ``CoefficientField`` to a :class:`DeformationField`.
""" """
return coefficientFieldToDisplacementField(self, dispType, premat) return coefficientFieldToDeformationField(self, defType, premat)
def transform(self, coords, from_=None, to=None, premat=True): def transform(self, coords, from_=None, to=None, premat=True):
...@@ -446,7 +433,7 @@ class CoefficientField(NonLinearTransform): ...@@ -446,7 +433,7 @@ class CoefficientField(NonLinearTransform):
:returns: ``coords``, transformed into the source image space :returns: ``coords``, transformed into the source image space
""" """
df = self.asDisplacementField(premat=premat) df = self.asDeformationField(premat=premat)
return df.transform(coords, from_, to) return df.transform(coords, from_, to)
...@@ -531,23 +518,23 @@ class CoefficientField(NonLinearTransform): ...@@ -531,23 +518,23 @@ class CoefficientField(NonLinearTransform):
return disps return disps
def detectDisplacementType(field): def detectDeformationType(field):
"""Attempt to automatically determine whether a displacement field is """Attempt to automatically determine whether a deformation field is
specified in absolute or relative coordinates. specified in absolute or relative coordinates.
:arg field: A :class:`DisplacementField` :arg field: A :class:`DeformationField`
:returns: ``'absolute'`` if it looks like ``field`` contains absolute :returns: ``'absolute'`` if it looks like ``field`` contains absolute
displacements, ``'relative'`` otherwise. coordinates, ``'relative'`` otherwise.
""" """
# This test is based on the assumption # This test is based on the assumption
# that a displacement field containing # that a deformation field containing
# absolute coordinates will have a # absolute coordinates will have a
# greater standard deviation than one # greater standard deviation than one
# which contains relative coordinates. # which contains relative coordinates.
absdata = field[:] absdata = field[:]
reldata = convertDisplacementType(field, 'relative') reldata = convertDeformationType(field, 'relative')
stdabs = absdata.std(axis=(0, 1, 2)).sum() stdabs = absdata.std(axis=(0, 1, 2)).sum()
stdrel = reldata.std(axis=(0, 1, 2)).sum() stdrel = reldata.std(axis=(0, 1, 2)).sum()
...@@ -555,20 +542,19 @@ def detectDisplacementType(field): ...@@ -555,20 +542,19 @@ def detectDisplacementType(field):
else: return 'relative' else: return 'relative'
def convertDisplacementType(field, dispType=None): def convertDeformationType(field, defType=None):
"""Convert a displacement field between storing absolute and relative """Convert a deformation field between storing absolute coordinates or
displacements. relative displacements.
:arg field: A :class:`DisplacementField` instance :arg field: A :class:`DeformationField` instance
:arg dispType: Either ``'absolute'`` or ``'relative'``. If not provided, :arg defType: Either ``'absolute'`` or ``'relative'``. If not provided,
the opposite type to ``field.displacementType`` is used. the opposite type to ``field.deformationType`` is used.
:returns: A ``numpy.array`` containing the adjusted displacement :returns: A ``numpy.array`` containing the adjusted deformation field.
field.
""" """
if dispType is None: if defType is None:
if field.displacementType == 'absolute': dispType = 'relative' if field.deformationType == 'absolute': defType = 'relative'
else: dispType = 'absolute' else: defType = 'absolute'
# Regardless of the conversion direction, # Regardless of the conversion direction,
# we need the coordinates of every voxel # we need the coordinates of every voxel
...@@ -588,36 +574,29 @@ def convertDisplacementType(field, dispType=None): ...@@ -588,36 +574,29 @@ def convertDisplacementType(field, dispType=None):
# (what is assumed to be) the relative shift. # (what is assumed to be) the relative shift.
# Or, to convert from absolute to relative, # Or, to convert from absolute to relative,
# we subtract the reference image voxels. # we subtract the reference image voxels.
if dispType == 'absolute': return field.data + coords if defType == 'absolute': return field.data + coords
elif dispType == 'relative': return field.data - coords elif defType == 'relative': return field.data - coords
def convertDisplacementSpace(field, from_, to): def convertDeformationSpace(field, from_, to):
"""Adjust the source and/or reference spaces of the given displacement """Adjust the source and/or reference spaces of the given deformation
field. See the :meth:`.Nifti.getAffine` method for the valid values for field. See the :meth:`.Nifti.getAffine` method for the valid values for
the ``from_`` and ``to`` arguments. the ``from_`` and ``to`` arguments.
:arg field: A :class:`DisplacementField` instance :arg field: A :class:`DeformationField` instance
:arg from_: New reference image coordinate system :arg from_: New reference image coordinate system
:arg to: New source image coordinate system :arg to: New source image coordinate system
:returns: A new :class:`DisplacementField` which transforms between :returns: A new :class:`DeformationField` which transforms between
the reference ``from_`` coordinate system and the source ``to`` the reference ``from_`` coordinate system and the source ``to``
coordinate system. coordinate system.
""" """
# We can't adjust the displacements
# for fields with an initial
# source-to-ref affine
if field.srcToRefMat is not None:
raise ValueError('Cannot adjust displacements of '
'fields with an initial affine')
# Get the field in absolute coordinates # Get the field in absolute coordinates
# if necessary - these are our source # if necessary - these are our source
# coordinates in the original "to" space. # coordinates in the original "to" space.
fieldcoords = field.data fieldcoords = field.data
if field.relative: srccoords = convertDisplacementType(field) if field.relative: srccoords = convertDeformationType(field)
else: srccoords = fieldcoords else: srccoords = fieldcoords
srccoords = srccoords.reshape((-1, 3)) srccoords = srccoords.reshape((-1, 3))
...@@ -631,13 +610,13 @@ def convertDisplacementSpace(field, from_, to): ...@@ -631,13 +610,13 @@ def convertDisplacementSpace(field, from_, to):
srccoords = affine.transform(srccoords, srcmat) srccoords = affine.transform(srccoords, srcmat)
# If we have been asked to return # If we have been asked to return
# an absolute displacement, the # absolute coordinates, the
# reference "from_" coordinate # reference "from_" coordinate
# system is irrelevant - we're done. # system is irrelevant - we're done.
if field.absolute: if field.absolute:
fieldcoords = srccoords fieldcoords = srccoords
# Otherwise our displacement field # Otherwise our deformation field
# will contain relative displacements # will contain relative displacements
# between the reference image "from_" # between the reference image "from_"
# coordinate system and the source # coordinate system and the source
...@@ -659,30 +638,30 @@ def convertDisplacementSpace(field, from_, to): ...@@ -659,30 +638,30 @@ def convertDisplacementSpace(field, from_, to):
fieldcoords = srccoords - refcoords fieldcoords = srccoords - refcoords
return DisplacementField( return DeformationField(
fieldcoords.reshape(field.shape), fieldcoords.reshape(field.shape),
header=field.header, header=field.header,
src=field.src, src=field.src,
ref=field.ref, ref=field.ref,
srcSpace=to, srcSpace=to,
refSpace=from_, refSpace=from_,
dispType=field.displacementType) defType=field.deformationType)
def coefficientFieldToDisplacementField(field, def coefficientFieldToDeformationField(field,
dispType='relative', defType='relative',
premat=True): premat=True):
"""Convert a :class:`CoefficientField` into a :class:`DisplacementField`. """Convert a :class:`CoefficientField` into a :class:`DeformationField`.
:arg field: :class:`CoefficientField` to convert :arg field: :class:`CoefficientField` to convert
:arg dispType: The type of displacement field - either ``'relative'`` (the :arg defType: The type of deformation field - either ``'relative'`` (the
default) or ``'absolute'``. default) or ``'absolute'``.
:arg premat: If ``True`` (the default), the :meth:`srcToRefMat` is :arg premat: If ``True`` (the default), the :meth:`srcToRefMat` is
encoded into the displacements. encoded into the deformation field.
:return: :class:`DisplacementField` calculated from ``field``. :return: :class:`DeformationField` calculated from ``field``.
""" """
# Generate coordinates for every # Generate coordinates for every
...@@ -715,22 +694,22 @@ def coefficientFieldToDisplacementField(field, ...@@ -715,22 +694,22 @@ def coefficientFieldToDisplacementField(field,
# from ref space to aligned-src # from ref space to aligned-src
# space. # space.
disps = field.displacements(xyz).reshape((ix, iy, iz, 3)) disps = field.displacements(xyz).reshape((ix, iy, iz, 3))
rdfield = DisplacementField(disps, rdfield = DeformationField(disps,
src=field.src, src=field.src,
ref=field.ref, ref=field.ref,
srcSpace=field.srcSpace, srcSpace=field.srcSpace,
refSpace=field.refSpace, refSpace=field.refSpace,
header=field.ref.header, header=field.ref.header,
dispType='relative') defType='relative')
if (dispType == 'relative') and (not premat): if (defType == 'relative') and (not premat):
return rdfield return rdfield
# Convert to absolute - the # Convert to absolute - the
# displacements will now be # deformations will now be
# absolute coordinates in # absolute coordinates in
# aligned-src space # aligned-src space
disps = convertDisplacementType(rdfield) disps = convertDeformationType(rdfield)
# Apply the premat if requested - # Apply the premat if requested -
# this will transform the coordinates # this will transform the coordinates
...@@ -756,23 +735,23 @@ def coefficientFieldToDisplacementField(field, ...@@ -756,23 +735,23 @@ def coefficientFieldToDisplacementField(field,
# #
# disps = affine.transform(disps, refToSrc) # disps = affine.transform(disps, refToSrc)
adfield = DisplacementField(disps, adfield = DeformationField(disps,
src=field.src, src=field.src,
ref=field.ref, ref=field.ref,
srcSpace=field.srcSpace, srcSpace=field.srcSpace,
refSpace=field.refSpace, refSpace=field.refSpace,
header=field.ref.header, header=field.ref.header,
dispType='absolute') defType='absolute')
# Not either return absolute displacements, # Not either return absolute displacements,
# or convert back to relative displacements # or convert back to relative displacements
if dispType == 'absolute': if defType == 'absolute':
return adfield return adfield
else: else:
return DisplacementField(convertDisplacementType(adfield), return DeformationField(convertDeformationType(adfield),
src=field.src, src=field.src,
ref=field.ref, ref=field.ref,
srcSpace=field.srcSpace, srcSpace=field.srcSpace,
refSpace=field.refSpace, refSpace=field.refSpace,
header=field.ref.header, header=field.ref.header,
dispType='relative') defType='relative')
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment