Runing dwifslpreproc in MRtrix version 3.0.8, an error occurs: mean_of_first_b0: Zero mean

Hi everyone,

I am currently using the latest version of MRtrix (3.0.8) with FSL software version 6.0.7.18 to process my single-phase encoding direction (AP, j-) data, which only has two b-values (b=0 and b=1000). I am currently using Synb0-DISCO to synthesize undistorted b0, but when running the dwifslpreproc command, I receive the error message: EDDY::ECScanManager::mean_of_first_b0: Zero mean

Here I provide all my data information and operational procedures, as everyone can identify and point out where my issues lie. Thank you.

  1. mrinfo dwi.mif
$ mrinfo dwi.mif 
************************************************
Image name:          "dwi.mif"
************************************************
  Dimensions:        128 x 128 x 78 x 67
  Voxel size:        2 x 2 x 2 x 8.5
  Data strides:      [ -1 2 3 4 ]
  Format:            MRtrix
  Data type:         signed 16 bit integer (little endian)
  Intensity scaling: offset = 0, multiplier = 1
  Transform:               0.9904      0.1181     0.07228      -147.2
                          -0.1179       0.993   -0.007124      -130.6
                         -0.07261   -0.001465      0.9974      -38.42
  command_history:   mrconvert -fslgrad sub-0001_dwi.bvec sub-0001_dwi.bval sub-0001_dwi.nii.gz dwi.mif -force  (version=3.0.8)
  comments:          TE=76;Time=143330.160;phase=1;mb=2
  dw_scheme:         0,0,0,0
  [67 entries]       0.9999874756,-2.53474669e-07,-0.005004869305,1000
                     ...
                     0,0,0,0
                     0,0,0,0
  mrtrix_version:    3.0.8

b=0 is only three volume, i.e., volume=0, 66, 67
  1. dwidenoise and mrdegibbs
$ dwidenoise dwi.mif denoise.mif -noise noiselevel.mif
$ mrdegibbs denoise.mif degibbs.mif
  1. Extract the mean of b0, and prepare to collect parameter files
$ dwiextract degibbs.mif -bzero - | mrmath - mean b0.nii.gz -axis 3
# acqparams.txt
0 -1 0 0.0476258
0 1 0 0
  1. performing Synb0-DISCO
$ docker run --rm --memory 30g --memory-swap 30g -v f:/ubuntuShare/sub-0001_T1w.nii.gz:/INPUTS/T1.nii.gz -v f:/ubuntuShare/b0.nii.gz:/INPUTS/b0.nii.gz -v f:/ubuntuShare/acqparams.txt:/INPUTS/acqparams.txt -v f:/ubuntuShare/outputs:/OUTPUTS/ -v e:/neurodesk/neurodesktop-storage/fs_license.txt:/extra/freesurfer/license.txt --user=root leonyichencai/synb0-disco:v3.1 --notopup 
  1. According to the GitHub issue, since the --notopup parameter was set, the two files (b0_d_smooth.nii.gz and b0_u.nii.gz) need to be merged manually. b0_d_smooth.nii.gz是
$ fslmerge -t b0_all.nii.gz b0_d_smooth.nii.gz b0_u.nii.gz && mrconvert b0_all.nii.gz b0_all.mif
$ mrstats b0_all.mif 
      volume       mean     median        std        min        max      count
       [ 0 ]    30.4446 5.53821e-05    84.7638  -0.793208    1936.44    1277952
       [ 1 ]    30.5626          0    77.3111   -1.42679    751.177    1277952
  1. performing dwifslpreproc
dwifslpreproc degibbs.mif distcorr.mif -pe_dir AP -rpe_pair -se_epi b0_all.mif -eddy_options " --data_is_shelled --slm=linear --niter=5 "

I received the following error message output:

