Diff of /R/RIA_lung.R [000000] .. [3b2327]

Switch to unified view

a b/R/RIA_lung.R
1
#' Calculate first-order, GLCM, and/or GLRLM radiomic features on the whole 3D lung
2
#'
3
#' This is a wrapper for \code{RIA} R package. It calculates first-order, GLCM, and/or GLRLM on the whole 3D lung, left and right lungs separately
4
#'
5
#' @param img CT scan in ANTs image file format
6
#' @param mask Mask of CT scan in ANTs image file format
7
#' @param sides Choose to calculate radiomic features on the right and/or left lungs. Note: Right lung = 1, left lung = 2, non-lung = 0
8
#' @param features Type of radiomic features to calculate. Options: first-order, GLCM, and/or GLRLM
9
#' @param bins_in Number of bins to discretize image
10
#' @param equal_prob logical, indicating to cut data into bins with equal relative frequencies.
11
#' If FALSE, then equal interval bins will be used.
12
#' @param distance integer, distance between the voxels being compared.
13
#' @param statistic string, defining the statistic to be calculated on the array of GLCM statistics.
14
#' By default, statistic is set to \emph{"mean"}, however any function may be provided. The proper
15
#' syntax is: function(X, attributes). The supplied string must contain a "X", which will be replaced
16
#' with the array of the GLCM statistics value. Further attributes of the function may also be given.
17
#' For example, if you wish to calculate the median of all GLCMs calculated in different directions,
18
#' then it must be supplied as: \emph{median(X, na.rm = TRUE)}.
19
#' @param verbose_in logical, indicating whether to print detailed information.
20
#' Most prints can also be suppressed using the \code{\link{suppressMessages}} function.
21
#'
22
#' @return list containing the statistical information
23
#' @export
24
# #' @importFrom RIA first_order discretize glcm_all glcm_stat glcm_stat_all glrlm_all glrlm_stat glrlm_stat_all
25
RIA_lung <- function(img,
26
                     mask,
27
                     sides = c("right", "left"),
28
                     features = c('fo', 'glcm', 'glrlm'),
29
                     bins_in = 8,
30
                     equal_prob = FALSE,
31
                     distance = 1,
32
                     statistic = "mean(X, na.rm = TRUE)",
33
                     verbose_in = TRUE){
34
35
  if (!requireNamespace("RIA", quietly = TRUE)) {
36
    stop("RIA package required for RIA_lung")
37
  }
38
  # Loop through mask values
39
  featuresMask <- lapply(sides, function(side){
40
41
    if(side == "right"){mv = 1}
42
    if(side == "left"){mv = 2}
43
44
    # Put image in array format and remove non-mask values
45
    data <- as.array(img)
46
    mask2 <- as.array(mask)
47
    data[mask2 != mv] <- NA
48
49
    # Crop image to speed up computation
50
    test <- apply(data, 1, function(x){sum(x, na.rm=T)})
51
    data <- data[which(test != 0),,]
52
    test <- apply(data, 2, function(x){sum(x, na.rm=T)})
53
    data <- data[,which(test != 0),]
54
    test <- apply(data, 3, function(x){sum(x, na.rm=T)})
55
    data <- data[,,which(test != 0)]
56
57
    ###create RIA_image structure
58
    RIA_image <- list(data = NULL, header = list(), log = list())
59
    if(length(dim(data)) == 3 | length(dim(data)) == 2) {class(RIA_image) <- append(class(RIA_image), "RIA_image")
60
    } else {stop(paste0("ANTsImage LOADED IS ", length(dim(data)), " DIMENSIONAL. ONLY 2D AND 3D DATA ARE SUPPORTED!"))}
61
    RIA_image$data$orig  <- data
62
    RIA_image$data$modif <- NULL
63
    class(RIA_image$header) <- append(class(RIA_image$header), "RIA_header")
64
    class(RIA_image$data) <- append(class(RIA_image$data), "RIA_data")
65
    class(RIA_image$log) <- append(class(RIA_image$log), "RIA_log")
66
    RIA_image$log$events  <- "Created"
67
    RIA_image$log$orig_dim  <- dim(data)
68
69
70
    # Calculate first order radiomic features
71
    if('fo' %in% features){
72
      RIA_image <- RIA::first_order(RIA_image, use_type = "single", use_orig = TRUE, verbose_in = verbose_in)
73
    }
74
75
76
    # Discretize image
77
    if('glcm' %in% features | 'glrlm' %in% features){
78
      RIA_image <- RIA::discretize(RIA_image, bins_in=bins_in, equal_prob = equal_prob, verbose_in = verbose_in)
79
80
      # Calculate GLCM radiomic features
81
      if('glcm' %in% features){
82
        for (i in 1: length(distance)) {
83
          RIA_image <- RIA::glcm_all(RIA_image, use_type = "discretized", distance = distance[i], verbose_in = verbose_in)
84
        }
85
        RIA_image <- RIA::glcm_stat(RIA_image, use_type = "glcm", verbose_in = verbose_in)
86
        RIA_image <- RIA::glcm_stat_all(RIA_image, statistic = statistic, verbose_in = verbose_in)
87
      }
88
89
90
      # Calculate GLRLM radiomic features
91
      if('glrlm' %in% features){
92
        RIA_image <- RIA::glrlm_all(RIA_image, use_type = "discretized", verbose_in = verbose_in)
93
        RIA_image <- RIA::glrlm_stat(RIA_image, use_type = "glrlm", verbose_in = verbose_in)
94
        RIA_image <- RIA::glrlm_stat_all(RIA_image, statistic = statistic, verbose_in = verbose_in)
95
      }else{RIA_image$stat_glrlm_mean <- NULL}
96
    }
97
98
99
    features <- list(first_order = RIA_image$stat_fo$orig,
100
                     glcm = RIA_image$stat_glcm_mean,
101
                     glrlm = RIA_image$stat_glrlm_mean)
102
103
104
    return(features)
105
  })
106
  names(featuresMask) <- sides
107
108
  return(featuresMask)
109
}