JAL-1950 represent duplicate sequences by their representative in the hit alignment
authorJim Procter <jprocter@issues.jalview.org>
Tue, 17 Nov 2015 16:33:18 +0000 (16:33 +0000)
committerJim Procter <jprocter@issues.jalview.org>
Tue, 17 Nov 2015 16:33:18 +0000 (16:33 +0000)
src/jalview/ws/ebi/HmmerJSONProcessor.java
test/jalview/ws/ebi/HmmerJSONProcessTest.java

index d0f3c18..a6b15cf 100644 (file)
@@ -7,9 +7,12 @@ import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.io.FileParse;
+import jalview.viewmodel.AlignmentViewport;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import org.json.simple.JSONArray;
@@ -18,8 +21,16 @@ import org.json.simple.parser.JSONParser;
 
 public class HmmerJSONProcessor
 {
+  /**
+   * result to be annotated. may not be null
+   */
   AlignmentI resultAl;
 
+  /**
+   * viewport on the alignment. may be null at construction time
+   */
+  AlignmentViewport viewAl = null;
+
   public HmmerJSONProcessor(AlignmentI searchResult)
   {
     resultAl = searchResult;
@@ -143,11 +154,16 @@ public class HmmerJSONProcessor
               .get("alimodel"), ppline = (String) dhit.get("alippline");
       //
       int found = 0;
+      SequenceI firsthit = null;
       for (SequenceI hitseq : hits)
       {
         // match alisqfrom,alisqto,seq
         if (hitseq.getStart() == alisqfrom && hitseq.getEnd() == alisqto)
         {
+          if (found == 0)
+          {
+            firsthit = hitseq;
+          }
           found++; // annotated a sequence
           AlignmentAnnotation alipp = parsePosteriorProb(ppline);
           AlignmentAnnotation pval = new AlignmentAnnotation("p-value",
@@ -176,17 +192,79 @@ public class HmmerJSONProcessor
           alipp.validateRangeAndDisplay();
         }
       }
-      if (found == 0)
+      // look for other sequences represented by this hit and create rep groups
+      // could be in "pdbs", or ..
+      addRedundantSeqGroup(firsthit, alisqfrom, alisqto,
+              (JSONArray) hmmrhit.get("seqs"));
+    }
+  }
+
+  /**
+   * series of operations to perform for the viewpanel associated with the
+   * alignment
+   */
+  private List<Runnable> viewOps = new ArrayList<Runnable>();
+
+  public void updateView(AlignmentViewport view)
+  {
+    viewAl = view;
+    for (Runnable op : viewOps)
+    {
+      op.run();
+    }
+  }
+
+  private void addRedundantSeqGroup(final SequenceI firsthit,
+          long alisqfrom,
+          long alisqto, JSONArray others)
+  {
+    if (others != null)
+    {
+      final SequenceGroup repgroup = new SequenceGroup();
+      repgroup.setSeqrep(firsthit);
+      repgroup.addOrRemove(firsthit, false);
+      repgroup.setStartRes(0);
+      repgroup.setEndRes(resultAl.getWidth() - 1);
+      for (Object otherseq : others.toArray(new JSONObject[0]))
       {
-        System.err.println("Warn - no match for json hit " + sname + "/"
-                + alisqfrom + "-" + alisqto);
+        String repseq = (String) ((JSONObject) otherseq).get("dn");
+        SequenceI[] other = resultAl.findSequenceMatch(repseq);
+        if (other != null && other.length > 0)
+        {
+          int ofound = 0;
+          for (SequenceI oth : other)
+          {
+            if (oth.getStart() == alisqfrom && oth.getEnd() == alisqto)
+            {
+              ofound++;
+              repgroup.addSequence(oth, false);
+            }
+          }
+          if (ofound == 0)
+          {
+            System.err.println("Warn - no match for redundant hit "
+                    + repseq + "/" + alisqfrom + "-" + alisqto);
+          }
+          if (ofound > 1)
+          {
+            System.err.println("Warn - multiple matches for redundant hit "
+                    + repseq + "/" + alisqfrom + "-" + alisqto);
+          }
+        }
       }
-      if (found > 1)
+      if (repgroup.getSequences().size() > 1)
       {
-        System.err.println("Warn - multiple matches for json hit " + sname
-                + "/" + alisqfrom + "-" + alisqto);
+        // queue a hide operation
+        final HmmerJSONProcessor me = this;
+        viewOps.add(new Runnable()
+        {
+          @Override
+          public void run()
+          {
+            me.viewAl.hideRepSequences(firsthit, repgroup);
+          }
+        });
       }
-      // look for other sequences represented by this hit and create
     }
   }
 
index 291a5a3..efd33f0 100644 (file)
@@ -112,7 +112,9 @@ public class HmmerJSONProcessTest {
   }
   // Groovy test
   // def al = Jalview.getAlignFrames()[0].getViewport().getAlignment()
-  // new jalview.ws.ebi.HmmerJSONProcessor(al).parseFrom(new
+  // def jproc = new jalview.ws.ebi.HmmerJSONProcessor(al)
+  // jproc.parseFrom(new
   // jalview.io.FileParse("examples/testdata/hmmer3/hmmeresult.json.gz","File"))
+  // jproc.updateView(Jalview.getAlignFrames()[0].getViewport())
 
 }