robbert-harms / MDT

Microstructure Diffusion Toolbox
GNU Lesser General Public License v3.0
50 stars 18 forks source link

How to get exact same output as the NODDI Matlab Toolbox? #9

Closed johnaeanderson closed 5 years ago

johnaeanderson commented 5 years ago

Hi, I love this toolbox so far - especially the speed and flexibility! I've noticed that MDT tends to down-weight CSF voxels in the ODI images. In general, this is fine, but I'm working with older adults who tend to have larger ventricles. As a result, MDT occasionally classifies their subcortical structures (e.g., caudate) as CSF and knocks out the signal from these regions.

Is there a way to get the exact same results as the NODDI Matlab toolbox?

Thanks in advance & thanks for contributing such an amazing resource,

John

robbert-harms commented 5 years ago

Hi John,

Thanks for the compliments, much appreciated.

If I understand your question correctly, your problem are the low ODI values in the ventricles? This could perhaps be easily solved with the following piece of Python code:


import mdt

my_results_dir = r'/my/path/NODDI'

results = mdt.load_volume_maps(my_results_dir)

csf_locations = results['w_csf.w'] >= 0.999
results['NDI'][csf_locations] = 0
results['NODDI_IC.kappa'][csf_locations] = 0
results['NODDI_EC.kappa'][csf_locations] = 0
results['ODI'][csf_locations] = 1

mdt.write_volume_maps(results, my_results_dir)

This basically loads the results, looks up the voxels with CSF > 0.999 and sets NDI, kappa and ODI values to a clipped value. This is possible since in regions with near unity CSF, the NDI, kappa and ODI are undefined and can take on any value.

The two relevant theoretical implications are as follows. The first is that a voxel with large CSF is approximately equal to a voxel with low CSF and high dispersion. The second is that in voxels with high CSF, the kappa values are uninformative since kappa is an parameter of the intra-cellular (IC) and extra-cellular (EC) compartments. In a voxel with large CSF volume fraction, the weights of the IC and EC compartments are so low that kappa can take on any value without changing the signal.

The script above should transform the MDT results to match the Matlab toolbox results. Please let me know if it works for you. Also let me know if I misinterpreted your question.

Best,

Robbert

johnaeanderson commented 5 years ago

Hi Robbert,

Thanks for your response - as I understand it, this code merely sets values that have a high likelihood of being CSF to 0. This doesn't necessarily restore estimates of ODI from regions that appear to be down-weighted by the MDT algorithm. My issue is that relative to output from the Matlab toolbox, for certain participants, the MDT pipeline will knock out the caudate nucleus and other deep structures (e.g., classify these as CSF). I was hoping to be able to generate the same output as the Matlab toolbox with respect to these deep structures.

Thanks,

John

robbert-harms commented 5 years ago

Hi John,

That is indeed what I proposed, but that might not work indeed. Could you perhaps try one more time with the newest MDT version? I made some changes to the optimization routines that improve the fit results, hopefully bringing it closer to your expected results.

Best wishes,

Robbert

johnaeanderson commented 5 years ago

Hi Robbert,

Thanks for following up with this - the results do look a lot more similar to the MATLAB toolbox output, which is very encouraging.

I have noticed for a few subjects the subcortical regions are still being clipped out (i.e. assigned to CSF - see attached). Is it possible to re-include these data in the ODI images?

Thanks again for your help,

John

screenshot from 2018-12-06 13-47-14

robbert-harms commented 5 years ago

Hi John,

Could you perhaps try running the NODDI model fit again but with a noise_std of 1? To my knowledge, last time I checked, the NODDI matlab toolbox fixes the noise_std to 1, probably since estimating the noise std is a bit tricky. MDT takes the approach of trying to estimate the noise standard deviation and using it in the model fitting. This will affect results.

With noise standard deviation I mean the noise in the magnitude reconstructed MR data. By default, MDT uses the OffsetGaussian noise model (see my article http://dx.doi.org/10.1016/j.neuroimage.2017.04.064 for details).

To set the noise standard deviation to 1, in the command line use "--noise-std 1", in the GUI go to "Additional data" and set a 1 in the designated field and using the Python API use

input_data = mdt.load_input_data(..., noise_std=1)

With that set, perhaps that aligns the results?

Best,

Robbert

johnaeanderson commented 5 years ago

Perfect - that fixed it. Incidentally, the area that was dropping out was heavily infiltrated by iron (visible on a T2 weighted image), so perhaps there is something to the idea that the microstructural properties are being altered in this region to be more similar to isotropic.

I really appreciate your help on this,

Best,

John

johnaeanderson commented 5 years ago

Hi Robbert, one last question: how would I update the batch-fit command with this new option? I'm currently running mdt-batch-fit . 'NODDI (Cascade|fixed)' .

Thanks again,

John

robbert-harms commented 5 years ago

Easy, put a file in each subject's folder with the filename "noise_std.txt" and in it put the value 1 .

There was a bug in MDT versions <v0.17.0 though that made it not pick up this file. If you are running an MDT version > 0.17.0 you are good.

Best,

Robbert

johnaeanderson commented 5 years ago

Thanks so much Robbert! And thanks again for creating this tool!