为什么没有用这些 Snakemake 规则和输出组合引发歧义规则异常?



我遇到了一些情况,我希望 Snakemake 会抱怨模棱两可的规则,但没有,所以我试图弄清楚预期的行为应该是什么。

例如,将此作为规则1.smk:

rule rule1:
output: "something.txt"
rule rule2:
output: "{thing}.txt"
rule rule3:
output: "{thing}.{ext}"

如果我请求文件.txt它会按预期抱怨:

$ snakemake -n --debug-dag -s rules1.smk file.txt
Building DAG of jobs...
candidate job rule2
wildcards: thing=file
candidate job rule3
wildcards: thing=file, ext=txt
AmbiguousRuleException:
Rules rule2 and rule3 are ambiguous for the file file.txt.
...

但是如果我请求什么.txt,它会直接进入规则 1 并停止:

$ snakemake -n --debug-dag -s rules1.smk something.txt
Building DAG of jobs...
candidate job rule1
wildcards: 
selected job rule1
...

我的问题是,它为什么要这样做? 难道不应该抱怨这三条规则对于该输出都是模棱两可的吗?

我的第一个想法是,产生没有通配符的输出匹配的规则可能隐式获得比使用任意数量通配符的规则更高的规则顺序定义,但我在文档中看不到类似的东西不明确的规则。

一个稍微复杂的示例显示了有关行为的更多信息:

if not config.get("noruleorder"):
ruleorder: rule1 > rule1alt
rule rule1:
output: "something.txt"
rule rule1alt:
output: "something.txt"
rule rule2:
output: "{thing}.txt"
rule rule3:
output: "{thing}.{ext}"

默认情况下,它有效,允许该规则顺序指令:

$ snakemake -n --debug-dag -s rules2.smk something.txt
Building DAG of jobs...
candidate job rule1
wildcards: 
selected job rule1
...

显然,如果没有规则顺序,它就无法工作,因为 rule1 和 rule1alt 尽可能模棱两可:

$ snakemake --config noruleorder=yep -n --debug-dag -s rules2.smk something.txt
Building DAG of jobs...
candidate job rule1alt
wildcards: 
candidate job rule1
wildcards: 
candidate job rule2
wildcards: thing=something
candidate job rule3
wildcards: thing=something, ext=txt
AmbiguousRuleException:
Rules rule1alt and rule1 are ambiguous for the file something.txt.
...

。但有趣的是,它随后考虑了我最初认为会成为候选人的所有规则。 我只是不确定这对候选人的工作逻辑有什么影响。 这一切似乎都与蛇作有关:没有检测到模棱两可的规则?但并不完全相同。

这是Snakemake 7.16.0。

没有通配符的规则隐式地被赋予比具有通配符的规则更高的规则顺序。 这在 3.2.2 的旧更新日志中就被注意到了,因为"没有通配符的规则现在在歧义的情况下会击败其他规则。 实际上有一个单元测试,看起来几乎与我在这里设置的完全一样。 我只是在文档中找不到任何这些。


我是如何找到这个的:

DAG.update遍历每个作业,如果找到比所有其他候选作业>的作业,则会断开循环。Job.__gt__只是调用Rule.__gt__Ruleorder.compare调用这样做:

# if no ruleorder given, prefer rule without wildcards
wildcard_cmp = rule2.has_wildcards() - rule1.has_wildcards()
if wildcard_cmp != 0:
return wildcard_cmp

如果我将其注释掉,我会得到我最初预期的行为:

$ snakemake -n --debug-dag -s rules1.smk something.txt
Building DAG of jobs...
candidate job rule1
wildcards: 
candidate job rule2
wildcards: thing=something
candidate job rule3
wildcards: thing=something, ext=txt
AmbiguousRuleException:
Rules rule1 and rule2 are ambiguous for the file something.txt.

行为和测试已添加到此提交中。 除非它已经存在并且我只是错过了它,否则这可能应该记录在关于模棱两可规则的部分中。

最新更新