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
9a99c71d
Commit
9a99c71d
authored
8 years ago
by
Paul McCarthy
Browse files
Options
Downloads
Patches
Plain Diff
test_image module rewritten so it generates its own data, instead of relying
on an existing data set.
parent
5d063e35
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/__init__.py
+6
-16
6 additions, 16 deletions
tests/__init__.py
tests/test_image.py
+436
-172
436 additions, 172 deletions
tests/test_image.py
tests/test_immv_imcp.py
+16
-5
16 additions, 5 deletions
tests/test_immv_imcp.py
with
458 additions
and
193 deletions
tests/__init__.py
+
6
−
16
View file @
9a99c71d
...
@@ -60,24 +60,14 @@ def cleardir(dir):
...
@@ -60,24 +60,14 @@ def cleardir(dir):
elif
op
.
isdir
(
f
):
shutil
.
rmtree
(
f
)
elif
op
.
isdir
(
f
):
shutil
.
rmtree
(
f
)
def
make_random_image
(
filename
,
dims
=
(
10
,
10
,
10
),
affine
=
None
):
def
make_random_image
(
filename
,
dims
=
(
10
,
10
,
10
)):
"""
Creates a NIFTI image with random data, returns the hash of said data.
"""
Creates a NIFTI1 image with random data, saves and
returns it.
"""
"""
if
affine
is
None
:
data
=
np
.
array
(
np
.
random
.
random
(
dims
)
*
100
,
dtype
=
np
.
float32
)
affine
=
np
.
eye
(
4
)
img
=
nib
.
Nifti1Image
(
data
,
np
.
eye
(
4
))
data
=
np
.
random
.
random
(
dims
)
img
=
nib
.
Nifti1Image
(
data
,
affine
)
nib
.
save
(
img
,
filename
)
nib
.
save
(
img
,
filename
)
return
hash
(
data
.
tobytes
())
return
img
def
check_image_hash
(
filename
,
datahash
):
"""
Checks that the given NIFTI image matches the given hash.
"""
img
=
nib
.
load
(
filename
)
assert
hash
(
img
.
get_data
().
tobytes
())
==
datahash
This diff is collapsed.
Click to expand it.
tests/test_image.py
+
436
−
172
View file @
9a99c71d
#!/usr/bin/env python
#!/usr/bin/env python
#
#
# test_image.py -
# test_image.py -
Unit tests for the fsl.data.image module.
#
#
# Author: Paul McCarthy <pauldmccarthy@gmail.com>
# Author: Paul McCarthy <pauldmccarthy@gmail.com>
#
#
"""
Unit tests for the fsl.data.image module.
"""
import
os.path
as
op
import
os.path
as
op
import
itertools
as
it
import
tempfile
import
shutil
import
glob
import
pytest
import
pytest
import
glob
import
numpy
as
np
import
numpy
as
np
import
numpy.linalg
as
npla
import
numpy.linalg
as
npla
...
@@ -20,17 +25,73 @@ import fsl.data.constants as constants
...
@@ -20,17 +25,73 @@ import fsl.data.constants as constants
import
fsl.data.image
as
fslimage
import
fsl.data.image
as
fslimage
import
fsl.utils.path
as
fslpath
import
fsl.utils.path
as
fslpath
from
.
import
make_random_image
from
.
import
make_dummy_file
def
make_image
(
filename
,
imgtype
=
1
,
dims
=
(
10
,
10
,
10
),
pixdims
=
(
1
,
1
,
1
),
dtype
=
np
.
float32
):
"""
Convenience function which makes an image containing random data.
Saves and returns the nibabel object.
imgtype == 0: ANALYZE
imgtype == 1: NIFTI1
imgtype == 2: NIFTI2
"""
if
imgtype
==
0
:
filename
=
'
{}.img
'
.
format
(
filename
)
else
:
filename
=
'
{}.nii
'
.
format
(
filename
)
if
imgtype
==
0
:
hdr
=
nib
.
AnalyzeHeader
()
elif
imgtype
==
1
:
hdr
=
nib
.
Nifti1Header
()
elif
imgtype
==
2
:
hdr
=
nib
.
Nifti2Header
()
pixdims
=
pixdims
[:
len
(
dims
)]
hdr
.
set_data_dtype
(
dtype
)
hdr
.
set_data_shape
(
dims
)
hdr
.
set_zooms
([
abs
(
p
)
for
p
in
pixdims
])
xform
=
np
.
eye
(
4
)
for
i
,
p
in
enumerate
(
pixdims
):
xform
[
i
,
i
]
=
p
data
=
np
.
array
(
np
.
random
.
random
(
dims
)
*
100
,
dtype
=
dtype
)
if
imgtype
==
0
:
img
=
nib
.
AnalyzeImage
(
data
,
xform
,
hdr
)
elif
imgtype
==
1
:
img
=
nib
.
Nifti1Image
(
data
,
xform
,
hdr
)
elif
imgtype
==
2
:
img
=
nib
.
Nifti2Image
(
data
,
xform
,
hdr
)
nib
.
save
(
img
,
filename
)
return
img
# Need to test:
# Need to test:
# - Create image from file name (create a temp .nii.gz)
# - Create image from existing nibabel image
# - Create image from existing nibabel image
# - Create image from numpy array
# - Create image from numpy array
# - calcRange
# - calcRange
# - loadData
# - loadData
def
test_load
(
testdir
):
assert
testdir
is
not
None
def
test_load
():
"""
Create an Image from a file name.
"""
# notnifti.nii.gz is just a plain text
# file, the rest are NIFTI images
toCreate
=
[
'
compressed.nii.gz
'
,
'
uncompressed.nii
'
,
'
img_hdr_pair.img
'
,
'
compressed_img_hdr_pair.img.gz
'
,
'
ambiguous.nii
'
,
'
ambiguous.img
'
,
'
ambiguous.img.gz
'
,
'
notnifti.nii.gz
'
]
shouldPass
=
[
'
compressed
'
,
shouldPass
=
[
'
compressed
'
,
'
compressed.nii.gz
'
,
'
compressed.nii.gz
'
,
...
@@ -52,48 +113,96 @@ def test_load(testdir):
...
@@ -52,48 +113,96 @@ def test_load(testdir):
(
'
ambiguous
'
,
fslpath
.
PathError
),
(
'
ambiguous
'
,
fslpath
.
PathError
),
(
'
notnifti
'
,
ImageFileError
),
(
'
notnifti
'
,
ImageFileError
),
(
'
notnifti.nii.gz
'
,
ImageFileError
)]
(
'
notnifti.nii.gz
'
,
ImageFileError
)]
# Not raising an error means the test passes
for
fname
in
shouldPass
:
fslimage
.
Image
(
op
.
join
(
testdir
,
'
nifti_formats
'
,
fname
))
# These should raise an error
testdir
=
tempfile
.
mkdtemp
()
for
fname
,
exc
in
shouldRaise
:
with
pytest
.
raises
(
exc
):
fslimage
.
Image
(
op
.
join
(
testdir
,
'
nifti_formats
'
,
fname
))
for
f
in
toCreate
:
if
f
.
startswith
(
'
notnifti
'
):
make_dummy_file
(
op
.
join
(
testdir
,
f
))
else
:
make_random_image
(
op
.
join
(
testdir
,
f
))
# Not raising an error means the test passes
try
:
for
fname
in
shouldPass
:
fslimage
.
Image
(
op
.
join
(
testdir
,
fname
))
# These should raise an error
for
fname
,
exc
in
shouldRaise
:
with
pytest
.
raises
(
exc
):
fslimage
.
Image
(
op
.
join
(
testdir
,
fname
))
finally
:
shutil
.
rmtree
(
testdir
)
def
test_Image_atts_analyze
():
_test_Image_atts
(
0
)
def
test_Image_atts_nifti1
():
_test_Image_atts
(
1
)
def
test_Image_atts_nifti2
():
_test_Image_atts
(
2
)
def
_test_Image_atts
(
imgtype
):
"""
Test that basic Nifti/Image attributes are correct.
"""
testdir
=
tempfile
.
mkdtemp
()
allowedExts
=
fslimage
.
ALLOWED_EXTENSIONS
fileGroups
=
fslimage
.
FILE_GROUPS
# (file, dims, pixdims, dtype)
dtypes
=
[
np
.
uint8
,
np
.
int16
,
np
.
int32
,
np
.
float32
,
np
.
double
]
dims
=
[(
10
,
1
,
1
),
(
1
,
10
,
1
),
(
1
,
1
,
10
),
(
10
,
10
,
1
),
(
10
,
1
,
10
),
(
1
,
10
,
10
),
(
10
,
10
,
10
),
(
1
,
1
,
1
,
5
),
(
10
,
10
,
1
,
5
),
(
10
,
1
,
10
,
5
),
(
1
,
10
,
10
,
5
),
(
10
,
10
,
10
,
5
)]
pixdims
=
[(
0.5
,
0.5
,
0.5
,
2
),
(
1.0
,
1.0
,
1.0
,
2
),
(
2.0
,
2.0
,
2.0
,
2
),
(
1.0
,
5.0
,
1.0
,
3
)]
tests
=
list
(
it
.
product
(
dims
,
pixdims
,
dtypes
))
paths
=
[
'
test{:03d}
'
.
format
(
i
)
for
i
in
range
(
len
(
tests
))]
for
path
,
(
dims
,
pixdims
,
dtype
)
in
zip
(
paths
,
tests
):
ndims
=
len
(
dims
)
pixdims
=
pixdims
[:
ndims
]
def
test_Image_atts
(
testdir
):
path
=
op
.
abspath
(
op
.
join
(
testdir
,
path
))
make_image
(
path
,
imgtype
,
dims
,
pixdims
,
dtype
)
allowedExts
=
fslimage
.
ALLOWED_EXTENSIONS
try
:
# (file, dims, pixdims)
for
path
,
(
dims
,
pixdims
,
dtype
)
in
zip
(
paths
,
tests
):
tests
=
[
(
'
MNI152_T1_0.5mm
'
,
(
364
,
436
,
364
),
(
0.5
,
0.5
,
0.5
),
np
.
uint8
),
(
'
MNI152_T1_1mm
'
,
(
182
,
218
,
182
),
(
1.0
,
1.0
,
1.0
),
np
.
int16
),
(
'
MNI152_T1_2mm
'
,
(
91
,
109
,
91
),
(
2.0
,
2.0
,
2.0
),
np
.
int16
),
(
'
MNI152_T1_2mm_4D
'
,
(
91
,
109
,
91
,
5
),
(
2.0
,
2.0
,
2.0
,
1.0
),
np
.
int16
),
(
op
.
join
(
'
nifti2D
'
,
'
MNI152_T1_2mm_sliceXY
'
),
(
91
,
109
,
1
),
(
2.0
,
2.0
,
2.0
),
np
.
int16
),
(
op
.
join
(
'
nifti2D
'
,
'
MNI152_T1_2mm_sliceXZ
'
),
(
91
,
1
,
91
),
(
2.0
,
2.0
,
2.0
),
np
.
int16
),
(
op
.
join
(
'
nifti2D
'
,
'
MNI152_T1_2mm_sliceYZ
'
),
(
1
,
109
,
91
),
(
2.0
,
2.0
,
2.0
),
np
.
int16
)]
for
path
,
dims
,
pixdims
,
dtype
in
tests
:
ndims
=
len
(
dims
)
pixdims
=
pixdims
[:
ndims
]
path
=
op
.
abspath
(
op
.
join
(
testdir
,
path
))
path
=
op
.
abspath
(
op
.
join
(
testdir
,
path
))
i
=
fslimage
.
Image
(
path
)
i
=
fslimage
.
Image
(
path
)
assert
tuple
(
i
.
shape
)
==
tuple
(
dims
)
assert
tuple
(
i
.
shape
)
==
tuple
(
dims
)
assert
tuple
(
i
.
pixdim
)
==
tuple
(
pixdims
)
assert
tuple
(
i
.
pixdim
)
==
tuple
(
pixdims
)
assert
tuple
(
i
.
nibImage
.
shape
)
==
tuple
(
dims
)
assert
tuple
(
i
.
nibImage
.
shape
)
==
tuple
(
dims
)
assert
tuple
(
i
.
nibImage
.
header
.
get_zooms
())
==
tuple
(
pixdims
)
assert
tuple
(
i
.
nibImage
.
header
.
get_zooms
())
==
tuple
(
pixdims
)
assert
i
.
dtype
==
dtype
assert
i
.
dtype
==
dtype
assert
i
.
name
==
op
.
basename
(
path
)
assert
i
.
name
==
op
.
basename
(
path
)
assert
i
.
dataSource
==
fslpath
.
addExt
(
path
,
allowedExts
,
mustExist
=
True
)
assert
i
.
dataSource
==
fslpath
.
addExt
(
path
,
allowedExts
=
allowedExts
,
mustExist
=
True
,
fileGroups
=
fileGroups
)
finally
:
shutil
.
rmtree
(
testdir
)
def
test_looksLikeImage
():
def
test_looksLikeImage
():
"""
Test the looksLikeImage function.
"""
# (file, expected)
# (file, expected)
tests
=
[
tests
=
[
...
@@ -111,9 +220,22 @@ def test_looksLikeImage():
...
@@ -111,9 +220,22 @@ def test_looksLikeImage():
assert
fslimage
.
looksLikeImage
(
path
)
==
expected
assert
fslimage
.
looksLikeImage
(
path
)
==
expected
def
test_addExt
(
testdir
):
def
test_addExt
():
"""
Test the addExt function.
"""
default
=
fslimage
.
defaultExt
()
default
=
fslimage
.
defaultExt
()
testdir
=
tempfile
.
mkdtemp
()
toCreate
=
[
'
compressed.nii.gz
'
,
'
uncompressed.nii
'
,
'
img_hdr_pair.img
'
,
'
compressed_img_hdr_pair.img.gz
'
,
'
ambiguous.nii
'
,
'
ambiguous.nii.gz
'
,
'
ambiguous.img
'
,
'
ambiguous.img.gz
'
]
# (file, mustExist, expected)
# (file, mustExist, expected)
tests
=
[
tests
=
[
...
@@ -141,85 +263,170 @@ def test_addExt(testdir):
...
@@ -141,85 +263,170 @@ def test_addExt(testdir):
(
'
ambiguous.img.gz
'
,
True
,
'
ambiguous.img.gz
'
),
(
'
ambiguous.img.gz
'
,
True
,
'
ambiguous.img.gz
'
),
(
'
ambiguous.hdr.gz
'
,
True
,
'
ambiguous.hdr.gz
'
)]
(
'
ambiguous.hdr.gz
'
,
True
,
'
ambiguous.hdr.gz
'
)]
for
path
,
mustExist
,
expected
in
tests
:
for
path
in
toCreate
:
if
mustExist
:
path
=
op
.
abspath
(
op
.
join
(
testdir
,
path
))
path
=
op
.
join
(
testdir
,
'
nifti_formats
'
,
path
)
make_random_image
(
path
)
expected
=
op
.
join
(
testdir
,
'
nifti_formats
'
,
expected
)
try
:
assert
fslimage
.
addExt
(
path
,
mustExist
)
==
expected
for
path
,
mustExist
,
expected
in
tests
:
with
pytest
.
raises
(
fslimage
.
PathError
):
path
=
op
.
abspath
(
op
.
join
(
testdir
,
path
))
path
=
op
.
join
(
testdir
,
'
nifti_formats
'
,
'
ambiguous
'
)
expected
=
op
.
abspath
(
op
.
join
(
testdir
,
expected
))
fslimage
.
addExt
(
path
,
mustExist
=
True
)
assert
fslimage
.
addExt
(
path
,
mustExist
)
==
expected
def
test_Image_orientation
(
testdir
):
# Make sure that an ambiguous path fails
with
pytest
.
raises
(
fslimage
.
PathError
):
neuro
=
op
.
join
(
testdir
,
'
dtifit
'
,
'
neuro
'
,
'
dti_FA
'
)
path
=
op
.
join
(
testdir
,
'
ambiguous
'
)
radio
=
op
.
join
(
testdir
,
'
dtifit
'
,
'
radio
'
,
'
dti_FA
'
)
fslimage
.
addExt
(
path
,
mustExist
=
True
)
finally
:
neuro
=
fslimage
.
Image
(
neuro
)
shutil
.
rmtree
(
testdir
)
radio
=
fslimage
.
Image
(
radio
)
def
test_Image_orientation_analyze_neuro
():
_test_Image_orientation
(
0
,
'
neuro
'
)
assert
neuro
.
isNeurological
()
def
test_Image_orientation_analyze_radio
():
_test_Image_orientation
(
0
,
'
radio
'
)
assert
not
radio
.
isNeurological
()
def
test_Image_orientation_nifti1_neuro
():
_test_Image_orientation
(
1
,
'
neuro
'
)
def
test_Image_orientation_nifti1_radio
():
_test_Image_orientation
(
1
,
'
radio
'
)
def
test_Image_orientation_nifti2_neuro
():
_test_Image_orientation
(
2
,
'
neuro
'
)
def
test_Image_orientation_nifti2_radio
():
_test_Image_orientation
(
2
,
'
radio
'
)
def
_test_Image_orientation
(
imgtype
,
voxorient
):
"""
Test the Nifti.isNeurological and Nifti.getOrientation methods.
"""
testdir
=
tempfile
.
mkdtemp
()
imagefile
=
op
.
join
(
testdir
,
'
image
'
)
# an image with RAS voxel storage order
# (affine has a positive determinant)
# is said to be "neurological", whereas
# an image with LAS voxel storage order
# (negative determinant - x axis must
# be flipped to bring it into RAS nifti
# world coordinates)) is said to be
# "radiological". The make_image function
# forms the affine from these pixdims.
if
voxorient
==
'
neuro
'
:
pixdims
=
(
1
,
1
,
1
)
elif
voxorient
==
'
radio
'
:
pixdims
=
(
-
1
,
1
,
1
)
make_image
(
imagefile
,
imgtype
,
(
10
,
10
,
10
),
pixdims
,
np
.
float32
)
image
=
fslimage
.
Image
(
imagefile
)
# analyze images are always assumed to be
# stored in radiological (LAS) orientation
if
imgtype
==
0
:
expectNeuroTest
=
False
expectvox0Orientation
=
constants
.
ORIENT_R2L
expectvox1Orientation
=
constants
.
ORIENT_P2A
expectvox2Orientation
=
constants
.
ORIENT_I2S
elif
voxorient
==
'
neuro
'
:
expectNeuroTest
=
True
expectvox0Orientation
=
constants
.
ORIENT_L2R
expectvox1Orientation
=
constants
.
ORIENT_P2A
expectvox2Orientation
=
constants
.
ORIENT_I2S
else
:
expectNeuroTest
=
False
expectvox0Orientation
=
constants
.
ORIENT_R2L
expectvox1Orientation
=
constants
.
ORIENT_P2A
expectvox2Orientation
=
constants
.
ORIENT_I2S
try
:
assert
image
.
isNeurological
()
==
expectNeuroTest
# All images should have the
# same orientation in the
# world coordinate system
assert
image
.
getOrientation
(
0
,
np
.
eye
(
4
))
==
constants
.
ORIENT_L2R
assert
image
.
getOrientation
(
1
,
np
.
eye
(
4
))
==
constants
.
ORIENT_P2A
assert
image
.
getOrientation
(
2
,
np
.
eye
(
4
))
==
constants
.
ORIENT_I2S
# But the voxel orientation
# is dependent on the affine
affine
=
image
.
voxToWorldMat
assert
image
.
getOrientation
(
0
,
affine
)
==
expectvox0Orientation
assert
image
.
getOrientation
(
1
,
affine
)
==
expectvox1Orientation
assert
image
.
getOrientation
(
2
,
affine
)
==
expectvox2Orientation
finally
:
shutil
.
rmtree
(
testdir
)
def
test_Image_sqforms_nifti1_normal
():
_test_Image_sqforms
(
1
,
1
,
1
)
def
test_Image_sqforms_nifti1_nosform
():
_test_Image_sqforms
(
1
,
0
,
1
)
def
test_Image_sqforms_nifti1_noqform
():
_test_Image_sqforms
(
1
,
1
,
0
)
def
test_Image_sqforms_nifti1_nosqform
():
_test_Image_sqforms
(
1
,
1
,
0
)
def
test_Image_sqforms_nifti2_normal
():
_test_Image_sqforms
(
2
,
1
,
1
)
def
test_Image_sqforms_nifti2_nosform
():
_test_Image_sqforms
(
2
,
0
,
1
)
def
test_Image_sqforms_nifti2_noqform
():
_test_Image_sqforms
(
2
,
1
,
0
)
def
test_Image_sqforms_nifti2_nosqform
():
_test_Image_sqforms
(
2
,
1
,
0
)
def
_test_Image_sqforms
(
imgtype
,
sformcode
,
qformcode
):
"""
Test the Nifti.getXFormCode method, and the voxToWorldMat/worldToVoxMat
attributes for NIFTI images with the given sform/qform code combination.
"""
testdir
=
tempfile
.
mkdtemp
()
imagefile
=
op
.
abspath
(
op
.
join
(
testdir
,
'
image.nii.gz
'
))
# For an image with no s/q form, we expect the
# fallback affine - a simple scaling matrix.
# We add some offsets to the actual affine so
# we can distinguish it from the fallback affine.
scaleMat
=
np
.
diag
([
2
,
2
,
2
,
1
])
invScaleMat
=
np
.
diag
([
0.5
,
0.5
,
0.5
,
1
])
affine
=
np
.
array
(
scaleMat
)
affine
[:
3
,
3
]
=
[
25
,
20
,
20
]
invAffine
=
npla
.
inv
(
affine
)
image
=
make_image
(
imagefile
,
imgtype
,
(
10
,
10
,
10
),
(
2
,
2
,
2
),
np
.
float32
)
image
.
set_sform
(
affine
,
sformcode
)
image
.
set_qform
(
affine
,
qformcode
)
image
.
update_header
()
nib
.
save
(
image
,
imagefile
)
# No s or qform - we expect the fallback affine
if
sformcode
==
0
and
qformcode
==
0
:
expAffine
=
scaleMat
invExpAffine
=
invScaleMat
expCode
=
constants
.
NIFTI_XFORM_UNKNOWN
# No sform, but valid qform - expect the affine
elif
sformcode
==
0
and
qformcode
>
0
:
expAffine
=
affine
invExpAffine
=
invAffine
expCode
=
qformcode
# Valid sform (qform irrelevant) - expect the affine
elif
sformcode
>
0
:
expAffine
=
affine
invExpAffine
=
invAffine
expCode
=
sformcode
image
=
fslimage
.
Image
(
imagefile
)
try
:
assert
np
.
all
(
np
.
isclose
(
image
.
voxToWorldMat
,
expAffine
))
assert
np
.
all
(
np
.
isclose
(
image
.
worldToVoxMat
,
invExpAffine
))
# Both images should have the
assert
image
.
getXFormCode
()
==
expCode
# same orientation in the
assert
image
.
getXFormCode
(
'
sform
'
)
==
sformcode
# world coordinate system
assert
image
.
getXFormCode
(
'
qform
'
)
==
qformcode
assert
neuro
.
getOrientation
(
0
,
np
.
eye
(
4
))
==
constants
.
ORIENT_L2R
finally
:
assert
neuro
.
getOrientation
(
1
,
np
.
eye
(
4
))
==
constants
.
ORIENT_P2A
shutil
.
rmtree
(
testdir
)
assert
neuro
.
getOrientation
(
2
,
np
.
eye
(
4
))
==
constants
.
ORIENT_I2S
assert
radio
.
getOrientation
(
0
,
np
.
eye
(
4
))
==
constants
.
ORIENT_L2R
assert
radio
.
getOrientation
(
1
,
np
.
eye
(
4
))
==
constants
.
ORIENT_P2A
assert
radio
.
getOrientation
(
2
,
np
.
eye
(
4
))
==
constants
.
ORIENT_I2S
# The radio image should be
# l/r flipped in the voxel
# coordinate system
assert
neuro
.
getOrientation
(
0
,
neuro
.
voxToWorldMat
)
==
constants
.
ORIENT_L2R
assert
neuro
.
getOrientation
(
1
,
neuro
.
voxToWorldMat
)
==
constants
.
ORIENT_P2A
assert
neuro
.
getOrientation
(
2
,
neuro
.
voxToWorldMat
)
==
constants
.
ORIENT_I2S
assert
radio
.
getOrientation
(
0
,
radio
.
voxToWorldMat
)
==
constants
.
ORIENT_R2L
assert
radio
.
getOrientation
(
1
,
radio
.
voxToWorldMat
)
==
constants
.
ORIENT_P2A
assert
radio
.
getOrientation
(
2
,
radio
.
voxToWorldMat
)
==
constants
.
ORIENT_I2S
def
test_Image_changeXform_analyze
():
_test_Image_changeXform
(
0
)
def
test_Image_changeXform_nifti1
():
_test_Image_changeXform
(
1
)
def
test_Image_changeXform_nifti2
():
_test_Image_changeXform
(
2
)
def
_test_Image_changeXform
(
imgtype
):
"""
Test changing the Nifti.voxToWorldMat attribute.
"""
def
test_Image_sqforms
(
testdir
):
testdir
=
tempfile
.
mkdtemp
()
imagefile
=
op
.
join
(
testdir
,
'
image
'
)
benchmark
=
fslimage
.
Image
(
op
.
join
(
testdir
,
'
MNI152_T1_2mm.nii.gz
'
))
make_image
(
imagefile
,
imgtype
)
nosform
=
fslimage
.
Image
(
op
.
join
(
testdir
,
'
MNI152_T1_2mm_nosform.nii.gz
'
))
noqform
=
fslimage
.
Image
(
op
.
join
(
testdir
,
'
MNI152_T1_2mm_noqform.nii.gz
'
))
nosqform
=
fslimage
.
Image
(
op
.
join
(
testdir
,
'
MNI152_T1_2mm_nosqform.nii.gz
'
))
scalemat
=
np
.
diag
([
2
,
2
,
2
,
1
])
invScalemat
=
np
.
diag
([
0.5
,
0.5
,
0.5
,
1
])
assert
np
.
all
(
np
.
isclose
(
nosform
.
voxToWorldMat
,
benchmark
.
voxToWorldMat
))
assert
np
.
all
(
np
.
isclose
(
nosform
.
worldToVoxMat
,
benchmark
.
worldToVoxMat
))
assert
np
.
all
(
np
.
isclose
(
noqform
.
voxToWorldMat
,
benchmark
.
voxToWorldMat
))
assert
np
.
all
(
np
.
isclose
(
noqform
.
worldToVoxMat
,
benchmark
.
worldToVoxMat
))
assert
np
.
all
(
np
.
isclose
(
nosqform
.
voxToWorldMat
,
scalemat
))
assert
np
.
all
(
np
.
isclose
(
nosqform
.
worldToVoxMat
,
invScalemat
))
assert
benchmark
.
getXFormCode
()
==
constants
.
NIFTI_XFORM_MNI_152
assert
benchmark
.
getXFormCode
(
'
sform
'
)
==
constants
.
NIFTI_XFORM_MNI_152
assert
benchmark
.
getXFormCode
(
'
qform
'
)
==
constants
.
NIFTI_XFORM_MNI_152
assert
nosform
.
getXFormCode
()
==
constants
.
NIFTI_XFORM_MNI_152
assert
nosform
.
getXFormCode
(
'
sform
'
)
==
constants
.
NIFTI_XFORM_UNKNOWN
assert
nosform
.
getXFormCode
(
'
qform
'
)
==
constants
.
NIFTI_XFORM_MNI_152
assert
noqform
.
getXFormCode
()
==
constants
.
NIFTI_XFORM_MNI_152
assert
noqform
.
getXFormCode
(
'
sform
'
)
==
constants
.
NIFTI_XFORM_MNI_152
assert
noqform
.
getXFormCode
(
'
qform
'
)
==
constants
.
NIFTI_XFORM_UNKNOWN
assert
nosqform
.
getXFormCode
()
==
constants
.
NIFTI_XFORM_UNKNOWN
assert
nosqform
.
getXFormCode
(
'
sform
'
)
==
constants
.
NIFTI_XFORM_UNKNOWN
assert
nosqform
.
getXFormCode
(
'
qform
'
)
==
constants
.
NIFTI_XFORM_UNKNOWN
def
test_Image_changeXform
(
testdir
):
img
=
fslimage
.
Image
(
op
.
join
(
testdir
,
'
MNI152_T1_2mm.nii.gz
'
))
notified
=
{}
notified
=
{}
...
@@ -227,30 +434,59 @@ def test_Image_changeXform(testdir):
...
@@ -227,30 +434,59 @@ def test_Image_changeXform(testdir):
notified
[
'
xform
'
]
=
True
notified
[
'
xform
'
]
=
True
def
onSave
(
*
a
):
def
onSave
(
*
a
):
notified
[
'
save
'
]
=
True
notified
[
'
save
'
]
=
True
img
=
fslimage
.
Image
(
imagefile
)
img
.
register
(
'
name1
'
,
onXform
,
'
transform
'
)
img
.
register
(
'
name1
'
,
onXform
,
'
transform
'
)
img
.
register
(
'
name2
'
,
onSave
,
'
saveState
'
)
img
.
register
(
'
name2
'
,
onSave
,
'
saveState
'
)
newXform
=
np
.
array
([[
5
,
0
,
0
,
10
],
[
0
,
2
,
0
,
23
],
[
0
,
0
,
14
,
5
],
[
0
,
0
,
0
,
1
]])
newXform
=
np
.
array
([[
5
,
0
,
0
,
10
],
[
0
,
2
,
0
,
23
],
[
0
,
0
,
14
,
5
],
[
0
,
0
,
0
,
1
]])
assert
img
.
saveState
try
:
img
.
voxToWorldMat
=
newXform
# Image state should initially be saved
assert
img
.
saveState
invx
=
npla
.
inv
(
newXform
)
if
imgtype
==
0
:
# ANALYZE affine is not editable
with
pytest
.
raises
(
Exception
):
img
.
voxToWorldMat
=
newXform
return
assert
notified
.
get
(
'
xform
'
,
False
)
img
.
voxToWorldMat
=
newXform
assert
notified
.
get
(
'
save
'
,
False
)
assert
not
img
.
saveState
invx
=
npla
.
inv
(
newXform
)
assert
np
.
all
(
np
.
isclose
(
img
.
voxToWorldMat
,
newXform
))
# Did we get notified?
assert
np
.
all
(
np
.
isclose
(
img
.
worldToVoxMat
,
invx
))
assert
notified
.
get
(
'
xform
'
,
False
)
assert
notified
.
get
(
'
save
'
,
False
)
assert
not
img
.
saveState
# Did the affine get updated?
assert
np
.
all
(
np
.
isclose
(
img
.
voxToWorldMat
,
newXform
))
assert
np
.
all
(
np
.
isclose
(
img
.
worldToVoxMat
,
invx
))
finally
:
shutil
.
rmtree
(
testdir
)
def
test_Image_changeData
(
testdir
):
img
=
fslimage
.
Image
(
op
.
join
(
testdir
,
'
dtypes
'
,
'
MNI152_T1_1mm_float.nii.gz
'
))
def
test_Image_changeData_analyze
(
seed
):
_test_Image_changeData
(
0
)
def
test_Image_changeData_nifti1
(
seed
):
_test_Image_changeData
(
1
)
def
test_Image_changeData_nifti2
(
seed
):
_test_Image_changeData
(
2
)
def
_test_Image_changeData
(
imgtype
):
"""
Test that changing image data triggers notification, and also causes
the dataRange attribute to be updated.
"""
testdir
=
tempfile
.
mkdtemp
()
imagefile
=
op
.
join
(
testdir
,
'
image
'
)
make_image
(
imagefile
,
imgtype
)
img
=
fslimage
.
Image
(
imagefile
)
notified
=
{}
notified
=
{}
...
@@ -258,7 +494,6 @@ def test_Image_changeData(testdir):
...
@@ -258,7 +494,6 @@ def test_Image_changeData(testdir):
return
(
np
.
random
.
randint
(
0
,
img
.
shape
[
0
]),
return
(
np
.
random
.
randint
(
0
,
img
.
shape
[
0
]),
np
.
random
.
randint
(
0
,
img
.
shape
[
1
]),
np
.
random
.
randint
(
0
,
img
.
shape
[
1
]),
np
.
random
.
randint
(
0
,
img
.
shape
[
2
]))
np
.
random
.
randint
(
0
,
img
.
shape
[
2
]))
def
onData
(
*
a
):
def
onData
(
*
a
):
notified
[
'
data
'
]
=
True
notified
[
'
data
'
]
=
True
...
@@ -273,71 +508,100 @@ def test_Image_changeData(testdir):
...
@@ -273,71 +508,100 @@ def test_Image_changeData(testdir):
img
.
register
(
'
name2
'
,
onSaveState
,
'
saveState
'
)
img
.
register
(
'
name2
'
,
onSaveState
,
'
saveState
'
)
img
.
register
(
'
name3
'
,
onDataRange
,
'
dataRange
'
)
img
.
register
(
'
name3
'
,
onDataRange
,
'
dataRange
'
)
# Calculate the actual data range
data
=
img
.
nibImage
.
get_data
()
data
=
img
.
nibImage
.
get_data
()
dmin
=
data
.
min
()
dmin
=
data
.
min
()
dmax
=
data
.
max
()
dmax
=
data
.
max
()
drange
=
dmax
-
dmin
drange
=
dmax
-
dmin
assert
img
.
saveState
try
:
assert
np
.
all
(
np
.
isclose
(
img
.
dataRange
,
(
dmin
,
dmax
)))
randval
=
dmin
+
np
.
random
.
random
()
*
drang
e
assert
img
.
saveStat
e
rx
,
ry
,
rz
=
randvox
(
)
assert
np
.
all
(
np
.
isclose
(
img
.
dataRange
,
(
dmin
,
dmax
))
)
img
[
rx
,
ry
,
rz
]
=
randval
randval
=
dmin
+
np
.
random
.
random
()
*
drange
rx
,
ry
,
rz
=
randvox
()
assert
np
.
isclose
(
img
[
rx
,
ry
,
rz
],
randval
)
img
[
rx
,
ry
,
rz
]
=
randval
assert
notified
.
get
(
'
data
'
,
False
)
assert
notified
.
get
(
'
save
'
,
False
)
assert
not
img
.
saveState
notified
.
pop
(
'
data
'
)
assert
np
.
isclose
(
img
[
rx
,
ry
,
rz
],
randval
)
assert
notified
.
get
(
'
data
'
,
False
)
assert
notified
.
get
(
'
save
'
,
False
)
assert
not
img
.
saveState
newdmin
=
dmin
-
100
notified
.
pop
(
'
data
'
)
newdmax
=
dmax
+
100
rx
,
ry
,
rz
=
randvox
()
newdmin
=
dmin
-
100
img
[
rx
,
ry
,
rz
]
=
newdmin
newdmax
=
dmax
+
100
assert
notified
.
get
(
'
data
'
,
False
)
rx
,
ry
,
rz
=
randvox
()
assert
notified
.
get
(
'
dataRange
'
,
False
)
img
[
rx
,
ry
,
rz
]
=
newdmin
assert
np
.
isclose
(
img
[
rx
,
ry
,
rz
],
newdmin
)
assert
np
.
all
(
np
.
isclose
(
img
.
dataRange
,
(
newdmin
,
dmax
)))
notified
.
pop
(
'
data
'
)
assert
notified
.
get
(
'
data
'
,
False
)
notified
.
pop
(
'
dataRange
'
)
assert
notified
.
get
(
'
dataRange
'
,
False
)
assert
np
.
isclose
(
img
[
rx
,
ry
,
rz
],
newdmin
)
assert
np
.
all
(
np
.
isclose
(
img
.
dataRange
,
(
newdmin
,
dmax
)))
rx
,
ry
,
rz
=
randvox
(
)
notified
.
pop
(
'
data
'
)
img
[
rx
,
ry
,
rz
]
=
newdmax
notified
.
pop
(
'
dataRange
'
)
assert
notified
.
get
(
'
data
'
,
False
)
rx
,
ry
,
rz
=
randvox
()
assert
notified
.
get
(
'
dataRange
'
,
False
)
img
[
rx
,
ry
,
rz
]
=
newdmax
assert
np
.
isclose
(
img
[
rx
,
ry
,
rz
],
newdmax
)
assert
np
.
all
(
np
.
isclose
(
img
.
dataRange
,
(
newdmin
,
newdmax
)))
def
test_2D_images
(
testdir
):
assert
notified
.
get
(
'
data
'
,
False
)
assert
notified
.
get
(
'
dataRange
'
,
False
)
assert
np
.
isclose
(
img
[
rx
,
ry
,
rz
],
newdmax
)
assert
np
.
all
(
np
.
isclose
(
img
.
dataRange
,
(
newdmin
,
newdmax
)))
tests
=
[(
'
MNI152_T1_2mm_sliceXY.nii.gz
'
,
(
91
,
109
,
1
),
(
2.0
,
2.0
,
2.0
)),
finally
:
(
'
MNI152_T1_2mm_sliceXZ.nii.gz
'
,
(
91
,
1
,
91
),
(
2.0
,
2.0
,
2.0
)),
shutil
.
rmtree
(
testdir
)
(
'
MNI152_T1_2mm_sliceYZ.nii.gz
'
,
(
1
,
109
,
91
),
(
2.0
,
2.0
,
2.0
)),
(
'
MNI152_T1_2mm_sliceXY_4D.nii.gz
'
,
(
91
,
109
,
1
,
5
),
(
2.0
,
2.0
,
2.0
,
1.0
)),
# When you create an XY slice with
# fslroi, it sets nifti/dim0 to 2.
# This should still be read in as
# a 3D image.
(
'
MNI152_T1_2mm_sliceXY_bad_dim0.nii.gz
'
,
(
91
,
109
,
1
),
(
2.0
,
2.0
,
2.0
))]
for
fname
,
shape
,
pixdim
in
tests
:
def
test_Image_2D_analyze
():
_test_Image_2D
(
0
)
def
test_Image_2D_nifti1
():
_test_Image_2D
(
1
)
def
test_Image_2D_nifti2
():
_test_Image_2D
(
2
)
def
_test_Image_2D
(
imgtype
):
fname
=
op
.
join
(
testdir
,
'
nifti2D
'
,
fname
)
testdir
=
tempfile
.
mkdtemp
()
image
=
fslimage
.
Image
(
fname
)
# The first shape tests when the
assert
len
(
shape
)
==
len
(
image
.
shape
)
# nifti dim0 field is set to 2,
assert
len
(
shape
)
==
len
(
image
[:].
shape
)
# which happens when you create
assert
len
(
pixdim
)
==
len
(
image
.
pixdim
)
# an XY slice with fslroi. This
# should still be read in as a
# 3D image.
testdims
=
[(
10
,
20
),
(
10
,
20
,
1
),
(
10
,
1
,
20
),
(
1
,
10
,
20
),
(
10
,
20
,
1
,
5
),
(
10
,
1
,
20
,
5
),
(
1
,
10
,
20
,
5
)]
try
:
for
shape
in
testdims
:
pixdim
=
[
2
]
*
len
(
shape
)
imagefile
=
op
.
join
(
testdir
,
'
image
'
)
make_image
(
imagefile
,
imgtype
,
shape
,
pixdim
)
image
=
fslimage
.
Image
(
imagefile
)
# 2D should appear as 3D
if
len
(
shape
)
==
2
:
shape
=
list
(
shape
)
+
[
1
]
pixdim
=
list
(
pixdim
)
+
[
1
]
assert
len
(
shape
)
==
len
(
image
.
shape
)
assert
len
(
shape
)
==
len
(
image
[:].
shape
)
assert
len
(
pixdim
)
==
len
(
image
.
pixdim
)
assert
tuple
(
map
(
float
,
shape
))
==
tuple
(
map
(
float
,
image
.
shape
))
assert
tuple
(
map
(
float
,
shape
))
==
tuple
(
map
(
float
,
image
[:].
shape
))
assert
tuple
(
map
(
float
,
pixdim
))
==
tuple
(
map
(
float
,
image
.
pixdim
))
assert
tuple
(
map
(
float
,
shape
))
==
tuple
(
map
(
float
,
image
.
shape
))
finally
:
assert
tuple
(
map
(
float
,
shape
))
==
tuple
(
map
(
float
,
image
[:].
shape
))
shutil
.
rmtree
(
testdir
)
assert
tuple
(
map
(
float
,
pixdim
))
==
tuple
(
map
(
float
,
image
.
pixdim
))
This diff is collapsed.
Click to expand it.
tests/test_immv_imcp.py
+
16
−
5
View file @
9a99c71d
...
@@ -31,11 +31,22 @@ import fsl.data.image as fslimage
...
@@ -31,11 +31,22 @@ import fsl.data.image as fslimage
from
.
import
make_random_image
from
.
import
make_random_image
from
.
import
make_dummy_file
from
.
import
make_dummy_file
from
.
import
check_image_hash
from
.
import
looks_like_image
from
.
import
looks_like_image
from
.
import
cleardir
from
.
import
cleardir
def
makeImage
(
filename
):
return
hash
(
make_random_image
(
filename
).
get_data
().
tobytes
())
def
checkImageHash
(
filename
,
datahash
):
"""
Checks that the given NIFTI image matches the given hash.
"""
img
=
nib
.
load
(
filename
)
assert
hash
(
img
.
get_data
().
tobytes
())
==
datahash
def
checkFilesToExpect
(
files
,
outdir
,
outputType
,
datahashes
):
def
checkFilesToExpect
(
files
,
outdir
,
outputType
,
datahashes
):
exts
=
{
exts
=
{
...
@@ -91,7 +102,7 @@ def checkFilesToExpect(files, outdir, outputType, datahashes):
...
@@ -91,7 +102,7 @@ def checkFilesToExpect(files, outdir, outputType, datahashes):
else
:
else
:
h
=
datahashes
[
op
.
basename
(
f
)]
h
=
datahashes
[
op
.
basename
(
f
)]
check
_i
mage
_h
ash
(
f
,
h
)
check
I
mage
H
ash
(
f
,
h
)
def
test_imcp_script_shouldPass
(
move
=
False
):
def
test_imcp_script_shouldPass
(
move
=
False
):
...
@@ -308,7 +319,7 @@ def test_imcp_script_shouldPass(move=False):
...
@@ -308,7 +319,7 @@ def test_imcp_script_shouldPass(move=False):
print
(
'
files_to_expect:
'
,
files_to_expect
)
print
(
'
files_to_expect:
'
,
files_to_expect
)
for
i
,
fname
in
enumerate
(
files_to_create
.
split
()):
for
i
,
fname
in
enumerate
(
files_to_create
.
split
()):
imageHashes
.
append
(
make
_random_i
mage
(
op
.
join
(
indir
,
fname
)))
imageHashes
.
append
(
make
I
mage
(
op
.
join
(
indir
,
fname
)))
imcp_args
=
imcp_args
.
split
()
imcp_args
=
imcp_args
.
split
()
...
@@ -413,7 +424,7 @@ def test_imcp_script_shouldFail(move=False):
...
@@ -413,7 +424,7 @@ def test_imcp_script_shouldFail(move=False):
imcp_args
=
imcp_args
.
split
()
imcp_args
=
imcp_args
.
split
()
for
fname
in
files_to_create
:
for
fname
in
files_to_create
:
make
_random_i
mage
(
op
.
join
(
indir
,
fname
))
make
I
mage
(
op
.
join
(
indir
,
fname
))
imcp_args
[:
-
1
]
=
[
op
.
join
(
indir
,
a
)
for
a
in
imcp_args
[:
-
1
]]
imcp_args
[:
-
1
]
=
[
op
.
join
(
indir
,
a
)
for
a
in
imcp_args
[:
-
1
]]
imcp_args
[
-
1
]
=
op
.
join
(
outdir
,
imcp_args
[
-
1
])
imcp_args
[
-
1
]
=
op
.
join
(
outdir
,
imcp_args
[
-
1
])
...
@@ -609,7 +620,7 @@ def test_imcp_shouldPass(move=False):
...
@@ -609,7 +620,7 @@ def test_imcp_shouldPass(move=False):
hashes
=
{}
hashes
=
{}
for
fn
in
files_to_create
:
for
fn
in
files_to_create
:
if
looks_like_image
(
fn
):
if
looks_like_image
(
fn
):
hashes
[
fn
]
=
make
_random_i
mage
(
op
.
join
(
indir
,
fn
))
hashes
[
fn
]
=
make
I
mage
(
op
.
join
(
indir
,
fn
))
else
:
else
:
hashes
[
fn
]
=
make_dummy_file
(
op
.
join
(
indir
,
fn
))
hashes
[
fn
]
=
make_dummy_file
(
op
.
join
(
indir
,
fn
))
...
...
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