moved visible sub-alignment extraction and update from MsaWSThread to
authorjprocter <Jim Procter>
Thu, 17 Aug 2006 13:33:59 +0000 (13:33 +0000)
committerjprocter <Jim Procter>
Thu, 17 Aug 2006 13:33:59 +0000 (13:33 +0000)
an AlignmentView method, refactored JPredClient to new abstraction and
added flags for canMergeResults and openResultsImmediatly to web
service gui.

src/jalview/datamodel/AlignmentView.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/WebserviceInfo.java
src/jalview/ws/JPredClient.java
src/jalview/ws/MsaWSThread.java
src/jalview/ws/WSClientI.java

index 3524942..2cc0e9f 100644 (file)
@@ -1,5 +1,7 @@
 package jalview.datamodel;
 
+
+
 /**
  * <p>Title: </p>
  *
@@ -49,6 +51,11 @@ public class AlignmentView
   {
     return contigs;
   }
+  /**
+   * get the full alignment and a columnselection object marking the hidden regions
+   * @param gapCharacter char
+   * @return Object[] { SequenceI[], ColumnSelection}
+   */
   public Object[] getAlignmentAndColumnSelection(char gapCharacter) {
     ColumnSelection colsel = new ColumnSelection();
 
@@ -69,7 +76,7 @@ public class AlignmentView
     return seqs;
   }
   /**
-   * 
+   *
    * @return visible number of columns in alignment view
    */
   public int getWidth() {
@@ -79,5 +86,271 @@ public class AlignmentView
   protected void setWidth(int width) {
     this.width = width;
   }
-  
+  /**
+   * get the contiguous subalignments in an alignment view.
+   * @param gapCharacter char
+   * @return SequenceI[][]
+   */
+  public SequenceI[][] getVisibleContigs(char gapCharacter) {
+    SequenceI[][] smsa;
+    int njobs = 1;
+    if (sequences==null || width<=0)
+      return null;
+    if (contigs != null && contigs.length > 0)
+    {
+      int start = 0;
+      njobs = 0;
+      int fwidth = width;
+      for (int contig = 0; contig < contigs.length; contig += 3)
+      {
+        if ( (contigs[contig + 1] - start) > 0)
+        {
+          njobs++;
+        }
+        fwidth += contigs[contig + 2]; // end up with full region width (including hidden regions)
+        start = contigs[contig + 1] + contigs[contig + 2];
+      }
+      if (start < fwidth)
+      {
+        njobs++;
+      }
+      smsa = new SequenceI[njobs][];
+      start = 0;
+      int j = 0;
+      for (int contig = 0; contig < contigs.length; contig += 3)
+      {
+        if (contigs[contig + 1] - start > 0)
+        {
+          SequenceI mseq[] = new SequenceI[sequences.length];
+          for (int s = 0; s < mseq.length; s++)
+          {
+            mseq[s] = sequences[s].getSeq(gapCharacter).getSubSequence(start,
+                contigs[contig + 1]);
+          }
+          smsa[j] = mseq;
+          j++;
+        }
+        start = contigs[contig + 1] + contigs[contig + 2];
+      }
+      if (start < fwidth)
+      {
+        SequenceI mseq[] = new SequenceI[sequences.length];
+        for (int s = 0; s < mseq.length; s++)
+        {
+          mseq[s] = sequences[s].getSeq(gapCharacter).getSubSequence(start,
+              fwidth + 1);
+        }
+        smsa[j] = mseq;
+        j++;
+      }
+    }
+    else
+    {
+      smsa = new SequenceI[1][];
+      smsa[0] = new SequenceI[sequences.length];
+      for (int s = 0; s < sequences.length; s++)
+      {
+        smsa[0][s] = sequences[s].getSeq(gapCharacter);
+      }
+    }
+    return smsa;
+  }
+  /**
+   * return full msa and hidden regions with visible blocks replaced with new sub alignments
+   * @param nvismsa SequenceI[][]
+   * @param orders AlignmentOrder[] corresponding to each SequenceI[] block.
+   * @return Object[]
+   */
+  public Object[] getUpdatedView(SequenceI[][] nvismsa, AlignmentOrder[] orders, char gapCharacter) {
+    if (sequences == null || width <= 0)
+    {
+      throw new Error("empty view cannot be updated.");
+    }
+    if (nvismsa == null)
+      throw new Error(
+          "nvismsa==null. use getAlignmentAndColumnSelection() instead.");
+    if (contigs != null && contigs.length > 0)
+    {
+      SequenceI[] alignment = new SequenceI[sequences.length];
+      ColumnSelection columnselection = new ColumnSelection();
+      if (contigs != null && contigs.length > 0)
+      {
+        int start = 0;
+        int nwidth = 0;
+        int owidth = width;
+        int j = 0;
+        for (int contig = 0; contig < contigs.length; contig += 3)
+        {
+          owidth += contigs[contig + 2]; // recover final column width
+          if (contigs[contig + 1] - start > 0)
+          {
+            int swidth = 0; // subalignment width
+            if (nvismsa[j] != null)
+            {
+              SequenceI mseq[] = nvismsa[j];
+              AlignmentOrder order=(orders==null) ? null : orders[j];
+              j++;
+              if (mseq.length!=sequences.length)
+                throw new Error("Mismatch between number of sequences in block "+j+" ("+mseq.length+") and the original view ("+sequences.length+")");
+              swidth = mseq[0].getLength(); // JBPNote: could ensure padded here.
+              for (int s = 0; s < mseq.length; s++)
+              {
+                if (alignment[s] == null)
+                {
+                  alignment[s] = mseq[s];
+                }
+                else
+                {
+                  alignment[s].setSequence(alignment[s].getSequence() +
+                                           mseq[s].getSequence());
+                  if (mseq[s].getStart() <= mseq[s].getEnd())
+                  {
+                    alignment[s].setEnd(mseq[s].getEnd());
+                  }
+                  if (order!=null) {
+                    order.updateSequence(mseq[s], alignment[s]);
+                  }
+                }
+              }
+            }
+            else
+            {
+              // recover original alignment block or place gaps
+              if (true)
+              {
+                // recover input data
+                for (int s = 0; s < sequences.length; s++)
+                {
+                  SequenceI oseq = sequences[s].getSeq(gapCharacter).getSubSequence(start,
+                      contigs[contig + 1]);
+                  if (swidth < oseq.getLength())
+                  {
+                    swidth = oseq.getLength();
+                  }
+                  if (alignment[s] == null)
+                  {
+                    alignment[s] = oseq;
+                  }
+                  else
+                  {
+                    alignment[s].setSequence(alignment[s].getSequence() +
+                                             oseq.getSequence());
+                    if (oseq.getEnd() >= oseq.getStart())
+                    {
+                      alignment[s].setEnd(oseq.getEnd());
+                    }
+                  }
+                }
+
+              }
+              j++;
+            }
+            nwidth += swidth;
+          }
+          // advance to begining of visible region
+          start = contigs[contig + 1] + contigs[contig + 2];
+          // add hidden segment to right of next region
+          for (int s = 0; s < sequences.length; s++)
+          {
+            SequenceI hseq = sequences[s].getSeq(gapCharacter).getSubSequence(contigs[contig +
+                1], start);
+            if (alignment[s] == null)
+            {
+              alignment[s] = hseq;
+            }
+            else
+            {
+              alignment[s].setSequence(alignment[s].getSequence() +
+                                       hseq.getSequence());
+              if (hseq.getEnd() >= hseq.getStart())
+              {
+                alignment[s].setEnd(hseq.getEnd());
+              }
+            }
+          }
+          // mark hidden segment as hidden in the new alignment
+          columnselection.hideColumns(nwidth, nwidth + contigs[contig + 2] - 1);
+          nwidth += contigs[contig + 2];
+        }
+        // Do final segment - if it exists
+        if (j < nvismsa.length)
+        {
+          int swidth = 0;
+          if (nvismsa[j] != null)
+          {
+            SequenceI mseq[] = nvismsa[j];
+            AlignmentOrder order = (orders!=null) ? orders[j] : null;
+            swidth = mseq[0].getLength();
+            for (int s = 0; s < mseq.length; s++)
+            {
+              if (alignment[s] == null)
+              {
+                alignment[s] = mseq[s];
+              }
+              else
+              {
+                alignment[s].setSequence(alignment[s].getSequence() +
+                                         mseq[s].getSequence());
+                if (mseq[s].getEnd() >= mseq[s].getStart())
+                {
+                  alignment[s].setEnd(mseq[s].getEnd());
+                }
+                if (order!=null) {
+                  order.updateSequence(mseq[s], alignment[s]);
+                }
+              }
+            }
+          }
+          else
+          {
+            if (start < owidth)
+            {
+              // recover input data or place gaps
+              if (true)
+              {
+                // recover input data
+                for (int s = 0; s < sequences.length; s++)
+                {
+                  SequenceI oseq = sequences[s].getSeq(gapCharacter).getSubSequence(start,
+                      owidth + 1);
+                  if (swidth < oseq.getLength())
+                  {
+                    swidth = oseq.getLength();
+                  }
+                  if (alignment[s] == null)
+                  {
+                    alignment[s] = oseq;
+                  }
+                  else
+                  {
+                    alignment[s].setSequence(alignment[s].getSequence() +
+                                             oseq.getSequence());
+                    if (oseq.getEnd() >= oseq.getStart())
+                    {
+                      alignment[s].setEnd(oseq.getEnd());
+                    }
+                  }
+                }
+                nwidth += swidth;
+              }
+              else
+              {
+                // place gaps.
+                throw new Error("Padding not yet implemented.");
+              }
+            }
+          }
+        }
+      }
+      return new Object[] { alignment, columnselection};
+    } else {
+      if (nvismsa.length!=1)
+        throw new Error("Mismatch between visible blocks to update and number of contigs in view (contigs=0,blocks="+nvismsa.length);
+      if (nvismsa[0]!=null)
+        return new Object[] { nvismsa[0], new ColumnSelection()};
+      else
+        return getAlignmentAndColumnSelection(gapCharacter);
+    }
+  }
+
 }
