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
99cc593f
Commit
99cc593f
authored
6 years ago
by
Paul McCarthy
Browse files
Options
Downloads
Patches
Plain Diff
RF,ENH: Support for GIFTI files with ultiple pointsets, and with vertex
data. Will prpbably need tweaking.
parent
e92f083a
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/data/gifti.py
+59
-42
59 additions, 42 deletions
fsl/data/gifti.py
with
59 additions
and
42 deletions
fsl/data/gifti.py
+
59
−
42
View file @
99cc593f
...
@@ -19,6 +19,7 @@ are available:
...
@@ -19,6 +19,7 @@ are available:
GiftiMesh
GiftiMesh
loadGiftiMesh
loadGiftiMesh
loadGiftiVertexData
loadGiftiVertexData
prepareGiftiVertexData
relatedFiles
relatedFiles
"""
"""
...
@@ -34,15 +35,13 @@ import fsl.data.constants as constants
...
@@ -34,15 +35,13 @@ import fsl.data.constants as constants
import
fsl.data.mesh
as
fslmesh
import
fsl.data.mesh
as
fslmesh
# We include '.gii' here because not all surface
ALLOWED_EXTENSIONS
=
[
'
.gii
'
]
# GIFTIs follow the file suffix convention.
ALLOWED_EXTENSIONS
=
[
'
.surf.gii
'
,
'
.gii
'
]
"""
List of file extensions that a file containing Gifti surface data
"""
List of file extensions that a file containing Gifti surface data
is expected to have.
is expected to have.
"""
"""
EXTENSION_DESCRIPTIONS
=
[
'
GIFTI
surface file
'
,
'
GIFTI
file
'
]
EXTENSION_DESCRIPTIONS
=
[
'
GIFTI file
'
]
"""
A description for each of the :data:`ALLOWED_EXTENSIONS`.
"""
"""
A description for each of the :data:`ALLOWED_EXTENSIONS`.
"""
...
@@ -60,7 +59,8 @@ class GiftiMesh(fslmesh.Mesh):
...
@@ -60,7 +59,8 @@ class GiftiMesh(fslmesh.Mesh):
"""
Load the given GIFTI file using ``nibabel``, and extracts surface
"""
Load the given GIFTI file using ``nibabel``, and extracts surface
data using the :func:`loadGiftiMesh` function.
data using the :func:`loadGiftiMesh` function.
:arg infile: A GIFTI surface file (``*.surf.gii``).
:arg infile: A GIFTI file (``*..gii``) which contains a surface
definition.
:arg fixWinding: Passed through to the :meth:`addVertices` method
:arg fixWinding: Passed through to the :meth:`addVertices` method
for the first vertex set.
for the first vertex set.
...
@@ -76,17 +76,20 @@ class GiftiMesh(fslmesh.Mesh):
...
@@ -76,17 +76,20 @@ class GiftiMesh(fslmesh.Mesh):
name
=
fslpath
.
removeExt
(
op
.
basename
(
infile
),
ALLOWED_EXTENSIONS
)
name
=
fslpath
.
removeExt
(
op
.
basename
(
infile
),
ALLOWED_EXTENSIONS
)
infile
=
op
.
abspath
(
infile
)
infile
=
op
.
abspath
(
infile
)
surfimg
,
vertices
,
indices
=
loadGiftiMesh
(
infile
)
surfimg
,
indices
,
vertices
,
vdata
=
loadGiftiMesh
(
infile
)
fslmesh
.
Mesh
.
__init__
(
self
,
fslmesh
.
Mesh
.
__init__
(
self
,
indices
,
indices
,
name
=
name
,
name
=
name
,
dataSource
=
infile
)
dataSource
=
infile
)
self
.
addVertices
(
vertices
,
infile
,
fixWinding
=
fixWinding
)
for
v
in
vertices
:
self
.
addVertices
(
v
,
infile
,
fixWinding
=
fixWinding
)
self
.
setMeta
(
infile
,
surfimg
)
self
.
setMeta
(
infile
,
surfimg
)
if
vdata
is
not
None
:
self
.
addVertexData
(
infile
,
vdata
)
# Find and load all other
# Find and load all other
# surfaces in the same directory
# surfaces in the same directory
# as the specfiied one.
# as the specfiied one.
...
@@ -157,9 +160,10 @@ def loadGiftiMesh(filename):
...
@@ -157,9 +160,10 @@ def loadGiftiMesh(filename):
The image is expected to contain the following``<DataArray>`` elements:
The image is expected to contain the following``<DataArray>`` elements:
- one comprising ``NIFTI_INTENT_POINTSET`` data (the surface vertices)
- one comprising ``NIFTI_INTENT_TRIANGLE`` data (vertex indices
- one comprising ``NIFTI_INTENT_TRIANGLE`` data (vertex indices
defining the triangles).
defining the triangles).
- one or more comprising ``NIFTI_INTENT_POINTSET`` data (the surface
vertices)
A ``ValueError`` will be raised if this is not the case.
A ``ValueError`` will be raised if this is not the case.
...
@@ -169,42 +173,62 @@ def loadGiftiMesh(filename):
...
@@ -169,42 +173,62 @@ def loadGiftiMesh(filename):
- The loaded ``nibabel.gifti.GiftiImage`` instance
- The loaded ``nibabel.gifti.GiftiImage`` instance
- A ``(N, 3)`` array containing ``N`` vertices.
- A ``(M, 3)`` array containing the vertex indices for
- A ``(M, 3))`` array containing the vertex indices for
``M`` triangles.
``M`` triangles.
"""
gimg
=
nib
.
load
(
filename
)
- A list of at least one ``(N, 3)`` arrays containing ``N``
vertices.
pointsetCode
=
constants
.
NIFTI_INTENT_POINTSET
- A ``(M, N)`` numpy array containing ``N`` data points for
triangleCode
=
constants
.
NIFTI_INTENT_TRIANGLE
``M`` vertices, or ``None`` if the file does not contain
any vertex data.
"""
pointsets
=
[
d
for
d
in
gimg
.
darrays
if
d
.
intent
==
pointsetCode
]
gimg
=
nib
.
load
(
filename
)
triangles
=
[
d
for
d
in
gimg
.
darrays
if
d
.
intent
==
triangleCode
]
if
len
(
gimg
.
darrays
)
!=
2
:
pscode
=
constants
.
NIFTI_INTENT_POINTSET
raise
ValueError
(
'
{}: GIFTI surface files must contain
'
tricode
=
constants
.
NIFTI_INTENT_TRIANGLE
'
exactly one pointset array and one
'
'
triangle array
'
.
format
(
filename
))
if
len
(
pointsets
)
!=
1
:
pointsets
=
[
d
for
d
in
gimg
.
darrays
if
d
.
intent
==
pscode
]
raise
ValueError
(
'
{}: GIFTI surface files must contain
'
triangles
=
[
d
for
d
in
gimg
.
darrays
if
d
.
intent
==
tricode
]
'
exactly one pointset array
'
.
format
(
filenam
e
)
)
vdata
=
[
d
for
d
in
gimg
.
darrays
if
d
.
intent
not
in
(
pscode
,
tricod
e
)
]
if
len
(
triangles
)
!=
1
:
if
len
(
triangles
)
!=
1
:
raise
ValueError
(
'
{}: GIFTI surface files must contain
'
raise
ValueError
(
'
{}: GIFTI surface files must contain
'
'
exactly one triangle array
'
.
format
(
filename
))
'
exactly one triangle array
'
.
format
(
filename
))
vertices
=
pointsets
[
0
].
data
if
len
(
pointsets
)
==
0
:
raise
ValueError
(
'
{}: GIFTI surface files must contain
'
'
at least one pointset array
'
.
format
(
filename
))
vertices
=
[
ps
.
data
for
ps
in
pointsets
]
indices
=
triangles
[
0
].
data
indices
=
triangles
[
0
].
data
return
gimg
,
vertices
,
indices
if
len
(
vdata
)
==
0
:
vdata
=
None
else
:
vdata
=
prepareGiftiVertexData
(
vdata
,
filename
)
return
gimg
,
indices
,
vertices
,
vdata
def
loadGiftiVertexData
(
filename
):
def
loadGiftiVertexData
(
filename
):
"""
Loads vertex data from the given GIFTI file.
"""
Loads vertex data from the given GIFTI file.
See :func:`prepareGiftiVertexData`.
Returns a tuple containing:
- The loaded ``nibabel.gifti.GiftiImage`` object
- A ``(M, N)`` numpy array containing ``N`` data points for ``M``
vertices
"""
gimg
=
nib
.
load
(
filename
)
return
gimg
,
prepareGiftiVertexData
(
gimg
.
darrays
,
filename
)
def
prepareGiftiVertexData
(
darrays
,
filename
=
None
):
"""
Prepares vertex data from the given list of GIFTI data arrays.
It is assumed that the given file does not contain any
It is assumed that the given file does not contain any
``NIFTI_INTENT_POINTSET`` or ``NIFTI_INTENT_TRIANGLE`` data arrays, and
``NIFTI_INTENT_POINTSET`` or ``NIFTI_INTENT_TRIANGLE`` data arrays, and
which contains either:
which contains either:
...
@@ -215,17 +239,11 @@ def loadGiftiVertexData(filename):
...
@@ -215,17 +239,11 @@ def loadGiftiVertexData(filename):
- One or more ``(M, 1)`` data arrays each containing a single data point
- One or more ``(M, 1)`` data arrays each containing a single data point
for ``M`` vertices, and all with the same intent code
for ``M`` vertices, and all with the same intent code
Returns a tuple containing:
Returns a ``(M, N)`` numpy array containing ``N`` data points for ``M``
vertices.
- The loaded ``nibabel.gifti.GiftiImage`` object
- A ``(M, N)`` numpy array containing ``N`` data points for ``M``
vertices
"""
"""
gimg
=
nib
.
load
(
filename
)
intents
=
set
([
d
.
intent
for
d
in
darrays
])
intents
=
set
([
d
.
intent
for
d
in
gimg
.
darrays
])
if
len
(
intents
)
!=
1
:
if
len
(
intents
)
!=
1
:
raise
ValueError
(
'
{} contains multiple (or no) intents
'
raise
ValueError
(
'
{} contains multiple (or no) intents
'
...
@@ -235,20 +253,19 @@ def loadGiftiVertexData(filename):
...
@@ -235,20 +253,19 @@ def loadGiftiVertexData(filename):
if
intent
in
(
constants
.
NIFTI_INTENT_POINTSET
,
if
intent
in
(
constants
.
NIFTI_INTENT_POINTSET
,
constants
.
NIFTI_INTENT_TRIANGLE
):
constants
.
NIFTI_INTENT_TRIANGLE
):
raise
ValueError
(
'
{} contains surface data
'
.
format
(
filename
))
raise
ValueError
(
'
{} contains surface data
'
.
format
(
filename
))
# Just a single array - return it as-is.
# Just a single array - return it as-is.
# n.b. Storing (M, N) data in a single
# n.b. Storing (M, N) data in a single
# DataArray goes against the GIFTI spec,
# DataArray goes against the GIFTI spec,
# but hey, it happens.
# but hey, it happens.
if
len
(
gimg
.
darrays
)
==
1
:
if
len
(
darrays
)
==
1
:
vdata
=
gimg
.
darrays
[
0
].
data
vdata
=
darrays
[
0
].
data
return
gimg
,
vdata
.
reshape
(
vdata
.
shape
[
0
],
-
1
)
return
vdata
.
reshape
(
vdata
.
shape
[
0
],
-
1
)
# Otherwise extract and concatenate
# Otherwise extract and concatenate
# multiple 1-dimensional arrays
# multiple 1-dimensional arrays
vdata
=
[
d
.
data
for
d
in
gimg
.
darrays
]
vdata
=
[
d
.
data
for
d
in
darrays
]
if
any
([
len
(
d
.
shape
)
!=
1
for
d
in
vdata
]):
if
any
([
len
(
d
.
shape
)
!=
1
for
d
in
vdata
]):
raise
ValueError
(
'
{} contains one or more non-vector
'
raise
ValueError
(
'
{} contains one or more non-vector
'
...
@@ -257,7 +274,7 @@ def loadGiftiVertexData(filename):
...
@@ -257,7 +274,7 @@ def loadGiftiVertexData(filename):
vdata
=
np
.
vstack
(
vdata
).
T
vdata
=
np
.
vstack
(
vdata
).
T
vdata
=
vdata
.
reshape
(
vdata
.
shape
[
0
],
-
1
)
vdata
=
vdata
.
reshape
(
vdata
.
shape
[
0
],
-
1
)
return
gimg
,
vdata
return
vdata
def
relatedFiles
(
fname
,
ftypes
=
None
):
def
relatedFiles
(
fname
,
ftypes
=
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