JAL-2938 revisions to implementation details
[jalview.git] / src / jalview / schemes / HmmerColourScheme.java
index d31f0e1..9ea468d 100644 (file)
@@ -12,10 +12,10 @@ import java.util.Map;
 
 /**
  * Base class for colour schemes based on a selected Hidden Markov Model. The
- * colour is
+ * colour is with reference to an HMM consensus sequence and HMM profile
  * <ul>
  * <li>white for a gap</li>
- * <li>red for an insertion</li>
+ * <li>red for an insertion (position is gapped in the HMM consensus)</li>
  * <li>orange for negative information content</li>
  * <li>white to blue for increasing information content</li>
  * </ul>
@@ -35,18 +35,26 @@ public abstract class HmmerColourScheme extends ResidueColourScheme
 {
   private static final Color INSERTION_COLOUR = new Color(230, 0, 0); // reddish
 
+  /*
+   * the aligned HMM consensus sequence to use as reference for colouring
+   */
+  private SequenceI hmmSeq;
+
   private HiddenMarkovModel hmm;
 
   private Map<Character, Float> frequencies;
 
   /**
-   * Constructor given a Hidden Markov Model
+   * Constructor given a Hidden Markov Model consensus sequence. This provides
+   * the HMM profile from which we can read the emission probabilities that
+   * determine the colour.
    * 
-   * @param markov
+   * @param consensusSeq
    */
-  public HmmerColourScheme(HiddenMarkovModel markov)
+  public HmmerColourScheme(SequenceI consensusSeq)
   {
-    hmm = markov;
+    hmmSeq = consensusSeq;
+    hmm = hmmSeq == null ? null : hmmSeq.getHMM();
   }
 
   /**
@@ -57,10 +65,10 @@ public abstract class HmmerColourScheme extends ResidueColourScheme
   }
 
   @Override
-  public Color findColour(char symbol, int position, SequenceI seq,
+  public Color findColour(char symbol, int column, SequenceI seq,
           String consensusResidue, float pid)
   {
-    return findColour(symbol, position);
+    return findColour(symbol, column);
   }
 
   /**
@@ -82,6 +90,10 @@ public abstract class HmmerColourScheme extends ResidueColourScheme
     {
       return Color.white;
     }
+    if (Comparison.isGap(hmmSeq.getCharAt(column)))
+    {
+      return INSERTION_COLOUR;
+    }
     if (Character.isLowerCase(symbol))
     {
       symbol = Character.toUpperCase(symbol);
@@ -100,19 +112,22 @@ public abstract class HmmerColourScheme extends ResidueColourScheme
     {
       freq = frequencies.get(symbol);
     }
-    if (prob == 0D)
-    {
-      return INSERTION_COLOUR;
-    }
-    double value = Math.log(prob / freq.floatValue());
-    Color colour = null;
-    if (value < 0)
+
+    /*
+     * Orange if match emission probability is less than background probability
+     */
+    double infoRatio = prob / freq.floatValue();
+    Color colour = Color.ORANGE;
+    if (infoRatio >= 1)
     {
-      return Color.ORANGE;
+      /*
+       * log-scale graduated shade of blue if prob is greater than background  
+       */
+      float infoLog = (float) Math.log(infoRatio);
+      colour = ColorUtils.getGraduatedColour(infoLog, 0, Color.WHITE,
+              getMaxInformationScore(), Color.blue);
     }
 
-    colour = ColorUtils.getGraduatedColour((float) value, 0, Color.WHITE,
-            getMaxInformationScore(), Color.blue);
     return colour;
   }
 
@@ -124,16 +139,6 @@ public abstract class HmmerColourScheme extends ResidueColourScheme
    */
   abstract float getMaxInformationScore();
 
-  @Override
-  public void alignmentChanged(AnnotatedCollectionI collection,
-          Map<SequenceI, SequenceCollectionI> hiddenReps)
-  {
-    /*
-     * ? no need to do anything if alignment is adjusted
-     * since findColour() handles everything 
-     */
-  }
-
   /**
    * Answers a new colour scheme instance based on the HMM of the first sequence
    * in ac that has an HMM
@@ -142,21 +147,16 @@ public abstract class HmmerColourScheme extends ResidueColourScheme
   public ColourSchemeI getInstance(AnnotatedCollectionI ac,
           Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
   {
-    SequenceI hmmSeq = ac.getHmmConsensus();
-    HiddenMarkovModel model = hmmSeq == null ? null : hmmSeq.getHMM();
-
-    return newInstance(ac, model);
+    return newInstance(ac);
   }
 
   /**
    * Answers a new instance of the colour scheme for the given HMM
    * 
    * @param ac
-   * @param model
    * @return
    */
-  protected abstract HmmerColourScheme newInstance(AnnotatedCollectionI ac,
-          HiddenMarkovModel model);
+  protected abstract HmmerColourScheme newInstance(AnnotatedCollectionI ac);
 
   @Override
   public boolean isSimple()
@@ -189,4 +189,8 @@ public abstract class HmmerColourScheme extends ResidueColourScheme
     return hmm;
   }
 
+  protected SequenceI getHmmSequence()
+  {
+    return hmmSeq;
+  }
 }