Skip to content

Commit

Permalink
Merge pull request #995 from drieslab/db
Browse files Browse the repository at this point in the history
feat: dbverse integration 
---
filterGiotto()
normalizeGiotto()
  • Loading branch information
Ed2uiz authored Jul 31, 2024
2 parents e2d4e2c + 7697019 commit 047d0b0
Show file tree
Hide file tree
Showing 7 changed files with 399 additions and 7 deletions.
3 changes: 2 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ Suggests:
tiff,
trendsceek,
testthat (>= 3.0.0),
qs
qs,
rmarkdown
Remotes:
drieslab/GiottoUtils,
drieslab/GiottoClass,
Expand Down
73 changes: 67 additions & 6 deletions R/auxiliary_giotto.R
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,13 @@
# mymatrix = log(mymatrix + offset)/log(base)
} else if (methods::is(mymatrix, "dgCMatrix")) {
mymatrix@x <- log(mymatrix@x + offset) / log(base)
# replace with sparseMatrixStats
# replace with sparseMatrixStats
} else if (methods::is(mymatrix, "Matrix")) {
mymatrix@x <- log(mymatrix@x + offset) / log(base)
} else {
} else if(methods::is(mymatrix, 'dbMatrix')) {
mymatrix[] <- dplyr::mutate(mymatrix[], x = x + offset) # workaround for lack of @x slot
mymatrix <- log(mymatrix)/log(base)
} else {
mymatrix <- log(as.matrix(mymatrix) + offset) / log(base)
}

Expand Down Expand Up @@ -732,14 +735,56 @@ filterGiotto <- function(
description = "_filter"
)

return(newGiottoObject)
return(newGiottoObject)


}




### normalization ####

#' @title compute_dbMatrix
#' @description saves dbMatrix to db if global option is set
#' @details
#' Set \code{options(giotto.dbmatrix_compute = FALSE)} if saving dbMatrix
#' after each step of normalization workflow is not desired.
#' @keywords internal
.compute_dbMatrix <- function(dbMatrix, name, verbose = TRUE) {
# input validation
if(!inherits(dbMatrix, 'dbMatrix')) {
stop('dbMatrix must be of class dbMatrix')
}

if(!is.character(name)) {
stop('name must be a character')
}

# TODO: update with dbData generic
con = dbMatrix:::get_con(dbMatrix)

# overwrite table by default
if(name %in% DBI::dbListTables(con)) {
DBI::dbRemoveTable(con, name)
}

if(verbose){
msg <- glue::glue('Computing {name} expression matrix on disk...')
cat(msg)
}

dbMatrix[] |>
dplyr::compute(temporary=F, name = name)

# TODO: update below with proper setters from dbMatrix
dbMatrix[] <- dplyr::tbl(con, name) # reassign to computed mat
dbMatrix@name <- name

if(verbose) cat('done \n')

return(dbMatrix)
}

