Dwifslpreproc error: b-value must be non-negative

Dear MRtrix experts,

I am running into a problem with dwifslpreproc, which probably has to do primarily with a problem in my DW encoding scheme.
The error I get when attempting to run the command:
dwifslpreproc degibbs.mif geomcorr_eddy.mif -rpe_none -pe_dir AP -eddy_options " --slm=linear --repol " -eddyqc_all eddyqc/

is the following:

Command:  eddy --imain=eddy_in.nii --mask=eddy_mask.nii --acqp=eddy_config.txt --index=eddy_indices.txt --bvecs=bvecs --bvals=bvals --slm=linear --repol --out=dwi_post_eddy --verbose
          libc++abi.dylib: terminating with uncaught exception of type EDDY::EddyException: eddy: msg=DiffPara::DiffPara: b-value must be non-negative

dwifslpreproc: [ERROR] eddy* --imain=eddy_in.nii --mask=eddy_mask.nii --acqp=eddy_config.txt --index=eddy_indices.txt --bvecs=bvecs --bvals=bvals --slm=linear --repol --out=dwi_post_eddy --verbose (app.py:197)
dwifslpreproc: [ERROR] Information from failed command:
dwifslpreproc:
               =========
               eddy_cuda
               =========
               
               
               ====
               eddy
               ====
               Reading images
               eddy: msg=DiffPara::DiffPara: b-value must be non-negative
               
               
               =========
               eddy_cuda
               =========
               dyld: Library not loaded: @rpath/libcudart.7.5.dylib
                 Referenced from: /usr/local/fsl/bin/eddy_cuda
                 Reason: image not found
               
               
               ====
               eddy
               ====
               libc++abi.dylib: terminating with uncaught exception of type EDDY::EddyException: eddy: msg=DiffPara::DiffPara: b-value must be non-negative

The problem is indeed that some of the b0 volumes have a negative b-value. Here is the output of mrinfo -dwgrad :

                 0                    0                    0               -16383
  -0.861795269114119    0.357031917905849    0.360329188005903                 1000
  -0.861622250494381   -0.357672261897667    0.360107831797651                 1000
  -0.863377119710764   -0.358428262504469   -0.355118472904427                 1000
  -0.863553414721423    0.357784876108876   -0.355338546108815                 1000
  -0.358433740402349    0.358433590402349    -0.86200383700565                 1000
  -0.357784872306874     0.86355340551659   -0.355338572306827                 1000
  -0.357032025696173    0.861795191890763    0.360329265896138                 1000
  -0.356348114390319    0.356348234390319    0.863731414976535                 1000
  -0.356129876497093   -0.356988786397086    0.863556898792952                 1000
  -0.356767176596269   -0.862016491890984    0.360062146596234                 1000
  -0.357517273407207   -0.863773455617413   -0.355072973607158                 1000
  -0.358433740402349   -0.358433590402349    -0.86200383700565                 1000
                   0                    0                    0               -16383
  -0.842678153857924   -0.216424400689194   -0.493005078875384                 1995
    0.87492211008887   -0.124921648598411   -0.467873789594048                 1995
  -0.111009188705875     0.97046373365136   -0.214189406111335                 2000
   0.846872030113457   -0.311775980004954    0.430817250006846                 2005
  -0.219743532700669    0.544028431401656    0.809781356702465                 2005
  -0.902910108534189    0.425803899316123   0.0586887999022223                 2000
  -0.154940155996924     0.37525222879255   -0.913881454481856                 1990
  -0.532461034809397    0.115926339802046    0.838478580614798                 2005
 -0.0452936001497172   -0.761383592595246    0.646717492195962                 2005
   0.626120730127172   -0.609536209026452   -0.486249361121102                 1995
   0.598249170398451   -0.795526370397941   0.0961026748797512                 2000
   0.611741447191967    0.658149324691358    0.438875686494237                 2005
   0.577350209189624   -0.577350329189624    0.577350269189624                    5
  -0.316863415295032   -0.945191936585182  -0.0788021513787646                 2000
  -0.141865749993124   -0.805595819960953   -0.575229939972119                 1995
   0.994247999031917    0.106629853103423   0.0100494202903226                 2000
  -0.781534420975464   -0.367090725788475    0.504428734184163                 2005
  -0.484843505605816    0.653662051007842   -0.581078908706971                 1995
  -0.805586364965754   -0.592035428374832   0.0229054607090263                 2000
   0.560370072178956  -0.0958044272064022    0.822682741969105                 2005
  0.0262364481002517  -0.0867375637308321   -0.995885658009554                 1990
   0.369541505610376    0.388290617410903    0.844197531423704                 2005
  -0.256061979500007    0.920461696300026    0.295266876400008                 2000
   0.385286919587153    0.384058639787194   -0.839078632072021                 1995
   0.477068153385919    0.788444198676729    -0.38828046898854                 1995
   0.577350209189624   -0.577350329189624    0.577350269189624                    5
                   0                    0                    0               -16383
   0.385983746502629    0.759484601905173   -0.523640799503567                 2995
  -0.762136051540026    0.647132948833986  -0.0191725187810069                 3000
   0.746466005324426   -0.322251245010545     0.58218780301905                 3005
  0.0101655505901426    0.197271211402767    0.980296246413748                 3010
    0.40683372907834    0.265410202885869    0.874095956453463                 3010
   0.104012291802266    0.166764058903633   -0.980495380821361                 2990
   0.724576528006702    0.599804098405548    -0.33944645910314                 2995
  -0.476709089118885    0.855588582033895    0.201783603507994                 3000
   0.184881998607796    0.979007652641282   0.0858059593536182                 3000
   0.713852437098488   -0.602379850098724   -0.357145928499244                 2995
   0.459866212784234    0.202673952393052    -0.86454978767036                 2990
   0.627130993400736  -0.0179671801000211    0.778706554200913                 3010
   0.577350209189624   -0.577350329189624    0.577350269189624                    5
  -0.466829618993068    0.363091754794608   -0.806371182788026                 2990
  -0.716723691411955   -0.310267214905175   -0.624532949910417                 2995
   0.833513685481386    -0.26913999239399   -0.482512798389225                 2995
   0.902148709193698   -0.351708945797543    0.249857006998255                 3005
   0.123776926903747   -0.935616930728323   -0.330605854910008                 2995
   0.933330132100929    0.336249144400335   -0.125822801600125                 3000
  -0.772691710629473   -0.634303123324195  -0.0246387513009398                 3000
  -0.143030485804879   -0.521349751117784   -0.841270894028698                 2990
  -0.695334673029167   0.0279851077111739    0.718141021130123                 3005
  0.0215612301695114    0.759780295982782   -0.649822295085274                 2995
   0.249740702113442    0.850216979145762    0.463422776824943                 3005
  -0.490448504705796   -0.854255643610096    0.172358810602037                 3000
   0.577350209189624   -0.577350329189624    0.577350269189624                    5
   0.503770723000055    0.838936931600091    0.205912319800022                 3000
   0.909343312114766    0.325936725905293    0.258572990504199                 3005
   0.961380221644481 0.000320769993914841   -0.275223484712734                 2995
  -0.167796476096209    0.985297837077737   -0.032132769249274                 3000
  -0.586588511525863   -0.470945219220764     0.65888126292905                 3005
  -0.141776046004628   -0.943730099830803    0.298785962609752                 3005
  -0.825594836976401   -0.245416429092985    0.508098358085477                 3005
  -0.995387536583265  0.00939013987284213  -0.0954750087083948                 3000
  -0.929368465287316    0.347535416995257    0.124472445398301                 3000
  -0.268301956094544   0.0829054487783142   -0.959760775880484                 2990
   0.367674706699034   -0.150883036299604    -0.91763261679759                 2990
  -0.244252223499957   -0.514733680599908    0.821821202799854                 3010
   0.577350209189624   -0.577350329189624    0.577350269189624                    5
 -0.0472568074484826    0.759757059075604    0.648487475079177                 3005
  -0.694760525678063   -0.599704403881064   -0.397067298987463                 2995
   0.118873460699291   -0.462994621797239    0.878353619294761                 3010
  -0.887254530720143 -0.00567486955712883   -0.461245264010471                 2995
    0.37258150748895   -0.670029575580127    0.642061825780957                 3005
  -0.575561814395987    0.413483765997117    0.705520923195082                 3005
   0.496037264299085   -0.850135303098432    0.176683329299674                 3000
  -0.443998803113935   -0.607671209619072   -0.658483685320667                 2995
   0.409444957908689   -0.726891269515426     -0.5513473576117                 2995
   0.215062927692957   -0.889992170470854    0.402071975686833                 3005
  -0.237676427211874    0.489156343724437    0.839187694941924                 3010
  -0.659282584587175     0.63024195618774   -0.410050667992023                 2995
   0.577350209189624   -0.577350329189624    0.577350269189624                    5

