refactored form of vamsas document interaction code
[jalview.git] / src / jalview / io / vamsas / Rangetype.java
1 package jalview.io.vamsas;\r
2 \r
3 \r
4 import java.util.Vector;\r
5 \r
6 import uk.ac.vamsas.objects.core.Local;\r
7 import uk.ac.vamsas.objects.core.Map;\r
8 import uk.ac.vamsas.objects.core.MapType;\r
9 import uk.ac.vamsas.objects.core.Mapped;\r
10 import uk.ac.vamsas.objects.core.RangeType;\r
11 import uk.ac.vamsas.objects.core.Seg;\r
12 import jalview.datamodel.Mapping;\r
13 import jalview.io.VamsasAppDatastore;\r
14 \r
15 public class Rangetype extends DatastoreItem\r
16 {\r
17 \r
18   public Rangetype()\r
19   {\r
20     super();\r
21   }\r
22 \r
23   public Rangetype(VamsasAppDatastore datastore)\r
24   {\r
25     super(datastore);\r
26   }\r
27 \r
28   /**\r
29    * get real bounds of a RangeType's specification. start and end are an\r
30    * inclusive range within which all segments and positions lie.\r
31    * TODO: refactor to vamsas utils\r
32    * @param dseta\r
33    * @return int[] { start, end}\r
34    */\r
35   protected int[] getBounds(RangeType dseta)\r
36   {\r
37     if (dseta != null)\r
38     {\r
39       int[] se = null;\r
40       if (dseta.getSegCount() > 0 && dseta.getPosCount() > 0)\r
41       {\r
42         throw new Error("Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");\r
43       }\r
44       if (dseta.getSegCount() > 0)\r
45       {\r
46         se = getSegRange(dseta.getSeg(0), true);\r
47         for (int s = 1, sSize = dseta.getSegCount(); s < sSize; s++)\r
48         {\r
49           int nse[] = getSegRange(dseta.getSeg(s), true);\r
50           if (se[0] > nse[0])\r
51           {\r
52             se[0] = nse[0];\r
53           }\r
54           if (se[1] < nse[1])\r
55           {\r
56             se[1] = nse[1];\r
57           }\r
58         }\r
59       }\r
60       if (dseta.getPosCount() > 0)\r
61       {\r
62         // could do a polarity for pos range too. and pass back indication of discontinuities.\r
63         int pos = dseta.getPos(0).getI();\r
64         se = new int[]\r
65             {\r
66             pos, pos};\r
67         for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++)\r
68         {\r
69           pos = dseta.getPos(p).getI();\r
70           if (se[0] > pos)\r
71           {\r
72             se[0] = pos;\r
73           }\r
74           if (se[1] < pos)\r
75           {\r
76             se[1] = pos;\r
77           }\r
78         }\r
79       }\r
80       return se;\r
81     }\r
82     return null;\r
83   }\r
84 \r
85   /**\r
86    * map from a rangeType's internal frame to the referenced object's coordinate frame.\r
87    * @param dseta\r
88    * @return int [] { ref(pos)...} for all pos in rangeType's frame.\r
89    */\r
90   protected int[] getMapping(RangeType dseta)\r
91   {\r
92     Vector posList = new Vector();\r
93     if (dseta != null)\r
94     {\r
95       int[] se = null;\r
96       if (dseta.getSegCount() > 0 && dseta.getPosCount() > 0)\r
97       {\r
98         throw new Error("Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");\r
99       }\r
100       if (dseta.getSegCount() > 0)\r
101       {\r
102         for (int s = 0, sSize = dseta.getSegCount(); s < sSize; s++)\r
103         {\r
104           se = getSegRange(dseta.getSeg(s), false);\r
105           int se_end = se[1 - se[2]] + (se[2] == 0 ? 1 : -1);\r
106           for (int p = se[se[2]]; p != se_end; p += se[2] == 0 ? 1 : -1)\r
107           {\r
108             posList.add(new Integer(p));\r
109           }\r
110         }\r
111       }\r
112       else if (dseta.getPosCount() > 0)\r
113       {\r
114         int pos = dseta.getPos(0).getI();\r
115   \r
116         for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++)\r
117         {\r
118           pos = dseta.getPos(p).getI();\r
119           posList.add(new Integer(pos));\r
120         }\r
121       }\r
122     }\r
123     if (posList != null && posList.size() > 0)\r
124     {\r
125       int[] range = new int[posList.size()];\r
126       for (int i = 0; i < range.length; i++)\r
127       {\r
128         range[i] = ( (Integer) posList.elementAt(i)).intValue();\r
129       }\r
130       posList.clear();\r
131       return range;\r
132     }\r
133     return null;\r
134   }\r
135 \r
136   protected int[] getIntervals(RangeType range)\r
137   {\r
138     int[] intervals=null;\r
139     Vector posList = new Vector();\r
140     if (range != null)\r
141     {\r
142       int[] se = null;\r
143       if (range.getSegCount() > 0 && range.getPosCount() > 0)\r
144       {\r
145         throw new Error("Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");\r
146       }\r
147       if (range.getSegCount() > 0)\r
148       {\r
149         for (int s = 0, sSize = range.getSegCount(); s < sSize; s++)\r
150         {\r
151           se = getSegRange(range.getSeg(s), false);\r
152           posList.addElement(new Integer(se[0]));\r
153           posList.addElement(new Integer(se[1]));\r
154         }\r
155       }\r
156       else if (range.getPosCount() > 0)\r
157       {\r
158         int pos = range.getPos(0).getI();\r
159   \r
160         for (int p = 0, pSize = range.getPosCount(); p < pSize; p++)\r
161         {\r
162           pos = range.getPos(p).getI();\r
163           posList.add(new Integer(pos));\r
164           posList.add(new Integer(pos));\r
165         }\r
166       }\r
167     }\r
168     if (posList != null && posList.size() > 0)\r
169     {\r
170       intervals=new int[posList.size()];\r
171       java.util.Enumeration e = posList.elements();\r
172       int i=0;\r
173       while (e.hasMoreElements())\r
174       {\r
175         intervals[i++] = ((Integer)e.nextElement()).intValue();\r
176       }\r
177     }\r
178     return intervals;\r
179   }\r
180   /**\r
181    * initialise a range type object from a set of start/end inclusive intervals\r
182    * @param mrt\r
183    * @param range\r
184    */\r
185   protected void initRangeType(RangeType mrt, int[] range)\r
186   {\r
187     for (int i=0; i<range.length; i+=2)\r
188     {\r
189       Seg vSeg = new Seg();\r
190       vSeg.setStart(range[i]);\r
191       vSeg.setEnd(range[i+1]);\r
192       vSeg.setInclusive(true);\r
193       mrt.addSeg(vSeg);\r
194     }\r
195   }\r
196 \r
197   /**\r
198    * \r
199    * @param maprange where the from range is the local mapped range, and the to range is the 'mapped' range in the MapRangeType\r
200    * @param default unit for local\r
201    * @param default unit for mapped\r
202    * @return MapList\r
203    */\r
204   protected jalview.util.MapList parsemapType(MapType maprange, int localu, int mappedu)\r
205   {\r
206     jalview.util.MapList ml = null;\r
207     int[] localRange = getIntervals(maprange.getLocal());\r
208     int[] mappedRange = getIntervals(maprange.getMapped());\r
209     long lu = maprange.getLocal().hasUnit() ? maprange.getLocal().getUnit() : localu;\r
210     long mu = maprange.getMapped().hasUnit() ? maprange.getMapped().getUnit() : mappedu;\r
211     ml = new jalview.util.MapList(localRange, mappedRange, (int)lu, (int)mu);\r
212     return ml;\r
213   }\r
214   protected jalview.util.MapList parsemapType(MapType map)\r
215   {\r
216     if (!map.getLocal().hasUnit() || map.getMapped().hasUnit())\r
217     {\r
218       jalview.bin.Cache.log.warn("using default mapping length of 1:1 for map "\r
219               +(map.isRegistered() ? map.getVorbaId().toString() : ("<no Id registered> "+map.toString())));\r
220     }\r
221     return parsemapType(map, 1, 1); \r
222   }\r
223 \r
224   /**\r
225    * initialise a MapType object from a MapList object.\r
226    * @param maprange\r
227    * @param ml\r
228    * @param setUnits\r
229    */\r
230   protected void initMapType(MapType maprange, jalview.util.MapList ml, boolean setUnits)\r
231   {\r
232     initMapType(maprange, ml, setUnits, false);\r
233   }\r
234   /**\r
235    * \r
236    * @param maprange\r
237    * @param ml\r
238    * @param setUnits\r
239    * @param reverse - reverse MapList mapping for Local and Mapped ranges and units \r
240    */\r
241   protected void initMapType(MapType maprange, jalview.util.MapList ml, boolean setUnits, boolean reverse)\r
242   {\r
243     if (ml==null)\r
244     {\r
245       throw new Error("Implementation error. MapList is null for initMapType.");\r
246     }\r
247     maprange.setLocal(new Local());\r
248     maprange.setMapped(new Mapped());\r
249     if (!reverse)\r
250       {\r
251       initRangeType(maprange.getLocal(), ml.getFromRanges());\r
252       initRangeType(maprange.getMapped(), ml.getToRanges());\r
253       } else {\r
254         initRangeType(maprange.getLocal(), ml.getToRanges());\r
255         initRangeType(maprange.getMapped(), ml.getFromRanges());\r
256       }\r
257     if (setUnits)\r
258     {\r
259       if (!reverse)\r
260       { \r
261         maprange.getLocal().setUnit(ml.getFromRatio());\r
262         maprange.getMapped().setUnit(ml.getToRatio());\r
263       } else {\r
264         maprange.getLocal().setUnit(ml.getToRatio());\r
265         maprange.getMapped().setUnit(ml.getFromRatio());\r
266       }\r
267     }\r
268   }\r
269 \r
270 }