如何正确使用Snakemake的allow_missing=True处理部分通配符缺失问题
问题原因
expand()函数的allow_missing=True参数作用仅为:允许调用expand时不传入所有占位符对应的变量,不会因为缺少通配符赋值抛出参数错误,完全不会自动检查文件存在性、跳过不存在的通配符组合,属于对参数功能的理解偏差。- 当前代码存在两处逻辑错误:
rule all中直接对SAMPLE和id列表做全量笛卡尔积展开,会要求Snakemake生成所有组合的输出文件,不管对应输入是否存在,自然会触发缺失文件警告。map_again规则的input写法错误:双大括号转义{{sample}}后再传入全量SAMPLE集合做expand,会导致单条任务的输入会引入所有样本下对应ID的fq.gz文件,和单样本单ID处理的逻辑完全不符。
- 额外隐患:原代码用
id作为变量名,会覆盖Python内置的id()函数,容易引发意外报错。
修正方法
不要依赖allow_missing做文件存在性判断,提前收集真实存在的合法通配符组合,再基于合法列表定义目标输出,同时修正单规则的输入匹配逻辑。
完整修正代码如下:
import os from itertools import product # 基础变量定义 SAMPLE = {"x", "y", "z"} with open(config["path"] + "barcodes.txt") as f: id_list = [line.rstrip() for line in f if line.strip()] # 收集所有真实存在输入文件的(sample, ID)组合 valid_wildcards = [] for sample, bid in product(SAMPLE, id_list): input_fq = config["path"] + f"{sample}/map/filtered.{sample}.R1.clean.id_{bid}.fq.gz" if os.path.exists(input_fq): valid_wildcards.append((sample, bid)) rule all: input: [config["path"] + f"{s}/remap/filtered.{s}.R1.clean.id_{i}.fq.bam" for s,i in valid_wildcards] rule map_again: output: config["path"] + "{sample}/remap/filtered.{sample}.R1.clean.id_{ID}.fq.bam" input: config["path"] + "{sample}/map/filtered.{sample}.R1.clean.id_{ID}.fq.gz" shell: "squire Map -1 {input} -r 150 -p 10"
补充说明:如果对应的输入fq.gz文件不是提前存在的静态文件,而是工作流上游规则的输出,不需要提前用
os.path.exists检查,换成Snakemake的checkpoints机制在运行时动态获取合法文件列表即可,静态输入场景下上述代码可直接运行。
内容的提问来源于stack exchange,提问作者P.Yuan
相关产品推荐
相关产品推荐

