From a23ea387c12b87e15490f4a7f9afbdf34c232cf1 Mon Sep 17 00:00:00 2001 From: gmungoc Date: Thu, 3 Dec 2015 14:46:53 +0000 Subject: [PATCH] JAL-653 handle reverse strand mappings also --- src/jalview/util/MappingUtils.java | 16 +++++++----- test/jalview/util/MappingUtilsTest.java | 41 ++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/src/jalview/util/MappingUtils.java b/src/jalview/util/MappingUtils.java index 47f7017..11597eb 100644 --- a/src/jalview/util/MappingUtils.java +++ b/src/jalview/util/MappingUtils.java @@ -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; } diff --git a/test/jalview/util/MappingUtilsTest.java b/test/jalview/util/MappingUtilsTest.java index 032af30..758694a 100644 --- a/test/jalview/util/MappingUtilsTest.java +++ b/test/jalview/util/MappingUtilsTest.java @@ -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 }))); + } } -- 1.7.10.2