QSIprep: Slice loss in the preprocessed images?

Summary of what happened:

Dear experts,

I have preprocessed some participants’ DWIs using QSIprep, and I found the “DWI Bias correction” part of the report shows that there appears to be a slice loss in the denoised image. When opening sub-XXXX_space-T1w_desc-preproc_dwi.nii.gz, I still saw strange horizontal lines in all volumes. However, the original image was intact, so the lines were assumed to be generated during the QSIprep process.

Based on a comparison of reports from several samples, it seems that this slice loss-like line occurs in samples with a lot of head motion.
The screenshots of “subXXXX_final_denoise_wf_biascorr.svg” and “sub-XXXX_space-T1w_desc-preproc_dwi.nii.gz” of a sample with a lot of head motion and those of a sample with little head motion are attached.

Are such problems common in QSIprep? And should samples with such problems not be used for subsequent analysis? Or is there any way to prevent this problem?
I would be grateful for your advice.

Best,

Command used (and if a helper script was used, a link to the helper script or the command generated):

qsiprep-docker /bids_root_dir /output_dir participant --participant-label XXXX --output-resolution 2 --omp-nthreads 1 --skull-strip-fixed-seed --fs-license-file /home/freesurfer/7.3.2/license.txt -w /home/qsiprep --dwi_denoise_window auto --denoise-method dwidenoise --unringing-method mrdegibbs --hmc_model eddy --stop-on-first-crash --notrack --anat-modality T1w

Version:

qsiprep v0.19.1

Environment (Docker, Singularity, custom installation):

Docker

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

Yes, BIDS validator did not report any specific problems.

Screenshots / relevant information:




Hi @Printemps ,

Slice loss in DWI images due to severe head motions do happen, and they are generally visible in the raw data. Could you check in all raw data volumes if those slice loss are visible as well?
Besides, FSL eddy, which is called by QSIPREP for head motion correction and eddy current correction, does have a strategy to detect outliers slice-wise and is able to replace those outliers by eddy’s prediction if you ask for it. Another option of eddy is to correct for slice-to-volume movement that would also correct for these dark slices. In your call of QSIPREP, you are just calling for the default of QSIPREP’s call for eddy, where the option are listed here. As you can see "repol" is set to "true" , so outlier replacement is indeed activated. If you wanted to use the slice-to-volume motion correction, you would need to activate eddy_cuda and additional options such as the one listed is an example file below. You may then pass this file to use additional options by using the option --eddy-config FILE in your QSIPREP call and giving a FILE with additional options to eddy.

Personalized eddy_params.json:

{
  "flm": "quadratic",
  "slm": "linear",
  "fep": false,
  "interp": "spline",
  "nvoxhp": 1000,
  "fudge_factor": 10,
  "dont_sep_offs_move": false,
  "dont_peas": false,
  "niter": 5,
  "method": "jac",
  "repol": true,
  "num_threads": 1,
  "is_shelled": true,
  "use_cuda": true,
  "cnr_maps": true,
  "residuals": true,
  "output_type": "NIFTI_GZ",
  "estimate_move_by_susceptibility": true,
  "mporder": 8,
  "slice_order": "/work/GesteSigne/code/qsiprep/slspec.txt",
  "args": "--ol_nstd=5"
}

as you can see, there is also a reference to an additional file slspec.txt where the slice order of your acquisition is specified. An example of creation of this slspec file is given here.

Here are more details about this option in eddy for “outlier replacement” and “slice to volume motion correction”:
https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/eddy/UsersGuide#eddy_with_outlier_replacement

1 Like

Dear @jsein ,

Thank you for being so detailed!
I checked the raw data again, there are zig-zag patterns in a coronal and sagittal view like the example image on the page of FSLwiki you introduced (Our data is not as bad as this example, but the pattern is very similar). Therefore, it seems that slice-to-volume motion correction is necessary for our data.

We acquire the images using a PHILIPS scanner, so, unfortunately, slice timing couldn’t be obtained from a JSON file. I will try to create the slspec.txt after I calculate and confirm the slice timing with the engineer.

Also, I would like to ask you about the configuration file for --eddy-config. Other than the “slice order” part, is there any other part of the sample file you gave me that needs to be rewritten according to our data?

Best,

Yes, there are several options that you can use that are detailed here.

Dear @jsein ,

Thank you for the above advice about --eddy-config, and I’m sorry for my late reply.
I tried QSIprep with slice-to-volume correction as you introduced, but I received the error message below;

traits.trait_errors.TraitError: The ‘slice_order’ trait of an EddyInputSpec instance must be a string or os.PathLike object referring to an existing file, but a value of ‘/media/brain/kageyama/test/qsiprep_test2/code/slspec.txt’ <class ‘str’> was specified.

The slspec.txt seems to be correct, so I’m wondering how to deal with this problem.
I apologize for the basic questions, but I would appreciate it if you could provide any advice.

I attached copies of my QSIprep script, eddy_param.json, and slspec.txt.

Best regards,

qsiprep_test.txt (1.0 KB)
eddy_params.txt (496 Bytes)
slspec.txt (288 Bytes)

