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
d93c4e65
Commit
d93c4e65
authored
7 years ago
by
Paul McCarthy
Browse files
Options
Downloads
Patches
Plain Diff
GiftiSurface renamed to GiftiMesh because it fits better with new
nomenclature.
parent
daea0469
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
fsl/data/gifti.py
+146
-59
146 additions, 59 deletions
fsl/data/gifti.py
with
146 additions
and
59 deletions
fsl/data/gifti.py
+
146
−
59
View file @
d93c4e65
...
...
@@ -16,62 +16,96 @@ are available:
.. autosummary::
:nosignatures:
GiftiSurface
loadGiftiSurface
GiftiMesh
loadGiftiMesh
loadGiftiVertexData
relatedFiles
"""
import
glob
import
os.path
as
op
import
deprecation
import
numpy
as
np
import
nibabel
as
nib
import
fsl.utils.path
as
fslpath
from
.
import
constants
from
.
import
mesh
import
fsl.utils.path
as
fslpath
import
fsl.data.constants
as
constants
import
fsl.data.mesh
as
fsl
mesh
class
GiftiSurface
(
mesh
.
TriangleMesh
):
ALLOWED_EXTENSIONS
=
[
'
.surf.gii
'
]
"""
List of file extensions that a file containing Gifti surface data
is expected to have.
"""
EXTENSION_DESCRIPTIONS
=
[
'
GIFTI surface file
'
]
"""
A description for each of the :data:`ALLOWED_EXTENSIONS`.
"""
class
GiftiMesh
(
fslmesh
.
Mesh
):
"""
Class which represents a GIFTI surface image. This is essentially
just a 3D model made of triangles.
In addition to the ``vertices`` and ``indices`` provided by the
:class:`.TriangleMesh` class (from which the ``GiftiSurface`` class
derives), a ``GiftiSurface`` instance has the following attributes:
============== ====================================================
``name`` A name, typically the file name sans-suffix.
``dataSource`` Full path to the GIFTI file.
``surfImg`` Reference to the loaded ``nibabel.gifti.GiftiImage``
============== ====================================================
For each GIFTI surface file that is loaded, the
``nibabel.gifti.GiftiImage`` instance is stored in the :class:`.Meta`
store, with the absolute path to the surface file as the key.
"""
def
__init__
(
self
,
infile
,
fixWinding
=
False
):
def
__init__
(
self
,
infile
,
fixWinding
=
False
,
loadAll
=
False
):
"""
Load the given GIFTI file using ``nibabel``, and extracts surface
data using the :func:`loadGiftiSurface` function.
:arg infile: A GIFTI surface file (``*.surf.gii``).
:arg infile: A GIFTI surface file (``*.surf.gii``).
:arg fixWinding: Passed through to the :meth:`addVertices` method
for the first vertex set.
:arg loadAll: If ``True``, the ``infile`` directory is scanned
for other surface files which are then loaded
as additional vertex sets.
.. todo:: Allow loading from a ``.topo.gii`` and ``.coord.gii`` file?
Maybe.
"""
name
=
fslpath
.
removeExt
(
op
.
basename
(
infile
),
ALLOWED_EXTENSIONS
)
infile
=
op
.
abspath
(
infile
)
surfimg
,
vertices
,
indices
=
loadGiftiSurface
(
infile
)
mesh
.
TriangleMesh
.
__init__
(
self
,
vertices
,
indices
,
fixWinding
)
fslmesh
.
Mesh
.
__init__
(
self
,
indices
,
name
=
name
,
dataSource
=
infile
)
name
=
fslpath
.
removeExt
(
op
.
basename
(
infile
)
,
ALLOWED_EXTENSIONS
)
infile
=
op
.
abspath
(
infile
)
self
.
addVertices
(
vertices
,
infile
,
fixWinding
=
fixWinding
)
self
.
setMeta
(
infile
,
surfimg
)
self
.
name
=
name
self
.
dataSource
=
infile
self
.
surfImg
=
surfimg
# Find and load all other
# surfaces in the same directory
# as the specfiied one.
if
loadAll
:
nvertices
=
vertices
.
shape
[
0
]
surfFiles
=
relatedFiles
(
infile
,
'
surf
'
)
def
loadVertexData
(
self
,
dataSource
,
vertexData
=
None
):
for
sfile
in
surfFiles
:
surfimg
,
vertices
,
_
=
loadGiftiSurface
(
sfile
)
if
vertices
.
shape
[
0
]
!=
nvertices
:
continue
self
.
addVertices
(
vertices
,
sfile
,
select
=
False
)
self
.
setMeta
(
sfile
,
surfimg
)
def
loadVertexData
(
self
,
infile
,
key
=
None
):
"""
Overrides the :meth:`.TriangleMesh.loadVertexData` method.
Attempts to load data associated with each vertex of this
...
...
@@ -79,27 +113,21 @@ class GiftiSurface(mesh.TriangleMesh):
a GIFTI file or a plain text file which contains vertex data.
"""
if
vertexData
is
None
:
if
dataSource
.
endswith
(
'
.gii
'
):
vertexData
=
loadGiftiVertexData
(
dataSource
)[
1
]
else
:
vertexData
=
None
infile
=
op
.
abspath
(
infile
)
return
mesh
.
TriangleMesh
.
loadVertexData
(
self
,
dataSource
,
vertexData
)
if
key
is
None
:
key
=
infile
if
infile
.
endswith
(
'
.gii
'
):
vdata
=
loadGiftiVertexData
(
infile
)[
1
]
self
.
addVertexData
(
key
,
vdata
)
return
vdata
ALLOWED_EXTENSIONS
=
[
'
.surf.gii
'
,
'
.gii
'
]
"""
List of file extensions that a file containing Gifti surface data
is expected to have.
"""
else
:
return
fslmesh
.
Mesh
.
loadVertexData
(
self
,
infile
,
key
)
EXTENSION_DESCRIPTIONS
=
[
'
GIFTI surface file
'
,
'
GIFTI surface file
'
]
"""
A description for each of the :data:`ALLOWED_EXTENSIONS`.
"""
def
loadGiftiSurface
(
filename
):
def
loadGiftiMesh
(
filename
):
"""
Extracts surface data from the given ``nibabel.gifti.GiftiImage``.
The image is expected to contain the following``<DataArray>`` elements:
...
...
@@ -116,11 +144,10 @@ def loadGiftiSurface(filename):
- The loaded ``nibabel.gifti.GiftiImage`` instance
- A :math:`N
\\
times 3` ``numpy`` array containing :math:`N`
vertices.
- A ``(N, 3)`` array containing ``N`` vertices.
- A
:math:`M
\\
times 3` ``numpy
`` array containing the
vertex indices for :math:
`M` triangles.
- A
``(M, 3))
`` array containing the
vertex indices for
`
`M`
`
triangles.
"""
gimg
=
nib
.
load
(
filename
)
...
...
@@ -132,16 +159,17 @@ def loadGiftiSurface(filename):
triangles
=
[
d
for
d
in
gimg
.
darrays
if
d
.
intent
==
triangleCode
]
if
len
(
gimg
.
darrays
)
!=
2
:
raise
ValueError
(
'
GIFTI surface files must contain exactly
'
'
one pointset array and one triangle array
'
)
raise
ValueError
(
'
{}: GIFTI surface files must contain
'
'
exactly one pointset array and one
'
'
triangle array
'
.
format
(
filename
))
if
len
(
pointsets
)
!=
1
:
raise
ValueError
(
'
GIFTI surface files must contain
'
'
exactly one pointset array
'
)
raise
ValueError
(
'
{}:
GIFTI surface files must contain
'
'
exactly one pointset array
'
.
format
(
filename
)
)
if
len
(
triangles
)
!=
1
:
raise
ValueError
(
'
GIFTI surface files must contain
'
'
exactly one triangle array
'
)
raise
ValueError
(
'
{}:
GIFTI surface files must contain
'
'
exactly one triangle array
'
.
format
(
filename
)
)
vertices
=
pointsets
[
0
].
data
indices
=
triangles
[
0
].
data
...
...
@@ -190,7 +218,8 @@ def loadGiftiVertexData(filename):
# DataArray goes against the GIFTI spec,
# but hey, it happens.
if
len
(
gimg
.
darrays
)
==
1
:
return
gimg
,
gimg
.
darrays
[
0
].
data
vdata
=
gimg
.
darrays
[
0
].
data
return
gimg
,
vdata
.
reshape
(
vdata
.
shape
[
0
],
-
1
)
# Otherwise extract and concatenate
# multiple 1-dimensional arrays
...
...
@@ -200,13 +229,21 @@ def loadGiftiVertexData(filename):
raise
ValueError
(
'
{} contains one or more non-vector
'
'
darrays
'
.
format
(
filename
))
return
gimg
,
np
.
vstack
(
vdata
).
T
vdata
=
np
.
vstack
(
vdata
).
T
vdata
=
vdata
.
reshape
(
vdata
.
shape
[
0
],
-
1
)
return
gimg
,
vdata
def
relatedFiles
(
fname
):
def
relatedFiles
(
fname
,
ftype
=
None
):
"""
Given a GIFTI file, returns a list of other GIFTI files in the same
directory which appear to be related with the given one. Files which
share the same prefix are assumed to be related to the given file.
:arg fname: Name of the file to search for related files for
:arg ftype: If provided, only files with a name ``
'
*.[ftype].gii
'
`` are
searched for.
"""
# We want to return all files in the same
...
...
@@ -221,7 +258,7 @@ def relatedFiles(fname):
#
# - we don't care about the middle
#
# - type is func, shape, label,
or
time
# - type is func, shape, label, time
, or `ftype`
# We determine the unique prefix of the
# given file, and back-up to the most
...
...
@@ -235,9 +272,59 @@ def relatedFiles(fname):
if
lastdot
==
-
1
:
return
[]
funcs
=
list
(
glob
.
glob
(
'
{}*.func.gii
'
.
format
(
prefix
)))
shapes
=
list
(
glob
.
glob
(
'
{}*.shape.gii
'
.
format
(
prefix
)))
labels
=
list
(
glob
.
glob
(
'
{}*.label.gii
'
.
format
(
prefix
)))
times
=
list
(
glob
.
glob
(
'
{}*.time.gii
'
.
format
(
prefix
)))
if
ftype
is
None
:
ftypes
=
[
'
func
'
,
'
shape
'
,
'
label
'
,
'
time
'
]
else
:
ftypes
=
[
ftype
]
related
=
[]
for
ftype
in
ftypes
:
related
+=
list
(
glob
.
glob
(
'
{}*.{}.gii
'
.
format
(
prefix
,
ftype
)))
return
[
r
for
r
in
related
if
r
!=
fname
]
class
GiftiSurface
(
fslmesh
.
TriangleMesh
):
"""
Deprecated - use GiftiMesh instead.
"""
@deprecation.deprecated
(
deprecated_in
=
'
1.6.0
'
,
removed_in
=
'
2.0.0
'
,
details
=
'
Use GiftiMesh instead
'
)
def
__init__
(
self
,
infile
,
fixWinding
=
False
):
"""
Deprecated - use GiftiMesh instead.
"""
surfimg
,
vertices
,
indices
=
loadGiftiSurface
(
infile
)
fslmesh
.
TriangleMesh
.
__init__
(
self
,
vertices
,
indices
,
fixWinding
)
return
funcs
+
shapes
+
labels
+
times
name
=
fslpath
.
removeExt
(
op
.
basename
(
infile
),
ALLOWED_EXTENSIONS
)
infile
=
op
.
abspath
(
infile
)
self
.
_Mesh__name
=
name
self
.
_Mesh__dataSource
=
infile
self
.
surfImg
=
surfimg
@deprecation.deprecated
(
deprecated_in
=
'
1.6.0
'
,
removed_in
=
'
2.0.0
'
,
details
=
'
Use GiftiMesh instead
'
)
def
loadVertexData
(
self
,
dataSource
,
vertexData
=
None
):
"""
Deprecated - use GiftiMesh instead.
"""
if
vertexData
is
None
:
if
dataSource
.
endswith
(
'
.gii
'
):
vertexData
=
loadGiftiVertexData
(
dataSource
)[
1
]
else
:
vertexData
=
None
return
fslmesh
.
TriangleMesh
.
loadVertexData
(
self
,
dataSource
,
vertexData
)
@deprecation.deprecated
(
deprecated_in
=
'
1.6.0
'
,
removed_in
=
'
2.0.0
'
,
details
=
'
Use loadGiftiMesh instead
'
)
def
loadGiftiSurface
(
filename
):
"""
Deprecated - use loadGiftiMesh instead.
"""
return
loadGiftiMesh
(
filename
)
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