snakemake - 不要删除失败规则的输出

snakemake - do not delete output of failed rules

我有一个 snakemake 工作流程,其中包含运行另一个“内部”snakemake 工作流程的规则。
有时内部工作流的某个规则失败,这意味着内部工作流失败。因此,内部工作流 output 下列出的所有文件都被外部工作流删除,即使创建它们的内部工作流规则已成功完成。
有没有办法防止 snakemake 删除失败规则的输出?或者您可以建议另一种解决方法?
一些注意事项:

像这样:

rule run_inner:
    input:
        inputs...
    output:
        outputs...
    shell:
        """
        snakemake -s inner.snakefile
        exit 0
        """

但输出仍然被删除。
将不胜感激任何帮助。谢谢!

一种解决方法是使用 run 而不是 shell

rule run_inner:
    input:
        inputs...
    output:
        outputs...
    run:
        shell("""snakemake -s inner.snakefile""")
        # Add your code here to store the files before removing

即使 shell 函数调用中的脚本失败,文件仍然存在,直到 run 部分中的脚本完成。您可以将文件复制到安全的地方。

更新: 您需要处理异常以在脚本 returns 出错时继续执行。下面的脚本说明了这个想法:except: 块中的 print 函数打印 Trueonerror 中的另一个函数打印 False

rule run_inner:
    output:
        "output.txt"
    run:
        try:
            shell("""touch output.txt; exit 1""")
        except:
            print(os.path.exists("output.txt"))

onerror:
    print(os.path.exists("output.txt"))

一个选项可能是让 run_inner 生成一个虚拟输出文件来标记规则的完成。 run_inner 之后的规则将输入虚拟文件。例如:

rule run_inner:
    ...
    output:
        # or just 'run_inner.done' if wildcards are not involved
        touch('{sample}.run_inner.done'), 
    shell:
        'snakemake -s inner.snakefile'

run next:
    input:
        '{sample}.run_inner.done',
    params:
        real_input= '{sample}.data.txt', # This is what run_inner actually produces
    shell:
        'do stuff {params.real_input}'

如果 snakemake -s inner.snakefile 失败,虚拟输出将被删除,但 snakemake -s inner.snakefile 将从它离开的地方重新开始。

另一种选择是将 inner.snakefile 中的规则集成到您的外部管道中,例如使用include 语句。我觉得这个选项更可取,但当然,实施起来会更复杂。

程序在返回非零 return 值时“失败”。因此,我们只需要“修复”这个问题来欺骗内心的 shell 认为所有程序都已成功完成。最简单的方法是使用 some error command || true。下面是一个最小的例子:

rule test:
    output:
        "test.output",
    shell:
        """
        touch test.output
        # below cat will trigger error 
        cat file_not_exist || true
        """

你会发现尽管 cat 抛出错误,test.output 仍然存在。