繁体   English   中英

如何收集与输入功能匹配通配符的Snakemake输入文件?

[英]How to collect Snakemake input files that match wildcard with the input function?

我有一组用BWA-MEM生成的BAM文件,并用GATK IndelRealigner等进行了进一步处理。我正在以较小的块预处理BAM文件,以加快处理速度。 但是,在变型调用之前,我必须将这些单独的文件合并到一个BAM文件中,这一直是我的Snakemake管道的主要问题。

我的输入文件遵循这种命名约定

# Sample 1 BAM files
OVCA-1-FRESH-1_S16_L001_realigned.bam
OVCA-1-FRESH-1_S16_L002_realigned.bam
OVCA-1-FRESH-1_S16_L003_realigned.bam
OVCA-1-FRESH-1_S16_L004_realigned.bam

# Sample 2 BAM files
OVCA-2-FRESH-1_S16_L001_realigned.bam
OVCA-2-FRESH-1_S16_L002_realigned.bam
OVCA-2-FRESH-1_S16_L003_realigned.bam
OVCA-2-FRESH-1_S16_L004_realigned.bam

有问题的管道如下所示:

# Map start input files
RUN_ID, LINE = glob_wildcards('{run_id}_L{line}_realigned.bam')

rule all:
   input:
      expand('{run_id}_realigned.bam', run_id=RUN_ID)

# Map input files for merging. This function should collect all
# BAM files that match the {run_id} wildcard.
def samtools_merge_inputs(wildcards):
   files = expand('{run_id}_L{line}_realigned.bam', run_id=RUN_ID, line=LINES)
   return files

# Perform BAM merging.
rule samtools_merge:
   input:
      samtools_merge_inputs
   output:
      '{run_id}_realigned.bam
   shell:
      'samtools merge -h {input} {output}'

我尝试构建一个输入功能,该功能收集与当前处理的通配符匹配的所有可用输入文件。 当我对管道执行一次Dryrun时,我可以看到samtools_merge_inputs函数无法正常工作,因为它会收集所有可用的BAM文件并重复多次:

rule samtools_merge:
   input:
      OVCA-1-FRESH-1_S16_L001_realigned.bam,
      OVCA-1-FRESH-1_S16_L002_realigned.bam,
      OVCA-1-FRESH-1_S16_L003_realigned.bam,
      OVCA-1-FRESH-1_S16_L004_realigned.bam,
      OVCA-1-FRESH-1_S16_L001_realigned.bam,
      OVCA-1-FRESH-1_S16_L002_realigned.bam,
      OVCA-1-FRESH-1_S16_L003_realigned.bam,
      OVCA-1-FRESH-1_S16_L004_realigned.bam,
      OVCA-1-FRESH-1_S16_L001_realigned.bam,
      OVCA-1-FRESH-1_S16_L002_realigned.bam,
      OVCA-1-FRESH-1_S16_L003_realigned.bam,
      OVCA-1-FRESH-1_S16_L004_realigned.bam,
      OVCA-1-FRESH-1_S16_L001_realigned.bam,
      OVCA-1-FRESH-1_S16_L002_realigned.bam,
      OVCA-1-FRESH-1_S16_L003_realigned.bam,
      OVCA-1-FRESH-1_S16_L004_realigned.bam,
      OVCA-2-FRESH-1_S4_L001_realigned.bam,
      OVCA-2-FRESH-1_S4_L002_realigned.bam,
      OVCA-2-FRESH-1_S4_L003_realigned.bam,
      OVCA-2-FRESH-1_S4_L004_realigned.bam,
      OVCA-2-FRESH-1_S4_L001_realigned.bam,
      OVCA-2-FRESH-1_S4_L002_realigned.bam,
      OVCA-2-FRESH-1_S4_L003_realigned.bam,
      OVCA-2-FRESH-1_S4_L004_realigned.bam,
      OVCA-2-FRESH-1_S4_L001_realigned.bam,
      OVCA-2-FRESH-1_S4_L002_realigned.bam,
      OVCA-2-FRESH-1_S4_L003_realigned.bam,
      OVCA-2-FRESH-1_S4_L004_realigned.bam,
      OVCA-2-FRESH-1_S4_L001_realigned.bam,
      OVCA-2-FRESH-1_S4_L002_realigned.bam,
      OVCA-2-FRESH-1_S4_L003_realigned.bam,
      OVCA-2-FRESH-1_S4_L004_realigned.bam
   output:
      OVCA-1-FRESH-1_S16_realigned.bam
   jobid:
      18
   wildcards:
      run_id=OVCA-1-FRESH-1_S16

