Issues with topup and eddy in qsiprep

Summary of what happened:

Hello qsiprep experts!

First of all, thanks for putting all this incredible pipeline together! I love it!!

I am trying to make it work for one of our datatsets and I am not sure I am setting this up correctly.
So, I slightly customized my eddy.param.json to run eddy_cuda.

{
  "flm": "quadratic",
  "slm": "linear",
  "fep": false,
  "interp": "spline",
  "nvoxhp": 1000,
  "fudge_factor": 10,
  "dont_sep_offs_move": false,
  "dont_peas": false,
  "method": "jac",
  "repol": true,
  "num_threads": 4,
  "is_shelled": true,
  "use_cuda": true,
  "cnr_maps": true,
  "residuals": true,
  "mporder": 27,
  "niter": 8,
  "estimate_move_by_susceptibility": true,
  "output_type": "NIFTI_GZ",
  "args": ""
}

and it looks like with this setting, qsiprep comes up with the following command:

eddy_cuda  \
--cnr_maps \
--field=/work/qsiprep_work/qsiprep_wf/single_subject_500_wf/dwi_preproc_ses_01_acq_PA_wf/hmc_sdc_wf/topup/fieldmap_HZ \
--field_mat=/work/qsiprep_work/qsiprep_wf/single_subject_500_wf/dwi_preproc_ses_01_acq_PA_wf/hmc_sdc_wf/topup_to_eddy_reg/topup_reg_image_flirt.mat --flm=quadratic \
--ff=10.0 \
--acqp=/work/qsiprep_work/qsiprep_wf/single_subject_500_wf/dwi_preproc_ses_01_acq_PA_wf/hmc_sdc_wf/gather_inputs/eddy_acqp.txt \
--bvals=/remote/iCARE/brainy/bids/sub-500/ses-01/dwi/sub-500_ses-01_acq-PA_dwi.bval \
--bvecs=/remote/iCARE/brainy/bids/sub-500/ses-01/dwi/sub-500_ses-01_acq-PA_dwi.bvec \
--imain=/work/qsiprep_work/qsiprep_wf/single_subject_500_wf/dwi_preproc_ses_01_acq_PA_wf/pre_hmc_wf/merge_and_denoise_wf/dwi_denoise_ses_01_acq_PA_dwi_wf/degibbser/sub-500_ses-01_acq-PA_dwi_denoised_mrdegibbs.nii.gz \
--index=/work/qsiprep_work/qsiprep_wf/single_subject_500_wf/dwi_preproc_ses_01_acq_PA_wf/hmc_sdc_wf/gather_inputs/eddy_index.txt \
--mask=/work/qsiprep_work/qsiprep_wf/single_subject_500_wf/dwi_preproc_ses_01_acq_PA_wf/hmc_sdc_wf/pre_eddy_b0_ref_wf/synthstrip_wf/mask_to_original_grid/topup_imain_corrected_avg_trans_mask_trans.nii.gz \
--interp=spline \
--data_is_shelled \
--resamp=jac \
--niter=5 \
--nvoxhp=1000 \
--out=/work/qsiprep_work/qsiprep_wf/single_subject_500_wf/dwi_preproc_ses_01_acq_PA_wf/hmc_sdc_wf/eddy/eddy_corrected \
--repol \
--residuals \
--slm=linear

where the eddy_acqp.txt is considering just the reversed b0 (but not the b0s in the dwi sequence… not even the 1st one):
0 1 0 0.059449
and eddy (eddy_index) is effectively using just the 1st b0 to correct for all volumes:

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

Now, qsiprep recognizes that I have multiple b0s interleaved in my dwi sequence, besides the epi/intended for b0:

|    ├── sub-500_ses-01_acq-AP_epi_b0-00.nii.gz
│   ├── sub-500_ses-01_acq-PA_dwi_b0-00.nii.gz
│   ├── sub-500_ses-01_acq-PA_dwi_b0-105.nii.gz
│   ├── sub-500_ses-01_acq-PA_dwi_b0-120.nii.gz
│   ├── sub-500_ses-01_acq-PA_dwi_b0-15.nii.gz
│   ├── sub-500_ses-01_acq-PA_dwi_b0-30.nii.gz
│   ├── sub-500_ses-01_acq-PA_dwi_b0-45.nii.gz
│   ├── sub-500_ses-01_acq-PA_dwi_b0-60.nii.gz
│   ├── sub-500_ses-01_acq-PA_dwi_b0-75.nii.gz
│   ├── sub-500_ses-01_acq-PA_dwi_b0-90.nii.gz

Yet, it decides to use just the 1st one, as per eddy_index.txt above.

Can anyone tell me what I am doing wrong in setting qsiprep up?
Also, is there a way for me to pass my “eddy_index.txt”, “eddy_acqp.txt” and “slspec” to qsiprep?

Thanks!!
Amelia

Command used:

