ShivaSvCallingTest.scala 8.38 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.shiva

Peter van 't Hof's avatar
Peter van 't Hof committed
17
import java.io.{ File, FileOutputStream }
Peter van 't Hof's avatar
Peter van 't Hof committed
18
import java.nio.file.Paths
19 20

import com.google.common.io.Files
Peter van 't Hof's avatar
Peter van 't Hof committed
21
import nl.lumc.sasc.biopet.extensions.breakdancer.{ BreakdancerCaller, BreakdancerConfig, BreakdancerVCF }
22 23
import nl.lumc.sasc.biopet.extensions.clever.CleverCaller
import nl.lumc.sasc.biopet.extensions.delly.DellyCaller
Peter van 't Hof's avatar
Peter van 't Hof committed
24 25
import nl.lumc.sasc.biopet.extensions.pindel.{ PindelCaller, PindelConfig, PindelVCF }
import nl.lumc.sasc.biopet.utils.{ ConfigUtils, Logging }
Wai Yi Leung's avatar
Wai Yi Leung committed
26
import nl.lumc.sasc.biopet.utils.config.Config
27
import org.apache.commons.io.FileUtils
28 29 30
import org.broadinstitute.gatk.queue.QSettings
import org.scalatest.Matchers
import org.scalatest.testng.TestNGSuite
Peter van 't Hof's avatar
Peter van 't Hof committed
31
import org.testng.annotations.{ AfterClass, DataProvider, Test }
32 33 34 35 36 37 38 39 40

import scala.collection.mutable.ListBuffer

/**
 * Test class for [[ShivaVariantcalling]]
 *
 * Created by pjvan_thof on 3/2/15.
 */
class ShivaSvCallingTest extends TestNGSuite with Matchers {
41
  def initPipeline(map: Map[String, Any], dir: File): ShivaSvCalling = {
42
    new ShivaSvCalling {
43
      override def configNamespace = "shivasvcalling"
44
      override def globalConfig = new Config(ConfigUtils.mergeMaps(map, ShivaSvCallingTest.config(dir)))
45 46 47 48 49
      qSettings = new QSettings
      qSettings.runName = "test"
    }
  }

50 51
  private var dirs: List[File] = Nil

52 53 54 55 56 57 58
  @DataProvider(name = "shivaSvCallingOptions")
  def shivaSvCallingOptions = {
    val bool = Array(true, false)
    (for (
      bams <- 0 to 3;
      delly <- bool;
      clever <- bool;
Wai Yi Leung's avatar
Wai Yi Leung committed
59 60 61
      breakdancer <- bool;
      pindel <- bool
    ) yield Array(bams, delly, clever, breakdancer, pindel)).toArray
62 63 64
  }

