public void TryStitch_CalculateStitchedCigar() { // ----------------------------------------------- // Read position maps disagree // ----------------------------------------------- // Should throw out the pair var read1 = TestHelper.CreateRead("chr1", "ATCGATCG", 12345, new CigarAlignment("2M2D3M1D3M"), qualityForAll: 30); //Within the overlap, we have a deletion so there will be a shifting of positions from that point on var read2 = TestHelper.CreateRead("chr1", "ATCGATCG", 12349, new CigarAlignment("8M"), qualityForAll: 30); var stitcher = StitcherTestHelpers.GetStitcher(10); var alignmentSet = new AlignmentSet(read1, read2); Assert.True(!alignmentSet.ReadsForProcessing.Any()); // ----------------------------------------------- // When calculating stitched cigar, stitched cigar should have // - everything from read1 before the overlap // - everything from read2 starting from the overlap // But since we ensure that the position maps agree in the overlap region, it's really not a matter of one taking precedence over the other // 1234... 1 - - 2 3 4 5 6 - - 7 8 9 0 // Read1 X X X X X X X X - - - - - // Read1 M I I M M M M M - - - - - // Read2 - - - X X X X X X X X - - // Read2 - - - M M M M M I M M - - // ----------------------------------------------- // Stitched cigar should have R1's insertion from before the overlap and R2's insertion from after the overlap read1 = TestHelper.CreateRead("chr1", "ATCGATCG", 12341, new CigarAlignment("1M2I5M"), qualityForAll: 30); read2 = TestHelper.CreateRead("chr1", "ATCGATCG", 12342, new CigarAlignment("5M1I2M"), qualityForAll: 30); stitcher = StitcherTestHelpers.GetStitcher(10); alignmentSet = new AlignmentSet(read1, read2); stitcher.TryStitch(alignmentSet); Assert.Equal("1M2I5M1I2M", StitcherTestHelpers.GetMergedRead(alignmentSet).CigarData.ToString()); }
public void TryStitch_ConsensusSequence() { // 1234... 1 - - 2 3 4 5 6 - - 7 8 9 0 //Reference Positions // Read1 X X X X X X X X - - - - - // Read1 M I I M M M M M - - - - - // Read1 A T C G A T C G - - - - - // Read2 - - - X X X X X X X X - - // Read2 - - - M M M M M I M M - - // Read2 - - - A T C G A T C G - - var r1qualities = 30; var r2qualities = 20; var read1 = TestHelper.CreateRead("chr1", "TTTTTTTT", 12341, new CigarAlignment("1M2I5M"), qualityForAll: (byte)r1qualities); var read2 = TestHelper.CreateRead("chr1", "AAAAAAAA", 12342, new CigarAlignment("5M1I2M"), qualityForAll: (byte)r2qualities); var stitcher = StitcherTestHelpers.GetStitcher(10); var alignmentSet = new AlignmentSet(read1, read2); stitcher.TryStitch(alignmentSet); // Merged A T C ? ? ? ? ? T C G - - // Merged M I I M M M M M I M M - - // Merged 0 1 2 3 4 5 6 7 8 9 0 1 2 var overlapStart = 3; var overlapEnd = 8; var overlapLength = 5; //Consensus sequence should have everything from read1 for positions before overlap var mergedRead = StitcherTestHelpers.GetMergedRead(alignmentSet); Assert.Equal("TTT", mergedRead.Sequence.Substring(0, overlapStart)); //Consensus sequence should have everything from read2 for positions after overlap Assert.Equal("AAA", mergedRead.Sequence.Substring(overlapEnd, 3)); //Consensus sequence should have an N where we have two high-quality (both above min) disagreeing bases Assert.Equal("NNNNN", mergedRead.Sequence.Substring(overlapStart, 5)); //Consensus sequence should have 0 quality where we have two high-quality (both above min) disagreeing bases Assert.True(mergedRead.Qualities.Take(overlapStart).All(q => q == r1qualities)); Assert.True(mergedRead.Qualities.Skip(overlapStart).Take(overlapLength).All(q => q == 0)); Assert.True(mergedRead.Qualities.Skip(overlapEnd).Take(mergedRead.Sequence.Length - overlapEnd).All(q => q == r2qualities)); //Consensus sequence should take higher quality base if one or more of the bases is below min quality //Read 2 trumps whole overlap read1.BamAlignment.Qualities = new byte[] { 30, 30, 30, 5, 5, 5, 5, 5 }; read2.BamAlignment.Qualities = new byte[] { 40, 40, 40, 40, 40, 20, 19, 18 }; alignmentSet = new AlignmentSet(read1, read2); stitcher.TryStitch(alignmentSet); mergedRead = StitcherTestHelpers.GetMergedRead(alignmentSet); Assert.Equal(read2.Sequence.Substring(0, 5), mergedRead.Sequence.Substring(overlapStart, 5)); Assert.Equal("TTTAAAAAAAA", mergedRead.Sequence); StitcherTestHelpers.CompareQuality(new byte[] { 30, 30, 30, 40, 40, 40, 40, 40, 20, 19, 18 }, mergedRead.Qualities); //Read 1 trumps whole overlap read1.BamAlignment.Qualities = new byte[] { 30, 30, 30, 40, 40, 40, 40, 40 }; read2.BamAlignment.Qualities = new byte[] { 5, 5, 5, 5, 5, 20, 19, 18 }; alignmentSet = new AlignmentSet(read1, read2); stitcher.TryStitch(alignmentSet); mergedRead = StitcherTestHelpers.GetMergedRead(alignmentSet); Assert.Equal(read1.Sequence.Substring(3, 5), mergedRead.Sequence.Substring(overlapStart, 5)); Assert.Equal("TTTTTTTTAAA", mergedRead.Sequence); StitcherTestHelpers.CompareQuality(new byte[] { 30, 30, 30, 40, 40, 40, 40, 40, 20, 19, 18 }, mergedRead.Qualities); //Little bit of each read1.BamAlignment.Qualities = new byte[] { 30, 30, 30, 5, 45, 5, 45, 5 }; read2.BamAlignment.Qualities = new byte[] { 40, 5, 40, 5, 40, 20, 19, 18 }; alignmentSet = new AlignmentSet(read1, read2); stitcher.TryStitch(alignmentSet); mergedRead = StitcherTestHelpers.GetMergedRead(alignmentSet); Assert.Equal("TTTATATAAAA", mergedRead.Sequence); StitcherTestHelpers.CompareQuality(new byte[] { 30, 30, 30, 40, 45, 40, 45, 40, 20, 19, 18 }, mergedRead.Qualities); //Consensus sequence should take base and assign the higher quality if both bases agree var read2_agreeingBases = TestHelper.CreateRead("chr1", "TTTTTTTT", 12342, new CigarAlignment("5M1I2M"), new byte[] { 40, 5, 40, 5, 40, 20, 19, 18 }); read1.BamAlignment.Qualities = new byte[] { 30, 30, 30, 5, 45, 5, 45, 5 }; alignmentSet = new AlignmentSet(read1, read2_agreeingBases); stitcher.TryStitch(alignmentSet); mergedRead = StitcherTestHelpers.GetMergedRead(alignmentSet); Assert.Equal("TTTTTTTTTTT", mergedRead.Sequence); StitcherTestHelpers.CompareQuality(new byte[] { 30, 30, 30, 40, 45, 40, 45, 40, 20, 19, 18 }, mergedRead.Qualities); //Bases disagree and both are below minimum quality, read1>read2 : take base/q from read1 read1.BamAlignment.Qualities = new byte[] { 30, 30, 30, 8, 8, 8, 8, 8 }; read2.BamAlignment.Qualities = new byte[] { 5, 5, 5, 5, 5, 20, 19, 18 }; alignmentSet = new AlignmentSet(read1, read2); stitcher.TryStitch(alignmentSet); mergedRead = StitcherTestHelpers.GetMergedRead(alignmentSet); Assert.Equal(read1.Sequence.Substring(3, 5), mergedRead.Sequence.Substring(overlapStart, 5)); Assert.Equal("TTTTTTTTAAA", mergedRead.Sequence); StitcherTestHelpers.CompareQuality(new byte[] { 30, 30, 30, 8, 8, 8, 8, 8, 20, 19, 18 }, mergedRead.Qualities); //Bases disagree and both are below minimum quality, read2>read1 : take base/q from read2 read1.BamAlignment.Qualities = new byte[] { 30, 30, 30, 5, 5, 5, 5, 5 }; read2.BamAlignment.Qualities = new byte[] { 8, 8, 8, 8, 8, 20, 19, 18 }; alignmentSet = new AlignmentSet(read1, read2); stitcher.TryStitch(alignmentSet); mergedRead = StitcherTestHelpers.GetMergedRead(alignmentSet); Assert.Equal(read2.Sequence.Substring(0, 5), mergedRead.Sequence.Substring(overlapStart, 5)); Assert.Equal("TTTAAAAAAAA", mergedRead.Sequence); StitcherTestHelpers.CompareQuality(new byte[] { 30, 30, 30, 8, 8, 8, 8, 8, 20, 19, 18 }, mergedRead.Qualities); //Bases disagree and both are below minimum quality, read1==read2 : take base/q from read1 read1.BamAlignment.Qualities = new byte[] { 30, 30, 30, 5, 5, 5, 5, 5 }; read2.BamAlignment.Qualities = new byte[] { 5, 5, 5, 5, 5, 20, 19, 18 }; alignmentSet = new AlignmentSet(read1, read2); stitcher.TryStitch(alignmentSet); mergedRead = StitcherTestHelpers.GetMergedRead(alignmentSet); Assert.Equal(read1.Sequence.Substring(3, 5), mergedRead.Sequence.Substring(overlapStart, 5)); Assert.Equal("TTTTTTTTAAA", mergedRead.Sequence); StitcherTestHelpers.CompareQuality(new byte[] { 30, 30, 30, 5, 5, 5, 5, 5, 20, 19, 18 }, mergedRead.Qualities); }
public void TryStitch_WithXCTag() { const string xcTagDiffFromCalculated = "4M2I4M"; const string expectedCalculatedCigar = "10M"; var read1 = TestHelper.CreateRead("chr1", "ATCGATCG", 12345, new CigarAlignment("8M"), qualityForAll: 30); var read2_overlap = TestHelper.CreateRead("chr1", "ATCGTT", 12349, new CigarAlignment("6M"), qualityForAll: 30); var stitcher = StitcherTestHelpers.GetStitcher(10); // ----------------------------------------------- // XC tag is available, and matching between R1 and R2, and expected length, // but is different from the cigar string we would have calculated // ----------------------------------------------- // XC tag should be taken read1.StitchedCigar = new CigarAlignment(xcTagDiffFromCalculated); read2_overlap.StitchedCigar = new CigarAlignment(xcTagDiffFromCalculated); var alignmentSet = new AlignmentSet(read1, read2_overlap); stitcher.TryStitch(alignmentSet); var mergedRead = StitcherTestHelpers.GetMergedRead(alignmentSet); Assert.Equal(xcTagDiffFromCalculated, mergedRead.CigarData.ToString()); // ----------------------------------------------- // XC tag is there, and matching between R1 and R2, but not expected length // ----------------------------------------------- // XC tag should be ignored if it is not expected length, and new cigar should be calculated read1.StitchedCigar = new CigarAlignment("8M"); read2_overlap.StitchedCigar = new CigarAlignment("8M"); alignmentSet = new AlignmentSet(read1, read2_overlap); stitcher.TryStitch(alignmentSet); mergedRead = StitcherTestHelpers.GetMergedRead(alignmentSet); Assert.Equal(expectedCalculatedCigar, mergedRead.CigarData.ToString()); // ----------------------------------------------- // XC tag is there on one read but not the other // ----------------------------------------------- // XC tag should be ignored, and new cigar should be calculated read1.StitchedCigar = null; read2_overlap.StitchedCigar = new CigarAlignment("9M1I"); alignmentSet = new AlignmentSet(read1, read2_overlap); stitcher.TryStitch(alignmentSet); mergedRead = StitcherTestHelpers.GetMergedRead(alignmentSet); Assert.Equal(expectedCalculatedCigar, mergedRead.CigarData.ToString()); read1.StitchedCigar = new CigarAlignment("9M1I"); read2_overlap.StitchedCigar = null; alignmentSet = new AlignmentSet(read1, read2_overlap); stitcher.TryStitch(alignmentSet); mergedRead = StitcherTestHelpers.GetMergedRead(alignmentSet); Assert.Equal(expectedCalculatedCigar, mergedRead.CigarData.ToString()); // ----------------------------------------------- // XC tag is not there // ----------------------------------------------- // New cigar should be calculated read1.StitchedCigar = null; read2_overlap.StitchedCigar = null; alignmentSet = new AlignmentSet(read1, read2_overlap); stitcher.TryStitch(alignmentSet); mergedRead = StitcherTestHelpers.GetMergedRead(alignmentSet); Assert.Equal(expectedCalculatedCigar, mergedRead.CigarData.ToString()); }