ensure lastSeq is refreshed if new feature added
[jalview.git] / src / jalview / util / ShiftList.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2006 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 jalview.datamodel.SequenceI;\r
22 \r
23 import java.util.*;\r
24 \r
25 /**\r
26  * ShiftList\r
27  * Simple way of mapping a linear series to a new linear range with new points introduced.\r
28  * Use at your own risk!\r
29  * Now growing to be used for interval ranges (position, offset) storing deletions/insertions\r
30  */\r
31 public class ShiftList\r
32 {\r
33     public Vector shifts;\r
34   public ShiftList()\r
35   {\r
36     shifts = new Vector();\r
37   }\r
38 \r
39   /**\r
40    * addShift\r
41    * @param pos start position for shift (in original reference frame)\r
42    * @param shift length of shift\r
43    */\r
44   public void addShift(int pos, int shift)\r
45   {\r
46     int sidx = 0;\r
47     int[] rshift=null;\r
48     while (sidx<shifts.size() && (rshift=(int[]) shifts.elementAt(sidx))[0]<pos)\r
49       sidx++;\r
50     if (sidx==shifts.size())\r
51       shifts.insertElementAt(new int[] { pos, shift}, sidx);\r
52     else\r
53       rshift[1]+=shift;\r
54   }\r
55 \r
56   /**\r
57    * shift\r
58    *\r
59    * @param pos int\r
60    * @return int shifted position\r
61    */\r
62   public int shift(int pos)\r
63   {\r
64     if (shifts.size()==0)\r
65       return pos;\r
66     int shifted=pos;\r
67     int sidx=0;\r
68     int rshift[];\r
69     while (sidx<shifts.size()\r
70            &&\r
71            (rshift=((int[]) shifts.elementAt(sidx++)))[0]<=pos) {\r
72       shifted += rshift[1];\r
73     }\r
74     return shifted;\r
75   }\r
76 \r
77   /**\r
78    * clear all shifts\r
79    */\r
80   public void clear()\r
81   {\r
82     shifts.removeAllElements();\r
83   }\r
84   /**\r
85    * invert the shifts\r
86    * @return ShiftList with inverse shift operations\r
87    */\r
88   public ShiftList getInverse() {\r
89     ShiftList inverse=new ShiftList();\r
90     if (shifts!=null) {\r
91       for (int i=0,j=shifts.size(); i<j; i++) {\r
92         int[] sh=(int[]) shifts.elementAt(i);\r
93         if (sh!=null)\r
94           inverse.shifts.addElement(new int[] {sh[0], -sh[1]});\r
95       }\r
96     }\r
97     return inverse;\r
98   }\r
99 \r
100   /**\r
101    * parse a 1d map of position 1<i<n to L<pos[i]<N\r
102    * such as that returned from SequenceI.gapMap()\r
103    * @param gapMap\r
104    * @return shifts from map index to mapped position\r
105    */\r
106   public static ShiftList parseMap(int[] gapMap) {\r
107     ShiftList shiftList = null;\r
108     if (gapMap!=null && gapMap.length>0) {\r
109       shiftList=new ShiftList();\r
110       for (int i=0,p=0; i<gapMap.length; p++,i++) {\r
111         if (p!=gapMap[i]) {\r
112           shiftList.addShift(p, gapMap[i]-p);\r
113           p=gapMap[i];\r
114         }\r
115       }\r
116     }\r
117     return shiftList;\r
118   }\r
119 }\r