JAL-2403 further test coverage for ScoreMatrix, min/max getters
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Tue, 28 Mar 2017 10:59:42 +0000 (11:59 +0100)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Tue, 28 Mar 2017 10:59:42 +0000 (11:59 +0100)
src/jalview/analysis/scoremodels/ScoreMatrix.java
test/jalview/analysis/scoremodels/ScoreMatrixTest.java

index c71658b..84e91ae 100644 (file)
@@ -90,6 +90,10 @@ public class ScoreMatrix implements SimilarityScoreModelI,
    */
   private boolean peptide;
 
+  private float minValue;
+
+  private float maxValue;
+
   /**
    * Constructor given a name, symbol alphabet, and matrix of scores for pairs
    * of symbols. The matrix should be square and of the same size as the
@@ -124,6 +128,8 @@ public class ScoreMatrix implements SimilarityScoreModelI,
 
     symbolIndex = buildSymbolIndex(alphabet);
 
+    findMinMax();
+
     /*
      * crude heuristic for now...
      */
@@ -131,6 +137,31 @@ public class ScoreMatrix implements SimilarityScoreModelI,
   }
 
   /**
+   * Record the minimum and maximum score values
+   */
+  protected void findMinMax()
+  {
+    float min = Float.MAX_VALUE;
+    float max = -Float.MAX_VALUE;
+    if (matrix != null)
+    {
+      for (float[] row : matrix)
+      {
+        if (row != null)
+        {
+          for (float f : row)
+          {
+            min = Math.min(min, f);
+            max = Math.max(max, f);
+          }
+        }
+      }
+    }
+    minValue = min;
+    maxValue = max;
+  }
+
+  /**
    * Returns an array A where A[i] is the position in the alphabet array of the
    * character whose value is i. For example if the alphabet is { 'A', 'D', 'X'
    * } then A['D'] = A[68] = 1.
@@ -281,6 +312,12 @@ public class ScoreMatrix implements SimilarityScoreModelI,
     {
       return matrix[cIndex][dIndex];
     }
+
+    /*
+     * one or both symbols not found in the matrix
+     * note: a possible strategy here would be to return the minimum
+     * matrix value if c != d
+     */
     return 0;
   }
 
@@ -532,4 +569,14 @@ public class ScoreMatrix implements SimilarityScoreModelI,
   {
     description = desc;
   }
+
+  public float getMinimumScore()
+  {
+    return minValue;
+  }
+
+  public float getMaximumScore()
+  {
+    return maxValue;
+  }
 }
index 24db894..9c9e917 100644 (file)
@@ -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;
 
@@ -159,7 +162,7 @@ public class ScoreMatrixTest
     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('.'), -1);
     assertEquals(sm.getMatrixIndex(' '), -1);
     assertEquals(sm.getMatrixIndex('?'), -1);
@@ -261,6 +264,12 @@ public class ScoreMatrixTest
             .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"));
   }
 
   /**
@@ -414,6 +423,12 @@ public class ScoreMatrixTest
   {
     ScoreMatrix sm = ScoreModels.getInstance().getBlosum62();
 
+    assertTrue(sm.isProtein());
+    assertFalse(sm.isDNA());
+    assertNull(sm.getDescription());
+    sm.setDescription("BLOSUM62");
+    assertEquals(sm.getDescription(), "BLOSUM62");
+
     /*
      * verify expected scores against ARNDCQEGHILKMFPSTWYVBZX
      * scraped from https://www.ncbi.nlm.nih.gov/Class/FieldGuide/BLOSUM62.txt
@@ -517,4 +532,62 @@ public class ScoreMatrixTest
   
     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 zero
+     */
+    assertEquals(sm.getPairwiseScore('A', '-'), 0f);
+    assertEquals(sm.getPairwiseScore('-', '-'), 0f);
+    assertEquals(sm.getPairwiseScore('Q', 'W'), 0f);
+
+    /*
+     * 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 = "<table border=\"1\"><tr><th></th><th>&nbsp;A&nbsp;</th><th>&nbsp;B&nbsp;</th></tr>\n"
+            + "<tr><td>A</td><td>1.0</td><td>2.0</td></tr>\n"
+            + "<tr><td>B</td><td>4.0</td><td>-5.3E-10</td></tr>\n"
+            + "</table>";
+    assertEquals(html, expected);
+  }
 }