Merge branch 'develop' into features/hmmer
[jalview.git] / src / jalview / viewmodel / AlignmentViewport.java
index 3702cd0..0ec07c0 100644 (file)
@@ -37,6 +37,8 @@ import jalview.datamodel.CigarArray;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.HiddenColumns;
 import jalview.datamodel.HiddenSequences;
+import jalview.datamodel.ProfileI;
+import jalview.datamodel.Profiles;
 import jalview.datamodel.ProfilesI;
 import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.Sequence;
@@ -57,6 +59,7 @@ import jalview.viewmodel.styles.ViewStyle;
 import jalview.workers.AlignCalcManager;
 import jalview.workers.ComplementConsensusThread;
 import jalview.workers.ConsensusThread;
+import jalview.workers.InformationThread;
 import jalview.workers.StrucConsensusThread;
 
 import java.awt.Color;
@@ -96,6 +99,7 @@ public abstract class AlignmentViewport
 
   protected Deque<CommandI> redoList = new ArrayDeque<>();
 
+
   /**
    * alignment displayed in the viewport. Please use get/setter
    */
@@ -604,10 +608,14 @@ public abstract class AlignmentViewport
 
   public boolean autoCalculateConsensus = true;
 
+  public boolean autoCalculateInformation = true;
+
   protected boolean autoCalculateStrucConsensus = true;
 
   protected boolean ignoreGapsInConsensusCalculation = false;
 
+  protected boolean ignoreBelowBackGroundFrequencyCalculation = false;
+
   protected ResidueShaderI residueShading = new ResidueShader();
 
   @Override
@@ -699,12 +707,21 @@ public abstract class AlignmentViewport
 
   protected AlignmentAnnotation[] groupConservation;
 
+  protected List<AlignmentAnnotation> groupInformation = new ArrayList<>();
+
+  protected List<AlignmentAnnotation> information = new ArrayList<>();
+
   /**
    * results of alignment consensus analysis for visible portion of view
    */
   protected ProfilesI hconsensus = null;
 
   /**
+   * results of information annotation analysis for the visible portion of view
+   */
+  protected List<ProfilesI> hinformation = new ArrayList<>();
+
+  /**
    * results of cDNA complement consensus visible portion of view
    */
   protected Hashtable[] hcomplementConsensus = null;
@@ -754,6 +771,30 @@ public abstract class AlignmentViewport
   }
 
   @Override
+  public void setSequenceInformationHashes(List<ProfilesI> info)
+  {
+    hinformation = info;
+  }
+
+  @Override
+  public void setSequenceInformationHash(ProfilesI info, int index)
+  {
+    hinformation.set(index, info);
+  }
+
+  @Override
+  public List<ProfilesI> getSequenceInformationHashes()
+  {
+    return hinformation;
+  }
+
+  @Override
+  public ProfilesI getSequenceInformationHash(int index)
+  {
+    return hinformation.get(index);
+  }
+
+  @Override
   public Hashtable[] getComplementConsensusHash()
   {
     return hcomplementConsensus;
@@ -791,6 +832,18 @@ public abstract class AlignmentViewport
   }
 
   @Override
+  public List<AlignmentAnnotation> getInformationAnnotations()
+  {
+    return information;
+  }
+
+  @Override
+  public AlignmentAnnotation getInformationAnnotation(int index)
+  {
+    return information.get(index);
+  }
+
+  @Override
   public AlignmentAnnotation getAlignmentGapAnnotation()
   {
     return gapcounts;
@@ -882,6 +935,20 @@ public abstract class AlignmentViewport
     }
   }
 
+  /**
+   * trigger update of information annotation
+   */
+  @Override
+  public void updateInformation(final AlignmentViewPanel ap)
+  {
+    if (calculator
+            .getRegisteredWorkersOfClass(InformationThread.class) == null)
+    {
+      calculator.registerWorker(new InformationThread(this, ap));
+    }
+
+  }
+
   // --------START Structure Conservation
   public void updateStrucConsensus(final AlignmentViewPanel ap)
   {
@@ -996,6 +1063,21 @@ public abstract class AlignmentViewport
   protected boolean showConsensusHistogram = true;
 
   /**
+   * should hmm profile be rendered by default
+   */
+  protected boolean showHMMSequenceLogo = false;
+
+  /**
+   * should hmm profile be rendered normalised to row height
+   */
+  protected boolean normaliseHMMSequenceLogo = false;
+
+  /**
+   * should information histograms be rendered by default
+   */
+  protected boolean showInformationHistogram = true;
+
+  /**
    * @return the showConsensusProfile
    */
   @Override
@@ -1005,6 +1087,15 @@ public abstract class AlignmentViewport
   }
 
   /**
+   * @return the showInformationProfile
+   */
+  @Override
+  public boolean isShowHMMSequenceLogo()
+  {
+    return showHMMSequenceLogo;
+  }
+
+  /**
    * @param showSequenceLogo
    *          the new value
    */
@@ -1022,6 +1113,16 @@ public abstract class AlignmentViewport
     this.showSequenceLogo = showSequenceLogo;
   }
 
+  public void setShowHMMSequenceLogo(boolean showHMMSequenceLogo)
+  {
+    if (showHMMSequenceLogo != this.showHMMSequenceLogo)
+    {
+      this.showHMMSequenceLogo = showHMMSequenceLogo;
+      calculator.updateAnnotationFor(InformationThread.class);
+    }
+    this.showHMMSequenceLogo = showHMMSequenceLogo;
+  }
+
   /**
    * @param showConsensusHistogram
    *          the showConsensusHistogram to set
@@ -1032,6 +1133,15 @@ public abstract class AlignmentViewport
   }
 
   /**
+   * @param showInformationHistogram
+   *          the showInformationHistogram to set
+   */
+  public void setShowInformationHistogram(boolean showInformationHistogram)
+  {
+    this.showInformationHistogram = showInformationHistogram;
+  }
+
+  /**
    * @return the showGroupConservation
    */
   public boolean isShowGroupConservation()
@@ -1077,6 +1187,17 @@ public abstract class AlignmentViewport
   }
 
   /**
+   * 
+   * @return flag to indicate if the information content histogram should be
+   *         rendered by default
+   */
+  @Override
+  public boolean isShowInformationHistogram()
+  {
+    return this.showInformationHistogram;
+  }
+
+  /**
    * when set, updateAlignment will always ensure sequences are of equal length
    */
   private boolean padGaps = false;
@@ -1235,6 +1356,16 @@ public abstract class AlignmentViewport
 
   }
 
+  public void setIgnoreBelowBackground(boolean b, AlignmentViewPanel ap)
+  {
+    ignoreBelowBackGroundFrequencyCalculation = b;
+    if (ap != null)
+    {
+      updateInformation(ap);
+    }
+
+  }
+
   private long sgrouphash = -1, colselhash = -1;
 
   /**
@@ -1289,6 +1420,12 @@ public abstract class AlignmentViewport
     return ignoreGapsInConsensusCalculation;
   }
 
+  @Override
+  public boolean isIgnoreBelowBackground()
+  {
+    return ignoreBelowBackGroundFrequencyCalculation;
+  }
+
   // property change stuff
   // JBPNote Prolly only need this in the applet version.
   private PropertyChangeSupport changeSupport = new PropertyChangeSupport(
@@ -1860,6 +1997,15 @@ public abstract class AlignmentViewport
     {
       updateStrucConsensus(ap);
     }
+    updateInformation(ap);
+
+    List<SequenceI> hmmSequences;
+    hmmSequences = alignment.getHMMConsensusSequences(false);
+
+    for (SequenceI seq : hmmSequences)
+    {
+      seq.updateHMMMapping();
+    }
 
     // Reset endRes of groups if beyond alignment width
     int alWidth = alignment.getWidth();
@@ -1935,6 +2081,7 @@ public abstract class AlignmentViewport
               MessageManager.getString("label.consensus_descr"),
               new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
       initConsensus(consensus);
+
       initGapCounts();
 
       initComplementConsensus();
@@ -1992,6 +2139,35 @@ public abstract class AlignmentViewport
     }
   }
 
+  @Override
+  public void initInformation()
+  {
+    for (SequenceI seq : alignment.getHMMConsensusSequences(false))
+    {
+      if (!seq.hasHMMAnnotation())
+      {
+        AlignmentAnnotation information;
+        information = new AlignmentAnnotation(seq.getName(),
+                MessageManager.getString("label.information_description"),
+                new Annotation[1], 0f, 6.52f,
+                AlignmentAnnotation.BAR_GRAPH);
+        information.hasText = true;
+        information.autoCalculated = true;
+        information.hasText = true;
+        information.autoCalculated = false;
+        information.sequenceRef = seq;
+        information.setCalcId("HMM annotation");
+        this.information.add(information);
+        hinformation.add(new Profiles(new ProfileI[1]));
+        alignment.addAnnotation(information);
+        seq.updateHMMMapping();
+        seq.setHasInfo(true);
+        seq.addAlignmentAnnotation(information);
+      }
+    }
+
+  }
+
   // these should be extracted from the view model - style and settings for
   // derived annotation
   private void initGapCounts()
@@ -2141,6 +2317,9 @@ public abstract class AlignmentViewport
     boolean showprf = isShowSequenceLogo();
     boolean showConsHist = isShowConsensusHistogram();
     boolean normLogo = isNormaliseSequenceLogo();
+    boolean showHMMPrf = isShowHMMSequenceLogo();
+    boolean showInfoHist = isShowInformationHistogram();
+    boolean normHMMLogo = isNormaliseHMMSequenceLogo();
 
     /**
      * TODO reorder the annotation rows according to group/sequence ordering on
@@ -2178,6 +2357,9 @@ public abstract class AlignmentViewport
           sg.setshowSequenceLogo(showprf);
           sg.setShowConsensusHistogram(showConsHist);
           sg.setNormaliseSequenceLogo(normLogo);
+          sg.setshowHMMSequenceLogo(showHMMPrf);
+          sg.setShowInformationHistogram(showInfoHist);
+          sg.setNormaliseHMMSequenceLogo(normHMMLogo);
         }
         if (conv)
         {