JAL-3878 Add getCalcName to AlignCalcWorkerI.
[jalview.git] / src / jalview / workers / ConsensusThread.java
index 5f0ec84..dc3bf06 100644 (file)
@@ -26,10 +26,9 @@ import jalview.api.AlignmentViewPanel;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Annotation;
+import jalview.datamodel.ProfilesI;
 import jalview.datamodel.SequenceI;
-import jalview.schemes.ColourSchemeI;
-
-import java.util.Hashtable;
+import jalview.renderer.ResidueShaderI;
 
 public class ConsensusThread extends AlignCalcWorker
 {
@@ -40,71 +39,41 @@ public class ConsensusThread extends AlignCalcWorker
   }
 
   @Override
+  public String getCalcName()
+  {
+    return "Consensus";
+  }
+
+  @Override
   public void run()
   {
-    if (calcMan.isPending(this))
+    AlignmentAnnotation consensus = getConsensusAnnotation();
+    AlignmentAnnotation gap = getGapAnnotation();
+    if ((consensus == null && gap == null))
     {
       return;
     }
-    calcMan.notifyStart(this);
-    long started = System.currentTimeMillis();
-    try
+    if (alignViewport.isClosed())
     {
-      AlignmentAnnotation consensus = getConsensusAnnotation();
-      if (consensus == null || calcMan.isPending(this))
-      {
-        calcMan.workerComplete(this);
-        return;
-      }
-      while (!calcMan.notifyWorking(this))
-      {
-        // System.err.println("Thread (Consensus"+Thread.currentThread().getName()+") Waiting around.");
-        try
-        {
-          if (ap != null)
-          {
-            ap.paintAlignment(false);
-          }
-          Thread.sleep(200);
-        } catch (Exception ex)
-        {
-          ex.printStackTrace();
-        }
-      }
-      if (alignViewport.isClosed())
-      {
-        abortAndDestroy();
-        return;
-      }
-      AlignmentI alignment = alignViewport.getAlignment();
+      abortAndDestroy();
+      return;
+    }
+    AlignmentI alignment = alignViewport.getAlignment();
 
-      int aWidth = -1;
+    int aWidth = -1;
 
-      if (alignment == null || (aWidth = alignment.getWidth()) < 0)
-      {
-        calcMan.workerComplete(this);
-        return;
-      }
+    if (alignment == null || (aWidth = alignment.getWidth()) < 0)
+    {
+      return;
+    }
 
-      eraseConsensus(aWidth);
-      computeConsensus(alignment);
-      updateResultAnnotation(true);
+    eraseConsensus(aWidth);
+    computeConsensus(alignment);
+    updateResultAnnotation(true);
 
-      if (ap != null)
-      {
-        ap.paintAlignment(true);
-      }
-    } catch (OutOfMemoryError error)
+    if (ap != null)
     {
-      calcMan.disableWorker(this);
-      ap.raiseOOMWarning("calculating consensus", error);
-    } finally
-    {
-      /*
-       * e.g. ArrayIndexOutOfBoundsException can happen due to a race condition
-       * - alignment was edited at same time as calculation was running
-       */
-      calcMan.workerComplete(this);
+      ap.paintAlignment(true, true);
     }
   }
 
