R/mrvnrfs.R

Defines functions mrvnrfs.predict mrvnrfs

Documented in mrvnrfs mrvnrfs.predict

#' multi-res voxelwise neighborhood random forest segmentation learning
#'
#' Represents multiscale feature images as a neighborhood and uses the features
#' to build a random forest segmentation model from an image population
#'
#' @param y list of training labels. either an image or numeric value
#' @param x a list of lists where each list contains feature images
#' @param labelmasks a mask (or list of masks) used to define where the
#' samples will come from. Note, two labels (e.g., GM and WM) will double
#' the number of samples from each feature images. If the mask is binary,
#' samples are selected randomly within 1 values.
#' @param rad vector of dimensionality d define nhood radius
#' @param nsamples (per subject to enter training)
#' @param ntrees (for the random forest model)
#' @param multiResSchedule an integer vector defining multi-res levels
#' @param asFactors boolean - treat the y entries as factors
#' @param voxchunk value of maximal voxels to predict at once. This value
#' is used to split the prediction into smaller chunks such that memory
#' requirements do not become too big
#' @param ... arguments to pass to \code{\link{vwnrfs}}
#' @return list a 4-list with the rf model, training vector, feature matrix
#' and the random mask
#' @author Avants BB, Tustison NJ, Pustina D
#'
#' @examples
#'
#' mask<-makeImage( c(10,10), 0 )
#' mask[ 3:6, 3:6 ]<-1
#' mask[ 5, 5:6]<-2
#' ilist<-list()
#' lablist<-list()
#' inds<-1:5
#' scl<-0.33 # a noise parameter
#' for ( predtype in c("label","scalar") )
#' {
#' for ( i in inds ) {
#'   img<-antsImageClone(mask)
#'   imgb<-antsImageClone(mask)
#'   limg<-antsImageClone(mask)
#'   if ( predtype == "label") {  # 4 class prediction
#'     img[ 3:6, 3:6 ]<-rnorm(16)*scl+(i %% 4)+scl*mean(rnorm(1))
#'     imgb[ 3:6, 3:6 ]<-rnorm(16)*scl+(i %% 4)+scl*mean(rnorm(1))
#'     limg[ 3:6, 3:6 ]<-(i %% 4)+1  # the label image is constant
#'     }
#'     if ( predtype == "scalar") {
#'       img[ 3:6, 3:6 ]<-rnorm(16,1)*scl*(i)+scl*mean(rnorm(1))
#'       imgb[ 3:6, 3:6 ]<-rnorm(16,1)*scl*(i)+scl*mean(rnorm(1))
#'       limg<-i^2.0  # a real outcome
#'       }
#'     ilist[[i]]<-list(img,imgb)  # two features
#'     lablist[[i]]<-limg
#'   }
#' rad<-rep( 1, 2 )
#' mr <- c(1.5,1)
#' rfm<-mrvnrfs( lablist , ilist, mask, rad=rad, multiResSchedule=mr,
#'      asFactors = (  predtype == "label" ) )
#' rfmresult<-mrvnrfs.predict( rfm$rflist,
#'      ilist, mask, rad=rad, asFactors=(  predtype == "label" ),
#'      multiResSchedule=mr )
#' if ( predtype == "scalar" )
#'   print( cor( unlist(lablist) , unlist( rfmresult$seg ) ) )
#' } # end predtype loop
#'
#'
#' @export mrvnrfs
mrvnrfs <- function( y, x, labelmasks, rad=NA, nsamples=1,
                     ntrees=500, multiResSchedule=c(4,2,1), asFactors=TRUE,
                     voxchunk=50000, ...) {
  
  # check if Y is antsImage or a number
  yisimg<-TRUE
  if ( typeof(y[[1]]) == "integer" | typeof(y[[1]]) == "double") yisimg<-FALSE
  rflist<-list()
  rfct<-1
  
  # for a single labelmask create a list with it
  useFirstMask=FALSE
  if ( typeof(labelmasks) != "list" ) {
    inmask = antsImageClone( labelmasks )
    labelmasks=list()
    for ( i in 1:length(x) ) labelmasks[[i]] = inmask
    useFirstMask = TRUE
  }
  
  # loop of resolutions
  verbose = FALSE # need to add this option to command line if you want messages
  mrcount=0
  for ( mr in multiResSchedule ) {
    mrcount=mrcount+1
    if ( verbose ) message(paste(mrcount,'of',length(multiResSchedule)))
    
    invisible(gc())
    
    # add newprobs from previous run, already correct dimension
    if ( rfct > 1 ) {
      for ( kk in 1:length(x) ) {
        p1<-unlist( x[[kk]] )
        p2<-unlist(newprobs[[kk]])
        temp<-lappend(  p1 ,  p2  )
        x[[kk]]<-temp
      }
      rm(newprobs); invisible(gc())
    }
    
    invisible(gc())
    
    # build model for this mr
    if (!useFirstMask) {
      sol <- vwnrfs(
        y = y,
        x = x,
        labelmasks = labelmasks,
        rad = rad,
        nsamples = nsamples,
        ntrees = ntrees,
        asFactors = asFactors,
        reduceFactor = mr,
        ...
      )
    }
    
    if (useFirstMask) {
      sol <- vwnrfs(
        y = y,
        x = x,
        labelmasks = labelmasks[[1]],
        rad = rad,
        nsamples = nsamples,
        ntrees = ntrees,
        asFactors = asFactors,
        reduceFactor = mr,
        ...
      )
    }

    
    sol$fm = sol$tv = sol$randmask = NULL
    
    invisible(gc())
    
    # if not last mr, predict new features for next round
    if (mrcount < length(multiResSchedule)) {
      predme = vwnrfs.predict(rfm=sol$rfm, x=x, labelmasks=labelmasks,
                              rad=rad, asFactors=asFactors, voxchunk=voxchunk,
                              reduceFactor = mr)
      
      newprobs=predme$probs
      rm(predme); invisible(gc())
      for ( tt1 in 1:length(newprobs) )
        for (tt2 in 1:length(newprobs[[tt1]]))
          newprobs[[tt1]][[tt2]]<-resampleImage( newprobs[[tt1]][[tt2]], dim(labelmasks[[tt1]]), useVoxels=1, 0 )
    }
    
    invisible(gc())
    rflist[[rfct]]<-sol$rfm
    rfct<-rfct+1
  } # mr loop
  
  return( list(rflist=rflist) )
}