index 7ec1f26..28961e5 100755 (executable)
@@ -2578,7 +2578,7 @@ public class AlignFrame
               if (msa.length == 1)\r
               {\r
                 // Single Sequence prediction\r
-                new jalview.ws.JPredClient(sh,title, msa[0]);\r
+                new jalview.ws.JPredClient(sh, title, msa[0], null);\r
               }\r
               else\r
               {\r
@@ -2586,7 +2586,7 @@ public class AlignFrame
                 {\r
                   // Single Sequence prediction\r
                   jalview.ws.JPredClient ct = new jalview.ws.JPredClient(sh,\r
-                      title, msa);\r
+                      title, msa, null);\r
                 }\r
               }\r
             }\r
index 328de9c..ccda9d1 100755 (executable)
@@ -63,7 +63,9 @@ public class WebserviceInfo extends GWebserviceInfo
     JInternalFrame frame;
     JTabbedPane subjobs=null;
     java.util.Vector jobPanes = null;
-    // tabbed or not
+    private boolean serviceCanMergeResults = false;
+    private boolean viewResultsImmediatly = true;
+  // tabbed or not
     public synchronized int addJobPane() {
       JScrollPane jobpane = new JScrollPane();
       JTextArea progressText = new JTextArea();
@@ -142,6 +144,7 @@ public class WebserviceInfo extends GWebserviceInfo
         thisService = newservice;
         serviceIsCancellable = newservice.isCancellable();
         frame.setClosable(!serviceIsCancellable);
+        serviceCanMergeResults = newservice.canMergeResults();
     }
 
     /**
@@ -359,16 +362,22 @@ public class WebserviceInfo extends GWebserviceInfo
         }
         frame.setClosable(true);
     }
-
+    /**
+     * Set up GUI for user to get at results - and possibly automatically display
+     * them if viewResultsImmediatly is set.
+     */
     public void setResultsReady()
     {
       frame.setClosable(true);
       buttonPanel.remove(cancel);
       buttonPanel.add(showResultsNewFrame);
-      buttonPanel.add(mergeResults);
+      if (serviceCanMergeResults)
+        buttonPanel.add(mergeResults);
       buttonPanel.setLayout(new GridLayout(2,1,5,5));
       buttonPanel.validate();
       validate();
+      if (viewResultsImmediatly)
+        showResultsNewFrame.doClick();
     }
 
   /**
index 2ec8e1e..d7e75f4 100755 (executable)
@@ -27,24 +27,54 @@ import jalview.analysis.*;
 import jalview.bin.*;\r
 import jalview.datamodel.*;\r
 import jalview.datamodel.Alignment;\r
+import jalview.datamodel.AlignmentView;\r
 import jalview.gui.*;\r
 import jalview.io.*;\r
+import jalview.util.*;\r
 import jalview.ws.WSThread.*;\r
 import vamsas.objects.simple.*;\r
-import jalview.util.Comparison;\r
 \r
 public class JPredClient\r
     extends WSClient\r
 {\r
-  public JPredClient(ext.vamsas.ServiceHandle sh, String title, SequenceI seq)\r
+  AlignFrame parentFrame=null;\r
+    /**\r
+     * crate a new GUI JPred Job\r
+     * @param sh ServiceHandle\r
+     * @param title String\r
+     * @param msa boolean - true - submit alignment as a sequence profile\r
+     * @param alview AlignmentView\r
+     */\r
+    public JPredClient(ext.vamsas.ServiceHandle sh, String title, boolean msa, AlignmentView alview, AlignFrame parentFrame) {\r
+    wsInfo=setWebService(sh);\r
+    this.parentFrame=parentFrame;\r
+    startJPredClient(title, msa, alview);\r
+\r
+  }\r
+\r
+  /**\r
+   * startJPredClient\r
+   *\r
+   * @param title String\r
+   * @param msa boolean\r
+   * @param alview AlignmentView\r
+   */\r
+  private void startJPredClient(String title, boolean msa,\r
+                                jalview.datamodel.AlignmentView alview)\r
+  {\r
+  }\r
+\r
+  public JPredClient(ext.vamsas.ServiceHandle sh, String title, SequenceI seq, AlignFrame parentFrame)\r
   {\r
     wsInfo = setWebService(sh);\r
+    this.parentFrame=parentFrame;\r
     startJPredClient(title, seq);\r
   }\r
 \r
-  public JPredClient(ext.vamsas.ServiceHandle sh, String title, SequenceI[] msa)\r
+  public JPredClient(ext.vamsas.ServiceHandle sh, String title, SequenceI[] msa, AlignFrame parentFrame)\r
   {\r
     wsInfo = setWebService(sh);\r
+    this.parentFrame=parentFrame;\r
     startJPredClient(title, msa);\r
   }\r
 \r
@@ -633,7 +663,6 @@ public class JPredClient
         }\r
       }\r
     }\r
-\r
     void pollJob(WSJob job)\r
         throws Exception\r
     {\r
@@ -649,6 +678,11 @@ public class JPredClient
       throw new Error("Implementation error!");\r
     }\r
 \r
+    public boolean canMergeResults()\r
+    {\r
+      return false;\r
+    }\r
+\r
   }\r
 }\r
 \r
index 62f076a..c38f901 100644 (file)
@@ -321,88 +321,27 @@ class MsaWSThread
     OutputHeader = wsInfo.getProgressText();
     alTitle = title;
     dataset = seqset;
-    SeqCigar[] msa = _msa.getSequences();
-    int[] contigs = _msa.getContigs();
-    int njobs = 1;
-    if (contigs != null && contigs.length > 0)
+    SequenceI[][] conmsa = _msa.getVisibleContigs('-');
+    if (conmsa != null)
     {
-      int start = 0;
-      njobs = 0;
-      int width = _msa.getWidth();
-      for (int contig = 0; contig < contigs.length; contig += 3)
-      {
-        if ( (contigs[contig + 1] - start) > 0)
-        {
-          njobs++;
-        }
-        width += contigs[contig + 2]; // end up with full region width (including hidden regions)
-        start = contigs[contig + 1] + contigs[contig + 2];
-      }
-      if (start < width)
-      {
-        njobs++;
-      }
+      int njobs = conmsa.length;
       jobs = new MsaWSJob[njobs];
-      start = 0;
-      int j = 0;
-      for (int contig = 0; contig < contigs.length; contig += 3)
+      for (int j = 0; j < njobs; j++)
       {
-        if (contigs[contig + 1] - start > 0)
-        {
-          SequenceI mseq[] = new SequenceI[msa.length];
-          for (int s = 0; s < mseq.length; s++)
-          {
-            mseq[s] = msa[s].getSeq('-').getSubSequence(start,
-                contigs[contig + 1]);
-          }
-          if (j != 0)
-          {
-            jobs[j] = new MsaWSJob(wsinfo.addJobPane(), mseq);
-          }
-          else
-          {
-            jobs[j] = new MsaWSJob(0, mseq);
-          }
-          wsinfo.setProgressName("region " + jobs[j].jobnum, jobs[j].jobnum);
-          wsinfo.setProgressText(jobs[j].jobnum, OutputHeader);
-          j++;
-        }
-        start = contigs[contig + 1] + contigs[contig + 2];
-      }
-      if (start < width)
-      {
-        SequenceI mseq[] = new SequenceI[msa.length];
-        for (int s = 0; s < mseq.length; s++)
-        {
-          mseq[s] = msa[s].getSeq('-').getSubSequence(start,
-              width + 1);
-        }
         if (j != 0)
         {
-          jobs[j] = new MsaWSJob(wsinfo.addJobPane(), mseq);
+          jobs[j] = new MsaWSJob(wsinfo.addJobPane(), conmsa[j]);
         }
         else
         {
-          jobs[j] = new MsaWSJob(0, mseq);
+          jobs[j] = new MsaWSJob(0, conmsa[j]);
         }
-        wsinfo.setProgressName("region " + jobs[j].jobnum, jobs[j].jobnum);
+        if (njobs > 0)
+          wsinfo.setProgressName("region " + jobs[j].jobnum, jobs[j].jobnum);
         wsinfo.setProgressText(jobs[j].jobnum, OutputHeader);
-        j++;
-      }
-    }
-    else
-    {
-      SequenceI mseq[] = new SequenceI[msa.length];
-      for (int s = 0; s < mseq.length; s++)
-      {
-        mseq[s] = msa[s].getSeq('-');
       }
-      jobs = new MsaWSJob[1];
-      wsinfo.setProgressText(OutputHeader); // ensures default text
-      jobs[0] = new MsaWSJob(0, mseq);
     }
   }
