a b/R/make_predictors.R
1
#' @title Make CT Predictors
2
#'
3
#' @description Create a set of predictors for ICH segmentation
4
#' for CT
5
#' @param img Filename of image intensities
6
#' @param mask Filename of brain mask
7
#' @param roi Filename of ROI for Y
8
#' @param nvoxels Voxel neighborhood
9
#' @param moments Moments of neighborhood to take
10
#' @param center Center the moments
11
#' @param lthresh Lower threshold for neighborhood setting
12
#' @param uthresh Upper threshold for neighborhood setting
13
#' @param sigmas Sigma values for Gaussian smoothed images (in mm)
14
#' @param save_imgs Logical to save all images that are created as
15
#' predictors
16
#' @param outdir Output directory of saved images, needs to be set
17
#' if \code{save_imgs = TRUE}
18
#' @param stub Basename to write image names if \code{save_imgs = TRUE}
19
#' @param overwrite If \code{save_imgs} is \code{TRUE},
20
#' then should
21
#' the files be overwritten?  If not, then files will be read
22
#' instead instead of code being re-run.
23
#' @param template.file Template to register to (CT Template)
24
#' @param mean.img Mean image in template space for z-scoring
25
#' @param sd.img SD image in template space for z-scoring
26
#' @param zscore.typeofTransform type of transform for z-scoring
27
#' @param zscore.interpolator type of interpolator for z-scoring
28
#' @param flip.typeofTransform type of transform for flipped difference
29
#' @param flip.interpolator type of interpolator for flipped difference
30
#' @param low_thresh Threshold for forcing values to zero
31
#' @param verbose Logical indicator if output messages should be
32
#' printed
33
#' @param shiny Should shiny progress be called?
34
#' @param erode_mask Should the brain mask be eroded?
35
#' @param ... options passed to \code{\link{get_neighbors}}
36
#' @importFrom neurobase readnii checkimg zscore_img finite_img
37
#' @importFrom fslr fslerode fsl_smooth
38
#' @importFrom oro.nifti zero_trans cal_img voxdim pixdim convert.datatype convert.bitpix
39
#' @importFrom extrantsr zscore_template otropos reg_flip perona_malik
40
#' @importFrom stats sd quantile predict complete.cases
41
#' @export
42
#' @return List of a data.frame of Predictors and set of
43
#' indices to
44
#' keep in mask and an empty nifti object for plotting.
45
#' Also the number of voxels of the roi that were not in the
46
#' mask
47
make_predictors <- function(img, mask, roi = NULL,
48
                            nvoxels = 1, moments = 1:4,
49
                            center = c(FALSE, TRUE, TRUE, TRUE),
50
                            lthresh = 40, uthresh = 80,
51
                            sigmas = c(5, 10, 20),
52
                            save_imgs = TRUE,
53
                            outdir = NULL,
54
                            stub = NULL,
55
                            overwrite = FALSE,
56
                            template.file = system.file(
57
                              "scct_unsmooth_SS_0.01.nii.gz",
58
                              package = "ichseg"),
59
                            mean.img = system.file(
60
                              "Mean_Image.nii.gz",
61
                              package = "ichseg"),
62
                            sd.img = system.file(
63
                              "SD_Image.nii.gz",
64
                              package = "ichseg"),
65
                            zscore.typeofTransform = "SyN",
66
                            zscore.interpolator = "Linear",
67
                            flip.typeofTransform = "Affine",
68
                            flip.interpolator = "LanczosWindowedSinc",
69
                            low_thresh = 1e-13,
70
                            verbose= TRUE,
71
                            shiny = FALSE,
72
                            erode_mask = TRUE,
73
                            ...) {
74
  make_fname = function(addstub){
75
    fname = addstub
76
    fname = file.path(outdir, paste0(stub, "_", fname, ".nii.gz"))
77
    fname
78
  }
79
80
  write_img = function(arr, addstub){
81
    fname = addstub
82
    fname = file.path(outdir, paste0(stub, "_", fname))
83
    if ( !inherits( arr, "nifti")){
84
      mom = nim
85
      mom@.Data = array(arr, dim = dim(mom))
86
    } else {
87
      mom = arr
88
    }
89
    mom = cal_img(mom)
90
    mom = zero_trans(mom)
91
    mom = datatyper(mom,
92
                    datatype = convert.datatype()$FLOAT32,
93
                    bitpix = convert.bitpix()$FLOAT32)
94
    writenii(mom, filename = fname)
95
  }
96
97
98
  make_moment_list = function(){
99
    mom.exist = sapply(moments, function(moment){
100
      addstub = paste0("moment", moment)
101
      fname = make_fname(addstub)
102
      file.exists(fname)
103
    })
104
105
    ### if all data does not exist or rewrite - remake data
106
    if (!all(mom.exist) | overwrite) {
107
      msg = "# Running Local_Moment"
108
      if (verbose){
109
        message(msg)
110
      }
111
      if (shiny) {
112
        shiny::incProgress(message = msg, amount = 0.02)
113
      }
114
      moms = local_moment(
115
        img,
116
        mask = mask,
117
        nvoxels = nvoxels,
118
        moment = moments, center = center,
119
        invert = FALSE,
120
        ...)
121
      if (save_imgs) {
122
        for (imom in seq_along(moments)) {
123
          moment = moments[imom]
124
          addstub = paste0("moment", moment)
125
          fname = make_fname(addstub)
126
          mom.img = moms[[imom]]
127
          write_img(mom.img, addstub)
128
        }
129
      }
130
    }
131
    ### if all data exists and not to rewrite - just read in
132
    if (all(mom.exist) & !overwrite) {
133
      moms = lapply(moments, function(moment){
134
        addstub = paste0("moment", moment)
135
        fname = make_fname(addstub)
136
        mom.img = readnii(fname, reorient = FALSE)
137
        return(mom.img)
138
      })
139
    }
140
    msg = "# Creating Moment Matrix"
141
    if (verbose) {
142
      message(msg)
143
    }
144
    if (shiny) {
145
      shiny::incProgress(message = msg, amount = 0.02)
146
    }
147
    mat = matrix(NA,
148
                 ncol = length(moms),
149
                 nrow = prod(dim(mask))
150
    )
151
    for (imom in seq_along(moms)) {
152
      mat[, imom] = c(moms[[imom]])
153
    }
154
    # moms = sapply(moms, c)
155
    rm(list = "moms"); gc(); gc();
156
    colnames(mat) = paste0("moment", moments)
157
    mat = as.data.frame(mat)
158
    return(mat)
159
  }
160
161
  img.fname = checkimg(img)
162
  img = check_nifti(img)
163
164
  mask.fname = checkimg(mask)
165
  orig.mask = mask = check_nifti(mask)
166
167
  if (!is.null(roi)) {
168
    #     roi.fname = roi
169
    roi = check_nifti(roi)
170
  }
171
172
  # stopifnot(class(roi) == "character")
173
  #   stopifnot(class(img) == "character")
174
  #   stopifnot(class(mask) == "character")
175
176
177
  if (save_imgs){
178
    stopifnot(!is.null(outdir))
179
    stopifnot(!is.null(stub))
180
  }
181
  if (is.null(outdir)){
182
    outdir = tempdir()
183
  }
184
  if (is.null(stub)){
185
    stub = nii.stub(img.fname, bn = TRUE)
186
  }
187
188
  msg = "# Reading Images"
189
  if (verbose) {
190
    message(msg)
191
  }
192
  if (shiny) {
193
    shiny::incProgress(message = msg, amount = 0.02)
194
  }
195
  # img = readnii(img.fname, reorient= FALSE)
196
  orig.img = img
197
  # stub = nii.stub(img.fname, bn=TRUE)
198
199
  nim = niftiarr(img, array(NA, dim = dim(orig.img)))
200
  nim = datatyper(nim,
201
                  datatype = convert.datatype()$FLOAT32,
202
                  bitpix = convert.bitpix()$FLOAT32)
203
  dimg = dim(nim)
204
  vdim = voxdim(nim)
205
206
  #   if (is.null(roi)){
207
  #     roi = niftiarr(img, array(0, dim = dim(nim)))
208
  #   }
209
210
  msg = "# Eroding Mask"
211
  addstub = "usemask"
212
  fname = make_fname(addstub)
213
214
  if (verbose) {
215
    message(msg)
216
  }
217
  if (shiny) {
218
    shiny::incProgress(message = msg, amount = 0.02)
219
  }
220
221
  if (file.exists(fname) & !overwrite){
222
    mask = readnii(fname, reorient = FALSE)
223
  } else {
224
    if (erode_mask) {
225
      # erode the mask
226
      mask = fslerode(file = mask.fname,
227
                      kopts = "-kernel box 3x3x1",
228
                      reorient = FALSE, retimg = TRUE,
229
                      verbose = verbose > 1)
230
    } else {
231
      mask = readnii(mask.fname)
232
    }
233
    #### may add this - think about it
234
    #     mask = fslfill(mask, bin=TRUE, retimg = TRUE)
235
    mask = mask > 0
236
    mask = datatyper(mask)
237
    if (save_imgs){
238
      write_img(mask, addstub)
239
    }
240
  }
241
242
  if (sum(mask) == 0) {
243
    msg = paste0(
244
      "Eroded mask is empty! Something went wrong with eroding ",
245
      "or Skull stripping")
246
    stop(msg)
247
  }
248
  orig.masked.img = mask_img(orig.img, orig.mask)
249
  masked.img = mask_img(orig.img, mask)
250
  if (!is.null(roi)){
251
    miss.roi = sum(mask == 0 & roi > 0 )
252
  } else {
253
    miss.roi = NULL
254
  }
255
256
257
  keep.ind = which(mask > 0)
258
259
  msg = "# Getting Moments"
260
  if (verbose) {
261
    message(msg)
262
  }
263
  if (shiny) {
264
    shiny::incProgress(message = msg, amount = 0.02)
265
  }
266
  ################################################
267
  # Making Moment Images
268
  ################################################
269
270
  df = make_moment_list()
271
  ###########
272
  # Creating Skew/Kurtosis
273
  ###########
274
  df$skew = df$moment3/df$moment2 ^ {3/2}
275
  df$kurtosis = df$moment4/df$moment2 ^ {2}
276
  df$moment3 = df$moment4 = NULL
277
278
  ###########
279
  # Writing Skew
280
  ###########
281
  addstub = "skew"
282
  fname = make_fname(addstub)
283
  if (file.exists(fname) & !overwrite) {
284
285
  } else {
286
    skew = niftiarr(img, df$skew)
287
    if (save_imgs) {
288
      write_img(skew, addstub)
289
    }
290
    rm(list = c("skew")); gc(); gc();
291
  }
292
293
  ###########
294
  # Writing Kurtosis
295
  ###########
296
  addstub = "kurtosis"
297
  fname = make_fname(addstub)
298
  if (file.exists(fname) & !overwrite) {
299
300
  } else {
301
    kurtosis = niftiarr(img, df$kurtosis)
302
    if (save_imgs) {
303
      write_img(kurtosis, addstub)
304
    }
305
    rm(list = c("kurtosis")); gc(); gc();
306
  }
307
308
  ################################################
309
  # Making Percent threshold image
310
  ################################################
311
  msg = paste0("# Getting thresholded from ",
312
               lthresh, " to ", uthresh, "\n")
313
  if (verbose) {
314
    message(msg)
315
  }
316
  if (shiny) {
317
    shiny::incProgress(message = msg, amount = 0.02)
318
  }
319
  addstub = paste0("thresh_", lthresh, "_", uthresh)
320
  fname = make_fname(addstub)
321
  if (file.exists(fname) & !overwrite){
322
    thresh_img = readnii(fname, reorient=FALSE)
323
  } else {
324
    thresh_img = niftiarr(img, img >= lthresh & img <= uthresh)
325
    if (save_imgs){
326
      write_img(thresh_img, addstub)
327
    }
328
  }
329
330
  df$value = c(masked.img)
331
  df$thresh = c(thresh_img)
332
333
  cn = colnames(df)
334
335
  ################################################
336
  # Making Z-score Images
337
  ################################################
338
  msg = "# Getting Z-scored images"
339
  if (verbose) {
340
    message(msg)
341
  }
342
  if (shiny) {
343
    shiny::incProgress(message = msg, amount = 0.02)
344
  }
345
  zimgs = lapply(1:3, function(i){
346
    addstub = paste0("zscore", i)
347
    fname = make_fname(addstub)
348
    if (file.exists(fname) & !overwrite){
349
      img = readnii(fname, reorient=FALSE)
350
    } else {
351
      img = zscore_img(masked.img, mask = mask, margin = i)
352
      if (save_imgs){
353
        write_img(img, addstub)
354
      }
355
    }
356
    return(img)
357
  })
358
  zimgs = sapply(zimgs, c)
359
  colnames(zimgs) = paste0("zscore", 1:3)
360
  zimgs = as.data.frame(zimgs)
361
  for (i in 1:3) {
362
    df[,  paste0("zscore", i)] = zimgs[, paste0("zscore", i)]
363
  }
364
  rm(list = c("zimgs")); gc(); gc();
365
366
  #   wmean2 = function(img, mask, trim = 0.2){
367
  #     x = img[ mask == 1]
368
  #     mn = psych::winsor.mean(x, trim = trim)
369
  #     s = psych::winsor.sd(x, trim = trim)
370
  #     z = (x-mn)/s
371
  #     img[mask == 1] = z
372
  #     img[mask == 0] = 0
373
  #     img = cal_img(img)
374
  #     return(img)
375
  #   }
376
377
  wmean = function(img, mask, trim = 0.2){
378
    x = img[ mask == 1 ]
379
    stopifnot(length(trim) == 1)
380
    stopifnot(trim > 0)
381
    stopifnot(trim <= 0.5)
382
    qtrim <- quantile(x,
383
                      c(trim, 0.5, 1 - trim),
384
                      na.rm = TRUE)
385
    xbot <- qtrim[1]
386
    xtop <- qtrim[3]
387
388
    if (trim < 0.5) {
389
      x[x < xbot] <- xbot
390
      x[x > xtop] <- xtop
391
    } else {
392
      x[!is.na(x)] <- qtrim[2]
393
    }
394
395
    mn = mean(x, na.rm=TRUE)
396
    s = sd(x, na.rm=TRUE)
397
    img = (img-mn)/s
398
    img = mask_img(img, mask)
399
    img = finite_img(img)
400
    return(img)
401
  }
402
403
  msg = "# Getting Winsorized Image"
404
  if (verbose) {
405
    message(msg)
406
  }
407
  if (shiny) {
408
    shiny::incProgress(message = msg, amount = 0.02)
409
  }
410
  addstub = paste0("win_z")
411
  fname = make_fname(addstub)
412
  if (file.exists(fname) & !overwrite){
413
    wmean_img = readnii(fname, reorient=FALSE)
414
  } else {
415
    wmean_img = wmean(orig.img, mask = mask, trim = 0.2)
416
    if (save_imgs){
417
      write_img(wmean_img, addstub)
418
    }
419
  }
420
  df$win_z = c(wmean_img)
421
  rm(list = c("wmean_img")); gc(); gc();
422
423
  ################################################
424
  # Making Percent threshold image
425
  ################################################
426
  msg = paste0("# Getting Percent thresholded from ",
427
               lthresh, " to ", uthresh)
428
  if (verbose) {
429
    message(msg)
430
  }
431
  if (shiny) {
432
    shiny::incProgress(message = msg, amount = 0.02)
433
  }
434
  addstub = paste0("pct_thresh_", lthresh, "_", uthresh)
435
  fname = make_fname(addstub)
436
  if (file.exists(fname) & !overwrite){
437
    pct_thresh = readnii(fname, reorient=FALSE)
438
  } else {
439
    pct_thresh = local_moment(thresh_img, mask = mask,
440
                              nvoxels = nvoxels,
441
                              moment = 1, center = FALSE,
442
                              ...)[[1]]
443
    if (save_imgs){
444
      write_img(pct_thresh, addstub)
445
    }
446
  }
447
448
  df$pct_thresh = c(pct_thresh)
449
  rm(list = c("thresh_img", "pct_thresh")); gc(); gc();
450
451
452
  ################################################
453
  # Making Probability
454
  ################################################
455
  msg = "# Getting Top Probability Segmentation from Atropos"
456
  if (verbose) {
457
    message(msg)
458
  }
459
  if (shiny) {
460
    shiny::incProgress(message = msg, amount = 0.02)
461
  }
462
  addstub = paste0("prob_img")
463
  fname = make_fname(addstub)
464
  if (file.exists(fname) & !overwrite){
465
    prob_img = readnii(fname, reorient = FALSE)
466
  } else {
467
    window.masked.img = window_img(masked.img, window = c(0, 100))
468
    seg = otropos( window.masked.img, i = "KMeans[4]", verbose = verbose > 1)
469
    prob_img = seg$probabilityimages[[3]] + seg$probabilityimages[[4]]
470
    rm(list = c("seg")); gc(); gc();
471
    if (save_imgs){
472
      write_img(prob_img, addstub)
473
    }
474
  }
475
476
  df$prob_img = c(prob_img)
477
  rm(list = c("prob_img")); gc(); gc();
478
479
480
  ################################################
481
  # Making Percent that are 0
482
  ################################################
483
  msg = "# Getting Percent 0"
484
  if (verbose) {
485
    message(msg)
486
  }
487
  if (shiny) {
488
    shiny::incProgress(message = msg, amount = 0.02)
489
  }
490
  ###### changed to masked.img
491
  thresh_0 = niftiarr(masked.img, masked.img == 0)
492
  addstub = "pct_zero_neighbor"
493
  fname = make_fname(addstub)
494
  if (file.exists(fname) & !overwrite){
495
    pct_zero_neighbor = readnii(fname, reorient=FALSE)
496
  } else {
497
    pct_zero_neighbor = local_moment(thresh_0, mask = NULL,
498
                                     nvoxels = nvoxels,
499
                                     moment = 1, center = FALSE,
500
                                     ...)[[1]]
501
    pct_zero_neighbor = mask_img(pct_zero_neighbor, mask)
502
    if (save_imgs){
503
      write_img(pct_zero_neighbor, addstub)
504
    }
505
  }
506
  df$pct_zero_neighbor = c(pct_zero_neighbor)
507
  rm(list = c("pct_zero_neighbor", "thresh_0")); gc(); gc();
508
509
  msg = "# Getting Any 0 Neighbors"
510
  if (verbose) {
511
    message(msg)
512
  }
513
  if (shiny) {
514
    shiny::incProgress(message = msg, amount = 0.02)
515
  }
516
  addstub = "any_zero_neighbor"
517
  df$any_zero_neighbor = (df$pct_zero_neighbor > 0) *1
518
519
  ################################################
520
  # Making Distance to centroid
521
  ################################################
522
  msg = "# Getting Distance to centroid"
523
  if (verbose) {
524
    message(msg)
525
  }
526
  if (shiny) {
527
    shiny::incProgress(message = msg, amount = 0.02)
528
  }
529
  addstub = "dist_centroid"
530
  fname = make_fname(addstub)
531
  if (file.exists(fname) & !overwrite){
532
    dist.img = readnii(fname, reorient=FALSE)
533
  } else {
534
    centroid = t(which(mask > 0, arr.ind=TRUE))
535
    all.ind = expand.grid(lapply(dimg, seq))
536
    colnames(all.ind) = paste0("dim", seq(length(dimg)))
537
    all.ind = t(as.matrix(all.ind))
538
    all.ind = all.ind * vdim
539
    centroid = centroid * vdim
540
    dist.img = t(all.ind - rowMeans(centroid))
541
    rm(list = c("all.ind")); gc(); gc();
542
543
    dist.img = sqrt(rowSums(dist.img^2))
544
    dist.img = niftiarr(img, array(dist.img, dim =dimg))
545
    dist.img = mask_img(dist.img, mask)
546
    dist.img = datatyper(dist.img,
547
                         datatype= convert.datatype()$FLOAT32,
548
                         bitpix= convert.bitpix()$FLOAT32)
549
    if (save_imgs){
550
      write_img(dist.img, addstub)
551
    }
552
  }
553
  df$dist_centroid = c(dist.img)
554
  rm(list = c("dist.img")); gc(); gc();
555
556
557
  ################################################
558
  # Making Distance to centroid
559
  ################################################
560
  msg = "# Perona Malik Smoother"
561
  if (verbose) {
562
    message(msg)
563
  }
564
  if (shiny) {
565
    shiny::incProgress(message = msg, amount = 0.02)
566
  }
567
  addstub = "perona_malik"
568
  fname = make_fname(addstub)
569
  if (file.exists(fname) & !overwrite) {
570
    dist.img = readnii(fname, reorient = FALSE)
571
  } else {
572
    pm_img = extrantsr::perona_malik(
573
      masked.img, n_iter = 10,
574
      conductance = 5)
575
    if (save_imgs) {
576
      write_img(pm_img, addstub)
577
    }
578
    rm(list = c("seg")); gc(); gc();
579
  }
580
  df$perona_malik = c(pm_img)
581
  rm(list = c("pm_img")); gc(); gc();
582
583
  ################################################
584
  # Making 10mm and 20mm smoother
585
  ################################################
586
  make_smooth_img = function(sigma){
587
    msg = paste0("# Getting Smooth ", sigma)
588
    if (verbose) {
589
      message(msg)
590
    }
591
    if (shiny) {
592
      shiny::incProgress(message = msg, amount = 0.02)
593
    }
594
    addstub = paste0("smooth", sigma)
595
    if (save_imgs){
596
      fname = make_fname(addstub)
597
    } else {
598
      fname = tempfile()
599
      if (file.exists(fname)){
600
        file.remove(fname)
601
      }
602
    }
603
    if (file.exists(fname) & !overwrite) {
604
      smooth.img = readnii(fname, reorient = FALSE)
605
    } else {
606
      smooth.mask = fslr::fsl_smooth(
607
        file = mask,
608
        sigma = sigma,
609
        mask = NULL,
610
        smooth_mask = FALSE,
611
        verbose = verbose > 1)
612
      smooth.img = fslsmooth(img.fname, sigma=sigma,
613
                             mask = mask, retimg = TRUE,
614
                             outfile = fname,
615
                             verbose = verbose > 1)
616
    }
617
    return(c(smooth.img))
618
  }
619
  #   df$smooth2 = make_smooth_img(sigma=2)
620
  #   df$smooth5 = make_smooth_img(sigma=5)
621
  smooths = sapply(sigmas, make_smooth_img)
622
  colnames(smooths) = paste0("smooth", sigmas)
623
  df = cbind(df, smooths)
624
  rm(list = c("smooths")); gc(); gc();
625
626
627
628
  msg = "# Z-score to template"
629
  if (verbose) {
630
    message(msg)
631
  }
632
  if (shiny) {
633
    shiny::incProgress(message = msg, amount = 0.02)
634
  }
635
  addstub = "zscore_template"
636
  fname = make_fname(addstub)
637
  if (file.exists(fname) & !overwrite) {
638
    zscore = readnii(fname, reorient = FALSE)
639
  } else {
640
    zscore = extrantsr::zscore_template(img = orig.masked.img,
641
                                        template.file = template.file,
642
                                        mean.img = mean.img,
643
                                        sd.img = sd.img,
644
                                        typeofTransform = zscore.typeofTransform,
645
                                        interpolator = zscore.interpolator,
646
                                        verbose = verbose > 1)
647
    if (save_imgs){
648
      write_img(zscore, addstub)
649
    }
650
  }
651
  df$zscore_template = c(zscore)
652
  rm(list = c("zscore")); gc(); gc();
653
654
  msg = "# Flipped Difference"
655
  if (verbose) {
656
    message(msg)
657
  }
658
  if (shiny) {
659
    shiny::incProgress(message = msg, amount = 0.02)
660
  }
661
  addstub = "flipped_value"
662
  fname = make_fname(addstub)
663
  if (file.exists(fname) & !overwrite) {
664
    flipped_value = readnii(fname, reorient=FALSE)
665
  } else {
666
    flipper = extrantsr::reg_flip(
667
      t1 = orig.masked.img,
668
      mask = orig.mask,
669
      template.file = template.file,
670
      typeofTransform = flip.typeofTransform,
671
      interpolator = flip.interpolator,
672
      verbose = verbose > 1)
673
    flipper = flipper$t1
674
    ##########################
675
    # Take difference
676
    ##########################
677
    flipped_value = orig.masked.img - flipper
678
    rm(list = c("flipper")); gc(); gc();
679
    if (save_imgs) {
680
      write_img(flipped_value, addstub)
681
    }
682
  }
683
  df$flipped_value = c(flipped_value)
684
  rm(list = c("flipped_value")); gc(); gc();
685
686
  msg = "# Thresholding small values"
687
  if (verbose) {
688
    message(msg)
689
  }
690
  if (shiny) {
691
    shiny::incProgress(message = msg, amount = 0.02)
692
  }
693
694
695
  for (icn in seq(ncol(df))) {
696
    x = df[, icn]
697
    if (!(class(x) %in% c("factor", "character"))) {
698
      x[ !is.finite(x) ] = 0
699
    }
700
    df[, icn] = x
701
  }
702
703
  df = as.matrix(df)
704
  low = abs(df) < low_thresh
705
  df[ low ] = 0
706
707
  df = data.frame(df, stringsAsFactors = FALSE)
708
  if (!is.null(roi)) {
709
    df$Y = c(roi)
710
  } else {
711
    df$Y = NA
712
  }
713
  df$mask = c(mask)
714
715
716
  return(list(df = df, keep.ind = keep.ind, nim = nim,
717
              miss.roi = miss.roi))
718
}
719
720