dwifslpreproc: 
dwifslpreproc: Note that this script makes use of commands / algorithms that have relevant articles for citation; INCLUDING FROM EXTERNAL SOFTWARE PACKAGES. Please consult the help page (-help option) for more information.
dwifslpreproc: 
dwifslpreproc: Generated scratch directory: /home/xxxx/share/dwifslpreproc-tmp-TLBFZ2/
Command:  mrconvert /home/xxxx/share/degibbs.mif /home/xxxx/share/dwifslpreproc-tmp-TLBFZ2/dwi.mif -json_export /home/xxxx/share/dwifslpreproc-tmp-TLBFZ2/dwi.json
Command:  mrconvert /home/xxxx/share/b0_all.mif /home/xxxx/share/dwifslpreproc-tmp-TLBFZ2/se_epi.mif
dwifslpreproc: Changing to scratch directory (/home/xxxx/share/dwifslpreproc-tmp-TLBFZ2/)
Command:  mrinfo dwi.mif -export_grad_mrtrix grad.b
Command:  mrconvert se_epi.mif topup_in.nii -import_pe_table se_epi_manual_pe_scheme.txt -strides -1,+2,+3,+4 -export_pe_topup topup_datain.txt
Command:  topup --imain=topup_in.nii --datain=topup_datain.txt --out=field --fout=field_map.nii.gz --config=/home/xxxx/fsl/etc/flirtsch/b02b0.cnf --verbose
Command:  mrconvert dwi.mif applytopup_in.nii -import_pe_table dwi_manual_pe_scheme.txt -strides -1,+2,+3,+4 -export_pe_eddy applytopup_config.txt applytopup_indices.txt -export_grad_fsl applytopup_in.bvec applytopup_in.bval -json_export applytopup_in.json
Command:  mrconvert applytopup_in.nii applytopup_in_pe1.nii -json_import applytopup_in.json -fslgrad applytopup_in.bvec applytopup_in.bval -coord 3 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66 -strides -1,+2,+3,+4 -json_export applytopup_in_pe1.json -export_grad_fsl applytopup_in_pe1.bvec applytopup_in_pe1.bval
Command:  applytopup --imain=applytopup_in_pe1.nii --datain=applytopup_config.txt --inindex=1 --topup=field --out=applytopup_in_pe1_applytopup.nii --method=jac
Command:  mrconvert applytopup_in_pe1_applytopup.nii.gz applytopup_in_pe1_applytopup.mif -json_import applytopup_in_pe1.json -fslgrad applytopup_in_pe1.bvec applytopup_in_pe1.bval
Command:  dwi2mask applytopup_in_pe1_applytopup.mif - | maskfilter - dilate - | mrconvert - eddy_mask.nii -datatype float32 -strides -1,+2,+3
Command:  mrconvert dwi.mif -import_pe_table dwi_manual_pe_scheme.txt eddy_in.nii -strides -1,+2,+3,+4 -export_grad_fsl bvecs bvals -export_pe_eddy eddy_config.txt eddy_indices.txt
Command:  eddy_cuda11.0 --imain=eddy_in.nii --mask=eddy_mask.nii --acqp=eddy_config.txt --index=eddy_indices.txt --bvecs=bvecs --bvals=bvals --topup=field --data_is_shelled --slm=linear --niter=5 --out=dwi_post_eddy --verbose
dwifslpreproc: CUDA version of 'eddy' was not successful; attempting OpenMP version
Command:  eddy_cpu --imain=eddy_in.nii --mask=eddy_mask.nii --acqp=eddy_config.txt --index=eddy_indices.txt --bvecs=bvecs --bvals=bvals --topup=field --data_is_shelled --slm=linear --niter=5 --out=dwi_post_eddy --verbose

