1

我尝试在能够运行自定义 perl 脚本的 Snakefile 中编写规则。有两个输入文件和一个输出文件。输入文件和输出文件中有通配符,因为我想为各种文件运行脚本。但是当我扩展以生成不同的输入和输出文件时,perl 脚本将所有可能的输入文件作为输入,而我希望它们一个一个地去。我应该怎么做才能让 perl 一个一个地“吃掉”输入文件?这是我的代码:

DOMAINS= ["Metallophos", "PP2C", "Y_phosphatase"]
SUPERGROUPS=["2supergroups","5supergroups"]

rule add_supergroups:
    input:
        newick=expand("data/{domain}/{supergroup}/RAxML_bipartitionsBranchLabels.bbhlist.txt.{domain}.fa.aligned.rp.me-25.id.phylip",domain=DOMAINS, supergroup=SUPERGROUPS),
        sup="data/species.v3.1.1.supergroups.txt"
    output:
        expand("results/{domain}/{supergroup}/RAxML_bipartitionsBranchLabels.bbhlist.txt.{domain}.fa.aligned.rp.me-25.id.phylip.supergroups", domain=DOMAINS, supergroup=SUPERGROUPS)
    shell:
        "perl scripts/change_newick.pl {input.sup} {input.newick} {output}"
4

2 回答 2

3

您可以删除 expand() 函数并使用规则“all”来定义您的目标。规则 add_supergroups 中通配符的值将自动从此目标文件中推断出来。

您甚至可以在规则“add_supergroups”中为通配符使用不同的名称,以便 Snakemake 识别并匹配这些模式。

DOMAINS= ["Metallophos", "PP2C", "Y_phosphatase"]
SUPERGROUPS=["2supergroups","5supergroups"]

rule all: 
    input: expand("results/{domain}/{supergroup}/RAxML_bipartitionsBranchLabels.bbhlist.txt.{domain}.fa.aligned.rp.me-25.id.phylip.supergroups"

rule add_supergroups:
    input:
        newick="data/{domain}/{supergroup}/RAxML_bipartitionsBranchLabels.bbhlist.txt.{domain}.fa.aligned.rp.me-25.id.phylip",
        sup="data/species.v3.1.1.supergroups.txt"
    output:
        "results/{domain}/{supergroup}/RAxML_bipartitionsBranchLabels.bbhlist.txt.{domain}.fa.aligned.rp.me-25.id.phylip.supergroups"
    shell:
        "perl scripts/change_newick.pl {input.sup} {input.newick} {output}"

从理论上讲,它甚至应该像这样工作:

DOMAINS= ["Metallophos", "PP2C", "Y_phosphatase"]
SUPERGROUPS=["2supergroups","5supergroups"]

rule all: 
    input: expand("results/{domain}/{supergroup}/RAxML_bipartitionsBranchLabels.bbhlist.txt.{domain}.fa.aligned.rp.me-25.id.phylip.supergroups"

rule add_supergroups:
    input:
        newick="data/{foo}",
        sup="data/species.v3.1.1.supergroups.txt"
    output:
        "results/{foo}.supergroups"
    shell:
        "perl scripts/change_newick.pl {input.sup} {input.newick} {output}"
于 2017-03-16T17:37:29.497 回答
1

您的规则想要运行所有文件的原因很简单:函数expand()

就像您似乎知道的那样,expand 使 Python 字符串列表对于管理 Snakemake 中的文件非常有用。

但是在您的示例中,该规则希望运行带有文件列表{input.newick}和一个文件的perl 脚本,{input.sup}以生成文件列表作为输出。

您可以通过不使用expand function on the input and output.

但是 Snakemake 将如何认识到他必须制作所有文件呢?通过在您之前创建一个规则目标rule add_supergroups,它将作为输入扩展您的rule add_supergroups.

让我们做一些代码:

DOMAINS= ["Metallophos", "PP2C", "Y_phosphatase"]
SUPERGROUPS=["2supergroups","5supergroups"]

rule target :
  input :
    expand("results/{domain}/{supergroup}/RAxML_bipartitionsBranchLabels.bbhlist.txt.{domain}.fa.aligned.rp.me-25.id.phylip.supergroups", 
           domain=DOMAINS,
           supergroup=SUPERGROUPS)

rule add_supergroups:
    input:
        newick="data/{domain}/{supergroup}/RAxML_bipartitionsBranchLabels.bbhlist.txt.{domain}.fa.aligned.rp.me-25.id.phylip",
        sup="data/species.v3.1.1.supergroups.txt"
    output:
        "results/{domain}/{supergroup}/RAxML_bipartitionsBranchLabels.bbhlist.txt.{domain}.fa.aligned.rp.me-25.id.phylip.supergroups"
    shell:
        "perl scripts/change_newick.pl {input.sup} {input.newick} {output}"

现在它应该可以工作了。Snakemake 需要一个target rule. 他搜索所有规则以查找是否可以生成这些文件。

在这种情况下,他认出pattern filenameoutput add_supergroups。所以他会自动完成DOMAINS和SUPERGROUPS的通配符。该规则add_supergroups将一个一个文件运行。

于 2017-03-16T16:13:27.460 回答