4. 标记重复(MarkDuplicates)参数与技巧归纳总结

标记重复,说白了就是找出测序里那些「拍了一样的照片」。PCR扩增的时候,同一个模板会被复制好多份,导致后续分析里一条read被反复计数。这就会造成变异频率的偏差。你想想看,一个5%的突变,要是被PCR扩增后占了30%的read,结果就完全歪了。

MarkDuplicates就是干这个活的。它把定位相同的read聚在一起,只留一条高质量的,其余标记成重复。我个人习惯,这个步骤绝对不会跳过,不管数据量多大。

核心原则: 不是所有重复都是PCR产物。自然片段化的DNA在打断时也可能产生完全一致的开始和结束位置。这叫光学重影(optical duplicate),尤其在测序芯片的边缘区域高发。

4.1 核心参数与使用场景

MarkDuplicates的参数不多,但每一个都值得细调。我整理了一个常用参数表,方便你对照使用。

参数 默认值 典型调整范围 我建议的使用场景
REMOVE_DUPLICATES false true / false 标记线粒体DNA或靶向捕获时建议置true;WGS/WES常规分析保持false,配合过滤
ASSUME_SORTED false true / false 如果输入已经按坐标排好序,置true能省掉一次排序检查
OPTICAL_DUPLICATE_PIXEL_DISTANCE 100 2500~10000(根据平台调整) Illumina X-Ten系列建议2500,NovaSeq 6000建议5000以上
DUPLICATE_SCORING_STRATEGY SUM_OF_BASE_QUALITIES SUM_OF_BASE_QUALITIES / TOTAL_MAPPED_READS 一般用默认;只要read数多的保守策略可切换
VALIDATION_STRINGENCY STRICT LENIENT / SILENT 数据质量参差不齐时设LENIENT,否则会卡在格式错误上
注意: REMOVE_DUPLICATES 设为 true 是永久删除重复read,而不是加标记。一旦删除,后续GATK不能再还原。我只有在处理mtDNA或者极低覆盖度靶向测序时才这么干。常规WGS/WES,永远设为false。后面用过滤命令筛掉就行。

命令很标准,像这样:

gatk MarkDuplicates \
    -I input.bam \
    -O marked_duplicates.bam \
    -M marked_dup_metrics.txt \
    --OPTICAL_DUPLICATE_PIXEL_DISTANCE 2500 \
    --ASSUME_SORTED true \
    --VALIDATION_STRINGENCY LENIENT

输出 metrics 文件里,我重点关注两个指标:PERCENT_DUPLICATION 和 ESTIMATED_LIBRARY_SIZE。前者超过40%说明文库复杂度偏低,后者是评估测序饱和度的好抓手。

4.2 一个真实的优化案例

前段时间我接手一个肿瘤-正常配对的全外显子组项目。正常样本的重复率20%,肿瘤样本却高达60%。按理说肿瘤样本DNA量少,PCR循环多,重复高也能接受。但问题是,很多关键驱动突变(比如EGFR第19号外显子缺失)的VAF只有2~3%,再被重复read稀释后就完全淹没在背景里了。

我做了什么?我把 OPTICAL_DUPLICATE_PIXEL_DISTANCE 从100调到了5000。嗯,这一步很关键。NovaSeq 6000的光学重影范围比老平台要大得多。默认100只能消除很近的重复,但实际大块芯片上,距离1000像素以内都可能算光学重影。调整后,肿瘤样本的重复率从60%降到了55%。别小看这5个点,它直接让后续VAF的计算准了许多。

避坑指南: 我曾经在一个项目中没调这个参数,结果肿瘤样本有好几个假阳性突变。后来拿到测序中心确认数据时,对方告诉我他们芯片是X-Ten,但用了默认的100。实际上2500才是合理的。从那以后,我每次拿到新批次数据,第一件事就是问清楚测序平台,再设这个参数。

4.3 通过验证保证质量

跑完MarkDuplicates,别急着做下一步。验证一下效果很有必要。我的常规做法是:

  • 检查metrics文件。看重复率、文库大小、光学重复比例。增幅异常就回头检查流程。
  • IGV可视化抽查。随机选10~20个高覆盖区域,看标记为重复的read有没有被正确处理。正常情况是「flag=1024」或「0x400」的read集中在相同位置。
  • 对比过滤前后覆盖度分布。在去除重复read后,覆盖度的波动应该减小,深度高的堆叠峰消失。

我习惯用这个命令快速查看标记后的情况:

samtools view -f 0x400 marked_duplicates.bam | head -20

结果应该看到大量read的flag包含0x400。如果不加 -f 0x400 正常read和重复read混在一起,那就说明标记没生效。

4.4 GATK4 MarkDuplicates vs Picard MarkDuplicates

很多人搞不清这俩工具。我个人统一用GATK4的命令行,理由是它内部直接调用Picard的引擎,但输出日志和HTSJDK版本都跟着GATK走,兼容性更好。另外,GATK4的版本对Spark模式也有更好的支持。

对比维度 GATK4 MarkDuplicates Picard MarkDuplicates
命令入口 gatk MarkDuplicates java -jar picard.jar MarkDuplicates
依赖 自带所有依赖 需单独配置Java和Picard JAR
Spark支持 支持Spark版本(MarkDuplicatesSpark) 不支持
输出格式 与GATK4后续流水线无缝对接 输出完全兼容,但日志格式不同
我今天的选择 ✅ 推荐 ❌ 旧项目保留使用

4.5 常见警告与解决办法

⚠ WARNING: Duplicate set ... contains read ... that was not marked as duplicate
这是MarkDuplicates运行时内部冲突的一种声明。不要紧张,它不代表你的数据有问题。通常由多对read合并后标记冲突引起。我遇到这种情况直接忽略,不影响最终结果。
💡 提示: 如果你在日志里看到大量 CRITICAL: Unknown annotation 'xxx',大概率是BAM文件里的RG标签格式不一致。先跑一下 samtools view -H input.bam | grep '@RG' 确认所有read group的ID、SM、LB、PU字段是否完整且唯一。

OK,关于MarkDuplicates的参数调优和实战技巧就讲这些。它看似简单,但参数值一设错,后续分析就像在流沙上建房子。我个人感觉,花10分钟把 OPTICAL_DUPLICATE_PIXEL_DISTANCE 调对,比后来花一天做纠偏要划算得多。

MarkDuplicates 核心工作流与优化决策树 MarkDuplicates 核心工作流与优化决策 输入:Sorted BAM/CRAM 核心参数检查点 • OPTICAL_DUPLICATE_PIXEL_DISTANCE • REMOVE_DUPLICATES 保持 false • VALIDATION_STRINGENCY 设为 LENIENT 运行 MarkDuplicates 输出 metrics 检查重复率 & 文库大小 输出标记后 BAM flag 0x400 标记重复 IGV 验证 & 覆盖度对比 💡 下次调参参考 平台决定像素距离

嗯,记住一点:标记重复不是万能的,但它做对了,后面的GATK变异检测才会准。你手里的参数就是杠杆,花十分钟调好,能省十小时的纠偏时间。