Cleanup and reorganize code
[loomr.git] / R / internal.R
1 # Validate a loom object
2 #
3 # @param object A loom object
4 #
5 # @return None, errors out if object is an invalid loom connection
6 #
7 # @seealso \code{\link{loom-class}}
8 #
9 validateLoom <- function(object) {
10   if (!inherits(x = object, what = 'loom')) {
11     stop("No need to validate a non-loom object")
12   }
13   # A loom file is a specific HDF5
14   # We need a dataset in /matrix that's a two-dimensional dense matrix
15   root.datasets <- list.datasets(object = object, path = '/', recursive = FALSE)
16   if (length(x = root.datasets) != 1) {
17     stop("There can only be one dataset at the root of the loom file")
18   }
19   if (root.datasets != 'matrix') {
20     stop("The root dataset must be called '/matrix'")
21   }
22   # There must be groups called '/col_attrs', '/row_attrs', and '/layers'
23   required.groups <- c('row_attrs', 'col_attrs', 'layers')
24   dim.matrix <- object[[root.datasets]]$dims # Columns x Rows
25   names(x = dim.matrix) <- required.groups[c(2, 1)]
26   root.groups <- list.groups(object = object, path = '/', recursive = FALSE)
27   group.msg <- paste0(
28     "There can only be three groups in the loom file: '",
29     paste(required.groups, collapse = "', '"),
30     "'"
31   )
32   if (length(x = root.groups) != 3) {
33     stop(group.msg)
34   }
35   if (!all(required.groups %in% root.groups)) {
36     stop(group.msg)
37   }
38   unlist(x = sapply(
39     X = required.groups[1:2],
40     FUN = function(group) {
41       if (length(x = list.groups(object = object[[group]], recursive = FALSE)) > 0) {
42         stop(paste("Group", group, "cannot have subgroups"))
43       }
44       if (length(x = list.attributes(object = object[[group]])) > 0) {
45         stop(paste("Group", group, "cannot have subattributes"))
46       }
47       for (dataset in list.datasets(object = object[[group]])) {
48         if (object[[paste(group, dataset, sep = '/')]]$dims != dim.matrix[group]) {
49           stop(paste("All datasets in group", group, "must be of length", required.groups[group]))
50         }
51       }
52     }
53   ))
54   for (dataset in list.datasets(object = object[['/layers']])) {
55     if (any(object[[paste('layers', dataset, sep = '/')]]$dims != dim.matrix)) {
56       stop(paste("All datasets in '/layers' must be", dim.matrix[1], 'by', dim.matrix[2]))
57     }
58   }
59 }