MergeIn() public method

Merge another neighboring segment into this one.
public MergeIn ( CanvasSegment s ) : void
s CanvasSegment Segment to merge in.
return void
Example #1
0
        public void TestSegment()
        {
            List<float> counts = new List<float>() {100, 90, 110, 100, 95, 105};
            CanvasSegment seg1 = new CanvasSegment("chr17", 100000000, 110000000, counts);
            // Silly constructor tests:
            Assert.AreEqual(seg1.Begin, 100000000);
            Assert.AreEqual(seg1.End, 110000000);
            Assert.AreEqual(seg1.BinCount, counts.Count);
            Assert.AreEqual(seg1.Chr, "chr17");
            // Property test:
            Assert.AreEqual(seg1.MeanCount, 100, 0.01);

            // Build a second segment, and merge them, and test results:
            CanvasSegment seg2 = new CanvasSegment("chr17", 110000000, 120000000, counts);
            seg1.MergeIn(seg2);
            Assert.AreEqual(seg1.Counts.Count, 12);
            Assert.AreEqual(seg1.End, seg2.End);
        }
Example #2
0
        /// <summary>
        /// Iterates through a list of segments and merges those which have the same copy number call.
        /// Also, for segments smaller than MinimumCallSize, assimilate them into the neighbor with the best
        /// quality score.  Two consecutive segments are considered neighbors if they're on the same chromosome
        /// and the space between them doesn't overlap with any excluded intervals.
        /// </summary>
        static public void MergeSegmentsUsingExcludedIntervals(ref List <CanvasSegment> segments, int MinimumCallSize,
                                                               Dictionary <string, List <SampleGenomicBin> > excludedIntervals)
        {
            if (!segments.Any())
            {
                return;
            }

            // Assimilate short segments into the *best* available neighbor:
            List <CanvasSegment> mergedSegments = new List <CanvasSegment>();
            int segmentIndex = 0;

            while (segmentIndex < segments.Count)
            {
                if (segments[segmentIndex].End - segments[segmentIndex].Begin >= MinimumCallSize)
                {
                    mergedSegments.Add(segments[segmentIndex]);
                    segmentIndex++;
                    continue;
                }
                int    prevIndex = -1;
                double prevQ     = 0;
                // Look back for a segment:
                for (int checkIndex = segmentIndex - 1; checkIndex > 0; checkIndex--)
                {
                    // Stop, if you jump to another chromosome, or cross a forbidden interval:
                    if (segments[checkIndex].Chr != segments[segmentIndex].Chr)
                    {
                        break;
                    }
                    if (segments[checkIndex].End - segments[checkIndex].Begin < MinimumCallSize)
                    {
                        continue;
                    }
                    if (IsForbiddenInterval(segments[checkIndex].Chr, segments[checkIndex].End, segments[segmentIndex].Begin, excludedIntervals))
                    {
                        break;
                    }
                    prevIndex = checkIndex;
                    prevQ     = segments[checkIndex].QScore;
                    break;
                }
                // Look forward for a segment:
                int    nextIndex = -1;
                double nextQ     = 0;
                for (int checkIndex = segmentIndex + 1; checkIndex < segments.Count; checkIndex++)
                {
                    if (segments[checkIndex].Chr != segments[segmentIndex].Chr)
                    {
                        break;
                    }
                    if (segments[checkIndex].End - segments[checkIndex].Begin < MinimumCallSize)
                    {
                        continue;
                    }
                    if (IsForbiddenInterval(segments[checkIndex].Chr, segments[segmentIndex].End, segments[checkIndex].Begin, excludedIntervals))
                    {
                        break;
                    }
                    nextIndex = checkIndex;
                    nextQ     = segments[checkIndex].QScore;
                    break;
                }

                if (prevQ > 0 && prevQ >= nextQ)
                {
                    // segments[prevIndex] assimilates segments[prevIndex+1...segmentIndex].
                    // Assimilation of previous segments was already done, so we just need to assimilate this one:
                    segments[prevIndex].MergeIn(segments[segmentIndex]);
                    segmentIndex++;
                    continue;
                }

                if (nextQ > 0)
                {
                    // segments[nextIndex] assimilates segments[segmentIndex...nextIndex - 1]
                    for (int tempIndex = segmentIndex; tempIndex < nextIndex; tempIndex++)
                    {
                        segments[nextIndex].MergeIn(segments[tempIndex]);
                    }
                    segmentIndex = nextIndex;
                    continue;
                }

                mergedSegments.Add(segments[segmentIndex]);
                segmentIndex++;
            }
            segments = mergedSegments;

            // Now, merge together adjacent segments with same calls!
            mergedSegments = new List <CanvasSegment>();
            CanvasSegment lastSegment = segments[0];

            mergedSegments.Add(lastSegment);
            segmentIndex = 1;
            while (segmentIndex < segments.Count)
            {
                // Assimilate an adjacent segment with the same copy number call and heterogeneity flag:
                if (lastSegment.CopyNumber == segments[segmentIndex].CopyNumber && lastSegment.Chr == segments[segmentIndex].Chr &&
                    !IsForbiddenInterval(lastSegment.Chr, lastSegment.End, segments[segmentIndex].Begin, excludedIntervals) &&
                    lastSegment.IsHeterogeneous == segments[segmentIndex].IsHeterogeneous)
                {
                    lastSegment.MergeIn(segments[segmentIndex]);
                    segmentIndex++;
                    continue;
                }
                lastSegment = segments[segmentIndex];
                mergedSegments.Add(segments[segmentIndex]);
                segmentIndex++;
            }
            segments = mergedSegments;
        }
