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

如何在Snakemake规则中运行for循环避免MissingOutputException

解决Snakemake中Kraken2批量处理样本的MissingOutputException问题

问题背景

需要添加一个kraken规则,一次性处理所有样本(让Kraken2数据库驻留内存以提升效率),而非用wildcard逐个处理。但尝试用shell循环实现时,频繁触发MissingOutputException错误。

现有Snakemake核心脚本:

import os

SAMPLES = [i.replace('sample_', '') for i in os.listdir('final_raw')]

rule all:
    input:
        expand('analysis/results/unmapped/hybrid/read1_{sample}_hy.fastq', sample = SAMPLES)

# trimming、create_hybrid_genome等其余规则保持不变

尝试的错误循环代码:

for FILE in $(ls analysis/results/unmapped/hybrid/read1_*_hy.fastq | sed 's/read1_*_hy.fastq//'); do \
        kraken2 --db {input.database} \
        --memory-mapping \
        --threads 8 \
        --use-names \
        --report analysis/results/kraken2/hybrid/{{}}${{FILE}}.kraken \
        --paired read1_${{FILE}}_hy.fastq read2_${{FILE}}_hy.fastq \
        --unclassified-out /analysis/results/unclassified/hybrid/{{}}${{FILE}}_uc#.fastq; done

常规单样本处理规则(效率低,无法驻留数据库):

rule kraken2:
    input:
        database = 'kraken2_db',
        read1 = 'analysis/results/unmapped/hybrid/read1_{sample}_hy.fastq',
        read2 = 'analysis/results/unmapped/hybrid/read2_{sample}_hy.fastq'
    output:
        'analysis/results/kraken2/hybrid/{sample}.kraken'
    shell:
        'kraken2 '
            '--db {input.database} '
            '--threads 8 '
            '--paired '
            '--use-names '
            '--unclassified-out {wildcards.sample}_uc#.fq '
            '--report {output} '
            '{input.read1} {input.read2}'

解决方案

核心问题:Snakemake需要明确知晓规则的所有输入输出文件,不能依赖shell动态文件查找(如ls),否则无法追踪输出是否生成,从而抛出MissingOutputException。

步骤1:更新rule all,明确所有目标输出

rule all:
    input:
        expand('analysis/results/unmapped/hybrid/read1_{sample}_hy.fastq', sample = SAMPLES),
        expand('analysis/results/kraken2/hybrid/{sample}.kraken', sample = SAMPLES),
        expand(['analysis/results/unclassified/hybrid/{sample}_uc_1.fastq', 
                'analysis/results/unclassified/hybrid/{sample}_uc_2.fastq'], 
               sample = SAMPLES)

步骤2:编写批量处理的kraken2_batch规则

rule kraken2_batch:
    input:
        database = 'kraken2_db',
        read1_list = expand('analysis/results/unmapped/hybrid/read1_{sample}_hy.fastq', sample = SAMPLES),
        read2_list = expand('analysis/results/unmapped/hybrid/read2_{sample}_hy.fastq', sample = SAMPLES)
    output:
        reports = expand('analysis/results/kraken2/hybrid/{sample}.kraken', sample = SAMPLES),
        uc_reads = expand(['analysis/results/unclassified/hybrid/{sample}_uc_1.fastq', 
                           'analysis/results/unclassified/hybrid/{sample}_uc_2.fastq'], 
                          sample = SAMPLES)
    threads: 8
    shell:
        """
        # 直接使用Snakemake定义的样本列表,避免动态查找
        for sample in {SAMPLES}; do
            kraken2 --db {input.database} \\
                --memory-mapping \\
                --threads {threads} \\
                --use-names \\
                --report analysis/results/kraken2/hybrid/${{sample}}.kraken \\
                --paired analysis/results/unmapped/hybrid/read1_${{sample}}_hy.fastq analysis/results/unmapped/hybrid/read2_${{sample}}_hy.fastq \\
                --unclassified-out analysis/results/unclassified/hybrid/${{sample}}_uc#.fastq
        done
        """

关键说明

  1. 输入输出明确化:所有输入输出通过expand基于SAMPLES生成,Snakemake可提前知晓所有需生成的文件,避免追踪失效。
  2. 循环变量一致性:直接用Snakemake定义的SAMPLES变量,确保循环样本列表与目标完全匹配。
  3. 语法冲突规避:shell变量用${sample}而非{sample},避免和Snakemake变量语法冲突。
  4. 内存驻留生效:--memory-mapping参数让Kraken2加载数据库后保持内存映射,批量处理时无需重复加载,提升效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 15:35:41