public void TryStitch_SoftclipScenarios() { //Migrated from old Pisces: Originally called Pisces_MergeRead2First var sequence = "GG" + "GGCCACGCGGGGAGCAGCCTCTGGCATTCTGGGAGCTTCATCTGGACCTGGGTCTTCAGTGAACCATTGTTCAATATCGTCCGGGGACAGCATCAAATCATCCATTGCTTGGGACGGCAAGG" + "GGGACTGTAGATGGGTGAAAAGAGCA"; var read1 = ReadTestHelper.CreateRead("chr1", sequence, 7579464, new CigarAlignment("2S122M26S"), Enumerable.Repeat((byte)30, sequence.Length).ToArray(), 7579464); StitcherTestHelpers.SetReadDirections(read1, DirectionType.Forward); sequence = "GTGTAGGAGCTGCTGGTGCAGG" + "GGCCACGCGGGGAGCAGCCTCTGGCATTCTGGGAGCTTCATCTGGACCTGGGTCTTCAGTGAACAATTGTTCAATATCGTCCGGGGCCAGCATCAAATCATCCATTGCTTGGGACGGCAAGG" + "GGGACT"; var read2 = ReadTestHelper.CreateRead("chr1", sequence, 7579464, new CigarAlignment("22S122M6S"), Enumerable.Repeat((byte)30, sequence.Length).ToArray(), 7579464); StitcherTestHelpers.SetReadDirections(read2, DirectionType.Reverse); string expectedWithNify = "GTGTAGGAGCTGCTGGTGCAGG" + "GGCCACGCGGGGAGCAGCCTCTGGCATTCTGGGAGCTTCATCTGGACCTGGGTCTTCAGTGAACNATTGTTCAATATCGTCCGGGGNCAGCATCAAATCATCCATTGCTTGGGACGGCAAGG" + "GGGACTGTAGATGGGTGAAAAGAGCA"; string expectedWithNoNify = "GTGTAGGAGCTGCTGGTGCAGG" + "GGCCACGCGGGGAGCAGCCTCTGGCATTCTGGGAGCTTCATCTGGACCTGGGTCTTCAGTGAACCATTGTTCAATATCGTCCGGGGACAGCATCAAATCATCCATTGCTTGGGACGGCAAGG" + "GGGACTGTAGATGGGTGAAAAGAGCA"; // both reads have the same reference position, but read2 really starts earlier // make sure we behave properly TestSuccesfullyStitchedRead(read1, read2, 0, "22S122M26S", (mergedRead) => { Assert.NotNull(mergedRead); Assert.Equal("22R122S26F", mergedRead.CigarDirections.ToString()); Assert.Equal(expectedWithNify, mergedRead.Sequence); }, nifyDisagreements: true); // Test with allowing probe softclips to merge TestSuccesfullyStitchedRead(read1, read2, 0, "22S122M26S", (mergedRead) => { Assert.NotNull(mergedRead); Assert.Equal("20R130S20F", mergedRead.CigarDirections.ToString()); Assert.Equal(expectedWithNify, mergedRead.Sequence); }, nifyDisagreements: true, ignoreProbeSoftclips: false); //here, the Q scores where we disagree are equal (30) so we give R1 the preference (R1 usually being better than R2, if we are forced to pick one) read1.BamAlignment.SetIsFirstMate(true); read2.BamAlignment.SetIsFirstMate(false); TestSuccesfullyStitchedRead(read1, read2, 0, "22S122M26S", (mergedRead) => { Assert.NotNull(mergedRead); Assert.Equal(expectedWithNoNify, mergedRead.Sequence); }, nifyDisagreements: false); }
public void GenerateNifiedMergedRead() { var read1 = DomainTestHelper.CreateRead("chr1", "AAAAA", 2, new CigarAlignment("1S4M")); var read2 = DomainTestHelper.CreateRead("chr1", "AAAAA", 2, new CigarAlignment("4M1S")); StitcherTestHelpers.SetReadDirections(read2, DirectionType.Reverse); var alignmentSet = new AlignmentSet(read1, read2); var stitchedRead = GetStitchedRead(alignmentSet); Assert.Equal("1S4M1S", stitchedRead.StitchedCigar.ToString()); Assert.Equal("NNNNNN", stitchedRead.Sequence); Assert.Equal("1F4S1R", stitchedRead.CigarDirections.ToString()); StitcherTestHelpers.SetReadDirections(read1, DirectionType.Reverse); StitcherTestHelpers.SetReadDirections(read2, DirectionType.Forward); stitchedRead = GetStitchedRead(alignmentSet); Assert.Equal("1S4M1S", stitchedRead.StitchedCigar.ToString()); Assert.Equal("NNNNNN", stitchedRead.Sequence); Assert.Equal("1R4S1F", stitchedRead.CigarDirections.ToString()); StitcherTestHelpers.SetReadDirections(read1, DirectionType.Forward); StitcherTestHelpers.SetReadDirections(read2, DirectionType.Reverse); // Insertion that we don't know what to do with -> Nified match read1 = DomainTestHelper.CreateRead("chr1", "AAAAA", 2, new CigarAlignment("1S3M1I")); alignmentSet = new AlignmentSet(read1, read2); stitchedRead = GetStitchedRead(alignmentSet); Assert.Equal("1S4M1S", stitchedRead.StitchedCigar.ToString()); Assert.Equal("NNNNNN", stitchedRead.Sequence); Assert.Equal("1F4S1R", stitchedRead.CigarDirections.ToString()); // Read 1 goes to end of read 2 read1 = DomainTestHelper.CreateRead("chr1", "AAAAAA", 2, new CigarAlignment("1S3M2I")); alignmentSet = new AlignmentSet(read1, read2); stitchedRead = GetStitchedRead(alignmentSet); Assert.Equal("1S5M", stitchedRead.StitchedCigar.ToString()); Assert.Equal("NNNNNN", stitchedRead.Sequence); Assert.Equal("1F5S", stitchedRead.CigarDirections.ToString()); // Read 1 goes past read 2 read1 = DomainTestHelper.CreateRead("chr1", "AAAAAAA", 2, new CigarAlignment("1S3M3I")); alignmentSet = new AlignmentSet(read1, read2); stitchedRead = GetStitchedRead(alignmentSet); Assert.Equal("1S6M", stitchedRead.StitchedCigar.ToString()); Assert.Equal("NNNNNNN", stitchedRead.Sequence); Assert.Equal("1F5S1F", stitchedRead.CigarDirections.ToString()); }
private void TestMerge(int pos1, string cigar1, int pos2, string cigar2, int posStitch = 0, string cigarStitch = "", string stitchDirections = "", bool shouldMerge = true, bool ignoreProbeSoftclips = true, int?maxReadLength = null) { var r1Bases = new string('A', (int)new CigarAlignment(cigar1).GetReadSpan()); var r2Bases = new string('A', (int)new CigarAlignment(cigar2).GetReadSpan()); var read1 = DomainTestHelper.CreateRead("chr1", r1Bases, pos1, new CigarAlignment(cigar1)); var read2 = DomainTestHelper.CreateRead("chr1", r2Bases, pos2, new CigarAlignment(cigar2)); StitcherTestHelpers.SetReadDirections(read2, DirectionType.Reverse); BasicStitcher stitcher; if (maxReadLength != null) { stitcher = new BasicStitcher(10, ignoreProbeSoftclips: ignoreProbeSoftclips, maxReadLength: maxReadLength.Value); } else { // Use the default stitcher = new BasicStitcher(10, ignoreProbeSoftclips: ignoreProbeSoftclips); } if (!shouldMerge) { var alignmentSet = new AlignmentSet(read1, read2); Assert.False(stitcher.TryStitch(alignmentSet)); //StitcherTestHelpers.TestUnstitchableReads(read1, read2, 0, null); } else { var alignmentSet = new AlignmentSet(read1, read2); var didStitch = stitcher.TryStitch(alignmentSet); Assert.True(didStitch); var mergedRead = StitcherTestHelpers.GetMergedRead(alignmentSet); Console.WriteLine(mergedRead.Position + " " + mergedRead.CigarData); Console.WriteLine("---------------"); if (cigarStitch != "") { Assert.Equal(posStitch, mergedRead.Position); Assert.Equal(cigarStitch, mergedRead.CigarData.ToString()); } if (stitchDirections != "") { Assert.Equal(stitchDirections, mergedRead.CigarDirections.ToString()); } } }
public void TryStitch_RealExamples() { // Real example from Kristina's problematic variant #73 var read1Bases = "GAAGCCACACTGACGTGCCTCTCCCTCCCTCCAGGAAGCCTTCCAGGAAGCCTACGTGATGGCCAGCGTGGACAACCCCCACGTGTGCCGCCTGCTGGGCATCTGCCTCACCTCCACCGTGCAGCTCATCACGCAGCTCATGCCCTTCGG"; var read2Bases = "AGGAAGCCTTCCAGGAAGCCTACGTGATGGCCAGCGTGGACAACCCCCACGTGTGCCGCCTGCTGGGCATCTGCCTCACCTCCACCGTGCAGCTCATCACGCAGCTCATGCCCTTCGGCTGCCTCCTGGACTATGTCCGGGAACACAAAG"; var read1 = DomainTestHelper.CreateRead("chr7", read1Bases, 55248972, new CigarAlignment("20S9M12I109M")); var read2 = DomainTestHelper.CreateRead("chr7", read2Bases, 55248981, new CigarAlignment("9S120M21S")); StitcherTestHelpers.SetReadDirections(read2, DirectionType.Reverse); var stitcher = new BasicStitcher(10, useSoftclippedBases: false); var alignmentSet = new AlignmentSet(read1, read2); stitcher.TryStitch(alignmentSet); var mergedRead = StitcherTestHelpers.GetMergedRead(alignmentSet); Assert.Equal("20S9M12I120M21S", mergedRead.CigarData.ToString()); Assert.Equal("41F109S32R", mergedRead.CigarDirections.ToString()); // Shouldn't stitch - problem Yu was having (tried to merge and then said the base at position 158 is null). read1Bases = "CGACGCTCTTGCGATCTTCAAAGCAATAGGATGGGTGATCAGGGATGTTGCTTACAAGAAAAGAACTGCCATACAGCTTCAACAACAACTTCTTCCACCCACCCCTAAAATGATGCTAAAAAGTAAGTCATCTCTGGTTCTCCCCCGATT"; read2Bases = "TCAAAGCAATAGGATGGATGATCAGAGATGTTGCTTACAAGAAAAGAACTGCCATACAGCTTCAACAACAACTTCTTCCACTCCCCCCTAAAGTGATGCTAAAAAGTAAATCATCCCTGTTTCTCCCCCGTTCGCGAATTTCTACGATCG"; read1 = DomainTestHelper.CreateRead("chr7", read1Bases, 109465121, new CigarAlignment("44S56M1I23M26S")); read2 = DomainTestHelper.CreateRead("chr7", read2Bases, 109465121, new CigarAlignment("27S55M1I24M43S")); StitcherTestHelpers.SetReadDirections(read2, DirectionType.Reverse); stitcher = new BasicStitcher(10, useSoftclippedBases: true); alignmentSet = new AlignmentSet(read1, read2); Assert.False(stitcher.TryStitch(alignmentSet)); }
public void TryStitch_MergeReadsSmall() { //Migrated from old Pisces: Originally called Pisces_MergeReadsSmall //test1: happy path //0 1 2 3 4 5 6 7 8 9 //- C A T A T //- - - - A T A G G var read1 = ReadTestHelper.CreateRead("chr1", "CATAT", 1, new CigarAlignment("5M"), new byte[] { 1, 2, 3, 4, 5 }, 4); StitcherTestHelpers.SetReadDirections(read1, DirectionType.Forward); var read2 = ReadTestHelper.CreateRead("chr1", "ATAGG", 4, new CigarAlignment("5M"), new byte[] { 1, 20, 30, 40, 50 }, 1); StitcherTestHelpers.SetReadDirections(read2, DirectionType.Reverse); var alignmentSet = new AlignmentSet(read1, read2); var stitcher = StitcherTestHelpers.GetStitcher(10, nifyDisagreements: false); stitcher.TryStitch(alignmentSet); TestSuccesfullyStitchedRead(read1, read2, 0, "8M", (mergedRead) => { Assert.Equal(mergedRead.Sequence, "CATATAGG"); StitcherTestHelpers.CompareQuality(new byte[] { 1, 2, 3, 5, 25, 30, 40, 50 }, mergedRead.Qualities); var expectedDirections = StitcherTestHelpers.BuildDirectionMap(new List <IEnumerable <DirectionType> > { StitcherTestHelpers.BuildDirectionSegment(DirectionType.Forward, 3), StitcherTestHelpers.BuildDirectionSegment(DirectionType.Stitched, 2), StitcherTestHelpers.BuildDirectionSegment(DirectionType.Reverse, 3) }); StitcherTestHelpers.VerifyDirectionType(expectedDirections, mergedRead.CigarDirections.Expand().ToArray()); }); //test2: different bases, one with low Q //0 1 2 3 4 5 6 7 8 9 //- C A T A G //- - - - A T A G G read1 = ReadTestHelper.CreateRead("chr1", "CATAG", 1, new CigarAlignment("5M"), new byte[] { 1, 2, 3, 4, 5 }, 4); StitcherTestHelpers.SetReadDirections(read1, DirectionType.Reverse); read2 = ReadTestHelper.CreateRead("chr1", "ATAGG", 4, new CigarAlignment("5M"), new byte[] { 1, 20, 30, 40, 50 }, 1); StitcherTestHelpers.SetReadDirections(read2, DirectionType.Forward); TestSuccesfullyStitchedRead(read1, read2, 10, "8M", (mergedRead) => { Assert.NotNull(mergedRead); Assert.Equal("CATATAGG", mergedRead.Sequence); StitcherTestHelpers.CompareQuality(new byte[] { 1, 2, 3, 5, 20, 30, 40, 50 }, mergedRead.Qualities); var expectedDirections = StitcherTestHelpers.BuildDirectionMap(new List <IEnumerable <DirectionType> > { StitcherTestHelpers.BuildDirectionSegment(DirectionType.Reverse, 3), StitcherTestHelpers.BuildDirectionSegment(DirectionType.Stitched, 2), StitcherTestHelpers.BuildDirectionSegment(DirectionType.Forward, 3) }); StitcherTestHelpers.VerifyDirectionType(expectedDirections, mergedRead.CigarDirections.Expand().ToArray()); }); //test3: different bases, both with high Q //0 1 2 3 4 5 6 7 8 9 //- C A T A G //- - - - A T A G G read1 = ReadTestHelper.CreateRead("chr1", "CATAG", 1, new CigarAlignment("5M"), new byte[] { 50, 92, 92, 92, 92 }, 4); read2 = ReadTestHelper.CreateRead("chr1", "ATAGG", 4, new CigarAlignment("5M"), new byte[] { 2, 20, 30, 40, 50 }, 1); StitcherTestHelpers.SetReadDirections(read1, DirectionType.Forward); StitcherTestHelpers.SetReadDirections(read2, DirectionType.Reverse); TestSuccesfullyStitchedRead(read1, read2, 10, "8M", (mergedRead) => { Assert.NotNull(mergedRead); Assert.Equal("CATANAGG", mergedRead.Sequence); StitcherTestHelpers.CompareQuality(new byte[] { 50, 92, 92, 93, 0, 30, 40, 50 }, mergedRead.Qualities); var expectedDirections = StitcherTestHelpers.BuildDirectionMap(new List <IEnumerable <DirectionType> > { StitcherTestHelpers.BuildDirectionSegment(DirectionType.Forward, 3), StitcherTestHelpers.BuildDirectionSegment(DirectionType.Stitched, 2), StitcherTestHelpers.BuildDirectionSegment(DirectionType.Reverse, 3) }); StitcherTestHelpers.VerifyDirectionType(expectedDirections, mergedRead.CigarDirections.Expand().ToArray()); }, nifyDisagreements: true); }
public void TryStitch_ReCo() { // Real example from ReCo, was failing to generate the correct stitched cigar var read1Bases = "GTACTCCTACAGTCCCACCCCTCCCCTATAAACCTTATGAATCCCCGTTCACTTAGATGCCAGCTTGGCAAGGAAGGGAAGTACACATCTGTTGACAGTAATGAAATATCCTTGATAAGGATTTAAATTTTGGATGTGCTG"; var read2Bases = "ACCTACAGTCCCACCCCTCCCCTATAAACCTTAGGAATCCCCGTTCACTTAGATGCCAGCTTGGCAAGGAAGGGAAGTACACATCTGTTGACAGTAATGAAATATCCTTGATAAGGATTTAAATTTTGGATGTGCTGAGCT"; // 8 9 // 3 4 5 6 7 8 9 0 1 2 // s s s s s M M M M M ... // - - - - M M M M M M ... // F F F F R S S S S S ... // Stitched directions if we don't allow softclip to contribute // F F F F S S S S S S ... // Stitched directions if we do allow softclip to contribute var read1 = DomainTestHelper.CreateRead("chr21", read1Bases, 16685488, new CigarAlignment("5S136M")); var read2 = DomainTestHelper.CreateRead("chr21", read2Bases, 16685487, new CigarAlignment("137M4S")); StitcherTestHelpers.SetReadDirections(read2, DirectionType.Reverse); var stitcher = new BasicStitcher(10, useSoftclippedBases: false); var alignmentSet = new AlignmentSet(read1, read2); stitcher.TryStitch(alignmentSet); // Without allowing softclips to count to support, should still get a M at an M/S overlap, but it won't be stitched. var mergedRead = StitcherTestHelpers.GetMergedRead(alignmentSet); Assert.Equal("4S137M4S", mergedRead.CigarData.ToString()); var expectedDirections = StitcherTestHelpers.BuildDirectionMap(new List <IEnumerable <DirectionType> > { StitcherTestHelpers.BuildDirectionSegment(DirectionType.Forward, 4), StitcherTestHelpers.BuildDirectionSegment(DirectionType.Reverse, 1), StitcherTestHelpers.BuildDirectionSegment(DirectionType.Stitched, 136), StitcherTestHelpers.BuildDirectionSegment(DirectionType.Reverse, 4) }); StitcherTestHelpers.VerifyDirectionType(expectedDirections, mergedRead.CigarDirections.Expand().ToArray()); stitcher = new BasicStitcher(10, useSoftclippedBases: true); alignmentSet = new AlignmentSet(read1, read2); stitcher.TryStitch(alignmentSet); mergedRead = StitcherTestHelpers.GetMergedRead(alignmentSet); Assert.Equal("4S137M4S", mergedRead.CigarData.ToString()); expectedDirections = StitcherTestHelpers.BuildDirectionMap(new List <IEnumerable <DirectionType> > { StitcherTestHelpers.BuildDirectionSegment(DirectionType.Forward, 4), StitcherTestHelpers.BuildDirectionSegment(DirectionType.Reverse, 1), StitcherTestHelpers.BuildDirectionSegment(DirectionType.Stitched, 136), StitcherTestHelpers.BuildDirectionSegment(DirectionType.Reverse, 4) }); StitcherTestHelpers.VerifyDirectionType(expectedDirections, mergedRead.CigarDirections.Expand().ToArray()); // If we're not ignoring probe softclips, go back to the original expected directions (1 more stitched from probe) stitcher = new BasicStitcher(10, useSoftclippedBases: true, ignoreProbeSoftclips: false); alignmentSet = new AlignmentSet(read1, read2); stitcher.TryStitch(alignmentSet); mergedRead = StitcherTestHelpers.GetMergedRead(alignmentSet); Assert.Equal("4S137M4S", mergedRead.CigarData.ToString()); expectedDirections = StitcherTestHelpers.BuildDirectionMap(new List <IEnumerable <DirectionType> > { StitcherTestHelpers.BuildDirectionSegment(DirectionType.Forward, 4), StitcherTestHelpers.BuildDirectionSegment(DirectionType.Stitched, 137), StitcherTestHelpers.BuildDirectionSegment(DirectionType.Reverse, 4) }); StitcherTestHelpers.VerifyDirectionType(expectedDirections, mergedRead.CigarDirections.Expand().ToArray()); }