Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
MappingUtilsTest | 62 | 672 | 39 |
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.internal.junit.ArrayAsserts.assertArrayEquals; | |
29 | ||
30 | import java.awt.Color; | |
31 | import java.io.IOException; | |
32 | import java.util.ArrayList; | |
33 | import java.util.Arrays; | |
34 | import java.util.Iterator; | |
35 | import java.util.List; | |
36 | ||
37 | import org.testng.annotations.BeforeClass; | |
38 | import org.testng.annotations.Test; | |
39 | ||
40 | import jalview.api.AlignViewportI; | |
41 | import jalview.bin.Console; | |
42 | import jalview.commands.EditCommand; | |
43 | import jalview.commands.EditCommand.Action; | |
44 | import jalview.commands.EditCommand.Edit; | |
45 | import jalview.datamodel.AlignedCodonFrame; | |
46 | import jalview.datamodel.Alignment; | |
47 | import jalview.datamodel.AlignmentI; | |
48 | import jalview.datamodel.ColumnSelection; | |
49 | import jalview.datamodel.HiddenColumns; | |
50 | import jalview.datamodel.SearchResultMatchI; | |
51 | import jalview.datamodel.SearchResultsI; | |
52 | import jalview.datamodel.Sequence; | |
53 | import jalview.datamodel.SequenceGroup; | |
54 | import jalview.datamodel.SequenceI; | |
55 | import jalview.gui.AlignViewport; | |
56 | import jalview.gui.JvOptionPane; | |
57 | import jalview.io.DataSourceType; | |
58 | import jalview.io.FileFormat; | |
59 | import jalview.io.FileFormatI; | |
60 | import jalview.io.FormatAdapter; | |
61 | ||
62 | public class MappingUtilsTest | |
63 | { | |
64 | 1 | @BeforeClass(alwaysRun = true) |
65 | public void setUp() | |
66 | { | |
67 | 1 | Console.initLogger(); |
68 | } | |
69 | ||
70 | 1 | @BeforeClass(alwaysRun = true) |
71 | public void setUpJvOptionPane() | |
72 | { | |
73 | 1 | JvOptionPane.setInteractiveMode(false); |
74 | 1 | JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION); |
75 | } | |
76 | ||
77 | private AlignViewportI dnaView; | |
78 | ||
79 | private AlignViewportI proteinView; | |
80 | ||
81 | /** | |
82 | * Simple test of mapping with no intron involved. | |
83 | */ | |
84 | 1 | @Test(groups = { "Functional" }) |
85 | public void testBuildSearchResults() | |
86 | { | |
87 | 1 | final Sequence seq1 = new Sequence("Seq1/5-10", "C-G-TA-GC"); |
88 | 1 | seq1.createDatasetSequence(); |
89 | ||
90 | 1 | final Sequence aseq1 = new Sequence("Seq1/12-13", "-P-R"); |
91 | 1 | aseq1.createDatasetSequence(); |
92 | ||
93 | /* | |
94 | * Map dna bases 5-10 to protein residues 12-13 | |
95 | */ | |
96 | 1 | AlignedCodonFrame acf = new AlignedCodonFrame(); |
97 | 1 | MapList map = new MapList(new int[] { 5, 10 }, new int[] { 12, 13 }, 3, |
98 | 1); | |
99 | 1 | acf.addMap(seq1.getDatasetSequence(), aseq1.getDatasetSequence(), map); |
100 | 1 | List<AlignedCodonFrame> acfList = Arrays |
101 | .asList(new AlignedCodonFrame[] | |
102 | { acf }); | |
103 | ||
104 | /* | |
105 | * Check protein residue 12 maps to codon 5-7, 13 to codon 8-10 | |
106 | */ | |
107 | 1 | SearchResultsI sr = MappingUtils.buildSearchResults(aseq1, 12, acfList); |
108 | 1 | assertEquals(1, sr.getResults().size()); |
109 | 1 | SearchResultMatchI m = sr.getResults().get(0); |
110 | 1 | assertEquals(seq1.getDatasetSequence(), m.getSequence()); |
111 | 1 | assertEquals(5, m.getStart()); |
112 | 1 | assertEquals(7, m.getEnd()); |
113 | 1 | sr = MappingUtils.buildSearchResults(aseq1, 13, acfList); |
114 | 1 | assertEquals(1, sr.getResults().size()); |
115 | 1 | m = sr.getResults().get(0); |
116 | 1 | assertEquals(seq1.getDatasetSequence(), m.getSequence()); |
117 | 1 | assertEquals(8, m.getStart()); |
118 | 1 | assertEquals(10, m.getEnd()); |
119 | ||
120 | /* | |
121 | * Check inverse mappings, from codons 5-7, 8-10 to protein 12, 13 | |
122 | */ | |
123 | 7 | for (int i = 5; i < 11; i++) |
124 | { | |
125 | 6 | sr = MappingUtils.buildSearchResults(seq1, i, acfList); |
126 | 6 | assertEquals(1, sr.getResults().size()); |
127 | 6 | m = sr.getResults().get(0); |
128 | 6 | assertEquals(aseq1.getDatasetSequence(), m.getSequence()); |
129 | 6 | int residue = i > 7 ? 13 : 12; |
130 | 6 | assertEquals(residue, m.getStart()); |
131 | 6 | assertEquals(residue, m.getEnd()); |
132 | } | |
133 | } | |
134 | ||
135 | /** | |
136 | * Simple test of mapping with introns involved. | |
137 | */ | |
138 | 1 | @Test(groups = { "Functional" }) |
139 | public void testBuildSearchResults_withIntron() | |
140 | { | |
141 | 1 | final Sequence seq1 = new Sequence("Seq1/5-17", "c-G-tAGa-GcAgCtt"); |
142 | 1 | seq1.createDatasetSequence(); |
143 | ||
144 | 1 | final Sequence aseq1 = new Sequence("Seq1/8-9", "-E-D"); |
145 | 1 | aseq1.createDatasetSequence(); |
146 | ||
147 | /* | |
148 | * Map dna bases [6, 8, 9], [11, 13, 115] to protein residues 8 and 9 | |
149 | */ | |
150 | 1 | AlignedCodonFrame acf = new AlignedCodonFrame(); |
151 | 1 | MapList map = new MapList( |
152 | new int[] | |
153 | { 6, 6, 8, 9, 11, 11, 13, 13, 15, 15 }, new int[] { 8, 9 }, 3, | |
154 | 1); | |
155 | 1 | acf.addMap(seq1.getDatasetSequence(), aseq1.getDatasetSequence(), map); |
156 | 1 | List<AlignedCodonFrame> acfList = Arrays |
157 | .asList(new AlignedCodonFrame[] | |
158 | { acf }); | |
159 | ||
160 | /* | |
161 | * Check protein residue 8 maps to [6, 8, 9] | |
162 | */ | |
163 | 1 | SearchResultsI sr = MappingUtils.buildSearchResults(aseq1, 8, acfList); |
164 | 1 | assertEquals(2, sr.getResults().size()); |
165 | 1 | SearchResultMatchI m = sr.getResults().get(0); |
166 | 1 | assertEquals(seq1.getDatasetSequence(), m.getSequence()); |
167 | 1 | assertEquals(6, m.getStart()); |
168 | 1 | assertEquals(6, m.getEnd()); |
169 | 1 | m = sr.getResults().get(1); |
170 | 1 | assertEquals(seq1.getDatasetSequence(), m.getSequence()); |
171 | 1 | assertEquals(8, m.getStart()); |
172 | 1 | assertEquals(9, m.getEnd()); |
173 | ||
174 | /* | |
175 | * Check protein residue 9 maps to [11, 13, 15] | |
176 | */ | |
177 | 1 | sr = MappingUtils.buildSearchResults(aseq1, 9, acfList); |
178 | 1 | assertEquals(3, sr.getResults().size()); |
179 | 1 | m = sr.getResults().get(0); |
180 | 1 | assertEquals(seq1.getDatasetSequence(), m.getSequence()); |
181 | 1 | assertEquals(11, m.getStart()); |
182 | 1 | assertEquals(11, m.getEnd()); |
183 | 1 | m = sr.getResults().get(1); |
184 | 1 | assertEquals(seq1.getDatasetSequence(), m.getSequence()); |
185 | 1 | assertEquals(13, m.getStart()); |
186 | 1 | assertEquals(13, m.getEnd()); |
187 | 1 | m = sr.getResults().get(2); |
188 | 1 | assertEquals(seq1.getDatasetSequence(), m.getSequence()); |
189 | 1 | assertEquals(15, m.getStart()); |
190 | 1 | assertEquals(15, m.getEnd()); |
191 | ||
192 | /* | |
193 | * Check inverse mappings, from codons to protein | |
194 | */ | |
195 | 14 | for (int i = 5; i < 18; i++) |
196 | { | |
197 | 13 | sr = MappingUtils.buildSearchResults(seq1, i, acfList); |
198 | 13 | int residue = (i == 6 || i == 8 || i == 9) ? 8 |
199 | 10 | : (i == 11 || i == 13 || i == 15 ? 9 : 0); |
200 | 13 | if (residue == 0) |
201 | { | |
202 | 7 | assertEquals(0, sr.getResults().size()); |
203 | 7 | continue; |
204 | } | |
205 | 6 | assertEquals(1, sr.getResults().size()); |
206 | 6 | m = sr.getResults().get(0); |
207 | 6 | assertEquals(aseq1.getDatasetSequence(), m.getSequence()); |
208 | 6 | assertEquals(residue, m.getStart()); |
209 | 6 | assertEquals(residue, m.getEnd()); |
210 | } | |
211 | } | |
212 | ||
213 | /** | |
214 | * Test mapping a sequence group made of entire sequences. | |
215 | * | |
216 | * @throws IOException | |
217 | */ | |
218 | 1 | @Test(groups = { "Functional" }) |
219 | public void testMapSequenceGroup_sequences() throws IOException | |
220 | { | |
221 | /* | |
222 | * Set up dna and protein Seq1/2/3 with mappings (held on the protein | |
223 | * viewport). | |
224 | */ | |
225 | 1 | AlignmentI cdna = loadAlignment(">Seq1\nACG\n>Seq2\nTGA\n>Seq3\nTAC\n", |
226 | FileFormat.Fasta); | |
227 | 1 | cdna.setDataset(null); |
228 | 1 | AlignmentI protein = loadAlignment(">Seq1\nK\n>Seq2\nL\n>Seq3\nQ\n", |
229 | FileFormat.Fasta); | |
230 | 1 | protein.setDataset(null); |
231 | 1 | AlignedCodonFrame acf = new AlignedCodonFrame(); |
232 | 1 | MapList map = new MapList(new int[] { 1, 3 }, new int[] { 1, 1 }, 3, 1); |
233 | 4 | for (int seq = 0; seq < 3; seq++) |
234 | { | |
235 | 3 | acf.addMap(cdna.getSequenceAt(seq).getDatasetSequence(), |
236 | protein.getSequenceAt(seq).getDatasetSequence(), map); | |
237 | } | |
238 | 1 | List<AlignedCodonFrame> acfList = Arrays |
239 | .asList(new AlignedCodonFrame[] | |
240 | { acf }); | |
241 | ||
242 | 1 | AlignViewportI dnaView = new AlignViewport(cdna); |
243 | 1 | AlignViewportI proteinView = new AlignViewport(protein); |
244 | 1 | protein.setCodonFrames(acfList); |
245 | ||
246 | /* | |
247 | * Select Seq1 and Seq3 in the protein | |
248 | */ | |
249 | 1 | SequenceGroup sg = new SequenceGroup(); |
250 | 1 | sg.setColourText(true); |
251 | 1 | sg.setIdColour(Color.GREEN); |
252 | 1 | sg.setOutlineColour(Color.LIGHT_GRAY); |
253 | 1 | sg.addSequence(protein.getSequenceAt(0), false); |
254 | 1 | sg.addSequence(protein.getSequenceAt(2), false); |
255 | 1 | sg.setEndRes(protein.getWidth() - 1); |
256 | ||
257 | /* | |
258 | * Verify the mapped sequence group in dna | |
259 | */ | |
260 | 1 | SequenceGroup mappedGroup = MappingUtils.mapSequenceGroup(sg, |
261 | proteinView, dnaView); | |
262 | 1 | assertTrue(mappedGroup.getColourText()); |
263 | 1 | assertSame(sg.getIdColour(), mappedGroup.getIdColour()); |
264 | 1 | assertSame(sg.getOutlineColour(), mappedGroup.getOutlineColour()); |
265 | 1 | assertEquals(2, mappedGroup.getSequences().size()); |
266 | 1 | assertSame(cdna.getSequenceAt(0), mappedGroup.getSequences().get(0)); |
267 | 1 | assertSame(cdna.getSequenceAt(2), mappedGroup.getSequences().get(1)); |
268 | 1 | assertEquals(0, mappedGroup.getStartRes()); |
269 | 1 | assertEquals(2, mappedGroup.getEndRes()); // 3 columns (1 codon) |
270 | ||
271 | /* | |
272 | * Verify mapping sequence group from dna to protein | |
273 | */ | |
274 | 1 | sg.clear(); |
275 | 1 | sg.addSequence(cdna.getSequenceAt(1), false); |
276 | 1 | sg.addSequence(cdna.getSequenceAt(0), false); |
277 | 1 | sg.setStartRes(0); |
278 | 1 | sg.setEndRes(2); |
279 | 1 | mappedGroup = MappingUtils.mapSequenceGroup(sg, dnaView, proteinView); |
280 | 1 | assertTrue(mappedGroup.getColourText()); |
281 | 1 | assertSame(sg.getIdColour(), mappedGroup.getIdColour()); |
282 | 1 | assertSame(sg.getOutlineColour(), mappedGroup.getOutlineColour()); |
283 | 1 | assertEquals(2, mappedGroup.getSequences().size()); |
284 | 1 | assertSame(protein.getSequenceAt(1), mappedGroup.getSequences().get(0)); |
285 | 1 | assertSame(protein.getSequenceAt(0), mappedGroup.getSequences().get(1)); |
286 | 1 | assertEquals(0, mappedGroup.getStartRes()); |
287 | 1 | assertEquals(0, mappedGroup.getEndRes()); |
288 | } | |
289 | ||
290 | /** | |
291 | * Helper method to load an alignment and ensure dataset sequences are set up. | |
292 | * | |
293 | * @param data | |
294 | * @param format | |
295 | * TODO | |
296 | * @return | |
297 | * @throws IOException | |
298 | */ | |
299 | 14 | protected AlignmentI loadAlignment(final String data, FileFormatI format) |
300 | throws IOException | |
301 | { | |
302 | 14 | AlignmentI a = new FormatAdapter().readFile(data, DataSourceType.PASTE, |
303 | format); | |
304 | 14 | a.setDataset(null); |
305 | 14 | return a; |
306 | } | |
307 | ||
308 | /** | |
309 | * Test mapping a column selection in protein to its dna equivalent | |
310 | * | |
311 | * @throws IOException | |
312 | */ | |
313 | 1 | @Test(groups = { "Functional" }) |
314 | public void testMapColumnSelection_proteinToDna() throws IOException | |
315 | { | |
316 | 1 | setupMappedAlignments(); |
317 | ||
318 | 1 | ColumnSelection colsel = new ColumnSelection(); |
319 | 1 | HiddenColumns hidden = new HiddenColumns(); |
320 | ||
321 | /* | |
322 | * Column 0 in protein picks up Seq2/L, Seq3/G which map to cols 0-4 and 0-3 | |
323 | * in dna respectively, overall 0-4 | |
324 | */ | |
325 | 1 | colsel.addElement(0); |
326 | 1 | ColumnSelection cs = new ColumnSelection(); |
327 | 1 | HiddenColumns hs = new HiddenColumns(); |
328 | 1 | MappingUtils.mapColumnSelection(colsel, hidden, proteinView, dnaView, |
329 | cs, hs); | |
330 | 1 | assertEquals("[0, 1, 2, 3, 4]", cs.getSelected().toString()); |
331 | ||
332 | /* | |
333 | * Column 1 in protein picks up Seq1/K which maps to cols 0-3 in dna | |
334 | */ | |
335 | 1 | cs.clear(); |
336 | 1 | colsel.clear(); |
337 | 1 | colsel.addElement(1); |
338 | 1 | MappingUtils.mapColumnSelection(colsel, hidden, proteinView, dnaView, |
339 | cs, hs); | |
340 | 1 | assertEquals("[0, 1, 2, 3]", cs.getSelected().toString()); |
341 | ||
342 | /* | |
343 | * Column 2 in protein picks up gaps only - no mapping | |
344 | */ | |
345 | 1 | cs.clear(); |
346 | 1 | colsel.clear(); |
347 | 1 | colsel.addElement(2); |
348 | 1 | MappingUtils.mapColumnSelection(colsel, hidden, proteinView, dnaView, |
349 | cs, hs); | |
350 | 1 | assertEquals("[]", cs.getSelected().toString()); |
351 | ||
352 | /* | |
353 | * Column 3 in protein picks up Seq1/P, Seq2/Q, Seq3/S which map to columns | |
354 | * 6-9, 6-10, 5-8 respectively, overall to 5-10 | |
355 | */ | |
356 | 1 | cs.clear(); |
357 | 1 | colsel.clear(); |
358 | 1 | colsel.addElement(3); |
359 | 1 | MappingUtils.mapColumnSelection(colsel, hidden, proteinView, dnaView, |
360 | cs, hs); | |
361 | 1 | assertEquals("[5, 6, 7, 8, 9, 10]", cs.getSelected().toString()); |
362 | ||
363 | /* | |
364 | * Combine selection of columns 1 and 3 to get a discontiguous mapped | |
365 | * selection | |
366 | */ | |
367 | 1 | cs.clear(); |
368 | 1 | colsel.clear(); |
369 | 1 | colsel.addElement(1); |
370 | 1 | colsel.addElement(3); |
371 | 1 | MappingUtils.mapColumnSelection(colsel, hidden, proteinView, dnaView, |
372 | cs, hs); | |
373 | 1 | assertEquals("[0, 1, 2, 3, 5, 6, 7, 8, 9, 10]", |
374 | cs.getSelected().toString()); | |
375 | } | |
376 | ||
377 | /** | |
378 | * Set up mappings for tests from 3 dna to 3 protein sequences. Sequences have | |
379 | * offset start positions for a more general test case. | |
380 | * | |
381 | * @throws IOException | |
382 | */ | |
383 | 4 | protected void setupMappedAlignments() throws IOException |
384 | { | |
385 | /* | |
386 | * Map (upper-case = coding): | |
387 | * Seq1/10-18 AC-GctGtC-T to Seq1/40 -K-P | |
388 | * Seq2/20-27 Tc-GA-G-T-T to Seq2/20-27 L--Q | |
389 | * Seq3/30-38 TtTT-AaCGg- to Seq3/60-61\nG--S | |
390 | */ | |
391 | 4 | AlignmentI cdna = loadAlignment(">Seq1/10-18\nAC-GctGtC-T\n" |
392 | + ">Seq2/20-27\nTc-GA-G-T-Tc\n" + ">Seq3/30-38\nTtTT-AaCGg-\n", | |
393 | FileFormat.Fasta); | |
394 | 4 | cdna.setDataset(null); |
395 | 4 | AlignmentI protein = loadAlignment( |
396 | ">Seq1/40-41\n-K-P\n>Seq2/50-51\nL--Q\n>Seq3/60-61\nG--S\n", | |
397 | FileFormat.Fasta); | |
398 | 4 | protein.setDataset(null); |
399 | ||
400 | // map first dna to first protein seq | |
401 | 4 | AlignedCodonFrame acf = new AlignedCodonFrame(); |
402 | 4 | MapList map = new MapList(new int[] { 10, 12, 15, 15, 17, 18 }, |
403 | new int[] | |
404 | { 40, 41 }, 3, 1); | |
405 | 4 | acf.addMap(cdna.getSequenceAt(0).getDatasetSequence(), |
406 | protein.getSequenceAt(0).getDatasetSequence(), map); | |
407 | ||
408 | // map second dna to second protein seq | |
409 | 4 | map = new MapList(new int[] { 20, 20, 22, 23, 24, 26 }, |
410 | new int[] | |
411 | { 50, 51 }, 3, 1); | |
412 | 4 | acf.addMap(cdna.getSequenceAt(1).getDatasetSequence(), |
413 | protein.getSequenceAt(1).getDatasetSequence(), map); | |
414 | ||
415 | // map third dna to third protein seq | |
416 | 4 | map = new MapList(new int[] { 30, 30, 32, 34, 36, 37 }, |
417 | new int[] | |
418 | { 60, 61 }, 3, 1); | |
419 | 4 | acf.addMap(cdna.getSequenceAt(2).getDatasetSequence(), |
420 | protein.getSequenceAt(2).getDatasetSequence(), map); | |
421 | 4 | List<AlignedCodonFrame> acfList = Arrays |
422 | .asList(new AlignedCodonFrame[] | |
423 | { acf }); | |
424 | ||
425 | 4 | dnaView = new AlignViewport(cdna); |
426 | 4 | proteinView = new AlignViewport(protein); |
427 | 4 | protein.setCodonFrames(acfList); |
428 | } | |
429 | ||
430 | /** | |
431 | * Test mapping a column selection in dna to its protein equivalent | |
432 | * | |
433 | * @throws IOException | |
434 | */ | |
435 | 1 | @Test(groups = { "Functional" }) |
436 | public void testMapColumnSelection_dnaToProtein() throws IOException | |
437 | { | |
438 | 1 | setupMappedAlignments(); |
439 | ||
440 | 1 | ColumnSelection colsel = new ColumnSelection(); |
441 | 1 | HiddenColumns hidden = new HiddenColumns(); |
442 | ||
443 | /* | |
444 | * Column 0 in dna picks up first bases which map to residue 1, columns 0-1 | |
445 | * in protein. | |
446 | */ | |
447 | 1 | ColumnSelection cs = new ColumnSelection(); |
448 | 1 | HiddenColumns hs = new HiddenColumns(); |
449 | 1 | colsel.addElement(0); |
450 | 1 | MappingUtils.mapColumnSelection(colsel, hidden, dnaView, proteinView, |
451 | cs, hs); | |
452 | 1 | assertEquals("[0, 1]", cs.getSelected().toString()); |
453 | ||
454 | /* | |
455 | * Columns 3-5 in dna map to the first residues in protein Seq1, Seq2, and | |
456 | * the first two in Seq3. Overall to columns 0, 1, 3 (col2 is all gaps). | |
457 | */ | |
458 | 1 | colsel.addElement(3); |
459 | 1 | colsel.addElement(4); |
460 | 1 | colsel.addElement(5); |
461 | 1 | cs.clear(); |
462 | 1 | MappingUtils.mapColumnSelection(colsel, hidden, dnaView, proteinView, |
463 | cs, hs); | |
464 | 1 | assertEquals("[0, 1, 3]", cs.getSelected().toString()); |
465 | } | |
466 | ||
467 | 1 | @Test(groups = { "Functional" }) |
468 | public void testMapColumnSelection_null() throws IOException | |
469 | { | |
470 | 1 | setupMappedAlignments(); |
471 | 1 | ColumnSelection cs = new ColumnSelection(); |
472 | 1 | HiddenColumns hs = new HiddenColumns(); |
473 | 1 | MappingUtils.mapColumnSelection(null, null, dnaView, proteinView, cs, |
474 | hs); | |
475 | 1 | assertTrue("mapped selection not empty", cs.getSelected().isEmpty()); |
476 | } | |
477 | ||
478 | /** | |
479 | * Tests for the method that converts a series of [start, end] ranges to | |
480 | * single positions | |
481 | */ | |
482 | 1 | @Test(groups = { "Functional" }) |
483 | public void testFlattenRanges() | |
484 | { | |
485 | 1 | assertEquals("[1, 2, 3, 4]", |
486 | Arrays.toString(MappingUtils.flattenRanges(new int[] | |
487 | { 1, 4 }))); | |
488 | 1 | assertEquals("[1, 2, 3, 4]", |
489 | Arrays.toString(MappingUtils.flattenRanges(new int[] | |
490 | { 1, 2, 3, 4 }))); | |
491 | 1 | assertEquals("[1, 2, 3, 4]", |
492 | Arrays.toString(MappingUtils.flattenRanges(new int[] | |
493 | { 1, 1, 2, 2, 3, 3, 4, 4 }))); | |
494 | 1 | assertEquals("[1, 2, 3, 4, 7, 8, 9, 12]", |
495 | Arrays.toString(MappingUtils.flattenRanges(new int[] | |
496 | { 1, 4, 7, 9, 12, 12 }))); | |
497 | // trailing unpaired start position is ignored: | |
498 | 1 | assertEquals("[1, 2, 3, 4, 7, 8, 9, 12]", |
499 | Arrays.toString(MappingUtils.flattenRanges(new int[] | |
500 | { 1, 4, 7, 9, 12, 12, 15 }))); | |
501 | } | |
502 | ||
503 | /** | |
504 | * Test mapping a sequence group made of entire columns. | |
505 | * | |
506 | * @throws IOException | |
507 | */ | |
508 | 1 | @Test(groups = { "Functional" }) |
509 | public void testMapSequenceGroup_columns() throws IOException | |
510 | { | |
511 | /* | |
512 | * Set up dna and protein Seq1/2/3 with mappings (held on the protein | |
513 | * viewport). | |
514 | */ | |
515 | 1 | AlignmentI cdna = loadAlignment( |
516 | ">Seq1\nACGGCA\n>Seq2\nTGACAG\n>Seq3\nTACGTA\n", | |
517 | FileFormat.Fasta); | |
518 | 1 | cdna.setDataset(null); |
519 | 1 | AlignmentI protein = loadAlignment(">Seq1\nKA\n>Seq2\nLQ\n>Seq3\nQV\n", |
520 | FileFormat.Fasta); | |
521 | 1 | protein.setDataset(null); |
522 | 1 | AlignedCodonFrame acf = new AlignedCodonFrame(); |
523 | 1 | MapList map = new MapList(new int[] { 1, 6 }, new int[] { 1, 2 }, 3, 1); |
524 | 4 | for (int seq = 0; seq < 3; seq++) |
525 | { | |
526 | 3 | acf.addMap(cdna.getSequenceAt(seq).getDatasetSequence(), |
527 | protein.getSequenceAt(seq).getDatasetSequence(), map); | |
528 | } | |
529 | 1 | List<AlignedCodonFrame> acfList = Arrays |
530 | .asList(new AlignedCodonFrame[] | |
531 | { acf }); | |
532 | ||
533 | 1 | AlignViewportI dnaView = new AlignViewport(cdna); |
534 | 1 | AlignViewportI proteinView = new AlignViewport(protein); |
535 | 1 | protein.setCodonFrames(acfList); |
536 | ||
537 | /* | |
538 | * Select all sequences, column 2 in the protein | |
539 | */ | |
540 | 1 | SequenceGroup sg = new SequenceGroup(); |
541 | 1 | sg.setColourText(true); |
542 | 1 | sg.setIdColour(Color.GREEN); |
543 | 1 | sg.setOutlineColour(Color.LIGHT_GRAY); |
544 | 1 | sg.addSequence(protein.getSequenceAt(0), false); |
545 | 1 | sg.addSequence(protein.getSequenceAt(1), false); |
546 | 1 | sg.addSequence(protein.getSequenceAt(2), false); |
547 | 1 | sg.setStartRes(1); |
548 | 1 | sg.setEndRes(1); |
549 | ||
550 | /* | |
551 | * Verify the mapped sequence group in dna | |
552 | */ | |
553 | 1 | SequenceGroup mappedGroup = MappingUtils.mapSequenceGroup(sg, |
554 | proteinView, dnaView); | |
555 | 1 | assertTrue(mappedGroup.getColourText()); |
556 | 1 | assertSame(sg.getIdColour(), mappedGroup.getIdColour()); |
557 | 1 | assertSame(sg.getOutlineColour(), mappedGroup.getOutlineColour()); |
558 | 1 | assertEquals(3, mappedGroup.getSequences().size()); |
559 | 1 | assertSame(cdna.getSequenceAt(0), mappedGroup.getSequences().get(0)); |
560 | 1 | assertSame(cdna.getSequenceAt(1), mappedGroup.getSequences().get(1)); |
561 | 1 | assertSame(cdna.getSequenceAt(2), mappedGroup.getSequences().get(2)); |
562 | 1 | assertEquals(3, mappedGroup.getStartRes()); |
563 | 1 | assertEquals(5, mappedGroup.getEndRes()); |
564 | ||
565 | /* | |
566 | * Verify mapping sequence group from dna to protein | |
567 | */ | |
568 | 1 | sg.clear(); |
569 | 1 | sg.addSequence(cdna.getSequenceAt(0), false); |
570 | 1 | sg.addSequence(cdna.getSequenceAt(1), false); |
571 | 1 | sg.addSequence(cdna.getSequenceAt(2), false); |
572 | // select columns 2 and 3 in DNA which span protein columns 0 and 1 | |
573 | 1 | sg.setStartRes(2); |
574 | 1 | sg.setEndRes(3); |
575 | 1 | mappedGroup = MappingUtils.mapSequenceGroup(sg, dnaView, proteinView); |
576 | 1 | assertTrue(mappedGroup.getColourText()); |
577 | 1 | assertSame(sg.getIdColour(), mappedGroup.getIdColour()); |
578 | 1 | assertSame(sg.getOutlineColour(), mappedGroup.getOutlineColour()); |
579 | 1 | assertEquals(3, mappedGroup.getSequences().size()); |
580 | 1 | assertSame(protein.getSequenceAt(0), mappedGroup.getSequences().get(0)); |
581 | 1 | assertSame(protein.getSequenceAt(1), mappedGroup.getSequences().get(1)); |
582 | 1 | assertSame(protein.getSequenceAt(2), mappedGroup.getSequences().get(2)); |
583 | 1 | assertEquals(0, mappedGroup.getStartRes()); |
584 | 1 | assertEquals(1, mappedGroup.getEndRes()); |
585 | } | |
586 | ||
587 | /** | |
588 | * Test mapping a sequence group made of a sequences/columns region. | |
589 | * | |
590 | * @throws IOException | |
591 | */ | |
592 | 1 | @Test(groups = { "Functional" }) |
593 | public void testMapSequenceGroup_region() throws IOException | |
594 | { | |
595 | /* | |
596 | * Set up gapped dna and protein Seq1/2/3 with mappings (held on the protein | |
597 | * viewport). | |
598 | */ | |
599 | 1 | AlignmentI cdna = loadAlignment( |
600 | ">Seq1\nA-CG-GC--AT-CA\n>Seq2\n-TG-AC-AG-T-AT\n>Seq3\n-T--ACG-TAAT-G\n", | |
601 | FileFormat.Fasta); | |
602 | 1 | cdna.setDataset(null); |
603 | 1 | AlignmentI protein = loadAlignment( |
604 | ">Seq1\n-KA-S\n>Seq2\n--L-QY\n>Seq3\nQ-V-M\n", | |
605 | FileFormat.Fasta); | |
606 | 1 | protein.setDataset(null); |
607 | 1 | AlignedCodonFrame acf = new AlignedCodonFrame(); |
608 | 1 | MapList map = new MapList(new int[] { 1, 9 }, new int[] { 1, 3 }, 3, 1); |
609 | 4 | for (int seq = 0; seq < 3; seq++) |
610 | { | |
611 | 3 | acf.addMap(cdna.getSequenceAt(seq).getDatasetSequence(), |
612 | protein.getSequenceAt(seq).getDatasetSequence(), map); | |
613 | } | |
614 | 1 | List<AlignedCodonFrame> acfList = Arrays |
615 | .asList(new AlignedCodonFrame[] | |
616 | { acf }); | |
617 | ||
618 | 1 | AlignViewportI dnaView = new AlignViewport(cdna); |
619 | 1 | AlignViewportI proteinView = new AlignViewport(protein); |
620 | 1 | protein.setCodonFrames(acfList); |
621 | ||
622 | /* | |
623 | * Select Seq1 and Seq2 in the protein, column 1 (K/-). Expect mapped | |
624 | * sequence group to cover Seq1, columns 0-3 (ACG). Because the selection | |
625 | * only includes a gap in Seq2 there is no mappable selection region in the | |
626 | * corresponding DNA. | |
627 | */ | |
628 | 1 | SequenceGroup sg = new SequenceGroup(); |
629 | 1 | sg.setColourText(true); |
630 | 1 | sg.setIdColour(Color.GREEN); |
631 | 1 | sg.setOutlineColour(Color.LIGHT_GRAY); |
632 | 1 | sg.addSequence(protein.getSequenceAt(0), false); |
633 | 1 | sg.addSequence(protein.getSequenceAt(1), false); |
634 | 1 | sg.setStartRes(1); |
635 | 1 | sg.setEndRes(1); |
636 | ||
637 | /* | |
638 | * Verify the mapped sequence group in dna | |
639 | */ | |
640 | 1 | SequenceGroup mappedGroup = MappingUtils.mapSequenceGroup(sg, |
641 | proteinView, dnaView); | |
642 | 1 | assertTrue(mappedGroup.getColourText()); |
643 | 1 | assertSame(sg.getIdColour(), mappedGroup.getIdColour()); |
644 | 1 | assertSame(sg.getOutlineColour(), mappedGroup.getOutlineColour()); |
645 | 1 | assertEquals(1, mappedGroup.getSequences().size()); |
646 | 1 | assertSame(cdna.getSequenceAt(0), mappedGroup.getSequences().get(0)); |
647 | // Seq2 in protein has a gap in column 1 - ignored | |
648 | // Seq1 has K which should map to columns 0-3 in Seq1 | |
649 | 1 | assertEquals(0, mappedGroup.getStartRes()); |
650 | 1 | assertEquals(3, mappedGroup.getEndRes()); |
651 | ||
652 | /* | |
653 | * Now select cols 2-4 in protein. These cover Seq1:AS Seq2:LQ Seq3:VM which | |
654 | * extend over DNA columns 3-12, 1-7, 6-13 respectively, or 1-13 overall. | |
655 | */ | |
656 | 1 | sg.setStartRes(2); |
657 | 1 | sg.setEndRes(4); |
658 | 1 | mappedGroup = MappingUtils.mapSequenceGroup(sg, proteinView, dnaView); |
659 | 1 | assertEquals(1, mappedGroup.getStartRes()); |
660 | 1 | assertEquals(13, mappedGroup.getEndRes()); |
661 | ||
662 | /* | |
663 | * Verify mapping sequence group from dna to protein | |
664 | */ | |
665 | 1 | sg.clear(); |
666 | 1 | sg.addSequence(cdna.getSequenceAt(0), false); |
667 | ||
668 | // select columns 4,5 - includes Seq1:codon2 (A) only | |
669 | 1 | sg.setStartRes(4); |
670 | 1 | sg.setEndRes(5); |
671 | 1 | mappedGroup = MappingUtils.mapSequenceGroup(sg, dnaView, proteinView); |
672 | 1 | assertEquals(2, mappedGroup.getStartRes()); |
673 | 1 | assertEquals(2, mappedGroup.getEndRes()); |
674 | ||
675 | // add Seq2 to dna selection cols 4-5 include codons 1 and 2 (LQ) | |
676 | 1 | sg.addSequence(cdna.getSequenceAt(1), false); |
677 | 1 | mappedGroup = MappingUtils.mapSequenceGroup(sg, dnaView, proteinView); |
678 | 1 | assertEquals(2, mappedGroup.getStartRes()); |
679 | 1 | assertEquals(4, mappedGroup.getEndRes()); |
680 | ||
681 | // add Seq3 to dna selection cols 4-5 include codon 1 (Q) | |
682 | 1 | sg.addSequence(cdna.getSequenceAt(2), false); |
683 | 1 | mappedGroup = MappingUtils.mapSequenceGroup(sg, dnaView, proteinView); |
684 | 1 | assertEquals(0, mappedGroup.getStartRes()); |
685 | 1 | assertEquals(4, mappedGroup.getEndRes()); |
686 | } | |
687 | ||
688 | 1 | @Test(groups = { "Functional" }) |
689 | public void testFindMappingsForSequence() | |
690 | { | |
691 | 1 | SequenceI seq1 = new Sequence("Seq1", "ABC"); |
692 | 1 | SequenceI seq2 = new Sequence("Seq2", "ABC"); |
693 | 1 | SequenceI seq3 = new Sequence("Seq3", "ABC"); |
694 | 1 | SequenceI seq4 = new Sequence("Seq4", "ABC"); |
695 | 1 | seq1.createDatasetSequence(); |
696 | 1 | seq2.createDatasetSequence(); |
697 | 1 | seq3.createDatasetSequence(); |
698 | 1 | seq4.createDatasetSequence(); |
699 | ||
700 | /* | |
701 | * Create mappings from seq1 to seq2, seq2 to seq1, seq3 to seq1 | |
702 | */ | |
703 | 1 | AlignedCodonFrame acf1 = new AlignedCodonFrame(); |
704 | 1 | MapList map = new MapList(new int[] { 1, 3 }, new int[] { 1, 3 }, 1, 1); |
705 | 1 | acf1.addMap(seq1.getDatasetSequence(), seq2.getDatasetSequence(), map); |
706 | 1 | AlignedCodonFrame acf2 = new AlignedCodonFrame(); |
707 | 1 | acf2.addMap(seq2.getDatasetSequence(), seq1.getDatasetSequence(), map); |
708 | 1 | AlignedCodonFrame acf3 = new AlignedCodonFrame(); |
709 | 1 | acf3.addMap(seq3.getDatasetSequence(), seq1.getDatasetSequence(), map); |
710 | ||
711 | 1 | List<AlignedCodonFrame> mappings = new ArrayList<>(); |
712 | 1 | mappings.add(acf1); |
713 | 1 | mappings.add(acf2); |
714 | 1 | mappings.add(acf3); |
715 | ||
716 | /* | |
717 | * Seq1 has three mappings | |
718 | */ | |
719 | 1 | List<AlignedCodonFrame> result = MappingUtils |
720 | .findMappingsForSequence(seq1, mappings); | |
721 | 1 | assertEquals(3, result.size()); |
722 | 1 | assertTrue(result.contains(acf1)); |
723 | 1 | assertTrue(result.contains(acf2)); |
724 | 1 | assertTrue(result.contains(acf3)); |
725 | ||
726 | /* | |
727 | * Seq2 has two mappings | |
728 | */ | |
729 | 1 | result = MappingUtils.findMappingsForSequence(seq2, mappings); |
730 | 1 | assertEquals(2, result.size()); |
731 | 1 | assertTrue(result.contains(acf1)); |
732 | 1 | assertTrue(result.contains(acf2)); |
733 | ||
734 | /* | |
735 | * Seq3 has one mapping | |
736 | */ | |
737 | 1 | result = MappingUtils.findMappingsForSequence(seq3, mappings); |
738 | 1 | assertEquals(1, result.size()); |
739 | 1 | assertTrue(result.contains(acf3)); |
740 | ||
741 | /* | |
742 | * Seq4 has no mappings | |
743 | */ | |
744 | 1 | result = MappingUtils.findMappingsForSequence(seq4, mappings); |
745 | 1 | assertEquals(0, result.size()); |
746 | ||
747 | 1 | result = MappingUtils.findMappingsForSequence(null, mappings); |
748 | 1 | assertEquals(0, result.size()); |
749 | ||
750 | 1 | result = MappingUtils.findMappingsForSequence(seq1, null); |
751 | 1 | assertEquals(0, result.size()); |
752 | ||
753 | 1 | result = MappingUtils.findMappingsForSequence(null, null); |
754 | 1 | assertEquals(0, result.size()); |
755 | } | |
756 | ||
757 | /** | |
758 | * just like the one above, but this time, we provide a set of sequences to | |
759 | * subselect the mapping search | |
760 | */ | |
761 | 1 | @Test(groups = { "Functional" }) |
762 | public void testFindMappingsForSequenceAndOthers() | |
763 | { | |
764 | 1 | SequenceI seq1 = new Sequence("Seq1", "ABC"); |
765 | 1 | SequenceI seq2 = new Sequence("Seq2", "ABC"); |
766 | 1 | SequenceI seq3 = new Sequence("Seq3", "ABC"); |
767 | 1 | SequenceI seq4 = new Sequence("Seq4", "ABC"); |
768 | 1 | seq1.createDatasetSequence(); |
769 | 1 | seq2.createDatasetSequence(); |
770 | 1 | seq3.createDatasetSequence(); |
771 | 1 | seq4.createDatasetSequence(); |
772 | ||
773 | /* | |
774 | * Create mappings from seq1 to seq2, seq2 to seq1, seq3 to seq1, seq3 to seq4 | |
775 | */ | |
776 | 1 | AlignedCodonFrame acf1 = new AlignedCodonFrame(); |
777 | 1 | MapList map = new MapList(new int[] { 1, 3 }, new int[] { 1, 3 }, 1, 1); |
778 | 1 | acf1.addMap(seq1.getDatasetSequence(), seq2.getDatasetSequence(), map); |
779 | 1 | AlignedCodonFrame acf2 = new AlignedCodonFrame(); |
780 | 1 | acf2.addMap(seq2.getDatasetSequence(), seq1.getDatasetSequence(), map); |
781 | 1 | AlignedCodonFrame acf3 = new AlignedCodonFrame(); |
782 | 1 | acf3.addMap(seq3.getDatasetSequence(), seq1.getDatasetSequence(), map); |
783 | 1 | AlignedCodonFrame acf4 = new AlignedCodonFrame(); |
784 | 1 | acf4.addMap(seq3.getDatasetSequence(), seq4.getDatasetSequence(), map); |
785 | ||
786 | 1 | List<AlignedCodonFrame> mappings = new ArrayList<>(); |
787 | 1 | mappings.add(acf1); |
788 | 1 | mappings.add(acf2); |
789 | 1 | mappings.add(acf3); |
790 | 1 | mappings.add(acf4); |
791 | ||
792 | /* | |
793 | * test for null args | |
794 | */ | |
795 | 1 | List<AlignedCodonFrame> result = MappingUtils |
796 | .findMappingsForSequenceAndOthers(null, mappings, | |
797 | Arrays.asList(new SequenceI[] | |
798 | { seq1, seq2 })); | |
799 | 1 | assertTrue(result.isEmpty()); |
800 | ||
801 | 1 | result = MappingUtils.findMappingsForSequenceAndOthers(seq1, null, |
802 | Arrays.asList(new SequenceI[] | |
803 | { seq1, seq2 })); | |
804 | 1 | assertTrue(result.isEmpty()); |
805 | ||
806 | /* | |
807 | * Seq1 has three mappings, but filter argument will only accept | |
808 | * those to seq2 | |
809 | */ | |
810 | 1 | result = MappingUtils.findMappingsForSequenceAndOthers(seq1, mappings, |
811 | Arrays.asList(new SequenceI[] | |
812 | { seq1, seq2, seq1.getDatasetSequence() })); | |
813 | 1 | assertEquals(2, result.size()); |
814 | 1 | assertTrue(result.contains(acf1)); |
815 | 1 | assertTrue(result.contains(acf2)); |
816 | 1 | assertFalse("Did not expect to find mapping acf3 - subselect failed", |
817 | result.contains(acf3)); | |
818 | 1 | assertFalse( |
819 | "Did not expect to find mapping acf4 - doesn't involve sequence", | |
820 | result.contains(acf4)); | |
821 | ||
822 | /* | |
823 | * and verify the no filter case | |
824 | */ | |
825 | 1 | result = MappingUtils.findMappingsForSequenceAndOthers(seq1, mappings, |
826 | null); | |
827 | 1 | assertEquals(3, result.size()); |
828 | 1 | assertTrue(result.contains(acf1)); |
829 | 1 | assertTrue(result.contains(acf2)); |
830 | 1 | assertTrue(result.contains(acf3)); |
831 | } | |
832 | ||
833 | 1 | @Test(groups = { "Functional" }) |
834 | public void testMapEditCommand() | |
835 | { | |
836 | 1 | SequenceI dna = new Sequence("Seq1", "---ACG---GCATCA", 8, 16); |
837 | 1 | SequenceI protein = new Sequence("Seq2", "-T-AS", 5, 7); |
838 | 1 | dna.createDatasetSequence(); |
839 | 1 | protein.createDatasetSequence(); |
840 | 1 | AlignedCodonFrame acf = new AlignedCodonFrame(); |
841 | 1 | MapList map = new MapList(new int[] { 8, 16 }, new int[] { 5, 7 }, 3, |
842 | 1); | |
843 | 1 | acf.addMap(dna.getDatasetSequence(), protein.getDatasetSequence(), map); |
844 | 1 | List<AlignedCodonFrame> mappings = new ArrayList<>(); |
845 | 1 | mappings.add(acf); |
846 | ||
847 | 1 | AlignmentI prot = new Alignment(new SequenceI[] { protein }); |
848 | 1 | prot.setCodonFrames(mappings); |
849 | 1 | AlignmentI nuc = new Alignment(new SequenceI[] { dna }); |
850 | ||
851 | /* | |
852 | * construct and perform the edit command to turn "-T-AS" in to "-T-A--S" | |
853 | * i.e. insert two gaps at column 4 | |
854 | */ | |
855 | 1 | EditCommand ec = new EditCommand(); |
856 | 1 | final Edit edit = ec.new Edit(Action.INSERT_GAP, |
857 | new SequenceI[] | |
858 | { protein }, 4, 2, '-'); | |
859 | 1 | ec.appendEdit(edit, prot, true, null); |
860 | ||
861 | /* | |
862 | * the mapped edit command should be to insert 6 gaps before base 4 in the | |
863 | * nucleotide sequence, which corresponds to aligned column 12 in the dna | |
864 | */ | |
865 | 1 | EditCommand mappedEdit = MappingUtils.mapEditCommand(ec, false, nuc, |
866 | '-', mappings); | |
867 | 1 | assertEquals(1, mappedEdit.getEdits().size()); |
868 | 1 | Edit e = mappedEdit.getEdits().get(0); |
869 | 1 | assertEquals(1, e.getSequences().length); |
870 | 1 | assertEquals(dna, e.getSequences()[0]); |
871 | 1 | assertEquals(12, e.getPosition()); |
872 | 1 | assertEquals(6, e.getNumber()); |
873 | } | |
874 | ||
875 | /** | |
876 | * Tests for the method that converts a series of [start, end] ranges to | |
877 | * single positions, where the mapping is to a reverse strand i.e. start is | |
878 | * greater than end point mapped to | |
879 | */ | |
880 | 1 | @Test(groups = { "Functional" }) |
881 | public void testFlattenRanges_reverseStrand() | |
882 | { | |
883 | 1 | assertEquals("[4, 3, 2, 1]", |
884 | Arrays.toString(MappingUtils.flattenRanges(new int[] | |
885 | { 4, 1 }))); | |
886 | 1 | assertEquals("[4, 3, 2, 1]", |
887 | Arrays.toString(MappingUtils.flattenRanges(new int[] | |
888 | { 4, 3, 2, 1 }))); | |
889 | 1 | assertEquals("[4, 3, 2, 1]", |
890 | Arrays.toString(MappingUtils.flattenRanges(new int[] | |
891 | { 4, 4, 3, 3, 2, 2, 1, 1 }))); | |
892 | 1 | assertEquals("[12, 9, 8, 7, 4, 3, 2, 1]", |
893 | Arrays.toString(MappingUtils.flattenRanges(new int[] | |
894 | { 12, 12, 9, 7, 4, 1 }))); | |
895 | // forwards and backwards anyone? | |
896 | 1 | assertEquals("[4, 5, 6, 3, 2, 1]", |
897 | Arrays.toString(MappingUtils.flattenRanges(new int[] | |
898 | { 4, 6, 3, 1 }))); | |
899 | // backwards and forwards | |
900 | 1 | assertEquals("[3, 2, 1, 4, 5, 6]", |
901 | Arrays.toString(MappingUtils.flattenRanges(new int[] | |
902 | { 3, 1, 4, 6 }))); | |
903 | // trailing unpaired start position is ignored: | |
904 | 1 | assertEquals("[12, 9, 8, 7, 4, 3, 2]", |
905 | Arrays.toString(MappingUtils.flattenRanges(new int[] | |
906 | { 12, 12, 9, 7, 4, 2, 1 }))); | |
907 | } | |
908 | ||
909 | /** | |
910 | * Test mapping a column selection including hidden columns | |
911 | * | |
912 | * @throws IOException | |
913 | */ | |
914 | 1 | @Test(groups = { "Functional" }) |
915 | public void testMapColumnSelection_hiddenColumns() throws IOException | |
916 | { | |
917 | 1 | setupMappedAlignments(); |
918 | ||
919 | 1 | ColumnSelection proteinSelection = new ColumnSelection(); |
920 | 1 | HiddenColumns hiddenCols = new HiddenColumns(); |
921 | ||
922 | /* | |
923 | * Column 0 in protein picks up Seq2/L, Seq3/G which map to cols 0-4 and 0-3 | |
924 | * in dna respectively, overall 0-4 | |
925 | */ | |
926 | 1 | proteinSelection.hideSelectedColumns(0, hiddenCols); |
927 | 1 | ColumnSelection dnaSelection = new ColumnSelection(); |
928 | 1 | HiddenColumns dnaHidden = new HiddenColumns(); |
929 | 1 | MappingUtils.mapColumnSelection(proteinSelection, hiddenCols, |
930 | proteinView, dnaView, dnaSelection, dnaHidden); | |
931 | 1 | assertEquals("[]", dnaSelection.getSelected().toString()); |
932 | 1 | Iterator<int[]> regions = dnaHidden.iterator(); |
933 | 1 | assertEquals(1, dnaHidden.getNumberOfRegions()); |
934 | 1 | assertEquals("[0, 4]", Arrays.toString(regions.next())); |
935 | ||
936 | /* | |
937 | * Column 1 in protein picks up Seq1/K which maps to cols 0-3 in dna | |
938 | */ | |
939 | 1 | dnaSelection = new ColumnSelection(); |
940 | 1 | dnaHidden = new HiddenColumns(); |
941 | 1 | hiddenCols.revealAllHiddenColumns(proteinSelection); |
942 | // the unhidden columns are now marked selected! | |
943 | 1 | assertEquals("[0]", proteinSelection.getSelected().toString()); |
944 | // deselect these or hideColumns will be expanded to include 0 | |
945 | 1 | proteinSelection.clear(); |
946 | 1 | proteinSelection.hideSelectedColumns(1, hiddenCols); |
947 | 1 | MappingUtils.mapColumnSelection(proteinSelection, hiddenCols, |
948 | proteinView, dnaView, dnaSelection, dnaHidden); | |
949 | 1 | regions = dnaHidden.iterator(); |
950 | 1 | assertEquals(1, dnaHidden.getNumberOfRegions()); |
951 | 1 | assertEquals("[0, 3]", Arrays.toString(regions.next())); |
952 | ||
953 | /* | |
954 | * Column 2 in protein picks up gaps only - no mapping | |
955 | */ | |
956 | 1 | dnaSelection = new ColumnSelection(); |
957 | 1 | dnaHidden = new HiddenColumns(); |
958 | 1 | hiddenCols.revealAllHiddenColumns(proteinSelection); |
959 | 1 | proteinSelection.clear(); |
960 | 1 | proteinSelection.hideSelectedColumns(2, hiddenCols); |
961 | 1 | MappingUtils.mapColumnSelection(proteinSelection, hiddenCols, |
962 | proteinView, dnaView, dnaSelection, dnaHidden); | |
963 | 1 | assertEquals(0, dnaHidden.getNumberOfRegions()); |
964 | ||
965 | /* | |
966 | * Column 3 in protein picks up Seq1/P, Seq2/Q, Seq3/S which map to columns | |
967 | * 6-9, 6-10, 5-8 respectively, overall to 5-10 | |
968 | */ | |
969 | 1 | dnaSelection = new ColumnSelection(); |
970 | 1 | dnaHidden = new HiddenColumns(); |
971 | 1 | hiddenCols.revealAllHiddenColumns(proteinSelection); |
972 | 1 | proteinSelection.clear(); |
973 | 1 | proteinSelection.hideSelectedColumns(3, hiddenCols); // 5-10 hidden in dna |
974 | 1 | proteinSelection.addElement(1); // 0-3 selected in dna |
975 | 1 | MappingUtils.mapColumnSelection(proteinSelection, hiddenCols, |
976 | proteinView, dnaView, dnaSelection, dnaHidden); | |
977 | 1 | assertEquals("[0, 1, 2, 3]", dnaSelection.getSelected().toString()); |
978 | 1 | regions = dnaHidden.iterator(); |
979 | 1 | assertEquals(1, dnaHidden.getNumberOfRegions()); |
980 | 1 | assertEquals("[5, 10]", Arrays.toString(regions.next())); |
981 | ||
982 | /* | |
983 | * Combine hiding columns 1 and 3 to get discontiguous hidden columns | |
984 | */ | |
985 | 1 | dnaSelection = new ColumnSelection(); |
986 | 1 | dnaHidden = new HiddenColumns(); |
987 | 1 | hiddenCols.revealAllHiddenColumns(proteinSelection); |
988 | 1 | proteinSelection.clear(); |
989 | 1 | proteinSelection.hideSelectedColumns(1, hiddenCols); |
990 | 1 | proteinSelection.hideSelectedColumns(3, hiddenCols); |
991 | 1 | MappingUtils.mapColumnSelection(proteinSelection, hiddenCols, |
992 | proteinView, dnaView, dnaSelection, dnaHidden); | |
993 | 1 | regions = dnaHidden.iterator(); |
994 | 1 | assertEquals(2, dnaHidden.getNumberOfRegions()); |
995 | 1 | assertEquals("[0, 3]", Arrays.toString(regions.next())); |
996 | 1 | assertEquals("[5, 10]", Arrays.toString(regions.next())); |
997 | } | |
998 | ||
999 | 1 | @Test(groups = { "Functional" }) |
1000 | public void testGetLength() | |
1001 | { | |
1002 | 1 | assertEquals(0, MappingUtils.getLength(null)); |
1003 | ||
1004 | /* | |
1005 | * [start, end] ranges | |
1006 | */ | |
1007 | 1 | List<int[]> ranges = new ArrayList<>(); |
1008 | 1 | assertEquals(0, MappingUtils.getLength(ranges)); |
1009 | 1 | ranges.add(new int[] { 1, 1 }); |
1010 | 1 | assertEquals(1, MappingUtils.getLength(ranges)); |
1011 | 1 | ranges.add(new int[] { 2, 10 }); |
1012 | 1 | assertEquals(10, MappingUtils.getLength(ranges)); |
1013 | 1 | ranges.add(new int[] { 20, 10 }); |
1014 | 1 | assertEquals(21, MappingUtils.getLength(ranges)); |
1015 | ||
1016 | /* | |
1017 | * [start, end, start, end...] ranges | |
1018 | */ | |
1019 | 1 | ranges.clear(); |
1020 | 1 | ranges.add(new int[] { 1, 5, 8, 4 }); |
1021 | 1 | ranges.add(new int[] { 8, 2 }); |
1022 | 1 | ranges.add(new int[] { 12, 12 }); |
1023 | 1 | assertEquals(18, MappingUtils.getLength(ranges)); |
1024 | } | |
1025 | ||
1026 | 1 | @Test(groups = { "Functional" }) |
1027 | public void testContains() | |
1028 | { | |
1029 | 1 | assertFalse(MappingUtils.contains(null, 1)); |
1030 | 1 | List<int[]> ranges = new ArrayList<>(); |
1031 | 1 | assertFalse(MappingUtils.contains(ranges, 1)); |
1032 | ||
1033 | 1 | ranges.add(new int[] { 1, 4 }); |
1034 | 1 | ranges.add(new int[] { 6, 6 }); |
1035 | 1 | ranges.add(new int[] { 8, 10 }); |
1036 | 1 | ranges.add(new int[] { 30, 20 }); |
1037 | 1 | ranges.add(new int[] { -16, -44 }); |
1038 | ||
1039 | 1 | assertFalse(MappingUtils.contains(ranges, 0)); |
1040 | 1 | assertTrue(MappingUtils.contains(ranges, 1)); |
1041 | 1 | assertTrue(MappingUtils.contains(ranges, 2)); |
1042 | 1 | assertTrue(MappingUtils.contains(ranges, 3)); |
1043 | 1 | assertTrue(MappingUtils.contains(ranges, 4)); |
1044 | 1 | assertFalse(MappingUtils.contains(ranges, 5)); |
1045 | ||
1046 | 1 | assertTrue(MappingUtils.contains(ranges, 6)); |
1047 | 1 | assertFalse(MappingUtils.contains(ranges, 7)); |
1048 | ||
1049 | 1 | assertTrue(MappingUtils.contains(ranges, 8)); |
1050 | 1 | assertTrue(MappingUtils.contains(ranges, 9)); |
1051 | 1 | assertTrue(MappingUtils.contains(ranges, 10)); |
1052 | ||
1053 | 1 | assertFalse(MappingUtils.contains(ranges, 31)); |
1054 | 1 | assertTrue(MappingUtils.contains(ranges, 30)); |
1055 | 1 | assertTrue(MappingUtils.contains(ranges, 29)); |
1056 | 1 | assertTrue(MappingUtils.contains(ranges, 20)); |
1057 | 1 | assertFalse(MappingUtils.contains(ranges, 19)); |
1058 | ||
1059 | 1 | assertFalse(MappingUtils.contains(ranges, -15)); |
1060 | 1 | assertTrue(MappingUtils.contains(ranges, -16)); |
1061 | 1 | assertTrue(MappingUtils.contains(ranges, -44)); |
1062 | 1 | assertFalse(MappingUtils.contains(ranges, -45)); |
1063 | } | |
1064 | ||
1065 | /** | |
1066 | * Test the method that drops positions from the start of a mapped range | |
1067 | */ | |
1068 | 1 | @Test(groups = "Functional") |
1069 | public void testRemoveStartPositions() | |
1070 | { | |
1071 | 1 | int[] ranges = new int[] { 1, 10 }; |
1072 | 1 | int[] adjusted = MappingUtils.removeStartPositions(0, ranges); |
1073 | 1 | assertEquals("[1, 10]", Arrays.toString(adjusted)); |
1074 | ||
1075 | 1 | adjusted = MappingUtils.removeStartPositions(1, ranges); |
1076 | 1 | assertEquals("[2, 10]", Arrays.toString(adjusted)); |
1077 | 1 | assertEquals("[1, 10]", Arrays.toString(ranges)); |
1078 | ||
1079 | 1 | ranges = adjusted; |
1080 | 1 | adjusted = MappingUtils.removeStartPositions(1, ranges); |
1081 | 1 | assertEquals("[3, 10]", Arrays.toString(adjusted)); |
1082 | 1 | assertEquals("[2, 10]", Arrays.toString(ranges)); |
1083 | ||
1084 | 1 | ranges = new int[] { 2, 3, 10, 12 }; |
1085 | 1 | adjusted = MappingUtils.removeStartPositions(1, ranges); |
1086 | 1 | assertEquals("[3, 3, 10, 12]", Arrays.toString(adjusted)); |
1087 | 1 | assertEquals("[2, 3, 10, 12]", Arrays.toString(ranges)); |
1088 | ||
1089 | 1 | ranges = new int[] { 2, 2, 8, 12 }; |
1090 | 1 | adjusted = MappingUtils.removeStartPositions(1, ranges); |
1091 | 1 | assertEquals("[8, 12]", Arrays.toString(adjusted)); |
1092 | 1 | assertEquals("[2, 2, 8, 12]", Arrays.toString(ranges)); |
1093 | ||
1094 | 1 | ranges = new int[] { 2, 2, 8, 12 }; |
1095 | 1 | adjusted = MappingUtils.removeStartPositions(2, ranges); |
1096 | 1 | assertEquals("[9, 12]", Arrays.toString(adjusted)); |
1097 | 1 | assertEquals("[2, 2, 8, 12]", Arrays.toString(ranges)); |
1098 | ||
1099 | 1 | ranges = new int[] { 2, 2, 4, 4, 9, 12 }; |
1100 | 1 | adjusted = MappingUtils.removeStartPositions(1, ranges); |
1101 | 1 | assertEquals("[4, 4, 9, 12]", Arrays.toString(adjusted)); |
1102 | 1 | assertEquals("[2, 2, 4, 4, 9, 12]", Arrays.toString(ranges)); |
1103 | ||
1104 | 1 | ranges = new int[] { 2, 2, 4, 4, 9, 12 }; |
1105 | 1 | adjusted = MappingUtils.removeStartPositions(2, ranges); |
1106 | 1 | assertEquals("[9, 12]", Arrays.toString(adjusted)); |
1107 | 1 | assertEquals("[2, 2, 4, 4, 9, 12]", Arrays.toString(ranges)); |
1108 | ||
1109 | 1 | ranges = new int[] { 2, 3, 9, 12 }; |
1110 | 1 | adjusted = MappingUtils.removeStartPositions(3, ranges); |
1111 | 1 | assertEquals("[10, 12]", Arrays.toString(adjusted)); |
1112 | 1 | assertEquals("[2, 3, 9, 12]", Arrays.toString(ranges)); |
1113 | } | |
1114 | ||
1115 | /** | |
1116 | * Test the method that drops positions from the start of a mapped range, on | |
1117 | * the reverse strand | |
1118 | */ | |
1119 | 1 | @Test(groups = "Functional") |
1120 | public void testRemoveStartPositions_reverseStrand() | |
1121 | { | |
1122 | 1 | int[] ranges = new int[] { 10, 1 }; |
1123 | 1 | int[] adjusted = MappingUtils.removeStartPositions(0, ranges); |
1124 | 1 | assertEquals("[10, 1]", Arrays.toString(adjusted)); |
1125 | 1 | assertEquals("[10, 1]", Arrays.toString(ranges)); |
1126 | ||
1127 | 1 | ranges = adjusted; |
1128 | 1 | adjusted = MappingUtils.removeStartPositions(1, ranges); |
1129 | 1 | assertEquals("[9, 1]", Arrays.toString(adjusted)); |
1130 | 1 | assertEquals("[10, 1]", Arrays.toString(ranges)); |
1131 | ||
1132 | 1 | ranges = adjusted; |
1133 | 1 | adjusted = MappingUtils.removeStartPositions(1, ranges); |
1134 | 1 | assertEquals("[8, 1]", Arrays.toString(adjusted)); |
1135 | 1 | assertEquals("[9, 1]", Arrays.toString(ranges)); |
1136 | ||
1137 | 1 | ranges = new int[] { 12, 11, 9, 6 }; |
1138 | 1 | adjusted = MappingUtils.removeStartPositions(1, ranges); |
1139 | 1 | assertEquals("[11, 11, 9, 6]", Arrays.toString(adjusted)); |
1140 | 1 | assertEquals("[12, 11, 9, 6]", Arrays.toString(ranges)); |
1141 | ||
1142 | 1 | ranges = new int[] { 12, 12, 8, 4 }; |
1143 | 1 | adjusted = MappingUtils.removeStartPositions(1, ranges); |
1144 | 1 | assertEquals("[8, 4]", Arrays.toString(adjusted)); |
1145 | 1 | assertEquals("[12, 12, 8, 4]", Arrays.toString(ranges)); |
1146 | ||
1147 | 1 | ranges = new int[] { 12, 12, 8, 4 }; |
1148 | 1 | adjusted = MappingUtils.removeStartPositions(2, ranges); |
1149 | 1 | assertEquals("[7, 4]", Arrays.toString(adjusted)); |
1150 | 1 | assertEquals("[12, 12, 8, 4]", Arrays.toString(ranges)); |
1151 | ||
1152 | 1 | ranges = new int[] { 12, 12, 10, 10, 8, 4 }; |
1153 | 1 | adjusted = MappingUtils.removeStartPositions(1, ranges); |
1154 | 1 | assertEquals("[10, 10, 8, 4]", Arrays.toString(adjusted)); |
1155 | 1 | assertEquals("[12, 12, 10, 10, 8, 4]", Arrays.toString(ranges)); |
1156 | ||
1157 | 1 | ranges = new int[] { 12, 12, 10, 10, 8, 4 }; |
1158 | 1 | adjusted = MappingUtils.removeStartPositions(2, ranges); |
1159 | 1 | assertEquals("[8, 4]", Arrays.toString(adjusted)); |
1160 | 1 | assertEquals("[12, 12, 10, 10, 8, 4]", Arrays.toString(ranges)); |
1161 | ||
1162 | 1 | ranges = new int[] { 12, 11, 8, 4 }; |
1163 | 1 | adjusted = MappingUtils.removeStartPositions(3, ranges); |
1164 | 1 | assertEquals("[7, 4]", Arrays.toString(adjusted)); |
1165 | 1 | assertEquals("[12, 11, 8, 4]", Arrays.toString(ranges)); |
1166 | } | |
1167 | ||
1168 | 1 | @Test(groups = { "Functional" }) |
1169 | public void testRangeContains() | |
1170 | { | |
1171 | /* | |
1172 | * both forward ranges | |
1173 | */ | |
1174 | 1 | assertTrue( |
1175 | MappingUtils.rangeContains(new int[] | |
1176 | { 1, 10 }, new int[] { 1, 10 })); | |
1177 | 1 | assertTrue( |
1178 | MappingUtils.rangeContains(new int[] | |
1179 | { 1, 10 }, new int[] { 2, 10 })); | |
1180 | 1 | assertTrue( |
1181 | MappingUtils.rangeContains(new int[] | |
1182 | { 1, 10 }, new int[] { 1, 9 })); | |
1183 | 1 | assertTrue( |
1184 | MappingUtils.rangeContains(new int[] | |
1185 | { 1, 10 }, new int[] { 4, 5 })); | |
1186 | 1 | assertFalse( |
1187 | MappingUtils.rangeContains(new int[] | |
1188 | { 1, 10 }, new int[] { 0, 9 })); | |
1189 | 1 | assertFalse( |
1190 | MappingUtils.rangeContains(new int[] | |
1191 | { 1, 10 }, new int[] { -10, -9 })); | |
1192 | 1 | assertFalse( |
1193 | MappingUtils.rangeContains(new int[] | |
1194 | { 1, 10 }, new int[] { 1, 11 })); | |
1195 | 1 | assertFalse( |
1196 | MappingUtils.rangeContains(new int[] | |
1197 | { 1, 10 }, new int[] { 11, 12 })); | |
1198 | ||
1199 | /* | |
1200 | * forward range, reverse query | |
1201 | */ | |
1202 | 1 | assertTrue( |
1203 | MappingUtils.rangeContains(new int[] | |
1204 | { 1, 10 }, new int[] { 10, 1 })); | |
1205 | 1 | assertTrue( |
1206 | MappingUtils.rangeContains(new int[] | |
1207 | { 1, 10 }, new int[] { 9, 1 })); | |
1208 | 1 | assertTrue( |
1209 | MappingUtils.rangeContains(new int[] | |
1210 | { 1, 10 }, new int[] { 10, 2 })); | |
1211 | 1 | assertTrue( |
1212 | MappingUtils.rangeContains(new int[] | |
1213 | { 1, 10 }, new int[] { 5, 5 })); | |
1214 | 1 | assertFalse( |
1215 | MappingUtils.rangeContains(new int[] | |
1216 | { 1, 10 }, new int[] { 11, 1 })); | |
1217 | 1 | assertFalse( |
1218 | MappingUtils.rangeContains(new int[] | |
1219 | { 1, 10 }, new int[] { 10, 0 })); | |
1220 | ||
1221 | /* | |
1222 | * reverse range, forward query | |
1223 | */ | |
1224 | 1 | assertTrue( |
1225 | MappingUtils.rangeContains(new int[] | |
1226 | { 10, 1 }, new int[] { 1, 10 })); | |
1227 | 1 | assertTrue( |
1228 | MappingUtils.rangeContains(new int[] | |
1229 | { 10, 1 }, new int[] { 1, 9 })); | |
1230 | 1 | assertTrue( |
1231 | MappingUtils.rangeContains(new int[] | |
1232 | { 10, 1 }, new int[] { 2, 10 })); | |
1233 | 1 | assertTrue( |
1234 | MappingUtils.rangeContains(new int[] | |
1235 | { 10, 1 }, new int[] { 6, 6 })); | |
1236 | 1 | assertFalse( |
1237 | MappingUtils.rangeContains(new int[] | |
1238 | { 10, 1 }, new int[] { 6, 11 })); | |
1239 | 1 | assertFalse( |
1240 | MappingUtils.rangeContains(new int[] | |
1241 | { 10, 1 }, new int[] { 11, 20 })); | |
1242 | 1 | assertFalse( |
1243 | MappingUtils.rangeContains(new int[] | |
1244 | { 10, 1 }, new int[] { -3, -2 })); | |
1245 | ||
1246 | /* | |
1247 | * both reverse | |
1248 | */ | |
1249 | 1 | assertTrue( |
1250 | MappingUtils.rangeContains(new int[] | |
1251 | { 10, 1 }, new int[] { 10, 1 })); | |
1252 | 1 | assertTrue( |
1253 | MappingUtils.rangeContains(new int[] | |
1254 | { 10, 1 }, new int[] { 9, 1 })); | |
1255 | 1 | assertTrue( |
1256 | MappingUtils.rangeContains(new int[] | |
1257 | { 10, 1 }, new int[] { 10, 2 })); | |
1258 | 1 | assertTrue( |
1259 | MappingUtils.rangeContains(new int[] | |
1260 | { 10, 1 }, new int[] { 3, 3 })); | |
1261 | 1 | assertFalse( |
1262 | MappingUtils.rangeContains(new int[] | |
1263 | { 10, 1 }, new int[] { 11, 1 })); | |
1264 | 1 | assertFalse( |
1265 | MappingUtils.rangeContains(new int[] | |
1266 | { 10, 1 }, new int[] { 10, 0 })); | |
1267 | 1 | assertFalse( |
1268 | MappingUtils.rangeContains(new int[] | |
1269 | { 10, 1 }, new int[] { 12, 11 })); | |
1270 | 1 | assertFalse( |
1271 | MappingUtils.rangeContains(new int[] | |
1272 | { 10, 1 }, new int[] { -5, -8 })); | |
1273 | ||
1274 | /* | |
1275 | * bad arguments | |
1276 | */ | |
1277 | 1 | assertFalse( |
1278 | MappingUtils.rangeContains(new int[] | |
1279 | { 1, 10, 12 }, new int[] { 1, 10 })); | |
1280 | 1 | assertFalse( |
1281 | MappingUtils.rangeContains(new int[] | |
1282 | { 1, 10 }, new int[] { 1 })); | |
1283 | 1 | assertFalse(MappingUtils.rangeContains(new int[] { 1, 10 }, null)); |
1284 | 1 | assertFalse(MappingUtils.rangeContains(null, new int[] { 1, 10 })); |
1285 | } | |
1286 | ||
1287 | 1 | @Test(groups = "Functional") |
1288 | public void testRemoveEndPositions() | |
1289 | { | |
1290 | 1 | List<int[]> ranges = new ArrayList<>(); |
1291 | ||
1292 | /* | |
1293 | * case 1: truncate last range | |
1294 | */ | |
1295 | 1 | ranges.add(new int[] { 1, 10 }); |
1296 | 1 | ranges.add(new int[] { 20, 30 }); |
1297 | 1 | MappingUtils.removeEndPositions(5, ranges); |
1298 | 1 | assertEquals(2, ranges.size()); |
1299 | 1 | assertEquals(25, ranges.get(1)[1]); |
1300 | ||
1301 | /* | |
1302 | * case 2: remove last range | |
1303 | */ | |
1304 | 1 | ranges.clear(); |
1305 | 1 | ranges.add(new int[] { 1, 10 }); |
1306 | 1 | ranges.add(new int[] { 20, 22 }); |
1307 | 1 | MappingUtils.removeEndPositions(3, ranges); |
1308 | 1 | assertEquals(1, ranges.size()); |
1309 | 1 | assertEquals(10, ranges.get(0)[1]); |
1310 | ||
1311 | /* | |
1312 | * case 3: truncate penultimate range | |
1313 | */ | |
1314 | 1 | ranges.clear(); |
1315 | 1 | ranges.add(new int[] { 1, 10 }); |
1316 | 1 | ranges.add(new int[] { 20, 21 }); |
1317 | 1 | MappingUtils.removeEndPositions(3, ranges); |
1318 | 1 | assertEquals(1, ranges.size()); |
1319 | 1 | assertEquals(9, ranges.get(0)[1]); |
1320 | ||
1321 | /* | |
1322 | * case 4: remove last two ranges | |
1323 | */ | |
1324 | 1 | ranges.clear(); |
1325 | 1 | ranges.add(new int[] { 1, 10 }); |
1326 | 1 | ranges.add(new int[] { 20, 20 }); |
1327 | 1 | ranges.add(new int[] { 30, 30 }); |
1328 | 1 | MappingUtils.removeEndPositions(3, ranges); |
1329 | 1 | assertEquals(1, ranges.size()); |
1330 | 1 | assertEquals(9, ranges.get(0)[1]); |
1331 | } | |
1332 | ||
1333 | 1 | @Test(groups = "Functional") |
1334 | public void testFindOverlap() | |
1335 | { | |
1336 | 1 | List<int[]> ranges = new ArrayList<>(); |
1337 | 1 | ranges.add(new int[] { 4, 8 }); |
1338 | 1 | ranges.add(new int[] { 10, 12 }); |
1339 | 1 | ranges.add(new int[] { 16, 19 }); |
1340 | ||
1341 | 1 | int[] overlap = MappingUtils.findOverlap(ranges, 5, 13); |
1342 | 1 | assertArrayEquals(overlap, new int[] { 5, 12 }); |
1343 | 1 | overlap = MappingUtils.findOverlap(ranges, -100, 100); |
1344 | 1 | assertArrayEquals(overlap, new int[] { 4, 19 }); |
1345 | 1 | overlap = MappingUtils.findOverlap(ranges, 7, 17); |
1346 | 1 | assertArrayEquals(overlap, new int[] { 7, 17 }); |
1347 | 1 | overlap = MappingUtils.findOverlap(ranges, 13, 15); |
1348 | 1 | assertNull(overlap); |
1349 | } | |
1350 | ||
1351 | /** | |
1352 | * Test mapping a sequence group where sequences in and outside the group | |
1353 | * share a dataset sequence (e.g. alternative CDS for the same gene) | |
1354 | * <p> | |
1355 | * This scenario doesn't arise after JAL-3763 changes, but test left as still | |
1356 | * valid | |
1357 | * | |
1358 | * @throws IOException | |
1359 | */ | |
1360 | 1 | @Test(groups = { "Functional" }) |
1361 | public void testMapSequenceGroup_sharedDataset() throws IOException | |
1362 | { | |
1363 | /* | |
1364 | * Set up dna and protein Seq1/2/3 with mappings (held on the protein | |
1365 | * viewport). CDS sequences share the same 'gene' dataset sequence. | |
1366 | */ | |
1367 | 1 | SequenceI dna = new Sequence("dna", "aaatttgggcccaaatttgggccc"); |
1368 | 1 | SequenceI cds1 = new Sequence("cds1/1-6", "aaattt"); |
1369 | 1 | SequenceI cds2 = new Sequence("cds1/4-9", "tttggg"); |
1370 | 1 | SequenceI cds3 = new Sequence("cds1/19-24", "gggccc"); |
1371 | ||
1372 | 1 | cds1.setDatasetSequence(dna); |
1373 | 1 | cds2.setDatasetSequence(dna); |
1374 | 1 | cds3.setDatasetSequence(dna); |
1375 | ||
1376 | 1 | SequenceI pep1 = new Sequence("pep1", "KF"); |
1377 | 1 | SequenceI pep2 = new Sequence("pep2", "FG"); |
1378 | 1 | SequenceI pep3 = new Sequence("pep3", "GP"); |
1379 | 1 | pep1.createDatasetSequence(); |
1380 | 1 | pep2.createDatasetSequence(); |
1381 | 1 | pep3.createDatasetSequence(); |
1382 | ||
1383 | /* | |
1384 | * add mappings from coding positions of dna to respective peptides | |
1385 | */ | |
1386 | 1 | AlignedCodonFrame acf = new AlignedCodonFrame(); |
1387 | 1 | acf.addMap(dna, pep1, |
1388 | new MapList(new int[] | |
1389 | { 1, 6 }, new int[] { 1, 2 }, 3, 1)); | |
1390 | 1 | acf.addMap(dna, pep2, |
1391 | new MapList(new int[] | |
1392 | { 4, 9 }, new int[] { 1, 2 }, 3, 1)); | |
1393 | 1 | acf.addMap(dna, pep3, |
1394 | new MapList(new int[] | |
1395 | { 19, 24 }, new int[] { 1, 2 }, 3, 1)); | |
1396 | ||
1397 | 1 | List<AlignedCodonFrame> acfList = Arrays |
1398 | .asList(new AlignedCodonFrame[] | |
1399 | { acf }); | |
1400 | ||
1401 | 1 | AlignmentI cdna = new Alignment(new SequenceI[] { cds1, cds2, cds3 }); |
1402 | 1 | AlignmentI protein = new Alignment( |
1403 | new SequenceI[] | |
1404 | { pep1, pep2, pep3 }); | |
1405 | 1 | AlignViewportI cdnaView = new AlignViewport(cdna); |
1406 | 1 | AlignViewportI peptideView = new AlignViewport(protein); |
1407 | 1 | protein.setCodonFrames(acfList); |
1408 | ||
1409 | /* | |
1410 | * Select pep1 and pep3 in the protein alignment | |
1411 | */ | |
1412 | 1 | SequenceGroup sg = new SequenceGroup(); |
1413 | 1 | sg.setColourText(true); |
1414 | 1 | sg.setIdColour(Color.GREEN); |
1415 | 1 | sg.setOutlineColour(Color.LIGHT_GRAY); |
1416 | 1 | sg.addSequence(pep1, false); |
1417 | 1 | sg.addSequence(pep3, false); |
1418 | 1 | sg.setEndRes(protein.getWidth() - 1); |
1419 | ||
1420 | /* | |
1421 | * Verify the mapped sequence group in dna is cds1 and cds3 | |
1422 | */ | |
1423 | 1 | SequenceGroup mappedGroup = MappingUtils.mapSequenceGroup(sg, |
1424 | peptideView, cdnaView); | |
1425 | 1 | assertTrue(mappedGroup.getColourText()); |
1426 | 1 | assertSame(sg.getIdColour(), mappedGroup.getIdColour()); |
1427 | 1 | assertSame(sg.getOutlineColour(), mappedGroup.getOutlineColour()); |
1428 | 1 | assertEquals(2, mappedGroup.getSequences().size()); |
1429 | 1 | assertSame(cds1, mappedGroup.getSequences().get(0)); |
1430 | 1 | assertSame(cds3, mappedGroup.getSequences().get(1)); |
1431 | // columns 1-6 selected (0-5 base zero) | |
1432 | 1 | assertEquals(0, mappedGroup.getStartRes()); |
1433 | 1 | assertEquals(5, mappedGroup.getEndRes()); |
1434 | ||
1435 | /* | |
1436 | * Select mapping sequence group from dna to protein | |
1437 | */ | |
1438 | 1 | sg.clear(); |
1439 | 1 | sg.addSequence(cds2, false); |
1440 | 1 | sg.addSequence(cds1, false); |
1441 | 1 | sg.setStartRes(0); |
1442 | 1 | sg.setEndRes(cdna.getWidth() - 1); |
1443 | 1 | mappedGroup = MappingUtils.mapSequenceGroup(sg, cdnaView, peptideView); |
1444 | 1 | assertTrue(mappedGroup.getColourText()); |
1445 | 1 | assertSame(sg.getIdColour(), mappedGroup.getIdColour()); |
1446 | 1 | assertSame(sg.getOutlineColour(), mappedGroup.getOutlineColour()); |
1447 | 1 | assertEquals(2, mappedGroup.getSequences().size()); |
1448 | 1 | assertSame(protein.getSequenceAt(1), mappedGroup.getSequences().get(0)); |
1449 | 1 | assertSame(protein.getSequenceAt(0), mappedGroup.getSequences().get(1)); |
1450 | 1 | assertEquals(0, mappedGroup.getStartRes()); |
1451 | 1 | assertEquals(1, mappedGroup.getEndRes()); // two columns |
1452 | } | |
1453 | } |