fully integrate HMMER3 file format into Jalview
[jalview.git] / src / jalview / datamodel / HiddenMarkovModel.java
index cd6490e..f614013 100644 (file)
@@ -26,9 +26,16 @@ public class HiddenMarkovModel
   // 0. Node 0 contains average emission probabilities for each symbol
   List<HMMNode> nodes = new ArrayList<>();
 
-  final String YES = "yes";
+  // contains the HMM node for each alignment column
+  Map<Integer, Integer> nodeLookup = new HashMap<>();
+  
+  //contains the symbol index for each symbol
+  Map<Character, Integer> symbolIndexLookup = new HashMap<>();
+
 
-  final String NO = "no";
+  final static String YES = "yes";
+
+  final static String NO = "no";
 
   int numberOfSymbols;
   
@@ -95,14 +102,26 @@ public class HiddenMarkovModel
     return TRANSITION_TYPES[index];
   }
 
+  public Map<Integer, Integer> getNodeLookup()
+  {
+    return nodeLookup;
+  }
+
+  public void setNodeLookup(Map<Integer, Integer> nodeLookup)
+  {
+    this.nodeLookup = nodeLookup;
+  }
+
   public String[] getTransitionTypes()
   {
     return TRANSITION_TYPES;
   }
-  public char getSymbol(int index)
+
+  public List<Character> getSymbols()
   {
-    return getSymbols().get(index);
+    return symbols;
   }
+
   public Map<String, String> getFileProperties()
   {
     return fileProperties;
@@ -258,49 +277,66 @@ public class HiddenMarkovModel
   }
   
   /**
-   * gets the match emission at a node for a symbol
-   * @param nodeIndex
-   * position of node in model
-   * @param symbolIndex
-   * index of symbol being searched
+   * get match emission probability for a given symbol at a column in the
+   * alignment
+   * 
+   * @param alignColumn
+   * @param symbol
    * @return
-   * negative log probability of a match emission of the given symbol
+   * 
    */
-  public double getMatchEmission(int nodeIndex, int symbolIndex)
+  public Double getMatchEmissionProbability(int alignColumn, char symbol)
   {
-    double value = nodes.get(nodeIndex).getMatchEmissions().get(symbolIndex);
-    return value;
+    int symbolIndex;
+    int nodeIndex;
+    Double probability;
+    symbolIndex = symbolIndexLookup.get(symbol);
+    nodeIndex = nodeLookup.get(alignColumn);
+    probability = getNode(nodeIndex).getMatchEmissions().get(symbolIndex);
+    return probability;
+
   }
-  
+
   /**
-   * gets the insert emission at a node for a symbol
-   * @param nodeIndex
-   * position of node in model
-   * @param symbolIndex
-   * index of symbol being searched
+   * get insert emission probability for a given symbol at a column in the
+   * alignment
+   * 
+   * @param alignColumn
+   * @param symbol
    * @return
-   * negative log probability of an insert emission of the given symbol
    */
-  public double getInsertEmission(int nodeIndex, int symbolIndex)
+  public Double getInsertEmissionProbability(int alignColumn, char symbol)
   {
-    double value = nodes.get(nodeIndex).getInsertEmissions().get(symbolIndex);
-    return value;
+    int symbolIndex;
+    int nodeIndex;
+    Double probability;
+    symbolIndex = symbolIndexLookup.get(symbol);
+    nodeIndex = nodeLookup.get(alignColumn);
+    probability = getNode(nodeIndex).getInsertEmissions().get(symbolIndex);
+    return probability;
+
   }
   
   /**
-   * gets the state transition at a node for a specific transition
-   * @param nodeIndex
-   * position of node in model
-   * @param transitionIndex
-   * index of stransition being searched
+   * get state transition probability for a given transition type at a column in
+   * the alignment
+   * 
+   * @param alignColumn
+   * @param transition
    * @return
-   * negative log probability of a state transition of the given type
    */
-  public double getStateTransition(int nodeIndex, int transitionIndex)
-  {
-    double value = nodes.get(nodeIndex).getStateTransitions()
+  public Double getStateTransitionProbability(int alignColumn,
+          String transition)
+  {
+    int transitionIndex;
+    int nodeIndex;
+    Double probability;
+    transitionIndex = getTransitionType(transition);
+    nodeIndex = nodeLookup.get(alignColumn);
+    probability = getNode(nodeIndex).getStateTransitions()
             .get(transitionIndex);
-    return value;
+    return probability;
+
   }
   
   public Integer getNodeAlignmentColumn(int nodeIndex)
@@ -356,11 +392,7 @@ public class HiddenMarkovModel
     this.numberOfSymbols = numberOfSymbols;
   }
 
-  public List<Character> getSymbols()
-  {
-    return symbols;
-  }
-
+  
 
   /**
    * fills symbol array and also finds numberOfSymbols
@@ -370,11 +402,14 @@ public class HiddenMarkovModel
    */
   public void fillSymbols(Scanner parser)
   {
+    int i = 0;
     while (parser.hasNext())
     {
       String strSymbol = parser.next();
       char[] symbol = strSymbol.toCharArray();
       symbols.add(symbol[0]);
+      symbolIndexLookup.put(symbol[0], i);
+      i++;
     }
     numberOfSymbols = symbols.size();
   }
@@ -616,5 +651,69 @@ public class HiddenMarkovModel
       fileProperties.put(CONSENSUS_STRUCTURE, NO);
     }
   }
+
+  /**
+   * 
+   * @param transition
+   *          type of transition occuring
+   * @return index value representing position along stateTransition array.
+   */
+  public Integer getTransitionType(String transition)
+  {
+    Integer index;
+    switch (transition)
+    {
+    case "mm":
+      index = 0;
+      break;
+    case "mi":
+      index = 1;
+      break;
+    case "md":
+      index = 2;
+      break;
+    case "im":
+      index = 3;
+      break;
+    case "ii":
+      index = 4;
+      break;
+    case "dm":
+      index = 5;
+      break;
+    case "dd":
+      index = 6;
+      break;
+    default:
+      index = null;
+    }
+    return index;
+  }
+
+  /**
+   * find the index of the node in a hidden Markov model based on the column in
+   * the alignment
+   * 
+   * @param alignmentColumn
+   */
+
+  public Integer findNodeIndex(int alignmentColumn)
+  {
+    Integer index;
+    index = nodeLookup.get(alignmentColumn);
+    return index;
+  }
+
+  public static String findStringFromBoolean(boolean value)
+  {
+    if (value)
+    {
+      return YES;
+    }
+    else
+    {
+      return NO;
+    }
+  }
 }