I ran dwidenoise and mrdegibbs without encountering any error message.
Any suggestion on how to solve this issue? Is it something that can be revised in the post-processing or is it a “revise-your-sequence” kind of problem?

Please let me know if I need to provide any additional information

Thanks in advance!
Sam

A b-value of -16,383 s/mm² really doesn’t look right… I assume given these are zero vectors, these should be b=0. How did you import these data…?

Yes, neither of these rely on the gradient table, they don’t need to interpret it in any way, so that wouldn’t have raised an error at that point. However, if the original DW encoding before these commands doesn’t show this same problem, then we’d need to look into it!

I imported the DICOMs with mrconvert, and I see that the original DW encoding as looked at from the DICOMs is the same as the one I reported…

I did notice something else tho.
My intention is to stay within MRtrix fully, hence the conversion from DICOM to .mif file using mrconvert. However, I did try some alternatives to see whether I’d encounter the same issue (experimenting only on 1 shell).

I used the dcm2niix tool to convert DICOMs to NIFTIs, which outputs bvals and bvecs files in FSL format. The weird value of -16383 is not present anymore, but a bval = 0 is reported instead (as it should be). Running eddy within FSL using the nii.gz file and the bval and bvec files obtained then works.

I then used mrconvert to convert the dcm2niix files to .mif, importing the FSL’s bval and bvec. The dw_scheme of the b=1000 shell is then the following:

                 0                  0                  0                 0
-0.861795196303545  0.357031770501469  0.360329508201482               1000
-0.861622369855611 -0.357672078681573  0.360107728181448               1000
-0.863377041310553 -0.358428252804381  -0.35511867330434               1000
 -0.86355313097891  0.357785238291262 -0.355338870991322               1000
-0.358434028473862  0.358433702673862 -0.862003670537141               1000
-0.357784693791024  0.863553411878336 -0.355338736591085               1000
 -0.35703228629389  0.861794936585252  0.360329618293834               1000
-0.356348537486427  0.356348068486427  0.863731308867102               1000
-0.356130469417871 -0.356988690917914  0.863556693743335               1000
-0.356766754393749 -0.862016654684896  0.360062175193691               1000
-0.357517238101071 -0.863773324302588 -0.355073328601064               1000
-0.358433244981957 -0.358433773781957 -0.862003966756609               1000

… and dwiflspreproc runs.

Directly converting to nii and to fsl’s bvec and bval files using mrconvert, however, does not work and leads me to the same problem.

Don’t know if this can help in any way in figuring out what might be happening?
This work-around could be ok but I’d prefer to avoid it, if possible :slight_smile:

Sam

Hi Sam,

If you’re confident that the manifestation of negative b-values is the only issue with your data (i.e. not a symptom of some other problem), then you can proceed with:

  • Converting via dcm2niix then mrconvert-ing to .mif;

  • mrconvert DICOM to .mih rather than .mif, open the .mih file in a text editor, and change the negative b-values in the gradient table to zeroes;

  • Use mrinfo -export_grad_mrtrix or mrinfo -export_grad_fsl, modify the relevant text file, and then import the fixed table using mrconvert -grad or mrconvert -fslgrad respectively.

From our perspective, while we can advocate that users apply bandaids to keep themselves going, we ultimately need to file down whatever sharp edges are lying around. It’s entirely possible that both MRtrix3 and dcm2niix “see” negative b-values, and the latter is simply clamping them to zero prior to export whereas we’re propagating that value through unchanged; maybe we should clamp such values to zero also, maybe we shouldn’t. It’s also possible that there’s some alternative DICOM encoding that dcm2niix is aware of and MRtrix3 isn’t, or that the appearance of negative b-values is symptomatic of some greater issue. For instance, if I were an MRI sequence developer, and I heard that people were getting negative b-values following DICOM conversion, I’d want to be checking to see that it wasn’t my buggy sequence code that was erroneously writing negative b-values to DICOM in the first place. So this is the kind of instance where sharing an exemplar dataset would be beneficial if possible.

