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.
21 package jalview.io.gff;
23 import static org.testng.AssertJUnit.assertEquals;
24 import static org.testng.AssertJUnit.assertNull;
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.datamodel.AlignedCodonFrame;
30 import jalview.datamodel.Alignment;
31 import jalview.datamodel.AlignmentI;
32 import jalview.datamodel.Sequence;
33 import jalview.datamodel.SequenceDummy;
34 import jalview.datamodel.SequenceFeature;
35 import jalview.datamodel.SequenceI;
36 import jalview.gui.JvOptionPane;
38 import java.io.IOException;
39 import java.util.ArrayList;
40 import java.util.List;
42 import org.testng.annotations.BeforeClass;
43 import org.testng.annotations.Test;
45 public class Gff3HelperTest
48 @BeforeClass(alwaysRun = true)
49 public void setUpJvOptionPane()
51 JvOptionPane.setInteractiveMode(false);
52 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
56 * Test processing one PASA GFF line giving a match from forward strand to
61 @Test(groups = "Functional")
62 public void testProcessCdnaMatch_forwardToForward() throws IOException
64 GffHelperBase testee = new Gff3Helper();
65 List<SequenceI> newseqs = new ArrayList<SequenceI>();
66 String[] gff = "gi|68711\tblat-pasa\tcDNA_match\t12923\t13060\t98.55\t+\t.\tID=align_68;Target=gi|N37351 1 138 +"
68 SequenceI seq = new Sequence("gi|68711",
69 "GAATTCGTTCATGTAGGTTGATTTTTATT");
70 seq.createDatasetSequence();
71 AlignmentI align = new Alignment(new SequenceI[] {});
74 * this should create a mapping from gi|68711/12923-13060
75 * to virtual sequence gi|N37351 (added to newseqs) positions 1-138
77 testee.processGff(seq, gff, align, newseqs, false);
78 assertEquals(1, newseqs.size());
79 assertTrue(newseqs.get(0) instanceof SequenceDummy);
80 assertEquals("gi|N37351", newseqs.get(0).getName());
81 assertEquals(1, align.getCodonFrames().size());
82 AlignedCodonFrame mapping = align.getCodonFrames().iterator().next();
85 * 'dnaseqs' (map from) is here [gi|68711]
86 * 'aaseqs' (map to) is here [gi|N37351]
88 // TODO use more suitable naming in AlignedCodonFrame
89 assertEquals(1, mapping.getAaSeqs().length);
90 assertSame(seq.getDatasetSequence(), mapping.getdnaSeqs()[0]);
91 assertEquals(1, mapping.getdnaSeqs().length);
92 assertSame(newseqs.get(0), mapping.getAaSeqs()[0]);
93 assertEquals(1, mapping.getdnaToProt().length);
94 assertEquals(1, mapping.getdnaToProt()[0].getFromRanges().size());
95 assertArrayEquals(new int[] { 12923, 13060 }, mapping.getdnaToProt()[0]
96 .getFromRanges().get(0));
97 assertEquals(1, mapping.getdnaToProt()[0].getToRanges().size());
98 assertArrayEquals(new int[] { 1, 138 }, mapping.getdnaToProt()[0]
99 .getToRanges().get(0));
103 * Test processing one PASA GFF line giving a match from forward strand to
106 * @throws IOException
108 @Test(groups = "Functional")
109 public void testProcessCdnaMatch_forwardToReverse() throws IOException
111 GffHelperBase testee = new Gff3Helper();
112 List<SequenceI> newseqs = new ArrayList<SequenceI>();
113 String[] gff = "gi|68711\tblat-pasa\tcDNA_match\t12923\t13060\t98.55\t+\t.\tID=align_68;Target=gi|N37351 1 138 -"
115 SequenceI seq = new Sequence("gi|68711",
116 "GAATTCGTTCATGTAGGTTGATTTTTATT");
117 seq.createDatasetSequence();
118 AlignmentI align = new Alignment(new SequenceI[] {});
121 * this should create a mapping from gi|68711/12923-13060
122 * to virtual sequence gi|N37351 (added to newseqs) positions 138-1
124 testee.processGff(seq, gff, align, newseqs, false);
125 assertEquals(1, newseqs.size());
126 assertTrue(newseqs.get(0) instanceof SequenceDummy);
127 assertEquals("gi|N37351", newseqs.get(0).getName());
128 assertEquals(1, align.getCodonFrames().size());
129 AlignedCodonFrame mapping = align.getCodonFrames().iterator().next();
132 * 'dnaseqs' (map from) is here [gi|68711]
133 * 'aaseqs' (map to) is here [gi|N37351]
135 // TODO use more suitable naming in AlignedCodonFrame
136 assertEquals(1, mapping.getAaSeqs().length);
137 assertSame(seq.getDatasetSequence(), mapping.getdnaSeqs()[0]);
138 assertEquals(1, mapping.getdnaSeqs().length);
139 assertSame(newseqs.get(0), mapping.getAaSeqs()[0]);
140 assertEquals(1, mapping.getdnaToProt().length);
141 assertEquals(1, mapping.getdnaToProt()[0].getFromRanges().size());
142 assertArrayEquals(new int[] { 12923, 13060 }, mapping.getdnaToProt()[0]
143 .getFromRanges().get(0));
144 assertEquals(1, mapping.getdnaToProt()[0].getToRanges().size());
145 assertArrayEquals(new int[] { 138, 1 }, mapping.getdnaToProt()[0]
146 .getToRanges().get(0));
150 * Test processing one PASA GFF line giving a match from reverse complement
151 * strand to forward strand
153 * @throws IOException
155 @Test(groups = "Functional")
156 public void testProcessCdnaMatch_reverseToForward() throws IOException
158 GffHelperBase testee = new Gff3Helper();
159 List<SequenceI> newseqs = new ArrayList<SequenceI>();
160 String[] gff = "gi|68711\tblat-pasa\tcDNA_match\t12923\t13060\t98.55\t-\t.\tID=align_68;Target=gi|N37351 1 138 +"
162 SequenceI seq = new Sequence("gi|68711",
163 "GAATTCGTTCATGTAGGTTGATTTTTATT");
164 seq.createDatasetSequence();
165 AlignmentI align = new Alignment(new SequenceI[] {});
168 * (For now) we don't process reverse complement mappings; to do this
169 * would require (a) creating a virtual sequence placeholder for the
170 * reverse complement (b) resolving the sequence by its id from some
171 * source (GFF ##FASTA or other) (c) creating the reverse complement
172 * sequence (d) updating the mapping to be to the reverse complement
174 SequenceFeature sf = testee.processGff(seq, gff, align, newseqs, false);
176 assertTrue(newseqs.isEmpty());
180 * Test processing two PASA GFF lines representing a spliced mapping
182 * @throws IOException
184 @Test(groups = "Functional")
185 public void testProcessCdnaMatch_spliced() throws IOException
187 GffHelperBase testee = new Gff3Helper();
188 List<SequenceI> newseqs = new ArrayList<SequenceI>();
189 SequenceI seq = new Sequence("gi|68711",
190 "GAATTCGTTCATGTAGGTTGATTTTTATT");
191 seq.createDatasetSequence();
192 AlignmentI align = new Alignment(new SequenceI[] {});
194 // mapping from gi|68711 12923-13060 to gi|N37351 1-138
195 String[] gff = "gi|68711\tblat-pasa\tcDNA_match\t12923\t13060\t98.55\t+\t.\tID=align_68;Target=gi|N37351 1 138 +"
197 testee.processGff(seq, gff, align, newseqs, false);
198 // mapping from gi|68711 13411-13550 to gi|N37351 139-278
199 gff = "gi|68711\tblat-pasa\tcDNA_match\t13411\t13550\t98.55\t+\t.\tID=align_68;Target=gi|N37351 139 278 +"
201 testee.processGff(seq, gff, align, newseqs, false);
203 assertEquals(1, newseqs.size());
204 assertTrue(newseqs.get(0) instanceof SequenceDummy);
205 assertEquals("gi|N37351", newseqs.get(0).getName());
207 // only 1 AlignedCodonFrame added to the alignment with both mappings!
208 // (this is important for 'align cdna to genome' to work correctly)
209 assertEquals(1, align.getCodonFrames().size());
210 AlignedCodonFrame mapping = align.getCodonFrames().get(0);
213 * 'dnaseqs' (map from) is here [gi|68711]
214 * 'aaseqs' (map to) is here [gi|N37351]
216 // TODO use more suitable naming in AlignedCodonFrame
217 assertEquals(1, mapping.getAaSeqs().length);
218 assertSame(seq.getDatasetSequence(), mapping.getdnaSeqs()[0]);
219 assertEquals(1, mapping.getdnaSeqs().length);
220 assertSame(newseqs.get(0), mapping.getAaSeqs()[0]);
221 assertEquals(1, mapping.getdnaToProt().length);
222 assertEquals(2, mapping.getdnaToProt()[0].getFromRanges().size());
223 // the two spliced dna ranges are combined in one MapList
224 assertArrayEquals(new int[] { 12923, 13060 }, mapping.getdnaToProt()[0]
225 .getFromRanges().get(0));
226 assertArrayEquals(new int[] { 13411, 13550 }, mapping.getdnaToProt()[0]
227 .getFromRanges().get(1));
228 assertEquals(1, mapping.getdnaToProt()[0].getToRanges().size());
229 // the two cdna ranges are merged into one contiguous region
230 assertArrayEquals(new int[] { 1, 278 }, mapping.getdnaToProt()[0]
231 .getToRanges().get(0));