BiopetQScript.scala 4.74 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
18
package nl.lumc.sasc.biopet.core

import java.io.File
Peter van 't Hof's avatar
Peter van 't Hof committed
19
import java.io.PrintWriter
20
import nl.lumc.sasc.biopet.core.config.{ ConfigValueIndex, Config, Configurable }
Peter van 't Hof's avatar
Peter van 't Hof committed
21
import org.broadinstitute.gatk.utils.commandline.Argument
Peter van 't Hof's avatar
Peter van 't Hof committed
22
23
import org.broadinstitute.gatk.queue.QSettings
import org.broadinstitute.gatk.queue.function.QFunction
24
import org.broadinstitute.gatk.queue.function.scattergather.ScatterGatherableFunction
25
import org.broadinstitute.gatk.queue.util.{ Logging => GatkLogging }
26
import scala.collection.mutable.ListBuffer
27

Peter van 't Hof's avatar
Peter van 't Hof committed
28
29
30
/**
 * Base for biopet pipeline
 */
31
trait BiopetQScript extends Configurable with GatkLogging {
32

33
  @Argument(doc = "JSON / YAML config file(s)", fullName = "config_file", shortName = "config", required = false)
34
  val configfiles: List[File] = Nil
bow's avatar
bow committed
35

36
  @Argument(doc = "Config values, value should be formatted like 'key=value' or 'path:path:key=value'", fullName = "config_value", shortName = "cv", required = false)
37
38
  val configValues: List[String] = Nil

Peter van 't Hof's avatar
Peter van 't Hof committed
39
40
  var outputDir: File = {
    Config.getValueFromMap(globalConfig.map, ConfigValueIndex(this.configName, configPath, "output_dir")) match {
41
      case Some(value) => new File(value.asString).getAbsoluteFile
Peter van 't Hof's avatar
Peter van 't Hof committed
42
      case _           => new File(".")
43
44
    }
  }
bow's avatar
bow committed
45

46
  @Argument(doc = "Disable all scatters", shortName = "DSC", required = false)
47
  var disableScatter: Boolean = false
48

bow's avatar
bow committed
49
50
  var outputFiles: Map[String, File] = Map()

Peter van 't Hof's avatar
Peter van 't Hof committed
51
  /** Get implemented from org.broadinstitute.gatk.queue.QScript */
Peter van 't Hof's avatar
Peter van 't Hof committed
52
  var qSettings: QSettings
bow's avatar
bow committed
53

Peter van 't Hof's avatar
Peter van 't Hof committed
54
55
56
57
  /** Get implemented from org.broadinstitute.gatk.queue.QScript */
  var functions: Seq[QFunction]

  /** Init for pipeline */
58
  def init
bow's avatar
bow committed
59

Peter van 't Hof's avatar
Peter van 't Hof committed
60
61
  /** Pipeline itself */
  def biopetScript
Peter van 't Hof's avatar
Peter van 't Hof committed
62

Peter van 't Hof's avatar
Peter van 't Hof committed
63
64
65
  /**
   * Script from queue itself, final to force some checks for each pipeline and write report
   */
66
  final def script() {
67
68
69
70
71
    if (config.contains("output_dir")) outputDir = config("output_dir").asFile.getAbsoluteFile
    else {
      outputDir = new File(".").getAbsoluteFile
      BiopetQScript.addError("No output_dir defined in config")
    }
72
73
    init
    biopetScript
74

75
    if (disableScatter) for (function <- functions) function match {
76
77
78
      case f: ScatterGatherableFunction => f.scatterCount = 1
      case _                            =>
    }
79
    for (function <- functions) function match {
80
      case f: BiopetCommandLineFunctionTrait => {
81
        f.preProcesExecutable
82
        f.beforeGraph
Peter van 't Hof's avatar
Peter van 't Hof committed
83
        f.commandLine
84
      }
Peter van 't Hof's avatar
Peter van 't Hof committed
85
      case _ =>
86
    }
Peter van 't Hof's avatar
Peter van 't Hof committed
87

Peter van 't Hof's avatar
Peter van 't Hof committed
88
89
90
    if (outputDir.getParentFile.canWrite || (outputDir.exists && outputDir.canWrite))
      globalConfig.writeReport(qSettings.runName, new File(outputDir, ".log/" + qSettings.runName))
    else BiopetQScript.addError("Parent of output dir: '" + outputDir.getParent + "' is not writeable, outputdir can not be created")
91
92

    BiopetQScript.checkErrors
93
  }
bow's avatar
bow committed
94

Peter van 't Hof's avatar
Peter van 't Hof committed
95
96
97
  /** Get implemented from org.broadinstitute.gatk.queue.QScript */
  def add(functions: QFunction*)

98
  /** Get implemented from org.broadinstitute.gatk.queue.QScript */
Peter van 't Hof's avatar
Peter van 't Hof committed
99
  def addAll(functions: scala.Traversable[org.broadinstitute.gatk.queue.function.QFunction])
100

Peter van 't Hof's avatar
Peter van 't Hof committed
101
102
103
104
105
  /**
   * Function to set isIntermediate and add in 1 line
   * @param function
   * @param isIntermediate
   */
bow's avatar
bow committed
106
  def add(function: QFunction, isIntermediate: Boolean = false) {
107
108
109
    function.isIntermediate = isIntermediate
    add(function)
  }
110
}
111
112
113
114

object BiopetQScript extends Logging {
  private val errors: ListBuffer[Exception] = ListBuffer()

115
116
  def addError(error: String, debug: String = null): Unit = {
    val msg = error + (if (debug != null && logger.isDebugEnabled) "; " + debug else "")
117
118
119
120
121
    errors.append(new Exception(msg))
  }

  protected def checkErrors: Unit = {
    if (!errors.isEmpty) {
122
123
124
125
126
127
128
129
      logger.error("*************************")
      logger.error("Biopet found some errors:")
      if (logger.isDebugEnabled) {
        for (e <- errors) {
          logger.error(e.getMessage)
          logger.debug(e.getStackTrace.mkString("Stack trace:\n", "\n", "\n"))
        }
      } else {
Peter van 't Hof's avatar
Peter van 't Hof committed
130
        errors.map(_.getMessage).sorted.distinct.foreach(logger.error(_))
131
132
133
134
      }
      throw new IllegalStateException("Biopet found errors")
    }
  }
135
}