如何将简单的目标模式规则转换为 snakemake?
How to translate a simple target pattern rule to snakemake?
我正在寻找一种在 Snakemake 中定义目标模式规则(无输入模式)的方法。
在这种情况下,我想要一个规则来创建文件 a
、b
和 c
作为目标文件模式的一部分,其中输入不包含模式。
在 GNU make 中,我会这样做:
.PHONY: all
all: a b c
%:
echo x > $@
但是,如果我在 Snakemake 中执行以下操作:
rule test:
output:
"{filename}"
wildcard_constraints:
filename = "[abc]"
shell:
"echo x > {filename}"
WorkflowError: Target rules may not contain wildcards. Please specify concrete files or a rule without wildcards.
我当然可以使用 expand()
调用指定 output
,但这意味着该规则会在调用一次时创建所有文件,但事实并非如此。相反,它应该在使用特定参数执行 shell
时创建 one 文件(此处示例中的 {filename}
)。
问题是 shell 指令中的 {input} 与 {wildcards.namedVar} 访问。 See here in the documentation。话虽如此,我没有看到您的驱动程序需要 Snakemake 设置,我也建议这样做。 (我已经在下面的回答中添加了它)。它将等同于 .PHONY 和所有规则模式(GNU Make 强迫我们进入的混乱约定)。
在您的 shell 指令中,变量 {filename} 可作为通配符对象的属性访问。您需要使用 python 点符号来访问它,例如 {wildcards.filename}。 话虽如此,更好的方法是直接访问输入通配符对象,因为它实际上已经构建在 toString 转换中,因为它只携带一个 single 字符串列表(因为通配符对象可以包含 multiple 个单独的通配符属性,所以行为是不可预测)。
你可以忽略“.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
尽管这是一种糟糕的做法,但从技术上讲,如果您更 "outcome" 并且不关心可重复性,这也是可行的。
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
你可以看到 dry-运行 调用实际上是不同的,因为它没有访问 "rule all",因此没有第 4 个作业。总的来说,Snakemake 的处理对于 shell 命令执行的处理通常是微不足道的。如果没有 "all" 规则,我预计性能差异很小。然而,使用 all 规则,你的代码应该做什么变得更加清晰,你可以轻松地重新 运行 完全相同的命令,而不必 'grep' 你的 'history'.
下面Tims的回答基本上已经解决了。不过既然你在推特上问过我,我就直接翻译你的Makefile:
rule all:
input:
expand("{filename}", filename=["a", "b", "c"])
rule test:
output:
"{filename}"
wildcard_constraints:
filename = "[abc]"
shell:
"echo x > {filename}"
所有这些基础知识都在 Snakemake tutorial 中进行了解释。
我正在寻找一种在 Snakemake 中定义目标模式规则(无输入模式)的方法。
在这种情况下,我想要一个规则来创建文件 a
、b
和 c
作为目标文件模式的一部分,其中输入不包含模式。
在 GNU make 中,我会这样做:
.PHONY: all
all: a b c
%:
echo x > $@
但是,如果我在 Snakemake 中执行以下操作:
rule test:
output:
"{filename}"
wildcard_constraints:
filename = "[abc]"
shell:
"echo x > {filename}"
WorkflowError: Target rules may not contain wildcards. Please specify concrete files or a rule without wildcards.
我当然可以使用 expand()
调用指定 output
,但这意味着该规则会在调用一次时创建所有文件,但事实并非如此。相反,它应该在使用特定参数执行 shell
时创建 one 文件(此处示例中的 {filename}
)。
问题是 shell 指令中的 {input} 与 {wildcards.namedVar} 访问。 See here in the documentation。话虽如此,我没有看到您的驱动程序需要 Snakemake 设置,我也建议这样做。 (我已经在下面的回答中添加了它)。它将等同于 .PHONY 和所有规则模式(GNU Make 强迫我们进入的混乱约定)。
在您的 shell 指令中,变量 {filename} 可作为通配符对象的属性访问。您需要使用 python 点符号来访问它,例如 {wildcards.filename}。 话虽如此,更好的方法是直接访问输入通配符对象,因为它实际上已经构建在 toString 转换中,因为它只携带一个 single 字符串列表(因为通配符对象可以包含 multiple 个单独的通配符属性,所以行为是不可预测)。
你可以忽略“.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
尽管这是一种糟糕的做法,但从技术上讲,如果您更 "outcome" 并且不关心可重复性,这也是可行的。
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
你可以看到 dry-运行 调用实际上是不同的,因为它没有访问 "rule all",因此没有第 4 个作业。总的来说,Snakemake 的处理对于 shell 命令执行的处理通常是微不足道的。如果没有 "all" 规则,我预计性能差异很小。然而,使用 all 规则,你的代码应该做什么变得更加清晰,你可以轻松地重新 运行 完全相同的命令,而不必 'grep' 你的 'history'.
下面Tims的回答基本上已经解决了。不过既然你在推特上问过我,我就直接翻译你的Makefile:
rule all:
input:
expand("{filename}", filename=["a", "b", "c"])
rule test:
output:
"{filename}"
wildcard_constraints:
filename = "[abc]"
shell:
"echo x > {filename}"
所有这些基础知识都在 Snakemake tutorial 中进行了解释。