singularity run \
--nv \
-B /mnt/resist/ \
/mnt/resist/singimages/qsiprep-stable.sif \
/mnt/resist/bids_data/ \
/mnt/resist/ \
participant \
--fs-license-file /mnt/resist/dpreproc/FS_license.txt \
--freesurfer-input /mnt/resist/preproc/sub-100/ses-01/anat/ \
--anat-modality T1w \
--anatomical-template MNI152NLin2009cAsym \
--output_resolution 1.7 \
--denoise_method dwidenoise \
 --unringing-method mrdegibbs \
--distortion-group-merge concat \
--hmc-model eddy \
--eddy-config /home/versacea22/qsiprep_eddy_params/eddy_params_resist.json \
--write-local-bvecs \
--nthreads 12 --omp_nthreads 12 \
-w /mnt/resist/dpreproc/ \
--write-graph \
--participant_label 100 \
--skip-bids-validation \
--stop-on-first-crash

Version:

version: 0.21.4

Env:

Singularity

Data formatted according to a validatable standard? Please provide the output of the validator:

PASTE VALIDATOR OUTPUT HERE

Relevant log outputs (up to 20 lines):

PASTE LOG OUTPUT HERE

Screenshots / relevant information:


Hi @A_V and welcome to neurostars!

In the future, please use the Software Support post category for questions like this, which prompt you for important information. You can see I edited your post to add it for you this time, but there is still information missing that you can edit your post to add.

What is this, your BIDS directory? If so, that doesn’t look BIDS valid.

Best,
Steven

Hi Steven,

Thanks for editing my post appropriately.

No, the b0s extraction is something that qsiprep did (in qsiprep_wf/single_subject_100_wf/dwi_preproc_ses_01_wf/hmc_sdc_wf/gather_inputs). I was just trying to understand the folds of the preprocessing.

This is what the bids data look like:

sub-100/
└── ses-01
    ├── anat
    │   ├── sub-100_ses-01_run-001_T1w.json
    │   └── sub-100_ses-01_run-001_T1w.nii.gz
    ├── dwi
    │   ├── sub-100_ses-01_dwi.bval
    │   ├── sub-100_ses-01_dwi.bvec
    │   ├── sub-100_ses-01_dwi.json
    │   └── sub-100_ses-01_dwi.nii.gz
    ├── fmap
    │   ├── sub-100_ses-01_acq-dMRIDistortionMap_dir-AP_epi.json
    │   ├── sub-100_ses-01_acq-dMRIDistortionMap_dir-AP_epi.nii.gz
    │   ├── sub-100_ses-01_acq-fMRIDistortionMap_dir-AP_epi.json
    │   ├── sub-100_ses-01_acq-fMRIDistortionMap_dir-AP_epi.nii.gz
    │   ├── sub-100_ses-01_acq-fMRIDistortionMap_dir-PA_epi.json
    │   └── sub-100_ses-01_acq-fMRIDistortionMap_dir-PA_epi.nii.gz
    ├── func
    │   ├── sub-100_ses-01_task-EDWM_run-001_bold.json
    │   ├── sub-100_ses-01_task-EDWM_run-001_bold.nii.gz
    │   ├── sub-100_ses-01_task-EDWM_run-001_events.tsv
    │   ├── sub-100_ses-01_task-EDWM_run-002_bold.json
    │   ├── sub-100_ses-01_task-EDWM_run-002_bold.nii.gz
    │   ├── sub-100_ses-01_task-EDWM_run-002_events.tsv
    │   ├── sub-100_ses-01_task-EDWM_run-003_bold.json
    │   ├── sub-100_ses-01_task-EDWM_run-003_bold.nii.gz
    │   ├── sub-100_ses-01_task-EDWM_run-003_events.tsv
    │   ├── sub-100_ses-01_task-EDWM_run-004_bold.json
    │   ├── sub-100_ses-01_task-EDWM_run-004_bold.nii.gz
    │   ├── sub-100_ses-01_task-EDWM_run-004_events.tsv
    │   ├── sub-100_ses-01_task-EDWM_run-005_bold.json
    │   ├── sub-100_ses-01_task-EDWM_run-005_bold.nii.gz
    │   ├── sub-100_ses-01_task-EDWM_run-005_events.tsv
    │   ├── sub-100_ses-01_task-emonback_run-001_bold.json
    │   ├── sub-100_ses-01_task-emonback_run-001_bold.nii.gz
    │   ├── sub-100_ses-01_task-emonback_run-001_events.tsv
    │   ├── sub-100_ses-01_task-emonback_run-002_bold.json
    │   ├── sub-100_ses-01_task-emonback_run-002_bold.nii.gz
    │   └── sub-100_ses-01_task-emonback_run-002_events.tsv
    └── sub-100_ses-01_scans.tsv

Hi @A_V,

What if you instead do not specify --hmc-model (which is default)? Then, according to the documentation:

If “none” the non-b0 images will be warped using the same transform as their nearest b0 image.

I also recommend adding -e to your singularity run command in general, to make sure no environment variables are being carried into the container by mistake.

And if you can update, do it, just to make sure there’s not a bug that’s already been addresed.

Best,
Steven