ANTsX / ANTsR

R interface to the ANTs biomedical image processing library
https://antsx.github.io/ANTsR
Apache License 2.0
127 stars 35 forks source link

Verifying CAT12 volume and voxel calculations for Neuromorphometrics Atlas using ANTsR labelGeometryMeasures #296

Closed kmarvel54 closed 4 years ago

kmarvel54 commented 4 years ago

Hi ANTsR community,,

CAT12 uses atlas plus defining the regions in an additional csv file. I verified the neuromorphometrics (CAT12) csv file by calculating the geometry of the (Neuromorphometrics atlas), that is volume and voxel using ANTsR, is given below

library(ANTsR)
neuromorphometrics_atlas  <- antsImageRead("neuromorphometrics.nii", dimension=3) 
geom_atlas <-labelGeometryMeasures(neuromorphometrics_atlas)

ANTsR approach is in concordance to CAT12 look up table for only 30 ROIs in terms of the number of voxel and volume. They differ from CAT12 for about 112 regions. The spreadsheet is given in the link below: Checking_cat12_volume_voxel_calculations.

Why the difference in ROI volumes?

Thank you, Kate


ntustison commented 4 years ago

Hi Kate,

That's a really interesting finding. The function labelGeometryMeasures directly uses the ITK program. How are the CAT12 volumes calculated?

Nick

kmarvel54 commented 4 years ago

Hi Nick,

Thank you for your feedback.

I am not sure how CAT12 volumes were calculated. It is not mentioned. Which approach should one use and why? Does it mean the volume calculations between different methods will differ? Please advise me. Thank you very much.

Kate

ntustison commented 4 years ago

If methodology isn't mentioned, I would follow up with the neuromorphetrics people to see if you can find out. As I mentioned, the program we use is a direct interface with the ITK code and that code has been described and vetted for quite some time. Simply based on that information, I'd be more inclined to go with our volumes.

kmarvel54 commented 4 years ago

Thank you very much Nick.

Kate

cookpa commented 4 years ago

It looks like the CAT12 volume is just the sum of the voxels multiplied by the volume of each voxel (0.15^3 cubic centimeters).

The ANTsX implementation will be different because we use the ITK implementation Nick links to above, which aims to measure the volume and surface area of the underlying object.

Separately to this, your voxel counts differ for your CAT12 and my_Voxels columns. I don't know why this is happening, but this is likely the cause of the largest discrepencies.

kmarvel54 commented 4 years ago

That's right Philip. The differences is caused by the voxel counts. I would go for ANTsR since it uses ITK which has been published. Thank you very much.

Kate

cookpa commented 4 years ago

OK, but I would verify that you are getting the voxel counts correct, because that should not vary between implementations. There's no key in your repo to map the label names to the label intensities in the neuromorphometrics.nii, but if you have that, you can also check the voxel counts using ITK-SNAP:

image

ITK-SNAP is also based on ITK so it should agree with ANTs on the voxel counts. The volume may differ because I don't think it uses the same framework as LabelGeometryMeasures.

muschellij2 commented 4 years ago

Should show you the results agree with ITK (in cubic cm, not mm):

library(ANTsRCore)
#> 
#> Attaching package: 'ANTsRCore'
#> The following objects are masked from 'package:stats':
#> 
#>     sd, var
#> The following objects are masked from 'package:base':
#> 
#>     all, any, apply, max, min, prod, range, sum
destfile = file.path(tempdir(), "neuromorphometrics.nii")
if (!file.exists(destfile)) {
    dl = download.file(
        "https://github.com/kmarvel54/Neuro/raw/master/neuromorphometrics.nii",
        destfile = destfile
    )
}
data = readr::read_csv(
    "https://github.com/kmarvel54/Neuro/raw/master/Checking_cat12_volume_voxel_calculations.csv")
#> Parsed with column specification:
#> cols(
#>   Label = col_character(),
#>   CAT12_Voxel = col_double(),
#>   CAT12_Volume = col_double(),
#>   `my_Voxels)` = col_double(),
#>   my_Volume = col_double()
#> )

neuromorphometrics_atlas  <- antsImageRead(destfile)
tab = table(neuromorphometrics_atlas)
df = as.data.frame(tab)
vres = antsGetSpacing(neuromorphometrics_atlas)
vres = prod(vres)/ 1000
df$volume = df$Freq * vres
head(df)
#>   neuromorphometrics_atlas    Freq      volume
#> 1                        0 1520861 5132.905875
#> 2                        1     152    0.513000
#> 3                        2     111    0.374625
#> 4                        3     285    0.961875
#> 5                        4     303    1.022625
#> 6                        5     151    0.509625

Created on 2020-02-24 by the reprex package (v0.3.0.9001)

