别被术语吓倒,咱们先聊聊“找不同”这件事
你手里有一台测序仪产生的海量数据(FASTQ文件),还有一本参考书(参考基因组,FASTA文件)。你的任务很简单:把测序得到的短片段,一个个“夹”回它们在参考书里的正确位置。
听起来简单?当你的“短片段”有几十亿条,长度只有150个碱基,而且里面还夹杂着测序错误、插入缺失甚至真正的变异时,这个过程就成了典型的“大海捞针”。
今天我要带你走过的,正是从原始数据到最终变异清单的完整旅程。这不是枯燥的教科书,而是我们实验室里每天都在跑、每天都在优化的实战流程。我会尽量讲得通透,让你既能看懂原理,又能上手操作。
第一章:数据进门前,先看看“原料”干不干净
在把数据丢进比对软件之前,绝大多数老手都会先做一次质控和预处理。这一步做不做,直接决定后面比对的成败。
1.1 为什么要做质控?
想象一下,如果你在读一本满是错别字、页码颠倒、甚至好几页被咖啡渍糊住的参考书,你还怎么准确地找答案?测序数据也是一样。原始数据里经常混杂着:
- 接头污染(Adapter contamination):测序引物连接的DNA片段,不是样本本身的内容。
- 低质量碱基:测序仪在读取链末端时容易出错,产生大量Q20以下的碱基。
- N碱基过多:测序仪无法确定的位置,用N表示。
这些“垃圾”如果不处理,比对软件要么找不到位置,要么会错误地匹配到不该在的地方,后续变异检测就会产生大量假阳性。
1.2 质控工具:FastQC + Trimmomatic
FastQC 用于生成数据质量报告。它不会修改你的文件,只是给你一个“体检表”。
# 运行FastQC
fastqc sample_R1.fastq.gz sample_R2.fastq.gz -o qc_report/
# 查看报告
# 重点关注:
# 1. Per sequence quality scores - 整体质量分布
# 2. Sequence Content - 各碱基比例是否异常
# 3. Adapter Content - 接头污染程度
# 4. K-mer Content - 是否存在高频污染序列
拿到报告后,如果发现问题(比如接头污染超过5%,或尾部质量骤降),就用 Trimmomatic 或 Cutadapt 进行修剪。
# 使用Trimmomatic修剪ILLUMINACLIP, LEADING, TRAILING, SLIDINGWINDOW, MINLEN
java -jar /path/to/trimmomatic-0.39.jar PE \
-phred33 \
sample_R1.fastq.gz sample_R2.fastq.gz \
sample_paired_R1.fastq.gz sample_unpaired_R1.fastq.gz \
sample_paired_R2.fastq.gz sample_unpaired_R2.fastq.gz \
ILLUMINACLIP:/path/to/adapters.fa:2:30:6 \
LEADING:3 TRAILING:3 \
SLIDINGWINDOW:4:15 MINLEN:36
# 解释:
# - ILLUMINACLIP: 去除接头,参数是2(匹配对数):30(相似度):6(最小重叠)
# - LEADING/TRAILING: 头部/尾部质量低于3的碱基直接切除
# - SLIDINGWINDOW: 4碱基窗口,平均质量低于15时切除
# - MINLEN: 保留长度>=36的片段,太短的不值得比对
修剪完之后,务必再用FastQC跑一遍,确认质量问题已解决。这一步不能省。
第二章:构建索引——给参考基因组建“字典”
比对软件(如BWA-MEM)不能直接拿着整个基因组去扫,那样太慢了。它需要一份“索引”,就像字典的页码目录,让软件能快速定位到任意位置。
2.1 BWA索引构建
BWA(Burrows-Wheeler Aligner)是目前最主流的比对工具之一,它的MEM(Maximal Exact Matches)算法在速度和灵敏度之间取得了很好的平衡。
# 下载人类参考基因组(以GRCh38为例)
# 注意:实际工作中请使用与你样本匹配的版本,T2T-CHM13是最新版本
# 1. 获取参考基因组
wget https://ftp.ebi.ac.uk/pub/databases/genomes/GRCh38/GRCh38_reference_sequence/GRCh38_full_analysis_set_plus_decoy_hla.fa.gz
gunzip GRCh38_full_analysis_set_plus_decoy_hla.fa.gz
# 2. 构建BWA索引
bwa index -a bwtsw GRCh38_full_analysis_set_plus_decoy_hla.fa
# 构建完成后,你会看到多个索引文件:
# .amb .ann .bwt .fas .pax .pin .sa
# 这些文件加起来大约3GB,但比对速度快得惊人
为什么用 decoy(诱饵)序列和HLA区域?
人类基因组里有很多重复序列和高度多态性的区域(比如HLA基因)。如果不把这些“复杂路段”也放进参考基因组,数据在读这些区域时会随机匹配,导致比对质量低、变异检出假阳性高。加上decoy和HLA,能让比对更稳健。
第三章:核心步骤——BWA-MEM比对
现在,数据干净了,索引建好了,可以开始“夹”数据了。
3.1 单样本比对流程
# BWA-MEM比对(paired-end数据)
bwa mem -t 16 -R '@RG\tID:sample1\tSM:sample1\tPL:ILLUMINA\tPU:unit1' \
GRCh38_full_analysis_set_plus_decoy_hla.fa \
sample_paired_R1.fastq.gz \
sample_paired_R2.fastq.gz \
> sample1.sam
# 参数解释:
# -t 16: 使用16个线程加速(根据你的CPU核心数调整)
# -R: 添加读组信息(Read Group),这对后续变异检测至关重要!
# ID: 读组ID,通常用样本名
# SM: 样本名,变异检测软件靠这个区分不同样本
# PL: 测序平台,如ILLUMINA、PACBIO、ONT
# PU: 平台单位,通常是 flowcell 或 lane 信息
3.2 SAM转BAM并排序
SAM是人类可读的文本格式,文件巨大(通常几十GB)。BAM是它的二进制压缩版本,高效且标准。
# 转换为BAM
samtools view -bS sample1.sam | samtools sort -o sample1.sorted.bam -
# 或者一行命令更简洁
bwa mem ... | samtools view -bS - | samtools sort -o sample1.sorted.bam -
# 建立索引
samtools index sample1.sorted.bam
# 此时你会得到:
# sample1.sorted.bam (几GB)
# sample1.sorted.bam.bai (几十MB,索引文件)
3.3 为什么排序这么重要?
排序后的BAM文件,读段按染色体位置排列。这对于后续步骤至关重要:
- 重复标记:识别PCR重复(同一原始分子被测序多次)
- 局部重比对:在indel附近重新校准比对质量
- 变异检测:GATK等工具要求输入是排序后的BAM
第四章:质量优化——标记重复与局部重比对
排序后的BAM还不是最终产物,还需要“精修”。这一步决定了你能否区分“真实变异”和“测序假象”。
4.1 标记PCR重复(MarkDuplicates)
PCR扩增是测序前的必要步骤,但同一DNA分子会被复制多次,产生多个完全相同的读段。这些“重复读段”不是独立的证据,如果全部计入,会严重干扰变异频率的计算。
# 使用Picard MarkDuplicates
java -jar picard.jar MarkDuplicates \
I=sample1.sorted.bam \
O=sample1.dedup.bam \
M=sample1.dup_metrics.txt \
REMOVE_SECONDARY_ALIGNMENTS=true \
ASSUME_SORTED=true
# 重新索引
samtools index sample1.dedup.bam
如何解读重复率?
# 查看metrics文件
cat sample1.dup_metrics.txt
# 关键指标:
# PCT_DUPLICATIONS: 重复率
# UNPAIRED_READS_EXAMINED: 未配对读段数
# READ_PAIRS_EXAMINED: 检查的配对数
# READ_PAIRS_DUPLICATED: 重复的配对数
# READ_PAIRS_OPTICALLY_DUPLICATED: 光学重复数
# 示例解读:
# PCT_DUPLICATIONS = 15% → 正常范围(WES)
# PCT_DUPLICATIONS = 30-40% → 可能起始材料少,或PCR循环数过多
# PCT_DUPLICATIONS > 50% → 数据质量堪忧,变异检测可靠性下降
4.2 局部重比对(Indel Re-alignment)
在旧版GATK流程中,这一步是必须的。但在GATK4中,BQSR(碱基质量分数重新校准)取代了部分功能,而局部重比对已不再强制推荐。不过,如果你处理的是indel-rich区域(如肿瘤样本、Microsatellite区域),手动重比对仍有价值。
# GATK4 推荐流程中,这一步被BaseRecalibrator和ApplyBQSR取代
# 以下是旧版GATK3的做法,供理解原理:
# 1. 确定需要重比对的范围
gatk GenomicLocsFromVcf -L targets.vcf > intervals.list
# 2. 执行重比对
gatk IndelRealigner \
-R reference.fa \
-I sample1.dedup.bam \
-o sample1.realign.bam \
-targetIntervals intervals.intervals
# 3. 重新索引
samtools index sample1.realign.bam
现代替代方案:Base Quality Score Recalibration (BQSR)
BQSR不改变比对位置,而是调整碱基的质量分数,使其更准确反映真实错误概率。
# 1. 生成重校准表
gatk BaseRecalibrator \
-R GRCh38_full_analysis_set_plus_decoy_hla.fa \
-I sample1.dedup.bam \
-knownSites dbsnp.vcf \
-O recal_data.table
# 2. 应用重校准
gatk ApplyBQSR \
-R GRCh38_full_analysis_set_plus_decoy_hla.fa \
-I sample1.dedup.bam \
--bqsr-recal-file recal_data.table \
-O sample1.bqsr.bam
# 3. 重新索引
samtools index sample1.bqsr.bam
BQSR的核心逻辑:
假设你的测序仪在特定上下文(比如连续5个G)下,错误率偏高。BQSR会学习这种模式,然后把那些位置的碱基质量分数调低。这样,变异检测软件在计算概率时,就不会过于相信这些“可疑”的碱基。
第五章:变异检测——从BAM到VCF
现在,我们有了高质量、已去重、已重校准的BAM文件。接下来就是激动人心的时刻:找出样本与参考基因组之间的差异。
5.1 为什么用GATK HaplotypeCaller?
市面上有多种变异检测工具(FreeBayes, VarScan, Strelka等),但GATK的HaplotypeCaller是目前最广泛使用、验证最充分的标准工具。它的核心优势是局部组装:
- 不像其他工具只做“投票式”计数
- HaplotypeCaller会在每个位点周围进行de Bruijn图组装
- 重新比对局部序列,能更准确地检测indel和复杂变异
# 单样本调用
gatk HaplotypeCaller \
-R GRCh38_full_analysis_set_plus_decoy_hla.fa \
-I sample1.bqsr.bam \
-O sample1.raw.vcf.gz \
--native-pair-hmm-threads 8 \
-ERC GVCF
# 关键参数解释:
# --native-pair-hmm-threads: 使用更高效的PairHMM算法
# -ERC GVCF: 输出gVCF格式,这对后续联合分析至关重要
什么是gVCF?
标准VCF只记录变异位点。gVCF(genomic VCF)在每个位置都记录“可信度”,包括非变异位点。这意味着你可以:
- 单独分析每个样本,但保留所有信息
- 后续进行跨样本联合分析时,无需重新比对原始数据
- 快速添加新样本到已有队列中
5.2 多样本联合分析
当你有几十个、几百个样本时,逐个生成VCF再合并效率极低。GATK的GQ(GenotypeGVCFs)能直接处理gVCF文件。
# 1. 创建gVCF文件列表
ls *.g.vcf.gz > gvcf_list.txt
# 2. 联合基因型调用
gatk GenotypeGVCFs \
-R GRCh38_full_analysis_set_plus_decoy_hla.fa \
-V gatk_list \
-O cohort.raw.vcf.gz
# 3. 硬过滤(Hard Filtering)
# GATK推荐对SNV和Indel使用不同的过滤策略
gatk VariantFiltration \
-R GRCh38_full_analysis_set_plus_decoy_hla.fa \
-V cohort.raw.vcf.gz \
-O cohort.filtered.vcf.gz \
--filter-expression "QD < 2.0 || FS > 60.0 || MQ < 40.0 || SOR > 3.0" \
--filter-name "SNV_FILTER" \
--filter-expression "QD < 2.0 || FS > 200.0 || MQ < 40.0 || SOR > 10.0 || MQRankSum < -12.5 || ReadPosRankSum < -8.0" \
--filter-name "INDEL_FILTER"
过滤参数的含义:
| 指标 | 全称 | 含义 | 过滤阈值 |
|---|---|---|---|
| QD | Quality by Depth | 变异质量除以深度 | SNV < 2, Indel < 2 |
| FS | Fisher Strand Bias | strand bias,检测正负链偏好 | SNV > 60, Indel > 200 |
| MQ | Mapping Quality | 平均比对质量 | < 40 |
| SOR | Strand Odds Ratio | 另一strand bias指标 | SNV > 3, Indel > 10 |
| MQRankSum | Mapping Quality Rank Sum | 变异和参考位点的比对质量差异 | Indel < -12.5 |
| ReadPosRankSum | Read Position Rank Sum | 变异在read中的位置偏好 | Indel < -8 |
第六章:实战场景——肿瘤样本的特殊处理
普通体细胞变异检测和肿瘤样本检测有本质区别。肿瘤样本通常包含:
- 肿瘤组织(Tumor):含有体细胞突变、拷贝数变异、杂合性缺失等
- 正常组织(Normal):作为对照,排除 germline 变异
- 低频突变:肿瘤异质性导致突变等位基因频率可能低至5-10%
6.1 肿瘤-正常配对分析
# 使用Mutect2进行体细胞变异检测
# 1. 建立panel of normals (PON),用于过滤测序 artifacts
gatk Mutect2 \
-R GRCh38_full_analysis_set_plus_decoy_hla.fa \
-I tumor.bqsr.bam \
-tumor tumor \
-I normal.bqsr.bam \
-normal normal \
--germline-resource af-only-gnomad.vcf.gz \
--panel-of-normals pon.vcf.gz \
-O tumor.normal.raw.vcf.gz
# 2. 过滤
gatk FilterMutectCalls \
-V tumor.normal.raw.vcf.gz \
-O tumor.normal.filtered.vcf.gz
# 3. 注释变异(使用SnpEff或VEP)
java -jar snpEff.jar \
-noDownloads \
-dataDir /path/to/snpEff_data \
GRCh38.105 tumor.normal.filtered.vcf.gz > tumor.normal.annotated.vcf
6.2 关键过滤策略
肿瘤变异检测的挑战在于假阳性。测序错误、PCR错误、比对错误都可能被误认为低频突变。
# Mutect2的默认过滤非常严格,但你可以进一步自定义
gatk FilterMutectCalls \
-V tumor.normal.raw.vcf.gz \
--min-tumor-fraction 0.05 \ # 最小肿瘤突变频率
--contamination-estimate 0.02 \ # 交叉污染估计
-O tumor.normal.filtered.vcf.gz
常见陷阱:
- FFPE artifact:福尔马林固定石蜡包埋的组织会产生C>T/G>A错误,集中在DNA损伤位点
- 氧化 artifact:测序前的氧化步骤会产生特定的错误模式
- PCR duplication:肿瘤样本往往起始DNA量少,PCR循环多,重复率高
第七章:性能优化——让流程跑得更快
当你的队列从几十样本扩展到几千样本时,速度就成问题了。
7.1 并行化策略
”`bash
策略1:按染色体并行(最常用)
for chr in $(seq 1 22
