Merge branch 'feature/JAL-1379' into develop
authorJim Procter <jprocter@dundee.ac.uk>
Thu, 12 Jun 2014 08:10:38 +0000 (09:10 +0100)
committerJim Procter <jprocter@dundee.ac.uk>
Thu, 12 Jun 2014 08:10:38 +0000 (09:10 +0100)
15 files changed:
src/jalview/ws/jws2/AAConClient.java
src/jalview/ws/jws2/AADisorderClient.java
src/jalview/ws/jws2/AbstractJabaCalcWorker.java [new file with mode: 0644]
src/jalview/ws/jws2/JPred301Client.java [new file with mode: 0644]
src/jalview/ws/jws2/JabawsAlignCalcWorker.java [deleted file]
src/jalview/ws/jws2/JabawsCalcWorker.java
src/jalview/ws/jws2/JabawsMsaInterfaceAlignCalcWorker.java [new file with mode: 0644]
src/jalview/ws/jws2/Jws2Client.java
src/jalview/ws/jws2/Jws2Discoverer.java
src/jalview/ws/jws2/MsaWSClient.java
src/jalview/ws/jws2/RNAalifoldClient.java
src/jalview/ws/jws2/SequenceAnnotationWSClient.java
src/jalview/ws/jws2/jabaws2/Jws2InstanceFactory.java
test/jalview/ws/jabaws/JalviewJabawsTestUtils.java
test/jalview/ws/jabaws/RNAStructExportImport.java

index 676b3ba..66338b1 100644 (file)
@@ -34,10 +34,11 @@ import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
 
+import compbio.data.sequence.FastaSequence;
 import compbio.data.sequence.Score;
 import compbio.metadata.Argument;
 
-public class AAConClient extends JabawsAlignCalcWorker
+public class AAConClient extends JabawsCalcWorker
 {
 
   public AAConClient(Jws2Instance service, AlignFrame alignFrame,
@@ -102,6 +103,12 @@ public class AAConClient extends JabawsAlignCalcWorker
   }
 
   @Override
+  boolean checkValidInputSeqs(boolean dynamic, List<FastaSequence> seqs)
+  {
+    return (seqs.size() > 1);
+  }
+
+  @Override
   public String getCalcId()
   {
     return CALC_ID;
index 34969d1..83eebdf 100644 (file)
@@ -40,6 +40,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
+import compbio.data.sequence.FastaSequence;
 import compbio.data.sequence.Range;
 import compbio.data.sequence.Score;
 import compbio.data.sequence.ScoreManager.ScoreHolder;
@@ -82,6 +83,12 @@ public class AADisorderClient extends JabawsCalcWorker implements
     return "Submitting amino acid sequences for disorder prediction.";
   }
 
+  @Override
+  boolean checkValidInputSeqs(boolean dynamic, List<FastaSequence> seqs)
+  {
+    return (seqs.size() > 0);
+  }
+
   private static Map<String, Map<String, String[]>> featureMap;
 
   private static Map<String, Map<String, Map<String, Object>>> annotMap;
@@ -374,4 +381,11 @@ public class AADisorderClient extends JabawsCalcWorker implements
     }
   }
 
+  @Override
+  public String getCalcId()
+  {
+    // Disorder predictions are not dynamically updated so we return null
+    return null;
+  }
+
 }
