nipy / mindboggle

Automated anatomical brain label/shape analysis software (+ website)
http://mindboggle.info
Other
143 stars 54 forks source link

Add ANTs LabelGeometryMeasures for volume stats per label #151

Closed binarybottle closed 5 years ago

binarybottle commented 6 years ago

As suggested by @satra and @ntustison in issue @150, we could add volume stats per label computed by LabelGeometryMeasures in ANTs.

@ntustison -- Why would I be getting the following error from the T1 and labeled version of the same?:

jovyan@76e723833dac:~/work$ LabelGeometryMeasures 3 /home/jovyan/work/CBIC/5545866_T1w_VNavNorm/mindboggle123_output/mindboggled/5545866_VNavNorm/labels/freesurfer_wmparc_labels_in_hybrid_graywhite.nii.gz /home/jovyan/work/Desktop/CBIC/5545866_T1w_VNavNorm/t1.nii.gz terminate called after throwing an instance of 'itk::ExceptionObject' what(): /opt/ANTs/build/ITKv4-install/include/ITK-4.11/itkImageToImageFilter.hxx:250: itk::ERROR: LabelGeometryImageFilter(0x3791490): Inputs do not occupy the same physical space! InputImage Origin: [9.8958282e+01, 1.1097722e+02, -9.7684586e+01], InputImage_1 Origin: [9.8958290e+01, 1.1097722e+02, -9.7684586e+01] Tolerance: 1.0000061e-06

Aborted

ntustison commented 6 years ago

The first element of the origins are different hence "They don't occupy the same physical space." This is an ITK requirement and somewhere during your processing the origins ended up changing due to, I'm guessing, floating point precision. We end up using CopyImageHeaderInformation during antsCorticalThickness.sh quite a bit to avoid this error popping up.

binarybottle commented 6 years ago

Thanks, @ntustison! It's been a while since I've used CopyImageHeaderInformation. What am I doing wrong in the following?:

jovyan@76e723833dac:~/work$ CopyImageHeaderInformation cbic_t1.nii.gz cbic_labels.nii.gz cbic_labels_t1hdr.nii.gz
jovyan@76e723833dac:~/work$ LabelGeometryMeasures 3 cbic_labels_t1hdr.nii.gz cbic_t1.nii.gz cbic_labelgeometrymeasures.csv
terminate called after throwing an instance of 'itk::ExceptionObject'
  what():  /opt/ANTs/build/ITKv4-install/include/ITK-4.11/itkImageToImageFilter.hxx:250:
itk::ERROR: LabelGeometryImageFilter(0x28f1610): Inputs do not occupy the same physical space! 
InputImage Origin: [9.8958282e+01, 1.1097722e+02, -9.7684586e+01], InputImage_1 Origin: [9.8958290e+01, 1.1097722e+02, -9.7684586e+01]
    Tolerance: 1.0000061e-06

Aborted
ntustison commented 6 years ago

Try

$ CopyImageHeaderInformation cbic_t1.nii.gz cbic_labels.nii.gz cbic_labels_t1hdr.nii.gz 1 1 1
binarybottle commented 6 years ago

Thank you. The output volume looks fine, but why are the label numbers in the csv file all over the place?:

Label

2 24 245 2457 24578 2457810 245781011 2.4578E+10 2.4578E+12 2.4578E+14 2.4578E+16 2.4578E+18 2.4578E+20 ...

ntustison commented 6 years ago

I have no idea. You should check the content of your images.

binarybottle commented 6 years ago

Very odd. I get weird labels in the csv file using the command:

CopyImageHeaderInformation ru_t1.nii.gz ru_labels_t1hdr.nii.gz 1 1 1
LabelGeometryMeasures 3 ru_labels_t1hdr.nii.gz ru_t1.nii.gz ru_labelgeometrymeasures.csv

But using the same CopyImageHeaderInformation output file, I get proper labels in stdout using the command:

