Clover icon

jalviewX

  1. Project Clover database Wed Oct 31 2018 15:13:58 GMT
  2. Package jalview.util

File MappingUtilsTest.java

 

Code metrics

18
605
23
1
1,287
872
36
0.06
26.3
23
1.57

Classes

Class Line # Actions
MappingUtilsTest 59 605 36 0
1.0100%
 

Contributing tests

This file is covered by 20 tests. .

Source view

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