如何在Snakemake中对值列表并行应用规则生成文件?
问题描述
我正在探索使用Snakemake作为工作流工具。我的使用场景并非从文件列表出发,而是基于一个值列表来生成对应的文件列表。
我通过一段Python代码片段创建文件的逻辑(对应foo规则)运行正常,但在第二个bar规则中尝试并行使用这些文件时,参数被拼接为一个整体:
rule all: input: expand('{file}.bar', file=data) rule foo: output: expand('{file}.foo', file=data) run: for item in data: with open(f'{item}.foo', 'w') as fout: fout.write('foo') rule bar: input: file=expand('{file}.foo', file=data) output: outfile=expand('{file}.bar', file=data) shell: """echo {output.outfile};echo bar > {output.outfile} """
运行后,示例会一次性打印出"one.bar two.bar three.bar",说明bar规则仅执行了一次,随后因预期的输出文件未创建而报错。请问如何实现对值列表的并行规则应用?
解决方案
核心问题是你没有让Snakemake为列表中的每个值单独实例化规则,而是让规则一次性处理所有文件,导致无法并行。调整方式如下:
1. 修改bar规则为单文件处理模式
把bar规则改成针对单个{file}参数的形式,Snakemake会自动为data列表中的每个值生成独立的规则实例,天然支持并行执行:
rule all: input: expand('{file}.bar', file=data) # 推荐:将foo规则也改为单文件模式,更符合Snakemake设计理念 rule foo: output: '{file}.foo' run: with open(output[0], 'w') as fout: fout.write('foo') rule bar: input: '{file}.foo' output: '{file}.bar' shell: """echo {output}; echo bar > {output}"""
2. 原写法失效的原因
你之前在bar规则的input和output中使用expand,会把所有文件路径拼成一个列表传给规则,导致规则仅执行一次。而shell命令里的echo bar > {output.outfile}只会将内容写入列表的最后一个文件,其他文件无法生成,最终触发报错。
3. 兼容原有foo规则的方案
如果一定要保留foo规则批量生成文件的逻辑,只需保证bar规则为单文件模式即可。Snakemake会在foo规则完成后,自动并行启动多个bar实例,分别处理每个生成的foo文件。
内容的提问来源于stack exchange,提问作者yahan
相关产品推荐
相关产品推荐

