Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
ExonerateHelperTest | 51 | 126 | 7 |
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.io.gff; | |
22 | ||
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; | |
28 | ||
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; | |
41 | ||
42 | import java.io.IOException; | |
43 | import java.util.ArrayList; | |
44 | import java.util.Iterator; | |
45 | import java.util.List; | |
46 | import java.util.Map; | |
47 | ||
48 | import org.testng.annotations.BeforeClass; | |
49 | import org.testng.annotations.Test; | |
50 | ||
51 | public class ExonerateHelperTest | |
52 | { | |
53 | ||
54 | 1 | @BeforeClass(alwaysRun = true) |
55 | public void setUpJvOptionPane() | |
56 | { | |
57 | 1 | JvOptionPane.setInteractiveMode(false); |
58 | 1 | JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION); |
59 | } | |
60 | ||
61 | 1 | @Test(groups = "Functional") |
62 | public void testGetMappingType() | |
63 | { | |
64 | // protein-to-dna: | |
65 | 1 | assertSame(MappingType.PeptideToNucleotide, ExonerateHelper |
66 | .getMappingType("exonerate:protein2genome:local")); | |
67 | 1 | assertSame(MappingType.PeptideToNucleotide, |
68 | ExonerateHelper.getMappingType("exonerate:protein2dna:local")); | |
69 | ||
70 | // dna-to-dna: | |
71 | 1 | assertSame(MappingType.NucleotideToNucleotide, |
72 | ExonerateHelper.getMappingType("coding2coding")); | |
73 | 1 | assertSame(MappingType.NucleotideToNucleotide, |
74 | ExonerateHelper.getMappingType("coding2genome")); | |
75 | 1 | assertSame(MappingType.NucleotideToNucleotide, |
76 | ExonerateHelper.getMappingType("cdna2genome")); | |
77 | 1 | assertSame(MappingType.NucleotideToNucleotide, |
78 | ExonerateHelper.getMappingType("genome2genome")); | |
79 | 1 | assertNull(ExonerateHelper.getMappingType("affine:local")); |
80 | } | |
81 | ||
82 | /** | |
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 | |
86 | * sequences' | |
87 | * | |
88 | * @throws IOException | |
89 | */ | |
90 | 1 | @Test(groups = "Functional") |
91 | public void testProcessGffSimilarity_protein2dna_forward_querygff() | |
92 | throws IOException | |
93 | { | |
94 | 1 | ExonerateHelper testee = new ExonerateHelper(); |
95 | 1 | List<SequenceI> newseqs = new ArrayList<SequenceI>(); |
96 | 1 | String[] gff = "Seq\texonerate:protein2dna:local\tsimilarity\t3\t10\t.\t+\t.\talignment_id 0 ; Target dna1 ; Align 3 400 8" |
97 | .split("\\t"); | |
98 | 1 | SequenceI seq = new Sequence("Seq", "PQRASTGKEEDVMIWCHQN"); |
99 | 1 | seq.createDatasetSequence(); |
100 | 1 | AlignmentI align = new Alignment(new SequenceI[] {}); |
101 | 1 | Map<String, List<String>> set = Gff2Helper.parseNameValuePairs(gff[8]); |
102 | ||
103 | /* | |
104 | * this should create a mapping from Seq2/3-10 to virtual sequence | |
105 | * dna1 (added to newseqs) positions 400-423 | |
106 | */ | |
107 | 1 | testee.processGffSimilarity(set, seq, gff, align, newseqs, false); |
108 | 1 | assertEquals(1, newseqs.size()); |
109 | 1 | assertTrue(newseqs.get(0) instanceof SequenceDummy); |
110 | 1 | assertEquals("dna1", newseqs.get(0).getName()); |
111 | 1 | assertEquals(1, align.getCodonFrames().size()); |
112 | 1 | AlignedCodonFrame mapping = align.getCodonFrames().iterator().next(); |
113 | 1 | assertEquals(1, mapping.getAaSeqs().length); |
114 | 1 | assertSame(seq.getDatasetSequence(), mapping.getAaSeqs()[0]); |
115 | 1 | assertEquals(1, mapping.getdnaSeqs().length); |
116 | 1 | assertSame(newseqs.get(0), mapping.getdnaSeqs()[0]); |
117 | 1 | assertEquals(1, mapping.getdnaToProt().length); |
118 | 1 | assertEquals(1, mapping.getdnaToProt()[0].getFromRanges().size()); |
119 | 1 | assertArrayEquals(new int[] { 400, 423 }, |
120 | mapping.getdnaToProt()[0].getFromRanges().get(0)); | |
121 | 1 | assertEquals(1, mapping.getdnaToProt()[0].getToRanges().size()); |
122 | 1 | assertArrayEquals(new int[] { 3, 10 }, |
123 | mapping.getdnaToProt()[0].getToRanges().get(0)); | |
124 | } | |
125 | ||
126 | /** | |
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 | |
129 | * reverse strand | |
130 | * | |
131 | * @throws IOException | |
132 | */ | |
133 | 1 | @Test(groups = "Functional") |
134 | public void testProcessGffSimilarity_protein2dna_reverse_querygff() | |
135 | throws IOException | |
136 | { | |
137 | 1 | ExonerateHelper testee = new ExonerateHelper(); |
138 | 1 | List<SequenceI> newseqs = new ArrayList<SequenceI>(); |
139 | 1 | String[] gff = "Seq\texonerate:protein2dna:local\tsimilarity\t3\t10\t0\t-\t.\talignment_id 0 ; Target dna1 ; Align 3 400 8" |
140 | .split("\\t"); | |
141 | 1 | SequenceI seq = new Sequence("Seq", "PQRASTGKEEDVMIWCHQN"); |
142 | 1 | seq.createDatasetSequence(); |
143 | 1 | AlignmentI align = new Alignment(new SequenceI[] {}); |
144 | 1 | Map<String, List<String>> set = Gff2Helper.parseNameValuePairs(gff[8]); |
145 | ||
146 | /* | |
147 | * this should create a mapping from Seq2/3-10 to virtual sequence | |
148 | * dna1 (added to newseqs) positions 400-377 (reverse) | |
149 | */ | |
150 | 1 | testee.processGffSimilarity(set, seq, gff, align, newseqs, false); |
151 | 1 | assertEquals(1, newseqs.size()); |
152 | 1 | assertTrue(newseqs.get(0) instanceof SequenceDummy); |
153 | 1 | assertEquals("dna1", newseqs.get(0).getName()); |
154 | 1 | assertEquals(1, align.getCodonFrames().size()); |
155 | 1 | AlignedCodonFrame mapping = align.getCodonFrames().iterator().next(); |
156 | 1 | assertEquals(1, mapping.getAaSeqs().length); |
157 | 1 | assertSame(seq.getDatasetSequence(), mapping.getAaSeqs()[0]); |
158 | 1 | assertEquals(1, mapping.getdnaSeqs().length); |
159 | 1 | assertSame(newseqs.get(0), mapping.getdnaSeqs()[0]); |
160 | 1 | assertEquals(1, mapping.getdnaToProt().length); |
161 | 1 | assertEquals(1, mapping.getdnaToProt()[0].getFromRanges().size()); |
162 | 1 | assertArrayEquals(new int[] { 400, 377 }, |
163 | mapping.getdnaToProt()[0].getFromRanges().get(0)); | |
164 | 1 | assertEquals(1, mapping.getdnaToProt()[0].getToRanges().size()); |
165 | 1 | assertArrayEquals(new int[] { 3, 10 }, |
166 | mapping.getdnaToProt()[0].getToRanges().get(0)); | |
167 | } | |
168 | ||
169 | /** | |
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 | |
172 | * forward strand | |
173 | * | |
174 | * @throws IOException | |
175 | */ | |
176 | 1 | @Test(groups = "Functional") |
177 | public void testProcessGffSimilarity_protein2dna_forward_targetgff() | |
178 | throws IOException | |
179 | { | |
180 | 1 | ExonerateHelper testee = new ExonerateHelper(); |
181 | 1 | List<SequenceI> newseqs = new ArrayList<SequenceI>(); |
182 | 1 | String[] gff = "dna1\texonerate:protein2dna:local\tsimilarity\t400\t423\t0\t+\t.\talignment_id 0 ; Query Prot1 ; Align 400 3 24" |
183 | .split("\\t"); | |
184 | 1 | SequenceI seq = new Sequence("dna1/391-430", |
185 | "CGATCCGATCCGATCCGATCCGATCCGATCCGATCCGATC"); | |
186 | 1 | seq.createDatasetSequence(); |
187 | 1 | 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 | 1 | Map<String, List<String>> set = Gff2Helper.parseNameValuePairs(gff[8]); |
191 | ||
192 | /* | |
193 | * this should create a mapping from virtual sequence dna1 (added to | |
194 | * newseqs) positions 400-423 to Prot1/3-10 | |
195 | */ | |
196 | 1 | testee.processGffSimilarity(set, seq, gff, align, newseqs, false); |
197 | 1 | assertEquals(1, newseqs.size()); |
198 | 1 | assertTrue(newseqs.get(0) instanceof SequenceDummy); |
199 | 1 | assertEquals("Prot1", newseqs.get(0).getName()); |
200 | 1 | assertEquals(1, align.getCodonFrames().size()); |
201 | 1 | AlignedCodonFrame mapping = align.getCodonFrames().iterator().next(); |
202 | 1 | assertEquals(1, mapping.getAaSeqs().length); |
203 | 1 | assertSame(newseqs.get(0), mapping.getAaSeqs()[0]); |
204 | 1 | assertSame(seq.getDatasetSequence(), mapping.getdnaSeqs()[0]); |
205 | 1 | assertEquals(1, mapping.getdnaSeqs().length); |
206 | 1 | assertEquals(1, mapping.getdnaToProt().length); |
207 | 1 | assertEquals(1, mapping.getdnaToProt()[0].getFromRanges().size()); |
208 | 1 | assertArrayEquals(new int[] { 400, 423 }, |
209 | mapping.getdnaToProt()[0].getFromRanges().get(0)); | |
210 | 1 | assertEquals(1, mapping.getdnaToProt()[0].getToRanges().size()); |
211 | 1 | assertArrayEquals(new int[] { 3, 10 }, |
212 | mapping.getdnaToProt()[0].getToRanges().get(0)); | |
213 | } | |
214 | ||
215 | /** | |
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 | |
218 | * reverse strand | |
219 | * | |
220 | * @throws IOException | |
221 | */ | |
222 | 1 | @Test(groups = "Functional") |
223 | public void testProcessGffSimilarity_protein2dna_reverse_targetgff() | |
224 | throws IOException | |
225 | { | |
226 | 1 | ExonerateHelper testee = new ExonerateHelper(); |
227 | 1 | List<SequenceI> newseqs = new ArrayList<SequenceI>(); |
228 | 1 | String[] gff = "dna1\texonerate:protein2dna:local\tsimilarity\t377\t400\t0\t-\t.\talignment_id 0 ; Query Prot1 ; Align 400 3 24" |
229 | .split("\\t"); | |
230 | 1 | SequenceI seq = new Sequence("dna1/371-410", |
231 | "CGATCCGATCCGATCCGATCCGATCCGATCCGATCCGATC"); | |
232 | 1 | seq.createDatasetSequence(); |
233 | 1 | 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 | 1 | Map<String, List<String>> set = Gff2Helper.parseNameValuePairs(gff[8]); |
237 | ||
238 | /* | |
239 | * this should create a mapping from virtual sequence dna1 (added to | |
240 | * newseqs) positions 400-377 (reverse) to Prot1/3-10 | |
241 | */ | |
242 | 1 | testee.processGffSimilarity(set, seq, gff, align, newseqs, false); |
243 | 1 | assertEquals(1, newseqs.size()); |
244 | 1 | assertTrue(newseqs.get(0) instanceof SequenceDummy); |
245 | 1 | assertEquals("Prot1", newseqs.get(0).getName()); |
246 | 1 | assertEquals(1, align.getCodonFrames().size()); |
247 | 1 | AlignedCodonFrame mapping = align.getCodonFrames().iterator().next(); |
248 | 1 | assertEquals(1, mapping.getAaSeqs().length); |
249 | 1 | assertSame(newseqs.get(0), mapping.getAaSeqs()[0]); |
250 | 1 | assertSame(seq.getDatasetSequence(), mapping.getdnaSeqs()[0]); |
251 | 1 | assertEquals(1, mapping.getdnaSeqs().length); |
252 | 1 | assertEquals(1, mapping.getdnaToProt().length); |
253 | 1 | assertEquals(1, mapping.getdnaToProt()[0].getFromRanges().size()); |
254 | 1 | assertArrayEquals(new int[] { 400, 377 }, |
255 | mapping.getdnaToProt()[0].getFromRanges().get(0)); | |
256 | 1 | assertEquals(1, mapping.getdnaToProt()[0].getToRanges().size()); |
257 | 1 | assertArrayEquals(new int[] { 3, 10 }, |
258 | mapping.getdnaToProt()[0].getToRanges().get(0)); | |
259 | } | |
260 | ||
261 | /** | |
262 | * Tests loading exonerate GFF2 output, including 'similarity' alignment | |
263 | * feature, on to sequences | |
264 | */ | |
265 | 1 | @Test(groups = { "Functional" }) |
266 | public void testAddExonerateGffToAlignment() | |
267 | { | |
268 | 1 | FileLoader loader = new FileLoader(false); |
269 | 1 | AlignFrame af = loader.LoadFileWaitTillLoaded( |
270 | "examples/testdata/exonerateseqs.fa", DataSourceType.FILE); | |
271 | ||
272 | 1 | af.loadJalviewDataFile("examples/testdata/exonerateoutput.gff", |
273 | DataSourceType.FILE, null, null); | |
274 | ||
275 | /* | |
276 | * verify one mapping to a dummy sequence, one to a real one | |
277 | */ | |
278 | 1 | List<AlignedCodonFrame> mappings = af.getViewport().getAlignment() |
279 | .getDataset().getCodonFrames(); | |
280 | 1 | assertEquals(2, mappings.size()); |
281 | 1 | Iterator<AlignedCodonFrame> iter = mappings.iterator(); |
282 | ||
283 | // first mapping is to dummy sequence | |
284 | 1 | AlignedCodonFrame mapping = iter.next(); |
285 | 1 | Mapping[] mapList = mapping.getProtMappings(); |
286 | 1 | assertEquals(1, mapList.length); |
287 | 1 | assertTrue(mapList[0].getTo() instanceof SequenceDummy); |
288 | 1 | assertEquals("DDB_G0269124", mapList[0].getTo().getName()); |
289 | ||
290 | // 143 in protein should map to codon [11270, 11269, 11268] in dna | |
291 | 1 | int[] mappedRegion = mapList[0].getMap().locateInFrom(143, 143); |
292 | 1 | assertArrayEquals(new int[] { 11270, 11268 }, mappedRegion); |
293 | ||
294 | // second mapping is to a sequence in the alignment | |
295 | 1 | mapping = iter.next(); |
296 | 1 | mapList = mapping.getProtMappings(); |
297 | 1 | assertEquals(1, mapList.length); |
298 | 1 | SequenceI proteinSeq = af.getViewport().getAlignment() |
299 | .findName("DDB_G0280897"); | |
300 | 1 | assertSame(proteinSeq.getDatasetSequence(), mapList[0].getTo()); |
301 | 1 | assertEquals(1, mapping.getdnaToProt().length); |
302 | ||
303 | // 143 in protein should map to codon [11270, 11269, 11268] in dna | |
304 | 1 | mappedRegion = mapList[0].getMap().locateInFrom(143, 143); |
305 | 1 | assertArrayEquals(new int[] { 11270, 11268 }, mappedRegion); |
306 | ||
307 | // 182 in protein should map to codon [11153, 11152, 11151] in dna | |
308 | 1 | mappedRegion = mapList[0].getMap().locateInFrom(182, 182); |
309 | 1 | assertArrayEquals(new int[] { 11153, 11151 }, mappedRegion); |
310 | ||
311 | // and the reverse mapping: | |
312 | 1 | mappedRegion = mapList[0].getMap().locateInTo(11151, 11153); |
313 | 1 | assertArrayEquals(new int[] { 182, 182 }, mappedRegion); |
314 | ||
315 | // 11150 in dna should _not_ map to protein | |
316 | 1 | mappedRegion = mapList[0].getMap().locateInTo(11150, 11150); |
317 | 1 | assertNull(mappedRegion); |
318 | ||
319 | // similarly 183 in protein should _not_ map to dna | |
320 | 1 | mappedRegion = mapList[0].getMap().locateInFrom(183, 183); |
321 | 1 | assertNull(mappedRegion); |
322 | } | |
323 | } |