dwifslpreproc: [ERROR] eddy* --imain=eddy_in.nii --mask=eddy_mask.nii --acqp=eddy_config.txt --index=eddy_indices.txt --bvecs=bvecs --bvals=bvals --topup=field --data_is_shelled --slm=linear --niter=5 --out=dwi_post_eddy --verbose (app.py:199)
dwifslpreproc: [ERROR] Information from failed command:
dwifslpreproc:
               =============
               eddy_cuda11.0
               =============
               
               Warning: In a future release the first argument will have to be "diffusion" when using eddy on diffusion data, i.e.
               eddy diffusion --imain='my_ima' --acqp='my_acqp' ...
               
               Warning: Writing of individual text files will be discontinued in favour of a single .json file in future versions
               
               Reading images
               EDDY::ECScanManager::mean_of_first_b0: Zero mean
               EDDY::ECScanClasses.cpp:::  double EDDY::ECScanManager::mean_of_first_b0(const NEWIMAGE::volume<float>&, const NEWIMAGE::volume<float>&, const Matrix&, const Matrix&) const:  Exception thrown
               EDDY::: Eddy failed with message EDDY::ECScanClasses.cpp:::  EDDY::ECScanManager::ECScanManager(const string&, const string&, const string&, const string&, const string&, const string&, const string&, const string&, const string&, double, double, EDDY::ECModelType, EDDY::ECModelType, EDDY::LongECModelType, const std::vector<unsigned int>&, const std::vector<unsigned int>&, const EDDY::PolationPara&, EDDY::MultiBandGroups, bool):  Exception thrown
               
               
               ========
               eddy_cpu
               ========
               
               Warning: In a future release the first argument will have to be "diffusion" when using eddy on diffusion data, i.e.
               eddy diffusion --imain='my_ima' --acqp='my_acqp' ...
               
               Warning: Writing of individual text files will be discontinued in favour of a single .json file in future versions
               
               Reading images
               EDDY::ECScanManager::mean_of_first_b0: Zero mean
               EDDY::ECScanClasses.cpp:::  double EDDY::ECScanManager::mean_of_first_b0(const NEWIMAGE::volume<float>&, const NEWIMAGE::volume<float>&, const NEWMAT::Matrix&, const NEWMAT::Matrix&) const:  Exception thrown
               EDDY::: Eddy failed with message EDDY::ECScanClasses.cpp:::  EDDY::ECScanManager::ECScanManager(const std::string&, const std::string&, const std::string&, const std::string&, const std::string&, const std::string&, const std::string&, const std::string&, const std::string&, double, double, EDDY::ECModelType, EDDY::ECModelType, EDDY::LongECModelType, const std::vector<unsigned int>&, const std::vector<unsigned int>&, const EDDY::PolationPara&, EDDY::MultiBandGroups, bool):  Exception thrown
               
               
               =============
               eddy_cuda11.0
               =============
               ERROR:: Empty mask image
               
               
               ========
               eddy_cpu
               ========
               ERROR:: Empty mask image
               
               
dwifslpreproc:
dwifslpreproc: [ERROR] For debugging, inspect contents of scratch directory: /home/xxxx/share/dwifslpreproc-tmp-TLBFZ2/
dwifslpreproc: Scratch directory retained; location: /home/xxxx/share/dwifslpreproc-tmp-TLBFZ2/

I also attempted to manually execute all commands in dwifslpreproc one by one and discovered the following issues:

  1. dwi_manual_pe_scheme.txt
0 -1 0 0.0476258
0 -1 0 0.0476258
0 -1 0 0.0476258
0 -1 0 0.0476258
0 -1 0 0.0476258
...... 
There are 63 more identical lines, totaling 68 lines.
  1. se_epi_manual_pe_scheme.txt and topup_datain.txt
0 -1 0 0.0476
0 1 0 0.0476

when performing topup, output

$ topup --imain=topup_in.nii --datain=topup_datain.txt --out=field --fout=field_map.nii.gz --config=/home/xxxx/fsl/etc/flirtsch/b02b0.cnf --verbose

SSD = -nan	n = 146816	Reg = -nan	Cost = -nan
SSD = -nan	n = 146816	Reg = -nan	Cost = -nan
SSD = -nan	n = 146816	Reg = -nan	Cost = -nan
SSD = -nan	n = 146816	Reg = -nan	Cost = -nan
SSD = -nan	n = 146816	Reg = -nan	Cost = -nan
SSD = -nan	n = 146816	Reg = -nan	Cost = -nan
SSD = -nan	n = 146816	Reg = -nan	Cost = -nan
SSD = -nan	n = 146816	Reg = -nan	Cost = -nan
SSD = -nan	n = 146816	Reg = -nan	Cost = -nan
SSD = -nan	n = 146816	Reg = -nan	Cost = -nan
SSD = -nan	n = 146816	Reg = -nan	Cost = -nan

