From 7e519850d1a3d263fd453ddaed1977754e5262b0 Mon Sep 17 00:00:00 2001 From: Jim Procter Date: Wed, 18 Aug 2021 16:41:55 +0100 Subject: [PATCH] JAL-3855 JAL-2349 download PAE matrix along with alpha fold structure from EBI and view PAE as contact map --- src/jalview/ws/dbsources/EBIAlfaFold.java | 76 ++++++++++++++++++---- test/jalview/ws/seqfetcher/DbRefFetcherTest.java | 29 +++++++++ 2 files changed, 92 insertions(+), 13 deletions(-) diff --git a/src/jalview/ws/dbsources/EBIAlfaFold.java b/src/jalview/ws/dbsources/EBIAlfaFold.java index 5edcafa..6c7818b 100644 --- a/src/jalview/ws/dbsources/EBIAlfaFold.java +++ b/src/jalview/ws/dbsources/EBIAlfaFold.java @@ -22,8 +22,11 @@ package jalview.ws.dbsources; import jalview.api.FeatureSettingsModelI; +import jalview.bin.Cache; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; +import jalview.datamodel.ContactMatrix; +import jalview.datamodel.ContactMatrixI; import jalview.datamodel.DBRefEntry; import jalview.datamodel.DBRefSource; import jalview.datamodel.PDBEntry; @@ -34,15 +37,23 @@ import jalview.io.FileFormat; import jalview.io.FileFormatI; import jalview.io.FormatAdapter; import jalview.io.PDBFeatureSettings; +import jalview.javascript.json.JSON; import jalview.structure.StructureImportSettings; import jalview.util.HttpUtils; import jalview.util.MessageManager; +import jalview.util.Platform; +import jalview.ws.datamodel.alphafold.PAEContactMatrix; import jalview.ws.ebi.EBIFetchClient; import jalview.ws.utils.UrlDownloadClient; +import java.io.BufferedReader; import java.io.File; +import java.io.FileInputStream; import java.util.ArrayList; import java.util.List; +import java.util.Map; + +import org.jmol.adapter.readers.simple.JSONReader; import com.stevesoft.pat.Regex; @@ -106,10 +117,18 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy { return "1"; } + public static String getAlphaFoldCifDownloadUrl(String id) { - return "https://alphafold.ebi.ac.uk/files/"+id+"-model_v1.cif"; + return "https://alphafold.ebi.ac.uk/files/" + id + "-model_v1.cif"; + } + + public static String getAlphaFoldPaeDownloadUrl(String id) + { + return "https://alphafold.ebi.ac.uk/files/" + id + + "-predicted_aligned_error_v1.json"; } + /* * (non-Javadoc) * @@ -133,24 +152,27 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy if (!isValidReference(id)) { - System.err.println("(AFClient) Ignoring invalid pdb query: '" + id + "'"); + System.err.println( + "(AFClient) Ignoring invalid alphafold query: '" + id + "'"); stopQuery(); return null; } String alphaFoldCif = getAlphaFoldCifDownloadUrl(id); - - try { - File tmpFile = File.createTempFile(id,"cif"); + + try + { + File tmpFile = File.createTempFile(id, "cif"); UrlDownloadClient.download(alphaFoldCif, tmpFile); file = tmpFile.getAbsolutePath(); if (file == null) { - return null; - } + return null; + } + // todo get rid of Type and use FileFormatI instead? FileFormatI fileFormat = FileFormat.MMCif; - pdbAlignment = new FormatAdapter().readFile(tmpFile, DataSourceType.FILE, - fileFormat); + pdbAlignment = new FormatAdapter().readFile(tmpFile, + DataSourceType.FILE, fileFormat); if (pdbAlignment != null) { List toremove = new ArrayList(); @@ -172,8 +194,7 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy { // FIXME seems to result in 'PDB|1QIP|1qip|A' - 1QIP is redundant. // TODO: suggest simplify naming to 1qip|A as default name defined - pdbcs.setName(id - + SEPARATOR + pdbcs.getName()); + pdbcs.setName(id + SEPARATOR + pdbcs.getName()); // Might need to add more metadata to the PDBEntry object // like below /* @@ -223,6 +244,17 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy { id, ((chain == null) ? "' '" : chain) })); } + // import PAE as contact matrix - assume this will work if there was a + // model + File pae = File.createTempFile(id, "pae_json"); + String paeURL = getAlphaFoldPaeDownloadUrl(id); + UrlDownloadClient.download(paeURL, pae); + if (!importPaeJSONAsContactMatrix(pdbAlignment, pae)) + { + Cache.log.debug("Couln't import contact matrix from " + paeURL + + " (stored in " + pae.toString() + ")"); + } + } catch (Exception ex) // Problem parsing PDB file { stopQuery(); @@ -231,6 +263,24 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy return pdbAlignment; } + private boolean importPaeJSONAsContactMatrix(AlignmentI pdbAlignment, + File pae) throws Exception + { + FileInputStream pae_input = new FileInputStream(pae); + + List pae_obj = (List) Platform + .parseJSON(pae_input); + if (pae_obj == null) + { + return false; + } + ContactMatrixI matrix = new PAEContactMatrix( + pdbAlignment.getSequenceAt(0), (Map)pae_obj.get(0)); + + pdbAlignment.getSequenceAt(0).addAlignmentAnnotation(pdbAlignment.addContactList(matrix)); + return true; + } + /* * (non-Javadoc) * @@ -249,13 +299,13 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy @Override public String getTestQuery() { - return "1QIP"; + return "AF-O15552-F1"; } @Override public String getDbName() { - return "PDB"; // getDbSource(); + return "ALPHAFOLD"; // getDbSource(); } @Override diff --git a/test/jalview/ws/seqfetcher/DbRefFetcherTest.java b/test/jalview/ws/seqfetcher/DbRefFetcherTest.java index a7e5806..bf34ea5 100644 --- a/test/jalview/ws/seqfetcher/DbRefFetcherTest.java +++ b/test/jalview/ws/seqfetcher/DbRefFetcherTest.java @@ -20,12 +20,14 @@ */ package jalview.ws.seqfetcher; +import static org.testng.Assert.assertNotEquals; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertFalse; import static org.testng.AssertJUnit.assertNotNull; import static org.testng.AssertJUnit.assertTrue; import jalview.analysis.CrossRef; +import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.DBRefEntry; import jalview.datamodel.DBRefSource; @@ -35,6 +37,7 @@ import jalview.datamodel.SequenceI; import jalview.gui.JvOptionPane; import jalview.util.DBRefUtils; import jalview.ws.SequenceFetcher; +import jalview.ws.dbsources.EBIAlfaFold; import jalview.ws.dbsources.Pdb; import jalview.ws.dbsources.Uniprot; @@ -42,6 +45,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import org.junit.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -202,4 +206,29 @@ public class DbRefFetcherTest assertEquals(dr.get(0).getSource() + "|" + dr.get(0).getAccessionId(), proteinSeq.getName()); } + + /** + * Tests retrieval of one entry from EMBLCDS. Test is dependent on + * availability of network and the EMBLCDS service. + * + * @throws Exception + */ + @Test(groups = { "External" }) + public void testAlphaFoldClien() throws Exception + { + DbSourceProxy alphafold = new EBIAlfaFold(); + AlignmentI resp = alphafold.getSequenceRecords(alphafold.getTestQuery()); + assertNotNull(resp); + assertEquals("One sequence only",resp.getHeight(), 1); + for (AlignmentAnnotation aa:resp.getAlignmentAnnotation()) { + if (aa.graph == AlignmentAnnotation.CUSTOMRENDERER) + { + assertTrue("Contact map didn't provide valid contact",resp.getContactListFor(aa, 1).getContactAt(1)!=-1d); + // test passes + return; + } + } + Assert.fail(); + } + } -- 1.7.10.2