Extract bvecs from vendor-provided tensor file?

Suppose I have a dataset from a colleague containing dicoms for a diffusion sequence.
After an initial pass with dcm2niix, we discover that the bv[al,ec] pair is incorrect, due to the scanner encoding the bvecs in the dicom header incorrectly, a la GE / ABCD_pepolar sequences. Thus my colleague will need to create the bv[al,ec] pair by reading from a vendor-provided tensor file.

Are these external tensor files in a similar format between vendors?

I’ve written a custom python script for one of our GE epi_pepolar_flex (ABCD) sequences and am hoping to extend it to extract bval/bvec pairs from other tensor files, if possible.

Users need to be extremely cautious with the ABCD research pepolar sequence. This sequence reports incorrect spatial information in the DICOM header. I describe the issue and provide exemplar images here.

The fall release of dcm2niix should automatically detect the images and adjust the image spatially. However, I was only provided b=0 images, and was not aware that anyone was acquiring diffusion weighted images with this sequence. If someone can provide me with a set of DICOMs with diffusion weighting, I will see if dcm2niix can be updated to handle these.

A basic tenet of DICOM to NIfTI converters is that they assume the DICOM images are truthful. This is not the case with the epi_pepolar sequence. While dcm2niix includes a kludge to handle these images, other tools like dicm2nii argue that this is not the role of a DICOM to NIfTI converter. Including kludges hampers maintainability and creates the real possibility of unintended consequences. There is a strong motivation for researchers to use these advanced sequences, however they have to remain extremely vigilant.

1 Like

Hi Chris,

I should have a new participant sometime next week and can ask their permission to share the epi_pepolar_flex (ABCD multishell) sequence with you.

Unfortunately, there is no way to determine the actual bval/bvec pair using just the header, as these only report the max bvalue, which is where this previous issue arose from. These values have to be determined by reading a set of tensor files provided by GE (unfortunately cannot share).

ABCD’s MMPS has functionality to read this tensor file. Individuals using these ABCD pepolar_flex multishell sequences would need to ask the ABCD team directly to provide the correct bval/bvec pair.

There are ~4 private tags that are used to derive which exact tensor file is read. If for whatever reason you would like to know, I can dm you the specific private tags.

I have consolidated information regarding GE diffusion gradient directions (i.e. tensorXX.dat).

