Merge remote-tracking branch 'origin/features/JAL-2620alternativeCodeTables' into...
[jalview.git] / src / jalview / schemes / ResidueProperties.java
index 18b11c1..d435065 100755 (executable)
@@ -20,6 +20,8 @@
  */
 package jalview.schemes;
 
+import jalview.analysis.GeneticCodes;
+
 import java.awt.Color;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -502,260 +504,6 @@ public class ResidueProperties
 
   public static String START = "ATG";
 
-  /**
-   * Nucleotide Ambiguity Codes
-   */
-  public static final Map<String, String[]> ambiguityCodes = new Hashtable<>();
-
-  /**
-   * Codon triplets with additional symbols for unambiguous codons that include
-   * ambiguity codes
-   */
-  public static final Hashtable<String, String> codonHash2 = new Hashtable<>();
-
-  /**
-   * all ambiguity codes for a given base
-   */
-  public final static Hashtable<String, List<String>> _ambiguityCodes = new Hashtable<>();
-
-  static
-  {
-    /*
-     * Ambiguity codes as per http://www.chem.qmul.ac.uk/iubmb/misc/naseq.html
-     */
-    ambiguityCodes.put("R", new String[] { "A", "G" });
-    ambiguityCodes.put("Y", new String[] { "T", "C" });
-    ambiguityCodes.put("W", new String[] { "A", "T" });
-    ambiguityCodes.put("S", new String[] { "G", "C" });
-    ambiguityCodes.put("M", new String[] { "A", "C" });
-    ambiguityCodes.put("K", new String[] { "G", "T" });
-    ambiguityCodes.put("H", new String[] { "A", "T", "C" });
-    ambiguityCodes.put("B", new String[] { "G", "T", "C" });
-    ambiguityCodes.put("V", new String[] { "G", "A", "C" });
-    ambiguityCodes.put("D", new String[] { "G", "A", "T" });
-    ambiguityCodes.put("N", new String[] { "G", "A", "T", "C" });
-
-    // Now build codon translation table
-    codonHash2.put("AAA", "K");
-    codonHash2.put("AAG", "K");
-    codonHash2.put("AAC", "N");
-    codonHash2.put("AAT", "N");
-
-    codonHash2.put("CAA", "Q");
-    codonHash2.put("CAG", "Q");
-    codonHash2.put("CAC", "H");
-    codonHash2.put("CAT", "H");
-
-    codonHash2.put("GAA", "E");
-    codonHash2.put("GAG", "E");
-    codonHash2.put("GAC", "D");
-    codonHash2.put("GAT", "D");
-
-    codonHash2.put("TAC", "Y");
-    codonHash2.put("TAT", "Y");
-
-    codonHash2.put("ACA", "T");
-    codonHash2.put("ACC", "T");
-    codonHash2.put("ACT", "T");
-    codonHash2.put("ACG", "T");
-
-    codonHash2.put("CCA", "P");
-    codonHash2.put("CCG", "P");
-    codonHash2.put("CCC", "P");
-    codonHash2.put("CCT", "P");
-
-    codonHash2.put("GCA", "A");
-    codonHash2.put("GCG", "A");
-    codonHash2.put("GCC", "A");
-    codonHash2.put("GCT", "A");
-
-    codonHash2.put("TCA", "S");
-    codonHash2.put("TCG", "S");
-    codonHash2.put("TCC", "S");
-    codonHash2.put("TCT", "S");
-    codonHash2.put("AGC", "S");
-    codonHash2.put("AGT", "S");
-
-    codonHash2.put("AGA", "R");
-    codonHash2.put("AGG", "R");
-    codonHash2.put("CGA", "R");
-    codonHash2.put("CGG", "R");
-    codonHash2.put("CGC", "R");
-    codonHash2.put("CGT", "R");
-
-    codonHash2.put("GGA", "G");
-    codonHash2.put("GGG", "G");
-    codonHash2.put("GGC", "G");
-    codonHash2.put("GGT", "G");
-
-    codonHash2.put("TGA", "*");
-    codonHash2.put("TAA", "*");
-    codonHash2.put("TAG", "*");
-
-    codonHash2.put("TGG", "W");
-
-    codonHash2.put("TGC", "C");
-    codonHash2.put("TGT", "C");
-
-    codonHash2.put("ATA", "I");
-    codonHash2.put("ATC", "I");
-    codonHash2.put("ATT", "I");
-
-    codonHash2.put("ATG", "M");
-
-    codonHash2.put("CTA", "L");
-    codonHash2.put("CTG", "L");
-    codonHash2.put("CTC", "L");
-    codonHash2.put("CTT", "L");
-    codonHash2.put("TTA", "L");
-    codonHash2.put("TTG", "L");
-
-    codonHash2.put("GTA", "V");
-    codonHash2.put("GTG", "V");
-    codonHash2.put("GTC", "V");
-    codonHash2.put("GTT", "V");
-
-    codonHash2.put("TTC", "F");
-    codonHash2.put("TTT", "F");
-
-    buildAmbiguityCodonSet();
-  }
-
-  /**
-   * programmatic generation of codons including ambiguity codes
-   */
-  public static void buildAmbiguityCodonSet()
-  {
-    if (_ambiguityCodes.size() > 0)
-    {
-      System.err
-              .println("Ignoring multiple calls to buildAmbiguityCodonSet");
-      return;
-    }
-    // Invert the ambiguity code set
-    for (Map.Entry<String, String[]> acode : ambiguityCodes.entrySet())
-    {
-      for (String r : acode.getValue())
-      {
-        List<String> codesfor = _ambiguityCodes.get(r);
-        if (codesfor == null)
-        {
-          _ambiguityCodes.put(r, codesfor = new ArrayList<>());
-        }
-        if (!codesfor.contains(acode.getKey()))
-        {
-          codesfor.add(acode.getKey());
-        }
-        else
-        {
-          System.err.println(
-                  "Inconsistency in the IUBMB ambiguity code nomenclature table: collision for "
-                          + acode.getKey() + " in residue " + r);
-        }
-      }
-    }
-    // and programmatically add in the ambiguity codes that yield the same amino
-    // acid
-    String[] unambcodons = codonHash2.keySet()
-            .toArray(new String[codonHash2.size()]);
-    for (String codon : unambcodons)
-    {
-      String residue = codonHash2.get(codon);
-      String acodon[][] = new String[codon.length()][];
-      for (int i = 0, iSize = codon.length(); i < iSize; i++)
-      {
-        String _ac = "" + codon.charAt(i);
-        List<String> acodes = _ambiguityCodes.get(_ac);
-        if (acodes != null)
-        {
-          acodon[i] = acodes.toArray(new String[acodes.size()]);
-        }
-        else
-        {
-          acodon[i] = new String[] {};
-        }
-      }
-      // enumerate all combinations and test for veracity of translation
-      int tpos[] = new int[codon.length()],
-              cpos[] = new int[codon.length()];
-      for (int i = 0; i < tpos.length; i++)
-      {
-        tpos[i] = -1;
-      }
-      tpos[acodon.length - 1] = 0;
-      int ipos, j;
-      while (tpos[0] < acodon[0].length)
-      {
-        // make all codons for this combination
-        char allres[][] = new char[tpos.length][];
-        String _acodon = "";
-        for (ipos = 0; ipos < tpos.length; ipos++)
-        {
-          if (acodon[ipos].length == 0 || tpos[ipos] < 0)
-          {
-            _acodon += codon.charAt(ipos);
-            allres[ipos] = new char[] { codon.charAt(ipos) };
-          }
-          else
-          {
-            _acodon += acodon[ipos][tpos[ipos]];
-            String[] altbase = ambiguityCodes.get(acodon[ipos][tpos[ipos]]);
-            allres[ipos] = new char[altbase.length];
-            j = 0;
-            for (String ab : altbase)
-            {
-              allres[ipos][j++] = ab.charAt(0);
-            }
-          }
-        }
-        // test all codons for this combination
-        for (ipos = 0; ipos < cpos.length; ipos++)
-        {
-          cpos[ipos] = 0;
-        }
-        boolean valid = true;
-        do
-        {
-          String _codon = "";
-          for (j = 0; j < cpos.length; j++)
-          {
-            _codon += allres[j][cpos[j]];
-          }
-          String tr = codonHash2.get(_codon);
-          if (valid = (tr != null && tr.equals(residue)))
-          {
-            // advance to next combination
-            ipos = acodon.length - 1;
-            while (++cpos[ipos] >= allres[ipos].length && ipos > 0)
-            {
-              cpos[ipos] = 0;
-              ipos--;
-            }
-          }
-        } while (valid && cpos[0] < allres[0].length);
-        if (valid)
-        {
-          // Add this to the set of codons we will translate
-          // System.out.println("Adding ambiguity codon: " + _acodon + " for "
-          // + residue);
-          codonHash2.put(_acodon, residue);
-        }
-        else
-        {
-          // System.err.println("Rejecting ambiguity codon: " + _acodon
-          // + " for " + residue);
-        }
-        // next combination
-        ipos = acodon.length - 1;
-        while (++tpos[ipos] >= acodon[ipos].length && ipos > 0)
-        {
-          tpos[ipos] = -1;
-          ipos--;
-        }
-      }
-    }
-  }
-
   // Stores residue codes/names and colours and other things
   public static Map<String, Map<String, Integer>> propHash = new Hashtable<>();
 
@@ -1148,12 +896,13 @@ public class ResidueProperties
 
   public static String codonTranslate(String lccodon)
   {
-    String cdn = codonHash2.get(lccodon.toUpperCase());
-    if ("*".equals(cdn))
+    String peptide = GeneticCodes.getInstance().getStandardCodeTable()
+            .translate(lccodon);
+    if ("*".equals(peptide))
     {
-      return STOP;
+      return "STOP";
     }
-    return cdn;
+    return peptide;
   }
 
   /*