  @Test(dataProvider = "shivaSvCallingOptions")
65 66 67
  def testShivaSvCalling(bams: Int,
                         delly: Boolean,
                         clever: Boolean,
Wai Yi Leung's avatar
Wai Yi Leung committed
68 69
                         breakdancer: Boolean,
                         pindel: Boolean) = {
70 71
    val outputDir = ShivaSvCallingTest.outputDir
    dirs :+= outputDir
72 73 74 75
    val callers: ListBuffer[String] = ListBuffer()
    if (delly) callers.append("delly")
    if (clever) callers.append("clever")
    if (breakdancer) callers.append("breakdancer")
Wai Yi Leung's avatar
Wai Yi Leung committed
76
    if (pindel) callers.append("pindel")
77
    val map = Map("sv_callers" -> callers.toList)
78
    val pipeline = initPipeline(map, outputDir)
79 80 81

    pipeline.inputBams = (for (n <- 1 to bams) yield n.toString -> ShivaSvCallingTest.inputTouch("bam_" + n + ".bam")).toMap

Wai Yi Leung's avatar
Wai Yi Leung committed
82
    val illegalArgumentException = pipeline.inputBams.isEmpty || (!delly && !clever && !breakdancer && !pindel)
83 84 85 86 87 88 89 90 91 92

    if (illegalArgumentException) intercept[IllegalArgumentException] {
      pipeline.init()
      pipeline.script()
    }

    if (!illegalArgumentException) {
      pipeline.init()
      pipeline.script()

akaljuvee's avatar
-  
akaljuvee committed
93
      val summaryCallers = pipeline.summarySettings.get("sv_callers").get.asInstanceOf[List[String]]
Peter van 't Hof's avatar
Peter van 't Hof committed
94 95 96 97 98 99
      if (delly) assert(summaryCallers.contains("delly"))
      else assert(!summaryCallers.contains("delly"))
      if (clever) assert(summaryCallers.contains("clever"))
      else assert(!summaryCallers.contains("clever"))
      if (breakdancer) assert(summaryCallers.contains("breakdancer"))
      else assert(!summaryCallers.contains("breakdancer"))
Wai Yi Leung's avatar
Wai Yi Leung committed
100 101
      if (pindel) assert(summaryCallers.contains("pindel"))
      else assert(!summaryCallers.contains("pindel"))
Peter van 't Hof's avatar
Peter van 't Hof committed
102

103
      pipeline.functions.count(_.isInstanceOf[BreakdancerConfig]) shouldBe (if (breakdancer) bams else 0)
Wai Yi Leung's avatar
Wai Yi Leung committed
104
      pipeline.functions.count(_.isInstanceOf[BreakdancerCaller]) shouldBe (if (breakdancer) bams else 0)
105
      pipeline.functions.count(_.isInstanceOf[BreakdancerVCF]) shouldBe (if (breakdancer) bams else 0)
Wai Yi Leung's avatar
Wai Yi Leung committed
106 107 108 109 110

      pipeline.functions.count(_.isInstanceOf[PindelConfig]) shouldBe (if (pindel) bams else 0)
      pipeline.functions.count(_.isInstanceOf[PindelCaller]) shouldBe (if (pindel) bams else 0)
      pipeline.functions.count(_.isInstanceOf[PindelVCF]) shouldBe (if (pindel) bams else 0)

111
      pipeline.functions.count(_.isInstanceOf[CleverCaller]) shouldBe (if (clever) bams else 0)
Peter van 't Hof's avatar
Peter van 't Hof committed
112
      pipeline.functions.count(_.isInstanceOf[DellyCaller]) shouldBe (if (delly) bams * 4 else 0)
113 114 115 116

    }
  }

117 118 119
  @DataProvider(name = "dellyOptions")
  def dellyOptions = {
    val bool = Array(true, false)
Peter van 't Hof's avatar
Peter van 't Hof committed
120
    for (
121 122 123 124
      del <- bool;
      dup <- bool;
      inv <- bool;
      tra <- bool
Peter van 't Hof's avatar
Peter van 't Hof committed
125
    ) yield Array(1, del, dup, inv, tra)
126 127 128 129
  }

  @Test(dataProvider = "dellyOptions")
  def testShivaDelly(bams: Int, del: Boolean, dup: Boolean, inv: Boolean, tra: Boolean): Unit = {
130 131
    val outputDir = ShivaSvCallingTest.outputDir
    dirs :+= outputDir
132

Peter van 't Hof's avatar
Peter van 't Hof committed
133
    val map = Map("sv_callers" -> List("delly"), "delly" ->
134 135
      Map("DEL" -> del, "DUP" -> dup, "INV" -> inv, "TRA" -> tra)
    )
136
    val pipeline = initPipeline(map, outputDir)
137

Peter van 't Hof's avatar
Peter van 't Hof committed
138
    pipeline.inputBams = Map("bam" -> ShivaSvCallingTest.inputTouch("bam" + ".bam"))
139

Peter van 't Hof's avatar
Peter van 't Hof committed
140
    if (!del && !dup && !inv && !tra) intercept[IllegalStateException] {
141 142 143 144 145 146 147 148 149 150 151 152
      pipeline.init()
      pipeline.script()
    }
    else {
      pipeline.init()
      pipeline.script()

      pipeline.functions.count(_.isInstanceOf[DellyCaller]) shouldBe
        ((if (del) 1 else 0) + (if (dup) 1 else 0) + (if (inv) 1 else 0) + (if (tra) 1 else 0))
    }
  }

153 154
  @Test
  def testWrongCaller(): Unit = {
155 156 157
    val outputDir = ShivaSvCallingTest.outputDir
    dirs :+= outputDir

158
    val map = Map("sv_callers" -> List("this is not a caller"))
159
    val pipeline = initPipeline(map, outputDir)
160

Peter van 't Hof's avatar
Peter van 't Hof committed
161
    pipeline.inputBams = Map("bam" -> ShivaSvCallingTest.inputTouch("bam" + ".bam"))
162 163 164 165

    intercept[IllegalArgumentException] {
      pipeline.script()
    }
Peter van 't Hof's avatar
Peter van 't Hof committed
166
    Logging.errors.clear()
167 168
  }

Peter van 't Hof's avatar
Peter van 't Hof committed
169 170 171 172 173 174
  private def resourcePath(p: String): String = {
    Paths.get(getClass.getResource(p).toURI).toString
  }

