输出字符串中通配符的字符串格式



我对 snakemake 比较陌生,我在将分散-收集 DeepVariant 工作流程改编成 snakemake 规则时遇到了一些麻烦。

在原始的Snakefile中,我想将第一步分散到一个集群中。 DeepVariant 使用*.00001-of-00256.*格式以中间文件格式跟踪分片编号,因此我需要使用字符串格式在inputoutputshell字段中提供分片编号和分片总数,并在scatter规则的params中提供分片编号作为通配符。gather规则的input字段中的expand()函数正在正确生成预期的文件名,但它无法找到scatter步骤将生成的输入文件路径。

我在下面生成了一个最小的可重现示例,以及运行此示例的输出(轻微编辑以删除一些路径信息)。

N_SHARDS = 8
rule all:
input: "done.txt"

rule scatter:
input: "start.txt"
output: f"test_{{shard:05}}-of-{N_SHARDS:05}.txt"
params:
shard = range(N_SHARDS)
message: "scattering"
shell:
f"echo {{wildcards.shard}} {N_SHARDS} > {{output}}"

rule gather:
input: expand(f"test_{{shard:05}}-of-{N_SHARDS:05}.txt", shard=range(N_SHARDS))
output: touch("done.txt")
shell: "echo gathering"
$ touch start.txt
$ snakemake -s example.smk -j 1
Building DAG of jobs...
MissingInputException in line 17 of /redacted/example.smk:
Missing input files for rule gather:
test_00002-of-00008.txt
test_00000-of-00008.txt
test_00006-of-00008.txt
test_00001-of-00008.txt
test_00004-of-00008.txt
test_00005-of-00008.txt
test_00007-of-00008.txt
test_00003-of-00008.txt

我已经为其他不需要通配符字符串格式的分散-收集概念构建了非常相似的规则,因此这是我能想到的唯一在这种情况下有所不同的事情。 我将不胜感激任何见解!

更新:一位乐于助人的推特用户指出,我可以删除scatter->output中的:05,并且规则有效。 这很棒,它恰好解决了我最初的问题,但这只是因为 DeepVariant 容忍在命令行传递的分片参数的零填充。 是否有允许我将格式应用于通配符的解决方案?

这就是我会这样做的:

N_SHARDS = '00008'
shard = ['%05d' % x for x in range(int(N_SHARDS))]
wildcard_constraints:
shard= '|'.join([re.escape(x) for x in shard])
rule all:
input: 
"done.txt",
rule scatter:
input: 
"start.txt",
output:
"test_{shard}-of-%s.txt" % N_SHARDS,
shell:
r"""
echo {wildcards.shard} %s > {output}"
""" % N_SHARDS

rule gather:
input:
expand('test_{shard}-of-%s.txt' % N_SHARDS, shard= shard),
output: 
touch("done.txt")
shell: 
"echo gathering"

wildcard_constraints位可能是多余的,但如果我确切地知道通配符将采用什么值,我倾向于非常自由地使用它。

一件事:您似乎事先知道 DeepVariant 将生成多少个分片(示例中N_SHARDS = 8)。事实果真如此吗?如果没有,我认为您需要求助于蛇制的检查点功能。

最新更新