R/import_ss.R

#' Import \emph{SuperSegger} data
#'
#' Imports the cell \code{.mat} data files generated by \emph{SuperSegger} and converts them into
#' a cell list containing all the cell instants of the movie.
#'
#' \emph{SuperSegger} treats the whole frame as a single colony.
#' \cr\cr
#' \emph{SuperSegger} users importing the data with this function
#' do not import any information about either the pixels of each cell or the pixels each colony.
#' \cr\cr
#' \emph{SuperSegger} users importing the data with this function are \bold{excluded} from using
#' \code{\link{plot_col_tree}},
#' \code{\link{split_cell}}, \code{\link{get_cand_merge_cells}}, \code{\link{merge_cells}},
#' \code{\link{get_cand_mother_cells}}, \code{\link{add_branch}},
#' \code{\link{create_movie}}, \code{\link{create_cell_life}} and \code{\link{view_cell}}.
#'
#' @param path A character string naming the \code{xy#/cell} directory with the cell \code{.mat} data files
#' generated by \emph{SuperSegger} (excluding the last \code{"/"})
#' from which the data is to be imported.
#' If it does not contain an absolute path, it is relative to the current working directory, \code{getwd()}.
#' \cr\cr
#' NOTE: The components should be separated by \code{"/"} on Windows.
#'
#' @param pixelR The pixel ratio in units of length, a non-zero positive numeric value.
#'
#' @return A named list with the following components:
#' \item{col_list}{NULL}
#' \item{cell_list}{A list containing all the cell instants of the movie.
#' Each element of the list is a named list with the following components:
#' \itemize{
#' \item \code{cellName} is the name of the cell, a character string in the format \code{"c<cellId>_f<frame>"}.
#' \item \code{frame} is the ID of the frame of the cell, a non-zero positive integer number.
#' \item \code{colony} is the ID of the colony of the cell in the \code{frame}, a non-zero positive integer number.
#' \item \code{daughterIds} is a vector of character strings containing the \code{cellName}
#' of the linked cell(s) in the next frame,
#' or \code{NULL} in case no such cells exist.
#'
#' \item \code{length} is the length of the cell in units of length, a non-zero positive numeric value.
#' \item \code{width} is the width of the cell in units of length, a non-zero positive numeric value.
#' \item \code{area} is the area of the cell in squared units of length, a non-zero positive numeric value.
#' \item \code{minorAxis} is the short axis of the ellipse surrounding the cell in units of length, a non-zero positive numeric value.
#' \item \code{majorAxis} is the long axis of the ellipse surrounding the cell in units of length, a non-zero positive numeric value.
#' \item \code{orientation} is a numeric value in the range \code{[0, 360)}
#' defining the orientation of the cell in \emph{degrees}.
#'
#' \item \code{cellDist} is the distance of the cell to the edge of the colony in units of length, a positive numeric value.
#' \item \code{edgeFlag} is a logical value (\code{TRUE} or \code{FALSE})
#' indicating whether the cell is at the edge of the image or not.
#' \item \code{contactHist} is a logical value (\code{TRUE} or \code{FALSE})
#' indicating whether the cell is in contact with other cell or not.
#'
#' \item \code{fluorescenceInt<i>.mean} is the \emph{mean} cell fluorescence intensity of channel \code{<i>},
#' a positive numeric value.
#' \item \code{fluorescenceInt<i>.std} is the \emph{standard deviation} of the cell fluorescence intensity of channel \code{<i>},
#' a positive numeric value.
#' \item \code{fluorescenceInt<i>.coverage} is the percentage of the cell area covered by fluorescence of channel \code{<i>},
#' a numeric value in the range \code{[0, 1]}.
#' }
#' The \code{fluorescenceInt<i>*} components are included in case they were exctracted by \emph{SuperSegger}.
#' }
#'
#' \item{Nframes}{Number of frames in the movie, a non-zero positive integer value.
#' IDs of frames are in the range \code{[1, Nframes]}.}
#' \item{Ncols}{Number of colonies in the movie, equal to \code{1}.
#' IDs of colonies are in the range \code{[1, Ncols]}.}
#' \item{frameH}{NULL}
#' \item{frameW}{NULL}
#'
#' @references \url{http://mtshasta.phys.washington.edu/website/SuperSegger.php}
#' @export
#' @importFrom utils setTxtProgressBar txtProgressBar


