Snakemake未执行createdb规则仅识别all规则的问题求助
核心问题分析
你的脚本中rule all可被识别,但createdb规则未触发,主要源于以下几个问题:
1. glob_wildcards执行时机导致输入依赖缺失
glob_wildcards在Snakemake脚本初始化阶段就会运行,而createdb的输入指向RESULTS目录下的文件——这些文件尚未生成时,glob_wildcards会返回空列表,导致createdb的input: files为空。Snakemake会判定该规则无需要处理的依赖,直接跳过。
2. expand的zip参数使用错误
你在createdb的输入中使用zip参数,会强制将jaspar、assembly、batch、tf、bed几个列表按索引一一配对生成路径。若这些列表长度不一致,或实际文件的对应关系并非按索引配对,会生成无效路径,无法与rule all的输出建立正确依赖。
3. Wildcard映射逻辑不明确
createdb的输出仅包含jaspar、assembly、batch三个wildcard,但输入中多了tf和bed。Snakemake无法自动推断“多个带tf/bed的输入文件对应一个带batch的输出文件”的逻辑,导致依赖链断裂。
修复方案
步骤1:调整输入依赖的获取方式
不要用glob_wildcards获取RESULTS目录下的文件(这类文件是后续生成的),而是通过rule all的wildcard反向推导,或用expand结合通配符匹配输入:
rule createdb: input: # 用通配符匹配对应batch下的所有bed文件,而非提前glob files = expand(os.path.join(RESULTS, "{jaspar}", "{assembly}", "data", "{batch}", "{tf}", "regions", "{bed}.bed"), tf=TFS, bed=BEDS) output: os.path.join(RESULTS, "{jaspar}", "{assembly}", "LOLA_dbs", "JASPAR2020_LOLA_{batch}.RDS") shell: """ R --vanilla --slave --silent -f {BIN}/create_lola_db.R \ --args {RESULTS}/{wildcards.jaspar}/{wildcards.assembly}/data/{wildcards.batch} \ {output}; """
注:TFS和BEDS从DATA目录的glob_wildcards获取是可行的,因为DATA下的文件是预先存在的。
步骤2:移除zip参数,明确分组逻辑
若每个batch对应一组tf和bed,可通过分组替代zip,确保依赖关系正确:
from collections import defaultdict # 按jaspar+assembly+batch分组,收集对应的tf和bed文件路径 batch_files = defaultdict(list) for jaspar, assembly, batch, tf, bed in zip(JASPARS, ASSEMBLIES, BATCHES, TFS, BEDS): batch_key = (jaspar, assembly, batch) batch_files[batch_key].append(os.path.join(RESULTS, jaspar, assembly, "data", batch, tf, "regions", f"{bed}.bed")) rule createdb: input: files = lambda wildcards: batch_files[(wildcards.jaspar, wildcards.assembly, wildcards.batch)] output: os.path.join(RESULTS, "{jaspar}", "{assembly}", "LOLA_dbs", "JASPAR2020_LOLA_{batch}.RDS") shell: """ R --vanilla --slave --silent -f {BIN}/create_lola_db.R \ --args {RESULTS}/{wildcards.jaspar}/{wildcards.assembly}/data/{wildcards.batch} \ {output}; """
这种方式能明确每个batch对应的所有输入文件,让Snakemake正确建立依赖链。
步骤3:验证依赖关系
运行Snakemake时添加--dry-run(或-n)参数,查看规则的依赖映射:
snakemake -n
若输出显示createdb规则被触发,说明依赖关系已正确建立;若仍未触发,检查rule all与createdb的输出路径是否完全一致(比如拼写错误、路径分隔符问题)。
内容的提问来源于stack exchange,提问作者Sushil Shakyawar

