/*\r
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.4)\r
- * Copyright (C) 2008 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)\r
+ * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle\r
* \r
- * This program 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 2\r
- * of the License, or (at your option) any later version.\r
+ * This file is part of Jalview.\r
* \r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\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
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA\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
protected int length = 0;\r
\r
protected int _inc_length = 10; // extension range for addition of new\r
- // operations\r
+\r
+ // operations\r
\r
protected char[] operation = null;\r
\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\r
- * null if no sequence)\r
- * @param GapChar -\r
- * the symbol to use for Insert operations\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
* turn a cigar string into a series of operation range pairs\r
* \r
* @param cigarString\r
- * String\r
+ * String\r
* @return object[] {char[] operation, int[] range}\r
* @throws java.lang.Exception\r
- * for improperly formated cigar strings or ones with unknown\r
- * operations\r
+ * for improperly formated cigar strings or ones with unknown\r
+ * operations\r
*/\r
public static Object[] parseCigarString(String cigarString)\r
throws Exception\r
* add an operation to cigar string\r
* \r
* @param op\r
- * char\r
+ * char\r
* @param range\r
- * int\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
+ if (range==0)\r
+ {\r
+ return; // No Operation to add.\r
+ }\r
+ if (range < 0)\r
{\r
throw new Error(\r
- "Invalid range string (must be non-zero positive number)");\r
+ "Invalid range string (must be zero or positive number)");\r
}\r
int lngth = 0;\r
if (operation == null)\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")\r
- * ( "1M10D5M".insert(0,M,3)->"1M10D8M") ( "1M10D5M".insert(1,M,3)->"\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
* \r
* @param pos\r
- * int -1, 0-length of visible region, or greater to append new\r
- * ops (with insertions in between)\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
+ * char\r
* @param range\r
- * int public void addOperationAt(int pos, char op, int range) {\r
- * int cursor = -1; // mark the position for the current\r
- * operation being edited. int o = 0; boolean last_d = false; //\r
- * previous op was a 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\r
- * more operations before pos if (pos-cursor>0)\r
- * addInsertion(pos-cursor); // then just add the new\r
- * operation. Regardless of what it is. addOperation(op,\r
- * range); } else { int diff = pos - cursor;\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. // diff<0 -\r
- * can only happen before first insertion or match. - affects op and all\r
- * following // dif==0 - only when at first position of existing op - //\r
- * diff>0 - must preserve some existing operations int[] e_range = new\r
- * int[e_length]; System.arraycopy(this.range, o, e_range, 0, e_length);\r
- * char[] e_op = new char[e_length]; System.arraycopy(this.operation, o, e_op,\r
- * 0, e_length); length = o; // can now use add_operation to extend list. int\r
- * e_o=0; // current operation being edited. switch (op) { case M: switch\r
- * (e_op[e_o]) { case M: if (last_d && diff <= 0) { // reduce D's, if possible\r
- * if (range<=this.range[o-1]) { this.range[o - 1] -= range; } else {\r
- * this.range[o-1]=0; } if (this.range[o-1]==0) o--; // lose this op. }\r
- * e_range[e_o] += range; // just add more matched residues break; case I: //\r
- * change 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; } else {\r
- * this.range[o-1]=0; } if (this.range[o-1]==0) o--; // lose this op. }\r
- * e_range[e_o] break; default: throw new Inp }\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) { addOperation(e_op[e_o],\r
- * e_range[e_o]); e_o++; } } }\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,\r
* and removes any insertions.\r
* \r
* @param start\r
- * int\r
+ * int\r
* @param end\r
- * int\r
+ * int\r
* @return deleted int - number of symbols marked as deleted\r
*/\r
public int deleteRange(int start, int end)\r
* mark a range of inserted residues\r
* \r
* @param range\r
- * int\r
+ * int\r
*/\r
public void addInsertion(int range)\r
{\r
* mark the next range residues as hidden (not aligned) or deleted\r
* \r
* @param range\r
- * int\r
+ * int\r
*/\r
public void addDeleted(int range)\r
{\r
* editing will remove insertion operations, and convert matches to deletions\r
* \r
* @param start\r
- * alignment column\r
+ * alignment column\r
* @param end\r
- * alignment column\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
+ * 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