JAL-4392 Merging consensus secondary structure
[jalview.git] / src / jalview / viewmodel / AlignmentViewport.java
index 3e1bc63..ccf6379 100644 (file)
@@ -76,6 +76,7 @@ import jalview.viewmodel.styles.ViewStyle;
 import jalview.workers.AlignCalcManager;
 import jalview.workers.ComplementConsensusThread;
 import jalview.workers.ConsensusThread;
+import jalview.workers.SecondaryStructureConsensusThread;
 import jalview.workers.StrucConsensusThread;
 
 /**
@@ -697,6 +698,8 @@ public abstract class AlignmentViewport
   }
 
   protected AlignmentAnnotation consensus;
+  
+  protected AlignmentAnnotation secondaryStructureConsensus;
 
   protected AlignmentAnnotation complementConsensus;
 
@@ -709,6 +712,8 @@ public abstract class AlignmentViewport
   protected AlignmentAnnotation quality;
 
   protected AlignmentAnnotation[] groupConsensus;
+  
+  protected AlignmentAnnotation[] groupSSConsensus;
 
   protected AlignmentAnnotation[] groupConservation;
 
@@ -716,6 +721,10 @@ public abstract class AlignmentViewport
    * results of alignment consensus analysis for visible portion of view
    */
   protected ProfilesI hconsensus = null;
+  
+  protected ProfilesI hSSConsensus = null;
+  
+  
 
   /**
    * results of cDNA complement consensus visible portion of view
@@ -753,7 +762,13 @@ public abstract class AlignmentViewport
   {
     this.hconsensus = hconsensus;
   }
-
+  
+  @Override
+  public void setSequenceSSConsensusHash(ProfilesI hSSConsensus)
+  {
+    this.hSSConsensus = hSSConsensus;
+  }
+  
   @Override
   public void setComplementConsensusHash(
           Hashtable<String, Object>[] hconsensus)
@@ -766,6 +781,12 @@ public abstract class AlignmentViewport
   {
     return hconsensus;
   }
+  
+  @Override
+  public ProfilesI getSequenceSSConsensusHash()
+  {
+    return hSSConsensus;
+  }
 
   @Override
   public Hashtable<String, Object>[] getComplementConsensusHash()
@@ -805,6 +826,14 @@ public abstract class AlignmentViewport
     return consensus;
   }
 
+  
+  @Override
+  public AlignmentAnnotation getAlignmentSecondaryStructureConsensusAnnotation()
+  {
+    return secondaryStructureConsensus;
+  }
+  
+
   @Override
   public AlignmentAnnotation getAlignmentGapAnnotation()
   {
@@ -896,6 +925,26 @@ public abstract class AlignmentViewport
       }
     }
   }
+  
+  
+  
+
+  /**
+   * trigger update of consensus annotation
+   */
+  public void updateSecondaryStructureConsensus(final AlignmentViewPanel ap)
+  {
+    // see note in mantis : issue number 8585
+    if (secondaryStructureConsensus == null || !autoCalculateConsensus)
+    {
+      return;
+    }
+    if (calculator
+            .getRegisteredWorkersOfClass(SecondaryStructureConsensusThread.class) == null)
+    {
+      calculator.registerWorker(new SecondaryStructureConsensusThread(this, ap));
+    }
+  }
 
   // --------START Structure Conservation
   public void updateStrucConsensus(final AlignmentViewPanel ap)
@@ -959,6 +1008,7 @@ public abstract class AlignmentViewport
     consensus = null;
     complementConsensus = null;
     strucConsensus = null;
+    secondaryStructureConsensus = null;
     conservation = null;
     quality = null;
     groupConsensus = null;
@@ -1005,6 +1055,8 @@ public abstract class AlignmentViewport
    * should consensus profile be rendered by default
    */
   protected boolean showSequenceLogo = false;
+  
+  protected boolean showSequenceSSLogo = false;
 
   /**
    * should consensus profile be rendered normalised to row height
@@ -1015,6 +1067,13 @@ public abstract class AlignmentViewport
    * should consensus histograms be rendered by default
    */
   protected boolean showConsensusHistogram = true;