#' multi-res voxelwise neighborhood random forest segmentation
#'
#' Represents multiscale feature images as a neighborhood and uses the features
#' to apply a random forest segmentation model to a new image
#'
#' @param rflist a list of random forest models from mrvnrfs
#' @param x a list of lists where each list contains feature images
#' @param labelmasks a mask (or list of masks) used to define the area to predict.
#' This is used to save time by contstrain the prediction in within the brain.
#' @param rad vector of dimensionality d define nhood radius
#' @param multiResSchedule an integer vector defining multi-res levels
#' @param asFactors boolean - treat the y entries as factors
#' @param voxchunk value of maximal voxels to predict at once. This value
#' is used to split the prediction into smaller chunks such that memory
#' requirements do not become too big
#' @return list a 4-list with the rf model, training vector, feature matrix
#' and the random mask
#' @author Avants BB, Tustison NJ, Pustina D
#'
#' @export mrvnrfs.predict
mrvnrfs.predict <- function( rflist, x, labelmasks, rad=NA,
                             multiResSchedule=c(4,2,1), asFactors=TRUE,
                             voxchunk=60000) {
  if ( ! usePkg("randomForest") )
    stop("Please install the randomForest package, example: install.packages('randomForest')")
  
  
  # for a single labelmask create a list the same
  useFirstMask=FALSE
  if ( typeof(labelmasks) != "list" ) {
    inmask = antsImageClone( labelmasks )
    labelmasks=list()
    for ( i in 1:length(x) ) labelmasks[[i]] = inmask
    useFirstMask = TRUE
  }
  
  predtype<-'response'
  if ( asFactors ) predtype<-'prob'
  
  rfct<-1
  for ( mr in multiResSchedule ){
    
    if ( rfct > 1 ) {
      for ( kk in 1:length(x) ) {
        p1<-unlist( x[[kk]] )
        p2<-unlist(newprobs[[kk]])
        temp<-lappend(  p1 ,  p2  )
        x[[kk]]<-temp
      }
      rm(newprobs); invisible(gc())
    }
    
    
    predme = vwnrfs.predict(rflist[[rfct]], x=x, labelmasks=labelmasks,
                            rad=rad, asFactors=asFactors, voxchunk=voxchunk,
                            reduceFactor = mr)
    
    newprobs = predme$probs
    newseg = predme$seg
    if (rfct < length(multiResSchedule)) {
      for ( tt1 in 1:length(newprobs) )
        for (tt2 in 1:length(newprobs[[tt1]]))
          newprobs[[tt1]][[tt2]]<-resampleImage( newprobs[[tt1]][[tt2]], dim(labelmasks[[1]]), useVoxels=1, 0 )
    }
    
    rfct<-rfct+1
  } # mr loop
  return(list(seg=newseg, probs=newprobs))
}
neuroconductor-devel/ANTsR documentation built on April 1, 2021, 1:02 p.m.