X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Futil%2FMappingUtils.java;h=ae4e55d3a31eea6ea64d8f4b742457627f03db1f;hb=c775190fba1fe7430b060d48d5d8cc13902a8f47;hp=16db13a09fbc1eea4afcf625f9b5904ce655a348;hpb=1e8c7a9ab9f5da589d0aa2482fd2e3361c320d57;p=jalview.git diff --git a/src/jalview/util/MappingUtils.java b/src/jalview/util/MappingUtils.java index 16db13a..ae4e55d 100644 --- a/src/jalview/util/MappingUtils.java +++ b/src/jalview/util/MappingUtils.java @@ -770,58 +770,8 @@ public final class MappingUtils } /** - * Remove the last 3 mapped positions from the given ranges - * - * @param ranges - * @param mappedLength - */ - public static void unmapStopCodon(List ranges, - int mappedLength) - { - if (mappedLength < 3) - { - return; - } - boolean done = false; - int targetLength = mappedLength - 3; - int mapped = 0; - Iterator 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(); - } - } - - /** - * Returns the total length of the supplied ranges + * Returns the total length of the supplied ranges, which may be as single + * [start, end] or multiple [start, end, start, end ...] * * @param ranges * @return @@ -835,7 +785,16 @@ public final class MappingUtils int length = 0; for (int[] range : ranges) { - length += Math.abs(range[1] - range[0]) + 1; + if (range.length % 2 != 0) + { + System.err.println("Error unbalance start/end ranges: " + + ranges.toString()); + return 0; + } + for (int i = 0; i < range.length - 1; i += 2) + { + length += Math.abs(range[i + 1] - range[i]) + 1; + } } return length; } @@ -872,4 +831,65 @@ public final class MappingUtils } return false; } + + /** + * Removes a specified number of positions from the start of a ranges list. + * For example, could be used to adjust cds ranges to allow for an incomplete + * start codon. Subranges are removed completely, or their start positions + * adjusted, until the required number of positions has been removed from the + * range. Reverse strand ranges are supported. The input array is not + * modified. + * + * @param removeCount + * @param ranges + * an array of [start, end, start, end...] positions + * @return a new array with the first removeCount positions removed + */ + public static int[] removeStartPositions(int removeCount, + final int[] ranges) + { + if (removeCount <= 0) + { + return ranges; + } + + int[] copy = Arrays.copyOf(ranges, ranges.length); + int sxpos = -1; + int cdspos = 0; + for (int x = 0; x < copy.length && sxpos == -1; x += 2) + { + cdspos += Math.abs(copy[x + 1] - copy[x]) + 1; + if (removeCount < cdspos) + { + /* + * we have removed enough, time to finish + */ + sxpos = x; + + /* + * increment start of first exon, or decrement if reverse strand + */ + if (copy[x] <= copy[x + 1]) + { + copy[x] = copy[x + 1] - cdspos + removeCount + 1; + } + else + { + copy[x] = copy[x + 1] + cdspos - removeCount - 1; + } + break; + } + } + + if (sxpos > 0) + { + /* + * we dropped at least one entire sub-range - compact the array + */ + int[] nxon = new int[copy.length - sxpos]; + System.arraycopy(copy, sxpos, nxon, 0, copy.length - sxpos); + return nxon; + } + return copy; + } }