当文件丢失时,SnakeMake是否可以强制重新运行规则

时间:2017-08-31 20:44:09

标签: delete-file snakemake

当删除之前在管道中创建的文件时,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行为。它有时可能是期望的行为,但有时您可能希望它检测并重建丢失的文件。怎么办呢?

3 个答案:

答案 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,则仅重新运行规则BC

为什么会这样?

如果我没记错的话,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选项都会重新生成所有其他文件。因此,这根本不理想。

解决方法1:强制重新生成文件

使用-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.txttestA1.txt更新

或者您可以使用--touch将相关文件(即testB1.txt,testC1.txt)标记为“较新”:

snakemake -s test.sf -f testA1.txt
snakemake -s test.sf --touch

解决方法2:创建新规则

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.