当我不想创建文件夹时,Snakemake 检查点如何工作?

How do Snakemake checkpoints work when i do not wanna make a folder?

我有一个 snakemake 文件,其中一个规则从 生成一个文件我想提取 header 并在我的规则中用作通配符。 Snakemake 指南提供了一个示例,它创建了一个像通配符一样命名的新文件夹,但如果我能避免它会很好,因为在某些情况下它需要创建 100-200 个文件夹。关于如何让它发挥作用有什么建议吗?

link snakemake 指南: https://snakemake.readthedocs.io/en/stable/snakefiles/rules.html

import pandas as pd

rule all:
    input: 
        final_report = expand('report_{fruit}.txt', fruit= ???)

rule create_file:
    input:
    output:
        fruit = 'fruit_file.csv'
    run:
        ....

rule next:
    input:
        fruit = 'fruit_file.csv'
    output:
        report = 'report_{phenotype}.txt'
    run:
        fruit_file = pd.read_csv({input.fruit}, header = 0, sep = '\t')
        fruits= fruit_file.columns.tolist()[2:]
        for i in fruits:
            cmd = 'touch report_' + i + '.txt'
            shell(cmd)

这是一个简化的工作流程,因为我实际上使用了一些长脚本来生成 pheno_file.csv 和报告文件。

pheno_file.csv 是 tab-seperated,可能看起来像这样:

FID IID Apple   Banana  Plum
Mouse   Mickey  0   0   1
Mouse Minnie    1   0   1
Duck    Donnald 0   1   0

我认为您误读了 snakemake 检查点示例。您只需要在您的案例中创建一个文件夹。他们在文件夹名称中有一个通配符 (sample),但输出名称的那部分是提前知道的。

checkpoint fruit_reports:
    input:
        fruit = 'fruit_file.csv'
    output:
        report_dir = directory('reports')
    run:
        fruit_file = pd.read_csv({input.fruit}, header = 0, sep = '\t')
        fruits= fruit_file.columns.tolist()[2:]
        for i in fruits:
            cmd = f'touch {output}/report_{i}.txt'
            shell(cmd)

由于您事先不知道所有名称(水果),因此不能将它们包含在 all 规则中。您需要引用一个中间规则来将所有内容组合在一起。也许使用最终报告文件:

rule all:
   input: 'report.txt'

然后在检查点之后:

def aggregate_fruit(wildcards):
     checkpoint_output = checkpoints.fruit_reports.get(**wildcards).output[0]
     return expand("reports/report_{i}.txt",
                    i=glob_wildcards(os.path.join(checkpoint_output, "report_{i}.txt")).i)


rule report:
    input:
        aggregate_input
    output:
        "report.txt"
    shell:
        "ls 1 {input} > {output}"