Use-syn-sdc not working for fmriprep 22.0.2


I’m trying to use fieldmap-free distortion correction in fmriprep, via the --use-syn-sdc flag, but it doesn’t seem to be working.

Has anyone come across a similar error? fmriprep output doesn’t raise any type of warning or error, as far as I can tell (the output is quite verbose, so I search for ‘distortion’ and ‘B0’ to check, but I also don’t get any other warnings or errors related to this issue).

I’m using fmriprep version 22.0.2 via singularity on a cluster.

My fmriprep command is…

singularity run --cleanenv \
 /u/project/CCN/apps/fmriprep/rh7/22.0.2/fmriprep-22.0.2.sif \
 /u/project/CCN/cparkins/data/ksah \
 /u/project/CCN/cparkins/data/ksah/derivatives \
 participant \
 -w $SCRATCH \
 --bids-filter-file /u/project/CCN/cparkins/data/ksah/code/ses-22wi2022_filter.json \
 --output-space T1w MNI152NLin2009cAsym \
 --ignore slicetiming \
 --use-syn-sdc \
 --fs-license-file /u/project/CCN/cparkins/data/fs_license.txt \
 --skip_bids_validation \
 --participant-label ${SUBJECTS[$SGE_TASK_ID]}

In case it matters, this code is part of a shell script that creates a job array for a list of subjects and submits each subject’s data to fmriprep as its own job.

Hi @jguassimoreira,

Some questions that would help us debug:

Does fMRIPrep finish, and if so, does the methods section of the HTML mention the SYN SDC method / include a SDC report?

Does this behavior persist on the most recent v23 stable release?

Is phase encoding direction defined for your BOLD files?

Are your data completely BIDS valid?


Thanks for the quick reply, Steven! My answers to your questions below…

Does fMRIPrep finish?
Yes, it finishes and does not report any errors. It does not mention the SYN SDC method in the method section. It explicitly states no SDC was applied in the preprocessing for each functional run.

v23 stable release behavior
Wouldn’t know, we only have the 22.0.2 .sif container file available to us at my institution :confused:

phase encoding direction
Yes: “j-”
In case it helps, data were converted using dcm2bids

completely BIDS valid
I’ll triple check this, but yes, they are.

I didn’t mention this before but it’s worth bringing up now, I guess – I do have fieldmaps for this dataset. fMRIPrep would process the field maps (indicated in the HTML output) but not use them for SDC. I have the ‘intended for’ field in their .json files filled out (tried it a couple different ways based on publicly available examples and other posts in this forum), but it still wasn’t working. So I’m trying to switch over to the SYN method.

You can try adding --force-syn to the command.

It appears you have singularity installed, is there any reason you cannot install your own container with singularity build fmriprep_23.1.4.sig docker://nipreps/fmriprep:23.1.4?

In the JSON is it explicitly defined under the field called PhaseEncodingDirection? This would really be more of a factor of the dcm2niix version, not dcm2bids (although I imagine any version of dcm2niix released in the past 5 years shouldn’t be messing this simple field up). dcm2niix, especially older versions, can be weird on GE scanners - does that apply to you?

I believe IntendedFor errors are included in the BIDS validation report, so sharing that report would be helpful. If fieldmaps are present, they will be favored ahead of SDC unless if --force-syn is on. So I wonder if fMRIPrep wants to use the fieldmaps, for some reason can’t, so is instead not doing any SDC.

Are your fieldmaps GRE or SE? GRE fieldmaps have been a bit hit-or-miss since v21, but work well in the long-term support branch (20.2.7). SE should work fine (in fact, better), on v23.


Do you have total readout time defined? There are several ways to calculate it, but at least one of them needs to succeed: sdcflows.utils.epimanip module - sdcflows 2.5.2.dev86+g3e318c52 documentation

It’s not obvious why that’s needed for SyN-SDC, which calculates displacements directly, but the reason is that we go a step further and estimate the fieldmap from the displacments, which requires a readout vector. We could just make up a number, but then we would need to be sure to be able to determine what that number was when applying the fieldmap.

Assuming this is the problem, you can just stick in a fake TotalReadoutTime. 0.03125 is a power of two that’s conveniently close to a plausible readout time. But you should definitely make a note somewhere that this is fake and no algorithms that require a true value should rely on this.