Diff of /R/ich_predict.R [000000] .. [242173]

Switch to unified view

a b/R/ich_predict.R
1
#' @title Predict ICH Images
2
#' @description This function will take the data.frame of predictors and
3
#' predict the ICH voxels from the model chosen.
4
#'
5
#' @param df \code{\link{data.frame}} of predictors.  If \code{multiplier}
6
#' column does not exist, then \code{\link{ich_candidate_voxels}} will
7
#' be called
8
#' @param nim object of class \code{\link{nifti}}, from
9
#' \code{\link{make_predictors}}
10
#' @param model model to use for prediction,
11
#' either the random forest (rf) or logistic
12
#' @param verbose Print diagnostic output
13
#' @param native Should native-space predictions be given?
14
#' @param native_img object of class \code{\link{nifti}}, which
15
#' is the dimensions of the native image
16
#' @param transformlist Transforms list for the transformations back to native space.
17
#' NOTE: these will be inverted.
18
#' @param interpolator Interpolator for the transformation back to native space
19
#' @param native_thresh Threshold for re-thresholding binary mask after
20
#' interpolation
21
#' @param shiny Should shiny progress be called?
22
#' @param model_list list of model objects, used mainly for retraining
23
#' but only expert use.
24
#' @param smoothed_cutoffs A list with an element
25
#' \code{mod.dice.coef}, only expert use.
26
#' @param outfile filename for output file.
27
#' We write the smoothed, thresholded image.  If \code{native = TRUE},
28
#' then the file will be native space, otherwise in registered
29
#' space
30
#' @param ... Additional options passsed to \code{\link{ich_preprocess}}
31
#'
32
#' @return List of output registered and native space
33
#' prediction/probability images
34
#' @importFrom neurobase remake_img
35
#' @importFrom extrantsr ants_bwlabel
36
#' @import randomForest
37
#' @seealso \code{\link{ich_candidate_voxels}}
38
#' @export
39
ich_predict = function(df,
40
                       nim,
41
                       model = c("rf", "logistic", "big_rf"),
42
                       verbose = TRUE,
43
                       native = TRUE,
44
                       native_img = NULL,
45
                       transformlist = NULL,
46
                       interpolator = NULL,
47
                       native_thresh = 0.5,
48
                       shiny = FALSE,
49
                       model_list = NULL,
50
                       smoothed_cutoffs = NULL,
51
                       outfile = NULL,
52
                       ...) {
53
54
  # if (!have_matlab()) {
55
  #   stop("MATLAB Path not defined!")
56
  # }
57
58
  if (is.null(outfile)) {
59
    outfile = tempfile(fileext = ".nii.gz")
60
  }
61
  cn = colnames(df)
62
  if (!("multiplier" %in% cn)) {
63
    df$multiplier = ich_candidate_voxels(df)
64
  }
65
  df$Y = NULL
66
  cc = complete.cases(df)
67
  if (!all(cc)) {
68
    warning("NAs or missing in DF, removing")
69
    for (icn in seq(ncol(df))) {
70
      x = df[, icn]
71
      if (!(class(x) %in% c("factor", "character"))) {
72
        x[ !is.finite(x) ] = 0
73
      }
74
      df[, icn] = x
75
    }
76
  }
77
  msg = "# Making Prediction"
78
  if (verbose) {
79
    message(msg)
80
  }
81
  if (shiny) {
82
    shiny::incProgress(message = msg)
83
  }
84
  env = as.environment("package:ichseg")
85
86
  # Getting modlist for model and cutoff
87
  if (is.null(model_list)) {
88
    modlist.name = paste0(model, "_modlist")
89
    modlist = env[[modlist.name]]
90
  } else {
91
    modlist = model_list
92
  }
93
  mod = modlist$mod
94
  cutoff = modlist$mod.dice.coef[1, "cutoff"]
95
96
  rm(list = c("modlist"))
97
98
  # Getting smoothed cutoff
99
  if (is.null(smoothed_cutoffs)) {
100
    smoothed_name = paste0("smoothed_", model, "_cutoffs")
101
    scutoffs = env[[smoothed_name]]
102
  } else {
103
    scutoffs = smoothed_cutoffs
104
  }
105
106
  smoothed_cutoff = scutoffs$mod.dice.coef[1, "cutoff"]
107
  rm(list = c("scutoffs", "smoothed_name"))
108
109
  p = switch(model,
110
             rf = predict(mod,
111
                          newdata = df[ df$multiplier, ],
112
                          type = "prob")[, "1"],
113
             big_rf = predict(mod,
114
                              newdata = df[ df$multiplier, ],
115
                              type = "prob")[, "1"],
116
             logistic = predict(mod,
117
                                df[ df$multiplier, ],
118
                                type = "response"))
119
  msg = "# Making Prediction Image"
120
  if (verbose) {
121
    message(msg)
122
  }
123
  nim = check_nifti(nim)
124
  mult_img = niftiarr(nim, df$multiplier)
125
126
  # p = predict(mod, df[ df$multiplier, ], type = "response")
127
  pimg = remake_img(p,
128
                    nim,
129
                    mult_img)
130
131
  mask = niftiarr(nim, df$mask)
132
  pimg = mask_img(pimg, mask)
133
  msg = "# Smoothing Image"
134
  if (verbose) {
135
    message(msg)
136
  }
137
  sm.pimg  = mean_image(pimg,
138
                        nvoxels = 1,
139
                        verbose = verbose)
140
  sm.pimg[abs(sm.pimg) <
141
            .Machine$double.eps ^ 0.5 ] = 0
142
  sm.pimg = niftiarr(nim, sm.pimg)
143
  sm.pimg[is.na(sm.pimg)] = 0
144
145
146
  sm.pred = sm.pimg > smoothed_cutoff
147
  pred = pimg > cutoff
148
149
  msg = "# Connected Components"
150
  if (verbose) {
151
    message(msg)
152
  }
153
  # cc = spm_bwlabel(pred, k = 100)
154
  # scc = spm_bwlabel(sm.pred, k = 100)
155
  cc = ants_bwlabel(img = pred, k = 100, binary = TRUE)
156
  scc = ants_bwlabel(img = sm.pred, k = 100, binary = TRUE)
157
158
  ##############################################################
159
  # Back to Native Space!
160
  ##############################################################
161
  res = list(
162
    prediction_image = cc,
163
    smoothed_prediction_image = scc,
164
    probability_image = pimg,
165
    smoothed_probability_image = sm.pimg)
166
167
  ##############################################################
168
  # Inverted!
169
  ##############################################################
170
  native_res = NULL
171
  if (native) {
172
    msg = "# Projecting back to Native Space"
173
    if (verbose) {
174
      message(msg)
175
    }
176
    stopifnot(!is.null(interpolator))
177
    stopifnot(!is.null(transformlist))
178
    native_res = lapply(res, function(x){
179
      ants_apply_transforms(fixed = native_img,
180
                            moving = x,
181
                            transformlist = transformlist,
182
                            interpolator = interpolator,
183
                            whichtoinvert = c(1)
184
      )
185
    })
186
    native_res$smoothed_prediction_image = neurobase::datatyper(
187
      native_res$smoothed_prediction_image > native_thresh
188
    )
189
    native_res$prediction_image = neurobase::datatyper(
190
      native_res$prediction_image > native_thresh
191
    )
192
    writenii(native_res$smoothed_prediction_image, outfile)
193
  } else {
194
    writenii(res$smoothed_prediction_image, outfile)
195
  }
196
  res$cutoff = cutoff
197
  res$smoothed_cutoff = smoothed_cutoff
198
199
  L = list(registered_prediction = res)
200
  L$native_prediction = native_res
201
  L$outfile = outfile
202
  return(L)
203
}