#' @title RNA standard normalization
#' @name .rna_standard_normalization
Expand Down Expand Up @@ -776,9 +821,6 @@ filterGiotto <- function(
feat_names <- rownames(raw_expr[])
col_names <- colnames(raw_expr[])




## 1. library size normalize
if (library_size_norm == TRUE) {
norm_expr <- .lib_norm_giotto(
Expand Down Expand Up @@ -853,6 +895,16 @@ filterGiotto <- function(
}

## 5. create and set exprObj
# Save dbMatrix to db
compute_mat <- getOption("giotto.dbmatrix_compute", default = FALSE)
if(compute_mat && !is.null(norm_expr)){
norm_expr <- .compute_dbMatrix(
dbMatrix = norm_expr,
name = 'normalized',
verbose = verbose
)
}

norm_expr <- create_expr_obj(
name = "normalized",
exprMat = norm_expr,
Expand All @@ -861,6 +913,15 @@ filterGiotto <- function(
provenance = provenance,
misc = NULL
)

# Save dbMatrix to db
if(compute_mat && !is.null(norm_scaled_expr)){
norm_scaled_expr = .compute_dbMatrix(
dbMatrix = norm_scaled_expr,
name = 'scaled',
verbose = verbose
)
}

norm_scaled_expr <- create_expr_obj(
name = "scaled",
Expand Down
45 changes: 45 additions & 0 deletions tests/testthat/test-dbMatrix_filterGiotto.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# silence deprecated internal functions
rlang::local_options(lifecycle_verbosity = "quiet")

# ---------------------------------------------------------------------------- #
# Setup data
visium = GiottoData::loadGiottoMini(dataset = "visium")
dgc = getExpression(visium, output = "matrix")

con = DBI::dbConnect(duckdb::duckdb(), ":memory:")

dbsm = dbMatrix::dbMatrix(value = dgc,
con = con,
name = 'dgc',
class = "dbSparseMatrix",
overwrite = TRUE)

# Create exprObj with dbsm
expObj_db = createExprObj(expression_data = dbsm,
expression_matrix_class = 'dbSparseMatrix',
name = 'raw')

# Create giotto object
gobject_db = suppressWarnings(createGiottoObject(expression = expObj_db))

# ---------------------------------------------------------------------------- #
# Perform filtering
visium_filtered = filterGiotto(visium, spat_unit = "cell",
feat_type = "rna",
expression_values = "raw")

gobject_db_filtered = filterGiotto(gobject_db, spat_unit = "cell",
feat_type = "rna",
expression_values = "raw")

# Get filtered matrix
dgc_visium = getExpression(visium_filtered, output = "matrix")
mat_db = getExpression(gobject_db_filtered, output = "matrix")
dgc_db = dbMatrix:::as_matrix(mat_db)

# ---------------------------------------------------------------------------- #
# Test filterGiotto() equivalence between dbMatrix and dgCMatrix

test_that("dbMatrix equivalent to dgCMatrix after filterGiotto()", {
expect_equal(dgc_visium, dgc_db)
})
64 changes: 64 additions & 0 deletions tests/testthat/test-dbMatrix_libNorm.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# silence deprecated internal functions
rlang::local_options(lifecycle_verbosity = "quiet")

# ---------------------------------------------------------------------------- #
# Setup data
visium = GiottoData::loadGiottoMini(dataset = "visium")
dgc = getExpression(visium, output = "matrix")

con = DBI::dbConnect(duckdb::duckdb(), ":memory:")

dbsm = dbMatrix::dbMatrix(value = dgc,
con = con,
name = 'dgc',
class = "dbSparseMatrix",
overwrite = TRUE)

# Create exprObj with dbsm
expObj_db = createExprObj(expression_data = dbsm,
expression_matrix_class = 'dbSparseMatrix',
name = 'raw')

# Create giotto object
gobject_db = suppressWarnings(createGiottoObject(expression = expObj_db))

# ---------------------------------------------------------------------------- #
# Perform filtering
visium_filtered = filterGiotto(visium, spat_unit = "cell",
feat_type = "rna",
expression_values = "raw")

gobject_db_filtered = filterGiotto(gobject_db, spat_unit = "cell",
feat_type = "rna",
expression_values = "raw")

# ---------------------------------------------------------------------------- #
# Perform library normalization and scaling
visium_filtered = normalizeGiotto(gobject = visium_filtered,
spat_unit = 'cell',
feat_type = 'rna',
expression_values = 'raw',
library_size_norm = TRUE,
log_norm = FALSE,
scale_feats = FALSE,
scale_cells = FALSE)


gobject_db_filtered = normalizeGiotto(gobject = gobject_db_filtered,
spat_unit = 'cell',
feat_type = 'rna',
expression_values = 'raw',
library_size_norm = TRUE,
log_norm = FALSE,
scale_feats = FALSE,
scale_cells = FALSE)
# Get normalized matrix
dgc_visium = getExpression(visium_filtered, output = "matrix", values = "normalized")
mat_db = getExpression(gobject_db_filtered, output = "matrix", values = "normalized")
dgc_db = dbMatrix:::as_matrix(mat_db)

# ---------------------------------------------------------------------------- #
# Test normalizeGiotto() equivalence between dbMatrix and dgCMatrix
test_that("dbMatrix equivalent to dgCMatrix after normalizeGiotto(library_size_norm = TRUE)", {
expect_equal(dgc_visium, dgc_db)
})
64 changes: 64 additions & 0 deletions tests/testthat/test-dbMatrix_logNorm.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# silence deprecated internal functions
rlang::local_options(lifecycle_verbosity = "quiet")

# ---------------------------------------------------------------------------- #
# Setup data
visium = GiottoData::loadGiottoMini(dataset = "visium")
dgc = getExpression(visium, output = "matrix")

con = DBI::dbConnect(duckdb::duckdb(), ":memory:")

dbsm = dbMatrix::dbMatrix(value = dgc,
con = con,
name = 'dgc',
class = "dbSparseMatrix",
overwrite = TRUE)

# Create exprObj with dbsm
expObj_db = createExprObj(expression_data = dbsm,
expression_matrix_class = 'dbSparseMatrix',
name = 'raw')

# Create giotto object
gobject_db = suppressWarnings(createGiottoObject(expression = expObj_db))

# ---------------------------------------------------------------------------- #
# Perform filtering
visium_filtered = filterGiotto(visium, spat_unit = "cell",
feat_type = "rna",
expression_values = "raw")

gobject_db_filtered = filterGiotto(gobject_db, spat_unit = "cell",
feat_type = "rna",
expression_values = "raw")

# ---------------------------------------------------------------------------- #
# Perform library normalization and scaling
visium_filtered = normalizeGiotto(gobject = visium_filtered,
spat_unit = 'cell',
feat_type = 'rna',
expression_values = 'raw',
library_size_norm = FALSE,
log_norm = TRUE,
scale_feats = FALSE,
scale_cells = FALSE)


gobject_db_filtered = normalizeGiotto(gobject = gobject_db_filtered,
spat_unit = 'cell',
feat_type = 'rna',
expression_values = 'raw',
library_size_norm = FALSE,
log_norm = TRUE,
scale_feats = FALSE,
scale_cells = FALSE)
# Get normalized matrix
dgc_visium = getExpression(visium_filtered, output = "matrix", values = "normalized")
mat_db = getExpression(gobject_db_filtered, output = "matrix", values = "normalized")
dgc_db = dbMatrix:::as_matrix(mat_db)

# ---------------------------------------------------------------------------- #
# Test normalizeGiotto() equivalence between dbMatrix and dgCMatrix
test_that("dbMatrix equivalent to dgCMatrix after normalizeGiotto(log_norm=TRUE)", {
expect_equal(dgc_visium, dgc_db)
})
64 changes: 64 additions & 0 deletions tests/testthat/test-dbMatrix_scale.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# silence deprecated internal functions
rlang::local_options(lifecycle_verbosity = "quiet")

# ---------------------------------------------------------------------------- #
# Setup data
visium = GiottoData::loadGiottoMini(dataset = "visium")
dgc = getExpression(visium, output = "matrix")

con = DBI::dbConnect(duckdb::duckdb(), ":memory:")

dbsm = dbMatrix::dbMatrix(value = dgc,
con = con,
name = 'dgc',
class = "dbSparseMatrix",
overwrite = TRUE)

# Create exprObj with dbsm
expObj_db = createExprObj(expression_data = dbsm,
expression_matrix_class = 'dbSparseMatrix',
name = 'raw')

# Create giotto object
gobject_db = suppressWarnings(createGiottoObject(expression = expObj_db))

# ---------------------------------------------------------------------------- #
# Perform filtering
visium_filtered = filterGiotto(visium, spat_unit = "cell",
feat_type = "rna",
expression_values = "raw")

gobject_db_filtered = filterGiotto(gobject_db, spat_unit = "cell",
feat_type = "rna",
expression_values = "raw")

# ---------------------------------------------------------------------------- #
# Perform library normalization and scaling
visium_filtered = normalizeGiotto(gobject = visium_filtered,
spat_unit = 'cell',
feat_type = 'rna',
expression_values = 'raw',
library_size_norm = FALSE,
log_norm = FALSE,
scale_feats = TRUE,
scale_cells = TRUE)


gobject_db_filtered = normalizeGiotto(gobject = gobject_db_filtered,
spat_unit = 'cell',
feat_type = 'rna',
expression_values = 'raw',
library_size_norm = FALSE,
log_norm = FALSE,
scale_feats = TRUE,
scale_cells = TRUE)
# Get normalized matrix
dgc_visium = getExpression(visium_filtered, output = "matrix", values = "scaled") |> as.matrix()
mat_db = getExpression(gobject_db_filtered, output = "matrix", values = "scaled")
dgc_db = dbMatrix:::as_matrix(mat_db)

# ---------------------------------------------------------------------------- #
# Test normalizeGiotto() equivalence between dbMatrix and dgCMatrix
test_that("dbMatrix equivalent to dgCMatrix after normalizeGiotto(scale_feats=T,scale=cells=T)", {
expect_equal(dgc_visium, dgc_db)
})
Loading

0 comments on commit 047d0b0

Please sign in to comment.