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

RF: Rename dispfield to nonlinear - best kept all together i think

parent 1cd1392f
No related branches found
No related tags found
No related merge requests found
#!/usr/bin/env python #!/usr/bin/env python
# #
# dispfield.py - FNIRT displacement fields # nonlinear.py -
# #
# Author: Paul McCarthy <pauldmccarthy@gmail.com> # Author: Paul McCarthy <pauldmccarthy@gmail.com>
# #
"""
FNIRT displacement field files may contain coordinates in one of two
formats:
"""
import numpy as np import numpy as np
import fsl.data.image as fslimage import fsl.data.image as fslimage
from . import affine
from . import affine
class DisplacementField(fslimage.Image):
""" class NonLinearTransform(fslimage.Image):
"""Class which represents a FNIRT non-linear transformation
""" """
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
""" """
""" """
source = kwargs.pop('source', None) src = kwargs.pop('src', None)
reference = kwargs.pop('reference', None) ref = kwargs.pop('ref', None)
dispType = kwargs.pop('dispType', None) srcSpace = kwargs.pop('srceSpace', 'fsl')
sourceSpace = kwargs.pop('sourceSpace', 'fsl') refSpace = kwargs.pop('refSpace', 'fsl')
referenceSpace = kwargs.pop('referenceSpace', 'fsl')
fslimage.Image.__init__(self, *args, **kwargs) fslimage.Image.__init__(self, *args, **kwargs)
if source is not None: source = source .header.copy() if src is not None: src = src .header.copy()
if reference is not None: reference = reference.header.copy() if ref is not None: ref = ref .header.copy()
else: reference = self .header.copy() else: ref = self.header.copy()
self.__dispType = dispType self.__src = src
self.__source = source self.__ref = ref
self.__reference = reference self.__srcSpace = srcSpace
self.__sourceSpace = sourceSpace self.__refSpace = refSpace
self.__referenceSpace = referenceSpace
@property @property
def source(self): def src(self):
return self.__source return self.__src
@property @property
def reference(self): def ref(self):
return self.__reference return self.__ref
@property @property
def sourceSpace(self): def srcSpace(self):
return self.__sourceSpace return self.__srcSpace
@property @property
def referenceSpace(self): def refSpace(self):
"""irrelevant if absolute displacement""" return self.__refSpace
return self.__referenceSpace
class DisplacementField(NonLinearTransform):
"""Class which represents a FNIRT displacement field which, at each voxel,
contains an absolute or relative displacement from a source space to a
reference space.
"""
def __init__(self, *args, **kwargs):
"""
"""
dispType = kwargs.pop('dispType', None)
NonLinearTransform.__init__(self, *args, **kwargs)
self.__dispType = dispType
@property @property
def displacementType(self): def displacementType(self):
if self.__dispType is None: if self.__dispType is None:
self.__dispType = detectType(self) self.__dispType = detectDisplacementType(self)
return self.__dispType return self.__dispType
...@@ -83,7 +91,8 @@ class DisplacementField(fslimage.Image): ...@@ -83,7 +91,8 @@ class DisplacementField(fslimage.Image):
return self.displacementType == 'relative' return self.displacementType == 'relative'
def detectType(field):
def detectDisplacementType(field):
"""Attempt to automatically determine whether a displacement field is """Attempt to automatically determine whether a displacement field is
specified in absolute or relative coordinates. specified in absolute or relative coordinates.
...@@ -99,7 +108,7 @@ def detectType(field): ...@@ -99,7 +108,7 @@ def detectType(field):
# standard deviation than one which # standard deviation than one which
# contains relative coordinates. # contains relative coordinates.
absdata = field[:] absdata = field[:]
reldata = convertType(field, 'relative') reldata = convertDisplacementType(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()
...@@ -107,7 +116,7 @@ def detectType(field): ...@@ -107,7 +116,7 @@ def detectType(field):
else: return 'relative' else: return 'relative'
def convertType(field, dispType=None): def convertDisplacementType(field, dispType=None):
"""Convert a displacement field between storing absolute and relative """Convert a displacement field between storing absolute and relative
displacements. displacements.
""" """
...@@ -120,7 +129,7 @@ def convertType(field, dispType=None): ...@@ -120,7 +129,7 @@ def convertType(field, dispType=None):
# we need the coordinates of every voxel # we need the coordinates of every voxel
# in the reference FSL coordinate system. # in the reference FSL coordinate system.
dx, dy, dz = field.shape[:3] dx, dy, dz = field.shape[:3]
v2fsl = field.getAffine('voxel', field.sourceSpace) v2fsl = field.getAffine('voxel', field.srcSpace)
coords = np.meshgrid(np.arange(dx), coords = np.meshgrid(np.arange(dx),
np.arange(dy), np.arange(dy),
np.arange(dz), indexing='ij') np.arange(dz), indexing='ij')
...@@ -137,7 +146,7 @@ def convertType(field, dispType=None): ...@@ -137,7 +146,7 @@ def convertType(field, dispType=None):
elif dispType == 'relative': return field.data - coords elif dispType == 'relative': return field.data - coords
def convertSpace(field, src, from_, to, ref=None, dispType=None): def convertDisplacementSpace(field, src, from_, to, ref=None, dispType=None):
"""Adjust the source and/or reference spaces of the given displacement """Adjust the source and/or reference spaces of the given displacement
field. field.
""" """
...@@ -148,14 +157,14 @@ def convertSpace(field, src, from_, to, ref=None, dispType=None): ...@@ -148,14 +157,14 @@ def convertSpace(field, src, from_, to, ref=None, dispType=None):
# Get the field in absolute # Get the field in absolute
# coordinates if necessary # coordinates if necessary
fieldcoords = field.data fieldcoords = field.data
if field.relative: srccoords = convertType(field) if field.relative: srccoords = convertDisplacementType(field)
else: srccoords = fieldcoords else: srccoords = fieldcoords
# Now transform those source # Now transform those source
# coordinates from the original # coordinates from the original
# source space to the source # source space to the source
# space specified by "from_" # space specified by "from_"
srcmat = src.getAffine(field.sourceSpace, from_) srcmat = src.getAffine(field.srcSpace, from_)
srccoords = srccoords.reshape((-1, 3)) srccoords = srccoords.reshape((-1, 3))
srccoords = affine.transform(srccoords, srcmat) srccoords = affine.transform(srccoords, srcmat)
...@@ -175,7 +184,7 @@ def convertSpace(field, src, from_, to, ref=None, dispType=None): ...@@ -175,7 +184,7 @@ def convertSpace(field, src, from_, to, ref=None, dispType=None):
# displacements from source "from_" # displacements from source "from_"
# space into reference "to" space. # space into reference "to" space.
else: else:
refmat = ref.getAffine(field.referenceSpace, to) refmat = ref.getAffine(field.refSpace, to)
refcoords = fieldcoords.reshape((-1, 3)) refcoords = fieldcoords.reshape((-1, 3))
refcoords = affine.transform(refcoords, refmat) refcoords = affine.transform(refcoords, refmat)
fieldcoords = srccoords - refcoords fieldcoords = srccoords - refcoords
...@@ -183,8 +192,8 @@ def convertSpace(field, src, from_, to, ref=None, dispType=None): ...@@ -183,8 +192,8 @@ def convertSpace(field, src, from_, to, ref=None, dispType=None):
return DisplacementField( return DisplacementField(
fieldcoords.reshape(field.shape), fieldcoords.reshape(field.shape),
header=field.header, header=field.header,
source=src, src=src,
reference=ref, ref=ref,
sourceSpace=from_, srcSpace=from_,
referenceSpace=to, refSpace=to,
dispType=dispType) dispType=dispType)
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