JAL-629 Some refactoring to allow more flexible use of PAE files. Not working as...
authorBen Soares <b.soares@dundee.ac.uk>
Thu, 2 Mar 2023 13:31:03 +0000 (13:31 +0000)
committerBen Soares <b.soares@dundee.ac.uk>
Thu, 2 Mar 2023 13:31:03 +0000 (13:31 +0000)
src/jalview/bin/Commands.java
src/jalview/datamodel/PDBEntry.java
src/jalview/ext/jmol/JmolParser.java
src/jalview/gui/AssociatePdbFileWithSeq.java
src/jalview/gui/PymolViewer.java
src/jalview/gui/StructureChooser.java
src/jalview/io/StructureFile.java
src/jalview/structure/StructureSelectionManager.java
src/jalview/ws/dbsources/EBIAlfaFold.java
test/jalview/structure/Mapping.java
test/jalview/structure/StructureSelectionManagerTest.java

index af8bf65..a98069a 100644 (file)
@@ -335,7 +335,7 @@ public class Commands
                     .getStructureSelectionManager(Desktop.instance);
             SequenceI seq = af.alignPanel.getAlignment().getSequenceAt(0);
             ssm.computeMapping(false, new SequenceI[] { seq }, null,
-                    openFile, DataSourceType.FILE, null);
+                    openFile, DataSourceType.FILE, null, null, null);
           }
         }
         else
@@ -479,25 +479,24 @@ public class Commands
           {
             Console.info("***** Attaching paeFile '" + paePath + "' to "
                     + "structfile=" + subVals.get("structfile"));
-            EBIAlfaFold.addAlphaFoldPAEToStructure(
-                    af.getCurrentView().getAlignment(), paeFile,
-                    subVals.getIndex(), subVals.get("structfile"), false);
+            EBIAlfaFold.addAlphaFoldPAE(af.getCurrentView().getAlignment(),
+                    paeFile, subVals.getIndex(), subVals.get("structfile"),
+                    true, false);
           }
           else if (subVals.has("structid"))
           {
             Console.info("***** Attaching paeFile '" + paePath + "' to "
                     + "structid=" + subVals.get("structid"));
-            EBIAlfaFold.addAlphaFoldPAEToStructure(
-                    af.getCurrentView().getAlignment(), paeFile,
-                    subVals.getIndex(), subVals.get("structid"), true);
+            EBIAlfaFold.addAlphaFoldPAE(af.getCurrentView().getAlignment(),
+                    paeFile, subVals.getIndex(), subVals.get("structid"),
+                    true, true);
           }
           else
           {
             Console.debug("***** Attaching paeFile '" + paePath
                     + "' to sequence index " + subVals.getIndex());
-            EBIAlfaFold.addAlphaFoldPAEToSequence(
-                    af.getCurrentView().getAlignment(), paeFile,
-                    subVals.getIndex(), null);
+            EBIAlfaFold.addAlphaFoldPAE(af.getCurrentView().getAlignment(),
+                    paeFile, subVals.getIndex(), null, false, false);
             // required to readjust the height and position of the pAE
             // annotation
           }
index 65ba18b..ae8523d 100755 (executable)
  */
 package jalview.datamodel;
 
-import jalview.util.CaseInsensitiveString;
-
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.Hashtable;
 
