Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
keller-mark committed Jun 20, 2024
1 parent a341cf8 commit 722e7db
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 119 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ LazyData: false
Language: en-US
StagedInstall: no
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.2.3
RoxygenNote: 7.3.1
VignetteBuilder: knitr
Imports:
Matrix,
Expand Down
3 changes: 3 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
export(get_giotto_obj)
export(get_sce_obj)
export(get_seurat_obj)
export(get_seurat_v5_obj)
export(get_spe_obj)
export(giotto_to_anndata_zarr)
export(obj_list)
export(sce_to_anndata_zarr)
export(seurat_to_anndata_zarr)
export(spe_to_anndata_zarr)
export(spe_to_ome_zarr)
import(Seurat)
import(SeuratObject)
importFrom(SingleCellExperiment,"reducedDims<-")
importFrom(SingleCellExperiment,int_colData)
importFrom(SingleCellExperiment,reducedDims)
Expand Down
116 changes: 4 additions & 112 deletions R/data_to_zarr.R → R/bioc_to_zarr.R
Original file line number Diff line number Diff line change
@@ -1,34 +1,3 @@

#' Save a Seurat object to an AnnData-Zarr store.
#'
#' @param seurat_obj The object to save.
#' @param out_path A path to the output Zarr store.
#' @param assay The name of the assay to save.
#' @return TRUE if the conversion succeeds.
#'
#' @export
#' @examples
#' obj <- get_seurat_obj()
#' seurat_to_anndata_zarr(obj, out_path = "data/seurat.zarr")
seurat_to_anndata_zarr <- function(seurat_obj, out_path) {
sce <- Seurat::as.SingleCellExperiment(seurat_obj)
store <- pizzarr::DirectoryStore$new(out_path)
anndataR::from_SingleCellExperiment(sce, "ZarrAnnData", store = store)
}

test_conversion <- function(num_workers = 8) {
options(
pizzarr.parallel_read_enabled = TRUE,
pizzarr.parallel_write_enabled = TRUE
)
doParallel::registerDoParallel(num_workers)

obj <- get_seurat_obj()
seurat_to_anndata_zarr(obj, "test.zarr")

doParallel::stopImplicitCluster()
}

#' Save a SingleCellExperiment to an AnnData-Zarr store.
#'
#' @param sce_obj The object to save.
Expand All @@ -48,20 +17,10 @@ sce_to_anndata_zarr <- function(sce_obj, out_path) {
# Reference: https://github.com/theislab/zellkonverter/blob/e1e95b1/R/SCE2AnnData.R#L159
colnames(reducedDims(sce_obj)[[obsm_key]]) <- NULL
}

# Use basilisk
proc <- basilisk::basiliskStart(py_env)
on.exit(basilisk::basiliskStop(proc))

success <- basilisk::basiliskRun(proc, function(sce_obj, out_path) {
anndata <- reticulate::import("anndata")
zarr <- reticulate::import("zarr")

adata <- zellkonverter::SCE2AnnData(sce_obj)
adata$write_zarr(out_path)
return(TRUE)
}, sce_obj = sce_obj, out_path = out_path)
return(success)

store <- pizzarr::DirectoryStore$new(out_path)
anndataR::from_SingleCellExperiment(sce_obj, "ZarrAnnData", store = store)
return(TRUE)
}

#' Save a SpatialExperiment to an AnnData-Zarr store.
Expand Down Expand Up @@ -166,70 +125,3 @@ spe_to_ome_zarr <- function(spe_obj, sample_id, image_id, out_path) {
}, img_arr = img_arr, sample_id = sample_id, image_id = image_id, out_path = out_path)
return(success)
}

