Skip to content

Commit

Permalink
Add metadata hints for v5 writing
Browse files Browse the repository at this point in the history
Expand tests
  • Loading branch information
mojaveazure committed Aug 14, 2024
1 parent f515484 commit 6461bc9
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 19 deletions.
7 changes: 7 additions & 0 deletions apis/r/R/utils-seurat.R
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,13 @@
return(commands[idx])
}

.assay_version_hint <- function(type = c('v3', 'v5')) {
type <- match.arg(type)
return(list(soma_ecosystem_seurat_assay_version = type))
}

.ragged_array_hint <- function() list(soma_ecosystem_seurat_v5_ragged = 'ragged')

.MINIMUM_SEURAT_VERSION <- function(repr = c('v', 'c')) {
repr <- repr[1L]
repr <- match.arg(arg = repr)
Expand Down
2 changes: 2 additions & 0 deletions apis/r/R/write_seurat.R
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ write_soma.Assay5 <- function(
platform_config = platform_config,
tiledbsoma_ctx = tiledbsoma_ctx
)
ms$set_metadata(.assay_version_hint('v5'))
X <- if (!'X' %in% ms$names()) {
SOMACollectionCreate(
uri = file_path(ms$uri, 'X'),
Expand Down Expand Up @@ -327,6 +328,7 @@ write_soma.Assay5 <- function(
shape = as.integer(shape)
)
arr$.__enclos_env__$private$.write_coo_dataframe(coo)
arr$set_metadata(.ragged_array_hint())
}

# Write feature-level meta data
Expand Down
96 changes: 77 additions & 19 deletions apis/r/tests/testthat/test-SeuratIngest.R
Original file line number Diff line number Diff line change
Expand Up @@ -139,37 +139,52 @@ test_that("Write Assay mechanics", {

test_that("Write v5 in-memory Assay mechanics", {
skip_if(!extended_tests())
skip_if_not_installed('SeuratObject', minimum_version = '5.0.1')
skip_if_not_installed("SeuratObject", minimum_version = "5.0.2")

uri <- withr::local_tempdir("write-v5-assay")
uri <- tempfile(pattern = "write-v5-assay")
collection <- SOMACollectionCreate(uri)
on.exit(collection$close(), add = TRUE, after = FALSE)

rna <- get_data('pbmc_small', package = 'SeuratObject')[['RNA']]
rna <- as(rna, 'Assay5')
rna <- get_data("pbmc_small", package = "SeuratObject")[["RNA"]]
rna <- as(rna, "Assay5")
expect_no_condition(ms <- write_soma(rna, soma_parent = collection))
expect_s3_class(ms, 'SOMAMeasurement')
expect_true(ms$exists())
on.exit(ms$close(), add = TRUE, after = FALSE)

expect_identical(ms$uri, file.path(collection$uri, 'rna'))
expect_identical(ms$names(), c('X', 'var'))
expect_s3_class(ms$var, 'SOMADataFrame')
expect_identical(setdiff(ms$var$attrnames(), 'var_id'), names(rna[[]]))
expect_s3_class(ms$X, 'SOMACollection')
expect_identical(ms$uri, file.path(collection$uri, "rna"))
assay_hint <- .assay_version_hint("v5")
expect_equivalent(
ms$get_metadata(names(assay_hint)),
assay_hint[[1L]]
)
expect_identical(ms$names(), c("X", "var"))
expect_s3_class(ms$var, "SOMADataFrame")
expect_identical(setdiff(ms$var$attrnames(), "var_id"), names(rna[[]]))
expect_s3_class(ms$X, "SOMACollection")
expect_identical(ms$X$names(), SeuratObject::Layers(rna))
fmat <- methods::slot(rna, name = 'features')
cmat <- methods::slot(rna, name = 'cells')
fmat <- methods::slot(rna, name = "features")
cmat <- methods::slot(rna, name = "cells")
ragged_hint <- .ragged_array_hint()
for (lyr in SeuratObject::Layers(rna)) {
idx <- which(cmat[, lyr])
jdx <- which(fmat[, lyr])
expect_equal(ms$X$get(lyr)$shape(), c(max(idx), max(jdx)), info = lyr)
switch(
EXPR = lyr,
scale.data = expect_equivalent(
ms$X$get(lyr)$get_metadata(names(ragged_hint)),
ragged_hint[[1L]],
info = lyr
),
expect_null(ms$X$get(lyr)$get_metadata(names(ragged_hint)), info = lyr)
)
}

# Test ragged arrays
mat <- SeuratObject::LayerData(rna, 'counts')
cells2 <- paste0(colnames(rna), '.2')
features2 <- paste0(rownames(rna), '.2')
mat <- SeuratObject::LayerData(rna, "counts")
cells2 <- paste0(colnames(rna), ".2")
features2 <- paste0(rownames(rna), ".2")
layers <- list(
mat = mat,
cells2 = `colnames<-`(mat, cells2),
Expand All @@ -179,19 +194,24 @@ test_that("Write v5 in-memory Assay mechanics", {
expect_s4_class(rna2 <- SeuratObject::.CreateStdAssay(layers), "Assay5")
expect_identical(dim(rna2), dim(rna) * 2)

expect_no_condition(ms2 <- write_soma(rna2, uri = 'ragged-arrays', soma_parent = collection))
expect_s3_class(ms2, 'SOMAMeasurement')
expect_no_condition(ms2 <- write_soma(rna2, uri = "ragged-arrays", soma_parent = collection))
expect_s3_class(ms2, "SOMAMeasurement")
expect_true(ms2$exists())
on.exit(ms2$close(), add = TRUE, after = FALSE)

expect_identical(ms2$uri, file.path(collection$uri, 'ragged-arrays'))
expect_identical(ms2$uri, file.path(collection$uri, "ragged-arrays"))
expect_identical(ms2$X$names(), SeuratObject::Layers(rna2))
fmat <- methods::slot(rna2, name = 'features')
cmat <- methods::slot(rna2, name = 'cells')
fmat <- methods::slot(rna2, name = "features")
cmat <- methods::slot(rna2, name = "cells")
for (lyr in SeuratObject::Layers(rna2)) {
idx <- which(cmat[, lyr])
jdx <- which(fmat[, lyr])
expect_equal(ms2$X$get(lyr)$shape(), c(max(idx), max(jdx)), info = lyr)
expect_equivalent(
ms2$X$get(lyr)$get_metadata(names(ragged_hint)),
ragged_hint[[1L]],
info = lyr
)
}
})

Expand Down Expand Up @@ -412,3 +432,41 @@ test_that("Write Seurat mechanics", {

gc()
})

test_that("Write Seurat with v3 and v5 assays", {
skip_if(!extended_tests())
skip_if_not_installed("SeuratObject", minimum_version = "5.0.2")

pbmc_small <- get_data("pbmc_small", package = "SeuratObject")
suppressWarnings(pbmc_small[["RNA5"]] <- methods::as(pbmc_small[["RNA"]], "Assay5"))
extra <- c(
SeuratObject::Graphs(pbmc_small),
SeuratObject::Reductions(pbmc_small),
SeuratObject::Command(pbmc_small)
)
for (i in extra) {
pbmc_small[[i]] <- NULL
}

assay_hint <- .assay_version_hint("v5")
uri <- tempfile(pattern = SeuratObject::Project(pbmc_small))

expect_no_condition(uri <- write_soma(pbmc_small, uri))
expect_type(uri, "character")
expect_no_condition(experiment <- SOMAExperimentOpen(uri))
on.exit(experiment$close(), add = TRUE, after = FALSE)

expect_s3_class(experiment, "SOMAExperiment")
expect_no_error(experiment$ms)
expect_identical(sort(experiment$ms$names()), sort(c("RNA", "RNA5")))
for (assay in experiment$ms$names()) {
expect_s3_class(experiment$ms$get(assay), "SOMAMeasurement")
if (inherits(pbmc_small[[assay]], "Assay5")) {
expect_equivalent(
experiment$ms$get(assay)$get_metadata(names(assay_hint)),
assay_hint[[1L]],
info = assay
)
}
}
})

0 comments on commit 6461bc9

Please sign in to comment.