+import jalview.io.StructureFile;
+import jalview.util.CaseInsensitiveString;
+
 public class PDBEntry
 {
 
@@ -56,6 +57,8 @@ public class PDBEntry
 
   private String id;
 
+  private StructureFile sf = null;
+
   public enum Type
   {
     // TODO is FILE needed; if not is this enum needed, or can we
@@ -626,4 +629,19 @@ public class PDBEntry
   {
     return _hasProperty(PROVIDER);
   }
+
+  public StructureFile getStructureFile()
+  {
+    return sf;
+  }
+
+  public void setStructureFile(StructureFile f)
+  {
+    sf = f;
+  }
+
+  public boolean hasStructureFile()
+  {
+    return sf != null && sf.inFile != null && sf.inFile.exists();
+  }
 }
index 2bc4869..969d195 100644 (file)
@@ -20,6 +20,7 @@
  */
 package jalview.ext.jmol;
 
+import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -67,8 +68,6 @@ public class JmolParser extends StructureFile implements JmolStatusListener
 {
   Viewer viewer = null;
 
-  private boolean alphaFoldModel;
-
   public JmolParser(boolean immediate, Object inFile,
           DataSourceType sourceType) throws IOException
   {
@@ -231,8 +230,9 @@ public class JmolParser extends StructureFile implements JmolStatusListener
       {
         setId(pdbId);
         setPDBIdAvailable(true);
-        alphaFoldModel = alphaFold.search(pdbId) && isMMCIF;
-
+        Console.debug("##### DATASOURCETYPE=" + getDataSourceType());
+        setAlphafoldModel(alphaFold.search(pdbId) && isMMCIF
+                && getDataSourceType() == DataSourceType.URL);
       }
       List<Atom> significantAtoms = convertSignificantAtoms(ms);
       for (Atom tmpatom : significantAtoms)
@@ -250,9 +250,8 @@ public class JmolParser extends StructureFile implements JmolStatusListener
         else
         {
           AnnotationRowBuilder builder = null;
-          String tempFString = null;
-          if (isAlphafoldModel() || StructureImportSettings.TFType.PLDDT
-                  .equals(getTemperatureFactorType()))
+          if (isAlphafoldModel()
+                  || getTemperatureFactorType() == StructureImportSettings.TFType.PLDDT)
           {
             builder = new AlphaFoldAnnotationRowBuilder();
           }
@@ -290,28 +289,49 @@ public class JmolParser extends StructureFile implements JmolStatusListener
           createAnnotation(chainseq, chain, ms.at);
         }
       }
-      if (isAlphafoldModel())
+      // if Alphafold, fetch the PAE matrix if doesn't already have one
+      if (isAlphafoldModel() && !hasPAEMatrix())
       {
-        // TODO - work out how to handle different ways that pAE is provided
-        //
         try
         {
           Console.info("retrieving pAE for " + pdbId);
-          Alignment al = new Alignment(prot.toArray(new SequenceI[0]));
-          EBIAlfaFold.retrieve_AlphaFold_pAE(pdbId, al, null);
-          if (al.getAlignmentAnnotation() != null)
-          {
-            for (AlignmentAnnotation alann : al.getAlignmentAnnotation())
-            {
-              annotations.add(alann);
-            }
-          }
-          ;
+          File paeFile = EBIAlfaFold.fetchAlphaFoldPAE(pdbId, null);
+          this.setPAEMatrix(paeFile.getAbsolutePath());
         } catch (Throwable t)
         {
           Console.error("Couldn't get the pAE for " + pdbId, t);
         }
       }
+      // add a PAEMatrix if set (either by above or otherwise)
+      Console.debug("##### hasPAEMatrix()=" + hasPAEMatrix());
+      Console.debug("##### isAlphafoldModel()=" + isAlphafoldModel());
+      Console.debug("##### getPAEMatrix()=" + getPAEMatrix());
+      if (hasPAEMatrix())
+      {
+        Alignment al = new Alignment(prot.toArray(new SequenceI[0]));
+        if (isAlphafoldModel())
+        {
+          EBIAlfaFold.addAlphaFoldPAE(al, new File(this.getPAEMatrix()), 0,
+                  null, false, false);
+        }
+        else
+        {
+          EBIAlfaFold.addPAEToStructure(null, this.getInFile(),
+                  new File(this.getPAEMatrix()));
+        }
+
+        Console.debug("##### al.getAlignmentAnnotation()="
+                + al.getAlignmentAnnotation());
+        if (al.getAlignmentAnnotation() != null)
+        {
+          for (AlignmentAnnotation alann : al.getAlignmentAnnotation())
+          {
+            Console.debug("##### Adding to alann" + alann.annotationId + "("
+                    + alann.getCalcId() + ")");
+            annotations.add(alann);
+          }
+        }
+      }
     } catch (OutOfMemoryError er)
     {
       System.out.println(
@@ -321,16 +341,6 @@ public class JmolParser extends StructureFile implements JmolStatusListener
     }
   }
 
-  public void setAlphafoldModel(boolean afm)
-  {
-    alphaFoldModel = afm;
-  }
-
-  private boolean isAlphafoldModel()
-  {
-    return alphaFoldModel;
-  }
-
   private List<Atom> convertSignificantAtoms(ModelSet ms)
   {
     List<Atom> significantAtoms = new ArrayList<Atom>();
index fe0aedf..fd89c50 100644 (file)
@@ -25,11 +25,10 @@ import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
 import jalview.io.DataSourceType;
 import jalview.io.StructureFile;
+import jalview.structure.StructureImportSettings.TFType;
 import jalview.structure.StructureSelectionManager;
 import jalview.util.MessageManager;
 
-import javax.swing.JOptionPane;
-
 /**
  * GUI related routines for associating PDB files with sequences
  * 
@@ -49,11 +48,20 @@ public class AssociatePdbFileWithSeq
           SequenceI sequence, boolean prompt,
           StructureSelectionManagerProvider ssmp)
   {
+    return associatePdbWithSeq(choice, file, sequence, prompt, ssmp,
+            TFType.DEFAULT, null);
+  }
+
+  public PDBEntry associatePdbWithSeq(String choice, DataSourceType file,
+          SequenceI sequence, boolean prompt,
+          StructureSelectionManagerProvider ssmp, TFType tft,
+          String paeFilename)
+  {
     PDBEntry entry = new PDBEntry();
-    StructureFile pdbfile = null;
-    pdbfile = StructureSelectionManager.getStructureSelectionManager(ssmp)
+    StructureFile pdbfile = StructureSelectionManager
+            .getStructureSelectionManager(ssmp)
             .setMapping(false, new SequenceI[]
-            { sequence }, null, choice, file);
+            { sequence }, null, choice, file, tft, paeFilename);
     if (pdbfile == null)
     {
       // stacktrace already thrown so just return
@@ -90,6 +98,7 @@ public class AssociatePdbFileWithSeq
       sequence.getDatasetSequence().addPDBId(entry);
       StructureSelectionManager.getStructureSelectionManager(ssmp)
               .registerPDBEntry(entry);
+      entry.setStructureFile(pdbfile);
     }
     return entry;
   }
index 9dc28c8..5069d93 100644 (file)
@@ -270,9 +270,18 @@ public class PymolViewer extends StructureViewerBase
               stopProgressBar("", startTime);
             }
 
-            StructureFile pdb = binding.getSsm().setMapping(
-                    binding.getSequence()[pos], binding.getChains()[pos],
-                    pe.getFile(), protocol, getProgressIndicator());
+            StructureFile pdb = null;
+            if (pe.hasStructureFile())
+            {
+              pdb = pe.getStructureFile();
+              Console.debug("##### (Re)Using StructureFile " + pdb.getId());
+            }
+            else
+            {
+              pdb = binding.getSsm().setMapping(binding.getSequence()[pos],
+                      binding.getChains()[pos], pe.getFile(), protocol,
+                      getProgressIndicator());
+            }
             binding.stashFoundChains(pdb, pe.getFile());
           } catch (Exception ex)
           {
index 0823652..e2eaabd 100644 (file)
@@ -25,7 +25,6 @@ import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.ItemEvent;
 import java.io.File;
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
@@ -44,15 +43,15 @@ import javax.swing.JTable;
 import javax.swing.SwingUtilities;
 import javax.swing.table.AbstractTableModel;
 
-import org.json.simple.parser.ParseException;
+import com.stevesoft.pat.Regex;
 
 import jalview.api.structures.JalviewStructureDisplayI;
 import jalview.bin.Cache;
 import jalview.bin.Console;
 import jalview.bin.Jalview;
-import jalview.datamodel.AlignmentI;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
+import jalview.ext.jmol.JmolParser;
 import jalview.fts.api.FTSData;
 import jalview.fts.api.FTSDataColumnI;
 import jalview.fts.api.FTSRestClientI;
@@ -67,7 +66,6 @@ import jalview.gui.structurechooser.ThreeDBStructureChooserQuerySource;
 import jalview.io.DataSourceType;
 import jalview.io.JalviewFileChooser;
 import jalview.io.JalviewFileView;
-import jalview.io.StructureFile;
 import jalview.jbgui.FilterOption;
 import jalview.jbgui.GStructureChooser;
 import jalview.structure.StructureImportSettings.TFType;
@@ -78,7 +76,6 @@ import jalview.util.Platform;
 import jalview.util.StringUtils;
 import jalview.ws.DBRefFetcher;
 import jalview.ws.DBRefFetcher.FetchFinishedListenerI;
-import jalview.ws.dbsources.EBIAlfaFold;
 import jalview.ws.seqfetcher.DbSourceProxy;
 import jalview.ws.sifts.SiftsSettings;
 
@@ -688,8 +685,9 @@ public class StructureChooser extends GStructureChooser
       boolean guessTFType = localPdbPaeMatrixFileName == null;
       localPdbPaeMatrixFileName = guessPAEFilename();
       guessTFType |= localPdbPaeMatrixFileName != null;
+      Regex alphaFold = JmolParser.getNewAlphafoldValidator();
       if (guessTFType
-              && new File(selectedPdbFileName).getName().startsWith("AF-")
+              && alphaFold.search(new File(selectedPdbFileName).getName())
               && !tempFacAsChanged)
       {
         // localPdbPaeMatrixFileName was null and now isn't and filename could
@@ -1268,38 +1266,29 @@ public class StructureChooser extends GStructureChooser
         }
         else if (currentView == VIEWS_FROM_FILE)
         {
-
-          // TEMPFAC NOT WORKING
           TFType tft = (TFType) StructureChooser.this.combo_tempFacAs
                   .getSelectedItem();
-          if (tft != null && tft != TFType.DEFAULT)
-          {
-            ssm.setAddTempFacAnnot(true);
-          }
-
+          String paeFilename = StructureChooser.this.localPdbPaeMatrixFileName;
           AssociateSeqOptions assSeqOpt = (AssociateSeqOptions) fileChooserAssSeqPanel
                   .getCmb_assSeq().getSelectedItem();
-
           SequenceI userSelectedSeq = assSeqOpt.getSequence();
           if (userSelectedSeq != null)
-          {
             selectedSequence = userSelectedSeq;
-          }
+          String pdbFilename = selectedPdbFileName;
+
           PDBEntry fileEntry = new AssociatePdbFileWithSeq()
-                  .associatePdbWithSeq(selectedPdbFileName,
-                          DataSourceType.FILE, selectedSequence, true,
-                          Desktop.instance);
+                  .associatePdbWithSeq(pdbFilename, DataSourceType.FILE,
+                          selectedSequence, true, Desktop.instance, tft,
+                          paeFilename);
 
-          List<SequenceI> seqList = new ArrayList<>();
-          seqList.add(selectedSequence);
+          /*
           SequenceI[] seqArray = new SequenceI[] { selectedSequence };
+          
           StructureFile sf = ssm.computeMapping(true, seqArray, null,
-                  selectedPdbFileName, DataSourceType.FILE, null);
-          // EBIAlfaFold.addAlphaFoldPAEToStructure(pdbAlignment, pae, index,
-          // structIdOrFile, isStructId);
+                  selectedPdbFileName, DataSourceType.FILE, null, tft,
+                  paeFilename);
           StructureMapping[] sm = ssm.getMapping(fileEntry.getFile());
           // DO SOMETHING WITH
-          String paeFilename = StructureChooser.this.localPdbPaeMatrixFileName;
           File paeFile = paeFilename == null ? null : new File(paeFilename);
           if (paeFilename != null && paeFile.exists())
           {
@@ -1307,14 +1296,14 @@ public class StructureChooser extends GStructureChooser
             try
             {
               EBIAlfaFold.importPaeJSONAsContactMatrixToSequence(al,
-                      paeFile, -1, selectedSequence.getName());
+                      paeFile, selectedSequence);
             } catch (IOException | ParseException e)
             {
               // TODO Auto-generated catch block
               e.printStackTrace();
             }
           }
-
+          */
           sViewer = launchStructureViewer(ssm, new PDBEntry[] { fileEntry },
                   ap, new SequenceI[]
                   { selectedSequence });
@@ -1400,6 +1389,10 @@ public class StructureChooser extends GStructureChooser
       for (SequenceI seq : sequences)
       {
         PDBEntry pdbe = pdbEntriesToView[p++];
+        Console.debug(
+                "##### pdbe=" + pdbe == null ? null : pdbe.toString());
+        Console.debug("##### pdbe.getFile()=" + pdbe == null ? null
+                : pdbe.getFile());
         if (pdbe != null && pdbe.getFile() != null)
         {
           StructureMapping[] smm = ssm.getMapping(pdbe.getFile());
@@ -1447,6 +1440,7 @@ public class StructureChooser extends GStructureChooser
       setProgressBar(MessageManager.formatMessage(
               "status.fetching_3d_structures_for",
               pdbEntriesToView[0].getId()), progressId);
+      // Can we pass a pre-computeMappinged pdbFile?
       theViewer.viewStructures(pdbEntriesToView[0], sequences, alignPanel);
     }
     setProgressBar(null, progressId);
index 0a0504e..f498c1e 100644 (file)
@@ -70,6 +70,25 @@ public abstract class StructureFile extends AlignFile
 
   private StructureImportSettings.TFType temperatureFactorType = TFType.DEFAULT;
 
+  private String paeMatrix = null;
+
+  private boolean alphaFoldModel;
+
+  public void setPAEMatrix(String paeFilename)
+  {
+    paeMatrix = paeFilename;
+  }
+
+  public String getPAEMatrix()
+  {
+    return paeMatrix;
+  }
+
+  public boolean hasPAEMatrix()
+  {
+    return paeMatrix != null;
+  }
+
   public void setTemperatureFactorType(StructureImportSettings.TFType t)
   {
     this.temperatureFactorType = t;
@@ -80,6 +99,16 @@ public abstract class StructureFile extends AlignFile
     return temperatureFactorType;
   }
 
+  public void setAlphafoldModel(boolean afm)
+  {
+    alphaFoldModel = afm;
+  }
+
+  public boolean isAlphafoldModel()
+  {
+    return alphaFoldModel;
+  }
+
   public StructureFile(Object inFile, DataSourceType sourceType)
           throws IOException
   {
index 594b3a3..3194cce 100644 (file)
@@ -53,6 +53,7 @@ import jalview.gui.IProgressIndicator;
 import jalview.io.AppletFormatAdapter;
 import jalview.io.DataSourceType;
 import jalview.io.StructureFile;
+import jalview.structure.StructureImportSettings.TFType;
 import jalview.util.MappingUtils;
 import jalview.util.MessageManager;
 import jalview.util.Platform;
@@ -326,7 +327,7 @@ public class StructureSelectionManager
           IProgressIndicator progress)
   {
     return computeMapping(true, sequence, targetChains, pdbFile, protocol,
-            progress);
+            progress, null, null);
   }
 
   /**
@@ -349,10 +350,11 @@ public class StructureSelectionManager
    */
   synchronized public StructureFile setMapping(boolean forStructureView,
           SequenceI[] sequenceArray, String[] targetChainIds,
-          String pdbFile, DataSourceType sourceType)
+          String pdbFile, DataSourceType sourceType, TFType tft,
+          String paeFilename)
   {
     return computeMapping(forStructureView, sequenceArray, targetChainIds,
-            pdbFile, sourceType, null);
+            pdbFile, sourceType, null, tft, paeFilename);
   }
 
   /**
@@ -382,7 +384,7 @@ public class StructureSelectionManager
   synchronized public StructureFile computeMapping(boolean forStructureView,
           SequenceI[] sequenceArray, String[] targetChainIds,
           String pdbFile, DataSourceType sourceType,
-          IProgressIndicator progress)
+          IProgressIndicator progress, TFType tft, String paeFilename)
   {
     long progressSessionId = System.currentTimeMillis() * 3;
 
@@ -402,6 +404,11 @@ public class StructureSelectionManager
       // FIXME if sourceType is not null, we've lost data here
       sourceType = AppletFormatAdapter.checkProtocol(pdbFile);
       pdb = new JmolParser(false, pdbFile, sourceType);
+      if (paeFilename != null)
+      {
+        pdb.setPAEMatrix(paeFilename);
+      }
+      pdb.setTemperatureFactorType(tft);
       pdb.addSettings(parseSecStr && processSecondaryStructure,
               parseSecStr && addTempFacAnnot,
               parseSecStr && secStructServices);
index 672f0ac..aba0d4b 100644 (file)
@@ -27,6 +27,8 @@ import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -219,8 +221,8 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy
   }
 
   /**
-   * get an alphafold pAE for the given id, and add it to sequence 0 in
-   * pdbAlignment (assuming it came from structurefile parser).
+   * get an alphafold pAE for the given id and return the File object of the
+   * downloaded (temp) file
    * 
    * @param id
    * @param pdbAlignment
@@ -230,8 +232,8 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy
    * @throws IOException
    * @throws Exception
    */
