
Snakemake未执行calculate_accessibility规则,核心原因是其output与run_tf_analyses_from_bam规则完全重复,且该规则将输入和输出设为同一目录——这违反了Snakemake对输出唯一性与构建确定性的强制要求。
snakemake未执行`calculate_accessibility`规则,核心原因是其`output`与`run_tf_analyses_from_bam`规则完全重复,且该规则将输入和输出设为同一目录——这违反了snakemake对输出唯一性与构建确定性的强制要求。
在Snakemake中,每个output必须唯一标识一个可构建的产物,且不能与其他规则的output路径重叠。您当前的配置存在两个关键问题:
? 问题1:输出路径冲突(Ambiguous Output)
rule run_tf_analyses_from_bam:
output:
directory(config["output_folder"] + "/{sampleID}") # ← 输出:./output/04B003764_R/
rule calculate_accessibility:
output:
directory(config["output_folder"] + "/{sampleID}") # ← 完全相同的输出路径!Snakemake在构建DAG时发现同一目标路径(如 output/04B003764_R/)可由多个规则生成,它会静默选择第一个匹配规则(即 run_tf_analyses_from_bam),而直接忽略后续规则(如 calculate_accessibility)。这就是为何 --debug-dag 中能看到 calculate_accessibility 被列为“candidate”,却从未进入“selected”列表。
✅ 正确做法:每个规则的
output必须唯一、不可重叠。若calculate_accessibility的结果存放在同一父目录下,应使用明确的子目录或标记文件作为输出。
? 问题2:输入=输出(逻辑错误)
rule calculate_accessibility:
input:
tf_results=config["output_folder"] + "/{sampleID}" # ← 输入是目录
output:
directory(config["output_folder"] + "/{sampleID}") # ← 输出是同一目录!这是根本性设计错误。Snakemake要求:规则必须“创建”其声明的全部输出。当声明 directory(...) 为输出时,Snakemake会在执行前清空该目录(若存在),再运行shell命令——但您的脚本 ./scoring_pipeline.sh 实际是向该目录追加写入(如 AccessibilityOutput/, WaveletOut/ 等子目录)。这导致:
- Snakemake认为该目录“已被前序规则完全生成”,无需再运行;
- 即使运行,也会先删掉
TranscriptionFactors/等已有内容,破坏数据流。
✅ 正确解决方案:定义精确、原子化的输出
将 calculate_accessibility 的 output 改为其实际生成的标志性产物,例如主结果文件或专属子目录:
rule calculate_accessibility:
input:
tf_results=directory(config["output_folder"] + "/{sampleID}"), # 依赖前序目录存在
output:
# ✅ 声明该规则真正创建的产物(不可省略!)
accessibility_out=directory(config["output_folder"] + "/{sampleID}/AccessibilityOutput"),
wavelet_out=directory(config["output_folder"] + "/{sampleID}/WaveletOut"),
log_file=config["output_folder"] + "/{sampleID}/log.txt"
message: "Running accessibility scoring for {wildcards.sampleID}"
shell:
"""
./scoring_pipeline.sh {input.tf_results} {wildcards.sampleID}
"""同时,修正 rule all 的最终目标,使其显式依赖所有终端产物(而非仅父目录):
rule all:
input:
expand(config["output_folder"] + "/{sampleID}/AccessibilityOutput", sampleID=SAMPLES),
expand(config["output_folder"] + "/{sampleID}/WaveletOut", sampleID=SAMPLES),
expand(config["output_folder"] + "/{sampleID}/log.txt", sampleID=SAMPLES)⚠️ 额外注意事项
-
避免
directory()作为唯一输出:它无法表达“目录内部分文件已存在”的状态。优先使用具体文件(如AccessibilityOutput/Accessibility1KSites.txt)或带时间戳的占位符(如AccessibilityOutput/.done)。 -
确保输入存在性:
input.tf_results使用directory(...)是合理的(表示依赖目录结构就绪),但必须确保run_tf_analyses_from_bam已成功生成该目录。 -
调试技巧:运行
snakemake -n -r --debug-dag查看完整DAG;用snakemake --dryrun --reason检查每条规则被选中/跳过的具体原因。
通过以上调整,calculate_accessibility 将拥有明确、无冲突的输出契约,Snakemake即可正确识别其必要性并纳入执行计划——真正实现三阶段流程的端到端自动化。

















