JAL-1807 explicit imports (jalview.io.*)
[jalview.git] / src / jalview / io / vamsas / Rangetype.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.io.vamsas;
22
23 import jalview.bin.Cache;
24 import jalview.io.VamsasAppDatastore;
25 import jalview.util.MapList;
26 import jalview.util.MessageManager;
27
28 import java.util.List;
29 import java.util.Vector;
30
31 import uk.ac.vamsas.client.Vobject;
32 import uk.ac.vamsas.objects.core.Local;
33 import uk.ac.vamsas.objects.core.MapType;
34 import uk.ac.vamsas.objects.core.Mapped;
35 import uk.ac.vamsas.objects.core.RangeType;
36 import uk.ac.vamsas.objects.core.Seg;
37
38 /**
39  * Enhances DatastoreItem objects with additional functions to do with RangeType
40  * objects
41  * 
42  * @author JimP
43  * 
44  */
45 public abstract class Rangetype extends DatastoreItem
46 {
47
48   public Rangetype()
49   {
50     super();
51   }
52
53   public Rangetype(VamsasAppDatastore datastore)
54   {
55     super(datastore);
56   }
57
58   public Rangetype(VamsasAppDatastore datastore, Vobject vobj, Class jvClass)
59   {
60     super(datastore, vobj, jvClass);
61   }
62
63   public Rangetype(VamsasAppDatastore datastore, Object jvobj, Class vClass)
64   {
65     super(datastore, jvobj, vClass);
66   }
67
68   /**
69    * get real bounds of a RangeType's specification. start and end are an
70    * inclusive range within which all segments and positions lie. TODO: refactor
71    * to vamsas utils
72    * 
73    * @param dseta
74    * @return int[] { start, end}
75    */
76   protected int[] getBounds(RangeType dseta)
77   {
78     if (dseta != null)
79     {
80       int[] se = null;
81       if (dseta.getSegCount() > 0 && dseta.getPosCount() > 0)
82       {
83         throw new Error(MessageManager.getString("error.invalid_vamsas_rangetype_cannot_resolve_lists"));
84       }
85       if (dseta.getSegCount() > 0)
86       {
87         se = getSegRange(dseta.getSeg(0), true);
88         for (int s = 1, sSize = dseta.getSegCount(); s < sSize; s++)
89         {
90           int nse[] = getSegRange(dseta.getSeg(s), true);
91           if (se[0] > nse[0])
92           {
93             se[0] = nse[0];
94           }
95           if (se[1] < nse[1])
96           {
97             se[1] = nse[1];
98           }
99         }
100       }
101       if (dseta.getPosCount() > 0)
102       {
103         // could do a polarity for pos range too. and pass back indication of
104         // discontinuities.
105         int pos = dseta.getPos(0).getI();
106         se = new int[]
107         { pos, pos };
108         for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++)
109         {
110           pos = dseta.getPos(p).getI();
111           if (se[0] > pos)
112           {
113             se[0] = pos;
114           }
115           if (se[1] < pos)
116           {
117             se[1] = pos;
118           }
119         }
120       }
121       return se;
122     }
123     return null;
124   }
125
126   /**
127    * map from a rangeType's internal frame to the referenced object's coordinate
128    * frame.
129    * 
130    * @param dseta
131    * @return int [] { ref(pos)...} for all pos in rangeType's frame.
132    */
133   protected int[] getMapping(RangeType dseta)
134   {
135     Vector posList = new Vector();
136     if (dseta != null)
137     {
138       int[] se = null;
139       if (dseta.getSegCount() > 0 && dseta.getPosCount() > 0)
140       {
141         throw new Error(MessageManager.getString("error.invalid_vamsas_rangetype_cannot_resolve_lists"));
142       }
143       if (dseta.getSegCount() > 0)
144       {
145         for (int s = 0, sSize = dseta.getSegCount(); s < sSize; s++)
146         {
147           se = getSegRange(dseta.getSeg(s), false);
148           int se_end = se[1 - se[2]] + (se[2] == 0 ? 1 : -1);
149           for (int p = se[se[2]]; p != se_end; p += se[2] == 0 ? 1 : -1)
150           {
151             posList.add(new Integer(p));
152           }
153         }
154       }
155       else if (dseta.getPosCount() > 0)
156       {
157         int pos = dseta.getPos(0).getI();
158
159         for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++)
160         {
161           pos = dseta.getPos(p).getI();
162           posList.add(new Integer(pos));
163         }
164       }
165     }
166     if (posList != null && posList.size() > 0)
167     {
168       int[] range = new int[posList.size()];
169       for (int i = 0; i < range.length; i++)
170       {
171         range[i] = ((Integer) posList.elementAt(i)).intValue();
172       }
173       posList.clear();
174       return range;
175     }
176     return null;
177   }
178
179   protected int[] getIntervals(RangeType range)
180   {
181     int[] intervals = null;
182     Vector posList = new Vector();
183     if (range != null)
184     {
185       int[] se = null;
186       if (range.getSegCount() > 0 && range.getPosCount() > 0)
187       {
188         throw new Error(MessageManager.getString("error.invalid_vamsas_rangetype_cannot_resolve_lists"));
189       }
190       if (range.getSegCount() > 0)
191       {
192         for (int s = 0, sSize = range.getSegCount(); s < sSize; s++)
193         {
194           se = getSegRange(range.getSeg(s), false);
195           posList.addElement(new Integer(se[0]));
196           posList.addElement(new Integer(se[1]));
197         }
198       }
199       else if (range.getPosCount() > 0)
200       {
201         int pos = range.getPos(0).getI();
202
203         for (int p = 0, pSize = range.getPosCount(); p < pSize; p++)
204         {
205           pos = range.getPos(p).getI();
206           posList.add(new Integer(pos));
207           posList.add(new Integer(pos));
208         }
209       }
210     }
211     if (posList != null && posList.size() > 0)
212     {
213       intervals = new int[posList.size()];
214       java.util.Enumeration e = posList.elements();
215       int i = 0;
216       while (e.hasMoreElements())
217       {
218         intervals[i++] = ((Integer) e.nextElement()).intValue();
219       }
220     }
221     return intervals;
222   }
223
224   /**
225    * initialise a range type object from a set of start/end inclusive intervals
226    * 
227    * @param mrt
228    * @param ranges
229    */
230   protected void initRangeType(RangeType mrt, List<int[]> ranges)
231   {
232     for (int[] range : ranges)
233     {
234       Seg vSeg = new Seg();
235       vSeg.setStart(range[0]);
236       vSeg.setEnd(range[1]);
237       vSeg.setInclusive(true);
238       mrt.addSeg(vSeg);
239     }
240   }
241
242   /**
243    * 
244    * @param maprange
245    *          where the from range is the local mapped range, and the to range
246    *          is the 'mapped' range in the MapRangeType
247    * @param default unit for local
248    * @param default unit for mapped
249    * @return MapList
250    */
251   protected MapList parsemapType(MapType maprange, int localu,
252           int mappedu)
253   {
254     MapList ml = null;
255     int[] localRange = getIntervals(maprange.getLocal());
256     int[] mappedRange = getIntervals(maprange.getMapped());
257     long lu = maprange.getLocal().hasUnit() ? maprange.getLocal().getUnit()
258             : localu;
259     long mu = maprange.getMapped().hasUnit() ? maprange.getMapped()
260             .getUnit() : mappedu;
261     ml = new MapList(localRange, mappedRange, (int) lu,
262             (int) mu);
263     return ml;
264   }
265
266   protected MapList parsemapType(MapType map)
267   {
268     if (!map.getLocal().hasUnit() || map.getMapped().hasUnit())
269     {
270       Cache.log
271               .warn("using default mapping length of 1:1 for map "
272                       + (map.isRegistered() ? map.getVorbaId().toString()
273                               : ("<no Id registered> " + map.toString())));
274     }
275     return parsemapType(map, 1, 1);
276   }
277
278   /**
279    * initialise a MapType object from a MapList object.
280    * 
281    * @param maprange
282    * @param ml
283    * @param setUnits
284    */
285   protected void initMapType(MapType maprange, MapList ml,
286           boolean setUnits)
287   {
288     initMapType(maprange, ml, setUnits, false);
289   }
290
291   /**
292    * 
293    * @param maprange
294    * @param ml
295    * @param setUnits
296    * @param reverse
297    *          - reverse MapList mapping for Local and Mapped ranges and units
298    */
299   protected void initMapType(MapType maprange, MapList ml,
300           boolean setUnits, boolean reverse)
301   {
302     if (ml == null)
303     {
304       throw new Error(MessageManager.getString("error.implementation_error_maplist_is_null"));
305     }
306     maprange.setLocal(new Local());
307     maprange.setMapped(new Mapped());
308     if (!reverse)
309     {
310       initRangeType(maprange.getLocal(), ml.getFromRanges());
311       initRangeType(maprange.getMapped(), ml.getToRanges());
312     }
313     else
314     {
315       initRangeType(maprange.getLocal(), ml.getToRanges());
316       initRangeType(maprange.getMapped(), ml.getFromRanges());
317     }
318     if (setUnits)
319     {
320       if (!reverse)
321       {
322         maprange.getLocal().setUnit(ml.getFromRatio());
323         maprange.getMapped().setUnit(ml.getToRatio());
324       }
325       else
326       {
327         maprange.getLocal().setUnit(ml.getToRatio());
328         maprange.getMapped().setUnit(ml.getFromRatio());
329       }
330       // TODO: and verify - raise an implementation fault notice if local/mapped
331       // range % Local/Mapped Ratio != 0
332       // if (uk.ac.vamsas.objects.utils.Range.getIntervals(range))
333
334     }
335   }
336
337 }