Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

All bvals are same #245

Closed
tashrifbillah opened this issue Nov 7, 2018 · 17 comments
Closed

All bvals are same #245

tashrifbillah opened this issue Nov 7, 2018 · 17 comments

Comments

@tashrifbillah
Copy link
Contributor

Did anyone experience this issue where output bvecs don't have unity magnitude but all the bvals have the same magnitude?

Having the above conflicts with fsl dtifit because it normalizes all bvecs to 1 and then multiplies by whatever is present in the bvals. That means, the data are not parsed correctly down the pipeline.

@neurolabusc
Copy link
Collaborator

This sounds very unusual. Can you confirm the version of dcm2niix you are using (e.g. v1.0.20181105) and the vendor that generated your images - GE, Siemens and Philips all use different ways of encoding DTI, but all should report bvals in s/mm2. If your data is really multi-shell, the b-values should vary across your images.

Ideally, you could provide a sample of the raw DICOM data, but failing that you could provide the DICOM header for one of the DWI images (e.g. something like dcmdump dwi.dcm > tags.txt).

@tashrifbillah
Copy link
Contributor Author

tashrifbillah commented Nov 8, 2018

Okay, the progress so far: I built the version you suggested. Now, it appears that bvals are obtained as follows:

bval= norm(bvec)^2 * max(bval)

Shouldn't it be multiplied by just norm(bvec) ?

Or are you following the FSL convention and outputting in square units?

b values (bvals): An ASCII text file containing a list of b values applied during each volume acquisition. The b values are assumed to be in s/mm^2 units. The order of entries in this file must match the order of volumes in the input data and entries in the gradient directions text file.

@neurolabusc
Copy link
Collaborator

FSL wants the values in s/mm^2, not s/mm. Hence, dcm2niix applies b-value scaling. Am I correct that we can close this issue?

@tashrifbillah
Copy link
Contributor Author

Okay, I agree with the scaling. I also figured out the mistake before, we were using November 2016 version which might not have scaled the bvalues. But thanks for confirming.

Now, the following issues have been noted:

  1. Not all 0 bvals are in the output. We see a message 'removing some ADC volumes'. It is expected that the output should have all the gradients.

  2. The volumes are reordered which is a problem for further processing. Let's say you want to register a particular volume to nearest 0 bvalue. Then, we want to register to the one that is closest to the gradient under consideration, not one that was obtained far before in the time axis. So, the output should have all the gradients in pristine order.

  3. The bvecs are not normalized to unity. I suppose FSL normalizes them before doing dtifit or stuffs. But it should be great to have the bvecs normalized to unity before printing to .bvec file.

Let me know what you think. I am happy to work on a PR if my time permits.

@neurolabusc
Copy link
Collaborator

  1. If these are derived images, this is a feature, not a weakness. Is your data from a GE or Philips scanner? These can store derived images in the same series as the raw data. These will generate the warning you are seeing. It is very important to strip derived images from your raw data (in fact, they are a violation of the DICOM standard: derived data must be saved as a separate series). If left in your data, they will disrupt subsequent processing (e.g. TOPUP/eddy, degibbs, dwidenoise). You will be able to generate much better derived images (e.g. using dtifit) after these processing steps. You may find that the dcm2niix argument -i n will save these volumes (in filename_ADC.nii), but I can think of no reason why you would want to keep them. You can verify this by looking at the raw data with your favorite DICOM viewer (e.g. Horos) - isotropic images look very different from your B=0 and B-weighted images.
  2. dcm2niix will attempt to save DWI images in the same order they were acquired. This is to minimize the volume-to-volume movement correction for subsequent processing. Therefore, they are intentionally not reordered by ascending B-value. The exception I am aware of to this rule is data from Philips systems, which often obscure the acquisition order of the diffusion data. In this case, we are at the mercy of the vendor. For more details, see issue 201.
  3. It would be simple to scale the BVecs to unity, but it would be helpful to have a dataset that exhibits the issue, and to know the vendor (as each vendor describes DWI gradients differently). Assuming you have a GE system, you could test this yourself by inserting the bottom 3 lines into nii_dicom_batch.cpp and recompiling:
