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.Mapping;
33 import jalview.datamodel.MappingType;
34 import jalview.datamodel.Sequence;
35 import jalview.datamodel.SequenceDummy;
36 import jalview.datamodel.SequenceI;
37 import jalview.gui.AlignFrame;
38 import jalview.gui.JvOptionPane;
39 import jalview.io.DataSourceType;
40 import jalview.io.FileLoader;
42 import java.io.IOException;
43 import java.util.ArrayList;
44 import java.util.Iterator;
45 import java.util.List;
48 import org.testng.annotations.BeforeClass;
49 import org.testng.annotations.Test;
51 public class ExonerateHelperTest
54 @BeforeClass(alwaysRun = true)
55 public void setUpJvOptionPane()
57 JvOptionPane.setInteractiveMode(false);
58 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
61 @Test(groups = "Functional")
62 public void testGetMappingType()
65 assertSame(MappingType.PeptideToNucleotide, ExonerateHelper
66 .getMappingType("exonerate:protein2genome:local"));
67 assertSame(MappingType.PeptideToNucleotide,
68 ExonerateHelper.getMappingType("exonerate:protein2dna:local"));
71 assertSame(MappingType.NucleotideToNucleotide,
72 ExonerateHelper.getMappingType("coding2coding"));
73 assertSame(MappingType.NucleotideToNucleotide,
74 ExonerateHelper.getMappingType("coding2genome"));
75 assertSame(MappingType.NucleotideToNucleotide,
76 ExonerateHelper.getMappingType("cdna2genome"));
77 assertSame(MappingType.NucleotideToNucleotide,
78 ExonerateHelper.getMappingType("genome2genome"));
79 assertNull(ExonerateHelper.getMappingType("affine:local"));
83 * Test processing one exonerate GFF line for the case where the mapping is
84 * protein2dna, similarity feature is on the query (the protein), match to the
85 * forward strand, target sequence is in neither the alignment nor the 'new
90 @Test(groups = "Functional")
91 public void testProcessGffSimilarity_protein2dna_forward_querygff()
94 ExonerateHelper testee = new ExonerateHelper();
95 List<SequenceI> newseqs = new ArrayList<SequenceI>();
96 String[] gff = "Seq\texonerate:protein2dna:local\tsimilarity\t3\t10\t.\t+\t.\talignment_id 0 ; Target dna1 ; Align 3 400 8"
98 SequenceI seq = new Sequence("Seq", "PQRASTGKEEDVMIWCHQN");
99 seq.createDatasetSequence();
100 AlignmentI align = new Alignment(new SequenceI[] {});
101 Map<String, List<String>> set = Gff2Helper.parseNameValuePairs(gff[8]);
104 * this should create a mapping from Seq2/3-10 to virtual sequence
105 * dna1 (added to newseqs) positions 400-423
107 testee.processGffSimilarity(set, seq, gff, align, newseqs, false);
108 assertEquals(1, newseqs.size());
109 assertTrue(newseqs.get(0) instanceof SequenceDummy);
110 assertEquals("dna1", newseqs.get(0).getName());
111 assertEquals(1, align.getCodonFrames().size());
112 AlignedCodonFrame mapping = align.getCodonFrames().iterator().next();
113 assertEquals(1, mapping.getAaSeqs().length);
114 assertSame(seq.getDatasetSequence(), mapping.getAaSeqs()[0]);
115 assertEquals(1, mapping.getdnaSeqs().length);
116 assertSame(newseqs.get(0), mapping.getdnaSeqs()[0]);
117 assertEquals(1, mapping.getdnaToProt().length);
118 assertEquals(1, mapping.getdnaToProt()[0].getFromRanges().size());
119 assertArrayEquals(new int[] { 400, 423 },
120 mapping.getdnaToProt()[0].getFromRanges().get(0));
121 assertEquals(1, mapping.getdnaToProt()[0].getToRanges().size());
122 assertArrayEquals(new int[] { 3, 10 },
123 mapping.getdnaToProt()[0].getToRanges().get(0));
127 * Test processing one exonerate GFF line for the case where the mapping is
128 * protein2dna, similarity feature is on the query (the protein), match to the
131 * @throws IOException
133 @Test(groups = "Functional")
134 public void testProcessGffSimilarity_protein2dna_reverse_querygff()
137 ExonerateHelper testee = new ExonerateHelper();
138 List<SequenceI> newseqs = new ArrayList<SequenceI>();
139 String[] gff = "Seq\texonerate:protein2dna:local\tsimilarity\t3\t10\t0\t-\t.\talignment_id 0 ; Target dna1 ; Align 3 400 8"
141 SequenceI seq = new Sequence("Seq", "PQRASTGKEEDVMIWCHQN");
142 seq.createDatasetSequence();
143 AlignmentI align = new Alignment(new SequenceI[] {});
144 Map<String, List<String>> set = Gff2Helper.parseNameValuePairs(gff[8]);
147 * this should create a mapping from Seq2/3-10 to virtual sequence
148 * dna1 (added to newseqs) positions 400-377 (reverse)
150 testee.processGffSimilarity(set, seq, gff, align, newseqs, false);
151 assertEquals(1, newseqs.size());
152 assertTrue(newseqs.get(0) instanceof SequenceDummy);
153 assertEquals("dna1", newseqs.get(0).getName());
154 assertEquals(1, align.getCodonFrames().size());
155 AlignedCodonFrame mapping = align.getCodonFrames().iterator().next();
156 assertEquals(1, mapping.getAaSeqs().length);
157 assertSame(seq.getDatasetSequence(), mapping.getAaSeqs()[0]);
158 assertEquals(1, mapping.getdnaSeqs().length);
159 assertSame(newseqs.get(0), mapping.getdnaSeqs()[0]);
160 assertEquals(1, mapping.getdnaToProt().length);
161 assertEquals(1, mapping.getdnaToProt()[0].getFromRanges().size());
162 assertArrayEquals(new int[] { 400, 377 },
163 mapping.getdnaToProt()[0].getFromRanges().get(0));
164 assertEquals(1, mapping.getdnaToProt()[0].getToRanges().size());
165 assertArrayEquals(new int[] { 3, 10 },
166 mapping.getdnaToProt()[0].getToRanges().get(0));
170 * Test processing one exonerate GFF line for the case where the mapping is
171 * protein2dna, similarity feature is on the target (the dna), match to the
174 * @throws IOException
176 @Test(groups = "Functional")
177 public void testProcessGffSimilarity_protein2dna_forward_targetgff()
180 ExonerateHelper testee = new ExonerateHelper();
181 List<SequenceI> newseqs = new ArrayList<SequenceI>();
182 String[] gff = "dna1\texonerate:protein2dna:local\tsimilarity\t400\t423\t0\t+\t.\talignment_id 0 ; Query Prot1 ; Align 400 3 24"
184 SequenceI seq = new Sequence("dna1/391-430",
185 "CGATCCGATCCGATCCGATCCGATCCGATCCGATCCGATC");
186 seq.createDatasetSequence();
187 AlignmentI align = new Alignment(new SequenceI[] { seq });
188 // GFF feature on the target describes mapping from base 400 for
189 // count 24 to position 3
190 Map<String, List<String>> set = Gff2Helper.parseNameValuePairs(gff[8]);
193 * this should create a mapping from virtual sequence dna1 (added to
194 * newseqs) positions 400-423 to Prot1/3-10
196 testee.processGffSimilarity(set, seq, gff, align, newseqs, false);
197 assertEquals(1, newseqs.size());
198 assertTrue(newseqs.get(0) instanceof SequenceDummy);
199 assertEquals("Prot1", newseqs.get(0).getName());
200 assertEquals(1, align.getCodonFrames().size());
201 AlignedCodonFrame mapping = align.getCodonFrames().iterator().next();
202 assertEquals(1, mapping.getAaSeqs().length);
203 assertSame(newseqs.get(0), mapping.getAaSeqs()[0]);
204 assertSame(seq.getDatasetSequence(), mapping.getdnaSeqs()[0]);
205 assertEquals(1, mapping.getdnaSeqs().length);
206 assertEquals(1, mapping.getdnaToProt().length);
207 assertEquals(1, mapping.getdnaToProt()[0].getFromRanges().size());
208 assertArrayEquals(new int[] { 400, 423 },
209 mapping.getdnaToProt()[0].getFromRanges().get(0));
210 assertEquals(1, mapping.getdnaToProt()[0].getToRanges().size());
211 assertArrayEquals(new int[] { 3, 10 },
212 mapping.getdnaToProt()[0].getToRanges().get(0));
216 * Test processing one exonerate GFF line for the case where the mapping is
217 * protein2dna, similarity feature is on the target (the dna), match to the
220 * @throws IOException
222 @Test(groups = "Functional")
223 public void testProcessGffSimilarity_protein2dna_reverse_targetgff()
226 ExonerateHelper testee = new ExonerateHelper();
227 List<SequenceI> newseqs = new ArrayList<SequenceI>();
228 String[] gff = "dna1\texonerate:protein2dna:local\tsimilarity\t377\t400\t0\t-\t.\talignment_id 0 ; Query Prot1 ; Align 400 3 24"
230 SequenceI seq = new Sequence("dna1/371-410",
231 "CGATCCGATCCGATCCGATCCGATCCGATCCGATCCGATC");
232 seq.createDatasetSequence();
233 AlignmentI align = new Alignment(new SequenceI[] { seq });
234 // GFF feature on the target describes mapping from base 400 for
235 // count 24 to position 3
236 Map<String, List<String>> set = Gff2Helper.parseNameValuePairs(gff[8]);
239 * this should create a mapping from virtual sequence dna1 (added to
240 * newseqs) positions 400-377 (reverse) to Prot1/3-10
242 testee.processGffSimilarity(set, seq, gff, align, newseqs, false);
243 assertEquals(1, newseqs.size());
244 assertTrue(newseqs.get(0) instanceof SequenceDummy);
245 assertEquals("Prot1", newseqs.get(0).getName());
246 assertEquals(1, align.getCodonFrames().size());
247 AlignedCodonFrame mapping = align.getCodonFrames().iterator().next();
248 assertEquals(1, mapping.getAaSeqs().length);
249 assertSame(newseqs.get(0), mapping.getAaSeqs()[0]);
250 assertSame(seq.getDatasetSequence(), mapping.getdnaSeqs()[0]);
251 assertEquals(1, mapping.getdnaSeqs().length);
252 assertEquals(1, mapping.getdnaToProt().length);
253 assertEquals(1, mapping.getdnaToProt()[0].getFromRanges().size());
254 assertArrayEquals(new int[] { 400, 377 },
255 mapping.getdnaToProt()[0].getFromRanges().get(0));
256 assertEquals(1, mapping.getdnaToProt()[0].getToRanges().size());
257 assertArrayEquals(new int[] { 3, 10 },
258 mapping.getdnaToProt()[0].getToRanges().get(0));
262 * Tests loading exonerate GFF2 output, including 'similarity' alignment
263 * feature, on to sequences
265 @Test(groups = { "Functional" })
266 public void testAddExonerateGffToAlignment()
268 FileLoader loader = new FileLoader(false);
269 AlignFrame af = loader.LoadFileWaitTillLoaded(
270 "examples/testdata/exonerateseqs.fa", DataSourceType.FILE);
272 af.loadJalviewDataFile("examples/testdata/exonerateoutput.gff",
273 DataSourceType.FILE, null, null);
276 * verify one mapping to a dummy sequence, one to a real one
278 List<AlignedCodonFrame> mappings = af.getViewport().getAlignment()
279 .getDataset().getCodonFrames();
280 assertEquals(2, mappings.size());
281 Iterator<AlignedCodonFrame> iter = mappings.iterator();
283 // first mapping is to dummy sequence
284 AlignedCodonFrame mapping = iter.next();
285 Mapping[] mapList = mapping.getProtMappings();
286 assertEquals(1, mapList.length);
287 assertTrue(mapList[0].getTo() instanceof SequenceDummy);
288 assertEquals("DDB_G0269124", mapList[0].getTo().getName());
290 // 143 in protein should map to codon [11270, 11269, 11268] in dna
291 int[] mappedRegion = mapList[0].getMap().locateInFrom(143, 143);
292 assertArrayEquals(new int[] { 11270, 11268 }, mappedRegion);
294 // second mapping is to a sequence in the alignment
295 mapping = iter.next();
296 mapList = mapping.getProtMappings();
297 assertEquals(1, mapList.length);
298 SequenceI proteinSeq = af.getViewport().getAlignment()
299 .findName("DDB_G0280897");
300 assertSame(proteinSeq.getDatasetSequence(), mapList[0].getTo());
301 assertEquals(1, mapping.getdnaToProt().length);
303 // 143 in protein should map to codon [11270, 11269, 11268] in dna
304 mappedRegion = mapList[0].getMap().locateInFrom(143, 143);
305 assertArrayEquals(new int[] { 11270, 11268 }, mappedRegion);
307 // 182 in protein should map to codon [11153, 11152, 11151] in dna
308 mappedRegion = mapList[0].getMap().locateInFrom(182, 182);
309 assertArrayEquals(new int[] { 11153, 11151 }, mappedRegion);
311 // and the reverse mapping:
312 mappedRegion = mapList[0].getMap().locateInTo(11151, 11153);
313 assertArrayEquals(new int[] { 182, 182 }, mappedRegion);
315 // 11150 in dna should _not_ map to protein
316 mappedRegion = mapList[0].getMap().locateInTo(11150, 11150);
317 assertNull(mappedRegion);
319 // similarly 183 in protein should _not_ map to dna
320 mappedRegion = mapList[0].getMap().locateInFrom(183, 183);
321 assertNull(mappedRegion);