Example #3
0
        /// <summary>
        /// Iterates through a list of segments and merges those which have the same copy number call.
        /// Also, for segments smaller than MinimumCallSize, assimilate them into the neighbor with the best
        /// quality score.  Two consecutive segments are considered neighbors if they're on the same chromosome
        /// and the space between them is not too large.
        /// </summary>
        static public void MergeSegments(ref List <CanvasSegment> segments, int MinimumCallSize = 0,
                                         int maximumMergeSpan = 10000)
        {
            if (!segments.Any())
            {
                return;
            }

            // Assimilate short segments into the *best* available neighbor:
            List <CanvasSegment> mergedSegments = new List <CanvasSegment>();
            int segmentIndex = 0;

            while (segmentIndex < segments.Count)
            {
                if (segments[segmentIndex].End - segments[segmentIndex].Begin >= MinimumCallSize)
                {
                    mergedSegments.Add(segments[segmentIndex]);
                    segmentIndex++;
                    continue;
                }
                int    prevIndex = -1;
                double prevQ     = -1;
                // Look back for a segment:
                for (int checkIndex = segmentIndex - 1; checkIndex >= 0; checkIndex--)
                {
                    // Stop, if you jump to another chromosome, or cross a forbidden interval:
                    if (segments[checkIndex].Chr != segments[segmentIndex].Chr)
                    {
                        break;
                    }
                    if (segments[checkIndex].End - segments[checkIndex].Begin < MinimumCallSize)
                    {
                        continue;
                    }
                    if (segments[segmentIndex].Begin - segments[checkIndex].End > maximumMergeSpan)
                    {
                        break;
                    }
                    prevIndex = checkIndex;
                    prevQ     = segments[checkIndex].QScore;
                    break;
                }
                // Look forward for a segment:
                int    nextIndex = -1;
                double nextQ     = -1;
                for (int checkIndex = segmentIndex + 1; checkIndex < segments.Count; checkIndex++)
                {
                    if (segments[checkIndex].Chr != segments[segmentIndex].Chr)
                    {
                        break;
                    }
                    if (segments[checkIndex].End - segments[checkIndex].Begin < MinimumCallSize)
                    {
                        continue;
                    }
                    if (segments[checkIndex].Begin - segments[segmentIndex].End > maximumMergeSpan)
                    {
                        continue;
                    }
                    nextIndex = checkIndex;
                    nextQ     = segments[checkIndex].QScore;
                    break;
                }

                if (prevQ >= 0 && prevQ >= nextQ)
                {
                    // segments[prevIndex] assimilates segments[prevIndex+1...segmentIndex].
                    // Assimilation of previous segments was already done, so we just need to assimilate this one:
                    segments[prevIndex].MergeIn(segments[segmentIndex]);
                    segmentIndex++;
                    continue;
                }

                if (nextQ >= 0)
                {
                    // segments[nextIndex] assimilates segments[segmentIndex...nextIndex - 1]
                    for (int tempIndex = segmentIndex; tempIndex < nextIndex; tempIndex++)
                    {
                        segments[nextIndex].MergeIn(segments[tempIndex]);
                    }
                    segmentIndex = nextIndex;
                    continue;
                }

                mergedSegments.Add(segments[segmentIndex]);
                segmentIndex++;
            }
            segments = mergedSegments;

            // Now, merge together adjacent segments with same calls!
            mergedSegments = new List <CanvasSegment>();
            CanvasSegment lastSegment = segments[0];

            mergedSegments.Add(lastSegment);
            segmentIndex = 1;
            while (segmentIndex < segments.Count)
            {
                // Assimilate an adjacent segment with the same copy number call:
                if (lastSegment.copyNumber == segments[segmentIndex].copyNumber && lastSegment.Chr == segments[segmentIndex].Chr &&
                    segments[segmentIndex].Begin - lastSegment.End < maximumMergeSpan)
                {
                    lastSegment.MergeIn(segments[segmentIndex]);
                    segmentIndex++;
                    continue;
                }
                lastSegment = segments[segmentIndex];
                mergedSegments.Add(segments[segmentIndex]);
                segmentIndex++;
            }
            segments = mergedSegments;
        }