From 7e3a6674abdd31bf48e7e249a74eff50fd2ce589 Mon Sep 17 00:00:00 2001 From: Ben Soares Date: Thu, 2 Mar 2023 13:31:03 +0000 Subject: [PATCH] JAL-629 Some refactoring to allow more flexible use of PAE files. Not working as desired yet --- src/jalview/bin/Commands.java | 19 ++- src/jalview/datamodel/PDBEntry.java | 22 ++- src/jalview/ext/jmol/JmolParser.java | 70 +++++---- src/jalview/gui/AssociatePdbFileWithSeq.java | 19 ++- src/jalview/gui/PymolViewer.java | 15 +- src/jalview/gui/StructureChooser.java | 48 +++--- src/jalview/io/StructureFile.java | 29 ++++ .../structure/StructureSelectionManager.java | 15 +- src/jalview/ws/dbsources/EBIAlfaFold.java | 154 ++++++++++++++------ test/jalview/structure/Mapping.java | 21 +-- .../structure/StructureSelectionManagerTest.java | 4 +- 11 files changed, 278 insertions(+), 138 deletions(-) diff --git a/src/jalview/bin/Commands.java b/src/jalview/bin/Commands.java index af8bf65..a98069a 100644 --- a/src/jalview/bin/Commands.java +++ b/src/jalview/bin/Commands.java @@ -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 } diff --git a/src/jalview/datamodel/PDBEntry.java b/src/jalview/datamodel/PDBEntry.java index 65ba18b..ae8523d 100755 --- a/src/jalview/datamodel/PDBEntry.java +++ b/src/jalview/datamodel/PDBEntry.java @@ -20,12 +20,13 @@ */ 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(); + } } diff --git a/src/jalview/ext/jmol/JmolParser.java b/src/jalview/ext/jmol/JmolParser.java index 2bc4869..969d195 100644 --- a/src/jalview/ext/jmol/JmolParser.java +++ b/src/jalview/ext/jmol/JmolParser.java @@ -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 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 convertSignificantAtoms(ModelSet ms) { List significantAtoms = new ArrayList(); diff --git a/src/jalview/gui/AssociatePdbFileWithSeq.java b/src/jalview/gui/AssociatePdbFileWithSeq.java index fe0aedf..fd89c50 100644 --- a/src/jalview/gui/AssociatePdbFileWithSeq.java +++ b/src/jalview/gui/AssociatePdbFileWithSeq.java @@ -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; } diff --git a/src/jalview/gui/PymolViewer.java b/src/jalview/gui/PymolViewer.java index 9dc28c8..5069d93 100644 --- a/src/jalview/gui/PymolViewer.java +++ b/src/jalview/gui/PymolViewer.java @@ -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) { diff --git a/src/jalview/gui/StructureChooser.java b/src/jalview/gui/StructureChooser.java index 0823652..e2eaabd 100644 --- a/src/jalview/gui/StructureChooser.java +++ b/src/jalview/gui/StructureChooser.java @@ -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 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); diff --git a/src/jalview/io/StructureFile.java b/src/jalview/io/StructureFile.java index 0a0504e..f498c1e 100644 --- a/src/jalview/io/StructureFile.java +++ b/src/jalview/io/StructureFile.java @@ -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 { diff --git a/src/jalview/structure/StructureSelectionManager.java b/src/jalview/structure/StructureSelectionManager.java index 594b3a3..3194cce 100644 --- a/src/jalview/structure/StructureSelectionManager.java +++ b/src/jalview/structure/StructureSelectionManager.java @@ -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); diff --git a/src/jalview/ws/dbsources/EBIAlfaFold.java b/src/jalview/ws/dbsources/EBIAlfaFold.java index 672f0ac..aba0d4b 100644 --- a/src/jalview/ws/dbsources/EBIAlfaFold.java +++ b/src/jalview/ws/dbsources/EBIAlfaFold.java @@ -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 paeDownloadCache = new HashMap<>(); + } diff --git a/test/jalview/structure/Mapping.java b/test/jalview/structure/Mapping.java index f1feced..ff17209 100644 --- a/test/jalview/structure/Mapping.java +++ b/test/jalview/structure/Mapping.java @@ -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()); diff --git a/test/jalview/structure/StructureSelectionManagerTest.java b/test/jalview/structure/StructureSelectionManagerTest.java index aac7b84..ac8235d 100644 --- a/test/jalview/structure/StructureSelectionManagerTest.java +++ b/test/jalview/structure/StructureSelectionManagerTest.java @@ -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()); -- 1.7.10.2