diff --git a/src/jalview/ws/jws2/AbstractJabaCalcWorker.java b/src/jalview/ws/jws2/AbstractJabaCalcWorker.java
new file mode 100644 (file)
index 0000000..a7cc5b6
--- /dev/null
@@ -0,0 +1,599 @@
+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.AnnotatedCollectionI;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.IProgressIndicator;
+import jalview.workers.AlignCalcWorker;
+import jalview.ws.jws2.dm.AAConSettings;
+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 compbio.data.sequence.FastaSequence;
+import compbio.metadata.Argument;
+import compbio.metadata.ChunkHolder;
+import compbio.metadata.JobStatus;
+import compbio.metadata.JobSubmissionException;
+import compbio.metadata.Option;
+import compbio.metadata.ResultNotAvailableException;
+
+public abstract class AbstractJabaCalcWorker extends AlignCalcWorker
+{
+
+  protected Jws2Instance service;
+
+  protected WsParamSetI preset;
+
+  protected List<Argument> arguments;
+
+  protected IProgressIndicator guiProgress;
+
+  protected boolean submitGaps = true;
+
+  /**
+   * Recover any existing parameters for this service
+   */
+  protected void initViewportParams()
+  {
+    if (getCalcId() != null)
+    {
+      ((jalview.gui.AlignViewport) alignViewport).setCalcIdSettingsFor(
+              getCalcId(),
+              new AAConSettings(true, service, this.preset,
+                      (arguments != null) ? JabaParamStore
+                              .getJwsArgsfromJaba(arguments) : null), true);
+    }
+  }
+
+  /**
+   * 
+   * @return null or a string used to recover all annotation generated by this
+   *         worker
+   */
+  public abstract String getCalcId();
+
+  public WsParamSetI getPreset()
+  {
+    return preset;
+  }
+
+  public List<Argument> getArguments()
+  {
+    return arguments;
+  }
+
+  /**
+   * reconfigure and restart the AAConClient. 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)
+  {
+    preset = newpreset;
+    arguments = newarguments;
+    calcMan.startWorker(this);
+    initViewportParams();
+  }
+
+  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;
+  }
+
+  protected boolean alignedSeqs = true;
+
+  protected boolean nucleotidesAllowed = false;
+
+  protected boolean proteinAllowed = false;
+
+  /**
+   * record sequences for mapping result back to afterwards
+   */
+  protected boolean bySequence = false;
+
+  protected Map<String, SequenceI> seqNames;
+
+  protected boolean[] gapMap;
+
+  int realw;
+
+  protected int start;
+
+  int end;
+
+  public AbstractJabaCalcWorker(AlignViewportI alignViewport,
+          AlignmentViewPanel alignPanel)
+  {
+    super(alignViewport, alignPanel);
+  }
+
+  public AbstractJabaCalcWorker(Jws2Instance service,
+          AlignFrame alignFrame, WsParamSetI preset, List<Argument> paramset)
+  {
+    this(alignFrame.getCurrentView(), alignFrame.alignPanel);
+    this.guiProgress = alignFrame;
+    this.preset = preset;
+    this.arguments = paramset;
+    this.service = service;
+  }
+
+  /**
+   * 
+   * @return true if the submission thread should attempt to submit data
+   */
+  abstract boolean hasService();
+
+  volatile String rslt = "JOB NOT DEFINED";
+
+  @Override
+  public void run()
+  {
+    if (!hasService())
+    {
+      return;
+    }
+    long progressId = -1;
+
+    int serverErrorsLeft = 3;
+
+    StringBuffer msg = new StringBuffer();
+    try
+    {
+      if (checkDone())
+      {
+        return;
+      }
+      List<compbio.data.sequence.FastaSequence> seqs = getInputSequences(
+              alignViewport.getAlignment(),
+              bySequence ? alignViewport.getSelectionGroup() : null);
+
+      if (seqs == null || !checkValidInputSeqs(true, seqs))
+      {
+        calcMan.workerComplete(this);
+        return;
+      }
+
+      AlignmentAnnotation[] aa = alignViewport.getAlignment()
+              .getAlignmentAnnotation();
+      if (guiProgress != null)
+      {
+        guiProgress.setProgressBar("JABA " + getServiceActionText(),
+                progressId = System.currentTimeMillis());
+      }
+      rslt = submitToService(seqs);
+
+      boolean finished = false;
+      long rpos = 0;
+      do
+      {
+        JobStatus status = getJobStatus(rslt);
+        if (status.equals(JobStatus.FINISHED))
+        {
+          finished = true;
+        }
+        if (calcMan.isPending(this) && isInteractiveUpdate())
+        {
+          finished = true;
+          // cancel this job and yield to the new job
+          try
+          {
+            if (cancelJob(rslt))
+            {
+              System.err.println("Cancelled AACon job: " + rslt);
+            }
+            else
+            {
+              System.err.println("FAILED TO CANCEL AACon job: " + rslt);
+            }
+
+          } catch (Exception x)
+          {
+
+          }
+          rslt = "CANCELLED JOB";
+          return;
+        }
+        long cpos;
+        ChunkHolder stats = null;
+        do
+        {
+          cpos = rpos;
+          boolean retry = false;
+          do
+          {
+            try
+            {
+              stats = pullExecStatistics(rslt, rpos);
+            } catch (Exception x)
+            {
+
+              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
+              {
+                if (--serverErrorsLeft > 0)
+                {
+                  retry = true;
+                  try
+                  {
+                    Thread.sleep(200);
+                  } catch (InterruptedException q)
+                  {
+                  }
+                  ;
+                }
+                else
+                {
+                  throw x;
+                }
+              }
+            }
+          } while (retry);
+          if (stats != null)
+          {
+            System.out.print(stats.getChunk());
+            msg.append(stats);
+            rpos = stats.getNextPosition();
+          }
+        } while (stats != null && rpos > cpos);
+
+        if (!finished && status.equals(JobStatus.FAILED))
+        {
+          try
+          {
+            Thread.sleep(200);
+          } catch (InterruptedException x)
+          {
+          }
+          ;
+        }
+      } while (!finished);
+      if (serverErrorsLeft > 0)
+      {
+        try
+        {
+          Thread.sleep(200);
+        } catch (InterruptedException x)
+        {
+        }
+        if (collectAnnotationResultsFor(rslt))
+        {
+          jalview.bin.Cache.log
+                  .debug("Updating result annotation from Job " + rslt
+                          + " at " + service.getUri());
+          updateResultAnnotation(true);
+          ap.adjustAnnotationHeight();
+        }
+      }
+    }
+
+    catch (JobSubmissionException x)
+    {
+
+      System.err.println("submission error with " + getServiceActionText()
+              + " :");
+      x.printStackTrace();
+      calcMan.workerCannotRun(this);
+    } catch (ResultNotAvailableException x)
+    {
+      System.err.println("collection error:\nJob ID: " + rslt);
+      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)
+      {
+        calcMan.workerComplete(this);
+        if (guiProgress != null && progressId != -1)
+        {
+          guiProgress.setProgressBar("", progressId);
+        }
+        ap.paintAlignment(true);
+      }
+      if (msg.length() > 0)
+      {
+        // TODO: stash message somewhere in annotation or alignment view.
+        // code below shows result in a text box popup
+        /*
+         * jalview.gui.CutAndPasteTransfer cap = new
+         * jalview.gui.CutAndPasteTransfer(); cap.setText(msg.toString());
+         * jalview.gui.Desktop.addInternalFrame(cap,
+         * "Job Status for "+getServiceActionText(), 600, 400);
+         */
+      }
+    }
+
+  }
+
+  /**
+   * validate input for dynamic/non-dynamic update context
+   * @param dynamic
+   * @param seqs
+   * @return true if input is valid
+   */
+  abstract boolean checkValidInputSeqs(boolean dynamic, List<FastaSequence> seqs);
+
+  abstract String submitToService(
+          List<compbio.data.sequence.FastaSequence> seqs)
+          throws JobSubmissionException;
+
+  abstract boolean cancelJob(String rslt) throws Exception;
+
+  abstract JobStatus getJobStatus(String rslt) throws Exception;
+
+  abstract ChunkHolder pullExecStatistics(String rslt, long rpos);
+
+  abstract boolean collectAnnotationResultsFor(String rslt)
+          throws ResultNotAvailableException;
+
+  public void cancelCurrentJob()
+  {
+    try
+    {
+      String id = rslt;
+      if (cancelJob(rslt))
+      {
+        System.err.println("Cancelled job "+id);
+      }
+      else 
+      {
+        System.err.println("Job "+id+" couldn't be cancelled.");
+      }
+    } catch (Exception q)
+    {
+      q.printStackTrace();
+    }
+  }
+
+  /**
+   * Interactive updating. Analysis calculations that work on the currently
+   * displayed alignment data should cancel existing jobs when the input data
+   * has changed.
+   * 
+   * @return true if a running job should be cancelled because new input data is
+   *         available for analysis
+   */
+  abstract boolean isInteractiveUpdate();
+
+  public List<FastaSequence> getInputSequences(AlignmentI alignment,
+          AnnotatedCollectionI inputSeqs)
+  {
+    if (alignment == null || alignment.getWidth() <= 0
+            || alignment.getSequences() == null || alignment.isNucleotide() ? !nucleotidesAllowed
+            : !proteinAllowed)
+    {
+      return null;
+    }
+    if (inputSeqs == null || inputSeqs.getWidth() <= 0
+            || inputSeqs.getSequences() == null
+            || inputSeqs.getSequences().size() < 1)
+    {
+      inputSeqs = alignment;
+    }
+
+    List<compbio.data.sequence.FastaSequence> seqs = new ArrayList<compbio.data.sequence.FastaSequence>();
+
+    int minlen = 10;
+    int ln = -1;
+    if (bySequence)
+    {
+      seqNames = new HashMap<String, SequenceI>();
+    }
+    gapMap = new boolean[0];
+    start = inputSeqs.getStartRes();
+    end = inputSeqs.getEndRes();
+
+    for (SequenceI sq : ((List<SequenceI>) inputSeqs.getSequences()))
+    {
+      if (bySequence ? sq.findPosition(end + 1)
+              - sq.findPosition(start + 1) > minlen - 1 : 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);
+        }
+        FastaSequence seq;
+        if (submitGaps)
+        {
+          seqs.add(seq = new compbio.data.sequence.FastaSequence(newname,
+                  sq.getSequenceAsString()));
+          if (gapMap == null || gapMap.length < seq.getSequence().length())
+          {
+            boolean[] tg = gapMap;
+            gapMap = new boolean[seq.getLength()];
+            System.arraycopy(tg, 0, gapMap, 0, tg.length);
+            for (int p = tg.length; p < gapMap.length; p++)
+            {
+              gapMap[p] = false; // init as a gap
+            }
+          }
+          for (int apos : sq.gapMap())
+          {
+            gapMap[apos] = true; // aligned.
+          }
+        }
+        else
+        {
+          seqs.add(seq = new compbio.data.sequence.FastaSequence(newname,
+                  AlignSeq.extractGaps(jalview.util.Comparison.GapChars,
+                          sq.getSequenceAsString(start, end + 1))));
+        }
+        if (seq.getSequence().length() > ln)
+        {
+          ln = seq.getSequence().length();
+        }
+      }
+    }
+    if (alignedSeqs && submitGaps)
+    {
+      realw = 0;
+      for (int i = 0; i < gapMap.length; i++)
+      {
+        if (gapMap[i])
+        {
+          realw++;
+        }
+      }
+      // try real hard to return something submittable
+      // TODO: some of AAcon measures need a minimum of two or three amino
+      // acids at each position, and AAcon doesn't gracefully degrade.
+      for (int p = 0; p < seqs.size(); p++)
+      {
+        FastaSequence sq = seqs.get(p);
+        int l = sq.getSequence().length();
+        // strip gapped columns
+        char[] padded = new char[realw], orig = sq.getSequence()
+                .toCharArray();
+        for (int i = 0, pp = 0; i < realw; pp++)
+        {
+          if (gapMap[pp])
+          {
+            if (orig.length > pp)
+            {
+              padded[i++] = orig[pp];
+            }
+            else
+            {
+              padded[i++] = '-';
+            }
+          }
+        }
+        seqs.set(p, new compbio.data.sequence.FastaSequence(sq.getId(),
+                new String(padded)));
+      }
+    }
+    return seqs;
+  }
+
+  @Override
+  public void updateAnnotation()
+  {
+    updateResultAnnotation(false);
+  }
+
+  public abstract void updateResultAnnotation(boolean immediate);
+
+  public abstract String getServiceActionText();
+
+  /**
+   * 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.
+   */
+  protected 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;
+  }
+
+  protected void updateOurAnnots(List<AlignmentAnnotation> ourAnnot)
+  {
+    List<AlignmentAnnotation> our = ourAnnots;
+    ourAnnots = ourAnnot;
+    AlignmentI alignment = alignViewport.getAlignment();
+    if (our != null)
+    {
+      if (our.size() > 0)
+      {
+        for (AlignmentAnnotation an : our)
+        {
+          if (!ourAnnots.contains(an))
+          {
+            // remove the old annotation
+            alignment.deleteAnnotation(an);
+          }
+        }
+      }
+      our.clear();
+
+      ap.adjustAnnotationHeight();
+    }
+  }
+
+}
diff --git a/src/jalview/ws/jws2/JPred301Client.java b/src/jalview/ws/jws2/JPred301Client.java
new file mode 100644 (file)
index 0000000..71cbb7e
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
+ * Copyright (C) 2014 The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.ws.jws2;
+
+import jalview.api.AlignCalcWorkerI;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Annotation;
+import jalview.gui.AlignFrame;
+import jalview.ws.jws2.jabaws2.Jws2Instance;
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.OptionI;
+import jalview.ws.params.WsParamSetI;
+import jalview.ws.uimodel.AlignAnalysisUIText;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+
+import compbio.data.sequence.FastaSequence;
+import compbio.data.sequence.JpredAlignment;
+import compbio.metadata.Argument;
+
+public class JPred301Client extends JabawsMsaInterfaceAlignCalcWorker
+        implements AlignCalcWorkerI
+{
+
+  /**
+   * 
+   * @return default args for this service when run as dynamic web service
+   */
+  public List<Argument> selectDefaultArgs()
+  {
+    List<ArgumentI> rgs = new ArrayList<ArgumentI>();
+    for (ArgumentI argi: service.getParamStore().getServiceParameters())
+    {
+      if (argi instanceof OptionI)
+      {
+        List<String> o = ((OptionI) argi).getPossibleValues();
+        if (o.contains("-pred-nohits"))
+        {
+          OptionI cpy = ((OptionI)argi).copy();
+          cpy.setValue("-pred-nohits");
+          rgs.add(cpy);
+        }
+      }
+    }
+    return JabaParamStore.getJabafromJwsArgs(rgs);
+  }
+
+  public JPred301Client(Jws2Instance service, AlignFrame alignFrame,
+          WsParamSetI preset, List<Argument> paramset)
+  {
+    super(service, alignFrame, preset, paramset);
+    submitGaps = true;
+    alignedSeqs = true;
+    nucleotidesAllowed = false;
+    proteinAllowed = true;
+    gapMap = new boolean[0];
+    updateParameters(null, selectDefaultArgs());
+  }
+
+  @Override
+  boolean checkValidInputSeqs(boolean dynamic, List<FastaSequence> seqs)
+  {
+    return (seqs.size() > 1);
+  }
+
+  public String getServiceActionText()
+  {
+    return "calculating consensus secondary structure prediction using JPred service";
+  }
+  private static HashMap<String, String[]> jpredRowLabels = new HashMap<String,String[]>();
+  private static HashSet<String>jpredRes_graph,jpredRes_ssonly;
+  {
+    jpredRes_ssonly=new HashSet();
+    jpredRes_ssonly.add("jnetpred".toLowerCase());
+    jpredRes_graph=new HashSet();
+    jpredRes_graph.add("jnetconf".toLowerCase());
+    
+  }
+  /**
+   * update the consensus annotation from the sequence profile data using
+   * current visualization settings.
+   */
+  public void updateResultAnnotation(boolean immediate)
+  {
+    if (immediate || !calcMan.isWorking(this) && msascoreset != null)
+    {
+      if (msascoreset instanceof compbio.data.sequence.JpredAlignment)
+      {
+        JpredAlignment jpres = (JpredAlignment) msascoreset;
+        int alWidth = alignViewport.getAlignment().getWidth();
+        ArrayList<AlignmentAnnotation> ourAnnot = new ArrayList<AlignmentAnnotation>();
+        for (FastaSequence fsq:jpres.getJpredSequences())
+        {
+          String[] k = jpredRowLabels.get(fsq.getId());
+          if (k==null)
+          {
+            k = new String[] { fsq.getId(), "JNet Output"};
+          }
+          createAnnotationRowFromString(ourAnnot, getCalcId(), alWidth,
+                  k[0],k[1],
+                  jpredRes_graph.contains(fsq.getId()) ?  AlignmentAnnotation.BAR_GRAPH : AlignmentAnnotation.NO_GRAPH, 0f, 0f,
+                  fsq.getSequence());
+
+        }
+        for (FastaSequence fsq: jpres.getSequences())
+        {
+          if (fsq.getId().equalsIgnoreCase("QUERY"))
+          {
+            createAnnotationRowFromString(ourAnnot, getCalcId(), alWidth,
+                    "Query", "JPred Reference Sequence",
+                    AlignmentAnnotation.NO_GRAPH, 0f, 0f,
+                    fsq.getSequence());
+          }
+        }
+        if (ourAnnot.size() > 0)
+        {
+          updateOurAnnots(ourAnnot);
+        }
+      }
+    }
+  }
+
+  private void createAnnotationRowFromString(
+          ArrayList<AlignmentAnnotation> ourAnnot, String calcId,
+          int alWidth, String label, String descr, int rowType, float min,
+          float max, String jpredPrediction)
+  {
+    // simple annotation row
+    AlignmentAnnotation annotation = alignViewport.getAlignment()
+            .findOrCreateAnnotation(label, calcId, true, null, null);
+    if (alWidth == gapMap.length) // scr.getScores().size())
+    {
+      annotation.label = new String(label);
+      annotation.description = new String(descr);
+      annotation.graph = rowType;
+      annotation.graphMin = min;
+      annotation.graphMax = max;
+      if (constructAnnotationFromString(annotation, jpredPrediction,
+              alWidth, rowType))
+      {
+        // created a valid annotation from the data
+        ourAnnot.add(annotation);
+      }
+    }
+  }
+
+  private boolean constructAnnotationFromString(
+          AlignmentAnnotation annotation, String sourceData, int alWidth,
+          int rowType)
+  {
+    if (sourceData.length()==0 && alWidth>0)
+    {
+      return false;
+    }
+    Annotation[] elm = new Annotation[alWidth];
+
+    for (int i = 0, iSize = sourceData.length(); i < iSize; i++)
+    {
+      char annot = sourceData.charAt(i);
+      // if we're at a gapped column then skip to next ungapped position
+      if (gapMap != null && gapMap.length > 0)
+      {
+        while (!gapMap[i])
+        {
+          elm[i++] = new Annotation("", "", ' ', Float.NaN);
+        }
+      }
+      switch (rowType)
+      {
+      case AlignmentAnnotation.NO_GRAPH:
+        elm[i] = new Annotation("" + annot, "" + annot, annot, Float.NaN);
+        break;
+      default:
+        try
+        {
+          elm[i] = new Annotation("" + annot, "" + annot, annot,
+                  Integer.valueOf(annot));
+        } catch (Exception x)
+        {
+          System.err.println("Expected numeric value in character '"
+                  + annot + "'");
+        }
+      }
+    }
+
+    annotation.annotations = elm;
+    annotation.belowAlignment = true;
+    annotation.validateRangeAndDisplay();
+    return true;
+  }
+
+  @Override
+  public String getCalcId()
+  {
+    return CALC_ID;
+  }
+
+  private static String CALC_ID = "jabaws21.JPred3Cons";
+
+  public static AlignAnalysisUIText getAlignAnalysisUITest()
+  {
+    return new AlignAnalysisUIText(
+            compbio.ws.client.Services.JpredWS.toString(),
+            jalview.ws.jws2.JPred301Client.class, CALC_ID, false, true,
+            true, "JPred Consensus",
+            "When checked, JPred consensus is updated automatically.",
+            "Change JPred Settings...",
+            "Modify settings for JPred calculations.");
+  }
+}
diff --git a/src/jalview/ws/jws2/JabawsAlignCalcWorker.java b/src/jalview/ws/jws2/JabawsAlignCalcWorker.java
deleted file mode 100644 (file)
index 43d7c63..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
- * Copyright (C) 2014 The Jalview Authors
- * 
- * This file is part of Jalview.
- * 
- * Jalview is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License 
- * as published by the Free Software Foundation, either version 3
- * of the License, or (at your option) any later version.
- *  
- * Jalview is distributed in the hope that it will be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty 
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
- * PURPOSE.  See the GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
- * The Jalview Authors are detailed in the 'AUTHORS' file.
- */
-package jalview.ws.jws2;
-
-import jalview.api.AlignViewportI;
-import jalview.api.AlignmentViewPanel;
-import jalview.gui.AlignFrame;
-import jalview.ws.jws2.dm.AAConSettings;
-import jalview.ws.jws2.jabaws2.Jws2Instance;
-import jalview.ws.params.WsParamSetI;
-
-import java.util.List;
-
-import compbio.metadata.Argument;
-
-public abstract class JabawsAlignCalcWorker extends JabawsCalcWorker
-{
-
-  public JabawsAlignCalcWorker(AlignViewportI alignViewport,
-          AlignmentViewPanel alignPanel)
-  {
-    super(alignViewport, alignPanel);
-  }
-
-  public JabawsAlignCalcWorker(Jws2Instance service, AlignFrame alignFrame,
-          WsParamSetI preset, List<Argument> paramset)
-  {
-    super(service, alignFrame, preset, paramset);
-  }
-
-  /**
-   * Recover any existing parameters for this service
-   */
-  protected void initViewportParams()
-  {
-    ((jalview.gui.AlignViewport) alignViewport).setCalcIdSettingsFor(
-            getCalcId(),
-            new AAConSettings(true, service, this.preset,
-                    (arguments != null) ? JabaParamStore
-                            .getJwsArgsfromJaba(arguments) : null), true);
-  }
-
-  /**
-   * 
-   * @return
-   */
-  public abstract String getCalcId();
-
-  @Override
-  public void updateParameters(WsParamSetI newpreset,
-          java.util.List<Argument> newarguments)
-  {
-    super.updateParameters(newpreset, newarguments);
-    initViewportParams();
-  }
-}
index 5223c52..afb46e9 100644 (file)
  */
 package jalview.ws.jws2;
 
