
Snakemake 未执行 calculate_accessibility 规则是由于其输入与输出路径完全相同,且与 run_tf_analyses_from_bam 规则存在输出路径冲突,导致 DAG 构建时规则被忽略或覆盖。
snakemake 未执行 `calculate_accessibility` 规则是由于其输入与输出路径完全相同,且与 `run_tf_analyses_from_bam` 规则存在输出路径冲突,导致 dag 构建时规则被忽略或覆盖。
在 Snakemake 中,每个规则的 output 必须唯一标识该规则的“产物”,且不能与其他规则的输出路径重叠;同时,input 和 output 绝对不可指向同一路径(尤其是 directory())——这会破坏依赖图(DAG)的拓扑排序逻辑,使 Snakemake 无法判断执行顺序,最终跳过该规则(如您所见,calculate_accessibility 仅出现在 candidate job 列表中,却从未被 selected)。
? 根本问题分析
-
输出路径冲突(Ambiguous Output)
以下两个规则均声明了完全相同的output:rule run_tf_analyses_from_bam: output: directory(config["output_folder"] + "/{sampleID}") rule calculate_accessibility: output: directory(config["output_folder"] + "/{sampleID}")Snakemake 要求每个输出路径只能由一个规则生成。当多个规则声称能生成同一目录时,它默认选择首个匹配的规则(此处为
run_tf_analyses_from_bam),后续规则(calculate_accessibility)将被静默忽略——即使其逻辑上应作用于前一规则的输出之上。 -
输入 = 输出(Invalid Dependency)
calculate_accessibility的定义违反了 Snakemake 的核心契约:input: config["output_folder"] + "/{sampleID}" # ← 同一目录 output: directory(config["output_folder"] + "/{sampleID}") # ← 完全相同这会导致:
- Snakemake 在构建 DAG 时无法区分“输入就绪”和“输出待生成”状态;
- 执行前会强制清空该目录(因
directory()输出意味着“本规则负责创建并拥有该目录”),但脚本scoring_pipeline.sh实际需读取其中已存在的TranscriptionFactors/子目录——结果是目录被删、依赖丢失、任务失败或跳过。
✅ 正确建模方式:显式声明层级化输出
应让每条规则产出明确、唯一、非重叠的输出路径,并通过 input 精确引用上游产物:
rule calculate_accessibility:
input:
tf_dir = config["output_folder"] + "/{sampleID}/TranscriptionFactors", # ← 明确依赖子目录
# 可选:添加关键文件作为输入锚点,增强确定性
# anchor = config["output_folder"] + "/{sampleID}/TranscriptionFactors/GTRD_CHIP_Only_1000sites/README.txt"
output:
# 输出必须是新路径!例如 AccessibilityOutput 目录(符合您描述的实际产出)
accessibility_out = directory(config["output_folder"] + "/{sampleID}/AccessibilityOutput"),
wavelet_out = directory(config["output_folder"] + "/{sampleID}/WaveletOut")
message: "Running accessibility scoring for {wildcards.sampleID}"
shell:
"""
./scoring_pipeline.sh {input.tf_dir} {wildcards.sampleID}
# 注意:确保 scoring_pipeline.sh 将结果写入 {output.accessibility_out} 和 {output.wavelet_out}
# 若脚本默认写入父目录,需在 shell 中做软链接或移动操作
"""
同时,修正 rule all 的最终目标,使其明确依赖 calculate_accessibility 的真实输出(而非模糊的 sample 根目录):
rule all:
input:
expand(
[
"{output_folder}/{sampleID}/AccessibilityOutput/Accessibility1KSites.txt",
"{output_folder}/{sampleID}/WaveletOut/plot_wavelet.png"
],
output_folder=config["output_folder"],
sampleID=SAMPLES
)
? 关键原则:
rule all的input应指向最下游、最具代表性的终态文件(如关键.txt或.png),而非宽泛的目录。这既避免歧义,又确保 Snakemake 能精准推导完整执行链。
⚠️ 其他注意事项
-
不要依赖
directory()的“存在即完成”语义:Snakemake 对directory(...)的处理等价于touch一个标记文件(如.snakemake_timestamp),但更安全的做法是输出至少一个明确文件(如AccessibilityOutput/.done),再用input:显式引用它。 -
调试技巧:运行
snakemake --dry-run --debug-dag | grep -A5 calculate_accessibility查看规则是否进入selected job;若仍不出现,说明 DAG 未将其纳入路径——大概率是rule all目标未正确关联到它的output。 -
配置健壮性:建议在
rule calculate_accessibility中添加前置检查,防止scoring_pipeline.sh因输入缺失而静默失败:test -d "{input.tf_dir}" || { echo "ERROR: TF dir missing!" >&2; exit 1; }
遵循以上结构调整后,calculate_accessibility 将被 Snakemake 正确识别、调度并执行,整个 pipeline 的依赖关系也将清晰、可追溯、可复现。