@@ -117,7 +86,15 @@ public class ConsensusThread extends AlignCalcWorker
   protected void eraseConsensus(int aWidth)
   {
     AlignmentAnnotation consensus = getConsensusAnnotation();
-    consensus.annotations = new Annotation[aWidth];
+    if (consensus != null)
+    {
+      consensus.annotations = new Annotation[aWidth];
+    }
+    AlignmentAnnotation gap = getGapAnnotation();
+    if (gap != null)
+    {
+      gap.annotations = new Annotation[aWidth];
+    }
   }
 
   /**
@@ -125,10 +102,11 @@ public class ConsensusThread extends AlignCalcWorker
    */
   protected void computeConsensus(AlignmentI alignment)
   {
-    Hashtable[] hconsensus = new Hashtable[alignment.getWidth()];
 
     SequenceI[] aseqs = getSequences();
-    AAFrequency.calculate(aseqs, 0, alignment.getWidth(), hconsensus, true);
+    int width = alignment.getWidth();
+    ProfilesI hconsensus = AAFrequency.calculate(aseqs, width, 0, width,
+            true);
 
     alignViewport.setSequenceConsensusHash(hconsensus);
     setColourSchemeConsensus(hconsensus);
@@ -145,13 +123,12 @@ public class ConsensusThread extends AlignCalcWorker
   /**
    * @param hconsensus
    */
-  protected void setColourSchemeConsensus(Hashtable[] hconsensus)
+  protected void setColourSchemeConsensus(ProfilesI hconsensus)
   {
-    ColourSchemeI globalColourScheme = alignViewport
-            .getGlobalColourScheme();
-    if (globalColourScheme != null)
+    ResidueShaderI cs = alignViewport.getResidueShading();
+    if (cs != null)
     {
-      globalColourScheme.setConsensus(hconsensus);
+      cs.setConsensus(hconsensus);
     }
   }
 
@@ -166,6 +143,16 @@ public class ConsensusThread extends AlignCalcWorker
   }
 
   /**
+   * Get the Gap annotation for the alignment
+   * 
+   * @return
+   */
+  protected AlignmentAnnotation getGapAnnotation()
+  {
+    return alignViewport.getAlignmentGapAnnotation();
+  }
+
+  /**
    * update the consensus annotation from the sequence profile data using
    * current visualization settings.
    */
@@ -178,11 +165,16 @@ public class ConsensusThread extends AlignCalcWorker
   public void updateResultAnnotation(boolean immediate)
   {
     AlignmentAnnotation consensus = getConsensusAnnotation();
-    Hashtable[] hconsensus = getViewportConsensus();
+    ProfilesI hconsensus = (ProfilesI) getViewportConsensus();
     if (immediate || !calcMan.isWorking(this) && consensus != null
             && hconsensus != null)
     {
       deriveConsensus(consensus, hconsensus);
+      AlignmentAnnotation gap = getGapAnnotation();
+      if (gap != null)
+      {
+        deriveGap(gap, hconsensus);
+      }
     }
   }
 
@@ -192,25 +184,44 @@ public class ConsensusThread extends AlignCalcWorker
    * 
    * @param consensusAnnotation
    *          the annotation to be populated
-   * @param consensusData
+   * @param hconsensus
    *          the computed consensus data
    */
   protected void deriveConsensus(AlignmentAnnotation consensusAnnotation,
-          Hashtable[] consensusData)
+          ProfilesI hconsensus)
   {
     long nseq = getSequences().length;
-    AAFrequency.completeConsensus(consensusAnnotation, consensusData, 0,
-            consensusData.length, alignViewport.isIgnoreGapsConsensus(),
+    AAFrequency.completeConsensus(consensusAnnotation, hconsensus,
+            hconsensus.getStartColumn(), hconsensus.getEndColumn() + 1,
+            alignViewport.isIgnoreGapsConsensus(),
             alignViewport.isShowSequenceLogo(), nseq);
   }
 
   /**
+   * Convert the computed consensus data into a gap annotation row for display.
+   * 
+   * @param gapAnnotation
+   *          the annotation to be populated
+   * @param hconsensus
+   *          the computed consensus data
+   */
+  protected void deriveGap(AlignmentAnnotation gapAnnotation,
+          ProfilesI hconsensus)
+  {
+    long nseq = getSequences().length;
+    AAFrequency.completeGapAnnot(gapAnnotation, hconsensus,
+            hconsensus.getStartColumn(), hconsensus.getEndColumn() + 1,
+            nseq);
+  }
+
+  /**
    * Get the consensus data stored on the viewport.
    * 
    * @return
    */
-  protected Hashtable[] getViewportConsensus()
+  protected Object getViewportConsensus()
   {
+    // TODO convert ComplementConsensusThread to use Profile
     return alignViewport.getSequenceConsensusHash();
   }
 }