【问题标题】:How to translate a simple target pattern rule to snakemake?如何将简单的目标模式规则翻译成蛇形?
【发布时间】:2018-02-22 05:13:41
【问题描述】:

我正在寻找一种在 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:目标规则可能不包含通配符。请指定具体文件或不带通配符的规则。

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

【问题讨论】:

  • 我不确定我是否理解您的 GNU Make 代码。您试图举例说明的目标模式是“all: a b c”,其中 all 是目标,“a b c”是模式是吗?
  • 我正在寻找一个规则,以在输入没有通配符模式时生成名称包含通配符的单个文件。这正是 Makefile 所说的:从无模式构造一个模式。在这种特殊情况下,该规则可用于创建具有任何名称和内容x 的文件。目标文件为abc,都是通过调用模式规则3次创建的。

标签: snakemake


【解决方案1】:

下面的蒂姆斯回答基本上包含了解决方案。不过既然你在 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 中解释了所有这些基础知识。

【讨论】:

  • 感谢您抽出宝贵时间,当我 ping 时没有答案,我真的很困惑,因为教程(您链接的)没有没有输入通配符的输出通配符。也许可以改进错误消息?毕竟,这是一个包含通配符的(有效)目标规则。
  • 是的,错误信息确实可以改进。目标规则可能不包含通配符。否则,Snakemake 将不知道如何填充它们。
  • s/wildcard/pattern/ 在我的评论中;抱歉使用不准确
  • 在较新版本的 Snakemake 中,shell: "echo x > {wildcards.filename}"
【解决方案2】:

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

在您的 shell 指令中,变量 {filename} 可作为通配符对象的属性访问。您需要使用 python 点符号来访问它,例如 {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}"

蛇文件:

 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

你可以看到试运行调用实际上是不同的,因为它没有访问“全部规则”,因此没有第 4 个工作。总体而言,Snakemake 的处理与 shell 命令执行的处理相比通常是微不足道的。如果没有“全部”规则,我预计性能差异很小。然而,使用 all 规则,您的代码应该在做什么变得更加清晰,并且您可以轻松地重新运行完全相同的命令,而无需“grep”您的“历史”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-26
    • 1970-01-01
    • 2022-07-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多