Session info ``` r sessioninfo::session_info() #> ─ Session info ─────────────────────────────────────────────────────────────── #> setting value #> version R version 3.6.2 (2019-12-12) #> os macOS Mojave 10.14.6 #> system x86_64, darwin15.6.0 #> ui X11 #> language (EN) #> collate en_US.UTF-8 #> ctype en_US.UTF-8 #> tz America/Edmonton #> date 2020-02-24 #> #> ─ Packages ─────────────────────────────────────────────────────────────────── #> package * version date lib source #> ANTsRCore * 0.7.3.1 2020-02-21 [1] local #> assertthat 0.2.1 2019-03-21 [1] CRAN (R 3.6.0) #> backports 1.1.5 2019-10-02 [1] CRAN (R 3.6.0) #> cli 2.0.1 2020-01-08 [1] CRAN (R 3.6.0) #> crayon 1.3.4 2017-09-16 [1] CRAN (R 3.6.0) #> curl 4.3 2019-12-02 [1] CRAN (R 3.6.0) #> digest 0.6.25 2020-02-23 [1] CRAN (R 3.6.0) #> evaluate 0.14 2019-05-28 [1] CRAN (R 3.6.0) #> fansi 0.4.1 2020-01-08 [1] CRAN (R 3.6.0) #> fs 1.3.1 2019-05-06 [1] CRAN (R 3.6.0) #> glue 1.3.1 2019-03-12 [1] CRAN (R 3.6.0) #> highr 0.8 2019-03-20 [1] CRAN (R 3.6.0) #> hms 0.5.3 2020-01-08 [1] CRAN (R 3.6.0) #> htmltools 0.4.0 2019-10-04 [1] CRAN (R 3.6.0) #> ITKR 0.5.2 2020-02-20 [1] Github (stnava/ITKR@fe97efa) #> knitr 1.28 2020-02-06 [1] CRAN (R 3.6.0) #> lattice 0.20-38 2018-11-04 [1] CRAN (R 3.6.2) #> magrittr 1.5 2014-11-22 [1] CRAN (R 3.6.0) #> Matrix 1.2-18 2019-11-27 [1] CRAN (R 3.6.2) #> pillar 1.4.3 2019-12-20 [1] CRAN (R 3.6.0) #> pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 3.6.0) #> purrr 0.3.3 2019-10-18 [1] CRAN (R 3.6.0) #> R6 2.4.1 2019-11-12 [1] CRAN (R 3.6.0) #> Rcpp 1.0.3 2019-11-08 [1] CRAN (R 3.6.2) #> RcppEigen 0.3.3.7.0 2019-11-16 [1] CRAN (R 3.6.0) #> readr 1.3.1 2018-12-21 [1] CRAN (R 3.6.0) #> reprex 0.3.0.9001 2020-01-05 [1] Github (tidyverse/reprex@5ae0b29) #> rlang 0.4.4 2020-01-28 [1] CRAN (R 3.6.0) #> rmarkdown 2.1 2020-01-20 [1] CRAN (R 3.6.0) #> rstudioapi 0.11.0-9000 2020-02-19 [1] Github (rstudio/rstudioapi@deb9c47) #> sessioninfo 1.1.1 2018-11-05 [1] CRAN (R 3.6.0) #> stringi 1.4.6 2020-02-17 [1] CRAN (R 3.6.0) #> stringr 1.4.0 2019-02-10 [1] CRAN (R 3.6.0) #> styler 1.3.2 2020-02-23 [1] CRAN (R 3.6.2) #> tibble 2.1.3 2019-06-06 [1] CRAN (R 3.6.0) #> vctrs 0.2.3 2020-02-20 [1] CRAN (R 3.6.0) #> withr 2.1.2 2018-03-15 [1] CRAN (R 3.6.0) #> xfun 0.12 2020-01-13 [1] CRAN (R 3.6.0) #> yaml 2.2.1 2020-02-01 [1] CRAN (R 3.6.0) #> #> [1] /Library/Frameworks/R.framework/Versions/3.6/Resources/library ```
kmarvel54 commented 4 years ago

Hi Philip,

Thank you very much for confirming the results using ITK-SNAP. I have added an updated version of the file, which contains the index for the region of interest. You first 12 ITK-SNAP results is in concondance with the ANTsR csv spreadsheet. See the csv file in

Checking_cat12_volume_voxel_calculations Version 2.

Thanks,

Kate

kmarvel54 commented 4 years ago

Absolutely correct. Thank you very much John.

stnava commented 4 years ago

thanks everyone - while this seems a relatively easy case, it's demonstrably not trivial to have a deeply validated framework like this ( ITK => ANTs/ITK-SNAP => ANTsX ) against which to compare other measurements. thanks to @kmarvel54 for asking for help/clarification on this. I think we've been under-selling this aspect of the framework for a long time.

stnava commented 4 years ago

+R of course.

kmarvel54 commented 4 years ago

Thank you all for the great help and discussion. K