死亡之触

时间:2019-03-03 01:35:04

标签: snakemake

在运行以下Snakefile之前,文件foo.txt是否已经存在

rule master :
        output :
                touch('foo.txt')

        input : 'task.done'

rule task :
        output :
                touch('task.done')

        shell : 'echo "bar" > foo.txt'

很明显有

Nothing to be done.

foo.txt的内容保持不变。如果在运行此Snakefile之前文件foo.txt 不存在,它会由rule task使用文本“ bar”创建,但是触摸{{1 }}。甚至有适当的警告

rule master

我完全理解发生了什么,但是为什么会这样做吗?为什么Warning: the following output files of rule master were not present when the DAG was created: {'foo.txt'} Touching output file foo.txt. 不仅可以在某些情况下“触摸”文件?

更新:

好吧,多亏了一个有用的评论,这与touch并没有特别的关系,而是一个关于未跟踪文件的问题(也许应该更改标题),尤其是那些<正如警告中明确提到的那样,创建DAG时em 不存在。例如,如果上面的Snakefile是

touch

我现在得到:

rule master :
        output : 'foo.txt'

        input : 'task.done'

rule task :
        output :
                touch('task.done')

        shell : 'echo "bar" > foo.txt'

这又是完全可以理解的行为:我收到关于文件Warning: the following output files of rule master were not present when the DAG was created: {'foo.txt'} Waiting at most 5 seconds for missing files. MissingOutputException in line 1 of /home/patterson/snaketest/touch-of-death.snake: Missing files after 5 seconds: foo.txt This might be due to filesystem latency. If that is the case, consider to increase the wait time with --latency-wait. 的警告,该文件在创建DAG之前不存在,然后等待foo.txt,它不是目标任何规则,所以snakemake看不到它:根据蛇形技术,它在技术上是缺失的。

我同意以上内容是不良设计的一个例子,这是因为我在扮演魔鬼的拥护者,试图了解为什么制蛇如此操作。

那么,为了争辩,让我们说,snakemake可能会注意工作流期间创建的文件---再次,我相信有人可以以某种方式用foo.txt强制这种行为(重新评估DAG),但我也不想这样做-甚至举一个例子,一个人可能真的会因为上面的(错误)设计而严重摔倒自己。< / p>

我意识到,这可能与为什么现在在snakemake中弃用checkpoints文件(支持dynamic)有关,也与python中并发进程的固有局限性有关(参见{{ 3}}),因为蛇终究是用python编写的。

2 个答案:

答案 0 :(得分:2)

与OP讨论后,我现在很清楚,具体的问题是为什么snakemake会用一个空文件而不是“ touched”来覆盖foo.txt。这是因为未跟踪“任务”创建的“ foo.txt”文件,因此在执行“主”规则后,该文件将被删除,因为snakemake认为它很旧。然后touch('foo.txt')被评估并创建一个新的空文件。此行为可确保规则的干净执行。

答案 1 :(得分:1)

输出关键字不应包含诸如touch之类的操作,因为这是“ run:”或“ shell:”的含义。输出和输入关键字应仅包含要使用或创建的实际文件。同样在规则“任务”中,您试图将“ task.done”定义为输出,但是您告诉它创建“ foo.txt”。 Snakemake显然会感到困惑并告诉您。

请考虑:

rule master :
    input : 'foo.txt'
    output : 'task.done'
    run:
           touch(output[0])

rule task :
        output : 'foo.txt'
        shell : 'echo "bar" > {output}'

'task'创建foo.txt,如果'task'规则成功,则'master'创建task.done。