【问题标题】:Specify input and output files in Snakefile在 Snakefile 中指定输入和输出文件
【发布时间】:2020-06-25 18:40:55
【问题描述】:

我是 Snakemake 的新手,我想创建一个管道,它接受给定的输入文本文件并将其内容连接到给定的输出文件。但是我希望能够在运行时指定输入和输出文件的名称,因此在 Snakefile 中两个文件名都没有硬编码。目前我能想到的只有:

rule all:
        input:
                "{input}.txt",
                "{output}.txt"

rule output_files:
        input:
                "{input}.txt"
        output:
                "{output}.txt"
        shell:
                "cat {input}.txt > {output}.txt"

我尝试使用“snakemake input1.txt output.txt”运行它,但出现错误:

正在构建作业的 DAG... Snakefile 第 6 行中的 WildcardError: 输入文件中的通配符无法从输出文件中确定: '输入'

任何建议将不胜感激。

【问题讨论】:

    标签: snakemake


    【解决方案1】:

    在您的示例中,您实际上使用cat shell 命令将单个输入文件复制 到输出文件中。这可以理解为将多个输入连接到一个输出的意图:

    rule concatenate:
        input:
            "input1.txt",
            "input2.txt"
        output:
            "output.txt"
        shell:
            "cat {input} > {output}"
    

    获取给定的输入文本文件并将其内容连接到给定的输出文件

    另一种理解问题的方法是您尝试将输入文件附加到输出的末尾。这更具挑战性:Snakemake 根据目标“思考”,其中每个目标都是一个不同的文件。 Snakemake 如何知道输出文件是原始文件还是串联版本?做到这一点的一种方法是拥有“标志”文件:此类文件的存在意味着目标已经实现并且不需要连接。还有一个问题:Snakemake 在运行规则之前会清除输出文件。比意味着您需要将其指定为输入:

    rule append:
        input:
            in = "input.txt",
            out = "output.txt"
        output:
            flag = "flag"
        shell:
            "cat {input.in} >> {input.out} && touch {output.flag}"
    

    现在回到您关于错误和在运行时指定文件名的方式的问题。您会收到此错误,因为通配符应该完全从 output 部分推断出来,并且您的两个规则都是格式错误的。让我们从rule all开始。

    你需要说 Snakemake 你正在建立什么目标。 input 中没有通配符,所有内容都应该消除歧义:

    def getInput():
        pass
        # form the actual goal (you may query the database, service, hardcode, etc.)
    
    rule all:
        input: getInput
    

    假设您决定目标应该是 3 个文件:["output1.txt", "output3.txt", "output3.txt"]:

    def getInput():
        magic_numbers_from_oracle = ["1", "2", "3"]
        return magic_numbers_from_oracle
    
    rule all:
        input: expand("output{number}.txt", number=getInput())
    

    好的,现在 Snakemake 知道目标了。下一步是编写一个规则,说明如何创建单个output{number}.txt 文件。为简单起见,我将采用 cat/copying 的初始方法:

    rule cat_copy:
        input:
            "input{n}.txt"
        output:
            "output{n}.txt"
        shell:
            "cat {input} > {output}"
    

    就是这样。只要你有文件input1.txtinput2.txtinput3.txt,你就会得到相应的输出。

    【讨论】:

    • 感谢您的回答 Dmitry,但是在您的示例中,您假设输入文件的格式为 input1、input2 和 input3.txt。对于我的应用程序,除了知道它们都是 .txt 文件之外,我不想假设输入和输出文件的文件名。我想概括一下,这样我这次可以选择 cat a.txt > b.txt,也许下次可以选择 cat yy.txt > zz.txt。这就是为什么我要问是否有办法在运行 snakemake 时指定输入和输出文件名。
    • @user9367574,到目前为止,您的任务定义不明确。剧本如何理解你的想法? a.txt > b.txtyy.txt > zz.txt 的共同点是什么? Snakemake 如何决定你想要a.txt > b.txt 而不是a.txt > c.txt?我给了你一个在数据库中设置任务的想法,但这取决于你如何提供这些信息。
    • 我想知道您是否可以在运行时告诉snakemake 输入和输出文件名。在我之前尝试使用的命令(“snakemake input1.txt output.txt”)中,我试图告诉 Snakemake 输入文件称为 input1.txt,输出文件称为 output.txt,它应该执行 input1 .txt > 输出.txt。显然这不起作用,但我想知道是否有办法做到这一点。
    • @user9367574 你可以这样做,但这主要是没有 Snakemake 的 Python。 Snakemake 的目的是运行具有一些已知模式的管道。如果您不知道自己的模式,则不需要 Snakemake:只需从 Python 运行 shell 命令即可。
    猜你喜欢
    • 2018-11-21
    • 2021-11-12
    • 1970-01-01
    • 1970-01-01
    • 2013-01-11
    • 2012-03-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多