patch to fix occasional arrayoutofbounds exception when working with hidden columns...
[jalview.git] / src / jalview / util / ShiftList.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.4)\r
3  * Copyright (C) 2008 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4  * \r
5  * This program is free software; you can redistribute it and/or\r
6  * modify it under the terms of the GNU General Public License\r
7  * as published by the Free Software Foundation; either version 2\r
8  * of the License, or (at your option) any later version.\r
9  * \r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  * \r
15  * You should have received a copy of the GNU General Public License\r
16  * along with this program; if not, write to the Free Software\r
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18  */\r
19 package jalview.util;\r
20 \r
21 import java.util.*;\r
22 \r
23 /**\r
24  * ShiftList Simple way of mapping a linear series to a new linear range with\r
25  * new points introduced. Use at your own risk! Now growing to be used for\r
26  * interval ranges (position, offset) storing deletions/insertions\r
27  */\r
28 public class ShiftList\r
29 {\r
30   public Vector shifts;\r
31 \r
32   public ShiftList()\r
33   {\r
34     shifts = new Vector();\r
35   }\r
36 \r
37   /**\r
38    * addShift\r
39    * \r
40    * @param pos\r
41    *                start position for shift (in original reference frame)\r
42    * @param shift\r
43    *                length of shift\r
44    */\r
45   public void addShift(int pos, int shift)\r
46   {\r
47     int sidx = 0;\r
48     int[] rshift = null;\r
49     while (sidx < shifts.size()\r
50             && (rshift = (int[]) shifts.elementAt(sidx))[0] < pos)\r
51     {\r
52       sidx++;\r
53     }\r
54     if (sidx == shifts.size())\r
55     {\r
56       shifts.insertElementAt(new int[]\r
57       { pos, shift }, sidx);\r
58     }\r
59     else\r
60     {\r
61       rshift[1] += shift;\r
62     }\r
63   }\r
64 \r
65   /**\r
66    * shift\r
67    * \r
68    * @param pos\r
69    *                int\r
70    * @return int shifted position\r
71    */\r
72   public int shift(int pos)\r
73   {\r
74     if (shifts.size() == 0)\r
75     {\r
76       return pos;\r
77     }\r
78     int shifted = pos;\r
79     int sidx = 0;\r
80     int rshift[];\r
81     while (sidx < shifts.size()\r
82             && (rshift = ((int[]) shifts.elementAt(sidx++)))[0] <= pos)\r
83     {\r
84       shifted += rshift[1];\r
85     }\r
86     return shifted;\r
87   }\r
88 \r
89   /**\r
90    * clear all shifts\r
91    */\r
92   public void clear()\r
93   {\r
94     shifts.removeAllElements();\r
95   }\r
96 \r
97   /**\r
98    * invert the shifts\r
99    * \r
100    * @return ShiftList with inverse shift operations\r
101    */\r
102   public ShiftList getInverse()\r
103   {\r
104     ShiftList inverse = new ShiftList();\r
105     if (shifts != null)\r
106     {\r
107       for (int i = 0, j = shifts.size(); i < j; i++)\r
108       {\r
109         int[] sh = (int[]) shifts.elementAt(i);\r
110         if (sh != null)\r
111         {\r
112           inverse.shifts.addElement(new int[]\r
113           { sh[0], -sh[1] });\r
114         }\r
115       }\r
116     }\r
117     return inverse;\r
118   }\r
119 \r
120   /**\r
121    * parse a 1d map of position 1<i<n to L<pos[i]<N such as that returned\r
122    * from SequenceI.gapMap()\r
123    * \r
124    * @param gapMap\r
125    * @return shifts from map index to mapped position\r
126    */\r
127   public static ShiftList parseMap(int[] gapMap)\r
128   {\r
129     ShiftList shiftList = null;\r
130     if (gapMap != null && gapMap.length > 0)\r
131     {\r
132       shiftList = new ShiftList();\r
133       for (int i = 0, p = 0; i < gapMap.length; p++, i++)\r
134       {\r
135         if (p != gapMap[i])\r
136         {\r
137           shiftList.addShift(p, gapMap[i] - p);\r
138           p = gapMap[i];\r
139         }\r
140       }\r
141     }\r
142     return shiftList;\r
143   }\r
144 }\r