关于 spatial-transcriptomics-tutorials-with-omicverse
这是面向空间基因表达数据研究者的 OmicVerse 空间转录组教程 Skill,涵盖预处理、去卷积和下游分析,并提供 API 指引与故障排查。
主要功能
- 01空间坐标验证与变换
- 02Visium HD 细胞分割
- 03细胞类型去卷积指导
- 04空间聚类与切片整合
- 05轨迹和细胞通信分析
- 06常见流程错误排查
适用场景
- 01预处理并分割 Visium HD 数据
- 02比较 Tangram 与 cell2location 去卷积
- 03整合并聚类组织切片
- 04分析空间细胞通信
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ omicverse/ omicverse --skill spatial-transcriptomics-tutorials-with-omicverse安装后在 Claude Code 中输入/spatial-transcriptomics-tutorials-with-omicverse确认已加载。
附带文件reference.md
详细介绍
使用 OmicVerse 进行空间转录组学分析
此技能涵盖分为三个阶段的空间分析工作流:预处理、解卷积和下游分析。每个阶段都包含关键函数调用、参数指南和常见问题。
防御性验证:始终先检查空间坐标
进行任何空间操作之前,请确认空间坐标存在且为数值型:
# Required check before spatial analysis
assert 'spatial' in adata.obsm, \
"Missing adata.obsm['spatial']. Load with ov.io.spatial.read_visium() or set manually."
# Cast to float64 to prevent coordinate precision issues during rotation/cropping
adata.obsm['spatial'] = adata.obsm['spatial'].astype('float64')
阶段 1:预处理
裁剪、旋转和对齐坐标
加载 Visium 数据,并调整空间坐标以进行区域选择和对齐:
import scanpy as sc, omicverse as ov
ov.plot_set()
adata = sc.datasets.visium_sge(sample_id="V1_Breast_Cancer_Block_A_Section_1")
library_id = list(adata.uns['spatial'].keys())[0]
# Cast coordinates before manipulation
adata.obsm['spatial'] = adata.obsm['spatial'].astype('float64')
# Crop to region of interest
adata_crop = ov.space.crop_space_visium(adata, crop_loc=(0, 0), crop_area=(1000, 1000),
library_id=library_id, scale=1)
# Rotate and auto-align
adata_rot = ov.space.rotate_space_visium(adata, angle=45, library_id=library_id)
ov.space.map_spatial_auto(adata_rot, method='phase')
# For manual refinement: ov.space.map_spatial_manual(adata_rot, ...)
Visium HD 细胞分割
使用 cellpose 将 Visium HD 网格分割为细胞:
adata = ov.space.read_visium_10x(path="binned_outputs/square_002um/",
source_image_path="tissue_image.btf")
ov.pp.filter_genes(adata, min_cells=3)
ov.pp.filter_cells(adata, min_counts=1)
# H&E-based segmentation
adata = ov.space.visium_10x_hd_cellpose_he(adata, mpp=0.3, gpu=True, buffer=150)
# Expand labels to neighboring bins
ov.space.visium_10x_hd_cellpose_expand(adata, labels_key='labels_he',
expanded_labels_key='labels_he_expanded', max_bin_distance=4)
# Gene-expression-driven seeds
ov.space.visium_10x_hd_cellpose_gex(adata, obs_key="n_counts_adjusted", mpp=0.3, sigma=5)
# Merge labels and aggregate to cell-level
ov.space.salvage_secondary_labels(adata, primary_label='labels_he_expanded',
secondary_label='labels_gex', labels_key='labels_joint')
cdata = ov.space.bin2cell(adata, labels_key='labels_joint')
阶段 2:解卷积
关键 API 参考:方法选择
# CORRECT — Tangram: method passed to deconvolution() call
decov_obj = ov.space.Deconvolution(adata_sc=sc_adata, adata_sp=sp_adata,
celltype_key='Subset', result_dir='result/tangram')
decov_obj.preprocess_sc(max_cells=5000)
decov_obj.preprocess_sp()
decov_obj.deconvolution(method='tangram', num_epochs=1000)
# CORRECT — cell2location: method passed at INIT time
cell2_obj = ov.space.Deconvolution(adata_sc=sc_adata, adata_sp=sp_adata,
celltype_key='Subset', result_dir='result/c2l',
method='cell2location')
cell2_obj.deconvolution(max_epochs=30000)
cell2_obj.save_model('result/c2l/model')
注意:对于 cell2location,method 参数在初始化时设置,而不是在调用 deconvolution() 时设置。对于 Tangram,则在调用 deconvolution() 时传入。
Starfysh 原型解卷积
from omicverse.external.starfysh import AA, utils, plot_utils
visium_args = utils.prepare_data(adata_path="data/counts.h5ad",
signature_path="data/signatures.csv",
min_cells=10, filter_hvg=True, n_top_genes=3000)
adata, adata_normed = visium_args.get_adata()
aa_model = AA.ArchetypalAnalysis(adata_orig=adata_normed)
aa_model.fit(k=12, n_init=10)
visium_args = utils.refine_anchors(visium_args, aa_model, add_marker=True)
model, history = utils.run_starfysh(visium_args, poe=False, n_repeat=5, lr=5e-3, max_epochs=500)
阶段 3:下游分析
空间聚类
# GraphST + mclust
ov.utils.cluster(adata, use_rep='graphst|original|X_pca', method='mclust', n_components=7)
# STAGATE
ov.utils.cluster(adata, use_rep='STAGATE', method='mclust', n_components=7)
# Merge small clusters
ov.space.merge_cluster(adata, groupby='mclust', resolution=0.5)
算法选择:GraphST 和 STAGATE 需要预先计算的潜在空间。对于不使用空间感知嵌入的常规聚类,直接使用 Leiden/Louvain。
多切片整合(STAligner)
import anndata as ad
Batch_list = [ov.read(p) for p in slice_paths]
adata_concat = ad.concat(Batch_list, label='slice_name', keys=section_ids)
STAligner_obj = ov.space.pySTAligner(adata=adata_concat, batch_key='slice_name',
hidden_dims=[256, 64], use_gpu=True)
STAligner_obj.train_STAligner_subgraph(nepochs=800, lr=1e-3)
STAligner_obj.train()
adata_aligned = STAligner_obj.predicted()
sc.pp.neighbors(adata_aligned, use_rep='STAligner')
空间轨迹
SpaceFlow — 伪空间图:
sf_obj = ov.space.pySpaceFlow(adata)
sf_obj.train(spatial_regularization_strength=0.1, num_epochs=300, patience=50)
sf_obj.cal_pSM(n_neighbors=20, resolution=1.0)
STT — 转换动力学:
STT_obj = ov.space.STT(adata, spatial_loc='xy_loc', region='Region', n_neighbors=20)
STT_obj.stage_estimate()
STT_obj.train(n_states=9, n_iter=15, weight_connectivities=0.5)
细胞通信(COMMOT + FlowSig)
df_cellchat = ov.external.commot.pp.ligand_receptor_database(species='human', database='cellchat')
df_cellchat = ov.external.commot.pp.filter_lr_database(df_cellchat, adata, min_expr_frac=0.05)
ov.external.commot.tl.spatial_communication(adata, lr_database=df_cellchat,
distance_threshold=500, result_prefix='cellchat')
# FlowSig network
adata.layers['normalized'] = adata.X.copy()
ov.external.flowsig.tl.construct_intercellular_flow_network(
adata, commot_output_key='commot-cellchat',
flowsig_output_key='flowsig-cellchat', edge_threshold=0.7)
结构层(GASTON)和切片对齐(SLAT)
GASTON — 等深度估计:
gas_obj = ov.space.GASTON(adata)
A = gas_obj.prepare_inputs(n_pcs=50)
gas_obj.load_rescale(A)
gas_obj.train(hidden_dims=[64, 32], dropout=0.1, max_epochs=2000)
gaston_isodepth, gaston_labels = gas_obj.cal_iso_depth(n_layers=5)
SLAT — 跨切片对齐:
from omicverse.external.scSLAT.model import Cal_Spatial_Net, load_anndatas, run_SLAT, spatial_match
Cal_Spatial_Net(adata1, k_cutoff=20, model='KNN')
Cal_Spatial_Net(adata2, k_cutoff=20, model='KNN')
edges, features = load_anndatas([adata1, adata2], feature='DPCA', check_order=False)
embeddings, *_ = run_SLAT(features, edges, LGCN_layer=5)
best, index, distance = spatial_match(embeddings, adatas=[adata1, adata2])
故障排除
- 旋转后出现
ValueError: spatial coordinates out of bounds:在调用rotate_space_visium之前,将adata.obsm['spatial']转换为float64。整数坐标在三角函数旋转过程中会丢失精度。 - Cellpose 分割因内存错误而失败:对于较大的
.btf图像,使用backend='tifffile'对图像进行内存映射。如果 GPU 内存不足,请减小buffer参数。 - Tangram/cell2location 中基因 ID 重叠失败:在调用
preprocess_sc/preprocess_sp之前,统一adata_sc和adata_sp中的标识符(ENSEMBL 与基因符号)。删除不重叠的基因。 mclust聚类错误:需要rpy2和 R 的mclust包。如果 R 绑定不可用,请改用method='louvain'或method='leiden'。- STAligner/SpaceFlow 嵌入塌缩为单点:确认
adata.obsm['spatial']存在且坐标缩放适当。调整学习率(尝试lr=5e-4)和正则化强度。 - FlowSig 返回空网络:在 Moran's I 过滤之前构建空间邻居图。如果网络过于稀疏,请增加自助抽样次数或降低
edge_threshold(尝试 0.5)。 - GASTON 训练中出现
RuntimeError:提供可写的out_dir路径。PyTorch 的非确定性可能导致不同运行结果有所差异,可设置torch.manual_seed()以确保可复现性。 - SLAT 对齐中低质量匹配过多:使用更高的
k_cutoff值重新生成空间图。检查low_quality_index标记,并过滤距离分数较高的细胞。 - STT 通路富集失败:
gseapy需要网络连接来下载基因集。使用ov.utils.geneset_prepare()在本地缓存基因集,并直接传入字典。
依赖项
- 核心:
omicverse、scanpy、anndata、squidpy、numpy、matplotlib - 分割:
cellpose、opencv-python/tifffile、可选的 GPU PyTorch - 解卷积:
tangram-sc、cell2location、pytorch-lightning;Starfysh 需要torch、scikit-learn - 下游:
scikit-learn、commot、flowsig、gseapy、基于 torch 的模块(STAligner、SpaceFlow、GASTON、SLAT)
示例
- “裁剪并旋转我的 Visium 切片,然后在 HD 数据上运行 cellpose 分割,并汇总为细胞级 AnnData。”
- “使用 Tangram 和 cell2location 对我的淋巴结空间数据进行反卷积,比较比例,并绘制细胞类型图谱。”
- “使用 STAligner 整合三个 DLPFC 切片,使用 STAGATE 聚类,并通过 COMMOT+FlowSig 推断细胞间通信。”
参考
- 快速复制/粘贴命令:
reference.md
评论
支持 Markdown