2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
23 import static org.testng.AssertJUnit.assertEquals;
24 import static org.testng.AssertJUnit.assertFalse;
25 import static org.testng.AssertJUnit.assertSame;
26 import static org.testng.AssertJUnit.assertTrue;
27 import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
29 import jalview.api.AlignViewportI;
30 import jalview.commands.EditCommand;
31 import jalview.commands.EditCommand.Action;
32 import jalview.commands.EditCommand.Edit;
33 import jalview.datamodel.AlignedCodonFrame;
34 import jalview.datamodel.Alignment;
35 import jalview.datamodel.AlignmentI;
36 import jalview.datamodel.ColumnSelection;
37 import jalview.datamodel.SearchResults;
38 import jalview.datamodel.SearchResults.Match;
39 import jalview.datamodel.Sequence;
40 import jalview.datamodel.SequenceGroup;
41 import jalview.datamodel.SequenceI;
42 import jalview.gui.AlignViewport;
43 import jalview.io.AppletFormatAdapter;
44 import jalview.io.FormatAdapter;
46 import java.awt.Color;
47 import java.io.IOException;
48 import java.util.ArrayList;
49 import java.util.Arrays;
50 import java.util.List;
52 import org.testng.annotations.Test;
54 public class MappingUtilsTest
56 private AlignViewportI dnaView;
58 private AlignViewportI proteinView;
61 * Simple test of mapping with no intron involved.
63 @Test(groups = { "Functional" })
64 public void testBuildSearchResults()
66 final Sequence seq1 = new Sequence("Seq1/5-10", "C-G-TA-GC");
67 seq1.createDatasetSequence();
69 final Sequence aseq1 = new Sequence("Seq1/12-13", "-P-R");
70 aseq1.createDatasetSequence();
73 * Map dna bases 5-10 to protein residues 12-13
75 AlignedCodonFrame acf = new AlignedCodonFrame();
76 MapList map = new MapList(new int[] { 5, 10 }, new int[] { 12, 13 }, 3,
78 acf.addMap(seq1.getDatasetSequence(), aseq1.getDatasetSequence(), map);
79 List<AlignedCodonFrame> acfList = Arrays.asList(new AlignedCodonFrame[]
83 * Check protein residue 12 maps to codon 5-7, 13 to codon 8-10
85 SearchResults sr = MappingUtils.buildSearchResults(aseq1, 12, acfList);
86 assertEquals(1, sr.getResults().size());
87 Match m = sr.getResults().get(0);
88 assertEquals(seq1.getDatasetSequence(), m.getSequence());
89 assertEquals(5, m.getStart());
90 assertEquals(7, m.getEnd());
91 sr = MappingUtils.buildSearchResults(aseq1, 13, acfList);
92 assertEquals(1, sr.getResults().size());
93 m = sr.getResults().get(0);
94 assertEquals(seq1.getDatasetSequence(), m.getSequence());
95 assertEquals(8, m.getStart());
96 assertEquals(10, m.getEnd());
99 * Check inverse mappings, from codons 5-7, 8-10 to protein 12, 13
101 for (int i = 5; i < 11; i++)
103 sr = MappingUtils.buildSearchResults(seq1, i, acfList);
104 assertEquals(1, sr.getResults().size());
105 m = sr.getResults().get(0);
106 assertEquals(aseq1.getDatasetSequence(), m.getSequence());
107 int residue = i > 7 ? 13 : 12;
108 assertEquals(residue, m.getStart());
109 assertEquals(residue, m.getEnd());
114 * Simple test of mapping with introns involved.
116 @Test(groups = { "Functional" })
117 public void testBuildSearchResults_withIntron()
119 final Sequence seq1 = new Sequence("Seq1/5-17", "c-G-tAGa-GcAgCtt");
120 seq1.createDatasetSequence();
122 final Sequence aseq1 = new Sequence("Seq1/8-9", "-E-D");
123 aseq1.createDatasetSequence();
126 * Map dna bases [6, 8, 9], [11, 13, 115] to protein residues 8 and 9
128 AlignedCodonFrame acf = new AlignedCodonFrame();
129 MapList map = new MapList(new int[] { 6, 6, 8, 9, 11, 11, 13, 13, 15,
130 15 }, new int[] { 8, 9 }, 3, 1);
131 acf.addMap(seq1.getDatasetSequence(), aseq1.getDatasetSequence(), map);
132 List<AlignedCodonFrame> acfList = Arrays.asList(new AlignedCodonFrame[]
136 * Check protein residue 8 maps to [6, 8, 9]
138 SearchResults sr = MappingUtils.buildSearchResults(aseq1, 8, acfList);
139 assertEquals(2, sr.getResults().size());
140 Match m = sr.getResults().get(0);
141 assertEquals(seq1.getDatasetSequence(), m.getSequence());
142 assertEquals(6, m.getStart());
143 assertEquals(6, m.getEnd());
144 m = sr.getResults().get(1);
145 assertEquals(seq1.getDatasetSequence(), m.getSequence());
146 assertEquals(8, m.getStart());
147 assertEquals(9, m.getEnd());
150 * Check protein residue 9 maps to [11, 13, 15]
152 sr = MappingUtils.buildSearchResults(aseq1, 9, acfList);
153 assertEquals(3, sr.getResults().size());
154 m = sr.getResults().get(0);
155 assertEquals(seq1.getDatasetSequence(), m.getSequence());
156 assertEquals(11, m.getStart());
157 assertEquals(11, m.getEnd());
158 m = sr.getResults().get(1);
159 assertEquals(seq1.getDatasetSequence(), m.getSequence());
160 assertEquals(13, m.getStart());
161 assertEquals(13, m.getEnd());
162 m = sr.getResults().get(2);
163 assertEquals(seq1.getDatasetSequence(), m.getSequence());
164 assertEquals(15, m.getStart());
165 assertEquals(15, m.getEnd());
168 * Check inverse mappings, from codons to protein
170 for (int i = 5; i < 18; i++)
172 sr = MappingUtils.buildSearchResults(seq1, i, acfList);
173 int residue = (i == 6 || i == 8 || i == 9) ? 8 : (i == 11 || i == 13
177 assertEquals(0, sr.getResults().size());
180 assertEquals(1, sr.getResults().size());
181 m = sr.getResults().get(0);
182 assertEquals(aseq1.getDatasetSequence(), m.getSequence());
183 assertEquals(residue, m.getStart());
184 assertEquals(residue, m.getEnd());
189 * Test mapping a sequence group made of entire sequences.
191 * @throws IOException
193 @Test(groups = { "Functional" })
194 public void testMapSequenceGroup_sequences() throws IOException
197 * Set up dna and protein Seq1/2/3 with mappings (held on the protein
200 AlignmentI cdna = loadAlignment(">Seq1\nACG\n>Seq2\nTGA\n>Seq3\nTAC\n",
202 cdna.setDataset(null);
203 AlignmentI protein = loadAlignment(">Seq1\nK\n>Seq2\nL\n>Seq3\nQ\n",
205 protein.setDataset(null);
206 AlignedCodonFrame acf = new AlignedCodonFrame();
207 MapList map = new MapList(new int[] { 1, 3 }, new int[] { 1, 1 }, 3, 1);
208 for (int seq = 0; seq < 3; seq++)
210 acf.addMap(cdna.getSequenceAt(seq).getDatasetSequence(), protein
211 .getSequenceAt(seq).getDatasetSequence(), map);
213 List<AlignedCodonFrame> acfList = Arrays.asList(new AlignedCodonFrame[]
216 AlignViewportI dnaView = new AlignViewport(cdna);
217 AlignViewportI proteinView = new AlignViewport(protein);
218 protein.setCodonFrames(acfList);
221 * Select Seq1 and Seq3 in the protein (startRes=endRes=0)
223 SequenceGroup sg = new SequenceGroup();
224 sg.setColourText(true);
225 sg.setIdColour(Color.GREEN);
226 sg.setOutlineColour(Color.LIGHT_GRAY);
227 sg.addSequence(protein.getSequenceAt(0), false);
228 sg.addSequence(protein.getSequenceAt(2), false);
231 * Verify the mapped sequence group in dna
233 SequenceGroup mappedGroup = MappingUtils.mapSequenceGroup(sg,
234 proteinView, dnaView);
235 assertTrue(mappedGroup.getColourText());
236 assertSame(sg.getIdColour(), mappedGroup.getIdColour());
237 assertSame(sg.getOutlineColour(), mappedGroup.getOutlineColour());
238 assertEquals(2, mappedGroup.getSequences().size());
239 assertSame(cdna.getSequenceAt(0), mappedGroup.getSequences().get(0));
240 assertSame(cdna.getSequenceAt(2), mappedGroup.getSequences().get(1));
241 assertEquals(0, mappedGroup.getStartRes());
242 assertEquals(2, mappedGroup.getEndRes());
245 * Verify mapping sequence group from dna to protein
248 sg.addSequence(cdna.getSequenceAt(1), false);
249 sg.addSequence(cdna.getSequenceAt(0), false);
252 mappedGroup = MappingUtils.mapSequenceGroup(sg, dnaView, proteinView);
253 assertTrue(mappedGroup.getColourText());
254 assertSame(sg.getIdColour(), mappedGroup.getIdColour());
255 assertSame(sg.getOutlineColour(), mappedGroup.getOutlineColour());
256 assertEquals(2, mappedGroup.getSequences().size());
257 assertSame(protein.getSequenceAt(1), mappedGroup.getSequences().get(0));
258 assertSame(protein.getSequenceAt(0), mappedGroup.getSequences().get(1));
259 assertEquals(0, mappedGroup.getStartRes());
260 assertEquals(0, mappedGroup.getEndRes());
264 * Helper method to load an alignment and ensure dataset sequences are set up.
270 * @throws IOException
272 protected AlignmentI loadAlignment(final String data, String format)
275 AlignmentI a = new FormatAdapter().readFile(data,
276 AppletFormatAdapter.PASTE, format);
282 * Test mapping a column selection in protein to its dna equivalent
284 * @throws IOException
286 @Test(groups = { "Functional" })
287 public void testMapColumnSelection_proteinToDna() throws IOException
289 setupMappedAlignments();
291 ColumnSelection colsel = new ColumnSelection();
294 * Column 0 in protein picks up Seq2/L, Seq3/G which map to cols 0-4 and 0-3
295 * in dna respectively, overall 0-4
297 colsel.addElement(0);
298 ColumnSelection cs = MappingUtils.mapColumnSelection(colsel,
299 proteinView, dnaView);
300 assertEquals("[0, 1, 2, 3, 4]", cs.getSelected().toString());
303 * Column 1 in protein picks up Seq1/K which maps to cols 0-3 in dna
306 colsel.addElement(1);
307 cs = MappingUtils.mapColumnSelection(colsel, proteinView, dnaView);
308 assertEquals("[0, 1, 2, 3]", cs.getSelected().toString());
311 * Column 2 in protein picks up gaps only - no mapping
314 colsel.addElement(2);
315 cs = MappingUtils.mapColumnSelection(colsel, proteinView, dnaView);
316 assertEquals("[]", cs.getSelected().toString());
319 * Column 3 in protein picks up Seq1/P, Seq2/Q, Seq3/S which map to columns
320 * 6-9, 6-10, 5-8 respectively, overall to 5-10
323 colsel.addElement(3);
324 cs = MappingUtils.mapColumnSelection(colsel, proteinView, dnaView);
325 assertEquals("[5, 6, 7, 8, 9, 10]", cs.getSelected().toString());
328 * Combine selection of columns 1 and 3 to get a discontiguous mapped
332 colsel.addElement(1);
333 colsel.addElement(3);
334 cs = MappingUtils.mapColumnSelection(colsel, proteinView, dnaView);
335 assertEquals("[0, 1, 2, 3, 5, 6, 7, 8, 9, 10]", cs.getSelected()
340 * Set up mappings for tests from 3 dna to 3 protein sequences. Sequences have
341 * offset start positions for a more general test case.
343 * @throws IOException
345 protected void setupMappedAlignments() throws IOException
348 * Map (upper-case = coding):
349 * Seq1/10-18 AC-GctGtC-T to Seq1/40 -K-P
350 * Seq2/20-27 Tc-GA-G-T-T to Seq2/20-27 L--Q
351 * Seq3/30-38 TtTT-AaCGg- to Seq3/60-61\nG--S
353 AlignmentI cdna = loadAlignment(">Seq1/10-18\nAC-GctGtC-T\n"
354 + ">Seq2/20-27\nTc-GA-G-T-Tc\n" + ">Seq3/30-38\nTtTT-AaCGg-\n",
356 cdna.setDataset(null);
357 AlignmentI protein = loadAlignment(
358 ">Seq1/40-41\n-K-P\n>Seq2/50-51\nL--Q\n>Seq3/60-61\nG--S\n",
360 protein.setDataset(null);
362 // map first dna to first protein seq
363 AlignedCodonFrame acf = new AlignedCodonFrame();
364 MapList map = new MapList(new int[] { 10, 12, 15, 15, 17, 18 },
365 new int[] { 40, 41 }, 3, 1);
366 acf.addMap(cdna.getSequenceAt(0).getDatasetSequence(), protein
367 .getSequenceAt(0).getDatasetSequence(), map);
369 // map second dna to second protein seq
370 map = new MapList(new int[] { 20, 20, 22, 23, 24, 26 }, new int[] { 50,
372 acf.addMap(cdna.getSequenceAt(1).getDatasetSequence(), protein
373 .getSequenceAt(1).getDatasetSequence(), map);
375 // map third dna to third protein seq
376 map = new MapList(new int[] { 30, 30, 32, 34, 36, 37 }, new int[] { 60,
378 acf.addMap(cdna.getSequenceAt(2).getDatasetSequence(), protein
379 .getSequenceAt(2).getDatasetSequence(), map);
380 List<AlignedCodonFrame> acfList = Arrays.asList(new AlignedCodonFrame[]
383 dnaView = new AlignViewport(cdna);
384 proteinView = new AlignViewport(protein);
385 protein.setCodonFrames(acfList);
389 * Test mapping a column selection in dna to its protein equivalent
391 * @throws IOException
393 @Test(groups = { "Functional" })
394 public void testMapColumnSelection_dnaToProtein() throws IOException
396 setupMappedAlignments();
398 ColumnSelection colsel = new ColumnSelection();
401 * Column 0 in dna picks up first bases which map to residue 1, columns 0-1
404 colsel.addElement(0);
405 ColumnSelection cs = MappingUtils.mapColumnSelection(colsel, dnaView,
407 assertEquals("[0, 1]", cs.getSelected().toString());
410 * Columns 3-5 in dna map to the first residues in protein Seq1, Seq2, and
411 * the first two in Seq3. Overall to columns 0, 1, 3 (col2 is all gaps).
413 colsel.addElement(3);
414 colsel.addElement(4);
415 colsel.addElement(5);
416 cs = MappingUtils.mapColumnSelection(colsel, dnaView, proteinView);
417 assertEquals("[0, 1, 3]", cs.getSelected().toString());
420 @Test(groups = { "Functional" })
421 public void testMapColumnSelection_null() throws IOException
423 setupMappedAlignments();
424 ColumnSelection cs = MappingUtils.mapColumnSelection(null, dnaView,
426 assertTrue("mapped selection not empty", cs.getSelected().isEmpty());
430 * Tests for the method that converts a series of [start, end] ranges to
433 @Test(groups = { "Functional" })
434 public void testFlattenRanges()
436 assertEquals("[1, 2, 3, 4]",
437 Arrays.toString(MappingUtils.flattenRanges(new int[] { 1, 4 })));
440 Arrays.toString(MappingUtils.flattenRanges(new int[] { 1, 2, 3,
444 Arrays.toString(MappingUtils.flattenRanges(new int[] { 1, 1, 2,
447 "[1, 2, 3, 4, 7, 8, 9, 12]",
448 Arrays.toString(MappingUtils.flattenRanges(new int[] { 1, 4, 7,
450 // trailing unpaired start position is ignored:
452 "[1, 2, 3, 4, 7, 8, 9, 12]",
453 Arrays.toString(MappingUtils.flattenRanges(new int[] { 1, 4, 7,
458 * Test mapping a sequence group made of entire columns.
460 * @throws IOException
462 @Test(groups = { "Functional" })
463 public void testMapSequenceGroup_columns() throws IOException
466 * Set up dna and protein Seq1/2/3 with mappings (held on the protein
469 AlignmentI cdna = loadAlignment(
470 ">Seq1\nACGGCA\n>Seq2\nTGACAG\n>Seq3\nTACGTA\n", "FASTA");
471 cdna.setDataset(null);
472 AlignmentI protein = loadAlignment(">Seq1\nKA\n>Seq2\nLQ\n>Seq3\nQV\n",
474 protein.setDataset(null);
475 AlignedCodonFrame acf = new AlignedCodonFrame();
476 MapList map = new MapList(new int[] { 1, 6 }, new int[] { 1, 2 }, 3, 1);
477 for (int seq = 0; seq < 3; seq++)
479 acf.addMap(cdna.getSequenceAt(seq).getDatasetSequence(), protein
480 .getSequenceAt(seq).getDatasetSequence(), map);
482 List<AlignedCodonFrame> acfList = Arrays.asList(new AlignedCodonFrame[]
485 AlignViewportI dnaView = new AlignViewport(cdna);
486 AlignViewportI proteinView = new AlignViewport(protein);
487 protein.setCodonFrames(acfList);
490 * Select all sequences, column 2 in the protein
492 SequenceGroup sg = new SequenceGroup();
493 sg.setColourText(true);
494 sg.setIdColour(Color.GREEN);
495 sg.setOutlineColour(Color.LIGHT_GRAY);
496 sg.addSequence(protein.getSequenceAt(0), false);
497 sg.addSequence(protein.getSequenceAt(1), false);
498 sg.addSequence(protein.getSequenceAt(2), false);
503 * Verify the mapped sequence group in dna
505 SequenceGroup mappedGroup = MappingUtils.mapSequenceGroup(sg,
506 proteinView, dnaView);
507 assertTrue(mappedGroup.getColourText());
508 assertSame(sg.getIdColour(), mappedGroup.getIdColour());
509 assertSame(sg.getOutlineColour(), mappedGroup.getOutlineColour());
510 assertEquals(3, mappedGroup.getSequences().size());
511 assertSame(cdna.getSequenceAt(0), mappedGroup.getSequences().get(0));
512 assertSame(cdna.getSequenceAt(1), mappedGroup.getSequences().get(1));
513 assertSame(cdna.getSequenceAt(2), mappedGroup.getSequences().get(2));
514 assertEquals(3, mappedGroup.getStartRes());
515 assertEquals(5, mappedGroup.getEndRes());
518 * Verify mapping sequence group from dna to protein
521 sg.addSequence(cdna.getSequenceAt(0), false);
522 sg.addSequence(cdna.getSequenceAt(1), false);
523 sg.addSequence(cdna.getSequenceAt(2), false);
524 // select columns 2 and 3 in DNA which span protein columns 0 and 1
527 mappedGroup = MappingUtils.mapSequenceGroup(sg, dnaView, proteinView);
528 assertTrue(mappedGroup.getColourText());
529 assertSame(sg.getIdColour(), mappedGroup.getIdColour());
530 assertSame(sg.getOutlineColour(), mappedGroup.getOutlineColour());
531 assertEquals(3, mappedGroup.getSequences().size());
532 assertSame(protein.getSequenceAt(0), mappedGroup.getSequences().get(0));
533 assertSame(protein.getSequenceAt(1), mappedGroup.getSequences().get(1));
534 assertSame(protein.getSequenceAt(2), mappedGroup.getSequences().get(2));
535 assertEquals(0, mappedGroup.getStartRes());
536 assertEquals(1, mappedGroup.getEndRes());
540 * Test mapping a sequence group made of a sequences/columns region.
542 * @throws IOException
544 @Test(groups = { "Functional" })
545 public void testMapSequenceGroup_region() throws IOException
548 * Set up gapped dna and protein Seq1/2/3 with mappings (held on the protein
551 AlignmentI cdna = loadAlignment(
552 ">Seq1\nA-CG-GC--AT-CA\n>Seq2\n-TG-AC-AG-T-AT\n>Seq3\n-T--ACG-TAAT-G\n",
554 cdna.setDataset(null);
555 AlignmentI protein = loadAlignment(
556 ">Seq1\n-KA-S\n>Seq2\n--L-QY\n>Seq3\nQ-V-M\n", "FASTA");
557 protein.setDataset(null);
558 AlignedCodonFrame acf = new AlignedCodonFrame();
559 MapList map = new MapList(new int[] { 1, 9 }, new int[] { 1, 3 }, 3, 1);
560 for (int seq = 0; seq < 3; seq++)
562 acf.addMap(cdna.getSequenceAt(seq).getDatasetSequence(), protein
563 .getSequenceAt(seq).getDatasetSequence(), map);
565 List<AlignedCodonFrame> acfList = Arrays.asList(new AlignedCodonFrame[]
568 AlignViewportI dnaView = new AlignViewport(cdna);
569 AlignViewportI proteinView = new AlignViewport(protein);
570 protein.setCodonFrames(acfList);
573 * Select Seq1 and Seq2 in the protein, column 1 (K/-). Expect mapped
574 * sequence group to cover Seq1, columns 0-3 (ACG). Because the selection
575 * only includes a gap in Seq2 there is no mappable selection region in the
578 SequenceGroup sg = new SequenceGroup();
579 sg.setColourText(true);
580 sg.setIdColour(Color.GREEN);
581 sg.setOutlineColour(Color.LIGHT_GRAY);
582 sg.addSequence(protein.getSequenceAt(0), false);
583 sg.addSequence(protein.getSequenceAt(1), false);
588 * Verify the mapped sequence group in dna
590 SequenceGroup mappedGroup = MappingUtils.mapSequenceGroup(sg,
591 proteinView, dnaView);
592 assertTrue(mappedGroup.getColourText());
593 assertSame(sg.getIdColour(), mappedGroup.getIdColour());
594 assertSame(sg.getOutlineColour(), mappedGroup.getOutlineColour());
595 assertEquals(1, mappedGroup.getSequences().size());
596 assertSame(cdna.getSequenceAt(0), mappedGroup.getSequences().get(0));
597 // Seq2 in protein has a gap in column 1 - ignored
598 // Seq1 has K which should map to columns 0-3 in Seq1
599 assertEquals(0, mappedGroup.getStartRes());
600 assertEquals(3, mappedGroup.getEndRes());
603 * Now select cols 2-4 in protein. These cover Seq1:AS Seq2:LQ Seq3:VM which
604 * extend over DNA columns 3-12, 1-7, 6-13 respectively, or 1-13 overall.
608 mappedGroup = MappingUtils.mapSequenceGroup(sg, proteinView, dnaView);
609 assertEquals(1, mappedGroup.getStartRes());
610 assertEquals(13, mappedGroup.getEndRes());
613 * Verify mapping sequence group from dna to protein
616 sg.addSequence(cdna.getSequenceAt(0), false);
618 // select columns 4,5 - includes Seq1:codon2 (A) only
621 mappedGroup = MappingUtils.mapSequenceGroup(sg, dnaView, proteinView);
622 assertEquals(2, mappedGroup.getStartRes());
623 assertEquals(2, mappedGroup.getEndRes());
625 // add Seq2 to dna selection cols 4-5 include codons 1 and 2 (LQ)
626 sg.addSequence(cdna.getSequenceAt(1), false);
627 mappedGroup = MappingUtils.mapSequenceGroup(sg, dnaView, proteinView);
628 assertEquals(2, mappedGroup.getStartRes());
629 assertEquals(4, mappedGroup.getEndRes());
631 // add Seq3 to dna selection cols 4-5 include codon 1 (Q)
632 sg.addSequence(cdna.getSequenceAt(2), false);
633 mappedGroup = MappingUtils.mapSequenceGroup(sg, dnaView, proteinView);
634 assertEquals(0, mappedGroup.getStartRes());
635 assertEquals(4, mappedGroup.getEndRes());
638 @Test(groups = { "Functional" })
639 public void testFindMappingsForSequence()
641 SequenceI seq1 = new Sequence("Seq1", "ABC");
642 SequenceI seq2 = new Sequence("Seq2", "ABC");
643 SequenceI seq3 = new Sequence("Seq3", "ABC");
644 SequenceI seq4 = new Sequence("Seq4", "ABC");
645 seq1.createDatasetSequence();
646 seq2.createDatasetSequence();
647 seq3.createDatasetSequence();
648 seq4.createDatasetSequence();
651 * Create mappings from seq1 to seq2, seq2 to seq1, seq3 to seq1
653 AlignedCodonFrame acf1 = new AlignedCodonFrame();
654 MapList map = new MapList(new int[] { 1, 3 }, new int[] { 1, 3 }, 1, 1);
655 acf1.addMap(seq1.getDatasetSequence(), seq2.getDatasetSequence(), map);
656 AlignedCodonFrame acf2 = new AlignedCodonFrame();
657 acf2.addMap(seq2.getDatasetSequence(), seq1.getDatasetSequence(), map);
658 AlignedCodonFrame acf3 = new AlignedCodonFrame();
659 acf3.addMap(seq3.getDatasetSequence(), seq1.getDatasetSequence(), map);
661 List<AlignedCodonFrame> mappings = new ArrayList<AlignedCodonFrame>();
667 * Seq1 has three mappings
669 List<AlignedCodonFrame> result = MappingUtils.findMappingsForSequence(
671 assertEquals(3, result.size());
672 assertTrue(result.contains(acf1));
673 assertTrue(result.contains(acf2));
674 assertTrue(result.contains(acf3));
677 * Seq2 has two mappings
679 result = MappingUtils.findMappingsForSequence(seq2, mappings);
680 assertEquals(2, result.size());
681 assertTrue(result.contains(acf1));
682 assertTrue(result.contains(acf2));
685 * Seq3 has one mapping
687 result = MappingUtils.findMappingsForSequence(seq3, mappings);
688 assertEquals(1, result.size());
689 assertTrue(result.contains(acf3));
692 * Seq4 has no mappings
694 result = MappingUtils.findMappingsForSequence(seq4, mappings);
695 assertEquals(0, result.size());
697 result = MappingUtils.findMappingsForSequence(null, mappings);
698 assertEquals(0, result.size());
700 result = MappingUtils.findMappingsForSequence(seq1, null);
701 assertEquals(0, result.size());
703 result = MappingUtils.findMappingsForSequence(null, null);
704 assertEquals(0, result.size());
707 @Test(groups = { "Functional" })
708 public void testMapEditCommand()
710 SequenceI dna = new Sequence("Seq1", "---ACG---GCATCA", 8, 16);
711 SequenceI protein = new Sequence("Seq2", "-T-AS", 5, 7);
712 dna.createDatasetSequence();
713 protein.createDatasetSequence();
714 AlignedCodonFrame acf = new AlignedCodonFrame();
715 MapList map = new MapList(new int[] { 8, 16 }, new int[] { 5, 7 }, 3, 1);
716 acf.addMap(dna.getDatasetSequence(), protein.getDatasetSequence(), map);
717 List<AlignedCodonFrame> mappings = new ArrayList<AlignedCodonFrame>();
720 AlignmentI prot = new Alignment(new SequenceI[] { protein });
721 prot.setCodonFrames(mappings);
722 AlignmentI nuc = new Alignment(new SequenceI[] { dna });
725 * construct and perform the edit command to turn "-T-AS" in to "-T-A--S"
726 * i.e. insert two gaps at column 4
728 EditCommand ec = new EditCommand();
729 final Edit edit = ec.new Edit(Action.INSERT_GAP,
730 new SequenceI[] { protein }, 4, 2, '-');
731 ec.appendEdit(edit, prot, true, null);
734 * the mapped edit command should be to insert 6 gaps before base 4 in the
735 * nucleotide sequence, which corresponds to aligned column 12 in the dna
737 EditCommand mappedEdit = MappingUtils.mapEditCommand(ec, false, nuc,
739 assertEquals(1, mappedEdit.getEdits().size());
740 Edit e = mappedEdit.getEdits().get(0);
741 assertEquals(1, e.getSequences().length);
742 assertEquals(dna, e.getSequences()[0]);
743 assertEquals(12, e.getPosition());
744 assertEquals(6, e.getNumber());
748 * Tests for the method that converts a series of [start, end] ranges to
749 * single positions, where the mapping is to a reverse strand i.e. start is
750 * greater than end point mapped to
752 @Test(groups = { "Functional" })
753 public void testFlattenRanges_reverseStrand()
755 assertEquals("[4, 3, 2, 1]",
756 Arrays.toString(MappingUtils.flattenRanges(new int[] { 4, 1 })));
759 Arrays.toString(MappingUtils.flattenRanges(new int[] { 4, 3, 2,
763 Arrays.toString(MappingUtils.flattenRanges(new int[] { 4, 4, 3,
766 "[12, 9, 8, 7, 4, 3, 2, 1]",
767 Arrays.toString(MappingUtils.flattenRanges(new int[] { 12, 12,
769 // forwards and backwards anyone?
771 "[4, 5, 6, 3, 2, 1]",
772 Arrays.toString(MappingUtils.flattenRanges(new int[] { 4, 6, 3,
774 // backwards and forwards
776 "[3, 2, 1, 4, 5, 6]",
777 Arrays.toString(MappingUtils.flattenRanges(new int[] { 3, 1, 4,
779 // trailing unpaired start position is ignored:
781 "[12, 9, 8, 7, 4, 3, 2]",
782 Arrays.toString(MappingUtils.flattenRanges(new int[] { 12, 12,
787 * Test mapping a column selection including hidden columns
789 * @throws IOException
791 @Test(groups = { "Functional" })
792 public void testMapColumnSelection_hiddenColumns() throws IOException
794 setupMappedAlignments();
796 ColumnSelection proteinSelection = new ColumnSelection();
799 * Column 0 in protein picks up Seq2/L, Seq3/G which map to cols 0-4 and 0-3
800 * in dna respectively, overall 0-4
802 proteinSelection.hideColumns(0);
803 ColumnSelection dnaSelection = MappingUtils.mapColumnSelection(proteinSelection,
804 proteinView, dnaView);
805 assertEquals("[]", dnaSelection.getSelected().toString());
806 List<int[]> hidden = dnaSelection.getHiddenColumns();
807 assertEquals(1, hidden.size());
808 assertEquals("[0, 4]", Arrays.toString(hidden.get(0)));
811 * Column 1 in protein picks up Seq1/K which maps to cols 0-3 in dna
813 proteinSelection.revealAllHiddenColumns();
814 // the unhidden columns are now marked selected!
815 assertEquals("[0]", proteinSelection.getSelected().toString());
816 // deselect these or hideColumns will be expanded to include 0
817 proteinSelection.clear();
818 proteinSelection.hideColumns(1);
819 dnaSelection = MappingUtils.mapColumnSelection(proteinSelection, proteinView, dnaView);
820 hidden = dnaSelection.getHiddenColumns();
821 assertEquals(1, hidden.size());
822 assertEquals("[0, 3]", Arrays.toString(hidden.get(0)));
825 * Column 2 in protein picks up gaps only - no mapping
827 proteinSelection.revealAllHiddenColumns();
828 proteinSelection.clear();
829 proteinSelection.hideColumns(2);
830 dnaSelection = MappingUtils.mapColumnSelection(proteinSelection, proteinView, dnaView);
831 assertTrue(dnaSelection.getHiddenColumns().isEmpty());
834 * Column 3 in protein picks up Seq1/P, Seq2/Q, Seq3/S which map to columns
835 * 6-9, 6-10, 5-8 respectively, overall to 5-10
837 proteinSelection.revealAllHiddenColumns();
838 proteinSelection.clear();
839 proteinSelection.hideColumns(3); // 5-10 hidden in dna
840 proteinSelection.addElement(1); // 0-3 selected in dna
841 dnaSelection = MappingUtils.mapColumnSelection(proteinSelection, proteinView, dnaView);
842 assertEquals("[0, 1, 2, 3]", dnaSelection.getSelected().toString());
843 hidden = dnaSelection.getHiddenColumns();
844 assertEquals(1, hidden.size());
845 assertEquals("[5, 10]", Arrays.toString(hidden.get(0)));
848 * Combine hiding columns 1 and 3 to get discontiguous hidden columns
850 proteinSelection.revealAllHiddenColumns();
851 proteinSelection.clear();
852 proteinSelection.hideColumns(1);
853 proteinSelection.hideColumns(3);
854 dnaSelection = MappingUtils.mapColumnSelection(proteinSelection, proteinView, dnaView);
855 hidden = dnaSelection.getHiddenColumns();
856 assertEquals(2, hidden.size());
857 assertEquals("[0, 3]", Arrays.toString(hidden.get(0)));
858 assertEquals("[5, 10]", Arrays.toString(hidden.get(1)));
861 @Test(groups = { "Functional" })
862 public void testGetLength()
864 assertEquals(0, MappingUtils.getLength(null));
865 List<int[]> ranges = new ArrayList<int[]>();
866 assertEquals(0, MappingUtils.getLength(ranges));
867 ranges.add(new int[] { 1, 1 });
868 assertEquals(1, MappingUtils.getLength(ranges));
869 ranges.add(new int[] { 2, 10 });
870 assertEquals(10, MappingUtils.getLength(ranges));
871 ranges.add(new int[] { 20, 10 });
872 assertEquals(21, MappingUtils.getLength(ranges));
875 @Test(groups = { "Functional" })
876 public void testContains()
878 assertFalse(MappingUtils.contains(null, 1));
879 List<int[]> ranges = new ArrayList<int[]>();
880 assertFalse(MappingUtils.contains(ranges, 1));
882 ranges.add(new int[] { 1, 4 });
883 ranges.add(new int[] { 6, 6 });
884 ranges.add(new int[] { 8, 10 });
885 ranges.add(new int[] { 30, 20 });
886 ranges.add(new int[] { -16, -44 });
888 assertFalse(MappingUtils.contains(ranges, 0));
889 assertTrue(MappingUtils.contains(ranges, 1));
890 assertTrue(MappingUtils.contains(ranges, 2));
891 assertTrue(MappingUtils.contains(ranges, 3));
892 assertTrue(MappingUtils.contains(ranges, 4));
893 assertFalse(MappingUtils.contains(ranges, 5));
895 assertTrue(MappingUtils.contains(ranges, 6));
896 assertFalse(MappingUtils.contains(ranges, 7));
898 assertTrue(MappingUtils.contains(ranges, 8));
899 assertTrue(MappingUtils.contains(ranges, 9));
900 assertTrue(MappingUtils.contains(ranges, 10));
902 assertFalse(MappingUtils.contains(ranges, 31));
903 assertTrue(MappingUtils.contains(ranges, 30));
904 assertTrue(MappingUtils.contains(ranges, 29));
905 assertTrue(MappingUtils.contains(ranges, 20));
906 assertFalse(MappingUtils.contains(ranges, 19));
908 assertFalse(MappingUtils.contains(ranges, -15));
909 assertTrue(MappingUtils.contains(ranges, -16));
910 assertTrue(MappingUtils.contains(ranges, -44));
911 assertFalse(MappingUtils.contains(ranges, -45));