使用目录作为输出时的Snakemake SyntaxError

时间:2018-08-24 15:06:48

标签: directory output snakemake

我想运行一个命令(chipseq-greylist),该命令每次使用一个输入文件运行时都会输出三个文件。该命令将自动选择输出文件的名称。一个示例是:

chipseq-greylist --outdir out_dir A.bam

此行将产生三个输出文件:A-greystats.csv, A-greydepth.tsv and A-grey.bed。我有兴趣将所有*-grey.bed文件收集到一个目录中,以便以后使用。

由于这是我在许多文件上使用的管道的一部分,因此我正在使用Snakemake处理所有这些作业。我知道可以将目录指定为输出(https://snakemake.readthedocs.io/en/stable/snakefiles/rules.html#directories-as-outputs),这完全符合我的要求。但是,当我以目录作为输出规则时,会出现SyntaxError。

from os.path import join

# Globals ---------------------------------------------------------------------

DIR = 'bowtie2/'

# A Snakemake regular expression matching BAM files.
SAMPLES, = glob_wildcards(join(DIR, '{sample,SRR\d+}_sorted_filtered.bam'))

# Rules -----------------------------------------------------------------------

rule all:
    input:
        expand("test/{sample}_sorted_filtered.bam.bai", sample=SAMPLES)

rule samtools_index:
    input:
        "bowtie2/{sample}_sorted_filtered.bam"
    output:
        "test/{sample}_sorted_filtered.bam.bai"
    log:
        "log/test/{sample}.log"
    shell:
        "samtools index {input} &> {log} > {output}"

rule greylist_call:
    input:
        "bowtie2/{sample}_sorted_filtered.bam"
    output:
        directory("greylist")
    log:
        "log/greylist/{sample}.log"
    shell:
        "chipseq-greylist --outdir {output} {input} &> {log}"

请注意,在我的示例中,我必须添加另一步骤以包括rule all的目标文件。 这是另一个问题,我发现使用directory()时遇到了麻烦,因为我找不到为rule all.指定目标的方法

我得到的错误是:

SyntaxError: Not all output, log and benchmark files of rule greylist_call contain the same wildcards. This is crucial though, in order to avoid that two or more jobs write to the same file. File "Snakefile", line 34, in <module>

如果我将wildcards添加到rule greylist_call中的输出目录名称中,则可以消除错误消息。

from os.path import join

# Globals ---------------------------------------------------------------------

DIR = 'bowtie2/'

# A Snakemake regular expression matching the forward mate FASTQ files.
SAMPLES, = glob_wildcards(join(DIR, '{sample,SRR\d+}_sorted_filtered.bam'))

# Rules -----------------------------------------------------------------------

rule all:
    input:
        expand("test/{sample}_sorted_filtered.bam.bai", sample=SAMPLES)

rule samtools_index:
    input:
        "bowtie2/{sample}_sorted_filtered.bam"
    output:
        "test/{sample}_sorted_filtered.bam.bai"
    log:
        "log/test/{sample}.log"
    shell:
        "samtools index {input} &> {log} > {output}"

rule greylist_call:
    input:
        "bowtie2/{sample}_sorted_filtered.bam"
    output:
        directory("greylist_{sample}")
    log:
        "log/greylist/{sample}.log"
    shell:
        "chipseq-greylist --outdir {output} {input} &> {log}"

但是,我觉得这违背了将所有文件直接放在同一文件中的目的,尽管我可以潜在地解决该问题,但是我仍然无法找到一种方法来强制snakemake运行此规则,因为我无法指定一个rule all中的目标文件。

对于在蛇形制作法中使用directory的任何帮助或有关如何改进这套规则的其他建议,我将不胜感激。

谢谢 安娜

1 个答案:

答案 0 :(得分:0)

我不明白为什么将文件夹定义为输出。如果您不给出命令的真实输出文件,snakemake将无法确定您的shell命令是否按预期工作。因此,如果要在同一目录中生成所有不同的示例文件,则可以简单地借助params来完成:

rule greylist_call:
    input:
        "bowtie2/{sample}_sorted_filtered.bam"
    output:
        "output_dir/{sample}-greystats.csv",
        "output_dir/{sample}-greydepth.tsv",
        "output_dir/{sample}-grey.bed"
    params:
        outputDir = "output_dir"
    log:
        "log/greylist/{sample}.log"
    shell:
        "chipseq-greylist --outdir {params.outputDir} {input} &> {log}"

在所有规则中,您添加:

expand("output_dir/{sample}-grey.bed", sample=SAMPLES)

这将产生同一目录中的所有文件。

如果以后要使用另一条规则收集该目录中的所有床文件,则将定义如下输入:

input:
    expand("output_dir/{sample}-grey.bed",sample=SAMPLES)

要解释该错误,请执行以下操作:通配符是从规则的输出中定义的。如果您在规则全部中要求文件xxx.bed,snakemake会找到规则,该规则的输出类似于{wildcard}.bed或文件xxx.bed本身。一旦找到规则,snakemake将能够将通配符应用于输入,日志,参数等。总而言之,如果输入,日志或参数(甚至shell命令)未定义,则不能在其中使用通配符在输出中。 这就是为什么它可以与您的以directory("greylist_{sample}")作为输出的规则一起使用的原因,尽管该规则并没有按照您希望的那样工作!