X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fdatamodel%2FCigarBase.java;h=d44d5993a881a4f546eaa3ac356dc76e2abcd8c2;hb=7bc226b58110fa26d9dbd3f0c78095d06909ffc3;hp=a36bf76d717a628d1442f3ea561a06b4b2db39f1;hpb=dd74fc4938723fe5ec48d4e5fdcfbe58ac42a48d;p=jalview.git diff --git a/src/jalview/datamodel/CigarBase.java b/src/jalview/datamodel/CigarBase.java index a36bf76..d44d599 100644 --- a/src/jalview/datamodel/CigarBase.java +++ b/src/jalview/datamodel/CigarBase.java @@ -1,6 +1,6 @@ /* * Jalview - A Sequence Alignment Editor and Viewer - * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle + * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -18,7 +18,7 @@ */ package jalview.datamodel; -import java.util.Vector; +import java.util.*; public abstract class CigarBase { @@ -58,18 +58,21 @@ public abstract class CigarBase */ public Object[] getSequenceAndDeletions(String reference, char GapChar) { - int rlength=0; + int rlength = 0; int[][] deletions = new int[length][]; int[][] trunc_deletions = null; StringBuffer sq = new StringBuffer(); - int cursor = 0, alcursor=0,start = 0, startpos=0, end = 0, endpos=0, delcount = -1; + int cursor = 0, alcursor = 0, start = 0, startpos = 0, end = 0, endpos = 0, + delcount = -1; boolean consecutive_del = false; if (length == 0) { return null; } - if (reference!=null) - rlength=reference.length(); + if (reference != null) + { + rlength = reference.length(); + } boolean modstart = true; for (int i = 0; i < length; i++) { @@ -99,22 +102,26 @@ public abstract class CigarBase if (modstart) { start = cursor; - startpos=alcursor; + startpos = alcursor; modstart = false; } - if (reference!=null) { - int sbend = cursor+range[i]; - if (sbend>rlength) { + if (reference != null) + { + int sbend = cursor + range[i]; + if (sbend > rlength) + { sq.append(reference.substring(cursor, rlength)); while (sbend-- >= rlength) { sq.append(GapChar); } - } else { + } + else + { sq.append(reference.substring(cursor, sbend)); } } - alcursor+=range[i]; + alcursor += range[i]; cursor += range[i]; end = cursor - 1; endpos = alcursor; @@ -131,29 +138,40 @@ public abstract class CigarBase deletions = null; return new Object[] { - ((reference!=null) ? sq.toString() : null), - new int[] { + ( (reference != null) ? sq.toString() : null), + new int[] + { start, startpos, end, endpos}, trunc_deletions}; } - protected void compact_operations() { - int i=1; - if (operation==null) + + protected void compact_operations() + { + int i = 1; + if (operation == null) + { return; + } char last = operation[0]; - while (i0) { + while (i < length) + { + if (last == operation[i]) + { + range[i - 1] += range[i]; + int r = length - i; + if (r > 0) + { System.arraycopy(range, i + 1, range, i, r); System.arraycopy(operation, i + 1, operation, i, r); } length--; - } else { + } + else + { last = operation[i++]; } } } + /** * turn a cigar string into a series of operation range pairs * @param cigarString String @@ -235,8 +253,10 @@ public abstract class CigarBase { throw new Error("Implementation error. Invalid operation string."); } - if (range<=0) + if (range <= 0) + { throw new Error("Invalid range string (must be non-zero positive number)"); + } int lngth = 0; if (operation == null) { @@ -254,10 +274,14 @@ public abstract class CigarBase System.arraycopy(rng, 0, this.range, 0, length); rng = null; } - if ((length>0) && (operation[length-1]==op)) + if ( (length > 0) && (operation[length - 1] == op)) + { length--; // modify existing operation. + } else - this.range[length]=0; // reset range + { + this.range[length] = 0; // reset range + } this.operation[length] = op; this.range[length++] += range; } @@ -284,9 +308,9 @@ public abstract class CigarBase * @param pos int -1, 0-length of visible region, or greater to append new ops (with insertions in between) * @param op char * @param range int - public void addOperationAt(int pos, char op, int range) - { - int cursor = -1; // mark the position for the current operation being edited. + public void addOperationAt(int pos, char op, int range) + { + int cursor = -1; // mark the position for the current operation being edited. int o = 0; boolean last_d = false; // previous op was a deletion. if (pos < -1) @@ -373,7 +397,7 @@ public abstract class CigarBase } break; default: - throw new Error("Implementation Error: Unknown operation in addOperation!"); + throw new Error("Implementation Error: Unknown operation in addOperation!"); } // finally, add remaining ops. while (e_oend) + if (start < 0 || start > end) + { throw new Error("Implementation Error: deleteRange out of bounds: start must be non-negative and less than end."); + } // find beginning int cursor = 0; // mark the position for the current operation being edited. - int rlength=1+end-start; // number of positions to delete - int oldlen=length; + int rlength = 1 + end - start; // number of positions to delete + int oldlen = length; int o = 0; - boolean editing=false; + boolean editing = false; char[] oldops = operation; int[] oldrange = range; - length=0; + length = 0; operation = null; range = null; compact_operations(); - while (o0) { - if (oldops[o] == D) { + while (o < oldlen && cursor <= end && rlength > 0) + { + if (oldops[o] == D) + { // absorbed into new deleted region. addDeleted(oldrange[o++]); continue; } int remain = oldrange[o]; // number of op characters left to edit - if (!editing) { + if (!editing) + { if ( (cursor + remain) <= start) { - addOperation(oldops[o],oldrange[o]); - cursor+=oldrange[o++]; + addOperation(oldops[o], oldrange[o]); + cursor += oldrange[o++]; continue; // next operation } - editing=true; + editing = true; // add operations before hidden region - if (start-cursor>0) { - addOperation(oldops[o], start- cursor); + if (start - cursor > 0) + { + addOperation(oldops[o], start - cursor); remain -= start - cursor; } } // start inserting new ops - if (o0 && remain>0) { - switch (oldops[o]) { + if (o < oldlen && editing && rlength > 0 && remain > 0) + { + switch (oldops[o]) + { case M: - if (rlength>remain) { + if (rlength > remain) + { addDeleted(remain); - deleted+=remain; - } else { - deleted+=rlength; + deleted += remain; + } + else + { + deleted += rlength; addDeleted(rlength); - if (remain-rlength>0) - this.addOperation(M,remain-rlength); // add remaining back. - rlength=0; - remain=0; + if (remain - rlength > 0) + { + this.addOperation(M, remain - rlength); // add remaining back. + } + rlength = 0; + remain = 0; } break; case I: - if (remain-rlength>0) { + if (remain - rlength > 0) + { // only remove some gaps - addInsertion(remain-rlength); - rlength=0; + addInsertion(remain - rlength); + rlength = 0; } break; case D: throw new Error("Implementation error."); // do nothing; default: - throw new Error("Implementation Error! Unknown operation '"+oldops[o]+"'"); + throw new Error("Implementation Error! Unknown operation '" + + oldops[o] + "'"); } - rlength-=remain; + rlength -= remain; remain = oldrange[++o]; // number of op characters left to edit } } // add remaining - while (o