JAL-3665 sequences shaded according to emmission probability of first aligned hmm...
authorJim Procter <jprocter@issues.jalview.org>
Mon, 22 Jun 2020 10:46:02 +0000 (11:46 +0100)
committerJim Procter <jprocter@issues.jalview.org>
Mon, 22 Jun 2020 10:46:02 +0000 (11:46 +0100)
src/jalview/schemes/HMMMatchScoreColourScheme.java
src/jalview/schemes/HmmerColourScheme.java
src/jalview/schemes/HmmerGlobalBackground.java

index 96eb26a..0b1cd40 100644 (file)
@@ -143,6 +143,7 @@ public class HMMMatchScoreColourScheme extends ResidueColourScheme
    */
   public HMMMatchScoreColourScheme(List<SequenceI> hmmSeqs)
   {
+    // TODO: generalise the MatchScore for multiple HMMs ?  
     hmmSeq = hmmSeqs.isEmpty() ? null : hmmSeqs.get(0);
     hmm = hmmSeq == null ? null : hmmSeq.getHMM();
 
index 05c9b66..fa62071 100644 (file)
@@ -39,10 +39,9 @@ public abstract class HmmerColourScheme extends ResidueColourScheme
   /*
    * the aligned HMM consensus sequence to use as reference for colouring
    */
-  private SequenceI hmmSeq;
-
-  private HiddenMarkovModel hmm;
+  private List<SequenceI> hmmSeqs=null;
 
+  
   private Map<Character, Float> frequencies;
 
   /**
@@ -54,8 +53,24 @@ public abstract class HmmerColourScheme extends ResidueColourScheme
    */
   public HmmerColourScheme(List<SequenceI> hmmSeqs)
   {
-    hmmSeq = hmmSeqs.isEmpty() ? null : hmmSeqs.get(0);
-    hmm = hmmSeq == null ? null : hmmSeq.getHMM();
+    this.hmmSeqs = hmmSeqs.isEmpty() ? null : hmmSeqs;
+  }
+
+  protected   String getAlphabetType()
+  {
+    if (hmmSeqs!=null) {
+      for (SequenceI hmmSeq : hmmSeqs)
+    {
+      if (hmmSeq != null)
+      {
+        HiddenMarkovModel hmm = hmmSeq.getHMM();
+        if (hmm != null)
+        {
+          return hmm.getAlphabetType();
+        }
+      }
+    }}
+    return ResidueProperties.ALPHABET_AMINO;
   }
 
   /**
@@ -87,49 +102,59 @@ public abstract class HmmerColourScheme extends ResidueColourScheme
    */
   private Color findColour(char symbol, int column)
   {
-    if (getHmm() == null || Comparison.isGap(symbol))
+    if (hmmSeqs==null || Comparison.isGap(symbol))
     {
+      // todo: could return probability of seeing a gap ?
       return Color.white;
     }
-    if (Comparison.isGap(hmmSeq.getCharAt(column)))
-    {
-      return INSERTION_COLOUR;
-    }
-    if (Character.isLowerCase(symbol))
-    {
-      symbol = Character.toUpperCase(symbol);
-    }
-
-    final double prob = getHmm().getMatchEmissionProbability(column,
-            symbol);
-
-    Float freq = 0f;
-
-    if (!frequencies.containsKey(symbol))
-    {
-      return Color.WHITE;
-    }
-    else
-    {
-      freq = frequencies.get(symbol);
-    }
-
-    /*
-     * Orange if match emission probability is less than background probability
-     */
-    double infoRatio = prob / freq.floatValue();
-    Color colour = Color.ORANGE;
-    if (infoRatio >= 1)
+    // locate first hmm with a non-gap at this position
+    for (SequenceI hmmSeq:hmmSeqs)
     {
-      /*
-       * 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);
+      if (hmmSeq==null)
+      {
+        continue;
+      }
+      if (!Comparison.isGap(hmmSeq.getCharAt(column)))
+      {
+        if (symbol >= 'a')
+        {
+          symbol += 'A' - 'a';
+        }
+
+        final double prob = hmmSeq.getHMM()
+                .getMatchEmissionProbability(column, symbol);
+
+        Float freq = 0f;
+
+        if (!frequencies.containsKey(symbol))
+        {
+          return Color.WHITE;
+        }
+        else
+        {
+          freq = frequencies.get(symbol);
+        }
+
+        /*
+         * Orange if match emission probability is less than background probability
+         */
+        double infoRatio = prob / freq.floatValue();
+        Color colour = Color.ORANGE;
+        if (infoRatio >= 1)
+        {
+          /*
+           * 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);
+        }
+
+        return colour;
+      }
     }
-
-    return colour;
+    // no more seqs. so
+    return INSERTION_COLOUR;
   }
 
   /**
@@ -184,14 +209,4 @@ public abstract class HmmerColourScheme extends ResidueColourScheme
   {
     this.frequencies = frequencies;
   }
-
-  protected HiddenMarkovModel getHmm()
-  {
-    return hmm;
-  }
-
-  protected SequenceI getHmmSequence()
-  {
-    return hmmSeq;
-  }
 }
index a24b7ab..17b9c2c 100644 (file)
@@ -2,7 +2,10 @@ package jalview.schemes;
 
 import jalview.api.AlignViewportI;
 import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.HiddenMarkovModel;
 import jalview.datamodel.SequenceCollectionI;
+import jalview.datamodel.SequenceI;
+import jalview.hmmer.HMMSearch;
 
 /**
  * An HMM colour scheme that uses global ('Uniprot') background frequencies for
@@ -27,9 +30,7 @@ public class HmmerGlobalBackground extends HmmerColourScheme
   public HmmerGlobalBackground(SequenceCollectionI ac)
   {
     super(ac.getHmmSequences());
-    String alphabetType = getHmm() == null
-            ? ResidueProperties.ALPHABET_AMINO
-            : getHmm().getAlphabetType();
+    String alphabetType = getAlphabetType();
     setFrequencies(
             ResidueProperties.backgroundFrequencies.get(alphabetType));
   }