-  public static void retrieve_AlphaFold_pAE(String id,
-          AlignmentI pdbAlignment, String retrievalUrl) throws IOException
+  public static File fetchAlphaFoldPAE(String id, String retrievalUrl)
+          throws IOException
   {
     // import PAE as contact matrix - assume this will work if there was a
     // model
@@ -244,7 +246,16 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy
               .replace(".cif", ".json");
     }
 
-    File pae = null;
+    // check the cache
+    File pae = paeDownloadCache.get(paeURL);
+    if (pae != null && pae.exists() && (new Date().getTime()
+            - pae.lastModified()) < PAE_CACHE_STALE_TIME)
+    {
+      Console.debug(
+              "Using existing file in PAE cache for '" + paeURL + "'");
+      return pae;
+    }
+
     try
     {
       pae = File.createTempFile(id == null ? "af_pae" : id, "pae_json");
@@ -254,21 +265,35 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy
     }
     Console.debug("Downloading pae from " + paeURL + " to " + pae.toString()
             + "");
-    UrlDownloadClient.download(paeURL, pae);
-    addAlphaFoldPAEToSequence(pdbAlignment, pae, 0, null);
-  }
-
-  public static void addAlphaFoldPAEToSequence(AlignmentI pdbAlignment,
-          File pae, int index, String seqId)
-  {
-    addAlphaFoldPAE(pdbAlignment, pae, index, seqId, false, false);
+    try
+    {
+      UrlDownloadClient.download(paeURL, pae);
+    } catch (IOException e)
+    {
+      throw e;
+    }
+    // cache and it if successful
+    paeDownloadCache.put(paeURL, pae);
+    return pae;
   }
 
