MultiSampleQScript.scala 6.25 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
 * 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
 *
 * A dual licensing mode is applied. The source code within this project that are
 * not part of GATK Queue is freely available for non-commercial use under an AGPL
 * license; For commercial users or users who do not want to follow the AGPL
 * license, please contact us to obtain a separate license.
 */
16
17
package nl.lumc.sasc.biopet.core

18
import nl.lumc.sasc.biopet.core.config.{ ConfigValue, Config, Configurable }
19
import nl.lumc.sasc.biopet.utils.ConfigUtils
20
import nl.lumc.sasc.biopet.utils.ConfigUtils._
21
22

trait MultiSampleQScript extends BiopetQScript {
Peter van 't Hof's avatar
Peter van 't Hof committed
23
  type LibraryOutput <: AbstractLibraryOutput
Peter van 't Hof's avatar
Peter van 't Hof committed
24
  type SampleOutput <: AbstractSampleOutput
Peter van 't Hof's avatar
Peter van 't Hof committed
25

Peter van 't Hof's avatar
Peter van 't Hof committed
26
  abstract class AbstractLibraryOutput
Peter van 't Hof's avatar
Peter van 't Hof committed
27
28
  abstract class AbstractSampleOutput {
    var libraries: Map[String, LibraryOutput] = Map()
Peter van 't Hof's avatar
Peter van 't Hof committed
29
    def getAllLibraries = libraries
Peter van 't Hof's avatar
Peter van 't Hof committed
30
    def getLibrary(key: String) = libraries(key)
Peter van 't Hof's avatar
Peter van 't Hof committed
31
  }
Peter van 't Hof's avatar
Peter van 't Hof committed
32

33
  if (!Config.global.map.contains("samples")) logger.warn("No Samples found in config")
Peter van 't Hof's avatar
Peter van 't Hof committed
34
35
36
37

  /**
   * Returns a map with all sample configs
   */
38
  val getSamplesConfig: Map[String, Any] = ConfigUtils.any2map(Config.global.map.getOrElse("samples", Map()))
Peter van 't Hof's avatar
Peter van 't Hof committed
39
40
41
42

  /**
   * Returns a list of all sampleIDs
   */
43
  val getSamples: Set[String] = getSamplesConfig.keySet
Peter van 't Hof's avatar
Peter van 't Hof committed
44
45
46
47
48

  /**
   * Returns the global sample directory
   * @return global sample directory
   */
Peter van 't Hof's avatar
Peter van 't Hof committed
49
  def globalSampleDir: String = outputDir + "samples/"
Peter van 't Hof's avatar
Peter van 't Hof committed
50

51
52
  var samplesOutput: Map[String, SampleOutput] = Map()

Peter van 't Hof's avatar
Peter van 't Hof committed
53
54
55
  /**
   * Runs runSingleSampleJobs method for each sample
   */
Peter van 't Hof's avatar
Peter van 't Hof committed
56
  final def runSamplesJobs() {
57
    for ((key, value) <- getSamplesConfig) {
58
      var sample = any2map(value)
59
60
      if (!sample.contains("ID")) sample += ("ID" -> key)
      if (sample("ID") == key) {
Peter van 't Hof's avatar
Peter van 't Hof committed
61
        currentSample = key
Peter van 't Hof's avatar
Peter van 't Hof committed
62
        samplesOutput += key -> runSingleSampleJobs(sample)
Peter van 't Hof's avatar
Peter van 't Hof committed
63
        currentSample = null
Peter van 't Hof's avatar
Peter van 't Hof committed
64
      } else logger.warn("Key is not the same as ID on value for sample")
bow's avatar
bow committed
65
    }
66
  }
bow's avatar
bow committed
67

Peter van 't Hof's avatar
Peter van 't Hof committed
68
  def runSingleSampleJobs(sampleConfig: Map[String, Any]): SampleOutput
Peter van 't Hof's avatar
Peter van 't Hof committed
69
70
71
72
73
74

