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

Switch to unified view

a b/R/deepbleed.R
1
#' DeepBleed Model
2
#'
3
#' @param outdir Output directory for `DeepBleed` model
4
#'
5
#' @note \url{https://github.com/muschellij2/deepbleed}
6
#'
7
#' @return A list of the output images and predictions.
8
#' @export
9
#' @rdname deepbleed
10
#'
11
#' @examples
12
#' \donttest{
13
#' destfile = file.path(tempdir(), "01.tar.xz")
14
#' dl = download.file(
15
#'   "https://archive.data.jhu.edu/api/access/datafile/1311?gbrecs=true",
16
#'   destfile = destfile)
17
#' res = untar(tarfile = destfile, exdir = tempdir())
18
#' fname = file.path(tempdir(), "01", "BRAIN_1_Anonymized.nii.gz")
19
#' mask = file.path(tempdir(), "01", "BRAIN_1_Anonymized_Mask.nii.gz")
20
#' tdir = tempfile()
21
#' dir.create(tdir)
22
#' download_deepbleed_model(outdir = tdir)
23
#' mod = load_deepbleed_model(outdir = tdir)
24
#' predict_deepbleed(fname, mask = mask, outdir = tdir)
25
#' }
26
download_deepbleed_model = function(outdir = NULL) {
27
  if (is.null(outdir)) {
28
    outdir = system.file(package = "ichseg")
29
  }
30
  fnames = c("_index", "_data-00000-of-00002",
31
             "checkpoint", "_data-00001-of-00002")
32
  real_fnames = sub("_", ".", fnames)
33
34
  outfiles = file.path(outdir, real_fnames)
35
  if (!all(file.exists(outfiles))) {
36
    url = paste0("https://www.dropbox.com/s/v2ptd9mfpo13gcb/",
37
                 "mistie_2-20200122T175000Z-001.zip?dl=1")
38
    tfile = tempfile(fileext = ".zip")
39
    dl = utils::download.file(url, destfile = tfile)
40
41
    ofiles_list = utils::unzip(
42
      tfile,
43
      exdir = outdir,
44
      list = TRUE,
45
      junkpaths = TRUE)
46
    ofiles = utils::unzip(tfile, exdir = outdir, junkpaths = TRUE)
47
    stopifnot(all(basename(ofiles) == fnames))
48
    file.rename(ofiles, outfiles)
49
  }
50
  stopifnot(all(file.exists(outfiles)))
51
52
  outdir = path.expand(outdir)
53
  outdir = normalizePath(outdir)
54
  if (!grepl("/$", outdir)) {
55
    outdir = paste0(outdir, "/")
56
  }
57
  return(outdir)
58
}
59
60
#' @rdname deepbleed
61
#' @export
62
load_deepbleed_model = function(outdir = NULL) {
63
  outdir = download_deepbleed_model(outdir)
64
  path = system.file("deepbleed", package = "ichseg")
65
  if (!requireNamespace("reticulate", quietly = TRUE)) {
66
    stop("You need the reticulate package for deepbleed")
67
  }
68
  model = reticulate::import_from_path("models.vnet", path)
69
  vnet = model$VNet()
70
  vnet$load_weights(outdir)
71
  vnet
72
}
73
74
#' @rdname deepbleed
75
#' @param image image to segment using `DeepBleed` model
76
#' @param mask brain mask image
77
#' @param verbose print diagnostic messages
78
#' @param ... additional arguments to send to
79
#' \code{\link{CT_Skull_Stripper_mask}}
80
#' @export
81
predict_deepbleed = function(image,
82
                             mask = NULL,
83
                             verbose = TRUE,
84
                             ...,
85
                             outdir = NULL) {
86
87
  if (verbose) {
88
    message("Loading DeepBleed Model")
89
  }
90
  L = register_deepbleed(
91
    image = image,
92
    mask = mask,
93
    verbose = verbose,
94
    ...)
95
  image = L$template_space
96
  reg = L$registration
97
  ss = L$skull_stripped
98
  image = array(image, dim = c(1L, dim(image), 1L))
99
100
101
  vnet = load_deepbleed_model(outdir = outdir)
102
  if (verbose) {
103
    message("Prediction")
104
  }
105
106
  prediction = vnet$predict(image)
107
108
  arr = drop(prediction)
109
  arr = neurobase::copyNIfTIHeader(arr =  arr, img = L$template_space)
110
  if (verbose) {
111
    message("Projecting back into Native Space")
112
  }
113
  native = extrantsr::ants_apply_transforms(
114
    fixed = ss,
115
    moving = arr,
116
    interpolator = "nearestNeighbor",
117
    transformlist = reg$invtransforms,
118
    verbose = verbose > 1,
119
    whichtoinvert = 1)
120
  L$registration_matrix = reg$fwdtransforms
121
  L$registration = NULL
122
  L$native_prediction = native
123
  L$template_prediction = arr
124
  return(L)
125
126
}
127
128
#' @rdname deepbleed
129
#' @param interpolator interpolation done for antsApplyTransforms
130
#' @export
131
register_deepbleed = function(
132
  image,
133
  mask = NULL,
134
  verbose = TRUE,
135
  interpolator = "Linear",
136
  ...) {
137
138
  image = check_nifti(image)
139
  if (is.null(mask)) {
140
    if (verbose) {
141
      message("Skull Stripping")
142
    }
143
    mask = CT_Skull_Stripper_mask(image, verbose = verbose, ...)
144
    mask = mask$mask
145
  }
146
  mask = check_nifti(mask)
147
  if (verbose) {
148
    message("Masking Image")
149
  }
150
  ss = mask_img(image, mask)
151
  template.file = system.file(
152
    'scct_unsmooth_SS_0.01_128x128x128.nii.gz',
153
    package = 'ichseg')
154
  if (verbose) {
155
    message("Registration")
156
  }
157
  reg = extrantsr::registration(
158
    ss,
159
    template.file = template.file,
160
    typeofTransform = "Rigid",
161
    affSampling = 64,
162
    interpolator = interpolator,
163
    verbose = verbose > 1)
164
  temp_space = reg$outfile
165
166
  L = list(
167
    skull_stripped = ss,
168
    brain_mask = mask,
169
    template_space = temp_space,
170
    registration = reg
171
  )
172
}