Merge branch 'develop' into developtomchmmer
[jalview.git] / src / jalview / viewmodel / AlignmentViewport.java
index ecca699..39a1c18 100644 (file)
@@ -37,8 +37,6 @@ import jalview.datamodel.Annotation;
 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;
@@ -70,6 +68,7 @@ import java.util.BitSet;
 import java.util.Deque;
 import java.util.HashMap;
 import java.util.Hashtable;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
@@ -113,8 +112,6 @@ public abstract class AlignmentViewport
 
   public boolean autoCalculateConsensus = true;
 
-  public boolean autoCalculateInformation = true;
-
   protected boolean autoCalculateStrucConsensus = true;
 
   protected boolean ignoreGapsInConsensusCalculation = false;
@@ -137,8 +134,6 @@ public abstract class AlignmentViewport
 
   protected AlignmentAnnotation quality;
 
-  protected List<AlignmentAnnotation> information = new ArrayList<>();
-
   /**
    * alignment displayed in the viewport
    */
@@ -147,25 +142,25 @@ public abstract class AlignmentViewport
   /**
    * results of alignment consensus analysis for visible portion of view
    */
-  protected ProfilesI hconsensus = null;
+  protected ProfilesI consensusProfiles;
 
   /**
-   * results of information annotation analysis for the visible portion of view
+   * HMM profile for the alignment
    */
-  protected List<ProfilesI> hinformation = new ArrayList<>();
+  protected ProfilesI hmmProfiles;
 
   /**
    * results of cDNA complement consensus visible portion of view
    */
-  protected Hashtable[] hcomplementConsensus = null;
+  protected Hashtable[] hcomplementConsensus;
 
   /**
    * results of secondary structure base pair consensus for visible portion of
    * view
    */
-  protected Hashtable[] hStrucConsensus = null;
+  protected Hashtable[] hStrucConsensus;
 
-  protected Conservation hconservation = null;
+  protected Conservation hconservation;
 
   public AlignmentViewport(AlignmentI al)
   {
@@ -707,7 +702,8 @@ public abstract class AlignmentViewport
          * retain any colour thresholds per group while
          * changing choice of colour scheme (JAL-2386)
          */
-        sg.setColourScheme(cs);
+        sg.setColourScheme(
+                cs == null ? null : cs.getInstance(this, sg));
         if (cs != null)
         {
           sg.getGroupColourScheme().alignmentChanged(sg,
@@ -747,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
@@ -759,37 +755,21 @@ public abstract class AlignmentViewport
   }
 
   @Override
-  public ProfilesI getSequenceConsensusHash()
+  public ProfilesI getConsensusProfiles()
   {
-    return hconsensus;
-  }
-
-  @Override
-  public void setSequenceInformationHashes(List<ProfilesI> info)
-  {
-    hinformation = info;
-  }
-
-  @Override
-  public void setSequenceInformationHash(ProfilesI info, int index)
-  {
-    if (hinformation.size() < index + 1)
-    {
-      return;
-    }
-    hinformation.set(index, info);
+    return consensusProfiles;
   }
 
   @Override
-  public List<ProfilesI> getSequenceInformationHashes()
+  public void setHmmProfiles(ProfilesI info)
   {
-    return hinformation;
+    hmmProfiles = info;
   }
 
   @Override
-  public ProfilesI getSequenceInformationHash(int index)
+  public ProfilesI getHmmProfiles()
   {
-    return hinformation.get(index);
+    return hmmProfiles;
   }
 
   @Override
@@ -830,13 +810,7 @@ public abstract class AlignmentViewport
   }
 
   @Override
-  public List<AlignmentAnnotation> getInformationAnnotations()
-  {
-    return information;
-  }
-
-  @Override
-  public AlignmentAnnotation getAlignmentGapAnnotation()
+  public AlignmentAnnotation getOccupancyAnnotation()
   {
     return occupancy;
   }
@@ -927,18 +901,14 @@ public abstract class AlignmentViewport
     }
   }
 
-  /**
-   * trigger update of information annotation
-   */
   @Override
-  public void updateInformation(final AlignmentViewPanel ap)
+  public void initInformationWorker(final AlignmentViewPanel ap)
   {
     if (calculator
             .getRegisteredWorkersOfClass(InformationThread.class) == null)
     {
       calculator.registerWorker(new InformationThread(this, ap));
     }
-
   }
 
   // --------START Structure Conservation
@@ -1004,7 +974,7 @@ public abstract class AlignmentViewport
     strucConsensus = null;
     conservation = null;
     quality = null;
-    hconsensus = null;
+    consensusProfiles = null;
     hconservation = null;
     hcomplementConsensus = null;
     occupancy = null;
@@ -1059,17 +1029,17 @@ public abstract class AlignmentViewport
   /**
    * should hmm profile be rendered by default
    */
-  protected boolean showHMMSequenceLogo = false;
+  protected boolean hmmShowSequenceLogo = false;
 
   /**
    * should hmm profile be rendered normalised to row height
    */
