Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
DnaTest | 46 | 199 | 23 |
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.analysis; | |
22 | ||
23 | import static org.testng.AssertJUnit.assertEquals; | |
24 | import static org.testng.AssertJUnit.assertNotNull; | |
25 | import static org.testng.AssertJUnit.assertTrue; | |
26 | ||
27 | import jalview.api.AlignViewportI; | |
28 | import jalview.datamodel.AlignedCodon; | |
29 | import jalview.datamodel.Alignment; | |
30 | import jalview.datamodel.AlignmentI; | |
31 | import jalview.datamodel.HiddenColumns; | |
32 | import jalview.datamodel.Sequence; | |
33 | import jalview.datamodel.SequenceI; | |
34 | import jalview.gui.AlignViewport; | |
35 | import jalview.gui.JvOptionPane; | |
36 | import jalview.io.DataSourceType; | |
37 | import jalview.io.FileFormat; | |
38 | import jalview.io.FormatAdapter; | |
39 | ||
40 | import java.io.IOException; | |
41 | import java.util.Iterator; | |
42 | ||
43 | import org.testng.annotations.BeforeClass; | |
44 | import org.testng.annotations.Test; | |
45 | ||
46 | public class DnaTest | |
47 | { | |
48 | 1 | @BeforeClass(alwaysRun = true) |
49 | public void setUpJvOptionPane() | |
50 | { | |
51 | 1 | JvOptionPane.setInteractiveMode(false); |
52 | 1 | JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION); |
53 | } | |
54 | ||
55 | // @formatter:off | |
56 | // AA encoding codons as ordered on the Jalview help page Amino Acid Table | |
57 | private static String fasta = ">B\n" + "GCT" + "GCC" + "GCA" + "GCG" | |
58 | + "TGT" + "TGC" + "GAT" + "GAC" + "GAA" + "GAG" + "TTT" + "TTC" | |
59 | + "GGT" + "GGC" + "GGA" + "GGG" + "CAT" + "CAC" + "ATT" + "ATC" | |
60 | + "ATA" + "AAA" + "AAG" + "TTG" + "TTA" + "CTT" + "CTC" + "CTA" | |
61 | + "CTG" + "ATG" + "AAT" + "AAC" + "CCT" + "CCC" + "CCA" + "CCG" | |
62 | + "CAA" + "CAG" + "CGT" + "CGC" + "CGA" + "CGG" + "AGA" + "AGG" | |
63 | + "TCT" + "TCC" + "TCA" + "TCG" + "AGT" + "AGC" + "ACT" + "ACC" | |
64 | + "ACA" + "ACG" + "GTT" + "GTC" + "GTA" + "GTG" + "TGG" + "TAT" | |
65 | + "TAC" + "TAA" + "TAG" + "TGA"; | |
66 | ||
67 | private static String JAL_1312_example_align_fasta = ">B.FR.83.HXB2_LAI_IIIB_BRU_K03455/45-306\n" | |
68 | + "ATGGGAAAAAATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATAAATTAAAACATATAGTATGGGCAAGCAG\n" | |
69 | + "GGAGCTAGAACGATTCGCAGTTAATCCTGGCCTGTTAGAAACATCAGAAGGCTGTAGACAAATACTGGGACA\n" | |
70 | + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAGATCATTATATAATACAGTAGCAACCCTCTATTG\n" | |
71 | + "TGTGCATCAAAGGATAGAGATAAAAGACACCAAGGAAGCTTTAGAC\n" | |
72 | + ">gi|27804621|gb|AY178912.1|/1-259\n" | |
73 | + "-TGGGAGAA-ATTCGGTT-CGGCCAGGGGGAAAGAAAAAATATCAGTTAAAACATATAGTATGGGCAAGCAG\n" | |
74 | + "AGAGCTAGAACGATTCGCAGTTAACCCTGGCCTTTTAGAGACATCACAAGGCTGTAGACAAATACTGGGACA\n" | |
75 | + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" | |
76 | + "TGTTCATCAAAGGATAGATATAAAAGACACCAAGGAAGCTTTAGAT\n" | |
77 | + ">gi|27804623|gb|AY178913.1|/1-259\n" | |
78 | + "-TGGGAGAA-ATTCGGTT-CGGCCAGGGGGAAAGAAAAAATATCAGTTAAAACATATAGTATGGGCAAGCAG\n" | |
79 | + "AGAGCTAGAACGATTCGCAGTTAACCCTGGCCTTTTAGAGACATCACAAGGCTGTAGACAAATACTGGAACA\n" | |
80 | + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" | |
81 | + "TGTTCATCAAAGGATAGATGTAAAAGACACCAAGGAAGCTTTAGAT\n" | |
82 | + ">gi|27804627|gb|AY178915.1|/1-260\n" | |
83 | + "-TGGGAAAA-ATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATAAGTTAAAACATATAGTATGGGCAAGCAG\n" | |
84 | + "GGAGCTAGAACGATTCGCAGTTAACCCTGGCCTGTTAGAAACATCAGAAGGTTGTAGACAAATATTGGGACA\n" | |
85 | + "GCTACAACCATCCCTTGAGACAGGATCAGAAGAACTTAAATCATTATWTAATACCATAGCAGTCCTCTATTG\n" | |
86 | + "TGTACATCAAAGGATAGATATAAAAGACACCAAGGAAGCTTTAGAG\n" | |
87 | + ">gi|27804631|gb|AY178917.1|/1-261\n" | |
88 | + "-TGGGAAAAAATTCGGTTGAGGCCAGGGGGAAAGAAAAAATATAAGTTAAAACATATAGTATGGGCAAGCAG\n" | |
89 | + "GGAGCTAGAACGATTCGCAGTCAACCCTGGCCTGTTAGAAACACCAGAAGGCTGTAGACAAATACTGGGACA\n" | |
90 | + "GCTACAACCGTCCCTTCAGACAGGATCGGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" | |
91 | + "TGTGCATCAAAGGATAGATGTAAAAGACACCAAGGAGGCTTTAGAC\n" | |
92 | + ">gi|27804635|gb|AY178919.1|/1-261\n" | |
93 | + "-TGGGAGAGAATTCGGTTACGGCCAGGAGGAAAGAAAAAATATAAATTGAAACATATAGTATGGGCAGGCAG\n" | |
94 | + "AGAGCTAGATCGATTCGCAGTCAATCCTGGCCTGTTAGAAACATCAGAAGGCTGCAGACAGATATTGGGACA\n" | |
95 | + "GCTACAACCGTCCCTTAAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" | |
96 | + "TGTACATCAAAGGATAGATGTAAAAGACACCAAGGAAGCTTTAGAT\n" | |
97 | + ">gi|27804641|gb|AY178922.1|/1-261\n" | |
98 | + "-TGGGAGAAAATTCGGTTACGGCCAGGGGGAAAGAAAAGATATAAGTTAAAACATATAGTATGGGCAAGCAG\n" | |
99 | + "GGAGCTAGAACGATTCGCAGTCAACCCTGGCCTGTTAGAAACATCAGAAGGCTGCAGACAAATACTGGGACA\n" | |
100 | + "GTTACACCCATCCCTTCATACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" | |
101 | + "TGTGCATCAAAGGATAGAAGTAAAAGACACCAAGGAAGCTTTAGAC\n" | |
102 | + ">gi|27804647|gb|AY178925.1|/1-261\n" | |
103 | + "-TGGGAAAAAATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATCAATTAAAACATGTAGTATGGGCAAGCAG\n" | |
104 | + "GGAACTAGAACGATTCGCAGTTAATCCTGGCCTGTTAGAAACATCAGAAGGCTGTAGACAAATATTGGGACA\n" | |
105 | + "GCTACAACCATCCCTTCAGACAGGATCAGAGGAACTTAAATCATTATTTAATACAGTAGCAGTCCTCTATTG\n" | |
106 | + "TGTACATCAAAGAATAGATGTAAAAGACACCAAGGAAGCTCTAGAA\n" | |
107 | + ">gi|27804649|gb|AY178926.1|/1-261\n" | |
108 | + "-TGGGAAAAAATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATAAGTTAAAACATATAGTATGGGCAAGCAG\n" | |
109 | + "GGAGCTAGAACGATTCGCGGTCAATCCTGGCCTGTTAGAAACATCAGAAGGCTGTAGACAACTACTGGGACA\n" | |
110 | + "GTTACAACCATCCCTTCAGACAGGATCAGAAGAACTCAAATCATTATATAATACAATAGCAACCCTCTATTG\n" | |
111 | + "TGTGCATCAAAGGATAGAGATAAAAGACACCAAGGAAGCCTTAGAT\n" | |
112 | + ">gi|27804653|gb|AY178928.1|/1-261\n" | |
113 | + "-TGGGAAAGAATTCGGTTAAGGCCAGGGGGAAAGAAACAATATAAATTAAAACATATAGTATGGGCAAGCAG\n" | |
114 | + "GGAGCTAGACCGATTCGCACTTAACCCCGGCCTGTTAGAAACATCAGAAGGCTGTAGACAAATATTGGGACA\n" | |
115 | + "GCTACAATCGTCCCTTCAGACAGGATCAGAAGAACTTAGATCACTATATAATACAGTAGCAGTCCTCTATTG\n" | |
116 | + "TGTGCATCAAAAGATAGATGTAAAAGACACCAAGGAAGCCTTAGAC\n" | |
117 | + ">gi|27804659|gb|AY178931.1|/1-261\n" | |
118 | + "-TGGGAAAAAATTCGGTTACGGCCAGGAGGAAAGAAAAGATATAAATTAAAACATATAGTATGGGCAAGCAG\n" | |
119 | + "GGAGCTAGAACGATTYGCAGTTAATCCTGGCCTTTTAGAAACAGCAGAAGGCTGTAGACAAATACTGGGACA\n" | |
120 | + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" | |
121 | + "TGTACATCAAAGGATAGAGATAAAAGACACCAAGGAAGCTTTAGAA\n"; | |
122 | // @formatter:on | |
123 | ||
124 | /** | |
125 | * Corner case for this test is the presence of codons after codons that were | |
126 | * not translated. | |
127 | * | |
128 | * @throws IOException | |
129 | */ | |
130 | 1 | @Test(groups = { "Functional" }) |
131 | public void testTranslateCdna_withUntranslatableCodons() | |
132 | throws IOException | |
133 | { | |
134 | 1 | AlignmentI alf = new FormatAdapter().readFile( |
135 | JAL_1312_example_align_fasta, DataSourceType.PASTE, | |
136 | FileFormat.Fasta); | |
137 | 1 | HiddenColumns cs = new HiddenColumns(); |
138 | 1 | AlignViewportI av = new AlignViewport(alf, cs); |
139 | 1 | Iterator<int[]> contigs = cs.getVisContigsIterator(0, alf.getWidth(), |
140 | false); | |
141 | 1 | Dna dna = new Dna(av, contigs); |
142 | 1 | AlignmentI translated = dna.translateCdna( |
143 | GeneticCodes.getInstance().getStandardCodeTable()); | |
144 | 1 | assertNotNull("Couldn't do a full width translation of test data.", |
145 | translated); | |
146 | } | |
147 | ||
148 | /** | |
149 | * Test variant in which 15 column blocks at a time are translated (the rest | |
150 | * hidden). | |
151 | * | |
152 | * @throws IOException | |
153 | */ | |
154 | 1 | @Test(groups = { "Functional" }) |
155 | public void testTranslateCdna_withUntranslatableCodonsAndHiddenColumns() | |
156 | throws IOException | |
157 | { | |
158 | 1 | AlignmentI alf = new FormatAdapter().readFile( |
159 | JAL_1312_example_align_fasta, DataSourceType.PASTE, | |
160 | FileFormat.Fasta); | |
161 | 1 | int vwidth = 15; |
162 | 18 | for (int ipos = 0; ipos + vwidth < alf.getWidth(); ipos += vwidth) |
163 | { | |
164 | 17 | HiddenColumns cs = new HiddenColumns(); |
165 | 17 | if (ipos > 0) |
166 | { | |
167 | 16 | cs.hideColumns(0, ipos - 1); |
168 | } | |
169 | 17 | cs.hideColumns(ipos + vwidth, alf.getWidth()); |
170 | 17 | Iterator<int[]> vcontigs = cs.getVisContigsIterator(0, alf.getWidth(), |
171 | false); | |
172 | 17 | AlignViewportI av = new AlignViewport(alf, cs); |
173 | 17 | Dna dna = new Dna(av, vcontigs); |
174 | 17 | AlignmentI transAlf = dna.translateCdna( |
175 | GeneticCodes.getInstance().getStandardCodeTable()); | |
176 | ||
177 | 17 | assertTrue( |
178 | "Translation failed (ipos=" + ipos + ") No alignment data.", | |
179 | transAlf != null); | |
180 | 17 | assertTrue("Translation failed (ipos=" + ipos + ") Empty alignment.", |
181 | transAlf.getHeight() > 0); | |
182 | 17 | assertTrue( |
183 | "Translation failed (ipos=" + ipos + ") Translated " | |
184 | + transAlf.getHeight() + " sequences from " | |
185 | + alf.getHeight() + " sequences", | |
186 | alf.getHeight() == transAlf.getHeight()); | |
187 | } | |
188 | } | |
189 | ||
190 | /** | |
191 | * Test simple translation to Amino Acids (with STOP codons translated to *). | |
192 | * | |
193 | * @throws IOException | |
194 | */ | |
195 | 1 | @Test(groups = { "Functional" }) |
196 | public void testTranslateCdna_simple() throws IOException | |
197 | { | |
198 | 1 | AlignmentI alf = new FormatAdapter().readFile(fasta, |
199 | DataSourceType.PASTE, FileFormat.Fasta); | |
200 | 1 | HiddenColumns cs = new HiddenColumns(); |
201 | 1 | AlignViewportI av = new AlignViewport(alf, cs); |
202 | 1 | Iterator<int[]> contigs = cs.getVisContigsIterator(0, alf.getWidth(), |
203 | false); | |
204 | 1 | Dna dna = new Dna(av, contigs); |
205 | 1 | AlignmentI translated = dna.translateCdna( |
206 | GeneticCodes.getInstance().getStandardCodeTable()); | |
207 | 1 | String aa = translated.getSequenceAt(0).getSequenceAsString(); |
208 | 1 | assertEquals( |
209 | "AAAACCDDEEFFGGGGHHIIIKKLLLLLLMNNPPPPQQRRRRRRSSSSSSTTTTVVVVWYY***", | |
210 | aa); | |
211 | } | |
212 | ||
213 | /** | |
214 | * Test translation excluding hidden columns. | |
215 | * | |
216 | * @throws IOException | |
217 | */ | |
218 | 1 | @Test(groups = { "Functional" }) |
219 | public void testTranslateCdna_hiddenColumns() throws IOException | |
220 | { | |
221 | 1 | AlignmentI alf = new FormatAdapter().readFile(fasta, |
222 | DataSourceType.PASTE, FileFormat.Fasta); | |
223 | 1 | HiddenColumns cs = new HiddenColumns(); |
224 | 1 | cs.hideColumns(6, 14); // hide codons 3/4/5 |
225 | 1 | cs.hideColumns(24, 35); // hide codons 9-12 |
226 | 1 | cs.hideColumns(177, 191); // hide codons 60-64 |
227 | 1 | AlignViewportI av = new AlignViewport(alf, cs); |
228 | 1 | Iterator<int[]> contigs = cs.getVisContigsIterator(0, alf.getWidth(), |
229 | false); | |
230 | 1 | Dna dna = new Dna(av, contigs); |
231 | 1 | AlignmentI translated = dna.translateCdna( |
232 | GeneticCodes.getInstance().getStandardCodeTable()); | |
233 | 1 | String aa = translated.getSequenceAt(0).getSequenceAsString(); |
234 | 1 | assertEquals("AACDDGGGGHHIIIKKLLLLLLMNNPPPPQQRRRRRRSSSSSSTTTTVVVVW", |
235 | aa); | |
236 | } | |
237 | ||
238 | /** | |
239 | * Use this test to help debug into any cases of interest. | |
240 | */ | |
241 | 1 | @Test(groups = { "Functional" }) |
242 | public void testCompareCodonPos_oneOnly() | |
243 | { | |
244 | 1 | assertFollows("-AA--A", "G--GG"); // 2 shifted seq2, 3 shifted seq1 |
245 | } | |
246 | ||
247 | /** | |
248 | * Tests for method that compares 'alignment' of two codon position triplets. | |
249 | */ | |
250 | 1 | @Test(groups = { "Functional" }) |
251 | public void testCompareCodonPos() | |
252 | { | |
253 | /* | |
254 | * Returns 0 for any null argument | |
255 | */ | |
256 | 1 | assertEquals(0, Dna.compareCodonPos(new AlignedCodon(1, 2, 3), null)); |
257 | 1 | assertEquals(0, Dna.compareCodonPos(null, new AlignedCodon(1, 2, 3))); |
258 | ||
259 | /* | |
260 | * Work through 27 combinations. First 9 cases where first position matches. | |
261 | */ | |
262 | 1 | assertMatches("AAA", "GGG"); // 2 and 3 match |
263 | 1 | assertFollows("AA-A", "GGG"); // 2 matches, 3 shifted seq1 |
264 | 1 | assertPrecedes("AAA", "GG-G"); // 2 matches, 3 shifted seq2 |
265 | 1 | assertFollows("A-AA", "GG-G"); // 2 shifted seq1, 3 matches |
266 | 1 | assertFollows("A-A-A", "GG-G"); // 2 shifted seq1, 3 shifted seq1 |
267 | 1 | assertPrecedes("A-AA", "GG--G"); // 2 shifted seq1, 3 shifted seq2 |
268 | 1 | assertPrecedes("AA-A", "G-GG"); // 2 shifted seq2, 3 matches |
269 | 1 | assertFollows("AA--A", "G-GG"); // 2 shifted seq2, 3 shifted seq1 |
270 | 1 | assertPrecedes("AAA", "G-GG"); // 2 shifted seq2, 3 shifted seq2 |
271 | ||
272 | /* | |
273 | * 9 cases where first position is shifted in first sequence. | |
274 | */ | |
275 | 1 | assertFollows("-AAA", "G-GG"); // 2 and 3 match |
276 | 1 | assertFollows("-AA-A", "G-GG"); // 2 matches, 3 shifted seq1 |
277 | // 'enclosing' case: pick first to start precedes | |
278 | 1 | assertFollows("-AAA", "G-G-G"); // 2 matches, 3 shifted seq2 |
279 | 1 | assertFollows("-A-AA", "G-G-G"); // 2 shifted seq1, 3 matches |
280 | 1 | assertFollows("-A-A-A", "G-G-G"); // 2 shifted seq1, 3 shifted seq1 |
281 | // 'enclosing' case: pick first to start precedes | |
282 | 1 | assertFollows("-A-AA", "G-G--G"); // 2 shifted seq1, 3 shifted seq2 |
283 | 1 | assertFollows("-AA-A", "G--GG"); // 2 shifted seq2, 3 matches |
284 | 1 | assertFollows("-AA--A", "G--GG"); // 2 shifted seq2, 3 shifted seq1 |
285 | 1 | assertPrecedes("-AAA", "G--GG"); // 2 shifted seq2, 3 shifted seq2 |
286 | ||
287 | /* | |
288 | * 9 cases where first position is shifted in second sequence. | |
289 | */ | |
290 | 1 | assertPrecedes("A-AA", "-GGG"); // 2 and 3 match |
291 | 1 | assertPrecedes("A-A-A", "-GGG"); // 2 matches, 3 shifted seq1 |
292 | 1 | assertPrecedes("A-AA", "-GG-G"); // 2 matches, 3 shifted seq2 |
293 | 1 | assertPrecedes("A--AA", "-GG-G"); // 2 shifted seq1, 3 matches |
294 | // 'enclosing' case with middle base deciding: | |
295 | 1 | assertFollows("A--AA", "-GGG"); // 2 shifted seq1, 3 shifted seq1 |
296 | 1 | assertPrecedes("A--AA", "-GG--G"); // 2 shifted seq1, 3 shifted seq2 |
297 | 1 | assertPrecedes("AA-A", "-GGG"); // 2 shifted seq2, 3 matches |
298 | 1 | assertPrecedes("AA--A", "-GGG"); // 2 shifted seq2, 3 shifted seq1 |
299 | 1 | assertPrecedes("AAA", "-GGG"); // 2 shifted seq2, 3 shifted seq2 |
300 | } | |
301 | ||
302 | /** | |
303 | * This test generates a random cDNA alignment and its translation, then | |
304 | * reorders the cDNA and retranslates, and verifies that the translations are | |
305 | * the same (apart from ordering). | |
306 | */ | |
307 | 1 | @Test(groups = { "Functional" }) |
308 | public void testTranslateCdna_sequenceOrderIndependent() | |
309 | { | |
310 | /* | |
311 | * Generate cDNA - 8 sequences of 12 bases each. | |
312 | */ | |
313 | 1 | AlignmentI cdna = new AlignmentGenerator(true).generate(12, 8, 97, 5, |
314 | 5); | |
315 | 1 | HiddenColumns cs = new HiddenColumns(); |
316 | 1 | AlignViewportI av = new AlignViewport(cdna, cs); |
317 | 1 | Iterator<int[]> contigs = cs.getVisContigsIterator(0, cdna.getWidth(), |
318 | false); | |
319 | 1 | Dna dna = new Dna(av, contigs); |
320 | 1 | AlignmentI translated = dna.translateCdna( |
321 | GeneticCodes.getInstance().getStandardCodeTable()); | |
322 | ||
323 | /* | |
324 | * Jumble the cDNA sequences and translate. | |
325 | */ | |
326 | 1 | SequenceI[] sorted = new SequenceI[cdna.getHeight()]; |
327 | 1 | final int[] jumbler = new int[] { 6, 7, 3, 4, 2, 0, 1, 5 }; |
328 | 1 | int seqNo = 0; |
329 | 1 | for (int i : jumbler) |
330 | { | |
331 | 8 | sorted[seqNo++] = cdna.getSequenceAt(i); |
332 | } | |
333 | 1 | AlignmentI cdnaReordered = new Alignment(sorted); |
334 | 1 | av = new AlignViewport(cdnaReordered, cs); |
335 | 1 | contigs = cs.getVisContigsIterator(0, cdna.getWidth(), false); |
336 | 1 | dna = new Dna(av, contigs); |
337 | 1 | AlignmentI translated2 = dna.translateCdna( |
338 | GeneticCodes.getInstance().getStandardCodeTable()); | |
339 | ||
340 | /* | |
341 | * Check translated sequences are the same in both alignments. | |
342 | */ | |
343 | 1 | System.out.println("Original"); |
344 | 1 | System.out.println(translated.toString()); |
345 | 1 | System.out.println("Sorted"); |
346 | 1 | System.out.println(translated2.toString()); |
347 | ||
348 | 1 | int sortedSequenceIndex = 0; |
349 | 1 | for (int originalSequenceIndex : jumbler) |
350 | { | |
351 | 8 | final String translation1 = translated |
352 | .getSequenceAt(originalSequenceIndex).getSequenceAsString(); | |
353 | 8 | final String translation2 = translated2 |
354 | .getSequenceAt(sortedSequenceIndex).getSequenceAsString(); | |
355 | 8 | assertEquals(translation2, translation1); |
356 | 8 | sortedSequenceIndex++; |
357 | } | |
358 | } | |
359 | ||
360 | /** | |
361 | * Test that all the cases in testCompareCodonPos have a 'symmetric' | |
362 | * comparison (without checking the actual comparison result). | |
363 | */ | |
364 | 1 | @Test(groups = { "Functional" }) |
365 | public void testCompareCodonPos_isSymmetric() | |
366 | { | |
367 | 1 | assertSymmetric("AAA", "GGG"); |
368 | 1 | assertSymmetric("AA-A", "GGG"); |
369 | 1 | assertSymmetric("AAA", "GG-G"); |
370 | 1 | assertSymmetric("A-AA", "GG-G"); |
371 | 1 | assertSymmetric("A-A-A", "GG-G"); |
372 | 1 | assertSymmetric("A-AA", "GG--G"); |
373 | 1 | assertSymmetric("AA-A", "G-GG"); |
374 | 1 | assertSymmetric("AA--A", "G-GG"); |
375 | 1 | assertSymmetric("AAA", "G-GG"); |
376 | 1 | assertSymmetric("-AAA", "G-GG"); |
377 | 1 | assertSymmetric("-AA-A", "G-GG"); |
378 | 1 | assertSymmetric("-AAA", "G-G-G"); |
379 | 1 | assertSymmetric("-A-AA", "G-G-G"); |
380 | 1 | assertSymmetric("-A-A-A", "G-G-G"); |
381 | 1 | assertSymmetric("-A-AA", "G-G--G"); |
382 | 1 | assertSymmetric("-AA-A", "G--GG"); |
383 | 1 | assertSymmetric("-AA--A", "G--GG"); |
384 | 1 | assertSymmetric("-AAA", "G--GG"); |
385 | 1 | assertSymmetric("A-AA", "-GGG"); |
386 | 1 | assertSymmetric("A-A-A", "-GGG"); |
387 | 1 | assertSymmetric("A-AA", "-GG-G"); |
388 | 1 | assertSymmetric("A--AA", "-GG-G"); |
389 | 1 | assertSymmetric("A--AA", "-GGG"); |
390 | 1 | assertSymmetric("A--AA", "-GG--G"); |
391 | 1 | assertSymmetric("AA-A", "-GGG"); |
392 | 1 | assertSymmetric("AA--A", "-GGG"); |
393 | 1 | assertSymmetric("AAA", "-GGG"); |
394 | } | |
395 | ||
396 | 27 | private void assertSymmetric(String codon1, String codon2) |
397 | { | |
398 | 27 | assertEquals( |
399 | "Comparison of '" + codon1 + "' and '" + codon2 | |
400 | + " not symmetric", | |
401 | Integer.signum(compare(codon1, codon2)), | |
402 | -Integer.signum(compare(codon2, codon1))); | |
403 | } | |
404 | ||
405 | /** | |
406 | * Assert that the first sequence should map to the same position as the | |
407 | * second in a translated alignment. Also checks that this is true if the | |
408 | * order of the codons is reversed. | |
409 | * | |
410 | * @param codon1 | |
411 | * @param codon2 | |
412 | */ | |
413 | 1 | private void assertMatches(String codon1, String codon2) |
414 | { | |
415 | 1 | assertEquals("Expected '" + codon1 + "' matches '" + codon2 + "'", 0, |
416 | compare(codon1, codon2)); | |
417 | 1 | assertEquals("Expected '" + codon2 + "' matches '" + codon1 + "'", 0, |
418 | compare(codon2, codon1)); | |
419 | } | |
420 | ||
421 | /** | |
422 | * Assert that the first sequence should precede the second in a translated | |
423 | * alignment | |
424 | * | |
425 | * @param codon1 | |
426 | * @param codon2 | |
427 | */ | |
428 | 13 | private void assertPrecedes(String codon1, String codon2) |
429 | { | |
430 | 13 | assertEquals("Expected '" + codon1 + "' precedes '" + codon2 + "'", -1, |
431 | compare(codon1, codon2)); | |
432 | } | |
433 | ||
434 | /** | |
435 | * Assert that the first sequence should follow the second in a translated | |
436 | * alignment | |
437 | * | |
438 | * @param codon1 | |
439 | * @param codon2 | |
440 | */ | |
441 | 14 | private void assertFollows(String codon1, String codon2) |
442 | { | |
443 | 14 | assertEquals("Expected '" + codon1 + "' follows '" + codon2 + "'", 1, |
444 | compare(codon1, codon2)); | |
445 | } | |
446 | ||
447 | /** | |
448 | * Convert two nucleotide strings to base positions and pass to | |
449 | * Dna.compareCodonPos, return the result. | |
450 | * | |
451 | * @param s1 | |
452 | * @param s2 | |
453 | * @return | |
454 | */ | |
455 | 83 | private int compare(String s1, String s2) |
456 | { | |
457 | 83 | final AlignedCodon cd1 = convertCodon(s1); |
458 | 83 | final AlignedCodon cd2 = convertCodon(s2); |
459 | 83 | System.out.println("K: " + s1 + " " + cd1.toString()); |
460 | 83 | System.out.println("G: " + s2 + " " + cd2.toString()); |
461 | 83 | System.out.println(); |
462 | 83 | return Dna.compareCodonPos(cd1, cd2); |
463 | } | |
464 | ||
465 | /** | |
466 | * Convert a string e.g. "-GC-T" to base positions e.g. [1, 2, 4]. The string | |
467 | * should have exactly 3 non-gap characters, and use '-' for gaps. | |
468 | * | |
469 | * @param s | |
470 | * @return | |
471 | */ | |
472 | 169 | private AlignedCodon convertCodon(String s) |
473 | { | |
474 | 169 | int[] codon = new int[3]; |
475 | 169 | int i = 0; |
476 | 915 | for (int j = 0; j < s.length(); j++) |
477 | { | |
478 | 746 | if (s.charAt(j) != '-') |
479 | { | |
480 | 507 | codon[i++] = j; |
481 | } | |
482 | } | |
483 | 169 | return new AlignedCodon(codon[0], codon[1], codon[2]); |
484 | } | |
485 | ||
486 | /** | |
487 | * Weirdly, maybe worth a test to prove the helper method of this test class. | |
488 | */ | |
489 | 1 | @Test(groups = { "Functional" }) |
490 | public void testConvertCodon() | |
491 | { | |
492 | 1 | assertEquals("[0, 1, 2]", convertCodon("AAA").toString()); |
493 | 1 | assertEquals("[0, 2, 5]", convertCodon("A-A--A").toString()); |
494 | 1 | assertEquals("[1, 3, 4]", convertCodon("-A-AA-").toString()); |
495 | } | |
496 | ||
497 | /** | |
498 | * Test dna complementing | |
499 | */ | |
500 | 1 | @Test(groups = "Functional") |
501 | public void testGetComplement() | |
502 | { | |
503 | 1 | assertEquals('t', Dna.getComplement('a')); |
504 | 1 | assertEquals('T', Dna.getComplement('A')); |
505 | 1 | assertEquals('a', Dna.getComplement('t')); |
506 | 1 | assertEquals('A', Dna.getComplement('T')); |
507 | 1 | assertEquals('c', Dna.getComplement('g')); |
508 | 1 | assertEquals('C', Dna.getComplement('G')); |
509 | 1 | assertEquals('g', Dna.getComplement('c')); |
510 | 1 | assertEquals('G', Dna.getComplement('C')); |
511 | // note uU --> aA but not vice versa | |
512 | 1 | assertEquals('a', Dna.getComplement('u')); |
513 | 1 | assertEquals('A', Dna.getComplement('U')); |
514 | // ambiguity codes, see http://www.bioinformatics.org/sms/iupac.html | |
515 | 1 | assertEquals('r', Dna.getComplement('y')); |
516 | 1 | assertEquals('R', Dna.getComplement('Y')); |
517 | 1 | assertEquals('y', Dna.getComplement('r')); |
518 | 1 | assertEquals('Y', Dna.getComplement('R')); |
519 | 1 | assertEquals('k', Dna.getComplement('m')); |
520 | 1 | assertEquals('K', Dna.getComplement('M')); |
521 | 1 | assertEquals('m', Dna.getComplement('k')); |
522 | 1 | assertEquals('M', Dna.getComplement('K')); |
523 | 1 | assertEquals('b', Dna.getComplement('v')); |
524 | 1 | assertEquals('B', Dna.getComplement('V')); |
525 | 1 | assertEquals('v', Dna.getComplement('b')); |
526 | 1 | assertEquals('V', Dna.getComplement('B')); |
527 | 1 | assertEquals('d', Dna.getComplement('h')); |
528 | 1 | assertEquals('D', Dna.getComplement('H')); |
529 | 1 | assertEquals('h', Dna.getComplement('d')); |
530 | 1 | assertEquals('H', Dna.getComplement('D')); |
531 | 1 | assertEquals('Q', Dna.getComplement('Q')); |
532 | } | |
533 | ||
534 | 1 | @Test(groups = "Functional") |
535 | public void testReverseSequence() | |
536 | { | |
537 | 1 | String seq = "-Ac-GtU--rYkMbVdHNX-"; |
538 | 1 | String seqRev = new StringBuilder(seq).reverse().toString(); |
539 | ||
540 | // reverse: | |
541 | 1 | SequenceI reversed = Dna.reverseSequence("Seq1", seq, false); |
542 | 1 | assertEquals(1, reversed.getStart()); |
543 | 1 | assertEquals(15, reversed.getEnd()); |
544 | 1 | assertEquals(20, reversed.getLength()); |
545 | 1 | assertEquals(seqRev, reversed.getSequenceAsString()); |
546 | 1 | assertEquals("Seq1|rev", reversed.getName()); |
547 | ||
548 | // reverse complement: | |
549 | 1 | SequenceI revcomp = Dna.reverseSequence("Seq1", seq, true); |
550 | 1 | assertEquals("-XNDhBvKmRy--AaC-gT-", revcomp.getSequenceAsString()); |
551 | 1 | assertEquals("Seq1|revcomp", revcomp.getName()); |
552 | } | |
553 | ||
554 | 1 | @Test(groups = "Functional") |
555 | public void testReverseCdna() | |
556 | { | |
557 | 1 | String seq = "-Ac-GtU--rYkMbVdHNX-"; |
558 | 1 | String seqRev = new StringBuilder(seq).reverse().toString(); |
559 | 1 | String seqDs = seq.replaceAll("-", ""); |
560 | 1 | String seqDsRev = new StringBuilder(seqDs).reverse().toString(); |
561 | ||
562 | 1 | SequenceI dna = new Sequence("Seq1", seq); |
563 | 1 | Alignment al = new Alignment(new SequenceI[] { dna }); |
564 | 1 | al.createDatasetAlignment(); |
565 | 1 | assertEquals(seqDs, |
566 | al.getSequenceAt(0).getDatasetSequence().getSequenceAsString()); | |
567 | ||
568 | 1 | HiddenColumns cs = new HiddenColumns(); |
569 | 1 | AlignViewportI av = new AlignViewport(al, cs); |
570 | 1 | Iterator<int[]> contigs = cs.getVisContigsIterator(0, al.getWidth(), |
571 | false); | |
572 | 1 | Dna testee = new Dna(av, contigs); |
573 | 1 | AlignmentI reversed = testee.reverseCdna(false); |
574 | 1 | assertEquals(1, reversed.getHeight()); |
575 | 1 | assertEquals(seqRev, reversed.getSequenceAt(0).getSequenceAsString()); |
576 | 1 | assertEquals(seqDsRev, reversed.getSequenceAt(0).getDatasetSequence() |
577 | .getSequenceAsString()); | |
578 | } | |
579 | } |