(JAL-974,JAL-975) refactor common code for a JABAWS sequence annotation client to...
authorjprocter <jprocter@compbio.dundee.ac.uk>
Mon, 7 Nov 2011 13:11:54 +0000 (13:11 +0000)
committerjprocter <jprocter@compbio.dundee.ac.uk>
Mon, 7 Nov 2011 13:11:54 +0000 (13:11 +0000)
src/jalview/ws/jws2/AAConsClient.java
src/jalview/ws/jws2/AADisorderClient.java [new file with mode: 0644]
src/jalview/ws/jws2/JabawsAlignCalcWorker.java [new file with mode: 0644]

index a720593..289d49b 100644 (file)
@@ -1,18 +1,9 @@
 package jalview.ws.jws2;
 
-
-import jalview.analysis.AlignSeq;
-import jalview.analysis.SeqsetUtils;
-import jalview.api.AlignViewportI;
-import jalview.api.AlignmentViewPanel;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Annotation;
-import jalview.datamodel.SequenceGroup;
-import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
-import jalview.workers.AlignCalcWorker;
-import jalview.ws.jws2.dm.JabaWsParamSet;
 import jalview.ws.jws2.jabaws2.Jws2Instance;
 import jalview.ws.params.WsParamSetI;
 
@@ -22,335 +13,32 @@ import java.util.List;
 import java.util.Map;
 import java.util.TreeSet;
 
-import compbio.data.msa.SequenceAnnotation;
 import compbio.data.sequence.Score;
-import compbio.data.sequence.ScoreManager;
 import compbio.metadata.Argument;
-import compbio.metadata.ChunkHolder;
-import compbio.metadata.JobStatus;
-import compbio.metadata.JobSubmissionException;
-import compbio.metadata.Option;
-import compbio.metadata.ResultNotAvailableException;
-import compbio.metadata.WrongParameterException;
 
