1414from .. import linear as nitl
1515from .utils import assert_affines_by_filename
1616
17- TESTS_BORDER_TOLERANCE = 0.05
17+ RMSE_TOL = 0.1
1818APPLY_LINEAR_CMD = {
1919 "fsl" : """\
2020 flirt -setbackground 0 -interp nearestneighbour -in {moving} -ref {reference} \
21- -applyxfm -init {transform} -out resampled.nii.gz \
21+ -applyxfm -init {transform} -out { resampled} \
2222 """ .format ,
2323 "itk" : """\
2424 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\
2626 """ .format ,
2727 "afni" : """\
2828 3dAllineate -base {reference} -input {moving} \
29- -prefix resampled.nii.gz -1Dmatrix_apply {transform} -final NN\
29+ -prefix { resampled} -1Dmatrix_apply {transform} -final NN\
3030 """ .format ,
3131 "fs" : """\
3232 mri_vol2vol --mov {moving} --targ {reference} --lta {transform} \
33- --o resampled.nii.gz --nearest""" .format ,
33+ --o { resampled} --nearest""" .format ,
3434}
3535
3636
@@ -121,13 +121,15 @@ def test_linear_save(tmpdir, data_path, get_testdata, image_orientation, sw_tool
121121 assert_affines_by_filename (xfm_fname1 , xfm_fname2 )
122122
123123
124- @pytest .mark .parametrize ("image_orientation" , ["RAS" , "LAS" , "LPS" ,]) # 'oblique',
124+ @pytest .mark .parametrize ("image_orientation" , ["RAS" , "LAS" , "LPS" , ]) # 'oblique',
125125@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 ):
127127 """Check implementation of exporting affines to formats."""
128128 tmpdir .chdir ()
129129
130130 img = get_testdata [image_orientation ]
131+ msk = get_testmask [image_orientation ]
132+
131133 # Generate test transform
132134 T = from_matvec (euler2mat (x = 0.9 , y = 0.001 , z = 0.001 ), [4.0 , 2.0 , - 1.0 ])
133135 xfm = nitl .Affine (T )
@@ -140,33 +142,60 @@ def test_apply_linear_transform(tmpdir, get_testdata, image_orientation, sw_tool
140142 ext = ".lta"
141143
142144 img .to_filename ("img.nii.gz" )
145+ msk .to_filename ("mask.nii.gz" )
146+
147+ # Write out transform file (software-dependent)
143148 xfm_fname = "M.%s%s" % (sw_tool , ext )
144149 xfm .to_filename (xfm_fname , fmt = sw_tool )
145150
146151 cmd = APPLY_LINEAR_CMD [sw_tool ](
147152 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" ),
150156 )
151157
152158 # skip test if command is not available on host
153159 exe = cmd .split (" " , 1 )[0 ]
154160 if not shutil .which (exe ):
155161 pytest .skip ("Command {} not found on host" .format (exe ))
156162
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+
157182 exit_code = check_call ([cmd ], shell = True )
158183 assert exit_code == 0
159184 sw_moved = nb .load ("resampled.nii.gz" )
185+ sw_moved .set_data_dtype (img .get_data_dtype ())
160186
161187 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+
163192 # 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
165194
166195 nt_moved = xfm .apply ("img.nii.gz" , order = 0 )
167196 diff = sw_moved .get_fdata () - nt_moved .get_fdata ()
168197 # 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
170199
171200
172201def test_Affine_to_x5 (tmpdir , testdata_path ):
0 commit comments