Hi @Printemps , I am not a user of qsiprep-docker but I guess that it is running qsiprep through docker? I don’t know how you could do that, but you need to check that your running docker container is really able to see: /media/brain/kageyama/test/qsiprep_test2/code/slspec.txt.
also, just to understand you changed the extension eddy_params.json into eddy_params.txt just for the upload in Neurostars?
Since the error mentioned an error involving slice_order, this means that qsiprep was able to read into eddy_params.json` .

Well, to be honest, I don’t really see what could be wrong here at the moment. It is very similar to what I do, and which works, except that I use singularity and not qsiprep-docker.

Hi again @Printemps ,

When looking at this page about qsiprep-docker, it looks like your local folder $bids_root_dir would be mounted as /data inside the docker container. If that is the case, the path you would need to specify to access the slspec.txt would be :

"slice_order": "/data/code/slspec.txt",

Try it with this change and let me know if that works for you!

Dear @jsein ,

Thank you for your reply.
I changed the specification of the slspec.txt as you taught, then it works!

However, I got another error which may be related to the execution of eddy as below.

240125-00:41:37,991 nipype.workflow WARNING:
[Node] Error on “qsiprep_wf.single_subject_F1098_wf.dwi_preproc_wf.hmc_sdc_wf.eddy” (/scratch/qsiprep_wf/single_subject_F1098_wf/dwi_preproc_wf/hmc_sdc_wf/eddy)

I tried the same process for several samples, then the above error was replicated across subjects.
Do you have any suggestions to solve this problem?
I attached a text file that copied the entire outputs around the error, and a log file for this process.

I understand if you’re busy, and I truly appreciate your assistance.

Kind regards,
error_Jan25.txt (13.6 KB)
crash-20240125-015923-root-eddy-28c1d0b8-5274-4bf2-b889-114bc89d51b6.txt (5.1 KB)

Are you planning on using CUDA on GPUs to accelerate eddy? The error is indicating that you are trying to use eddy_cuda but the CUDA libraries are not on your system (or not being found).

Best,
Steven

Dear @Steven,

Thank you for your comment.
Yes, I would like to use CUDA because slice-to-volume correction needs it.
I recently installed CUDA on Ubuntu 20.04, which I am using for this analysis.
So, it seems that somehow CUDA is not recognized when doing QSIprep…

Best,

Hi @Printemps,

You did not add the --gpus flag in qsiprep-docker (https://github.com/PennLINC/qsiprep/blob/eda84d5aae448a5522a67311ff6c6f108b94b3ef/wrapper/qsiprep_docker.py#L279), which is required for CUDA to work (equivalent of adding --gpus in docker run)

Best,
Steven

1 Like

Hi @Printemps,

I should also mention that there was a bug in previous versions where the CUDA libraries were not loaded in the container properly (nvidia/gpu issues with v0.19.0 · Issue #623 · PennLINC/qsiprep · GitHub). This is hopefully addressed in the most recent 0.20.0 release (you’ll still need the --gpus flag).

Best,
Steven

Dear @jsein ,

I haven’t been in touch for a while. Since I couldn’t perform ‘slice-to-volume correction’ using QSIPrep-docker as you previously advised, I decided to do it with FSL without going through QSIPrep. However, when I executed the following command, an error occurred. Do you have any idea about the cause of this error or how to resolve it?

Sincerely,

Code

eddy_cuda10.2 --imain=dir-AP_dwi_clipped.nii.gz --mask=b0_AP_brain_mask.nii.gz --acqp=../acqusition_parameters.txt --index=../eddy_index.txt --bvecs=../../../sub-N0001/dwi/sub-N0001_dir-AP_dwi.bvec --bvals=../../../sub-N0001/dwi/sub-N0001_dir-AP_dwi.bval --topup=topup_AP_PA_b0 --fwhm=0 --flm=quadratic --cnr_maps --repol --mporder=6 --slspec=../slspec.txt --s2v_niter=5 --s2v_lambda=1 --s2v_interp=trilinear --out=dir-AP_aftereddy.nii.gz

Error message

...................Allocated GPU # 0...................
Segmentation violation, Unknown reason, Offending address = (nil)
eddy_cuda10.2 EDDY::ReplacementManager::Update(EDDY::DiffStatsVector const&) [0x564d9b946dba]
*** buffer overflow detected ***: terminated

Hi @Printemps,

it looks like an error related to a lack of memory. I am not an expert on that kind of topic, but could you try the command: nvidia-smi to look at the status of your GPU ressources? If you don’t find other answer on neurostars, I advise you to ask this FSL-related issue on the FSL forum.

Dear @jsein

After much consideration, I decided to carry out preprocessing without qsiprep: the missing slices that would require slice-to-vol correction only occurred when using qsiprep and not when preprocessing with FSL alone.
Therefore I forget for the moment the above error regarding slice-to-voltage correction.
Thank you for your kind support!

Hi @Printemps , thanks for the update!
This is interesting: were you able to recover the missing slice pattern from the raw data with FSL preprocessing? Would you be willing to share the command you used? Thank you!