Синтаксис Snakemake для нескольких выходов с использованием контрольной точки - PullRequest
1 голос
/ 06 января 2020

Я использую snakemake для создания конвейера. У меня есть контрольная точка, которая должна производить несколько выходных файлов. Эти выходные файлы позже используются в моем правиле все в рамках расширения. Дело в том, что я не знаю, сколько файлов будет создано, и поэтому не могу указать набор данных в расширении.

Файлы будут созданы в R-сценарии.

Пример:

rule all:
    input:
        expand(["results/{output}],
               output=????)



checkpoint rscript:
    input:
        "foo.input"
    output:
        report("somedir/{output}"),
    script:
        "../scripts/foo.R" 

Конечно, это только небольшая часть, но в моем R-скрипте есть все oop для вывода нескольких файлов в somedir. Но так как я не знаю, сколько и потому что они вначале оцениваются в сценарии R. Я не могу установить вывод в расширении.

Может быть, это действительно тривиальный вопрос для некоторых из вас, или даже глупый вопрос, и есть лучшие способы сделать это. Если бы это было так, я все равно был бы благодарен, потому что у меня были проблемы с пониманием большинства функций создания змеи из-за моей способности понимать функции в английском языке sh.

Если есть еще вопросы, я с удовольствием отвечу , (Для меня лучше всего было бы разрешить выводу иметь имена, которые я мог бы указать во время выполнения в скрипте R)

(я также не могу объединить созданные файлы в другое правило, потому что каждый файл будет отображать другой сюжет)

Редактировать: Основная проблема по-прежнему заключается в том, что rscript контрольной точки не может создать несколько {выходных} файлов в «somedir /». Попытка касания ("rscript_fini sh .flag"), похоже, выводит только файл svg как "rscript_fini sh .flag" или, кажется, переопределяет "rscript_fini sh .flag" каждый раз, когда l oop в мой rscript пишет в snakemake@output [[1]].

1 Ответ

2 голосов
/ 06 января 2020

Глупых вопросов нет :). Надеюсь, я понял, и это на самом деле был совсем не тривиальный вопрос!

def all_input(wildcards):
    checkpoints.rscript.get()  # make sure that checkpoint rscript is executed
    filenames, = glob_wildcards("somedir/{filenames}.png")  # find all the output_files of rscript
    return expand("somedir_cp/{fn}", fn=filenames)


rule all:
    input:
        all_input


rule add_to_report:
    input:
        "somedir/{filename}.png"
    output:
        report("somedir_cp/{filename}.png")
    shell:
        "cp {input} {output}"


checkpoint rscript:
    input:
        "foo.input"
    output:
        touch("rscript_finish.flag")
    script:
        "../scripts/foo.R"

Я на самом деле не тестировал код, поэтому не уверен, работает ли он сразу, но я думаю, что логика c правильно.

Чтобы решить эту проблему, нужно использовать дополнительное правило, которое я назвал add_to_report. Все, что делает это правило, - это сделать копию существующего вывода rscript и добавить ее в отчет. Способ rule all работает так: сначала он вызывает выполнение checkpoint rscript. Как только это выполнено, это находит все файлы, которые это произвело Затем он говорит, что rule all требует в качестве входных данных копию каждого сгенерированного файла rscript, который будет создан rule add_to_report, и, таким образом, файлы будут добавлены в отчет.

...