-
   public boolean isCancellable()
   {
     return true;
@@ -629,198 +568,37 @@ class MsaWSThread
   void displayResults(boolean newFrame)
   {
     // view input or result data for each block
-    // warn user if a block is input rather than aligned data ?
-
-    int contigs[] = input.getContigs();
-    SeqCigar[] seqs = input.getSequences();
-    SequenceI[] alignment = new SequenceI[seqs.length];
-    ColumnSelection columnselection = new ColumnSelection();
     Vector alorders = new Vector();
-    if (contigs != null && contigs.length > 0)
-    {
-      int start = 0;
-      int nwidth = 0;
-      int owidth = input.getWidth();
-      int j = 0;
-      for (int contig = 0; contig < contigs.length; contig += 3)
-      {
-        owidth += contigs[contig + 2]; // recover final column width
-        if (contigs[contig + 1] - start > 0)
-        {
-          int width = 0; // subalignment width
-          if (jobs[j].hasResults())
-          {
-            Object[] subalg = ((MsaWSJob) jobs[j++]).getAlignment();
-            alorders.add(subalg[1]);
-            SequenceI mseq[] = (SequenceI[]) subalg[0];
-            width = mseq[0].getLength();
-            for (int s = 0; s < mseq.length; s++)
-            {
-              if (alignment[s] == null)
-              {
-                alignment[s] = mseq[s];
-              }
-              else
-              {
-                alignment[s].setSequence(alignment[s].getSequence() +
-                                         mseq[s].getSequence());
-                if (mseq[s].getStart() <= mseq[s].getEnd())
-                {
-                  alignment[s].setEnd(mseq[s].getEnd());
-                }
-                ( (AlignmentOrder) subalg[1]).updateSequence(mseq[s],
-                    alignment[s]);
-              }
-            }
-          }
-          else
-          {
-            // recover input data or place gaps
-            if (true)
-            {
-              // recover input data
-              for (int s = 0; s < seqs.length; s++)
-              {
-                SequenceI oseq = seqs[s].getSeq('-').getSubSequence(start,
-                    contigs[contig + 1]);
-                if (width < oseq.getLength())
-                {
-                  width = oseq.getLength();
-                }
-                if (alignment[s] == null)
-                {
-                  alignment[s] = oseq;
-                }
-                else
-                {
-                  alignment[s].setSequence(alignment[s].getSequence() +
-                                           oseq.getSequence());
-                  if (oseq.getEnd() >= oseq.getStart())
-                  {
-                    alignment[s].setEnd(oseq.getEnd());
-                  }
-                }
-              }
-
-            }
-            j++;
-          }
-          nwidth += width;
-        }
-        // advance to begining of visible region
-        start = contigs[contig + 1] + contigs[contig + 2];
-        // add hidden segment to right of next region
-        for (int s = 0; s < seqs.length; s++)
-        {
-          SequenceI hseq = seqs[s].getSeq('-').getSubSequence(contigs[contig +
-              1], start);
-          if (alignment[s] == null)
-          {
-            alignment[s] = hseq;
-          }
-          else
-          {
-            alignment[s].setSequence(alignment[s].getSequence() +
-                                     hseq.getSequence());
-            if (hseq.getEnd() >= hseq.getStart())
-            {
-              alignment[s].setEnd(hseq.getEnd());
-            }
-          }
-        }
-        // mark hidden segment as hidden in the new alignment
-        columnselection.hideColumns(nwidth, nwidth + contigs[contig + 2] - 1);
-        nwidth += contigs[contig + 2];
-      }
-      // Do final job - if it exists
-      if (j < jobs.length)
-      {
-        int width = 0;
-        if (jobs[j].hasResults())
-        {
-          Object[] subalg = ((MsaWSJob) jobs[j]).getAlignment();
-          alorders.add(subalg[1]);
-          SequenceI mseq[] = (SequenceI[]) subalg[0];
-          width = mseq[0].getLength();
-          for (int s = 0; s < mseq.length; s++)
-          {
-            if (alignment[s] == null)
-            {
-              alignment[s] = mseq[s];
-            }
-            else
-            {
-              alignment[s].setSequence(alignment[s].getSequence() +
-                                       mseq[s].getSequence());
-              if (mseq[s].getEnd() >= mseq[s].getStart())
-              {
-                alignment[s].setEnd(mseq[s].getEnd());
-              }
-              ( (AlignmentOrder) subalg[1]).updateSequence(mseq[s], alignment[s]);
-            }
-          }
-        }
-        else
-        {
-          if (start < owidth)
-          {
-            // recover input data or place gaps
-            if (true)
-            {
-              // recover input data
-              for (int s = 0; s < seqs.length; s++)
-              {
-                SequenceI oseq = seqs[s].getSeq('-').getSubSequence(start,
-                    owidth + 1);
-                if (width < oseq.getLength())
-                {
-                  width = oseq.getLength();
-                }
-                if (alignment[s] == null)
-                {
-                  alignment[s] = oseq;
-                }
-                else
-                {
-                  alignment[s].setSequence(alignment[s].getSequence() +
-                                           oseq.getSequence());
-                  if (oseq.getEnd() >= oseq.getStart())
-                  {
-                    alignment[s].setEnd(oseq.getEnd());
-                  }
-                }
-              }
-              nwidth += width;
-            }
-            else
-            {
-              // place gaps.
-              throw new Error("Padding not yet implemented.");
-            }
-          }
-        }
+    SequenceI[][] results=new SequenceI[jobs.length][];
+    AlignmentOrder[] orders = new AlignmentOrder[jobs.length];
+    SequenceI[] first=null;
+    for (int j=0; j<jobs.length; j++) {
+      if (jobs[j].hasResults()) {
+        Object[] res = ( (MsaWSJob) jobs[j]).getAlignment();
+        alorders.add(res[1]);
+        results[j] = (SequenceI[]) res[0];
+        orders[j] = (AlignmentOrder) res[1];
+//    SequenceI[] alignment = input.getUpdated
+      } else {
+        results[j]=null;
       }
     }
-    else
-    {
-      if (jobs[0].hasResults())
-      {
-        Object[] alg = ((MsaWSJob) jobs[0]).getAlignment();
-        alignment = (SequenceI[]) alg[0];
-        alorders.add(alg[1]);
-      }
-      else
-      {
-        alignment = SeqCigar.createAlignmentSequences(seqs, '-',
-            columnselection, null);
-      }
+    Object[] newview = input.getUpdatedView(results, orders, '-');
+    // trash references to original result data
+    for (int j=0; j<jobs.length; j++) {
+      results[j] = null;
+      orders[j] = null;
     }
+    SequenceI[] alignment = (SequenceI[]) newview[0];
+    ColumnSelection columnselection = (ColumnSelection) newview[1];
     Alignment al = new Alignment(alignment);
     if (dataset != null)
     {
       al.setDataset(dataset);
     }
 
+    // JBNote- TODO: warn user if a block is input rather than aligned data ?
+
     if (newFrame)
     {
       AlignFrame af = new AlignFrame(al, columnselection);
@@ -829,6 +607,7 @@ class MsaWSThread
       // found!!<<<
       af.getFeatureRenderer().transferSettings(
           alignFrame.getFeatureRenderer());
+      // update orders
       if (alorders.size() > 0)
       {
         if (alorders.size() == 1)
@@ -890,4 +669,9 @@ class MsaWSThread
 
     }
   }
+
+  public boolean canMergeResults()
+  {
+    return false;
+  }
 }
index 97eaa7f..431efe4 100755 (executable)
@@ -20,7 +20,15 @@ package jalview.ws;
 
 public interface WSClientI
 {
-  boolean isCancellable();
-
+    /**
+     *
+     * @return boolean true if job is cancellable
+     */
+    boolean isCancellable();
+    /**
+     *
+     * @return boolean true if results can be merged into the source of input data
+     */
+  boolean canMergeResults();
   void cancelJob();
 }