if ((vLen > 0.03) && (vLen < 0.97)) {
        	//bVal scaled by norm(g)^2 https://github.com/rordenlab/dcm2niix/issues/163
        	float bVal = vx[i].V[0] * (vLen * vLen);
        	printMessage("GE BVal scaled %g -> %g\n", vx[i].V[0], bVal);
        	vx[i].V[0] = bVal;
        	vx[i].V[1] = vx[i].V[1]/vLen;  
        	vx[i].V[2] = vx[i].V[2]/vLen; 
        	vx[i].V[3] = vx[i].V[3]/vLen;

@tashrifbillah
Copy link
Contributor Author

The data is from GE scanner, shared personally with Prof. Chris.

@neurolabusc
Copy link
Collaborator

The new version has two changes specific to GE. Since I do not have GE hardware, please check ((I would be grateful for comments from @captainnova).
1.) If bval > 0, and bvecs length is non-zero: bvecs generated with unity length.
2.) If bval > 0 but bvec length is zero: the volume is assumed to be bval=0 unless all volumes in the series have this property (in which case they are assumed to be trace images).

The second change reflects an odd aspect of @tashrifbillah's GE DWI dataset: the 1st volume is a standard B=0 volume with BVec=0,0,0. In contrast, volumes 15,30,44,58,73,87 report B=900 but have BVec=0,0,0. I am not sure if this reflects a custom gradient table, but it appears to conflict with GE and Philips standard practice of using this combination to indicate a trace scan for that B-value. Unfortunately, GE does not appear to report trace scans in any other way (e.g. one would expect the ImageType to be DIFFUSION TRACE). For a concrete example, series 16 from @nikadon. My kludge for this is to assume they are trace images if the vendor is GE and all the volumes have B>0 and BVec=0,0,0. Since GE (unlike Philips) seems to save derived trace images as a separate series from the raw data, this appears to work.

The volumes are saved in the order specified by the acquisition number provided by the vendor. The RTIA timer is not provided, but I have no reason to think the order saved does not match the order acquired.

@captainnova
Copy link
Collaborator

captainnova commented Nov 9, 2018 via email

@neurolabusc
Copy link
Collaborator

@captainnova thanks for your rapid response. Visual inspection of the data from @tashrifbillah clearly shows that the images with bval=900 and bvec=0,0,0 are raw B=0 images and not derived TRACE images. Fortunately, since (in my limited experience) GE always saves derived images in a separate series from the raw data (as required by the DICOM standard), I think my kludge should provide a robust solution to this problem. I think your assumption is correct: the users provided a custom tensor file to coax interspersed B=0 images. If the vendor allows this and we can reliably discriminate these from derived images, I think we should provide this function.

When the latest commit of dcm2niix detects GE bvec/bval images like this it will generate the warning Some images had bval>0 but bvec=0 (either Trace or b=0, see issue 245). Hopefully, the B=0 and trace images will be discriminated 100% of the time, but this warning will encourage users to validate the results (potentially detecting unintended consequences of this patch).

For those with GE hardware, I would suggest you lobby yourGE Research Collaboration Managers to fix this at the source:

  1. Trace images should set the DICOM tag Image Type (0008,0008) to read DERIVED\PRIMARY\DIFFUSION\TRACEW not ORIGINAL\PRIMARY\OTHER.
  2. For raw data, it might be helpful to set Slop_int_6 to zero when the b-vectors have zero length.

@tashrifbillah
Copy link
Contributor Author

Great work dcm2niix team. Now the bvals are scaled properly, and bvecs have unity magnitude. Also, the numbers agree with DWIConvert.

