* <p>
* The main use case for this method is when mapping cDNA sequence to its
* protein product, based on CDS feature ranges which derive from spliced
- * exons, but are contiguous on the cDNA sequence. For example
+ * exons, but are contiguous on the cDNA sequence. For example
+ *
* <pre>
* CDS 1-20 // from exon1
* CDS 21-35 // from exon2
}
int fromRemainder = (fromCount[0] - 1) % fromRatio;
int toCount = 1 + (((fromCount[0] - 1) / fromRatio) * toRatio);
- int[] toPos = countToPos(shiftFrom, toCount);
+ int[] toPos = traverseToPosition(shiftFrom, toCount);
if (toPos == null)
{
return null; // throw new Error("Bad Mapping!");
}
/**
- * count out pos positions into a series of intervals and return the position
+ * Reads through the given intervals until {@code count} positions have been
+ * traversed, and returns an array consisting of two values:
+ * <ul>
+ * <li>the value at the {@code count'th} position</li>
+ * <li>+1 if the last interval read is forwards, -1 if reverse direction</li>
+ * </ul>
+ * Returns null if the ranges include less than {@code count} positions, or if
+ * {@code count < 1}.
*
- * @param shiftFrom
- * @param pos
- * @return position pos in interval set
+ * @param intervals
+ * a list of [start, end] ranges
+ * @param count
+ * the number of positions to traverse
+ * @return
*/
- protected static int[] countToPos(List<int[]> shiftFrom, int pos)
+ protected static int[] traverseToPosition(List<int[]> intervals,
+ final int count)
{
- int count = 0, diff = 0, iv = 0, ivSize = shiftFrom.size();
- int[] intv = { 0, 0 };
+ int traversed = 0;
+ int ivSize = intervals.size();
+ int iv = 0;
+
+ if (count < 1)
+ {
+ return null;
+ }
+
while (iv < ivSize)
{
- intv = shiftFrom.get(iv++);
- diff = intv[1] - intv[0];
+ int[] intv = intervals.get(iv++);
+ int diff = intv[1] - intv[0];
if (diff >= 0)
{
- if (pos <= count + 1 + diff)
+ if (count <= traversed + 1 + diff)
{
- return new int[] { pos - count - 1 + intv[0], +1 };
+ return new int[] { intv[0] + (count - traversed - 1), +1 };
}
else
{
- count += 1 + diff;
+ traversed += 1 + diff;
}
}
else
{
- if (pos <= count + 1 - diff)
+ if (count <= traversed + 1 - diff)
{
- return new int[] { intv[0] - (pos - count - 1), -1 };
+ return new int[] { intv[0] - (count - traversed - 1), -1 };
}
else
{
- count += 1 - diff;
+ traversed += 1 - diff;
}
}
}
- return null;// (diff<0) ? (intv[1]-1) : (intv[0]+1);
+ return null;
}
/**