The final field_fieldcoef.nii.gz and field_map.nii.gz files are empty, and field_movpar.txt contains:

0  0  0  0  0  0  
0  0  0  0  0  0  

Therefore, I suspect there is an issue with the topup process. I’m not sure if this is caused by the dwi_manual_pe_scheme.txt and topup_datain.txt files automatically generated after executing the dwifslpreproc command. When I manually ran each command within dwifslpreproc, these files weren’t generated automatically. Therefore, I copied them directly from the temporary directory of a previous failed run.

At the same time, I also attempted to run topup on Synb0-DISCO first, but I found that the topup_fieldcoef.nii.gz file generated by Synb0-DISCO was not empty. Furthermore, the contents of topup_movpar.txt are as follows:

0  0  0  0  0  0  
-0.04493781506  0  -0.01307249765  0.001978314033  -0.0006216608082  0.000977341481  

I also attempted testing with the public dataset OpenNeuro, which provides PA phases b=0, 1000, 2000 and AP phases b=0, 1000. When executing dwifslpreproc, the same error occurs also. Below is the code for the entire workflow.

$ mrconvert -fslgrad *104_dwi.bvec *104_dwi.bval *104_dwi.nii.gz dwi1000AP.mif
mrconvert: [100%] uncompressing image "sub-cIIIs01_ses-s1Bx1_acq-b1000n3r21x21x22peAPA_run-104_dwi.nii.gz"
mrconvert: [100%] copying from "sub-cIIIs0...x22peAPA_run-104_dwi.nii.gz" to "dwi1000AP.mif"
$ mrconvert -fslgrad *103_dwi.bvec *103_dwi.bval *103_dwi.nii.gz dwi2000PA.mif
mrconvert: [100%] uncompressing image "sub-cIIIs01_ses-s1Bx1_acq-b2000n56r21x21x22peAPP_run-103_dwi.nii.gz"
mrconvert: [100%] copying from "sub-cIIIs0...x22peAPP_run-103_dwi.nii.gz" to "dwi2000PA.mif"
$ mrconvert -fslgrad *311_dwi.bvec *311_dwi.bval *311_dwi.nii.gz dwi1000PA.mif
mrconvert: [100%] uncompressing image "sub-cIIIs01_ses-s1Bx1_acq-b1000n40r21x21x22peAPP_run-311_dwi.nii.gz"
mrconvert: [100%] copying from "sub-cIIIs0...x22peAPP_run-311_dwi.nii.gz" to "dwi1000PA.mif"
$  mrcat dwi1000PA.mif dwi2000PA.mif dwi.mif
$ dwi2mask dwi.mif - | maskfilter - dilate preproc_mask.mif -npass 3
$ dwidenoise dwi.mif denoise.mif -noise noiselevel.mif -mask preproc_mask.mif
dwidenoise: [100%] preloading data for "dwi.mif"
dwidenoise: [100%] running MP-PCA denoising
mrdegibbs denoise.mif degibbs.mif
$ dwiextract dwi1000AP.mif b0_AP.mif -bzero
$ dwiextract dwi1000PA.mif - -bzero | mrconvert - -coord 3 0 b0_PA.mif
$ mrcat b0_PA.mif b0_AP.mif b0_pair.mif
dwifslpreproc degibbs.mif distcorr.mif -pe_dir PA -rpe_pair -se_epi b0_pair.mif -eddy_options " --data_is_shelled --slm=linear --niter=5 "

And in the previous MRtrix3 version (3.0.7), at least I was able to successfully execute dwifslpreproc using the above command. However, a recent bug has emerged where the import_pe_table option in mrconvert se_epi.mif topup_in.nii -import_pe_table fails to recognize the parameter, forcing me to update MRtrix to 3.0.8. Therefore, I suspect that another new MRtrix bug is preventing the correct output from being generated during the topup process.