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
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