我正在寻找一种在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:目标规则可能不包含通配符。请指定具体文件或没有通配符的规则。
我当然可以使用output
调用来指定expand()
,但这意味着规则会在调用一次时创建所有文件,但事实并非如此。相反,它应该在使用某个参数执行shell
时创建一个文件(此处示例中为{filename}
)。
答案 0 :(得分:3)
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”您的“历史记录”。