Skip to content

Commit

Permalink
Let the DuplexConsensusCaller support UMI pairs with one absent
Browse files Browse the repository at this point in the history
  • Loading branch information
clintval committed Dec 30, 2023
1 parent d510954 commit 9d5a422
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@
package com.fulcrumgenomics.umi

import java.lang.Math.min

import com.fulcrumgenomics.FgBioDef._
import com.fulcrumgenomics.bam.api.SamRecord
import com.fulcrumgenomics.commons.util.LazyLogging
import com.fulcrumgenomics.umi.DuplexConsensusCaller._
import com.fulcrumgenomics.umi.UmiConsensusCaller.ReadType.{ReadType, _}
import com.fulcrumgenomics.umi.UmiConsensusCaller.{SimpleRead, SourceRead}
import com.fulcrumgenomics.umi.Umis.UmiSeparatorPattern
import com.fulcrumgenomics.util.NumericTypes.PhredScore

/**
Expand Down Expand Up @@ -324,7 +324,7 @@ class DuplexConsensusCaller(override val readNamePrefix: String,
// UMI bases are present, `None` otherwise.
reads.flatMap(_.sam).flatMap { rec =>
rec.get[String](ConsensusTags.UmiBases).map { umi =>
if (rec.firstOfPair == firstOfPair) umi else umi.split('-').reverse.mkString("-")
if (rec.firstOfPair == firstOfPair) umi else UmiSeparatorPattern.split(umi, -1).reverse.mkString("-")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,29 @@ class DuplexConsensusCallerTest extends UnitSpec with OptionValues {
r2.quals(0) > 30 shouldBe true
}

Seq(
Seq("right", "ACT-", "-ACT"),
Seq("left", "-ACT", "ACT-"),
).foreach { case Seq(orientation, leftUmi, rightUmi) =>
it should s"create a simple double stranded consensus for a pair of A and a pair of B reads in which the $orientation UMI is absent" in {
val builder = new SamBuilder(readLength = 10, baseQuality = 20)
builder.addPair(name = "q1", start1 = 100, start2 = 200, strand1 = Plus, strand2 = Minus, bases1 = "AAAAAAAAAA", bases2 = "CCCCCCCCCC", attrs = Map(MI -> "foo/A", RX -> leftUmi))
builder.addPair(name = "q2", start1 = 200, start2 = 100, strand1 = Minus, strand2 = Plus, bases1 = "CCCCCCCCCC", bases2 = "AAAAAAAAAA", attrs = Map(MI -> "foo/B", RX -> rightUmi))

val recs = c.consensusReadsFromSamRecords(builder.toSeq)
recs should have size 2
val r1 = recs.find(_.firstOfPair).getOrElse(fail("No first of pair."))
val r2 = recs.find(_.secondOfPair).getOrElse(fail("No second of pair."))
r1.basesString shouldBe "AAAAAAAAAA"
r2.basesString shouldBe "GGGGGGGGGG" // after un-revcomping
r1.quals(0) > 30 shouldBe true
r2.quals(0) > 30 shouldBe true
// Both R1 and R2 inherit the RX pattern of the "A" family which is the left-oriented read pair in this test.
r1.get[String](RX) shouldBe Some(leftUmi)
r2.get[String](RX) shouldBe Some(leftUmi)
}
}

Seq(true).foreach { allowSingleStrand =>
val extraName: String = if (allowSingleStrand) "" else "not "
Seq("A", "B").foreach { duplexStrand =>
Expand Down

0 comments on commit 9d5a422

Please sign in to comment.