Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
MapListTest | 42 | 710 | 64 |
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.util; | |
22 | ||
23 | import static org.testng.AssertJUnit.assertEquals; | |
24 | import static org.testng.AssertJUnit.assertFalse; | |
25 | import static org.testng.AssertJUnit.assertNull; | |
26 | import static org.testng.AssertJUnit.assertSame; | |
27 | import static org.testng.AssertJUnit.assertTrue; | |
28 | import static org.testng.AssertJUnit.fail; | |
29 | import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals; | |
30 | ||
31 | import java.util.ArrayList; | |
32 | import java.util.Arrays; | |
33 | import java.util.BitSet; | |
34 | import java.util.List; | |
35 | ||
36 | import org.testng.annotations.BeforeClass; | |
37 | import org.testng.annotations.Test; | |
38 | ||
39 | import jalview.bin.Console; | |
40 | import jalview.gui.JvOptionPane; | |
41 | ||
42 | public class MapListTest | |
43 | { | |
44 | 1 | @BeforeClass(alwaysRun = true) |
45 | public void setUp() | |
46 | { | |
47 | 1 | Console.initLogger(); |
48 | } | |
49 | ||
50 | 1 | @BeforeClass(alwaysRun = true) |
51 | public void setUpJvOptionPane() | |
52 | { | |
53 | 1 | JvOptionPane.setInteractiveMode(false); |
54 | 1 | JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION); |
55 | } | |
56 | ||
57 | 0 | @Test(groups = { "Functional" }, enabled = false) |
58 | public void testSomething() | |
59 | { | |
60 | 0 | MapList ml = new MapList(new int[] { 1, 5, 10, 15, 25, 20 }, |
61 | new int[] | |
62 | { 51, 1 }, 1, 3); | |
63 | 0 | MapList ml1 = new MapList(new int[] { 1, 3, 17, 4 }, |
64 | new int[] | |
65 | { 51, 1 }, 1, 3); | |
66 | 0 | MapList ml2 = new MapList(new int[] { 1, 60 }, new int[] { 1, 20 }, 3, |
67 | 1); | |
68 | // test internal consistency | |
69 | 0 | int to[] = new int[51]; |
70 | 0 | testMap(ml, 1, 60); |
71 | 0 | MapList mldna = new MapList(new int[] { 2, 2, 6, 8, 12, 16 }, |
72 | new int[] | |
73 | { 1, 3 }, 3, 1); | |
74 | 0 | int[] frm = mldna.locateInFrom(1, 1); |
75 | 0 | testLocateFrom(mldna, 1, 1, new int[] { 2, 2, 6, 7 }); |
76 | 0 | testMap(mldna, 1, 3); |
77 | /* | |
78 | * for (int from=1; from<=51; from++) { int[] too=ml.shiftTo(from); int[] | |
79 | * toofrom=ml.shiftFrom(too[0]); | |
80 | * System.out.println("ShiftFrom("+from+")=="+too[0]+" % | |
81 | * "+too[1]+"\t+-+\tShiftTo("+too[0]+")=="+toofrom[0]+" % "+toofrom[1]); } | |
82 | */ | |
83 | } | |
84 | ||
85 | 0 | private static void testLocateFrom(MapList mldna, int i, int j, int[] ks) |
86 | { | |
87 | 0 | int[] frm = mldna.locateInFrom(i, j); |
88 | 0 | assertEquals("Failed test locate from " + i + " to " + j, |
89 | Arrays.toString(frm), Arrays.toString(ks)); | |
90 | } | |
91 | ||
92 | /** | |
93 | * test routine. not incremental. | |
94 | * | |
95 | * @param ml | |
96 | * @param fromS | |
97 | * @param fromE | |
98 | */ | |
99 | 0 | private void testMap(MapList ml, int fromS, int fromE) |
100 | { | |
101 | // todo convert to JUnit style tests | |
102 | 0 | for (int from = 1; from <= 25; from++) |
103 | { | |
104 | 0 | int[] too = ml.shiftFrom(from); |
105 | 0 | System.out.print("ShiftFrom(" + from + ")=="); |
106 | 0 | if (too == null) |
107 | { | |
108 | 0 | System.out.print("NaN\n"); |
109 | } | |
110 | else | |
111 | { | |
112 | 0 | System.out.print(too[0] + " % " + too[1] + " (" + too[2] + ")"); |
113 | 0 | System.out.print("\t+--+\t"); |
114 | 0 | int[] toofrom = ml.shiftTo(too[0]); |
115 | 0 | if (toofrom != null) |
116 | { | |
117 | 0 | if (toofrom[0] != from) |
118 | { | |
119 | 0 | System.err.println("Mapping not reflexive:" + from + " " |
120 | + too[0] + "->" + toofrom[0]); | |
121 | } | |
122 | 0 | System.out.println("ShiftTo(" + too[0] + ")==" + toofrom[0] |
123 | + " % " + toofrom[1] + " (" + toofrom[2] + ")"); | |
124 | } | |
125 | else | |
126 | { | |
127 | 0 | System.out.println("ShiftTo(" + too[0] + ")==" |
128 | + "NaN! - not Bijective Mapping!"); | |
129 | } | |
130 | } | |
131 | } | |
132 | 0 | int mmap[][] = ml.makeFromMap(); |
133 | 0 | System.out.println("FromMap : (" + mmap[0][0] + " " + mmap[0][1] + " " |
134 | + mmap[0][2] + " " + mmap[0][3] + " "); | |
135 | 0 | for (int i = 1; i <= mmap[1].length; i++) |
136 | { | |
137 | 0 | if (mmap[1][i - 1] == -1) |
138 | { | |
139 | 0 | System.out.print(i + "=XXX"); |
140 | ||
141 | } | |
142 | else | |
143 | { | |
144 | 0 | System.out.print(i + "=" + (mmap[0][2] + mmap[1][i - 1])); |
145 | } | |
146 | 0 | if (i % 20 == 0) |
147 | { | |
148 | 0 | System.out.print("\n"); |
149 | } | |
150 | else | |
151 | { | |
152 | 0 | System.out.print(","); |
153 | } | |
154 | } | |
155 | // test range function | |
156 | 0 | System.out.print("\nTest locateInFrom\n"); |
157 | { | |
158 | 0 | int f = mmap[0][2], t = mmap[0][3]; |
159 | 0 | while (f <= t) |
160 | { | |
161 | 0 | System.out.println("Range " + f + " to " + t); |
162 | 0 | int rng[] = ml.locateInFrom(f, t); |
163 | 0 | if (rng != null) |
164 | { | |
165 | 0 | for (int i = 0; i < rng.length; i++) |
166 | { | |
167 | 0 | System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";")); |
168 | } | |
169 | } | |
170 | else | |
171 | { | |
172 | 0 | System.out.println("No range!"); |
173 | } | |
174 | 0 | System.out.print("\nReversed\n"); |
175 | 0 | rng = ml.locateInFrom(t, f); |
176 | 0 | if (rng != null) |
177 | { | |
178 | 0 | for (int i = 0; i < rng.length; i++) |
179 | { | |
180 | 0 | System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";")); |
181 | } | |
182 | } | |
183 | else | |
184 | { | |
185 | 0 | System.out.println("No range!"); |
186 | } | |
187 | 0 | System.out.print("\n"); |
188 | 0 | f++; |
189 | 0 | t--; |
190 | } | |
191 | } | |
192 | 0 | System.out.print("\n"); |
193 | 0 | mmap = ml.makeToMap(); |
194 | 0 | System.out.println("ToMap : (" + mmap[0][0] + " " + mmap[0][1] + " " |
195 | + mmap[0][2] + " " + mmap[0][3] + " "); | |
196 | 0 | for (int i = 1; i <= mmap[1].length; i++) |
197 | { | |
198 | 0 | if (mmap[1][i - 1] == -1) |
199 | { | |
200 | 0 | System.out.print(i + "=XXX"); |
201 | ||
202 | } | |
203 | else | |
204 | { | |
205 | 0 | System.out.print(i + "=" + (mmap[0][2] + mmap[1][i - 1])); |
206 | } | |
207 | 0 | if (i % 20 == 0) |
208 | { | |
209 | 0 | System.out.print("\n"); |
210 | } | |
211 | else | |
212 | { | |
213 | 0 | System.out.print(","); |
214 | } | |
215 | } | |
216 | 0 | System.out.print("\n"); |
217 | // test range function | |
218 | 0 | System.out.print("\nTest locateInTo\n"); |
219 | { | |
220 | 0 | int f = mmap[0][2], t = mmap[0][3]; |
221 | 0 | while (f <= t) |
222 | { | |
223 | 0 | System.out.println("Range " + f + " to " + t); |
224 | 0 | int rng[] = ml.locateInTo(f, t); |
225 | 0 | if (rng != null) |
226 | { | |
227 | 0 | for (int i = 0; i < rng.length; i++) |
228 | { | |
229 | 0 | System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";")); |
230 | } | |
231 | } | |
232 | else | |
233 | { | |
234 | 0 | System.out.println("No range!"); |
235 | } | |
236 | 0 | System.out.print("\nReversed\n"); |
237 | 0 | rng = ml.locateInTo(t, f); |
238 | 0 | if (rng != null) |
239 | { | |
240 | 0 | for (int i = 0; i < rng.length; i++) |
241 | { | |
242 | 0 | System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";")); |
243 | } | |
244 | } | |
245 | else | |
246 | { | |
247 | 0 | System.out.println("No range!"); |
248 | } | |
249 | 0 | f++; |
250 | 0 | t--; |
251 | 0 | System.out.print("\n"); |
252 | } | |
253 | } | |
254 | } | |
255 | ||
256 | /** | |
257 | * Tests for method that locates ranges in the 'from' map for given range in | |
258 | * the 'to' map. | |
259 | */ | |
260 | 1 | @Test(groups = { "Functional" }) |
261 | public void testLocateInFrom_noIntrons() | |
262 | { | |
263 | /* | |
264 | * Simple mapping with no introns | |
265 | */ | |
266 | 1 | int[] codons = new int[] { 1, 12 }; |
267 | 1 | int[] protein = new int[] { 1, 4 }; |
268 | 1 | MapList ml = new MapList(codons, protein, 3, 1); |
269 | 1 | assertEquals("[1, 3]", Arrays.toString(ml.locateInFrom(1, 1))); |
270 | 1 | assertEquals("[4, 6]", Arrays.toString(ml.locateInFrom(2, 2))); |
271 | 1 | assertEquals("[7, 9]", Arrays.toString(ml.locateInFrom(3, 3))); |
272 | 1 | assertEquals("[10, 12]", Arrays.toString(ml.locateInFrom(4, 4))); |
273 | 1 | assertEquals("[1, 6]", Arrays.toString(ml.locateInFrom(1, 2))); |
274 | 1 | assertEquals("[1, 9]", Arrays.toString(ml.locateInFrom(1, 3))); |
275 | // reversed range treated as if forwards: | |
276 | 1 | assertEquals("[1, 9]", Arrays.toString(ml.locateInFrom(3, 1))); |
277 | 1 | assertEquals("[1, 12]", Arrays.toString(ml.locateInFrom(1, 4))); |
278 | 1 | assertEquals("[4, 9]", Arrays.toString(ml.locateInFrom(2, 3))); |
279 | 1 | assertEquals("[4, 12]", Arrays.toString(ml.locateInFrom(2, 4))); |
280 | 1 | assertEquals("[7, 12]", Arrays.toString(ml.locateInFrom(3, 4))); |
281 | 1 | assertEquals("[10, 12]", Arrays.toString(ml.locateInFrom(4, 4))); |
282 | ||
283 | /* | |
284 | * partial overlap | |
285 | */ | |
286 | 1 | assertEquals("[1, 12]", Arrays.toString(ml.locateInFrom(1, 5))); |
287 | 1 | assertEquals("[1, 3]", Arrays.toString(ml.locateInFrom(-1, 1))); |
288 | ||
289 | /* | |
290 | * no overlap | |
291 | */ | |
292 | 1 | assertNull(ml.locateInFrom(0, 0)); |
293 | ||
294 | } | |
295 | ||
296 | /** | |
297 | * Tests for method that locates ranges in the 'from' map for given range in | |
298 | * the 'to' map. | |
299 | */ | |
300 | 1 | @Test(groups = { "Functional" }) |
301 | public void testLocateInFrom_withIntrons() | |
302 | { | |
303 | /* | |
304 | * Exons at positions [2, 3, 5] [6, 7, 9] [10, 12, 14] [16, 17, 18] i.e. | |
305 | * 2-3, 5-7, 9-10, 12-12, 14-14, 16-18 | |
306 | */ | |
307 | 1 | int[] codons = { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 }; |
308 | 1 | int[] protein = { 1, 4 }; |
309 | 1 | MapList ml = new MapList(codons, protein, 3, 1); |
310 | 1 | assertEquals("[2, 3, 5, 5]", Arrays.toString(ml.locateInFrom(1, 1))); |
311 | 1 | assertEquals("[6, 7, 9, 9]", Arrays.toString(ml.locateInFrom(2, 2))); |
312 | 1 | assertEquals("[10, 10, 12, 12, 14, 14]", |
313 | Arrays.toString(ml.locateInFrom(3, 3))); | |
314 | 1 | assertEquals("[16, 18]", Arrays.toString(ml.locateInFrom(4, 4))); |
315 | ||
316 | /* | |
317 | * codons at 11-16, 21-26, 31-36 mapped to peptide positions 1, 3-4, 6-8 | |
318 | */ | |
319 | 1 | ml = new MapList(new int[] { 11, 16, 21, 26, 31, 36 }, |
320 | new int[] | |
321 | { 1, 1, 3, 4, 6, 8 }, 3, 1); | |
322 | 1 | assertArrayEquals(new int[] { 11, 13 }, ml.locateInFrom(1, 1)); |
323 | 1 | assertArrayEquals(new int[] { 11, 16 }, ml.locateInFrom(1, 3)); |
324 | 1 | assertArrayEquals(new int[] { 11, 16, 21, 23 }, ml.locateInFrom(1, 4)); |
325 | 1 | assertArrayEquals(new int[] { 14, 16, 21, 23 }, ml.locateInFrom(3, 4)); |
326 | ||
327 | } | |
328 | ||
329 | 1 | @Test(groups = { "Functional" }) |
330 | public void testLocateInFrom_reverseStrand() | |
331 | { | |
332 | 1 | int[] codons = new int[] { 12, 1 }; |
333 | 1 | int[] protein = new int[] { 1, 4 }; |
334 | 1 | MapList ml = new MapList(codons, protein, 3, 1); |
335 | 1 | assertEquals("[12, 10]", Arrays.toString(ml.locateInFrom(1, 1))); |
336 | 1 | assertEquals("[9, 4]", Arrays.toString(ml.locateInFrom(2, 3))); |
337 | } | |
338 | ||
339 | /** | |
340 | * Tests for method that locates the overlap of the ranges in the 'from' map | |
341 | * for given range in the 'to' map | |
342 | */ | |
343 | 1 | @Test(groups = { "Functional" }) |
344 | public void testGetOverlapsInFrom_withIntrons() | |
345 | { | |
346 | /* | |
347 | * Exons at positions [2, 3, 5] [6, 7, 9] [10, 12, 14] [16, 17, 18] i.e. | |
348 | * 2-3, 5-7, 9-10, 12-12, 14-14, 16-18 | |
349 | */ | |
350 | 1 | int[] codons = { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 }; |
351 | 1 | int[] protein = { 11, 14 }; |
352 | 1 | MapList ml = new MapList(codons, protein, 3, 1); |
353 | ||
354 | 1 | assertEquals("[2, 3, 5, 5]", |
355 | Arrays.toString(ml.getOverlapsInFrom(11, 11))); | |
356 | 1 | assertEquals("[2, 3, 5, 7, 9, 9]", |
357 | Arrays.toString(ml.getOverlapsInFrom(11, 12))); | |
358 | // out of range 5' : | |
359 | 1 | assertEquals("[2, 3, 5, 7, 9, 9]", |
360 | Arrays.toString(ml.getOverlapsInFrom(8, 12))); | |
361 | // out of range 3' : | |
362 | 1 | assertEquals("[10, 10, 12, 12, 14, 14, 16, 18]", |
363 | Arrays.toString(ml.getOverlapsInFrom(13, 16))); | |
364 | // out of range both : | |
365 | 1 | assertEquals("[2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18]", |
366 | Arrays.toString(ml.getOverlapsInFrom(1, 16))); | |
367 | // no overlap: | |
368 | 1 | assertNull(ml.getOverlapsInFrom(20, 25)); |
369 | } | |
370 | ||
371 | /** | |
372 | * Tests for method that locates the overlap of the ranges in the 'to' map for | |
373 | * given range in the 'from' map | |
374 | */ | |
375 | 1 | @Test(groups = { "Functional" }) |
376 | public void testGetOverlapsInTo_withIntrons() | |
377 | { | |
378 | /* | |
379 | * Exons at positions [2, 3, 5] [6, 7, 9] [10, 12, 14] [17, 18, 19] i.e. | |
380 | * 2-3, 5-7, 9-10, 12-12, 14-14, 17-19 | |
381 | */ | |
382 | 1 | int[] codons = { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 17, 19 }; |
383 | /* | |
384 | * Mapped proteins at positions 1, 3, 4, 6 in the sequence | |
385 | */ | |
386 | 1 | int[] protein = { 1, 1, 3, 4, 6, 6 }; |
387 | 1 | MapList ml = new MapList(codons, protein, 3, 1); |
388 | ||
389 | /* | |
390 | * Can't map from an unmapped position | |
391 | */ | |
392 | 1 | assertNull(ml.getOverlapsInTo(1, 1)); |
393 | 1 | assertNull(ml.getOverlapsInTo(4, 4)); |
394 | 1 | assertNull(ml.getOverlapsInTo(15, 16)); |
395 | ||
396 | /* | |
397 | * nor from a range that includes no mapped position (exon) | |
398 | */ | |
399 | 1 | assertNull(ml.getOverlapsInTo(15, 16)); |
400 | ||
401 | // end of codon 1 maps to first peptide | |
402 | 1 | assertEquals("[1, 1]", Arrays.toString(ml.getOverlapsInTo(2, 2))); |
403 | // end of codon 1 and start of codon 2 maps to first 2 peptides | |
404 | 1 | assertEquals("[1, 1, 3, 3]", Arrays.toString(ml.getOverlapsInTo(3, 7))); |
405 | ||
406 | // range overlaps 5' end of dna: | |
407 | 1 | assertEquals("[1, 1, 3, 3]", Arrays.toString(ml.getOverlapsInTo(1, 6))); |
408 | 1 | assertEquals("[1, 1, 3, 3]", Arrays.toString(ml.getOverlapsInTo(1, 8))); |
409 | ||
410 | // range overlaps 3' end of dna: | |
411 | 1 | assertEquals("[6, 6]", Arrays.toString(ml.getOverlapsInTo(17, 24))); |
412 | 1 | assertEquals("[6, 6]", Arrays.toString(ml.getOverlapsInTo(16, 24))); |
413 | ||
414 | // dna positions 8, 11 are intron but include end of exon 2 and start of | |
415 | // exon 3 | |
416 | 1 | assertEquals("[3, 4]", Arrays.toString(ml.getOverlapsInTo(8, 11))); |
417 | } | |
418 | ||
419 | /** | |
420 | * Tests for method that locates ranges in the 'to' map for given range in the | |
421 | * 'from' map. | |
422 | */ | |
423 | 1 | @Test(groups = { "Functional" }) |
424 | public void testLocateInTo_noIntrons() | |
425 | { | |
426 | /* | |
427 | * Simple mapping with no introns | |
428 | */ | |
429 | 1 | int[] codons = new int[] { 1, 12 }; |
430 | 1 | int[] protein = new int[] { 1, 4 }; |
431 | 1 | MapList ml = new MapList(codons, protein, 3, 1); |
432 | 1 | assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(1, 3))); |
433 | 1 | assertEquals("[2, 2]", Arrays.toString(ml.locateInTo(4, 6))); |
434 | 1 | assertEquals("[3, 3]", Arrays.toString(ml.locateInTo(7, 9))); |
435 | 1 | assertEquals("[4, 4]", Arrays.toString(ml.locateInTo(10, 12))); |
436 | 1 | assertEquals("[1, 2]", Arrays.toString(ml.locateInTo(1, 6))); |
437 | 1 | assertEquals("[1, 3]", Arrays.toString(ml.locateInTo(1, 9))); |
438 | 1 | assertEquals("[1, 4]", Arrays.toString(ml.locateInTo(1, 12))); |
439 | 1 | assertEquals("[2, 2]", Arrays.toString(ml.locateInTo(4, 6))); |
440 | 1 | assertEquals("[2, 4]", Arrays.toString(ml.locateInTo(4, 12))); |
441 | // reverse range treated as if forwards: | |
442 | 1 | assertEquals("[2, 4]", Arrays.toString(ml.locateInTo(12, 4))); |
443 | ||
444 | /* | |
445 | * A part codon is treated as if a whole one. | |
446 | */ | |
447 | 1 | assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(1, 1))); |
448 | 1 | assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(1, 2))); |
449 | 1 | assertEquals("[1, 2]", Arrays.toString(ml.locateInTo(1, 4))); |
450 | 1 | assertEquals("[1, 3]", Arrays.toString(ml.locateInTo(2, 8))); |
451 | 1 | assertEquals("[1, 4]", Arrays.toString(ml.locateInTo(3, 11))); |
452 | 1 | assertEquals("[2, 4]", Arrays.toString(ml.locateInTo(5, 11))); |
453 | ||
454 | /* | |
455 | * partial overlap | |
456 | */ | |
457 | 1 | assertEquals("[1, 4]", Arrays.toString(ml.locateInTo(1, 13))); |
458 | 1 | assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(-1, 2))); |
459 | ||
460 | /* | |
461 | * no overlap | |
462 | */ | |
463 | 1 | assertNull(ml.locateInTo(0, 0)); |
464 | } | |
465 | ||
466 | /** | |
467 | * Tests for method that locates ranges in the 'to' map for given range in the | |
468 | * 'from' map. | |
469 | */ | |
470 | 1 | @Test(groups = { "Functional" }) |
471 | public void testLocateInTo_withIntrons() | |
472 | { | |
473 | /* | |
474 | * Exons at positions [2, 3, 5] [6, 7, 9] [10, 12, 14] [16, 17, 18] i.e. | |
475 | * 2-3, 5-7, 9-10, 12-12, 14-14, 16-18 | |
476 | */ | |
477 | 1 | int[] codons = { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 }; |
478 | /* | |
479 | * Mapped proteins at positions 1, 3, 4, 6 in the sequence | |
480 | */ | |
481 | 1 | int[] protein = { 1, 1, 3, 4, 6, 6 }; |
482 | 1 | MapList ml = new MapList(codons, protein, 3, 1); |
483 | ||
484 | /* | |
485 | * Valid range or subrange of codon1 maps to protein1 | |
486 | */ | |
487 | 1 | assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(2, 2))); |
488 | 1 | assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(3, 3))); |
489 | 1 | assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(3, 5))); |
490 | 1 | assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(2, 3))); |
491 | 1 | assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(2, 5))); |
492 | ||
493 | // codon position 6 starts the next protein: | |
494 | 1 | assertEquals("[1, 1, 3, 3]", Arrays.toString(ml.locateInTo(3, 6))); |
495 | ||
496 | // codon positions 7 to 17 (part) cover proteins 2/3/4 at positions 3/4/6 | |
497 | 1 | assertEquals("[3, 4, 6, 6]", Arrays.toString(ml.locateInTo(7, 17))); |
498 | ||
499 | /* | |
500 | * partial overlap | |
501 | */ | |
502 | 1 | assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(1, 2))); |
503 | 1 | assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(1, 4))); |
504 | 1 | assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(2, 4))); |
505 | ||
506 | /* | |
507 | * no overlap | |
508 | */ | |
509 | 1 | assertNull(ml.locateInTo(4, 4)); |
510 | } | |
511 | ||
512 | /** | |
513 | * Test equals method. | |
514 | */ | |
515 | 1 | @Test(groups = { "Functional" }) |
516 | public void testEquals() | |
517 | { | |
518 | 1 | int[] codons = new int[] { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 }; |
519 | 1 | int[] protein = new int[] { 1, 4 }; |
520 | 1 | MapList ml = new MapList(codons, protein, 3, 1); |
521 | 1 | MapList ml1 = new MapList(codons, protein, 3, 1); // same values |
522 | 1 | MapList ml2 = new MapList(codons, protein, 2, 1); // fromRatio differs |
523 | 1 | MapList ml3 = new MapList(codons, protein, 3, 2); // toRatio differs |
524 | 1 | codons[2] = 4; |
525 | 1 | MapList ml6 = new MapList(codons, protein, 3, 1); // fromShifts differ |
526 | 1 | protein[1] = 3; |
527 | 1 | MapList ml7 = new MapList(codons, protein, 3, 1); // toShifts differ |
528 | ||
529 | 1 | assertTrue(ml.equals(ml)); |
530 | 1 | assertEquals(ml.hashCode(), ml.hashCode()); |
531 | 1 | assertTrue(ml.equals(ml1)); |
532 | 1 | assertEquals(ml.hashCode(), ml1.hashCode()); |
533 | 1 | assertTrue(ml1.equals(ml)); |
534 | ||
535 | 1 | assertFalse(ml.equals(null)); |
536 | 1 | assertFalse(ml.equals("hello")); |
537 | 1 | assertFalse(ml.equals(ml2)); |
538 | 1 | assertFalse(ml.equals(ml3)); |
539 | 1 | assertFalse(ml.equals(ml6)); |
540 | 1 | assertFalse(ml.equals(ml7)); |
541 | 1 | assertFalse(ml6.equals(ml7)); |
542 | ||
543 | 1 | try |
544 | { | |
545 | 1 | MapList ml4 = new MapList(codons, null, 3, 1); // toShifts null |
546 | 0 | assertFalse(ml.equals(ml4)); |
547 | } catch (NullPointerException e) | |
548 | { | |
549 | // actually thrown by constructor before equals can be called | |
550 | } | |
551 | 1 | try |
552 | { | |
553 | 1 | MapList ml5 = new MapList(null, protein, 3, 1); // fromShifts null |
554 | 0 | assertFalse(ml.equals(ml5)); |
555 | } catch (NullPointerException e) | |
556 | { | |
557 | // actually thrown by constructor before equals can be called | |
558 | } | |
559 | } | |
560 | ||
561 | /** | |
562 | * Test for the method that flattens a list of ranges into a single array. | |
563 | */ | |
564 | 1 | @Test(groups = { "Functional" }) |
565 | public void testGetRanges() | |
566 | { | |
567 | 1 | List<int[]> ranges = new ArrayList<>(); |
568 | 1 | ranges.add(new int[] { 2, 3 }); |
569 | 1 | ranges.add(new int[] { 5, 6 }); |
570 | 1 | assertEquals("[2, 3, 5, 6]", |
571 | Arrays.toString(MapList.getRanges(ranges))); | |
572 | } | |
573 | ||
574 | /** | |
575 | * Check state after construction | |
576 | */ | |
577 | 1 | @Test(groups = { "Functional" }) |
578 | public void testConstructor() | |
579 | { | |
580 | 1 | int[] codons = { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 }; |
581 | 1 | int[] protein = { 1, 1, 3, 4, 6, 6 }; |
582 | 1 | MapList ml = new MapList(codons, protein, 3, 1); |
583 | 1 | assertEquals(3, ml.getFromRatio()); |
584 | 1 | assertEquals(2, ml.getFromLowest()); |
585 | 1 | assertEquals(18, ml.getFromHighest()); |
586 | 1 | assertEquals(1, ml.getToLowest()); |
587 | 1 | assertEquals(6, ml.getToHighest()); |
588 | 1 | assertEquals("{[2, 3], [5, 7], [9, 10], [12, 12], [14, 14], [16, 18]}", |
589 | prettyPrint(ml.getFromRanges())); | |
590 | 1 | assertEquals("{[1, 1], [3, 4], [6, 6]}", prettyPrint(ml.getToRanges())); |
591 | ||
592 | /* | |
593 | * Also copy constructor | |
594 | */ | |
595 | 1 | MapList ml2 = new MapList(ml); |
596 | 1 | assertEquals(3, ml2.getFromRatio()); |
597 | 1 | assertEquals(2, ml2.getFromLowest()); |
598 | 1 | assertEquals(18, ml2.getFromHighest()); |
599 | 1 | assertEquals(1, ml2.getToLowest()); |
600 | 1 | assertEquals(6, ml2.getToHighest()); |
601 | 1 | assertEquals("{[2, 3], [5, 7], [9, 10], [12, 12], [14, 14], [16, 18]}", |
602 | prettyPrint(ml2.getFromRanges())); | |
603 | 1 | assertEquals("{[1, 1], [3, 4], [6, 6]}", |
604 | prettyPrint(ml2.getToRanges())); | |
605 | ||
606 | /* | |
607 | * reverse direction | |
608 | */ | |
609 | 1 | codons = new int[] { 9, 6 }; |
610 | 1 | protein = new int[] { 100, 91, 80, 79 }; |
611 | 1 | ml = new MapList(codons, protein, 3, 1); |
612 | 1 | assertEquals(6, ml.getFromLowest()); |
613 | 1 | assertEquals(9, ml.getFromHighest()); |
614 | 1 | assertEquals(79, ml.getToLowest()); |
615 | 1 | assertEquals(100, ml.getToHighest()); |
616 | } | |
617 | ||
618 | /** | |
619 | * Test constructor used to merge consecutive ranges but now just leaves them | |
620 | * as supplied (JAL-3751) | |
621 | */ | |
622 | 1 | @Test(groups = { "Functional" }) |
623 | public void testConstructor_mergeRanges() | |
624 | { | |
625 | 1 | int[] codons = { 2, 3, 3, 7, 9, 10, 12, 12, 13, 14, 16, 17 }; |
626 | 1 | int[] protein = { 1, 1, 2, 3, 6, 6 }; |
627 | 1 | MapList ml = new MapList(codons, protein, 3, 1); |
628 | 1 | assertEquals(3, ml.getFromRatio()); |
629 | 1 | assertEquals(2, ml.getFromLowest()); |
630 | 1 | assertEquals(17, ml.getFromHighest()); |
631 | 1 | assertEquals(1, ml.getToLowest()); |
632 | 1 | assertEquals(6, ml.getToHighest()); |
633 | 1 | assertEquals("{[2, 3], [3, 7], [9, 10], [12, 12], [13, 14], [16, 17]}", |
634 | prettyPrint(ml.getFromRanges())); | |
635 | 1 | assertEquals("{[1, 1], [2, 3], [6, 6]}", prettyPrint(ml.getToRanges())); |
636 | } | |
637 | ||
638 | /** | |
639 | * Convert a List of {[i, j], [k, l], ...} to "[[i, j], [k, l], ...]" | |
640 | * | |
641 | * @param ranges | |
642 | * @return | |
643 | */ | |
644 | 14 | private String prettyPrint(List<int[]> ranges) |
645 | { | |
646 | 14 | StringBuilder sb = new StringBuilder(ranges.size() * 5); |
647 | 14 | boolean first = true; |
648 | 14 | sb.append("{"); |
649 | 14 | for (int[] range : ranges) |
650 | { | |
651 | 53 | if (!first) |
652 | { | |
653 | 39 | sb.append(", "); |
654 | } | |
655 | 53 | sb.append(Arrays.toString(range)); |
656 | 53 | first = false; |
657 | } | |
658 | 14 | sb.append("}"); |
659 | 14 | return sb.toString(); |
660 | } | |
661 | ||
662 | /** | |
663 | * Test the method that creates an inverse mapping | |
664 | */ | |
665 | 1 | @Test(groups = { "Functional" }) |
666 | public void testGetInverse() | |
667 | { | |
668 | 1 | int[] codons = { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 }; |
669 | 1 | int[] protein = { 1, 1, 3, 4, 6, 6 }; |
670 | ||
671 | 1 | MapList ml = new MapList(codons, protein, 3, 1); |
672 | 1 | MapList ml2 = ml.getInverse(); |
673 | 1 | assertEquals(ml.getFromRatio(), ml2.getToRatio()); |
674 | 1 | assertEquals(ml.getFromRatio(), ml2.getToRatio()); |
675 | 1 | assertEquals(ml.getToHighest(), ml2.getFromHighest()); |
676 | 1 | assertEquals(ml.getFromHighest(), ml2.getToHighest()); |
677 | 1 | assertEquals(prettyPrint(ml.getFromRanges()), |
678 | prettyPrint(ml2.getToRanges())); | |
679 | 1 | assertEquals(prettyPrint(ml.getToRanges()), |
680 | prettyPrint(ml2.getFromRanges())); | |
681 | } | |
682 | ||
683 | 1 | @Test(groups = { "Functional" }) |
684 | public void testToString() | |
685 | { | |
686 | 1 | MapList ml = new MapList(new int[] { 1, 5, 10, 15, 25, 20 }, |
687 | new int[] | |
688 | { 51, 1 }, 1, 3); | |
689 | 1 | String s = ml.toString(); |
690 | 1 | assertEquals("[ [1, 5] [10, 15] [25, 20] ] 1:3 to [ [51, 1] ]", s); |
691 | } | |
692 | ||
693 | 1 | @Test(groups = { "Functional" }) |
694 | public void testAddMapList() | |
695 | { | |
696 | 1 | MapList ml = new MapList(new int[] { 11, 15, 20, 25, 35, 30 }, |
697 | new int[] | |
698 | { 72, 22 }, 1, 3); | |
699 | 1 | assertEquals(11, ml.getFromLowest()); |
700 | 1 | assertEquals(35, ml.getFromHighest()); |
701 | 1 | assertEquals(22, ml.getToLowest()); |
702 | 1 | assertEquals(72, ml.getToHighest()); |
703 | ||
704 | 1 | MapList ml2 = new MapList(new int[] { 2, 4, 37, 40 }, |
705 | new int[] | |
706 | { 12, 17, 78, 83, 88, 96 }, 1, 3); | |
707 | 1 | ml.addMapList(ml2); |
708 | 1 | assertEquals(2, ml.getFromLowest()); |
709 | 1 | assertEquals(40, ml.getFromHighest()); |
710 | 1 | assertEquals(12, ml.getToLowest()); |
711 | 1 | assertEquals(96, ml.getToHighest()); |
712 | ||
713 | 1 | String s = ml.toString(); |
714 | 1 | assertEquals( |
715 | "[ [11, 15] [20, 25] [35, 30] [2, 4] [37, 40] ] 1:3 to [ [72, 22] [12, 17] [78, 83] [88, 96] ]", | |
716 | s); | |
717 | } | |
718 | ||
719 | /** | |
720 | * Test that confirms adding a map twice does nothing | |
721 | */ | |
722 | 1 | @Test(groups = { "Functional" }) |
723 | public void testAddMapList_sameMap() | |
724 | { | |
725 | 1 | MapList ml = new MapList(new int[] { 11, 15, 20, 25, 35, 30 }, |
726 | new int[] | |
727 | { 72, 22 }, 1, 3); | |
728 | 1 | String before = ml.toString(); |
729 | 1 | ml.addMapList(ml); |
730 | 1 | assertEquals(before, ml.toString()); |
731 | 1 | ml.addMapList(new MapList(ml)); |
732 | 1 | assertEquals(before, ml.toString()); |
733 | } | |
734 | ||
735 | 1 | @Test(groups = { "Functional" }) |
736 | public void testAddMapList_contiguous() | |
737 | { | |
738 | 1 | MapList ml = new MapList(new int[] { 11, 15 }, new int[] { 72, 58 }, 1, |
739 | 3); | |
740 | ||
741 | 1 | MapList ml2 = new MapList(new int[] { 15, 16 }, new int[] { 58, 53 }, 1, |
742 | 3); | |
743 | 1 | ml.addMapList(ml2); |
744 | 1 | assertEquals("[ [11, 16] ] 1:3 to [ [72, 53] ]", ml.toString()); |
745 | } | |
746 | ||
747 | 1 | @Test(groups = "Functional") |
748 | public void testAddRange() | |
749 | { | |
750 | 1 | int[] range = { 1, 5 }; |
751 | 1 | List<int[]> ranges = new ArrayList<>(); |
752 | ||
753 | // add to empty list: | |
754 | 1 | MapList.addRange(range, ranges); |
755 | 1 | assertEquals(1, ranges.size()); |
756 | 1 | assertSame(range, ranges.get(0)); |
757 | ||
758 | // extend contiguous (same position): | |
759 | 1 | MapList.addRange(new int[] { 5, 10 }, ranges); |
760 | 1 | assertEquals(1, ranges.size()); |
761 | 1 | assertEquals(1, ranges.get(0)[0]); |
762 | 1 | assertEquals(10, ranges.get(0)[1]); |
763 | ||
764 | // extend contiguous (next position): | |
765 | 1 | MapList.addRange(new int[] { 11, 15 }, ranges); |
766 | 1 | assertEquals(1, ranges.size()); |
767 | 1 | assertEquals(1, ranges.get(0)[0]); |
768 | 1 | assertEquals(15, ranges.get(0)[1]); |
769 | ||
770 | // change direction: range is not merged: | |
771 | 1 | MapList.addRange(new int[] { 16, 10 }, ranges); |
772 | 1 | assertEquals(2, ranges.size()); |
773 | 1 | assertEquals(16, ranges.get(1)[0]); |
774 | 1 | assertEquals(10, ranges.get(1)[1]); |
775 | ||
776 | // extend reverse contiguous (same position): | |
777 | 1 | MapList.addRange(new int[] { 10, 8 }, ranges); |
778 | 1 | assertEquals(2, ranges.size()); |
779 | 1 | assertEquals(16, ranges.get(1)[0]); |
780 | 1 | assertEquals(8, ranges.get(1)[1]); |
781 | ||
782 | // extend reverse contiguous (next position): | |
783 | 1 | MapList.addRange(new int[] { 7, 6 }, ranges); |
784 | 1 | assertEquals(2, ranges.size()); |
785 | 1 | assertEquals(16, ranges.get(1)[0]); |
786 | 1 | assertEquals(6, ranges.get(1)[1]); |
787 | ||
788 | // change direction: range is not merged: | |
789 | 1 | MapList.addRange(new int[] { 6, 9 }, ranges); |
790 | 1 | assertEquals(3, ranges.size()); |
791 | 1 | assertEquals(6, ranges.get(2)[0]); |
792 | 1 | assertEquals(9, ranges.get(2)[1]); |
793 | ||
794 | // not contiguous: not merged | |
795 | 1 | MapList.addRange(new int[] { 11, 12 }, ranges); |
796 | 1 | assertEquals(4, ranges.size()); |
797 | 1 | assertEquals(11, ranges.get(3)[0]); |
798 | 1 | assertEquals(12, ranges.get(3)[1]); |
799 | } | |
800 | ||
801 | /** | |
802 | * Check state after construction | |
803 | */ | |
804 | 1 | @Test(groups = { "Functional" }) |
805 | public void testConstructor_withLists() | |
806 | { | |
807 | /* | |
808 | * reverse direction | |
809 | */ | |
810 | 1 | int[][] codons = new int[][] { { 9, 6 } }; |
811 | 1 | int[][] protein = new int[][] { { 100, 91 }, { 80, 79 } }; |
812 | 1 | MapList ml = new MapList(Arrays.asList(codons), Arrays.asList(protein), |
813 | 3, 1); | |
814 | 1 | assertEquals(6, ml.getFromLowest()); |
815 | 1 | assertEquals(9, ml.getFromHighest()); |
816 | 1 | assertEquals(79, ml.getToLowest()); |
817 | 1 | assertEquals(100, ml.getToHighest()); |
818 | } | |
819 | ||
820 | /** | |
821 | * Test that method that inspects for the (first) forward or reverse from | |
822 | * range. Single position ranges are ignored. | |
823 | */ | |
824 | 1 | @Test(groups = { "Functional" }) |
825 | public void testIsFromForwardStrand() | |
826 | { | |
827 | // [3-9] declares forward strand | |
828 | 1 | MapList ml = new MapList(new int[] { 2, 2, 3, 9, 12, 11 }, |
829 | new int[] | |
830 | { 20, 11 }, 1, 1); | |
831 | 1 | assertTrue(ml.isFromForwardStrand()); |
832 | ||
833 | // [11-5] declares reverse strand ([13-14] is ignored) | |
834 | 1 | ml = new MapList(new int[] { 2, 2, 11, 5, 13, 14 }, |
835 | new int[] | |
836 | { 20, 11 }, 1, 1); | |
837 | 1 | assertFalse(ml.isFromForwardStrand()); |
838 | ||
839 | // all single position ranges - defaults to forward strand | |
840 | 1 | ml = new MapList(new int[] { 2, 2, 4, 4, 6, 6 }, new int[] { 3, 1 }, 1, |
841 | 1); | |
842 | 1 | assertTrue(ml.isFromForwardStrand()); |
843 | } | |
844 | ||
845 | /** | |
846 | * Test the method that merges contiguous ranges | |
847 | */ | |
848 | 1 | @Test(groups = { "Functional" }) |
849 | public void testCoalesceRanges() | |
850 | { | |
851 | 1 | assertNull(MapList.coalesceRanges(null)); |
852 | 1 | List<int[]> ranges = new ArrayList<>(); |
853 | 1 | assertSame(ranges, MapList.coalesceRanges(ranges)); |
854 | 1 | ranges.add(new int[] { 1, 3 }); |
855 | 1 | assertSame(ranges, MapList.coalesceRanges(ranges)); |
856 | ||
857 | // add non-contiguous range: | |
858 | 1 | ranges.add(new int[] { 5, 6 }); |
859 | 1 | assertSame(ranges, MapList.coalesceRanges(ranges)); |
860 | ||
861 | // 'contiguous' range in opposite direction is not merged: | |
862 | 1 | ranges.add(new int[] { 7, 6 }); |
863 | 1 | assertSame(ranges, MapList.coalesceRanges(ranges)); |
864 | ||
865 | // merging in forward direction: | |
866 | 1 | ranges.clear(); |
867 | 1 | ranges.add(new int[] { 1, 3 }); |
868 | 1 | ranges.add(new int[] { 4, 5 }); // contiguous |
869 | 1 | ranges.add(new int[] { 5, 5 }); // overlap! |
870 | 1 | ranges.add(new int[] { 6, 7 }); // contiguous |
871 | 1 | List<int[]> merged = MapList.coalesceRanges(ranges); |
872 | 1 | assertEquals(2, merged.size()); |
873 | 1 | assertArrayEquals(new int[] { 1, 5 }, merged.get(0)); |
874 | 1 | assertArrayEquals(new int[] { 5, 7 }, merged.get(1)); |
875 | // verify input list is unchanged | |
876 | 1 | assertEquals(4, ranges.size()); |
877 | 1 | assertArrayEquals(new int[] { 1, 3 }, ranges.get(0)); |
878 | 1 | assertArrayEquals(new int[] { 4, 5 }, ranges.get(1)); |
879 | 1 | assertArrayEquals(new int[] { 5, 5 }, ranges.get(2)); |
880 | 1 | assertArrayEquals(new int[] { 6, 7 }, ranges.get(3)); |
881 | ||
882 | // merging in reverse direction: | |
883 | 1 | ranges.clear(); |
884 | 1 | ranges.add(new int[] { 7, 5 }); |
885 | 1 | ranges.add(new int[] { 5, 4 }); // overlap |
886 | 1 | ranges.add(new int[] { 4, 4 }); // overlap |
887 | 1 | ranges.add(new int[] { 3, 1 }); // contiguous |
888 | 1 | merged = MapList.coalesceRanges(ranges); |
889 | 1 | assertEquals(3, merged.size()); |
890 | 1 | assertArrayEquals(new int[] { 7, 5 }, merged.get(0)); |
891 | 1 | assertArrayEquals(new int[] { 5, 4 }, merged.get(1)); |
892 | 1 | assertArrayEquals(new int[] { 4, 1 }, merged.get(2)); |
893 | ||
894 | // merging with switches of direction: | |
895 | 1 | ranges.clear(); |
896 | 1 | ranges.add(new int[] { 1, 3 }); |
897 | 1 | ranges.add(new int[] { 4, 5 }); // contiguous |
898 | 1 | ranges.add(new int[] { 5, 5 }); // overlap |
899 | 1 | ranges.add(new int[] { 6, 6 }); // contiguous |
900 | 1 | ranges.add(new int[] { 12, 10 }); |
901 | 1 | ranges.add(new int[] { 9, 8 }); // contiguous |
902 | 1 | ranges.add(new int[] { 8, 8 }); // overlap |
903 | 1 | ranges.add(new int[] { 7, 7 }); // contiguous |
904 | 1 | merged = MapList.coalesceRanges(ranges); |
905 | 1 | assertEquals(4, merged.size()); |
906 | 1 | assertArrayEquals(new int[] { 1, 5 }, merged.get(0)); |
907 | 1 | assertArrayEquals(new int[] { 5, 6 }, merged.get(1)); |
908 | 1 | assertArrayEquals(new int[] { 12, 8 }, merged.get(2)); |
909 | 1 | assertArrayEquals(new int[] { 8, 7 }, merged.get(3)); |
910 | ||
911 | // 'subsumed' ranges are preserved | |
912 | 1 | ranges.clear(); |
913 | 1 | ranges.add(new int[] { 10, 30 }); |
914 | 1 | ranges.add(new int[] { 15, 25 }); |
915 | ||
916 | 1 | merged = MapList.coalesceRanges(ranges); |
917 | 1 | assertEquals(2, merged.size()); |
918 | 1 | assertArrayEquals(new int[] { 10, 30 }, merged.get(0)); |
919 | 1 | assertArrayEquals(new int[] { 15, 25 }, merged.get(1)); |
920 | } | |
921 | ||
922 | /** | |
923 | * Test the method that compounds ('traverses') two mappings | |
924 | */ | |
925 | 1 | @Test(groups = "Functional") |
926 | public void testTraverse() | |
927 | { | |
928 | /* | |
929 | * simple 1:1 plus 1:1 forwards | |
930 | */ | |
931 | 1 | MapList ml1 = new MapList(new int[] { 3, 4, 8, 12 }, |
932 | new int[] | |
933 | { 5, 8, 11, 13 }, 1, 1); | |
934 | 1 | assertEquals("{[3, 4], [8, 12]}", prettyPrint(ml1.getFromRanges())); |
935 | 1 | assertEquals("{[5, 8], [11, 13]}", prettyPrint(ml1.getToRanges())); |
936 | ||
937 | 1 | MapList ml2 = new MapList(new int[] { 1, 50 }, |
938 | new int[] | |
939 | { 40, 45, 70, 75, 90, 127 }, 1, 1); | |
940 | 1 | assertEquals("{[1, 50]}", prettyPrint(ml2.getFromRanges())); |
941 | 1 | assertEquals("{[40, 45], [70, 75], [90, 127]}", |
942 | prettyPrint(ml2.getToRanges())); | |
943 | ||
944 | 1 | MapList compound = ml1.traverse(ml2); |
945 | ||
946 | 1 | assertEquals(1, compound.getFromRatio()); |
947 | 1 | assertEquals(1, compound.getToRatio()); |
948 | 1 | List<int[]> fromRanges = compound.getFromRanges(); |
949 | 1 | assertEquals(2, fromRanges.size()); |
950 | 1 | assertArrayEquals(new int[] { 3, 4 }, fromRanges.get(0)); |
951 | 1 | assertArrayEquals(new int[] { 8, 12 }, fromRanges.get(1)); |
952 | 1 | List<int[]> toRanges = compound.getToRanges(); |
953 | 1 | assertEquals(4, toRanges.size()); |
954 | // 5-8 maps to 44-45,70-71 | |
955 | // 11-13 maps to 74-75,90 | |
956 | 1 | assertArrayEquals(new int[] { 44, 45 }, toRanges.get(0)); |
957 | 1 | assertArrayEquals(new int[] { 70, 71 }, toRanges.get(1)); |
958 | 1 | assertArrayEquals(new int[] { 74, 75 }, toRanges.get(2)); |
959 | 1 | assertArrayEquals(new int[] { 90, 90 }, toRanges.get(3)); |
960 | ||
961 | /* | |
962 | * 1:1 over 1:1 backwards ('reverse strand') | |
963 | */ | |
964 | 1 | ml1 = new MapList(new int[] { 1, 50 }, new int[] { 70, 119 }, 1, 1); |
965 | 1 | ml2 = new MapList(new int[] { 1, 500 }, |
966 | new int[] | |
967 | { 1000, 901, 600, 201 }, 1, 1); | |
968 | 1 | compound = ml1.traverse(ml2); |
969 | ||
970 | 1 | assertEquals(1, compound.getFromRatio()); |
971 | 1 | assertEquals(1, compound.getToRatio()); |
972 | 1 | fromRanges = compound.getFromRanges(); |
973 | 1 | assertEquals(1, fromRanges.size()); |
974 | 1 | assertArrayEquals(new int[] { 1, 50 }, fromRanges.get(0)); |
975 | 1 | toRanges = compound.getToRanges(); |
976 | 1 | assertEquals(2, toRanges.size()); |
977 | 1 | assertArrayEquals(new int[] { 931, 901 }, toRanges.get(0)); |
978 | 1 | assertArrayEquals(new int[] { 600, 582 }, toRanges.get(1)); |
979 | ||
980 | /* | |
981 | * 1:1 plus 1:3 should result in 1:3 | |
982 | */ | |
983 | 1 | ml1 = new MapList(new int[] { 1, 30 }, new int[] { 11, 40 }, 1, 1); |
984 | 1 | ml2 = new MapList(new int[] { 1, 100 }, new int[] { 1, 50, 91, 340 }, 1, |
985 | 3); | |
986 | 1 | compound = ml1.traverse(ml2); |
987 | ||
988 | 1 | assertEquals(1, compound.getFromRatio()); |
989 | 1 | assertEquals(3, compound.getToRatio()); |
990 | 1 | fromRanges = compound.getFromRanges(); |
991 | 1 | assertEquals(1, fromRanges.size()); |
992 | 1 | assertArrayEquals(new int[] { 1, 30 }, fromRanges.get(0)); |
993 | // 11-40 maps to 31-50,91-160 | |
994 | 1 | toRanges = compound.getToRanges(); |
995 | 1 | assertEquals(2, toRanges.size()); |
996 | 1 | assertArrayEquals(new int[] { 31, 50 }, toRanges.get(0)); |
997 | 1 | assertArrayEquals(new int[] { 91, 160 }, toRanges.get(1)); |
998 | ||
999 | /* | |
1000 | * 3:1 plus 1:1 should result in 3:1 | |
1001 | */ | |
1002 | 1 | ml1 = new MapList(new int[] { 1, 30 }, new int[] { 11, 20 }, 3, 1); |
1003 | 1 | ml2 = new MapList(new int[] { 1, 100 }, new int[] { 1, 15, 91, 175 }, 1, |
1004 | 1); | |
1005 | 1 | compound = ml1.traverse(ml2); |
1006 | ||
1007 | 1 | assertEquals(3, compound.getFromRatio()); |
1008 | 1 | assertEquals(1, compound.getToRatio()); |
1009 | 1 | fromRanges = compound.getFromRanges(); |
1010 | 1 | assertEquals(1, fromRanges.size()); |
1011 | 1 | assertArrayEquals(new int[] { 1, 30 }, fromRanges.get(0)); |
1012 | // 11-20 maps to 11-15, 91-95 | |
1013 | 1 | toRanges = compound.getToRanges(); |
1014 | 1 | assertEquals(2, toRanges.size()); |
1015 | 1 | assertArrayEquals(new int[] { 11, 15 }, toRanges.get(0)); |
1016 | 1 | assertArrayEquals(new int[] { 91, 95 }, toRanges.get(1)); |
1017 | ||
1018 | /* | |
1019 | * 1:3 plus 3:1 should result in 1:1 | |
1020 | */ | |
1021 | 1 | ml1 = new MapList(new int[] { 21, 40 }, new int[] { 13, 72 }, 1, 3); |
1022 | 1 | ml2 = new MapList(new int[] { 1, 300 }, new int[] { 51, 70, 121, 200 }, |
1023 | 3, 1); | |
1024 | 1 | compound = ml1.traverse(ml2); |
1025 | ||
1026 | 1 | assertEquals(1, compound.getFromRatio()); |
1027 | 1 | assertEquals(1, compound.getToRatio()); |
1028 | 1 | fromRanges = compound.getFromRanges(); |
1029 | 1 | assertEquals(1, fromRanges.size()); |
1030 | 1 | assertArrayEquals(new int[] { 21, 40 }, fromRanges.get(0)); |
1031 | // 13-72 maps 3:1 to 55-70, 121-124 | |
1032 | 1 | toRanges = compound.getToRanges(); |
1033 | 1 | assertEquals(2, toRanges.size()); |
1034 | 1 | assertArrayEquals(new int[] { 55, 70 }, toRanges.get(0)); |
1035 | 1 | assertArrayEquals(new int[] { 121, 124 }, toRanges.get(1)); |
1036 | ||
1037 | /* | |
1038 | * 3:1 plus 1:3 should result in 1:1 | |
1039 | */ | |
1040 | 1 | ml1 = new MapList(new int[] { 31, 90 }, new int[] { 13, 32 }, 3, 1); |
1041 | 1 | ml2 = new MapList(new int[] { 11, 40 }, new int[] { 41, 50, 71, 150 }, |
1042 | 1, 3); | |
1043 | 1 | compound = ml1.traverse(ml2); |
1044 | ||
1045 | 1 | assertEquals(1, compound.getFromRatio()); |
1046 | 1 | assertEquals(1, compound.getToRatio()); |
1047 | 1 | fromRanges = compound.getFromRanges(); |
1048 | 1 | assertEquals(1, fromRanges.size()); |
1049 | 1 | assertArrayEquals(new int[] { 31, 90 }, fromRanges.get(0)); |
1050 | // 13-32 maps to 47-50,71-126 | |
1051 | 1 | toRanges = compound.getToRanges(); |
1052 | 1 | assertEquals(2, toRanges.size()); |
1053 | 1 | assertArrayEquals(new int[] { 47, 50 }, toRanges.get(0)); |
1054 | 1 | assertArrayEquals(new int[] { 71, 126 }, toRanges.get(1)); |
1055 | ||
1056 | /* | |
1057 | * if not all regions are mapped through, returns what is | |
1058 | */ | |
1059 | 1 | ml1 = new MapList(new int[] { 1, 50 }, new int[] { 101, 150 }, 1, 1); |
1060 | 1 | ml2 = new MapList(new int[] { 131, 180 }, new int[] { 201, 250 }, 1, 1); |
1061 | 1 | compound = ml1.traverse(ml2); |
1062 | 1 | assertNull(compound); |
1063 | } | |
1064 | ||
1065 | /** | |
1066 | * Test that method that inspects for the (first) forward or reverse 'to' | |
1067 | * range. Single position ranges are ignored. | |
1068 | */ | |
1069 | 1 | @Test(groups = { "Functional" }) |
1070 | public void testIsToForwardsStrand() | |
1071 | { | |
1072 | // [3-9] declares forward strand | |
1073 | 1 | MapList ml = new MapList(new int[] { 20, 11 }, |
1074 | new int[] | |
1075 | { 2, 2, 3, 9, 12, 11 }, 1, 1); | |
1076 | 1 | assertTrue(ml.isToForwardStrand()); |
1077 | ||
1078 | // [11-5] declares reverse strand ([13-14] is ignored) | |
1079 | 1 | ml = new MapList(new int[] { 20, 11 }, |
1080 | new int[] | |
1081 | { 2, 2, 11, 5, 13, 14 }, 1, 1); | |
1082 | 1 | assertFalse(ml.isToForwardStrand()); |
1083 | ||
1084 | // all single position ranges - defaults to forward strand | |
1085 | 1 | ml = new MapList(new int[] { 3, 1 }, new int[] { 2, 2, 4, 4, 6, 6 }, 1, |
1086 | 1); | |
1087 | 1 | assertTrue(ml.isToForwardStrand()); |
1088 | } | |
1089 | ||
1090 | /** | |
1091 | * Test for mapping with overlapping ranges | |
1092 | */ | |
1093 | 1 | @Test(groups = { "Functional" }) |
1094 | public void testLocateInFrom_withOverlap() | |
1095 | { | |
1096 | /* | |
1097 | * gene to protein... | |
1098 | */ | |
1099 | 1 | int[] codons = new int[] { 1, 12, 12, 17 }; |
1100 | 1 | int[] protein = new int[] { 1, 6 }; |
1101 | 1 | MapList ml = new MapList(codons, protein, 3, 1); |
1102 | 1 | assertEquals("[1, 3]", Arrays.toString(ml.locateInFrom(1, 1))); |
1103 | 1 | assertEquals("[4, 6]", Arrays.toString(ml.locateInFrom(2, 2))); |
1104 | 1 | assertEquals("[7, 9]", Arrays.toString(ml.locateInFrom(3, 3))); |
1105 | 1 | assertEquals("[10, 12]", Arrays.toString(ml.locateInFrom(4, 4))); |
1106 | 1 | assertEquals("[12, 14]", Arrays.toString(ml.locateInFrom(5, 5))); |
1107 | 1 | assertEquals("[15, 17]", Arrays.toString(ml.locateInFrom(6, 6))); |
1108 | 1 | assertEquals("[1, 6]", Arrays.toString(ml.locateInFrom(1, 2))); |
1109 | 1 | assertEquals("[1, 9]", Arrays.toString(ml.locateInFrom(1, 3))); |
1110 | 1 | assertEquals("[1, 12]", Arrays.toString(ml.locateInFrom(1, 4))); |
1111 | 1 | assertEquals("[1, 12, 12, 14]", Arrays.toString(ml.locateInFrom(1, 5))); |
1112 | 1 | assertEquals("[1, 12, 12, 17]", Arrays.toString(ml.locateInFrom(1, 6))); |
1113 | 1 | assertEquals("[4, 9]", Arrays.toString(ml.locateInFrom(2, 3))); |
1114 | 1 | assertEquals("[7, 12, 12, 17]", Arrays.toString(ml.locateInFrom(3, 6))); |
1115 | ||
1116 | /* | |
1117 | * partial overlap of range | |
1118 | */ | |
1119 | 1 | assertEquals("[4, 12, 12, 17]", Arrays.toString(ml.locateInFrom(2, 7))); |
1120 | 1 | assertEquals("[1, 3]", Arrays.toString(ml.locateInFrom(-1, 1))); |
1121 | ||
1122 | /* | |
1123 | * no overlap in range | |
1124 | */ | |
1125 | 1 | assertNull(ml.locateInFrom(0, 0)); |
1126 | ||
1127 | /* | |
1128 | * gene to CDS...from EMBL:MN908947 | |
1129 | */ | |
1130 | 1 | int[] gene = new int[] { 266, 13468, 13468, 21555 }; |
1131 | 1 | int[] cds = new int[] { 1, 21291 }; |
1132 | 1 | ml = new MapList(gene, cds, 1, 1); |
1133 | 1 | assertEquals("[13468, 13468]", |
1134 | Arrays.toString(ml.locateInFrom(13203, 13203))); | |
1135 | 1 | assertEquals("[13468, 13468]", |
1136 | Arrays.toString(ml.locateInFrom(13204, 13204))); | |
1137 | 1 | assertEquals("[13468, 13468, 13468, 13468]", |
1138 | Arrays.toString(ml.locateInFrom(13203, 13204))); | |
1139 | } | |
1140 | ||
1141 | /** | |
1142 | * Test for mapping with overlapping ranges | |
1143 | */ | |
1144 | 1 | @Test(groups = { "Functional" }) |
1145 | public void testLocateInTo_withOverlap() | |
1146 | { | |
1147 | /* | |
1148 | * gene to protein... | |
1149 | */ | |
1150 | 1 | int[] codons = new int[] { 1, 12, 12, 17 }; |
1151 | 1 | int[] protein = new int[] { 1, 6 }; |
1152 | 1 | MapList ml = new MapList(codons, protein, 3, 1); |
1153 | 1 | assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(1, 1))); |
1154 | 1 | assertEquals("[1, 3]", Arrays.toString(ml.locateInTo(3, 8))); |
1155 | 1 | assertEquals("[1, 4]", Arrays.toString(ml.locateInTo(2, 11))); |
1156 | 1 | assertEquals("[1, 4]", Arrays.toString(ml.locateInTo(3, 11))); |
1157 | ||
1158 | // we want base 12 to map to both of the amino acids it codes for | |
1159 | 1 | assertEquals("[4, 5]", Arrays.toString(ml.locateInTo(12, 12))); |
1160 | 1 | assertEquals("[4, 5]", Arrays.toString(ml.locateInTo(11, 12))); |
1161 | 1 | assertEquals("[4, 6]", Arrays.toString(ml.locateInTo(11, 15))); |
1162 | 1 | assertEquals("[6, 6]", Arrays.toString(ml.locateInTo(15, 17))); |
1163 | ||
1164 | /* | |
1165 | * no overlap | |
1166 | */ | |
1167 | 1 | assertNull(ml.locateInTo(0, 0)); |
1168 | ||
1169 | /* | |
1170 | * partial overlap | |
1171 | */ | |
1172 | 1 | assertEquals("[1, 6]", Arrays.toString(ml.locateInTo(1, 18))); |
1173 | 1 | assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(-1, 1))); |
1174 | ||
1175 | /* | |
1176 | * gene to CDS...from EMBL:MN908947 | |
1177 | * the base at 13468 is used twice in transcription | |
1178 | */ | |
1179 | 1 | int[] gene = new int[] { 266, 13468, 13468, 21555 }; |
1180 | 1 | int[] cds = new int[] { 1, 21291 }; |
1181 | 1 | ml = new MapList(gene, cds, 1, 1); |
1182 | 1 | assertEquals("[13203, 13204]", |
1183 | Arrays.toString(ml.locateInTo(13468, 13468))); | |
1184 | ||
1185 | /* | |
1186 | * gene to protein | |
1187 | * the base at 13468 is in the codon for 4401N and also 4402R | |
1188 | */ | |
1189 | 1 | gene = new int[] { 266, 13468, 13468, 21552 }; // stop codon excluded |
1190 | 1 | protein = new int[] { 1, 7096 }; |
1191 | 1 | ml = new MapList(gene, protein, 3, 1); |
1192 | 1 | assertEquals("[4401, 4402]", |
1193 | Arrays.toString(ml.locateInTo(13468, 13468))); | |
1194 | } | |
1195 | ||
1196 | 1 | @Test(groups = { "Functional" }) |
1197 | public void testTraverseToPosition() | |
1198 | { | |
1199 | 1 | List<int[]> ranges = new ArrayList<>(); |
1200 | 1 | assertNull(MapList.traverseToPosition(ranges, 0)); |
1201 | ||
1202 | 1 | ranges.add(new int[] { 3, 6 }); |
1203 | 1 | assertNull(MapList.traverseToPosition(ranges, 0)); |
1204 | } | |
1205 | ||
1206 | 1 | @Test(groups = { "Functional" }) |
1207 | public void testCountPositions() | |
1208 | { | |
1209 | 1 | try |
1210 | { | |
1211 | 1 | MapList.countPositions(null, 1); |
1212 | 0 | fail("expected exception"); |
1213 | } catch (NullPointerException e) | |
1214 | { | |
1215 | // expected | |
1216 | } | |
1217 | ||
1218 | 1 | List<int[]> intervals = new ArrayList<>(); |
1219 | 1 | assertNull(MapList.countPositions(intervals, 1)); |
1220 | ||
1221 | /* | |
1222 | * forward strand | |
1223 | */ | |
1224 | 1 | intervals.add(new int[] { 10, 20 }); |
1225 | 1 | assertNull(MapList.countPositions(intervals, 9)); |
1226 | 1 | assertNull(MapList.countPositions(intervals, 21)); |
1227 | 1 | assertArrayEquals(new int[] { 1, 1 }, |
1228 | MapList.countPositions(intervals, 10)); | |
1229 | 1 | assertArrayEquals(new int[] { 6, 1 }, |
1230 | MapList.countPositions(intervals, 15)); | |
1231 | 1 | assertArrayEquals(new int[] { 11, 1 }, |
1232 | MapList.countPositions(intervals, 20)); | |
1233 | ||
1234 | 1 | intervals.add(new int[] { 25, 25 }); |
1235 | 1 | assertArrayEquals(new int[] { 12, 1 }, |
1236 | MapList.countPositions(intervals, 25)); | |
1237 | ||
1238 | // next interval repeats position 25 - which should be counted twice if | |
1239 | // traversed | |
1240 | 1 | intervals.add(new int[] { 25, 26 }); |
1241 | 1 | assertArrayEquals(new int[] { 12, 1 }, |
1242 | MapList.countPositions(intervals, 25)); | |
1243 | 1 | assertArrayEquals(new int[] { 14, 1 }, |
1244 | MapList.countPositions(intervals, 26)); | |
1245 | ||
1246 | /* | |
1247 | * reverse strand | |
1248 | */ | |
1249 | 1 | intervals.clear(); |
1250 | 1 | intervals.add(new int[] { 5, -5 }); |
1251 | 1 | assertNull(MapList.countPositions(intervals, 6)); |
1252 | 1 | assertNull(MapList.countPositions(intervals, -6)); |
1253 | 1 | assertArrayEquals(new int[] { 1, -1 }, |
1254 | MapList.countPositions(intervals, 5)); | |
1255 | 1 | assertArrayEquals(new int[] { 7, -1 }, |
1256 | MapList.countPositions(intervals, -1)); | |
1257 | 1 | assertArrayEquals(new int[] { 11, -1 }, |
1258 | MapList.countPositions(intervals, -5)); | |
1259 | ||
1260 | /* | |
1261 | * reverse then forward | |
1262 | */ | |
1263 | 1 | intervals.add(new int[] { 5, 10 }); |
1264 | 1 | assertArrayEquals(new int[] { 13, 1 }, |
1265 | MapList.countPositions(intervals, 6)); | |
1266 | ||
1267 | /* | |
1268 | * reverse then forward then reverse | |
1269 | */ | |
1270 | 1 | intervals.add(new int[] { -10, -20 }); |
1271 | 1 | assertArrayEquals(new int[] { 20, -1 }, |
1272 | MapList.countPositions(intervals, -12)); | |
1273 | ||
1274 | /* | |
1275 | * an interval [x, x] is treated as forward | |
1276 | */ | |
1277 | 1 | intervals.add(new int[] { 30, 30 }); |
1278 | 1 | assertArrayEquals(new int[] { 29, 1 }, |
1279 | MapList.countPositions(intervals, 30)); | |
1280 | ||
1281 | /* | |
1282 | * it is the first matched occurrence that is returned | |
1283 | */ | |
1284 | 1 | intervals.clear(); |
1285 | 1 | intervals.add(new int[] { 1, 2 }); |
1286 | 1 | intervals.add(new int[] { 2, 3 }); |
1287 | 1 | assertArrayEquals(new int[] { 2, 1 }, |
1288 | MapList.countPositions(intervals, 2)); | |
1289 | 1 | intervals.add(new int[] { -1, -2 }); |
1290 | 1 | intervals.add(new int[] { -2, -3 }); |
1291 | 1 | assertArrayEquals(new int[] { 6, -1 }, |
1292 | MapList.countPositions(intervals, -2)); | |
1293 | } | |
1294 | ||
1295 | /** | |
1296 | * Tests for helper method that adds any overlap (plus offset) to a set of | |
1297 | * overlaps | |
1298 | */ | |
1299 | 1 | @Test(groups = { "Functional" }) |
1300 | public void testAddOffsetPositions() | |
1301 | { | |
1302 | 1 | List<int[]> mapped = new ArrayList<>(); |
1303 | 1 | int[] range = new int[] { 10, 20 }; |
1304 | 1 | BitSet offsets = new BitSet(); |
1305 | ||
1306 | 1 | MapList.addOffsetPositions(mapped, 0, range, offsets); |
1307 | 1 | assertTrue(mapped.isEmpty()); // nothing marked for overlap |
1308 | ||
1309 | 1 | offsets.set(11); |
1310 | 1 | MapList.addOffsetPositions(mapped, 0, range, offsets); |
1311 | 1 | assertTrue(mapped.isEmpty()); // no offset 11 in range |
1312 | ||
1313 | 1 | offsets.set(4, 6); // this sets bits 4 and 5 |
1314 | 1 | MapList.addOffsetPositions(mapped, 0, range, offsets); |
1315 | 1 | assertEquals(1, mapped.size()); |
1316 | 1 | assertArrayEquals(new int[] { 14, 15 }, mapped.get(0)); |
1317 | ||
1318 | 1 | mapped.clear(); |
1319 | 1 | offsets.set(10); |
1320 | 1 | MapList.addOffsetPositions(mapped, 0, range, offsets); |
1321 | 1 | assertEquals(2, mapped.size()); |
1322 | 1 | assertArrayEquals(new int[] { 14, 15 }, mapped.get(0)); |
1323 | 1 | assertArrayEquals(new int[] { 20, 20 }, mapped.get(1)); |
1324 | ||
1325 | /* | |
1326 | * reverse range | |
1327 | */ | |
1328 | 1 | range = new int[] { 20, 10 }; |
1329 | 1 | mapped.clear(); |
1330 | 1 | offsets.clear(); |
1331 | 1 | MapList.addOffsetPositions(mapped, 0, range, offsets); |
1332 | 1 | assertTrue(mapped.isEmpty()); // nothing marked for overlap |
1333 | 1 | offsets.set(11); |
1334 | 1 | MapList.addOffsetPositions(mapped, 0, range, offsets); |
1335 | 1 | assertTrue(mapped.isEmpty()); // no offset 11 in range |
1336 | 1 | offsets.set(0); |
1337 | 1 | offsets.set(10); |
1338 | 1 | offsets.set(6, 8); // sets bits 6 and 7 |
1339 | 1 | MapList.addOffsetPositions(mapped, 0, range, offsets); |
1340 | 1 | assertEquals(3, mapped.size()); |
1341 | 1 | assertArrayEquals(new int[] { 20, 20 }, mapped.get(0)); |
1342 | 1 | assertArrayEquals(new int[] { 14, 13 }, mapped.get(1)); |
1343 | 1 | assertArrayEquals(new int[] { 10, 10 }, mapped.get(2)); |
1344 | } | |
1345 | ||
1346 | 1 | @Test(groups = { "Functional" }) |
1347 | public void testGetPositionsForOffsets() | |
1348 | { | |
1349 | 1 | List<int[]> ranges = new ArrayList<>(); |
1350 | 1 | BitSet offsets = new BitSet(); |
1351 | 1 | List<int[]> mapped = MapList.getPositionsForOffsets(ranges, offsets); |
1352 | 1 | assertTrue(mapped.isEmpty()); // no ranges and no offsets! |
1353 | ||
1354 | 1 | offsets.set(5, 1000); |
1355 | 1 | mapped = MapList.getPositionsForOffsets(ranges, offsets); |
1356 | 1 | assertTrue(mapped.isEmpty()); // no ranges |
1357 | ||
1358 | /* | |
1359 | * one range with overlap of offsets | |
1360 | */ | |
1361 | 1 | ranges.add(new int[] { 15, 25 }); |
1362 | 1 | mapped = MapList.getPositionsForOffsets(ranges, offsets); |
1363 | 1 | assertEquals(1, mapped.size()); |
1364 | 1 | assertArrayEquals(new int[] { 20, 25 }, mapped.get(0)); |
1365 | ||
1366 | /* | |
1367 | * two ranges | |
1368 | */ | |
1369 | 1 | ranges.add(new int[] { 300, 320 }); |
1370 | 1 | mapped = MapList.getPositionsForOffsets(ranges, offsets); |
1371 | 1 | assertEquals(2, mapped.size()); |
1372 | 1 | assertArrayEquals(new int[] { 20, 25 }, mapped.get(0)); |
1373 | 1 | assertArrayEquals(new int[] { 300, 320 }, mapped.get(1)); |
1374 | ||
1375 | /* | |
1376 | * boundary case - right end of first range overlaps | |
1377 | */ | |
1378 | 1 | offsets.clear(); |
1379 | 1 | offsets.set(10); |
1380 | 1 | mapped = MapList.getPositionsForOffsets(ranges, offsets); |
1381 | 1 | assertEquals(1, mapped.size()); |
1382 | 1 | assertArrayEquals(new int[] { 25, 25 }, mapped.get(0)); |
1383 | ||
1384 | /* | |
1385 | * boundary case - left end of second range overlaps | |
1386 | */ | |
1387 | 1 | offsets.set(11); |
1388 | 1 | mapped = MapList.getPositionsForOffsets(ranges, offsets); |
1389 | 1 | assertEquals(2, mapped.size()); |
1390 | 1 | assertArrayEquals(new int[] { 25, 25 }, mapped.get(0)); |
1391 | 1 | assertArrayEquals(new int[] { 300, 300 }, mapped.get(1)); |
1392 | ||
1393 | /* | |
1394 | * offsets into a circular range are reported in | |
1395 | * the order in which they are traversed | |
1396 | */ | |
1397 | 1 | ranges.clear(); |
1398 | 1 | ranges.add(new int[] { 100, 150 }); |
1399 | 1 | ranges.add(new int[] { 60, 80 }); |
1400 | 1 | offsets.clear(); |
1401 | 1 | offsets.set(45, 55); // sets bits 45 to 54 |
1402 | 1 | mapped = MapList.getPositionsForOffsets(ranges, offsets); |
1403 | 1 | assertEquals(2, mapped.size()); |
1404 | 1 | assertArrayEquals(new int[] { 145, 150 }, mapped.get(0)); // offsets 45-50 |
1405 | 1 | assertArrayEquals(new int[] { 60, 63 }, mapped.get(1)); // offsets 51-54 |
1406 | ||
1407 | /* | |
1408 | * reverse range overlap is reported with start < end | |
1409 | */ | |
1410 | 1 | ranges.clear(); |
1411 | 1 | ranges.add(new int[] { 4321, 4000 }); |
1412 | 1 | offsets.clear(); |
1413 | 1 | offsets.set(20, 22); // sets bits 20 and 21 |
1414 | 1 | offsets.set(30); |
1415 | 1 | mapped = MapList.getPositionsForOffsets(ranges, offsets); |
1416 | 1 | assertEquals(2, mapped.size()); |
1417 | 1 | assertArrayEquals(new int[] { 4301, 4300 }, mapped.get(0)); |
1418 | 1 | assertArrayEquals(new int[] { 4291, 4291 }, mapped.get(1)); |
1419 | } | |
1420 | ||
1421 | 1 | @Test(groups = { "Functional" }) |
1422 | public void testGetMappedOffsetsForPositions() | |
1423 | { | |
1424 | /* | |
1425 | * start by verifying the examples in the method's Javadoc! | |
1426 | */ | |
1427 | 1 | List<int[]> ranges = new ArrayList<>(); |
1428 | 1 | ranges.add(new int[] { 10, 20 }); |
1429 | 1 | ranges.add(new int[] { 31, 40 }); |
1430 | 1 | BitSet overlaps = MapList.getMappedOffsetsForPositions(1, 9, ranges, 1, |
1431 | 1); | |
1432 | 1 | assertTrue(overlaps.isEmpty()); |
1433 | 1 | overlaps = MapList.getMappedOffsetsForPositions(1, 11, ranges, 1, 1); |
1434 | 1 | assertEquals(2, overlaps.cardinality()); |
1435 | 1 | assertTrue(overlaps.get(0)); |
1436 | 1 | assertTrue(overlaps.get(1)); |
1437 | 1 | overlaps = MapList.getMappedOffsetsForPositions(15, 35, ranges, 1, 1); |
1438 | 1 | assertEquals(11, overlaps.cardinality()); |
1439 | 8 | for (int i = 5; i <= 11; i++) |
1440 | { | |
1441 | 7 | assertTrue(overlaps.get(i)); |
1442 | } | |
1443 | ||
1444 | 1 | ranges.clear(); |
1445 | 1 | ranges.add(new int[] { 1, 200 }); |
1446 | 1 | overlaps = MapList.getMappedOffsetsForPositions(9, 9, ranges, 1, 3); |
1447 | 1 | assertEquals(3, overlaps.cardinality()); |
1448 | 1 | assertTrue(overlaps.get(24)); |
1449 | 1 | assertTrue(overlaps.get(25)); |
1450 | 1 | assertTrue(overlaps.get(26)); |
1451 | ||
1452 | 1 | ranges.clear(); |
1453 | 1 | ranges.add(new int[] { 101, 150 }); |
1454 | 1 | ranges.add(new int[] { 171, 180 }); |
1455 | 1 | overlaps = MapList.getMappedOffsetsForPositions(101, 102, ranges, 3, 1); |
1456 | 1 | assertEquals(1, overlaps.cardinality()); |
1457 | 1 | assertTrue(overlaps.get(0)); |
1458 | 1 | overlaps = MapList.getMappedOffsetsForPositions(150, 171, ranges, 3, 1); |
1459 | 1 | assertEquals(1, overlaps.cardinality()); |
1460 | 1 | assertTrue(overlaps.get(16)); |
1461 | ||
1462 | 1 | ranges.clear(); |
1463 | 1 | ranges.add(new int[] { 101, 150 }); |
1464 | 1 | ranges.add(new int[] { 21, 30 }); |
1465 | 1 | overlaps = MapList.getMappedOffsetsForPositions(24, 40, ranges, 3, 1); |
1466 | 1 | assertEquals(3, overlaps.cardinality()); |
1467 | 1 | assertTrue(overlaps.get(17)); |
1468 | 1 | assertTrue(overlaps.get(18)); |
1469 | 1 | assertTrue(overlaps.get(19)); |
1470 | ||
1471 | /* | |
1472 | * reverse range 1:1 (e.g. reverse strand gene to transcript) | |
1473 | */ | |
1474 | 1 | ranges.clear(); |
1475 | 1 | ranges.add(new int[] { 20, 10 }); |
1476 | 1 | overlaps = MapList.getMappedOffsetsForPositions(12, 13, ranges, 1, 1); |
1477 | 1 | assertEquals(2, overlaps.cardinality()); |
1478 | 1 | assertTrue(overlaps.get(7)); |
1479 | 1 | assertTrue(overlaps.get(8)); |
1480 | ||
1481 | /* | |
1482 | * reverse range 3:1 (e.g. reverse strand gene to peptide) | |
1483 | * from EMBL:J03321 to P0CE20 | |
1484 | */ | |
1485 | 1 | ranges.clear(); |
1486 | 1 | ranges.add(new int[] { 1480, 488 }); |
1487 | 1 | overlaps = MapList.getMappedOffsetsForPositions(1460, 1460, ranges, 3, |
1488 | 1); | |
1489 | // 1460 is the end of the 7th codon | |
1490 | 1 | assertEquals(1, overlaps.cardinality()); |
1491 | 1 | assertTrue(overlaps.get(6)); |
1492 | // add one base (part codon) | |
1493 | 1 | overlaps = MapList.getMappedOffsetsForPositions(1459, 1460, ranges, 3, |
1494 | 1); | |
1495 | 1 | assertEquals(2, overlaps.cardinality()); |
1496 | 1 | assertTrue(overlaps.get(6)); |
1497 | 1 | assertTrue(overlaps.get(7)); |
1498 | // add second base (part codon) | |
1499 | 1 | overlaps = MapList.getMappedOffsetsForPositions(1458, 1460, ranges, 3, |
1500 | 1); | |
1501 | 1 | assertEquals(2, overlaps.cardinality()); |
1502 | 1 | assertTrue(overlaps.get(6)); |
1503 | 1 | assertTrue(overlaps.get(7)); |
1504 | // add third base (whole codon) | |
1505 | 1 | overlaps = MapList.getMappedOffsetsForPositions(1457, 1460, ranges, 3, |
1506 | 1); | |
1507 | 1 | assertEquals(2, overlaps.cardinality()); |
1508 | 1 | assertTrue(overlaps.get(6)); |
1509 | 1 | assertTrue(overlaps.get(7)); |
1510 | // add one more base (part codon) | |
1511 | 1 | overlaps = MapList.getMappedOffsetsForPositions(1456, 1460, ranges, 3, |
1512 | 1); | |
1513 | 1 | assertEquals(3, overlaps.cardinality()); |
1514 | 1 | assertTrue(overlaps.get(6)); |
1515 | 1 | assertTrue(overlaps.get(7)); |
1516 | 1 | assertTrue(overlaps.get(8)); |
1517 | } | |
1518 | } |