Комбинируйте командные строки оболочки в snakemake

Я хотел бы объединить две командные строки в одну, чтобы избежать промежуточных файлов.

workdir: "/path/to/workdir/"

rule all:
    input: 
        "my.filtered.vcf.gz"

rule bedtools:
    input:
        invcf="/path/to/my.vcf.gz",
        bedgz="/path/to/my.bed.gz"
    output:
        outvcf="my.filtered.vcf.gz"
    shell:
        "/Tools/bedtools2/bin/bedtools intersect -a {input.invcf} -b {input.bedgz} -header -wa |"
        "/Tools/bcftools/bcftools annotate -c CHROM,FROM,TO,GENE -h <(echo '##INFO=<ID=GENE,Number=1,Type=String,Description="Gene name">') > {output.outvcf}"

Я получаю неверную синтаксическую ошибку. Я был бы признателен, если бы вы могли объяснить, как объединить несколько линий оболочки в snakemake.


person user3224522    schedule 19.02.2020    source источник


Ответы (2)


Вы, вероятно, получите неверный синтаксис из-за ", который вы используете здесь в своей оболочке: Description="Gene name">. Это закрывает вашу оболочку. Вы можете избежать этих кавычек или использовать синтаксис """:

rule bedtools:
    input:
        invcf="/path/to/my.vcf.gz",
        bedgz="/path/to/my.bed.gz"
    output:
        outvcf="my.filtered.vcf.gz"
    shell:
        "/Tools/bedtools2/bin/bedtools intersect -a {input.invcf} -b {input.bedgz} -header -wa |"
        "/Tools/bcftools/bcftools annotate -c CHROM,FROM,TO,GENE -h <(echo '##INFO=<ID=GENE,Number=1,Type=String,Description=\"Gene name\">') > {output.outvcf}"

or

rule bedtools:
    input:
        invcf="/path/to/my.vcf.gz",
        bedgz="/path/to/my.bed.gz"
    output:
        outvcf="my.filtered.vcf.gz"
    shell:
        """
        /Tools/bedtools2/bin/bedtools intersect -a {input.invcf} -b {input.bedgz} -header -wa | /Tools/bcftools/bcftools annotate -c CHROM,FROM,TO,GENE -h <(echo '##INFO=<ID=GENE,Number=1,Type=String,Description="Gene name">') > {output.outvcf}
        """

Обратите внимание, что вы можете использовать многострочную строку с """. Пример без труб:

shell:
    """
    bedtools .... {input} > tempFile 
    bcftools .... tempFile > tempFile2
    whatever .... tempFile2 > {output}
    """
person Eric C.    schedule 19.02.2020
comment
спасибо, Эрик, сейчас это работает, но дает мне промежуточный результат, а не последний .... Думаю, чего-то не хватает: / - person user3224522; 19.02.2020
comment
Хорошо, я добавил -a {input.bedgz} в строку оболочки: / Tools / bedtools2 / bin / bedtools correct -a {input.invcf} -b {input.bedgz} -header -wa | / Tools / bcftools / bcftools annotate -a {input.bedgz} -c CHROM, FROM, TO, GENE -h ‹(echo '## INFO =‹ ID = GENE, Number = 1, Type = String, Description = Имя гена ›')› {Output.outvcf} - person user3224522; 19.02.2020

Проблема заключается в том, чтобы избежать двойных кавычек, но нужно добавить немного больше о форматировании и каналах.

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

rule bedtools:
    input:
        invcf="/path/to/my.vcf.gz",
        bedgz="/path/to/my.bed.gz"
    output:
        outvcf="my.filtered.vcf.gz"
    shell:
        "/Tools/bedtools2/bin/bedtools "
           "intersect "
           "-a {input.invcf} "
           "-b {input.bedgz} "
           "-header -wa "
        "| /Tools/bcftools/bcftools "
           "annotate "
           "-c CHROM,FROM,TO,GENE "
           "-h <(echo '##INFO=<ID=GENE,Number=1,Type=String,Description=\"Gene name\">') "
        "> {output.outvcf}"

Я нахожу, что это более ясно видеть каждый аргумент и легче изменить, перемещая линии. Но обратите внимание, что конечный пробел каждой строки является обязательным, и вы должны использовать явную новую строку, \n, если вам нужна отдельная команда. Когда приглашение напечатано, вывод будет красиво оформлен. При использовании синтаксиса """ вы должны экранировать каждую новую строку с помощью \ в конце, а пробелы в начале строки сохраняются при печати.

Если у вас много работы с трубкой, попробуйте канал флаг. Вы пишете свой первый шаг как правило, а snakemake создает именованный канал между правилами, отправляя их как группу:

rule bedtools_intersect:
    input:
        invcf="/path/to/my.vcf.gz",
        bedgz="/path/to/my.bed.gz"
    output:
        outvcf=pipe("my.intersected.vcf.gz")
    shell:
        "/Tools/bedtools2/bin/bedtools "
           "intersect "
           "-a {input.invcf} "
           "-b {input.bedgz} "
           "-header -wa "
        "> {output.outvcf}"

rule bcftools_annotate:
    input:
        invcf="my.intersected.vcf.gz"
    output:
        outvcf="my.filtered.vcf.gz"
    shell:
        "/Tools/bcftools/bcftools "
           "annotate "
           "-c CHROM,FROM,TO,GENE "
           "-h <(echo '##INFO=<ID=GENE,Number=1,Type=String,Description=\"Gene name\">') "
           "{input.invcf} "
        "> {output.outvcf}"

Преимущество состоит в том, что вы можете повторно использовать каждое правило по всему конвейеру для пересечения или аннотирования, избегая при этом временных файлов.

person Troy Comi    schedule 19.02.2020