You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Snakemake是否有内置参数可容忍缺失输入?

在Snakemake中处理动态生成的输入文件(容忍缺失输入)

Snakemake没有直接“容忍缺失输入”的内置参数,但可以通过Checkpoint机制处理这种“先动态生成部分文件,再基于实际存在的文件进行下游分析”的场景——这是官方推荐的处理动态输出/输入的标准方案。

你的核心问题在于:初始定义的CHR列表是固定的,但实际运行中只会生成部分染色体的文件;而Snakemake在初始化阶段就会解析所有规则的目标文件,所以在规则内部修改全局CHR变量无法改变后续规则的执行逻辑。

解决方案:用Checkpoint捕获动态生成的文件

下面是修改后的完整代码,核心思路是:

  1. 用Checkpoint替代原来的get_CHR规则,动态生成染色体对应的文件,并以目录作为Checkpoint的输出(标记这是一个动态生成的文件集合)
  2. 编写一个函数,在运行时收集Checkpoint生成的所有文件,动态生成下游规则的目标列表
  3. 下游规则基于实际存在的动态文件执行,不会因“预期但未生成的文件”报错
import os
import pandas as pd
import glob

CHR = [1,2,3,4,5]  # 初始值仅作为占位,实际会被动态覆盖

rule all:
    input:
        # 动态获取实际需要生成的my_file_{chr}.txt文件列表
        lambda wildcards: get_chr_files()

rule one:
    input:
        config["Inputfile"]
    output:
        config["outdir"] + "/rslts/rule_1/rule_1.csv"
    shell:
        """
        # 这里写你的rule1逻辑,生成包含染色体信息的csv文件
        whatever
        """

# 用Checkpoint替代原get_CHR规则,处理动态输出
checkpoint get_CHR:
    input:
        config["outdir"] + "/rslts/rule_1/rule_1.csv"
    params:
        outdir = config["outdir"] + "/rslts/update_CHR/"
    output:
        directory(params.outdir)  # 以目录作为输出,标记动态生成的文件集合
    run:
        # 创建输出目录(如果不存在)
        os.makedirs(params.outdir, exist_ok=True)
        # 读取rule1生成的csv,提取实际存在的染色体
        chr_df = pd.read_csv(input[0], sep=",")
        actual_chrs = chr_df["chromosome_name"].tolist()
        # 生成每个染色体对应的update_*.txt文件
        for chr in actual_chrs:
            # 这里替换为你实际的文件生成逻辑,示例中假设取csv第二列的值写入文件
            chr_value = chr_df[chr_df["chromosome_name"] == chr].iloc[0, 1]
            with open(f"{params.outdir}/update_{chr}.txt", "w") as f:
                f.write(f"{chr_value}\n")

# 收集Checkpoint生成的所有update_*.txt文件,生成下游目标文件列表
def get_chr_files():
    # 获取Checkpoint的输出目录
    checkpoint_dir = checkpoints.get_CHR.get_output()[0]
    # 遍历目录下的所有update_*.txt文件
    chr_files = glob.glob(os.path.join(checkpoint_dir, "update_*.txt"))
    # 提取染色体编号,生成对应的my_file_{chr}.txt路径
    actual_chrs = [os.path.basename(f).replace("update_", "").replace(".txt", "") for f in chr_files]
    return expand("my_file_{chr}.txt", chr=actual_chrs)

rule three:
    input:
        # 根据wildcard动态匹配对应的输入文件
        lambda wildcards: os.path.join(config["outdir"], f"rslts/update_CHR/update_{wildcards.chr}.txt")
    output:
        "my_file_{chr}.txt"
    shell:
        """
        # 这里写你的下游处理逻辑
        whatever
        """

关键说明

  1. Checkpoint的作用:Checkpoint会暂停Snakemake的DAG解析,先执行该规则生成动态文件,之后再重新解析后续规则的依赖关系,确保后续规则只处理实际存在的文件。
  2. 动态目标列表:get_chr_files函数在运行时读取Checkpoint生成的文件,动态生成rule all的目标,避免了初始固定CHR列表带来的“缺失输入”问题。
  3. 为什么原来的方法无效:Snakemake在启动时会一次性解析所有规则的依赖和目标文件,规则内部修改全局变量CHR的操作发生在运行阶段,无法影响初始化阶段已经确定的DAG结构。

替代方案(仅适用于预先生成文件的场景)

如果你的染色体文件是在Snakemake运行前就已经存在的,可以用glob_wildcards在初始化阶段直接匹配现有文件:

# 直接匹配目录下已有的update_*.txt文件
chr_wildcards = glob_wildcards(config["outdir"] + "/rslts/update_CHR/update_{chr}.txt")
actual_chrs = chr_wildcards.chr

rule all:
    input:
        expand("my_file_{chr}.txt", chr=actual_chrs)

但这种方法不适用于文件是由Snakemake动态生成的场景,因为初始化阶段文件还未生成。

内容的提问来源于stack exchange,提问作者Toffi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 12:33:17