-import java.util.ArrayList;
-import java.util.HashMap;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Annotation;
+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 java.util.Map;
 
 import compbio.data.msa.SequenceAnnotation;
-import compbio.data.sequence.FastaSequence;
 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;
-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.AnnotatedCollectionI;
-import jalview.datamodel.Annotation;
-import jalview.datamodel.SequenceI;
-import jalview.gui.AlignFrame;
-import jalview.gui.IProgressIndicator;
-import jalview.workers.AlignCalcWorker;
-import jalview.ws.jws2.dm.JabaWsParamSet;
-import jalview.ws.jws2.jabaws2.Jws2Instance;
-import jalview.ws.params.WsParamSetI;
 
-public abstract class JabawsCalcWorker extends AlignCalcWorker
+public abstract class JabawsCalcWorker extends AbstractJabaCalcWorker
 {
 
-  protected Jws2Instance service;
-
   @SuppressWarnings("unchecked")
   protected SequenceAnnotation aaservice;
 
   protected ScoreManager scoremanager;
 
-  protected WsParamSetI preset;
-
-  protected List<Argument> arguments;
-
-  protected IProgressIndicator guiProgress;
-
-  public JabawsCalcWorker(AlignViewportI alignViewport,
-          AlignmentViewPanel alignPanel)
-  {
-    super(alignViewport, alignPanel);
-  }
-
   public JabawsCalcWorker(Jws2Instance service, AlignFrame alignFrame,
           WsParamSetI preset, List<Argument> paramset)
   {
-    this(alignFrame.getCurrentView(), alignFrame.alignPanel);
-    this.guiProgress = alignFrame;
-    this.preset = preset;
-    this.arguments = paramset;
-    this.service = service;
+    super(service, alignFrame, preset, paramset);
     aaservice = (SequenceAnnotation) service.service;
-
   }
 
-  public WsParamSetI getPreset()
+  @Override
+  ChunkHolder pullExecStatistics(String rslt, long rpos)
   {
-    return preset;
+    return aaservice.pullExecStatistics(rslt, rpos);
   }
 
-  public List<Argument> getArguments()
+  @Override
+  boolean collectAnnotationResultsFor(String rslt)
+          throws ResultNotAvailableException
   {
-    return arguments;
+    scoremanager = aaservice.getAnnotation(rslt);
+    if (scoremanager != null)
+    {
+      return true;
+    }
+    return false;
   }
 
-  /**
-   * reconfigure and restart the AAConClient. 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)
+  @Override
+  boolean cancelJob(String rslt) throws Exception
   {
-    preset = newpreset;
-    arguments = newarguments;
-    calcMan.startWorker(this);
+    return aaservice.cancelJob(rslt);
   }
 
-  public List<Option> getJabaArguments()
+  @Override
+  protected JobStatus getJobStatus(String rslt) throws Exception
   {
-    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;
+    return aaservice.getJobStatus(rslt);
   }
 
   @Override
-  public void run()
+  boolean hasService()
   {
-    if (aaservice == null)
-    {
-      return;
-    }
-    long progressId = -1;
-
-    int serverErrorsLeft = 3;
-
-    String rslt = "JOB NOT DEFINED";
-    StringBuffer msg = new StringBuffer();
-    try
-    {
-      if (checkDone())
-      {
-        return;
-      }
-      List<compbio.data.sequence.FastaSequence> seqs = getInputSequences(
-              alignViewport.getAlignment(),
-              bySequence ? alignViewport.getSelectionGroup() : null);
-
-      if (seqs == null)
-      {
-        calcMan.workerComplete(this);
-        return;
-      }
-
-      AlignmentAnnotation[] aa = alignViewport.getAlignment()
-              .getAlignmentAnnotation();
-      if (guiProgress != null)
-      {
-        guiProgress.setProgressBar("JABA " + getServiceActionText(),
-                progressId = System.currentTimeMillis());
-      }
-      if (preset == null && arguments == null)
-      {
-        rslt = aaservice.analize(seqs);
-      }
-      else
-      {
-        try
-        {
-          rslt = aaservice.customAnalize(seqs, getJabaArguments());
-        } catch (WrongParameterException x)
-        {
-          throw new JobSubmissionException(
-                  "Invalid parameter set. Check Jalview implementation.", x);
-
-        }
-      }
-      boolean finished = false;
-      long rpos = 0;
-      do
-      {
-        JobStatus status = aaservice.getJobStatus(rslt);
-        if (status.equals(JobStatus.FINISHED))
-        {
-          finished = true;
-        }
-        if (calcMan.isPending(this) && this instanceof AAConClient)
-        {
-          finished = true;
-          // cancel this job and yield to the new job
-          try
-          {
-            if (aaservice.cancelJob(rslt))
-            {
-              System.err.println("Cancelled AACon job: " + rslt);
-            }
-            else
-            {
-              System.err.println("FAILED TO CANCEL AACon job: " + rslt);
-            }
-
-          } catch (Exception x)
-          {
-
-          }
-
-          return;
-        }
-        long cpos;
-        ChunkHolder stats = null;
-        do
-        {
-          cpos = rpos;
-          boolean retry = false;
-          do
-          {
-            try
-            {
-              stats = aaservice.pullExecStatistics(rslt, rpos);
-            } catch (Exception x)
-            {
-
-              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
-              {
-                if (--serverErrorsLeft > 0)
-                {
-                  retry = true;
-                  try
-                  {
-                    Thread.sleep(200);
-                  } catch (InterruptedException q)
-                  {
-                  }
-                  ;
-                }
-                else
-                {
-                  throw x;
-                }
-              }
-            }
-          } while (retry);
-          if (stats != null)
-          {
-            System.out.print(stats.getChunk());
-            msg.append(stats);
-            rpos = stats.getNextPosition();
-          }
-        } while (stats != null && rpos > cpos);
-
-        if (!finished && status.equals(JobStatus.FAILED))
-        {
-          try
-          {
-            Thread.sleep(200);
-          } catch (InterruptedException x)
-          {
-          }
-          ;
-        }
-      } while (!finished);
-      if (serverErrorsLeft > 0)
-      {
-        try
-        {
-          Thread.sleep(200);
-        } catch (InterruptedException x)
-        {
-        }
-        ;
-        scoremanager = aaservice.getAnnotation(rslt);
-        if (scoremanager != null)
-        {
-          jalview.bin.Cache.log
-                  .debug("Updating result annotation from Job " + rslt
-                          + " at " + service.getUri());
-          updateResultAnnotation(true);
-          ap.adjustAnnotationHeight();
-        }
-      }
-    }
-
-    catch (JobSubmissionException x)
-    {
-
-      System.err.println("submission error with " + getServiceActionText()
-              + " :");
-      x.printStackTrace();
-      calcMan.workerCannotRun(this);
-    } catch (ResultNotAvailableException x)
-    {
-      System.err.println("collection error:\nJob ID: " + rslt);
-      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)
-      {
-        calcMan.workerComplete(this);
-        if (guiProgress != null && progressId != -1)
-        {
-          guiProgress.setProgressBar("", progressId);
-        }
-        ap.paintAlignment(true);
-      }
-      if (msg.length() > 0)
-      {
-        // TODO: stash message somewhere in annotation or alignment view.
-        // code below shows result in a text box popup
-        /*
-         * jalview.gui.CutAndPasteTransfer cap = new
-         * jalview.gui.CutAndPasteTransfer(); cap.setText(msg.toString());
-         * jalview.gui.Desktop.addInternalFrame(cap,
-         * "Job Status for "+getServiceActionText(), 600, 400);
-         */
-      }
-    }
-
+    return aaservice != null;
   }
 
   @Override
