JAL-653 handle reverse strand mappings also
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Thu, 3 Dec 2015 14:46:53 +0000 (14:46 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Thu, 3 Dec 2015 14:46:53 +0000 (14:46 +0000)
src/jalview/util/MappingUtils.java
test/jalview/util/MappingUtilsTest.java

index 47f7017..11597eb 100644 (file)
@@ -621,8 +621,8 @@ public final class MappingUtils
   }
 
   /**
-   * Converts a series of [start, end] ranges into an array of individual
-   * positions.
+   * Converts a series of [start, end] range pairs into an array of individual
+   * positions. This also caters for 'reverse strand' (start > end) cases.
    * 
    * @param ranges
    * @return
@@ -635,17 +635,21 @@ public final class MappingUtils
     int count = 0;
     for (int i = 0; i < ranges.length - 1; i += 2)
     {
-      count += ranges[i + 1] - ranges[i] + 1;
+      count += Math.abs(ranges[i + 1] - ranges[i]) + 1;
     }
 
     int[] result = new int[count];
     int k = 0;
     for (int i = 0; i < ranges.length - 1; i += 2)
     {
-      for (int j = ranges[i]; j <= ranges[i + 1]; j++)
+      int from = ranges[i];
+      final int to = ranges[i + 1];
+      int step = from <= to ? 1 : -1;
+      do
       {
-        result[k++] = j;
-      }
+        result[k++] = from;
+        from += step;
+      } while (from != to + step);
     }
     return result;
   }
index 032af30..758694a 100644 (file)
@@ -442,7 +442,7 @@ public class MappingUtilsTest
             "[1, 2, 3, 4, 7, 8, 9, 12]",
             Arrays.toString(MappingUtils.flattenRanges(new int[] { 1, 4, 7,
                 9, 12, 12 })));
-    // unpaired start position is ignored:
+    // trailing unpaired start position is ignored:
     assertEquals(
             "[1, 2, 3, 4, 7, 8, 9, 12]",
             Arrays.toString(MappingUtils.flattenRanges(new int[] { 1, 4, 7,
@@ -736,4 +736,43 @@ public class MappingUtilsTest
     assertEquals(12, e.getPosition());
     assertEquals(6, e.getNumber());
   }
+
+  /**
+   * Tests for the method that converts a series of [start, end] ranges to
+   * single positions, where the mapping is to a reverse strand i.e. start is
+   * greater than end point mapped to
+   */
+  @Test(groups = { "Functional" })
+  public void testFlattenRanges_reverseStrand()
+  {
+    assertEquals("[4, 3, 2, 1]",
+            Arrays.toString(MappingUtils.flattenRanges(new int[] { 4, 1 })));
+    assertEquals(
+            "[4, 3, 2, 1]",
+            Arrays.toString(MappingUtils.flattenRanges(new int[] { 4, 3, 2,
+                1 })));
+    assertEquals(
+            "[4, 3, 2, 1]",
+            Arrays.toString(MappingUtils.flattenRanges(new int[] { 4, 4, 3,
+                3, 2, 2, 1, 1 })));
+    assertEquals(
+            "[12, 9, 8, 7, 4, 3, 2, 1]",
+            Arrays.toString(MappingUtils.flattenRanges(new int[] { 12, 12,
+                9, 7, 4, 1 })));
+    // forwards and backwards anyone?
+    assertEquals(
+            "[4, 5, 6, 3, 2, 1]",
+            Arrays.toString(MappingUtils.flattenRanges(new int[] { 4, 6, 3,
+                1 })));
+    // backwards and forwards
+    assertEquals(
+            "[3, 2, 1, 4, 5, 6]",
+            Arrays.toString(MappingUtils.flattenRanges(new int[] { 3, 1, 4,
+                6 })));
+    // trailing unpaired start position is ignored:
+    assertEquals(
+            "[12, 9, 8, 7, 4, 3, 2]",
+            Arrays.toString(MappingUtils.flattenRanges(new int[] { 12, 12,
+                9, 7, 4, 2, 1 })));
+  }
 }