+  
+  protected boolean showSSConsensusHistogram = true;
+
+  public void setShowSSConsensusHistogram(boolean showSSConsensusHistogram)
+  {
+    this.showSSConsensusHistogram = showSSConsensusHistogram;
+  }
 
   /**
    * @return the showConsensusProfile
@@ -1024,6 +1083,12 @@ public abstract class AlignmentViewport
   {
     return showSequenceLogo;
   }
+  
+  @Override
+  public boolean isShowSequenceSSLogo()
+  {
+    return showSequenceSSLogo;
+  }
 
   /**
    * @param showSequenceLogo
@@ -1042,6 +1107,18 @@ public abstract class AlignmentViewport
     }
     this.showSequenceLogo = showSequenceLogo;
   }
+  
+  public void setShowSequenceSSLogo(boolean showSequenceSSLogo)
+  {
+    if (showSequenceSSLogo != this.showSequenceSSLogo)
+    {
+      // TODO: decouple settings setting from calculation when refactoring
+      // annotation update method from alignframe to viewport
+      this.showSequenceSSLogo = showSequenceSSLogo;
+      calculator.updateAnnotationFor(SecondaryStructureConsensusThread.class);
+    }
+    this.showSequenceSSLogo = showSequenceSSLogo;
+  }
 
   /**
    * @param showConsensusHistogram
@@ -1096,6 +1173,12 @@ public abstract class AlignmentViewport
   {
     return this.showConsensusHistogram;
   }
+  
+  @Override
+  public boolean isShowSSConsensusHistogram()
+  {
+    return this.showSSConsensusHistogram;
+  }
 
   /**
    * when set, updateAlignment will always ensure sequences are of equal length
@@ -1247,6 +1330,7 @@ public abstract class AlignmentViewport
     if (ap != null)
     {
       updateConsensus(ap);
+      updateSecondaryStructureConsensus(ap);
       if (residueShading != null)
       {
         residueShading.setThreshold(residueShading.getThreshold(),
@@ -1872,6 +1956,7 @@ public abstract class AlignmentViewport
     if (autoCalculateConsensus)
     {
       updateConsensus(ap);
+      updateSecondaryStructureConsensus(ap);
     }
     if (hconsensus != null && autoCalculateConsensus)
     {
@@ -1955,13 +2040,19 @@ public abstract class AlignmentViewport
       consensus = new AlignmentAnnotation("Consensus",
               MessageManager.getString("label.consensus_descr"),
               new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
+      
+      secondaryStructureConsensus = new AlignmentAnnotation("SecondaryStructureConsensus",
+              MessageManager.getString("label.ssconsensus_descr"),
+              new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
+      
       initConsensus(consensus);
+      initSSConsensus(secondaryStructureConsensus);
       initGapCounts();
-
       initComplementConsensus();
     }
   }
 
+
   /**
    * If this is a protein alignment and there are mappings to cDNA, adds the
    * cDNA consensus annotation and returns true, else returns false.
@@ -2012,6 +2103,17 @@ public abstract class AlignmentViewport
       alignment.addAnnotation(aa);
     }
   }
+  
+  private void initSSConsensus(AlignmentAnnotation aa)
+  {
+    aa.hasText = true;
+    aa.autoCalculated = true;
+
+    if (showConsensus)
+    {
+      alignment.addAnnotation(aa);
+    }
+  }
 
   // these should be extracted from the view model - style and settings for
   // derived annotation
@@ -2160,7 +2262,9 @@ public abstract class AlignmentViewport
     boolean conv = isShowGroupConservation();
     boolean cons = isShowGroupConsensus();
     boolean showprf = isShowSequenceLogo();
+    boolean showSSprf = isShowSequenceSSLogo();
     boolean showConsHist = isShowConsensusHistogram();
+    boolean showSSConsHist = isShowSSConsensusHistogram();
     boolean normLogo = isNormaliseSequenceLogo();
 
     /**
@@ -2197,7 +2301,9 @@ public abstract class AlignmentViewport
         {
           // set defaults for this group's conservation/consensus
           sg.setshowSequenceLogo(showprf);
+          sg.setshowSequenceSSLogo(showSSprf);
           sg.setShowConsensusHistogram(showConsHist);
+          sg.setShowSSConsensusHistogram(showSSConsHist);
           sg.setNormaliseSequenceLogo(normLogo);
         }
         if (conv)
@@ -2209,6 +2315,7 @@ public abstract class AlignmentViewport
         {
           updateCalcs = true;
           alignment.addAnnotation(sg.getConsensus(), 0);
+          alignment.addAnnotation(sg.getSSConsensus(), 0);
         }
         // refresh the annotation rows
         if (updateCalcs)
@@ -2998,6 +3105,41 @@ public abstract class AlignmentViewport
             + ((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));
     return sq;
   }
+  
+  public SequenceI getSSConsensusSeq()
+  {
+    if (secondaryStructureConsensus == null)
+    {
+      updateSecondaryStructureConsensus(null);
+    }
+    if (secondaryStructureConsensus == null)
+    {
+      return null;
+    }
+    StringBuffer seqs = new StringBuffer();
+    for (int i = 0; i < secondaryStructureConsensus.annotations.length; i++)
+    {
+      Annotation annotation = secondaryStructureConsensus.annotations[i];
+      if (annotation != null)
+      {
+        String description = annotation.description;
+        if (description != null && description.startsWith("["))
+        {
+          // consensus is a tie - just pick the first one
+          seqs.append(description.charAt(1));
+        }
+        else
+        {
+          seqs.append(annotation.displayCharacter);
+        }
+      }
+    }
+
+    SequenceI sq = new Sequence("Sec Str Consensus", seqs.toString());
+    sq.setDescription("Percentage Identity Sec Str Consensus "
+            + ((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));
+    return sq;
+  }
 
   @Override
   public void setCurrentTree(TreeModel tree)