LabelGeometryMeasures 3 ru_labels_t1hdr.nii.gz`

Hey, does LabelGeometryMeasures compute surface area in the same way as LabelThickness2? Can I generate LabelThickness2 values by dividing LabelGeometryMeasures Volume(voxels) by SurfArea(mm^2)?

ntustison commented 6 years ago

Hey, does LabelGeometryMeasures compute surface area in the same way as LabelThickness2? Can I generate LabelThickness2 values by dividing LabelGeometryMeasures Volume(voxels) by SurfArea(mm^2)?

Yes. I don't ever use LabelThickness2 but rather use LabelGeometryMeasures to keep all that info.

binarybottle commented 6 years ago

Good to know! Thank you, Nick! In that case I have GOT to include LabelGeometryMeasures output with output from the mindboggle123 pipeline, once I figure out how to get sensible label values!

ntustison commented 6 years ago

I noticed you didn't link this plot. Did you ever see it? One of the metrics for our 2014 cortical thickness paper was age prediction. In the paper we only show mean squared error of the FreeSurfer vs. ANTs prediction results for 1000 training/testing data permutations. The plot linked to above was also made including the results of ATITH relative to the two others. I guess you didn't as that would've been something compelling to include in your paper.

binarybottle commented 6 years ago

I definitely don't remember seeing this plot! Thank you for sharing.

I assume that these predictions were made on region-based thickness, not locally (vertex-wise or voxel-wise), correct? If so, how did you generate a single thickness measure per region for ANTs, given that antsCorticalThickness.sh generates an image volume with a different value per voxel?

ntustison commented 6 years ago

I assume that these predictions were made on region-based thickness, not locally (vertex-wise or voxel-wise), correct? If so, how did you generate a single thickness measure per region for ANTs, given that antsCorticalThickness.sh generates an image volume with a different value per voxel?

joint label fusion + DKT labels

binarybottle commented 6 years ago

So that's how you established the labeled regions, but how did you compute a single thickness measure per region from Direct/KellySlater/KellyKapowski? Did you simply take the average across all voxels in the region?

ntustison commented 6 years ago

Did you simply take the average across all voxels in the region?

Yes.

binarybottle commented 6 years ago

If according to the plot you shared above this average thickness value per region is a better predictor of age, gender, etc. than the LabelThickness2 (= LabelGeometryMeasures vol/surf ratio), then why isn't this measure included in the LabelGeometryMeasures output table?

ntustison commented 6 years ago

Good software engineering decisions consider more than single-use cases. All the existing measurements precisely map between their values and common everyday usage in terms of language. That's not the case with LabelThickness? which is more a surrogate measure for actual thickness (albeit a really good one). That could mislead the naive user. For the more knowledgeable user, those surrogate thickness values are easily available from the columns of the existing table.

binarybottle commented 6 years ago

Perhaps I wasn't clear. I was asking why the average KellyKapowski measure per region isn't included in the LabelGeometryMeasures output table, not why the LabelGeometryMeasures vol/surf ratio isn't included as a column in the output table. The voxel-wise KellyKapowski measures are not in the table, only in the volume image, so there's no way to derive the average KellyKapowski value per region from the table. If this value is a better predictor than FreeSurfer's thickness (averaged over all voxels in a label) or LabelThickness2, then why not include it?

ntustison commented 6 years ago

Thanks for the clarification. So the same general motivation "good software engineering decisions" applies. LabelGeometryMeasures is a simple program which mainly takes a single input and provides as output, almost instantaneously, a set of measurements. Adding KK output capabilities would significantly change (i.e., complicate) that.

binarybottle commented 6 years ago

Makes perfect sense not to complicate the LabelGeometryMeasures function.

Since mindboggle123 runs antsCorticalThickness.sh, should I include in mindboggle123 output tables average KellyKapowski measures, LabelGeometryMeasures vol/surf measures, or both?

ntustison commented 6 years ago

It's been a long time since I've looked at mindboggle so I don't really have an opinion.

binarybottle commented 6 years ago

That's cool. Since people use mindboggle output for prediction, I'll give them both, the whole table, and the kitchen sink, to boot!

Thank you very much for clarifying the relationships between LabelGeometryMeasures, LabelThickness2, and KellyKapowski!

binarybottle commented 6 years ago

Oh, and what's the easiest way to get the average KellyKapowski values? Do you already compute it when running antsCT and store it somewhere, or should I run?:

ImageMath 3 output.csv ROIStatistics roinames.txt LabelImage.nii.gz ValueImage.nii.gz

If yes to the above command, how do I format roinames.txt?

ntustison commented 6 years ago

You can use that. I don't use it but I would imagine roinames.txt is simply a text file where each row is the label name for that specific row. You'd have to ask Brian.

Be sure to mask out the non-zero thickness values as your KK thickness map won't necessarily line up with the joint label fusion output.

binarybottle commented 5 years ago

@satra -- Shall I close this issue now that you've added nipype's LabelGeometry (= ants LabelGeometryMeasures)?

satra commented 5 years ago

@binarybottle - indeed - closed by #156