#' Save a Giotto object to an AnnData-Zarr store
#'
#' @param giotto_obj The object to save.
#' @param out_path A path to the output Zarr store.
#' @param X_slot The name of the slot in the Giotto object to use for adata.X
#' @return TRUE if the conversion succeeds.
#'
#' @export
#' @examples
#' obj <- get_giotto_obj()
#' giotto_to_anndata_zarr(obj, "data/giotto.zarr")
#' @importFrom methods slot
giotto_to_anndata_zarr <- function(giotto_obj, out_path, X_slot = "raw_exprs") {

# Use basilisk
proc <- basilisk::basiliskStart(py_env)
on.exit(basilisk::basiliskStop(proc))

success <- basilisk::basiliskRun(proc, function(giotto_obj, out_path, X_slot) {
anndata <- reticulate::import("anndata")
zarr <- reticulate::import("zarr")

# Reference: https://github.com/theislab/zellkonverter/blob/master/R/SCE2AnnData.R#L237
make_numpy_friendly <- function(x, transpose = TRUE) {
if (transpose) {
x <- Matrix::t(x)
}
if (DelayedArray::is_sparse(x)) {
methods::as(x, "dgCMatrix")
} else {
as.matrix(x)
}
}

X <- make_numpy_friendly(slot(giotto_obj, X_slot))
obs <- slot(giotto_obj, "cell_metadata")
var <- slot(giotto_obj, "gene_metadata")

adata <- anndata$AnnData(X = X, obs = obs, var = var)

obsm <- list()

if(!is.null(slot(giotto_obj, "spatial_locs"))) {
spatial_locs <- slot(giotto_obj, "spatial_locs")
obsm[['spatial']] <- t(as.matrix(spatial_locs[, c("sdimx", "sdimy")]))
}

if(!is.null(slot(giotto_obj, "dimension_reduction"))) {
dim_reducs <- slot(giotto_obj, "dimension_reduction")$cells
for(dim_reduc_name in names(dim_reducs)) {
dim_reduc_coords <- dim_reducs[[dim_reduc_name]][[dim_reduc_name]]$coordinates
obsm[[dim_reduc_name]] <- t(as.matrix(dim_reduc_coords))
}
}

if(length(obsm) > 0) {
# TODO make_numpy_friendly is outside scope
obsm <- lapply(obsm, make_numpy_friendly)
adata$obsm <- obsm
}

adata$write_zarr(out_path)
return(TRUE)
}, giotto_obj = giotto_obj, out_path = out_path, X_slot = X_slot)
return(success)
}
3 changes: 3 additions & 0 deletions R/giotto_to_bioc.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
giotto_to_spe <- function(gio) {
return(GiottoClass::giottoToSpatialExperiment(gio))
}
19 changes: 13 additions & 6 deletions R/mock_objects.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
library(Seurat)
library(SeuratObject)
#' Get a Seurat v5 object for tests and examples.
#' @return The object.
#' @keywords internal
#' @export
#' @examples
#' obj <- get_seurat_v5_obj()
#' @import Seurat
#' @import SeuratObject
get_seurat_v5_obj <- function() {
SeuratData::InstallData("pbmcsca")
obj <- SeuratData::LoadData("pbmcsca")
return(obj)
}

#' Create a mock Seurat object for tests and examples.
#' @return The object.
Expand All @@ -12,10 +23,6 @@ get_seurat_obj <- function() {
if(!requireNamespace("Seurat", quietly = TRUE)) {
stop("Install 'Seurat' to enable creation of Seurat objects.")
}

SeuratData::InstallData("pbmcsca")
obj <- SeuratData::LoadData("pbmcsca")
return(obj)

ncells <- 100
u <- matrix(rpois(20000, 5), ncol=ncells)
Expand Down
62 changes: 62 additions & 0 deletions R/seurat_to_bioc.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
seurat_to_sce <- function(seu) {
sce <- Seurat::as.SingleCellExperiment(seu)
return(sce)
}

seurat_to_spe <- function(seu, sample_id = NA, img_id = NA) {
# Reference: https://github.com/drighelli/SpatialExperiment/issues/115
sce <- seurat_to_sce(seu)

if(is.na(sample_id)) {
sample_id <- "sample0"
}

if(length(object@images) >= 1) {

if(is.na(img_id)) {
img_id <- names(object@images)[1]
}

## Extract spatial coordinates
if("VisiumV2" %in% class(seu@images[[img_id]])) {
spatialCoords <- as.matrix(
seu@images[[img_id]]@boundaries$centroids@coords
)
} else {
spatialCoords <- as.matrix(
seu@images[[img_id]]@coordinates[, c("imagecol", "imagerow")]
)
}


## Extract and process image data
img <- SpatialExperiment::SpatialImage(
x = as.raster(seu@images[[img_id]]@image)
)

imgData <- S4Vectors::DataFrame(
sample_id = sample_id,
image_id = img_id,
data = I(list(img)),
scaleFactor = seu@images[[img_id]]@scale.factors$lowres
)
}

# Convert to SpatialExperiment
spe <- SpatialExperiment::SpatialExperiment(
assays = SummarizedExperiment::assays(sce),
rowData = SingleCellExperiment::rowData(sce),
colData = SingleCellExperiment::colData(sce),
metadata = S4Vectors::metadata(sce),
reducedDims = SingleCellExperiment::reducedDims(sce),
altExps = SingleCellExperiment::altExps(sce),
sample_id = sample_id,
spatialCoords = spatialCoords,
imgData = imgData
)
# indicate all spots are on the tissue
spe$in_tissue <- 1
spe$sample_id <- sample_id
# Return Spatial Experiment object
return(spe)
}

0 comments on commit 722e7db

Please sign in to comment.