-  public void updateAnnotation()
+  protected boolean isInteractiveUpdate()
   {
-    updateResultAnnotation(false);
+    return this instanceof AAConClient;
   }
 
-  public abstract void updateResultAnnotation(boolean immediate);
-
-  public abstract String getServiceActionText();
-
-  protected boolean submitGaps = true;
-
-  protected boolean alignedSeqs = true;
-
-  protected boolean nucleotidesAllowed = false;
-
-  protected boolean proteinAllowed = false;
-
-  /**
-   * record sequences for mapping result back to afterwards
-   */
-  protected boolean bySequence = false;
-
-  protected Map<String, SequenceI> seqNames;
-
-  protected boolean[] gapMap;
-
-  int realw;
-
-  int start, end;
-
-  public List<FastaSequence> getInputSequences(AlignmentI alignment,
-          AnnotatedCollectionI inputSeqs)
+  @Override
+  protected String submitToService(
+          List<compbio.data.sequence.FastaSequence> seqs)
+          throws JobSubmissionException
   {
-    if (alignment == null || alignment.getWidth() <= 0
-            || alignment.getSequences() == null || alignment.isNucleotide() ? !nucleotidesAllowed
-            : !proteinAllowed)
-    {
-      return null;
-    }
-    if (inputSeqs == null || inputSeqs.getWidth() <= 0
-            || inputSeqs.getSequences() == null
-            || inputSeqs.getSequences().size() < 1)
-    {
-      inputSeqs = alignment;
-    }
-
-    List<compbio.data.sequence.FastaSequence> seqs = new ArrayList<compbio.data.sequence.FastaSequence>();
-
-    int minlen = 10;
-    int ln = -1;
-    if (bySequence)
-    {
-      seqNames = new HashMap<String, SequenceI>();
-    }
-    gapMap = new boolean[0];
-    start = inputSeqs.getStartRes();
-    end = inputSeqs.getEndRes();
-
-    for (SequenceI sq : ((List<SequenceI>) inputSeqs.getSequences()))
-    {
-      if (bySequence ? sq.findPosition(end + 1)
-              - sq.findPosition(start + 1) > minlen - 1 : 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);
-        }
-        FastaSequence seq;
-        if (submitGaps)
-        {
-          seqs.add(seq = new compbio.data.sequence.FastaSequence(newname,
-                  sq.getSequenceAsString()));
-          if (gapMap == null || gapMap.length < seq.getSequence().length())
-          {
-            boolean[] tg = gapMap;
-            gapMap = new boolean[seq.getLength()];
-            System.arraycopy(tg, 0, gapMap, 0, tg.length);
-            for (int p = tg.length; p < gapMap.length; p++)
-            {
-              gapMap[p] = false; // init as a gap
-            }
-          }
-          for (int apos : sq.gapMap())
-          {
-            gapMap[apos] = true; // aligned.
-          }
-        }
-        else
-        {
-          seqs.add(seq = new compbio.data.sequence.FastaSequence(newname,
-                  AlignSeq.extractGaps(jalview.util.Comparison.GapChars,
-                          sq.getSequenceAsString(start, end + 1))));
-        }
-        if (seq.getSequence().length() > ln)
-        {
-          ln = seq.getSequence().length();
-        }
-      }
-    }
-    if (alignedSeqs && submitGaps)
+    String rslt;
+    if (preset == null && arguments == null)
     {
-      realw = 0;
-      for (int i = 0; i < gapMap.length; i++)
-      {
-        if (gapMap[i])
-        {
-          realw++;
-        }
-      }
-      // try real hard to return something submittable
-      // TODO: some of AAcon measures need a minimum of two or three amino
-      // acids at each position, and AAcon doesn't gracefully degrade.
-      for (int p = 0; p < seqs.size(); p++)
-      {
-        FastaSequence sq = seqs.get(p);
-        int l = sq.getSequence().length();
-        // strip gapped columns
-        char[] padded = new char[realw], orig = sq.getSequence()
-                .toCharArray();
-        for (int i = 0, pp = 0; i < realw; pp++)
-        {
-          if (gapMap[pp])
-          {
-            if (orig.length > pp)
-            {
-              padded[i++] = orig[pp];
-            }
-            else
-            {
-              padded[i++] = '-';
-            }
-          }
-        }
-        seqs.set(p, new compbio.data.sequence.FastaSequence(sq.getId(),
-                new String(padded)));
-      }
+      rslt = aaservice.analize(seqs);
     }
