diff --git a/R/data_to_zarr.R b/R/data_to_zarr.R index ba90988..a126304 100644 --- a/R/data_to_zarr.R +++ b/R/data_to_zarr.R @@ -218,9 +218,9 @@ spe_to_ome_zarr <- function(spe_obj, sample_id, image_id, out_path) { #' @export #' @examples #' obj <- get_giotto_obj() -#' giotto_to_anndata_zarr(obj, "data/giotto.zarr") +#' giotto_to_anndata_zarr(obj, "data/giotto.zarr", "raw_exprs") #' @importFrom methods slot -giotto_to_anndata_zarr <- function(giotto_obj, out_path, X_slot = "raw_exprs") { +giotto_to_anndata_zarr <- function(giotto_obj, out_path, X_slot) { # Use basilisk proc <- basilisk::basiliskStart(py_env) @@ -229,22 +229,34 @@ giotto_to_anndata_zarr <- function(giotto_obj, out_path, X_slot = "raw_exprs") { success <- basilisk::basiliskRun(proc, function(giotto_obj, out_path, X_slot) { anndata <- reticulate::import("anndata") zarr <- reticulate::import("zarr") + np <- reticulate::import("numpy", convert=FALSE) # Reference: https://github.com/theislab/zellkonverter/blob/master/R/SCE2AnnData.R#L237 - make_numpy_friendly <- function(x, transpose = TRUE) { + make_numpy_friendly <- function(x, transpose = TRUE, as_type = NA) { if (transpose) { x <- Matrix::t(x) } if (DelayedArray::is_sparse(x)) { - methods::as(x, "dgCMatrix") + x <- methods::as(x, "dgCMatrix") } else { - as.matrix(x) + x <- as.matrix(x) } + if(!is.na(as_type)) { + x <- np$array(x) + x <- x$astype(as_type) + } + + return(x) } - X <- make_numpy_friendly(slot(giotto_obj, X_slot)) + if(!is.na(X_slot)) { + X <- make_numpy_friendly(slot(giotto_obj, X_slot)) + var <- slot(giotto_obj, "gene_metadata") + } else { + X <- NULL + var <- NULL + } obs <- slot(giotto_obj, "cell_metadata") - var <- slot(giotto_obj, "gene_metadata") adata <- anndata$AnnData(X = X, obs = obs, var = var) @@ -264,8 +276,7 @@ giotto_to_anndata_zarr <- function(giotto_obj, out_path, X_slot = "raw_exprs") { } if(length(obsm) > 0) { - # TODO make_numpy_friendly is outside scope - obsm <- lapply(obsm, make_numpy_friendly) + obsm <- lapply(obsm, make_numpy_friendly, as_type = "}} \if{latex}{\out{\hypertarget{method-new}{}}} \subsection{Method \code{new()}}{ -Create a wrapper around a Seurat object. +Create a wrapper around a Giotto object. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{GiottoWrapper$new( obj, + expr_matrix = NA, cell_embeddings = NA, cell_embedding_names = NA, cell_embedding_dims = NA, @@ -99,7 +102,9 @@ Create a wrapper around a Seurat object. \describe{ \item{\code{obj}}{The object to wrap.} -\item{\code{cell_embeddings}}{The keys in the Seurat object's reductions/cell.embeddings +\item{\code{expr_matrix}}{The name of the slot in the Giotto object.} + +\item{\code{cell_embeddings}}{The keys in the Giotto object's reductions/cell.embeddings to use for creating dimensionality reduction plots.} \item{\code{cell_embedding_names}}{Names diff --git a/man/giotto_to_anndata_zarr.Rd b/man/giotto_to_anndata_zarr.Rd index 50eea05..4401520 100644 --- a/man/giotto_to_anndata_zarr.Rd +++ b/man/giotto_to_anndata_zarr.Rd @@ -4,7 +4,7 @@ \alias{giotto_to_anndata_zarr} \title{Save a Giotto object to an AnnData-Zarr store} \usage{ -giotto_to_anndata_zarr(giotto_obj, out_path, X_slot = "raw_exprs") +giotto_to_anndata_zarr(giotto_obj, out_path, X_slot) } \arguments{ \item{giotto_obj}{The object to save.} @@ -21,6 +21,6 @@ Save a Giotto object to an AnnData-Zarr store } \examples{ obj <- get_giotto_obj() -giotto_to_anndata_zarr(obj, "data/giotto.zarr") +giotto_to_anndata_zarr(obj, "data/giotto.zarr", "raw_exprs") } \keyword{internal} diff --git a/pkgdown/_pkgdown.yml b/pkgdown/_pkgdown.yml index fa407d9..faba53a 100644 --- a/pkgdown/_pkgdown.yml +++ b/pkgdown/_pkgdown.yml @@ -38,6 +38,8 @@ navbar: href: articles/single_cell_experiment.html - text: "Usage with SpatialExperiment" href: articles/spatial_experiment.html + - text: "Usage with Giotto: Basic Example" + href: articles/giotto_basic.html - text: "Usage with OME-TIFF: Local Example" href: articles/ome_tiff_local.html - text: "Usage with JSON: Local Example" diff --git a/vignettes/giotto.Rmd b/vignettes/giotto_basic.Rmd similarity index 85% rename from vignettes/giotto.Rmd rename to vignettes/giotto_basic.Rmd index be60e8b..4ec8b4d 100644 --- a/vignettes/giotto.Rmd +++ b/vignettes/giotto_basic.Rmd @@ -1,8 +1,8 @@ --- -title: "Usage with Giotto" +title: "Usage with Giotto: Basic Example" output: rmarkdown::html_vignette vignette: > - %\VignetteIndexEntry{Usage with Giotto} + %\VignetteIndexEntry{Usage with Giotto: Basic Example} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- @@ -118,6 +118,22 @@ SS_seqfish <- runPCA(gobject = SS_seqfish, genes_to_use = featgenes, scale_unit SS_seqfish <- runtSNE(SS_seqfish, dimensions_to_use = 1:15) ``` +Rescale the coordinates to help with saving as a NumPy array: + +```r +# Rescale dimensionality reduction coordinates +for(dr in names(SS_seqfish@dimension_reduction$cells)) { + old_coord_2d <- SS_seqfish@dimension_reduction$cells[[dr]][[dr]]$coordinates[, c(1, 2)] + old_coord_2d[, 1] <- old_coord_2d[, 1] - min(old_coord_2d[, 1]) + old_coord_2d[, 1] <- (old_coord_2d[, 1] / max(old_coord_2d[, 1])) * 10000 + old_coord_2d[, 2] <- old_coord_2d[, 2] - min(old_coord_2d[, 2]) + old_coord_2d[, 2] <- (old_coord_2d[, 2] / max(old_coord_2d[, 2])) * 10000 + + new_coord_2d <- old_coord_2d + SS_seqfish@dimension_reduction$cells[[dr]][[dr]]$coordinates[, c(1, 2)] <- new_coord_2d +} +``` + Set up the Vitessce widget: ```r @@ -125,6 +141,7 @@ library(vitessceR) w <- GiottoWrapper$new( SS_seqfish, + expr_matrix = "raw_exprs", cell_set_metas = c("cell_types"), cell_set_meta_names = c("Cell Types"), cell_embeddings = c("pca", "tsne"), diff --git a/vignettes/giotto_nanostring.Rmd b/vignettes/giotto_nanostring.Rmd new file mode 100644 index 0000000..08e3bbe --- /dev/null +++ b/vignettes/giotto_nanostring.Rmd @@ -0,0 +1,117 @@ +--- +title: "Usage with Giotto: NanoString dataset" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Usage with Giotto: NanoString dataset} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +The following is an example of usage of the widget with a [Giotto](https://github.com/RubD/Giotto) object from [NanoString](https://www.nanostring.com/products/cosmx-spatial-molecular-imager/ffpe-dataset/). + +First, install the R dependencies: + +```r +install.packages("devtools") +devtools::install_github("RubD/Giotto") +``` + +Download and un-tar the Giotto object: https://nanostring-public-share.s3.us-west-2.amazonaws.com/SMI-Compressed/All+SMI+Giotto+object.tar.gz + + +Load the Giotto object in R: + +```r +rdata_path <- file.path("data", "giotto", "SMI_Giotto_Object.RData") +load(rdata_path) + +# Clean up +gem@cell_metadata <- gem@cell_metadata$rna +gem@spatial_locs <- gem@spatial_locs$raw +gem@raw_exprs <- NULL +gem@norm_expr <- NULL +gem@norm_scaled_expr <- NULL +gem@custom_expr <- NULL +gem@gene_metadata <- NULL +gem@gene_ID <- NULL +``` + +Filter to select only the data from the "Lung13" tissue sample: + +```r +cell_metadata <- gem@cell_metadata +cell_ids <- cell_metadata[cell_metadata$tissue %in% c("Lung13")]$cell_ID +gem <- Giotto::subsetGiotto(gem, cell_ids = cell_ids) + +for(dr in names(gem@dimension_reduction$cells)) { + old_coord <- gem@dimension_reduction$cells[[dr]][[dr]]$coordinates + new_coord <- old_coord[rownames(old_coord) %in% cell_ids,] + gem@dimension_reduction$cells[[dr]][[dr]]$coordinates <- new_coord +} +``` + +Rescale the coordinates to help with saving as a NumPy array: + +```r +# Rescale spatial coordinates +spatial_locs <- gem@spatial_locs +spatial_locs$sdimx <- spatial_locs$sdimx*10000 +spatial_locs$sdimy <- spatial_locs$sdimy*10000 +gem@spatial_locs <- spatial_locs + +# Rescale dimensionality reduction coordinates +for(dr in names(gem@dimension_reduction$cells)) { + old_coord_2d <- gem@dimension_reduction$cells[[dr]][[dr]]$coordinates[, c(1, 2)] + old_coord_2d[, 1] <- old_coord_2d[, 1] - min(old_coord_2d[, 1]) + old_coord_2d[, 1] <- (old_coord_2d[, 1] / max(old_coord_2d[, 1])) * 10000 + old_coord_2d[, 2] <- old_coord_2d[, 2] - min(old_coord_2d[, 2]) + old_coord_2d[, 2] <- (old_coord_2d[, 2] / max(old_coord_2d[, 2])) * 10000 + + new_coord_2d <- old_coord_2d + gem@dimension_reduction$cells[[dr]][[dr]]$coordinates[, c(1, 2)] <- new_coord_2d +} +``` + +Set up the Vitessce widget: + +```r +library(vitessceR) + +w <- GiottoWrapper$new( + gem, + cell_set_metas = c("patient", "tissue", "cell_type", "niche"), + cell_set_meta_names = c("Patient", "Tissue", "Cell Type", "Niche"), + cell_embeddings = c("pca", "umapnew", "um.n200"), + cell_embedding_names = c("PCA", "Expression profile UMAP", "Neighborhood UMAP"), + out_dir = file.path("data", "giotto_nanostring") +) + +vc <- VitessceConfig$new("My config") +dataset <- vc$add_dataset("My dataset")$add_object(w) +spatial <- vc$add_view(dataset, Component$SPATIAL) +scatterplot_expr <- vc$add_view(dataset, Component$SCATTERPLOT, mapping = "Expression profile UMAP") +scatterplot_nbrh <- vc$add_view(dataset, Component$SCATTERPLOT, mapping = "Neighborhood UMAP") +cell_sets <- vc$add_view(dataset, Component$CELL_SETS) +status <- vc$add_view(dataset, Component$STATUS) +desc <- vc$add_view(dataset, Component$DESCRIPTION) +desc <- desc$set_props(description = "Visualization of a Giotto object.") + +vc$layout( + hconcat( + vconcat( + spatial, + scatterplot_expr + ), + vconcat( + hconcat(cell_sets, vconcat(desc, status)), + scatterplot_nbrh + ) + ) +) + +# Render the Vitessce widget +vc$widget(theme = "light") +``` + + +