From 22890d927f0b4f26c57e36ed7d8ce84a62c196e4 Mon Sep 17 00:00:00 2001 From: Artur-man Date: Tue, 21 Jul 2026 08:47:39 +0200 Subject: [PATCH 01/10] add ZarrADMatrix class --- NAMESPACE | 52 +++++++++---- R/ZarrADMatrix-class.R | 52 +++++++++++++ R/ZarrADMatrixSeed-class.R | 134 ++++++++++++++++++++++++++++++++++ ZarrArray.Rproj | 18 +++++ man/ZarrADMatrix-class.Rd | 118 ++++++++++++++++++++++++++++++ man/ZarrADMatrixSeed-class.Rd | 133 +++++++++++++++++++++++++++++++++ 6 files changed, 494 insertions(+), 13 deletions(-) create mode 100644 R/ZarrADMatrix-class.R create mode 100644 R/ZarrADMatrixSeed-class.R create mode 100644 ZarrArray.Rproj create mode 100644 man/ZarrADMatrix-class.Rd create mode 100644 man/ZarrADMatrixSeed-class.Rd diff --git a/NAMESPACE b/NAMESPACE index 7154728..746f0c8 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -8,8 +8,7 @@ import(IRanges) import(S4Arrays) import(SparseArray) import(DelayedArray) -importFrom(Rarr, read_zarr_array, create_empty_zarr_array, update_zarr_array, - read_zarr_attributes) +importFrom(Rarr, read_zarr_array, create_empty_zarr_array, update_zarr_array) ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -21,16 +20,20 @@ exportClasses( ZarrArray, ZarrMatrix, ZarrRealizationSink, ZarrSparseMatrixSeed, CSC_ZarrSparseMatrixSeed, CSR_ZarrSparseMatrixSeed, - ZarrSparseMatrix + ZarrSparseMatrix, + ZarrADMatrixSeed, + Dense_ZarrADMatrixSeed, CSC_ZarrADMatrixSeed, CSR_ZarrADMatrixSeed, + ZarrADMatrix ) - ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### Export S3 methods ### S3method(t, CSC_ZarrSparseMatrixSeed) S3method(t, CSR_ZarrSparseMatrixSeed) +S3method(t, CSC_ZarrADMatrixSeed) +S3method(t, CSR_ZarrADMatrixSeed) ### We also export them thru the export() directive so that (a) they can be ### called directly, (b) tab-completion on the name of the generic shows them, @@ -38,30 +41,34 @@ S3method(t, CSR_ZarrSparseMatrixSeed) export( t.CSC_ZarrSparseMatrixSeed, - t.CSR_ZarrSparseMatrixSeed + t.CSR_ZarrSparseMatrixSeed, + t.CSC_ZarrADMatrixSeed, + t.CSR_ZarrADMatrixSeed ) - ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### Export S4 methods for generics not defined in ZarrArray ### exportMethods( ## Methods for generics defined in the base package: - dim, t, + dim, ## Methods for generics defined in the methods package: show, coerce, ## Methods for generics defined in the BiocGenerics package: path, type, - + ## Methods for generics defined in the S4Arrays package: - extract_array, write_block, is_sparse, + extract_array, is_sparse, ## Methods for generics defined in the SparseArray package: nzcount, extract_sparse_array, + ## Methods for generics defined in the S4Arrays package: + extract_array, write_block, + ## Methods for generics defined in the DelayedArray package: chunkdim, matrixClass, DelayedArray @@ -88,11 +95,30 @@ export( ## writeZarrArray.R: ZarrRealizationSink, writeZarrArray, - - ## ZarrSparseMatrixSeed-class.R: + + ## ZarrSparseMatrixSeed-class.R ZarrSparseMatrixSeed, + + ## ZarrSparseMatrix-class.R + ZarrSparseMatrix, + + ## ZarrADMatrixSeed-class.R + ZarrADMatrixSeed, + + ## ZarrADMatrix-class.R + ZarrADMatrix +) - ## ZarrSparseMatrix-class.R: - ZarrSparseMatrix +### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +### Export S4 generics defined in HDF5Array, and corresponding methods +### + +export( + ## ZarrSparseMatrixSeed-class.R: + extractNonzeroDataByCol, extractNonzeroDataByRow ) +### Exactly the same list as above. +exportMethods( + extractNonzeroDataByCol, extractNonzeroDataByRow +) diff --git a/R/ZarrADMatrix-class.R b/R/ZarrADMatrix-class.R new file mode 100644 index 0000000..5556a8b --- /dev/null +++ b/R/ZarrADMatrix-class.R @@ -0,0 +1,52 @@ +### ========================================================================= +### ZarrADMatrix objects +### ------------------------------------------------------------------------- +### + +setClass("ZarrADMatrix", + contains="DelayedMatrix", + representation(seed="ZarrADMatrixSeed") +) + + +### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +### Constructor +### + +setMethod("DelayedArray", "ZarrADMatrixSeed", + function(seed) new_DelayedArray(seed, Class="ZarrADMatrix") +) + +### Works directly on an ZarrADMatrixSeed derivative, in which case it must +### be called with a single argument. +ZarrADMatrix <- function(filepath, layer=NULL) +{ + if (is(filepath, "ZarrADMatrixSeed")) { + if (!is.null(layer)) + stop(wmsg("ZarrADMatrix() must be called with a single argument ", + "when passed an ZarrADMatrixSeed derivative")) + seed <- filepath + } else { + seed <- ZarrADMatrixSeed(filepath, layer=layer) + } + DelayedArray(seed) +} + + +### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +### Taking advantage of sparsity +### + +### Will work only if the seed is an H5SparseMatrixSeed derivative, that is, +### if it's a CSC_ZarrADMatrixSeed or CSR_ZarrADMatrixSeed object. +setMethod("nzcount", "ZarrADMatrix", function(x) nzcount(x@seed)) + +### Will work only if the seed is a CSC_ZarrADMatrixSeed object. +setMethod("extractNonzeroDataByCol", "ZarrADMatrix", + function(x, j) extractNonzeroDataByCol(x@seed, j) +) + +### Will work only if the seed is a CSR_ZarrADMatrixSeed object. +setMethod("extractNonzeroDataByRow", "ZarrADMatrix", + function(x, i) extractNonzeroDataByCol(x@seed, i) +) \ No newline at end of file diff --git a/R/ZarrADMatrixSeed-class.R b/R/ZarrADMatrixSeed-class.R new file mode 100644 index 0000000..c623a3e --- /dev/null +++ b/R/ZarrADMatrixSeed-class.R @@ -0,0 +1,134 @@ +### ========================================================================= +### ZarrADMatrixSeed objects +### ------------------------------------------------------------------------- + + +setClass("ZarrADMatrixSeed", + contains=c("Array", "OutOfMemoryObject"), + representation("VIRTUAL") +) + +setClass("Dense_ZarrADMatrixSeed", + contains=c("ZarrADMatrixSeed", "ZarrArraySeed"), + representation(dimnames="list"), + prototype(dimnames=list(NULL, NULL)) +) +setClass("CSC_ZarrADMatrixSeed", + contains=c("ZarrADMatrixSeed", "CSC_ZarrSparseMatrixSeed") +) +setClass("CSR_ZarrADMatrixSeed", + contains=c("ZarrADMatrixSeed", "CSR_ZarrSparseMatrixSeed") +) + + +### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +### dimnames() method for Dense_ZarrADMatrixSeed objects +### + +### We overwrite the method for HDF5ArraySeed objects with a method that +### accesses the slot, not the store +setMethod("dimnames", "Dense_ZarrADMatrixSeed", + function(x) S4Arrays:::simplify_NULL_dimnames(x@dimnames) +) + + +### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +### Transposition +### + +### S3/S4 combo for t.CSC_ZarrADMatrixSeed +t.CSC_ZarrADMatrixSeed <- function(x) +{ + new2("CSR_ZarrADMatrixSeed", callNextMethod()) +} +setMethod("t", "CSC_ZarrADMatrixSeed", t.CSC_ZarrADMatrixSeed) + +### S3/S4 combo for t.CSR_ZarrADMatrixSeed +t.CSR_ZarrADMatrixSeed <- function(x) +{ + new2("CSC_ZarrADMatrixSeed", callNextMethod()) +} +setMethod("t", "CSR_ZarrADMatrixSeed", t.CSR_ZarrADMatrixSeed) + + +### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +### Constructor +### + +.load_zarr_ad_rownames <- function(filepath, name="var") +{ + ok <- try(zarrisdataset(filepath, name), silent=TRUE) + if (isTRUE(ok)) { + ## Must use rhdf5::h5read() for now, until h5mread() knows how + ## to read COMPOUND datasets. + ans <- h5read(filepath, name)$index + if (!is.null(ans)) + ans <- as.character(ans) + return(ans) + } + ok <- try(zarrisgroup(filepath, name), silent=TRUE) + if (!isTRUE(ok)) + return(NULL) + ROWNAMES_DATASET <- paste0(name, "/_index") + ok <- try(zarrisdataset(filepath, ROWNAMES_DATASET), silent=TRUE) + if (!isTRUE(ok)) + return(NULL) + zarr_mread(filepath, ROWNAMES_DATASET) +} + +### Must return a list of length 2. +.load_zarr_ad_dimnames <- function(filepath) +{ + ans_rownames <- .load_zarr_ad_rownames(filepath) + ans_colnames <- .load_zarr_ad_rownames(filepath, name="obs") + if (is.null(ans_rownames) && is.null(ans_colnames)) + warning(wmsg("could not find dimnames in this anndata-zarr store")) + list(ans_rownames, ans_colnames) +} + +### Returns an ZarrADMatrixSeed derivative (can be either a Dense_ZarrADMatrixSeed, +### or a CSC_ZarrSparseMatrixSeed, or a CSR_ZarrSparseMatrixSeed object). +ZarrADMatrixSeed <- function(filepath, layer=NULL) +{ + if (!isSingleString(filepath)) + stop(wmsg("'filepath' must be a single string specifying the ", + "path to the anndata-zarr store")) + filepath <- file_path_as_absolute(filepath) + if (is.null(layer)) { + name <- "/X" + } else { + if (!isSingleString(layer) || layer == "") + stop(wmsg("'layer' must be NULL or a single non-empty string")) + name <- paste0("/layers/", layer) + } + if (!zarrexists(filepath, name)) { + msg <- c("Zarr object \"", name, "\" does not exist ", + "in this Zarr store") + if (is.null(layer)) + msg <- c(msg, " Is this a valid anndata-zarr store?") + stop(wmsg(msg)) + } + dimnames <- .load_zarr_ad_dimnames(filepath) + + if (zarrisdataset(filepath, name)) { + ans0 <- HDF5ArraySeed(filepath, name) + if (length(dim(ans0)) != 2L) + stop(wmsg("Zarr dataset \"", name, "\" in store \"", filepath, "\" ", + "does not have exactly 2 dimensions. Please consider ", + "using the HDF5Array() constructor to access this ", + "dataset.")) + ans <- new2("Dense_ZarrADMatrixSeed", ans0, dimnames=dimnames) + } else if (zarrisgroup(filepath, name)) { + ans0 <- ZarrSparseMatrixSeed(filepath, name) + if (is(ans0, "CSC_ZarrSparseMatrixSeed")) + ans_class <- "CSC_ZarrADMatrixSeed" + else + ans_class <- "CSR_ZarrADMatrixSeed" + ans <- new2(ans_class, ans0, dimnames=dimnames) + } else { + stop(wmsg("Zarr object \"", name, "\" in store \"", filepath, "\" ", + "is neither a dataset or a group. Is this a valid ", + "anndata-zarr store?")) + } + ans +} \ No newline at end of file diff --git a/ZarrArray.Rproj b/ZarrArray.Rproj new file mode 100644 index 0000000..eaa6b81 --- /dev/null +++ b/ZarrArray.Rproj @@ -0,0 +1,18 @@ +Version: 1.0 + +RestoreWorkspace: Default +SaveWorkspace: Default +AlwaysSaveHistory: Default + +EnableCodeIndexing: Yes +UseSpacesForTab: Yes +NumSpacesForTab: 2 +Encoding: UTF-8 + +RnwWeave: Sweave +LaTeX: pdfLaTeX + +BuildType: Package +PackageUseDevtools: Yes +PackageInstallArgs: --no-multiarch --with-keep.source +PackageRoxygenize: rd,collate,namespace diff --git a/man/ZarrADMatrix-class.Rd b/man/ZarrADMatrix-class.Rd new file mode 100644 index 0000000..48ce07c --- /dev/null +++ b/man/ZarrADMatrix-class.Rd @@ -0,0 +1,118 @@ +\name{ZarrADMatrix-class} +\docType{class} + +\alias{class:ZarrADMatrix} +\alias{ZarrADMatrix-class} +\alias{ZarrADMatrix} + +\alias{DelayedArray,ZarrADMatrixSeed-method} + +\alias{nzcount,ZarrADMatrix-method} +\alias{extractNonzeroDataByCol,ZarrADMatrix-method} +\alias{extractNonzeroDataByRow,ZarrADMatrix-method} + +\title{anndata-zarr central matrices (or matrices in the /layers group) + as DelayedMatrix objects} + +\description{ + \code{anndata-zarr} stores are Zarr stores used for on-disk representation + of AnnData Python objects. At the very minimum, they contain a central + data matrix, named \code{X}, of shape #observations x #variables, and + possibly additional data matrices (stored in the Zarr group \code{/layers}) + that share the shape and dimnames of \code{X}. + See \url{https://anndata.readthedocs.io/} for more information. + + The ZarrADMatrix class is a \link[DelayedArray]{DelayedMatrix} subclass + for representing and operating on the central matrix of an \code{anndata-zarr} + store, or any matrix in its \code{/layers} group. + + All the operations available for \link[DelayedArray]{DelayedMatrix} + objects work on ZarrADMatrix objects. +} + +\usage{ +## Constructor function: +ZarrADMatrix(filepath, layer=NULL) +} + +\arguments{ + \item{filepath}{ + The path (as a single string) to the \code{anndata-zarr} store. + } + \item{layer}{ + \code{NULL} (the default) or the name of a matrix in the \code{/layers} + group. By default (i.e. when \code{layer} is not specified) + \code{ZarrADMatrix()} returns the central matrix (\code{X}). + } +} + +\value{ + \code{ZarrADMatrix()} returns an ZarrADMatrix object of shape #variables x + #observations. Note that in Python and Zarr the shape of this matrix is + considered to be #observations x #variables, but in R it is transposed. + This follows the widely adopted convention of transposing Zarr matrices + when they get loaded into R. +} + +\references{ + \url{https://anndata.readthedocs.io/} for AnnData Python objects + and the \code{anndata-zarr} format. +} + +\seealso{ + \itemize{ + \item \link{ZarrArray} objects for representing conventional (a.k.a. + dense) Zarr datasets as \link[DelayedArray]{DelayedArray} objects. + + \item \link{ZarrSparseMatrix} objects for representing Zarr sparse matrices + as \link[DelayedArray]{DelayedMatrix} objects. + + \item \link[DelayedArray]{DelayedMatrix} objects in the \pkg{DelayedArray} + package. + + \item The \link{ZarrADMatrixSeed} helper class. + + \item \code{\link[anndataR]{read_zarr}} and + \code{\link[anndataR]{write_zarr}} in + the \pkg{anndataR} package for + importing/exporting an \code{anndata-zarr} store as/from a + \link[SingleCellExperiment]{SingleCellExperiment} object. + + \item \link[SparseArray]{SparseArray} objects in the \pkg{SparseArray} + package. + } +} + +\examples{ +library(anndataR) +zarr_zip <- system.file("extdata", + paste0("example_v2.zarr.zip"), + package = "anndataR") +td <- tempdir(check = TRUE) +unzip(zarr_zip, exdir = td) +zarr_store <- file.path(td, paste0("example_v2.zarr")) + +X <- ZarrADMatrix(zarr_store) +X + +class(X) # ZarrADMatrix +is(X, "DelayedMatrix") # TRUE + +class(seed(X)) # Dense_ZarrADMatrixSeed + +dim(X) +path(X) +is_sparse(X) # FALSE + +## Use coercion to load the full dataset into memory: +as.matrix(X) # as ordinary array (usually not recommended) + +\dontrun{ + ## Works only if ZarrADMatrix object is sparse! + as(X, "dgCMatrix") # as dgCMatrix + as(X, "SparseArray") # as SparseArray object (most efficient) + SparseArray(X) # equivalent to 'as(X, "SparseArray")' +} +} +\keyword{classes} +\keyword{methods} diff --git a/man/ZarrADMatrixSeed-class.Rd b/man/ZarrADMatrixSeed-class.Rd new file mode 100644 index 0000000..546c69b --- /dev/null +++ b/man/ZarrADMatrixSeed-class.Rd @@ -0,0 +1,133 @@ +\name{ZarrADMatrixSeed-class} +\docType{class} + +\alias{class:ZarrADMatrixSeed} +\alias{ZarrADMatrixSeed-class} +\alias{ZarrADMatrixSeed} + +\alias{class:Dense_ZarrADMatrixSeed} +\alias{Dense_ZarrADMatrixSeed-class} +\alias{Dense_ZarrADMatrixSeed} + +\alias{class:CSC_ZarrADMatrixSeed} +\alias{CSC_ZarrADMatrixSeed-class} +\alias{CSC_ZarrADMatrixSeed} + +\alias{class:CSR_ZarrADMatrixSeed} +\alias{CSR_ZarrADMatrixSeed-class} +\alias{CSR_ZarrADMatrixSeed} + +\alias{dimnames,Dense_ZarrADMatrixSeed-method} + +\alias{t.CSC_ZarrADMatrixSeed} +\alias{t,CSC_ZarrADMatrixSeed-method} +\alias{t.CSR_ZarrADMatrixSeed} +\alias{t,CSR_ZarrADMatrixSeed-method} + +\title{ZarrADMatrixSeed objects} + +\description{ + ZarrADMatrixSeed is a low-level helper class used to represent a pointer + to the central matrix stored of an \code{anndata-zarr} store, or to one of the + matrices in the \code{/layers} group. + + It is a virtual class with three concrete subclasses: Dense_ZarrADMatrixSeed, + CSC_ZarrADMatrixSeed, and CSR_ZarrADMatrixSeed: + \itemize{ + \item The Dense_ZarrADMatrixSeed class is used when the matrix is stored + as a conventional Zarr dataset in the \code{anndata-zarr} store. It is + a direct entension of the \link{ZarrArraySeed} class. + + \item The CSC_ZarrADMatrixSeed or CSR_ZarrADMatrixSeed classes is used + when the matrix is stored in the \emph{Compressed Sparse Column} + or \emph{Compressed Sparse Row} format in the \code{anndata-zarr} + store. CSC_ZarrADMatrixSeed is a direct entension of + \link{CSC_ZarrSparseMatrixSeed}, and CSR_ZarrADMatrixSeed a + direct entension of \link{CSR_ZarrSparseMatrixSeed}. + } + + Note that an ZarrADMatrixSeed derivative is not intended to be used directly. + Most end users will typically create and manipulate a higher-level + \link{ZarrADMatrix} object instead. See \code{?\link{ZarrADMatrix}} for + more information. +} + +\usage{ +## Constructor function: +ZarrADMatrixSeed(filepath, layer=NULL) +} + +\arguments{ + \item{filepath, layer}{ + See \code{?\link{ZarrADMatrix}} for a description of these arguments. + } +} + +\details{ + Dense_ZarrADMatrixSeed objects support the same limited set of methods as + \link{ZarrArraySeed} objects, and CSC_ZarrADMatrixSeed and CSR_ZarrADMatrixSeed + objects support the same limited set of methods as \link{ZarrSparseMatrixSeed} + objects. + See \code{?\link{ZarrArraySeed}} and \code{?\link{ZarrSparseMatrixSeed}} + for the details. +} + +\value{ + \code{ZarrADMatrixSeed()} returns an ZarrADMatrixSeed derivative + (Dense_ZarrADMatrixSeed or CSC_ZarrADMatrixSeed or CSR_ZarrADMatrixSeed) + of shape #variables x #observations. +} + +\section{ZarrADMatrixSeed vs ZarrADMatrix objects}{ + In order to have access to the full set of operations that are available + for \link[DelayedArray]{DelayedMatrix} objects, an ZarrADMatrixSeed + derivative first needs to be wrapped in a \link[DelayedArray]{DelayedMatrix} + object, typically by calling the \code{\link[DelayedArray]{DelayedArray}()} + constructor on it. + + This is what the \code{\link{ZarrADMatrix}()} constructor function does. + + Note that the result of this wrapping is an \link{ZarrADMatrix} object, + which is just an ZarrADMatrixSeed derivative wrapped in a + \link[DelayedArray]{DelayedMatrix} object. +} + +\references{ + \url{https://anndata.readthedocs.io/} for AnnData Python objects + and the \code{ZarrAD} format. +} + +\seealso{ + \itemize{ + \item \link{ZarrADMatrix} objects. + + \item \link{ZarrArraySeed} and \link{ZarrSparseMatrixSeed} objects. + + \item \code{\link[zellkonverter]{readZarrAD}} and + \code{\link[zellkonverter]{writeZarrAD}} in + the \pkg{zellkonverter} package for + importing/exporting an \code{anndata-zarr} store as/from a + \link[SingleCellExperiment]{SingleCellExperiment} object. + } +} + +\examples{ +library(anndataR) +zarr_zip <- system.file("extdata", + paste0("example_v2.zarr.zip"), + package = "anndataR") +td <- tempdir(check = TRUE) +unzip(zarr_zip, exdir = td) +zarr_store <- file.path(td, paste0("example_v2.zarr")) + +seed <- ZarrADMatrix(zarr_store) +seed +path(seed) +dim(seed) +is_sparse(seed) + +DelayedArray(seed) +stopifnot(class(DelayedArray(seed)) == "ZarrADMatrix") +} +\keyword{classes} +\keyword{methods} From fde72dae8760ae85d073b18b042b4b0fd9e329e5 Mon Sep 17 00:00:00 2001 From: Artur-man Date: Tue, 21 Jul 2026 08:51:31 +0200 Subject: [PATCH 02/10] add tests --- tests/testthat/test-ZarrADMatrix-class.R | 30 ++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 tests/testthat/test-ZarrADMatrix-class.R diff --git a/tests/testthat/test-ZarrADMatrix-class.R b/tests/testthat/test-ZarrADMatrix-class.R new file mode 100644 index 0000000..79c78f5 --- /dev/null +++ b/tests/testthat/test-ZarrADMatrix-class.R @@ -0,0 +1,30 @@ +library(Rarr) +library(ZarrArray) +skip_if_not_installed("anndataR") + +# test on both v2 and v3 +for(v in c("v2", "v3")){ + + # unpack zarr + zarr_dir <- system.file("extdata", + paste0("example_", v, ".zarr.zip"), + package = "anndataR") + td <- tempdir(check = TRUE) + unzip(zarr_dir, exdir = td) + zarr_path <- file.path(td, paste0("example_", v, ".zarr")) + + test_that("read sparse", { + + # read sparse matrix + A <- ZarrADMatrix(zarr_path) + expect_true(is(A, "ZarrADMatrix")) + expect_true(is(A, "DelayedArray")) + expect_true(is(seed(A), "ZarrADMatrixSeed")) + expect_identical(tools::file_path_as_absolute(path(A)), zarr_path) + expect_identical(dim(A), c(100L, 50L)) + expect_identical(type(A), "double") + expect_identical(chunkdim(A), c(100L, 1L)) + + expect_equal(1,1) + }) +} \ No newline at end of file From d2e9a92d660ad524bdd52229f974dfb91b6926bd Mon Sep 17 00:00:00 2001 From: Artur-man Date: Tue, 21 Jul 2026 09:12:20 +0200 Subject: [PATCH 03/10] update NAMESPACE --- NAMESPACE | 39 +++++++++++++-------------------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 746f0c8..89f5797 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -8,7 +8,8 @@ import(IRanges) import(S4Arrays) import(SparseArray) import(DelayedArray) -importFrom(Rarr, read_zarr_array, create_empty_zarr_array, update_zarr_array) +importFrom(Rarr, read_zarr_array, create_empty_zarr_array, update_zarr_array, + read_zarr_attributes) ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -26,6 +27,7 @@ exportClasses( ZarrADMatrix ) + ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### Export S3 methods ### @@ -46,29 +48,27 @@ export( t.CSR_ZarrADMatrixSeed ) + ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### Export S4 methods for generics not defined in ZarrArray ### exportMethods( ## Methods for generics defined in the base package: - dim, + dim, t, ## Methods for generics defined in the methods package: show, coerce, ## Methods for generics defined in the BiocGenerics package: path, type, - + ## Methods for generics defined in the S4Arrays package: - extract_array, is_sparse, + extract_array, write_block, is_sparse, ## Methods for generics defined in the SparseArray package: nzcount, extract_sparse_array, - ## Methods for generics defined in the S4Arrays package: - extract_array, write_block, - ## Methods for generics defined in the DelayedArray package: chunkdim, matrixClass, DelayedArray @@ -95,30 +95,17 @@ export( ## writeZarrArray.R: ZarrRealizationSink, writeZarrArray, - - ## ZarrSparseMatrixSeed-class.R + + ## ZarrSparseMatrixSeed-class.R: ZarrSparseMatrixSeed, - - ## ZarrSparseMatrix-class.R + + ## ZarrSparseMatrix-class.R: ZarrSparseMatrix, + extractNonzeroDataByCol, extractNonzeroDataByRow ## ZarrADMatrixSeed-class.R ZarrADMatrixSeed, ## ZarrADMatrix-class.R ZarrADMatrix -) - -### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -### Export S4 generics defined in HDF5Array, and corresponding methods -### - -export( - ## ZarrSparseMatrixSeed-class.R: - extractNonzeroDataByCol, extractNonzeroDataByRow -) - -### Exactly the same list as above. -exportMethods( - extractNonzeroDataByCol, extractNonzeroDataByRow -) +) \ No newline at end of file From b5f7b88da83328861593587942ae6170b1997989 Mon Sep 17 00:00:00 2001 From: Artur-man Date: Tue, 21 Jul 2026 10:36:05 +0200 Subject: [PATCH 04/10] implement ZarrADMatrix --- DESCRIPTION | 2 ++ NAMESPACE | 3 +-- R/ZarrADMatrix-class.R | 21 +-------------------- R/ZarrADMatrixSeed-class.R | 27 +++++++++------------------ R/ZarrSparseMatrixSeed-class.R | 2 +- man/ZarrSparseMatrix-class.Rd | 2 +- 6 files changed, 15 insertions(+), 42 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 8be8cab..bd468c7 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -42,4 +42,6 @@ Collate: writeZarrArray.R ZarrSparseMatrixSeed-class.R ZarrSparseMatrix-class.R + ZarrADMatrixSeed-class.R + ZarrADMatrix-class.R zzz.R diff --git a/NAMESPACE b/NAMESPACE index 89f5797..568b661 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -101,8 +101,7 @@ export( ## ZarrSparseMatrix-class.R: ZarrSparseMatrix, - extractNonzeroDataByCol, extractNonzeroDataByRow - + ## ZarrADMatrixSeed-class.R ZarrADMatrixSeed, diff --git a/R/ZarrADMatrix-class.R b/R/ZarrADMatrix-class.R index 5556a8b..392003e 100644 --- a/R/ZarrADMatrix-class.R +++ b/R/ZarrADMatrix-class.R @@ -30,23 +30,4 @@ ZarrADMatrix <- function(filepath, layer=NULL) seed <- ZarrADMatrixSeed(filepath, layer=layer) } DelayedArray(seed) -} - - -### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -### Taking advantage of sparsity -### - -### Will work only if the seed is an H5SparseMatrixSeed derivative, that is, -### if it's a CSC_ZarrADMatrixSeed or CSR_ZarrADMatrixSeed object. -setMethod("nzcount", "ZarrADMatrix", function(x) nzcount(x@seed)) - -### Will work only if the seed is a CSC_ZarrADMatrixSeed object. -setMethod("extractNonzeroDataByCol", "ZarrADMatrix", - function(x, j) extractNonzeroDataByCol(x@seed, j) -) - -### Will work only if the seed is a CSR_ZarrADMatrixSeed object. -setMethod("extractNonzeroDataByRow", "ZarrADMatrix", - function(x, i) extractNonzeroDataByCol(x@seed, i) -) \ No newline at end of file +} \ No newline at end of file diff --git a/R/ZarrADMatrixSeed-class.R b/R/ZarrADMatrixSeed-class.R index c623a3e..e38dc51 100644 --- a/R/ZarrADMatrixSeed-class.R +++ b/R/ZarrADMatrixSeed-class.R @@ -25,7 +25,7 @@ setClass("CSR_ZarrADMatrixSeed", ### dimnames() method for Dense_ZarrADMatrixSeed objects ### -### We overwrite the method for HDF5ArraySeed objects with a method that +### We overwrite the method for ZarrArraySeed objects with a method that ### accesses the slot, not the store setMethod("dimnames", "Dense_ZarrADMatrixSeed", function(x) S4Arrays:::simplify_NULL_dimnames(x@dimnames) @@ -57,23 +57,14 @@ setMethod("t", "CSR_ZarrADMatrixSeed", t.CSR_ZarrADMatrixSeed) .load_zarr_ad_rownames <- function(filepath, name="var") { - ok <- try(zarrisdataset(filepath, name), silent=TRUE) - if (isTRUE(ok)) { - ## Must use rhdf5::h5read() for now, until h5mread() knows how - ## to read COMPOUND datasets. - ans <- h5read(filepath, name)$index - if (!is.null(ans)) - ans <- as.character(ans) - return(ans) - } - ok <- try(zarrisgroup(filepath, name), silent=TRUE) + ok <- try(zarr_node_is_group(filepath, name), silent=TRUE) if (!isTRUE(ok)) return(NULL) ROWNAMES_DATASET <- paste0(name, "/_index") - ok <- try(zarrisdataset(filepath, ROWNAMES_DATASET), silent=TRUE) + ok <- try(zarr_node_is_dataset(filepath, ROWNAMES_DATASET), silent=TRUE) if (!isTRUE(ok)) return(NULL) - zarr_mread(filepath, ROWNAMES_DATASET) + read_zarr_array(file.path(filepath, ROWNAMES_DATASET)) } ### Must return a list of length 2. @@ -101,7 +92,7 @@ ZarrADMatrixSeed <- function(filepath, layer=NULL) stop(wmsg("'layer' must be NULL or a single non-empty string")) name <- paste0("/layers/", layer) } - if (!zarrexists(filepath, name)) { + if (!zarr_exists(filepath, name)) { msg <- c("Zarr object \"", name, "\" does not exist ", "in this Zarr store") if (is.null(layer)) @@ -110,15 +101,15 @@ ZarrADMatrixSeed <- function(filepath, layer=NULL) } dimnames <- .load_zarr_ad_dimnames(filepath) - if (zarrisdataset(filepath, name)) { - ans0 <- HDF5ArraySeed(filepath, name) + if (zarr_node_is_dataset(filepath, name)) { + ans0 <- ZarrArraySeed(filepath, name) if (length(dim(ans0)) != 2L) stop(wmsg("Zarr dataset \"", name, "\" in store \"", filepath, "\" ", "does not have exactly 2 dimensions. Please consider ", - "using the HDF5Array() constructor to access this ", + "using the ZarrArray() constructor to access this ", "dataset.")) ans <- new2("Dense_ZarrADMatrixSeed", ans0, dimnames=dimnames) - } else if (zarrisgroup(filepath, name)) { + } else if (zarr_node_is_group(filepath, name)) { ans0 <- ZarrSparseMatrixSeed(filepath, name) if (is(ans0, "CSC_ZarrSparseMatrixSeed")) ans_class <- "CSC_ZarrADMatrixSeed" diff --git a/R/ZarrSparseMatrixSeed-class.R b/R/ZarrSparseMatrixSeed-class.R index 3ac16a8..fef01c8 100644 --- a/R/ZarrSparseMatrixSeed-class.R +++ b/R/ZarrSparseMatrixSeed-class.R @@ -322,7 +322,7 @@ ZarrSparseMatrixSeed <- function(zarr_store, group, subdata=NULL, dim <- .get_sparse_matrix_dim(zarr_store, group, dim=dim) ## Get sparse layout to use ("CSC" or "CSR"). - ## For consistency with H5SparseMatrixSeed, we flip the notions of rows + ## For consistency with ZarrSparseMatrixSeed, we flip the notions of rows ## and columns w.r.t. to the AnnData convention. So: ## - "compressed sparse row" in the AnnData-style Zarr store ## becomes "compressed sparse column" at the R level, diff --git a/man/ZarrSparseMatrix-class.Rd b/man/ZarrSparseMatrix-class.Rd index 22426c6..6706d45 100644 --- a/man/ZarrSparseMatrix-class.Rd +++ b/man/ZarrSparseMatrix-class.Rd @@ -97,7 +97,7 @@ class(ZSM) # ZarrSparseMatrix is(ZSM, "DelayedMatrix") # TRUE seed(ZSM) -class(seed(ZSM)) # CSC_H5SparseMatrixSeed +class(seed(ZSM)) # CSC_ZarrSparseMatrixSeed dim(ZSM) path(ZSM) From f7a70d9d1803d66e7c4e6de3a89d43947a4b5d4c Mon Sep 17 00:00:00 2001 From: Artur-man Date: Tue, 21 Jul 2026 10:37:23 +0200 Subject: [PATCH 05/10] remove Rproj --- .../DBEDCF51/pcs/debug-breakpoints.pper | 5 +++++ .Rproj.user/DBEDCF51/pcs/files-pane.pper | 9 +++++++++ .Rproj.user/DBEDCF51/pcs/source-pane.pper | 3 +++ .../DBEDCF51/pcs/windowlayoutstate.pper | 14 ++++++++++++++ .Rproj.user/DBEDCF51/pcs/workbench-pane.pper | 6 ++++++ ZarrArray.Rproj | 18 ------------------ 6 files changed, 37 insertions(+), 18 deletions(-) create mode 100644 .Rproj.user/DBEDCF51/pcs/debug-breakpoints.pper create mode 100644 .Rproj.user/DBEDCF51/pcs/files-pane.pper create mode 100644 .Rproj.user/DBEDCF51/pcs/source-pane.pper create mode 100644 .Rproj.user/DBEDCF51/pcs/windowlayoutstate.pper create mode 100644 .Rproj.user/DBEDCF51/pcs/workbench-pane.pper delete mode 100644 ZarrArray.Rproj diff --git a/.Rproj.user/DBEDCF51/pcs/debug-breakpoints.pper b/.Rproj.user/DBEDCF51/pcs/debug-breakpoints.pper new file mode 100644 index 0000000..4893a8a --- /dev/null +++ b/.Rproj.user/DBEDCF51/pcs/debug-breakpoints.pper @@ -0,0 +1,5 @@ +{ + "debugBreakpointsState": { + "breakpoints": [] + } +} \ No newline at end of file diff --git a/.Rproj.user/DBEDCF51/pcs/files-pane.pper b/.Rproj.user/DBEDCF51/pcs/files-pane.pper new file mode 100644 index 0000000..a1abc06 --- /dev/null +++ b/.Rproj.user/DBEDCF51/pcs/files-pane.pper @@ -0,0 +1,9 @@ +{ + "sortOrder": [ + { + "columnIndex": 2, + "ascending": true + } + ], + "path": "~/Dropbox/Research/MDC/Projects/SpatialData/Packages/ZarrArray" +} \ No newline at end of file diff --git a/.Rproj.user/DBEDCF51/pcs/source-pane.pper b/.Rproj.user/DBEDCF51/pcs/source-pane.pper new file mode 100644 index 0000000..ea660b4 --- /dev/null +++ b/.Rproj.user/DBEDCF51/pcs/source-pane.pper @@ -0,0 +1,3 @@ +{ + "activeTab": 6 +} \ No newline at end of file diff --git a/.Rproj.user/DBEDCF51/pcs/windowlayoutstate.pper b/.Rproj.user/DBEDCF51/pcs/windowlayoutstate.pper new file mode 100644 index 0000000..9df7d8f --- /dev/null +++ b/.Rproj.user/DBEDCF51/pcs/windowlayoutstate.pper @@ -0,0 +1,14 @@ +{ + "left": { + "splitterpos": 343, + "topwindowstate": "NORMAL", + "panelheight": 944, + "windowheight": 982 + }, + "right": { + "splitterpos": 485, + "topwindowstate": "NORMAL", + "panelheight": 944, + "windowheight": 982 + } +} \ No newline at end of file diff --git a/.Rproj.user/DBEDCF51/pcs/workbench-pane.pper b/.Rproj.user/DBEDCF51/pcs/workbench-pane.pper new file mode 100644 index 0000000..2f9ca36 --- /dev/null +++ b/.Rproj.user/DBEDCF51/pcs/workbench-pane.pper @@ -0,0 +1,6 @@ +{ + "TabSet1": 4, + "TabSet2": 0, + "TabZoom": {}, + "Sidebar": 0 +} \ No newline at end of file diff --git a/ZarrArray.Rproj b/ZarrArray.Rproj deleted file mode 100644 index eaa6b81..0000000 --- a/ZarrArray.Rproj +++ /dev/null @@ -1,18 +0,0 @@ -Version: 1.0 - -RestoreWorkspace: Default -SaveWorkspace: Default -AlwaysSaveHistory: Default - -EnableCodeIndexing: Yes -UseSpacesForTab: Yes -NumSpacesForTab: 2 -Encoding: UTF-8 - -RnwWeave: Sweave -LaTeX: pdfLaTeX - -BuildType: Package -PackageUseDevtools: Yes -PackageInstallArgs: --no-multiarch --with-keep.source -PackageRoxygenize: rd,collate,namespace From 8e54f66c75e79b13fc5b99338602e7ee435a5862 Mon Sep 17 00:00:00 2001 From: Artur-man Date: Tue, 21 Jul 2026 10:41:15 +0200 Subject: [PATCH 06/10] update TODO --- TODO | 3 --- 1 file changed, 3 deletions(-) diff --git a/TODO b/TODO index 934bac7..781e274 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,3 @@ -o Implement ZarrADMatrixSeed and ZarrADMatrix objects (analog to - H5ADMatrixSeed and H5ADMatrix objects from the HDF5Array package). - o Does Rarr provide an equivalent of h5ls() for quick inspection of a Zarr store? This would be very useful in the context of using things like ZarrSparseMatrixSeed() or ZarrSparseMatrix() where the From 254f0c7d805535afe26d84d4116aa16c7cc3e21d Mon Sep 17 00:00:00 2001 From: Artur-man Date: Tue, 21 Jul 2026 10:43:02 +0200 Subject: [PATCH 07/10] rmv artifacts --- .Rproj.user/DBEDCF51/pcs/debug-breakpoints.pper | 5 ----- .Rproj.user/DBEDCF51/pcs/files-pane.pper | 9 --------- .Rproj.user/DBEDCF51/pcs/source-pane.pper | 3 --- .Rproj.user/DBEDCF51/pcs/windowlayoutstate.pper | 14 -------------- .Rproj.user/DBEDCF51/pcs/workbench-pane.pper | 6 ------ 5 files changed, 37 deletions(-) delete mode 100644 .Rproj.user/DBEDCF51/pcs/debug-breakpoints.pper delete mode 100644 .Rproj.user/DBEDCF51/pcs/files-pane.pper delete mode 100644 .Rproj.user/DBEDCF51/pcs/source-pane.pper delete mode 100644 .Rproj.user/DBEDCF51/pcs/windowlayoutstate.pper delete mode 100644 .Rproj.user/DBEDCF51/pcs/workbench-pane.pper diff --git a/.Rproj.user/DBEDCF51/pcs/debug-breakpoints.pper b/.Rproj.user/DBEDCF51/pcs/debug-breakpoints.pper deleted file mode 100644 index 4893a8a..0000000 --- a/.Rproj.user/DBEDCF51/pcs/debug-breakpoints.pper +++ /dev/null @@ -1,5 +0,0 @@ -{ - "debugBreakpointsState": { - "breakpoints": [] - } -} \ No newline at end of file diff --git a/.Rproj.user/DBEDCF51/pcs/files-pane.pper b/.Rproj.user/DBEDCF51/pcs/files-pane.pper deleted file mode 100644 index a1abc06..0000000 --- a/.Rproj.user/DBEDCF51/pcs/files-pane.pper +++ /dev/null @@ -1,9 +0,0 @@ -{ - "sortOrder": [ - { - "columnIndex": 2, - "ascending": true - } - ], - "path": "~/Dropbox/Research/MDC/Projects/SpatialData/Packages/ZarrArray" -} \ No newline at end of file diff --git a/.Rproj.user/DBEDCF51/pcs/source-pane.pper b/.Rproj.user/DBEDCF51/pcs/source-pane.pper deleted file mode 100644 index ea660b4..0000000 --- a/.Rproj.user/DBEDCF51/pcs/source-pane.pper +++ /dev/null @@ -1,3 +0,0 @@ -{ - "activeTab": 6 -} \ No newline at end of file diff --git a/.Rproj.user/DBEDCF51/pcs/windowlayoutstate.pper b/.Rproj.user/DBEDCF51/pcs/windowlayoutstate.pper deleted file mode 100644 index 9df7d8f..0000000 --- a/.Rproj.user/DBEDCF51/pcs/windowlayoutstate.pper +++ /dev/null @@ -1,14 +0,0 @@ -{ - "left": { - "splitterpos": 343, - "topwindowstate": "NORMAL", - "panelheight": 944, - "windowheight": 982 - }, - "right": { - "splitterpos": 485, - "topwindowstate": "NORMAL", - "panelheight": 944, - "windowheight": 982 - } -} \ No newline at end of file diff --git a/.Rproj.user/DBEDCF51/pcs/workbench-pane.pper b/.Rproj.user/DBEDCF51/pcs/workbench-pane.pper deleted file mode 100644 index 2f9ca36..0000000 --- a/.Rproj.user/DBEDCF51/pcs/workbench-pane.pper +++ /dev/null @@ -1,6 +0,0 @@ -{ - "TabSet1": 4, - "TabSet2": 0, - "TabZoom": {}, - "Sidebar": 0 -} \ No newline at end of file From 744bac47f8572d57240ffc18f789bece9ce1f458 Mon Sep 17 00:00:00 2001 From: Artur-man Date: Tue, 21 Jul 2026 10:54:34 +0200 Subject: [PATCH 08/10] fix some tests --- tests/testthat/test-ZarrADMatrix-class.R | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/testthat/test-ZarrADMatrix-class.R b/tests/testthat/test-ZarrADMatrix-class.R index 79c78f5..3025c67 100644 --- a/tests/testthat/test-ZarrADMatrix-class.R +++ b/tests/testthat/test-ZarrADMatrix-class.R @@ -1,5 +1,3 @@ -library(Rarr) -library(ZarrArray) skip_if_not_installed("anndataR") # test on both v2 and v3 @@ -27,4 +25,4 @@ for(v in c("v2", "v3")){ expect_equal(1,1) }) -} \ No newline at end of file +} From a5a5ca1aef67141019ca9be12b9b6528c889e642 Mon Sep 17 00:00:00 2001 From: Artur-man Date: Tue, 21 Jul 2026 21:29:42 +0200 Subject: [PATCH 09/10] chg filepath to zarr_store --- R/ZarrADMatrix-class.R | 8 ++++---- R/ZarrADMatrixSeed-class.R | 38 +++++++++++++++++------------------ man/ZarrADMatrix-class.Rd | 4 ++-- man/ZarrADMatrixSeed-class.Rd | 4 ++-- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/R/ZarrADMatrix-class.R b/R/ZarrADMatrix-class.R index 392003e..6bb9f56 100644 --- a/R/ZarrADMatrix-class.R +++ b/R/ZarrADMatrix-class.R @@ -19,15 +19,15 @@ setMethod("DelayedArray", "ZarrADMatrixSeed", ### Works directly on an ZarrADMatrixSeed derivative, in which case it must ### be called with a single argument. -ZarrADMatrix <- function(filepath, layer=NULL) +ZarrADMatrix <- function(zarr_store, layer=NULL) { - if (is(filepath, "ZarrADMatrixSeed")) { + if (is(zarr_store, "ZarrADMatrixSeed")) { if (!is.null(layer)) stop(wmsg("ZarrADMatrix() must be called with a single argument ", "when passed an ZarrADMatrixSeed derivative")) - seed <- filepath + seed <- zarr_store } else { - seed <- ZarrADMatrixSeed(filepath, layer=layer) + seed <- ZarrADMatrixSeed(zarr_store, layer=layer) } DelayedArray(seed) } \ No newline at end of file diff --git a/R/ZarrADMatrixSeed-class.R b/R/ZarrADMatrixSeed-class.R index e38dc51..b159543 100644 --- a/R/ZarrADMatrixSeed-class.R +++ b/R/ZarrADMatrixSeed-class.R @@ -55,23 +55,23 @@ setMethod("t", "CSR_ZarrADMatrixSeed", t.CSR_ZarrADMatrixSeed) ### Constructor ### -.load_zarr_ad_rownames <- function(filepath, name="var") +.load_zarr_ad_rownames <- function(zarr_store, name="var") { - ok <- try(zarr_node_is_group(filepath, name), silent=TRUE) + ok <- try(zarr_node_is_group(zarr_store, name), silent=TRUE) if (!isTRUE(ok)) return(NULL) ROWNAMES_DATASET <- paste0(name, "/_index") - ok <- try(zarr_node_is_dataset(filepath, ROWNAMES_DATASET), silent=TRUE) + ok <- try(zarr_node_is_dataset(zarr_store, ROWNAMES_DATASET), silent=TRUE) if (!isTRUE(ok)) return(NULL) - read_zarr_array(file.path(filepath, ROWNAMES_DATASET)) + read_zarr_array(file.path(zarr_store, ROWNAMES_DATASET)) } ### Must return a list of length 2. -.load_zarr_ad_dimnames <- function(filepath) +.load_zarr_ad_dimnames <- function(zarr_store) { - ans_rownames <- .load_zarr_ad_rownames(filepath) - ans_colnames <- .load_zarr_ad_rownames(filepath, name="obs") + ans_rownames <- .load_zarr_ad_rownames(zarr_store) + ans_colnames <- .load_zarr_ad_rownames(zarr_store, name="obs") if (is.null(ans_rownames) && is.null(ans_colnames)) warning(wmsg("could not find dimnames in this anndata-zarr store")) list(ans_rownames, ans_colnames) @@ -79,12 +79,12 @@ setMethod("t", "CSR_ZarrADMatrixSeed", t.CSR_ZarrADMatrixSeed) ### Returns an ZarrADMatrixSeed derivative (can be either a Dense_ZarrADMatrixSeed, ### or a CSC_ZarrSparseMatrixSeed, or a CSR_ZarrSparseMatrixSeed object). -ZarrADMatrixSeed <- function(filepath, layer=NULL) +ZarrADMatrixSeed <- function(zarr_store, layer=NULL) { - if (!isSingleString(filepath)) - stop(wmsg("'filepath' must be a single string specifying the ", + if (!isSingleString(zarr_store)) + stop(wmsg("'zarr_store' must be a single string specifying the ", "path to the anndata-zarr store")) - filepath <- file_path_as_absolute(filepath) + zarr_store <- file_path_as_absolute(zarr_store) if (is.null(layer)) { name <- "/X" } else { @@ -92,32 +92,32 @@ ZarrADMatrixSeed <- function(filepath, layer=NULL) stop(wmsg("'layer' must be NULL or a single non-empty string")) name <- paste0("/layers/", layer) } - if (!zarr_exists(filepath, name)) { + if (!zarr_exists(zarr_store, name)) { msg <- c("Zarr object \"", name, "\" does not exist ", "in this Zarr store") if (is.null(layer)) msg <- c(msg, " Is this a valid anndata-zarr store?") stop(wmsg(msg)) } - dimnames <- .load_zarr_ad_dimnames(filepath) + dimnames <- .load_zarr_ad_dimnames(zarr_store) - if (zarr_node_is_dataset(filepath, name)) { - ans0 <- ZarrArraySeed(filepath, name) + if (zarr_node_is_dataset(zarr_store, name)) { + ans0 <- ZarrArraySeed(zarr_store, name) if (length(dim(ans0)) != 2L) - stop(wmsg("Zarr dataset \"", name, "\" in store \"", filepath, "\" ", + stop(wmsg("Zarr dataset \"", name, "\" in store \"", zarr_store, "\" ", "does not have exactly 2 dimensions. Please consider ", "using the ZarrArray() constructor to access this ", "dataset.")) ans <- new2("Dense_ZarrADMatrixSeed", ans0, dimnames=dimnames) - } else if (zarr_node_is_group(filepath, name)) { - ans0 <- ZarrSparseMatrixSeed(filepath, name) + } else if (zarr_node_is_group(zarr_store, name)) { + ans0 <- ZarrSparseMatrixSeed(zarr_store, name) if (is(ans0, "CSC_ZarrSparseMatrixSeed")) ans_class <- "CSC_ZarrADMatrixSeed" else ans_class <- "CSR_ZarrADMatrixSeed" ans <- new2(ans_class, ans0, dimnames=dimnames) } else { - stop(wmsg("Zarr object \"", name, "\" in store \"", filepath, "\" ", + stop(wmsg("Zarr object \"", name, "\" in store \"", zarr_store, "\" ", "is neither a dataset or a group. Is this a valid ", "anndata-zarr store?")) } diff --git a/man/ZarrADMatrix-class.Rd b/man/ZarrADMatrix-class.Rd index 48ce07c..da03103 100644 --- a/man/ZarrADMatrix-class.Rd +++ b/man/ZarrADMatrix-class.Rd @@ -32,11 +32,11 @@ \usage{ ## Constructor function: -ZarrADMatrix(filepath, layer=NULL) +ZarrADMatrix(zarr_store, layer=NULL) } \arguments{ - \item{filepath}{ + \item{zarr_store}{ The path (as a single string) to the \code{anndata-zarr} store. } \item{layer}{ diff --git a/man/ZarrADMatrixSeed-class.Rd b/man/ZarrADMatrixSeed-class.Rd index 546c69b..995e36e 100644 --- a/man/ZarrADMatrixSeed-class.Rd +++ b/man/ZarrADMatrixSeed-class.Rd @@ -54,11 +54,11 @@ \usage{ ## Constructor function: -ZarrADMatrixSeed(filepath, layer=NULL) +ZarrADMatrixSeed(zarr_store, layer=NULL) } \arguments{ - \item{filepath, layer}{ + \item{zarr_store, layer}{ See \code{?\link{ZarrADMatrix}} for a description of these arguments. } } From 6cf11baf2d01d709a0b4b09052394bb8f9189fba Mon Sep 17 00:00:00 2001 From: Artur-man Date: Tue, 21 Jul 2026 21:45:22 +0200 Subject: [PATCH 10/10] update path management in ad_matrix, rmv extra slashes --- R/ZarrADMatrixSeed-class.R | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/R/ZarrADMatrixSeed-class.R b/R/ZarrADMatrixSeed-class.R index b159543..706cc4a 100644 --- a/R/ZarrADMatrixSeed-class.R +++ b/R/ZarrADMatrixSeed-class.R @@ -60,7 +60,7 @@ setMethod("t", "CSR_ZarrADMatrixSeed", t.CSR_ZarrADMatrixSeed) ok <- try(zarr_node_is_group(zarr_store, name), silent=TRUE) if (!isTRUE(ok)) return(NULL) - ROWNAMES_DATASET <- paste0(name, "/_index") + ROWNAMES_DATASET <- file.path(name, "_index") ok <- try(zarr_node_is_dataset(zarr_store, ROWNAMES_DATASET), silent=TRUE) if (!isTRUE(ok)) return(NULL) @@ -86,11 +86,11 @@ ZarrADMatrixSeed <- function(zarr_store, layer=NULL) "path to the anndata-zarr store")) zarr_store <- file_path_as_absolute(zarr_store) if (is.null(layer)) { - name <- "/X" + name <- "X" } else { - if (!isSingleString(layer) || layer == "") + if (!isSingleString(layer) || !nzchar(layer)) stop(wmsg("'layer' must be NULL or a single non-empty string")) - name <- paste0("/layers/", layer) + name <- file.path("layers", layer) } if (!zarr_exists(zarr_store, name)) { msg <- c("Zarr object \"", name, "\" does not exist ",