diff --git a/DESCRIPTION b/DESCRIPTION index 40e66b7..8e31e14 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: alabaster.matrix Title: Load and Save Artifacts from File -Version: 1.5.4 -Date: 2024-06-21 +Version: 1.5.5 +Date: 2024-07-16 Authors@R: person("Aaron", "Lun", role=c("aut", "cre"), email="infinite.monkeys.with.keyboards@gmail.com") License: MIT + file LICENSE Description: @@ -15,9 +15,9 @@ Imports: methods, BiocGenerics, S4Vectors, - DelayedArray (>= 0.27.2), + DelayedArray (>= 0.31.8), S4Arrays, - SparseArray, + SparseArray (>= 1.5.22), rhdf5 (>= 2.47.1), HDF5Array, Matrix, @@ -31,7 +31,7 @@ Suggests: ResidualMatrix LinkingTo: Rcpp VignetteBuilder: knitr -RoxygenNote: 7.3.1 +RoxygenNote: 7.3.2 biocViews: DataImport, DataRepresentation diff --git a/NAMESPACE b/NAMESPACE index f2268bd..dfeb00a 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -29,7 +29,6 @@ exportClasses(ReloadedMatrix) exportClasses(WrapperArray) exportClasses(WrapperArraySeed) exportMethods(DelayedArray) -exportMethods(OLD_extract_sparse_array) exportMethods(chunkdim) exportMethods(dim) exportMethods(dimnames) @@ -54,32 +53,23 @@ importClassesFrom(Matrix,Matrix) importClassesFrom(Matrix,dgCMatrix) importClassesFrom(Matrix,dsparseMatrix) importClassesFrom(SparseArray,SVT_SparseMatrix) +importFrom(BiocGenerics,"type<-") importFrom(BiocGenerics,path) importFrom(BiocGenerics,start) -importFrom(DelayedArray,"type<-") +importFrom(BiocGenerics,type) importFrom(DelayedArray,DelayedArray) -importFrom(DelayedArray,OLD_extract_sparse_array) -importFrom(DelayedArray,acbind) -importFrom(DelayedArray,arbind) importFrom(DelayedArray,blockApply) importFrom(DelayedArray,chunkdim) importFrom(DelayedArray,colAutoGrid) importFrom(DelayedArray,currentViewport) importFrom(DelayedArray,defaultSinkAutoGrid) -importFrom(DelayedArray,extract_array) importFrom(DelayedArray,getAutoBlockLength) importFrom(DelayedArray,getAutoBlockSize) importFrom(DelayedArray,isPristine) -importFrom(DelayedArray,is_sparse) importFrom(DelayedArray,matrixClass) importFrom(DelayedArray,new_DelayedArray) -importFrom(DelayedArray,nzdata) -importFrom(DelayedArray,nzindex) -importFrom(DelayedArray,path) -importFrom(DelayedArray,read_sparse_block) importFrom(DelayedArray,rowAutoGrid) importFrom(DelayedArray,seed) -importFrom(DelayedArray,type) importFrom(HDF5Array,H5SparseMatrixSeed) importFrom(HDF5Array,HDF5Array) importFrom(HDF5Array,HDF5ArraySeed) @@ -89,10 +79,15 @@ importFrom(HDF5Array,getHDF5DumpCompressionLevel) importFrom(HDF5Array,writeHDF5Array) importFrom(Matrix,t) importFrom(Rcpp,sourceCpp) +importFrom(S4Arrays,acbind) +importFrom(S4Arrays,arbind) +importFrom(S4Arrays,extract_array) importFrom(S4Arrays,is_sparse) importFrom(S4Vectors,new2) importFrom(SparseArray,extract_sparse_array) -importFrom(SparseArray,nzdata) +importFrom(SparseArray,nzvals) +importFrom(SparseArray,nzwhich) +importFrom(SparseArray,read_block_as_sparse) importFrom(alabaster.base,.loadObject) importFrom(alabaster.base,.stageObject) importFrom(alabaster.base,.writeMetadata) diff --git a/R/AmalgamatedArray.R b/R/AmalgamatedArray.R index 51c0cb2..769e6ed 100644 --- a/R/AmalgamatedArray.R +++ b/R/AmalgamatedArray.R @@ -56,7 +56,7 @@ NULL #' @export -#' @importFrom DelayedArray arbind acbind +#' @importFrom S4Arrays arbind acbind AmalgamatedArraySeed <- function(components, along = 1) { sample.names <- names(components) if (anyDuplicated(sample.names) || any(sample.names == "")) { diff --git a/R/DelayedMask.R b/R/DelayedMask.R index 239155c..f171182 100644 --- a/R/DelayedMask.R +++ b/R/DelayedMask.R @@ -27,7 +27,6 @@ #' is_sparse,DelayedMask-method #' extract_array,DelayedMask-method #' extract_sparse_array,DelayedMask-method -#' OLD_extract_sparse_array,DelayedMask-method #' #' @examples #' original <- DelayedArray(matrix(rpois(40, lambda=2), ncol=5)) @@ -56,7 +55,7 @@ setMethod("dim", "DelayedMask", function(x) callGeneric(x@seed)) setMethod("dimnames", "DelayedMask", function(x) callGeneric(x@seed)) #' @export -#' @importFrom DelayedArray is_sparse +#' @importFrom S4Arrays is_sparse setMethod("is_sparse", "DelayedMask", function(x) { if (is.finite(x@placeholder) && x@placeholder == 0) { return(FALSE) @@ -66,7 +65,7 @@ setMethod("is_sparse", "DelayedMask", function(x) { }) #' @export -#' @importFrom DelayedArray extract_array +#' @importFrom S4Arrays extract_array setMethod("extract_array", "DelayedMask", function(x, index) { ans <- callGeneric(x@seed, index) .replace_missing(ans, x@placeholder) @@ -79,19 +78,12 @@ setMethod("extract_sparse_array", "DelayedMask", function(x, index) { if (is(ans, "COO_SparseArray")) { ans@nzdata <- .replace_missing(ans@nzdata, x@placeholder) } else { - ans@SVT <- .replace_missing_svt(ans@SVT, length(dim(x)) - 1L, x@placeholder) + nzidx <- nzwhich(ans) + ans[nzidx] <- .replace_missing(ans[nzidx], x@placeholder) } ans }) -#' @export -#' @importFrom DelayedArray OLD_extract_sparse_array -setMethod("OLD_extract_sparse_array", "DelayedMask", function(x, index) { - ans <- callGeneric(x@seed, index) - ans@nzdata <- .replace_missing(ans@nzdata, x@placeholder) - ans -}) - .replace_missing <- function(vec, placeholder) { if (is.na(placeholder)) { if (anyNA(vec)) { @@ -118,21 +110,3 @@ setMethod("OLD_extract_sparse_array", "DelayedMask", function(x, index) { vec } -.replace_missing_svt <- function(tree, dim, placeholder) { - if (dim == 1L) { - for (i in seq_along(tree)) { - current <- tree[[i]] - if (!is.null(current)) { - tree[[i]][[2]] <- .replace_missing(tree[[i]][[2]], placeholder) - } - } - } else { - for (i in seq_along(tree)) { - current <- tree[[i]] - if (!is.null(current)) { - tree[[i]] <- .replace_missing_svt(current, dim - 1L, placeholder) - } - } - } - tree -} diff --git a/R/WrapperArraySeed.R b/R/WrapperArraySeed.R index 780ff2c..51f348c 100644 --- a/R/WrapperArraySeed.R +++ b/R/WrapperArraySeed.R @@ -21,7 +21,6 @@ #' is_sparse,WrapperArraySeed-method #' extract_array,WrapperArraySeed-method #' extract_sparse_array,WrapperArraySeed-method -#' OLD_extract_sparse_array,WrapperArraySeed-method #' WrapperArray-class #' coerce,WrapperArray,dgCMatrix-method #' coerce,WrapperArraySeed,dgCMatrix-method @@ -38,7 +37,7 @@ #' dim(foo) #' is_sparse(foo) #' extract_array(foo, list(1:10, 1:10)) -#' OLD_extract_sparse_array(foo, list(1:10, 1:10)) +#' extract_sparse_array(foo, list(1:10, 1:10)) #' #' @name WrapperArraySeed NULL @@ -54,25 +53,21 @@ setMethod("dimnames", "WrapperArraySeed", function(x) callGeneric(x@seed)) setMethod("chunkdim", "WrapperArraySeed", function(x) callGeneric(x@seed)) #' @export -#' @importFrom DelayedArray path +#' @importFrom BiocGenerics path setMethod("path", "WrapperArraySeed", function(object, ...) callGeneric(object@seed)) #' @export -#' @importFrom DelayedArray is_sparse +#' @importFrom S4Arrays is_sparse setMethod("is_sparse", "WrapperArraySeed", function(x) callGeneric(x@seed)) #' @export -#' @importFrom DelayedArray extract_array +#' @importFrom S4Arrays extract_array setMethod("extract_array", "WrapperArraySeed", function(x, index) callGeneric(x@seed, index)) #' @export #' @importFrom SparseArray extract_sparse_array setMethod("extract_sparse_array", "WrapperArraySeed", function(x, index) callGeneric(x@seed, index)) -#' @export -#' @importFrom DelayedArray OLD_extract_sparse_array -setMethod("OLD_extract_sparse_array", "WrapperArraySeed", function(x, index) callGeneric(x@seed, index)) - ############################## # We define the coercion methods here to give us the opportunity to diff --git a/R/optimize_storage.R b/R/optimize_storage.R index 507bd8e..df23e0d 100644 --- a/R/optimize_storage.R +++ b/R/optimize_storage.R @@ -100,14 +100,15 @@ setMethod("collect_integer_attributes", "SVT_SparseMatrix", function(x) { }) #' @importFrom S4Arrays is_sparse -#' @importFrom SparseArray nzdata +#' @importFrom SparseArray nzvals setMethod("collect_integer_attributes", "ANY", function(x) { output <- list() if (is_sparse(x)) { collated <- blockApply(x, function(y) { - out <- .simple_integer_collector(nzdata(y)) - out$non_zero <- length(nzdata(y)) + y_nzvals <- nzvals(y) + out <- .simple_integer_collector(y_nzvals) + out$non_zero <- length(y_nzvals) out }, as.sparse=TRUE) output$non_zero <- aggregate_sum(collated, "non_zero") @@ -208,14 +209,14 @@ setMethod("collect_float_attributes", "SVT_SparseMatrix", function(x) { }) #' @importFrom S4Arrays is_sparse -#' @importFrom SparseArray nzdata +#' @importFrom SparseArray nzvals setMethod("collect_float_attributes", "ANY", function(x) { output <- list() if (is_sparse(x)) { collated <- blockApply(x, function(y) { - nzd <- nzdata(y) - out <- collect_double_attributes(nzd) - out$non_zero <- length(nzd) + y_nzvals <- nzvals(y) + out <- collect_double_attributes(y_nzvals) + out$non_zero <- length(y_nzvals) out }, as.sparse=TRUE) output$non_zero <- aggregate_sum(collated, "non_zero") @@ -267,7 +268,7 @@ optimize_float_storage <- function(x) { # Fallback that just goes through and pulls out all unique values. if (is.null(placeholder)) { if (is_sparse(x)) { - u <- Reduce(union, blockApply(x, function(y) unique(nzdata(y)))) + u <- Reduce(union, blockApply(x, function(y) unique(nzvals(y)))) } else { u <- Reduce(union, blockApply(x, function(y) unique(as.vector(y)))) } @@ -364,7 +365,10 @@ setGeneric("collect_boolean_attributes", function(x) standardGeneric("collect_bo setMethod("collect_boolean_attributes", "ANY", function(x) { output <- list() if (is_sparse(x)) { - collated <- blockApply(x, function(x) list(missing=anyNA(nzdata(x)), non_zero=length(nzdata(x))), as.sparse=TRUE) + collated <- blockApply(x, function(x) { + x_nzvals <- nzvals(x) + list(missing=anyNA(x_nzvals), non_zero=length(x_nzvals)) + }, as.sparse=TRUE) output$non_zero <- aggregate_sum(collated, "non_zero") } else { collated <- list(list(missing=anyNA(x))) diff --git a/R/readArray.R b/R/readArray.R index e060a5c..bdd674c 100644 --- a/R/readArray.R +++ b/R/readArray.R @@ -29,8 +29,8 @@ #' @export #' @aliases #' loadArray +#' @importFrom BiocGenerics type<- #' @importFrom HDF5Array HDF5Array -#' @importFrom DelayedArray type<- readArray <- function(path, metadata, ...) { fpath <- file.path(path, "array.h5") diff --git a/R/readSparseMatrix.R b/R/readSparseMatrix.R index 172100c..6175f53 100644 --- a/R/readSparseMatrix.R +++ b/R/readSparseMatrix.R @@ -22,8 +22,8 @@ #' readObject(dir) #' #' @export +#' @importFrom BiocGenerics type<- #' @importFrom HDF5Array H5SparseMatrixSeed -#' @importFrom DelayedArray type<- readSparseMatrix <- function(path, metadata, ...) { fpath <- file.path(path, "matrix.h5") name <- "compressed_sparse_matrix" diff --git a/R/saveArray.R b/R/saveArray.R index 730b347..910c064 100644 --- a/R/saveArray.R +++ b/R/saveArray.R @@ -144,7 +144,7 @@ h5_write_array <- function(handle, name, x, type, placeholder, extract.native=NU ######### OLD STUFF ########## ############################## -#' @importFrom DelayedArray is_sparse +#' @importFrom S4Arrays is_sparse #' @importFrom rhdf5 h5createFile #' @importFrom HDF5Array writeHDF5Array #' @importFrom alabaster.base transformVectorForHdf5 addMissingPlaceholderAttributeForHdf5 @@ -258,7 +258,7 @@ setMethod("stageObject", "DelayedArray", function(x, dir, path, child=FALSE) .st ) } -#' @importFrom DelayedArray is_sparse +#' @importFrom S4Arrays is_sparse .stage_any_matrix <- function(x, dir, path, child=FALSE) { if (is_sparse(x)) { .stage_sparse_matrix(x, dir, path, child=child) diff --git a/R/saveSparseMatrix.R b/R/saveSparseMatrix.R index 622e22a..b53e8f2 100644 --- a/R/saveSparseMatrix.R +++ b/R/saveSparseMatrix.R @@ -244,9 +244,9 @@ setMethod("h5_write_sparse_matrix", "ANY", function(x, handle, details, ...) { start <- 1 # don't use integers to avoid overflow pointers <- list(0) for (i in seq_along(grid)) { - block <- read_sparse_block(x, grid[[i]]) + block <- read_block_as_sparse(x, grid[[i]]) - nzdex <- nzindex(block) + nzdex <- nzwhich(block, arr.ind=TRUE) if (layout == "CSC") { primary <- nzdex[, 2] secondary <- nzdex[, 1] @@ -256,7 +256,7 @@ setMethod("h5_write_sparse_matrix", "ANY", function(x, handle, details, ...) { secondary <- nzdex[, 2] ndim <- nrow(block) } - v <- nzdata(block) + v <- nzvals(block) o <- order(primary, secondary) primary <- primary[o] diff --git a/R/utils.R b/R/utils.R index fddd7d4..fc03883 100644 --- a/R/utils.R +++ b/R/utils.R @@ -1,4 +1,4 @@ -#' @importFrom DelayedArray type +#' @importFrom BiocGenerics type to_array_type <- function(x) { switch(type(x), integer="integer", diff --git a/R/writeSparseMatrix.R b/R/writeSparseMatrix.R index 73a2e83..84643ec 100644 --- a/R/writeSparseMatrix.R +++ b/R/writeSparseMatrix.R @@ -63,7 +63,9 @@ writeSparseMatrix <- function(x, file, name, chunk=10000, column=TRUE, tenx=FALS #' @import methods #' @importFrom rhdf5 h5write h5createGroup H5Gopen H5Gopen H5Fopen H5Fclose #' h5writeAttribute h5createDataset h5writeDataset H5Sunlimited H5Gclose -#' @importFrom DelayedArray colAutoGrid rowAutoGrid read_sparse_block type +#' @importFrom BiocGenerics type +#' @importFrom SparseArray read_block_as_sparse +#' @importFrom DelayedArray colAutoGrid rowAutoGrid #' @importClassesFrom Matrix dgCMatrix .write_CS_matrix <- function(file, name, mat, chunk_dim = 10000, by_column=TRUE, use_tenx=FALSE, guess_type=TRUE) { handle <- H5Fopen(file) @@ -211,7 +213,8 @@ setGeneric(".extract_sparse_details", function(x) standardGeneric(".extract_spar } #' @importClassesFrom Matrix dsparseMatrix -#' @importFrom DelayedArray getAutoBlockLength type +#' @importFrom BiocGenerics type +#' @importFrom DelayedArray getAutoBlockLength setMethod(".extract_sparse_details", "dsparseMatrix", function(x) { chunksize <- getAutoBlockLength(type(x)) @@ -292,9 +295,9 @@ setMethod(".extract_sparse_details", "DelayedAbind", function(x) { #' @importClassesFrom DelayedArray DelayedMatrix setMethod(".extract_sparse_details", "DelayedMatrix", function(x) .extract_sparse_details(x@seed)) -#' @importFrom DelayedArray nzdata +#' @importFrom SparseArray nzvals .extract_sparse_details_fragment <- function(sparse) { - vals <- nzdata(sparse) + vals <- nzvals(sparse) any.negative <- any(vals < 0, na.rm=TRUE) any.nonint <- any(vals != round(vals), na.rm=TRUE) extreme.val <- max(abs(vals), na.rm=TRUE) @@ -344,8 +347,9 @@ setMethod(".dump_column_sparse_matrix", "dgCMatrix", function(x, handle, index.p } #' @importFrom rhdf5 h5writeDataset +#' @importFrom BiocGenerics type #' @importClassesFrom SparseArray SVT_SparseMatrix -#' @importFrom DelayedArray getAutoBlockSize type +#' @importFrom DelayedArray getAutoBlockSize setMethod(".dump_column_sparse_matrix", "SVT_SparseMatrix", function(x, handle, index.path, data.path, start, transformer) { if (x@.svt_version > 0L) { stop("SVT_SparseMatrix objects of version >= 1 are not yet supported") @@ -407,14 +411,15 @@ setMethod(".dump_column_sparse_matrix", "DelayedAbind", function(x, handle, inde unlist(collected) }) -#' @importFrom DelayedArray colAutoGrid read_sparse_block +#' @importFrom SparseArray read_block_as_sparse +#' @importFrom DelayedArray colAutoGrid setMethod(".dump_column_sparse_matrix", "ANY", function(x, handle, index.path, data.path, start, transformer) { start <- .sanitize_start(start) grid <- colAutoGrid(x) out <- vector("list", length(grid)) for (i in seq_along(grid)) { - block <- read_sparse_block(x, grid[[i]]) + block <- read_block_as_sparse(x, grid[[i]]) cout <- .blockwise_sparse_writer( block, start, @@ -432,14 +437,15 @@ setMethod(".dump_column_sparse_matrix", "ANY", function(x, handle, index.path, d unlist(out) }) -#' @importFrom DelayedArray rowAutoGrid read_sparse_block +#' @importFrom SparseArray read_block_as_sparse +#' @importFrom DelayedArray rowAutoGrid .dump_row_sparse_matrix <- function(x, handle, index.path, data.path, start, transformer) { start <- .sanitize_start(start) grid <- rowAutoGrid(x) out <- vector("list", length(grid)) for (i in seq_along(grid)) { - block <- read_sparse_block(x, grid[[i]]) + block <- read_block_as_sparse(x, grid[[i]]) cout <- .blockwise_sparse_writer( block, start, @@ -457,10 +463,10 @@ setMethod(".dump_column_sparse_matrix", "ANY", function(x, handle, index.path, d unlist(out) } -#' @importFrom DelayedArray nzindex nzdata +#' @importFrom SparseArray nzwhich nzvals #' @importFrom rhdf5 h5writeDataset .blockwise_sparse_writer <- function(block, last, transformer, file, index.path, data.path, by_column) { - nzdex <- nzindex(block) + nzdex <- nzwhich(block, arr.ind=TRUE) if (by_column) { primary <- nzdex[, 2] secondary <- nzdex[, 1] @@ -470,7 +476,7 @@ setMethod(".dump_column_sparse_matrix", "ANY", function(x, handle, index.path, d secondary <- nzdex[, 2] ndim <- nrow(block) } - v <- nzdata(block) + v <- nzvals(block) o <- order(primary, secondary) primary <- primary[o] diff --git a/man/DelayedMask.Rd b/man/DelayedMask.Rd index 3fd4c1f..1055270 100644 --- a/man/DelayedMask.Rd +++ b/man/DelayedMask.Rd @@ -10,7 +10,6 @@ \alias{is_sparse,DelayedMask-method} \alias{extract_array,DelayedMask-method} \alias{extract_sparse_array,DelayedMask-method} -\alias{OLD_extract_sparse_array,DelayedMask-method} \title{Delayed masking} \usage{ DelayedMask(x, placeholder) diff --git a/man/WrapperArraySeed.Rd b/man/WrapperArraySeed.Rd index fbd8b9b..8ac26b8 100644 --- a/man/WrapperArraySeed.Rd +++ b/man/WrapperArraySeed.Rd @@ -11,7 +11,6 @@ \alias{is_sparse,WrapperArraySeed-method} \alias{extract_array,WrapperArraySeed-method} \alias{extract_sparse_array,WrapperArraySeed-method} -\alias{OLD_extract_sparse_array,WrapperArraySeed-method} \alias{WrapperArray-class} \alias{coerce,WrapperArray,dgCMatrix-method} \alias{coerce,WrapperArraySeed,dgCMatrix-method} @@ -39,6 +38,6 @@ foo <- new("FooArraySeed", seed=y, foo_id="FOO.0001") dim(foo) is_sparse(foo) extract_array(foo, list(1:10, 1:10)) -OLD_extract_sparse_array(foo, list(1:10, 1:10)) +extract_sparse_array(foo, list(1:10, 1:10)) } diff --git a/tests/testthat/test-DelayedMask.R b/tests/testthat/test-DelayedMask.R index 5afec82..36518f3 100644 --- a/tests/testthat/test-DelayedMask.R +++ b/tests/testthat/test-DelayedMask.R @@ -34,11 +34,8 @@ test_that("sparse tests for DelayedMask", { expect_identical(ref, as.matrix(masked)) dimnames(ref) <- NULL -# spmat <- extract_sparse_array(masked, list(NULL, NULL)) -# expect_identical(ref, as.matrix(spmat)) - - spseed <- OLD_extract_sparse_array(masked, list(NULL, NULL)) - expect_identical(ref, as.matrix(spseed)) + spmat <- extract_sparse_array(masked, list(NULL, NULL)) + expect_identical(ref, as.matrix(spmat)) # Behaves correctly if zero is the placeholder. masked <- DelayedArray(DelayedMask(original, 0)) diff --git a/tests/testthat/test-optimize_storage.R b/tests/testthat/test-optimize_storage.R index e73b771..665e138 100644 --- a/tests/testthat/test-optimize_storage.R +++ b/tests/testthat/test-optimize_storage.R @@ -410,7 +410,7 @@ test_that("storage optimization works for sparse objects", { } else if (i == 2L) { fun <- function(x) as(x, "SVT_SparseMatrix") } else { - fun <- function(x) DelayedArray(as(x, "SparseArraySeed")) + fun <- function(x) DelayedArray(as(x, "COO_SparseArray")) } # Integer. diff --git a/tests/testthat/test-sparse.R b/tests/testthat/test-sparse.R index 711b8d9..426a05e 100644 --- a/tests/testthat/test-sparse.R +++ b/tests/testthat/test-sparse.R @@ -19,7 +19,7 @@ test_that("writing to a sparse matrix works as expected", { tmp <- tempfile(fileext=".h5") writeSparseMatrix(x, tmp, "csc_matrix") - if (i <= 3) { # TODO: SVT matrices don't work with read_sparse_block(), for some reason. + if (i <= 3) { writeSparseMatrix(x, tmp, "csr_matrix", column=FALSE) } writeSparseMatrix(x, tmp, "tenx_matrix", tenx=TRUE) @@ -45,7 +45,7 @@ test_that("writing to a sparse matrix works with tiny chunks", { tmp <- tempfile(fileext=".h5") setAutoBlockSize(max(dim(x))*8) writeSparseMatrix(x, tmp, "csc_matrix") - if (i <= 2) { # TODO: uncomment when SVT matrices work with read_sparse_block(). + if (i <= 2) { writeSparseMatrix(x, tmp, "csr_matrix", column=FALSE) }