B value : 900.0
bval	scaled_bvec DWIConvert scaled_bvec
0.0 	0.0         DWMRI_gradient_0000 : 0.0
100.0	900.0       DWMRI_gradient_0001 : 100.0
100.0	900.0       DWMRI_gradient_0002 : 100.0
100.0	900.0       DWMRI_gradient_0003 : 100.0
100.0	900.0       DWMRI_gradient_0004 : 100.0
100.0	900.0       DWMRI_gradient_0005 : 100.0
100.0	900.0       DWMRI_gradient_0006 : 100.0
400.0	900.0       DWMRI_gradient_0007 : 400.0
400.0	900.0       DWMRI_gradient_0008 : 400.0
400.0	900.0       DWMRI_gradient_0009 : 400.0
400.0	900.0       DWMRI_gradient_0010 : 400.0
400.0	900.0       DWMRI_gradient_0011 : 400.0
400.0	900.0       DWMRI_gradient_0012 : 400.0
400.0	900.0       DWMRI_gradient_0013 : 400.0
0.0 	0.0         DWMRI_gradient_0014 : 0.0
400.0	900.0       DWMRI_gradient_0015 : 400.0
400.0	900.0       DWMRI_gradient_0016 : 400.0
400.0	900.0       DWMRI_gradient_0017 : 400.0
900.0	900.0       DWMRI_gradient_0018 : 900.0
900.0	900.0       DWMRI_gradient_0019 : 900.0
900.0	900.0       DWMRI_gradient_0020 : 900.0
900.0	900.0       DWMRI_gradient_0021 : 900.0
900.0	900.0       DWMRI_gradient_0022 : 900.0
900.0	900.0       DWMRI_gradient_0023 : 900.0
900.0	900.0       DWMRI_gradient_0024 : 900.0
900.0	900.0       DWMRI_gradient_0025 : 900.0
900.0	900.0       DWMRI_gradient_0026 : 900.0
900.0	900.0       DWMRI_gradient_0027 : 900.0
900.0	900.0       DWMRI_gradient_0028 : 900.0
0.0 	0.0         DWMRI_gradient_0029 : 0.0
900.0	900.0       DWMRI_gradient_0030 : 900.0
900.0	900.0       DWMRI_gradient_0031 : 900.0
900.0	900.0       DWMRI_gradient_0032 : 900.0
900.0	900.0       DWMRI_gradient_0033 : 900.0
900.0	900.0       DWMRI_gradient_0034 : 900.0
900.0	900.0       DWMRI_gradient_0035 : 900.0
900.0	900.0       DWMRI_gradient_0036 : 900.0
900.0	900.0       DWMRI_gradient_0037 : 900.0
900.0	900.0       DWMRI_gradient_0038 : 900.0
900.0	900.0       DWMRI_gradient_0039 : 900.0
900.0	900.0       DWMRI_gradient_0040 : 900.0
900.0	900.0       DWMRI_gradient_0041 : 900.0
900.0	900.0       DWMRI_gradient_0042 : 900.0
0.0 	0.0         DWMRI_gradient_0043 : 0.0
900.0	900.0       DWMRI_gradient_0044 : 900.0
900.0	900.0       DWMRI_gradient_0045 : 900.0
900.0	900.0       DWMRI_gradient_0046 : 900.0
900.0	900.0       DWMRI_gradient_0047 : 900.0
900.0	900.0       DWMRI_gradient_0048 : 900.0
900.0	900.0       DWMRI_gradient_0049 : 900.0
900.0	900.0       DWMRI_gradient_0050 : 900.0
900.0	900.0       DWMRI_gradient_0051 : 900.0
900.0	900.0       DWMRI_gradient_0052 : 900.0
900.0	900.0       DWMRI_gradient_0053 : 900.0
900.0	900.0       DWMRI_gradient_0054 : 900.0
900.0	900.0       DWMRI_gradient_0055 : 900.0
900.0	900.0       DWMRI_gradient_0056 : 900.0
0.0 	0.0         DWMRI_gradient_0057 : 0.0
900.0	900.0       DWMRI_gradient_0058 : 900.0
900.0	900.0       DWMRI_gradient_0059 : 900.0
900.0	900.0       DWMRI_gradient_0060 : 900.0
900.0	900.0       DWMRI_gradient_0061 : 900.0
900.0	900.0       DWMRI_gradient_0062 : 900.0
900.0	900.0       DWMRI_gradient_0063 : 900.0
900.0	900.0       DWMRI_gradient_0064 : 900.0
900.0	900.0       DWMRI_gradient_0065 : 900.0
900.0	900.0       DWMRI_gradient_0066 : 900.0
900.0	900.0       DWMRI_gradient_0067 : 900.0
900.0	900.0       DWMRI_gradient_0068 : 900.0
900.0	900.0       DWMRI_gradient_0069 : 900.0
900.0	900.0       DWMRI_gradient_0070 : 900.0
900.0	900.0       DWMRI_gradient_0071 : 900.0
0.0 	0.0         DWMRI_gradient_0072 : 0.0
900.0	900.0       DWMRI_gradient_0073 : 900.0
900.0	900.0       DWMRI_gradient_0074 : 900.0
900.0	900.0       DWMRI_gradient_0075 : 900.0
900.0	900.0       DWMRI_gradient_0076 : 900.0
900.0	900.0       DWMRI_gradient_0077 : 900.0
900.0	900.0       DWMRI_gradient_0078 : 900.0
900.0	900.0       DWMRI_gradient_0079 : 900.0
900.0	900.0       DWMRI_gradient_0080 : 900.0
900.0	900.0       DWMRI_gradient_0081 : 900.0
900.0	900.0       DWMRI_gradient_0082 : 900.0
900.0	900.0       DWMRI_gradient_0083 : 900.0
900.0	900.0       DWMRI_gradient_0084 : 900.0
900.0	900.0       DWMRI_gradient_0085 : 900.0
0.0 	0.0         DWMRI_gradient_0086 : 0.0

Thanks for working on this.

