@@ -103,7 +103,6 @@ lib.app.gotoTempDir()
103103series_size = getHeaderInfo ('series.mif' , 'size' ).split ()
104104grad = getHeaderInfo ('series.mif' , 'dwgrad' ).split ('\n ' )
105105stride = getHeaderInfo ('series.mif' , 'stride' )
106- transform = getHeaderInfo ('series.mif' , 'transform' )
107106if PE_design == 'Pair' :
108107 Pair1_size = getHeaderInfo ('pair1.mif' , 'size' ).split ()
109108 Pair2_size = getHeaderInfo ('pair2.mif' , 'size' ).split ()
@@ -183,17 +182,17 @@ if not PE_design == 'None':
183182
184183# Convert the input files as necessary for FSL tools
185184if PE_design == 'None' :
186- runCommand ('mrconvert ' + series_path + ' dwi_pre_topup.nii -stride + 1,+2,+3,+4' )
185+ runCommand ('mrconvert ' + series_path + ' dwi_pre_topup.nii -stride - 1,+2,+3,+4' )
187186if PE_design == 'Pair' :
188- runCommand ('mrconvert ' + series_path + ' dwi_pre_topup.nii -stride + 1,+2,+3,+4' )
189- runCommand ('mrcat ' + pair1_path + ' ' + pair2_path + ' - -axis 3 | mrconvert - topup_in.nii -stride + 1,+2,+3,+4' )
187+ runCommand ('mrconvert ' + series_path + ' dwi_pre_topup.nii -stride - 1,+2,+3,+4' )
188+ runCommand ('mrcat ' + pair1_path + ' ' + pair2_path + ' - -axis 3 | mrconvert - topup_in.nii -stride - 1,+2,+3,+4' )
190189elif PE_design == 'All' :
191190 runCommand ('dwiextract ' + series_path + ' -bzero pair1.mif' )
192191 runCommand ('dwiextract ' + series2_path + ' -bzero pair2.mif' )
193- runCommand ('mrcat pair1.mif pair2.mif - -axis 3 | mrconvert - topup_in.nii -stride + 1,+2,+3,+4' )
194- runCommand ('mrconvert ' + series_path + ' dwi1_pre_topup.nii -stride + 1,+2,+3,+4' )
192+ runCommand ('mrcat pair1.mif pair2.mif - -axis 3 | mrconvert - topup_in.nii -stride - 1,+2,+3,+4' )
193+ runCommand ('mrconvert ' + series_path + ' dwi1_pre_topup.nii -stride - 1,+2,+3,+4' )
195194 delFile (series_path )
196- runCommand ('mrconvert ' + series2_path + ' dwi2_pre_topup.nii -stride + 1,+2,+3,+4' )
195+ runCommand ('mrconvert ' + series2_path + ' dwi2_pre_topup.nii -stride - 1,+2,+3,+4' )
197196 delFile (series2_path )
198197 runCommand ('mrcat dwi1_pre_topup.nii dwi2_pre_topup.nii dwi_pre_eddy.nii -axis 3' )
199198
@@ -249,8 +248,8 @@ eddy_in_topup = ''
249248if PE_design == 'None' :
250249
251250 # Generate a processing mask for eddy based on the input series
252- runCommand ('dwi2mask ' + series_path + ' - | maskfilter - dilate - | mrconvert - mask.nii -datatype float32 -stride + 1,+2,+3' )
253- runCommand ('mrconvert ' + series_path + ' - -stride + 1,+2,+3,+4 | mrinfo - -export_grad_fsl bvecs bvals' )
251+ runCommand ('dwi2mask ' + series_path + ' - | maskfilter - dilate - | mrconvert - mask.nii -datatype float32 -stride - 1,+2,+3' )
252+ runCommand ('mrconvert ' + series_path + ' - -stride - 1,+2,+3,+4 | mrinfo - -export_grad_fsl bvecs bvals' )
254253
255254else :
256255
@@ -276,7 +275,7 @@ else:
276275 # Create the diffusion gradient table in FSL format
277276 # Make sure the strides are identical to the image actually being passed to eddy before exporting the gradient table
278277 if PE_design == 'Pair' :
279- runCommand ('mrconvert ' + series_path + ' - -stride + 1,+2,+3,+4 | mrinfo - -export_grad_fsl bvecs bvals' )
278+ runCommand ('mrconvert ' + series_path + ' - -stride - 1,+2,+3,+4 | mrinfo - -export_grad_fsl bvecs bvals' )
280279 else :
281280 # Concatenate the diffusion gradient table twice
282281 with open ('grad.b' , 'w' ) as outfile :
@@ -288,7 +287,7 @@ else:
288287
289288
290289 # Use the initial corrected image series from applytopup to derive a processing mask for eddy
291- runCommand ('mrconvert dwi_post_topup' + fsl_suffix + ' -fslgrad bvecs bvals - | dwi2mask - - | maskfilter - dilate - | mrconvert - mask.nii -datatype float32 -stride + 1,+2,+3' )
290+ runCommand ('mrconvert dwi_post_topup' + fsl_suffix + ' -fslgrad bvecs bvals - | dwi2mask - - | maskfilter - dilate - | mrconvert - mask.nii -datatype float32 -stride - 1,+2,+3' )
292291
293292 eddy_in_topup = ' --topup=field'
294293
@@ -356,27 +355,36 @@ else: # 'All'
356355 bvals = bvals [0 :num_volumes ]
357356 with open ('bvals_combined' , 'w' ) as f :
358357 f .write (' ' .join (bvals ))
359-
360358
361- # Derive the weight images
362- # To properly get a voxel displacement field, need to scale the field map (which is output in Hz) appropriately
363- # Scaling appears to be correct; however FSL is a bit ambiguous when it comes to image transforms & strides
364- # Looks like topup flips the x-axis on output (both corrected images and field), and erases image transform
365- # Eddy seems to expect this and operates accordingly; but since we're doing things external to FSL and
366- # voxel-by-voxel, need to do the flip explicitly; also import the transform from the first input image
367- # for the sake of visualisation
368- with open ( 'transform.txt' , 'w' ) as f :
369- for line in transform :
370- f .write (line )
371- runCommand ('mrtransform field_map' + fsl_suffix + ' - -flip 0 -linear transform.txt -replace | mrconvert - field_map_flip.mif' + stride_option )
372- delFile ('field_map' + fsl_suffix )
359+ # Prior to 5.0.8, a bug resulted in the output field map image from topup having an identity transform,
360+ # regardless of the transform of the input image
361+ # Detect this, and manually replace the transform if necessary
362+ # (even if this doesn't cause an issue with the subsequent mrcalc command, it may in the future, it's better for
363+ # visualising the script temporary files, and it gives the user a warning about an out-of-date FSL)
364+ input_transform_text = getHeaderInfo ('topup_in.nii' , 'transform' )
365+ input_transform = [ float (f ) for f in input_transform_text .replace ('\n ' , ' ' ).replace (',' , ' ' ).split () ]
366+ topup_transform = [ float (f ) for f in getHeaderInfo ('field_map' + fsl_suffix , 'transform' ).replace ('\n ' , ' ' ).replace (',' , ' ' ).split () ]
367+ transform_error = False
368+ field_map_image = 'field_map' + fsl_suffix
369+ for i , t in zip (input_transform , topup_transform ):
370+ if (abs (i - t ) / (0.5 * (i + t ))) > 0.001 :
371+ transform_error = True
372+ if transform_error :
373+ warnMessage ('topup output field image has incorrect transform; recommend updating FSL to version 5.0.8 or later' )
374+ with open ( 'transform.txt' , 'w' ) as f :
375+ for line in input_transform_text :
376+ f .write (line )
377+ field_map_image = 'field_map_fix' + fsl_suffix
378+ runCommand ('mrtransform field_map' + fsl_suffix + ' -linear transform.txt -replace ' + field_map_image )
379+ delFile ('field_map' + fsl_suffix )
373380
374381
382+ # Derive the weight images
375383 # Scaling term for field map is identical to the bandwidth provided in the topup config file
376384 # (converts Hz to pixel count; that way a simple image gradient can be used to get the Jacobians)
377385 # Let mrfilter apply the default 1 voxel size gaussian smoothing filter before calculating the field gradient
378- runCommand ('mrcalc field_map_flip.mif 0.1 -mult - | mrfilter - gradient - | mrconvert - field_deriv_pe.mif -coord 3 1 -axes 0,1,2' )
379- delFile ('field_map_flip.mif' )
386+ runCommand ('mrcalc ' + field_map_image + ' 0.1 -mult - | mrfilter - gradient - | mrconvert - field_deriv_pe.mif -coord 3 1 -axes 0,1,2' )
387+ delFile (field_map_image )
380388 runCommand ('mrcalc 1.0 field_deriv_pe.mif -add 0.0 -max jacobian1.mif' )
381389 runCommand ('mrcalc 1.0 field_deriv_pe.mif -sub 0.0 -max jacobian2.mif' )
382390 delFile ('field_deriv_pe.mif' )
0 commit comments