Artwork from anime 'mono'
740 words
4 minutes
Spotlight细胞注释
好家伙, 小小 spitlight, 硬控我半天>_
必须要写一篇博客记录一下自己的屈辱历史
关于 spotlight 细胞注释的原理, 我在另一篇博客中有简单聊过, 要是觉得不过具体的话, 可以看原论文.
背景
先简单讲一下我在使用 spotlight 前的工作状态
处理 gem 的空间转录组数据, 使用的是华大写的 stereopy 库, 到注释这一步, stereoy 包装了 singleR 工具, 试用后发现速度奇慢无比, 集群中的 GPU 资源也比较有限, 排不上队, 而同组的师姐使用 spotlight 很快就注释好了, 遂尝试使用 spotlight
工作流
在 R 中读取 h5ad
因为我之前的数据都是使用 python 进行处理的, 这里需要读取 h5ad 文件 在使用 stereopy 保存数据的时候, flavor 选择”Seurat”
st.io.stereo_to_anndata( data, flavor="seurat", output="./out/tissue_seurat.h5ad")接下来在 R 中读取时空组数据(adata)和已经注释好的单细胞经验数据(reurat_ref), 由于前者是一个 anndata 对象, Spotlight 不支持, 故接下来进一步从中获取表达谱, 构成稀疏矩阵
library(reticulate)use_condaenv(condaenv = "/path/to/anaconda/envs/env_name/bin/python", require = TRUE)ad <- import("anndata")
cat("1. loading data ...\n")adata <- ad$read_h5ad("./out/tissue_seurat.h5ad")seurat_ref <- readRDS("data/12T_harmony_celltype.rds")
expr_matrix <- t(adata$X) # 获取表达谱colnames(expr_matrix) <- as.character(adata$obs_names$tolist()) # 列名为捕获位置rownames(expr_matrix) <- as.character(adata$var_names$tolist()) # 行名为基因CAUTION注意, 注意!!! 如果你看了 NMF 的原理, 你就会知道, 对于已经注释好的单细胞表达谱(也就是上面的 seurat_ref), 应该构造出行=基因, 列=细胞的矩阵, 而对于待注释的空间组数据(expr_matrix), 应该构造行=基因, 列=捕获位置的矩阵
预处理
cat("2. preprocessing ...\n")sce <- as.SingleCellExperiment(seurat_ref)sce <- logNormCounts(sce)
# # 获取sce和seurat_obj中的共有基因集# common_gene <- intersect(rownames(sce), rownames(seurat_obj))## # 过滤sce和seurat_obj以仅保留共有基因# sce <- sce[common_gene, ]# expr_matrix <- expr_matrix[common_gene, ]# seurat_obj <- CreateSeuratObject(counts = expr_matrix)# sce <- as.SingleCellExperiment(seurat_ref)
# 去掉核糖体和线粒体基因gene <- !grepl( pattern = "^RP[L|S]|MT", x = rownames(sce))dec <- modelGeneVar(sce , subset.row = gene)
# 计算高变基因hvg <- getTopHVGs(dec, n = config$n_top_genes)
# 加上细胞注释信息colLabels(sce) <- colData(sce)$celltype
# Compute marker genesmgs <- scoreMarkers(sce, subset.row = gene)
# 保留最相关的marker基因mgs_fil <- lapply(names(mgs), function(i) { x <- mgs[[i]] # Filter and keep relevant marker genes, those with AUC > 0.8 x <- x[x$mean.AUC > 0.8, ] # Sort the genes from highest to lowest weight x <- x[order(x$mean.AUC, decreasing = TRUE), ] # Add gene and cluster id to the dataframe x$gene <- rownames(x) x$cluster <- i data.frame(x)})mgs_df <- do.call(rbind, mgs_fil)跑起来
cat("3. spotlight runing ...\n")x_matrix <- GetAssayData(seurat_ref, assay = "RNA", layer = "data")# x_matrix <- as(x_matrix, "RsparseMatrix")x <- SingleCellExperiment(list(counts = x_matrix))y <- SingleCellExperiment(list(counts = expr_matrix))groups <- sce$celltypeprint(class(x_matrix))print(class(expr_matrix))rm(seurat_ref,adata,expr_matrix,x_matrix,sce,dec)<!--ID: 1728657598895-->
res <- SPOTlight( x = x, y = y, groups = groups, mgs = mgs_df, hvg = hvg, weight_id = "mean.AUC", group_id = "cluster", gene_id = "gene")
cat("saving ... \n")saveRDS(res, file = config$spotlight_res_path)TIP另外, 经过测试, spotlight 在构建 NMF 后, 实际上会将两个稀疏矩阵 x 和 y 全部转换成 dense matrix 进行模型计算, 内存开销极大
Spotlight细胞注释
https://blog.lihuax.online/posts/work/bgi/spotlight细胞注释/