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
Model registry
Operate
Environments
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
FSL
fslpy
Commits
f480a89a
Commit
f480a89a
authored
7 years ago
by
Paul McCarthy
Browse files
Options
Downloads
Patches
Plain Diff
unit tests for atlasq
parent
9c5ce793
No related branches found
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
tests/test_atlasq_list_summary.py
+80
-0
80 additions, 0 deletions
tests/test_atlasq_list_summary.py
tests/test_atlasq_ohi.py
+198
-0
198 additions, 0 deletions
tests/test_atlasq_ohi.py
tests/test_atlasq_query.py
+473
-0
473 additions, 0 deletions
tests/test_atlasq_query.py
with
751 additions
and
0 deletions
tests/test_atlasq_list_summary.py
0 → 100644
+
80
−
0
View file @
f480a89a
#!/usr/bin/env python
#
# test_list_summary.py -
#
# Author: Paul McCarthy <pauldmccarthy@gmail.com>
#
import
os
import
itertools
as
it
import
fsl.data.atlases
as
fslatlases
import
fsl.atlasq.atlasq
as
fslatlasq
from
.
import
CaptureStdout
def
setup_module
():
if
os
.
environ
.
get
(
'
FSLDIR
'
,
None
)
is
None
:
raise
Exception
(
'
FSLDIR is not set - atlas tests cannot be run
'
)
def
test_list
():
fslatlases
.
rescanAtlases
()
adescs
=
fslatlases
.
listAtlases
()
capture
=
CaptureStdout
()
tests
=
[
'
list
'
,
'
list --extended
'
]
extendeds
=
[
False
,
True
]
for
test
,
extended
in
zip
(
tests
,
extendeds
):
capture
.
reset
()
with
capture
:
fslatlasq
.
main
(
test
.
split
())
stdout
=
capture
.
stdout
for
desc
in
adescs
:
assert
desc
.
atlasID
in
stdout
assert
desc
.
name
in
stdout
assert
(
desc
.
specPath
in
stdout
)
==
extended
for
image
in
it
.
chain
(
desc
.
images
,
desc
.
summaryImages
):
assert
(
image
in
stdout
)
==
extended
assert
(
image
in
stdout
)
==
extended
def
test_summary
():
fslatlases
.
rescanAtlases
()
adescs
=
fslatlases
.
listAtlases
()
capture
=
CaptureStdout
()
for
desc
in
adescs
:
tests
=
[
desc
.
atlasID
,
desc
.
name
]
for
test
in
tests
:
capture
.
reset
()
with
capture
:
fslatlasq
.
main
([
'
summary
'
,
test
])
stdout
=
capture
.
stdout
assert
desc
.
atlasID
in
stdout
assert
desc
.
name
in
stdout
assert
desc
.
specPath
in
stdout
assert
desc
.
atlasType
in
stdout
for
image
in
it
.
chain
(
desc
.
images
,
desc
.
summaryImages
):
assert
image
in
stdout
for
label
in
desc
.
labels
:
assert
label
.
name
in
stdout
This diff is collapsed.
Click to expand it.
tests/test_atlasq_ohi.py
0 → 100644
+
198
−
0
View file @
f480a89a
#!/usr/bin/env python
#
# test_ohi.py - Test the fsl.atlasq ohi interface, which mimics the behaviour
# of the old atlasquery tool.
#
# Author: Paul McCarthy <pauldmccarthy@gmail.com>
#
import
os.path
as
op
import
os
import
shlex
import
numpy
as
np
import
fsl.atlasq.atlasq
as
fslatlasq
import
fsl.data.atlases
as
fslatlases
from
.
import
(
tempdir
,
make_random_mask
,
CaptureStdout
)
def
setup_module
():
if
os
.
environ
.
get
(
'
FSLDIR
'
,
None
)
is
None
:
raise
Exception
(
'
FSLDIR is not set - atlas tests cannot be run
'
)
def
test_dumpatlases
():
"""
Test the ohi --dumpatlases option.
"""
capture
=
CaptureStdout
()
with
capture
:
fslatlasq
.
main
(
'
ohi --dumpatlases
'
.
split
())
atlases
=
fslatlases
.
listAtlases
()
atlases
=
[
a
.
name
for
a
in
atlases
]
atlases
=
sorted
(
atlases
)
assert
capture
.
stdout
.
strip
()
==
'
\n
'
.
join
(
atlases
)
def
test_coords
(
seed
):
"""
Test the ohi -a
"
atlas
"
-c
"
coords
"
mode.
"""
def
expectedProbOutput
(
atlas
,
coords
):
probs
=
atlas
.
proportions
(
coords
)
expected
=
'
<b>{}</b><br>
'
.
format
(
atlas
.
desc
.
name
)
nzprobs
=
[]
for
i
,
p
in
enumerate
(
probs
):
if
p
>
0
:
label
=
atlas
.
desc
.
labels
[
i
].
name
nzprobs
.
append
((
p
,
label
))
if
len
(
nzprobs
)
>
0
:
nzprobs
=
reversed
(
sorted
(
nzprobs
,
key
=
lambda
b
:
b
[
0
]))
nzprobs
=
[
'
{:d}% {}
'
.
format
(
int
(
round
(
p
)),
l
)
for
(
p
,
l
)
in
nzprobs
]
expected
+=
'
,
'
.
join
(
nzprobs
)
else
:
expected
+=
'
No label found!
'
return
expected
def
expectedLabelOutput
(
atlas
,
coords
):
label
=
atlas
.
label
(
coords
)
expected
=
'
<b>{}</b><br>
'
.
format
(
atlas
.
desc
.
name
)
if
label
is
None
:
return
expected
+
'
Unclassified
'
else
:
return
expected
+
atlas
.
desc
.
labels
[
int
(
label
)].
name
capture
=
CaptureStdout
()
# random coordinates in MNI152 space,
# with some coordinates out of bounds
ncoords
=
50
xc
=
-
100
+
190
*
np
.
random
.
random
(
ncoords
)
yc
=
-
130
+
220
*
np
.
random
.
random
(
ncoords
)
zc
=
-
80
+
120
*
np
.
random
.
random
(
ncoords
)
coords
=
np
.
vstack
((
xc
,
yc
,
zc
)).
T
fslatlases
.
rescanAtlases
()
atlases
=
fslatlases
.
listAtlases
()
for
ad
in
atlases
:
# atlasquery/ohi always uses 2mm resolution
atlas
=
fslatlases
.
loadAtlas
(
ad
.
atlasID
,
resolution
=
2
)
print
(
ad
.
name
)
for
x
,
y
,
z
in
coords
:
cmd
=
'
ohi -a
"
{}
"
-c
"
{},{},{}
"'
.
format
(
ad
.
name
,
x
,
y
,
z
)
capture
.
reset
()
with
capture
:
fslatlasq
.
main
(
shlex
.
split
(
cmd
))
if
isinstance
(
atlas
,
fslatlases
.
ProbabilisticAtlas
):
expected
=
expectedProbOutput
(
atlas
,
(
x
,
y
,
z
))
# LabelAtlas
else
:
expected
=
expectedLabelOutput
(
atlas
,
(
x
,
y
,
z
))
assert
capture
.
stdout
.
strip
()
==
expected
.
strip
()
def
test_bad_atlas
():
"""
Test the ohi -a
"
atlas
"
..., with a non-existent atlas.
"""
capture
=
CaptureStdout
()
atlases
=
fslatlases
.
listAtlases
()
atlases
=
sorted
([
a
.
name
for
a
in
atlases
])
expected
=
[
'
Invalid atlas name. Try one of:
'
]
+
atlases
expected
=
'
\n
'
.
join
(
expected
)
cmds
=
[
'
ohi -a
"
non-existent atlas
"
-c
"
0,0,0
"'
,
'
ohi -a
"
non-existent atlas
"
-m
"
nomask
"'
]
for
cmd
in
cmds
:
capture
.
reset
()
with
capture
:
fslatlasq
.
main
(
shlex
.
split
(
cmd
))
assert
capture
.
stdout
.
strip
()
==
expected
def
test_mask
(
seed
):
"""
Test the ohi -a
"
atlas
"
-m
"
mask
"
mode, with label and probabilistic
atlases.
"""
def
expectedLabelOutput
(
mask
,
atlas
):
labels
,
props
=
atlas
.
maskLabel
(
mask
)
exp
=
[]
for
lbl
,
prop
in
zip
(
labels
,
props
):
exp
.
append
(
'
{}:{:0.4f}
'
.
format
(
desc
.
labels
[
int
(
lbl
)].
name
,
prop
))
return
'
\n
'
.
join
(
exp
)
def
expectedProbOutput
(
mask
,
atlas
):
props
=
atlas
.
maskProportions
(
mask
)
labels
=
[
l
.
index
for
l
in
atlas
.
desc
.
labels
]
exp
=
[]
for
lbl
,
prop
in
zip
(
labels
,
props
):
if
prop
>
0
:
exp
.
append
(
'
{}:{:0.4f}
'
.
format
(
desc
.
labels
[
int
(
lbl
)].
name
,
prop
))
return
'
\n
'
.
join
(
exp
)
fslatlases
.
rescanAtlases
()
capture
=
CaptureStdout
()
atlases
=
fslatlases
.
listAtlases
()
with
tempdir
()
as
td
:
maskfile
=
op
.
join
(
td
,
'
mask.nii
'
)
for
desc
in
atlases
:
# atlasquery always uses 2mm
# resolution versions of atlases
atlas2mm
=
fslatlases
.
loadAtlas
(
desc
.
atlasID
,
resolution
=
2
)
# Test with 1mm and 2mm masks
for
res
in
[
1
,
2
]:
atlasimg
=
fslatlases
.
loadAtlas
(
desc
.
atlasID
,
resolution
=
res
)
maskimg
=
make_random_mask
(
maskfile
,
atlasimg
.
shape
[:
3
],
atlasimg
.
voxToWorldMat
)
cmd
=
'
ohi -a
"
{}
"
-m {}
'
.
format
(
desc
.
name
,
maskfile
)
print
(
cmd
)
capture
.
reset
()
with
capture
:
fslatlasq
.
main
(
shlex
.
split
(
cmd
))
if
isinstance
(
atlasimg
,
fslatlases
.
LabelAtlas
):
expected
=
expectedLabelOutput
(
maskimg
,
atlas2mm
)
elif
isinstance
(
atlasimg
,
fslatlases
.
ProbabilisticAtlas
):
expected
=
expectedProbOutput
(
maskimg
,
atlas2mm
)
assert
capture
.
stdout
.
strip
()
==
expected
This diff is collapsed.
Click to expand it.
tests/test_atlasq_query.py
0 → 100644
+
473
−
0
View file @
f480a89a
#!/usr/bin/env python
#
# test_query.py -
#
# Author: Paul McCarthy <pauldmccarthy@gmail.com>
#
import
os
import
os.path
as
op
import
re
import
itertools
as
it
import
six
import
numpy
as
np
import
scipy.ndimage
as
ndi
import
fsl.utils.transform
as
transform
import
fsl.data.atlases
as
fslatlases
import
fsl.data.image
as
fslimage
import
fsl.atlasq.atlasq
as
fslatlasq
from
.
import
(
tempdir
,
make_random_mask
,
CaptureStdout
)
def
setup_module
():
if
os
.
environ
.
get
(
'
FSLDIR
'
,
None
)
is
None
:
raise
Exception
(
'
FSLDIR is not set - atlas tests cannot be run
'
)
atlases
=
[
'
harvardoxford-cortical
'
,
'
talairach
'
]
# False: do not use the --label flag
# True: use the --label flag
#
# ('label', True) should be equivalent to ('label', False)
use_labels
=
[
True
,
False
]
# mask_1 == 1mm mask image
# mask_2 == 2mm mask image
query_types
=
[
'
coordinate
'
,
'
voxel
'
,
'
mask_1
'
,
'
mask_2
'
]
# 'in': query is inside the atlas (results expected)
# 'zero': query is inside the atlas, but out of any region (no results
# expected)
# 'out': query is outside the atlas (no results expected)
query_is_in
=
[
'
in
'
,
'
zero
'
,
'
out
'
]
resolutions
=
[
1
,
2
]
output_types
=
[
'
normal
'
,
'
short
'
]
tests
=
list
(
it
.
product
(
atlases
,
use_labels
,
query_types
,
query_is_in
,
resolutions
,
output_types
))
# side-test - multiple queries together,
# in both short and normal output formats
def
test_query_voxel
(
seed
):
_test_query
([
t
for
t
in
tests
if
t
[
2
]
==
'
voxel
'
])
def
test_query_coord
(
seed
):
_test_query
([
t
for
t
in
tests
if
t
[
2
]
==
'
coordinate
'
])
def
test_query_mask
(
seed
):
_test_query
([
t
for
t
in
tests
if
t
[
2
].
startswith
(
'
mask
'
)])
def
_test_query
(
tests
):
fslatlases
.
rescanAtlases
()
capture
=
CaptureStdout
()
print
()
for
atlas
,
use_label
,
q_type
,
q_in
,
res
,
o_type
in
tests
:
with
tempdir
()
as
td
:
if
q_type
in
(
'
voxel
'
,
'
coordinate
'
):
genfunc
=
_gen_coord_voxel_query
evalfunc
=
_eval_coord_voxel_query
else
:
genfunc
=
_gen_mask_query
evalfunc
=
_eval_mask_query
print
(
'
Test: {} {}mm label={} type={} in={} type={}
'
.
format
(
atlas
,
res
,
use_label
,
q_type
,
q_in
,
o_type
))
query
=
genfunc
(
atlas
,
use_label
,
q_type
,
q_in
,
res
)
cmd
=
_build_command_line
(
atlas
,
query
,
use_label
,
q_type
,
res
,
o_type
)
print
(
'
fslatlasq {}
'
.
format
(
'
'
.
join
(
cmd
)))
capture
.
reset
()
with
capture
:
fslatlasq
.
main
(
cmd
)
evalfunc
(
capture
.
stdout
,
atlas
,
query
,
use_label
,
q_type
,
q_in
,
res
,
o_type
)
_atlases
=
{}
def
_get_atlas
(
aid
,
use_label
,
res
):
atlas
=
_atlases
.
get
((
aid
,
use_label
,
res
),
None
)
if
atlas
is
None
:
atlas
=
fslatlases
.
loadAtlas
(
aid
,
loadSummary
=
use_label
,
resolution
=
res
)
_atlases
[
aid
]
=
atlas
return
atlas
_zero_masks
=
{}
def
_get_zero_mask
(
a_img
,
atlas
,
use_label
,
res
):
# Make a mask which tells us which
# voxels in the atlas are all zeros
zmask
=
_zero_masks
.
get
((
atlas
,
use_label
,
res
),
None
)
if
zmask
is
None
:
if
isinstance
(
a_img
,
fslatlases
.
LabelAtlas
):
zmask
=
a_img
[:]
==
0
elif
isinstance
(
a_img
,
fslatlases
.
ProbabilisticAtlas
):
zmask
=
np
.
all
(
a_img
[:]
==
0
,
axis
=-
1
)
_zero_masks
[
atlas
,
use_label
,
res
]
=
zmask
return
zmask
def
_gen_coord_voxel_query
(
atlas
,
use_label
,
q_type
,
q_in
,
res
):
a_img
=
_get_atlas
(
atlas
,
use_label
,
res
)
voxel
=
q_type
==
'
voxel
'
if
voxel
:
dtype
=
int
else
:
dtype
=
float
if
q_in
==
'
out
'
:
if
voxel
:
dlo
=
(
0
,
0
,
0
)
dhi
=
a_img
.
shape
else
:
dlo
,
dhi
=
transform
.
axisBounds
(
a_img
.
shape
,
a_img
.
voxToWorldMat
)
dlen
=
[
hi
-
lo
for
lo
,
hi
in
zip
(
dlo
,
dhi
)]
coords
=
[]
for
d
in
range
(
3
):
# over
if
np
.
random
.
random
()
>
0.5
:
coords
.
append
(
dlo
[
d
]
+
dlen
[
d
]
+
dlen
[
d
]
*
np
.
random
.
random
())
# or under
else
:
coords
.
append
(
dlo
[
d
]
-
dlen
[
d
]
*
np
.
random
.
random
())
coords
=
np
.
array
(
coords
,
dtype
=
dtype
)
else
:
# Make a mask which tells us which
# voxels in the atlas are all zeros
zmask
=
_get_zero_mask
(
a_img
,
atlas
,
use_label
,
res
)
# get indices to voxels which are
# either all zero, or which are
# not all all zero, depending on
# the value of q_in
if
q_in
==
'
in
'
:
zidxs
=
np
.
where
(
zmask
==
0
)
else
:
zidxs
=
np
.
where
(
zmask
)
# Randomly choose a voxel
cidx
=
np
.
random
.
randint
(
0
,
len
(
zidxs
[
0
]))
coords
=
[
zidxs
[
0
][
cidx
],
zidxs
[
1
][
cidx
],
zidxs
[
2
][
cidx
]]
coords
=
np
.
array
(
coords
,
dtype
=
dtype
)
if
not
voxel
:
coords
=
transform
.
transform
(
coords
,
a_img
.
voxToWorldMat
)
return
tuple
([
dtype
(
c
)
for
c
in
coords
])
def
_eval_coord_voxel_query
(
stdout
,
atlas
,
query
,
use_label
,
q_type
,
q_in
,
res
,
o_type
):
a_img
=
_get_atlas
(
atlas
,
use_label
,
res
)
voxel
=
q_type
==
'
voxel
'
prob
=
a_img
.
desc
.
atlasType
==
'
probabilistic
'
x
,
y
,
z
=
query
if
voxel
:
squery
=
'
{:0.0f} {:0.0f} {:0.0f}
'
.
format
(
*
query
)
else
:
squery
=
'
{:0.2f} {:0.2f} {:0.2f}
'
.
format
(
*
query
)
if
voxel
:
lsquery
=
'
voxel {}
'
.
format
(
squery
)
else
:
lsquery
=
'
coordinate {}
'
.
format
(
squery
)
def
evalLabelNormalOutput
(
explabel
):
assert
lsquery
in
stdout
# all label atlases have an entry for 0
if
q_in
==
'
in
'
or
(
q_in
==
'
zero
'
and
not
prob
):
if
prob
:
labelobj
=
a_img
.
desc
.
labels
[
explabel
-
1
]
else
:
labelobj
=
a_img
.
desc
.
labels
[
explabel
]
assert
labelobj
.
name
in
stdout
assert
'
{}
'
.
format
(
explabel
)
in
stdout
if
prob
:
assert
'
{}
'
.
format
(
labelobj
.
index
)
in
stdout
else
:
assert
'
No label
'
in
stdout
def
evalLabelShortOutput
(
explabel
):
if
q_in
==
'
in
'
or
(
q_in
==
'
zero
'
and
not
prob
):
if
prob
:
labelobj
=
a_img
.
desc
.
labels
[
explabel
-
1
]
else
:
labelobj
=
a_img
.
desc
.
labels
[
explabel
]
exp
=
[
q_type
,
squery
,
labelobj
.
name
]
else
:
exp
=
[
q_type
,
squery
,
'
No label
'
]
_stdout
=
re
.
sub
(
'
\s+
'
,
'
'
,
stdout
).
strip
()
assert
_stdout
==
'
'
.
join
(
exp
)
def
evalProbNormalOutput
(
expprops
):
assert
lsquery
in
stdout
if
q_in
==
'
in
'
:
lines
=
stdout
.
split
(
'
\n
'
)
explabels
=
[
a_img
.
desc
.
labels
[
i
]
for
i
in
range
(
len
(
expprops
))]
for
explabel
,
expprop
in
zip
(
explabels
,
expprops
):
if
expprop
==
0
:
continue
hits
=
[
l
for
l
in
lines
if
explabel
.
name
in
l
]
assert
len
(
hits
)
==
1
line
=
hits
[
0
]
assert
'
{}
'
.
format
(
explabel
.
index
)
in
line
assert
'
{}
'
.
format
(
explabel
.
index
+
1
)
in
line
assert
'
{:0.4f}
'
.
format
(
expprop
)
in
line
else
:
assert
'
No results
'
in
stdout
def
evalProbShortOutput
(
expprops
):
if
q_in
==
'
in
'
:
exp
=
[
q_type
,
squery
]
labels
=
[
a_img
.
desc
.
labels
[
i
].
name
for
i
in
range
(
len
(
expprops
))]
for
expprop
,
explabel
in
reversed
(
sorted
(
zip
(
expprops
,
labels
))):
if
expprop
==
0
:
break
exp
.
append
(
'
{} {:0.4f}
'
.
format
(
explabel
,
expprop
))
else
:
exp
=
[
q_type
,
squery
]
_stdout
=
re
.
sub
(
'
\s+
'
,
'
'
,
stdout
).
strip
()
assert
_stdout
==
'
'
.
join
(
exp
)
if
isinstance
(
a_img
,
fslatlases
.
LabelAtlas
):
explabel
=
a_img
.
label
(
query
,
voxel
=
voxel
)
if
o_type
==
'
normal
'
:
evalLabelNormalOutput
(
explabel
)
else
:
evalLabelShortOutput
(
explabel
)
elif
isinstance
(
a_img
,
fslatlases
.
ProbabilisticAtlas
):
expprops
=
a_img
.
proportions
(
query
,
voxel
=
voxel
)
if
o_type
==
'
normal
'
:
evalProbNormalOutput
(
expprops
)
else
:
evalProbShortOutput
(
expprops
)
def
_gen_mask_query
(
atlas
,
use_label
,
q_type
,
q_in
,
res
):
maskres
=
int
(
q_type
[
-
1
])
maskfile
=
'
mask.nii.gz
'
a_img
=
_get_atlas
(
atlas
,
use_label
,
res
)
if
q_in
==
'
out
'
:
make_random_mask
(
maskfile
,
(
20
,
20
,
20
),
np
.
eye
(
4
))
else
:
zmask
=
_get_zero_mask
(
a_img
,
atlas
,
use_label
,
res
)
if
q_in
==
'
in
'
:
zmask
=
zmask
==
0
mask
=
make_random_mask
(
maskfile
,
a_img
.
shape
[:
3
],
a_img
.
voxToWorldMat
,
zmask
)
mask
.
save
(
'
/Users/paulmc/Projects/fsl-atlasq/mask_before_resample.nii.gz
'
)
mask
.
save
(
'
/Users/paulmc/Projects/fsl-atlasq/mask.nii.gz
'
)
fslimage
.
Image
(
np
.
array
(
zmask
,
dtype
=
np
.
uint8
),
xform
=
a_img
.
voxToWorldMat
).
save
(
'
/Users/paulmc/Projects/fsl-atlasq/zmask.nii.gz
'
)
if
maskres
!=
res
:
zmask
=
ndi
.
binary_erosion
(
zmask
,
iterations
=
3
)
fslimage
.
Image
(
np
.
array
(
zmask
,
dtype
=
np
.
uint8
),
xform
=
a_img
.
voxToWorldMat
).
save
(
'
/Users/paulmc/Projects/fsl-atlasq/zmask.nii.gz
'
)
mask
[
zmask
==
0
]
=
0
a
=
_get_atlas
(
atlas
,
True
,
maskres
)
# Make sure that when the mask gets
# resampled into the atlas resolution,
# it is still either in or out of the
# atlas space
mask
,
xform
=
mask
.
resample
(
a
.
shape
[:
3
],
dtype
=
np
.
float32
,
order
=
1
)
thres
=
np
.
percentile
(
mask
[
mask
>
0
],
75
)
mask
[
mask
>=
thres
]
=
1
mask
[
mask
<
thres
]
=
0
mask
=
np
.
array
(
mask
,
dtype
=
np
.
uint8
)
mask
=
fslimage
.
Image
(
mask
,
xform
=
xform
)
mask
.
save
(
'
/Users/paulmc/Projects/fsl-atlasq/mask.nii.gz
'
)
mask
.
save
(
maskfile
)
return
maskfile
def
_eval_mask_query
(
stdout
,
atlas
,
query
,
use_label
,
q_type
,
q_in
,
res
,
o_type
):
maskimg
=
fslimage
.
Image
(
query
)
aimg
=
_get_atlas
(
atlas
,
use_label
,
res
)
prob
=
aimg
.
desc
.
atlasType
==
'
probabilistic
'
def
evalNormalOutput
(
explabels
,
expprops
):
assert
'
mask {}
'
.
format
(
op
.
abspath
(
query
))
in
stdout
if
len
(
explabels
)
==
0
:
assert
'
No results
'
in
stdout
return
lines
=
stdout
.
split
(
'
\n
'
)
for
explabel
,
expprop
in
zip
(
explabels
,
expprops
):
hits
=
[
l
for
l
in
lines
if
explabel
.
name
+
'
'
in
l
]
if
expprop
==
0
:
assert
len
(
hits
)
==
0
continue
assert
len
(
hits
)
==
1
line
=
hits
[
0
]
assert
'
{:0.4f}
'
.
format
(
expprop
)
in
line
assert
'
{}
'
.
format
(
explabel
.
index
)
in
line
if
prob
:
assert
'
{}
'
.
format
(
explabel
.
index
+
1
)
in
line
def
evalShortOutput
(
explabels
,
expprops
):
explabels
=
[
l
.
name
for
l
in
explabels
]
exp
=
[
'
mask
'
,
op
.
abspath
(
query
)]
for
expprop
,
explabel
in
reversed
(
sorted
(
zip
(
expprops
,
explabels
))):
if
expprop
>
0
:
exp
.
append
(
'
{} {:0.4f}
'
.
format
(
explabel
,
expprop
))
_stdout
=
re
.
sub
(
'
\s+
'
,
'
'
,
stdout
).
strip
()
assert
_stdout
==
'
'
.
join
(
exp
)
if
isinstance
(
aimg
,
fslatlases
.
LabelAtlas
):
try
:
explabels
,
expprops
=
aimg
.
maskLabel
(
maskimg
)
if
prob
:
explabels
=
[
aimg
.
desc
.
labels
[
i
-
1
]
for
i
in
explabels
]
else
:
explabels
=
[
aimg
.
desc
.
labels
[
i
]
for
i
in
explabels
]
except
fslatlases
.
MaskError
:
explabels
,
expprops
=
[],
[]
elif
isinstance
(
aimg
,
fslatlases
.
ProbabilisticAtlas
):
try
:
expprops
=
aimg
.
maskProportions
(
maskimg
)
explabels
=
aimg
.
desc
.
labels
except
fslatlases
.
MaskError
:
explabels
=
[]
expprops
=
[]
if
q_in
==
'
out
'
:
assert
stdout
.
strip
()
==
'
Mask is not in the same space as atlas
'
return
if
o_type
==
'
normal
'
:
evalNormalOutput
(
explabels
,
expprops
)
else
:
evalShortOutput
(
explabels
,
expprops
)
def
_build_command_line
(
atlas
,
query
,
use_label
,
q_type
,
res
,
o_type
):
cmd
=
[
'
query
'
,
atlas
,
'
-r
'
,
str
(
res
)]
if
use_label
:
cmd
.
append
(
'
-l
'
)
if
o_type
==
'
short
'
:
cmd
.
append
(
'
-s
'
)
if
q_type
.
startswith
(
'
mask
'
):
cmd
+=
[
'
-m
'
,
query
]
elif
q_type
==
'
voxel
'
:
cmd
+=
[
'
-v
'
]
+
'
{} {} {}
'
.
format
(
*
query
).
split
()
elif
q_type
==
'
coordinate
'
:
cmd
+=
[
'
-c
'
]
+
'
{} {} {}
'
.
format
(
*
query
).
split
()
return
cmd
def
test_bad_mask
(
seed
):
fslatlases
.
rescanAtlases
()
capture
=
CaptureStdout
()
with
tempdir
()
as
td
:
for
atlasID
,
use_label
in
it
.
product
(
atlases
,
use_labels
):
atlas
=
fslatlases
.
loadAtlas
(
atlasID
,
loadSummary
=
use_label
)
ashape
=
list
(
atlas
.
shape
[:
3
])
wrongdims
=
fslimage
.
Image
(
np
.
random
.
random
(
list
(
ashape
)
+
[
10
]))
wrongspace
=
fslimage
.
Image
(
np
.
random
.
random
((
20
,
20
,
20
)),
xform
=
transform
.
concat
(
atlas
.
voxToWorldMat
,
np
.
diag
([
2
,
2
,
2
,
1
])))
print
(
wrongdims
.
shape
)
print
(
wrongspace
.
shape
)
wrongdims
.
save
(
'
wrongdims.nii.gz
'
)
wrongspace
.
save
(
'
wrongspace.nii.gz
'
)
cmd
=
[
'
query
'
,
atlasID
,
'
-m
'
,
'
wrongdims
'
]
expected
=
'
Mask has wrong number of dimensions
'
capture
.
reset
()
with
capture
:
assert
fslatlasq
.
main
(
cmd
)
!=
0
assert
capture
.
stdout
.
strip
()
==
expected
cmd
=
[
'
query
'
,
atlasID
,
'
-m
'
,
'
wrongspace
'
]
expected
=
'
Mask is not in the same space as atlas
'
capture
.
reset
()
with
capture
:
assert
fslatlasq
.
main
(
cmd
)
!=
0
assert
capture
.
stdout
.
strip
()
==
expected
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