  /**
   * Run sample with only sampleID
   * @param sample sampleID
   * @return
   */
Peter van 't Hof's avatar
Peter van 't Hof committed
75
  def runSingleSampleJobs(sample: String): SampleOutput = {
76
    var map = any2map(getSamplesConfig(sample))
77
78
79
80
    if (map.contains("ID") && map("ID") != sample)
      throw new IllegalStateException("ID in config not the same as the key")
    else map += ("ID" -> sample)
    return runSingleSampleJobs(map)
81
  }
bow's avatar
bow committed
82

Peter van 't Hof's avatar
Peter van 't Hof committed
83
84
85
86
87
  /**
   * Runs runSingleLibraryJobs method for each library found in sampleConfig
   * @param sampleConfig sample config
   * @return Map with libraryID -> LibraryOutput object
   */
Peter van 't Hof's avatar
Peter van 't Hof committed
88
89
  final def runLibraryJobs(sampleConfig: Map[String, Any]): Map[String, LibraryOutput] = {
    var output: Map[String, LibraryOutput] = Map()
Peter van 't Hof's avatar
Peter van 't Hof committed
90
    val sampleID = sampleConfig("ID").toString
Peter van 't Hof's avatar
Peter van 't Hof committed
91
    if (sampleConfig.contains("libraries")) {
92
      val runs = any2map(sampleConfig("libraries"))
bow's avatar
bow committed
93
      for ((key, value) <- runs) {
94
        var library = any2map(value)
Peter van 't Hof's avatar
Peter van 't Hof committed
95
96
        if (!library.contains("ID")) library += ("ID" -> key)
        if (library("ID") == key) {
Peter van 't Hof's avatar
Peter van 't Hof committed
97
          currentLibrary = key
Peter van 't Hof's avatar
Peter van 't Hof committed
98
          output += key -> runSingleLibraryJobs(library, sampleConfig)
Peter van 't Hof's avatar
Peter van 't Hof committed
99
          currentLibrary = null
Peter van 't Hof's avatar
Peter van 't Hof committed
100
        } else logger.warn("Key is not the same as ID on value for run of sample: " + sampleID)
101
102
103
104
      }
    } else logger.warn("No runs found in config for sample: " + sampleID)
    return output
  }
Peter van 't Hof's avatar
Peter van 't Hof committed
105
  def runSingleLibraryJobs(runConfig: Map[String, Any], sampleConfig: Map[String, Any]): LibraryOutput
106

Peter van 't Hof's avatar
Peter van 't Hof committed
107
108
  protected var currentSample: String = null
  protected var currentLibrary: String = null
109

Peter van 't Hof's avatar
Peter van 't Hof committed
110
111
112
113
  /**
   * Set current sample manual, only use this when not using runSamplesJobs method
   * @param sample
   */
114
  def setCurrentSample(sample: String) {
Peter van 't Hof's avatar
Peter van 't Hof committed
115
    logger.debug("Manual sample set to: " + sample)
116
117
118
    currentSample = sample
  }

Peter van 't Hof's avatar
Peter van 't Hof committed
119
120
121
122
  /**
   * Gets current sample
   * @return current sample
   */
123
124
  def getCurrentSample = currentSample

Peter van 't Hof's avatar
Peter van 't Hof committed
125
126
127
128
129
  /**
   * Reset current sample manual, only use this when not using runSamplesJobs method
   */
  def resetCurrentSample() {
    logger.debug("Manual sample reset")
130
131
132
    currentSample = null
  }

Peter van 't Hof's avatar
Peter van 't Hof committed
133
134
135
136
  /**
   * Set current library manual, only use this when not using runLibraryJobs method
   * @param library
   */
137
  def setCurrentLibrary(library: String) {
Peter van 't Hof's avatar
Peter van 't Hof committed
138
    logger.debug("Manual library set to: " + library)
139
140
141
    currentLibrary = library
  }

Peter van 't Hof's avatar
Peter van 't Hof committed
142
143
144
145
  /**
   * Gets current library
   * @return current library
   */
146
147
  def getCurrentLibrary = currentLibrary

148
  /** Reset current library manual, only use this when not using runLibraryJobs method */
Peter van 't Hof's avatar
Peter van 't Hof committed
149
150
  def resetCurrentLibrary() {
    logger.debug("Manual library reset")
151
152
153
154
155
156
157
158
159
    currentLibrary = null
  }

  override protected[core] def configFullPath: List[String] = {
    (if (currentSample != null) "samples" :: currentSample :: Nil else Nil) :::
      (if (currentLibrary != null) "libraries" :: currentLibrary :: Nil else Nil) :::
      super.configFullPath
  }

160
161
162
  override val config = new ConfigFunctionsExt

  protected class ConfigFunctionsExt extends super.ConfigFunctions {
163
164
165
166
167
    override def apply(key: String,
                       default: Any = null,
                       submodule: String = null,
                       required: Boolean = false,
                       freeVar: Boolean = true,
168
169
170
171
172
                       sample: String = null,
                       library: String = null): ConfigValue = {
      val s = if (sample == null) currentSample else sample
      val l = if (library == null) currentLibrary else library
      super.apply(key, default, submodule, required, freeVar, s, l)
173
174
175
176
177
    }

    override def contains(key: String,
                          submodule: String = null,
                          freeVar: Boolean = true,
178
179
180
181
182
                          sample: String = null,
                          library: String = null) = {
      val s = if (sample == null) currentSample else sample
      val l = if (library == null) currentLibrary else library
      super.contains(key, submodule, freeVar, s, l)
183
184
    }
  }
185
}