ctDNA 液体活检数据分析¶
一句话说明¶
ctDNA(循环肿瘤 DNA)是肿瘤细胞死亡后释放到血液里的 DNA 碎片,通过抽血就能检测肿瘤突变,不需要手术取组织——这就是"液体活检"的核心思路。
核心知识点¶
1. ctDNA 基础概念¶
- cfDNA:循环游离 DNA(cell-free DNA),血液中所有游离 DNA 的总称
- ctDNA:循环肿瘤 DNA,cfDNA 中来源于肿瘤细胞的部分
- ctDNA 占比:早期肿瘤可能只有 0.01-0.1%,晚期可达 10%+
- 片段大小:cfDNA 主要峰在 ~167 bp(一个核小体缠绕长度)
- 白话:血液里漂着的 DNA 碎片大部分来自正常细胞,肿瘤贡献的只占一小部分,像大海捞针
2. 核心技术挑战¶
- 极低 VAF:突变频率可能只有 0.01-1%,需要超高灵敏度
- 分子标签(UMI):给每条 DNA 分子贴唯一标签,消除 PCR 和测序错误
- 背景噪音:正常细胞的突变(克隆性造血 CHIP)会干扰 ctDNA 检测
- 测序深度:通常需要 10,000-100,000x 的去重深度
3. 主要应用¶
| 应用 | 说明 |
|---|---|
| 早期筛查(MCED) | 多癌种早期检测(如 Grail Galleri) |
| 伴随诊断 | 检测靶向治疗相关突变(EGFR等) |
| MRD 监测 | 术后微小残留病灶检测 |
| 疗效监控 | 治疗过程中动态追踪突变 |
| 耐药监测 | 检测新出现的耐药突变 |
4. 分析流程特殊步骤¶
- UMI 处理:提取 UMI → 比对 → UMI 分组 → 共识序列
- 误差抑制:背景错误建模 + 分子标签去噪
- 片段组学(fragmentomics):利用 cfDNA 片段大小模式辅助诊断
实战代码¶
# === ctDNA 数据分析流程(含 UMI 处理) ===
# 1. 提取 UMI 并添加到读段名称
# 假设 UMI 在 read2 的前8bp
fastp -i R1.fq.gz -I R2.fq.gz \ # 输入配对数据
-o trimmed_R1.fq.gz \ # 输出修剪后R1
-O trimmed_R2.fq.gz \ # 输出修剪后R2
--umi --umi_loc read2 \ # UMI在read2
--umi_len 8 # UMI长度8bp
# 2. 比对到参考基因组
bwa mem -t 16 \ # 16线程
-R "@RG\tID:sample\tSM:sample" \ # 读组信息
hg38.fa \ # 参考基因组
trimmed_R1.fq.gz trimmed_R2.fq.gz | \ # 输入
samtools sort -o aligned.bam # 排序
# 3. UMI 分组(fgbio 工具)
fgbio GroupReadsByUmi \ # 按UMI分组
-i aligned.bam \ # 输入BAM
-o grouped.bam \ # 分组后BAM
-s adjacency \ # 分组策略(允许1bp错误)
-m 20 # 最小比对质量
# 4. 生成共识序列(去除PCR和测序错误)
fgbio CallMolecularConsensusReads \ # 分子共识
-i grouped.bam \ # 分组后BAM
-o consensus_unmapped.bam \ # 未比对的共识BAM
-M 3 \ # 最少3条读段才形成共识
--read-name-prefix "consensus" # 名称前缀
# 5. 重新比对共识序列
samtools fastq consensus_unmapped.bam | \ # 转FASTQ
bwa mem -t 16 hg38.fa - | \ # 重新比对
samtools sort -o consensus.bam # 排序
# 6. 过滤低置信度共识
fgbio FilterConsensusReads \ # 过滤共识序列
-i consensus.bam \ # 输入
-o filtered_consensus.bam \ # 输出
-r hg38.fa \ # 参考基因组
-M 3 \ # 最少支持分子数
-N 40 \ # 最低共识碱基质量
-E 0.05 # 最大错误率
# 7. 变异检测(使用 VarDict 或专用 ctDNA 工具)
vardict-java \
-G hg38.fa \ # 参考基因组
-b filtered_consensus.bam \ # 输入BAM
-f 0.001 \ # 最小VAF阈值0.1%
-N sample \ # 样本名
-c 1 -S 2 -E 3 \ # BED文件列定义
target.bed | \ # 靶区域
var2vcf_valid.pl -f 0.001 | \ # 转VCF格式
bcftools sort -o ctdna_variants.vcf # 排序输出
# ctDNA 分析:VAF 动态监测可视化
import pandas as pd # 数据处理
import matplotlib.pyplot as plt # 绑图
# 模拟治疗期间多时间点 ctDNA 数据
data = {
"时间点": ["基线", "2周", "4周", "8周", "12周", "16周"],
"EGFR_L858R_VAF": [15.2, 8.5, 2.1, 0.5, 0.1, 0.0], # 主突变VAF
"TP53_R248W_VAF": [12.8, 7.2, 1.8, 0.3, 0.05, 0.0], # 伴随突变
"EGFR_T790M_VAF": [0.0, 0.0, 0.0, 0.0, 0.2, 1.5], # 耐药突变出现!
}
df = pd.DataFrame(data) # 创建DataFrame
# 绘制 VAF 动态变化图
fig, ax = plt.subplots(figsize=(10, 6)) # 创建画布
for col in ["EGFR_L858R_VAF", "TP53_R248W_VAF", "EGFR_T790M_VAF"]:
ax.plot(df["时间点"], df[col], # 绘制折线
marker="o", linewidth=2, # 圆点+线宽
label=col.replace("_VAF", "")) # 图例
ax.set_ylabel("VAF (%)") # Y轴标签
ax.set_xlabel("治疗时间点") # X轴标签
ax.set_title("ctDNA VAF 动态监测") # 标题
ax.legend() # 显示图例
ax.set_yscale("symlog", linthresh=0.1) # 对称对数坐标(显示0附近)
plt.savefig("ctdna_monitoring.png", dpi=150) # 保存
print("注意:T790M耐药突变在12周开始出现!") # 临床提示
面试常问点¶
★ ctDNA 检测为什么需要 UMI?¶
参考答案:因为 ctDNA 的 VAF 极低(可能只有 0.01-1%),而 PCR 扩增和测序过程本身的错误率约为 0.1-1%,与真实突变信号重叠。UMI(唯一分子标识符)给每条原始 DNA 分子贴上独特标签,来自同一原始分子的 PCR 拷贝共享同一个 UMI。通过对同一 UMI 组的所有读段做共识序列,可以区分真实突变(所有拷贝都有)和 PCR/测序错误(只有部分拷贝有),将检测限降低到 0.01% 甚至更低。
★ 什么是 CHIP?对 ctDNA 分析有什么影响?¶
参考答案:CHIP(Clonal Hematopoiesis of Indeterminate Potential,不确定潜能的克隆性造血)是正常衰老过程中造血干细胞积累体细胞突变后克隆性扩增的现象。CHIP 相关突变(如 DNMT3A、TET2、ASXL1)会出现在 cfDNA 中,但并非来自肿瘤。如果不排除 CHIP,会产生假阳性。解决方法是同时检测白细胞 DNA(matched WBC),排除造血来源的突变。
速查卡片¶
| 问题 | 答案 |
|---|---|
| ctDNA 全称 | Circulating Tumor DNA |
| cfDNA 片段大小 | 主峰 ~167 bp |
| ctDNA 占比 | 0.01%-10%+ |
| 关键技术 | UMI 分子标签 |
| 测序深度 | 10,000-100,000x |
| UMI 处理工具 | fgbio, UMI-tools |
| 变异检测工具 | VarDict, Mutect2, Strelka2 |
| CHIP 影响 | 假阳性(需WBC排除) |
| MRD 检测限 | ~0.01% VAF |
| 临床应用 | 早筛、伴随诊断、MRD、耐药监测 |