1 package jalview.analysis;
3 import static org.junit.Assert.assertEquals;
4 import jalview.datamodel.AlignmentI;
5 import jalview.datamodel.ColumnSelection;
6 import jalview.io.FormatAdapter;
8 import java.io.IOException;
9 import java.util.Arrays;
11 import org.junit.Test;
15 // AA encoding codons as ordered on the Jalview help page Amino Acid Table
16 private static String fasta = ">B\n" + "GCT" + "GCC" + "GCA" + "GCG"
17 + "TGT" + "TGC" + "GAT" + "GAC" + "GAA" + "GAG" + "TTT" + "TTC"
18 + "GGT" + "GGC" + "GGA" + "GGG" + "CAT" + "CAC" + "ATT" + "ATC"
19 + "ATA" + "AAA" + "AAG" + "TTG" + "TTA" + "CTT" + "CTC" + "CTA"
20 + "CTG" + "ATG" + "AAT" + "AAC" + "CCT" + "CCC" + "CCA" + "CCG"
21 + "CAA" + "CAG" + "CGT" + "CGC" + "CGA" + "CGG" + "AGA" + "AGG"
22 + "TCT" + "TCC" + "TCA" + "TCG" + "AGT" + "AGC" + "ACT" + "ACC"
23 + "ACA" + "ACG" + "GTT" + "GTC" + "GTA" + "GTG" + "TGG" + "TAT"
24 + "TAC" + "TAA" + "TAG" + "TGA";
27 * Test simple translation to Amino Acids (with STOP codons translated to X).
32 public void testCdnaTranslate_simple() throws IOException
34 AlignmentI alf = new FormatAdapter().readFile(fasta,
35 FormatAdapter.PASTE, "FASTA");
36 final String sequenceAsString = alf
37 .getSequenceAt(0).getSequenceAsString();
38 AlignmentI translated = Dna.cdnaTranslate(alf.getSequencesArray(),
40 { sequenceAsString }, new int[]
41 { 0, alf.getWidth() - 1 }, alf.getGapCharacter(), null,
42 alf.getWidth(), null);
43 String aa = translated.getSequenceAt(0).getSequenceAsString();
45 "AAAACCDDEEFFGGGGHHIIIKKLLLLLLMNNPPPPQQRRRRRRSSSSSSTTTTVVVVWYYXXX",
50 * Test translation excluding hidden columns.
55 public void testCdnaTranslate_hiddenColumns() throws IOException
57 AlignmentI alf = new FormatAdapter().readFile(fasta,
58 FormatAdapter.PASTE, "FASTA");
59 ColumnSelection cs = new jalview.datamodel.ColumnSelection();
60 cs.hideColumns(6, 14); // hide codons 3/4/5
61 cs.hideColumns(24, 35); // hide codons 9-12
62 cs.hideColumns(177, 191); // hide codons 60-64
63 AlignmentI translated = Dna.cdnaTranslate(alf.getSequencesArray(),
64 cs.getVisibleSequenceStrings(0, alf.getWidth(),
65 alf.getSequencesArray()), new int[]
66 { 0, alf.getWidth() - 1 }, alf.getGapCharacter(), null,
67 alf.getWidth(), null);
68 String aa = translated.getSequenceAt(0).getSequenceAsString();
69 assertEquals("AACDDGGGGHHIIIKKLLLLLLMNNPPPPQQRRRRRRSSSSSSTTTTVVVVW", aa);
73 * Tests for method that compares 'alignment' of two codon position triplets.
76 public void testCompareCodonPos()
79 * Returns 0 for any null argument
81 assertEquals(0, Dna.compareCodonPos(new int[]
83 assertEquals(0, Dna.compareCodonPos(null, new int[]
87 * Work through 27 combinations. First 9 cases where first position matches.
89 assertMatches("AAA", "GGG"); // 2 and 3 match
90 assertFollows("AA-A", "GGG"); // 2 matches, 3 shifted seq1
91 assertPrecedes("AAA", "GG-G"); // 2 matches, 3 shifted seq2
92 assertFollows("A-AA", "GG-G"); // 2 shifted seq1, 3 matches
93 assertFollows("A-A-A", "GG-G"); // 2 shifted seq1, 3 shifted seq1
94 // TODO is this right?
95 assertPrecedes("A-AA", "GG--G"); // 2 shifted seq1, 3 shifted seq2
96 assertPrecedes("AA-A", "G-GG"); // 2 shifted seq2, 3 matches
97 assertPrecedes("AA--A", "G-GG"); // 2 shifted seq2, 3 shifted seq1
98 assertPrecedes("AAA", "G-GG"); // 2 shifted seq2, 3 shifted seq2
101 * 9 cases where first position is shifted in first sequence.
103 assertFollows("-AAA", "G-GG"); // 2 and 3 match
104 assertFollows("-AA-A", "G-GG"); // 2 matches, 3 shifted seq1
105 assertPrecedes("-AAA", "G-G-G"); // 2 matches, 3 shifted seq2
106 assertFollows("-A-AA", "G-G-G"); // 2 shifted seq1, 3 matches
107 assertFollows("-A-A-A", "G-G-G"); // 2 shifted seq1, 3 shifted seq1
108 // is this right? codon2 ends after codon1
109 assertPrecedes("-A-AA", "G-G--G"); // 2 shifted seq1, 3 shifted seq2
110 assertPrecedes("-AA-A", "G--GG"); // 2 shifted seq2, 3 matches
111 assertPrecedes("-AA--A", "G--GG"); // 2 shifted seq2, 3 shifted seq1
112 assertPrecedes("-AAA", "G--GG"); // 2 shifted seq2, 3 shifted seq2
115 * 9 cases where first position is shifted in second sequence.
117 assertPrecedes("A-AA", "-GGG"); // 2 and 3 match
118 assertPrecedes("A-A-A", "-GGG"); // 2 matches, 3 shifted seq1
119 assertPrecedes("A-AA", "-GG-G"); // 2 matches, 3 shifted seq2
120 assertPrecedes("A--AA", "-GG-G"); // 2 shifted seq1, 3 matches
121 assertPrecedes("A--AA", "-GGG"); // 2 shifted seq1, 3 shifted seq1
122 assertPrecedes("A--AA", "-GG--G"); // 2 shifted seq1, 3 shifted seq2
123 assertPrecedes("AA-A", "-GGG"); // 2 shifted seq2, 3 matches
124 assertPrecedes("AA--A", "-GGG"); // 2 shifted seq2, 3 shifted seq1
125 assertPrecedes("AAA", "-GGG"); // 2 shifted seq2, 3 shifted seq2
128 * two codon positions can each 'precede' the other! the comparison is
129 * biased to the first sequence
131 // TODO is this correct?
132 assertPrecedes("-A--AA", "--GGG");
133 assertPrecedes("--AAA", "-A--AA");
137 * Assert that the first sequence should map to the same position as the
138 * second in a translated alignment
143 private void assertMatches(String codon1, String codon2)
145 assertEquals("Expected match (0)", 0, compare(codon1, codon2));
149 * Assert that the first sequence should precede the second in a translated
155 private void assertPrecedes(String codon1, String codon2)
157 assertEquals("Expected precedes (-1)", -1, compare(codon1, codon2));
161 * Assert that the first sequence should follow the second in a translated
167 private void assertFollows(String codon1, String codon2)
169 assertEquals("Expected follows (1)", 1, compare(codon1, codon2));
173 * Convert two nucleotide strings to base positions and pass to
174 * Dna.compareCodonPos, return the result.
180 private int compare(String s1, String s2)
182 final int[] cd1 = convertCodon(s1);
183 final int[] cd2 = convertCodon(s2);
184 System.out.println("K: " + s1 + " " + Arrays.toString(cd1));
185 System.out.println("G: " + s2 + " " + Arrays.toString(cd2));
186 System.out.println();
187 return Dna.compareCodonPos(cd1, cd2);
191 * Convert a string e.g. "-GC-T" to base positions e.g. [1, 2, 4]. The string
192 * should have exactly 3 non-gap characters, and use '-' for gaps.
197 private int[] convertCodon(String s)
199 int[] result = new int[3];
201 for (int j = 0; j < s.length(); j++)
203 if (s.charAt(j) != '-')
212 * Weirdly, maybe worth a test to prove the helper method of this test class.
215 public void testConvertCodon()
217 assertEquals("[0, 1, 2]", Arrays.toString(convertCodon("AAA")));
218 assertEquals("[0, 2, 5]", Arrays.toString(convertCodon("A-A--A")));
219 assertEquals("[1, 3, 4]", Arrays.toString(convertCodon("-A-AA-")));