  @Test
  def testInputBamsArg(): Unit = {
175 176 177 178
    val outputDir = ShivaSvCallingTest.outputDir
    dirs :+= outputDir

    val pipeline = initPipeline(Map(), outputDir)
Peter van 't Hof's avatar
Peter van 't Hof committed
179 180 181 182 183 184

    pipeline.inputBamsArg :+= new File(resourcePath("/paired01.bam"))

    pipeline.init()
    pipeline.script()

akaljuvee's avatar
-  
akaljuvee committed
185
    val summaryCallers: List[String] = pipeline.summarySettings.get("sv_callers").get.asInstanceOf[List[String]]
Peter van 't Hof's avatar
Peter van 't Hof committed
186 187 188 189
    assert(summaryCallers.contains("delly"))
    assert(summaryCallers.contains("clever"))
    assert(summaryCallers.contains("breakdancer"))
  }
190 191 192 193 194

  // remove temporary run directory all tests in the class have been run
  @AfterClass def removeTempOutputDir() = {
    dirs.foreach(FileUtils.deleteDirectory)
  }
195 196 197
}

object ShivaSvCallingTest {
198 199 200
  def outputDir = Files.createTempDir()
  val inputDir = Files.createTempDir()

Peter van 't Hof's avatar
Peter van 't Hof committed
201
  private def inputTouch(name: String): File = {
202
    val file = new File(outputDir, name).getAbsoluteFile
203 204 205 206 207 208
    Files.touch(file)
    file
  }

  private def copyFile(name: String): Unit = {
    val is = getClass.getResourceAsStream("/" + name)
209
    val os = new FileOutputStream(new File(inputDir, name))
210 211 212 213 214 215 216 217
    org.apache.commons.io.IOUtils.copy(is, os)
    os.close()
  }

  copyFile("ref.fa")
  copyFile("ref.dict")
  copyFile("ref.fa.fai")

218
  def config(outputDir: File) = Map(
219
    "skip_write_dependencies" -> true,
220 221 222 223 224
    "name_prefix" -> "test",
    "output_dir" -> outputDir,
    "cache" -> true,
    "dir" -> "test",
    "vep_script" -> "test",
225
    "reference_fasta" -> (inputDir + File.separator + "ref.fa"),
226 227 228 229 230 231 232
    "gatk_jar" -> "test",
    "samtools" -> Map("exe" -> "test"),
    "md5sum" -> Map("exe" -> "test"),
    "bgzip" -> Map("exe" -> "test"),
    "tabix" -> Map("exe" -> "test"),
    "breakdancerconfig" -> Map("exe" -> "test"),
    "breakdancercaller" -> Map("exe" -> "test"),
Wai Yi Leung's avatar
Wai Yi Leung committed
233 234 235
    "pindelconfig" -> Map("exe" -> "test"),
    "pindelcaller" -> Map("exe" -> "test"),
    "pindelvcf" -> Map("exe" -> "test"),
236 237
    "clever" -> Map("exe" -> "test"),
    "delly" -> Map("exe" -> "test"),
Wai Yi Leung's avatar
Wai Yi Leung committed
238 239 240 241 242
    "varscan_jar" -> "test",
    "pysvtools" -> Map(
      "exe" -> "test",
      "exclusion_regions" -> "test",
      "translocations_only" -> false)
243 244
  )
}