GearsSingle.scala 7.08 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
/**
 * Biopet is built on top of GATK Queue for building bioinformatic
 * pipelines. It is mainly intended to support LUMC SHARK cluster which is running
 * SGE. But other types of HPC that are supported by GATK Queue (such as PBS)
 * should also be able to execute Biopet tools and pipelines.
 *
 * Copyright 2014 Sequencing Analysis Support Core - Leiden University Medical Center
 *
 * Contact us at: sasc@lumc.nl
 *
11
 * A dual licensing mode is applied. The source code within this project is freely available for non-commercial use under an AGPL
12
13
14
15
16
 * license; For commercial users or users who do not want to follow the AGPL
 * license, please contact us to obtain a separate license.
 */
package nl.lumc.sasc.biopet.pipelines.gears

Peter van 't Hof's avatar
Peter van 't Hof committed
17
import nl.lumc.sasc.biopet.core.summary.SummaryQScript
Peter van 't Hof's avatar
Peter van 't Hof committed
18
import nl.lumc.sasc.biopet.core.BiopetQScript.InputFile
Peter van 't Hof's avatar
Peter van 't Hof committed
19
import nl.lumc.sasc.biopet.core.{ PipelineCommand, SampleLibraryTag }
Peter van 't Hof's avatar
Peter van 't Hof committed
20
import nl.lumc.sasc.biopet.pipelines.flexiprep.Flexiprep
Peter van 't Hof's avatar
Peter van 't Hof committed
21
import nl.lumc.sasc.biopet.utils.Logging
Peter van 't Hof's avatar
Peter van 't Hof committed
22
import nl.lumc.sasc.biopet.utils.config.Configurable
23
24
import org.broadinstitute.gatk.queue.QScript

25
/**
Wai Yi Leung's avatar
Wai Yi Leung committed
26
 * Created by wyleung
27
 */