-  public static void addAlphaFoldPAEToStructure(AlignmentI pdbAlignment,
-          File pae, int index, String structIdOrFile, boolean isStructId)
+  /**
+   * get an alphafold pAE for the given id, and add it to sequence 0 in
+   * pdbAlignment (assuming it came from structurefile parser).
+   * 
+   * @param id
+   * @param pdbAlignment
+   * @param retrievalUrl
+   *          - URL of .mmcif from EBI-AlphaFold - will be used to generate the
+   *          pAE URL automatically
+   * @throws IOException
+   * @throws Exception
+   */
+  public static void retrieve_AlphaFold_pAE(String id,
+          AlignmentI pdbAlignment, String retrievalUrl) throws IOException
   {
-    addAlphaFoldPAE(pdbAlignment, pae, index, structIdOrFile, true,
-            isStructId);
+    File pae = fetchAlphaFoldPAE(id, retrievalUrl);
+    addAlphaFoldPAE(pdbAlignment, pae, 0, null, false, false);
   }
 
   public static void addAlphaFoldPAE(AlignmentI pdbAlignment, File pae,
@@ -291,26 +316,8 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy
               .getStructureSelectionManager(Desktop.instance);
       if (ssm != null)
       {
-        String structFile = isStructId ? ssm.findFileForPDBId(id) : id;
-
-        StructureMapping[] smArray = ssm.getMapping(structFile);
-
-        try
-        {
-          if (!importPaeJSONAsContactMatrixToStructure(smArray, paeInput))
-          {
-            Console.warn("Could not import contact matrix from '"
-                    + pae.getAbsolutePath() + "' to structure.");
-          }
-        } catch (IOException e1)
-        {
-          Console.error("Error when importing pAE file '"
-                  + pae.getAbsolutePath() + "'", e1);
-        } catch (ParseException e2)
-        {
-          Console.error("Error when parsing pAE file '"
-                  + pae.getAbsolutePath() + "'", e2);
-        }
+        String structFilename = isStructId ? ssm.findFileForPDBId(id) : id;
+        addPAEToStructure(ssm, structFilename, pae);
       }
 
     }
