complete Information Content annotation
authorTZVanaalten <TZVanaalten@LS30916.ad.lifesci.dundee.ac.uk>
Tue, 11 Jul 2017 13:59:08 +0000 (14:59 +0100)
committerTZVanaalten <TZVanaalten@LS30916.ad.lifesci.dundee.ac.uk>
Tue, 11 Jul 2017 13:59:08 +0000 (14:59 +0100)
src/jalview/analysis/AAFrequency.java
src/jalview/datamodel/HiddenMarkovModel.java
src/jalview/gui/AnnotationLabels.java
src/jalview/renderer/AnnotationRenderer.java
src/jalview/schemes/HMMERColourScheme.java

index b806355..514b300 100755 (executable)
@@ -449,6 +449,7 @@ public class AAFrequency
     return result;
   }
 
+
   /**
    * Extract a sorted extract of cDNA codon profile data. The returned array
    * contains
@@ -531,7 +532,7 @@ public class AAFrequency
     for (int col = 0; col < cols; col++)
     {
       // todo would prefer a Java bean for consensus data
-      Hashtable<String, int[]> columnHash = new Hashtable<String, int[]>();
+      Hashtable<String, int[]> columnHash = new Hashtable<>();
       // #seqs, #ungapped seqs, counts indexed by (codon encoded + 1)
       int[] codonCounts = new int[66];
       codonCounts[0] = alignment.getSequences().size();
index 7c8d075..bcfa1c9 100644 (file)
@@ -36,6 +36,8 @@ public class HiddenMarkovModel
 
   Map<Character, Double> backgroundFrequencies = new HashMap();
 
+  ProfilesI profiles;
+
 
   final static String YES = "yes";
 
@@ -385,7 +387,7 @@ public class HiddenMarkovModel
    return value;
   }
   
-  public char getConsensus(int columnIndex)
+  public char getConsensusAtAlignColumn(int columnIndex)
   {
     char value;
     Integer index = findNodeIndex(columnIndex + 1);
@@ -771,16 +773,23 @@ public class HiddenMarkovModel
   {
     Annotation[] annotations = new Annotation[length];
     float max = 0f;
-    for (int i = 0; i < length; i++)
+    for (int alignPos = 0; alignPos < length; alignPos++)
     {
-      Float content = getInformationContent(i);
+      Float content = getInformationContent(alignPos);
       if (content > max)
       {
         max = content;
       }
+
+      Character cons;
+      cons = getConsensusAtAlignColumn(alignPos);
+      cons = Character.toUpperCase(cons);
+
       String description = String.format("%.3f", content);
       description += " bits";
-      annotations[i] = new Annotation(null, description, ' ', content);
+      annotations[alignPos] = new Annotation(cons.toString(), description,
+              ' ',
+              content);
 
     }
     AlignmentAnnotation annotation = new AlignmentAnnotation(
@@ -815,5 +824,6 @@ public class HiddenMarkovModel
 
     return informationContent;
   }
+
 }
 
index 9127106..3e23ac0 100755 (executable)
@@ -435,7 +435,8 @@ public class AnnotationLabels extends JPanel implements MouseListener,
           pop.add(item);
         }
       }
-      else if (label.indexOf("Consensus") > -1)
+      else if (label.indexOf("Consensus") > -1
+              || label.indexOf("Information Content") > -1)
       {
         pop.addSeparator();
         // av and sequencegroup need to implement same interface for
index 518c179..640bf45 100644 (file)
@@ -29,12 +29,14 @@ import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.HiddenColumns;
+import jalview.datamodel.HiddenMarkovModel;
 import jalview.datamodel.ProfilesI;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.NucleotideColourScheme;
 import jalview.schemes.ResidueProperties;
 import jalview.schemes.ZappoColourScheme;
 import jalview.util.Platform;
+import jalview.util.QuickSort;
 
 import java.awt.BasicStroke;
 import java.awt.Color;
@@ -48,6 +50,7 @@ import java.awt.geom.AffineTransform;
 import java.awt.image.ImageObserver;
 import java.util.BitSet;
 import java.util.Hashtable;
+import java.util.List;
 
 public class AnnotationRenderer
 {
@@ -57,6 +60,10 @@ public class AnnotationRenderer
 
   private static final int CHAR_Z = 'Z'; // 90
 
+  private static final int AMINO = 0;
+
+  private static final int DNA = 1;
+
   /**
    * flag indicating if timing and redraw parameter info should be output
    */
@@ -337,6 +344,95 @@ public class AnnotationRenderer
     av_ignoreGapsConsensus = av.isIgnoreGapsConsensus();
   }
 
+  public int[] getHMMProfileFor(AlignmentAnnotation aa, int column,
+          boolean removeBelowBackground)
+  {
+
+    HiddenMarkovModel hmm;
+    hmm = aa.getHMM();
+    int size = 0;
+    int alphabet = 0;
+    String alph = hmm.getAlphabetType();
+    if (alph.equals("amino"))
+    {
+      size = 20;
+      alphabet = AMINO;
+    }
+    else if (alph.equals("DNA"))
+    {
+      size = 4;
+      alphabet = DNA;
+    }
+
+    char symbols[] = new char[size];
+    int values[] = new int[size];
+
+    List<Character> charList = hmm.getSymbols();
+
+    int i = 0;
+    for (char character : charList)
+    {
+      symbols[i] = character;
+      i++;
+    }
+
+    Integer totalCount = 0;
+    for (int j = 0; j < size; j++)
+    {
+      Double value;
+      char symbol = symbols[j];
+      value = hmm.getMatchEmissionProbability(column, symbol);
+      double freq;
+
+      if (alphabet == AMINO && removeBelowBackground)
+      {
+        freq = ResidueProperties.aminoBackgroundFrequencies.get(symbol);
+        if (value < freq)
+        {
+          value = 0d;
+        }
+      }
+      else if (alphabet == DNA && removeBelowBackground)
+      {
+        freq = ResidueProperties.nucleotideBackgroundFrequencies
+                .get(symbol);
+        if (value < freq)
+        {
+          value = 0d;
+        }
+      }
+      value = value * 10000;
+      values[j] = value.intValue();
+      totalCount += value.intValue();
+    }
+
+    QuickSort.sort(values, symbols);
+
+    int[] profile = new int[3 + size * 2];
+
+    profile[0] = AlignmentAnnotation.SEQUENCE_PROFILE;
+    profile[1] = size;
+    profile[2] = totalCount;
+
+    if (totalCount != 0)
+    {
+      int arrayPos = 3;
+      for (int k = size - 1; k >= 0; k--)
+      {
+        Double percentage;
+        Integer value = values[k];
+        percentage = (value.doubleValue() / totalCount.doubleValue())
+                * 100d;
+        profile[arrayPos] = symbols[k];
+        profile[arrayPos + 1] = percentage.intValue();
+        arrayPos += 2;
+      }
+    }
+
+    return profile;
+
+  }
+
   /**
    * Returns profile data; the first element is the profile type, the second is
    * the number of distinct values, the third the total count, and the remainder
@@ -352,6 +448,10 @@ public class AnnotationRenderer
     // properties/rendering attributes as a global 'alignment group' which holds
     // all vis settings for the alignment as a whole rather than a subset
     //
+    if (aa.label.startsWith("Information"))
+    {
+      return getHMMProfileFor(aa, column, true);
+    }
     if (aa.autoCalculated
             && (aa.label.startsWith("Consensus") || aa.label
                     .startsWith("cDNA Consensus")))
index b2d0742..a7fc8b8 100644 (file)
@@ -1,9 +1,12 @@
 package jalview.schemes;
 
+import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AnnotatedCollectionI;
 import jalview.datamodel.HiddenMarkovModel;
 import jalview.datamodel.SequenceCollectionI;
 import jalview.datamodel.SequenceI;
+import jalview.util.ColorUtils;
+import jalview.util.Comparison;
 
 import java.awt.Color;
 import java.util.Map;
@@ -34,7 +37,7 @@ public class HMMERColourScheme extends ResidueColourScheme
   {
     if (hmm ==null)
     {
-      return new Color(255, 255, 255);
+      return Color.white;
     }
     return findColour(symbol, position);
   }
@@ -42,46 +45,72 @@ public class HMMERColourScheme extends ResidueColourScheme
   public Color findColour(char symbol, int position)
   {
 
+    if (Comparison.isGap(symbol))
+    {
+      return Color.white;
+    }
+    Double prob;
+    prob = hmm.getMatchEmissionProbability(position, symbol);
+    double freq = ResidueProperties.aminoBackgroundFrequencies.get(symbol);
+    Double value = prob - freq;
 
-    Double probability;
-    probability = hmm.getMatchEmissionProbability(position, symbol);
-    // Double redModifier = Math.pow(probability, 0.9);
-    Double doubleGreenModifier;
-    float greenModifier;
-    if (probability < 0.5)
+    Color colour = null;
+    if (value >= 0)
     {
-      doubleGreenModifier = probability;
-      greenModifier = doubleGreenModifier.floatValue();
+
+      colour = ColorUtils.getGraduatedColour(value.floatValue(), 0,
+              Color.WHITE, 1f, Color.green);
     }
-    else
+    else if (value < 0)
     {
-      doubleGreenModifier = Math.pow(probability, 1 / 1.9);
-      greenModifier = doubleGreenModifier.floatValue();
+      return Color.YELLOW;
+
     }
-    // Double blueModifier = Math.pow(probability, 0.9);
-    return new Color(1f, 1f - greenModifier, 0.f);
+    return colour;
 
   }
+    
+
+
+
+
 
   @Override
   public void alignmentChanged(AnnotatedCollectionI collection,
           Map<SequenceI, SequenceCollectionI> hiddenReps)
   {
+    AlignmentAnnotation[] annArr = collection.getAlignmentAnnotation();
+    for (AlignmentAnnotation ann : annArr)
+    {
+      if (ann.label.indexOf("Information Content") > -1)
+      {
+        hmm = ann.getHMM();
+      }
+    }
 
-    collection.setHMM(hmm);
   }
 
   @Override
   public ColourSchemeI getInstance(AnnotatedCollectionI sg,
           Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
   {
+    HiddenMarkovModel markov = null;
+    AlignmentAnnotation[] annArr = sg.getAlignmentAnnotation();
+    for (AlignmentAnnotation ann : annArr)
+    {
+      if (ann.label.indexOf("Information Content") > -1)
+      {
+        markov = ann.getHMM();
+      }
+    }
     
     
     
     
 
-    HMMERColourScheme markov = new HMMERColourScheme(sg.getHMM());
-    return markov;
+    HMMERColourScheme colour = new HMMERColourScheme(markov);
+    return colour;
+
   }
 
   @Override