流程搭建基础:WDL/Cromwell 工作流简介、标准 GATK Best Practices 管线配置归纳总结
好了,进入第二章。
说实话,很多刚接触 GATK 的朋友,上来就急着跑变异检测命令,结果环境一换、数据一换,脚本就崩得一塌糊涂。我当年也吃过这个亏。所以咱们先不急着跑分析,先把流程的“骨架”搭起来——也就是理解 WDL 和 Cromwell,以及标准 GATK Best Practices 的管线是怎么组织的。
为什么要先讲这个?因为你一旦掌握了 WDL,GATK 的官方流程你就能直接看懂、直接改、直接跑。这比你自己从头拼 shell 脚本要靠谱得多。
2.1 为什么是 WDL + Cromwell?
GATK 团队官方推荐的工作流语言是 WDL,执行引擎是 Cromwell。说白了,WDL 负责描述“做什么、按什么顺序做”,Cromwell 负责“找机器、跑命令、管数据”。
我个人习惯把 WDL 看作“编程语言版的实验记录本”——每条分析步骤写得清清楚楚,输入、输出、参数、资源需求一目了然。而且它天然支持并行、容错,特别适合高吞吐的生信分析。
核心概念对照
| 概念 | WDL 中的角色 | 我的理解 |
|---|---|---|
| workflow | 定义流程整体 | 就像一张流程图,把任务串起来 |
| task | 定义单个分析步骤 | 封装一个工具的命令和参数 |
| call | 在 workflow 中调用 task | 跟函数调用差不多 |
| runtime | 指定计算资源需求 | 告诉 Cromwell 给我多少 CPU、内存 |
| Cromwell | 工作流执行引擎 | 调度器 + 执行器 + 日志系统 |
2.2 WDL 基本语法——够用就行
我不会教你写复杂的 WDL,我们只学能看懂 GATK 官方流程的语法就够了。嗯,大概七八个关键词,你就已经能改流程了。
记住这个结构模板
version 1.0
workflow MyGATKWorkflow {
input {
File my_bam
File my_reference
}
call PreprocessBam {
input: bam = my_bam, ref = my_reference
}
call CallVariants {
input: processed_bam = PreprocessBam.output_bam, ref = my_reference
}
output {
File final_vcf = CallVariants.variants
}
}
task PreprocessBam {
input {
File bam
File ref
}
command {
gatk MarkDuplicates \
-I ~{bam} \
-O marked_dups.bam \
-M marked_dup_metrics.txt
}
output {
File output_bam = "marked_dups.bam"
}
runtime {
cpu: 4
memory: "16 GB"
}
}
你看,WDL 的结构很直观:workflow 包裹整个流程,task 定义每个步骤。输入用 File 声明,引用变量用 ~{变量名}。就这么简单。
我个人经验:刚开始不要追求写出完美的 WDL。拿一个官方的 .wdl 文件下来,照着改改参数,跑一跑,比学语法快得多。
2.3 Cromwell 的配置——踩过的坑
Cromwell 本身就是一个 Java 程序,你用 java -jar cromwell.jar run workflow.wdl 就可以启动。但实际生产中,大家都会写配置文件来指定后端计算资源。我遇到过最坑的是:配置文件里没写镜像,结果 Cromwell 用本地环境跑,版本全对不上,跑了一天全白费。
避坑:Cromwell 配置必须写镜像
backend {
default: "Local"
providers {
Local {
actor-factory = "cromwell.backend.impl.sfs.config.ConfigBackendLifecycleActorFactory"
config {
concurrent-job-limit = 2
runtime-attributes = """
String? docker
"""
submit = """
docker run --rm -v ${cwd}:${cwd} ${docker} ${job_shell} ${command}
"""
}
}
}
}
这个配置里最关键的一行就是 String? docker。它允许你在 WDL 的 runtime 块里指定 Docker 镜像。比如:
runtime {
docker: "broadinstitute/gatk:4.4.0.0"
}
这样 Cromwell 就会拉取官方的 GATK 镜像,环境百分百一致。
2.4 标准 GATK Best Practices 管线——一张流程图说清楚
下面这张 SVG 图,是我把整个 GATK 种系变异检测管线(Germline short variant discovery)的核心流程画出来的。你仔细看,注意它是怎么从原始 BAM 一步步走到最终 VCF 的。
这张图里我标了四个核心阶段:数据预处理 → 变异检测 → 过滤评估 → 最终 VCF。每个阶段内部,用的工具都是 GATK 命令行工具。你记住这个流水线结构,再看官方 WDL 脚本就豁然开朗了。
2.5 标准管线配置归纳——一张表记住全部步骤
很多教程把 GATK Best Practices 讲得特别复杂。我把它归纳成下面这张表,你看一遍就能在心里搭起框架。
| 阶段 | 工具 | 主要功能 | 关键参数 |
|---|---|---|---|
| 数据预处理 | MarkDuplicates | 标记 PCR 重复 | REMOVE_DUPLICATES=false |
| BaseRecalibrator | 学习碱基质量变异模型 | knownSites 数据库路径 | |
| ApplyBQSR | 根据模型重校准碱基质量 | --bqsr-recal-file | |
| 变异检测 | HaplotypeCaller | 单样本 gVCF 生成 | --emit-ref-confidence GVCF |
| GenomicsDBImport | 群体 gVCF 聚合 | --genomicsdb-workspace-path | |
| GenotypeGVCFs | 联合基因分型 | --include-non-variant-sites | |
| 过滤评估 | VariantRecalibrator | VQSR 模型训练 | --mode SNP / INDEL |
| ApplyVQSR | 应用过滤阈值 | --ts-filter-level 99.0 | |
| 输出 | SelectVariants / CombineGVCFs | 格式化 & 合并 | --exclude-filtered |
个人建议:刚开始跑 GATK 流程,不要贪多。先把 MarkDuplicates + HaplotypeCaller 这个最小闭环跑通,再逐步加上 BQSR 和 VQSR。一句话,先出结果,再谈优化。
2.6 常见坑与我的应对
- 路径问题:WDL 里所有文件路径必须是绝对路径或者 Cromwell 能访问到的。我建议把所有输入统一放在一个
inputs.json配置文件里,不要硬编码。 - 镜像版本:GATK 大版本升级有时会改命令行参数。我吃过一次 4.2 到 4.4 迁移的亏,
--emit-ref-confidence参数变了,跑了一天才发现结果不对。 - Cromwell 日志:默认日志在
cromwell-executions目录下。流程卡死时,先看stdout和stderr。
曾经我犯过的错误:有一次我把 docker 标签写错了,结果 Cromwell 默默使用本地环境,版本差异导致 HaplotypeCaller 运行时 OOM 崩溃。检查了半天才发现是镜像名少了个版本号。所以我现在每个 WDL 脚本的第一个 runtime 块,一定会写死镜像 tag,比如 broadinstitute/gatk:4.4.0.0。
好了,这一章的内容就到这。你把 WDL 的基础语法、Cromwell 配置要点、以及 GATK Best Practices 的标准管线结构理清楚,后面章节我们再深入每个参数怎么调优。就这样,下一段路咱们实地跑一跑流程。