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 genes
mgs <- 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$celltype
print(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细胞注释/
Author
Lihuax
Published at
2024-07-22
License
CC BY-NC-SA 4.0