如何从子目录中收集文件以在Snakemake中运行作业?

时间:2017-08-21 20:42:38

标签: snakemake

我目前正致力于这个项目,我正在努力解决这个问题。

我当前的目录结构是

 /shared/dir1/file1.bam
 /shared/dir2/file2.bam
 /shared/dir3/file3.bam

我想在结果目录中将各种.bam文件转换为fastq

  results/file1_1.fastq.gz 
  results/file1_2.fastq.gz
  results/file2_1.fastq.gz 
  results/file2_2.fastq.gz
  results/file3_1.fastq.gz 
  results/file3_2.fastq.gz  

我有以下代码:

END=["1","2"]
(dirs, files) = glob_wildcards("/shared/{dir}/{file}.bam")

rule all:
    input: expand( "/results/{sample}_{end}.fastq.gz",sample=files,  end=END)

rule bam_to_fq:
    input:  {dir}/{sample}.bam"
    output: left="/results/{sample}_1.fastq", right="/results/{sample}_2.fastq"
    shell: "/shared/packages/bam2fastq/bam2fastq --force -o /results/{sample}.fastq {input}"

这会输出以下错误:

Wildcards in input files cannot be determined from output files:
'dir'

任何帮助将不胜感激

1 个答案:

答案 0 :(得分:0)

你只是错过了" dir"在规则bam_to_fq的输入指令中。在您的代码中,您正试图让Snakemake确定" {dir}"从同一规则的输出中,因为您将其设置为通配符。由于它不存在,作为输出指令中的变量,您收到错误。

    input:  
         "{dir}/{sample}.bam"
    output: 
         left="/results/{sample}_1.fastq", 
         right="/results/{sample}_2.fastq",

经验法则:输入和输出通配符必须匹配

rule all:
    input: 
         expand("/results/{sample}_{end}.fastq.gz", sample=files, end=END)

rule bam_to_fq:
    input:  
         expand("{dir}/{{sample}}.bam", dir=dirs)
    output: 
         left="/results/{sample}_1.fastq", 
         right="/results/{sample}_2.fastq"
    shell: 
         "/shared/packages/bam2fastq/bam2fastq --force -o /results/{sample}.fastq {input}

备注

  1. 输入指令中的示例变量现在需要double {},因为这是在扩展中识别通配符的方式。
  2. dir不再是通配符,它​​被明确设置为指向由glob_wildcard调用确定并分配给变量" dirs"的目录列表。我假设你早先在你的脚本中制作,因为其中一个变量的分配已经成功,在你的规则中所有输入" sample = files"。
  3. 我喜欢并推荐易于辨别的变量名称。我不是使用变量名称" dir"和" dirs"的忠实粉丝。这使您容易出现迂腐拼写错误。考虑将其更改为" dirLIST"和" dir" ......或者其他任何东西。我只是害怕有一天会有人会错过一个'在某个地方调试它会让人感到沮丧。我个人有罪,这是一个轻微的伪君子,因为我使用" sample = samples"在我的核心Snakefile中。它给我带来了轻微的压力,因此我提出这个建议。此外,其他人也可以更轻松地阅读您的代码。
  4. 编辑1;添加到响应,因为我最初错过了dir和样本的键值匹配要求

    我建议将路径和样本名称分开放在不同的变量中。我能想到的两种方法:

    1. 继续使用glob_wildcards对所有可能的变量进行全面搜索,然后使用python函数验证哪些路径+文件组合是合法的。
    2. 删除glob_wildcards的用法。在整个规则中将目录名称作为通配符变量{dir}传播。只需将其设置为"结果"的子目录。使用pandas将文件中列出的已知键值对传递给规则all。最初我建议手动生成键值对文件,但最终,它的生成可能只是其他人的上游规则。
    3. 稍微概括一下bam_to_fq ...利用外部配置,比如....

      来自pandas import read_table

      rule all:
          input: 
               expand("/results/{{sample[1][dir]}}/{sample[1][file]}_{end}.fastq.gz", sample=read_table(config["sampleFILE"], " ").iterrows(), end=['1','2'])
      
      rule bam_to_fq:
          input:  
               "{dir}/{sample}.bam"
          output: 
               left="/results/{dir}/{sample}_1.fastq", 
               right="/results/{dir}/{sample}_2.fastq"
          shell: 
               "/shared/packages/bam2fastq/bam2fastq --force -o /results/{sample}.fastq {input}
      

      sampleFILE

      dir file
      dir1 file1
      dir2 file2
      dir3 file3