@@ -338,6 +345,47 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy
 
   }
 
+  public static void addPAEToStructure(StructureSelectionManager ssm,
+          String structFilename, File pae)
+  {
+    FileInputStream paeInput = null;
+    try
+    {
+      paeInput = new FileInputStream(pae);
+    } catch (FileNotFoundException e)
+    {
+      Console.error(
+              "Could not find pAE file '" + pae.getAbsolutePath() + "'", e);
+      return;
+    }
+    if (ssm == null)
+    {
+      ssm = StructureSelectionManager
+              .getStructureSelectionManager(Desktop.instance);
+    }
+    if (ssm != null)
+    {
+      StructureMapping[] smArray = ssm.getMapping(structFilename);
+
+      try
+      {
+        if (!importPaeJSONAsContactMatrixToStructure(smArray, paeInput))
+        {
+          Console.warn("Could not import contact matrix from '"
+                  + pae.getAbsolutePath() + "' to structure.");
+        }
+      } catch (IOException e1)
+      {
+        Console.error("Error when importing pAE file '"
+                + pae.getAbsolutePath() + "'", e1);
+      } catch (ParseException e2)
+      {
+        Console.error("Error when parsing pAE file '"
+                + pae.getAbsolutePath() + "'", e2);
+      }
+    }
+  }
+
   /**
    * parses the given pAE matrix and adds it to sequence 0 in the given
    * alignment
@@ -389,7 +437,26 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy
         sequence = sequences[0]; // just use the first sequence with this seqId
       }
     }
+    if (sequence == null)
+    {
+      return false;
+    }
+    return importPaeJSONAsContactMatrixToSequence(pdbAlignment, pae_input,
+            sequence);
+  }
+
+  public static boolean importPaeJSONAsContactMatrixToSequence(
+          AlignmentI pdbAlignment, File pae_input, SequenceI sequence)
+          throws IOException, ParseException
+  {
+    return importPaeJSONAsContactMatrixToSequence(pdbAlignment,
+            new FileInputStream(pae_input), sequence);
+  }
 
+  public static boolean importPaeJSONAsContactMatrixToSequence(
+          AlignmentI pdbAlignment, InputStream pae_input,
+          SequenceI sequence) throws IOException, ParseException
+  {
     JSONObject paeDict = parseJSONtoPAEContactMatrix(pae_input);
     if (paeDict == null)
     {
@@ -439,14 +506,6 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy
   }
 
   public static boolean importPaeJSONAsContactMatrixToStructure(
-          StructureMapping sm, File paeFile)
-          throws FileNotFoundException, IOException, ParseException
-  {
-    return importPaeJSONAsContactMatrixToStructure(sm,
-            new FileInputStream(paeFile));
-  }
-
-  public static boolean importPaeJSONAsContactMatrixToStructure(
           StructureMapping sm, InputStream paeInput)
           throws IOException, ParseException
   {
@@ -629,4 +688,9 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy
     return new PDBFeatureSettings();
   }
 
+  // days * 86400000
+  private static final long PAE_CACHE_STALE_TIME = 1 * 86400000;
+
+  private static Map<String, File> paeDownloadCache = new HashMap<>();
+
 }
index f1feced..ff17209 100644 (file)
@@ -23,6 +23,11 @@ package jalview.structure;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertTrue;
 
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.Sequence;
@@ -34,11 +39,6 @@ import jalview.io.FileFormat;
 import jalview.io.FileLoader;
 import jalview.io.StructureFile;
 
-import org.testng.Assert;
-import org.testng.AssertJUnit;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
 public class Mapping
 {
 
@@ -80,7 +80,7 @@ public class Mapping
       StructureFile pmap = ssm.setMapping(true, new SequenceI[] { uprot },
               new String[]
               { "A" }, "test/jalview/ext/jmol/1QCF.pdb",
-              DataSourceType.FILE);
+              DataSourceType.FILE, null, null);
       assertTrue(pmap != null);
       SequenceI protseq = pmap.getSeqsAsArray()[0];
       AlignmentAnnotation pstra = protseq
@@ -149,7 +149,8 @@ public class Mapping
     // source
     StructureFile pde = ssm.setMapping(true, new SequenceI[] { sq },
             new String[]
-            { "A" }, inFile = "examples/1gaq.txt", DataSourceType.FILE);
+            { "A" }, inFile = "examples/1gaq.txt", DataSourceType.FILE,
+            null, null);
     assertTrue("PDB File couldn't be found", pde != null);
     StructureMapping[] mp = ssm.getMapping(inFile);
     assertTrue("No mappings made.", mp != null && mp.length > 0);
@@ -248,7 +249,7 @@ public class Mapping
     StructureSelectionManager ssm = new jalview.structure.StructureSelectionManager();
     StructureFile pmap = ssm.setMapping(true, new SequenceI[] { newseq },
             new String[]
-            { null }, "examples/3W5V.pdb", DataSourceType.FILE);
+            { null }, "examples/3W5V.pdb", DataSourceType.FILE, null, null);
     if (pmap == null)
     {
       AssertJUnit.fail("Couldn't make a mapping for 3W5V to FER1_MAIZE");
@@ -278,8 +279,8 @@ public class Mapping
     ssm.setAddTempFacAnnot(true);
     StructureFile pmap = ssm.setMapping(true, new SequenceI[] { newseq },
             new String[]
-            { null }, "test/jalview/ext/jmol/1QCF.pdb",
-            DataSourceType.FILE);
+            { null }, "test/jalview/ext/jmol/1QCF.pdb", DataSourceType.FILE,
+            null, null);
     assertTrue(pmap != null);
     assertEquals("Original and copied sequence of different lengths.",
             refseq.getLength(), newseq.getLength());
index aac7b84..ac8235d 100644 (file)
@@ -164,7 +164,7 @@ public class StructureSelectionManagerTest extends Jalview2xmlBase
     sm.setAddTempFacAnnot(true);
     StructureFile pmap = sm.setMapping(true, new SequenceI[] { seq },
             new String[]
-            { null }, "examples/1gaq.txt", DataSourceType.FILE);
+            { null }, "examples/1gaq.txt", DataSourceType.FILE, null, null);
     assertTrue(pmap != null);
 
     assertEquals(3, pmap.getSeqs().size());
@@ -220,7 +220,7 @@ public class StructureSelectionManagerTest extends Jalview2xmlBase
     sm.setAddTempFacAnnot(true);
     StructureFile pmap = sm.setMapping(true, new SequenceI[] { seq },
             new String[]
-            { null }, P4IM2_MISSING, DataSourceType.FILE);
+            { null }, P4IM2_MISSING, DataSourceType.FILE, null, null);
     assertTrue(pmap != null);
 
     assertEquals(1, pmap.getSeqs().size());