X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=test%2Fjalview%2Fanalysis%2Fscoremodels%2FScoreMatrixTest.java;h=15bdce1784005587479d8be6649afe4042574ffa;hb=4f936503eb2c2122f5034b82ceb0d5253778d98b;hp=24db8942ee0ae04235a91c201345704780d2fec0;hpb=adca107ff292173bc844ad4a5c6c7eba958ad24a;p=jalview.git diff --git a/test/jalview/analysis/scoremodels/ScoreMatrixTest.java b/test/jalview/analysis/scoremodels/ScoreMatrixTest.java index 24db894..15bdce1 100644 --- a/test/jalview/analysis/scoremodels/ScoreMatrixTest.java +++ b/test/jalview/analysis/scoremodels/ScoreMatrixTest.java @@ -1,8 +1,11 @@ package jalview.analysis.scoremodels; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotEquals; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNotSame; +import static org.testng.Assert.assertNull; import static org.testng.Assert.assertTrue; import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals; @@ -10,6 +13,7 @@ import jalview.api.analysis.SimilarityParamsI; import jalview.io.DataSourceType; import jalview.io.FileParse; import jalview.io.ScoreMatrixFile; +import jalview.math.Matrix; import jalview.math.MatrixI; import jalview.schemes.ResidueProperties; @@ -19,6 +23,8 @@ import java.util.Arrays; import org.testng.annotations.Test; +import junit.extensions.PA; + public class ScoreMatrixTest { @Test(groups = "Functional") @@ -27,24 +33,29 @@ public class ScoreMatrixTest // note score matrix does not have to be symmetric (though it should be!) float[][] scores = new float[3][]; scores[0] = new float[] { 1f, 2f, 3f }; - scores[1] = new float[] { 4f, 5f, 6f }; + scores[1] = new float[] { -4f, 5f, 6f }; scores[2] = new float[] { 7f, 8f, 9f }; ScoreMatrix sm = new ScoreMatrix("Test", "ABC".toCharArray(), scores); + assertFalse(sm.isSymmetric()); assertEquals(sm.getSize(), 3); assertArrayEquals(scores, sm.getMatrix()); assertEquals(sm.getPairwiseScore('A', 'a'), 1f); assertEquals(sm.getPairwiseScore('b', 'c'), 6f); assertEquals(sm.getPairwiseScore('c', 'b'), 8f); - assertEquals(sm.getPairwiseScore('A', 'D'), 0f); assertEquals(sm.getMatrixIndex('c'), 2); assertEquals(sm.getMatrixIndex(' '), -1); - assertEquals(sm.getGapIndex(), -1); // no gap symbol + // substitution to or from unknown symbol gets minimum score + assertEquals(sm.getPairwiseScore('A', 'D'), -4f); + assertEquals(sm.getPairwiseScore('D', 'A'), -4f); + // unknown-to-self gets a score of 1 + assertEquals(sm.getPairwiseScore('D', 'D'), 1f); } @Test( groups = "Functional", - expectedExceptions = { IllegalArgumentException.class }) + expectedExceptions = + { IllegalArgumentException.class }) public void testConstructor_matrixTooSmall() { float[][] scores = new float[2][]; @@ -55,7 +66,8 @@ public class ScoreMatrixTest @Test( groups = "Functional", - expectedExceptions = { IllegalArgumentException.class }) + expectedExceptions = + { IllegalArgumentException.class }) public void testConstructor_matrixTooBig() { float[][] scores = new float[2][]; @@ -66,7 +78,8 @@ public class ScoreMatrixTest @Test( groups = "Functional", - expectedExceptions = { IllegalArgumentException.class }) + expectedExceptions = + { IllegalArgumentException.class }) public void testConstructor_matrixNotSquare() { float[][] scores = new float[2][]; @@ -158,8 +171,8 @@ public class ScoreMatrixTest assertEquals(sm.getMatrixIndex('D'), 3); assertEquals(sm.getMatrixIndex('X'), 22); assertEquals(sm.getMatrixIndex('x'), 22); - assertEquals(sm.getMatrixIndex('-'), 23); - assertEquals(sm.getMatrixIndex('*'), 24); + assertEquals(sm.getMatrixIndex('-'), -1); + assertEquals(sm.getMatrixIndex('*'), 23); assertEquals(sm.getMatrixIndex('.'), -1); assertEquals(sm.getMatrixIndex(' '), -1); assertEquals(sm.getMatrixIndex('?'), -1); @@ -167,13 +180,6 @@ public class ScoreMatrixTest } @Test(groups = "Functional") - public void testGetGapIndex() - { - ScoreMatrix sm = ScoreModels.getInstance().getBlosum62(); - assertEquals(sm.getGapIndex(), 23); - } - - @Test(groups = "Functional") public void testGetSize() { ScoreMatrix sm = ScoreModels.getInstance().getBlosum62(); @@ -241,8 +247,8 @@ public class ScoreMatrixTest * @throws MalformedURLException */ @Test(groups = "Functional") - public void testOutputMatrix_roundTrip() throws MalformedURLException, - IOException + public void testOutputMatrix_roundTrip() + throws MalformedURLException, IOException { ScoreMatrix sm = ScoreModels.getInstance().getBlosum62(); String output = sm.outputMatrix(false); @@ -257,10 +263,16 @@ public class ScoreMatrixTest public void testEqualsAndHashCode() { ScoreMatrix sm = ScoreModels.getInstance().getBlosum62(); - ScoreMatrix sm2 = new ScoreMatrix(sm.getName(), sm.getSymbols() - .toCharArray(), sm.getMatrix()); + ScoreMatrix sm2 = new ScoreMatrix(sm.getName(), + sm.getSymbols().toCharArray(), sm.getMatrix()); assertTrue(sm.equals(sm2)); assertEquals(sm.hashCode(), sm2.hashCode()); + + sm2 = ScoreModels.getInstance().getPam250(); + assertFalse(sm.equals(sm2)); + assertNotEquals(sm.hashCode(), sm2.hashCode()); + + assertFalse(sm.equals("hello")); } /** @@ -275,19 +287,20 @@ public class ScoreMatrixTest String s1 = "FR-K-S"; String s2 = "FS--L"; ScoreMatrix blosum = ScoreModels.getInstance().getBlosum62(); - + /* * score gap-gap and gap-char * shorter sequence treated as if with trailing gaps * score = F^F + R^S + -^- + K^- + -^L + S^- * = 6 + -1 + 1 + -4 + -4 + -4 = -6 */ - SimilarityParamsI params = new SimilarityParams(true, true, true, false); + SimilarityParamsI params = new SimilarityParams(true, true, true, + false); assertEquals(blosum.computeSimilarity(s1, s2, params), -6d); // matchGap (arg2) is ignored: params = new SimilarityParams(true, false, true, false); assertEquals(blosum.computeSimilarity(s1, s2, params), -6d); - + /* * score gap-char but not gap-gap * score = F^F + R^S + 0 + K^- + -^L + S^- @@ -298,7 +311,7 @@ public class ScoreMatrixTest // matchGap (arg2) is ignored: params = new SimilarityParams(false, false, true, false); assertEquals(blosum.computeSimilarity(s1, s2, params), -7d); - + /* * score gap-gap but not gap-char * score = F^F + R^S + -^- + 0 + 0 + 0 @@ -309,7 +322,7 @@ public class ScoreMatrixTest // matchGap (arg2) is ignored: params = new SimilarityParams(true, true, false, false); assertEquals(blosum.computeSimilarity(s1, s2, params), 6d); - + /* * score neither gap-gap nor gap-char * score = F^F + R^S + 0 + 0 + 0 + 0 @@ -347,7 +360,7 @@ public class ScoreMatrixTest // matchGap (arg2) is ignored: params = new SimilarityParams(true, false, true, true); assertEquals(blosum.computeSimilarity(s1, s2, params), -2d); - + /* * score gap-char but not gap-gap * score = F^F + R^S + 0 + K^- + -^L @@ -358,7 +371,7 @@ public class ScoreMatrixTest // matchGap (arg2) is ignored: params = new SimilarityParams(false, false, true, true); assertEquals(blosum.computeSimilarity(s1, s2, params), -3d); - + /* * score gap-gap but not gap-char * score = F^F + R^S + -^- + 0 + 0 @@ -369,7 +382,7 @@ public class ScoreMatrixTest // matchGap (arg2) is ignored: params = new SimilarityParams(true, true, false, true); assertEquals(blosum.computeSimilarity(s1, s2, params), 6d); - + /* * score neither gap-gap nor gap-char * score = F^F + R^S + 0 + 0 + 0 @@ -390,6 +403,12 @@ public class ScoreMatrixTest verifySymmetric(ScoreModels.getInstance().getDefaultModel(false)); // dna } + /** + * A helper method that inspects a loaded matrix and reports any asymmetry as + * a test failure + * + * @param sm + */ private void verifySymmetric(ScoreMatrix sm) { float[][] m = sm.getMatrix(); @@ -399,9 +418,10 @@ public class ScoreMatrixTest 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])); + assertEquals(m[row][col], m[col][row], + String.format("%s [%s, %s]", sm.getName(), + ResidueProperties.aa[row], + ResidueProperties.aa[col])); } } } @@ -414,67 +434,106 @@ public class ScoreMatrixTest { ScoreMatrix sm = ScoreModels.getInstance().getBlosum62(); + assertTrue(sm.isProtein()); + assertFalse(sm.isDNA()); + assertNull(sm.getDescription()); + /* * verify expected scores against ARNDCQEGHILKMFPSTWYVBZX * scraped from https://www.ncbi.nlm.nih.gov/Class/FieldGuide/BLOSUM62.txt */ - verifyValues(sm, 'A', new float[] { 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 float[] { -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 float[] { -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 float[] { -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 float[] { 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 float[] { -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 float[] { -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 float[] { 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 float[] { -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 float[] { -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 float[] { -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 float[] { -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 float[] { -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 float[] { -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 float[] { -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 float[] { 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 float[] { 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 float[] { -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 float[] { -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 float[] { 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 float[] { -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 float[] { -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 float[] { 0, -1, -1, -1, -2, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -2, 0, 0, -2, -1, -1, -1, -1, -1 }); + verifyValues(sm, 'A', + new float[] + { 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 float[] + { -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 float[] + { -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 float[] + { -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 float[] + { 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 float[] + { -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 float[] + { -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 float[] + { 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 float[] + { -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 float[] + { -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 float[] + { -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 float[] + { -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 float[] + { -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 float[] + { -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 float[] + { -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 float[] + { 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 float[] + { 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 float[] + { -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 float[] + { -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 float[] + { 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 float[] + { -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 float[] + { -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 float[] + { 0, -1, -1, -1, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, 0, + 0, -2, -1, -1, -1, -1, -1 }); } /** @@ -514,7 +573,138 @@ public class ScoreMatrixTest assertEquals(sm.getMatrixIndex('-'), 1); assertEquals(sm.getMatrixIndex(' '), -1); assertEquals(sm.getMatrixIndex('.'), -1); - - assertEquals(sm.getGapIndex(), 1); + } + + @Test(groups = "Functional") + public void testGetPairwiseScore() + { + float[][] scores = new float[2][]; + scores[0] = new float[] { 1f, 2f }; + scores[1] = new float[] { -4f, 5f }; + ScoreMatrix sm = new ScoreMatrix("Test", new char[] { 'A', 'B' }, + scores); + assertEquals(sm.getPairwiseScore('A', 'A'), 1f); + assertEquals(sm.getPairwiseScore('A', 'a'), 1f); + assertEquals(sm.getPairwiseScore('A', 'B'), 2f); + assertEquals(sm.getPairwiseScore('b', 'a'), -4f); + assertEquals(sm.getPairwiseScore('B', 'b'), 5f); + + /* + * unknown symbols currently score minimum score + * or 1 for identity with self + */ + assertEquals(sm.getPairwiseScore('A', '-'), -4f); + assertEquals(sm.getPairwiseScore('-', 'A'), -4f); + assertEquals(sm.getPairwiseScore('-', '-'), 1f); + assertEquals(sm.getPairwiseScore('Q', 'W'), -4f); + assertEquals(sm.getPairwiseScore('Q', 'Q'), 1f); + + /* + * symbols not in basic ASCII set score zero + */ + char c = (char) 200; + assertEquals(sm.getPairwiseScore('Q', c), 0f); + assertEquals(sm.getPairwiseScore(c, 'Q'), 0f); + } + + @Test(groups = "Functional") + public void testGetMinimumScore() + { + ScoreMatrix sm = ScoreModels.getInstance().getBlosum62(); + assertEquals(sm.getMinimumScore(), -4f); + } + + @Test(groups = "Functional") + public void testGetMaximumScore() + { + ScoreMatrix sm = ScoreModels.getInstance().getBlosum62(); + assertEquals(sm.getMaximumScore(), 11f); + } + + @Test(groups = "Functional") + public void testOutputMatrix_html() + { + float[][] scores = new float[2][]; + scores[0] = new float[] { 1f, 2f }; + scores[1] = new float[] { 4f, -5.3E-10f }; + ScoreMatrix sm = new ScoreMatrix("Test", "AB".toCharArray(), scores); + String html = sm.outputMatrix(true); + String expected = "
A | B | |
---|---|---|
A | 1.0 | 2.0 |
B | 4.0 | -5.3E-10 |