Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update comments #7

Merged
merged 1 commit into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 42 additions & 58 deletions R/ZarrAnnData.R
Original file line number Diff line number Diff line change
@@ -1,27 +1,23 @@
#' @title ZarrAnnData
#'
#' @description
#' Implementation of an in memory AnnData object.
#' Implementation of a Zarr-based AnnData object.
#' @noRd
ZarrAnnData <- R6::R6Class("ZarrAnnData", # nolint
inherit = AbstractAnnData,
private = list(
zarr_store = NULL,
zarr_root = NULL,
# .n_obs = NULL,
# .n_vars = NULL,
# .obs_names = NULL,
# .var_names = NULL,
.compression = NULL
),
active = list(
#' @field X The X slot
X = function(value) {
if (missing(value)) {
# trackstatus: class=HDF5AnnData, feature=get_X, status=done
# trackstatus: class=ZarrAnnData, feature=get_X, status=done
read_zarr_element(private$zarr_store, "/X")
} else {
# trackstatus: class=HDF5AnnData, feature=set_X, status=done
# trackstatus: class=ZarrAnnData, feature=set_X, status=done
value <- private$.validate_aligned_array(
value,
"X",
Expand All @@ -37,10 +33,10 @@ ZarrAnnData <- R6::R6Class("ZarrAnnData", # nolint
#' `obs` and `var`.
layers = function(value) {
if (missing(value)) {
# trackstatus: class=HDF5AnnData, feature=get_layers, status=done
# trackstatus: class=ZarrAnnData, feature=get_layers, status=done
read_zarr_element(private$zarr_store, "layers")
} else {
# trackstatus: class=HDF5AnnData, feature=set_layers, status=done
# trackstatus: class=ZarrAnnData, feature=set_layers, status=done
value <- private$.validate_aligned_mapping(
value,
"layers",
Expand All @@ -55,10 +51,10 @@ ZarrAnnData <- R6::R6Class("ZarrAnnData", # nolint
#' with all elements having the same number of rows as `obs`.
obsm = function(value) {
if (missing(value)) {
# trackstatus: class=HDF5AnnData, feature=get_obsm, status=done
# trackstatus: class=ZarrAnnData, feature=get_obsm, status=done
read_zarr_element(private$zarr_store, "obsm")
} else {
# trackstatus: class=HDF5AnnData, feature=set_obsm, status=done
# trackstatus: class=ZarrAnnData, feature=set_obsm, status=done
value <- private$.validate_aligned_mapping(
value,
"obsm",
Expand All @@ -72,10 +68,10 @@ ZarrAnnData <- R6::R6Class("ZarrAnnData", # nolint
#' with all elements having the same number of rows as `var`.
varm = function(value) {
if (missing(value)) {
# trackstatus: class=HDF5AnnData, feature=get_varm, status=done
# trackstatus: class=ZarrAnnData, feature=get_varm, status=done
read_zarr_element(private$zarr_store, "varm")
} else {
# trackstatus: class=HDF5AnnData, feature=set_varm, status=done
# trackstatus: class=ZarrAnnData, feature=set_varm, status=done
value <- private$.validate_aligned_mapping(
value,
"varm",
Expand All @@ -89,10 +85,10 @@ ZarrAnnData <- R6::R6Class("ZarrAnnData", # nolint
#' with all elements having the same number of rows and columns as `obs`.
obsp = function(value) {
if (missing(value)) {
# trackstatus: class=HDF5AnnData, feature=get_obsp, status=done
# trackstatus: class=ZarrAnnData, feature=get_obsp, status=done
read_zarr_element(private$zarr_store, "obsp")
} else {
# trackstatus: class=HDF5AnnData, feature=set_obsp, status=done
# trackstatus: class=ZarrAnnData, feature=set_obsp, status=done
value <- private$.validate_aligned_mapping(
value,
"obsp",
Expand All @@ -107,10 +103,10 @@ ZarrAnnData <- R6::R6Class("ZarrAnnData", # nolint
#' with all elements having the same number of rows and columns as `var`.
varp = function(value) {
if (missing(value)) {
# trackstatus: class=HDF5AnnData, feature=get_varp, status=done
# trackstatus: class=ZarrAnnData, feature=get_varp, status=done
read_zarr_element(private$zarr_store, "varp")
} else {
# trackstatus: class=HDF5AnnData, feature=set_varp, status=done
# trackstatus: class=ZarrAnnData, feature=set_varp, status=done
value <- private$.validate_aligned_mapping(
value,
"varp",
Expand All @@ -125,11 +121,11 @@ ZarrAnnData <- R6::R6Class("ZarrAnnData", # nolint
#' @field obs The obs slot
obs = function(value) {
if (missing(value)) {
# trackstatus: class=HDF5AnnData, feature=get_obs, status=done
# trackstatus: class=ZarrAnnData, feature=get_obs, status=done
# TODO: shall we keep include_index = TRUE, or get rid of the argument ?
read_zarr_element(private$zarr_store, "/obs", include_index = TRUE)
} else {
# trackstatus: class=HDF5AnnData, feature=set_obs, status=done
# trackstatus: class=ZarrAnnData, feature=set_obs, status=done
value <- private$.validate_obsvar_dataframe(value, "obs")
write_zarr_element(
value,
Expand All @@ -143,11 +139,11 @@ ZarrAnnData <- R6::R6Class("ZarrAnnData", # nolint
#' @field var The var slot
var = function(value) {
if (missing(value)) {
# trackstatus: class=HDF5AnnData, feature=get_var, status=done
# trackstatus: class=ZarrAnnData, feature=get_var, status=done
# TODO: shall we keep include_index = TRUE, or get rid of the argument ?
read_zarr_element(private$zarr_store, "/var", include_index = TRUE)
} else {
# trackstatus: class=HDF5AnnData, feature=set_var, status=done
# trackstatus: class=ZarrAnnData, feature=set_var, status=done
value <- private$.validate_obsvar_dataframe(value, "var")
write_zarr_element(
value,
Expand All @@ -160,48 +156,39 @@ ZarrAnnData <- R6::R6Class("ZarrAnnData", # nolint
#' @field obs_names Names of observations
obs_names = function(value) {
if (missing(value)) {
# trackstatus: class=HDF5AnnData, feature=get_obs_names, status=done
# trackstatus: class=ZarrAnnData, feature=get_obs_names, status=done
rownames(self$obs)
} else {
# trackstatus: class=HDF5AnnData, feature=set_obs_names, status=done
# trackstatus: class=ZarrAnnData, feature=set_obs_names, status=done
rownames(self$obs) <- value
}
},
#' @field var_names Names of variables
var_names = function(value) {
if (missing(value)) {
# trackstatus: class=HDF5AnnData, feature=get_var_names, status=done
# trackstatus: class=ZarrAnnData, feature=get_var_names, status=done
rownames(self$var)
} else {
# trackstatus: class=HDF5AnnData, feature=set_var_names, status=done
# trackstatus: class=ZarrAnnData, feature=set_var_names, status=done
rownames(self$var) <- value
}
},
#' @field uns The uns slot. Must be `NULL` or a named list.
uns = function(value) {
if (missing(value)) {
# trackstatus: class=HDF5AnnData, feature=get_uns, status=done
# trackstatus: class=ZarrAnnData, feature=get_uns, status=done
read_zarr_element(private$zarr_store, "uns")
} else {
# trackstatus: class=HDF5AnnData, feature=set_uns, status=done
# trackstatus: class=ZarrAnnData, feature=set_uns, status=done
value <- private$.validate_named_list(value, "uns")
write_zarr_element(value, private$zarr_store, "/uns")
}
}
),
public = list(
#' @description HDF5AnnData constructor
#' @description ZarrAnnData constructor
#'
#' @param file The filename (character) of the `.h5ad` file. If this
#' file does not exist yet, `obs_names` and `var_names` must be provided.
#' @param obs_names A vector of unique identifiers
#' used to identify each row of `obs` and to act as an index into the
#' observation dimension of the AnnData object. The length of `obs_names`
#' defines the observation dimension of the AnnData object.
#' @param var_names A vector of unique identifiers used to identify each row
#' of `var` and to act as an index into the variable dimension of the
#' AnnData object. The length of `var_names` defines the variable
#' dimension of the AnnData object.
#' @param store The Zarr store instance.
#' @param X Either `NULL` or a observation × variable matrix with
#' dimensions consistent with `obs` and `var`.
#' @param layers Either `NULL` or a named list, where each element is an
Expand All @@ -227,20 +214,17 @@ ZarrAnnData <- R6::R6Class("ZarrAnnData", # nolint
#' element is a sparse matrix where each dimension has length `n_vars`.
#' @param uns The uns slot is used to store unstructured annotation. It must
#' be either `NULL` or a named list.
#' @param compression The compression algorithm to use when writing the
#' HDF5 file. Can be one of `"none"`, `"gzip"` or `"lzf"`. Defaults to
#' @param compression The compression algorithm to use when writing
#' Zarr arrays. Can be one of `"none"`, `"gzip"` or `"lzf"`. Defaults to
#' `"none"`.
#'
#' @details
#' The constructor creates a new HDF5 AnnData interface object. This can
#' either be used to either connect to an existing `.h5ad` file or to
#' create a new one. To create a new file both `obs_names` and `var_names`
#' must be specified. In both cases, any additional slots provided will be
#' The constructor creates a new Zarr AnnData interface object. This can
#' either be used to either connect to an existing `.zarr` store or to
#' populate an empty one. In both cases, any additional slots provided will be
#' set on the created object. This will cause data to be overwritten if the
#' file already exists.
initialize = function(store,
# obs_names = NULL,
# var_names = NULL,
X = NULL,
obs = NULL,
var = NULL,
Expand Down Expand Up @@ -324,7 +308,7 @@ ZarrAnnData <- R6::R6Class("ZarrAnnData", # nolint
# get root
root <- pizzarr::zarr_open_group(store, path = "/")

# Check the file is a valid H5AD
# Check the file is a valid AnnData format
attrs <- root$get_attrs()$to_list()

if (!all(c("encoding-type", "encoding-version") %in% names(attrs))) {
Expand Down Expand Up @@ -398,25 +382,25 @@ ZarrAnnData <- R6::R6Class("ZarrAnnData", # nolint
)
)

#' Convert an AnnData object to an HDF5AnnData object
#' Convert an AnnData object to a ZarrAnnData object
#'
#' This function takes an AnnData object and converts it to an HDF5AnnData
#' This function takes an AnnData object and converts it to a ZarrAnnData
#' object, loading all fields into memory.
#'
#' @param adata An AnnData object to be converted to HDF5AnnData.
#' @param file The filename (character) of the `.h5ad` file.
#' @param compression The compression algorithm to use when writing the
#' HDF5 file. Can be one of `"none"`, `"gzip"` or `"lzf"`. Defaults to
#' @param adata An AnnData object to be converted to ZarrAnnData.
#' @param store The Zarr store.
#' @param compression The compression algorithm to use when writing
#' Zarr arrays. Can be one of `"none"`, `"gzip"` or `"lzf"`. Defaults to
#' `"none"`.
#' @param mode The mode to open the HDF5 file.
#' @param mode The mode to open the Zarr store.
#'
#' * `a` creates a new file or opens an existing one for read/write.
#' * `r` opens an existing file for reading.
#' * `r+` opens an existing file for read/write.
#' * `w` creates a file, truncating any existing ones.
#' * `w-`/`x` are synonyms, creating a file and failing if it already exists.
#'
#' @return An HDF5AnnData object with the same data as the input AnnData
#' @return a ZarrAnnData object with the same data as the input AnnData
#' object.
#'
#' @noRd
Expand All @@ -433,9 +417,9 @@ ZarrAnnData <- R6::R6Class("ZarrAnnData", # nolint
#' obs_names = LETTERS[1:3],
#' var_names = letters[1:5]
#' )
#' to_HDF5AnnData(ad, "test.h5ad")
#' # remove file
#' file.remove("test.h5ad")
#' to_ZarrAnnData(ad, "test.zarr")
#' # remove store directory
#' unlink("test.zarr", recursive = TRUE)
to_ZarrAnnData <- function(adata,
store,
compression = c("none", "gzip", "lzf"),
Expand Down
13 changes: 7 additions & 6 deletions R/read_zarr.R
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#'
#' Read data from a Zarr store
#'
#' @param path Path to the H5AD file to read
#' @param path Path to the Zarr store to read
#' @param to The type of object to return. Must be one of: "InMemoryAnnData",
#' "HDF5AnnData", "SingleCellExperiment", "Seurat"
#' @param ... Extra arguments provided to [to_SingleCellExperiment()] or
Expand All @@ -12,16 +12,17 @@
#' @export
#'
#' @examples
#' h5ad_file <- system.file("extdata", "example.h5ad", package = "anndataR")
#' file <- system.file("extdata", "example.zarr", package = "anndataR")
#' store <- pizzarr::DirectoryStore$new(file)
#'
#' # Read the H5AD as a SingleCellExperiment object
#' # Read the Zarr store as a SingleCellExperiment object
#' if (requireNamespace("SingleCellExperiment", quietly = TRUE)) {
#' sce <- read_zarr(h5ad_file, to = "SingleCellExperiment")
#' sce <- read_zarr(store, to = "SingleCellExperiment")
#' }
#'
#' # Read the H5AD as a Seurat object
#' # Read the Zarr store as a Seurat object
#' if (requireNamespace("SeuratObject", quietly = TRUE)) {
#' seurat <- read_zarr(h5ad_file, to = "Seurat")
#' seurat <- read_zarr(store, to = "Seurat")
#' }
read_zarr <- function(
path,
Expand Down
Loading