将通配符添加到工作流中-最佳做法

时间:2019-10-29 14:03:31

标签: python snakemake

我有一个非常复杂的snakemake生物信息学工作流程,包含200多个规则。它基本上是从一组FASTQ文件开始的,从中可以推断出变量,如下所示:

(WC1, WC2, WC3, WC4) = glob_wildcards(FASTQPATH + "{wc1}_{wc2}_{wc3}_{wc4}.fastq.gz") 

然后将其展开以生成目标文件,例如(为简洁起见,我跳过了中间规则):

rule all:
 expand("mappings/{wc1}_{wc2}_{wc3}_{wc4}.bam", wc1=WC1, wc2=WC2, wc3=WC3, wc4=WC4),

在项目过程中,元数据会不断演变,并且需要添加通配符,例如wc5

(WC1, WC2, WC3, WC4, WC5) = glob_wildcards(FASTQPATH + "{wc1}_{wc2}_{wc3}_{wc4}_{wc5}.fastq.gz") 

这将导致手动编辑约200个工作流程规则以符合新输入。我想知道社区中是否有人想出一个更优雅,更轻松的解决方案(也许使用输入功能?),还是我们都必须忍受的Snakemake限制?

预先感谢

2 个答案:

答案 0 :(得分:1)

我有一个用于ChIP-seq数据的工作流,我的fastq文件以MARK_TISSUE_REPLICATE.fastq.gz的格式命名,例如H3K4me3_Liver_B.fastq.gz。对于我的许多规则,我不需要为标记,组织和复制使用单独的通配符。我可以这样写我的规则:

rule example:
    input: "{library}.fq.gz"
    output: "{library}.bam"

然后对于需要多个输入(可能是通过复制合并在一起或在所有组织中执行某些操作)的规则,我有一个称为“库”的函数,该函数返回具有特定条件的库列表。例如,库(mark =“ H3K4me3”)将返回该标记的所有库,或者库(tissue =“ Liver”,复制=“ A”)将返回该特定组织样本中所有标记的库。我可以使用它来编写需要组合多个库的规则,例如:

rule example2:
    input: lambda wildcards: expand("{library}.bam", library=libraries(mark=wildcards.mark))
    output: "{mark}_Heatmap_Clustering.png"

要解决一些奇怪或模棱两可的规则问题,我发现设置如下通配符约束会有所帮助:

wildcard_constraints:
    mark="[^_/]+",
    tissue="[^_/]+",
    replicate="[^_/]+",
    library="[^_/]+_[^_/]+_[^_/]+"

希望您可以将其中一些想法应用到自己的工作流程中。

答案 1 :(得分:1)

我认为@Colin在这里是最正确的选择。但是,如果您想使用通配符,例如在日志中,或者它们指定了某些参数,那么您可以尝试用一个变量替换通配符,然后将其插入规则的输入和输出中:

metadata = "{wc1}_{wc2}_{wc3}_{wc4}"
WC1, WC2, WC3, WC4 = glob_wildcards(FASTQPATH + metadata + ".fastq.gz") 

rule map:
    input:
        expand(f"unmapped/{metadata}.fq")
    input:
        expand(f"mappings/{metadata}.fq")
    shell:
        """
        echo {wildcards.wc1};
        mv {input} {output}
        """

rule all:
    expand("mappings/{wc1}_{wc2}_{wc3}_{wc4}.bam", wc1=WC1, wc2=WC2, wc3=WC3, wc4=WC4)

以这种方式更改为或多或少的通配符相对容易。

免责声明,我还没有测试过其中任何一项是否真的有效:)