JAL-1807 Bob's JalviewJS prototype first commit
[jalviewjs.git] / src / jalview / util / ShiftList.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.util;
22
23 import java.util.ArrayList;
24 import java.util.List;
25
26 /**
27  * ShiftList Simple way of mapping a linear series to a new linear range with
28  * new points introduced. Use at your own risk! Now growing to be used for
29  * interval ranges (position, offset) storing deletions/insertions
30  */
31 public class ShiftList
32 {
33   private List<int[]> shifts;
34
35   public ShiftList()
36   {
37     shifts = new ArrayList<int[]>();
38   }
39
40   /**
41    * addShift
42    * 
43    * @param pos
44    *          start position for shift (in original reference frame)
45    * @param shift
46    *          length of shift
47    */
48   public void addShift(int pos, int shift)
49   {
50     synchronized (shifts)
51     {
52       int sidx = 0;
53       int[] rshift = null;
54       while (sidx < shifts.size() && (rshift = shifts.get(sidx))[0] < pos)
55       {
56         sidx++;
57       }
58       if (sidx == shifts.size())
59       {
60         shifts.add(sidx, new int[]
61         { pos, shift });
62       }
63       else
64       {
65         rshift[1] += shift;
66       }
67     }
68   }
69
70   /**
71    * shift
72    * 
73    * @param pos
74    *          int
75    * @return int shifted position
76    */
77   public int shift(int pos)
78   {
79     if (shifts.size() == 0)
80     {
81       return pos;
82     }
83     int shifted = pos;
84     int sidx = 0;
85     int rshift[];
86     while (sidx < shifts.size()
87             && (rshift = (shifts.get(sidx++)))[0] <= pos)
88     {
89       shifted += rshift[1];
90     }
91     return shifted;
92   }
93
94   /**
95    * clear all shifts
96    */
97   public synchronized void clear()
98   {
99     shifts.clear();
100   }
101
102   /**
103    * invert the shifts
104    * 
105    * @return ShiftList with inverse shift operations
106    */
107   public ShiftList getInverse()
108   {
109     ShiftList inverse = new ShiftList();
110     synchronized (shifts)
111     {
112       if (shifts != null)
113       {
114         for (int[] sh : shifts)
115         {
116           if (sh != null)
117           {
118             inverse.shifts.add(new int[]
119             { sh[0], -sh[1] });
120           }
121         }
122       }
123     }
124     return inverse;
125   }
126
127   /**
128    * parse a 1d map of position 1&lt;i&lt;n to L&lt;pos[i]&lt;N such as that
129    * returned from SequenceI.gapMap()
130    * 
131    * @param gapMap
132    * @return shifts from map index to mapped position
133    */
134   public static ShiftList parseMap(int[] gapMap)
135   {
136     ShiftList shiftList = null;
137     if (gapMap != null && gapMap.length > 0)
138     {
139       shiftList = new ShiftList();
140       for (int i = 0, p = 0; i < gapMap.length; p++, i++)
141       {
142         if (p != gapMap[i])
143         {
144           shiftList.addShift(p, gapMap[i] - p);
145           p = gapMap[i];
146         }
147       }
148     }
149     return shiftList;
150   }
151
152   public List<int[]> getShifts()
153   {
154     return shifts;
155   }
156 }