28
class GearsSingle(val root: Configurable) extends QScript with SummaryQScript with SampleLibraryTag {
29
  def this() = this(null)
30

Wai Yi Leung's avatar
Wai Yi Leung committed
31
32
  @Input(doc = "R1 reads in FastQ format", shortName = "R1", required = false)
  var fastqR1: Option[File] = None
33

Wai Yi Leung's avatar
Wai Yi Leung committed
34
35
  @Input(doc = "R2 reads in FastQ format", shortName = "R2", required = false)
  var fastqR2: Option[File] = None
36

Wai Yi Leung's avatar
Wai Yi Leung committed
37
  @Input(doc = "All unmapped reads will be extracted from this bam for analysis", shortName = "bam", required = false)
Peter van 't Hof's avatar
Peter van 't Hof committed
38
  var bamFile: Option[File] = None
39

Peter van 't Hof's avatar
Peter van 't Hof committed
40
41
  @Argument(required = false)
  var outputName: String = _
42

Peter van 't Hof's avatar
Peter van 't Hof committed
43
  lazy val krakenScript = if (config("gears_use_kraken", default = true)) Some(new GearsKraken(this)) else None
Peter van 't Hof's avatar
Peter van 't Hof committed
44
  lazy val centrifugeScript = if (config("gears_use_centrifuge", default = false)) Some(new GearsCentrifuge(this)) else None
Peter van 't Hof's avatar
Peter van 't Hof committed
45
46
  lazy val qiimeRatx = if (config("gears_use_qiime_rtax", default = false)) Some(new GearsQiimeRtax(this)) else None
  lazy val qiimeClosed = if (config("gears_use_qiime_closed", default = false)) Some(new GearsQiimeClosed(this)) else None
Peter van 't Hof's avatar
Peter van 't Hof committed
47
  lazy val qiimeOpen = if (config("gears_use_qiime_open", default = false)) Some(new GearsQiimeOpen(this)) else None
Peter van 't Hof's avatar
Peter van 't Hof committed
48
  lazy val seqCount = if (config("gears_use_seq_count", default = false)) Some(new GearsSeqCount(this)) else None
Peter van 't Hof's avatar
Peter van 't Hof committed
49

Peter van 't Hof's avatar
Peter van 't Hof committed
50
51
  /** Executed before running the script */
  def init(): Unit = {
Peter van 't Hof's avatar
Peter van 't Hof committed
52
53
    if (!fastqR1.isDefined && !bamFile.isDefined) Logging.addError("Please specify fastq-file(s) or bam file")
    if (fastqR1.isDefined == bamFile.isDefined) Logging.addError("Provide either a bam file or a R1/R2 file")
Peter van 't Hof's avatar
Peter van 't Hof committed
54
    if (sampleId == null || sampleId == None) Logging.addError("Missing sample ID on GearsSingle module")
Peter van 't Hof's avatar
Peter van 't Hof committed
55
56

    if (outputName == null) {
Wai Yi Leung's avatar
Wai Yi Leung committed
57
      if (fastqR1.isDefined) outputName = fastqR1.map(_.getName
Peter van 't Hof's avatar
Peter van 't Hof committed
58
59
60
61
62
        .stripSuffix(".gz")
        .stripSuffix(".fastq")
        .stripSuffix(".fq"))
        .getOrElse("noName")
      else outputName = bamFile.map(_.getName.stripSuffix(".bam")).getOrElse("noName")
63
    }
Peter van 't Hof's avatar
Peter van 't Hof committed
64
65
66
67

    if (fastqR1.isDefined) {
      fastqR1.foreach(inputFiles :+= InputFile(_))
      fastqR2.foreach(inputFiles :+= InputFile(_))
Peter van 't Hof's avatar
Peter van 't Hof committed
68
    } else bamFile.foreach(inputFiles :+= InputFile(_))
Peter van 't Hof's avatar
Peter van 't Hof committed
69
  }
70

Wai Yi Leung's avatar
Wai Yi Leung committed
71
  override def reportClass = {
72
    val gears = new GearsSingleReport(this)
Wai Yi Leung's avatar
Wai Yi Leung committed
73
74
    gears.outputDir = new File(outputDir, "report")
    gears.summaryFile = summaryFile
75
76
    sampleId.foreach(gears.args += "sampleId" -> _)
    libId.foreach(gears.args += "libId" -> _)
Wai Yi Leung's avatar
Wai Yi Leung committed
77
78
    Some(gears)
  }
79

Peter van 't Hof's avatar
Peter van 't Hof committed
80
81
  protected var skipFlexiprep: Boolean = config("skip_flexiprep", default = false)

82
  protected def executeFlexiprep(r1: File, r2: Option[File]): (File, Option[File]) = {
Peter van 't Hof's avatar
Peter van 't Hof committed
83
    if (!skipFlexiprep) {
84
      val flexiprep = new Flexiprep(this)
Sander van der Zeeuw's avatar
Sander van der Zeeuw committed
85
      flexiprep.inputR1 = r1
86
      flexiprep.inputR2 = r2
Peter van 't Hof's avatar
Peter van 't Hof committed
87
88
      flexiprep.sampleId = if (sampleId.isEmpty) Some("noSampleName") else sampleId
      flexiprep.libId = if (libId.isEmpty) Some("noLibName") else libId
89
90
91
92
93
94
      flexiprep.outputDir = new File(outputDir, "flexiprep")
      add(flexiprep)
      (flexiprep.fastqR1Qc, flexiprep.fastqR2Qc)
    } else (r1, r2)
  }

Peter van 't Hof's avatar
Peter van 't Hof committed
95
96
  /** Method to add jobs */
  def biopetScript(): Unit = {
Peter van 't Hof's avatar
Peter van 't Hof committed
97
    val (r1, r2): (File, Option[File]) = (fastqR1, fastqR2, bamFile) match {
98
      case (Some(r1), _, _) => executeFlexiprep(r1, fastqR2)
Peter van 't Hof's avatar
Peter van 't Hof committed
99
100
      case (_, _, Some(bam)) =>
        val extract = new ExtractUnmappedReads(this)
Peter van 't Hof's avatar
Peter van 't Hof committed
101
        extract.outputDir = outputDir
Peter van 't Hof's avatar
Peter van 't Hof committed
102
        extract.bamFile = bam
Peter van 't Hof's avatar
Peter van 't Hof committed
103
        extract.outputName = outputName
Peter van 't Hof's avatar
Peter van 't Hof committed
104
        add(extract)
Peter van 't Hof's avatar
Peter van 't Hof committed
105
        executeFlexiprep(extract.fastqUnmappedR1, extract.fastqUnmappedR2)
Peter van 't Hof's avatar
Peter van 't Hof committed
106
      case _ => throw new IllegalArgumentException("Missing input files")
Peter van 't Hof's avatar
Peter van 't Hof committed
107
108
    }

Peter van 't Hof's avatar
Peter van 't Hof committed
109
110
111
    lazy val combinedFastq = {
      r2 match {
        case Some(r2) =>
112
113
114
115
116
117
          val combineReads = new CombineReads(this)
          combineReads.outputDir = new File(outputDir, "combine_reads")
          combineReads.fastqR1 = r1
          combineReads.fastqR2 = r2
          add(combineReads)
          combineReads.combinedFastq
Peter van 't Hof's avatar
Peter van 't Hof committed
118
119
120
121
        case _ => r1
      }
    }

Peter van 't Hof's avatar
Peter van 't Hof committed
122
    krakenScript foreach { kraken =>
Peter van 't Hof's avatar
Peter van 't Hof committed
123
      kraken.outputDir = new File(outputDir, "kraken")
124
125
      kraken.fastqR1 = r1
      kraken.fastqR2 = r2
Peter van 't Hof's avatar
Peter van 't Hof committed
126
      kraken.outputName = outputName
Peter van 't Hof's avatar
Peter van 't Hof committed
127
      add(kraken)
Peter van 't Hof's avatar
Peter van 't Hof committed
128
129
    }

Peter van 't Hof's avatar
Peter van 't Hof committed
130
131
132
133
134
135
136
137
    centrifugeScript foreach { centrifuge =>
      centrifuge.outputDir = new File(outputDir, "centrifuge")
      centrifuge.fastqR1 = r1
      centrifuge.fastqR2 = r2
      centrifuge.outputName = outputName
      add(centrifuge)
    }

Peter van 't Hof's avatar
Peter van 't Hof committed
138
    qiimeRatx foreach { qiimeRatx =>
Peter van 't Hof's avatar
Peter van 't Hof committed
139
      qiimeRatx.outputDir = new File(outputDir, "qiime_rtax")
140
141
      qiimeRatx.fastqR1 = r1
      qiimeRatx.fastqR2 = r2
Peter van 't Hof's avatar
Peter van 't Hof committed
142
      add(qiimeRatx)
Peter van 't Hof's avatar
Peter van 't Hof committed
143
    }
144

Peter van 't Hof's avatar
Peter van 't Hof committed
145
    qiimeClosed foreach { qiimeClosed =>
Peter van 't Hof's avatar
Peter van 't Hof committed
146
      qiimeClosed.outputDir = new File(outputDir, "qiime_closed")
Peter van 't Hof's avatar
Peter van 't Hof committed
147
      qiimeClosed.fastqInput = combinedFastq
Peter van 't Hof's avatar
Peter van 't Hof committed
148
      add(qiimeClosed)
149
150
    }

Peter van 't Hof's avatar
Peter van 't Hof committed
151
152
153
154
155
156
    qiimeOpen foreach { qiimeOpen =>
      qiimeOpen.outputDir = new File(outputDir, "qiime_open")
      qiimeOpen.fastqInput = combinedFastq
      add(qiimeOpen)
    }

Peter van 't Hof's avatar
Peter van 't Hof committed
157
158
159
160
161
162
    seqCount.foreach { seqCount =>
      seqCount.fastqInput = combinedFastq
      seqCount.outputDir = new File(outputDir, "seq_count")
      add(seqCount)
    }

Wai Yi Leung's avatar
Wai Yi Leung committed
163
    addSummaryJobs()
164
  }
Peter van 't Hof's avatar
Peter van 't Hof committed
165
166

