Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
F
fslpy
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Container Registry
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor 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
Michiel Cottaar
fslpy
Commits
e30514af
Commit
e30514af
authored
8 years ago
by
Paul McCarthy
Browse files
Options
Downloads
Patches
Plain Diff
Nifti class explicitly supports ANALYZE images
parent
3623a316
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/data/constants.py
+4
-0
4 additions, 0 deletions
fsl/data/constants.py
fsl/data/image.py
+65
-16
65 additions, 16 deletions
fsl/data/image.py
with
69 additions
and
16 deletions
fsl/data/constants.py
+
4
−
0
View file @
e30514af
...
@@ -81,6 +81,10 @@ NIFTI_XFORM_MNI_152 = 4
...
@@ -81,6 +81,10 @@ NIFTI_XFORM_MNI_152 = 4
"""
MNI 152 normalized coordinates.
"""
"""
MNI 152 normalized coordinates.
"""
NIFTI_XFORM_ANALYZE
=
5
"""
Code which indicates that this is an ANALYZE image, not a NIFTI image.
"""
# NIFTI file intent codes
# NIFTI file intent codes
NIFTI_INTENT_NONE
=
0
NIFTI_INTENT_NONE
=
0
NIFTI_INTENT_CORREL
=
2
NIFTI_INTENT_CORREL
=
2
...
...
This diff is collapsed.
Click to expand it.
fsl/data/image.py
+
65
−
16
View file @
e30514af
...
@@ -64,20 +64,52 @@ class Nifti(object):
...
@@ -64,20 +64,52 @@ class Nifti(object):
================= ====================================================
================= ====================================================
``header`` The :mod:`nibabel` NIFTI header object.
``header`` The :mod:`nibabel` NIFTI1/NIFTI2/Analyze header
object.
``shape`` A list/tuple containing the number of voxels along
``shape`` A list/tuple containing the number of voxels along
each image dimension.
each image dimension.
``pixdim`` A list/tuple containing the length of one voxel
``pixdim`` A list/tuple containing the length of one voxel
along each image dimension.
along each image dimension.
``voxToWorldMat`` A 4*4 array specifying the affine transformation
``voxToWorldMat`` A 4*4 array specifying the affine transformation
for transforming voxel coordinates into real world
for transforming voxel coordinates into real world
coordinates.
coordinates.
``worldToVoxMat`` A 4*4 array specifying the affine transformation
``worldToVoxMat`` A 4*4 array specifying the affine transformation
for transforming real world coordinates into voxel
for transforming real world coordinates into voxel
coordinates.
coordinates.
``intent`` The NIFTI intent code specified in the header.
``intent`` The NIFTI intent code specified in the header (or
:attr:`.constants.NIFTI_INTENT_NONE` for Analyze
images).
================= ====================================================
================= ====================================================
A ``Nifti`` instance expects to be passed either a
``nibabel.nifti1.Nifti1Header`` or a ``nibabel.nifti2.Nifti2Header``, but
can als encapsulate a ``nibabel.analyze.AnalyzeHeader``. In this case:
- The image voxel orientation is assumed to be R->L, P->A, I->S.
- The affine will be set to a diagonal matrix with the header pixdims as
its elements (with the X pixdim negated), and an offset specified by
the ANALYZE ``origin`` fields. Construction of the affine is handled
by ``nibabel``.
- The :meth:`niftiVersion` method will return ``0``.
- The :meth:`getXFormCode` method will return
:attr:`.constants.NIFTI_XFORM_ANALYZE`.
.. warning:: The ``header`` field may either be a ``nifti1``, ``nifti2``,
or ``analyze`` header object. Make sure to take this into
account if you are writing code that should work with all
three. Use the :meth:`niftiVersion` property if you need to
know what type of image you are dealing with.
.. note:: The ``shape`` attribute may not precisely match the image shape
.. note:: The ``shape`` attribute may not precisely match the image shape
as reported in the NIFTI header, because trailing dimensions of
as reported in the NIFTI header, because trailing dimensions of
...
@@ -85,19 +117,22 @@ class Nifti(object):
...
@@ -85,19 +117,22 @@ class Nifti(object):
:meth:`mapIndices` methods.
:meth:`mapIndices` methods.
"""
"""
def
__init__
(
self
,
header
):
def
__init__
(
self
,
header
):
"""
Create a ``Nifti`` object.
"""
Create a ``Nifti`` object.
:arg header: A :class:`nibabel.nifti1.Nifti1Header` or
:arg header: A :class:`nibabel.nifti1.Nifti1Header`,
:class:`nibabel.nifti2.Nifti2Header` to be used as the
:class:`nibabel.nifti2.Nifti2Header`, or
image header.
``nibabel.analyze.AnalyzeHeader`` to be used as the
image header.
"""
"""
import
nibabel
as
nib
import
nibabel
as
nib
# Nifti2Header is a sub-class of Nifti1Header,
# Nifti2Header is a sub-class of Nifti1Header,
# so we don't need to test for it
# and Nifti1Header a sub-class of AnalyzeHeader,
if
not
isinstance
(
header
,
nib
.
nifti1
.
Nifti1Header
):
# so we only need to test for the latter.
if
not
isinstance
(
header
,
nib
.
analyze
.
AnalyzeHeader
):
raise
ValueError
(
'
Unrecognised header: {}
'
.
format
(
header
))
raise
ValueError
(
'
Unrecognised header: {}
'
.
format
(
header
))
header
=
header
.
copy
()
header
=
header
.
copy
()
...
@@ -121,14 +156,21 @@ class Nifti(object):
...
@@ -121,14 +156,21 @@ class Nifti(object):
@property
@property
def
niftiVersion
(
self
):
def
niftiVersion
(
self
):
"""
Returns the NIFTI file version - either ``1`` or ``2``.
"""
"""
Returns the NIFTI file version:
- ``0`` for ANALYZE
- ``1`` for NIFTI1
- ``2`` for NIFTI2
"""
import
nibabel
as
nib
import
nibabel
as
nib
# nib.Nifti2 is a subclass of Nifti1,
# nib.Nifti2 is a subclass of Nifti1,
# so we have to check it first.
# and Nifti1 a subclass of Analyze,
if
isinstance
(
self
.
header
,
nib
.
nifti2
.
Nifti2Header
):
return
2
# so we have to check in order
elif
isinstance
(
self
.
header
,
nib
.
nifti1
.
Nifti1Header
):
return
1
if
isinstance
(
self
.
header
,
nib
.
nifti2
.
Nifti2Header
):
return
2
elif
isinstance
(
self
.
header
,
nib
.
nifti1
.
Nifti1Header
):
return
1
elif
isinstance
(
self
.
header
,
nib
.
analyze
.
AnalyzeHeader
):
return
0
else
:
raise
RuntimeError
(
'
Unrecognised header: {}
'
.
format
(
self
.
header
))
else
:
raise
RuntimeError
(
'
Unrecognised header: {}
'
.
format
(
self
.
header
))
...
@@ -138,12 +180,15 @@ class Nifti(object):
...
@@ -138,12 +180,15 @@ class Nifti(object):
coordinate transformation matrix that is associated with this
coordinate transformation matrix that is associated with this
``Nifti`` instance.
``Nifti`` instance.
"""
"""
# We have to treat FSL/FNIRT images
# We have to treat FSL/FNIRT images
# specially, as FNIRT clobbers the
# specially, as FNIRT clobbers the
# sform section of the NIFTI header
# sform section of the NIFTI header
# to store other data.
# to store other data.
intent
=
header
.
get
(
'
intent_code
'
,
-
1
)
intent
=
header
.
get
(
'
intent_code
'
,
-
1
)
qform
=
header
.
get
(
'
qform_code
'
,
-
1
)
sform
=
header
.
get
(
'
sform_code
'
,
-
1
)
if
intent
in
(
constants
.
FSL_FNIRT_DISPLACEMENT_FIELD
,
if
intent
in
(
constants
.
FSL_FNIRT_DISPLACEMENT_FIELD
,
constants
.
FSL_CUBIC_SPLINE_COEFFICIENTS
,
constants
.
FSL_CUBIC_SPLINE_COEFFICIENTS
,
constants
.
FSL_DCT_COEFFICIENTS
,
constants
.
FSL_DCT_COEFFICIENTS
,
...
@@ -161,12 +206,12 @@ class Nifti(object):
...
@@ -161,12 +206,12 @@ class Nifti(object):
# corresponds to world location (0, 0, 0).
# corresponds to world location (0, 0, 0).
# This goes against the NIFTI spec - it
# This goes against the NIFTI spec - it
# should just be a straight scaling matrix.
# should just be a straight scaling matrix.
elif
header
[
'
qform_code
'
]
==
0
and
header
[
'
sform_code
'
]
==
0
:
elif
qform
==
0
and
sform
==
0
:
pixdims
=
header
.
get_zooms
()
pixdims
=
header
.
get_zooms
()
voxToWorldMat
=
transform
.
scaleOffsetXform
(
pixdims
,
0
)
voxToWorldMat
=
transform
.
scaleOffsetXform
(
pixdims
,
0
)
# Otherwise we let nibabel decide
# Otherwise we let nibabel decide
# which transform to use.
# which transform to use.
else
:
else
:
voxToWorldMat
=
np
.
array
(
header
.
get_best_affine
())
voxToWorldMat
=
np
.
array
(
header
.
get_best_affine
())
...
@@ -238,8 +283,12 @@ class Nifti(object):
...
@@ -238,8 +283,12 @@ class Nifti(object):
- :data:`~.constants.NIFTI_XFORM_ALIGNED_ANAT`
- :data:`~.constants.NIFTI_XFORM_ALIGNED_ANAT`
- :data:`~.constants.NIFTI_XFORM_TALAIRACH`
- :data:`~.constants.NIFTI_XFORM_TALAIRACH`
- :data:`~.constants.NIFTI_XFORM_MNI_152`
- :data:`~.constants.NIFTI_XFORM_MNI_152`
- :data:`~.constants.NIFTI_XFORM_ANALYZE`
"""
"""
if
self
.
niftiVersion
==
0
:
return
constants
.
NIFTI_XFORM_ANALYZE
if
code
==
'
sform
'
:
code
=
'
sform_code
'
if
code
==
'
sform
'
:
code
=
'
sform_code
'
elif
code
==
'
qform
'
:
code
=
'
qform_code
'
elif
code
==
'
qform
'
:
code
=
'
qform_code
'
elif
code
is
not
None
:
elif
code
is
not
None
:
...
...
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