-public class AAConsClient extends AlignCalcWorker
+public class AAConsClient extends JabawsAlignCalcWorker
 {
 
-  public AAConsClient(AlignViewportI alignViewport,
-          AlignmentViewPanel alignPanel)
-  {
-    super(alignViewport, alignPanel);
-  }
-
-  @SuppressWarnings("unchecked")
-  SequenceAnnotation aaservice;
-
-  private ScoreManager scoremanager;
-
-  private WsParamSetI preset;
-
-  private List<Argument> arguments;
-  
-  public WsParamSetI getPreset()
-  {
-    return preset;
-  }
-  public List<Argument> getArguments()
-  {
-    return arguments;
-  }
-  /**
-   * reconfigure and restart the AAConsClient. This method will spawn a new thread that will wait until any current jobs are finished, modify the parameters and restart the conservation calculation with the new values.
-   * @param newpreset
-   * @param newarguments
-   */
-  public void updateParameters(final WsParamSetI newpreset, final List<Argument> newarguments)
-  {
-    if (calcMan.isWorking(this))
-    {
-      new Thread(new Runnable() {
-        @Override
-        public void run()
-        {
-         
-          try {Thread.sleep(200);
-          } catch (InterruptedException x) {};
-            updateParameters(newpreset, newarguments);
-          }
-        }
-      ).start();
-    } else {
-      preset=newpreset;
-      arguments=newarguments;
-      calcMan.startWorker(this);
-    }
-  }
-
   public AAConsClient(Jws2Instance service, AlignFrame alignFrame,
           WsParamSetI preset, List<Argument> paramset)
   {
-    this(alignFrame.getCurrentView(), alignFrame.alignPanel);
-    this.preset = preset;
-    this.arguments = paramset;
-    aaservice = (SequenceAnnotation) service.service;
-
+    super(service, alignFrame, preset, paramset);
+    submitGaps=true;
+    alignedSeqs=true;
+    nucleotidesAllowed=false;
+    proteinAllowed=true;
   }
 
-  public List<Option> getJabaArguments()
+  public String getServiceActionText()
   {
-    List<Option> newargs = new ArrayList<Option>();
-    if (preset != null && preset instanceof JabaWsParamSet)
-    {
-      newargs.addAll(((JabaWsParamSet) preset).getjabaArguments());
-    }
-    if (arguments != null && arguments.size() > 0)
-    {
-      for (Argument rg : arguments)
-      {
-        if (Option.class.isAssignableFrom(rg.getClass()))
-        {
-          newargs.add((Option) rg);
-        }
-      }
-    }
-    return newargs;
-  }
-
-  @Override
-  public void run()
-  {
-    if (aaservice == null)
-    {
-      return;
-    }
-
-    try
-    {
-      if (checkDone())
-      {
-        return; 
-      }
-      AlignmentI alignment = alignViewport.getAlignment();
-
-      int aWidth = -1;
-
-      if (alignment == null || (aWidth = alignment.getWidth()) < 0 || alignment.isNucleotide())
-      {
-        calcMan.workerComplete(this);
-        return;
-      }
-
-      /*
-       * AlignmentAnnotation
-       * strucConsensus=alignViewport.getAlignmentStrucConsensusAnnotation();
-       * Hashtable[]
-       * hStrucConsensus=alignViewport.getRnaStructureConsensusHash();
-       * strucConsensus.annotations = null; strucConsensus.annotations = new
-       * Annotation[aWidth];
-       * 
-       * hStrucConsensus = new Hashtable[aWidth];
-       */
-      AlignmentAnnotation[] aa = alignViewport.getAlignment()
-              .getAlignmentAnnotation();
-      /*
-       * AlignmentAnnotation rnaStruc = null; // select rna struct to use for
-       * calculation for (int i = 0; i < aa.length; i++) { if
-       * (aa[i].getRNAStruc() != null && aa[i].isValidStruc()) { rnaStruc =
-       * aa[i]; break; } } // check to see if its valid
-       * 
-       * if (rnaStruc==null || !rnaStruc.isValidStruc()) {
-       * calcMan.workerComplete(this); return; }
-       */
-      List<compbio.data.sequence.FastaSequence> seqs = new ArrayList<compbio.data.sequence.FastaSequence>();
-
-      boolean submitGaps = true;
-      int minlen = 10;
-      for (SequenceI sq : ((List<SequenceI>) alignment.getSequences()))
-      {
-
-        if (sq.getEnd() - sq.getStart() > minlen - 1)
-        {
-          String newname = SeqsetUtils.unique_name(seqs.size() + 1);
-          // make new input sequence with or without gaps
-          seqs.add(new compbio.data.sequence.FastaSequence(newname,
-                  (submitGaps) ? sq.getSequenceAsString() : AlignSeq
-                          .extractGaps(jalview.util.Comparison.GapChars,
-                                  sq.getSequenceAsString())));
-        }
-      }
-
-      String rslt;
-      if (preset == null)
-      {
-        rslt=aaservice.analize(seqs);
-      }
-      else
-      {
-        try {
-        rslt=aaservice.customAnalize(seqs,  getJabaArguments());
-        } catch (WrongParameterException x)
-        {
-          throw new JobSubmissionException("Invalid paremeter set. Check Jalview implementation.",x);
-          
-        }
-      }
-      boolean finished = false;
-      long rpos = 0;
-      do
-      {
-        JobStatus status = aaservice.getJobStatus(rslt);
-        if (status.equals(JobStatus.FINISHED))
-        {
-          finished = true;
-        }
-        long cpos;
-        do
-        {
-          cpos = rpos;
-          ChunkHolder stats = aaservice.pullExecStatistics(rslt, rpos);
-          if (stats != null)
-          {
-            System.out.print(stats.getChunk());
-            rpos = stats.getNextPosition();
-          }
-        } while (rpos > cpos);
-
-        if (!finished && status.equals(JobStatus.FAILED))
-        {
-          try
-          {
-            Thread.sleep(200);
-          } catch (InterruptedException x)
-          {
-          }
-          ;
-        }
-
-      } while (!finished);
-      try
-      {
-        Thread.sleep(200);
-      } catch (InterruptedException x)
-      {
-      }
-      ;
-      scoremanager = aaservice.getAnnotation(rslt);
-      if (scoremanager != null)
-      {
-        updateResultAnnotation(true);
-      }
-    } catch (JobSubmissionException x)
-    {
-
-      System.err.println("submission error:");
-      x.printStackTrace();
-      calcMan.workerCannotRun(this);
-    } catch (ResultNotAvailableException x)
-    {
-      System.err.println("collection error:");
-      x.printStackTrace();
-      calcMan.workerCannotRun(this);
-
-    } catch (OutOfMemoryError error)
-    {
-      calcMan.workerCannotRun(this);
-
-      // consensus = null;
-      // hconsensus = null;
-      ap.raiseOOMWarning("calculating Amino acid consensus using AACons service", error);
-    }
-    catch (Exception x)
-    {
-      calcMan.workerCannotRun(this);
-
-      // consensus = null;
-      // hconsensus = null;
-      System.err.println("Blacklisting worker due to unexpected exception:");
-      x.printStackTrace();
-    }
-    finally {
-
-    calcMan.workerComplete(this);
-    if (ap != null)
-    {
-      ap.paintAlignment(true);
-    }
-    }
-
-  }
-
-  /**
-   * notify manager that we have started, and wait for a free calculation slot
-   * @return true if slot is obtained and work still valid, false if another thread has done our work for us.
-   */
-  private boolean checkDone()
-  {
-    calcMan.notifyStart(this);
-    // ap.paintAlignment(false);
-    while (!calcMan.notifyWorking(this))
-    {
-      if (calcMan.isWorking(this))
-      {
-        return true;
-      }
-      try
-      {
-        if (ap != null)
-        {
-          ap.paintAlignment(false);
-        }
-
-        Thread.sleep(200);
-      } catch (Exception ex)
-      {
-        ex.printStackTrace();
-      }
-    }
-    if (alignViewport.isClosed())
-    {
-      abortAndDestroy();
-      return true;
-    }
-    return false;
+    return "calculating Amino acid consensus using AACons service";
   }
 
   /**
    * update the consensus annotation from the sequence profile data using
    * current visualization settings.
    */
-  public void updateAnnotation()
-  {
-    updateResultAnnotation(false);
-  }
 
-  private AlignmentAnnotation findOrCreate(String name, boolean autoCalc,
-          SequenceI seqRef, SequenceGroup groupRef)
-  {
-    for (AlignmentAnnotation annot : alignViewport.getAlignment()
-            .getAlignmentAnnotation())
-    {
-      if (annot.autoCalculated == autoCalc
-              && annot.getCalcId().equals(name)
-              && annot.sequenceRef == seqRef && annot.groupRef == groupRef)
-      {
-        return annot;
-      }
-    }
-    AlignmentAnnotation annot = new AlignmentAnnotation(name, name,
-            new Annotation[1], 0f, 0f, AlignmentAnnotation.BAR_GRAPH);
-    annot.hasText=false;
-    annot.setCalcId(new String(name));
-    annot.autoCalculated = autoCalc;
-    if (seqRef != null)
-    {
-      annot.setSequenceRef(seqRef);
-    }
-    annot.groupRef = groupRef;
-    alignViewport.getAlignment().addAnnotation(annot);
-
-    return annot;
-  }
   public void updateResultAnnotation(boolean immediate)
   {
 
diff --git a/src/jalview/ws/jws2/AADisorderClient.java b/src/jalview/ws/jws2/AADisorderClient.java
new file mode 100644 (file)
index 0000000..3fe25af
--- /dev/null
@@ -0,0 +1,123 @@
+package jalview.ws.jws2;
+
+import jalview.api.AlignCalcWorkerI;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.ws.jws2.jabaws2.Jws2Instance;
+import jalview.ws.params.WsParamSetI;
+
+import java.util.Iterator;
+import java.util.List;
+
+import compbio.data.sequence.Range;
+import compbio.data.sequence.Score;
+import compbio.data.sequence.ScoreManager.ScoreHolder;
+import compbio.metadata.Argument;
+
+public class AADisorderClient extends JabawsAlignCalcWorker implements
+        AlignCalcWorkerI
+{
+
+  String typeName;
+
+  String methodName;
+
+  String groupName;
+
+  AlignFrame af;
+
+  public AADisorderClient(Jws2Instance sh, AlignFrame alignFrame,
+          WsParamSetI preset, List<Argument> paramset)
+  {
+    super(sh, alignFrame, preset, paramset);
+    af = alignFrame;
+    typeName = sh.action;
+    methodName = sh.serviceType;
+
+    submitGaps = false;
+    alignedSeqs = false;
+    nucleotidesAllowed = false;
+    proteinAllowed = true;
+    bySequence = true;
+  }
+
+  @Override
+  public String getServiceActionText()
+  {
+    return "Submitting amino acid sequences for disorder prediction.";
+  }
+
+  @Override
+  public void updateResultAnnotation(boolean immediate)
+  {
+
+    if (immediate || !calcMan.isWorking(this) && scoremanager != null)
+    {
+      boolean dispFeatures = false;
+      for (String seqId : seqNames.keySet())
+      {
+        SequenceI dseq, seq = seqNames.get(seqId);
+        int base = seq.getStart() - 1;
+        while ((dseq = seq).getDatasetSequence() != null)
+        {
+          seq = seq.getDatasetSequence();
+        }
+        ;
+        ScoreHolder scores = scoremanager.getAnnotationForSequence(seqId);
+
+        for (Score scr : scores.scores)
+        {
+
+          if (scr.getRanges() != null && scr.getRanges().size() > 0)
+          {
+            Iterator<Float> vals = scr.getScores().iterator();
+            // make features on sequence
+            for (Range rn : scr.getRanges())
+            {
+
+              SequenceFeature sf;
+              if (vals.hasNext())
+              {
+                sf = new SequenceFeature(typeName + "(" + scr.getMethod()
+                        + ")", "Disordered Region", base + rn.from, base
+                        + rn.to, vals.next().floatValue(), methodName);
+              }
+              else
+              {
+                sf = new SequenceFeature(typeName + "(" + scr.getMethod()
+                        + ")", "Disordered Region", null, base + rn.from,
+                        base + rn.to, methodName);
+              }
+              dseq.addSequenceFeature(sf);
+              dispFeatures = true;
+            }
+          }
+          else
+          {
+            Iterator<Float> vals = scr.getScores().iterator();
+            for (int start = base + 1; vals.hasNext(); start++)
+            {
+              SequenceFeature sf = new SequenceFeature(typeName + "("
+                      + scr.getMethod() + ")", "Disordered Region", start,
+                      start, vals.next().floatValue(), methodName);
+              dseq.addSequenceFeature(sf);
+              dispFeatures = true;
+            }
+          }
+        }
+      }
+      {
+        if (dispFeatures)
+        {
+          af.alignPanel.av.setShowSequenceFeatures(true);
+          ap.paintAlignment(true);
+        }
+      }
+      /*
+       * else { ap.paintAlignment(true); }
+       */
+    }
+  }
+
+}
diff --git a/src/jalview/ws/jws2/JabawsAlignCalcWorker.java b/src/jalview/ws/jws2/JabawsAlignCalcWorker.java
new file mode 100644 (file)
index 0000000..7ee6e08
--- /dev/null
@@ -0,0 +1,410 @@
+package jalview.ws.jws2;
+
+import jalview.analysis.AlignSeq;
+import jalview.analysis.SeqsetUtils;
+import jalview.api.AlignViewportI;
+import jalview.api.AlignmentViewPanel;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.workers.AlignCalcWorker;
+import jalview.ws.jws2.dm.JabaWsParamSet;
+import jalview.ws.jws2.jabaws2.Jws2Instance;
+import jalview.ws.params.WsParamSetI;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.sun.xml.internal.ws.developer.ServerSideException;
+import compbio.data.msa.SequenceAnnotation;
+import compbio.data.sequence.FastaSequence;
+import compbio.data.sequence.ScoreManager;
+import compbio.metadata.Argument;
+import compbio.metadata.ChunkHolder;
+import compbio.metadata.JobStatus;
+import compbio.metadata.JobSubmissionException;
+import compbio.metadata.Option;
+import compbio.metadata.ResultNotAvailableException;
+import compbio.metadata.WrongParameterException;
+
+public abstract class JabawsAlignCalcWorker extends AlignCalcWorker
+{
+
+  @SuppressWarnings("unchecked")
+  protected SequenceAnnotation aaservice;
+
+  protected ScoreManager scoremanager;
+
+  protected WsParamSetI preset;
+
+  protected List<Argument> arguments;
+
+  public JabawsAlignCalcWorker(AlignViewportI alignViewport,
+          AlignmentViewPanel alignPanel)
+  {
+    super(alignViewport, alignPanel);
+  }
+
+  public JabawsAlignCalcWorker(Jws2Instance service, AlignFrame alignFrame,
+          WsParamSetI preset, List<Argument> paramset)
+  {
+    this(alignFrame.getCurrentView(), alignFrame.alignPanel);
+    this.preset = preset;
+    this.arguments = paramset;
+    aaservice = (SequenceAnnotation) service.service;
+
+  }
+
+  public WsParamSetI getPreset()
+  {
+    return preset;
+  }
+
+  public List<Argument> getArguments()
+  {
+    return arguments;
+  }
+
+  /**
+   * reconfigure and restart the AAConsClient. This method will spawn a new
+   * thread that will wait until any current jobs are finished, modify the
+   * parameters and restart the conservation calculation with the new values.
+   * 
+   * @param newpreset
+   * @param newarguments
+   */
+  public void updateParameters(final WsParamSetI newpreset,
+          final List<Argument> newarguments)
+  {
+    if (calcMan.isWorking(this))
+    {
+      new Thread(new Runnable()
+      {
+        @Override
+        public void run()
+        {
+
+          try
+          {
+            Thread.sleep(200);
+          } catch (InterruptedException x)
+          {
+          }
+          ;
+          updateParameters(newpreset, newarguments);
+        }
+      }).start();
+    }
+    else
+    {
+      preset = newpreset;
+      arguments = newarguments;
+      calcMan.startWorker(this);
+    }
+  }
+
+  public List<Option> getJabaArguments()
+  {
+    List<Option> newargs = new ArrayList<Option>();
+    if (preset != null && preset instanceof JabaWsParamSet)
+    {
+      newargs.addAll(((JabaWsParamSet) preset).getjabaArguments());
+    }
+    if (arguments != null && arguments.size() > 0)
+    {
+      for (Argument rg : arguments)
+      {
+        if (Option.class.isAssignableFrom(rg.getClass()))
+        {
+          newargs.add((Option) rg);
+        }
+      }
+    }
+    return newargs;
+  }
+
+  @Override
+  public void run()
+  {
+    if (aaservice == null)
+    {
+      return;
+    }
+
+    try
+    {
+      if (checkDone())
+      {
+        return;
+      }
+      List<compbio.data.sequence.FastaSequence> seqs = getInputSequences(alignViewport
+              .getAlignment());
+
+      if (seqs == null)
+      {
+        calcMan.workerComplete(this);
+        return;
+      }
+
+      AlignmentAnnotation[] aa = alignViewport.getAlignment()
+              .getAlignmentAnnotation();
+
+      String rslt;
+      if (preset == null)
+      {
+        rslt = aaservice.analize(seqs);
+      }
+      else
+      {
+        try
+        {
+          rslt = aaservice.customAnalize(seqs, getJabaArguments());
+        } catch (WrongParameterException x)
+        {
+          throw new JobSubmissionException(
+                  "Invalid paremeter set. Check Jalview implementation.", x);
+
+        }
+      }
+      boolean finished = false;
+      long rpos = 0;
+      do
+      {
+        JobStatus status = aaservice.getJobStatus(rslt);
+        if (status.equals(JobStatus.FINISHED))
+        {
+          finished = true;
+        }
+        long cpos;
+        ChunkHolder stats;
+        do
+        {
+          cpos = rpos;
+          try
+          {
+            stats = aaservice.pullExecStatistics(rslt, rpos);
+          } catch (Exception x)
+          {
+
+            if (x.getCause() instanceof ServerSideException)
+            {
+              if (x.getMessage().contains("Position in a file could not be negative!"))
+              {
+                // squash index out of bounds exception- seems to happen for
+                // disorder predictors which don't (apparently) produce any
+                // progress information and JABA server throws an exception
+                // because progress length is -1.
+                stats = null;
+              }
+              else
+              {
+                throw x;
+              }
+            }
+            else
+            {
+              throw x;
+            }
+          }
+          if (stats != null)
+          {
+            System.out.print(stats.getChunk());
+            rpos = stats.getNextPosition();
+          }
+        } while (stats != null && rpos > cpos);
+
+        if (!finished && status.equals(JobStatus.FAILED))
+        {
+          try
+          {
+            Thread.sleep(200);
+          } catch (InterruptedException x)
+          {
+          }
+          ;
+        }
+
+      } while (!finished);
+      try
+      {
+        Thread.sleep(200);
+      } catch (InterruptedException x)
+      {
+      }
+      ;
+      scoremanager = aaservice.getAnnotation(rslt);
+      if (scoremanager != null)
+      {
+        updateResultAnnotation(true);
+      }
+    } catch (JobSubmissionException x)
+    {
+
+      System.err.println("submission error:");
+      x.printStackTrace();
+      calcMan.workerCannotRun(this);
+    } catch (ResultNotAvailableException x)
+    {
+      System.err.println("collection error:");
+      x.printStackTrace();
+      calcMan.workerCannotRun(this);
+
+    } catch (OutOfMemoryError error)
+    {
+      calcMan.workerCannotRun(this);
+
+      // consensus = null;
+      // hconsensus = null;
+      ap.raiseOOMWarning(getServiceActionText(), error);
+    } catch (Exception x)
+    {
+      calcMan.workerCannotRun(this);
+
+      // consensus = null;
+      // hconsensus = null;
+      System.err
+              .println("Blacklisting worker due to unexpected exception:");
+      x.printStackTrace();
+    } finally
+    {
+
+      calcMan.workerComplete(this);
+      if (ap != null)
+      {
+        ap.paintAlignment(true);
+      }
+    }
+
+  }
+
+  public void updateAnnotation()
+  {
+    updateResultAnnotation(false);
+  }
+
+  public abstract void updateResultAnnotation(boolean immediate);
+
+  public abstract String getServiceActionText();
+
+  boolean submitGaps = true;
+
+  boolean alignedSeqs = true;
+
+  boolean nucleotidesAllowed = false;
+
+  boolean proteinAllowed = false;
+  
+  /**
+   * record sequences for mapping result back to afterwards
+   */
+  protected boolean bySequence=false;
+
+  Map<String,SequenceI> seqNames;
+  public List<FastaSequence> getInputSequences(AlignmentI alignment)
+  {
+
+    if (alignment == null || alignment.getWidth() <= 0
+            || alignment.getSequences() == null
+            || (alignedSeqs && !alignment.isAligned())
+            || alignment.isNucleotide() ? !nucleotidesAllowed
+            : !proteinAllowed)
+    {
+      return null;
+    }
+    List<compbio.data.sequence.FastaSequence> seqs = new ArrayList<compbio.data.sequence.FastaSequence>();
+
+    int minlen = 10;
+    if (bySequence)
+    {
+      seqNames=new HashMap<String,SequenceI>();
+    }
+    for (SequenceI sq : ((List<SequenceI>) alignment.getSequences()))
+    {
+
+      if (sq.getEnd() - sq.getStart() > minlen - 1)
+      {
+        String newname = SeqsetUtils.unique_name(seqs.size() + 1);
+        // make new input sequence with or without gaps
+        if (seqNames!=null) {
+          seqNames.put(newname,sq);
+        }
+        seqs.add(new compbio.data.sequence.FastaSequence(newname,
+                (submitGaps) ? sq.getSequenceAsString() : AlignSeq
+                        .extractGaps(jalview.util.Comparison.GapChars,
+                                sq.getSequenceAsString())));
+      }
+    }
+    return seqs;
+  }
+
+  protected AlignmentAnnotation findOrCreate(String name, boolean autoCalc,
+          SequenceI seqRef, SequenceGroup groupRef)
+  {
+    for (AlignmentAnnotation annot : alignViewport.getAlignment()
+            .getAlignmentAnnotation())
+    {
+      if (annot.autoCalculated == autoCalc
+              && annot.getCalcId().equals(name)
+              && annot.sequenceRef == seqRef && annot.groupRef == groupRef)
+      {
+        return annot;
+      }
+    }
+    AlignmentAnnotation annot = new AlignmentAnnotation(name, name,
+            new Annotation[1], 0f, 0f, AlignmentAnnotation.BAR_GRAPH);
+    annot.hasText = false;
+    annot.setCalcId(new String(name));
+    annot.autoCalculated = autoCalc;
+    if (seqRef != null)
+    {
+      annot.setSequenceRef(seqRef);
+    }
+    annot.groupRef = groupRef;
+    alignViewport.getAlignment().addAnnotation(annot);
+
+    return annot;
+  }
+
+  /**
+   * notify manager that we have started, and wait for a free calculation slot
+   * 
+   * @return true if slot is obtained and work still valid, false if another
+   *         thread has done our work for us.
+   */
+  boolean checkDone()
+  {
+    calcMan.notifyStart(this);
+    // ap.paintAlignment(false);
+    while (!calcMan.notifyWorking(this))
+    {
+      if (calcMan.isWorking(this))
+      {
+        return true;
+      }
+      try
+      {
+        if (ap != null)
+        {
+          ap.paintAlignment(false);
+        }
+
+        Thread.sleep(200);
+      } catch (Exception ex)
+      {
+        ex.printStackTrace();
+      }
+    }
+    if (alignViewport.isClosed())
+    {
+      abortAndDestroy();
+      return true;
+    }
+    return false;
+  }
+
+}