1 package uk.ac.vamsas.objects.utils;
\r
3 import java.util.Vector;
\r
5 import uk.ac.vamsas.objects.core.Local;
\r
6 import uk.ac.vamsas.objects.core.MapType;
\r
7 import uk.ac.vamsas.objects.core.Mapped;
\r
8 import uk.ac.vamsas.objects.core.RangeType;
\r
9 import uk.ac.vamsas.objects.core.Seg;
\r
12 * Utilities for working with RangeType and MapType objects.
\r
13 * Derived from bitter experience.
\r
17 public class Range {
\r
18 static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getFactory().getLog(Range.class);
\r
21 * get start<end range of segment, adjusting for inclusivity flag and
\r
25 * @param ensureDirection when true - always ensure start is less than end.
\r
26 * @return int[] { start, end, direction} where direction==1 for range running from end to start.
\r
28 public static int[] getSegRange(Seg visSeg, boolean ensureDirection)
\r
30 boolean incl = visSeg.getInclusive();
\r
31 // adjust for inclusive flag.
\r
32 int pol = (visSeg.getStart() <= visSeg.getEnd()) ? 1 : -1; // polarity of
\r
34 int start = visSeg.getStart() + (incl ? 0 : pol);
\r
35 int end = visSeg.getEnd() + (incl ? 0 : -pol);
\r
36 if (ensureDirection && pol == -1)
\r
38 // jalview doesn't deal with inverted ranges, yet.
\r
45 start, end, pol < 0 ? 1 : 0};
\r
49 * get real bounds of a RangeType's specification. start and end are an
\r
50 * inclusive range within which all segments and positions lie.
\r
51 * TODO: refactor to vamsas utils
\r
53 * @return int[] { start, end}
\r
55 public static int[] getBounds(RangeType dseta)
\r
60 if (dseta.getSegCount() > 0 && dseta.getPosCount() > 0)
\r
62 throw new Error("Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");
\r
64 if (dseta.getSegCount() > 0)
\r
66 se = getSegRange(dseta.getSeg(0), true);
\r
67 for (int s = 1, sSize = dseta.getSegCount(); s < sSize; s++)
\r
69 int nse[] = getSegRange(dseta.getSeg(s), true);
\r
80 if (dseta.getPosCount() > 0)
\r
82 // could do a polarity for pos range too. and pass back indication of discontinuities.
\r
83 int pos = dseta.getPos(0).getI();
\r
87 for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++)
\r
89 pos = dseta.getPos(p).getI();
\r
106 * map from a rangeType's internal frame to the referenced object's coordinate frame.
\r
108 * @return int [] { ref(pos)...} for all pos in rangeType's frame.
\r
110 public static int[] getMapping(RangeType dseta)
\r
112 Vector posList = new Vector();
\r
116 if (dseta.getSegCount() > 0 && dseta.getPosCount() > 0)
\r
118 throw new Error("Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");
\r
120 if (dseta.getSegCount() > 0)
\r
122 for (int s = 0, sSize = dseta.getSegCount(); s < sSize; s++)
\r
124 se = getSegRange(dseta.getSeg(s), false);
\r
125 int se_end = se[1 - se[2]] + (se[2] == 0 ? 1 : -1);
\r
126 for (int p = se[se[2]]; p != se_end; p += se[2] == 0 ? 1 : -1)
\r
128 posList.add(new Integer(p));
\r
132 else if (dseta.getPosCount() > 0)
\r
134 int pos = dseta.getPos(0).getI();
\r
136 for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++)
\r
138 pos = dseta.getPos(p).getI();
\r
139 posList.add(new Integer(pos));
\r
143 if (posList != null && posList.size() > 0)
\r
145 int[] range = new int[posList.size()];
\r
146 for (int i = 0; i < range.length; i++)
\r
148 range[i] = ( (Integer) posList.elementAt(i)).intValue();
\r
156 public static int[] getIntervals(RangeType range)
\r
158 int[] intervals=null;
\r
159 Vector posList = new Vector();
\r
163 if (range.getSegCount() > 0 && range.getPosCount() > 0)
\r
165 throw new Error("Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");
\r
167 if (range.getSegCount() > 0)
\r
169 for (int s = 0, sSize = range.getSegCount(); s < sSize; s++)
\r
171 se = getSegRange(range.getSeg(s), false);
\r
172 posList.addElement(new Integer(se[0]));
\r
173 posList.addElement(new Integer(se[1]));
\r
176 else if (range.getPosCount() > 0)
\r
178 int pos = range.getPos(0).getI();
\r
179 for (int p = 0, pSize = range.getPosCount(); p < pSize; p++)
\r
181 pos = range.getPos(p).getI();
\r
182 posList.add(new Integer(pos));
\r
183 posList.add(new Integer(pos));
\r
187 if (posList != null && posList.size() > 0)
\r
189 intervals=new int[posList.size()];
\r
190 java.util.Enumeration e = posList.elements();
\r
192 while (e.hasMoreElements())
\r
194 intervals[i++] = ((Integer)e.nextElement()).intValue();
\r
200 * initialise a range type object from a set of start/end inclusive intervals
\r
204 public static void initRangeType(RangeType mrt, int[] range)
\r
206 for (int i=0; i<range.length; i+=2)
\r
208 Seg vSeg = new Seg();
\r
209 vSeg.setStart(range[i]);
\r
210 vSeg.setEnd(range[i+1]);
\r
211 vSeg.setInclusive(true);
\r
218 * @param maprange where the from range is the local mapped range, and the to range is the 'mapped' range in the MapRangeType
\r
219 * @param default unit for local
\r
220 * @param default unit for mapped
\r
223 public static MapList parsemapType(MapType maprange, int localu, int mappedu)
\r
226 int[] localRange = getIntervals(maprange.getLocal());
\r
227 int[] mappedRange = getIntervals(maprange.getMapped());
\r
228 long lu = maprange.getLocal().hasUnit() ? maprange.getLocal().getUnit() : localu;
\r
229 long mu = maprange.getMapped().hasUnit() ? maprange.getMapped().getUnit() : mappedu;
\r
230 ml = new MapList(localRange, mappedRange, (int)lu, (int)mu);
\r
234 * Parse map with default units of 1,1
\r
236 * @return MapList representing map
\r
238 public static MapList parsemapType(MapType map)
\r
240 if (!map.getLocal().hasUnit() || !map.getMapped().hasUnit())
\r
242 if (log.isDebugEnabled())
\r
245 "using default mapping length of 1:1 for map "
\r
246 +(map.isRegistered() ? map.getVorbaId().toString() : ("<no Id registered> "+map.toString())));
\r
249 return parsemapType(map, 1, 1);
\r
253 * initialise a MapType object from a MapList object.
\r
258 public static void initMapType(MapType maprange, MapList ml, boolean setUnits)
\r
260 initMapType(maprange, ml, setUnits, false);
\r
267 * @param reverse - reverse MapList mapping for Local and Mapped ranges and units
\r
269 public static void initMapType(MapType maprange, MapList ml, boolean setUnits, boolean reverse)
\r
271 maprange.setLocal(new Local());
\r
272 maprange.setMapped(new Mapped());
\r
275 initRangeType(maprange.getLocal(), ml.getFromRanges());
\r
276 initRangeType(maprange.getMapped(), ml.getToRanges());
\r
278 initRangeType(maprange.getLocal(), ml.getToRanges());
\r
279 initRangeType(maprange.getMapped(), ml.getFromRanges());
\r
285 maprange.getLocal().setUnit(ml.getFromRatio());
\r
286 maprange.getMapped().setUnit(ml.getToRatio());
\r
288 maprange.getLocal().setUnit(ml.getToRatio());
\r
289 maprange.getMapped().setUnit(ml.getFromRatio());
\r