Snakemake 未知数量的输出文件/根据中间文件定义通配符

Snakemake unknown number of output files / defining wildcards based on intermediate files

为了加快我的工作流程,我想做一些类似于

的事情
SAMPLE = "sample_a"

rule all:
    expand("results/{sample}-final-combined.bam", sample=SAMPLE)


rule exclude_blacklist:
    input:
        region_file = "data/{sample}.bed",
        blacklist = "data/blacklists/universal_blacklist.bed"
    output:
        "results/{sample}_blacklist-excluded.bed"
    shell:
        """
        bedtools intersect -v -a {input.region_file} -b {input.blacklist} > {output}
        """

rule target_regions_by_chrom:
    input:
        region_file ="results/{sample}_blacklist-excluded.bed",
    output:
        temp("results/{sample}_{chrom}.bed")
    script:
        "scripts/split_region_by_chrom.py"

rule simulate_reads:
    input:
        "results/{sample}_{chrom}.bed"
    output:
        "results/{sample}_{chrom}.bam"
    script:
        "scripts/simulate_reads.py"

rule combine_regions_again:
    input:
        files = expand("results/{sample}_{chrom}.bam", sample=SAMPLE, chrom=get_chroms())
    output:
        "results/{sample}-final-combined.bam"
    script:
        "scripts/combine_bams.py"

工作流程应采用具有未过滤区域的 .bed 文件,从黑名单中排除有问题的区域,按染色体拆分过滤后的 .bed 文件,然后模拟这些区域的读取(为简单起见,我不赘述细节),生成.bam 文件。最终,这些 .bam 文件应该再次组合成一个输出文件。

主要问题是如何事先解决染色体数目未知的问题。如果我使用输入的 .bed 文件,我会得到一些错误,因为有些文件是空的。我考虑过在排除黑名单区域后使用输入函数(此处 get_chroms())从输出 .bed 文件(“results/{sample}_blacklist-excluded.bed”)恢复染色体,但是这会导致在创建 DAG 期间出错,因为该文件不存在。

有没有人对如何解决这些问题有任何建议:

  1. 在不知道当前染色体的情况下按染色体拆分 .bed 文件
  2. 基于工作流中的中间文件定义通配符

如有任何帮助,我们将不胜感激!

Snakemake 的 Dynamic Files 功能可能是您所需要的:

Dynamic files can be used whenever one has a rule for which the number of output files is unknown before the rule was executed.

您应该在输入和输出对应项中用 dynamic() 修饰符包装 "results/{sample}_{chrom}.bed"

rule target_regions_by_chrom:
    output:
        dynamic("results/{sample}_{chrom}.bed")

rule simulate_reads:
    input:
        dynamic("results/{sample}_{chrom}.bed")