qsiprep icon indicating copy to clipboard operation
qsiprep copied to clipboard

b0 harmonization error if there is only one b0 image in a series

Open bermanj100 opened this issue 1 year ago • 1 comments

Summary

Incorrect b0 harmonization when there is only one b=0 image in a series. The reported mean of b0 is the mean of ALL volumes in a DWI series if there is only one b=0 in a series.

Additional details

  • QSIPrep version: 19.1 and current

What were you trying to do?

Run QSIPrep on a diffusion acquisition with two diffusion sequences. The first sequence contains one b=0 and multiple b=1000 volumes with phase encoding PA. The second sequence contains four b=0 volumes and multiple b-values up to 5000 with phase encoding AP. The sequences are matched on voxel size, TE, etc.

What did you expect to happen?

I expect the b0 harmonization to scale two series' intensities such that the b=0 intensities match. I expect this scaling to be very subtle since the raw b=0 volumes are inherently very similar in intensity.

What actually happened?

The harmonized dwi data contains b=0 volumes which differ greatly in intensity (a scaling factor of about 3). The result is incorrect FA maps, etc because the b=0 intensities (and DWI intensities) are not consistent across acquisition series.

Reproducing the bug

Please share any steps you performed that revealed the bug--> Please include any code snippets. Enclose them in triple back-ticks (```)

This error occurs if you have a diffusion series with one b=0 volume. The code below seems to have an error where if the number of b=0 volumes is 1, the b0_mean is the average of all dwi volumes (not just the b0 volumes). The error is most severe if you have mismatched diffusion series (like I do) where one series has one b=0 and the other has multiple b=0. With mismatched series, one series gets the mean of the b=0 volumes and the other series sets the mean of all the DWI volumes, producing a large scaling factor.

The error is suppressed by setting qsiprep to not perform b0 harmonization.

https://github.com/PennLINC/qsiprep/blob/36b93fe470272294b88069742f9fa1295bd69133/qsiprep/interfaces/dwi_merge.py#L690C1-L705C33

# Load the dwi data and get the mean values from the b=0 images
num_dwis = len(dwi_files)
dwi_niis = []
b0_means = []
for dwi_file, bval_file in zip(dwi_files, bvals):
    dwi_nii = load_img(dwi_file)
    _bvals = np.loadtxt(bval_file)
    b0_indices = np.flatnonzero(_bvals < b0_threshold)
    if b0_indices.size == 0:
        b0_mean = np.nan
    else:
        if len(b0_indices) > 1:
            b0_mean = index_img(dwi_nii, b0_indices).get_fdata().mean()
        else:
            b0_mean = dwi_nii.get_fdata().mean()
    b0_means.append(b0_mean)
    dwi_niis.append(dwi_nii)

bermanj100 avatar May 15 '24 13:05 bermanj100

Thanks for finding this @bermanj100! Should be a quick fix

mattcieslak avatar May 15 '24 18:05 mattcieslak