import_ss <- function(path, pixelR) {

  cell_list <- list()
  cell_files <- list.files(path = path)
  Ncells <- length(cell_files)

  cat("Creating cell list...\n")
  pb <- txtProgressBar(min = 0, max = Ncells, style = 3) ### set progress bar
  ipb <- 0

  for (i_cell in 1:Ncells) {

    ipb <- ipb + 1
    setTxtProgressBar(pb, ipb) ### update progress bar

    data <- R.matlab::readMat(paste(path, "/", cell_files[i_cell], sep = ""))

    # for dealing with error Ninstants != length(data$CellA)
    Ninstants <- data$death - data$birth + 1

    for (i in 1:Ninstants) {

      frame <- as.integer(data$birth[1, 1] + (i - 1))

      if (length(data$daughterID) != 0) {
        if (i != length(data$CellA)) {
          daughterIds <- paste("c", i_cell, ".", i + 1, "_f", frame + 1, sep = "")
        } else {
          daughterIds <- paste("c", as.vector(data$daughterID), ".", "1", "_f", frame + 1, sep = "")
        }
      } else {
        daughterIds <- NULL
      }

      a <- data$CellA[[i]][[1]][,,1]

      orientation <- a$coord[,,1]$orientation[1, 1]
      if (orientation < 0) {
        orientation <- 360 + orientation
      }

      cell_list[[length(cell_list) + 1]] <- list(cellName = paste("c", i_cell, ".", i, "_f", frame, sep = ""),
                                                 frame = frame,
                                                 colony = 1,
                                                 daughterIds = daughterIds,
                                                 length = a$cellLength[1, 1] * pixelR,
                                                 width = a$cellLength[1, 2] * pixelR,
                                                 area = a$coord[,,1]$A[1, 1] * pixelR * pixelR,
                                                 minorAxis = a$length[1, 1] * pixelR,
                                                 majorAxis = a$length[1, 2] * pixelR,
                                                 orientation = orientation,
                                                 cellDist = a$cell.dist[1, 1] * pixelR,
                                                 edgeFlag = as.logical(a$edgeFlag[1, 1]),
                                                 contactHist = as.logical(a$contactHist[1, 1]))

      cellImage <- a$mask
      pixelList <- which(cellImage == 1, arr.ind = TRUE)

      fluors <- grep(pattern = "^fluor\\d+\\.filtered$", x = names(a), value = TRUE)
      for (f in fluors) {
        i_f <- unlist(strsplit(unlist(strsplit(f, split = "fluor"))[2], split = ".filtered"))
        cell_list[[length(cell_list)]][[paste("fluorescenceInt", i_f, ".mean", sep = "")]] <- mean(a[[f]][pixelList])
        cell_list[[length(cell_list)]][[paste("fluorescenceInt", i_f, ".std", sep = "")]] <- sd(a[[f]][pixelList])
        cell_list[[length(cell_list)]][[paste("fluorescenceInt", i_f, ".coverage", sep = "")]] <-
          length(which(a[[f]][pixelList] == 0, arr.ind = TRUE)) / nrow(pixelList)
      }

    }

  }

  close(pb) ### close progress bar
  cat("\n")

  cat("Checking cell list...\n")
  cell_list <- checkCellList(cell_list = cell_list, col_list = NULL) #col_list)

  Nframes <- length(unique(unlist(sapply(cell_list, function(x) x$frame))))

  return(list(col_list = NULL, cell_list = cell_list,
              Nframes = Nframes, Ncols = 1,
              frameH = NULL, frameW = NULL))

}
vicstefanou/ViSCA documentation built on May 31, 2019, 10:50 p.m.