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,
67 .getMappingType("exonerate:protein2genome:local"));
68 assertSame(MappingType.PeptideToNucleotide,
69 ExonerateHelper.getMappingType("exonerate:protein2dna:local"));
72 assertSame(MappingType.NucleotideToNucleotide,
73 ExonerateHelper.getMappingType("coding2coding"));
74 assertSame(MappingType.NucleotideToNucleotide,
75 ExonerateHelper.getMappingType("coding2genome"));
76 assertSame(MappingType.NucleotideToNucleotide,
77 ExonerateHelper.getMappingType("cdna2genome"));
78 assertSame(MappingType.NucleotideToNucleotide,
79 ExonerateHelper.getMappingType("genome2genome"));
80 assertNull(ExonerateHelper.getMappingType("affine:local"));
84 * Test processing one exonerate GFF line for the case where the mapping is
85 * protein2dna, similarity feature is on the query (the protein), match to the
86 * forward strand, target sequence is in neither the alignment nor the 'new
91 @Test(groups = "Functional")
92 public void testProcessGffSimilarity_protein2dna_forward_querygff()
95 ExonerateHelper testee = new ExonerateHelper();
96 List<SequenceI> newseqs = new ArrayList<SequenceI>();
97 String[] gff = "Seq\texonerate:protein2dna:local\tsimilarity\t3\t10\t.\t+\t.\talignment_id 0 ; Target dna1 ; Align 3 400 8"
99 SequenceI seq = new Sequence("Seq", "PQRASTGKEEDVMIWCHQN");
100 seq.createDatasetSequence();
101 AlignmentI align = new Alignment(new SequenceI[] {});
102 Map<String, List<String>> set = Gff2Helper.parseNameValuePairs(gff[8]);
105 * this should create a mapping from Seq2/3-10 to virtual sequence
106 * dna1 (added to newseqs) positions 400-423
108 testee.processGffSimilarity(set, seq, gff, align, newseqs, false);
109 assertEquals(1, newseqs.size());
110 assertTrue(newseqs.get(0) instanceof SequenceDummy);
111 assertEquals("dna1", newseqs.get(0).getName());
112 assertEquals(1, align.getCodonFrames().size());
113 AlignedCodonFrame mapping = align.getCodonFrames().iterator().next();
114 assertEquals(1, mapping.getAaSeqs().length);
115 assertSame(seq.getDatasetSequence(), mapping.getAaSeqs()[0]);
116 assertEquals(1, mapping.getdnaSeqs().length);
117 assertSame(newseqs.get(0), mapping.getdnaSeqs()[0]);
118 assertEquals(1, mapping.getdnaToProt().length);
119 assertEquals(1, mapping.getdnaToProt()[0].getFromRanges().size());
120 assertArrayEquals(new int[] { 400, 423 }, mapping.getdnaToProt()[0]
121 .getFromRanges().get(0));
122 assertEquals(1, mapping.getdnaToProt()[0].getToRanges().size());
123 assertArrayEquals(new int[] { 3, 10 }, mapping.getdnaToProt()[0]
124 .getToRanges().get(0));
128 * Test processing one exonerate GFF line for the case where the mapping is
129 * protein2dna, similarity feature is on the query (the protein), match to the
132 * @throws IOException
134 @Test(groups = "Functional")
135 public void testProcessGffSimilarity_protein2dna_reverse_querygff()
138 ExonerateHelper testee = new ExonerateHelper();
139 List<SequenceI> newseqs = new ArrayList<SequenceI>();
140 String[] gff = "Seq\texonerate:protein2dna:local\tsimilarity\t3\t10\t0\t-\t.\talignment_id 0 ; Target dna1 ; Align 3 400 8"
142 SequenceI seq = new Sequence("Seq", "PQRASTGKEEDVMIWCHQN");
143 seq.createDatasetSequence();
144 AlignmentI align = new Alignment(new SequenceI[] {});
145 Map<String, List<String>> set = Gff2Helper.parseNameValuePairs(gff[8]);
148 * this should create a mapping from Seq2/3-10 to virtual sequence
149 * dna1 (added to newseqs) positions 400-377 (reverse)
151 testee.processGffSimilarity(set, seq, gff, align, newseqs, false);
152 assertEquals(1, newseqs.size());
153 assertTrue(newseqs.get(0) instanceof SequenceDummy);
154 assertEquals("dna1", newseqs.get(0).getName());
155 assertEquals(1, align.getCodonFrames().size());
156 AlignedCodonFrame mapping = align.getCodonFrames().iterator().next();
157 assertEquals(1, mapping.getAaSeqs().length);
158 assertSame(seq.getDatasetSequence(), mapping.getAaSeqs()[0]);
159 assertEquals(1, mapping.getdnaSeqs().length);
160 assertSame(newseqs.get(0), mapping.getdnaSeqs()[0]);
161 assertEquals(1, mapping.getdnaToProt().length);
162 assertEquals(1, mapping.getdnaToProt()[0].getFromRanges().size());
163 assertArrayEquals(new int[] { 400, 377 }, mapping.getdnaToProt()[0]
164 .getFromRanges().get(0));
165 assertEquals(1, mapping.getdnaToProt()[0].getToRanges().size());
166 assertArrayEquals(new int[] { 3, 10 }, mapping.getdnaToProt()[0]
167 .getToRanges().get(0));
171 * Test processing one exonerate GFF line for the case where the mapping is
172 * protein2dna, similarity feature is on the target (the dna), match to the
175 * @throws IOException
177 @Test(groups = "Functional")
178 public void testProcessGffSimilarity_protein2dna_forward_targetgff()
181 ExonerateHelper testee = new ExonerateHelper();
182 List<SequenceI> newseqs = new ArrayList<SequenceI>();
183 String[] gff = "dna1\texonerate:protein2dna:local\tsimilarity\t400\t423\t0\t+\t.\talignment_id 0 ; Query Prot1 ; Align 400 3 24"
185 SequenceI seq = new Sequence("dna1/391-430",
186 "CGATCCGATCCGATCCGATCCGATCCGATCCGATCCGATC");
187 seq.createDatasetSequence();
188 AlignmentI align = new Alignment(new SequenceI[] { seq });
189 // GFF feature on the target describes mapping from base 400 for
190 // count 24 to position 3
191 Map<String, List<String>> set = Gff2Helper.parseNameValuePairs(gff[8]);
194 * this should create a mapping from virtual sequence dna1 (added to
195 * newseqs) positions 400-423 to Prot1/3-10
197 testee.processGffSimilarity(set, seq, gff, align, newseqs, false);
198 assertEquals(1, newseqs.size());
199 assertTrue(newseqs.get(0) instanceof SequenceDummy);
200 assertEquals("Prot1", newseqs.get(0).getName());
201 assertEquals(1, align.getCodonFrames().size());
202 AlignedCodonFrame mapping = align.getCodonFrames().iterator().next();
203 assertEquals(1, mapping.getAaSeqs().length);
204 assertSame(newseqs.get(0), mapping.getAaSeqs()[0]);
205 assertSame(seq.getDatasetSequence(), mapping.getdnaSeqs()[0]);
206 assertEquals(1, mapping.getdnaSeqs().length);
207 assertEquals(1, mapping.getdnaToProt().length);
208 assertEquals(1, mapping.getdnaToProt()[0].getFromRanges().size());
209 assertArrayEquals(new int[] { 400, 423 }, mapping.getdnaToProt()[0]
210 .getFromRanges().get(0));
211 assertEquals(1, mapping.getdnaToProt()[0].getToRanges().size());
212 assertArrayEquals(new int[] { 3, 10 }, mapping.getdnaToProt()[0]
213 .getToRanges().get(0));
217 * Test processing one exonerate GFF line for the case where the mapping is
218 * protein2dna, similarity feature is on the target (the dna), match to the
221 * @throws IOException
223 @Test(groups = "Functional")
224 public void testProcessGffSimilarity_protein2dna_reverse_targetgff()
227 ExonerateHelper testee = new ExonerateHelper();
228 List<SequenceI> newseqs = new ArrayList<SequenceI>();
229 String[] gff = "dna1\texonerate:protein2dna:local\tsimilarity\t377\t400\t0\t-\t.\talignment_id 0 ; Query Prot1 ; Align 400 3 24"
231 SequenceI seq = new Sequence("dna1/371-410",
232 "CGATCCGATCCGATCCGATCCGATCCGATCCGATCCGATC");
233 seq.createDatasetSequence();
234 AlignmentI align = new Alignment(new SequenceI[] { seq });
235 // GFF feature on the target describes mapping from base 400 for
236 // count 24 to position 3
237 Map<String, List<String>> set = Gff2Helper.parseNameValuePairs(gff[8]);
240 * this should create a mapping from virtual sequence dna1 (added to
241 * newseqs) positions 400-377 (reverse) to Prot1/3-10
243 testee.processGffSimilarity(set, seq, gff, align, newseqs, false);
244 assertEquals(1, newseqs.size());
245 assertTrue(newseqs.get(0) instanceof SequenceDummy);
246 assertEquals("Prot1", newseqs.get(0).getName());
247 assertEquals(1, align.getCodonFrames().size());
248 AlignedCodonFrame mapping = align.getCodonFrames().iterator().next();
249 assertEquals(1, mapping.getAaSeqs().length);
250 assertSame(newseqs.get(0), mapping.getAaSeqs()[0]);
251 assertSame(seq.getDatasetSequence(), mapping.getdnaSeqs()[0]);
252 assertEquals(1, mapping.getdnaSeqs().length);
253 assertEquals(1, mapping.getdnaToProt().length);
254 assertEquals(1, mapping.getdnaToProt()[0].getFromRanges().size());
255 assertArrayEquals(new int[] { 400, 377 }, mapping.getdnaToProt()[0]
256 .getFromRanges().get(0));
257 assertEquals(1, mapping.getdnaToProt()[0].getToRanges().size());
258 assertArrayEquals(new int[] { 3, 10 }, mapping.getdnaToProt()[0]
259 .getToRanges().get(0));
263 * Tests loading exonerate GFF2 output, including 'similarity' alignment
264 * feature, on to sequences
266 @Test(groups = { "Functional" })
267 public void testAddExonerateGffToAlignment()
269 FileLoader loader = new FileLoader(false);
270 AlignFrame af = loader.LoadFileWaitTillLoaded(
271 "examples/testdata/exonerateseqs.fa",
272 DataSourceType.FILE);
274 af.loadJalviewDataFile("examples/testdata/exonerateoutput.gff",
275 DataSourceType.FILE, null, null);
278 * verify one mapping to a dummy sequence, one to a real one
280 List<AlignedCodonFrame> mappings = af
281 .getViewport().getAlignment().getDataset().getCodonFrames();
282 assertEquals(2, mappings.size());
283 Iterator<AlignedCodonFrame> iter = mappings.iterator();
285 // first mapping is to dummy sequence
286 AlignedCodonFrame mapping = iter.next();
287 Mapping[] mapList = mapping.getProtMappings();
288 assertEquals(1, mapList.length);
289 assertTrue(mapList[0].getTo() instanceof SequenceDummy);
290 assertEquals("DDB_G0269124", mapList[0].getTo().getName());
292 // 143 in protein should map to codon [11270, 11269, 11268] in dna
293 int[] mappedRegion = mapList[0].getMap().locateInFrom(143, 143);
294 assertArrayEquals(new int[] { 11270, 11268 }, mappedRegion);
296 // second mapping is to a sequence in the alignment
297 mapping = iter.next();
298 mapList = mapping.getProtMappings();
299 assertEquals(1, mapList.length);
300 SequenceI proteinSeq = af.getViewport().getAlignment()
301 .findName("DDB_G0280897");
302 assertSame(proteinSeq.getDatasetSequence(), mapList[0].getTo());
303 assertEquals(1, mapping.getdnaToProt().length);
305 // 143 in protein should map to codon [11270, 11269, 11268] in dna
306 mappedRegion = mapList[0].getMap().locateInFrom(143, 143);
307 assertArrayEquals(new int[] { 11270, 11268 }, mappedRegion);
309 // 182 in protein should map to codon [11153, 11152, 11151] in dna
310 mappedRegion = mapList[0].getMap().locateInFrom(182, 182);
311 assertArrayEquals(new int[] { 11153, 11151 }, mappedRegion);
313 // and the reverse mapping:
314 mappedRegion = mapList[0].getMap().locateInTo(11151, 11153);
315 assertArrayEquals(new int[] { 182, 182 }, mappedRegion);
317 // 11150 in dna should _not_ map to protein
318 mappedRegion = mapList[0].getMap().locateInTo(11150, 11150);
319 assertNull(mappedRegion);
321 // similarly 183 in protein should _not_ map to dna
322 mappedRegion = mapList[0].getMap().locateInFrom(183, 183);
323 assertNull(mappedRegion);