+/*\r
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.6)\r
+ * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle\r
+ * \r
+ * This file is part of Jalview.\r
+ * \r
+ * Jalview is free software: you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License \r
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\r
+ * \r
+ * Jalview is distributed in the hope that it will be useful, but \r
+ * WITHOUT ANY WARRANTY; without even the implied warranty \r
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR \r
+ * PURPOSE. See the GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
package jalview.datamodel;\r
\r
-import java.util.Vector;\r
+import java.util.*;\r
\r
public abstract class CigarBase\r
{\r
/**\r
- * Base class for compact idiosyncratic representation of gaps and aligned residues\r
- * Regards to Tom Oldfield for his DynamicArray class.\r
- * 17th July 2006\r
+ * Base class for compact idiosyncratic representation of gaps and aligned\r
+ * residues Regards to Tom Oldfield for his DynamicArray class. 17th July 2006\r
* Not thread safe.\r
*/\r
public CigarBase()\r
}\r
\r
protected int length = 0;\r
- protected int _inc_length = 10; // extension range for addition of new operations\r
+\r
+ protected int _inc_length = 10; // extension range for addition of new\r
+\r
+ // operations\r
+\r
protected char[] operation = null;\r
+\r
protected int[] range = null;\r
+\r
/**\r
* Range of Hidden residues in seq (translated as deleted in seq)\r
*/\r
- public static final char D = 'D'; /**\r
- * Range of insertions to seq\r
- */\r
- public static final char I = 'I'; /**\r
- * Range of aligned residues\r
- */\r
- public static final char M = 'M';\r
+ public static final char D = 'D';\r
+\r
+ /**\r
+ * Range of insertions to seq\r
+ */\r
+ public static final char I = 'I';\r
+\r
+ /**\r
+ * Range of aligned residues\r
+ */\r
+ public static final char M = 'M';\r
+\r
static protected final char _case_shift = 'a' - 'A';\r
+\r
/**\r
- * Ugly function to get edited sequence string, start and end symbol positions and the deletion regions as an array of int pairs\r
- * May return null for an empty cigar string.\r
- * May return null for deletion ranges if there are none.\r
- * @param reference - the symbol sequence to apply the cigar operations to (or null if no sequence)\r
- * @param GapChar - the symbol to use for Insert operations\r
- * @return Object[] { String, int[] {start, startcol, end, endcol}, int[][3] {start, end, col} or null} the gapped sequence, first and last residue index, and the deletion ranges on the reference sequence\r
+ * Ugly function to get edited sequence string, start and end symbol positions\r
+ * and the deletion regions as an array of int pairs May return null for an\r
+ * empty cigar string. May return null for deletion ranges if there are none.\r
+ * \r
+ * @param reference\r
+ * - the symbol sequence to apply the cigar operations to (or null if\r
+ * no sequence)\r
+ * @param GapChar\r
+ * - the symbol to use for Insert operations\r
+ * @return Object[] { String, int[] {start, startcol, end, endcol}, int[][3]\r
+ * {start, end, col} or null} the gapped sequence, first and last\r
+ * residue index, and the deletion ranges on the reference sequence\r
*/\r
public Object[] getSequenceAndDeletions(String reference, char GapChar)\r
{\r
- int rlength=0;\r
+ int rlength = 0;\r
int[][] deletions = new int[length][];\r
int[][] trunc_deletions = null;\r
StringBuffer sq = new StringBuffer();\r
- int cursor = 0, alcursor=0,start = 0, startpos=0, end = 0, endpos=0, delcount = -1;\r
+ int cursor = 0, alcursor = 0, start = 0, startpos = 0, end = 0, endpos = 0, delcount = -1;\r
boolean consecutive_del = false;\r
if (length == 0)\r
{\r
return null;\r
}\r
- if (reference!=null)\r
- rlength=reference.length();\r
+ if (reference != null)\r
+ {\r
+ rlength = reference.length();\r
+ }\r
boolean modstart = true;\r
for (int i = 0; i < length; i++)\r
{\r
switch (operation[i])\r
{\r
- case D:\r
- if (!consecutive_del)\r
- {\r
- deletions[++delcount] = new int[]\r
- {\r
- cursor, 0, alcursor};\r
- }\r
- cursor += range[i];\r
- deletions[delcount][1] = cursor - 1;\r
- consecutive_del = true;\r
- break;\r
- case I:\r
- consecutive_del = false;\r
- for (int r = 0; r < range[i]; r++)\r
+ case D:\r
+ if (!consecutive_del)\r
+ {\r
+ deletions[++delcount] = new int[]\r
+ { cursor, 0, alcursor };\r
+ }\r
+ cursor += range[i];\r
+ deletions[delcount][1] = cursor - 1;\r
+ consecutive_del = true;\r
+ break;\r
+ case I:\r
+ consecutive_del = false;\r
+ for (int r = 0; r < range[i]; r++)\r
+ {\r
+ sq.append(GapChar);\r
+ alcursor++;\r
+ }\r
+ break;\r
+ case M:\r
+ consecutive_del = false;\r
+ if (modstart)\r
+ {\r
+ start = cursor;\r
+ startpos = alcursor;\r
+ modstart = false;\r
+ }\r
+ if (reference != null)\r
+ {\r
+ int sbend = cursor + range[i];\r
+ if (sbend > rlength)\r
{\r
- sq.append(GapChar);\r
- alcursor++;\r
+ sq.append(reference.substring(cursor, rlength));\r
+ while (sbend-- >= rlength)\r
+ {\r
+ sq.append(GapChar);\r
+ }\r
}\r
- break;\r
- case M:\r
- consecutive_del = false;\r
- if (modstart)\r
+ else\r
{\r
- start = cursor;\r
- startpos=alcursor;\r
- modstart = false;\r
+ sq.append(reference.substring(cursor, sbend));\r
}\r
- if (reference!=null) {\r
- int sbend = cursor+range[i];\r
- if (sbend>rlength) {\r
- sq.append(reference.substring(cursor, rlength));\r
- while (sbend-- >= rlength)\r
- {\r
- sq.append(GapChar);\r
- }\r
- } else {\r
- sq.append(reference.substring(cursor, sbend));\r
- }\r
- }\r
- alcursor+=range[i];\r
- cursor += range[i];\r
- end = cursor - 1;\r
- endpos = alcursor;\r
- break;\r
- default:\r
- throw new Error("Unknown SeqCigar operation '" + operation[i] + "'");\r
+ }\r
+ alcursor += range[i];\r
+ cursor += range[i];\r
+ end = cursor - 1;\r
+ endpos = alcursor;\r
+ break;\r
+ default:\r
+ throw new Error("Unknown SeqCigar operation '" + operation[i] + "'");\r
}\r
}\r
if (++delcount > 0)\r
}\r
deletions = null;\r
return new Object[]\r
- {\r
- ((reference!=null) ? sq.toString() : null),\r
- new int[] {\r
- start, startpos, end, endpos}, trunc_deletions};\r
+ { ((reference != null) ? sq.toString() : null), new int[]\r
+ { start, startpos, end, endpos }, trunc_deletions };\r
}\r
- protected void compact_operations() {\r
- int i=1;\r
- if (operation==null)\r
+\r
+ protected void compact_operations()\r
+ {\r
+ int i = 1;\r
+ if (operation == null)\r
+ {\r
return;\r
+ }\r
char last = operation[0];\r
- while (i<length) {\r
- if (last==operation[i]) {\r
- range[i-1]+=range[i];\r
- int r = length-i;\r
- if (r>0) {\r
+ while (i < length)\r
+ {\r
+ if (last == operation[i])\r
+ {\r
+ range[i - 1] += range[i];\r
+ int r = length - i;\r
+ if (r > 0)\r
+ {\r
System.arraycopy(range, i + 1, range, i, r);\r
System.arraycopy(operation, i + 1, operation, i, r);\r
}\r
length--;\r
- } else {\r
+ }\r
+ else\r
+ {\r
last = operation[i++];\r
}\r
}\r
}\r
+\r
/**\r
* turn a cigar string into a series of operation range pairs\r
- * @param cigarString String\r
+ * \r
+ * @param cigarString\r
+ * String\r
* @return object[] {char[] operation, int[] range}\r
- * @throws java.lang.Exception for improperly formated cigar strings or ones with unknown operations\r
+ * @throws java.lang.Exception\r
+ * for improperly formated cigar strings or ones with unknown\r
+ * operations\r
*/\r
public static Object[] parseCigarString(String cigarString)\r
- throws Exception\r
+ throws Exception\r
{\r
int ops = 0;\r
for (int i = 0, l = cigarString.length(); i < l; i++)\r
{\r
char c = cigarString.charAt(i);\r
- if (c == M || c == (M - _case_shift) || c == I || c == (I - _case_shift) ||\r
- c == D || c == (D - _case_shift))\r
+ if (c == M || c == (M - _case_shift) || c == I\r
+ || c == (I - _case_shift) || c == D || c == (D - _case_shift))\r
{\r
ops++;\r
}\r
do\r
{\r
c = cigarString.charAt(j++);\r
- }\r
- while (c >= '0' && c <= '9' && j < l);\r
+ } while (c >= '0' && c <= '9' && j < l);\r
if (j >= l && c >= '0' && c <= '9')\r
{\r
throw new Exception("Unterminated cigar string.");\r
String rangeint = cigarString.substring(i, j - 1);\r
range[op] = Integer.parseInt(rangeint);\r
i = j;\r
- }\r
- catch (Exception e)\r
+ } catch (Exception e)\r
{\r
throw new Error("Implementation bug in parseCigarString");\r
}\r
{\r
c -= _case_shift;\r
}\r
- if ( (c == M || c == I || c == D))\r
+ if ((c == M || c == I || c == D))\r
{\r
operation[op++] = c;\r
}\r
else\r
{\r
- throw new Exception("Unexpected operation '" + c +\r
- "' in cigar string (position " + i + " in '" +\r
- cigarString + "'");\r
+ throw new Exception("Unexpected operation '" + c\r
+ + "' in cigar string (position " + i + " in '"\r
+ + cigarString + "'");\r
}\r
}\r
return new Object[]\r
- {\r
- operation, range};\r
+ { operation, range };\r
}\r
\r
/**\r
* add an operation to cigar string\r
- * @param op char\r
- * @param range int\r
+ * \r
+ * @param op\r
+ * char\r
+ * @param range\r
+ * int\r
*/\r
public void addOperation(char op, int range)\r
{\r
{\r
throw new Error("Implementation error. Invalid operation string.");\r
}\r
- if (range<=0)\r
- throw new Error("Invalid range string (must be non-zero positive number)");\r
+ if (range <= 0)\r
+ {\r
+ throw new Error(\r
+ "Invalid range string (must be non-zero positive number)");\r
+ }\r
int lngth = 0;\r
if (operation == null)\r
{\r
System.arraycopy(rng, 0, this.range, 0, length);\r
rng = null;\r
}\r
- if ((length>0) && (operation[length-1]==op))\r
+ if ((length > 0) && (operation[length - 1] == op))\r
+ {\r
length--; // modify existing operation.\r
+ }\r
else\r
- this.range[length]=0; // reset range\r
+ {\r
+ this.range[length] = 0; // reset range\r
+ }\r
this.operation[length] = op;\r
this.range[length++] += range;\r
}\r
\r
/**\r
- * semi-efficient insert an operation on the current cigar string set at column pos (from 1)\r
- * NOTE: Insertion operations simply extend width of cigar result - affecting registration of alignment\r
- * Deletion ops will shorten length of result - and affect registration of alignment\r
- * Match ops will also affect length of result - affecting registration of alignment\r
- * (ie "10M".insert(4,I,3)->"4M3I3M") - (replace?)\r
- * (ie "10M".insert(4,D,3)->"4M3D3M") - (shortens alignment)\r
- * (ie "5I5M".insert(4,I,3)->"8I5M") - real insertion\r
- * (ie "5I5M".insert(4,D,3)->"4I2D3M") - shortens aligment - I's are removed, Ms changed to Ds\r
- * (ie "10M".insert(4,M,3)->"13M") - lengthens - Is changed to M, Ds changed to M.\r
- * (ie "5I5M".insert(4,M,3)->"4I8M") - effectively shifts sequence left by 1 residue and extends it by 3\r
- * ( "10D5M".insert(-1,M,3)->"3M7D5M")\r
- * ( "10D5M".insert(0,M,3)->"7D8M")\r
- * ( "10D5M".insert(1,M,3)->"10D8M")\r
- *\r
- * ( "1M10D5M".insert(0,M,3)->"1M10D8M")\r
- * ( "1M10D5M".insert(1,M,3)->"\r
- *\r
+ * semi-efficient insert an operation on the current cigar string set at\r
+ * column pos (from 1) NOTE: Insertion operations simply extend width of cigar\r
+ * result - affecting registration of alignment Deletion ops will shorten\r
+ * length of result - and affect registration of alignment Match ops will also\r
+ * affect length of result - affecting registration of alignment (ie\r
+ * "10M".insert(4,I,3)->"4M3I3M") - (replace?) (ie\r
+ * "10M".insert(4,D,3)->"4M3D3M") - (shortens alignment) (ie\r
+ * "5I5M".insert(4,I,3)->"8I5M") - real insertion (ie\r
+ * "5I5M".insert(4,D,3)->"4I2D3M") - shortens aligment - I's are removed, Ms\r
+ * changed to Ds (ie "10M".insert(4,M,3)->"13M") - lengthens - Is changed to\r
+ * M, Ds changed to M. (ie "5I5M".insert(4,M,3)->"4I8M") - effectively shifts\r
+ * sequence left by 1 residue and extends it by 3 (\r
+ * "10D5M".insert(-1,M,3)->"3M7D5M") ( "10D5M".insert(0,M,3)->"7D8M") (\r
+ * "10D5M".insert(1,M,3)->"10D8M") ( "1M10D5M".insert(0,M,3)->"1M10D8M") (\r
+ * "1M10D5M".insert(1,M,3)->"\r
+ * \r
* if pos is beyond width - I operations are added before the operation\r
- * @param pos int -1, 0-length of visible region, or greater to append new ops (with insertions in between)\r
- * @param op char\r
- * @param range int\r
- public void addOperationAt(int pos, char op, int range)\r
- {\r
- int cursor = -1; // mark the position for the current operation being edited.\r
- int o = 0;\r
- boolean last_d = false; // previous op was a deletion.\r
- if (pos < -1)\r
- throw new Error("pos<-1 is not supported.");\r
- while (o<length) {\r
- if (operation[o] != D)\r
- {\r
- if ( (cursor + this.range[o]) < pos)\r
- {\r
- cursor += this.range[o];\r
- o++;\r
- last_d=false;\r
- }\r
- else\r
- {\r
- break;\r
- }\r
- }\r
- else {\r
- last_d=true;\r
- o++;\r
- }\r
- }\r
- if (o==length) {\r
- // must insert more operations before pos\r
- if (pos-cursor>0)\r
- addInsertion(pos-cursor);\r
- // then just add the new operation. Regardless of what it is.\r
- addOperation(op, range);\r
- } else {\r
- int diff = pos - cursor;\r
-\r
- int e_length = length-o; // new edit operation array length.\r
- // diff<0 - can only happen before first insertion or match. - affects op and all following\r
- // dif==0 - only when at first position of existing op -\r
- // diff>0 - must preserve some existing operations\r
- int[] e_range = new int[e_length];\r
- System.arraycopy(this.range, o, e_range, 0, e_length);\r
- char[] e_op = new char[e_length];\r
- System.arraycopy(this.operation, o, e_op, 0, e_length);\r
- length = o; // can now use add_operation to extend list.\r
- int e_o=0; // current operation being edited.\r
- switch (op) {\r
- case M:\r
- switch (e_op[e_o])\r
- {\r
- case M:\r
- if (last_d && diff <= 0)\r
- {\r
- // reduce D's, if possible\r
- if (range<=this.range[o-1]) {\r
- this.range[o - 1] -= range;\r
- } else {\r
- this.range[o-1]=0;\r
- }\r
- if (this.range[o-1]==0)\r
- o--; // lose this op.\r
- }\r
- e_range[e_o] += range; // just add more matched residues\r
- break;\r
- case I:\r
- // change from insertion to match\r
- if (last_d && diff<=0)\r
- {\r
- // reduce D's, if possible\r
- if (range<=this.range[o-1]) {\r
- this.range[o - 1] -= range;\r
- } else {\r
- this.range[o-1]=0;\r
- }\r
- if (this.range[o-1]==0)\r
- o--; // lose this op.\r
- }\r
- e_range[e_o]\r
- break;\r
- default:\r
- throw new Inp\r
- }\r
-\r
- break;\r
- case I:\r
- break;\r
- case D:\r
- }\r
- break;\r
- default:\r
- throw new Error("Implementation Error: Unknown operation in addOperation!");\r
- }\r
- // finally, add remaining ops.\r
- while (e_o<e_length) {\r
- addOperation(e_op[e_o], e_range[e_o]);\r
- e_o++;\r
- }\r
- }\r
- }\r
-**/\r
+ * \r
+ * @param pos\r
+ * int -1, 0-length of visible region, or greater to append new ops\r
+ * (with insertions in between)\r
+ * @param op\r
+ * char\r
+ * @param range\r
+ * int public void addOperationAt(int pos, char op, int range) { int\r
+ * cursor = -1; // mark the position for the current operation being\r
+ * edited. int o = 0; boolean last_d = false; // previous op was a\r
+ * deletion. if (pos < -1) throw new\r
+ * Error("pos<-1 is not supported."); while (o<length) { if\r
+ * (operation[o] != D) { if ( (cursor + this.range[o]) < pos) {\r
+ * cursor += this.range[o]; o++; last_d=false; } else { break; } }\r
+ * else { last_d=true; o++; } } if (o==length) { // must insert more\r
+ * operations before pos if (pos-cursor>0) addInsertion(pos-cursor);\r
+ * // then just add the new operation. Regardless of what it is.\r
+ * addOperation(op, range); } else { int diff = pos - cursor;\r
+ * \r
+ * int e_length = length-o; // new edit operation array length. //\r
+ * diff<0 - can only happen before first insertion or match. -\r
+ * affects op and all following // dif==0 - only when at first\r
+ * position of existing op - // diff>0 - must preserve some existing\r
+ * operations int[] e_range = new int[e_length];\r
+ * System.arraycopy(this.range, o, e_range, 0, e_length); char[] e_op\r
+ * = new char[e_length]; System.arraycopy(this.operation, o, e_op, 0,\r
+ * e_length); length = o; // can now use add_operation to extend\r
+ * list. int e_o=0; // current operation being edited. switch (op) {\r
+ * case M: switch (e_op[e_o]) { case M: if (last_d && diff <= 0) { //\r
+ * reduce D's, if possible if (range<=this.range[o-1]) { this.range[o\r
+ * - 1] -= range; } else { this.range[o-1]=0; } if\r
+ * (this.range[o-1]==0) o--; // lose this op. } e_range[e_o] +=\r
+ * range; // just add more matched residues break; case I: // change\r
+ * from insertion to match if (last_d && diff<=0) { // reduce D's, if\r
+ * possible if (range<=this.range[o-1]) { this.range[o - 1] -= range;\r
+ * } else { this.range[o-1]=0; } if (this.range[o-1]==0) o--; // lose\r
+ * this op. } e_range[e_o] break; default: throw new Inp }\r
+ * \r
+ * break; case I: break; case D: } break; default: throw new\r
+ * Error("Implementation Error: Unknown operation in addOperation!");\r
+ * } // finally, add remaining ops. while (e_o<e_length) {\r
+ * addOperation(e_op[e_o], e_range[e_o]); e_o++; } } }\r
+ */\r
/**\r
- * Mark residues from start to end (inclusive) as deleted from the alignment, and removes any insertions.\r
- * @param start int\r
- * @param end int\r
+ * Mark residues from start to end (inclusive) as deleted from the alignment,\r
+ * and removes any insertions.\r
+ * \r
+ * @param start\r
+ * int\r
+ * @param end\r
+ * int\r
* @return deleted int - number of symbols marked as deleted\r
*/\r
- public int deleteRange(int start, int end) {\r
- int deleted=0;\r
- if (length==0) {\r
+ public int deleteRange(int start, int end)\r
+ {\r
+ int deleted = 0;\r
+ if (length == 0)\r
+ {\r
// nothing to do here\r
return deleted;\r
}\r
- if (start<0 || start>end)\r
- throw new Error("Implementation Error: deleteRange out of bounds: start must be non-negative and less than end.");\r
+ if (start < 0 || start > end)\r
+ {\r
+ throw new Error(\r
+ "Implementation Error: deleteRange out of bounds: start must be non-negative and less than end.");\r
+ }\r
// find beginning\r
int cursor = 0; // mark the position for the current operation being edited.\r
- int rlength=1+end-start; // number of positions to delete\r
- int oldlen=length;\r
+ int rlength = 1 + end - start; // number of positions to delete\r
+ int oldlen = length;\r
int o = 0;\r
- boolean editing=false;\r
+ boolean editing = false;\r
char[] oldops = operation;\r
int[] oldrange = range;\r
- length=0;\r
+ length = 0;\r
operation = null;\r
range = null;\r
compact_operations();\r
- while (o<oldlen && cursor<=end && rlength>0) {\r
- if (oldops[o] == D) {\r
+ while (o < oldlen && cursor <= end && rlength > 0)\r
+ {\r
+ if (oldops[o] == D)\r
+ {\r
// absorbed into new deleted region.\r
addDeleted(oldrange[o++]);\r
continue;\r
}\r
\r
int remain = oldrange[o]; // number of op characters left to edit\r
- if (!editing) {\r
- if ( (cursor + remain) <= start)\r
+ if (!editing)\r
+ {\r
+ if ((cursor + remain) <= start)\r
{\r
- addOperation(oldops[o],oldrange[o]);\r
- cursor+=oldrange[o++];\r
+ addOperation(oldops[o], oldrange[o]);\r
+ cursor += oldrange[o++];\r
continue; // next operation\r
}\r
- editing=true;\r
+ editing = true;\r
// add operations before hidden region\r
- if (start-cursor>0) {\r
- addOperation(oldops[o], start- cursor);\r
+ if (start - cursor > 0)\r
+ {\r
+ addOperation(oldops[o], start - cursor);\r
remain -= start - cursor;\r
}\r
}\r
// start inserting new ops\r
- if (o<oldlen && editing && rlength>0 && remain>0) {\r
- switch (oldops[o]) {\r
- case M:\r
- if (rlength>remain) {\r
- addDeleted(remain);\r
- deleted+=remain;\r
- } else {\r
- deleted+=rlength;\r
- addDeleted(rlength);\r
- if (remain-rlength>0)\r
- this.addOperation(M,remain-rlength); // add remaining back.\r
- rlength=0;\r
- remain=0;\r
- }\r
- break;\r
- case I:\r
- if (remain-rlength>0) {\r
- // only remove some gaps\r
- addInsertion(remain-rlength);\r
- rlength=0;\r
+ if (o < oldlen && editing && rlength > 0 && remain > 0)\r
+ {\r
+ switch (oldops[o])\r
+ {\r
+ case M:\r
+ if (rlength > remain)\r
+ {\r
+ addDeleted(remain);\r
+ deleted += remain;\r
+ }\r
+ else\r
+ {\r
+ deleted += rlength;\r
+ addDeleted(rlength);\r
+ if (remain - rlength > 0)\r
+ {\r
+ this.addOperation(M, remain - rlength); // add remaining back.\r
}\r
- break;\r
- case D:\r
- throw new Error("Implementation error."); // do nothing;\r
- default:\r
- throw new Error("Implementation Error! Unknown operation '"+oldops[o]+"'");\r
+ rlength = 0;\r
+ remain = 0;\r
+ }\r
+ break;\r
+ case I:\r
+ if (remain - rlength > 0)\r
+ {\r
+ // only remove some gaps\r
+ addInsertion(remain - rlength);\r
+ rlength = 0;\r
+ }\r
+ break;\r
+ case D:\r
+ throw new Error("Implementation error."); // do nothing;\r
+ default:\r
+ throw new Error("Implementation Error! Unknown operation '"\r
+ + oldops[o] + "'");\r
}\r
- rlength-=remain;\r
+ rlength -= remain;\r
remain = oldrange[++o]; // number of op characters left to edit\r
}\r
}\r
// add remaining\r
- while (o<oldlen) {\r
- addOperation(oldops[o],oldrange[o++]);\r
+ while (o < oldlen)\r
+ {\r
+ addOperation(oldops[o], oldrange[o++]);\r
}\r
- //if (cursor<(start+1)) {\r
- // ran out of ops - nothing to do here ?\r
- // addInsertion(start-cursor);\r
- //}\r
+ // if (cursor<(start+1)) {\r
+ // ran out of ops - nothing to do here ?\r
+ // addInsertion(start-cursor);\r
+ // }\r
return deleted;\r
}\r
\r
/**\r
- * Deleted regions mean that there will be discontinuous sequence numbering in the\r
- * sequence returned by getSeq(char).\r
+ * Deleted regions mean that there will be discontinuous sequence numbering in\r
+ * the sequence returned by getSeq(char).\r
+ * \r
* @return true if there deletions\r
*/\r
public boolean hasDeletedRegions()\r
{\r
- for (int i = 0; i<length ; i++)\r
+ for (int i = 0; i < length; i++)\r
{\r
if (operation[i] == D)\r
{\r
}\r
return false;\r
}\r
+\r
/**\r
* enumerate the ranges on seq that are marked as deleted in this cigar\r
+ * \r
* @return int[] { vis_start, sym_start, length }\r
*/\r
- public int[] getDeletedRegions() {\r
- if (length==0)\r
+ public int[] getDeletedRegions()\r
+ {\r
+ if (length == 0)\r
+ {\r
return null;\r
+ }\r
Vector dr = new Vector();\r
- int cursor=0, vcursor=0;\r
- for (int i=0;i<length;i++) {\r
- switch (operation[i]) {\r
- case M:\r
- cursor+=range[i];\r
- case I:\r
- vcursor+=range[i];\r
- break;\r
- case D:\r
- dr.addElement(new int[] { vcursor, cursor, range[i]});\r
- cursor+=range[i];\r
+ int cursor = 0, vcursor = 0;\r
+ for (int i = 0; i < length; i++)\r
+ {\r
+ switch (operation[i])\r
+ {\r
+ case M:\r
+ cursor += range[i];\r
+ case I:\r
+ vcursor += range[i];\r
+ break;\r
+ case D:\r
+ dr.addElement(new int[]\r
+ { vcursor, cursor, range[i] });\r
+ cursor += range[i];\r
}\r
}\r
- if (dr.size()==0)\r
+ if (dr.size() == 0)\r
+ {\r
return null;\r
- int[] delregions = new int[dr.size()*3];\r
- for (int i=0,l=dr.size(); i<l; i++) {\r
+ }\r
+ int[] delregions = new int[dr.size() * 3];\r
+ for (int i = 0, l = dr.size(); i < l; i++)\r
+ {\r
int[] reg = (int[]) dr.elementAt(i);\r
- delregions[i*3] = reg[0];\r
- delregions[i*3+1] = reg[1];\r
- delregions[i*3+2] = reg[2];\r
+ delregions[i * 3] = reg[0];\r
+ delregions[i * 3 + 1] = reg[1];\r
+ delregions[i * 3 + 2] = reg[2];\r
}\r
return delregions;\r
}\r
+\r
/**\r
* sum of ranges in cigar string\r
- * @return int number of residues hidden, matched, or gaps inserted into sequence\r
+ * \r
+ * @return int number of residues hidden, matched, or gaps inserted into\r
+ * sequence\r
*/\r
public int getFullWidth()\r
{\r
\r
/**\r
* Visible length of aligned sequence\r
+ * \r
* @return int length of including gaps and less hidden regions\r
*/\r
public int getWidth()\r
}\r
return w;\r
}\r
+\r
/**\r
* mark a range of inserted residues\r
- * @param range int\r
+ * \r
+ * @param range\r
+ * int\r
*/\r
public void addInsertion(int range)\r
{\r
\r
/**\r
* mark the next range residues as hidden (not aligned) or deleted\r
- * @param range int\r
+ * \r
+ * @param range\r
+ * int\r
*/\r
public void addDeleted(int range)\r
{\r
/**\r
* Modifies operation list to delete columns from start to end (inclusive)\r
* editing will remove insertion operations, and convert matches to deletions\r
- * @param start alignment column\r
- * @param end alignment column\r
- * @return boolean true if residues were marked as deleted.\r
- public boolean deleteRange(int start, int end)\r
- {\r
- boolean deleted = false;\r
- int op = 0, prevop = -1, firstm = -1,\r
- lastm = -1, postop = -1;\r
- int width = 0; // zero'th column\r
- if (length > 0)\r
- {\r
- // find operation bracketing start of the range\r
- do\r
- {\r
- if (operation[op] != D)\r
- {\r
- width += range[prevop = op];\r
- }\r
- op++;\r
- }\r
- while (op < length && width < start);\r
- }\r
- if (width < start)\r
- {\r
- // run off end - add more operations up to deletion.\r
- addInsertion(start - width);\r
- }\r
- else\r
- {\r
- // edit existing operations.\r
- op = prevop;\r
- width -= range[prevop];\r
- int[] oldrange = range;\r
- char[] oldops = operation;\r
- range = new int[oldrange.length];\r
- operation = new char[oldops.length];\r
- if (op < length)\r
- {\r
- do\r
- {\r
- if (operation[op] != D)\r
- {\r
- width += range[postop = op];\r
- }\r
- op++;\r
- }\r
- while (op < length && width <= end);\r
- }\r
- }\r
- if (deleted == true)\r
- {\r
- addDeleted(end - start + 1);\r
- }\r
- return deleted;\r
- }\r
-*/\r
+ * \r
+ * @param start\r
+ * alignment column\r
+ * @param end\r
+ * alignment column\r
+ * @return boolean true if residues were marked as deleted. public boolean\r
+ * deleteRange(int start, int end) { boolean deleted = false; int op =\r
+ * 0, prevop = -1, firstm = -1, lastm = -1, postop = -1; int width =\r
+ * 0; // zero'th column if (length > 0) { // find operation bracketing\r
+ * start of the range do { if (operation[op] != D) { width +=\r
+ * range[prevop = op]; } op++; } while (op < length && width < start);\r
+ * } if (width < start) { // run off end - add more operations up to\r
+ * deletion. addInsertion(start - width); } else { // edit existing\r
+ * operations. op = prevop; width -= range[prevop]; int[] oldrange =\r
+ * range; char[] oldops = operation; range = new int[oldrange.length];\r
+ * operation = new char[oldops.length]; if (op < length) { do { if\r
+ * (operation[op] != D) { width += range[postop = op]; } op++; } while\r
+ * (op < length && width <= end); } } if (deleted == true) {\r
+ * addDeleted(end - start + 1); } return deleted; }\r
+ */\r
/**\r
- * Return an ENSEMBL style cigar string where D may indicates excluded parts of seq\r
+ * Return an ENSEMBL style cigar string where D may indicates excluded parts\r
+ * of seq\r
+ * \r
* @return String of form ([0-9]+[IMD])+\r
*/\r
public String getCigarstring()\r