JAL-629 Allow attachment of pAE file to a particular sequence
authorBen Soares <b.soares@dundee.ac.uk>
Thu, 8 Dec 2022 14:19:23 +0000 (14:19 +0000)
committerBen Soares <b.soares@dundee.ac.uk>
Thu, 8 Dec 2022 14:19:23 +0000 (14:19 +0000)
src/jalview/bin/ArgParser.java
src/jalview/bin/Commands.java
src/jalview/ws/dbsources/EBIAlfaFold.java

index bcd4498..0f9ac2e 100644 (file)
@@ -104,7 +104,7 @@ public class ArgParser
       TEMPFAC_DESC.setOptions(Opt.STRING, Opt.LINKED);
       TEMPFAC_SHADING.setOptions(Opt.STRING, Opt.LINKED);
       TITLE.setOptions(Opt.STRING, Opt.LINKED);
-      PAEMATRIX.setOptions(Opt.STRING, Opt.LINKED);
+      PAEMATRIX.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI);
       WRAP.setOptions(Opt.BOOLEAN, Opt.LINKED);
     }
 
index 4ff82aa..f01b2b3 100644 (file)
@@ -11,10 +11,12 @@ import java.util.Locale;
 import java.util.Map;
 
 import jalview.analysis.AlignmentUtils;
+import jalview.api.AlignmentViewPanel;
 import jalview.bin.ArgParser.Arg;
 import jalview.bin.ArgParser.ArgValues;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.gui.AlignFrame;
+import jalview.gui.AlignViewport;
 import jalview.gui.Desktop;
 import jalview.io.AppletFormatAdapter;
 import jalview.io.DataSourceType;
@@ -221,9 +223,6 @@ public class Commands
                       .getFirstSequenceAnnotationOfType(
                               af.getCurrentView().getAlignment(),
                               AlignmentAnnotation.LINE_GRAPH);
-              Console.debug("***** Trying to change label from '"
-                      + (aa == null ? aa : aa.label) + "' to '"
-                      + m.get(Arg.TEMPFAC_LABEL).getValue() + "'");
               if (aa != null)
               {
                 aa.label = m.get(Arg.TEMPFAC_LABEL).getValue();
@@ -231,16 +230,6 @@ public class Commands
             }
           }
 
-          //
-
-          // load a pAE file?
-          if (m.get(Arg.PAEMATRIX) != null)
-          {
-            File paeFile = new File(m.get(Arg.PAEMATRIX).getValue());
-            EBIAlfaFold.addAlphaFoldPAE(af.getCurrentView().getAlignment(),
-                    paeFile);
-          }
-
           // store the AlignFrame for this id
           afMap.put(id, af);
         }
@@ -271,6 +260,97 @@ public class Commands
       }
 
     }
+
+    // load a pAE file if given
+    if (m.get(Arg.PAEMATRIX) != null)
+    {
+      AlignFrame af = afMap.get(id);
+      if (af != null)
+      {
+        for (String val : m.get(Arg.PAEMATRIX).getValues())
+        {
+          SubId subId = new SubId(val);
+          File paeFile = new File(subId.content);
+          EBIAlfaFold.addAlphaFoldPAE(af.getCurrentView().getAlignment(),
+                  paeFile, subId.index,
+                  "id".equals(subId.keyName) ? subId.keyValue : null);
+          // required to readjust the height and position of the pAE
+          // annotation
+          for (AlignmentViewPanel ap : af.getAlignPanels())
+          {
+            ap.adjustAnnotationHeight();
+          }
+        }
+      }
+    }
   }
 
+  /**
+   * A helper class to parse a string of the possible forms "content"
+   * "[index]content", "[keyName=keyValue]content" and return the integer index,
+   * the strings keyName and keyValue, and the content after the square brackets
+   * (if present). Values not set will be -1 or null.
+   */
+  protected class SubId
+  {
+    protected int index = 0;
+
+    protected String keyName = null;
+
+    protected String keyValue = null;
+
+    protected String content = null;
+
+    protected SubId(String item)
+    {
+      if (item.indexOf('[') == 0 && item.indexOf(']') > 1)
+      {
+        int openBracket = item.indexOf('[');
+        int closeBracket = item.indexOf(']');
+        String indexString = item.substring(openBracket + 1, closeBracket);
+        this.content = item.substring(closeBracket + 1);
+        int equals = indexString.indexOf('=');
+        if (equals > -1)
+        {
+          this.keyName = indexString.substring(0, equals);
+          this.keyValue = indexString.substring(equals + 1);
+          this.index = -1;
+        }
+        else
+        {
+          try
+          {
+            this.index = Integer.parseInt(indexString);
+          } catch (NumberFormatException e)
+          {
+            Console.warn("Failed to obtain sequenced id or index from '"
+                    + item + "'. Setting index=0 and using content='"
+                    + content + "'.");
+          }
+        }
+      }
+      else
+      {
+        this.content = item;
+      }
+    }
+  }
+
+  private void testMethod()
+  {
+    Desktop Jalview = Desktop.instance;
+    jalview.bin.Cache.setProperty("SVG_RENDERING", "Text");
+    for (AlignFrame af : Jalview.getAlignFrames())
+    {
+      String title = af.getTitle();
+      System.out.println("Title: " + af.getTitle());
+      AlignViewport view = af.getCurrentView();
+      view.setShowText(false);
+      view.setShowAnnotation(false);
+      af.deselectAllSequenceMenuItem_actionPerformed(null);
+      af.repaint();
+      af.createPNG(new File(title + ".png"));
+      af.createSVG(new File(title + ".svg"));
+    }
+  }
 }
index 5314207..5575cb8 100644 (file)
@@ -249,10 +249,11 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy
     Console.debug("Downloading pae from " + paeURL + " to " + pae.toString()
             + "");
     UrlDownloadClient.download(paeURL, pae);
-    addAlphaFoldPAE(pdbAlignment, pae);
+    addAlphaFoldPAE(pdbAlignment, pae, 0, null);
   }
 
-  public static void addAlphaFoldPAE(AlignmentI pdbAlignment, File pae)
+  public static void addAlphaFoldPAE(AlignmentI pdbAlignment, File pae,
+          int index, String seqId)
   {
     FileInputStream pae_input = null;
     try
@@ -266,7 +267,8 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy
 
     try
     {
-      if (!importPaeJSONAsContactMatrix(pdbAlignment, pae_input))
+      if (!importPaeJSONAsContactMatrix(pdbAlignment, pae_input, index,
+              seqId))
       {
         Console.warn("Could not import contact matrix from '"
                 + pae.getAbsolutePath() + "'");
@@ -299,18 +301,61 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy
           AlignmentI pdbAlignment, InputStream pae_input)
           throws IOException, ParseException
   {
+    return importPaeJSONAsContactMatrix(pdbAlignment, pae_input, 0, null);
+  }
+
+  public static boolean importPaeJSONAsContactMatrix(
+          AlignmentI pdbAlignment, InputStream pae_input, int index,
+          String seqId) throws IOException, ParseException
+  {
 
     List<Object> pae_obj = (List<Object>) Platform.parseJSON(pae_input);
     if (pae_obj == null)
     {
+      Console.debug("JSON file did not parse properly.");
       return false;
     }
-    ContactMatrixI matrix = new PAEContactMatrix(
-            pdbAlignment.getSequenceAt(0),
+    SequenceI sequence = null;
+    /* debugging */
+    SequenceI[] seqs = pdbAlignment.getSequencesArray();
+    if (seqs == null)
+      Console.debug("******* sequences is null");
+    else
+    {
+      for (int i = 0; i < seqs.length; i++)
+      {
+        SequenceI s = seqs[i];
+        Console.debug("******* sequences[" + i + "]='" + s.getName() + "'");
+      }
+    }
+    /* end debug */
+    if (seqId == null)
+    {
+      int seqToGet = index > 0 ? index : 0;
+      sequence = pdbAlignment.getSequenceAt(seqToGet);
+      Console.debug("***** Got sequence at index " + seqToGet + ": "
+              + (sequence == null ? null : sequence.getName()));
+    }
+    else
+    {
+      Console.debug("***** Looking for sequence with id '" + seqId + "'");
+
+      SequenceI[] sequences = pdbAlignment.findSequenceMatch(seqId);
+      if (sequences == null || sequences.length < 1)
+      {
+        Console.warn("Could not find sequence with id '" + seqId
+                + "' to attach pAE matrix to. Ignoring matrix.");
+        return false;
+      }
+      else
+      {
+        sequence = sequences[0]; // just use the first sequence with this seqId
+      }
+    }
+    ContactMatrixI matrix = new PAEContactMatrix(sequence,
             (Map<String, Object>) pae_obj.get(0));
 
-    AlignmentAnnotation cmannot = pdbAlignment.getSequenceAt(0)
-            .addContactList(matrix);
+    AlignmentAnnotation cmannot = sequence.addContactList(matrix);
     pdbAlignment.addAnnotation(cmannot);
     return true;
   }