合并到Snakemake中不同规则的输出

时间:2020-08-13 18:11:12

标签: snakemake

我想使用snakemake首先合并某些文件,然后再基于该合并处理其他文件。 (较少的摘要:我想将两组不同的IGG bam控制文件组合在一起,而不是使用它们对其他文件执行峰值调用。

在一个最小的示例中,文件夹结构如下所示。

├── data
│   ├── toBeMerged
│   │   ├── singleA
│   │   ├── singleB
│   │   ├── singleC
│   │   └── singleD
│   └── toBeProcessed
│       ├── NotProcess1
│       ├── NotProcess2
│       ├── NotProcess3
│       ├── NotProcess4
│       └── NotProcess5
├── merge.cfg
├── output
│   ├── mergeAB_merge
│   ├── mergeCD_merge
│   ├── NotProcess1_processed
│   ├── NotProcess2_processed
│   ├── NotProcess3_processed
│   ├── NotProcess4_processed
│   └── NotProcess5_processed
├── process.cfg
└── Snakefile

合并的文件和要处理的文件在两个配置文件中定义。 merge.cfg

singlePath  controlName
data/toBeMerged/singleA output/controlAB
data/toBeMerged/singleB output/controlAB
data/toBeMerged/singleC output/controlCD
data/toBeMerged/singleD output/controlCD

和process.cfg

controlName inName
output/controlAB    data/toBeProcessed/NotProcess1
output/controlAB    data/toBeProcessed/NotProcess2
output/controlCD    data/toBeProcessed/NotProcess3
output/controlCD    data/toBeProcessed/NotProcess4
output/controlAB    data/toBeProcessed/NotProcess5

我目前被这样的蛇文件困住了,它本身不起作用,并给我一个错误,即两个规则都不明确。而且我怀疑,即使我可以使用它,因为流程规则,这不是“正确”的方法,应该以{mergeName}作为输入来构建其dag。但这是行不通的,因为那样一来我就需要两个通配符。

import pandas as pd
cfgMerge = pd.read_table("merge.cfg").set_index("controlName", drop=False)
cfgProc= pd.read_table("process.cfg").set_index("inName", drop=False)


rule all:
    input:
        expand('{mergeName}', mergeName= cfgMerge.controlName),
        expand('{rawName}_processed', rawName= cfgProc.inName)

rule merge:
    input:
        lambda wc: cfgMerge[cfgMerge.controlName == wc.mergeName].singlePath
    output:
        "{mergeName}"
    shell:
        "cat {input} > {output}"

rule process:
    input:
        inMerge=lambda wc: cfgProc[cfgProc.inName == wc.rawName].controlName.iloc[0],
        Name=lambda wc: cfgProc[cfgProc.inName == wc.rawName].inName.iloc[0]
    output:
        '{rawName}_processed'
    shell:
    "cat {input.inMerge} {input.Name} > {output}"

我想关键的问题是,当规则的输出不依赖于同一通配符或包含其他通配符时,如何将其输出用作另一条规则的输入。

1 个答案:

答案 0 :(得分:0)

供将来参考: 问题似乎不在于“当规则的输出不依赖于同一通配符或包括其他通配符时,将规则的输出用作另一条规则的输入”。 似乎所有规则的输入和其他两个规则的输出都不明确。简单的解决方案是将每个输出放在不同的目录中,并且可以正常工作(见下文)。

import pandas as pd
cfgMerge = pd.read_table("merge.cfg").set_index("controlName", drop=False)
cfgProc= pd.read_table("process.cfg").set_index("inName", drop=False)

#ruleorder: merge > process

rule all:
    input:
        expand('output/bam/{rawName}_processed', rawName= cfgProc.inName),
        expand('output/control/{controlNameSnake}', controlNameSnake= cfgMerge.controlName.unique())

rule merge:
    input:
        lambda wc: cfgMerge[cfgMerge.controlName == wc.controlNameSnake].singlePath.unique()
    output:
        'output/control/{controlNameSnake}'
    shell:
        'echo {input} > {output}'


rule process:
    input:
        in1="data/toBeProcessed/{rawName}",
        in2=lambda wc: "output/control/"+"".join(cfgProc[cfgProc.inName == wc.rawName].controlName.unique())
    output:
        'output/bam/{rawName}_processed'
    shell:
        'echo {input} > {output}'