Как работают контрольные точки Snakemake, когда я не хочу создавать папку?

#snakemake

Вопрос:

У меня есть файл snakemake, в котором одно правило создает файл, из которого я хотел бы извлечь заголовок и использовать его в качестве подстановочных знаков во всех моих правилах. В руководстве по змеиному змею приведен пример, в котором он создает новые папки с именами, подобными подстановочным знакам, но если я смогу этого избежать, было бы неплохо, так как в некоторых случаях тогда потребуется создать 100-200 папок. Есть какие-нибудь предложения о том, как заставить его работать?

ссылка на руководство по змееподобию: 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 разделен вкладками и может выглядеть следующим образом:

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

Комментарии:

1. Я не знаю ответа на ваш вопрос, но создание 100-200 папок не является проблемой. В любом случае у вас будет 100-200 файлов в одном каталоге.

Ответ №1:

Я думаю, что вы неправильно истолковываете пример контрольной точки 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)
 

Поскольку вы не знаете всех названий (фруктов) заранее, вы не можете включить их в правило «все». Вам нужно сослаться на промежуточное правило, чтобы свести все воедино. Может быть, использовать файл окончательного отчета:

 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}"