* <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;
}
/**
{
Cache.initLogger();
}
-
+
@BeforeClass(alwaysRun = true)
public void setUpJvOptionPane()
{
public void testAddMapList_sameMap()
{
MapList ml = new MapList(new int[] { 11, 15, 20, 25, 35, 30 },
- new int[] { 72, 22 }, 1, 3);
+ new int[]
+ { 72, 22 }, 1, 3);
String before = ml.toString();
ml.addMapList(ml);
assertEquals(before, ml.toString());
assertArrayEquals(new int[] { 5, 6 }, merged.get(1));
assertArrayEquals(new int[] { 12, 8 }, merged.get(2));
assertArrayEquals(new int[] { 8, 7 }, merged.get(3));
-
+
// 'subsumed' ranges are preserved
ranges.clear();
ranges.add(new int[] { 10, 30 });
- ranges.add(new int[] { 15, 25 });
+ ranges.add(new int[] { 15, 25 });
merged = MapList.coalesceRanges(ranges);
assertEquals(2, merged.size());
assertArrayEquals(new int[] { 10, 30 }, merged.get(0));
assertEquals("[1, 12, 12, 17]", Arrays.toString(ml.locateInFrom(1, 6)));
assertEquals("[4, 9]", Arrays.toString(ml.locateInFrom(2, 3)));
assertEquals("[7, 12, 12, 17]", Arrays.toString(ml.locateInFrom(3, 6)));
-
+
assertNull(ml.locateInFrom(0, 0));
assertNull(ml.locateInFrom(1, 7));
assertNull(ml.locateInFrom(-1, 1));
assertEquals("[1, 3]", Arrays.toString(ml.locateInTo(3, 8)));
assertEquals("[1, 4]", Arrays.toString(ml.locateInTo(2, 11)));
assertEquals("[1, 4]", Arrays.toString(ml.locateInTo(3, 11)));
-
- // we want 'greedy' mapping of base 12 to both peptides it codes for
+
+ // we want base 12 to map to both of the amino acids it codes for
assertEquals("[4, 5]", Arrays.toString(ml.locateInTo(12, 12)));
assertEquals("[4, 5]", Arrays.toString(ml.locateInTo(11, 12)));
assertEquals("[4, 6]", Arrays.toString(ml.locateInTo(11, 15)));
assertEquals("[6, 6]", Arrays.toString(ml.locateInTo(15, 17)));
-
+
assertNull(ml.locateInTo(0, 0));
assertNull(ml.locateInTo(1, 18));
assertNull(ml.locateInTo(-1, 1));
}
+
+ @Test(groups = { "Functional" })
+ public void testTraverseToPosition()
+ {
+ List<int[]> ranges = new ArrayList<>();
+ assertNull(MapList.traverseToPosition(ranges, 0));
+
+ ranges.add(new int[] { 3, 6 });
+ assertNull(MapList.traverseToPosition(ranges, 0));
+ }
}