R/parse_volume.R

Defines functions get_volume parse_volume

Documented in get_volume parse_volume

#' @title Parse Volume from CIFTI
#' @description Extracts information about Volumes from CIFTI file
#' @param nodeset Set of XML nodes corresponding to \code{Volume}
#' @param verbose print diagnostic messages
#'
#' @return List of values
#' @export
#'
#' @examples \dontrun{
#' doc = cifti_xml(fname)
#' nodes = xml_find_all(doc, "/CIFTI/Matrix/MatrixIndicesMap")
#' nodeset = xml_find_all(nodes, "./Volume")
#' parse_volume(nodeset)
#' }
parse_volume = function(nodeset) {
  if (is.list(nodeset) &&
      !inherits(nodeset, "xml_nodes") &&
      !inherits(nodeset, "xml_nodeset")) {
    return(lapply(nodeset, parse_volume))
  }
  n_nodes = length(nodeset)
  all_names = xml_attrs(nodeset,
                        "VolumeDimensions")
  all_names = unlist(all_names)

  vert_nodes = lapply(nodeset,
                      xml_find_all,
                      xpath = "./TransformationMatrixVoxelIndicesIJKtoXYZ")

  get_mat = function(node) {
    vert_attr = xml_attrs(node)
    if (length(vert_attr) > 1){
      vert_attr = lapply(vert_attr,
                         as.list)
    } else {
      if (length(vert_attr) == 0) {
        vert_attr = NULL
      }
      vert_attr = as.list(vert_attr[[1]])
    }
    verts = xml_text(node)
    if (length(verts) > 0) {
      verts = strsplit(verts, split = "\n")[[1]]
      verts = verts[ !(verts %in% "")]
      verts = strsplit(verts, " ")
      verts = lapply(verts, as.numeric)
      verts = do.call("rbind", verts)
      # attributes(vert) = vert_attr
    }
    return(verts)
  }
  verts = lapply(vert_nodes, get_mat)
  verts = mapply(function(x, a) {
    list(mat = x, VolumeDimensions = a)
  }, verts, all_names, SIMPLIFY = FALSE)
  if (length(verts) == 1) {
    verts = verts[[1]]
  }
  return(verts)
}


#' @rdname parse_volume
#' @param fname filename of CIFTI file
#' @export
get_volume = function(fname, verbose = TRUE) {
  nodes = matrix_ind_map_nodes(fname)
  nodeset = lapply(nodes, xml_find_all, xpath = "./Volume")
  nodeset = keep_sub_nodeset(nodeset)
  if (verbose) {
    message("Parsing Volume Data")
  }
  parse_volume(nodeset)
}
neuroconductor/cifti documentation built on May 19, 2021, 5:18 a.m.