-    return seqs;
-  }
-
-  /**
-   * 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))
+    else
     {
-      if (calcMan.isWorking(this))
-      {
-        return true;
-      }
       try
       {
-        if (ap != null)
-        {
-          ap.paintAlignment(false);
-        }
-
-        Thread.sleep(200);
-      } catch (Exception ex)
+        rslt = aaservice.customAnalize(seqs, getJabaArguments());
+      } catch (WrongParameterException x)
       {
-        ex.printStackTrace();
+        throw new JobSubmissionException(
+                "Invalid parameter set. Check Jalview implementation.", x);
+
       }
     }
-    if (alignViewport.isClosed())
-    {
-      abortAndDestroy();
-      return true;
-    }
-    return false;
+    return rslt;
   }
 
   protected void createAnnotationRowsForScores(
@@ -622,28 +207,4 @@ public abstract class JabawsCalcWorker extends AlignCalcWorker
     annotation.validateRangeAndDisplay();
   }
 
-  protected void updateOurAnnots(List<AlignmentAnnotation> ourAnnot)
-  {
-    List<AlignmentAnnotation> our = ourAnnots;
-    ourAnnots = ourAnnot;
-    AlignmentI alignment = alignViewport.getAlignment();
-    if (our != null)
-    {
-      if (our.size() > 0)
-      {
-        for (AlignmentAnnotation an : our)
-        {
-          if (!ourAnnots.contains(an))
-          {
-            // remove the old annotation
-            alignment.deleteAnnotation(an);
-          }
-        }
-      }
-      our.clear();
-
-      ap.adjustAnnotationHeight();
-    }
-  }
-
 }
diff --git a/src/jalview/ws/jws2/JabawsMsaInterfaceAlignCalcWorker.java b/src/jalview/ws/jws2/JabawsMsaInterfaceAlignCalcWorker.java
new file mode 100644 (file)
index 0000000..1f0d92c
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
+ * Copyright (C) 2014 The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.ws.jws2;
+
+import java.util.Iterator;
+import java.util.List;
+
+import compbio.data.msa.MsaWS;
+import compbio.data.msa.SequenceAnnotation;
+import compbio.data.sequence.Alignment;
+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.ResultNotAvailableException;
+import compbio.metadata.WrongParameterException;
+import jalview.api.AlignViewportI;
+import jalview.api.AlignmentViewPanel;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.workers.AlignCalcWorker;
+import jalview.ws.jws2.jabaws2.Jws2Instance;
+import jalview.ws.params.WsParamSetI;
+
+public abstract class JabawsMsaInterfaceAlignCalcWorker extends AbstractJabaCalcWorker
+{
+
+  @SuppressWarnings("unchecked")
+  protected MsaWS msaservice;
+
+  protected Alignment msascoreset;
+
+  public JabawsMsaInterfaceAlignCalcWorker(AlignViewportI alignViewport,
+          AlignmentViewPanel alignPanel)
+  {
+    super(alignViewport, alignPanel);
+  }
+
+  public JabawsMsaInterfaceAlignCalcWorker(Jws2Instance service, AlignFrame alignFrame,
+          WsParamSetI preset, List<Argument> paramset)
+  {
+    this(alignFrame.getCurrentView(), alignFrame.alignPanel);
+    this.guiProgress = alignFrame;
+    this.preset = preset;
+    this.arguments = paramset;
+    this.service = service;
+    msaservice = (MsaWS) service.service;
+
+  }
+
+  @Override
+  ChunkHolder pullExecStatistics(String rslt, long rpos)
+  {
+    return msaservice.pullExecStatistics(rslt, rpos);
+  }
+
+  @Override
+  boolean collectAnnotationResultsFor(String rslt)
+          throws ResultNotAvailableException
+  {
+    msascoreset = msaservice.getResult(rslt);
+    if (msascoreset != null)
+    {
+      return true;
+    }
+    return false;
+  }
+
+  @Override
+  boolean cancelJob(String rslt) throws Exception
+  {
+    return msaservice.cancelJob(rslt);
+  }
+
+  @Override
+  protected JobStatus getJobStatus(String rslt) throws Exception
+  {
+    return msaservice.getJobStatus(rslt);
+  }
+
+  @Override
+  boolean hasService()
+  {
+    return msaservice != null;
+  }
+
+  @Override
+  protected boolean isInteractiveUpdate()
+  {
+    return false; // this instanceof AAConClient;
+  }
+
+  @Override
+  protected String submitToService(
+          List<compbio.data.sequence.FastaSequence> seqs)
+          throws JobSubmissionException
+  {
+    String rslt;
+    if (preset == null && arguments == null)
+    {
+      rslt = msaservice.align(seqs);
+    }
+    else
+    {
+      try
+      {
+        rslt = msaservice.customAlign(seqs, getJabaArguments());
+      } catch (WrongParameterException x)
+      {
+        throw new JobSubmissionException(
+                "Invalid parameter set. Check Jalview implementation.", x);
+
+      }
+    }
+    return rslt;
+  }
+
+  protected void createAnnotationRowsForScores(
+          List<AlignmentAnnotation> ourAnnot, String calcId, int alWidth,
+          Score scr)
+  {
+    // simple annotation row
+    AlignmentAnnotation annotation = alignViewport.getAlignment()
+            .findOrCreateAnnotation(scr.getMethod(), calcId, true, null,
+                    null);
+    if (alWidth == gapMap.length) // scr.getScores().size())
+    {
+      constructAnnotationFromScore(annotation, 0, alWidth, scr);
+      ourAnnot.add(annotation);
+    }
+  }
+
+  protected AlignmentAnnotation createAnnotationRowsForScores(
+          List<AlignmentAnnotation> ourAnnot, String typeName,
+          String calcId, SequenceI dseq, int base, Score scr)
+  {
+    System.out.println("Creating annotation on dseq:" + dseq.getStart()
+            + " base is " + base + " and length=" + dseq.getLength()
+            + " == " + scr.getScores().size());
+    // AlignmentAnnotation annotation = new AlignmentAnnotation(
+    // scr.getMethod(), typeName, new Annotation[]
+    // {}, 0, -1, AlignmentAnnotation.LINE_GRAPH);
+    // annotation.setCalcId(calcId);
+    AlignmentAnnotation annotation = alignViewport.getAlignment()
+            .findOrCreateAnnotation(typeName, calcId, false, dseq, null);
+    constructAnnotationFromScore(annotation, 0, dseq.getLength(), scr);
+    annotation.createSequenceMapping(dseq, base, false);
+    annotation.adjustForAlignment();
+    dseq.addAlignmentAnnotation(annotation);
+    ourAnnot.add(annotation);
+    return annotation;
+  }
+
+  private void constructAnnotationFromScore(AlignmentAnnotation annotation,
+          int base, int alWidth, Score scr)
+  {
+    Annotation[] elm = new Annotation[alWidth];
+    Iterator<Float> vals = scr.getScores().iterator();
+    float m = 0f, x = 0f;
+    for (int i = 0; vals.hasNext(); i++)
+    {
+      float val = vals.next().floatValue();
+      if (i == 0)
+      {
+        m = val;
+        x = val;
+      }
+      else
+      {
+        if (m > val)
+        {
+          m = val;
+        }
+        ;
+        if (x < val)
+        {
+          x = val;
+        }
+      }
+      // if we're at a gapped column then skip to next ungapped position
+      if (gapMap != null && gapMap.length > 0)
+      {
+        while (!gapMap[i])
+        {
+          elm[i++] = new Annotation("", "", ' ', Float.NaN);
+        }
+      }
+      elm[i] = new Annotation("", "" + val, ' ', val);
+    }
+
+    annotation.annotations = elm;
+    annotation.belowAlignment = true;
+    if (x < 0)
+    {
+      x = 0;
+    }
+    x += (x - m) * 0.1;
+    annotation.graphMax = x;
+    annotation.graphMin = m;
+    annotation.validateRangeAndDisplay();
+  }
+
+}
index 2c96009..b2b676f 100644 (file)
  */
 package jalview.ws.jws2;
 
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
 import java.util.List;
 
