Skip to content
Snippets Groups Projects
Commit ef2a9acd authored by bow's avatar bow
Browse files

Update to htsjdk use in GATK 3.3

parent cc6a184f
No related branches found
No related tags found
No related merge requests found
...@@ -9,19 +9,20 @@ import java.io.File ...@@ -9,19 +9,20 @@ import java.io.File
import scala.collection.mutable.{ Set => MSet } import scala.collection.mutable.{ Set => MSet }
import scala.collection.JavaConverters._ import scala.collection.JavaConverters._
import htsjdk.samtools.SAMFileReader
import htsjdk.samtools.QueryInterval import htsjdk.samtools.QueryInterval
import htsjdk.samtools.SamReaderFactory
import htsjdk.samtools.ValidationStringency
import htsjdk.samtools.fastq.{ BasicFastqWriter, FastqReader, FastqRecord } import htsjdk.samtools.fastq.{ BasicFastqWriter, FastqReader, FastqRecord }
import htsjdk.tribble.Feature import htsjdk.samtools.util.Interval
import htsjdk.tribble.BasicFeature
import nl.lumc.sasc.biopet.core.ToolCommand import nl.lumc.sasc.biopet.core.ToolCommand
object ExtractAlignedFastq extends ToolCommand { object ExtractAlignedFastq extends ToolCommand {
type FastqPair = (FastqRecord, FastqRecord) type FastqPair = (FastqRecord, FastqRecord)
/** /**
* Function to create iterator over features given input interval string * Function to create iterator over Interval given input interval string
* *
* Valid interval strings are either of these: * Valid interval strings are either of these:
* - chr5:10000-11000 * - chr5:10000-11000
...@@ -38,7 +39,7 @@ object ExtractAlignedFastq extends ToolCommand { ...@@ -38,7 +39,7 @@ object ExtractAlignedFastq extends ToolCommand {
* *
* @param inStrings iterable yielding input interval string * @param inStrings iterable yielding input interval string
*/ */
def makeFeatureFromString(inStrings: Iterable[String]): Iterator[Feature] = { def makeIntervalFromString(inStrings: Iterable[String]): Iterator[Interval] = {
// FIXME: can we combine these two patterns into one regex? // FIXME: can we combine these two patterns into one regex?
// matches intervals with start and end coordinates // matches intervals with start and end coordinates
...@@ -47,15 +48,16 @@ object ExtractAlignedFastq extends ToolCommand { ...@@ -47,15 +48,16 @@ object ExtractAlignedFastq extends ToolCommand {
val ptn2 = """([\w_-]+):([\d.,]+)""".r val ptn2 = """([\w_-]+):([\d.,]+)""".r
// make ints from coordinate strings // make ints from coordinate strings
// NOTE: while it is possible for coordinates to exceed Int.MaxValue, we are limited // NOTE: while it is possible for coordinates to exceed Int.MaxValue, we are limited
// by the BasicFeature constructor only accepting ints // by the Interval constructor only accepting ints
def intFromCoord(s: String): Int = s.replaceAll(",", "").replaceAll("\\.", "").toInt def intFromCoord(s: String): Int = s.replaceAll(",", "").replaceAll("\\.", "").toInt
inStrings.map(x => x match { inStrings.map(x => x match {
case ptn1(chr, start, end) => new BasicFeature(chr, intFromCoord(start), intFromCoord(end)) case ptn1(chr, start, end) => new Interval(chr, intFromCoord(start), intFromCoord(end))
case ptn2(chr, start) => val startCoord = intFromCoord(start) case ptn2(chr, start) =>
new BasicFeature(chr, startCoord, startCoord) val startCoord = intFromCoord(start)
case _ => throw new IllegalArgumentException("Invalid interval string: " + x) new Interval(chr, startCoord, startCoord)
}) case _ => throw new IllegalArgumentException("Invalid interval string: " + x)
})
.toIterator .toIterator
} }
...@@ -69,34 +71,30 @@ object ExtractAlignedFastq extends ToolCommand { ...@@ -69,34 +71,30 @@ object ExtractAlignedFastq extends ToolCommand {
* @param commonSuffixLength length of suffix common to all read pairs * @param commonSuffixLength length of suffix common to all read pairs
* @return * @return
*/ */
def makeMembershipFunction(iv: Iterator[Feature], def makeMembershipFunction(iv: Iterator[Interval],
inAln: File, inAln: File,
minMapQ: Int = 0, minMapQ: Int = 0,
commonSuffixLength: Int = 0 commonSuffixLength: Int = 0): (FastqPair => Boolean) = {
): (FastqPair => Boolean) = {
/** function to make interval queries for BAM files */
def makeQueryInterval(aln: SAMFileReader, feat: Feature): QueryInterval =
if (aln.getFileHeader.getSequenceIndex(feat.getChr) > -1)
aln.makeQueryInterval(feat.getChr, feat.getStart, feat.getEnd)
else if (feat.getChr.startsWith("chr")
&& aln.getFileHeader.getSequenceIndex(feat.getChr.substring(3)) > -1)
aln.makeQueryInterval(feat.getChr.substring(3), feat.getStart, feat.getEnd)
else if (!feat.getChr.startsWith("chr")
&& aln.getFileHeader.getSequenceIndex("chr" + feat.getChr) > -1)
aln.makeQueryInterval("chr" + feat.getChr, feat.getStart, feat.getEnd)
else
throw new IllegalStateException("Unexpected feature: " + feat.toString)
val inAlnReader = new SAMFileReader(inAln) val inAlnReader = SamReaderFactory
.make()
.validationStringency(ValidationStringency.LENIENT)
.open(inAln)
require(inAlnReader.hasIndex) require(inAlnReader.hasIndex)
def getSequenceIndex(name: String): Int = inAlnReader.getFileHeader.getSequenceIndex(name) match {
case x if x >= 0 =>
x
case otherwise =>
throw new IllegalArgumentException("Chromosome " + name + " is not found in the alignment file")
}
val queries: Array[QueryInterval] = iv.toList val queries: Array[QueryInterval] = iv.toList
// sort features // sort Interval
.sortBy(x => (x.getChr, x.getStart, x.getEnd)) .sortBy(x => (x.getSequence, x.getStart, x.getEnd))
// turn them into QueryInterval objects // transform to QueryInterval
.map(x => makeQueryInterval(inAlnReader, x)) .map(x => new QueryInterval(getSequenceIndex(x.getSequence), x.getStart, x.getEnd))
// return as an array // cast to array
.toArray .toArray
lazy val selected: MSet[String] = inAlnReader lazy val selected: MSet[String] = inAlnReader
...@@ -112,11 +110,11 @@ object ExtractAlignedFastq extends ToolCommand { ...@@ -112,11 +110,11 @@ object ExtractAlignedFastq extends ToolCommand {
logger.debug("Adding " + x.getReadName + " to set ...") logger.debug("Adding " + x.getReadName + " to set ...")
acc += x.getReadName acc += x.getReadName
} }
) )
(pair: FastqPair) => pair._2 match { (pair: FastqPair) => pair._2 match {
case null => selected.contains(pair._1.getReadHeader) case null => selected.contains(pair._1.getReadHeader)
case otherwise => case otherwise =>
require(commonSuffixLength < pair._1.getReadHeader.length) require(commonSuffixLength < pair._1.getReadHeader.length)
require(commonSuffixLength < pair._2.getReadHeader.length) require(commonSuffixLength < pair._2.getReadHeader.length)
selected.contains(pair._1.getReadHeader.dropRight(commonSuffixLength)) selected.contains(pair._1.getReadHeader.dropRight(commonSuffixLength))
...@@ -131,8 +129,8 @@ object ExtractAlignedFastq extends ToolCommand { ...@@ -131,8 +129,8 @@ object ExtractAlignedFastq extends ToolCommand {
val i1 = inputFastq1.iterator.asScala val i1 = inputFastq1.iterator.asScala
val i2 = inputFastq2 match { val i2 = inputFastq2 match {
case null => Iterator.continually(null) case null => Iterator.continually(null)
case otherwise => otherwise.iterator.asScala case otherwise => otherwise.iterator.asScala
} }
val o1 = outputFastq1 val o1 = outputFastq1
val o2 = (inputFastq2, outputFastq2) match { val o2 = (inputFastq2, outputFastq2) match {
...@@ -152,18 +150,18 @@ object ExtractAlignedFastq extends ToolCommand { ...@@ -152,18 +150,18 @@ object ExtractAlignedFastq extends ToolCommand {
case (rec1, rec2) => case (rec1, rec2) =>
o1.write(rec1) o1.write(rec1)
o2.write(rec2) o2.write(rec2)
} }
} }
case class Args (inputBam: File = null, case class Args(inputBam: File = null,
intervals: List[String] = List.empty[String], intervals: List[String] = List.empty[String],
inputFastq1: File = null, inputFastq1: File = null,
inputFastq2: File = null, inputFastq2: File = null,
outputFastq1: File = null, outputFastq1: File = null,
outputFastq2: File = null, outputFastq2: File = null,
minMapQ: Int = 0, minMapQ: Int = 0,
commonSuffixLength: Int = 0) extends AbstractArgs commonSuffixLength: Int = 0) extends AbstractArgs
class OptParser extends AbstractOptParser { class OptParser extends AbstractOptParser {
...@@ -172,36 +170,44 @@ object ExtractAlignedFastq extends ToolCommand { ...@@ -172,36 +170,44 @@ object ExtractAlignedFastq extends ToolCommand {
|$commandName - Select aligned FASTQ records |$commandName - Select aligned FASTQ records
""".stripMargin) """.stripMargin)
opt[File]('I', "input_file") required() valueName "<bam>" action { (x, c) => opt[File]('I', "input_file") required () valueName "<bam>" action { (x, c) =>
c.copy(inputBam = x) } validate { c.copy(inputBam = x)
} validate {
x => if (x.exists) success else failure("Input BAM file not found") x => if (x.exists) success else failure("Input BAM file not found")
} text "Input BAM file" } text "Input BAM file"
opt[String]('r', "interval") required() unbounded() valueName "<interval>" action { (x, c) => opt[String]('r', "interval") required () unbounded () valueName "<interval>" action { (x, c) =>
// yes, we are appending and yes it's O(n) ~ preserving order is more important than speed here // yes, we are appending and yes it's O(n) ~ preserving order is more important than speed here
c.copy(intervals = c.intervals :+ x) } text "Interval strings" c.copy(intervals = c.intervals :+ x)
} text "Interval strings"
opt[File]('i', "in1") required() valueName "<fastq>" action { (x, c) => opt[File]('i', "in1") required () valueName "<fastq>" action { (x, c) =>
c.copy(inputFastq1 = x) } validate { c.copy(inputFastq1 = x)
} validate {
x => if (x.exists) success else failure("Input FASTQ file 1 not found") x => if (x.exists) success else failure("Input FASTQ file 1 not found")
} text "Input FASTQ file 1" } text "Input FASTQ file 1"
opt[File]('j', "in2") optional() valueName "<fastq>" action { (x, c) => opt[File]('j', "in2") optional () valueName "<fastq>" action { (x, c) =>
c.copy(inputFastq1 = x) } validate { c.copy(inputFastq1 = x)
} validate {
x => if (x.exists) success else failure("Input FASTQ file 2 not found") x => if (x.exists) success else failure("Input FASTQ file 2 not found")
} text "Input FASTQ file 2 (default: none)" } text "Input FASTQ file 2 (default: none)"
opt[File]('o', "out1") required() valueName "<fastq>" action { (x, c) => opt[File]('o', "out1") required () valueName "<fastq>" action { (x, c) =>
c.copy(outputFastq1 = x) } text "Output FASTQ file 1" c.copy(outputFastq1 = x)
} text "Output FASTQ file 1"
opt[File]('p', "out2") optional() valueName "<fastq>" action { (x, c) => opt[File]('p', "out2") optional () valueName "<fastq>" action { (x, c) =>
c.copy(outputFastq1 = x) } text "Output FASTQ file 2 (default: none)" c.copy(outputFastq1 = x)
} text "Output FASTQ file 2 (default: none)"
opt[Int]('Q', "min_mapq") optional() action { (x, c) => opt[Int]('Q', "min_mapq") optional () action { (x, c) =>
c.copy(minMapQ = x) } text "Minimum MAPQ of reads in target region to remove (default: 0)" c.copy(minMapQ = x)
} text "Minimum MAPQ of reads in target region to remove (default: 0)"
opt[Int]('s', "read_suffix_length") optional() action { (x, c) => opt[Int]('s', "read_suffix_length") optional () action { (x, c) =>
c.copy(commonSuffixLength = x) } text "Length of common suffix from each read pair (default: 0)" c.copy(commonSuffixLength = x)
} text "Length of common suffix from each read pair (default: 0)"
note( note(
""" """
...@@ -229,7 +235,7 @@ object ExtractAlignedFastq extends ToolCommand { ...@@ -229,7 +235,7 @@ object ExtractAlignedFastq extends ToolCommand {
.getOrElse(sys.exit(1)) .getOrElse(sys.exit(1))
val memFunc = makeMembershipFunction( val memFunc = makeMembershipFunction(
iv = makeFeatureFromString(commandArgs.intervals), iv = makeIntervalFromString(commandArgs.intervals),
inAln = commandArgs.inputBam, inAln = commandArgs.inputBam,
minMapQ = commandArgs.minMapQ, minMapQ = commandArgs.minMapQ,
commonSuffixLength = commandArgs.commonSuffixLength) commonSuffixLength = commandArgs.commonSuffixLength)
......
...@@ -14,8 +14,8 @@ import org.scalatest.mock.MockitoSugar ...@@ -14,8 +14,8 @@ import org.scalatest.mock.MockitoSugar
import org.scalatest.testng.TestNGSuite import org.scalatest.testng.TestNGSuite
import org.testng.annotations.{ DataProvider, Test } import org.testng.annotations.{ DataProvider, Test }
import htsjdk.samtools.util.Interval
import htsjdk.samtools.fastq.{ BasicFastqWriter, FastqReader, FastqRecord } import htsjdk.samtools.fastq.{ BasicFastqWriter, FastqReader, FastqRecord }
import htsjdk.tribble._
class ExtractAlignedFastqUnitTest extends TestNGSuite with MockitoSugar with Matchers { class ExtractAlignedFastqUnitTest extends TestNGSuite with MockitoSugar with Matchers {
...@@ -24,8 +24,8 @@ class ExtractAlignedFastqUnitTest extends TestNGSuite with MockitoSugar with Mat ...@@ -24,8 +24,8 @@ class ExtractAlignedFastqUnitTest extends TestNGSuite with MockitoSugar with Mat
private def resourceFile(p: String): File = private def resourceFile(p: String): File =
new File(Paths.get(getClass.getResource(p).toURI).toString) new File(Paths.get(getClass.getResource(p).toURI).toString)
private def makeFeature(chr: String, start: Int, end: Int): Feature = private def makeInterval(chr: String, start: Int, end: Int): Interval =
new BasicFeature(chr, start ,end) new Interval(chr, start, end)
private def makeRecord(header: String): FastqRecord = private def makeRecord(header: String): FastqRecord =
new FastqRecord(header, "ATGC", "", "HIHI") new FastqRecord(header, "ATGC", "", "HIHI")
...@@ -40,41 +40,52 @@ class ExtractAlignedFastqUnitTest extends TestNGSuite with MockitoSugar with Mat ...@@ -40,41 +40,52 @@ class ExtractAlignedFastqUnitTest extends TestNGSuite with MockitoSugar with Mat
tName + " on " + f.getName + ", read " + rName + ": " tName + " on " + f.getName + ", read " + rName + ": "
@Test def testIntervalStartEnd() = { @Test def testIntervalStartEnd() = {
val obs = makeFeatureFromString(List("chr5:1000-1100")).next() val obs = makeIntervalFromString(List("chr5:1000-1100")).next()
val exp = new BasicFeature("chr5", 1000, 1100) val exp = new Interval("chr5", 1000, 1100)
obs.getChr should === (exp.getChr) obs.getSequence should === (exp.getSequence)
obs.getStart should === (exp.getStart) obs.getStart should === (exp.getStart)
obs.getEnd should === (exp.getEnd) obs.getEnd should === (exp.getEnd)
} }
@Test def testIntervalStartEndComma() = { @Test def testIntervalStartEndComma() = {
val obs = makeFeatureFromString(List("chr5:1,000-1,100")).next() val obs = makeIntervalFromString(List("chr5:1,000-1,100")).next()
val exp = new BasicFeature("chr5", 1000, 1100) val exp = new Interval("chr5", 1000, 1100)
obs.getChr should === (exp.getChr) obs.getSequence should === (exp.getSequence)
obs.getStart should === (exp.getStart) obs.getStart should === (exp.getStart)
obs.getEnd should === (exp.getEnd) obs.getEnd should === (exp.getEnd)
} }
@Test def testIntervalStartEndDot() = { @Test def testIntervalStartEndDot() = {
val obs = makeFeatureFromString(List("chr5:1.000-1.100")).next() val obs = makeIntervalFromString(List("chr5:1.000-1.100")).next()
val exp = new BasicFeature("chr5", 1000, 1100) val exp = new Interval("chr5", 1000, 1100)
obs.getChr should === (exp.getChr) obs.getSequence should === (exp.getSequence)
obs.getStart should === (exp.getStart) obs.getStart should === (exp.getStart)
obs.getEnd should === (exp.getEnd) obs.getEnd should === (exp.getEnd)
} }
@Test def testIntervalStart() = { @Test def testIntervalStart() = {
val obs = makeFeatureFromString(List("chr5:1000")).next() val obs = makeIntervalFromString(List("chr5:1000")).next()
val exp = new BasicFeature("chr5", 1000, 1000) val exp = new Interval("chr5", 1000, 1000)
obs.getChr should === (exp.getChr) obs.getSequence should === (exp.getSequence)
obs.getStart should === (exp.getStart) obs.getStart should === (exp.getStart)
obs.getEnd should === (exp.getEnd) obs.getEnd should === (exp.getEnd)
} }
@Test def testIntervalError() = @Test def testIntervalError() = {
intercept[IllegalArgumentException] { val thrown = intercept[IllegalArgumentException] {
makeFeatureFromString(List("chr5:1000-")).next() makeIntervalFromString(List("chr5:1000-")).next()
}
thrown.getMessage should === ("Invalid interval string: chr5:1000-")
}
@Test def testMemFuncIntervalError() = {
val iv = Iterator(new Interval("chrP", 1, 1000))
val inAln = resourceFile("/single01.bam")
val thrown = intercept[IllegalArgumentException] {
makeMembershipFunction(iv, inAln)
} }
thrown.getMessage should === ("Chromosome chrP is not found in the alignment file")
}
@DataProvider(name = "singleAlnProvider1", parallel = true) @DataProvider(name = "singleAlnProvider1", parallel = true)
def singleAlnProvider1() = { def singleAlnProvider1() = {
...@@ -84,20 +95,20 @@ class ExtractAlignedFastqUnitTest extends TestNGSuite with MockitoSugar with Mat ...@@ -84,20 +95,20 @@ class ExtractAlignedFastqUnitTest extends TestNGSuite with MockitoSugar with Mat
Array( Array(
Array("adjacent left", Array("adjacent left",
makeFeature("chrQ", 30, 49), sBam01, sFastq1, sFastq1Default), makeInterval("chrQ", 30, 49), sBam01, sFastq1, sFastq1Default),
Array("adjacent right", Array("adjacent right",
makeFeature("chrQ", 200, 210), sBam01, sFastq1, sFastq1Default), makeInterval("chrQ", 200, 210), sBam01, sFastq1, sFastq1Default),
Array("no overlap", Array("no overlap",
makeFeature("chrQ", 220, 230), sBam01, sFastq1, sFastq1Default), makeInterval("chrQ", 220, 230), sBam01, sFastq1, sFastq1Default),
Array("partial overlap", Array("partial overlap",
makeFeature("chrQ", 430, 460), sBam01, sFastq1, sFastq1Default.updated("r04", true)), makeInterval("chrQ", 430, 460), sBam01, sFastq1, sFastq1Default.updated("r04", true)),
Array("enveloped", Array("enveloped",
makeFeature("chrQ", 693, 698), sBam01, sFastq1, sFastq1Default.updated("r03", true)) makeInterval("chrQ", 693, 698), sBam01, sFastq1, sFastq1Default.updated("r03", true))
) )
} }
@Test(dataProvider = "singleAlnProvider1") @Test(dataProvider = "singleAlnProvider1")
def testSingleBamDefault(name: String, feat: Feature, inAln: File, def testSingleBamDefault(name: String, feat: Interval, inAln: File,
fastqMap: Map[String, FastqPair], resultMap: Map[String, Boolean]) = { fastqMap: Map[String, FastqPair], resultMap: Map[String, Boolean]) = {
require(resultMap.keySet == fastqMap.keySet) require(resultMap.keySet == fastqMap.keySet)
val memFunc = makeMembershipFunction(Iterator(feat), inAln) val memFunc = makeMembershipFunction(Iterator(feat), inAln)
...@@ -116,16 +127,16 @@ class ExtractAlignedFastqUnitTest extends TestNGSuite with MockitoSugar with Mat ...@@ -116,16 +127,16 @@ class ExtractAlignedFastqUnitTest extends TestNGSuite with MockitoSugar with Mat
Array( Array(
Array("less than minimum MAPQ", Array("less than minimum MAPQ",
makeFeature("chrQ", 830, 890), sBam02, 60, sFastq2, sFastq2Default), makeInterval("chrQ", 830, 890), sBam02, 60, sFastq2, sFastq2Default),
Array("greater than minimum MAPQ", Array("greater than minimum MAPQ",
makeFeature("chrQ", 830, 890), sBam02, 20, sFastq2, sFastq2Default.updated("r07", true)), makeInterval("chrQ", 830, 890), sBam02, 20, sFastq2, sFastq2Default.updated("r07", true)),
Array("equal to minimum MAPQ", Array("equal to minimum MAPQ",
makeFeature("chrQ", 260, 320), sBam02, 30, sFastq2, sFastq2Default.updated("r01", true)) makeInterval("chrQ", 260, 320), sBam02, 30, sFastq2, sFastq2Default.updated("r01", true))
) )
} }
@Test(dataProvider = "singleAlnProvider2") @Test(dataProvider = "singleAlnProvider2")
def testSingleBamMinMapQ(name: String, feat: Feature, inAln: File, minMapQ: Int, def testSingleBamMinMapQ(name: String, feat: Interval, inAln: File, minMapQ: Int,
fastqMap: Map[String, FastqPair], resultMap: Map[String, Boolean]) = { fastqMap: Map[String, FastqPair], resultMap: Map[String, Boolean]) = {
require(resultMap.keySet == fastqMap.keySet) require(resultMap.keySet == fastqMap.keySet)
val memFunc = makeMembershipFunction(Iterator(feat), inAln, minMapQ) val memFunc = makeMembershipFunction(Iterator(feat), inAln, minMapQ)
...@@ -148,22 +159,22 @@ class ExtractAlignedFastqUnitTest extends TestNGSuite with MockitoSugar with Mat ...@@ -148,22 +159,22 @@ class ExtractAlignedFastqUnitTest extends TestNGSuite with MockitoSugar with Mat
Array( Array(
Array("adjacent left", Array("adjacent left",
makeFeature("chrQ", 30, 49), pBam01, pFastq1, pFastq1Default), makeInterval("chrQ", 30, 49), pBam01, pFastq1, pFastq1Default),
Array("adjacent right", Array("adjacent right",
makeFeature("chrQ", 200, 210), pBam01, pFastq1, pFastq1Default), makeInterval("chrQ", 200, 210), pBam01, pFastq1, pFastq1Default),
Array("no overlap", Array("no overlap",
makeFeature("chrQ", 220, 230), pBam01, pFastq1, pFastq1Default), makeInterval("chrQ", 220, 230), pBam01, pFastq1, pFastq1Default),
Array("partial overlap", Array("partial overlap",
makeFeature("chrQ", 430, 460), pBam01, pFastq1, pFastq1Default.updated("r04", true)), makeInterval("chrQ", 430, 460), pBam01, pFastq1, pFastq1Default.updated("r04", true)),
Array("enveloped", Array("enveloped",
makeFeature("chrQ", 693, 698), pBam01, pFastq1, pFastq1Default.updated("r03", true)), makeInterval("chrQ", 693, 698), pBam01, pFastq1, pFastq1Default.updated("r03", true)),
Array("in intron", Array("in intron",
makeFeature("chrQ", 900, 999), pBam01, pFastq1, pFastq1Default.updated("r05", true)) makeInterval("chrQ", 900, 999), pBam01, pFastq1, pFastq1Default.updated("r05", true))
) )
} }
@Test(dataProvider = "pairAlnProvider1") @Test(dataProvider = "pairAlnProvider1")
def testPairBamDefault(name: String, feat: Feature, inAln: File, def testPairBamDefault(name: String, feat: Interval, inAln: File,
fastqMap: Map[String, FastqPair], resultMap: Map[String, Boolean]) = { fastqMap: Map[String, FastqPair], resultMap: Map[String, Boolean]) = {
require(resultMap.keySet == fastqMap.keySet) require(resultMap.keySet == fastqMap.keySet)
val memFunc = makeMembershipFunction(Iterator(feat), inAln, commonSuffixLength = 2) val memFunc = makeMembershipFunction(Iterator(feat), inAln, commonSuffixLength = 2)
...@@ -175,13 +186,13 @@ class ExtractAlignedFastqUnitTest extends TestNGSuite with MockitoSugar with Mat ...@@ -175,13 +186,13 @@ class ExtractAlignedFastqUnitTest extends TestNGSuite with MockitoSugar with Mat
} }
@Test def testWriteSingleBamDefault() = { @Test def testWriteSingleBamDefault() = {
val memFunc = (recs: FastqPair) => Set("r01", "r03").contains(recs._1.getReadHeader) val memFunc = (recs: FastqPair) => Set("r01", "r03").contains(recs._1.getReadHeader)
val in1 = new FastqReader(resourceFile("/single01.fq")) val in1 = new FastqReader(resourceFile("/single01.fq"))
val mo1 = mock[BasicFastqWriter] val mo1 = mock[BasicFastqWriter]
selectFastqReads(memFunc, in1, mo1) selectFastqReads(memFunc, in1, mo1)
verify(mo1, times(2)).write(anyObject.asInstanceOf[FastqRecord]) verify(mo1, times(2)).write(anyObject.asInstanceOf[FastqRecord])
verify(mo1).write(new FastqRecord("r01", "A", "", "H")) verify(mo1).write(new FastqRecord("r01", "A", "", "H"))
verify(mo1).write(new FastqRecord("r03", "G", "", "H")) verify(mo1).write(new FastqRecord("r03", "G", "", "H"))
} }
@Test def testWritePairBamDefault() = { @Test def testWritePairBamDefault() = {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment