3. 比对与变异检测:BWA/GATK标准流程,VCF文件的生成与基本过滤

测序数据下机之后,你手里握着一堆 FASTQ 文件。下一步干嘛?当然是找到这些 reads 在基因组上的位置,然后揪出变异位点。这套流程我跑了不下两百次,从最初的生信小白到现在闭着眼都能写脚本,踩过的坑能绕实验室一圈。

今天咱们就把 BWA 比对和 GATK 变异检测的底裤扒干净。说白了,就是三步:把 reads 怼到参考基因组上 → 找差异 → 生成 VCF 文件。

BWA/GATK 标准流程概览 FASTQ 原始数据 BWA mem 比对 → SAM 文件 SortSam + MarkDuplicates → 排序 BAM BaseRecalibrator + ApplyBQSR HaplotypeCaller → GVCF GenotypeGVCFs → VCF 关键点:每一步都要做质量检查,别等最后才发现样本污染

3.1 BWA 比对:把 reads 放回基因组地图

BWA 是目前最主流的短序列比对工具。我当年刚入行时用过 bowtie2,后来全面转向了 BWA-mem,为什么?因为它对 gap 的处理更聪明,特别是对于长 reads 和存在结构变异的区域。

先建索引。这一步不能省,而且 索引文件必须和参考基因组版本严格对应。我吃过一次亏:用 hg19 的索引匹配了 hg38 的参考序列,结果一堆 reads 比对不上,浪费了三天。

# 下载参考基因组(以 GRCh38 为例)
wget ftp://ftp.ensembl.org/pub/release-110/fasta/homo_sapiens/dna/Homo_sapiens.GRCh38.dna.primary_assembly.fa.gz
gunzip Homo_sapiens.GRCh38.dna.primary_assembly.fa.gz

# 建立 BWA 索引
bwa index -a bwtsw Homo_sapiens.GRCh38.dna.primary_assembly.fa

比对命令很简单,但参数别乱改。我个人习惯用默认参数,除非你明确知道改动的后果。

bwa mem -t 8 -R '@RG\tID:sample1\tSM:sample1\tPL:ILLUMINA' \
    Homo_sapiens.GRCh38.dna.primary_assembly.fa \
    sample1_R1.fastq.gz sample1_R2.fastq.gz > sample1.sam

这个小细节我记得特别清楚:"-R" 参数加的 read group 信息是 GATK 后续流程的必需品。少了它,GATK 会报错,你还要回头重跑。SM 标签一定要写对,它是样本的唯一标识。

参数 作用 我的建议
-t 线程数 根据服务器核数设定,通常 8-16
-R Read Group 信息 必须包含 ID、SM、PL,不然 GATK 不认
-M 将 split reads 标记为 supplementary 做 RNA-seq 时用,DNA 一般不推荐

3.2 SAM → BAM:压缩与排序

SAM 文件是文本格式,占地方还慢。所有下游工具都要求 BAM 格式。先转格式,再排序。

# SAM → BAM
samtools view -Sb sample1.sam > sample1.bam

# 排序(按坐标)
samtools sort sample1.bam -o sample1.sorted.bam

# 建索引
samtools index sample1.sorted.bam

你想想看,这里有个很多人忽略的点:排序后的 BAM 必须建立索引 (.bai),不然 IGV 看不了,GATK 也跑不动。我曾经帮同事排查问题,他的 GATK 总是报 "No index found",其实就是这步漏了。

3.3 GATK 流程:打磨 BAM 文件

GATK 的变异检测流程,我把核心步骤列出来。这四步是标准套餐,少了哪一步都有可能引入假阳性。

  1. MarkDuplicates:标记 PCR 重复。说白了就是同一模板扩出来的多条 reads,只保留一条。
  2. FixMateInformation:修复双端 reads 的配对信息,确保两端正确关联。
  3. BaseRecalibrator + ApplyBQSR:碱基质量校正。GATK 根据已知 SNP 位点重新校准 base quality score,这一步能大幅提升变异检测准确性。
  4. HaplotypeCaller:核心变异检测,输出 GVCF 格式。
# 标记重复
gatk MarkDuplicates \
    -I sample1.sorted.bam \
    -O sample1.dedup.bam \
    -M sample1.metrics.txt

