public void TestALLtypePairedReadsInSAMFile() { string samfilePath = @"TestUtils\SAM\PairedReadsTest.sam"; using (SAMParser parser = new SAMParser()) { SequenceAlignmentMap map = parser.Parse(samfilePath); int TotalReadsCount = 77; int unpairedReadsCount = 2; int multipleHitsPairCount = 2; int multipleHitReadsCount = 8; int normalPairCount = 4; int normalreadsCount = 2 * normalPairCount; int orphanPairsCount = 3; int orphanreadsCount = 5; int chimerapaircount = 15; int chimerareadsCount = 2 * chimerapaircount; int strucAnomPairCount = 3; int strucAnomReadsCount = 2 * strucAnomPairCount; int lenAnomPairCount = 9; int LenAnomReadsCount = 2 * lenAnomPairCount; int total = unpairedReadsCount + multipleHitReadsCount + normalreadsCount + orphanreadsCount + chimerareadsCount + strucAnomReadsCount + LenAnomReadsCount; Assert.AreEqual(TotalReadsCount, total); IList <PairedRead> reads = map.GetPairedReads(200, 50); IList <PairedRead> multipleHits = reads.Where(PE => PE.PairedType == PairedReadType.MultipleHits).ToList(); IList <PairedRead> normal = reads.Where(PE => PE.PairedType == PairedReadType.Normal).ToList(); IList <PairedRead> orphan = reads.Where(PE => PE.PairedType == PairedReadType.Orphan).ToList(); IList <PairedRead> chimera = reads.Where(PE => PE.PairedType == PairedReadType.Chimera).ToList(); IList <PairedRead> strucAnom = reads.Where(PE => PE.PairedType == PairedReadType.StructuralAnomaly).ToList(); IList <PairedRead> lenAnom = reads.Where(PE => PE.PairedType == PairedReadType.LengthAnomaly).ToList(); Assert.AreEqual(TotalReadsCount, map.QuerySequences.Count); Assert.AreEqual(multipleHitsPairCount, multipleHits.Count()); Assert.AreEqual(multipleHitReadsCount, multipleHits.Sum(PE => PE.Reads.Count)); Assert.AreEqual(normalPairCount, normal.Count()); Assert.AreEqual(normalreadsCount, normal.Sum(PE => PE.Reads.Count)); Assert.AreEqual(orphanPairsCount, orphan.Count()); Assert.AreEqual(orphanreadsCount, orphan.Sum(PE => PE.Reads.Count)); Assert.AreEqual(chimerapaircount, chimera.Count()); Assert.AreEqual(chimerareadsCount, chimera.Sum(PE => PE.Reads.Count)); Assert.AreEqual(strucAnomPairCount, strucAnom.Count()); Assert.AreEqual(strucAnomReadsCount, strucAnom.Sum(PE => PE.Reads.Count)); Assert.AreEqual(lenAnomPairCount, lenAnom.Count()); Assert.AreEqual(LenAnomReadsCount, lenAnom.Sum(PE => PE.Reads.Count)); } }
public void TestGettingPairedReads() { string bamfilePath = @"TestUtils\BAM\SeqAlignment.bam"; BAMParser parser = null; try { parser = new BAMParser(); SequenceAlignmentMap alignmentMap = parser.Parse(bamfilePath); Assert.IsTrue(alignmentMap != null); IList <PairedRead> pairedReads = alignmentMap.GetPairedReads(); Assert.IsTrue(pairedReads.Count > 0); pairedReads = alignmentMap.GetPairedReads(250, 50); Assert.IsTrue(pairedReads.Count > 0); } finally { if (parser != null) { parser.Dispose(); } } }
/// <summary> /// Get Chimera data /// </summary> /// <param name="filename">Path of the BAM file</param> /// <param name="mean">Mean value</param> /// <param name="deviation">Standard deviation</param> /// <returns></returns> private Matrix <string, string, string> GetChimeraData(string filename) { SequenceAlignmentMap alignmentMapobj = null; if (!SAMInput) { BAMParser bamParser = new BAMParser(); alignmentMapobj = bamParser.Parse(filename); } else { SAMParser samParser = new SAMParser(); alignmentMapobj = samParser.Parse(filename); } // get reads from sequence alignment map object. IList <PairedRead> pairedReads = null; pairedReads = alignmentMapobj.GetPairedReads(200, 50); // select chimeras from reads. var chimeras = pairedReads.Where(PE => PE.PairedType == PairedReadType.Chimera); // Group chimeras based on first reads chromosomes name. var groupedChimeras = chimeras.GroupBy(PR => PR.Read1.RName); IList <string> chrs = alignmentMapobj.GetRefSequences(); // Declare sparse matrix to store statistics. SparseMatrix <string, string, string> statistics = SparseMatrix <string, string, string> .CreateEmptyInstance( chrs, chrs, "0"); // For each group create sub group depending on the second reads chromosomes. foreach (var group in groupedChimeras) { foreach (var subgroup in group.GroupBy(PE => PE.Read2.RName)) { // store the count to stats statistics[group.Key, subgroup.Key] = subgroup.Count().ToString(); } } return(statistics); }
/// <summary> /// Tests chromoses with orphan regions /// </summary> /// <param name="alignmentMapobj">Sequence alignment map.</param> private static void TestOrphanRegions(SequenceAlignmentMap alignmentMapobj) { string expectedOutput; string actualOutput; expectedOutput = "9437-9447:"; actualOutput = string.Empty; // get reads from sequence alignment map object. IList <PairedRead> pairedReads = null; pairedReads = alignmentMapobj.GetPairedReads(0, 0); // Get the orphan regions. var orphans = pairedReads.Where(PR => PR.PairedType == PairedReadType.Orphan); if (orphans.Count() == 0) { Assert.Fail(); } List <ISequenceRange> orphanRegions = new List <ISequenceRange>(orphans.Count()); foreach (PairedRead orphanRead in orphans) { orphanRegions.Add(GetRegion(orphanRead.Read1)); } // Get sequence range grouping object. SequenceRangeGrouping rangeGroup = new SequenceRangeGrouping(orphanRegions); SequenceRangeGrouping mergedRegions = rangeGroup.MergeOverlaps(); foreach (var range in mergedRegions.GroupRanges) { actualOutput += range.Start + "-" + range.End + ":"; } Assert.AreEqual(expectedOutput, actualOutput); }
/// <summary> /// Tests Chimeric stats. /// </summary> private static void TestChimeraData(SequenceAlignmentMap alignmentMapobj) { string expectedOutput; string actualOutput; expectedOutput = "varchr1chr2chr3chr4chr10320chr22040chr33100chr40000"; // get reads from sequence alignment map object. IList <PairedRead> pairedReads = null; pairedReads = alignmentMapobj.GetPairedReads(200, 50); // select chimeras from reads. var chimeras = pairedReads.Where(PE => PE.PairedType == PairedReadType.Chimera); // Group chimeras based on first reads chromosomes name. var groupedChimeras = chimeras.GroupBy(PR => PR.Read1.RName); IList <string> chrs = alignmentMapobj.GetRefSequences(); // Declare sparse matrix to store statistics. SparseMatrix <string, string, string> statistics = SparseMatrix <string, string, string> .CreateEmptyInstance( chrs, chrs, "0"); // For each group create sub group depending on the second reads chromosomes. foreach (var group in groupedChimeras) { foreach (var subgroup in group.GroupBy(PE => PE.Read2.RName)) { // store the count to stats statistics[group.Key, subgroup.Key] = subgroup.Count().ToString(CultureInfo.InvariantCulture); } } actualOutput = statistics.ToString2D().Replace(Environment.NewLine, "").Replace("\t", ""); Assert.AreEqual(expectedOutput, actualOutput); }
/// <summary> /// Indentify hot spot chromosomes for length anamoly regions. /// </summary> /// <param name="inputFile"> Input file</param> /// <param name="mean">Mean value</param> /// <param name="standardDeviation">Standard deviation</param> private void IdentifyLentghAnamolies(string filename, float mean = -1, float deviation = -1) { bool calculateMeanNdeviation = false; if (mean == -1 || deviation == -1) { calculateMeanNdeviation = true; } SequenceAlignmentMap alignmentMapobj = null; if (!SAMInput) { BAMParser bamParser = new BAMParser(); alignmentMapobj = bamParser.Parse(filename); } else { SAMParser samParser = new SAMParser(); alignmentMapobj = samParser.Parse(filename); } // get reads from sequence alignment map object. IList <PairedRead> pairedReads = null; if (calculateMeanNdeviation) { pairedReads = alignmentMapobj.GetPairedReads(); } else { pairedReads = alignmentMapobj.GetPairedReads(mean, deviation); } // Get the orphan regions. var orphans = pairedReads.Where(PR => PR.PairedType == PairedReadType.Orphan); if (orphans.Count() == 0) { Console.WriteLine("No Orphans to display"); } List <ISequenceRange> orphanRegions = new List <ISequenceRange>(orphans.Count()); foreach (PairedRead orphanRead in orphans) { orphanRegions.Add(GetRegion(orphanRead.Read1)); } // Get sequence range grouping for Orphan regions. SequenceRangeGrouping orphanRangegroup = new SequenceRangeGrouping(orphanRegions); // Get the Length anomalies regions. var lengthAnomalies = pairedReads.Where(PE => PE.PairedType == PairedReadType.LengthAnomaly); if (lengthAnomalies.Count() == 0) { Console.WriteLine("No Anomalies to display"); } List <ISequenceRange> lengthAnomalyRegions = new List <ISequenceRange>(lengthAnomalies.Count()); foreach (PairedRead laRead in lengthAnomalies) { SequenceRange range = new SequenceRange(); range.ID = laRead.Read1.RName; range.Start = laRead.Read1.Pos; range.End = laRead.Read1.Pos + laRead.InsertLength; lengthAnomalyRegions.Add(range); } // Get sequence range grouping for length anomaly regions. SequenceRangeGrouping lengthAnomalyRangegroup = new SequenceRangeGrouping(lengthAnomalyRegions); if (lengthAnomalyRangegroup.GroupIDs.Count() == 0) { Console.Write("\r\nNo Length anomalies reads to display"); } else { Console.Write("Region of length anomaly:"); DisplaySequenceRange(lengthAnomalyRangegroup); } if (orphanRangegroup.GroupIDs.Count() == 0) { Console.Write("\r\nNo Orphan reads to display"); } else { Console.Write("\r\nRegion of Orphan reads:"); DisplaySequenceRange(orphanRangegroup); } SequenceRangeGrouping intersectedRegions = lengthAnomalyRangegroup.Intersect(orphanRangegroup); if (intersectedRegions.GroupIDs.Count() == 0) { Console.Write("\r\nNo Hot spots found"); } else { Console.Write("\r\nChromosomal Hot spot of length anomaly and Orphan region:"); DisplaySequenceRange(intersectedRegions); } }
/// <summary> /// Get chromoses with orphan regions /// </summary> /// <param name="filename">Path of the BAM file</param> /// <param name="mean">Mean value</param> /// <param name="deviation">Standard deviation</param> /// <returns></returns> private void DisplayOrphans(string filename) { SequenceAlignmentMap alignmentMapobj = null; if (!SAMInput) { BAMParser bamParser = new BAMParser(); alignmentMapobj = bamParser.ParseOne <SequenceAlignmentMap>(filename); } else { SAMParser samParser = new SAMParser(); alignmentMapobj = samParser.ParseOne <SequenceAlignmentMap>(filename); } // get reads from sequence alignment map object. IList <PairedRead> pairedReads = null; // Get Aligned sequences IList <SAMAlignedSequence> alignedSeqs = alignmentMapobj.QuerySequences; pairedReads = alignmentMapobj.GetPairedReads(0, 0); // Get the orphan regions. var orphans = pairedReads.Where(PR => PR.PairedType == PairedReadType.Orphan); int count = orphans.Count(); if (count == 0) { Console.WriteLine("No Orphans to display"); } var orphanRegions = new List <ISequenceRange>(count); orphanRegions.AddRange(orphans.Select(orphanRead => GetRegion(orphanRead.Read1))); // Get sequence range grouping object. SequenceRangeGrouping rangeGroup = new SequenceRangeGrouping(orphanRegions); if (!rangeGroup.GroupIDs.Any()) { Console.Write("\r\nNo Orphan reads to display"); } else { Console.Write("Region of Orphan reads:"); DisplaySequenceRange(rangeGroup); } SequenceRangeGrouping mergedRegions = rangeGroup.MergeOverlaps(); if (!mergedRegions.GroupIDs.Any()) { Console.Write("\r\nNo hot spots to display"); } else { Console.Write("\r\nChromosomal hot spot:"); DisplaySequenceRange(mergedRegions); } }
/// <summary> /// Validate different paired read types /// </summary> /// <param name="nodeName">XML node name</param> /// <param name="pams">GetPairedReadTypes method parameters</param> void ValidatePairedReadTypes(string nodeName, GetPairedReadTypeParameters pams) { // Get input and output values from xml node. string bamFilePath = utilityObj.xmlUtil.GetTextValue(nodeName, Constants.FilePathNode); string mean = utilityObj.xmlUtil.GetTextValue( nodeName, Constants.MeanNode); string deviation = utilityObj.xmlUtil.GetTextValue( nodeName, Constants.DeviationValueNode); string library = utilityObj.xmlUtil.GetTextValue( nodeName, Constants.LibraryNameNode); string[] pairedReadType = utilityObj.xmlUtil.GetTextValue( nodeName, Constants.PairedReadTypeNode).Split(','); string[] insertLength = utilityObj.xmlUtil.GetTextValue( nodeName, Constants.InsertLengthNode).Split(','); IList <PairedRead> pairedReads = null; BAMParser bamParser = new BAMParser(); SequenceAlignmentMap seqAlignmentMapObj = bamParser.Parse(bamFilePath); CloneLibraryInformation libraryInfo; int i = 0; try { switch (pams) { case GetPairedReadTypeParameters.PaireReadTypeUsingLibraryName: pairedReads = seqAlignmentMapObj.GetPairedReads(float.Parse(mean, (IFormatProvider)null), float.Parse(deviation, (IFormatProvider)null)); foreach (PairedRead read in pairedReads) { PairedReadType type = PairedRead.GetPairedReadType(read, library); Assert.AreEqual(type.ToString(), pairedReadType[i]); i++; } break; case GetPairedReadTypeParameters.PaireReadTypeUsingCloneLibraryInfo: pairedReads = seqAlignmentMapObj.GetPairedReads(float.Parse(mean, (IFormatProvider)null), float.Parse(deviation, (IFormatProvider)null)); libraryInfo = CloneLibrary.Instance.GetLibraryInformation(library); foreach (PairedRead read in pairedReads) { PairedReadType type = PairedRead.GetPairedReadType(read, libraryInfo); Assert.AreEqual(type.ToString(), pairedReadType[i]); i++; } break; case GetPairedReadTypeParameters.PaireReadTypeUsingMeanAndDeviation: pairedReads = seqAlignmentMapObj.GetPairedReads(float.Parse(mean, (IFormatProvider)null), float.Parse(deviation, (IFormatProvider)null)); foreach (PairedRead read in pairedReads) { PairedReadType type = PairedRead.GetPairedReadType(read, float.Parse(mean, (IFormatProvider)null), float.Parse(deviation, (IFormatProvider)null)); Assert.AreEqual(type.ToString(), pairedReadType[i]); i++; } break; case GetPairedReadTypeParameters.PaireReadTypeUsingReadsAndLibrary: pairedReads = seqAlignmentMapObj.GetPairedReads(float.Parse(mean, (IFormatProvider)null), float.Parse(deviation, (IFormatProvider)null)); foreach (PairedRead read in pairedReads) { PairedReadType type = PairedRead.GetPairedReadType(read.Read1, read.Read2, library); Assert.AreEqual(type.ToString(), pairedReadType[i]); i++; } break; case GetPairedReadTypeParameters.PaireReadTypeUsingReadsAndLibraryInfo: pairedReads = seqAlignmentMapObj.GetPairedReads(float.Parse(mean, (IFormatProvider)null), float.Parse(deviation, (IFormatProvider)null)); libraryInfo = CloneLibrary.Instance.GetLibraryInformation(library); foreach (PairedRead read in pairedReads) { PairedReadType type = PairedRead.GetPairedReadType(read.Read1, read.Read2, libraryInfo); Assert.AreEqual(type.ToString(), pairedReadType[i]); i++; } break; case GetPairedReadTypeParameters.GetInsertLength: pairedReads = seqAlignmentMapObj.GetPairedReads(float.Parse(mean, (IFormatProvider)null), float.Parse(deviation, (IFormatProvider)null)); libraryInfo = CloneLibrary.Instance.GetLibraryInformation(library); foreach (PairedRead read in pairedReads) { int length = PairedRead.GetInsertLength(read.Read1, read.Read2); Assert.AreEqual(length.ToString((IFormatProvider)null), insertLength[i]); i++; } break; } ApplicationLog.WriteLine(string.Format((IFormatProvider)null, "BAM Parser BVT : Validated Paired read Type Successfully")); } finally { bamParser.Dispose(); } }
/// <summary> /// Validate GetPaired method /// </summary> /// <param name="nodeName">XML node name</param> /// <param name="pams">GetPairedReads method parameters</param> void ValidatePairedReads(string nodeName, GetPairedReadParameters pams) { // Get input and output values from xml node. string bamFilePath = utilityObj.xmlUtil.GetTextValue(nodeName, Constants.FilePathNode); string expectedAlignedSeqFilePath = utilityObj.xmlUtil.GetTextValue( nodeName, Constants.ExpectedSequence); string mean = utilityObj.xmlUtil.GetTextValue( nodeName, Constants.MeanNode); string deviation = utilityObj.xmlUtil.GetTextValue( nodeName, Constants.DeviationValueNode); string library = utilityObj.xmlUtil.GetTextValue( nodeName, Constants.LibraryNameNode); string pairedReadsCount = utilityObj.xmlUtil.GetTextValue( nodeName, Constants.PairedReadsNode); string[] insertLength = utilityObj.xmlUtil.GetTextValue( nodeName, Constants.InsertLengthNode).Split(','); string[] pairedReadType = utilityObj.xmlUtil.GetTextValue( nodeName, Constants.PairedReadTypeNode).Split(','); SequenceAlignmentMap seqAlignment = null; IList <PairedRead> pairedReads = null; BAMParser bamParser = new BAMParser(); FastAParser parserObj = new FastAParser(expectedAlignedSeqFilePath); try { seqAlignment = bamParser.Parse(bamFilePath); IEnumerable <ISequence> expectedSequences = parserObj.Parse(); switch (pams) { case GetPairedReadParameters.GetPairedReadWithParameters: pairedReads = seqAlignment.GetPairedReads(float.Parse(mean, (IFormatProvider)null), float.Parse(deviation, (IFormatProvider)null)); break; case GetPairedReadParameters.GetPairedReadWithLibraryName: pairedReads = seqAlignment.GetPairedReads(library); break; case GetPairedReadParameters.GetPairedReadWithCloneLibraryInfo: CloneLibraryInformation libraryInfo = CloneLibrary.Instance.GetLibraryInformation(library); pairedReads = seqAlignment.GetPairedReads(libraryInfo); break; case GetPairedReadParameters.Default: pairedReads = seqAlignment.GetPairedReads(); break; } Assert.AreEqual(pairedReadsCount, pairedReads.Count.ToString((IFormatProvider)null)); int i = 0; foreach (PairedRead read in pairedReads) { Assert.AreEqual(insertLength[i], read.InsertLength.ToString((IFormatProvider)null)); Assert.AreEqual(pairedReadType[i], read.PairedType.ToString()); foreach (SAMAlignedSequence seq in read.Reads) { Assert.AreEqual(new string(expectedSequences.ElementAt(i).Select(a => (char)a).ToArray()), new string(seq.QuerySequence.Select(a => (char)a).ToArray())); // Log to NUNIT GUI. ApplicationLog.WriteLine(string.Format((IFormatProvider)null, "BAM Parser BVT : Validated Paired read :{0} successfully", seq.QuerySequence.ToString())); } i++; } } finally { bamParser.Dispose(); } }
/// <summary> /// Tests Coverage and snps /// </summary> /// <param name="readname">Chromosoem name</param> /// <param name="alignmentMapobj">Alignment object</param> /// <param name="possibility">True for Nucleaotide distribution</param> private static void TestCoverage(string readname, SequenceAlignmentMap alignmentMapobj, string possibility) { TextReader reader = null; StringWriter writer = new StringWriter(CultureInfo.InvariantCulture); try { if (possibility == "true") { reader = new StreamReader(@"TestUtils\SAM\CoverageOutput2.txt"); } else { reader = new StreamReader(@"TestUtils\SAM\CoverageOutput1.txt"); } // Get reads aligned to chromosome. // Reduce the output by considering only normal forward reads. var alignedPairedReads = alignmentMapobj.GetPairedReads(200, 50).Where(PE => PE.PairedType == PairedReadType.Normal).Select(PE => PE.Read1) .Where(QS => readname.Equals(QS.RName)).ToList(); //List<ISequenceItem> distinctChars = // new List<ISequenceItem>(Alphabets.DNA); List <ISequenceItem> distinctChars = new List <ISequenceItem> { Alphabets.DNA.A, Alphabets.DNA.T, Alphabets.DNA.G, Alphabets.DNA.C }; // Dictionary to hold coverage profile. Dictionary <long, double[]> coverageProfile = new Dictionary <long, double[]>(); // Get the position specific alphabet count. foreach (var read in alignedPairedReads) { for (int i = 0; i < read.QuerySequence.Count; i++) { double[] values; if (!coverageProfile.TryGetValue(read.Pos + i, out values)) { coverageProfile.Add(read.Pos + i, new double[distinctChars.Count]); } ISequenceItem item = read.QuerySequence[i]; coverageProfile[read.Pos + i][distinctChars.IndexOf(item)]++; } } // Get the position specific alphabet coverage. foreach (long i in coverageProfile.Keys) { double count = coverageProfile[i].Sum(); for (int j = 0; j < distinctChars.Count; j++) { coverageProfile[i][j] = coverageProfile[i][j] / count; } } // Display foreach (long pos in coverageProfile.Keys.OrderBy(P => P)) { double[] values = coverageProfile[pos]; if (possibility == "true") { string possibleOccurence = GetMoreOccurences(values[0], values[1], values[2], values[3]); writer.Write("\r\n{0,10}\t\t{1,4}%\t{2,4}%\t{3,4}%\t{4,4}%\t\t{5,4}", pos.ToString(CultureInfo.InvariantCulture), values[0] * 100, values[1] * 100, values[2] * 100, values[3] * 100, possibleOccurence); } else { writer.Write("\r\n{0,10}\t\t{1,4:0.00}\t{2,4:0.00}\t{3,4:0.00}\t{4,4:0.00}", pos.ToString(CultureInfo.InvariantCulture), values[0], values[1], values[2], values[3]); } } writer.Flush(); Assert.AreEqual(writer.ToString(), reader.ReadToEnd()); } finally { if (reader != null) { reader.Close(); reader = null; } if (writer != null) { writer.Close(); writer = null; } } }
/// <summary> /// Tests Length Anomalies /// </summary> /// <param name="alignmentMapobj">Sequence alignment map.</param> private static void TestLengthAnomalies(SequenceAlignmentMap alignmentMapobj) { string expectedOutput; string actualOutput; expectedOutput = "9437-9447:9440-9447:"; actualOutput = string.Empty; // get reads from sequence alignment map object. IList <PairedRead> pairedReads = null; pairedReads = alignmentMapobj.GetPairedReads(200, 50); // Get the orphan regions. var orphans = pairedReads.Where(PR => PR.PairedType == PairedReadType.Orphan); if (orphans.Count() == 0) { Assert.Fail(); } List <ISequenceRange> orphanRegions = new List <ISequenceRange>(orphans.Count()); foreach (PairedRead orphanRead in orphans) { orphanRegions.Add(GetRegion(orphanRead.Read1)); } // Get sequence range grouping for Orphan regions. SequenceRangeGrouping orphanRangegroup = new SequenceRangeGrouping(orphanRegions); // Get the Length anomalies regions. var lengthAnomalies = pairedReads.Where(PE => PE.PairedType == PairedReadType.LengthAnomaly); if (lengthAnomalies.Count() == 0) { Assert.Fail(); } List <ISequenceRange> lengthAnomalyRegions = new List <ISequenceRange>(lengthAnomalies.Count()); foreach (PairedRead laRead in lengthAnomalies) { SequenceRange range = new SequenceRange(); range.ID = laRead.Read1.RName; range.Start = laRead.Read1.Pos; range.End = laRead.Read1.Pos + laRead.InsertLength; lengthAnomalyRegions.Add(range); } // Get sequence range grouping for length anomaly regions. SequenceRangeGrouping lengthAnomalyRangegroup = new SequenceRangeGrouping(lengthAnomalyRegions); SequenceRangeGrouping intersectedRegions = lengthAnomalyRangegroup.Intersect(orphanRangegroup); foreach (var range in intersectedRegions.GroupRanges) { actualOutput += range.Start + "-" + range.End + ":"; } Assert.AreEqual(expectedOutput, actualOutput); }