yarikoptic added a commit to neurodebian/dcm2niix that referenced this issue Dec 3, 2018
* tag 'v1.0.20181114': (70 commits)
  New stable release: update documentation (v1.0.20181114)
  Avoid using GDCM's internal OpenJPEG library.
  Discriminate trace from raw GE DWI scans (rordenlab#245)
  Restore Philips enhanced (rordenlab@3c31d18)
  Clean up readme, interpolation errors less verbose, add date-of-birth to BIDS (requires '-ba n')
  Not all GE DWI with b>0 bvec=0 are trace (rordenlab#245)
  calculate Zmm for enhanced DICOM w/o 0018,0088 (rordenlab#241)
  Kludge for Siemens MoCo slice timing interfered with CMRR fix (CMRR-C2P/MB#29)
  Bruker enhanced 4D data (rordenlab#241)
  XA10A tag substitutes (rordenlab#240)
  Huffman tables repeated for RGB planes for jpg_0XC3 (rordenlab#244)
  change MoCo naming and derived detection (rordenlab#243)
  Update dcm_qa_nih submodule.
  Update dcm_qa_nih submodule.
  Update dcm_qa submodule.
  experimental dcm4che enhanced support (rordenlab#241)
  Vida partial Fourier update (rordenlab#240)
  XA10A Vida dwell time (rordenlab#240)
  More XA10A Vida header info (rordenlab#240)
  UIH bvecs (rordenlab#225 (comment))
  ...
@katymanning
Copy link

@neurolabusc I am currently using the latest release I could find (?) [Chris Rorden's dcm2niiX version v1.0.20181125] and am working with the large NIH ABCD dataset that involves multi-shell DTI data from Siemens, Philips and GE scanners. I am getting the same error as above (all b values and b vectors are set to 0 during conversion) on some, but not all, of the GE images. Your help is greatly appreciated.

@neurolabusc
Copy link
Collaborator

Can you provide an example set of DICOMs?

@katymanning
Copy link

katymanning commented Feb 13, 2019 via email

@neurolabusc
Copy link
Collaborator

@katymanning this is not a problem with dcm2niix but with the DICOM images. You should contact the ABCD team to have them resolve this.

These images were acquired on a GE DISCOVERY MR750, so one would expect the B-value stored in 0043,1039 and the B-vectors in 0019,10bb, 0019,10bc, 0019,10bd. You can view the DICOM header with your favorite tool (e.g. Horos, dcmdump) and select an image where visual inspection reveals there is a clear spatially selective diffusion gradient applied (below I chose instance 2735). Note that the B-value for this slice is reported as 3000, but the bvector is reported as 0,0,0. In GE speak, an image with a positive bvalue and a bvector of 0,0,0 is a derived image, such as an isotropic image. The appearance of this slice is not consistent with a derived image. Therefore, the DICOM file is incorrect. Since b-vector information is not present in the DICOM, dcm2niix can not report it. I note the scan was acquired aligned to the scanner bore (0020,0037), so if you have another scan with this same alignment and the same sequence that does have b-vectors, you could substitute those.

(0020,0013) IS [2735] # 4, 1 InstanceNumber
(0043,1039) IS [3000\8\0\0]
(0019,10bb) DS [0] # 2, 1 Unknown Tag & Data
(0019,10bc) DS [0] # 2, 1 Unknown Tag & Data
(0019,10bd) DS [0] # 2, 1 Unknown Tag & Data
(0019,10e0) DS [102] # 4, 1 Unknown Tag & Data
(0019,10df) DS [1] # 2, 1 Unknown Tag & Data
(0019,10d9) DS [0] # 2, 1 Unknown Tag & Data
(0021,105a) SL 16 # 4, 1 Unknown Tag & Data

@mharms
Copy link
Collaborator

mharms commented Feb 14, 2019

FYI: I'd be cautious about assuming that the DICOMs provided by ABCD contain everything that is needed for successful conversion of the ABCD data from all scanner vendors. For example, at least initially in ABCD, GE scanners didn't even have an online (host) reconstruction available for its multi-band acquisitions, so the raw (k-space) data had to be saved and converted to images via offline scripts. My simple understanding is that the ABCD Study has it own image conversion utilities, which may include some "tricks" necessary to get the data (including bvals/bvecs) properly converted for GE (and possibly Philips) data. Your life is likely to be much simpler if you use the already converted images that ABCD is providing. Perhaps @HaukeBartsch can comment more definitely.

@katymanning
Copy link

Thank you so much for taking the time to explain these inconsistencies. I will contact them and attempt to gain access to the converted images.

@mharms
Copy link
Collaborator

mharms commented Feb 14, 2019

Converted data for ABCD is available through the NDA: https://data-archive.nimh.nih.gov/abcd

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants