JAL-3807 - Re-implement results processing.
authorMateusz Warowny <mmzwarowny@dundee.ac.uk>
Thu, 11 Feb 2021 16:15:25 +0000 (17:15 +0100)
committerMateusz Warowny <mmzwarowny@dundee.ac.uk>
Mon, 22 Feb 2021 17:53:53 +0000 (18:53 +0100)
src/jalview/ws/JPredThread.java
src/jalview/ws/api/JPredMutlipleAlignmentServiceI.java
src/jalview/ws/slivkaws/SlivkaJPredServiceInstance.java

index ed6d4af..215ae4d 100644 (file)
@@ -5,8 +5,10 @@ import static java.lang.String.format;
 import java.util.Hashtable;
 import java.util.List;
 
+import jalview.analysis.SeqsetUtils;
 import jalview.bin.Cache;
 import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.AlignmentView;
 import jalview.datamodel.HiddenColumns;
@@ -14,6 +16,8 @@ import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
 import jalview.gui.Desktop;
 import jalview.gui.WebserviceInfo;
+import jalview.io.JPredFile;
+import jalview.io.JnetAnnotationMaker;
 import jalview.util.MessageManager;
 import jalview.ws.api.CancellableI;
 import jalview.ws.api.JPredMutlipleAlignmentServiceI;
@@ -26,32 +30,39 @@ class JPredJob extends WsJob
   Hashtable<?, ?> sequenceInfo;
   List<SequenceI> msf;
   int[] delMap;
-  public AlignmentI alignment;
-  
+  AlignmentI alignment = null;
+  HiddenColumns hiddenCols = null;
+
   public JPredJob(Hashtable<?, ?> sequenceInfo, SequenceI[] msf, int[] delMap)
   {
     this.sequenceInfo = sequenceInfo;
     this.msf = List.of(msf);
     this.delMap = delMap;
   }
-  
+
   @Override
   public boolean hasValidInput()
   {
     return true;
   }
+
+  @Override
+  public boolean hasResults()
+  {
+    return (isSubjobComplete() && alignment != null);
+  }
 }
 
 
 public class JPredThread extends AWSThread implements WSClientI
 {
-  
+
   private JPredMutlipleAlignmentServiceI server;
   private String title;
   private Hashtable<?, ?> sequenceInfo;
   private SequenceI[] msf;
-  private int[] delMap;  
-  
+  private int[] delMap;
+
   public JPredThread(WebserviceInfo wsInfo, String title,
       JPredMutlipleAlignmentServiceI server, Hashtable<?, ?> sequenceInfo,
       SequenceI[] msf, int[] delMap, AlignmentView view, AlignFrame frame,
@@ -83,7 +94,7 @@ public class JPredThread extends AWSThread implements WSClientI
   public void cancelJob()
   {
     // TODO Auto-generated method stub
-    
+
   }
 
   @Override
@@ -110,7 +121,7 @@ public class JPredThread extends AWSThread implements WSClientI
         var jobHandle = server.align(job.msf);
         if (jobHandle != null)
           job.setJobHandle(jobHandle);
-      } 
+      }
       catch (Throwable th) {
         if (!server.handleSubmitError(th, job, wsInfo)) {
           throw th;
@@ -138,7 +149,7 @@ public class JPredThread extends AWSThread implements WSClientI
       wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR);
       wsInfo.setStatus(job.getJobnum(),
               WebserviceInfo.STATE_STOPPED_SERVERERROR);
-      
+
     }
     finally
     {
@@ -178,7 +189,7 @@ public class JPredThread extends AWSThread implements WSClientI
           Cache.log.debug(format("Job Execution file for job: %s " +
               "on server %s%n%s", job.getJobId(), WsUrl, job.getStatus()));
           try {
-            job.alignment = server.getResult(job.getJobHandle());
+            prepareJobResult(job);
           }
           catch (Exception e) {
             if (!server.handleCollectionException(e, job, wsInfo)) {
@@ -206,17 +217,107 @@ public class JPredThread extends AWSThread implements WSClientI
       wsInfo.setResultsReady();
     }
     else {
+      wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);
+      wsInfo.appendInfoText("No jobs ran.");
       wsInfo.setFinishedNoResults();
     }
     updateGlobalStatus(finalState);
     wsInfo.removeProgressBar(progbar);
   }
 
-  
+  private void prepareJobResult(JPredJob job) throws Exception
+  {
+    HiddenColumns hiddenCols = null;
+    int firstSeq = -1;
+    AlignmentI alignment;
+    var prediction = server.getPrediction(job.getJobHandle());
+    var preds = prediction.getSeqsAsArray();
+
+    if (job.delMap != null)
+    {
+      Object[] alandcolsel = input
+              .getAlignmentAndHiddenColumns(getGapChar());
+      alignment = new Alignment((SequenceI[]) alandcolsel[0]);
+      hiddenCols = (HiddenColumns) alandcolsel[1];
+    }
+    else
+    {
+      alignment = server.getAlignment(job.getJobHandle());
+      var seqs = new SequenceI[alignment.getHeight()];
+      for (int i = 0; i < alignment.getHeight(); i++)
+      {
+        seqs[i] = alignment.getSequenceAt(i);
+      }
+      if (!SeqsetUtils.deuniquify(sequenceInfo, seqs))
+      {
+        throw (new Exception(MessageManager.getString(
+                "exception.couldnt_recover_sequence_properties_for_alignment")));
+      }
+    }
+    firstSeq = 0;
+    if (currentView.getDataset() != null)
+    {
+      alignment.setDataset(currentView.getDataset());
+    }
+    else
+    {
+      alignment.setDataset(null);
+    }
+    JnetAnnotationMaker.add_annotation(prediction, alignment, firstSeq, false,
+            job.delMap);
+
+    for (var annot : alignment.getAlignmentAnnotation())
+    {
+      if (annot.sequenceRef != null)
+      {
+        replaceAnnotationOnAlignmentWith(annot, annot.label,
+                "jalview.ws.JPred", annot.sequenceRef);
+      }
+    }
+    job.alignment = alignment;
+    job.hiddenCols = hiddenCols;
+  }
+
+  private static void replaceAnnotationOnAlignmentWith(
+          AlignmentAnnotation newAnnot, String typeName, String calcId,
+          SequenceI aSeq)
+  {
+    SequenceI dsseq = aSeq.getDatasetSequence();
+    while (dsseq.getDatasetSequence() != null)
+    {
+      dsseq = dsseq.getDatasetSequence();
+    }
+    // look for same annotation on dataset and lift this one over
+    List<AlignmentAnnotation> dsan = dsseq.getAlignmentAnnotations(calcId,
+            typeName);
+    if (dsan != null && dsan.size() > 0)
+    {
+      for (AlignmentAnnotation dssan : dsan)
+      {
+        dsseq.removeAlignmentAnnotation(dssan);
+      }
+    }
+    AlignmentAnnotation dssan = new AlignmentAnnotation(newAnnot);
+    dsseq.addAlignmentAnnotation(dssan);
+    dssan.adjustForAlignment();
+  }
 
   private void displayResults(boolean newWindow)
   {
-    System.out.println("DISPLAYING THE RESULT");
+    if (jobs == null || jobs.length == 0)
+    {
+      return;
+    }
+    var job = (JPredJob) jobs[0];
+    if (job.hasResults() && newWindow)
+    {
+      AlignFrame frame;
+      job.alignment.setSeqrep(job.alignment.getSequenceAt(0));
+      frame = new AlignFrame(job.alignment, job.hiddenCols,
+              AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
+      Desktop.addInternalFrame(frame, title, AlignFrame.DEFAULT_WIDTH,
+              AlignFrame.DEFAULT_HEIGHT);
+    }
   }
-  
+
 }
index 261f1f8..f897140 100644 (file)
@@ -4,10 +4,13 @@ import java.util.List;
 
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.SequenceI;
+import jalview.io.JPredFile;
 
 public interface JPredMutlipleAlignmentServiceI extends JalviewWebServiceI
 {
   public JobId align(List<SequenceI> sequences) throws Throwable;
-  
-  public AlignmentI getResult(JobId jobId) throws Exception;
+
+  public AlignmentI getAlignment(JobId jobId) throws Exception;
+
+  public JPredFile getPrediction(JobId jobId) throws Exception;
 }
index a614f02..b8e4d2f 100644 (file)
@@ -6,6 +6,8 @@ import java.util.List;
 
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.SequenceI;
+import jalview.io.DataSourceType;
+import jalview.io.JPredFile;
 import jalview.ws.api.JPredMutlipleAlignmentServiceI;
 import jalview.ws.api.JobId;
 import uk.ac.dundee.compbio.slivkaclient.RemoteFile;
@@ -30,18 +32,36 @@ public class SlivkaJPredServiceInstance extends SlivkaWSInstance
   }
 
   @Override
-  public AlignmentI getResult(JobId jobId) throws Exception
+  public AlignmentI getAlignment(JobId jobId) throws Exception
   {
     List<RemoteFile> files;
     try {
       files = client.getJobResults(jobId.getJobId());
       for (RemoteFile f : files) {
-        return readAlignment(f);
+        var alignment = readAlignment(f);
+        if (alignment != null)
+        {
+          return alignment;
+        }
       }
     }
     catch (IOException e) {
       throw new IOError(e);
     }
-    return null;  
+    return null;
+  }
+
+  @Override
+  public JPredFile getPrediction(JobId jobId) throws Exception
+  {
+    List<RemoteFile> files = client.getJobResults(jobId.getJobId());
+    for (RemoteFile f : files)
+    {
+      if (f.getLabel().equals("concise"))
+      {
+        return new JPredFile(f.getURL(), DataSourceType.URL);
+      }
+    }
+    return null;
   }
 }