Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
F
fslpy
Manage
Activity
Members
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Analyze
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Evan Edmond
fslpy
Commits
ca204fed
Commit
ca204fed
authored
5 years ago
by
Paul McCarthy
Browse files
Options
Downloads
Patches
Plain Diff
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
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
fsl/transform/nonlinear.py
+155
-176
155 additions, 176 deletions
fsl/transform/nonlinear.py
with
155 additions
and
176 deletions
fsl/transform/nonlinear.py
+
155
−
176
View file @
ca204fed
...
@@ -8,17 +8,18 @@
...
@@ -8,17 +8,18 @@
FNIRT-style nonlinear transformations.
FNIRT-style nonlinear transformations.
The :class:`D
isplacement
Field` and :class:`CoefficientField` can be used to
The :class:`D
eformation
Field` 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:
detectD
isplacement
Type
detectD
eformation
Type
convertD
isplacement
Type
convertD
eformation
Type
convertD
isplacement
Space
convertD
eformation
Space
coefficientFieldToD
isplacement
Field
coefficientFieldToD
eformation
Field
"""
"""
...
@@ -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:`D
isplacement
Field` and :class:`CoefficientField`
class for the :class:`D
eformation
Field` 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 d
isp
Type: Either ``
'
absolute
'
`` or ``
'
relative
'
``, indicating
:arg d
ef
Type: 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:`detectD
isplacement
Type`
will be inferred via the :func:`detectD
eformation
Type`
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
d
isp
Type
=
kwargs
.
pop
(
'
d
isp
Type
'
,
None
)
d
ef
Type
=
kwargs
.
pop
(
'
d
ef
Type
'
,
None
)
if
d
isp
Type
not
in
(
None
,
'
relative
'
,
'
absolute
'
):
if
d
ef
Type
not
in
(
None
,
'
relative
'
,
'
absolute
'
):
raise
ValueError
(
'
Invalid value for d
isp
Type: {}
'
.
format
(
d
isp
Type
))
raise
ValueError
(
'
Invalid value for d
ef
Type: {}
'
.
format
(
d
ef
Type
))
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
.
__d
isp
Type
=
d
isp
Type
self
.
__d
ef
Type
=
d
ef
Type
@property
@property
def
d
isplacement
Type
(
self
):
def
d
eformation
Type
(
self
):
"""
The type of this ``D
isplacement
Field`` - ``
'
absolute
'
`` or
"""
The type of this ``D
eformation
Field`` - ``
'
absolute
'
`` or
``
'
relative
'
``.
``
'
relative
'
``.
"""
"""
if
self
.
__d
isp
Type
is
None
:
if
self
.
__d
ef
Type
is
None
:
self
.
__d
isp
Type
=
detectD
isplacement
Type
(
self
)
self
.
__d
ef
Type
=
detectD
eformation
Type
(
self
)
return
self
.
__d
isp
Type
return
self
.
__d
ef
Type
@property
@property
def
absolute
(
self
):
def
absolute
(
self
):
"""
``True`` if this ``D
isplacement
Field`` contains absolute
"""
``True`` if this ``D
eformation
Field`` contains absolute
displacement
s.
coordinate
s.
"""
"""
return
self
.
d
isplacement
Type
==
'
absolute
'
return
self
.
d
eformation
Type
==
'
absolute
'
@property
@property
def
relative
(
self
):
def
relative
(
self
):
"""
``True`` if this ``D
isplacement
Field`` contains relative
"""
``True`` if this ``D
eformation
Field`` contains relative
displacements.
displacements.
"""
"""
return
self
.
d
isplacement
Type
==
'
relative
'
return
self
.
d
eformation
Type
==
'
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
asD
isplacement
Field
(
self
,
d
isp
Type
=
'
relative
'
,
premat
=
True
):
def
asD
eformation
Field
(
self
,
d
ef
Type
=
'
relative
'
,
premat
=
True
):
"""
Convert this ``CoefficientField`` to a :class:`D
isplacement
Field`.
"""
Convert this ``CoefficientField`` to a :class:`D
eformation
Field`.
"""
"""
return
coefficientFieldToD
isplacement
Field
(
self
,
d
isp
Type
,
premat
)
return
coefficientFieldToD
eformation
Field
(
self
,
d
ef
Type
,
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
.
asD
isplacement
Field
(
premat
=
premat
)
df
=
self
.
asD
eformation
Field
(
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
detectD
isplacement
Type
(
field
):
def
detectD
eformation
Type
(
field
):
"""
Attempt to automatically determine whether a d
isplacement
field is
"""
Attempt to automatically determine whether a d
eformation
field is
specified in absolute or relative coordinates.
specified in absolute or relative coordinates.
:arg field: A :class:`D
isplacement
Field`
:arg field: A :class:`D
eformation
Field`
:returns: ``
'
absolute
'
`` if it looks like ``field`` contains absolute
:returns: ``
'
absolute
'
`` if it looks like ``field`` contains absolute
displacement
s, ``
'
relative
'
`` otherwise.
coordinate
s, ``
'
relative
'
`` otherwise.
"""
"""
# This test is based on the assumption
# This test is based on the assumption
# that a d
isplacement
field containing
# that a d
eformation
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
=
convertD
isplacement
Type
(
field
,
'
relative
'
)
reldata
=
convertD
eformation
Type
(
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
convertD
isplacement
Type
(
field
,
d
isp
Type
=
None
):
def
convertD
eformation
Type
(
field
,
d
ef
Type
=
None
):
"""
Convert a d
isplacement
field between storing absolute
and relative
"""
Convert a d
eformation
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
d
isp
Type
is
None
:
if
d
ef
Type
is
None
:
if
field
.
d
isplacement
Type
==
'
absolute
'
:
d
isp
Type
=
'
relative
'
if
field
.
d
eformation
Type
==
'
absolute
'
:
d
ef
Type
=
'
relative
'
else
:
disp
Type
=
'
absolute
'
else
:
def
Type
=
'
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
d
isp
Type
==
'
absolute
'
:
return
field
.
data
+
coords
if
d
ef
Type
==
'
absolute
'
:
return
field
.
data
+
coords
elif
d
isp
Type
==
'
relative
'
:
return
field
.
data
-
coords
elif
d
ef
Type
==
'
relative
'
:
return
field
.
data
-
coords
def
convertD
isplacement
Space
(
field
,
from_
,
to
):
def
convertD
eformation
Space
(
field
,
from_
,
to
):
"""
Adjust the source and/or reference spaces of the given d
isplacement
"""
Adjust the source and/or reference spaces of the given d
eformation
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:`D
isplacement
Field` instance
:arg field: A :class:`D
eformation
Field` 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:`D
isplacement
Field` which transforms between
:returns: A new :class:`D
eformation
Field` 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
=
convertD
isplacement
Type
(
field
)
if
field
.
relative
:
srccoords
=
convertD
eformation
Type
(
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 d
isplacement
field
# Otherwise our d
eformation
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
D
isplacement
Field
(
return
D
eformation
Field
(
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_
,
d
isp
Type
=
field
.
d
isplacement
Type
)
d
ef
Type
=
field
.
d
eformation
Type
)
def
coefficientFieldToD
isplacement
Field
(
field
,
def
coefficientFieldToD
eformation
Field
(
field
,
disp
Type
=
'
relative
'
,
def
Type
=
'
relative
'
,
premat
=
True
):
premat
=
True
):
"""
Convert a :class:`CoefficientField` into a :class:`D
isplacement
Field`.
"""
Convert a :class:`CoefficientField` into a :class:`D
eformation
Field`.
:arg field:
:class:`CoefficientField` to convert
:arg field: :class:`CoefficientField` to convert
:arg d
isp
Type: The type of d
isplacement
field - either ``
'
relative
'
`` (the
:arg d
ef
Type: The type of d
eformation
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 d
isplacements
.
encoded into the d
eformation field
.
:return:
:class:`D
isplacement
Field` calculated from ``field``.
:return: :class:`D
eformation
Field` 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
=
D
isplacement
Field
(
disps
,
rdfield
=
D
eformation
Field
(
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
,
disp
Type
=
'
relative
'
)
def
Type
=
'
relative
'
)
if
(
d
isp
Type
==
'
relative
'
)
and
(
not
premat
):
if
(
d
ef
Type
==
'
relative
'
)
and
(
not
premat
):
return
rdfield
return
rdfield
# Convert to absolute - the
# Convert to absolute - the
# d
isplacement
s will now be
# d
eformation
s will now be
# absolute coordinates in
# absolute coordinates in
# aligned-src space
# aligned-src space
disps
=
convertD
isplacement
Type
(
rdfield
)
disps
=
convertD
eformation
Type
(
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
=
D
isplacement
Field
(
disps
,
adfield
=
D
eformation
Field
(
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
,
disp
Type
=
'
absolute
'
)
def
Type
=
'
absolute
'
)
# Not either return absolute displacements,
# Not either return absolute displacements,
# or convert back to relative displacements
# or convert back to relative displacements
if
d
isp
Type
==
'
absolute
'
:
if
d
ef
Type
==
'
absolute
'
:
return
adfield
return
adfield
else
:
else
:
return
D
isplacement
Field
(
convertD
isplacement
Type
(
adfield
),
return
D
eformation
Field
(
convertD
eformation
Type
(
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
,
disp
Type
=
'
relative
'
)
def
Type
=
'
relative
'
)
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment