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
Model registry
Operate
Environments
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
FSL
fslpy
Commits
66c008d5
Commit
66c008d5
authored
5 years ago
by
Paul McCarthy
Browse files
Options
Downloads
Patches
Plain Diff
RF,BF: Refactored x5/fnirt modules for new specs - I think the refactoring is
complete?
parent
ed5835ab
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
fsl/transform/fnirt.py
+52
-55
52 additions, 55 deletions
fsl/transform/fnirt.py
fsl/transform/x5.py
+17
-11
17 additions, 11 deletions
fsl/transform/x5.py
with
69 additions
and
66 deletions
fsl/transform/fnirt.py
+
52
−
55
View file @
66c008d5
...
...
@@ -124,33 +124,40 @@ header of the coefficient field file.
import
logging
import
numpy
as
np
import
nibabel
as
nib
import
numpy
as
np
import
fsl.data.constants
as
constants
import
fsl.data.image
as
fslimage
from
.
import
affine
from
.
import
nonlinear
log
=
logging
.
getLogger
(
__name__
)
def
_readFnirtD
isplacement
Field
(
fname
,
img
,
src
,
ref
,
d
isp
Type
=
None
):
"""
Loads ``fname``, assumed to be a FNIRT d
isplacement
field.
def
_readFnirtD
eformation
Field
(
fname
,
img
,
src
,
ref
,
d
ef
Type
=
None
):
"""
Loads ``fname``, assumed to be a FNIRT d
eformation
field.
:arg fname: File name of FNIRT displacement field
:arg img: ``fname`` loaded as an :class:`.Image`
:arg src: Source image
:arg ref: Reference image
:arg dispType: Displacement type - either ``
'
absolute
'
`` or ``
'
relative
'
``.
If not provided, is automatically inferred from the data.
:return: A :class:`.DisplacementField`
:arg fname: File name of FNIRT deformation field
:arg img: ``fname`` loaded as an :class:`.Image`
:arg src: Source image
:arg ref: Reference image
:arg defType: Deformation type - either ``
'
absolute
'
`` or ``
'
relative
'
``.
If not provided, is automatically inferred from the data.
:return: A :class:`.DeformationField` object
"""
from
.
import
nonlinear
return
nonlinear
.
DisplacementField
(
fname
,
src
,
ref
,
srcSpace
=
'
fsl
'
,
refSpace
=
'
fsl
'
,
dispType
=
dispType
)
return
nonlinear
.
DeformationField
(
fname
,
src
,
ref
,
srcSpace
=
'
fsl
'
,
refSpace
=
'
fsl
'
,
defType
=
defType
)
def
_readFnirtCoefficientField
(
fname
,
img
,
src
,
ref
):
...
...
@@ -163,9 +170,6 @@ def _readFnirtCoefficientField(fname, img, src, ref):
:return: A :class:`.CoefficientField`
"""
from
.
import
affine
from
.
import
nonlinear
# FNIRT uses NIFTI header fields in
# non-standard ways to store some
# additional information about the
...
...
@@ -226,22 +230,22 @@ def _readFnirtCoefficientField(fname, img, src, ref):
fieldToRefMat
=
fieldToRefMat
)
def
readFnirt
(
fname
,
src
,
ref
,
d
isp
Type
=
None
):
def
readFnirt
(
fname
,
src
,
ref
,
d
ef
Type
=
None
):
"""
Reads a non-linear FNIRT transformation image, returning
a :class:`.D
isplacement
Field` or :class:`.CoefficientField` depending
a :class:`.D
eformation
Field` or :class:`.CoefficientField` depending
on the file type.
:arg fname: File name of FNIRT transformation
:arg src: Source image
:arg ref: Reference image
:arg dispType: Displacement type - either ``
'
absolute
'
`` or ``
'
relative
'
``.
If not provided, is automatically inferred from the data.
:arg defType: Deformation type - either ``
'
absolute
'
`` or ``
'
relative
'
``.
Only used if the file is a deformation field. If not
provided, is automatically inferred from the data.
"""
# Figure out whether the file
# is a d
isplacement
field or
# is a d
eformation
field or
# a coefficient field
import
fsl.data.image
as
fslimage
img
=
fslimage
.
Image
(
fname
,
loadData
=
False
)
disps
=
(
constants
.
FSL_FNIRT_DISPLACEMENT_FIELD
,
...
...
@@ -253,7 +257,7 @@ def readFnirt(fname, src, ref, dispType=None):
constants
.
FSL_TOPUP_QUADRATIC_SPLINE_COEFFICIENTS
)
if
img
.
intent
in
disps
:
return
_readFnirtD
isplacement
Field
(
fname
,
img
,
src
,
ref
,
d
isp
Type
)
return
_readFnirtD
eformation
Field
(
fname
,
img
,
src
,
ref
,
d
ef
Type
)
elif
img
.
intent
in
coefs
:
return
_readFnirtCoefficientField
(
fname
,
img
,
src
,
ref
)
else
:
...
...
@@ -263,15 +267,13 @@ def readFnirt(fname, src, ref, dispType=None):
def
toFnirt
(
field
):
"""
Convert a :class:`.NonLinearTransform` to a FNIRT-compatible
:class:`.D
isplacement
Field` or :class:`.CoefficientField`.
:class:`.D
eformation
Field` or :class:`.CoefficientField`.
:arg field: :class:`.NonLinearTransform` to convert
:return: A FNIRT-compatible :class:`.D
isplacement
Field` or
:return: A FNIRT-compatible :class:`.D
eformation
Field` or
:class:`.CoefficientField`.
"""
from
.
import
nonlinear
# If we have a coefficient field
# which transforms between fsl
# space, we can just create a copy.
...
...
@@ -330,36 +332,35 @@ def toFnirt(field):
srcToRefMat
=
field
.
srcToRefMat
)
# Otherwise we have a non-FSL coefficient
# field, or a displacement field.
#
# We can't convert a CoefficientField
# which doesn't transform in FSL
# coordinates, because the coefficients
# will have been calculated between some
# other source/reference coordinate
# systems, and we can't adjust the
# coefficients to encode an FSL->FSL
# deformation.
# field, or a deformation field.
else
:
# We can't convert a CoefficientField
# which doesn't transform in FSL
# coordinates, because the coefficients
# will have been calculated between some
# other source/reference coordinate
# systems, and we can't adjust the
# coefficients to encode an FSL->FSL
# deformation.
if
isinstance
(
field
,
nonlinear
.
CoefficientField
):
field
=
nonlinear
.
coefficientFieldToD
isplacement
Field
(
field
)
field
=
nonlinear
.
coefficientFieldToD
eformation
Field
(
field
)
# Again, if we have a displacement
# field which transforms between
# fsl spaces, we can just take a copy
if
field
.
srcSpace
==
'
fsl
'
and
field
.
refSpace
==
'
fsl
'
:
field
=
nonlinear
.
D
isplacement
Field
(
field
=
nonlinear
.
D
eformation
Field
(
field
.
data
,
header
=
field
.
header
,
src
=
field
.
src
,
ref
=
field
.
ref
,
xform
=
field
.
voxToWorldMat
,
dispType
=
field
.
displacementType
)
defType
=
field
.
deformationType
)
# Otherwise we have to adjust the
# displacements so they transform
# between fsl coordinates.
field
=
nonlinear
.
convertD
isplacement
Space
(
field
=
nonlinear
.
convertD
eformation
Space
(
field
,
from_
=
'
fsl
'
,
to
=
'
fsl
'
)
field
.
header
[
'
intent_code
'
]
=
constants
.
FSL_FNIRT_DISPLACEMENT_FIELD
...
...
@@ -369,23 +370,19 @@ def toFnirt(field):
def
fromFnirt
(
field
,
from_
=
'
world
'
,
to
=
'
world
'
):
"""
Convert a FNIRT-style :class:`.NonLinearTransform` to a generic
:class:`.D
isplacement
Field`.
:class:`.D
eformation
Field`.
:arg field: A FNIRT-style :class:`.CoefficientField` or
:class:`.D
isplacement
Field`
:class:`.D
eformation
Field`
:arg from_: Desired reference image coordinate system
:arg to: Desired source image coordinate system
:return: A :class:`.D
isplacement
Field` which contains displacements
:return: A :class:`.D
eformation
Field` which contains displacements
from the reference image ``from_`` cordinate system to the
source image ``to`` coordinate syste.
"""
from
.
import
nonlinear
# see comments in toFnirt
if
isinstance
(
field
,
nonlinear
.
CoefficientField
):
field
=
nonlinear
.
coefficientFieldToDisplacementField
(
field
)
return
nonlinear
.
convertDisplacementSpace
(
field
,
from_
=
from_
,
to
=
to
)
field
=
nonlinear
.
coefficientFieldToDeformationField
(
field
)
return
nonlinear
.
convertDeformationSpace
(
field
,
from_
=
from_
,
to
=
to
)
This diff is collapsed.
Click to expand it.
fsl/transform/x5.py
+
17
−
11
View file @
66c008d5
...
...
@@ -397,16 +397,17 @@ def readNonLinearX5(fname):
_readMetadata
(
f
)
ref
=
_readSpace
(
f
[
'
/A
'
])
src
=
_readSpace
(
f
[
'
/B
'
])
field
,
spac
e
=
_readDeformation
(
f
[
'
/Transform
'
])
ref
=
_readSpace
(
f
[
'
/A
'
])
src
=
_readSpace
(
f
[
'
/B
'
])
field
,
xform
,
defTyp
e
=
_readDeformation
(
f
[
'
/Transform
'
])
return
nonlinear
.
DeformationField
(
field
,
header
=
space
.
header
,
xform
=
xform
,
src
=
src
,
ref
=
ref
,
srcSpace
=
'
world
'
,
refSpace
=
'
world
'
)
refSpace
=
'
world
'
,
defType
=
defType
)
def
writeNonLinearX5
(
fname
,
field
):
...
...
@@ -421,8 +422,8 @@ def writeNonLinearX5(fname, field):
f
.
attrs
[
'
Type
'
]
=
'
nonlinear
'
_writeMetadata
(
f
)
_writeSpace
(
f
.
create_group
(
'
/A
'
),
f
.
ref
)
_writeSpace
(
f
.
create_group
(
'
/B
'
),
f
.
src
)
_writeSpace
(
f
.
create_group
(
'
/A
'
),
f
ield
.
ref
)
_writeSpace
(
f
.
create_group
(
'
/B
'
),
f
ield
.
src
)
_writeDeformation
(
f
.
create_group
(
'
/Transform
'
),
field
)
...
...
@@ -538,8 +539,8 @@ def _readDeformation(group):
- A ``numpy.arrayThe`` containing the deformation field
- A
:class:`.Nifti` object representing the deformation
field space
- A
``numpy.array`` of shape ``(4, 4) `` containing the
voxel to world affine for the deformation field
- The deformation type - either ``
'
absolute
'
`` or
``
'
relative
'
``
...
...
@@ -554,7 +555,7 @@ def _readDeformation(group):
if
subtype
not
in
(
'
absolute
'
,
'
relative
'
):
raise
X5Error
(
'
Unknown deformation type: {}
'
.
format
(
subtype
))
mapping
=
_read
Spac
e
(
group
[
'
Mapping
'
])
mapping
=
_read
Affin
e
(
group
[
'
Mapping
'
])
field
=
group
[
'
Matrix
'
]
if
len
(
field
.
shape
)
!=
4
or
field
.
shape
[
3
]
!=
3
:
...
...
@@ -570,10 +571,15 @@ def _writeDeformation(group, field):
:arg field: A :class:`.DeformationField` object
"""
if
field
.
srcSpace
!=
'
world
'
or
\
field
.
refSpace
!=
'
world
'
:
raise
X5Error
(
'
Deformation field must encode a
'
'
world<->world transformation
'
)
group
.
attrs
[
'
Type
'
]
=
'
deformation
'
group
.
attrs
[
'
SubType
'
]
=
field
.
deformationType
mapping
=
group
.
create_group
(
'
Mapping
'
)
group
.
create_dataset
(
'
Matrix
'
,
data
=
field
.
data
)
_write
Spac
e
(
mapping
,
field
)
_write
Affin
e
(
mapping
,
field
.
getAffine
(
'
voxel
'
,
'
world
'
)
)
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