This question might be a naive but here it is anyway.
We are converting some old datasets to BIDS. In this process we found that for some reason we have cases when the diffusion data is compelte (i.e., 70 volumes) but the bval/bvec data is incomplete (i.e., 65 entries). In one occasion, we have completely missing bval/bvec data. All the data we got are Nifti, although we had some dicom examples.
I was wondering if there is a way to impute the missing bvecs from the existing ones when they are incomplete, or perhaps impute the entire bval/bvec file when they are absent.
I thought this might be possible because my understanding is that the DWI directions inside the MRI sequence is always fixed, but we get different bvecs from subject to subject depending on the way the head is tilted. I don’t know if shimming plays a role in altering the true bvecs though. Hence the question: is it possible to use the data from a “good” subject to find out what the bvecs should be in a “corrupt” bvec file?
Thanks in advance for any explanation or tip on why this would or would not work.
1 Like
The answer depends on whether your data comes from a Siemens/Philips or GE scanner. GE gradients are applied in the scanner frame of reference, similar (but not identical to) FSL’s bvec image-space frame of reference. Therefore, the same GE sequence applied to different people should generate the same transform for all participants. In contrast, Siemens and Philips describe gradients in terms of the coordinates of the scanner bore. Therefore, you only get the same FSL bvecs if the image angulation is identical.
- Since you have some DICOM images, you can process some and extract the raw gradients. I think that dicm2nii stores the raw gradients by default. Alternatively, if you run dcm2niix with extra verbosity (e.g.
dcm2niix -v 2 /path/to/DICOMs
it will report these to the console.
- You will then want to determine the DICOM image orientation (0020,0037) for each series and transform your gradient vectors with the image orientation.
This assumes an identical gradient vector table (e.g. the same MRI sequence). Hopefully, all your series have the same approximate transforms, but you should be aware that FSL will mirror the image columns but not the bvecs’s to ensure a negative determinant. This is not intuitive and has caused a lot of confusion. While dcm2niix tries to infer all of this for you, the AFNI GradFlipTest provides a robust brute-force solution as long as your gradients are angulated correctly but have inverted signs.
2 Likes
Thanks @Chris_Rorden, this is great. The scanner is the same Siemens TrioTim from Monash University. From what you are saying, we should be able to use the default bore-centric gradients obtained from dcm2nii and transform them to the image orientation bvecs with the same siemensPhilipsCorrectBvecs
transforms. Pardon the ignorance on this, I don’t know if header (0020,0037) in dicom is put into nifti as well, is that the qform? All we have from the corrupt data is niftis, no dicoms. Many thanks again, and looking forward to meet again.
Dorian
@dorianps yes you can derive 0020,0037 from the affine spatial transform. I suspect your Siemens DICOMs are saved as mosaics, which will obfuscate this. This can also be dependent on how dcm2niix was set to flip the row order (DICOM files have the first row at the top of the screen, the way we write English. NIfTI has the first row at the bottom of the screen, the way we draw a Cartesian graph) and the spatial coordinates (in DICOM +X moves leftward, in NIfTI it moves rightward). The code below is the skeleton of a solution, you will want to set need to flip or rotate the matrix to resolve these issues. You can always test your solution on the data where you have both the DICOM and NIfTI to make sure you replicate the transformation correctly.
import numpy as np
import nibabel as nb
nii = nb.load('1.nii')
#assume axial slicing
x = nii.affine[0:3, 0]
y = nii.affine[0:3, 1]
nx = x / np.linalg.norm(x)
ny = y / np.linalg.norm(y)
#TODO flip from NIfTI to DICOM space, dcm2niix flip/mirror settings
print(" (0020,0037) = {:g}, {:g} {:g}, {:g} {:g}, {:g}".format( nx[0], nx[1], nx[2], ny[0], ny[1], ny[2]))
As an aside, I was surprised that available NIfTI to DICOM tools do not set the spatial rotation correctly. If you develop a good generalized solution you could always extend those projects.
Hi @Chris_Rorden , I am finding that m1.h.DTI_MGH_60Dir.bvec_original
from dicm2nii is different than what dcm2niix -v 2 /path/to/DICOMs
produces as DiffusionGradientDirection
. Why would that be ?
Also, even though the raw bvecs are different, the final output bvecs are identical from both softwares. Additionally, the output bvecs can be reproduced identically when siemensPhilipsCorrectBvecs
code is applied to m1.h.DTI_MGH_60Dir.bvec_original
.
The dicm2nii matrix bvec_original is in the coordinate system used by the manufacturer (e.g. relative to the Scanner bore if you are using a Siemens scanner), while the final bvec files are in FSL format, which uses the image space as the frame of reference (plus an odd requirement for the volume determinant). In addition, some manufacturers will adjust the b-vector length to encode the b-value, whereas FSL requires unit vectors. See the dcm2niix notes for your manufacturer for more details, e.g. Siemens. The role of function siemensPhilipsCorrectBvecs() is to transform the vector reported in the manufacturer’s format to the FSL format, e.g. rotating based on the image angulation relative to the scanner bore.
Thanks. What is then the format for the raw vectors reported as DiffusionGradientDirection
by dcm2niix (as opposed to “in the coordinate system used by the manufacturer”) ?
@ins0mniac I am not sure of the context for DiffusionGradientDirection
. Siemens does provide a tag named DiffusionGradientDirection
in their proprietary CSA header. These are described here and the frame of reference used by Siemens is with respect to the scanner bore, not the image space.
You may want to look at the NAMIC DT Wiki. You can also look at the dcm2niix manufacturer specific pages for Canon, GE, Philips and Siemens.
The public DICOM Tag DiffusionGradientOrientation (0018,9089) is defined with respect to the patient (e.g. in the world space of the scanner bore).