如何将Snakemake解析输出文件内容作为后续规则的通配符?
解决Snakemake无法从输入文件确定输出文件的问题
你的问题核心在于get_samples规则中的{individual}通配符无法被Snakemake自动解析——Snakemake仅能通过文件名模式推断通配符取值,无法直接读取文件内容来生成目标列表。以下是具体修复方案:
步骤1:添加读取样本列表的辅助函数
先定义一个函数,从每个family对应的样本文件中读取有效样本名称:
def get_individuals(wildcards): with open(f"output/{wildcards.family}.txt") as f: return [line.strip() for line in f if line.strip()]
步骤2:定义总目标规则rule all
显式告知Snakemake需要生成的所有样本文件,结合expand和上述函数生成完整目标列表:
rule all: input: expand( "output/{individual}.vcf.gz", individual=flatten([get_individuals({"family": fam}) for fam in FAMILY]) )
这里用flatten将嵌套的样本列表展开为一维结构,确保expand能正确生成所有输出路径。
步骤3:修正get_samples规则
原规则存在拼写错误、输入依赖错误和冗余逻辑问题,修正后的规则如下:
rule get_samples: input: # 依赖原始vcf文件用于提取样本,同时依赖样本列表文件保证执行顺序 vcf="muscle/{family}.vcf.gz", sample_list="output/{family}.txt" output: "output/{individual}.vcf.gz" # 约束wildcard,让Snakemake能通过individual反向匹配对应的family wildcard_constraints: individual=lambda ind: any(ind in get_individuals({"family": fam}) for fam in FAMILY) shell: # 直接用bcftools提取指定样本,无需冗余的python循环和xargs "bcftools view -O z -s {wildcards.individual} -o {output} {input.vcf}"
补充说明
wildcard_constraints的作用是建立{individual}与{family}的关联,让Snakemake可以反向推导依赖关系,避免匹配混乱。- 原shell命令中的python循环和xargs属于冗余操作,直接通过
bcftools view的-s参数指定样本即可完成提取,更高效且不易出错。
内容的提问来源于stack exchange,提问作者moth
相关产品推荐
相关产品推荐

