JAL-3954 Add query sequence aligned to consensus to search result
authorMateusz Warowny <mmzwarowny@dundee.ac.uk>
Fri, 2 Jun 2023 10:36:47 +0000 (12:36 +0200)
committerMateusz Warowny <mmzwarowny@dundee.ac.uk>
Fri, 2 Jun 2023 13:16:47 +0000 (15:16 +0200)
src/jalview/ws2/actions/hmmer/PhmmerTask.java
src/jalview/ws2/client/ebi/PhmmerWSClient.java

index 0565300..e077b61 100644 (file)
@@ -3,13 +3,18 @@ package jalview.ws2.actions.hmmer;
 import static jalview.util.Comparison.GapChars;
 
 import java.io.IOException;
+import java.util.Arrays;
 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;
@@ -56,11 +61,51 @@ class PhmmerTask extends AbstractPollableTask<BaseJob, AlignmentI>
   protected AlignmentI done() throws IOException
   {
     var job = getSubJobs().get(0);
-    var jobId = job.getServerJob().getJobId();
-    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(), job.getStatus()));
+    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;
+  }
 }
index 0bcb2f9..9c5f14f 100644 (file)
@@ -1,16 +1,22 @@
 package jalview.ws2.client.ebi;
 
+import java.io.BufferedReader;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.StringReader;
 import java.net.URI;
 import java.util.List;
 
 import jalview.bin.Console;
+import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.SequenceI;
 import jalview.io.DataSourceType;
 import jalview.io.FileFormat;
+import jalview.io.FileParse;
 import jalview.io.FormatAdapter;
+import jalview.io.StockholmFile;
 import jalview.ws.params.ArgumentI;
 import jalview.ws.params.simple.BooleanOption;
 import jalview.ws.params.simple.DoubleParameter;
@@ -243,6 +249,15 @@ public class PhmmerWSClient implements AlignmentWebServiceClientI
   public AlignmentI getAlignment(WebServiceJobHandle job) throws IOException
   {
     URI url = client.getResultURL(job.getJobId(), "sto");
-    return new FormatAdapter().readFile(url.toString(), DataSourceType.URL, FileFormat.Stockholm);
+    try(InputStream stream = client.getResultStream(job.getJobId(), "sto"))
+    {
+      StockholmFile file = new StockholmFile(new FileParse(
+              new BufferedReader(new InputStreamReader(stream)),
+              url.toString(), DataSourceType.URL));
+      var aln = new Alignment(file.getSeqsAsArray());
+      for (var annotation : file.getAnnotations())
+        aln.addAnnotation(annotation);
+      return aln;
+    }
   }
 }