【问题标题】:Snakemake: catch output file whose name cannot be changedSnakemake:捕获名称无法更改的输出文件
【发布时间】:2021-08-25 11:57:29
【问题描述】:

作为我正在构建的 Snakemake 管道的一部分,我必须使用一个不允许我指定输出文件的文件路径或名称的程序。

例如在工作目录workdir/ 中运行程序时,它会产生以下输出: workdir/output.txt

我的蛇形规则看起来像这样:

rule NAME:
    input: "path/to/inputfile"
    output: "path/to/outputfile"
    shell: "somecommand {input} {output}"

因此,每次运行规则 NAME 时,我都会在 snakemake 工作目录中获得一个附加文件 output.txt,如果规则 NAME 多次运行或并行运行,则会覆盖该文件。

我知道影子规则,添加shadow: "full" 可以让我简单地忽略output.txt 文件。但是,我想保留output.txt 并将其保存在与outputfile 相同的目录中。有没有办法实现这一点,无论是使用影子指令还是其他方式?

我还认为我可以在 somecommand 前面加上 cd 命令,但是在将其他规则链接到规则 NAME 的输出时,我可能会在下游遇到其他问题。

【问题讨论】:

    标签: snakemake


    【解决方案1】:

    之后直接在 shell 部分中移动它怎么样(前提是somecommand 成功完成)?

    rule NAME:
        input: "path/to/inputfile"
        output: "path/to/outputfile"
        params: 
            output_dir = "path/to/output_dir",
        shell: "somecommand {input} {output} && mv output.txt {params.output_dir}/output.txt"
    

    编辑:对于 NAME 的多个并行执行,结合 shadow: "full" 可以工作:

    rule NAME:
        input: "path/to/inputfile"
        output:
            output_file = "path/to/outputfile"
            output_txt = "path/to/output_dir/output.txt"
        shadow: "full"
        shell: "somecommand {input} {output.output_file} && mv output.txt {output.output_txt}"
    

    这应该在它自己的临时目录中运行规则的每次执行,并且通过将移动的 output.txt 指定为输出,一旦规则运行完毕,Snakemake 应该将其移动到真正的输出目录。

    【讨论】:

    • 非常感谢您的回答!这会起作用,但前提是没有并行运行的规则 NAME 的作业。否则将不清楚output.txt 文件属于哪个作业。
    • @D-Cru 很好,现在进行了调整 - 我认为你在 shadow 的正确轨道上,文档说一个用例是“通过不必担心独特性来简化你的工作流程所有规则的所有输出的文件名”,它确实保留了任何指定为输出的文件。
    • 非常感谢@Kat Steinke。我已经测试了你的建议,它似乎非常适合这种情况。
    【解决方案2】:

    我还想我可以在 somecommand 前面加上 cd 命令,但是当将其他规则链接到规则 NAME 的输出时,我可能会在下游遇到其他问题。

    我认为你在这里是正确的。每个shell 块都在一个单独的进程中运行,工作目录继承自snakemake 进程(在命令行中使用--directory 参数指定)。因此,一个shell 块中的cd 命令不会影响来自同一规则的其他作业或其他下游/上游作业。

    rule NAME:
        input: "path/to/inputfile"
        output: "path/to/outputfile"
        shell: 
            """
            input_file=$(realpath "{input}")  # get the absolute path, before the `cd`
            base_dir=$(dirname "{output}")
            cd "$base_dir"
            somecommand ...
            """
    

    【讨论】:

    • 谢谢 - 这很好用!如果有许多不同的输入/输出,可能会得到相当长的 shell 命令,但它避免了使用影子。在同一输出文件夹中并行运行规则 NAME 的多个实例时,它无法正常工作。但是对于这种情况,可以通过通配符轻松指定不同的输出文件夹。
    猜你喜欢
    • 1970-01-01
    • 2017-06-12
    • 2015-06-14
    • 1970-01-01
    • 1970-01-01
    • 2013-03-31
    • 2017-12-22
    • 2021-04-26
    • 1970-01-01
    相关资源
    最近更新 更多