+import javax.swing.JCheckBoxMenuItem;
 import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.event.MenuEvent;
+import javax.swing.event.MenuListener;
 
 import compbio.metadata.Argument;
-
+import jalview.api.AlignCalcWorkerI;
+import jalview.bin.Cache;
 import jalview.gui.AlignFrame;
 import jalview.gui.Desktop;
+import jalview.gui.JvSwingUtils;
 import jalview.gui.WebserviceInfo;
 import jalview.gui.WsJobParameters;
 import jalview.util.MessageManager;
+import jalview.ws.jws2.dm.AAConSettings;
 import jalview.ws.jws2.dm.JabaWsParamSet;
 import jalview.ws.jws2.jabaws2.Jws2Instance;
 import jalview.ws.params.WsParamSetI;
+import jalview.ws.uimodel.AlignAnalysisUIText;
 
 /**
  * provides metadata for a jabaws2 service instance - resolves names, etc.
@@ -164,5 +174,252 @@ public abstract class Jws2Client extends jalview.ws.WSClient
    */
   abstract void attachWSMenuEntry(JMenu wsmenu, final Jws2Instance service,
           final AlignFrame alignFrame);
+  
+
+  protected boolean registerAAConWSInstance(final JMenu wsmenu,
+          final Jws2Instance service, final AlignFrame alignFrame)
+  {
+    final AlignAnalysisUIText aaui = service.getAlignAnalysisUI(); // null ; //
+                                                                   // AlignAnalysisUIText.aaConGUI.get(service.serviceType.toString());
+    if (aaui == null)
+    {
+      // not an instantaneous calculation GUI type service
+      return false;
+    }
+    // create the instaneous calculation GUI bits and update state if existing
+    // GUI elements already present
+
+    JCheckBoxMenuItem _aaConEnabled = null;
+    for (int i = 0; i < wsmenu.getItemCount(); i++)
+    {
+      JMenuItem item = wsmenu.getItem(i);
+      if (item instanceof JCheckBoxMenuItem
+              && item.getText().equals(aaui.getAAconToggle()))
+      {
+        _aaConEnabled = (JCheckBoxMenuItem) item;
+      }
+    }
+    // is there an aaCon worker already present - if so, set it to use the
+    // given service handle
+    {
+      List<AlignCalcWorkerI> aaconClient = alignFrame.getViewport()
+              .getCalcManager()
+              .getRegisteredWorkersOfClass(aaui.getClient());
+      if (aaconClient != null && aaconClient.size() > 0)
+      {
+        AbstractJabaCalcWorker worker = (AbstractJabaCalcWorker) aaconClient
+                .get(0);
+        if (!worker.service.hosturl.equals(service.hosturl))
+        {
+          // javax.swing.SwingUtilities.invokeLater(new Runnable()
+          {
+            // @Override
+            // public void run()
+            {
+              removeCurrentAAConWorkerFor(aaui, alignFrame);
+              buildCurrentAAConWorkerFor(aaui, alignFrame, service);
+            }
+          }// );
+        }
+      }
+    }
+
+    // is there a service already registered ? there shouldn't be if we are
+    // being called correctly
+    if (_aaConEnabled == null)
+    {
+      final JCheckBoxMenuItem aaConEnabled = new JCheckBoxMenuItem(
+              aaui.getAAconToggle());
+
+      aaConEnabled.setToolTipText("<html><p>"
+              + JvSwingUtils.wrapTooltip(aaui.getAAconToggleTooltip()
+                      + "</p>") + "</html>");
+      aaConEnabled.addActionListener(new ActionListener()
+      {
+        @Override
+        public void actionPerformed(ActionEvent arg0)
+        {
+          List<AlignCalcWorkerI> aaconClient = alignFrame.getViewport()
+                  .getCalcManager()
+                  .getRegisteredWorkersOfClass(aaui.getClient());
+          if (aaconClient != null && aaconClient.size() > 0)
+          {
+            removeCurrentAAConWorkerFor(aaui, alignFrame);
+          }
+          else
+          {
+            buildCurrentAAConWorkerFor(aaui, alignFrame);
+
+          }
+        }
+
+      });
+      wsmenu.add(aaConEnabled);
+      final JMenuItem modifyParams = new JMenuItem(aaui.getAAeditSettings());
+      modifyParams.setToolTipText("<html><p>"
+              + JvSwingUtils.wrapTooltip(aaui.getAAeditSettingsTooltip()
+                      + "</p>") + "</html>");
+      modifyParams.addActionListener(new ActionListener()
+      {
+
+        @Override
+        public void actionPerformed(ActionEvent arg0)
+        {
+          showAAConAnnotationSettingsFor(aaui, alignFrame);
+        }
+      });
+      wsmenu.add(modifyParams);
+      wsmenu.addMenuListener(new MenuListener()
+      {
+
+        @Override
+        public void menuSelected(MenuEvent arg0)
+        {
+          // TODO: refactor to the implementing class.
+          if (alignFrame.getViewport().getAlignment().isNucleotide() ? aaui
+                  .isNa() : aaui.isPr())
+          {
+            aaConEnabled.setEnabled(true);
+            modifyParams.setEnabled(true);
+          }
+          else
+          {
+            aaConEnabled.setEnabled(false);
+            modifyParams.setEnabled(false);
+          }
+          List<AlignCalcWorkerI> aaconClient = alignFrame.getViewport()
+                  .getCalcManager()
+                  .getRegisteredWorkersOfClass(aaui.getClient());
+          if (aaconClient != null && aaconClient.size() > 0)
+          {
+            aaConEnabled.setSelected(true);
+          }
+          else
+          {
+            aaConEnabled.setSelected(false);
+          }
+        }
+
+        @Override
+        public void menuDeselected(MenuEvent arg0)
+        {
+          // TODO Auto-generated method stub
+
+        }
+
+        @Override
+        public void menuCanceled(MenuEvent arg0)
+        {
+          // TODO Auto-generated method stub
+
+        }
+      });
+
+    }
+    return true;
+  }
+
+  private static void showAAConAnnotationSettingsFor(
+          final AlignAnalysisUIText aaui, AlignFrame alignFrame)
+  {
+    /*
+     * preferred settings Whether AACon is automatically recalculated Which
+     * AACon server to use What parameters to use
+     */
+    // could actually do a class search for this too
+    AAConSettings fave = (AAConSettings) alignFrame.getViewport()
+            .getCalcIdSettingsFor(aaui.getCalcId());
+    if (fave == null)
+    {
+      fave = createDefaultAAConSettings(aaui);
+    }
+    new SequenceAnnotationWSClient(fave, alignFrame, true);
+
+  }
+
+  private static void buildCurrentAAConWorkerFor(
+          final AlignAnalysisUIText aaui, AlignFrame alignFrame)
+  {
+    buildCurrentAAConWorkerFor(aaui, alignFrame, null);
+  }
+
+  private static void buildCurrentAAConWorkerFor(
+          final AlignAnalysisUIText aaui, AlignFrame alignFrame,
+          Jws2Instance service)
+  {
+    /*
+     * preferred settings Whether AACon is automatically recalculated Which
+     * AACon server to use What parameters to use
+     */
+    AAConSettings fave = (AAConSettings) alignFrame.getViewport()
+            .getCalcIdSettingsFor(aaui.getCalcId());
+    if (fave == null)
+    {
+      fave = createDefaultAAConSettings(aaui, service);
+    }
+    else
+    {
+      if (service != null
+              && !fave.getService().hosturl.equals(service.hosturl))
+      {
+        Cache.log.debug("Changing AACon service to " + service.hosturl
+                + " from " + fave.getService().hosturl);
+        fave.setService(service);
+      }
+    }
+    new SequenceAnnotationWSClient(fave, alignFrame, false);
+  }
+
+  private static AAConSettings createDefaultAAConSettings(
+          AlignAnalysisUIText aaui)
+  {
+    return createDefaultAAConSettings(aaui, null);
+  }
+
+  private static AAConSettings createDefaultAAConSettings(
+          AlignAnalysisUIText aaui, Jws2Instance service)
+  {
+    if (service != null)
+    {
+      if (!service.serviceType.toString().equals(
+              compbio.ws.client.Services.AAConWS.toString()))
+      {
+        Cache.log
+                .warn("Ignoring invalid preferred service for AACon calculations (service type was "
+                        + service.serviceType + ")");
+        service = null;
+      }
+      else
+      {
+        // check service is actually in the list of currently avaialable
+        // services
+        if (!Jws2Discoverer.getDiscoverer().getServices().contains(service))
+        {
+          // it isn't ..
+          service = null;
+        }
+      }
+    }
+    if (service == null)
+    {
+      // get the default service for AACon
+      service = Jws2Discoverer.getDiscoverer().getPreferredServiceFor(null,
+              aaui.getServiceType());
+    }
+    if (service == null)
+    {
+      // TODO raise dialog box explaining error, and/or open the JABA
+      // preferences menu.
+      throw new Error("No AACon service found.");
+    }
+    return new AAConSettings(true, service, null, null);
+  }
+
+  private static void removeCurrentAAConWorkerFor(AlignAnalysisUIText aaui,
+          AlignFrame alignFrame)
+  {
+    alignFrame.getViewport().getCalcManager()
+            .removeRegisteredWorkersOfClass(aaui.getClient());
+  }
 
 }
