Merge branch 'mmw/JAL-4199-web-services-testing' into mmw/bug/JAL-4241-annotation...
[jalview.git] / src / jalview / ws2 / actions / hmmer / PhmmerTask.java
index 0565300..ede61d3 100644 (file)
@@ -7,34 +7,36 @@ import java.util.List;
 
 import jalview.analysis.AlignSeq;
 import jalview.bin.Console;
+import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.AlignmentView;
+import jalview.datamodel.Annotation;
 import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+import jalview.util.Comparison;
 import jalview.ws.params.ArgumentI;
-import jalview.ws2.actions.AbstractPollableTask;
 import jalview.ws2.actions.BaseJob;
+import jalview.ws2.actions.BaseTask;
 import jalview.ws2.actions.ServiceInputInvalidException;
-import jalview.ws2.actions.api.TaskEventListener;
 import jalview.ws2.api.Credentials;
 import jalview.ws2.api.JobStatus;
 import jalview.ws2.client.api.AlignmentWebServiceClientI;
 
-class PhmmerTask extends AbstractPollableTask<BaseJob, AlignmentI>
+class PhmmerTask extends BaseTask<BaseJob, AlignmentI>
 {
   private final AlignmentWebServiceClientI client;
   private final AlignmentView view;
 
   PhmmerTask(AlignmentWebServiceClientI client, List<ArgumentI> args,
-          Credentials credentials, AlignmentView view,
-          TaskEventListener<AlignmentI> eventListener)
+          Credentials credentials, AlignmentView view)
   {
-    super(client, args, credentials, eventListener);
+    super(client, args, credentials);
     this.client = client;
     this.view = view;
   }
 
   @Override
-  protected List<BaseJob> prepare() throws ServiceInputInvalidException
+  protected List<BaseJob> prepareJobs() throws ServiceInputInvalidException
   {
     Console.info("Preparing sequence for phmmer job");
     var sequence = view.getVisibleAlignment('-').getSequenceAt(0);
@@ -53,14 +55,57 @@ class PhmmerTask extends AbstractPollableTask<BaseJob, AlignmentI>
   }
 
   @Override
-  protected AlignmentI done() throws IOException
+  protected AlignmentI collectResult(List<BaseJob> jobs) throws IOException
   {
-    var job = getSubJobs().get(0);
-    var jobId = job.getServerJob().getJobId();
+    var job = jobs.get(0);
     var status = job.getStatus();
     Console.info(String.format("phmmer finished job \"%s\" with status %s",
-            jobId, status));
-    return client.getAlignment(job.getServerJob());
+            job.getServerJob().getJobId(), status));
+    if (status != JobStatus.COMPLETED)
+      return null;
+    var outputAlignment = client.getAlignment(job.getServerJob());
+    var querySeq = job.getInputSequences().get(0).deriveSequence();
+    {
+      AlignmentAnnotation refpos = null;
+      for (var annot : outputAlignment.getAlignmentAnnotation())
+      {
+        if (annot.sequenceRef == null && annot.label.equals("Reference Positions"))
+        {
+          refpos = annot;
+          break;
+        }
+      }
+      if (refpos != null)
+      {
+        querySeq = alignQeuryToReferencePositions(querySeq, refpos);
+      }
+    }
+    outputAlignment.insertSequenceAt(0, querySeq);
+    return outputAlignment;
   }
 
+  private SequenceI alignQeuryToReferencePositions(SequenceI query, AlignmentAnnotation refpos)
+  {
+    var sequenceBuilder = new StringBuilder();
+    var index = 0;
+    for (Annotation a : refpos.annotations)
+    {
+      // TODO: we assume that the number of "x" annotations is equal to the number
+      // of residues. may need a safeguard against invalid input
+      if (a != null && a.displayCharacter.equals("x"))
+      {
+        char c;
+        do
+          c = query.getCharAt(index++);
+        while (Comparison.isGap(c));
+        sequenceBuilder.append(c);
+      }
+      else
+      {
+        sequenceBuilder.append(Comparison.GAP_DASH);
+      }
+    }
+    query.setSequence(sequenceBuilder.toString());
+    return query;
+  }
 }