第1章 Snakemake入门:简介、安装与核心概念
1.1 Snakemake是什么
Snakemake 是一个 Python 写的流程管理工具。说白了,它帮你把一串命令行工具串起来,自动处理依赖、并行和重复运行。
我最早接触它是在一个大项目里——要处理两百多个肿瘤样本的 WES 质控。用 Shell 脚本写了一套 pipiline,每次换参数都要手动改好几处,错了还不知道从哪断的。后来同事推荐 Snakemake,半天就把流程重写好了。嗯,从那以后我再也回不去纯 Shell 了。
它的核心思路很简单:
- 每条分析步骤定义成一个 规则(rule)
- 规则里写上输入文件、输出文件、要执行的命令
- Snakemake 自动根据文件时间戳判断哪些需要重跑
- 支持集群、云、多线程,一套代码到处跑
1.2 为什么生物信息学需要Snakemake
你想想看,生物信息学的日常工作是什么?fastp 质控、BWA 比对、samtools 排序、GATK 变异检测……每一步都依赖上一步的结果,中间还可能根据样本名生成不同文件。手动跑不仅容易忘,还容易把中间产物搞混。
Snakemake 正好解决这几个痛点:
| 痛点 | Snakemake 的解法 |
|---|---|
| 依赖混乱 | 规则自动推导 DAG,不需要手动指定执行顺序 |
| 重复劳动 | 通配符(wildcards)自动批量处理样本 |
| 断点续跑 | 只重新运行因输入或参数改变的步骤 |
| 并行复杂 | 内置多线程、集群提交、资源调度 |
| 可追溯差 | 每个步骤的输入、输出、参数、版本都被记录 |
1.3 安装Snakemake
安装方式有好几种。我个人最推荐用 Conda/Mamba,因为隔离环境好,依赖不会和系统打架。
方法一:通过 Conda 安装(推荐)
conda create -n snakemake_env -c conda-forge -c bioconda snakemake
conda activate snakemake_env
如果觉得 Conda 解析依赖太慢,换 Mamba:
conda install -c conda-forge mamba
mamba create -n snakemake_env -c conda-forge -c bioconda snakemake
方法二:通过 pip 安装
pip install snakemake
但要注意,系统里可能缺一些底层库(比如 graphviz 画图)。
验证安装
snakemake --version
输出类似 8.25.5 就是成功了。
snakemake --dag 报错说 graphviz 找不到。后来才发现系统没装 graphviz 的二进制包。Ubuntu 下需要先 sudo apt install graphviz。如果你是 Conda 装的,它会自带 graphviz,省心很多。
1.4 工作流基本概念:规则、输入、输出、通配符
Snakemake 的核心概念就四个,弄懂它们你就能写 80% 的流程了。
规则(rule)
每个规则定义一个分析步骤,包含名称、输入文件、输出文件和要运行的命令。
rule fastp_qc:
input:
"raw/{sample}_R1.fastq.gz",
"raw/{sample}_R2.fastq.gz"
output:
"clean/{sample}_R1.clean.fastq.gz",
"clean/{sample}_R2.clean.fastq.gz"
shell:
"fastp -i {input[0]} -I {input[1]} -o {output[0]} -O {output[1]}"
输入(input)与输出(output)
Snakemake 看输出文件的修改时间。如果输出文件不存在,或者比输入文件旧,就执行规则。否则跳过。你想想看,这个机制天然支持断点续跑。
通配符(wildcards)
上例里的 {sample} 就是通配符。Snakemake 自动把所有匹配的文件名提取出来,批量生成任务。比如说你 raw 目录下有 sampleA_R1.fastq.gz 和 sampleB_R1.fastq.gz,那么 {sample} 就会分别变成 sampleA 和 sampleB,每个样本独立跑一次。
完整 Snakefile 最简结构:
# Snakefile
rule all:
input:
"clean/sample1_R1.clean.fastq.gz",
"clean/sample2_R1.clean.fastq.gz"
rule fastp_qc:
input:
"raw/{sample}_R1.fastq.gz",
"raw/{sample}_R2.fastq.gz"
output:
"clean/{sample}_R1.clean.fastq.gz",
"clean/{sample}_R2.clean.fastq.gz"
shell:
"fastp -i {input[0]} -I {input[1]} -o {output[0]} -O {output[1]}"
运行:
snakemake -j 4
它会自动发现 raw 目录下所有匹配 {sample}_R1.fastq.gz 的文件,生成对应的 clean 输出。
1.5 核心概念的结构图
下面这张 SVG 图展示了一条 Snakemake 工作流的最小骨架。节点代表规则,箭头代表文件依赖。
1.6 第一个Snakemake工作流实操体验
纸上得来终觉浅。咱们拿一个小例子跑一遍,帮你建立手感。
项目目录结构:
batch_qc_tutorial/
├── Snakefile
├── raw/
│ ├── sample1_R1.fastq.gz
│ ├── sample1_R2.fastq.gz
│ ├── sample2_R1.fastq.gz
│ └── sample2_R2.fastq.gz
└── clean/ (运行时自动创建)
Snakefile 内容:
rule all:
input:
expand("clean/{sample}_R1.clean.fastq.gz", sample=["sample1", "sample2"]),
expand("clean/{sample}_R2.clean.fastq.gz", sample=["sample1", "sample2"])
rule fastp_qc:
input:
"raw/{sample}_R1.fastq.gz",
"raw/{sample}_R2.fastq.gz"
output:
"clean/{sample}_R1.clean.fastq.gz",
"clean/{sample}_R2.clean.fastq.gz"
shell:
"fastp -i {input[0]} -I {input[1]} -o {output[0]} -O {output[1]}"
运行命令:
cd batch_qc_tutorial
snakemake -j 2 --use-conda
--use-conda 参数让 Snakemake 自动为每个规则创建 Conda 环境(如果你在规则里写了 conda: 指令)。对于简单的本地调试,可以不加。
执行后你会在终端看到类似输出:
Building DAG of jobs...
Job stats:
job count min threads max threads
--------------- ---------- ------------- -------------
all 1 1 1
fastp_qc 2 1 1
total 3 1 1
[Fri Dec 16 10:30:05 2025]
rule fastp_qc:
input: raw/sample1_R1.fastq.gz, raw/sample1_R2.fastq.gz
output: clean/sample1_R1.clean.fastq.gz, clean/sample1_R2.clean.fastq.gz
jobid: 1
wildcards: sample=sample1
...
看到 Building DAG of jobs... 就说明 Snakemake 已经在工作了。结束后去 clean 目录看看,两个样本的质控结果已经躺好了。
snakemake -n 做 dry-run,它会打印所有要执行的任务,但不会真的跑。这步能帮你提前发现拼写错误或路径问题,省得中途翻车。
如果你在实验环境里没有 fastp 命令,可以按下面的方式改用简单的 echo 模拟一下:
rule fastp_qc:
input:
"raw/{sample}_R1.fastq.gz"
output:
"clean/{sample}_R1.clean.fastq.gz"
shell:
"echo 'Pretend to process {input} -> {output}'"
这样虽然不会真的生成文件,但足够让你理解规则是怎么触发的。嗯,先跑通再上真工具,是我一贯的调试策略。