我想在 Snakefile 中创建一个可以调用其他规则的规则。
例如,我想创建一个规则
re
,调用 clean
,然后调用 all
。.PHONY=all clean re
all: toto.txt
toto.txt:
touch toto.txt
clean:
rm toto.txt
re: clean all
在此 Makefile 中,
re
导致创建的文件完全重新生成。re
中的规则内容(没办法,我的真实案例太复杂了)。touch("rule.done")
放在被调用规则的输出中,并在“re”规则中调用它们。这些文件在文档中称为标志文件。问题,规则完成后它留下了一些文件,所以我发现......temp("filename")
放在调用规则的输出中,告诉 Snakefile 在运行后删除它们。所以我的蛇文件最终是这样的:
rule all:
input: toto.txt
output: temp(touch("all.done"))
rule generate_toto:
output: toto.txt
shell: touch toto.txt
rule clean:
output: temp(touch("clean.done"))
shell: rm toto.txt
rule re:
input: "all.done", "clean.done"
但是它不起作用,因为 Snakemake 按以下顺序启动规则:
generate_toto > 清理 > 全部
这会导致超时,因为作业
all
等待 toto.txt 创建。我没有找到一种方法来告诉 Snakemake 在做 clean
之前先做 all
。
看起来这是一个小问题,但这只是一个例子,而不是我的真实案例:我想要
all
调用启动脚本的规则,但我无法做到这一点。我的.PHONY 在哪里? :'(
所以继续:
我没有测试过,但我认为您可以通过滥用检查点语法来完成从另一个规则调用一个规则。将 clean 规则设置为检查点(或添加依赖于 clean 的中间规则)。接下来,将
re
的输入设为如下函数:
def re_input(wildcards):
checkpoints.clean.get().output # force running clean
return ALL_INPUTS # may be able to use rules.all.input?
检查点强制该规则首先运行,然后返回所有的正常输出。
对于第二个问题,您可以使用 priorities 来确保
clean
首先运行。您仍然需要假触摸文件才能运行所有内容,但之后 clean 将首先运行。