-  protected boolean normaliseHMMSequenceLogo = false;
+  protected boolean hmmNormaliseSequenceLogo = false;
 
   /**
    * should information histograms be rendered by default
    */
-  protected boolean showInformationHistogram = true;
+  protected boolean hmmShowHistogram = true;
 
   /**
    * @return the showConsensusProfile
@@ -1086,7 +1056,7 @@ public abstract class AlignmentViewport
   @Override
   public boolean isShowHMMSequenceLogo()
   {
-    return showHMMSequenceLogo;
+    return hmmShowSequenceLogo;
   }
 
   /**
@@ -1109,12 +1079,14 @@ public abstract class AlignmentViewport
 
   public void setShowHMMSequenceLogo(boolean showHMMSequenceLogo)
   {
-    if (showHMMSequenceLogo != this.showHMMSequenceLogo)
+    if (showHMMSequenceLogo != this.hmmShowSequenceLogo)
     {
-      this.showHMMSequenceLogo = showHMMSequenceLogo;
-      calculator.updateAnnotationFor(InformationThread.class);
+      this.hmmShowSequenceLogo = showHMMSequenceLogo;
+      // TODO: updateAnnotation if description (tooltip) will show
+      // profile in place of information content?
+      // calculator.updateAnnotationFor(InformationThread.class);
     }
-    this.showHMMSequenceLogo = showHMMSequenceLogo;
+    this.hmmShowSequenceLogo = showHMMSequenceLogo;
   }
 
   /**
@@ -1128,11 +1100,10 @@ public abstract class AlignmentViewport
 
   /**
    * @param showInformationHistogram
-   *          the showInformationHistogram to set
    */
   public void setShowInformationHistogram(boolean showInformationHistogram)
   {
-    this.showInformationHistogram = showInformationHistogram;
+    this.hmmShowHistogram = showInformationHistogram;
   }
 
   /**
@@ -1188,7 +1159,7 @@ public abstract class AlignmentViewport
   @Override
   public boolean isShowInformationHistogram()
   {
-    return this.showInformationHistogram;
+    return this.hmmShowHistogram;
   }
 
   /**
@@ -1340,34 +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;
-    if (ap != null)
-    {
-      updateInformation(ap);
-    }
-
   }
 
   public void setInfoLetterHeight(boolean b, AlignmentViewPanel ap)
   {
     infoLetterHeight = b;
-    if (ap != null)
-    {
-      updateInformation(ap);
-    }
-
   }
 
   private long sgrouphash = -1, colselhash = -1;
@@ -1778,6 +1737,7 @@ public abstract class AlignmentViewport
   public void invertColumnSelection()
   {
     colSel.invertColumnSelection(0, alignment.getWidth(), alignment);
+    isColSelChanged(true);
   }
 
   @Override
@@ -1801,7 +1761,8 @@ public abstract class AlignmentViewport
     }
     else
     {
-      sequences = selectionGroup.getSelectionAsNewSequences(alignment);
+      sequences = selectionGroup.getSelectionAsNewSequences(alignment,
+              true);
     }
 
     return sequences;
@@ -1883,8 +1844,12 @@ public abstract class AlignmentViewport
     if (alignment.getHiddenColumns() != null
             && alignment.getHiddenColumns().hasHiddenColumns())
     {
-      selection = alignment.getHiddenColumns()
-              .getVisibleSequenceStrings(start, end, seqs);
+      for (i = 0; i < iSize; i++)
+      {
+        Iterator<int[]> blocks = alignment.getHiddenColumns()
+                .getVisContigsIterator(start, end + 1, false);
+        selection[i] = seqs[i].getSequenceStringFromIterator(blocks);
+      }
     }
     else
     {
@@ -1911,10 +1876,10 @@ public abstract class AlignmentViewport
       {
         if (start == 0)
         {
-          start = hidden.adjustForHiddenColumns(start);
+          start = hidden.visibleToAbsoluteColumn(start);
         }
 
-        end = hidden.getHiddenBoundaryRight(start);
+        end = hidden.getNextHiddenBoundary(false, start);
         if (start == end)
         {
           end = max;
@@ -1929,8 +1894,8 @@ public abstract class AlignmentViewport
 
       if (hidden != null && hidden.hasHiddenColumns())
       {
-        start = hidden.adjustForHiddenColumns(end);
-        start = hidden.getHiddenBoundaryLeft(start) + 1;
+        start = hidden.visibleToAbsoluteColumn(end);
+        start = hidden.getNextHiddenBoundary(true, start) + 1;
       }
     } while (end < max);
 
@@ -1952,13 +1917,13 @@ public abstract class AlignmentViewport
         AlignmentAnnotation clone = new AlignmentAnnotation(annot);
         if (selectedOnly && selectionGroup != null)
         {
-          alignment.getHiddenColumns().makeVisibleAnnotation(
+          clone.makeVisibleAnnotation(
                   selectionGroup.getStartRes(), selectionGroup.getEndRes(),
-                  clone);
+                  alignment.getHiddenColumns());
         }
         else
         {
-          alignment.getHiddenColumns().makeVisibleAnnotation(clone);
+          clone.makeVisibleAnnotation(alignment.getHiddenColumns());
         }
         ala.add(clone);
       }
@@ -1991,28 +1956,6 @@ public abstract class AlignmentViewport
     {
       alignment.padGaps();
     }
-    if (autoCalculateConsensus)
-    {
-      updateConsensus(ap);
-    }
-    if (hconsensus != null && autoCalculateConsensus)
-    {
-      updateConservation(ap);
-    }
-    if (autoCalculateStrucConsensus)
-    {
-      updateStrucConsensus(ap);
-    }
-    initInformation();
-    updateInformation(ap);
-
-    List<SequenceI> hmmSequences;
-    hmmSequences = alignment.getHMMConsensusSequences();
-
-    for (SequenceI seq : hmmSequences)
-    {
-      seq.updateHMMMapping();
-    }
 
     // Reset endRes of groups if beyond alignment width
     int alWidth = alignment.getWidth();
@@ -2035,7 +1978,6 @@ public abstract class AlignmentViewport
 
     updateAllColourSchemes();
     calculator.restartWorkers();
-    // alignment.adjustSequenceAnnotations();
   }
 
   /**
@@ -2048,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",
@@ -2073,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())
       {
@@ -2146,30 +2088,6 @@ public abstract class AlignmentViewport
     }
   }
 
-  @Override
-  public void initInformation()
-  {
-    for (SequenceI seq : alignment.getHMMConsensusSequences())
-    {
-      if (!seq.hasHMMAnnotation())
-      {
-        AlignmentAnnotation info = new AlignmentAnnotation(seq.getName(),
-                MessageManager.getString("label.information_description"),
-                new Annotation[1], 0f, 6.52f,
-                AlignmentAnnotation.BAR_GRAPH);
-        info.hasText = true;
-        info.autoCalculated = false;
-        info.sequenceRef = seq;
-        info.setCalcId(InformationThread.HMM_CALC_ID);
-        this.information.add(info);
-        hinformation.add(new Profiles(new ProfileI[1]));
-        alignment.addAnnotation(info);
-        seq.updateHMMMapping();
-        seq.addAlignmentAnnotation(info);
-      }
-    }
-  }
-
   // these should be extracted from the view model - style and settings for
   // derived annotation
   private void initOccupancy()
@@ -2359,7 +2277,7 @@ public abstract class AlignmentViewport
           sg.setshowSequenceLogo(showprf);
           sg.setShowConsensusHistogram(showConsHist);
           sg.setNormaliseSequenceLogo(normLogo);
-          sg.setshowHMMSequenceLogo(showHMMPrf);
+          sg.setShowHMMSequenceLogo(showHMMPrf);
           sg.setShowInformationHistogram(showInfoHist);
           sg.setNormaliseHMMSequenceLogo(normHMMLogo);
         }
@@ -2965,7 +2883,7 @@ public abstract class AlignmentViewport
     int lastSeq = alignment.getHeight() - 1;
     List<AlignedCodonFrame> seqMappings = null;
     for (int seqNo = ranges
-            .getStartSeq(); seqNo < lastSeq; seqNo++, seqOffset++)
+            .getStartSeq(); seqNo <= lastSeq; seqNo++, seqOffset++)
     {
       sequence = getAlignment().getSequenceAt(seqNo);
       if (hiddenSequences != null && hiddenSequences.isHidden(sequence))
@@ -3146,4 +3064,90 @@ 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
+   */
+
+  private boolean needToUpdateStructureViews = false;
+
+  @Override
+  public boolean isUpdateStructures()
+  {
+    return needToUpdateStructureViews;
+  }
+
+  @Override
+  public void setUpdateStructures(boolean update)
+  {
+    needToUpdateStructureViews = update;
+  }
+
+  @Override
+  public boolean needToUpdateStructureViews()
+  {
+    boolean update = needToUpdateStructureViews;
+    needToUpdateStructureViews = false;
+    return update;
+  }
+
+  @Override
+  public void addSequenceGroup(SequenceGroup sequenceGroup)
+  {
+    alignment.addGroup(sequenceGroup);
+
+    Color col = sequenceGroup.idColour;
+    if (col != null)
+    {
+      col = col.brighter();
+
+      for (SequenceI sq : sequenceGroup.getSequences())
+      {
+        setSequenceColour(sq, col);
+      }
+    }
+
+    if (codingComplement != null)
+    {
+      SequenceGroup mappedGroup = MappingUtils
+              .mapSequenceGroup(sequenceGroup, this, codingComplement);
+      if (mappedGroup.getSequences().size() > 0)
+      {
+        codingComplement.getAlignment().addGroup(mappedGroup);
+
+        if (col != null)
+        {
+          for (SequenceI seq : mappedGroup.getSequences())
+          {
+            codingComplement.setSequenceColour(seq, col);
+          }
+        }
+      }
+      // propagate the structure view update flag according to our own setting
+      codingComplement.setUpdateStructures(needToUpdateStructureViews);
+    }
+  }
 }