Cheers
Rob

P.S. -16,383 happens to be the minimal number that can be represented using a 16-bit signed magnitude integer representation with one reserved / parity bit. So if this were how the vendor were to store such data internally (for some god-forsaken reason), and those data were to be erroneously over-written with all 1’s, this is the value that would come out. :nerd_face:

Hi Rob,

I am indeed at the stage of evaluating the DWI sequence at my disposal, so this is the perfect time to make sure that no such problems are there.
I previously did some quality checks mostly focused on the quality of DW gradient orientation, whether they were distributed uniformly etc. In this regard the sequence is fine, metrics from dirstat are very very close to those obtained with dirgen. The only warning is the asymmetry index in the b=1000 shell (I only have 12 directions), which I was hoping to compensate for by using the "--slm=linear" option for eddy correction.
Anything that is very obvious to look at when evaluating a sequence and checking if there are any problems? Or which problems did you have in mind that might cause the -16383 value in the DW encoding?

Next to the 3 shells in AP directions, I also have 6 b0 volumes acquired with opposite phase-encoding. I can show the original DW encoding of these:

               0                  0                  0             -16383
 0.724547313947243                 -0 -0.689225064729828                 20
                -0  0.724547313947243 -0.689225064729828                 20
                -0  0.689225064729828  0.724547313947243                 20
-0.707106781186548  0.707106781186548                  0                 20
 0.707106781186548  0.707106781186548                  0                 20

So same behavior here.

You mean sharing it with you? How would this work? Which platform do you usually use for data sharing?

The workaround indeed can work, but since I can still potentially change the sequence before starting data acquisition, it would be nice to know what is actually going on here and eventually fix it

Best,
Sam

Not really; just anything that jumps out at you looking at raw data that might be missed if the data are just fed blindly to a pipeline.

For the -16383 specifically, the fact that in your reversed phase encoding b=0 volumes it’s only the first volume with a zero direction vector gives a bit of a hint. It suggests that somewhere internally in the sequence code, there’s a normalisation by vector norm going on (like what we do here), but that code is failing to check for a zero norm before doing the division, which produces a NaN if done in floating-point, and it’s conceivable that there could then be a conversion from floating-point to integer for the b-value, for which a NaN input (which can’t be represented using an integer type) results in the minimal value achievable for that data type being written. But I couldn’t be any more confident or precise than that without full access to sequence / DICOM export code…

For your reversed phase encoding acquisition, if you were to use a corresponding spin-echo sequence rather than the DWI sequence, there wouldn’t even be / need to be a gradient table. I’ve done this in the past myself. Not a solution, just a thought.

You mean sharing it with you? How would this work? Which platform do you usually use for data sharing?

Yeah; obviously it involves sharing non-anonymised DICOMs, so that needs to pass whatever local ethics are relevant, but it’s something we do semi-regularly with users to update the DICOM code for upstream vendor / sequence changes. Since Aus-specific services aren’t an option, pretty much any service that will accept that size of data is fine, but I’ll PM you a couple of options.

Cheers
Rob

Thanks for the sample data @sambal.

I’ve not yet looked at the raw encoding within the DICOM, but even in just the output of dcminfo there’s a couple that stand out:

[DCM] 0018 0024 SH       10     1418   SequenceName                           ep_b-16383
[DCM] 0019 100C IS        6     1880   SiemensBValue                          -16383

At the Siemens console, in the Sequence -> Special tag, you typically have to select the number of unique b-values, and then in a table nominate what those b-values are1. Typically two b-values will be nominated, one at b=0 and one at the maximal intended b-value. Selection of b=0 as the “first b-value” results in acquisition of a single b=0 volume before commencing reading from the gradient vector table, and hence the number of output volumes is one greater than the length of the selected gradient vector set.

