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