如何将简单的目标模式规则转换为snakemake?

时间:2017-09-13 13:06:55

标签: snakemake

我正在寻找一种在Snakemake中定义目标模式规则(没有输入模式)的方法。

在这种情况下,我想要一个规则,创建文件abc作为目标文件中输入不包含模式的模式的一部分。

在GNU make中,我会这样做:

.PHONY: all
all: a b c

%:
    echo x > $@

但是,如果我在Snakemake中执行以下操作:

rule test:
    output:
        "{filename}"
    wildcard_constraints:
        filename = "[abc]"
    shell:
        "echo x > {filename}"
  

WorkflowError:目标规则可能不包含通配符。请指定具体文件或没有通配符的规则。

我当然可以使用output调用来指定expand(),但这意味着规则会在调用一次时创建所有文件,但事实并非如此。相反,它应该在使用某个参数执行shell时创建一个文件(此处示例中为{filename})。

2 个答案:

答案 0 :(得分:3)

蒂姆的回答基本上包含了解决方案。但是既然你在Twitter上问我,让我直接翻译你的Makefile:

rule all:
    input:
        expand("{filename}", filename=["a", "b", "c"])

rule test:
    output:
        "{filename}"
    wildcard_constraints:
        filename = "[abc]"
    shell:
        "echo x > {filename}"

所有这些基础知识都在Snakemake tutorial中解释。

答案 1 :(得分:1)

问题是shell指令中的{input}与{wildcards.namedVar}访问权限。 See here in the documentation。话虽如此,我没有看到你的驱动程序要求Snakemake设置,我也建议。 (我在下面的答案中添加了它)。它等同于.PHONY和所有规则模式(GNU Make强迫我们进入的混乱约定)。

在shell指令中,变量{filename}可作为通配符对象的属性访问。你需要使用python dot表示法来访问它,比如{wildcards.filename}。有了这个说法,更好的方法是直接访问输入通配符对象,因为它实际上内置了toString转换,因为它带有只有单个字符串列表(其中通配符对象可以包含多个个别通配符属性,因此行为不可预测)。

您可以忽略“.snk”后缀,我认为它对Snakemake规则文件很有用。在代码中,这就是我的意思:

<强> test.snk

 rule test:
     output:
         "{filename}"
     wildcard_constraints:
         filename = "[abc]"
     shell:
         "echo x > {wildcards.filename}"

以同样的方式,你也可以这样做, test.snk:

 rule test:
     output:
         "{filename}"
     wildcard_constraints:
         filename = "[abc]"
     shell:
         "echo x > {output}"

推荐的代码库:

<强> test1.snk:

 rule test:
     output:
         "{filename}"
     wildcard_constraints:
         filename = "[abc]"
     shell:
         "echo x > {output}"

<强> Snakefile:

 configfile: "config.yaml"

 rule all:
     input:
         expand("{sample}", sample=config["fileName"])

 include: "test1.snk"

<强> config.yaml

fileName: ['a','b','c']

$ snakemake -n:

 rule test:
     output: a
     jobid: 1
     wildcards: filename=a


 rule test:
     output: c
     jobid: 2
     wildcards: filename=c


 rule test:
     output: b
     jobid: 3
     wildcards: filename=b


 localrule all:
     input: a, b, c
     jobid: 0

 Job counts:
     count   jobs
     1   all
     3   test
     4

其他信息

此外,这个设置很好地扩展:)只使用CLI调用Snakemake运行它,没有任何参数。像:

 snakemake

虽然这是一种可怕的做法,但从技术上讲,如果你更注重“结果”,并且不关心可重复性,那么它也是可能的。

 snakemake -n -s "test1.snk" a b c

这基本上只针对规则“test1.snk”并从中请求“a”,“b”和“c”。

rule test:
    output: c
    jobid: 0
    wildcards: filename=c


rule test:
    output: b
    jobid: 1
    wildcards: filename=b


rule test:
    output: a
    jobid: 2
    wildcards: filename=a

Job counts:
        count   jobs
        3       test
        3

你可以看到干运行呼叫实际上是不同的,因为它没有访问“全部规则”,因此没有第四个工作。总的来说,Snakemake的处理对于shell命令执行的处理通常是微不足道的。如果没有“全部”规则,我预计性能差异很小。然而,根据所有规则,您的代码所做的事情会更加清晰,并且您可以轻松地重新运行完全相同的命令,而无需“grep”您的“历史记录”。