JAL-1705 helper method for mapping excluding stop codon
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Fri, 19 Feb 2016 16:37:02 +0000 (16:37 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Fri, 19 Feb 2016 16:37:02 +0000 (16:37 +0000)
src/jalview/util/MappingUtils.java
test/jalview/util/MappingUtilsTest.java

index 1bbfc73..267e871 100644 (file)
@@ -768,4 +768,55 @@ public final class MappingUtils
     }
     return result;
   }
+
+  /**
+   * Remove the last 3 mapped positions from the given ranges
+   * 
+   * @param ranges
+   * @param mappedLength
+   */
+  public static void unmapStopCodon(List<int[]> ranges,
+          int mappedLength)
+  {
+    if (mappedLength < 3)
+    {
+      return;
+    }
+    boolean done = false;
+    int targetLength = mappedLength - 3;
+    int mapped = 0;
+    Iterator<int[]> it = ranges.iterator();
+    while (!done && it.hasNext())
+    {
+      int[] range = it.next();
+      int length = Math.abs(range[1] - range[0]) + 1;
+      if (mapped + length == targetLength)
+      {
+        done = true;
+      }
+      else if (mapped + length < targetLength)
+      {
+        mapped += length;
+        continue;
+      }
+      else
+      {
+        /*
+         * need just a bit of this range
+         */
+        int needed = targetLength - mapped;
+        int sense = range[1] >= range[0] ? 1 : -1;
+        range[1] = range[0] + (sense * (needed - 1));
+        done = true;
+      }
+    }
+    /*
+     * remove any trailing ranges
+     */
+    while (it.hasNext())
+    {
+      it.next();
+      it.remove();
+    }
+  }
 }
index 7100381..095ab1b 100644 (file)
@@ -23,6 +23,7 @@ package jalview.util;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertSame;
 import static org.testng.AssertJUnit.assertTrue;
+import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
 
 import jalview.api.AlignViewportI;
 import jalview.commands.EditCommand;
@@ -855,4 +856,59 @@ public class MappingUtilsTest
     assertEquals("[0, 3]", Arrays.toString(hidden.get(0)));
     assertEquals("[5, 10]", Arrays.toString(hidden.get(1)));
   }
+
+  /**
+   * Tests for the method that removes the trailing stop codon from a mapping
+   * range i.e. the last 3 positions (whether split or not)
+   */
+  @Test(groups = { "Functional" })
+  public void testUnmapStopCodon()
+  {
+    List<int[]> ranges = new ArrayList<int[]>();
+
+    // simple case, forward strand:
+    ranges.add(new int[] { 1, 3 });
+    ranges.add(new int[] { 9, 14 });
+    MappingUtils.unmapStopCodon(ranges, 9);
+    assertEquals(2, ranges.size());
+    assertArrayEquals(new int[] { 1, 3 }, ranges.get(0));
+    assertArrayEquals(new int[] { 9, 11 }, ranges.get(1));
+
+    // split stop codon, forward strand:
+    ranges.clear();
+    ranges.add(new int[] { 1, 8 });
+    ranges.add(new int[] { 10, 10 });
+    MappingUtils.unmapStopCodon(ranges, 9);
+    assertEquals(1, ranges.size());
+    assertArrayEquals(new int[] { 1, 6 }, ranges.get(0));
+
+    // very split stop codon, forward strand:
+    ranges.clear();
+    ranges.add(new int[] { 1, 1 });
+    ranges.add(new int[] { 3, 4 });
+    ranges.add(new int[] { 6, 6 });
+    ranges.add(new int[] { 8, 8 });
+    ranges.add(new int[] { 10, 10 });
+    MappingUtils.unmapStopCodon(ranges, 6);
+    assertEquals(2, ranges.size());
+    assertArrayEquals(new int[] { 1, 1 }, ranges.get(0));
+    assertArrayEquals(new int[] { 3, 4 }, ranges.get(1));
+
+    // simple case, reverse strand:
+    ranges.clear();
+    ranges.add(new int[] { 12, 10 });
+    ranges.add(new int[] { 6, 1 });
+    MappingUtils.unmapStopCodon(ranges, 9);
+    assertEquals(2, ranges.size());
+    assertArrayEquals(new int[] { 12, 10 }, ranges.get(0));
+    assertArrayEquals(new int[] { 6, 4 }, ranges.get(1));
+
+    // split stop codon, reverse strand:
+    ranges.clear();
+    ranges.add(new int[] { 12, 6 });
+    ranges.add(new int[] { 4, 3 });
+    MappingUtils.unmapStopCodon(ranges, 9);
+    assertEquals(1, ranges.size());
+    assertArrayEquals(new int[] { 12, 7 }, ranges.get(0));
+  }
 }