1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package org.utgenome.gwt.utgb.client.track;
26
27 import java.io.Serializable;
28
29 import org.utgenome.gwt.utgb.client.bio.OnGenome;
30
31
32
33
34
35
36
37
38 public class TrackWindow implements Serializable, Comparable<TrackWindow> {
39
40 private static final long serialVersionUID = 1L;
41
42 private final int pixelWidth;
43 private final int startIndexOnGenome;
44 private final int endIndexOnGenome;
45
46 public TrackWindow() {
47 this.pixelWidth = -1;
48 this.startIndexOnGenome = -1;
49 this.endIndexOnGenome = -1;
50 }
51
52 public TrackWindow(int pixelWidth, int startIndexOnGenome, int endIndexOnGenome) {
53 this.pixelWidth = pixelWidth;
54 this.startIndexOnGenome = startIndexOnGenome;
55 this.endIndexOnGenome = endIndexOnGenome;
56 }
57
58 public TrackWindow(TrackWindow other) {
59 this(other.pixelWidth, other.getStartOnGenome(), other.getEndOnGenome());
60 }
61
62
63
64
65
66
67
68 public int convertToPixelX(int indexOnGenome) {
69 double v = (indexOnGenome - startIndexOnGenome) * (double) pixelWidth;
70 double v2 = v / (endIndexOnGenome - startIndexOnGenome + 1);
71 if (!isReverseStrand())
72 return (int) (v2 + 0.5d);
73 else
74 return (int) (pixelWidth - v2 + 0.5d);
75 }
76
77 public double convertToPixelXDouble(int indexOnGenome) {
78 double v = (indexOnGenome - startIndexOnGenome) * (double) pixelWidth;
79 double v2 = v / (endIndexOnGenome - startIndexOnGenome + 1);
80 if (!isReverseStrand())
81 return v2;
82 else
83 return (pixelWidth - v2);
84 }
85
86
87
88
89
90
91 public int convertToGenomePosition(int xOnWindow) {
92 if (!isReverseStrand()) {
93 double genomeLengthPerBit = (double) (endIndexOnGenome - startIndexOnGenome) / (double) pixelWidth;
94 return (int) (startIndexOnGenome + xOnWindow * genomeLengthPerBit);
95 }
96 else {
97
98 double genomeLengthPerBit = (double) (startIndexOnGenome - endIndexOnGenome) / (double) pixelWidth;
99 return (int) (endIndexOnGenome + (pixelWidth - xOnWindow) * genomeLengthPerBit);
100 }
101 }
102
103 public int convertToPixelLength(int rangeOnGenome) {
104 return (int) ((pixelWidth * rangeOnGenome) / (double) (endIndexOnGenome - startIndexOnGenome));
105 }
106
107
108
109
110 public double getPixelLengthPerBase() {
111 return (double) pixelWidth / (double) (endIndexOnGenome - startIndexOnGenome);
112 }
113
114
115
116
117 public int getPixelWidth() {
118 return pixelWidth;
119 }
120
121
122
123
124 public int getSequenceLength() {
125 if (startIndexOnGenome <= endIndexOnGenome)
126 return endIndexOnGenome - startIndexOnGenome;
127 else
128 return startIndexOnGenome - endIndexOnGenome;
129 }
130
131 public int getViewStartOnGenome() {
132 if (isReverseStrand())
133 return endIndexOnGenome;
134 else
135 return startIndexOnGenome;
136 }
137
138 public int getViewEndOnGenome() {
139 if (isReverseStrand())
140 return startIndexOnGenome;
141 else
142 return endIndexOnGenome;
143 }
144
145
146
147
148 public int getStartOnGenome() {
149 return startIndexOnGenome;
150 }
151
152
153
154
155 public int getEndOnGenome() {
156 return endIndexOnGenome;
157 }
158
159 public boolean sameRangeWith(TrackWindow window) {
160 return this.startIndexOnGenome == window.getStartOnGenome() && this.endIndexOnGenome == window.getEndOnGenome();
161 }
162
163 public boolean isReverseStrand() {
164 return getStartOnGenome() > getEndOnGenome();
165 }
166
167 public boolean isPositiveStrand() {
168 return !isReverseStrand();
169 }
170
171 public TrackWindow newWindow(int newStartOnGenome, int newEndOnGenome) {
172 return new TrackWindow(this.pixelWidth, newStartOnGenome, newEndOnGenome);
173 }
174
175 public TrackWindow scroll(int startDiff) {
176 return new TrackWindow(this.pixelWidth, this.startIndexOnGenome + startDiff, this.endIndexOnGenome + startDiff);
177 }
178
179 public TrackWindow newPixelWidthWindow(int pixelSize) {
180 return new TrackWindow(pixelSize, this.startIndexOnGenome, this.endIndexOnGenome);
181 }
182
183 public boolean contains(TrackWindow other) {
184 int s1 = getViewStartOnGenome();
185 int e1 = getViewEndOnGenome();
186 int s2 = other.getViewStartOnGenome();
187 int e2 = other.getViewEndOnGenome();
188 return s1 <= s2 && e2 <= e1;
189 }
190
191 public boolean overlapWith(OnGenome g) {
192 int s1 = getStartOnGenome();
193 int e1 = getEndOnGenome();
194 int s2 = g.getStart();
195 int e2 = g.getEnd();
196
197 return s1 <= e2 && s2 <= e1;
198 }
199
200 public boolean overlapWith(TrackWindow other) {
201 int s1 = getStartOnGenome();
202 int e1 = getEndOnGenome();
203 int s2 = other.getStartOnGenome();
204 int e2 = other.getEndOnGenome();
205
206 return s1 < e2 && s2 < e1;
207 }
208
209 public boolean hasSameScaleWith(TrackWindow other) {
210 if (other == null)
211 return false;
212 return this.getPixelWidth() == other.getPixelWidth() && this.getSequenceLength() == other.getSequenceLength();
213 }
214
215 public TrackWindow mask(TrackWindow mask) {
216 int s, e, pixelWidth;
217 if (this.getStartOnGenome() < mask.getStartOnGenome()) {
218 s = this.getStartOnGenome();
219 e = mask.getStartOnGenome();
220 pixelWidth = convertToPixelX(e);
221 }
222 else {
223 s = mask.getEndOnGenome();
224 e = this.getEndOnGenome();
225 pixelWidth = this.getPixelWidth() - convertToPixelX(s);
226 }
227 return new TrackWindow(pixelWidth, s, e);
228 }
229
230 public int compareTo(TrackWindow o) {
231 return this.getViewStartOnGenome() - o.getViewStartOnGenome();
232 }
233
234
235 @Override
236 public boolean equals(Object o) {
237 if (o instanceof TrackWindow) {
238 TrackWindow window = (TrackWindow) o;
239 return sameRangeWith(window) && (this.pixelWidth == window.getPixelWidth());
240 }
241 else
242 return false;
243 }
244
245 public int center() {
246 return (int) ((startIndexOnGenome + endIndexOnGenome) / 2.0 + 0.5);
247 }
248
249 @Override
250 public int hashCode() {
251 int hash = 3;
252 hash += 137 * startIndexOnGenome;
253 hash += 137 * endIndexOnGenome;
254 hash += 137 * pixelWidth;
255 return hash / 1987;
256 }
257
258 @Override
259 public String toString() {
260 return "[" + getStartOnGenome() + ", " + getEndOnGenome() + ") pixel width: " + pixelWidth;
261 }
262 }