#' @include zzz.R
#'
NULL
#' Figure out which objects to load from an h5Seurat file
#'
#' @inheritParams LoadH5Seurat
#' @param index An h5Seurat index (\code{\link{h5SI}}) object
#'
#' @seealso \code{\link{LoadH5Seurat}}
#'
#' @rdname GetObject
#' @name GetObject
#'
#' @keywords internal
#'
NULL
#' @return \code{GetAssays}: A named list where each entry is a vector
#' describing the slots of an assay to load and the names are the assays to load
#'
#' @rdname GetObject
#'
GetAssays <- function(assays, index) {
index.assays <- setdiff(x = names(x = index), y = c('global', 'no.assay'))
assay.slots <- c('counts', 'data', 'scale.data')
assay.msg <- paste(
'Assay specification must include either the name of an assay',
'or one or more assay slots'
)
assays <- assays %||% index.assays
if (!is.null(x = names(x = assays))) {
assays <- as.list(x = assays)
}
if (!is.list(x = assays)) {
if (any(assays %in% index.assays) && any(assays %in% assay.slots)) {
stop("Ambiguous assays", call. = FALSE)
} else if (any(assays %in% index.assays)) {
assays <- assays[assays %in% index.assays]
assays <- sapply(
X = assays,
FUN = function(...) {
return(assay.slots)
},
simplify = FALSE,
USE.NAMES = TRUE
)
} else {
assays <- assays[assays %in% assay.slots]
if (length(x = assays) < 1) {
stop(assay.msg, call. = FALSE)
}
assays <- list(assays)
assays <- rep_len(x = assays, length.out = length(x = index.assays))
names(x = assays) <- index.assays
}
} else {
for (i in 1:length(x = assays)) {
assay.name <- names(x = assays)[i] %||% index.assays[i] %||% ''
if (!assay.name %in% index.assays) {
if (assays[[i]][1] %in% index.assays) {
assay.name <- assays[[i]][1]
} else if (any(assays[[i]] %in% assay.slots)) {
assay.name <- hdf5r::h5attr(x = file, which = 'active.assay')
}
}
if (nchar(x = assay.name) < 0 || !assay.name %in% index.assays) {
stop(assay.msg, call. = FALSE)
}
assay.content <- assays[[i]]
if (assay.content[1] %in% index.assays) {
assay.content <- assay.slots
} else {
assay.content <- assay.content[assay.content %in% assay.slots]
if (length(x = assay.content) < 1) {
stop(assay.msg, call. = FALSE)
}
}
assays[i] <- list(assay.content)
names(x = assays)[i] <- assay.name
}
}
assays.checked <- assays
unique.assays <- unique(x = names(x = assays.checked))
assays <- vector(mode = 'list', length = length(x = unique.assays))
names(x = assays) <- unique.assays
for (i in unique.assays) {
assays.use <- which(x = names(x = assays.checked) == i)
slots.use <- unique(x = unlist(
x = assays.checked[assays.use],
use.names = FALSE
))
slots.use <- slots.use[match(x = names(x = index[[i]]$slots), table = slots.use)]
slots.use <- as.character(x = na.omit(object = slots.use[index[[i]]$slots]))
assays[[i]] <- slots.use
}
for (i in seq_along(along.with = assays)) {
if (!any(c('counts', 'data') %in% assays[[i]])) {
stop(
"Call assays must have either a 'counts' or 'data' slot, missing for ",
names(x = assays)[i],
call. = FALSE
)
}
}
return(assays)
}
#' @return \code{GetCommands}: A vector of command log names that are derived
#' from an assay in \code{assay}
#'
#' @rdname GetObject
#'
GetCommands <- function(index, assays = NULL) {
assays <- GetAssays(assays = assays, index = index)
return(unique(x = unlist(x = lapply(
X = names(x = assays),
FUN = function(x) {
return(index[[x]]$commands)
}
))))
}
#' @return \code{GetDimReducs}: A vector of reduction names that are derived
#' from an assay in \code{assays} or global dimensional reductions
#'
#' @rdname GetObject
#'
GetDimReducs <- function(reductions, index, assays = NULL) {
if (isFALSE(x = reductions)) {
return(NULL)
} else if (!is.null(x = reductions) && all(is.na(x = reductions))) {
return(index$global$reductions)
}
if (is.null(x = reductions)) {
reductions <- unique(x = unlist(x = lapply(
X = setdiff(x = names(x = index), y = 'no.assay'),
FUN = function(x) {
if (x == 'global') {
return(index[[x]]$reductions)
}
return(names(x = index[[x]]$reductions))
}
)))
}
if (isTRUE(x = getOption(x = 'SeuratDisk.dimreducs.allglobal', default = FALSE))) {
return(reductions)
}
assays <- GetAssays(assays = assays, index = index)
assays.reducs <- lapply(
X = names(x = assays),
FUN = function(x) {
return(names(x = index[[x]]$reductions))
}
)
assays.reducs <- unique(x = c(unlist(x = assays.reducs), index$global$reductions))
return(intersect(x = reductions, y = assays.reducs))
}
#' @return \code{GetGraphs}: A vector of graph names that are derived from an
#' assay in \code{assays}
#'
#' @rdname GetObject
#'
GetGraphs <- function(graphs, index, assays = NULL) {
if (isFALSE(x = graphs)) {
return(NULL)
} else if (is.null(x = graphs)) {
graphs <- unique(x = unlist(x = lapply(
X = setdiff(x = names(x = index), y = c('global', 'no.assay')),
FUN = function(x) {
return(index[[x]]$graphs)
}
)))
}
assays <- GetAssays(assays = assays, index = index)
assays.graphs <- unique(x = unlist(x = lapply(
X = names(x = assays),
FUN = function(x) {
return(index[[x]]$graphs)
}
)))
return(intersect(x = graphs, y = assays.graphs))
}
#' @return \code{GetImages}: A vector of image names
#'
#' @rdname GetObject
#'
GetImages <- function(images, index, assays = NULL) {
if (isFALSE(x = images)) {
return(NULL)
} else if (!is.null(x = images) && all(is.na(x = images))) {
return(index$global$images)
} else if (is.null(x = images)) {
images <- unique(x = unlist(x = lapply(
X = names(x = index),
FUN = function(x) {
return(index[[x]]$images)
}
)))
}
assays <- GetAssays(assays = assays, index = index)
assays.images <- lapply(
X = names(x = assays),
FUN = function(x) {
return(index[[x]]$images)
}
)
assays.images <- unique(x = c(unlist(x = assays.images, index$global$images)))
return(intersect(x = images, y = assays.images))
}
#' @return \code{GetNeighbors}: A vector of neighbor names
#'
#' @rdname GetObject
#'
GetNeighbors <- function(neighbors, index) {
if (isFALSE(x = neighbors)) {
return(NULL)
} else if (is.null(x = neighbors)) {
return(index[["global"]]$neighbors)
} else {
return(intersect(x = neighbors, y = index[["global"]]$neighbors))
}
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.