b20cb5bf2db74586fa3c9c4c260f01c96566f9a2
[vamsas.git] / src / uk / ac / vamsas / objects / utils / Range.java
1 package uk.ac.vamsas.objects.utils;\r
2 \r
3 import java.util.Vector;\r
4 \r
5 \r
6 import uk.ac.vamsas.objects.core.RangeType;\r
7 import uk.ac.vamsas.objects.core.Seg;\r
8 \r
9 public class Range {\r
10 \r
11   /**\r
12    * get start<end range of segment, adjusting for inclusivity flag and\r
13    * polarity.\r
14    *\r
15    * @param visSeg\r
16    * @param ensureDirection when true - always ensure start is less than end.\r
17    * @return int[] { start, end, direction} where direction==1 for range running from end to start.\r
18    */\r
19   public static int[] getSegRange(Seg visSeg, boolean ensureDirection)\r
20   {\r
21     boolean incl = visSeg.getInclusive();\r
22     // adjust for inclusive flag.\r
23     int pol = (visSeg.getStart() <= visSeg.getEnd()) ? 1 : -1; // polarity of\r
24     // region.\r
25     int start = visSeg.getStart() + (incl ? 0 : pol);\r
26     int end = visSeg.getEnd() + (incl ? 0 : -pol);\r
27     if (ensureDirection && pol == -1)\r
28     {\r
29       // jalview doesn't deal with inverted ranges, yet.\r
30       int t = end;\r
31       end = start;\r
32       start = t;\r
33     }\r
34     return new int[]\r
35         {\r
36         start, end, pol < 0 ? 1 : 0};\r
37   }\r
38 \r
39   /**\r
40    * get real bounds of a RangeType's specification. start and end are an\r
41    * inclusive range within which all segments and positions lie.\r
42    * TODO: refactor to vamsas utils\r
43    * @param dseta\r
44    * @return int[] { start, end}\r
45    */\r
46   public static int[] getBounds(RangeType dseta)\r
47   {\r
48     if (dseta != null)\r
49     {\r
50       int[] se = null;\r
51       if (dseta.getSegCount() > 0 && dseta.getPosCount() > 0)\r
52       {\r
53         throw new Error("Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");\r
54       }\r
55       if (dseta.getSegCount() > 0)\r
56       {\r
57         se = getSegRange(dseta.getSeg(0), true);\r
58         for (int s = 1, sSize = dseta.getSegCount(); s < sSize; s++)\r
59         {\r
60           int nse[] = getSegRange(dseta.getSeg(s), true);\r
61           if (se[0] > nse[0])\r
62           {\r
63             se[0] = nse[0];\r
64           }\r
65           if (se[1] < nse[1])\r
66           {\r
67             se[1] = nse[1];\r
68           }\r
69         }\r
70       }\r
71       if (dseta.getPosCount() > 0)\r
72       {\r
73         // could do a polarity for pos range too. and pass back indication of discontinuities.\r
74         int pos = dseta.getPos(0).getI();\r
75         se = new int[]\r
76             {\r
77             pos, pos};\r
78         for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++)\r
79         {\r
80           pos = dseta.getPos(p).getI();\r
81           if (se[0] > pos)\r
82           {\r
83             se[0] = pos;\r
84           }\r
85           if (se[1] < pos)\r
86           {\r
87             se[1] = pos;\r
88           }\r
89         }\r
90       }\r
91       return se;\r
92     }\r
93     return null;\r
94   }\r
95 \r
96   /**\r
97    * map from a rangeType's internal frame to the referenced object's coordinate frame.\r
98    * @param dseta\r
99    * @return int [] { ref(pos)...} for all pos in rangeType's frame.\r
100    */\r
101   public static int[] getMapping(RangeType dseta)\r
102   {\r
103     Vector posList = new Vector();\r
104     if (dseta != null)\r
105     {\r
106       int[] se = null;\r
107       if (dseta.getSegCount() > 0 && dseta.getPosCount() > 0)\r
108       {\r
109         throw new Error("Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");\r
110       }\r
111       if (dseta.getSegCount() > 0)\r
112       {\r
113         for (int s = 0, sSize = dseta.getSegCount(); s < sSize; s++)\r
114         {\r
115           se = getSegRange(dseta.getSeg(s), false);\r
116           int se_end = se[1 - se[2]] + (se[2] == 0 ? 1 : -1);\r
117           for (int p = se[se[2]]; p != se_end; p += se[2] == 0 ? 1 : -1)\r
118           {\r
119             posList.add(new Integer(p));\r
120           }\r
121         }\r
122       }\r
123       else if (dseta.getPosCount() > 0)\r
124       {\r
125         int pos = dseta.getPos(0).getI();\r
126 \r
127         for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++)\r
128         {\r
129           pos = dseta.getPos(p).getI();\r
130           posList.add(new Integer(pos));\r
131         }\r
132       }\r
133     }\r
134     if (posList != null && posList.size() > 0)\r
135     {\r
136       int[] range = new int[posList.size()];\r
137       for (int i = 0; i < range.length; i++)\r
138       {\r
139         range[i] = ( (Integer) posList.elementAt(i)).intValue();\r
140       }\r
141       posList.clear();\r
142       return range;\r
143     }\r
144     return null;\r
145   }\r
146 }\r