39. 注释#
关键要点
ADT 数据注释通过用表面蛋白标记来补充 RNA 数据,从而改善细胞识别,对免疫细胞尤其有帮助。
环境设置
安装 conda:
在创建环境之前,请确保 conda 已安装在您的系统中。
保存 yml 内容:
将 yml 选项卡中的内容复制到名为
environment.yml的文件中。
创建环境:
打开终端或命令提示符。
运行以下命令:
conda env create -f environment.yml
激活环境:
创建好环境后,使用以下命令激活它:
conda activate <environment_name>
替换
<environment_name>,名称就是在environment.yml文件中指定的那个。在 yml 文件里,它看起来像这样:name: <environment_name>
验证安装:
通过运行以下命令,检查环境是否创建成功:
conda env list
name: surface-protein
channels:
- conda-forge
dependencies:
- python=3.13
- scanpy=1.12
- muon=0.1.7
- python-igraph=1.0.0
- ipykernel=7.2.0
- pip==26.0.1
- pip:
- lamindb==2.3.1
- harmonypy==0.0.9
获取数据和笔记本
本书使用 lamindb,并通过 theislab/sc-best-practices 实例 来存储、共享和加载数据集与笔记本。感谢 Lamin Labs 提供免费托管服务。
安装 lamindb
安装 lamindb Python 软件包:
pip install lamindb
可选择创建 lamin 账户
按照以下 说明 注册并登录。
验证你的设置
运行
lamin connect命令:
import lamindb as ln ln.Artifact.connect("theislab/sc-best-practices").df()
你现在应该看到最多 100 个存储的数据集。
访问数据集(Artifact)
在 Artifacts 页面 搜索该数据集。
加载一个 Artifact 及其对应的对象:
import lamindb as ln af = ln.Artifact.connect("theislab/sc-best-practices").get(key="key_of_dataset", is_latest=True) obj = af.load()
该对象现在已可在内存中访问,并可用于分析。请调整
ln.Artifact.connect("theislab/sc-best-practices").get("SOMEIDXXXX")后缀以获取相应的版本。访问笔记本(Transform)
在 Transforms 页面 搜索该笔记本。
加载笔记本:
lamin load <notebook url>
这会把笔记本下载到当前工作目录。与
Artifacts类似,你可以调整后缀 ID 来获取旧版本。
39.1. 动机#
与 scRNA-seq 数据类似,也可以基于表面蛋白标记对 ADT 数据进行注释。这对免疫细胞的注释尤其有益,因为免疫细胞在 RNA 层面很难注释,而它们的表面蛋白却能很好地刻画它们。scRNA-seq 数据可能存在 dropout(基因漏检):即某个基因虽然在某个细胞群中表达,但由于测序流程的限制,在部分细胞中却检测不到。相比之下,由于 ADT 使用抗体来定量表面蛋白,受 dropout 的影响要小得多。因此,单个表面蛋白在 ADT 数据中的信号比在 RNA 数据中更强。
例如,尽管被测序的免疫细胞通常包含 CD45 阳性细胞,但 CD45 基因在 RNA 数据中并不总是高表达。通过(额外)在 ADT 层面进行注释,可以缓解这一问题。
一般的注释流程使用与 RNA 数据相同的函数,不需要 ADT 特有的函数。
39.2. 环境设置#
import warnings
import muon as mu
import scanpy as sc
warnings.filterwarnings("ignore")
mu.set_options(pull_on_update=False)
sc.settings.verbosity = 0
sc.set_figure_params(
dpi=80,
facecolor="white",
frameon=False,
)
import lamindb as ln
ln.track()
→ loaded Transform('BnpvfJLWjHuE0005', key='annotation.ipynb'), re-started Run('QEKKxvVQBGXwIHKf') at 2026-04-10 17:37:56 UTC
→ notebook imports: lamindb-core==2.3.1 muon==0.1.7 scanpy==1.12
• recommendation: to identify the notebook across renames, pass the uid: ln.track("BnpvfJLWjHuE")
39.3. 加载数据#
我们载入上一章 批次校正 末尾保存的 MuData 对象:
af = ln.Artifact.connect("theislab/sc-best-practices").get(
key="surface-protein/cite_batch_correction.h5mu", is_latest=True
)
mdata = af.load()
mdata
MuData object with n_obs × n_vars = 117951 × 36737
var: 'gene_ids', 'feature_types'
2 modalities
rna: 117951 x 36601
obs: 'donor', 'batch'
var: 'gene_ids', 'feature_types'
prot: 117951 x 136
obs: 'donor', 'batch', 'n_genes_by_counts', 'log1p_n_genes_by_counts', 'total_counts', 'log1p_total_counts', 'n_counts', 'outliers', 'doublets_markers'
var: 'gene_ids', 'feature_types', 'n_cells_by_counts', 'mean_counts', 'log1p_mean_counts', 'pct_dropout_by_counts', 'total_counts', 'log1p_total_counts'
uns: 'batch_colors', 'donor_colors', 'doublets_markers_colors', 'neighbors', 'pca', 'umap'
obsm: 'X_pca', 'X_pca_harmony', 'X_umap'
varm: 'PCs'
obsp: 'connectivities', 'distances'39.4. 手动注释#
首先,我们检查 CD45 的表达。CD45 是 T 细胞质膜上最丰富的蛋白之一,是 TCR 信号传导所必需的。它会激活 Lck,而 Lck 又是磷酸化 TCR 复合体所必需的 [Courtney et al., 2019]。因此,CD45 应在我们的数据集中广泛表达,并在 T 细胞中表达得更高。
由于与 RNA 基因存在名称冲突,所测量的 ADT 使用的命名略有不同。var_names_make_unique 函数用于将基因名与蛋白质名分离,蛋白质可能带有 -1 后缀。我们查找一个示例基因名(CD38),以此示例性地确定其在变量名中的确切命名:
mdata["prot"].var[mdata["prot"].var.gene_ids.str.contains("CD38")]
| gene_ids | feature_types | n_cells_by_counts | mean_counts | log1p_mean_counts | pct_dropout_by_counts | total_counts | log1p_total_counts | |
|---|---|---|---|---|---|---|---|---|
| CD38-1 | CD38 | Antibody Capture | 116434 | 52.892694 | 3.986995 | 4.57481 | 6453755.0 | 15.680173 |
我们以相对较低的分辨率对细胞进行聚类。与 scRNA-seq 数据注释类似,也可以提高分辨率以获得更精细的注释。
sc.tl.leiden(
mdata["prot"],
resolution=0.1,
flavor="igraph",
n_iterations=2,
directed=False,
random_state=0,
)
为了检查哪种细胞类型中存在哪些表面标记,我们使用 scanpy 的 rank_genes_groups() 函数,然后绘制一张点图(dotplot)。该点图会标出每个聚类中差异表达最显著的 3 个基因。
sc.tl.rank_genes_groups(mdata["prot"], groupby="leiden")
sc.tl.dendrogram(mdata["prot"], groupby="leiden")
sc.pl.rank_genes_groups_dotplot(
mdata["prot"], n_genes=3, values_to_plot="logfoldchanges"
)
我们已经可以通过 CD3 的表达把第 0 和第 2 类识别为 T 细胞群,并通过 CD19 的表达把第 7 类识别为 B 细胞。接下来,我们绘制前几章中计算得到的 UMAP,并按聚类进行着色。
我们将检查几个已知的主要免疫细胞类型的标记,以确定每个聚类对应的是哪种细胞类型。
正如点图中所示,第 7 类表达 CD19,这是一个 B 细胞标记。
下面我们更详细地考察 T 细胞,并把它们分成 CD4 和 CD8 细胞。
在接下来的几张图中,我们继续寻找其他细胞类型的已知标记:NK 细胞、单核细胞和树突状细胞。
# NKT cells are CD3+ and CD56+
# NK cells are CD3- and CD56+
sc.pl.umap(mdata["prot"], color=["CD56"], frameon=False)
# CD16 is expressed in NK cells and in CD16 monocytes, which are CD14-, CD16+ and CD11c+
sc.pl.umap(mdata["prot"], color="CD16", frameon=False)
现在我们已经知道每个聚类对应哪种细胞类型,下面就用真实的细胞类型名称来替换 0–8 这些聚类编号:
mdata["prot"].obs["celltype"] = mdata["prot"].obs.leiden.copy()
mdata["prot"].obs.celltype.replace(
{
"0": "CD4 T",
"1": "Cytotoxic T",
"2": "CD8 T",
"3": "CD14 Mono",
"4": "Proliferating cells",
"5": "DC",
"6": "CD16 Mono",
"7": "B",
"8": "NK",
},
inplace=True,
)
sc.pl.umap(
mdata["prot"],
color="celltype",
legend_loc="on data",
legend_fontsize=11,
legend_fontoutline=2,
)
我们已经发现并注释了数据中的主要细胞类型。现在,我们可以通过提高聚类分辨率、并对由此得到的精细聚类进行注释,来做更精细的注释。
在本章中,我们介绍了如何基于 CITE-seq 的 ADT 数据对细胞类型进行注释。另一个有意思的方向是结合 ADT 和 RNA 数据的信息来注释细胞类型。请参阅 配对整合 章节。
af_annotation = ln.Artifact.from_mudata(
mdata,
key="surface-protein/cite_annotation.h5mu",
description="CITE-seq data after annotation",
)
af_annotation.save()
ln.finish()
39.5. 自动注释#
从技术上讲,可以使用在 ADT 数据上训练的细胞类型分类器,并对照 ADT 参考数据集进行映射。然而,专门针对 ADT 的方法很少,甚至几乎没有;关于方法学细节,请参阅 RNA 注释一章 注释。
39.6. 参考文献#
Adam H Courtney, Alexey A Shvets, Wen Lu, Gloria Griffante, Marianne Mollenauer, Veronika Horkova, Wan-Lin Lo, Steven Yu, Ondrej Stepanek, Arup K Chakraborty, and Arthur Weiss. Cd45 functions as a signaling gatekeeper in t cells. Sci. Signal., 12(604):eaaw8151, October 2019.
39.7. 贡献者#
我们衷心感谢以下人员的贡献:
39.7.2. 审阅者#
Lukas Heumos
Anna Schaar