当删除之前在管道中创建的文件时,SnakeMake似乎不会考虑这个问题,只要以后的文件存在:
rule All:
input: "testC1.txt", "testC2.txt"
rule A:
input: "{X}{Y}.txt"
output: "{X}A{Y}.txt"
shell: "cp {input} {output}"
rule B:
input: "{X}A{Y}.txt"
output: "{X}B{Y}.txt"
shell: "cp {input} {output}"
rule C:
input: "{X}B{Y}.txt"
output: "{X}C{Y}.txt"
shell: "cp {input} {output}"
将此SnakeFile保存在test.sf中并执行以下操作:
rm testA*.txt testB*.txt testC*.txt
echo "test1" >test1.txt
echo "test2" >test2.txt
snakemake -s test.sf
# Rerun:
snakemake -s test.sf
# SnakeMake says all is up to date, which it is.
# Remove intermediate results:
rm testA1.txt
# Rerun:
snakemake -s test.sf
SnakeMake表示一切都是最新的。它没有检测到缺少testA1.txt。
我似乎记得在线SnakeMake手册中有关于此的内容,但我再也找不到了。
我认为这是预期的SnakeMake行为。它有时可能是期望的行为,但有时您可能希望它检测并重建丢失的文件。怎么办呢?
答案 0 :(得分:2)
前一段时间我发现了thread这个可能提供信息的--forcerun
/ -R
参数。
最终,如果您想重新生成该中间文件而没有单独的规则或将其作为目标包含在内,则snakemake将强制执行整个管道。
答案 1 :(得分:1)
如this other answer中所述,-R
参数可以提供帮助,但还有更多选择:
致电时
snakemake -F
这将触发整个管道的重建。这基本上意味着,忘记所有中间文件,然后重新开始。这样肯定会(重新)生成所有中间文件。缺点是:可能需要一些时间。
这是-R <rule>
参数的领域。这将重新运行给定规则以及所有依赖于此规则的规则。所以就你而言
snakemake -R A -s test.sf
将重新运行规则A(从testA1.txt
构建test.txt
以及规则B,C和全部,因为它们依赖于A。请记住,这将运行所需的规则A的所有副本,因此在您的示例testA2.txt
中,其后的所有内容也会重新构建。
如果在您的示例中,您将删除testB1.txt
,则仅重新运行规则B
和C
。
如果我没记错的话,snakemake会检测是否需要通过其utime来重建文件。因此,如果您的testA1.txt
版本比testB1.txt
更年轻(如最近创建的),则必须使用testB1.txt
重建rule B
,以确保一切正常至今。因此,除非不以某种方式更改文件的时间,否则就无法轻松地仅重建testA1.txt
而不构建所有后续文件。
我还没有尝试过,但是可以使用snakemakes --touch
参数来完成。如果您仅设法运行规则A
,然后运行snakemake -R B -t
,它会触及规则B
及其后的所有输出文件,则可以得到有效的工作流状态,而无需实际重新运行其中的所有步骤。之间。
答案 2 :(得分:0)
的确,如果snakemake带有一个标志来寻找中间结果丢失,并在缺少中间结果时重新生成它们(所有相关性),那将是很好的。
我不知道这样的选项,但是有一些解决方法。
请注意,无论是否缺少中间文件,m00am和Jon Chung建议的-R
选项都会重新生成所有其他文件。因此,这根本不理想。
使用-R
或-f
标志(在下面复制帮助)来强制重新创建中间文件。此处的关键是明确针对文件而不是规则。
snakemake -s test.sf testA1.txt # only works if testA1.txt was deleted
# or
snakemake -s test.sf -R testA1.txt # testA1.txt can be present or absent
# or
snakemake -s test.sf -f testA1.txt
# or
snakemake -s test.sf -F testA1.txt
注意,后面的两个,需要再次运行管道以更新依赖项:
snakemake -s test.sf
如果您不希望更新从属文件(即testB1.txt,testC1.txt),则还有其他选项。
您可以重新生成testA1.txt,然后“重置”修改时间,例如到源文件,这将阻止管道更新任何内容:
snakemake -s test.sf -f testA1.txt
touch testA1.txt -r test1.txt
snakemake -s test.sf
现在什么都不会做,因为testB1.txt
比testA1.txt
更新
或者您可以使用--touch
将相关文件(即testB1.txt,testC1.txt)标记为“较新”:
snakemake -s test.sf -f testA1.txt
snakemake -s test.sf --touch
snakefile可以通过新规则扩展:
rule A_all:
input: "testA1.txt", "testA2.txt"
然后可以这样称呼它:
snakemake A_all -s test.sf
这只会生成testA1.txt
,类似于上面的工作流程中的-f
,因此需要重新运行管道或可以更改修改时间。
使用--touch
snakemake -s test.sf --touch testA1.txt -n
这将“更新” testA1.txt
。要重新创建依赖文件,snakemake之后需要正常运行:
snakemake -s test.sf
请注意,如果删除testA1.txt
,此操作将不起作用,需要执行此操作而不是删除。
--touch, -t Touch output files (mark them up to date without
really changing them) instead of running their
commands. This is used to pretend that the rules were
executed, in order to fool future invocations of
snakemake. Fails if a file does not yet exist.
--force, -f Force the execution of the selected target or the
first rule regardless of already created output.
--forceall, -F Force the execution of the selected (or the first)
rule and all rules it is dependent on regardless of
already created output.
--forcerun [TARGET [TARGET ...]], -R [TARGET [TARGET ...]]
Force the re-execution or creation of the given rules
or files. Use this option if you changed a rule and
want to have all its output in your workflow updated.