index 206bdc8..144a860 100644 (file)
@@ -135,7 +135,7 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
     // first set up exclusion list if needed
     final Set<String> ignoredServices = new HashSet<String>();
     for (String ignored : jalview.bin.Cache.getDefault(
-            "IGNORED_JABAWS_SERVICETYPES", Services.JpredWS.toString())
+            "IGNORED_JABAWS_SERVICETYPES", "")
             .split("\\|"))
     {
       ignoredServices.add(ignored);
index 37231fd..285dcc0 100644 (file)
@@ -193,6 +193,11 @@ public class MsaWSClient extends Jws2Client
   public void attachWSMenuEntry(JMenu rmsawsmenu,
           final Jws2Instance service, final AlignFrame alignFrame)
   {
+    if (registerAAConWSInstance(rmsawsmenu, service, alignFrame))
+    {
+      // Alignment dependent analysis calculation WS gui
+      return;
+    }
     setWebService(service, true); // headless
     boolean finished = true, submitGaps = false;
     JMenu msawsmenu = rmsawsmenu;
index 5d0df8a..253a797 100644 (file)
@@ -37,6 +37,7 @@ import java.util.TreeSet;
 import java.util.regex.Pattern;
 
 import compbio.data.sequence.RNAStructReader.AlifoldResult;
+import compbio.data.sequence.FastaSequence;
 import compbio.data.sequence.RNAStructScoreManager;
 import compbio.data.sequence.Range;
 import compbio.data.sequence.Score;
@@ -49,7 +50,7 @@ import compbio.metadata.Argument;
  * 
  */
 
-public class RNAalifoldClient extends JabawsAlignCalcWorker implements
+public class RNAalifoldClient extends JabawsCalcWorker implements
         AlignCalcWorkerI
 {
 
@@ -65,10 +66,6 @@ public class RNAalifoldClient extends JabawsAlignCalcWorker implements
           WsParamSetI preset, List<Argument> paramset)
   {
     super(sh, alignFrame, preset, paramset);
-
-    // if (arguments == null)
-    // arguments = new ArrayList<Argument>();
-
     af = alignFrame;
     methodName = sh.serviceType;
     alignedSeqs = true;
@@ -109,6 +106,12 @@ public class RNAalifoldClient extends JabawsAlignCalcWorker implements
   }
 
   @Override
+  boolean checkValidInputSeqs(boolean dynamic, List<FastaSequence> seqs)
+  {
+    return (seqs.size() > 1);
+  }
+
+  @Override
   public void updateResultAnnotation(boolean immediate)
   {
 
index 77ba300..13568ea 100644 (file)
@@ -88,7 +88,7 @@ public class SequenceAnnotationWSClient extends Jws2Client
 
       List<AlignCalcWorkerI> clnts = alignFrame.getViewport()
               .getCalcManager().getRegisteredWorkersOfClass(clientClass);
-      JabawsAlignCalcWorker worker;
+      AbstractJabaCalcWorker worker;
       if (clnts == null || clnts.size() == 0)
       {
         if (!processParams(sh, editParams))
@@ -97,7 +97,7 @@ public class SequenceAnnotationWSClient extends Jws2Client
         }
         try
         {
-          worker = (JabawsAlignCalcWorker) (clientClass
+          worker = (AbstractJabaCalcWorker) (clientClass
                   .getConstructor(new Class[]
                   { Jws2Instance.class, AlignFrame.class,
                       WsParamSetI.class, List.class })
@@ -114,7 +114,7 @@ public class SequenceAnnotationWSClient extends Jws2Client
       }
       else
       {
-        worker = (JabawsAlignCalcWorker) clnts.get(0);
+        worker = (AbstractJabaCalcWorker) clnts.get(0);
         if (editParams)
         {
           paramset = worker.getArguments();
@@ -257,250 +257,4 @@ public class SequenceAnnotationWSClient extends Jws2Client
       }
     }
   }
-
-  private boolean registerAAConWSInstance(final JMenu wsmenu,
-          final Jws2Instance service, final AlignFrame alignFrame)
-  {
-    final AlignAnalysisUIText aaui = service.getAlignAnalysisUI(); // null ; //
-                                                                   // AlignAnalysisUIText.aaConGUI.get(service.serviceType.toString());
-    if (aaui == null)
-    {
-      // not an instantaneous calculation GUI type service
-      return false;
-    }
-    // create the instaneous calculation GUI bits and update state if existing
-    // GUI elements already present
-
-    JCheckBoxMenuItem _aaConEnabled = null;
-    for (int i = 0; i < wsmenu.getItemCount(); i++)
-    {
-      JMenuItem item = wsmenu.getItem(i);
-      if (item instanceof JCheckBoxMenuItem
-              && item.getText().equals(aaui.getAAconToggle()))
-      {
-        _aaConEnabled = (JCheckBoxMenuItem) item;
-      }
-    }
-    // is there an aaCon worker already present - if so, set it to use the
-    // given service handle
-    {
-      List<AlignCalcWorkerI> aaconClient = alignFrame.getViewport()
-              .getCalcManager()
-              .getRegisteredWorkersOfClass(aaui.getClient());
-      if (aaconClient != null && aaconClient.size() > 0)
-      {
-        JabawsAlignCalcWorker worker = (JabawsAlignCalcWorker) aaconClient
-                .get(0);
-        if (!worker.service.hosturl.equals(service.hosturl))
-        {
-          // javax.swing.SwingUtilities.invokeLater(new Runnable()
-          {
-            // @Override
-            // public void run()
-            {
-              removeCurrentAAConWorkerFor(aaui, alignFrame);
-              buildCurrentAAConWorkerFor(aaui, alignFrame, service);
-            }
-          }// );
-        }
-      }
-    }
-
-    // is there a service already registered ? there shouldn't be if we are
-    // being called correctly
-    if (_aaConEnabled == null)
-    {
-      final JCheckBoxMenuItem aaConEnabled = new JCheckBoxMenuItem(
-              aaui.getAAconToggle());
-
-      aaConEnabled.setToolTipText("<html><p>"
-              + JvSwingUtils.wrapTooltip(aaui.getAAconToggleTooltip()
-                      + "</p>") + "</html>");
-      aaConEnabled.addActionListener(new ActionListener()
-      {
-        @Override
-        public void actionPerformed(ActionEvent arg0)
-        {
-          List<AlignCalcWorkerI> aaconClient = alignFrame.getViewport()
-                  .getCalcManager()
-                  .getRegisteredWorkersOfClass(aaui.getClient());
-          if (aaconClient != null && aaconClient.size() > 0)
-          {
-            removeCurrentAAConWorkerFor(aaui, alignFrame);
-          }
-          else
-          {
-            buildCurrentAAConWorkerFor(aaui, alignFrame);
-
-          }
-        }
-
-      });
-      wsmenu.add(aaConEnabled);
-      final JMenuItem modifyParams = new JMenuItem(aaui.getAAeditSettings());
-      modifyParams.setToolTipText("<html><p>"
-              + JvSwingUtils.wrapTooltip(aaui.getAAeditSettingsTooltip()
-                      + "</p>") + "</html>");
-      modifyParams.addActionListener(new ActionListener()
-      {
-
-        @Override
-        public void actionPerformed(ActionEvent arg0)
-        {
-          showAAConAnnotationSettingsFor(aaui, alignFrame);
-        }
-      });
-      wsmenu.add(modifyParams);
-      wsmenu.addMenuListener(new MenuListener()
-      {
-
-        @Override
-        public void menuSelected(MenuEvent arg0)
-        {
-          // TODO: refactor to the implementing class.
-          if (alignFrame.getViewport().getAlignment().isNucleotide() ? aaui
-                  .isNa() : aaui.isPr())
-          {
-            aaConEnabled.setEnabled(true);
-            modifyParams.setEnabled(true);
-          }
-          else
-          {
-            aaConEnabled.setEnabled(false);
-            modifyParams.setEnabled(false);
-          }
-          List<AlignCalcWorkerI> aaconClient = alignFrame.getViewport()
-                  .getCalcManager()
-                  .getRegisteredWorkersOfClass(aaui.getClient());
-          if (aaconClient != null && aaconClient.size() > 0)
-          {
-            aaConEnabled.setSelected(true);
-          }
-          else
-          {
-            aaConEnabled.setSelected(false);
-          }
-        }
-
-        @Override
-        public void menuDeselected(MenuEvent arg0)
-        {
-          // TODO Auto-generated method stub
-
-        }
-
-        @Override
-        public void menuCanceled(MenuEvent arg0)
-        {
-          // TODO Auto-generated method stub
-
-        }
-      });
-
-    }
-    return true;
-  }
-
-  private static void showAAConAnnotationSettingsFor(
-          final AlignAnalysisUIText aaui, AlignFrame alignFrame)
-  {
-    /*
-     * preferred settings Whether AACon is automatically recalculated Which
-     * AACon server to use What parameters to use
-     */
-    // could actually do a class search for this too
-    AAConSettings fave = (AAConSettings) alignFrame.getViewport()
-            .getCalcIdSettingsFor(aaui.getCalcId());
-    if (fave == null)
-    {
-      fave = createDefaultAAConSettings(aaui);
-    }
-    new SequenceAnnotationWSClient(fave, alignFrame, true);
-
-  }
-
-  private static void buildCurrentAAConWorkerFor(
-          final AlignAnalysisUIText aaui, AlignFrame alignFrame)
-  {
-    buildCurrentAAConWorkerFor(aaui, alignFrame, null);
-  }
-
-  private static void buildCurrentAAConWorkerFor(
-          final AlignAnalysisUIText aaui, AlignFrame alignFrame,
-          Jws2Instance service)
-  {
-    /*
-     * preferred settings Whether AACon is automatically recalculated Which
-     * AACon server to use What parameters to use
-     */
-    AAConSettings fave = (AAConSettings) alignFrame.getViewport()
-            .getCalcIdSettingsFor(aaui.getCalcId());
-    if (fave == null)
-    {
-      fave = createDefaultAAConSettings(aaui, service);
-    }
-    else
-    {
-      if (service != null
-              && !fave.getService().hosturl.equals(service.hosturl))
-      {
-        Cache.log.debug("Changing AACon service to " + service.hosturl
-                + " from " + fave.getService().hosturl);
-        fave.setService(service);
-      }
-    }
-    new SequenceAnnotationWSClient(fave, alignFrame, false);
-  }
-
-  private static AAConSettings createDefaultAAConSettings(
-          AlignAnalysisUIText aaui)
-  {
-    return createDefaultAAConSettings(aaui, null);
-  }
-
-  private static AAConSettings createDefaultAAConSettings(
-          AlignAnalysisUIText aaui, Jws2Instance service)
-  {
-    if (service != null)
-    {
-      if (!service.serviceType.toString().equals(
-              compbio.ws.client.Services.AAConWS.toString()))
-      {
-        Cache.log
-                .warn("Ignoring invalid preferred service for AACon calculations (service type was "
-                        + service.serviceType + ")");
-        service = null;
-      }
-      else
-      {
-        // check service is actually in the list of currently avaialable
-        // services
-        if (!Jws2Discoverer.getDiscoverer().getServices().contains(service))
-        {
-          // it isn't ..
-          service = null;
-        }
-      }
-    }
-    if (service == null)
-    {
-      // get the default service for AACon
-      service = Jws2Discoverer.getDiscoverer().getPreferredServiceFor(null,
-              aaui.getServiceType());
-    }
-    if (service == null)
-    {
-      // TODO raise dialog box explaining error, and/or open the JABA
-      // preferences menu.
-      throw new Error("No AACon service found.");
-    }
-    return new AAConSettings(true, service, null, null);
-  }
-
-  private static void removeCurrentAAConWorkerFor(AlignAnalysisUIText aaui,
-          AlignFrame alignFrame)
-  {
-    alignFrame.getViewport().getCalcManager()
-            .removeRegisteredWorkersOfClass(aaui.getClient());
-  }
 }
index db50a9d..bcc7735 100644 (file)
@@ -23,8 +23,8 @@ package jalview.ws.jws2.jabaws2;
 import java.util.HashMap;
 
 import compbio.data.msa.JABAService;
-
 import jalview.ws.jws2.AAConClient;
+import jalview.ws.jws2.JPred301Client;
 import jalview.ws.jws2.RNAalifoldClient;
 import jalview.ws.uimodel.AlignAnalysisUIText;
 
@@ -47,6 +47,8 @@ public class Jws2InstanceFactory
               AAConClient.getAlignAnalysisUITest());
       aaConGUI.put(compbio.ws.client.Services.RNAalifoldWS.toString(),
               RNAalifoldClient.getAlignAnalysisUITest());
+      aaConGUI.put(compbio.ws.client.Services.JpredWS.toString(),
+              JPred301Client.getAlignAnalysisUITest());
     }
   }
 
