Комбинация входных данных в сценарии оболочки snakemake

У меня есть скрипт ниже bash, который я хотел бы преобразовать в snakefile:

mmseqs rbh flye_db megahit_db flye_megahit_rbh --min-seq-id 0.9 mmseq2_tmp --threads 12
mmseqs rbh flye_db metaspades_db flye_metaspades_rbh --min-seq-id 0.9 mmseq2_tmp --threads 12
mmseqs rbh megahit_db metaspades_db megahit_metaspades_rbh --min-seq-id 0.9 mmseq2_tmp --threads 12

Мне удалось придумать следующее, но мне было интересно, есть ли способ использовать регулярные выражения или расширения для дальнейшего улучшения кода:

rule mmseq2_compare:
    input:
        mm1=expand(os.path.join(RESULTS_DIR, "annotation/mmseq2/{assembler}_db"), assembler="flye"),
        mm2=expand(os.path.join(RESULTS_DIR, "annotation/mmseq2/{assembler}_db"), assembler="megahit"),
        mm3=expand(os.path.join(RESULTS_DIR, "annotation/mmseq2/{assembler}_db"), assembler="metaspades_hybrid")
    output: 
        mo1=os.path.join(RESULTS_DIR, "annotation/mmseq2/flye_megahit_rbh"),
        mo2=os.path.join(RESULTS_DIR, "annotation/mmseq2/flye_metaspades_hybrid_rbh"),
        mo3=os.path.join(RESULTS_DIR, "annotation/mmseq2/megahit_metaspades_hybrid_rbh")
    log: os.path.join(RESULTS_DIR, "annotation/mmseq2/compare.mmseq2.log")
    conda: "cd-hit.yml"
    shell:
        """
        (date &&
        mmseqs rbh {input.mm1} {input.mm2} {output.mo1} --min-seq-id 0.9 mmseq2_tmp --threads 12 &&
        mmseqs rbh {input.mm1} {input.mm3} {output.mo2} --min-seq-id 0.9 mmseq2_tmp --threads 12 &&
        mmseqs rbh {input.mm2} {input.mm3} {output.mo3} --min-seq-id 0.9 mmseq2_tmp --threads 12 &&
        date) &> >(tee {log})
        """

С 3 ассемблерами (flye, megahit и metaspades_hybrid) есть ли способ удалить избыточность, особенно в «оболочке»?

Спасибо!

Пробный выход

Building DAG of jobs...
Job counts:
        count   jobs
        1       all
        1       mmseq_compare
        2

[Thu Mar 26 12:25:14 2020]
rule mmseq_compare:
    input: results/annotation/mmseq2/flye_db, results/annotation/mmseq2/megahit_db
    output: results/annotation/mmseq2/flye_megahit_rbh
    jobid: 1
    wildcards: assembler1=flye, assembler2=megahit

mmseqs rbh results/annotation/mmseq2/flye_db results/annotation/mmseq2/megahit_db results/annotation/mmseq2/flye_megahit_rbh --min-seq-id 0.9 mmseq2_tmp --threads 12

[Thu Mar 26 12:25:14 2020]
localrule all:
    input: results/annotation/mmseq2/flye_megahit_rbh, results/annotation/mmseq2/flye_metaspades_hybrid_rbh, results/annotation/mmseq2/megahit_metaspades_hybrid_rbh
    jobid: 0

Job counts:
        count   jobs
        1       all
        1       mmseq_compare
        2
This was a dry-run (flag -n). The order of jobs does not reflect the order of execution.```

Всего 1 ответ


Во-первых, вам не нужно expand свой вклад. Это необходимо, если вы хотите создать список имен файлов с одинаковым шаблоном.

Далее, если вы уже используете косую черту Unix-типа в своих путях, вы можете добавить RESULTS_DIR в f-строки для удобства чтения (но не забудьте удвоить скобки для подстановочных знаков).

Наконец, нет необходимости в разделении конвейера скриптов с &&: для этого и предназначен Snakemake.

Моя версия переработанного скрипта:

rule all:
    input:
        expand(f"{RESULTS_DIR}/annotation/mmseq2/{{assembler1}}__{{assembler2}}_rbh", zip,
               assembler1=["flye", "flye", "megahit"],
               assembler2=["megahit", "megahit_metaspades_hybrid", "megahit_metaspades_hybrid"])

rule mmseq_compare:
    input:
        f"{RESULTS_DIR}/annotation/mmseq2/{{assembler1}}_db",
        f"{RESULTS_DIR}/annotation/mmseq2/{{assembler2}}_db"
    output: 
        f"{RESULTS_DIR}/annotation/mmseq2/{{assembler1}}__{{assembler2}}_rbh"
    conda:
        "cd-hit.yml"
    shell:
        "mmseqs rbh {input[0]} {input[1]} {output} --min-seq-id 0.9 mmseq2_tmp --threads 12"

Я исключил date и ведение журнала. Мое решение имеет ограничение на то, что порядок выполнения сравнений не определен: в этом случае вам необходимо пересмотреть стратегию ведения журнала.


Есть идеи?

10000