Small differences in affines and bvecs bewtween AP and PA scans crash qsiprep

Summary of what happened:

Hi all,

I have a question for the diffusion experts.

I acquire diffusion-weighted data from a Simens scanner using the Free diffusion mode and optimized gradient table from Emmanuel Caruyer’s tool. I acquire the dataset twice (in the HCP-like format), with reversed phase-encoding directions: AP and PA. The two scans immediately follow each other and I create a copy reference to ensure the images have the same orientation. I select the “center of slice groups and saturation regions” option for the copy reference.

However, when converting the dicoms to bids, the affines and bvecs don’t match exactly. The difference is quite small (to the 6th decimal point), so I assume it is due to some computational inaccuracy. This is an example of the differences between the affines:

array([[ 0.00000000e+00,  3.11993062e-08,  1.10827386e-07,
        -7.62939453e-06],
       [-2.11875886e-08,  0.00000000e+00,  0.00000000e+00,
         0.00000000e+00],
       [ 1.05239451e-07,  0.00000000e+00,  0.00000000e+00,
        -9.91821289e-05],
       [ 0.00000000e+00,  0.00000000e+00,  0.00000000e+00,
         0.00000000e+00]])

This causes a crash in qsiprep while merging the two datasets (raw_rpe_concat) because the image FOV is different.

As a quick and dirty solution, I manually match one of the dataset’s sform and qform with nibabel and overwrite the bvecs with the other dataset’s values in the bids directory.

Is there a better way to deal with this, either at the acquisition stage or during preprocessing?

I would appreciate any tips on this! Also, big thanks for your time and effort on this forum! It’s been the greatest learning resource so far :slight_smile:

Best,
Roman

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

qsiprep /input /output participant --output-resolution 1 --hmc-model eddy --eddy-config /config/eddy_params.json --fs-license-file /config/license.txt --pepolar-method TOPUP --denoise-method dwidenoise --unringing-method mrdegibbs --work-dir /output/work --nthreads 30 --skip-bids-validation --distortion-group-merge average

Version:

0.21.4

Environment (Docker, Singularity / Apptainer, custom installation):

Docker

Relevant log outputs (up to 20 lines):

Traceback:
	Traceback (most recent call last):
	  File "/opt/conda/envs/qsiprep/lib/python3.10/site-packages/nipype/interfaces/base/core.py", line 397, in run
	    runtime = self._run_interface(runtime)
	  File "/opt/conda/envs/qsiprep/lib/python3.10/site-packages/qsiprep/interfaces/nilearn.py", line 145, in _run_interface
	    new_nii = concat_imgs(self.inputs.in_files, dtype=self.inputs.dtype)
	  File "/opt/conda/envs/qsiprep/lib/python3.10/site-packages/nilearn/_utils/niimg_conversions.py", line 525, in concat_niimgs
	    for index, (size, niimg) in enumerate(
	  File "/opt/conda/envs/qsiprep/lib/python3.10/site-packages/nilearn/_utils/niimg_conversions.py", line 173, in _iter_check_niimg
	    raise ValueError(
	ValueError: Field of view of image #1 is different from reference FOV.
	Reference affine:
	array([[-1.04992306e+00, -7.69646838e-03, -1.05863577e-02,
         1.08450203e+02],
       [-3.13855452e-03,  9.66595292e-01, -4.29630697e-01,
        -7.62742691e+01],
       [-1.23085175e-02,  4.10041809e-01,  1.01257372e+00,
        -9.30755386e+01],
       [ 0.00000000e+00,  0.00000000e+00,  0.00000000e+00,
         1.00000000e+00]])
	Image affine:
	array([[-1.04992306e+00, -7.69649958e-03, -1.05864685e-02,
         1.08450211e+02],
       [-3.13853333e-03,  9.66595292e-01, -4.29630697e-01,
        -7.62742691e+01],
       [-1.23086227e-02,  4.10041809e-01,  1.01257372e+00,
        -9.30754395e+01],
       [ 0.00000000e+00,  0.00000000e+00,  0.00000000e+00,
         1.00000000e+00]])

Hi @romanbelenya, and welcome to neurostars!

Please see this thread which already addressed this: Different FOV errors - #2 by mattcieslak

I am not sure you want to be changing your bvec files though.

Best.
Steven

1 Like

Thanks for the tip, Steven!

Best,
Roman

Sorry for reopening this closed thread, but I’m encountering a similar issue. I acquired single-shell DWI data with 128 directions in both AP and PA directions on a Philips scanner, with the acquisitions immediately following each other.

It seems there is a small difference between the b-vectors. Below is an example from one participant:

AP PA
x y z x y z x diff y diff z diff
0 0 0 0 0 0 0 0 0
-0.00028 0.000131 1.000288 -0.00028 0.000131 1.000288 0 0 0
0.769656 -0.50027 0.39597 -0.77037 0.500765 0.39623 -0.000711 -0.0005 -0.00026
0.616577 0.691102 0.376127 -0.61676 -0.69092 0.376103 -0.000186 0.000182 2.4E-05
-0.12033 -0.95569 0.269041 0.119617 0.955592 0.268425 0.000708 9.8E-05 0.000616
-0.36998 0.801907 0.469132 0.369962 -0.80204 0.468715 2E-05 -0.000128 0.000417
-0.84353 -0.23851 0.480877 0.843801 0.238541 0.481666 -0.000273 -2.9E-05 -0.000789
0.349373 -0.9108 0.219853 -0.34923 0.910555 0.219653 0.000141 0.000243 0.0002
-0.48148 0.285396 0.82833 0.481892 -0.28501 0.828454 -0.000412 0.000384 -0.000124
-0.56945 -0.78282 0.251813 0.570341 0.782493 0.2515 -0.000887 0.000324 0.000313

I wanted to merge the two acquisitions in qsiprep using the --distortion-group-merge average flag. However, that crashes because of the difference in b-vectors.

The data processes fine without averaging, but having two sets of 128 directions that are nearly identical doesn’t seem optimal.

Is there any way to resolve this issue and salvage the data?

Thank you in advance for your help!