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