如何在Snakemake中尽可能执行可运行的工作流部分?
Snakemake多数据源工作流执行优化方案
问题场景
我用Snakemake搭了个多数据源的数据管道,工作流拓扑是这样的:
A1-->A2--\ C1-->C2 B1-->B2--/
有时候A1就绪但B1没准备好,有时候反过来,也有时候两者都就绪。管道里每部分跑起来费时间又占资源,所以想让Snakemake尽可能把能跑的部分都跑完,哪怕没法一次性完成整个流程。试过--until、--keep-going和--omit-from这几个参数,都达不到需求。哪怕最后Snakemake返回错误码和提示信息也没关系,只要能多跑些内容就行。
可行解决方案
1. 加几个自定义目标规则
直接在Snakefile里加几个目标规则,对应不同分支的完成状态:
rule all_a: input: "A2" rule all_b: input: "B2" rule all_full: input: "C2"
跑的时候看情况选目标:
- 只有A1就绪:执行
snakemake all_a,把A1→A2的分支跑完 - 只有B1就绪:执行
snakemake all_b,跑完B1→B2的分支 - 两者都就绪:执行
snakemake all_full,跑完整流程
2. 用--allowed-rules限定执行范围
不想加额外规则的话,直接指定允许执行的规则:
- 只跑A分支:
snakemake --allowed-rules A1,A2 - 只跑B分支:
snakemake --allowed-rules B1,B2
这个参数会让Snakemake只执行指定规则和它们的依赖,自动跳过需要未就绪数据源的部分。
3. 写个预处理脚本自动适配目标
搞个简单的shell脚本,先检查A1、B1是否存在,再动态生成目标传给Snakemake:
targets="" if [ -f "A1" ]; then targets="$targets A2"; fi if [ -f "B1" ]; then targets="$targets B2"; fi if [ -f "A1" ] && [ -f "B1" ]; then targets="$targets C2"; fi snakemake --keep-going $targets
脚本会自动根据数据源状态设置目标,--keep-going能保证某个分支因为数据源缺失失败时,其他就绪的分支照样跑完。
4. 给规则加条件判断
在规则里加个检查,确认依赖的数据源存在再执行,避免直接终止整个流程:
rule A1: output: "A1" shell: # 只有source_A就绪时才执行生成A1的命令,否则生成空文件标记状态 "if [ -f 'source_A' ]; then your_command_for_A1; else touch {output}; fi" # B1规则同理,后续A2、B2正常依赖A1、B1就行
这种方式能让Snakemake跳过未就绪的分支,继续跑能执行的部分,注意用touch生成空文件是为了让流程认为该规则已完成,不会一直卡着。
内容的提问来源于stack exchange,提问作者Ben Root
相关产品推荐
相关产品推荐

