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.

In case it is of interest to my fellow masochistic individuals, this was resolved over at Runing dwifslpreproc in MRtrix version 3.0.8, an error occurs: mean_of_first_b0: Zero mean · Issue #3226 · MRtrix3/mrtrix3 · GitHub, and turned out to be a highly esoteric issue involving virtual machines and unformatted hard drives.