如何从一个样本中选择所有文件?

时间:2019-02-15 14:49:58

标签: wildcard snakemake

我在弄清楚如何使输入指令仅选择以下规则中的所有{samples}文件时遇到问题。

rule MarkDup:
    input:
        expand("Outputs/MergeBamAlignment/{samples}_{lanes}_{flowcells}.merged.bam", zip,
            samples=samples['sample'],
            lanes=samples['lane'],
            flowcells=samples['flowcell']),
    output:
        bam = "Outputs/MarkDuplicates/{samples}_markedDuplicates.bam",
        metrics = "Outputs/MarkDuplicates/{samples}_markedDuplicates.metrics",
    shell:
        "gatk --java-options -Djava.io.tempdir=`pwd`/tmp \
        MarkDuplicates \
        $(echo ' {input}' | sed 's/ / --INPUT /g') \
        -O {output.bam} \
        --VALIDATION_STRINGENCY LENIENT \
        --METRICS_FILE {output.metrics} \
        --MAX_FILE_HANDLES_FOR_READ_ENDS_MAP 200000 \
        --CREATE_INDEX true \
        --TMP_DIR Outputs/MarkDuplicates/tmp"

当前它将创建正确命名的输出文件,但是它将基于所有通配符选择与模式匹配的所有文件。所以我可能已经走了一半。我尝试将输入指令中的{samples}更改为{{samples}},例如:

expand("Outputs/MergeBamAlignment/{{samples}}_{lanes}_{flowcells}.merged.bam", zip,
            lanes=samples['lane'],
            flowcells=samples['flowcell']),`

但是这以某种方式违反了先前的规则。所以解决方案就像

input:
     "{sample}_*.bam"

但是显然这是行不通的。 是否可以收集与某个功能匹配的{sample}_*.bam的所有文件并将其用作输入?如果是这样,该函数是否仍可与shell指令中的$(echo ' {input}' etc...)一起使用?

2 个答案:

答案 0 :(得分:1)

如果我理解正确,则zip仅应应用于{lane}{flowcells}而不是{samples}。在这种情况下,使用两个expand实例就可以实现。

input:
    expand(expand("Outputs/MergeBamAlignment/{{samples}}_{lanes}_{flowcells}.merged.bam", 
        zip, lanes=samples['lane'], flowcells=samples['flowcell']), 
            samples=samples['sample'])

PS:output.tmp文件使用{sample}而不是{samples}。错字?

答案 1 :(得分:1)

如果只需要目录中的所有文件,则可以使用lambda函数

from glob import glob

rule MarkDup:
    input:
        lambda wcs: glob('Outputs/MergeBamAlignment/%s*.bam' % wcs.samples)
    output:
        bam="Outputs/MarkDuplicates/{samples}_markedDuplicates.bam",
        metrics="Outputs/MarkDuplicates/{samples}_markedDuplicates.metrics"
    shell:
        ...

请注意,这种方法无法对丢失的文件进行任何检查,因为它将始终报告所需的文件是存在的文件。如果确实需要确认上游规则已执行,则可以让前一个规则触摸一个标志,然后将其用作此规则的输入(尽管除了强制执行顺序外,实际上并没有使用该文件)