JAL-2416 allow alphabet symbol (optional) in first column of score table
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 13 Feb 2017 17:00:37 +0000 (17:00 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 13 Feb 2017 17:00:37 +0000 (17:00 +0000)
resources/scoreModel/blosum62.scm
resources/scoreModel/pam250.scm
src/jalview/analysis/scoremodels/ScoreMatrix.java
test/jalview/analysis/scoremodels/ScoreMatrixTest.java
test/jalview/analysis/scoremodels/ScoreModelsTest.java [new file with mode: 0644]

index 3df8833..c7af6b0 100644 (file)
@@ -5,38 +5,39 @@ ARNDCQEGHILKMFPSTWYVBZX *
 # The first line declares a ScoreMatrix with the name BLOSUM62 (shown in menus)
 # The second line gives the symbols for which scores are held in the matrix
 # These may include a space (but not as the first or last character)
-# Scores are not case sensitive, unless column(s) are provided for lower case characters
 #
+# Scores are not symbol case sensitive, unless column(s) are provided for lower case characters
+# The 'guide symbol' at the start of each row of score values is optional
 #
-# Comment line with symbols is provided as a guide
+# Comment header line with symbols is provided as a guide
 # Values may be integer or floating point, delimited by tab, space, comma or combinations
 #
 #      A       R       N       D       C       Q       E       G       H       I       L       K       M       F       P       S       T       W       Y       V       B       Z       X           *
 #
-       4       -1      -2      -2      0       -1      -1      0       -2      -1      -1      -1      -1      -2      -1      1       0       -3      -2      0       -2      -1      0       -4 -4
-       -1      5       0       -2      -3      1       0       -2      0       -3      -2      2       -1      -3      -2      -1      -1      -3      -2      -3      -1      0       -1      -4 -4
-       -2      0       6       1       -3      0       0       0       1       -3      -3      0       -2      -3      -2      1       0       -4      -2      -3      3       0       -1      -4 -4
-       -2      -2      1       6       -3      0       2       -1      -1      -3      -4      -1      -3      -3      -1      0       -1      -4      -3      -3      4       1       -1      -4 -4
-       0       3       -3      -3      9       -3      -4      -3      -3      -1      -1      -3      -1      -2      -3      -1      -1      -2      -2      -1      -3      -3      -2      -4 -4
-       -1      1       0       0       -3      5       2       -2      0       -3      -2      1       0       -3      -1      0       -1      -2      -1      -2      0       3       -1      -4 -4
-       -1      0       0       2       -4      2       5       -2      0       -3      -3      1       -2      -3      -1      0       -1      -3      -2      -2      1       4       -1      -4 -4
-       0       -2      0       -1      -3      -2      -2      6       -2      -4      -4      -2      -3      -3      -2      0       -2      -2      -3      -3      -1      -2      -1      -4 -4
-       -2      0       1       -1      -3      0       0       -2      8       -3      -3      -1      -2      -1      -2      -1      -2      -2      2       -3      0       0       -1      -4 -4
-       -1      -3      -3      -3      -1      -3      -3      -4      -3      4       2       -3      1       0       -3      -2      -1      -3      -1      3       -3      -3      -1      -4 -4
-       -1      -2      -3      -4      -1      -2      -3      -4      -3      2       4       -2      2       0       -3      -2      -1      -2      -1      1       -4      -3      -1      -4 -4
-       -1      2       0       -1      -3      1       1       -2      -1      -3      -2      5       -1      -3      -1      0       -1      -3      -2      -2      0       1       -1      -4 -4
-       -1      -1      -2      -3      -1      0       -2      -3      -2      1       2       -1      5       0       -2      -1      -1      -1      -1      1       -3      -1      -1      -4 -4
-       -2      -3      -3      -3      -2      -3      -3      -3      -1      0       0       -3      0       6       -4      -2      -2      1       3       -1      -3      -3      -1      -4 -4
-       -1      -2      -2      -1      -3      -1      -1      -2      -2      -3      -3      -1      -2      -4      7       -1      -1      -4      -3      -2      -2      -1      -2      -4 -4
-       1       -1      1       0       -1      0       0       0       -1      -2      -2      0       -1      -2      -1      4       1       -3      -2      -2      0       0       0       -4 -4
-       0       -1      0       -1      -1      -1      -1      -2      -2      -1      -1      -1      -1      -2      -1      1       5       -2      -2      0       -1      -1      0       -4 -4
-       -3      -3      -4      -4      -2      -2      -3      -2      -2      -3      -2      -3      -1      1       -4      -3      -2      11      2       -3      -4      -3      -2      -4 -4
-       -2      -2      -2      -3      -2      -1      -2      -3      2       -1      -1      -2      -1      3       -3      -2      -2      2       7       -1      -3      -2      -1      -4 -4
-       0       -3      -3      -3      -1      -2      -2      -3      -3      3       1       -2      1       -1      -2      -2      0       -3      -1      4       -3      -2      -1      -4 -4
-       -2      -1      3       4       -3      0       1       -1      0       -3      -4      0       -3      -3      -2      0       -1      -4      -3      -3      4       1       -1      -4 -4
-       -1      0       0       1       -3      3       4       -2      0       -3      -3      1       -1      -3      -1      0       -1      -3      -2      -2      1       4       -1      -4 -4
-       0       -1      -1      -1      -2      -1      -1      -1      -1      -1      -1      -1      -1      -1      -2      0       0       -2      -1      -1      -1      -1      -1      -4 -4
-       -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      1  1
+A      4       -1      -2      -2      0       -1      -1      0       -2      -1      -1      -1      -1      -2      -1      1       0       -3      -2      0       -2      -1      0       -4 -4
+R      -1      5       0       -2      -3      1       0       -2      0       -3      -2      2       -1      -3      -2      -1      -1      -3      -2      -3      -1      0       -1      -4 -4
+N      -2      0       6       1       -3      0       0       0       1       -3      -3      0       -2      -3      -2      1       0       -4      -2      -3      3       0       -1      -4 -4
+D      -2      -2      1       6       -3      0       2       -1      -1      -3      -4      -1      -3      -3      -1      0       -1      -4      -3      -3      4       1       -1      -4 -4
+C      0       3       -3      -3      9       -3      -4      -3      -3      -1      -1      -3      -1      -2      -3      -1      -1      -2      -2      -1      -3      -3      -2      -4 -4
+Q      -1      1       0       0       -3      5       2       -2      0       -3      -2      1       0       -3      -1      0       -1      -2      -1      -2      0       3       -1      -4 -4
+E      -1      0       0       2       -4      2       5       -2      0       -3      -3      1       -2      -3      -1      0       -1      -3      -2      -2      1       4       -1      -4 -4
+G      0       -2      0       -1      -3      -2      -2      6       -2      -4      -4      -2      -3      -3      -2      0       -2      -2      -3      -3      -1      -2      -1      -4 -4
+H      -2      0       1       -1      -3      0       0       -2      8       -3      -3      -1      -2      -1      -2      -1      -2      -2      2       -3      0       0       -1      -4 -4
+I      -1      -3      -3      -3      -1      -3      -3      -4      -3      4       2       -3      1       0       -3      -2      -1      -3      -1      3       -3      -3      -1      -4 -4
+L      -1      -2      -3      -4      -1      -2      -3      -4      -3      2       4       -2      2       0       -3      -2      -1      -2      -1      1       -4      -3      -1      -4 -4
+K      -1      2       0       -1      -3      1       1       -2      -1      -3      -2      5       -1      -3      -1      0       -1      -3      -2      -2      0       1       -1      -4 -4
+M      -1      -1      -2      -3      -1      0       -2      -3      -2      1       2       -1      5       0       -2      -1      -1      -1      -1      1       -3      -1      -1      -4 -4
+F      -2      -3      -3      -3      -2      -3      -3      -3      -1      0       0       -3      0       6       -4      -2      -2      1       3       -1      -3      -3      -1      -4 -4
+P      -1      -2      -2      -1      -3      -1      -1      -2      -2      -3      -3      -1      -2      -4      7       -1      -1      -4      -3      -2      -2      -1      -2      -4 -4
+S      1       -1      1       0       -1      0       0       0       -1      -2      -2      0       -1      -2      -1      4       1       -3      -2      -2      0       0       0       -4 -4
+T      0       -1      0       -1      -1      -1      -1      -2      -2      -1      -1      -1      -1      -2      -1      1       5       -2      -2      0       -1      -1      0       -4 -4
+W      -3      -3      -4      -4      -2      -2      -3      -2      -2      -3      -2      -3      -1      1       -4      -3      -2      11      2       -3      -4      -3      -2      -4 -4
+Y      -2      -2      -2      -3      -2      -1      -2      -3      2       -1      -1      -2      -1      3       -3      -2      -2      2       7       -1      -3      -2      -1      -4 -4
+V      0       -3      -3      -3      -1      -2      -2      -3      -3      3       1       -2      1       -1      -2      -2      0       -3      -1      4       -3      -2      -1      -4 -4
+B      -2      -1      3       4       -3      0       1       -1      0       -3      -4      0       -3      -3      -2      0       -1      -4      -3      -3      4       1       -1      -4 -4
+Z      -1      0       0       1       -3      3       4       -2      0       -3      -3      1       -1      -3      -1      0       -1      -3      -2      -2      1       4       -1      -4 -4
+X      0       -1      -1      -1      -2      -1      -1      -1      -1      -1      -1      -1      -1      -1      -2      0       0       -2      -1      -1      -1      -1      -1      -4 -4
        -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      1  1
+*      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      -4      1  1
 #
 #      A       R       N       D       C       Q       E       G       H       I       L       K       M       F       P       S       T       W       Y       V       B       Z       X       *
index b57485e..8df39a1 100644 (file)
@@ -11,7 +11,7 @@ ARNDCQEGHILKMFPSTWYVBZX *
 # Comment line with symbols is provided as a guide
 # Values may be integer or floating point, delimited by tab, space, comma or combinations
 #
-#      A       R       N       D       C       Q       E       G       H       I       L       K       M       F       P       S       T       W       Y       V       B       Z       X       *
+#      A       R       N       D       C       Q       E       G       H       I       L       K       M       F       P       S       T       W       Y       V       B       Z       X               *
 #
        2       -2      0       0       -2      0       0       1       -1      -1      -2      -1      -1      -3      1       1       1       -6      -3      0       0        0      0       -8      -8      
        -2      6       0       -1      -4      1       -1      -3      2       -2      -3      3       0       -4      0       0       -1      2       -4      -2      -1       0      -1      -8      -8      
index f0115bf..3e63209 100644 (file)
@@ -254,6 +254,19 @@ public class ScoreMatrix extends PairwiseSeqScoreModel implements
    * Parse a score matrix from the given input stream and returns a ScoreMatrix
    * object. If parsing fails, error messages are written to syserr and null is
    * returned. It is the caller's responsibility to close the input stream.
+   * Expected format:
+   * 
+   * <pre>
+   * ScoreMatrix displayName
+   * # comment lines begin with hash sign
+   * # symbol alphabet should be the next non-comment line
+   * ARNDCQEGHILKMFPSTWYVBZX *
+   * # scores matrix, with space, comma or tab delimited values
+   * # [i, j] = score for substituting symbol[i] with symbol[j]
+   * # first column in each row is optionally the 'substituted' symbol
+   * A 4 -1 -2 -2 0 -1 -1 0 -2 -1 -1 -1 -1 -2 -1 1 0 -3 -2 0 -2 -1 0 -4 -4
+   * ..etc..
+   * </pre>
    * 
    * @param is
    * @return
@@ -334,20 +347,39 @@ public class ScoreMatrix extends PairwiseSeqScoreModel implements
         
         /*
          * subsequent lines should be the symbol scores
+         * optionally with the symbol as the first column for readability
          */
         StringTokenizer scoreLine = new StringTokenizer(data, DELIMITERS);
+        if (scoreLine.countTokens() == size + 1)
+        {
+          /*
+           * check 'guide' symbol is the row'th letter of the alphabet
+           */
+          String symbol = scoreLine.nextToken();
+          if (symbol.length() > 1
+                  || symbol.charAt(0) != alphabet.charAt(row))
+          {
+            System.err
+                    .println(String
+                            .format("Error parsing score matrix at line %d, expected %s but found %s",
+                                    lineNo, alphabet.charAt(row), symbol));
+            return null;
+          }
+        }
         if (scoreLine.countTokens() != size)
         {
           System.err.println(String.format(
-                  "Expected %d tokens at line %d but found %d", size,
+                  "Expected %d scores at line %d but found %d", size,
                   lineNo, scoreLine.countTokens()));
           return null;
         }
         scores[row] = new float[size];
         int col = 0;
         String value = null;
-        while (scoreLine.hasMoreTokens()) {
-          try {
+        while (scoreLine.hasMoreTokens())
+        {
+          try
+          {
             value = scoreLine.nextToken();
             scores[row][col] = Float.valueOf(value);
             col++;
index 462edf2..7c62854 100644 (file)
@@ -72,15 +72,16 @@ public class ScoreMatrixTest
     /*
      * some messy but valid input data, with comma, space
      * or tab (or combinations) as score value delimiters
+     * this example includes 'guide' symbols on score rows
      */
     String data = "ScoreMatrix MyTest\n" + "ATU tx-\n"
-            + "1.1,1.2,1.3,1.4, 1.5, 1.6, 1.7\n"
-            + "2.1 2.2 2.3 2.4 2.5 2.6 2.7\n"
-            + "3.1\t3.2\t3.3\t3.4\t3.5\t3.6\t3.7\n"
+            + "A,1.1,1.2,1.3,1.4, 1.5, 1.6, 1.7\n"
+            + "T,2.1 2.2 2.3 2.4 2.5 2.6 2.7\n"
+            + "U\t3.1\t3.2\t3.3\t3.4\t3.5\t3.6\t3.7\n"
             + " 4.1 ,4.2,\t,4.3 ,\t4.4\t, \4.5,4.6 4.7\n"
-            + ", 5.1,5.3,5.3,5.4,5.5, 5.6, 5.7\n"
-            + "\t6.1, 6.2 6.3 6.4 6.5 6.6 6.7\n"
-            + ", \t7.1\t7.2 7.3, 7.4, 7.5\t,7.6,7.7\n";
+            + "t, 5.1,5.3,5.3,5.4,5.5, 5.6, 5.7\n"
+            + "x\t6.1, 6.2 6.3 6.4 6.5 6.6 6.7\n"
+            + "-, \t7.1\t7.2 7.3, 7.4, 7.5\t,7.6,7.7\n";
     ScoreMatrix sm = ScoreMatrix.parse(new ByteArrayInputStream(data
             .getBytes()));
     assertNotNull(sm);
@@ -99,6 +100,18 @@ public class ScoreMatrixTest
     assertEquals(sm.getPairwiseScore('A', '.'), 0f); // . unmapped
     assertEquals(sm.getPairwiseScore('-', '-'), 7.7f);
     assertEquals(sm.getPairwiseScore('A', (char) 128), 0f); // out of range
+
+    /*
+     * without guide symbols on score rows
+     */
+    data = "ScoreMatrix MyTest\nXY\n1 2\n3 4\n";
+    sm = ScoreMatrix.parse(new ByteArrayInputStream(data.getBytes()));
+    assertNotNull(sm);
+    assertEquals(sm.getPairwiseScore('X', 'X'), 1f);
+    assertEquals(sm.getPairwiseScore('X', 'y'), 2f);
+    assertEquals(sm.getPairwiseScore('y', 'x'), 3f);
+    assertEquals(sm.getPairwiseScore('y', 'Y'), 4f);
+    assertEquals(sm.getPairwiseScore('D', 'R'), 0f);
   }
 
   @Test(groups = "Functional")
@@ -168,5 +181,11 @@ public class ScoreMatrixTest
     sm = ScoreMatrix.parse(new ByteArrayInputStream(data.getBytes()));
     assertNull(sm);
 
+    /*
+     * Bad guide character on scores row
+     */
+    data = "ScoreMatrix MyTest\nXY\nX 1 2\ny 3 4\n";
+    sm = ScoreMatrix.parse(new ByteArrayInputStream(data.getBytes()));
+    assertNull(sm);
   }
 }
diff --git a/test/jalview/analysis/scoremodels/ScoreModelsTest.java b/test/jalview/analysis/scoremodels/ScoreModelsTest.java
new file mode 100644 (file)
index 0000000..03c4b84
--- /dev/null
@@ -0,0 +1,54 @@
+package jalview.analysis.scoremodels;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import jalview.api.analysis.ScoreModelI;
+
+import java.util.Iterator;
+
+import org.testng.annotations.Test;
+
+public class ScoreModelsTest
+{
+  /**
+   * Verify that the singleton constructor successfully loads Jalview's built-in
+   * score models
+   */
+  @Test
+  public void testConstructor()
+  {
+    Iterator<ScoreModelI> models = ScoreModels.getInstance().getModels()
+            .iterator();
+    assertTrue(models.hasNext());
+
+    /*
+     * models are served in alphabetical order of name
+     * it so happens the 3 ScoreMatrix models precede the two
+     * others
+     */
+    ScoreModelI sm = models.next();
+    assertTrue(sm instanceof ScoreMatrix);
+    assertEquals(sm.getName(), "BLOSUM62");
+    assertEquals(((ScoreMatrix) sm).getPairwiseScore('I', 'R'), -3f);
+
+    sm = models.next();
+    assertTrue(sm instanceof ScoreMatrix);
+    assertEquals(sm.getName(), "DNA");
+    assertEquals(((ScoreMatrix) sm).getPairwiseScore('c', 'x'), 1f);
+
+    sm = models.next();
+    assertTrue(sm instanceof ScoreMatrix);
+    assertEquals(sm.getName(), "PAM250");
+    assertEquals(((ScoreMatrix) sm).getPairwiseScore('R', 'C'), -4f);
+
+    sm = models.next();
+    assertFalse(sm instanceof ScoreMatrix);
+    assertEquals(sm.getName(), "PID");
+
+    sm = models.next();
+    assertFalse(sm instanceof ScoreMatrix);
+    assertEquals(sm.getName(), "Sequence Feature Similarity");
+  }
+}