index ba78107..295c3bf 100644 (file)
@@ -56,19 +56,25 @@ public class JalviewJabawsTestUtils
 
   public static jalview.ws.jws2.Jws2Discoverer getJabawsDiscoverer()
   {
+    return getJabawsDiscoverer(true);
+  }
+  public static Jws2Discoverer getJabawsDiscoverer(boolean localhost)
+  {
     jalview.ws.jws2.Jws2Discoverer disc = jalview.ws.jws2.Jws2Discoverer
             .getDiscoverer();
-    int p = 0;
     String svcurls = "";
-    Vector<String> services = new Vector<String>();
-    for (String url : JalviewJabawsTestUtils.serviceUrls)
+    if (localhost)
     {
-      svcurls += url + "; ";
-      services.add(url);
+      int p = 0;
+      Vector<String> services = new Vector<String>();
+      for (String url : JalviewJabawsTestUtils.serviceUrls)
+      {
+        svcurls += url + "; ";
+        services.add(url);
+      }
+      ;
+      Jws2Discoverer.setServiceUrls(services);
     }
-    ;
-    Jws2Discoverer.setServiceUrls(services);
-
     try
     {
       disc.run();
@@ -82,4 +88,5 @@ public class JalviewJabawsTestUtils
     return disc;
   }
 
+
 }
index 61e0782..9a723ca 100644 (file)
@@ -70,7 +70,7 @@ public class RNAStructExportImport
   {
 
     jalview.bin.Cache.initLogger();
-    disc = JalviewJabawsTestUtils.getJabawsDiscoverer();
+    disc = JalviewJabawsTestUtils.getJabawsDiscoverer(false);
 
     for (Jws2Instance svc : disc.getServices())
     {