/// <summary> /// Apply a Variant to a marker. Variant is a duplication /// </summary> /// <param name="variant"></param> /// <returns></returns> protected Interval ApplyDup(Variant variant) { Interval m = new Interval(this); if (variant.OneBasedEnd < m.OneBasedStart) { // Duplication before marker start? => Adjust both coordinates long lenChange = variant.LengthChange(); m.OneBasedStart += lenChange; m.OneBasedEnd += lenChange; } else if (variant.Includes(m)) { // Duplication includes whole marker? => Adjust both coordinates long lenChange = variant.LengthChange(); m.OneBasedStart += lenChange; m.OneBasedEnd += lenChange; } else if (m.Includes(variant)) { // Duplication included in marker? => Adjust end coordinate m.OneBasedEnd += variant.LengthChange(); } else if (variant.Intersects(m)) { // Duplication includes part of marker? => Adjust end m.OneBasedEnd += variant.IntersectSize(m); } else { // Duplication after end, no effect on marker coordinates } return(m); }
/// <summary> /// Apply a Variant to a marker. Variant is a deletion /// </summary> /// <param name="variant"></param> /// <returns></returns> protected Interval ApplyDel(Variant variant) { Interval m = new Interval(this); if (variant.OneBasedEnd < m.OneBasedStart) { // Deletion before start: Adjust coordinates long lenChange = variant.LengthChange(); m.OneBasedStart += lenChange; m.OneBasedEnd += lenChange; } else if (variant.Includes(m)) { // Deletion completely includes this marker => The whole marker deleted return(null); } else if (m.Includes(variant)) { // This marker completely includes the deletion, but deletion does not include // marker. Marker is shortened (i.e. only 'end' coordinate needs to be updated) m.OneBasedEnd += variant.LengthChange(); } else { // Variant is partially included in this marker. // This is treated as three different type of deletions: // 1- One after the marker // 2- One inside the marker // 3- One before the marker // Note that type 1 and 3 cannot exists at the same time, otherwise the // deletion would fully include the marker (previous case) // Part 1: Deletion after the marker if (m.OneBasedEnd < variant.OneBasedEnd) { // Actually this does not affect the coordinates, so we don't care about this part } // Part 2: Deletion matching the marker (intersection) long istart = Math.Max(variant.OneBasedStart, m.OneBasedStart); long iend = Math.Min(variant.OneBasedEnd, m.OneBasedEnd); if (iend < istart) { throw new ArgumentOutOfRangeException("This should never happen!"); } // Sanity check m.OneBasedEnd -= (iend - istart + 1); // Update end coordinate // Part 3: Deletion before the marker if (variant.OneBasedStart < m.OneBasedEnd) { // Update coordinates shifting the marker to the left long delta = m.OneBasedStart - variant.OneBasedStart; m.OneBasedStart -= delta; m.OneBasedEnd -= delta; } } return(m); }
/// <summary> /// Apply a Variant to a marker. Variant is an insertion /// </summary> /// <param name="variant"></param> /// <returns></returns> protected Interval ApplyIns(Variant variant) { Interval m = new Interval(this); if (variant.OneBasedStart < m.OneBasedStart) { // Insertion point before marker start? => Adjust both coordinates long lenChange = variant.LengthChange(); m.OneBasedStart += lenChange; m.OneBasedEnd += lenChange; } else if (variant.OneBasedStart <= m.OneBasedEnd) { // Insertion point after start, but before end? => Adjust end coordinate m.OneBasedEnd += variant.LengthChange(); } else { // Insertion point after end, no effect on marker coordinates } return(m); }