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
c60cda17
Commit
c60cda17
authored
8 years ago
by
Paul McCarthy
Browse files
Options
Downloads
Patches
Plain Diff
My first set of unit tests for fslpy - tests functions in the
imagewrapper module.
parent
6c1405a4
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
test/test_imagewrapper.py
+320
-0
320 additions, 0 deletions
test/test_imagewrapper.py
with
320 additions
and
0 deletions
test/test_imagewrapper.py
0 → 100644
+
320
−
0
View file @
c60cda17
#!/usr/bin/env python
#
# test_imagewrapper.py -
#
# Author: Paul McCarthy <pauldmccarthy@gmail.com>
import
collections
import
random
import
itertools
as
it
import
numpy
as
np
import
fsl.data.image
as
image
import
fsl.data.imagewrapper
as
imagewrap
def
setup_module
():
pass
def
teardown_module
():
pass
def
random_coverage
(
shape
):
ndims
=
len
(
shape
)
-
1
nvols
=
shape
[
-
1
]
print
'
{}D (shape: {}, {} vectors/slices/volumes)
'
.
format
(
ndims
,
shape
,
nvols
)
# Generate a random coverage.
# We use the same coverage for
# each vector/slice/volume, so
# are not fully testing the function.
coverage
=
np
.
zeros
((
2
,
ndims
,
nvols
),
dtype
=
np
.
uint32
)
for
dim
in
range
(
ndims
):
dsize
=
shape
[
dim
]
# Random low/high indices for each dimension.
low
=
np
.
random
.
randint
(
0
,
dsize
)
# We have to make sure that the coverage is not
# complete, as some of the tests will fail if
# the coverage is complete.
if
low
==
0
:
high
=
np
.
random
.
randint
(
low
+
1
,
dsize
)
else
:
high
=
np
.
random
.
randint
(
low
+
1
,
dsize
+
1
)
coverage
[
0
,
dim
,
:]
=
low
coverage
[
1
,
dim
,
:]
=
high
return
coverage
def
random_slices
(
coverage
,
shape
,
mode
):
ndims
=
len
(
shape
)
-
1
nvols
=
shape
[
-
1
]
slices
=
np
.
zeros
((
2
,
len
(
shape
)))
for
dim
,
size
in
enumerate
(
shape
):
# Volumes
if
dim
==
ndims
:
lowCover
=
np
.
random
.
randint
(
0
,
nvols
)
highCover
=
np
.
random
.
randint
(
lowCover
+
1
,
nvols
+
1
)
slices
[:,
dim
]
=
lowCover
,
highCover
continue
# Assuming that coverage is same for each volume
lowCover
=
coverage
[
0
,
dim
,
0
]
highCover
=
coverage
[
1
,
dim
,
0
]
# Generate some slices that will
# be contained within the coverage
if
mode
==
'
in
'
:
lowSlice
=
np
.
random
.
randint
(
lowCover
,
highCover
)
highSlice
=
np
.
random
.
randint
(
lowSlice
+
1
,
highCover
+
1
)
# Generate some indices which will
# randomly overlap with the coverage
# (if it is possible to do so)
elif
mode
==
'
overlap
'
:
if
highCover
==
size
:
lowSlice
=
np
.
random
.
randint
(
0
,
lowCover
)
else
:
lowSlice
=
np
.
random
.
randint
(
0
,
highCover
)
if
lowSlice
<
lowCover
:
highSlice
=
np
.
random
.
randint
(
lowCover
+
1
,
size
+
1
)
else
:
highSlice
=
np
.
random
.
randint
(
highCover
+
1
,
size
+
1
)
elif
mode
==
'
out
'
:
# The coverage is full, so we can't
# generate an outside range
if
lowCover
==
0
and
highCover
==
size
:
lowSlice
=
np
.
random
.
randint
(
lowCover
,
highCover
)
highSlice
=
np
.
random
.
randint
(
lowSlice
+
1
,
highCover
+
1
)
# If low coverage is 0, the slice
# must be above the coverage
elif
lowCover
==
0
:
lowSlice
=
np
.
random
.
randint
(
highCover
,
size
)
highSlice
=
np
.
random
.
randint
(
lowSlice
+
1
,
size
+
1
)
# If high coverage is size, the
# slice must be below the coverage
elif
highCover
==
size
:
lowSlice
=
np
.
random
.
randint
(
0
,
lowCover
)
highSlice
=
np
.
random
.
randint
(
lowSlice
+
1
,
lowCover
+
1
)
# Otherwise the slice could be
# below or above the coverage
else
:
lowSlice
=
random
.
choice
((
np
.
random
.
randint
(
0
,
lowCover
),
np
.
random
.
randint
(
highCover
,
size
)))
if
lowSlice
<
lowCover
:
highSlice
=
np
.
random
.
randint
(
lowSlice
+
1
,
lowCover
+
1
)
else
:
highSlice
=
np
.
random
.
randint
(
lowSlice
+
1
,
size
+
1
)
slices
[
0
,
dim
]
=
lowSlice
slices
[
1
,
dim
]
=
highSlice
slices
=
[
tuple
(
map
(
int
,
pair
))
for
pair
in
slices
.
T
]
return
slices
def
test_sliceObjToSliceTuple
():
func
=
imagewrap
.
sliceObjToSliceTuple
shape
=
(
10
,
10
,
10
)
assert
func
(
2
,
shape
)
==
((
2
,
3
),
(
0
,
10
),
(
0
,
10
))
assert
func
(
slice
(
None
),
shape
)
==
((
0
,
10
),
(
0
,
10
),
(
0
,
10
))
assert
func
((
slice
(
None
),
slice
(
None
),
slice
(
None
)),
shape
)
==
((
0
,
10
),
(
0
,
10
),
(
0
,
10
))
assert
func
((
9
,
slice
(
None
),
slice
(
None
)),
shape
)
==
((
9
,
10
),
(
0
,
10
),
(
0
,
10
))
assert
func
((
slice
(
None
),
5
,
slice
(
None
)),
shape
)
==
((
0
,
10
),
(
5
,
6
),
(
0
,
10
))
assert
func
((
slice
(
None
),
slice
(
None
),
3
),
shape
)
==
((
0
,
10
),
(
0
,
10
),
(
3
,
4
))
assert
func
((
slice
(
4
,
6
),
slice
(
None
),
slice
(
None
)),
shape
)
==
((
4
,
6
),
(
0
,
10
),
(
0
,
10
))
assert
func
((
8
,
slice
(
1
,
10
),
slice
(
None
)),
shape
)
==
((
8
,
9
),
(
1
,
10
),
(
0
,
10
))
def
test_sliceTupleToSliceObj
():
func
=
imagewrap
.
sliceTupleToSliceObj
shape
=
(
10
,
10
,
10
)
for
x1
,
y1
,
z1
in
it
.
product
(
*
[
range
(
d
-
1
)
for
d
in
shape
]):
for
x2
,
y2
,
z2
in
it
.
product
(
*
[
range
(
s
+
1
,
d
)
for
s
,
d
in
zip
((
x1
,
y1
,
z1
),
shape
)]):
slices
=
[[
x1
,
x2
],
[
y1
,
y2
],
[
z1
,
z2
]]
sliceobj
=
(
slice
(
x1
,
x2
,
1
),
slice
(
y1
,
y2
,
1
),
slice
(
z1
,
z2
,
1
))
assert
func
(
slices
)
==
sliceobj
def
test_adjustCoverage
():
# TODO Randomise
# Each test is a tuple of (coverage, expansion, expectedResult)
tests
=
[([[
3
,
5
],
[
2
,
6
]],
[[
6
,
7
],
[
8
,
10
]],
[[
3
,
7
],
[
2
,
10
]]),
([[
0
,
0
],
[
0
,
0
]],
[[
1
,
2
],
[
3
,
5
]],
[[
0
,
2
],
[
0
,
5
]]),
([[
2
,
3
],
[
0
,
6
]],
[[
1
,
5
],
[
4
,
10
]],
[[
1
,
5
],
[
0
,
10
]]),
([[
0
,
1
],
[
0
,
1
]],
[[
0
,
7
],
[
19
,
25
],
[
0
,
1
]],
[[
0
,
7
],
[
0
,
25
]]),
]
for
coverage
,
expansion
,
result
in
tests
:
result
=
np
.
array
(
result
)
.
T
coverage
=
np
.
array
(
coverage
).
T
assert
np
.
all
(
imagewrap
.
adjustCoverage
(
coverage
,
expansion
)
==
result
)
def
test_sliceCovered
():
# A bunch of random coverages
for
i
in
range
(
500
):
# 2D, 3D or 4D?
# ndims is the number of dimensions
# in one vector/slice/volume
ndims
=
random
.
choice
((
2
,
3
,
4
))
-
1
# Shape of one vector[2D]/slice[3D]/volume[4D]
shape
=
np
.
random
.
randint
(
5
,
100
,
size
=
ndims
+
1
)
# Number of vectors/slices/volumes
nvols
=
shape
[
-
1
]
coverage
=
random_coverage
(
shape
)
# Generate some slices that should
# be contained within the coverage
for
j
in
range
(
500
):
slices
=
random_slices
(
coverage
,
shape
,
'
in
'
)
assert
imagewrap
.
sliceCovered
(
slices
,
coverage
,
shape
)
# Generate some slices that should
# overlap with the coverage
for
j
in
range
(
500
):
slices
=
random_slices
(
coverage
,
shape
,
'
overlap
'
)
assert
not
imagewrap
.
sliceCovered
(
slices
,
coverage
,
shape
)
# Generate some slices that should
# be outside of the coverage
for
j
in
range
(
500
):
slices
=
random_slices
(
coverage
,
shape
,
'
out
'
)
assert
not
imagewrap
.
sliceCovered
(
slices
,
coverage
,
shape
)
# The sum of the coverage ranges + the
# expansion ranges should be equal to
# the coverage, expanded to include the
# original slices (or the expansions
# - should be equivalent). Note that
# if imagewrapper.adjustCoverage is
# broken, this validation will also be
# broken.
def
_test_expansion
(
coverage
,
slices
,
volumes
,
expansions
):
ndims
=
coverage
.
shape
[
1
]
print
print
'
Slice:
"
{}
"'
.
format
(
"
"
.
join
([
"
{:2d} {:2d}
"
.
format
(
l
,
h
)
for
l
,
h
in
slices
]))
# Bin the expansions by volume
expsByVol
=
collections
.
defaultdict
(
list
)
for
vol
,
exp
in
zip
(
volumes
,
expansions
):
print
'
{:3d}:
"
{}
"'
.
format
(
vol
,
"
"
.
join
([
"
{:2d} {:2d}
"
.
format
(
l
,
h
)
for
l
,
h
in
exp
]))
expsByVol
[
vol
].
append
(
exp
)
for
vol
,
exps
in
expsByVol
.
items
():
# Figure out what the adjusted
# coverage should look like (assumes
# that adjustCoverage is working).
oldCoverage
=
coverage
[...,
vol
]
newCoverage
=
imagewrap
.
adjustCoverage
(
oldCoverage
,
slices
)
nc
=
newCoverage
dimranges
=
[]
for
d
in
range
(
ndims
):
dimranges
.
append
(
np
.
arange
(
nc
[
0
,
d
],
nc
[
1
,
d
]))
points
=
it
.
product
(
*
dimranges
)
for
point
in
points
:
# Is this point in the old coverage?
covered
=
True
for
dim
in
range
(
ndims
):
covLow
,
covHigh
=
oldCoverage
[:,
dim
]
if
point
[
dim
]
<
covLow
or
point
[
dim
]
>
covHigh
:
covered
=
False
break
if
covered
:
break
# Is this point in any of the expansions
covered
=
[
False
]
*
len
(
exps
)
for
i
,
exp
in
enumerate
(
exps
):
covered
[
i
]
=
True
for
dim
in
range
(
ndims
):
expLow
,
expHigh
=
exp
[
dim
]
if
point
[
dim
]
<
expLow
or
point
[
dim
]
>
expHigh
:
covered
[
i
]
=
False
break
if
not
any
(
covered
):
raise
AssertionError
(
point
)
def
test_calcSliceExpansion
():
for
i
in
range
(
500
):
ndims
=
3
# random.choice((2, 3, 4)) - 1
shape
=
np
.
random
.
randint
(
5
,
100
,
size
=
ndims
+
1
)
coverage
=
random_coverage
(
shape
)
cov
=
[(
lo
,
hi
)
for
lo
,
hi
in
coverage
[:,
:,
0
].
T
]
print
'
Shape: {}
'
.
format
(
shape
)
print
'
Coverage: {}
'
.
format
(
cov
)
print
print
'
-- In --
'
for
j
in
range
(
250
):
slices
=
random_slices
(
coverage
,
shape
,
'
in
'
)
vols
,
exps
=
imagewrap
.
calcExpansion
(
slices
,
coverage
)
_test_expansion
(
coverage
,
slices
,
vols
,
exps
)
print
print
'
-- Overlap --
'
for
j
in
range
(
250
):
slices
=
random_slices
(
coverage
,
shape
,
'
overlap
'
)
vols
,
exps
=
imagewrap
.
calcExpansion
(
slices
,
coverage
)
_test_expansion
(
coverage
,
slices
,
vols
,
exps
)
print
print
'
-- Out --
'
for
j
in
range
(
250
):
slices
=
random_slices
(
coverage
,
shape
,
'
out
'
)
vols
,
exps
=
imagewrap
.
calcExpansion
(
slices
,
coverage
)
_test_expansion
(
coverage
,
slices
,
vols
,
exps
)
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