# 碱基质量校正(已知 SNPs 位点文件)
gatk BaseRecalibrator \
    -R Homo_sapiens.GRCh38.dna.primary_assembly.fa \
    -I sample1.dedup.bam \
    --known-sites dbsnp_151.vcf.gz \
    -O sample1.recal.table

gatk ApplyBQSR \
    -R Homo_sapiens.GRCh38.dna.primary_assembly.fa \
    -I sample1.dedup.bam \
    --bqsr-recal-file sample1.recal.table \
    -O sample1.recal.bam

曾经有个项目让我记忆犹新:团队成员直接用 MarkDuplicates 的默认参数,结果肿瘤样本的重复率高达 60%,导致后续变异检测灵敏度严重下降。对于 WGS 数据,我个人习惯把 REMOVE_DUPLICATES=true 加上,直接删掉重复 reads 而不是只标记。

3.4 HaplotypeCaller:变异检测核心

HaplotypeCaller 是 GATK 最强模块。它不像老方法那样直接比对 reads,而是先在目标区域构建局部单倍型,再判断可能的变异。这样做的好处很明显:对复杂区域(比如 indels 密集区)的检测准确率远高于旧算法。

# 单样本 GVCF 模式
gatk HaplotypeCaller \
    -R Homo_sapiens.GRCh38.dna.primary_assembly.fa \
    -I sample1.recal.bam \
    -O sample1.g.vcf.gz \
    -ERC GVCF

# 如果要做多个样本的 joint genotyping,这个 GVCF 是必须的

参数方面,-ERC GVCF 是推荐选项。它把所有位点的信息都输出(包括非变异位点),这是后续联合分析的基础。如果你只输出 VCF,那只有变异位点的信息,很多统计模型就没法算了。

3.5 VCF 文件生成与基本过滤

单个样本的 GVCF 做完,要汇聚成群体 VCF。这才是大家期待的最终产物。

# 合并 GVCF
gatk GenomicsDBImport \
    -V sample1.g.vcf.gz \
    -V sample2.g.vcf.gz \
    -V sample3.g.vcf.gz \
    --genomicsdb-workspace-path my_database \
    -L intervals.list

# 联合基因分型
gatk GenotypeGVCFs \
    -R Homo_sapiens.GRCh38.dna.primary_assembly.fa \
    -V gendb://my_database \
    -O cohort.vcf.gz

VCF 文件生成之后,别急着交差。原始 VCF 里充斥着各种假阳性,必须做过滤。GATK 推荐用 VariantFiltration 做硬过滤,或者用 VQSR 做软过滤。

黄金过滤参数(适用于 WGS 数据):

  • QD (质量深度) < 2.0
  • FS (链偏好 Fisher 检验) > 60.0
  • MQ (比对质量) < 40.0
  • MQRankSum < -12.5
  • ReadPosRankSum < -8.0
# 硬过滤示例
gatk VariantFiltration \
    -R Homo_sapiens.GRCh38.dna.primary_assembly.fa \
    -V cohort.vcf.gz \
    -O cohort.filtered.vcf.gz \
    --filter-expression "QD < 2.0" --filter-name "LowQD" \
    --filter-expression "FS > 60.0" --filter-name "HighFS" \
    --filter-expression "MQ < 40.0" --filter-name "LowMQ" \
    --filter-expression "MQRankSum < -12.5" --filter-name "LowMQRankSum" \
    --filter-expression "ReadPosRankSum < -8.0" --filter-name "LowReadPosRankSum"
过滤标准 说明 建议阈值
QD 变异质量值 / 深度,低 QD 通常表示支持证据不足 < 2.0
FS 链偏好 Fisher 检验,高 FS 表示 reads 偏向一条链 > 60.0 (SNP), > 200.0 (INDEL)
MQ 比对质量,低 MQ 表示 reads 比对到重复区域 < 40.0

最后说个经验:过滤参数别死板照搬。WES 和 WGS 的数据特性不同,WES 的深度高但覆盖不均匀,WES 的 QD 和 FS 阈值可以适当放宽。我通常先看看 VCF 中各指标的分布,再决定阈值。