肿瘤克隆进化分析¶
一句话概述¶
使用PyClone、SciClone、PhyloWGS等工具从肿瘤体细胞突变数据中推断亚克隆结构、估计克隆细胞比例(CCF),重建肿瘤进化树以揭示肿瘤异质性和演化历程。
核心知识点总览¶
| 知识点 | 关键内容 | 重要程度 |
|---|---|---|
| 克隆与亚克隆 | 肿瘤异质性/克隆结构概念 | ⭐⭐⭐⭐⭐ |
| VAF与CCF | 变异等位基因频率→细胞克隆频率转换 | ⭐⭐⭐⭐⭐ |
| PyClone-VI | 贝叶斯聚类推断克隆结构 | ⭐⭐⭐⭐⭐ |
| SciClone | 变分贝叶斯Beta混合模型/仅用CN中性区域 | ⭐⭐⭐⭐ |
| PhyloWGS | 整合SNV+CNV构建进化树 | ⭐⭐⭐⭐ |
| 拷贝数整合 | CN状态对VAF→CCF转换的影响 | ⭐⭐⭐⭐ |
| 多区域/纵向采样 | 时空异质性揭示进化动态 | ⭐⭐⭐ |
| 进化模型 | 线性/分支/中性进化模式 | ⭐⭐⭐ |
各步骤详解¶
第一步:肿瘤克隆进化的概念基础¶
白话解释: 肿瘤不是一坨均匀的坏细胞,而是由多个不同的"子群"(克隆/亚克隆)混合而成。这些子群有共同的祖先,但在进化过程中积累了不同的突变,就像一棵树从一个根分出很多枝一样。了解肿瘤的克隆结构有助于理解耐药机制和指导治疗策略。
技术细节: 关键概念: - VAF (Variant Allele Frequency):测序数据中突变reads占总reads的比例 - CCF (Cancer Cell Fraction):携带该突变的肿瘤细胞比例 - Clonal mutation:存在于所有肿瘤细胞中(CCF≈1) - Subclonal mutation:只存在于部分肿瘤细胞中(CCF<1) - Tumor purity:样本中肿瘤细胞的比例
VAF到CCF的转换需要考虑:肿瘤纯度、局部拷贝数、突变所在等位基因的拷贝数。
# VAF → CCF 转换公式
# CCF = VAF × (purity × CN_total + (1-purity) × 2) / (purity × CN_mutant)
#
# purity: 肿瘤纯度
# CN_total: 突变位点的总拷贝数
# CN_mutant: 携带突变的等位基因拷贝数(通常为1)
#
# 例:纯度=0.8, 二倍体区域(CN=2), 杂合突变
# CCF = VAF × (0.8×2 + 0.2×2) / (0.8×1) = VAF × 2/0.8 = 2.5 × VAF
# 如果 VAF=0.4, 则 CCF=1.0(克隆突变)
# 如果 VAF=0.2, 则 CCF=0.5(亚克隆,50%肿瘤细胞携带)
第二步:输入数据准备¶
白话解释: 克隆分析需要两类关键输入:(1) 体细胞突变的VAF信息(从肿瘤-正常配对测序中获得);(2) 拷贝数信息(告诉我们每个突变位点的基因组拷贝状态)。还需要肿瘤纯度估计。
技术细节:
# === 输入数据准备 ===
# 1. 体细胞突变检测(Mutect2)
gatk Mutect2 \
-R reference.fasta \
-I tumor.bam \
-I normal.bam \
-normal normal_sample_name \
-O somatic.vcf.gz \
--f1r2-tar-gz f1r2.tar.gz
# 过滤
gatk FilterMutectCalls \
-R reference.fasta \
-V somatic.vcf.gz \
-O somatic.filtered.vcf.gz
# 2. 拷贝数分析(FACETS / Sequenza / ASCAT)
# FACETS示例
Rscript run_facets.R tumor.bam normal.bam
# 3. 肿瘤纯度估计(从FACETS/ASCAT获得)
# purity通常从拷贝数分析中同时估计
# 4. 准备PyClone输入
# 从VCF提取必要信息
bcftools query -f '%CHROM\t%POS\t%REF\t%ALT\t[%AD]\n' \
somatic.filtered.vcf.gz > mutations_for_pyclone.txt
# 准备PyClone-VI输入文件
import pandas as pd
import numpy as np
# 读取突变信息
mutations = pd.read_csv("mutations_for_pyclone.txt", sep="\t",
header=None, names=['chrom', 'pos', 'ref', 'alt', 'AD'])
# 解析AD字段(ref_count,alt_count)
mutations[['ref_counts', 'alt_counts']] = mutations['AD'].str.split(',', expand=True).astype(int)
mutations['total_counts'] = mutations['ref_counts'] + mutations['alt_counts']
mutations['vaf'] = mutations['alt_counts'] / mutations['total_counts']
# 读取拷贝数信息(从FACETS/Sequenza)
cn_segments = pd.read_csv("copy_number_segments.txt", sep="\t")
# 为每个突变匹配CN信息
def get_cn(row, cn_df):
seg = cn_df[(cn_df['chrom'] == row['chrom']) &
(cn_df['start'] <= row['pos']) &
(cn_df['end'] >= row['pos'])]
if len(seg) > 0:
return seg.iloc[0]['major_cn'], seg.iloc[0]['minor_cn']
return 1, 1
mutations[['major_cn', 'minor_cn']] = mutations.apply(
lambda row: pd.Series(get_cn(row, cn_segments)), axis=1)
mutations['total_cn'] = mutations['major_cn'] + mutations['minor_cn']
# 过滤:只保留有足够深度的位点
mutations_filtered = mutations[mutations['total_counts'] >= 20].copy()
# 生成PyClone-VI输入
pyclone_input = pd.DataFrame({
'mutation_id': mutations_filtered['chrom'] + ':' + mutations_filtered['pos'].astype(str),
'sample_id': 'tumor_sample',
'ref_counts': mutations_filtered['ref_counts'],
'alt_counts': mutations_filtered['alt_counts'],
'major_cn': mutations_filtered['major_cn'],
'minor_cn': mutations_filtered['minor_cn'],
'normal_cn': 2,
'tumour_content': 0.75 # 肿瘤纯度
})
pyclone_input.to_csv("pyclone_input.tsv", sep="\t", index=False)
第三步:PyClone-VI克隆推断¶
白话解释: PyClone-VI把所有突变根据它们的CCF相似性聚成几个"簇"(cluster),每个簇代表一个克隆或亚克隆。同一簇中的突变被认为是在进化过程中同一时间点产生的,因此存在于同一比例的肿瘤细胞中。
技术细节: PyClone-VI使用变分贝叶斯推断(比原版PyClone的MCMC快10-100倍),通过Beta-Binomial混合模型对突变reads count建模,考虑了拷贝数状态和肿瘤纯度对观测VAF的影响。已在PCAWG(1,717例患者)和TRACERx(100例患者)数据上验证。
# === PyClone-VI 运行 ===
pip install pyclone-vi
# 运行PyClone-VI
pyclone-vi fit \
-i pyclone_input.tsv \
-o pyclone_results.h5 \
-c 40 \
-d beta-binomial \
-r 10
# 参数说明:
# -c 40: 最大簇数(算法会自动选择实际簇数)
# -d beta-binomial: 数据分布模型(推荐)
# -r 10: 重启次数(取最优ELBO)
# 输出结果
pyclone-vi write-results-file \
-i pyclone_results.h5 \
-o pyclone_clusters.tsv
# PyClone-VI 结果解析与可视化
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 读取结果
results = pd.read_csv("pyclone_clusters.tsv", sep="\t")
# 查看克隆结构
cluster_summary = results.groupby('cluster_id').agg(
n_mutations=('mutation_id', 'count'),
mean_ccf=('cellular_prevalence', 'mean'),
std_ccf=('cellular_prevalence', 'std')
).sort_values('mean_ccf', ascending=False)
print("Clone structure:")
print(cluster_summary)
# 可视化:CCF分布
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
# 左:CCF密度图
for cluster in results['cluster_id'].unique():
subset = results[results['cluster_id'] == cluster]
axes[0].hist(subset['cellular_prevalence'], alpha=0.5,
label=f"Cluster {cluster} (n={len(subset)})", bins=20)
axes[0].set_xlabel("Cellular Prevalence (CCF)")
axes[0].set_ylabel("Number of mutations")
axes[0].legend()
# 右:簇大小 vs 平均CCF
axes[1].scatter(cluster_summary['mean_ccf'], cluster_summary['n_mutations'],
s=100, alpha=0.7)
for idx, row in cluster_summary.iterrows():
axes[1].annotate(f"C{idx}", (row['mean_ccf'], row['n_mutations']))
axes[1].set_xlabel("Mean CCF")
axes[1].set_ylabel("Number of mutations")
plt.tight_layout()
plt.savefig("clone_structure.pdf")
第四步:SciClone亚克隆分析¶
白话解释: SciClone特别适合从全外显子组(WES)数据中检测亚克隆。它的独特之处在于只使用拷贝数中性区域(CN=2的区域)的突变,避免了CN异常对VAF解释的复杂影响。SciClone使用变分贝叶斯Beta混合模型(VBBMM)自动推断聚类数目,计算效率远高于MCMC方法。注意:在多区域测序时,如果CN异常区域较多,可用突变数可能很少,此时PyClone-VI可能更合适。
技术细节:
# === SciClone 分析 ===
library(sciClone)
# 准备输入
# 1. VAF表(chr, pos, ref_reads, var_reads, vaf)
vafs <- read.table("sample_vafs.txt", header = TRUE)
# 列:chr, pos, ref_count, var_count, vaf
# 2. 拷贝数segments
cn_segs <- read.table("copy_number_segs.txt", header = TRUE)
# 列:chr, start, end, segment_mean (log2ratio)
# 3. 需排除的区域(LOH区域)
loh_regions <- read.table("loh_regions.txt", header = TRUE)
# 运行SciClone
sc <- sciClone(
vafs = vafs,
copyNumberCalls = cn_segs,
sampleNames = "Tumor_Sample",
regionsToExclude = loh_regions,
minimumDepth = 20,
maximumClusters = 10,
clusterMethod = "bmm" # beta mixture model
)
# 输出结果
writeClusterTable(sc, "sciclone_clusters.txt")
# 可视化
sc.plot1d(sc, "sciclone_1d.pdf")
sc.plot2d(sc, "sciclone_2d.pdf") # 需要多区域采样
# 多区域采样分析(2个区域)
sc_multi <- sciClone(
vafs = list(vafs_region1, vafs_region2),
copyNumberCalls = list(cn_region1, cn_region2),
sampleNames = c("Region1", "Region2"),
minimumDepth = 20
)
sc.plot2d(sc_multi, "multi_region_2d.pdf")
第五步:PhyloWGS进化树重建¶
白话解释: PyClone和SciClone告诉我们"有几个克隆、各含多少突变",但没有告诉我们这些克隆之间的进化关系(谁是谁的祖先?)。PhyloWGS通过贝叶斯方法同时推断克隆结构和进化树拓扑,告诉你肿瘤是如何一步步进化的。
技术细节: PhyloWGS使用树结构先验和MCMC采样,整合SNV和CNV信息,推断最可能的进化树。它的输出是一组可能的进化树及其后验概率。
# === PhyloWGS 运行 ===
# 准备SSM(Simple Somatic Mutations)文件
# 格式:id, gene, a(var_reads), d(total_reads), mu_r, mu_v
python parser/create_phylowgs_inputs.py \
--vcf-type mutect \
--tumor-sample TUMOR \
--cnvs cnv_data.txt \
--output-variants ssm_data.txt \
--output-params params.json \
somatic.filtered.vcf.gz
# 运行PhyloWGS
python multievolve.py \
--num-chains 4 \
--ssms ssm_data.txt \
--cnvs cnv_data.txt \
--params params.json \
--output-dir phylowgs_output
# 解析结果
python write_results.py \
phylowgs_output/trees.zip \
phylowgs_output/results \
--include-ssm-names
# PhyloWGS结果可视化
import json
import numpy as np
# 读取最优树
with open("phylowgs_output/results/best_tree.json") as f:
tree = json.load(f)
# 打印克隆结构
for node_id, node_data in tree['populations'].items():
print(f"Clone {node_id}:")
print(f" CCF: {node_data['cellular_prevalence']:.3f}")
print(f" Num SSMs: {len(node_data['ssms'])}")
print(f" Num CNVs: {len(node_data['cnvs'])}")
print(f" Children: {node_data.get('children', [])}")
print()
# 使用ETE3绘制进化树
from ete3 import Tree, TreeStyle
def build_newick(tree_data, node_id="0"):
children = tree_data['populations'][node_id].get('children', [])
if not children:
return f"Clone_{node_id}"
child_strs = [build_newick(tree_data, str(c)) for c in children]
return f"({','.join(child_strs)})Clone_{node_id}"
newick = build_newick(tree) + ";"
t = Tree(newick)
t.render("evolution_tree.pdf")
第六步:多区域/纵向取样的克隆进化分析¶
白话解释: 从肿瘤的一个位置采样只能看到"快照",无法直接观察进化过程。如果从肿瘤的多个空间位置采样(多区域),或在治疗前后多次采样(纵向),就能直接观察克隆的时空动态——哪些克隆在扩张,哪些在治疗后消失。
技术细节:
# === 多区域/纵向分析 ===
# 使用CITUP(Clonality Inference in Tumors Using Phylogenetics)
# 或 CliP(Clonality in Pairwise samples)
# 方法1:PyClone多样本联合分析
# 准备多样本输入(同一个病人的多个样本)
# pyclone_input_multisample.tsv 包含多个sample_id
# PyClone-VI 自动处理多样本
pyclone-vi fit \
-i multisample_input.tsv \
-o multisample_results.h5 \
-c 40 \
-d beta-binomial \
-r 10
# 方法2:使用fishplot可视化克隆动态
library(fishplot)
# 定义时间点
timepoints <- c(0, 30, 100, 200) # 天数
# 定义各克隆在各时间点的细胞比例
# 行=克隆, 列=时间点
frac.table <- matrix(
c(100, 50, 10, 0, # Clone A (对治疗敏感)
30, 80, 90, 95, # Clone B (耐药克隆)
0, 10, 20, 5), # Clone C (新出现)
ncol = 4, byrow = TRUE
)
# 定义父子关系
parents <- c(0, 1, 1) # Clone B和C都从Clone A衍生
# 创建fishplot
fish <- createFishObject(frac.table, parents, timepoints = timepoints,
clone.labels = c("Clone A", "Clone B", "Clone C"))
fish <- setCol(fish, c("#E41A1C", "#377EB8", "#4DAF4A"))
fishPlot(fish, shape = "spline", title.btm = "Clonal Evolution Under Treatment",
vlines = c(30), vlab = c("Treatment Start"))
第七步:结果解释与临床意义¶
白话解释: 克隆进化分析的最终目的是指导临床决策:理解耐药机制(哪个亚克隆携带耐药突变?)、预测复发(治疗后残存的亚克隆是什么?)、设计联合治疗策略。
技术细节:
# === 克隆进化结果的临床解读 ===
# 1. 驱动突变与克隆归属
# 确定每个驱动突变属于哪个克隆
driver_genes <- c("TP53", "KRAS", "PIK3CA", "PTEN")
driver_mutations <- results[results$gene %in% driver_genes, ]
driver_clone_assignment <- merge(driver_mutations, cluster_results,
by = "mutation_id")
# 2. 克隆的时间顺序推断
# 克隆型(CCF≈1)突变:早期/创始突变
# 亚克隆(CCF<1)突变:晚期/进展相关突变
early_mutations <- results[results$cellular_prevalence > 0.9, ]
late_mutations <- results[results$cellular_prevalence < 0.5, ]
# 3. 治疗相关克隆动态
# 比较治疗前后的CCF变化
pre_treatment <- read.csv("pre_treatment_ccf.csv")
post_treatment <- read.csv("post_treatment_ccf.csv")
ccf_change <- merge(pre_treatment, post_treatment, by = "cluster_id",
suffixes = c("_pre", "_post"))
ccf_change$delta_ccf <- ccf_change$ccf_post - ccf_change$ccf_pre
# delta_ccf > 0: 耐药克隆扩张
# delta_ccf < 0: 对治疗敏感
实战命令速查¶
# 完整克隆进化分析流程
# 1. 变异检测
gatk Mutect2 -I tumor.bam -I normal.bam -normal NORMAL -O somatic.vcf.gz
# 2. 拷贝数
Rscript run_facets.R tumor.bam normal.bam
# 3. 准备输入
python prepare_pyclone_input.py somatic.vcf.gz cn_segments.txt 0.75
# 4. 克隆推断
pyclone-vi fit -i input.tsv -o results.h5 -c 40 -d beta-binomial -r 10
pyclone-vi write-results-file -i results.h5 -o clusters.tsv
# 5. 进化树
python phylowgs/multievolve.py --ssms ssm.txt --cnvs cnv.txt
面试常问点¶
Q1: VAF和CCF的关系是什么?为什么不能直接用VAF代表克隆比例?¶
A: VAF是观测值(突变reads/总reads),CCF是生物学量(携带突变的肿瘤细胞比例)。VAF受三个因素影响:(1) 肿瘤纯度——正常细胞稀释突变信号;(2) 局部拷贝数——基因组扩增/缺失改变expected VAF;(3) 突变等位基因拷贝数。只有在纯度100%、二倍体、杂合突变的理想情况下,CCF = 2×VAF。
Q2: PyClone和SciClone的主要区别?¶
A: PyClone-VI使用所有突变(包括CN异常区域),通过Beta-Binomial混合模型显式建模CN和纯度对VAF的影响,使用变分贝叶斯推断(比原版PyClone的MCMC快10-100倍)。SciClone只使用CN中性区域(CN=2)的突变,采用变分贝叶斯Beta混合模型(VBBMM)聚类VAF,简化了模型但损失了CN异常区域的数据。SciClone的2D/3D VAF图直观展示多区域采样的克隆结构。实际中,SciClone在多区域测序时可用突变数可能很少(因为要求所有区域都是CN中性),PyClone-VI适用性更广。Benchmarking研究推荐 Mutect2 + FACETS + PyClone-VI 为最优组合。
Q3: 什么是肿瘤的中性进化模式?¶
A: 中性进化假说认为肿瘤一旦建立,后续多数亚克隆是被动"搭便车"(passenger)扩张,而非被正选择驱动。其特征是:VAF分布遵循1/f幂律分布,没有明显的亚克隆peak。检测方法包括Williams等2016年提出的1/f拟合检验。非中性进化则表现为明显的亚克隆VAF peak。
Q4: 多区域采样如何改善克隆分析?¶
A: 单点采样面临采样偏差——可能遗漏空间异质的亚克隆。多区域采样可以:(1) 发现空间受限的亚克隆;(2) 通过突变在不同区域的存在/缺失模式更准确地推断进化树拓扑;(3) 区分平行进化(convergent evolution)和线性进化。ITH(Intra-Tumor Heterogeneity)TRACERx项目就是基于多区域采样的大型研究。
Q5: 克隆进化分析对精准医疗有什么价值?¶
A: (1) 指导靶向治疗——如果耐药突变在亚克隆中,提前设计联合方案可防止耐药克隆扩张;(2) 液体活检监测——ctDNA中追踪特定克隆的VAF变化可早期预警复发;(3) 预后预测——高ITH通常预示更差预后;(4) 新抗原疫苗设计——优先选择克隆性新抗原(存在于所有肿瘤细胞)以避免免疫逃逸。
易错点¶
1. 忽略拷贝数对VAF的影响¶
在CN扩增区域(如chr8p gain),相同CCF的突变其VAF会被稀释;在LOH区域,VAF会升高。不校正CN直接聚类VAF会产生虚假的亚克隆。
2. 肿瘤纯度估计不准¶
纯度估计偏低会使所有CCF被高估,纯度偏高会使CCF被低估。建议用多种方法(FACETS/ASCAT/ABSOLUTE)估计纯度并取共识值。
3. 测序深度不足导致CCF不准¶
低深度测序(<100x)时,VAF的采样方差大,小的亚克隆难以可靠检测。WGS(30x)只能检测>10% CCF的克隆;深度靶向测序(>500x)可检测低至1%的亚克隆。
4. 聚类数过度解读¶
PyClone可能因数据噪声产生额外的小簇。不应过度解读含<5个突变的小簇。建议结合生物学先验(如驱动突变分布)评估簇的可靠性。
5. 忽略克隆之间的树约束¶
多个亚克隆之间必须满足进化树约束(如"嵌套"关系——子克隆的CCF不能超过其父克隆)。如果聚类结果违反树约束,说明存在模型假设错误或数据问题。
补充知识¶
其他克隆分析工具¶
- ABSOLUTE (Broad):联合估计纯度、倍性和CCF
- DPClust:PCAWG项目使用的DP混合模型
- CloneFinder:快速聚类方法
- Canopy:贝叶斯方法同时推断CNA和进化树
- CITUP:使用整数线性规划推断进化树
工具推荐(基于2021年Nature Communications benchmarking)¶
最优亚克隆解卷积流程:Mutect2(突变检测) + FACETS(拷贝数) + PyClone-VI(克隆聚类)。该组合在多种模拟和真实数据集上表现最优。
液体活检中的克隆追踪¶
- ctDNA中突变的动态监测可实时追踪克隆进化
- 分子残留病灶(MRD)检测使用clone-specific突变
- 治疗过程中出现新突变提示耐药克隆出现
引用推荐¶
- PyClone-VI: Gillis & Roth, BMC Bioinformatics, 2020(非2021年,发表于2020年12月10日,DOI: 10.1186/s12859-020-03919-2)
- SciClone: Miller et al., PLoS Computational Biology, 2014
- PhyloWGS: Deshwar et al., Genome Biology, 2015
- TRACERx: Jamal-Hanjani et al., NEJM, 2017
- 最优流程推荐: Benchmarking研究(2021, Nature Communications)推荐 Mutect2 + FACETS + PyClone-VI 组合