Commit cfcd6e0e authored by Sander Bollen's avatar Sander Bollen
Browse files

VcfWithVcfTest completion

parent c4742c8d
......@@ -46,7 +46,7 @@ object SummaryToTsv extends ToolCommand {
opt[String]('m', "mode") maxOccurs 1 unbounded () valueName "<root|sample|lib>" action { (x, c) =>
c.copy(mode = x)
} validate {
x => if (Set("root","sample","lib").contains(x)) success else failure("Unsupported mode")
x => if (Set("root", "sample", "lib").contains(x)) success else failure("Unsupported mode")
} text
"""
|Determines on what level to aggregate data.
......
......@@ -18,11 +18,12 @@ package nl.lumc.sasc.biopet.tools
import java.io.File
import java.util
import htsjdk.variant.variantcontext.{VariantContext, VariantContextBuilder}
import htsjdk.variant.variantcontext.{ VariantContext, VariantContextBuilder }
import htsjdk.variant.variantcontext.writer.{ AsyncVariantContextWriter, VariantContextWriterBuilder }
import htsjdk.variant.vcf._
import nl.lumc.sasc.biopet.core.{ ToolCommandFuntion, ToolCommand }
import nl.lumc.sasc.biopet.core.config.Configurable
import nl.lumc.sasc.biopet.utils.VcfUtils.scalaListToJavaObjectArrayList
import org.broadinstitute.gatk.utils.commandline.{ Output, Input }
import scala.collection.JavaConversions._
......@@ -162,26 +163,26 @@ object VcfWithVcf extends ToolCommand {
logger.info("Done")
}
/**
* Create Map of field -> List of attributes in secondary records
* @param fields List of Field
* @param secondaryRecords List of VariantContext with secondary records
* @return Map of fields and their values in secondary records
*/
def createFieldMap(fields: List[Fields], secondaryRecords: List[VariantContext]) : Map[String, List[Any]] = {
def createFieldMap(fields: List[Fields], secondaryRecords: List[VariantContext]): Map[String, List[Any]] = {
val fieldMap = (for (
f <- fields if secondaryRecords.exists(_.hasAttribute(f.inputField))
) yield {
f.outputField -> (for (
secondRecord <- secondaryRecords if secondRecord.hasAttribute(f.inputField)
) yield {
secondRecord.getAttribute(f.inputField) match {
case l: List[_] => l
case x => List(x)
}
}).fold(Nil)(_ ::: _)
}).toMap
f.outputField -> (for (
secondRecord <- secondaryRecords if secondRecord.hasAttribute(f.inputField)
) yield {
secondRecord.getAttribute(f.inputField) match {
case l: List[_] => l
case y: util.ArrayList[_] => y.toList
case x => List(x)
}
}).fold(Nil)(_ ::: _)
}).toMap
fieldMap
}
......@@ -193,7 +194,7 @@ object VcfWithVcf extends ToolCommand {
* @return List of VariantContext
*/
def getSecondaryRecords(secondaryReader: VCFFileReader,
record: VariantContext, matchAllele: Boolean) : List[VariantContext] = {
record: VariantContext, matchAllele: Boolean): List[VariantContext] = {
if (matchAllele) {
secondaryReader.query(record.getContig, record.getStart, record.getEnd).toList.
filter(x => record.getAlternateAlleles.exists(x.hasAlternateAllele))
......@@ -208,41 +209,21 @@ object VcfWithVcf extends ToolCommand {
builder.attribute(attribute._1, fields.filter(_.outputField == attribute._1).head.fieldMethod match {
case FieldMethod.max =>
header.getInfoHeaderLine(attribute._1).getType match {
case VCFHeaderLineType.Integer => sL2JOAL(List(attribute._2.map(_.toString.toInt).max))
case VCFHeaderLineType.Float => sL2JOAL(List(attribute._2.map(_.toString.toFloat).max))
case VCFHeaderLineType.Integer => scalaListToJavaObjectArrayList(List(attribute._2.map(_.toString.toInt).max))
case VCFHeaderLineType.Float => scalaListToJavaObjectArrayList(List(attribute._2.map(_.toString.toFloat).max))
case _ => throw new IllegalArgumentException("Type of field " + attribute._1 + " is not numeric")
}
case FieldMethod.min =>
header.getInfoHeaderLine(attribute._1).getType match {
case VCFHeaderLineType.Integer => sL2JOAL(List(attribute._2.map(_.toString.toInt).min))
case VCFHeaderLineType.Float => sL2JOAL(List(attribute._2.map(_.toString.toFloat).min))
case VCFHeaderLineType.Integer => scalaListToJavaObjectArrayList(List(attribute._2.map(_.toString.toInt).min))
case VCFHeaderLineType.Float => scalaListToJavaObjectArrayList(List(attribute._2.map(_.toString.toFloat).min))
case _ => throw new IllegalArgumentException("Type of field " + attribute._1 + " is not numeric")
}
case FieldMethod.unique => sL2JOAL(attribute._2.distinct)
case _ => sL2JOAL(attribute._2)
case FieldMethod.unique => scalaListToJavaObjectArrayList(attribute._2.distinct)
case _ => {
print(attribute._2.getClass.toString)
scalaListToJavaObjectArrayList(attribute._2) }
})
}).make()
}
/**
* HACK!!
* Stands for scalaListToJavaObjectArrayList
* Convert a scala List[Any] to a java ArrayList[Object]. This is necessary for BCF conversions
* As scala ints and floats cannot be directly cast to java objects (they aren't objects),
* we need to box them.
* For items not int and float, we assume them to be strings (TODO: sane assumption?)
* @param array scala List[Any]
* @return converted java ArrayList[Object]
*/
private def sL2JOAL(array: List[Any]): util.ArrayList[Object] = {
val out = new util.ArrayList[Object]()
array.foreach {
case x: Int => out.add(Int.box(x))
case x: Float => out.add(Float.box(x))
case x => out.add(x.toString)
}
out
}
}
......@@ -15,6 +15,8 @@
*/
package nl.lumc.sasc.biopet.utils
import java.util
import htsjdk.variant.variantcontext.VariantContext
import scala.collection.JavaConversions._
......@@ -43,4 +45,48 @@ object VcfUtils {
def fillAllele(bases: String, newSize: Int, fillWith: Char = '-'): String = {
bases + Array.fill[Char](newSize - bases.length)(fillWith).mkString
}
/**
* HACK!!
* Stands for scalaListToJavaObjectArrayList
* Convert a scala List[Any] to a java ArrayList[Object]. This is necessary for BCF conversions
* As scala ints and floats cannot be directly cast to java objects (they aren't objects),
* we need to box them.
* For items not Int, Float or Object, we assume them to be strings (TODO: sane assumption?)
* @param array scala List[Any]
* @return converted java ArrayList[Object]
*/
def scalaListToJavaObjectArrayList(array: List[Any]): util.ArrayList[Object] = {
val out = new util.ArrayList[Object]()
array.foreach {
case x: Int => out.add(Int.box(x))
case x: Float => out.add(Float.box(x))
case x: String => out.add(x)
case x: Object => out.add(x)
case x => out.add(x.toString)
}
out
}
def identicalVariantContext(var1: VariantContext, var2: VariantContext): Boolean = {
if(var1.getContig != var2.getContig) {
false
}
if(var1.getStart != var2.getStart) {
false
}
if(var1.getEnd != var2.getEnd) {
false
}
if(!var1.getAttributes.forall(x => var2.hasAttribute(x._1)) || !var2.getAttributes.forall(x => var1.hasAttribute(x._1))){
false
}
if(!var1.getAttributes.forall(x => var2.getAttribute(x._1) == var1.getAttribute(x._1)) ||
!var2.getAttributes.forall(x => var1.getAttribute(x._1) == var2.getAttribute(x._1))){
false
}
true
}
}
......@@ -11,7 +11,6 @@ import org.testng.annotations.Test
import nl.lumc.sasc.biopet.core.summary.Summary
/**
* Created by ahbbollen on 31-8-15.
*/
......@@ -34,7 +33,7 @@ class SummaryToTsvTest extends TestNGSuite with MockitoSugar with Matchers {
}
@Test
def testHeader = {
def testHeader = {
val tsv = resourcePath("/test.summary.json")
val path = List("something=flexiprep:settings:skip_trim")
......
......@@ -28,6 +28,8 @@ import org.testng.annotations.Test
import scala.util.Random
import scala.collection.JavaConversions._
import nl.lumc.sasc.biopet.utils.VcfUtils.identicalVariantContext
/**
* Test class for [[VcfWithVcfTest]]
*
......@@ -65,32 +67,32 @@ class VcfWithVcfTest extends TestNGSuite with MockitoSugar with Matchers {
@Test def testOutputFieldException = {
val tmpPath = File.createTempFile("VCFWithVCf", ".vcf").getAbsolutePath
val args = Array("-I", unveppedPath, "-s", veppedPath, "-o", tmpPath, "-f", "CSQ:AC")
an [IllegalArgumentException] should be thrownBy main(args)
val thrown = the [IllegalArgumentException] thrownBy main(args)
an[IllegalArgumentException] should be thrownBy main(args)
val thrown = the[IllegalArgumentException] thrownBy main(args)
thrown.getMessage should equal("Field 'AC' already exists in input vcf")
}
@Test def testInputFieldException = {
val tmpPath = File.createTempFile("VCFWithVCf", ".vcf").getAbsolutePath
val args = Array("-I", unveppedPath, "-s", unveppedPath, "-o", tmpPath, "-f", "CSQ:NEW_CSQ")
an [IllegalArgumentException] should be thrownBy main(args)
val thrown = the [IllegalArgumentException] thrownBy main(args)
an[IllegalArgumentException] should be thrownBy main(args)
val thrown = the[IllegalArgumentException] thrownBy main(args)
thrown.getMessage should equal("Field 'CSQ' does not exist in secondary vcf")
}
@Test def testMinMethodException = {
val tmpPath = File.createTempFile("VcfWithVcf_", ".vcf").getAbsolutePath
val args = Array("-I", unveppedPath, "-s", veppedPath, "-o", tmpPath, "-f", "CSQ:CSQ:min")
an [IllegalArgumentException] should be thrownBy main(args)
val thrown = the [IllegalArgumentException] thrownBy main(args)
an[IllegalArgumentException] should be thrownBy main(args)
val thrown = the[IllegalArgumentException] thrownBy main(args)
thrown.getMessage should equal("Type of field CSQ is not numeric")
}
@Test def testMaxMethodException = {
val tmpPath = File.createTempFile("VcfWithVcf_", ".vcf").getAbsolutePath
val args = Array("-I", unveppedPath, "-s", veppedPath, "-o", tmpPath, "-f", "CSQ:CSQ:max")
an [IllegalArgumentException] should be thrownBy main(args)
val thrown = the [IllegalArgumentException] thrownBy main(args)
an[IllegalArgumentException] should be thrownBy main(args)
val thrown = the[IllegalArgumentException] thrownBy main(args)
thrown.getMessage should equal("Type of field CSQ is not numeric")
}
......@@ -124,7 +126,6 @@ class VcfWithVcfTest extends TestNGSuite with MockitoSugar with Matchers {
fields :::= List(new Fields("VQSLOD", "VQSLOD"))
fields :::= List(new Fields("culprit", "culprit"))
val fieldMap = createFieldMap(fields, List(unvep_record))
fieldMap("FG") shouldBe List("intron")
......@@ -133,9 +134,7 @@ class VcfWithVcfTest extends TestNGSuite with MockitoSugar with Matchers {
fieldMap("GL") shouldBe List("SAMD11")
fieldMap("CP") shouldBe List("0.000")
fieldMap("CG") shouldBe List("-1.630")
val cn = new util.ArrayList[String]
cn.addAll(List("2294", "3274", "30362", "112930"))
fieldMap("CN") shouldBe List(cn)
fieldMap("CN") shouldBe List("2294", "3274", "30362", "112930")
fieldMap("DSP") shouldBe List("107")
fieldMap("AC") shouldBe List("2")
fieldMap("AF") shouldBe List("0.333")
......@@ -148,16 +147,35 @@ class VcfWithVcfTest extends TestNGSuite with MockitoSugar with Matchers {
fieldMap("MQ0") shouldBe List("0")
fieldMap("MQRankSum") shouldBe List("-0.197")
fieldMap("QD") shouldBe List("19.03")
val rpa = new util.ArrayList[String]
rpa.addAll(List("1", "2"))
fieldMap("RPA") shouldBe List(rpa)
fieldMap("RPA") shouldBe List("1", "2")
fieldMap("RU") shouldBe List("A")
fieldMap("ReadPosRankSum") shouldBe List("-0.424")
fieldMap("VQSLOD") shouldBe List("0.079")
fieldMap("culprit") shouldBe List("FS")
}
@Test def testGetSecondaryRecords = {
val unvep_record = new VCFFileReader(new File(unveppedPath)).iterator().next()
val vep_reader = new VCFFileReader(new File(veppedPath))
val vep_record = vep_reader.iterator().next()
val secRec = getSecondaryRecords(vep_reader, unvep_record, false)
secRec.foreach(x => identicalVariantContext(x, vep_record) shouldBe true)
}
@Test def testCreateRecord = {
val unvep_record = new VCFFileReader(new File(unveppedPath)).iterator().next()
val vep_reader = new VCFFileReader(new File(veppedPath))
val header = vep_reader.getFileHeader
val vep_record = vep_reader.iterator().next()
val secRec = getSecondaryRecords(vep_reader, unvep_record, false)
val fieldMap = createFieldMap(List(new Fields("CSQ", "CSQ")), secRec)
val created_record = createRecord(fieldMap, unvep_record, List(new Fields("CSQ", "CSQ")), header)
identicalVariantContext(created_record, vep_record) shouldBe true
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment