package jalview.schemes; import static org.testng.Assert.assertEquals; import jalview.math.MatrixI; import org.testng.annotations.Test; public class ScoreMatrixTest { @Test(groups = "Functional") public void testSymmetric() { verifySymmetric(ResidueProperties.getScoreMatrix("BLOSUM62")); verifySymmetric(ResidueProperties.getScoreMatrix("PAM250")); verifySymmetric(ResidueProperties.getScoreMatrix("DNA")); } private void verifySymmetric(ScoreMatrix sm) { int[][] m = sm.getMatrix(); int rows = m.length; for (int row = 0; row < rows; row++) { assertEquals(m[row].length, rows); for (int col = 0; col < rows; col++) { assertEquals(m[row][col], m[col][row], String.format("%s [%s, %s]", sm.getName(), ResidueProperties.aa[row], ResidueProperties.aa[col])); } } /* * also check the score matrix is sized for * the number of symbols scored, plus gap */ assertEquals(rows, (sm.isDNA() ? ResidueProperties.maxNucleotideIndex : ResidueProperties.maxProteinIndex) + 1); } /** * A test that just asserts the expected values in the Blosum62 score matrix */ @Test(groups = "Functional") public void testBlosum62_values() { ScoreMatrix sm = ResidueProperties.getScoreMatrix("BLOSUM62"); /* * verify expected scores against ARNDCQEGHILKMFPSTWYVBZX * scraped from https://www.ncbi.nlm.nih.gov/Class/FieldGuide/BLOSUM62.txt */ verifyValues(sm, 'A', new int[] { 4, -1, -2, -2, 0, -1, -1, 0, -2, -1, -1, -1, -1, -2, -1, 1, 0, -3, -2, 0, -2, -1, 0 }); verifyValues(sm, 'R', new int[] { -1, 5, 0, -2, -3, 1, 0, -2, 0, -3, -2, 2, -1, -3, -2, -1, -1, -3, -2, -3, -1, 0, -1 }); verifyValues(sm, 'N', new int[] { -2, 0, 6, 1, -3, 0, 0, 0, 1, -3, -3, 0, -2, -3, -2, 1, 0, -4, -2, -3, 3, 0, -1 }); verifyValues(sm, 'D', new int[] { -2, -2, 1, 6, -3, 0, 2, -1, -1, -3, -4, -1, -3, -3, -1, 0, -1, -4, -3, -3, 4, 1, -1 }); verifyValues(sm, 'C', new int[] { 0, -3, -3, -3, 9, -3, -4, -3, -3, -1, -1, -3, -1, -2, -3, -1, -1, -2, -2, -1, -3, -3, -2 }); verifyValues(sm, 'Q', new int[] { -1, 1, 0, 0, -3, 5, 2, -2, 0, -3, -2, 1, 0, -3, -1, 0, -1, -2, -1, -2, 0, 3, -1 }); verifyValues(sm, 'E', new int[] { -1, 0, 0, 2, -4, 2, 5, -2, 0, -3, -3, 1, -2, -3, -1, 0, -1, -3, -2, -2, 1, 4, -1 }); verifyValues(sm, 'G', new int[] { 0, -2, 0, -1, -3, -2, -2, 6, -2, -4, -4, -2, -3, -3, -2, 0, -2, -2, -3, -3, -1, -2, -1 }); verifyValues(sm, 'H', new int[] { -2, 0, 1, -1, -3, 0, 0, -2, 8, -3, -3, -1, -2, -1, -2, -1, -2, -2, 2, -3, 0, 0, -1 }); verifyValues(sm, 'I', new int[] { -1, -3, -3, -3, -1, -3, -3, -4, -3, 4, 2, -3, 1, 0, -3, -2, -1, -3, -1, 3, -3, -3, -1 }); verifyValues(sm, 'L', new int[] { -1, -2, -3, -4, -1, -2, -3, -4, -3, 2, 4, -2, 2, 0, -3, -2, -1, -2, -1, 1, -4, -3, -1 }); verifyValues(sm, 'K', new int[] { -1, 2, 0, -1, -3, 1, 1, -2, -1, -3, -2, 5, -1, -3, -1, 0, -1, -3, -2, -2, 0, 1, -1 }); verifyValues(sm, 'M', new int[] { -1, -1, -2, -3, -1, 0, -2, -3, -2, 1, 2, -1, 5, 0, -2, -1, -1, -1, -1, 1, -3, -1, -1 }); verifyValues(sm, 'F', new int[] { -2, -3, -3, -3, -2, -3, -3, -3, -1, 0, 0, -3, 0, 6, -4, -2, -2, 1, 3, -1, -3, -3, -1 }); verifyValues(sm, 'P', new int[] { -1, -2, -2, -1, -3, -1, -1, -2, -2, -3, -3, -1, -2, -4, 7, -1, -1, -4, -3, -2, -2, -1, -2 }); verifyValues(sm, 'S', new int[] { 1, -1, 1, 0, -1, 0, 0, 0, -1, -2, -2, 0, -1, -2, -1, 4, 1, -3, -2, -2, 0, 0, 0 }); verifyValues(sm, 'T', new int[] { 0, -1, 0, -1, -1, -1, -1, -2, -2, -1, -1, -1, -1, -2, -1, 1, 5, -2, -2, 0, -1, -1, 0 }); verifyValues(sm, 'W', new int[] { -3, -3, -4, -4, -2, -2, -3, -2, -2, -3, -2, -3, -1, 1, -4, -3, -2, 11, 2, -3, -4, -3, -2 }); verifyValues(sm, 'Y', new int[] { -2, -2, -2, -3, -2, -1, -2, -3, 2, -1, -1, -2, -1, 3, -3, -2, -2, 2, 7, -1, -3, -2, -1 }); verifyValues(sm, 'V', new int[] { 0, -3, -3, -3, -1, -2, -2, -3, -3, 3, 1, -2, 1, -1, -2, -2, 0, -3, -1, 4, -3, -2, -1 }); verifyValues(sm, 'B', new int[] { -2, -1, 3, 4, -3, 0, 1, -1, 0, -3, -4, 0, -3, -3, -2, 0, -1, -4, -3, -3, 4, 1, -1 }); verifyValues(sm, 'Z', new int[] { -1, 0, 0, 1, -3, 3, 4, -2, 0, -3, -3, 1, -1, -3, -1, 0, -1, -3, -2, -2, 1, 4, -1 }); verifyValues(sm, 'X', new int[] { 0, -1, -1, -1, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, 0, 0, -2, -1, -1, -1, -1, -1 }); } /** * Helper method to check pairwise scores for one residue * * @param sm * @param res * @param expected * score values against 'res', in ResidueProperties.aaIndex order */ private void verifyValues(ScoreMatrix sm, char res, int[] expected) { for (int j = 0; j < expected.length; j++) { char c2 = ResidueProperties.aa[j].charAt(0); assertEquals(sm.getPairwiseScore(res, c2), expected[j], String.format("%s->%s", res, c2)); } } @Test(groups = "Functional") public void testComputePairwiseScores() { String[] seqs = new String[] { "FKL", "R-D", "QIA", "GWC" }; ScoreMatrix sm = ResidueProperties.getScoreMatrix("BLOSUM62"); MatrixI pairwise = sm.computePairwiseScores(seqs); /* * should be NxN where N = number of sequences */ assertEquals(pairwise.height(), 4); assertEquals(pairwise.width(), 4); /* * should be symmetrical (because BLOSUM62 is) */ for (int i = 0; i < pairwise.height(); i++) { for (int j = 0; j < pairwise.width(); j++) { assertEquals(pairwise.getValue(i, j), pairwise.getValue(j, i), "Not symmetric"); } } /* * verify expected BLOSUM dot product scores */ // F.F + K.K + L.L = 6 + 5 + 4 = 15 assertEquals(pairwise.getValue(0, 0), 15d); // R.R + -.- + D.D = 5 + 1 + 6 = 12 assertEquals(pairwise.getValue(1, 1), 12d); // Q.Q + I.I + A.A = 5 + 4 + 4 = 13 assertEquals(pairwise.getValue(2, 2), 13d); // G.G + W.W + C.C = 6 + 11 + 9 = 26 assertEquals(pairwise.getValue(3, 3), 26d); // F.R + K.- + L.D = -3 + -4 + -4 = -11 assertEquals(pairwise.getValue(0, 1), -11d); // F.Q + K.I + L.A = -3 + -3 + -1 = -7 assertEquals(pairwise.getValue(0, 2), -7d); // F.G + K.W + L.C = -3 + -3 + -1 = -7 assertEquals(pairwise.getValue(0, 3), -7d); // R.Q + -.I + D.A = 1 + -4 + -2 = -5 assertEquals(pairwise.getValue(1, 2), -5d); // R.G + -.W + D.C = -2 + -4 + -3 = -9 assertEquals(pairwise.getValue(1, 3), -9d); // Q.G + I.W + A.C = -2 + -3 + 0 = -5 assertEquals(pairwise.getValue(2, 3), -5d); } }