My leading hypothesis right now is that you have deviated from this typical usage by nominating just one b-value, relying instead on the presence of zero-filled rows in the gradient vector set to obtain b=0 volumes. Theoretically at least this should be entirely permissible. I’m pretty sure that it precludes any form of online DWI recon - of which I note that your DICOM directory does not contain any - since the online recon doesn’t look for zero-filled entries in the gradient vector file, it looks for multiple b-values in its own explicit b-value table, and with only one b-value it can’t do a tensor fit. There is some chance that there’s a piece of code somewhere that is assuming the presence of (at least) two b-values, and is therefore experiencing a buffer overrun when it attempts to sample from the second value. Indeed as shown above it appears as though it is even reading (nominally) from this table in order to insert that value into the sequence name (which I recall having seen myself from either product or CMRR sequences).

So independently of deciding how to interpret such DICOMs once they reach our software, I would suggest that you need to look at the sequence parameters at the scanner console and/or in the sequence PDF printout, and check the contents of that b-value listing in the Sequence -> Special card, as well as the name of the sequence as reported by the vendor. Even if there’s not much I can do with that information myself, that would be highly valuable information to feed to the sequence developer.


1 Note though that this is not how multi-shell acquisitions are typically achieved, since it results in re-acquisition of the entire gradient vector table for each b-value, which is not optimal. Instead, the contents of the vector gradient table itself are manipulated in such a way so as to achieve the intended multi-shell acquisition nature. See e.g. https://mrtrix.readthedocs.io/en/latest/concepts/dw_scheme.html#b-value-scaling.

Thanks for already having a look!

I can already share the sequence PDF printout: Protocol 7T.pdf (93.3 KB)

There is a difference between the b1000 and b2000/3000 shells. As you were mentioning, only 1 diffusion weighting with 1 b-value is listed for the b2000 and b3000 shells. However, for the b1000 shell, a b=0 s/mm2 is explicitly mentioned and the number of volumes is indeed 1 greater than the length of the gradient vector set (12). So this should be the typical implementation yet a value of -16383?

If you think the information provided in the PDF printout is not enough, I can arrange to go and have a look at the Sequence -> Special card on the scanner.

Sam

The value of -16383 is present in both:

  • [0019, 100C] (Siemens private DW encoding tags) (code);
  • Siemens CSA (code)

In both of these cases, the value stored in the DICOM is actually a floating-point number. So that supports the notion that the error is upstream of generation of the DICOM, and not an error of MRtrix3 parsing the DICOM (at least beyond its current failure to detect the presence of an erroneous value and correct / report such).

There is a difference between the b1000 and b2000/3000 shells. As you were mentioning, only 1 diffusion weighting with 1 b-value is listed for the b2000 and b3000 shells. However, for the b1000 shell, a b=0 s/mm2 is explicitly mentioned

Well, some of your protocols show 2 b-values and others show 1, yet all of them contain the erroneously reported b-value. So that suggests that the selection of 1 vs. 2 b-values is not the underlying source of this issue, as I had hypothesized. You also have a mix of Free and MDDW diffusion direction schemes, as I’d guessed you may, so that’s not the source either.

I’m trying to figure out why, if this is an issue for some sequence, you are the first to report such: whether you’ve done something differently to how others typically use a sequence, or whether you’re simply the first to encounter the issue by chance. From this observation alone it may be the latter.


I can already share the sequence PDF printout:

Off-topic, but since you shared:

cmrr_mbep2d_dev_1pt5_iPAT3_PA_TOPUP
USER: cmrr_mbep2d_bold_dev

Gradient echo EPI should not be used with topup. Fundamental to the operation of topup is that the total density of spins is equivalent across images, only that their displacement due to the inhomogeneity field differs between them. With a gradient echo, the voxel intensities will be modulated by not only the compression / expansion of spins, but also the dephasing that occurs across spins within that voxel; that dephasing will be different between images of different phase encoding, breaking this fundamental assumption. While topup won’t give you an error if it’s provided with gradient echo data, and will give you some field inhomogeneity estimate that will resemble the actual field inhomogeneity, it is nevertheless inappropriate application of the relevant theory.

topup (and the more general theory of field estimation using EPIs with different distortions) can still be applied to fMRI data; but it needs to be estimated based on spin-echo EPIs, and then applied to the fMRI data; gradient-echo fMRI data should not be used in the process of estimating that field.