它看起来应该像这样:

rule samtools_merge:
   input:
      OVCA-1-FRESH-1_S16_L001_realigned.bam,
      OVCA-1-FRESH-1_S16_L002_realigned.bam,
      OVCA-1-FRESH-1_S16_L003_realigned.bam,
      OVCA-1-FRESH-1_S16_L004_realigned.bam
   output:
      OVCA-1-FRESH-1_S16_realigned.bam
   jobid:
      18
   wildcards:
      run_id=OVCA-1-FRESH-1_S16

我应该如何编辑samtools_merge_inputs函数以收集所需的输入文件? 我确实意识到我可以简单地忘记输入函数,而只需使用通配符在samtools_merge中键入四个输入文件,但是我真的很想学习如何在这种情况下使用输入函数,因为我在其他管道中也遇到了类似的问题也一样 我试图从其他帖子中寻求帮助,但到目前为止,我还没有找到适合我目的的答案。

谢谢您的帮助!

您的功能在此处不使用通配符。 应该是这样的:

def samtools_merge_inputs(wildcards):
    files = expand(wildcards.run_id+'_L{line}_realigned.bam', line=LINES)
    return files

当然,如果您在所有泳道上都有所有样本。 当您调用函数时,所有通配符都将作为对象传递给函数的wildcards参数。

您也可以:

files = expand('{run_id}_L{line}_realigned.bam', run_id=wildcards.run_id, line=LINES)  

您有很多东西无法在蛇文件中使用。
首先,您在samtools合并规则中缺少“”:

rule samtools_merge:
    input:
        samtools_merge_inputs
    output:
        '{run_id}_realigned.bam'<-----
    shell:
        'samtools merge -h {input} {output}'

并注意变量名(LINE vs LINES)

其次,函数glob_wildcards()将返回找到的所有值的列表,这意味着您的两个变量将如下所示:

RUN_ID, LINES = glob_wildcards('{run_id}_L{line}_realigned.bam')

print(RUN_ID)
['OVCA-2-FRESH-1_S16', 'OVCA-2-FRESH-1_S16', 'OVCA-1-FRESH-1_S16', 'OVCA-1-FRESH-1_S16', 'OVCA-1-FRESH-1_S16', 'OVCA-1-FRESH-1_S16', 'OVCA-2-FRESH-1_S16', 'OVCA-2-FRESH-1_S16']

print(LINES)
['002', '001', '001', '002', '004', '003', '003', '004']

我确定这不是您想要的。 解决方案是采用正确的结构来描述您的样品。 例如(同样,如果所有样本都在所有泳道上):

RUN_ID = ["OVCA-1-FRESH-1_S16","OVCA-2-FRESH-1_S16"]
LINES = ["1","2","3","4"]

最后一件事:通配符不能区分您的输入和输出,这意味着您将最终遇到错误Cyclic dependency on rule samtools_mergeRecursionError: maximum recursion depth exceeded in comparison Cyclic dependency on rule samtools_merge RecursionError: maximum recursion depth exceeded in comparison 我建议您为输出选择其他名称。 全部放在一起:

# Map start input files
RUN_ID = ["OVCA-1-FRESH-1_S16","OVCA-2-FRESH-1_S16"]
LINES = ["001","002","003","004"]

rule all:
   input:
      expand('{run_id}_realignedFinal.bam', run_id=RUN_ID)

# Map input files for merging. This function should collect all
# BAM files that match the {run_id} wildcard.
def samtools_merge_inputs(wildcards):
   files = expand('{run_id}_L{line}_realigned.bam', run_id=wildcards.run_id, line=LINES)
   return files

# Perform BAM merging.
rule samtools_merge:
   input:
      samtools_merge_inputs
   output:
      '{run_id}_realignedFinal.bam'
   shell:
      'samtools merge -h {input} {output}'

尚未检查您的shell命令,但我的文档说:
Usage: samtools merge [-nurlf] [-h inh.sam] [-b <bamlist.fofn>] <out.bam> <in1.bam> [<in2.bam> ... <inN.bam>]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM