Merge branch 'develop' into developtomchmmer
[jalview.git] / src / jalview / viewmodel / AlignmentViewport.java
index 148ea16..39a1c18 100644 (file)
@@ -57,6 +57,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;
@@ -97,10 +98,69 @@ public abstract class AlignmentViewport
 
   protected Deque<CommandI> redoList = new ArrayDeque<>();
 
+  protected String sequenceSetID;
+
+  /*
+   * probably unused indicator that view is of a dataset rather than an
+   * alignment
+   */
+  protected boolean isDataset = false;
+
+  private Map<SequenceI, SequenceCollectionI> hiddenRepSequences;
+
+  protected ColumnSelection colSel = new ColumnSelection();
+
+  public boolean autoCalculateConsensus = true;
+
+  protected boolean autoCalculateStrucConsensus = true;
+
+  protected boolean ignoreGapsInConsensusCalculation = false;
+
+  protected boolean ignoreBelowBackGroundFrequencyCalculation = false;
+
+  protected boolean infoLetterHeight = false;
+
+  protected ResidueShaderI residueShading = new ResidueShader();
+
+  protected AlignmentAnnotation consensus;
+
+  protected AlignmentAnnotation complementConsensus;
+
+  protected AlignmentAnnotation occupancy;
+
+  protected AlignmentAnnotation strucConsensus;
+
+  protected AlignmentAnnotation conservation;
+
+  protected AlignmentAnnotation quality;
+
+  /**
+   * alignment displayed in the viewport
+   */
+  private AlignmentI alignment;
+
+  /**
+   * results of alignment consensus analysis for visible portion of view
+   */
+  protected ProfilesI consensusProfiles;
+
+  /**
+   * HMM profile for the alignment
+   */
+  protected ProfilesI hmmProfiles;
+
+  /**
+   * results of cDNA complement consensus visible portion of view
+   */
+  protected Hashtable[] hcomplementConsensus;
+
   /**
-   * alignment displayed in the viewport. Please use get/setter
+   * results of secondary structure base pair consensus for visible portion of
+   * view
    */
-  protected AlignmentI alignment;
+  protected Hashtable[] hStrucConsensus;
+
+  protected Conservation hconservation;
 
   public AlignmentViewport(AlignmentI al)
   {
@@ -581,14 +641,6 @@ public abstract class AlignmentViewport
     return alignment.getGapCharacter();
   }
 
-  protected String sequenceSetID;
-
-  /**
-   * probably unused indicator that view is of a dataset rather than an
-   * alignment
-   */
-  protected boolean isDataset = false;
-
   public void setDataset(boolean b)
   {
     isDataset = b;
@@ -599,18 +651,6 @@ public abstract class AlignmentViewport
     return isDataset;
   }
 
-  private Map<SequenceI, SequenceCollectionI> hiddenRepSequences;
-
-  protected ColumnSelection colSel = new ColumnSelection();
-
-  public boolean autoCalculateConsensus = true;
-
-  protected boolean autoCalculateStrucConsensus = true;
-
-  protected boolean ignoreGapsInConsensusCalculation = false;
-
-  protected ResidueShaderI residueShading = new ResidueShader();
-
   @Override
   public void setGlobalColourScheme(ColourSchemeI cs)
   {
@@ -684,41 +724,6 @@ public abstract class AlignmentViewport
   {
     return residueShading;
   }
-
-  protected AlignmentAnnotation consensus;
-
-  protected AlignmentAnnotation complementConsensus;
-
-  protected AlignmentAnnotation gapcounts;
-
-  protected AlignmentAnnotation strucConsensus;
-
-  protected AlignmentAnnotation conservation;
-
-  protected AlignmentAnnotation quality;
-
-  protected AlignmentAnnotation[] groupConsensus;
-
-  protected AlignmentAnnotation[] groupConservation;
-
-  /**
-   * results of alignment consensus analysis for visible portion of view
-   */
-  protected ProfilesI hconsensus = null;
-
-  /**
-   * results of cDNA complement consensus visible portion of view
-   */
-  protected Hashtable[] hcomplementConsensus = null;
-
-  /**
-   * results of secondary structure base pair consensus for visible portion of
-   * view
-   */
-  protected Hashtable[] hStrucConsensus = null;
-
-  protected Conservation hconservation = null;
-
   @Override
   public void setConservation(Conservation cons)
   {
@@ -738,9 +743,9 @@ public abstract class AlignmentViewport
   }
 
   @Override
-  public void setSequenceConsensusHash(ProfilesI hconsensus)
+  public void setConsensusProfiles(ProfilesI hconsensus)
   {
-    this.hconsensus = hconsensus;
+    this.consensusProfiles = hconsensus;
   }
 
   @Override
@@ -750,9 +755,21 @@ public abstract class AlignmentViewport
   }
 
   @Override
-  public ProfilesI getSequenceConsensusHash()
+  public ProfilesI getConsensusProfiles()
+  {
+    return consensusProfiles;
+  }
+
+  @Override
+  public void setHmmProfiles(ProfilesI info)
+  {
+    hmmProfiles = info;
+  }
+
+  @Override
+  public ProfilesI getHmmProfiles()
   {
-    return hconsensus;
+    return hmmProfiles;
   }
 
   @Override
@@ -793,9 +810,9 @@ public abstract class AlignmentViewport
   }
 
   @Override
-  public AlignmentAnnotation getAlignmentGapAnnotation()
+  public AlignmentAnnotation getOccupancyAnnotation()
   {
-    return gapcounts;
+    return occupancy;
   }
 
   @Override
@@ -884,6 +901,16 @@ public abstract class AlignmentViewport
     }
   }
 
+  @Override
+  public void initInformationWorker(final AlignmentViewPanel ap)
+  {
+    if (calculator
+            .getRegisteredWorkersOfClass(InformationThread.class) == null)
+    {
+      calculator.registerWorker(new InformationThread(this, ap));
+    }
+  }
+
   // --------START Structure Conservation
   public void updateStrucConsensus(final AlignmentViewPanel ap)
   {
@@ -947,12 +974,10 @@ public abstract class AlignmentViewport
     strucConsensus = null;
     conservation = null;
     quality = null;
-    groupConsensus = null;
-    groupConservation = null;
-    hconsensus = null;
+    consensusProfiles = null;
     hconservation = null;
     hcomplementConsensus = null;
-    gapcounts = null;
+    occupancy = null;
     calculator = null;
     residueShading = null; // may hold a reference to Consensus
     changeSupport = null;
@@ -1002,6 +1027,21 @@ public abstract class AlignmentViewport
   protected boolean showConsensusHistogram = true;
 
   /**
+   * should hmm profile be rendered by default
+   */
+  protected boolean hmmShowSequenceLogo = false;
+
+  /**
+   * should hmm profile be rendered normalised to row height
+   */
+  protected boolean hmmNormaliseSequenceLogo = false;
+
+  /**
+   * should information histograms be rendered by default
+   */
+  protected boolean hmmShowHistogram = true;
+
+  /**
    * @return the showConsensusProfile
    */
   @Override
@@ -1011,6 +1051,15 @@ public abstract class AlignmentViewport
   }
 
   /**
+   * @return the showInformationProfile
+   */
+  @Override
+  public boolean isShowHMMSequenceLogo()
+  {
+    return hmmShowSequenceLogo;
+  }
+
+  /**
    * @param showSequenceLogo
    *          the new value
    */
@@ -1028,6 +1077,18 @@ public abstract class AlignmentViewport
     this.showSequenceLogo = showSequenceLogo;
   }
 
+  public void setShowHMMSequenceLogo(boolean showHMMSequenceLogo)
+  {
+    if (showHMMSequenceLogo != this.hmmShowSequenceLogo)
+    {
+      this.hmmShowSequenceLogo = showHMMSequenceLogo;
+      // TODO: updateAnnotation if description (tooltip) will show
+      // profile in place of information content?
+      // calculator.updateAnnotationFor(InformationThread.class);
+    }
+    this.hmmShowSequenceLogo = showHMMSequenceLogo;
+  }
+
   /**
    * @param showConsensusHistogram
    *          the showConsensusHistogram to set
@@ -1038,6 +1099,14 @@ public abstract class AlignmentViewport
   }
 
   /**
+   * @param showInformationHistogram
+   */
+  public void setShowInformationHistogram(boolean showInformationHistogram)
+  {
+    this.hmmShowHistogram = showInformationHistogram;
+  }
+
+  /**
    * @return the showGroupConservation
    */
   public boolean isShowGroupConservation()
@@ -1083,6 +1152,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.hmmShowHistogram;
+  }
+
+  /**
    * when set, updateAlignment will always ensure sequences are of equal length
    */
   private boolean padGaps = false;
@@ -1231,14 +1311,22 @@ public abstract class AlignmentViewport
     ignoreGapsInConsensusCalculation = b;
     if (ap != null)
     {
-      updateConsensus(ap);
       if (residueShading != null)
       {
         residueShading.setThreshold(residueShading.getThreshold(),
                 ignoreGapsInConsensusCalculation);
       }
     }
+  }
+
+  public void setIgnoreBelowBackground(boolean b, AlignmentViewPanel ap)
+  {
+    ignoreBelowBackGroundFrequencyCalculation = b;
+  }
 
+  public void setInfoLetterHeight(boolean b, AlignmentViewPanel ap)
+  {
+    infoLetterHeight = b;
   }
 
   private long sgrouphash = -1, colselhash = -1;
@@ -1295,6 +1383,18 @@ public abstract class AlignmentViewport
     return ignoreGapsInConsensusCalculation;
   }
 
+  @Override
+  public boolean isIgnoreBelowBackground()
+  {
+    return ignoreBelowBackGroundFrequencyCalculation;
+  }
+
+  @Override
+  public boolean isInfoLetterHeight()
+  {
+    return infoLetterHeight;
+  }
+
   // property change stuff
   // JBPNote Prolly only need this in the applet version.
   private PropertyChangeSupport changeSupport = new PropertyChangeSupport(
@@ -1661,7 +1761,8 @@ public abstract class AlignmentViewport
     }
     else
     {
-      sequences = selectionGroup.getSelectionAsNewSequences(alignment);
+      sequences = selectionGroup.getSelectionAsNewSequences(alignment,
+              true);
     }
 
     return sequences;
@@ -1855,18 +1956,6 @@ public abstract class AlignmentViewport
     {
       alignment.padGaps();
     }
-    if (autoCalculateConsensus)
-    {
-      updateConsensus(ap);
-    }
-    if (hconsensus != null && autoCalculateConsensus)
-    {
-      updateConservation(ap);
-    }
-    if (autoCalculateStrucConsensus)
-    {
-      updateStrucConsensus(ap);
-    }
 
     // Reset endRes of groups if beyond alignment width
     int alWidth = alignment.getWidth();
@@ -1889,7 +1978,6 @@ public abstract class AlignmentViewport
 
     updateAllColourSchemes();
     calculator.restartWorkers();
-    // alignment.adjustSequenceAnnotations();
   }
 
   /**
@@ -1902,7 +1990,7 @@ public abstract class AlignmentViewport
     {
       rs.alignmentChanged(alignment, hiddenRepSequences);
 
-      rs.setConsensus(hconsensus);
+      rs.setConsensus(consensusProfiles);
       if (rs.conservationApplied())
       {
         rs.setConservation(Conservation.calculateConservation("All",
@@ -1927,7 +2015,7 @@ public abstract class AlignmentViewport
     // depending on if the user wants to see the annotation or not in a
     // specific alignment
 
-    if (hconsensus == null && !isDataset)
+    if (consensusProfiles == null && !isDataset)
     {
       if (!alignment.isNucleotide())
       {
@@ -1942,7 +2030,8 @@ public abstract class AlignmentViewport
               MessageManager.getString("label.consensus_descr"),
               new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
       initConsensus(consensus);
-      initGapCounts();
+
+      initOccupancy();
 
       initComplementConsensus();
     }
@@ -2001,20 +2090,20 @@ public abstract class AlignmentViewport
 
   // these should be extracted from the view model - style and settings for
   // derived annotation
-  private void initGapCounts()
+  private void initOccupancy()
   {
     if (showOccupancy)
     {
-      gapcounts = new AlignmentAnnotation("Occupancy",
+      occupancy = new AlignmentAnnotation("Occupancy",
               MessageManager.getString("label.occupancy_descr"),
               new Annotation[1], 0f, alignment.getHeight(),
               AlignmentAnnotation.BAR_GRAPH);
-      gapcounts.hasText = true;
-      gapcounts.autoCalculated = true;
-      gapcounts.scaleColLabel = true;
-      gapcounts.graph = AlignmentAnnotation.BAR_GRAPH;
+      occupancy.hasText = true;
+      occupancy.autoCalculated = true;
+      occupancy.scaleColLabel = true;
+      occupancy.graph = AlignmentAnnotation.BAR_GRAPH;
 
-      alignment.addAnnotation(gapcounts);
+      alignment.addAnnotation(occupancy);
     }
   }
 
@@ -2148,6 +2237,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
@@ -2185,6 +2277,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)
         {
@@ -2945,6 +3040,19 @@ public abstract class AlignmentViewport
     return sq;
   }
 
+  public boolean hasReferenceAnnotation()
+  {
+    AlignmentAnnotation[] annots = this.alignment.getAlignmentAnnotation();
+    for (AlignmentAnnotation annot : annots)
+    {
+      if ("RF".equals(annot.label) || annot.label.contains("Reference"))
+      {
+        return true;
+      }
+    }
+    return false;
+  }
+
   @Override
   public void setCurrentTree(TreeModel tree)
   {
@@ -2957,6 +3065,28 @@ public abstract class AlignmentViewport
     return currentTree;
   }
 
+  @Override
+  public boolean isNormaliseSequenceLogo()
+  {
+    return normaliseSequenceLogo;
+  }
+
+  public void setNormaliseSequenceLogo(boolean state)
+  {
+    normaliseSequenceLogo = state;
+  }
+
+  @Override
+  public boolean isNormaliseHMMSequenceLogo()
+  {
+    return hmmNormaliseSequenceLogo;
+  }
+
+  public void setNormaliseHMMSequenceLogo(boolean state)
+  {
+    hmmNormaliseSequenceLogo = state;
+  }
+
   /**
    * flag set to indicate if structure views might be out of sync with sequences
    * in the alignment