Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Michiel Cottaar
fslpy
Commits
60f6e154
Commit
60f6e154
authored
Feb 24, 2021
by
Paul McCarthy
🚵
Browse files
Merge branch 'bf/mesh' into 'master'
Bf/mesh See merge request fsl/fslpy!288
parents
3c57660e
71e2cada
Changes
11
Show whitespace changes
Inline
Side-by-side
CHANGELOG.rst
View file @
60f6e154
...
@@ -31,6 +31,13 @@ Deprecated
...
@@ -31,6 +31,13 @@ Deprecated
library on [PyPI](https://pypi.org/project/file-tree/).
library on [PyPI](https://pypi.org/project/file-tree/).
Fixed
^^^^^
* Fixed an edge-case in the :mod:`.gifti` module, where a surface with a
single triangle was being loaded incorrectly.
3.5.3 (Tuesday 9th February 2021)
3.5.3 (Tuesday 9th February 2021)
---------------------------------
---------------------------------
...
...
fsl/data/gifti.py
View file @
60f6e154
...
@@ -229,7 +229,7 @@ def loadGiftiMesh(filename):
...
@@ -229,7 +229,7 @@ def loadGiftiMesh(filename):
'at least one pointset array'
.
format
(
filename
))
'at least one pointset array'
.
format
(
filename
))
vertices
=
[
ps
.
data
for
ps
in
pointsets
]
vertices
=
[
ps
.
data
for
ps
in
pointsets
]
indices
=
triangles
[
0
].
data
indices
=
np
.
atleast_2d
(
triangles
[
0
].
data
)
if
len
(
vdata
)
==
0
:
vdata
=
None
if
len
(
vdata
)
==
0
:
vdata
=
None
else
:
vdata
=
prepareGiftiVertexData
(
vdata
,
filename
)
else
:
vdata
=
prepareGiftiVertexData
(
vdata
,
filename
)
...
...
fsl/data/mesh.py
View file @
60f6e154
...
@@ -573,7 +573,7 @@ class Mesh(notifier.Notifier, meta.Meta):
...
@@ -573,7 +573,7 @@ class Mesh(notifier.Notifier, meta.Meta):
# sort by ray. I'm Not sure if this is
# sort by ray. I'm Not sure if this is
# needed - does trimesh do it for us?
# needed - does trimesh do it for us?
rayIdxs
=
np
.
asarray
(
np
.
argsort
(
rays
)
,
np
.
int
)
rayIdxs
=
np
.
asarray
(
np
.
argsort
(
rays
))
locs
=
locs
[
rayIdxs
]
locs
=
locs
[
rayIdxs
]
tris
=
tris
[
rayIdxs
]
tris
=
tris
[
rayIdxs
]
...
@@ -687,7 +687,7 @@ def calcFaceNormals(vertices, indices):
...
@@ -687,7 +687,7 @@ def calcFaceNormals(vertices, indices):
fnormals
=
np
.
cross
((
v1
-
v0
),
(
v2
-
v0
))
fnormals
=
np
.
cross
((
v1
-
v0
),
(
v2
-
v0
))
fnormals
=
affine
.
normalise
(
fnormals
)
fnormals
=
affine
.
normalise
(
fnormals
)
return
fnormals
return
np
.
atleast_2d
(
fnormals
)
def
calcVertexNormals
(
vertices
,
indices
,
fnormals
):
def
calcVertexNormals
(
vertices
,
indices
,
fnormals
):
...
...
fsl/transform/nonlinear.py
View file @
60f6e154
...
@@ -280,7 +280,7 @@ class DeformationField(NonLinearTransform):
...
@@ -280,7 +280,7 @@ class DeformationField(NonLinearTransform):
# Mask out the coordinates
# Mask out the coordinates
# that are out of bounds of
# that are out of bounds of
# the deformation field
# the deformation field
voxels
=
np
.
round
(
voxels
).
astype
(
np
.
int
)
voxels
=
np
.
round
(
voxels
).
astype
(
np
.
int
32
)
voxmask
=
(
voxels
>=
[
0
,
0
,
0
])
&
(
voxels
<
self
.
shape
[:
3
])
voxmask
=
(
voxels
>=
[
0
,
0
,
0
])
&
(
voxels
<
self
.
shape
[:
3
])
voxmask
=
voxmask
.
all
(
axis
=
1
)
voxmask
=
voxmask
.
all
(
axis
=
1
)
voxels
=
voxels
[
voxmask
]
voxels
=
voxels
[
voxmask
]
...
@@ -508,9 +508,9 @@ class CoefficientField(NonLinearTransform):
...
@@ -508,9 +508,9 @@ class CoefficientField(NonLinearTransform):
u
=
np
.
remainder
(
i
,
1
)
u
=
np
.
remainder
(
i
,
1
)
v
=
np
.
remainder
(
j
,
1
)
v
=
np
.
remainder
(
j
,
1
)
w
=
np
.
remainder
(
k
,
1
)
w
=
np
.
remainder
(
k
,
1
)
i
=
np
.
floor
(
i
).
astype
(
np
.
int
)
i
=
np
.
floor
(
i
).
astype
(
np
.
int
32
)
j
=
np
.
floor
(
j
).
astype
(
np
.
int
)
j
=
np
.
floor
(
j
).
astype
(
np
.
int
32
)
k
=
np
.
floor
(
k
).
astype
(
np
.
int
)
k
=
np
.
floor
(
k
).
astype
(
np
.
int
32
)
disps
=
np
.
zeros
(
coords
.
shape
)
disps
=
np
.
zeros
(
coords
.
shape
)
...
...
tests/test_atlases_query.py
View file @
60f6e154
...
@@ -85,7 +85,7 @@ def _get_zero_mask(aimg):
...
@@ -85,7 +85,7 @@ def _get_zero_mask(aimg):
elif
isinstance
(
aimg
,
fslatlases
.
ProbabilisticAtlas
):
elif
isinstance
(
aimg
,
fslatlases
.
ProbabilisticAtlas
):
# Keep memory usage down
# Keep memory usage down
zmask
=
np
.
ones
(
aimg
.
shape
[:
3
],
dtype
=
np
.
bool
)
zmask
=
np
.
ones
(
aimg
.
shape
[:
3
],
dtype
=
bool
)
for
vol
in
range
(
aimg
.
shape
[
-
1
]):
for
vol
in
range
(
aimg
.
shape
[
-
1
]):
zmask
=
np
.
logical_and
(
zmask
,
aimg
[...,
vol
]
==
0
)
zmask
=
np
.
logical_and
(
zmask
,
aimg
[...,
vol
]
==
0
)
...
...
tests/test_gifti.py
View file @
60f6e154
...
@@ -381,3 +381,21 @@ def test_GiftiMesh_needsFixing():
...
@@ -381,3 +381,21 @@ def test_GiftiMesh_needsFixing():
surf
=
gifti
.
GiftiMesh
(
fname
,
fixWinding
=
True
)
surf
=
gifti
.
GiftiMesh
(
fname
,
fixWinding
=
True
)
assert
np
.
all
(
np
.
isclose
(
surf
.
indices
,
idxs_fixed
))
assert
np
.
all
(
np
.
isclose
(
surf
.
indices
,
idxs_fixed
))
def
test_loadGiftiMesh_onetriangle
():
verts
=
np
.
array
([[
0
,
0
,
0
],
[
1
,
1
,
1
],
[
0
,
1
,
0
]])
idxs
=
np
.
array
([[
0
,
1
,
2
]])
verts
=
nib
.
gifti
.
GiftiDataArray
(
verts
,
intent
=
'NIFTI_INTENT_POINTSET'
)
idxs
=
nib
.
gifti
.
GiftiDataArray
(
idxs
,
intent
=
'NIFTI_INTENT_TRIANGLE'
)
gimg
=
nib
.
gifti
.
GiftiImage
(
darrays
=
[
verts
,
idxs
])
with
tempdir
():
fname
=
op
.
abspath
(
'test.gii'
)
gimg
.
to_filename
(
fname
)
gimg
,
tris
,
verts
,
_
=
gifti
.
loadGiftiMesh
(
'test.gii'
)
verts
=
verts
[
0
]
assert
verts
.
shape
==
(
3
,
3
)
assert
tris
.
shape
==
(
1
,
3
)
tests/test_image_resample.py
View file @
60f6e154
...
@@ -75,7 +75,7 @@ def test_resample(seed):
...
@@ -75,7 +75,7 @@ def test_resample(seed):
(
np
.
isclose
(
np
.
modf
(
origtestcoords
)[
0
],
0.5
)))
(
np
.
isclose
(
np
.
modf
(
origtestcoords
)[
0
],
0.5
)))
out
=
np
.
any
(
out
,
axis
=
1
)
|
(
resvals
==
0
)
out
=
np
.
any
(
out
,
axis
=
1
)
|
(
resvals
==
0
)
origtestcoords
=
np
.
array
(
origtestcoords
.
round
(),
dtype
=
np
.
int
)
origtestcoords
=
np
.
array
(
origtestcoords
.
round
(),
dtype
=
int
)
origtestcoords
=
origtestcoords
[
~
out
,
:]
origtestcoords
=
origtestcoords
[
~
out
,
:]
restestcoords
=
restestcoords
[
~
out
,
:]
restestcoords
=
restestcoords
[
~
out
,
:]
...
@@ -166,8 +166,8 @@ def test_resampleToPixdims():
...
@@ -166,8 +166,8 @@ def test_resampleToPixdims():
img
=
fslimage
.
Image
(
make_random_image
(
dims
=
(
10
,
10
,
10
)))
img
=
fslimage
.
Image
(
make_random_image
(
dims
=
(
10
,
10
,
10
)))
imglo
,
imghi
=
affine
.
axisBounds
(
img
.
shape
,
img
.
voxToWorldMat
)
imglo
,
imghi
=
affine
.
axisBounds
(
img
.
shape
,
img
.
voxToWorldMat
)
oldpix
=
np
.
array
(
img
.
pixdim
,
dtype
=
np
.
float
)
oldpix
=
np
.
array
(
img
.
pixdim
,
dtype
=
float
)
oldshape
=
np
.
array
(
img
.
shape
,
dtype
=
np
.
float
)
oldshape
=
np
.
array
(
img
.
shape
,
dtype
=
float
)
for
i
,
origin
in
it
.
product
(
range
(
25
),
(
'centre'
,
'corner'
)):
for
i
,
origin
in
it
.
product
(
range
(
25
),
(
'centre'
,
'corner'
)):
...
@@ -215,16 +215,16 @@ def test_resampleToReference2():
...
@@ -215,16 +215,16 @@ def test_resampleToReference2():
# More specific test - output
# More specific test - output
# data gets transformed correctly
# data gets transformed correctly
# into reference space
# into reference space
img
=
np
.
zeros
((
5
,
5
,
5
),
dtype
=
np
.
float
)
img
=
np
.
zeros
((
5
,
5
,
5
),
dtype
=
float
)
img
[
1
,
1
,
1
]
=
1
img
[
1
,
1
,
1
]
=
1
img
=
fslimage
.
Image
(
img
)
img
=
fslimage
.
Image
(
img
)
refv2w
=
affine
.
scaleOffsetXform
([
1
,
1
,
1
],
[
-
1
,
-
1
,
-
1
])
refv2w
=
affine
.
scaleOffsetXform
([
1
,
1
,
1
],
[
-
1
,
-
1
,
-
1
])
ref
=
np
.
zeros
((
5
,
5
,
5
),
dtype
=
np
.
float
)
ref
=
np
.
zeros
((
5
,
5
,
5
),
dtype
=
float
)
ref
=
fslimage
.
Image
(
ref
,
xform
=
refv2w
)
ref
=
fslimage
.
Image
(
ref
,
xform
=
refv2w
)
res
=
resample
.
resampleToReference
(
img
,
ref
,
order
=
0
)
res
=
resample
.
resampleToReference
(
img
,
ref
,
order
=
0
)
exp
=
np
.
zeros
((
5
,
5
,
5
),
dtype
=
np
.
float
)
exp
=
np
.
zeros
((
5
,
5
,
5
),
dtype
=
float
)
exp
[
2
,
2
,
2
]
=
1
exp
[
2
,
2
,
2
]
=
1
assert
np
.
all
(
np
.
isclose
(
res
[
0
],
exp
))
assert
np
.
all
(
np
.
isclose
(
res
[
0
],
exp
))
...
...
tests/test_imagewrapper.py
View file @
60f6e154
...
@@ -1195,7 +1195,7 @@ def test_3D_indexing(shape=None, img=None):
...
@@ -1195,7 +1195,7 @@ def test_3D_indexing(shape=None, img=None):
assert
type
(
img
[
0
,
0
,
0
])
==
np
.
float64
assert
type
(
img
[
0
,
0
,
0
])
==
np
.
float64
mask1
=
np
.
zeros
(
shape
,
dtype
=
np
.
bool
)
mask1
=
np
.
zeros
(
shape
,
dtype
=
bool
)
mask1
[
0
,
0
,
0
]
=
True
mask1
[
0
,
0
,
0
]
=
True
mask1
[
1
,
0
,
0
]
=
True
mask1
[
1
,
0
,
0
]
=
True
...
@@ -1252,7 +1252,7 @@ def test_3D_4D_indexing():
...
@@ -1252,7 +1252,7 @@ def test_3D_4D_indexing():
assert
type
(
img
[
0
,
0
,
0
,
0
])
==
np
.
float64
assert
type
(
img
[
0
,
0
,
0
,
0
])
==
np
.
float64
assert
type
(
img
[
0
,
0
,
0
,
:])
==
np
.
float64
assert
type
(
img
[
0
,
0
,
0
,
:])
==
np
.
float64
mask
=
np
.
zeros
(
padShape
,
dtype
=
np
.
bool
)
mask
=
np
.
zeros
(
padShape
,
dtype
=
bool
)
mask
[
0
,
0
,
0
,
0
]
=
True
mask
[
0
,
0
,
0
,
0
]
=
True
assert
type
(
img
[
mask
])
==
np
.
ndarray
assert
type
(
img
[
mask
])
==
np
.
ndarray
...
@@ -1282,13 +1282,13 @@ def test_3D_len_one_indexing(shape=None, img=None):
...
@@ -1282,13 +1282,13 @@ def test_3D_len_one_indexing(shape=None, img=None):
assert
type
(
img
[
0
,
0
])
==
np
.
ndarray
assert
type
(
img
[
0
,
0
])
==
np
.
ndarray
assert
type
(
img
[
0
,
0
,
0
])
==
np
.
float64
assert
type
(
img
[
0
,
0
,
0
])
==
np
.
float64
mask
=
np
.
zeros
(
shape
[:
2
],
dtype
=
np
.
bool
)
mask
=
np
.
zeros
(
shape
[:
2
],
dtype
=
bool
)
mask
[
0
,
0
]
=
True
mask
[
0
,
0
]
=
True
assert
type
(
img
[
mask
])
==
np
.
ndarray
assert
type
(
img
[
mask
])
==
np
.
ndarray
assert
img
[
mask
].
shape
==
(
1
,
)
assert
img
[
mask
].
shape
==
(
1
,
)
mask
=
np
.
zeros
(
shape
,
dtype
=
np
.
bool
)
mask
=
np
.
zeros
(
shape
,
dtype
=
bool
)
mask
[
0
,
0
,
0
]
=
True
mask
[
0
,
0
,
0
]
=
True
assert
type
(
img
[
mask
])
==
np
.
ndarray
assert
type
(
img
[
mask
])
==
np
.
ndarray
...
@@ -1352,7 +1352,7 @@ def test_4D_indexing(shape=None, img=None):
...
@@ -1352,7 +1352,7 @@ def test_4D_indexing(shape=None, img=None):
assert
type
(
img
[
0
,
0
,
0
,
0
])
==
np
.
float64
assert
type
(
img
[
0
,
0
,
0
,
0
])
==
np
.
float64
mask1
=
np
.
zeros
(
shape
,
dtype
=
np
.
bool
)
mask1
=
np
.
zeros
(
shape
,
dtype
=
bool
)
mask1
[
0
,
0
,
0
,
0
]
=
True
mask1
[
0
,
0
,
0
,
0
]
=
True
mask1
[
1
,
0
,
0
,
0
]
=
True
mask1
[
1
,
0
,
0
,
0
]
=
True
...
...
tests/test_mesh.py
View file @
60f6e154
...
@@ -234,6 +234,13 @@ def test_normals():
...
@@ -234,6 +234,13 @@ def test_normals():
-
fnormals
,
fslmesh
.
calcFaceNormals
(
verts
,
triangles_cw
)))
-
fnormals
,
fslmesh
.
calcFaceNormals
(
verts
,
triangles_cw
)))
assert
np
.
all
(
np
.
isclose
(
assert
np
.
all
(
np
.
isclose
(
fnormals
,
fslmesh
.
calcFaceNormals
(
verts
,
triangles_ccw
)))
fnormals
,
fslmesh
.
calcFaceNormals
(
verts
,
triangles_ccw
)))
# Make sure result is (1, 3) for input of (1, 3)
onetri
=
np
.
atleast_2d
(
triangles_ccw
[
0
,
:])
result
=
fslmesh
.
calcFaceNormals
(
verts
,
onetri
)
assert
result
.
shape
==
(
1
,
3
)
assert
np
.
all
(
np
.
isclose
(
fnormals
[
0
,
:],
result
))
assert
np
.
all
(
np
.
isclose
(
assert
np
.
all
(
np
.
isclose
(
-
vnormals
,
fslmesh
.
calcVertexNormals
(
verts
,
triangles_cw
,
-
fnormals
)))
-
vnormals
,
fslmesh
.
calcVertexNormals
(
verts
,
triangles_cw
,
-
fnormals
)))
assert
np
.
all
(
np
.
isclose
(
assert
np
.
all
(
np
.
isclose
(
...
...
tests/test_transform/test_affine.py
View file @
60f6e154
...
@@ -395,7 +395,7 @@ def test_transform():
...
@@ -395,7 +395,7 @@ def test_transform():
mask
=
np
.
array
([[
1
,
0
,
0
,
1
],
mask
=
np
.
array
([[
1
,
0
,
0
,
1
],
[
0
,
1
,
0
,
1
],
[
0
,
1
,
0
,
1
],
[
0
,
0
,
1
,
1
],
[
0
,
0
,
1
,
1
],
[
0
,
0
,
0
,
1
]],
dtype
=
np
.
bool
)
[
0
,
0
,
0
,
1
]],
dtype
=
bool
)
return
np
.
all
((
xform
!=
0
)
==
mask
)
return
np
.
all
((
xform
!=
0
)
==
mask
)
...
...
tests/test_transform/test_nonlinear.py
View file @
60f6e154
...
@@ -161,7 +161,7 @@ def test_convertDeformationSpace():
...
@@ -161,7 +161,7 @@ def test_convertDeformationSpace():
refcoords
=
[
np
.
random
.
randint
(
0
,
basefield
.
shape
[
0
],
5
),
refcoords
=
[
np
.
random
.
randint
(
0
,
basefield
.
shape
[
0
],
5
),
np
.
random
.
randint
(
0
,
basefield
.
shape
[
1
],
5
),
np
.
random
.
randint
(
0
,
basefield
.
shape
[
1
],
5
),
np
.
random
.
randint
(
0
,
basefield
.
shape
[
2
],
5
)]
np
.
random
.
randint
(
0
,
basefield
.
shape
[
2
],
5
)]
refcoords
=
np
.
array
(
refcoords
,
dtype
=
np
.
int
).
T
refcoords
=
np
.
array
(
refcoords
,
dtype
=
int
).
T
refcoords
=
affine
.
transform
(
refcoords
,
ref
.
voxToScaledVoxMat
)
refcoords
=
affine
.
transform
(
refcoords
,
ref
.
voxToScaledVoxMat
)
srccoords
=
basefield
.
transform
(
refcoords
)
srccoords
=
basefield
.
transform
(
refcoords
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment