1 package jalview.analysis.scoremodels;
2 import static org.testng.Assert.assertEquals;
3 import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
5 import jalview.math.MatrixI;
7 import org.testng.annotations.Test;
9 public class ScoreMatrixTest
11 @Test(groups = "Functional")
12 public void testConstructor()
14 // note score matrix does not have to be symmetric (though it should be!)
15 float[][] scores = new float[3][];
16 scores[0] = new float[] { 1f, 2f, 3f };
17 scores[1] = new float[] { 4f, 5f, 6f };
18 scores[2] = new float[] { 7f, 8f, 9f };
19 ScoreMatrix sm = new ScoreMatrix("Test", "ABC".toCharArray(), scores);
20 assertEquals(sm.getSize(), 3);
21 assertArrayEquals(scores, sm.getMatrix());
22 assertEquals(sm.getPairwiseScore('A', 'a'), 1f);
23 assertEquals(sm.getPairwiseScore('b', 'c'), 6f);
24 assertEquals(sm.getPairwiseScore('c', 'b'), 8f);
25 assertEquals(sm.getPairwiseScore('A', 'D'), 0f);
26 assertEquals(sm.getMatrixIndex('c'), 2);
27 assertEquals(sm.getMatrixIndex(' '), -1);
31 groups = "Functional",
32 expectedExceptions = { IllegalArgumentException.class })
33 public void testConstructor_matrixTooSmall()
35 float[][] scores = new float[2][];
36 scores[0] = new float[] { 1f, 2f };
37 scores[1] = new float[] { 3f, 4f };
38 new ScoreMatrix("Test", "ABC".toCharArray(), scores);
42 groups = "Functional",
43 expectedExceptions = { IllegalArgumentException.class })
44 public void testConstructor_matrixTooBig()
46 float[][] scores = new float[2][];
47 scores[0] = new float[] { 1f, 2f };
48 scores[1] = new float[] { 3f, 4f };
49 new ScoreMatrix("Test", "A".toCharArray(), scores);
53 groups = "Functional",
54 expectedExceptions = { IllegalArgumentException.class })
55 public void testConstructor_matrixNotSquare()
57 float[][] scores = new float[2][];
58 scores[0] = new float[] { 1f, 2f };
59 scores[1] = new float[] { 3f };
60 new ScoreMatrix("Test", "AB".toCharArray(), scores);
63 @Test(groups = "Functional")
64 public void testBuildSymbolIndex()
66 short[] index = ScoreMatrix.buildSymbolIndex("AX-. yxYp".toCharArray());
68 assertEquals(index.length, 128); // ASCII character set size
70 assertEquals(index['A'], 0);
71 assertEquals(index['a'], 0); // lower-case mapping added
72 assertEquals(index['X'], 1);
73 assertEquals(index['-'], 2);
74 assertEquals(index['.'], 3);
75 assertEquals(index[' '], 4);
76 assertEquals(index['y'], 5); // lower-case override
77 assertEquals(index['x'], 6); // lower-case override
78 assertEquals(index['Y'], 7);
79 assertEquals(index['p'], 8);
80 assertEquals(index['P'], -1); // lower-case doesn't map upper-case
83 * check all unmapped symbols have index for unmapped
85 for (int c = 0; c < index.length; c++)
87 if (!"AaXx-. Yyp".contains(String.valueOf((char) c)))
89 assertEquals(index[c], -1);
95 * check that characters not in the basic ASCII set are simply ignored
97 @Test(groups = "Functional")
98 public void testBuildSymbolIndex_nonAscii()
100 char[] weird = new char[] { 128, 245, 'P' };
101 short[] index = ScoreMatrix.buildSymbolIndex(weird);
102 assertEquals(index.length, 128);
103 assertEquals(index['P'], 2);
104 assertEquals(index['p'], 2);
105 for (int c = 0; c < index.length; c++)
107 if (c != 'P' && c != 'p')
109 assertEquals(index[c], -1);
114 @Test(groups = "Functional")
115 public void testGetMatrixIndex()
117 ScoreMatrix sm = ScoreModels.getInstance().getBlosum62();
118 assertEquals(sm.getMatrixIndex('A'), 0);
119 assertEquals(sm.getMatrixIndex('R'), 1);
120 assertEquals(sm.getMatrixIndex('r'), 1);
121 assertEquals(sm.getMatrixIndex('N'), 2);
122 assertEquals(sm.getMatrixIndex('D'), 3);
123 assertEquals(sm.getMatrixIndex('X'), 22);
124 assertEquals(sm.getMatrixIndex('x'), 22);
125 assertEquals(sm.getMatrixIndex(' '), 23);
126 assertEquals(sm.getMatrixIndex('*'), 24);
127 assertEquals(sm.getMatrixIndex('.'), -1);
128 assertEquals(sm.getMatrixIndex('-'), -1);
129 assertEquals(sm.getMatrixIndex('?'), -1);
130 assertEquals(sm.getMatrixIndex((char) 128), -1);
133 @Test(groups = "Functional")
134 public void testGetSize()
136 ScoreMatrix sm = ScoreModels.getInstance().getBlosum62();
137 assertEquals(sm.getMatrix().length, sm.getSize());
140 @Test(groups = "Functional")
141 public void testComputePairwiseScores()
144 * NB score matrix assumes space for gap - Jalview converts
145 * space to gap before computing PCA or Tree
147 String[] seqs = new String[] { "FKL", "R D", "QIA", "GWC" };
148 ScoreMatrix sm = ScoreModels.getInstance().getBlosum62();
150 MatrixI pairwise = sm.computePairwiseScores(seqs);
153 * should be NxN where N = number of sequences
155 assertEquals(pairwise.height(), 4);
156 assertEquals(pairwise.width(), 4);
159 * should be symmetrical (because BLOSUM62 is)
161 for (int i = 0; i < pairwise.height(); i++)
163 for (int j = i + 1; j < pairwise.width(); j++)
165 assertEquals(pairwise.getValue(i, j), pairwise.getValue(j, i),
166 String.format("Not symmetric at [%d, %d]", i, j));
170 * verify expected BLOSUM dot product scores
172 // F.F + K.K + L.L = 6 + 5 + 4 = 15
173 assertEquals(pairwise.getValue(0, 0), 15d);
174 // R.R + -.- + D.D = 5 + 1 + 6 = 12
175 assertEquals(pairwise.getValue(1, 1), 12d);
176 // Q.Q + I.I + A.A = 5 + 4 + 4 = 13
177 assertEquals(pairwise.getValue(2, 2), 13d);
178 // G.G + W.W + C.C = 6 + 11 + 9 = 26
179 assertEquals(pairwise.getValue(3, 3), 26d);
180 // F.R + K.- + L.D = -3 + -4 + -4 = -11
181 assertEquals(pairwise.getValue(0, 1), -11d);
182 // F.Q + K.I + L.A = -3 + -3 + -1 = -7
183 assertEquals(pairwise.getValue(0, 2), -7d);
184 // F.G + K.W + L.C = -3 + -3 + -1 = -7
185 assertEquals(pairwise.getValue(0, 3), -7d);
186 // R.Q + -.I + D.A = 1 + -4 + -2 = -5
187 assertEquals(pairwise.getValue(1, 2), -5d);
188 // R.G + -.W + D.C = -2 + -4 + -3 = -9
189 assertEquals(pairwise.getValue(1, 3), -9d);
190 // Q.G + I.W + A.C = -2 + -3 + 0 = -5
191 assertEquals(pairwise.getValue(2, 3), -5d);