  /** Location of summary file */
Peter van 't Hof's avatar
Peter van 't Hof committed
167
  def summaryFile = new File(outputDir, sampleId.getOrElse("sampleName_unknown") + ".gears.summary.json")
Peter van 't Hof's avatar
Peter van 't Hof committed
168

169
  /** Pipeline settings shown in the summary file */
Peter van 't Hof's avatar
Peter van 't Hof committed
170
171
172
173
  def summarySettings: Map[String, Any] = Map(
    "skip_flexiprep" -> skipFlexiprep,
    "gears_use_kraken" -> krakenScript.isDefined,
    "gear_use_qiime_rtax" -> qiimeRatx.isDefined,
Peter van 't Hof's avatar
Peter van 't Hof committed
174
175
    "gear_use_qiime_closed" -> qiimeClosed.isDefined,
    "gear_use_qiime_open" -> qiimeOpen.isDefined
Peter van 't Hof's avatar
Peter van 't Hof committed
176
  )
Peter van 't Hof's avatar
Peter van 't Hof committed
177

178
  /** Statistics shown in the summary file */
Wai Yi Leung's avatar
Wai Yi Leung committed
179
180
  def summaryFiles: Map[String, File] = Map.empty ++
    (if (bamFile.isDefined) Map("input_bam" -> bamFile.get) else Map()) ++
Wai Yi Leung's avatar
Wai Yi Leung committed
181
    (if (fastqR1.isDefined) Map("input_R1" -> fastqR1.get) else Map()) ++
Peter van 't Hof's avatar
Peter van 't Hof committed
182
    (if (fastqR2.isDefined) Map("input_R2" -> fastqR2.get) else Map()) ++
Wai Yi Leung's avatar
Wai Yi Leung committed
183
    outputFiles
184
185
186
}

/** This object give a default main method to the pipelines */
187
object GearsSingle extends PipelineCommand