Snakemake动态生成未知数量文件及后续规则调用问题
解决Snakemake动态输出文件的问题
针对你遇到的MissingOutputException以及通配符推断问题,核心解决方案是使用Snakemake Checkpoint处理运行时生成的未知数量/路径的输出文件,具体步骤如下:
1. 将extract_accessions改为Checkpoint
普通规则要求输出路径提前确定,而Checkpoint专门适配动态输出场景。将规则改为Checkpoint,输出设为包含{sample}的目录(确保Snakemake能推断sample通配符):
checkpoint extract_accessions: input: coverage="coverage/{sample}.cov" output: directory("accessions/{sample}") # 用目录作为输出标记,脚本将所有动态文件写入此目录 shell: """ python your_accession_script.py --input {input.coverage} --output-dir {output} """
2. 修改Python脚本的输出逻辑
调整你的Python脚本,将生成的文件按固定命名规则写入指定目录:
- 每个taxid的最长序列accession文件命名为:
longest_{taxid}.txt - 每个taxid的所有accession文件命名为:
all_{taxid}.txt
确保脚本执行完成后,所有动态生成的文件都存放在accessions/{sample}/目录下。
3. 编写函数收集动态生成的文件
在Snakefile中添加辅助函数,从Checkpoint的输出目录提取所有taxid并对应到生成的文件路径:
import os from snakemake.io import glob_wildcards def get_taxid_files(wildcards): # 获取当前sample对应的Checkpoint输出目录 checkpoint_dir = checkpoints.extract_accessions.output[0].format(sample=wildcards.sample) # 匹配目录下的所有taxid文件 taxids = glob_wildcards(os.path.join(checkpoint_dir, "longest_{taxid}.txt")).taxid # 返回两种文件的路径列表 return { "longest": [os.path.join(checkpoint_dir, f"longest_{t}.txt") for t in taxids], "all": [os.path.join(checkpoint_dir, f"all_{t}.txt") for t in taxids] }
4. 配置后续规则extract_reads_from_sam
利用上述函数获取动态输入文件,同时使用{sample}和{taxid}通配符:
rule extract_reads_from_sam: input: sam="alignments/{sample}.sam", # 根据wildcards中的taxid匹配对应的accession文件 longest_accession=lambda wc: os.path.join("accessions", wc.sample, f"longest_{wc.taxid}.txt"), all_accessions=lambda wc: os.path.join("accessions", wc.sample, f"all_{wc.taxid}.txt") output: "reads/{sample}_{taxid}.sam" shell: """ # 示例:使用all_accessions文件过滤sam文件 samtools view -N {input.all_accessions} {input.sam} > {output} """
为什么之前的job.done方案失败?
job.done文件没有包含{sample}通配符的关联信息,Snakemake无法从该输出推断出sample的可能取值,因此触发通配符无法确定的报错。而Checkpoint的输出目录包含{sample},Snakemake可以先确定sample的取值,运行Checkpoint后再收集动态生成的taxid。
内容的提问来源于stack exchange,提问作者tretol
相关产品推荐
相关产品推荐