Please let me know if you need any help. I am happy to help you convert to FSL bval/bvec format if you could share your DICOM images. DICOM is for extracting necessary scan parameters (# of T2 (b0), frequency/phase encoding direction, Max. b-value) for conversion. Here is the link to ABCD tensor file, tensor4321.dat (b=500, 1000, 2000, 3000 s/mm2).

I also documented the ABCD epi_pepolar PSD issue as Chris noted above.

Thanks for the heads up! I thought the tensor.dat files for ABCD were proprietary, so nice to see they can be shared.

I have access to the ones from ABCD already, but thank you for offering to help!
My main question was if the formats of GE tensor.dat files were similar.

You are welcome! Hope the above GE_tensor.pdf documentation answered your question. I have a python script to convert tensor.dat to bval/bvec format.

For example,

  1. tensor.dat, # of T2 = 1, # of directions = 6, b=1000, freq. encoding direction=RL,
    from tensor.dat:
    -----------------------------------------------
    6
    1.000000 0.000000 0.000000
    0.446000 0.895000 0.000000
    0.447000 0.275000 0.851000
    0.448000 -0.723000 -0.525000
    0.447000 -0.724000 0.526000
    -0.449000 -0.277000 0.850000
    -----------------------------------------------
    bval
    -----------------------------------------------
    0 1000 1000 1000 1000 1000 1000
    -----------------------------------------------
    bvec
    -----------------------------------------------
    0 -1 -0.446 -0.447 -0.448 -0.447 0.449
    0 0 0.895 0.275 -0.723 -0.724 -0.277
    0 0 0 0.851 -0.525 0.526 0.85

  2. Similarly, for your case,
    tensor4321.dat, # of T2 = 2, # of directions = 102, b=3000, freq. encoding direction=RL,
    -----------------------------------------------
    bval
    -----------------------------------------------
    0 0 0 3000 3000 2000 3000 1000 3000 3000 2000 3000 1000 3000 3000 500 3000 2000 3000 3000 1000 3000 500 3000 3000 2000 3000 1000 3000 3000 2000 3000 1000 3000 3000 0 3000 2000 3000 1000 3000 3000 500 3000 2000 3000 3000 1000 3000 0 3000 3000 2000 3000 1000 3000 3000 2000 3000 1000 3000 3000 500 3000 2000 3000 3000 1000 3000 0 3000 2000 3000 3000 1000 3000 500 3000 3000 2000 3000 1000 3000 3000 2000 3000 1000 3000 3000 0 3000 2000 3000 3000 1000 3000 500 3000 3000 2000 3000 1000 3000 0
    -----------------------------------------------
    bvec
    -----------------------------------------------
    0 0 0 -0.654875 -0.271924 0.957386740201419 0.11881 0.957387619782082 0.326879 -0.394817 -0.190618067038515 0.906253 -0.190617387525378 0.56633 -0.55854 -0.006226602926155 0.648904 -0.325491871255643 0.435216 -0.060085 0.325492183910766 0.290295 -0.636678722413432 0.008761 0.098843 0.022796176291212 -0.162887 -0.022795520678414 0.095045 -0.21496 -0.596977392662402 0.741627 -0.596977291590727 0.847852 0.943158 0 0.21565 0.416250365205245 0.06036 0.416249914176568 0.814723 -0.265965 -0.399915942855496 -0.441982 -0.73444765600688 0.566124 -0.716591 0.734448432136661 -0.331272 0 -0.465735 -0.480716 0.58188118737763 -0.961362 0.581880736751957 -0.92036 0.393331 -0.928822015565953 0.852276 0.928822637863656 -0.571183 -0.535413 0.789558725729758 0.442791 -0.861660681053453 0.143848 0.89346 -0.861660635749365 0.795825 0 0.399108 0.525769501094824 0.806535 0.69138 -0.525769218789955 0.973847 -0.887690183805138 0.052107 0.696694 -0.034273260481022 0.626272 -0.034273821380173 0.994108 0.738939 -0.08450739612602 0.702182 -0.084508490952093 -0.505053 -0.37123 0 0.05087 -0.630412927651393 0.170569 0.31216 -0.630412800380037 -0.887018 0.152551771690794 0.605767 -0.215791 -0.491239044190809 0.210754 0.491239053890262 0.787853 0
    0 0 0 0.355659 0.933965 0.187071205890965 0.110437 0.187070147471477 0.866547 0.108337 0.585245561539342 0.349334 0.585244379420256 0.470917 -0.665203 0.064446075132625 -0.611989 -0.844582838566768 0.497941 -0.972644 0.844582614786736 0.619397 -0.653134394505449 -0.548745 -0.63796 0.678409454416358 0.917294 -0.678409660308578 0.821836 -0.721063 0.258722455101988 -0.039918 0.258721625278986 -0.200363 0.304222 0 -0.732737 0.343102477761383 -0.223624 0.343103676522126 -0.56112 -0.335097 0.828419880499013 -0.764517 0.292307408965288 0.807614 -0.584614 -0.292307822488554 -0.943028 0 0.168038 0.789299 0.362502436524225 0.253123 0.362502645566898 -0.003999 -0.915435 0.354406872924327 -0.324551 -0.354407040092321 0.799445 -0.167226 -0.384929964609148 0.203222 -0.322776611875768 0.431269 -0.41491 -0.322776328244498 0.511407 0 -0.523871 -0.761171589100644 0.590581 -0.710203 0.761172244046641 -0.080055 -0.101313345251255 -0.996034 0.03436 -0.991161529519785 -0.2862 -0.991162610529675 0.072683 -0.519516 -0.056169249291761 0.353175 -0.056168675638651 0.581614 0.77018 0 -0.85837 -0.75666207848418 -0.325484 -0.422488 -0.756661983743732 -0.152189 0.851205034086383 0.776332 -0.937112 0.826625629262425 0.013433 -0.826626444064669 0.274495 0
    0 0 0 0.666817 0.231877 -0.220033989359599 0.986756 -0.220034538441127 0.377155 -0.91235 0.788133122699459 -0.238058 0.788133346917259 -0.676393 -0.495518 -0.997902525291924 -0.452098 -0.425128540777963 0.750095 -0.224396 0.425128406616166 -0.729435 0.40994415386245 0.835944 -0.7637 -0.734331305244098 -0.363371 0.734330652681747 -0.56174 -0.658681 -0.759394484292255 -0.669624 -0.759395159918076 0.49092 0.133799 0 0.645439 0.842030470254788 0.972805 0.842031303947187 -0.146185 0.903866 -0.392155959350358 0.469218 0.612488786458577 -0.165116 0.380425 -0.612489538623314 -0.03094 0 0.868823 -0.381994 -0.728016520687202 0.108216 -0.728015595437351 0.391053 0.08526 -0.108098431838764 -0.410233 0.108097290900374 0.18611 0.82787 -0.477939539632368 0.873291 -0.391608498392846 0.890682 0.171983 -0.391608027337285 0.32423 0 -0.752511 0.379713776201891 -0.026762 0.132686 -0.37971403444171 0.212633 -0.449158035154666 0.072118 0.716545 0.12815240436293 0.725171 0.128152707201214 -0.080414 0.429037 0.994838213623703 0.61823 0.994838022343336 -0.637689 0.518664 0 -0.510502 0.173325894199338 -0.930036 0.850917 0.173326324313418 -0.435932 0.502174791147465 0.174228 0.274326 0.274542484605753 -0.977447 -0.27454217735532 -0.551307 0

Please let me know if you have any questions.

As do I :slight_smile:
I have to read 4 private DICOM tags in order to (1) find the file applicable, (2) extract said bvecs, (3) derive bvals. The tensor.dat file is then read line by line once the ndir line is past, each line being put into an ndir x 3 numpy array.
The only part I’m “stuck on”, which @Chris_Rorden has given help with, is speeding up how to identify the correct DICOM series/file to read from.

The purpose of this post was, will I ever have to read an external tensor.dat file for other, non-ABCD data? E.g. if someone uses a custom sequence on a Siemens or GE scanner? If there will ever be a non-ABCD sequence that I will have to read an external tensor.dat file for, will these tensor.dat files have a similar structure to the ABCD GE tensor files?

And again, thank you so much!

For GE scanner,

  1. Any tensor files including tensor.dat (default GE tensor), any custom tensor file have a similar structure to the ABCD tensor file.
  2. As noted in the GE_tensor.pdf, they are in “MR physics” logical coordinate. So, bval/bvec will be identical regardless of oblique acquisitions, i.e. all same across different subjects as long as freq encoding direction remains same(RL or AP). Note that AP or PA doesn’t change bvec.
  3. If data was collected with earlier software version using custom tensor file, DICOM tags (bvecs) may be incorrect. (Please see the GE_tensor.pdf for details). Which GE scanner/version?
  4. But, you can always convert from tensorXXX.dat to bval/bvec format without reading the DICOM bvec tags.

For Siemens/Philips, as Chris noted here, unlike GE, oblique acquisition leads to different bvecs for the same diffusion table. (Siemens or Philips reports them “with reference to the scanner bore” vs FSL tools (bvec) expect them “with reference to the imaging plane”). So, you may want to ready DICOM tags, instead of reading external diffusion table. @Chris_Rorden please comment here if needed.

Please let me know if there is anything I can help you with, especially with GE scanner.

2 Likes

@mr-jaemin the details in your ge-mri repository are terrific. I wonder if we could work together to allow your Python script and dcm2niix to work together seamlessly.
a. Validate behavior when Patient Orientation is not HFS.
b. Validate behavior when for slices other than Axial (Coronal, Sagittal).
c. Validate behavior when slice direction is negative, e.g. slices stored to disk in head-to-foot not foot-to-head order.
d. dcm2niix should store the setting of isFlipY is the BIDS JSON file. This impacts how row order is stored to disk.
e. A bizarre feature of the FSL bvec format is that FSL will flip image data column data (the first dimension on disk) to ensure a negative determinant, but the bvec direction is not flipped. This situation decouples the FSL bvec format from MR physics logical coordinates used by GE (e.g. the X value may or may not need to be flipped, depending on the determinant).
f. I assume that dcm2niix could store the CV11 value in the BIDS JSON file, as well as the number of volumes, maximum b-value, etc. This would allow a Python script to use a user supplied custom gradient file.

I realize this is a long list, but I do think we could accomplish this with a brief hack.

1 Like

Sounds great! Thanks for your suggestions/initiative.

I think that one of the simplest approach would be to feed an (optional) tensor file to dcm2niix, which replace/override information in DICOM tags: (0019, 10bb), (0019, 10bc), (0019, 10bd), which is essentially same information as tensor file. Also, the DICOM tag (0043, 1030) can be utilized to identify the T2 images (GE’s default b0 images) (T2=14 vs DTI=16 including interspersed b0 from tensor file.)

Of course, your validation/testing procedures would always be good to have.

Let’s discuss the detail in your dcm2niix github.

@Chris_Rorden and @mr-jaemin , please do let me know if you would like either ABCD phantom multishell RSI datasets or the custom tensor.dat files for testing. I’ve reached out to the ABCD team (work in same building) and they are happy to send either to both of you :slight_smile:

1 Like