14
14
from .. import linear as nitl
15
15
from .utils import assert_affines_by_filename
16
16
17
- TESTS_BORDER_TOLERANCE = 0.05
17
+ RMSE_TOL = 0.1
18
18
APPLY_LINEAR_CMD = {
19
19
"fsl" : """\
20
20
flirt -setbackground 0 -interp nearestneighbour -in {moving} -ref {reference} \
21
- -applyxfm -init {transform} -out resampled.nii.gz \
21
+ -applyxfm -init {transform} -out { resampled} \
22
22
""" .format ,
23
23
"itk" : """\
24
24
antsApplyTransforms -d 3 -r {reference} -i {moving} \
25
- -o resampled.nii.gz -n NearestNeighbor -t {transform} --float\
25
+ -o { resampled} -n NearestNeighbor -t {transform} --float\
26
26
""" .format ,
27
27
"afni" : """\
28
28
3dAllineate -base {reference} -input {moving} \
29
- -prefix resampled.nii.gz -1Dmatrix_apply {transform} -final NN\
29
+ -prefix { resampled} -1Dmatrix_apply {transform} -final NN\
30
30
""" .format ,
31
31
"fs" : """\
32
32
mri_vol2vol --mov {moving} --targ {reference} --lta {transform} \
33
- --o resampled.nii.gz --nearest""" .format ,
33
+ --o { resampled} --nearest""" .format ,
34
34
}
35
35
36
36
@@ -121,13 +121,15 @@ def test_linear_save(tmpdir, data_path, get_testdata, image_orientation, sw_tool
121
121
assert_affines_by_filename (xfm_fname1 , xfm_fname2 )
122
122
123
123
124
- @pytest .mark .parametrize ("image_orientation" , ["RAS" , "LAS" , "LPS" ,]) # 'oblique',
124
+ @pytest .mark .parametrize ("image_orientation" , ["RAS" , "LAS" , "LPS" , ]) # 'oblique',
125
125
@pytest .mark .parametrize ("sw_tool" , ["itk" , "fsl" , "afni" , "fs" ])
126
- def test_apply_linear_transform (tmpdir , get_testdata , image_orientation , sw_tool ):
126
+ def test_apply_linear_transform (tmpdir , get_testdata , get_testmask , image_orientation , sw_tool ):
127
127
"""Check implementation of exporting affines to formats."""
128
128
tmpdir .chdir ()
129
129
130
130
img = get_testdata [image_orientation ]
131
+ msk = get_testmask [image_orientation ]
132
+
131
133
# Generate test transform
132
134
T = from_matvec (euler2mat (x = 0.9 , y = 0.001 , z = 0.001 ), [4.0 , 2.0 , - 1.0 ])
133
135
xfm = nitl .Affine (T )
@@ -140,33 +142,60 @@ def test_apply_linear_transform(tmpdir, get_testdata, image_orientation, sw_tool
140
142
ext = ".lta"
141
143
142
144
img .to_filename ("img.nii.gz" )
145
+ msk .to_filename ("mask.nii.gz" )
146
+
147
+ # Write out transform file (software-dependent)
143
148
xfm_fname = "M.%s%s" % (sw_tool , ext )
144
149
xfm .to_filename (xfm_fname , fmt = sw_tool )
145
150
146
151
cmd = APPLY_LINEAR_CMD [sw_tool ](
147
152
transform = os .path .abspath (xfm_fname ),
148
- reference = os .path .abspath ("img.nii.gz" ),
149
- moving = os .path .abspath ("img.nii.gz" ),
153
+ reference = os .path .abspath ("mask.nii.gz" ),
154
+ moving = os .path .abspath ("mask.nii.gz" ),
155
+ resampled = os .path .abspath ("resampled_brainmask.nii.gz" ),
150
156
)
151
157
152
158
# skip test if command is not available on host
153
159
exe = cmd .split (" " , 1 )[0 ]
154
160
if not shutil .which (exe ):
155
161
pytest .skip ("Command {} not found on host" .format (exe ))
156
162
163
+ # resample mask
164
+ exit_code = check_call ([cmd ], shell = True )
165
+ assert exit_code == 0
166
+ sw_moved_mask = nb .load ("resampled_brainmask.nii.gz" )
167
+ nt_moved_mask = xfm .apply (msk , order = 0 )
168
+ nt_moved_mask .set_data_dtype (msk .get_data_dtype ())
169
+ diff = np .asanyarray (sw_moved_mask .dataobj ) - np .asanyarray (nt_moved_mask .dataobj )
170
+
171
+ assert np .sqrt ((diff ** 2 ).mean ()) < RMSE_TOL
172
+
173
+ cmd = APPLY_LINEAR_CMD [sw_tool ](
174
+ transform = os .path .abspath (xfm_fname ),
175
+ reference = os .path .abspath ("img.nii.gz" ),
176
+ moving = os .path .abspath ("img.nii.gz" ),
177
+ resampled = os .path .abspath ("resampled.nii.gz" ),
178
+ )
179
+
180
+ brainmask = np .asanyarray (nt_moved_mask .dataobj , dtype = bool )
181
+
157
182
exit_code = check_call ([cmd ], shell = True )
158
183
assert exit_code == 0
159
184
sw_moved = nb .load ("resampled.nii.gz" )
185
+ sw_moved .set_data_dtype (img .get_data_dtype ())
160
186
161
187
nt_moved = xfm .apply (img , order = 0 )
162
- diff = sw_moved .get_fdata () - nt_moved .get_fdata ()
188
+ diff = (sw_moved .get_fdata () - nt_moved .get_fdata ())
189
+ diff [~ brainmask ] = 0.0
190
+ diff [np .abs (diff ) < 1e-3 ] = 0
191
+
163
192
# A certain tolerance is necessary because of resampling at borders
164
- assert ( np .abs ( diff ) > 1e-3 ). sum () / diff . size < TESTS_BORDER_TOLERANCE
193
+ assert np .sqrt (( diff ** 2 ). mean ()) < RMSE_TOL
165
194
166
195
nt_moved = xfm .apply ("img.nii.gz" , order = 0 )
167
196
diff = sw_moved .get_fdata () - nt_moved .get_fdata ()
168
197
# A certain tolerance is necessary because of resampling at borders
169
- assert ( np .abs ( diff ) > 1e-3 ). sum () / diff . size < TESTS_BORDER_TOLERANCE
198
+ assert np .sqrt (( diff [ brainmask ] ** 2 ). mean ()) < RMSE_TOL
170
199
171
200
172
201
def test_Affine_to_x5 (tmpdir , testdata_path ):
0 commit comments