JAL-3829 work in progress - look up additional metadata from PDBe for structures...
authorJim Procter <j.procter@dundee.ac.uk>
Mon, 6 Sep 2021 13:48:46 +0000 (14:48 +0100)
committerJim Procter <j.procter@dundee.ac.uk>
Mon, 6 Sep 2021 13:48:46 +0000 (14:48 +0100)
src/jalview/gui/structurechooser/PDBStructureChooserQuerySource.java
src/jalview/gui/structurechooser/ThreeDBStructureChooserQuerySource.java
test/jalview/gui/structurechooser/StructureChooserQuerySourceTest.java

index 3d1b982..75e7fc0 100644 (file)
@@ -355,4 +355,10 @@ public class PDBStructureChooserQuerySource
     return lastPdbRequest;
   }
 
+
+  public FTSRestResponse executePDBFTSRestRequest(FTSRestRequest pdbRequest) throws Exception
+  {
+    return pdbRestClient.executeRequest(pdbRequest);
+  }
+
 }
\ No newline at end of file
index 0bf9fdb..b3242de 100644 (file)
@@ -13,6 +13,7 @@ import jalview.datamodel.DBRefEntry;
 import jalview.datamodel.DBRefSource;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
+import jalview.fts.api.FTSData;
 import jalview.fts.api.FTSDataColumnI;
 import jalview.fts.api.FTSRestClientI;
 import jalview.fts.core.FTSDataColumnPreferences;
@@ -38,6 +39,8 @@ public class ThreeDBStructureChooserQuerySource
 
   protected FTSRestClientI tdbRestClient;
 
+  private FTSRestRequest lastPdbRequest;
+
   public ThreeDBStructureChooserQuerySource()
   {
     tdbRestClient = TDBeaconsFTSRestClient.getInstance();
@@ -47,10 +50,10 @@ public class ThreeDBStructureChooserQuerySource
 
   }
 
-
   /**
-   * Builds a query string for a given sequences using its DBRef entries
-   * 3d Beacons is only useful for uniprot IDs
+   * Builds a query string for a given sequences using its DBRef entries 3d
+   * Beacons is only useful for uniprot IDs
+   * 
    * @param seq
    *          the sequences to build a query for
    * @return the built query string
@@ -77,12 +80,13 @@ public class ThreeDBStructureChooserQuerySource
         if (isValidSeqName(getDBRefId(dbRef))
                 && queryBuilder.length() < MAX_QLENGTH)
         {
-          if (dbRef.getSource().equalsIgnoreCase(DBRefSource.UNIPROT) && dbRef.isCanonical())
+          if (dbRef.getSource().equalsIgnoreCase(DBRefSource.UNIPROT)
+                  && dbRef.isCanonical())
           {
-            // TODO: pick best Uniprot accession 
-            isUniProtRefsFound=true;
+            // TODO: pick best Uniprot accession
+            isUniProtRefsFound = true;
             return getDBRefId(dbRef);
-            
+
           }
         }
       }
@@ -90,8 +94,6 @@ public class ThreeDBStructureChooserQuerySource
     return null;
   }
 
-
   /**
    * Ensures sequence ref names are not less than 3 characters and does not
    * contain a database name
@@ -154,16 +156,17 @@ public class ThreeDBStructureChooserQuerySource
     lastTdbRequest = tdbRequest;
     return resultList;
   }
-  
 
-  private FTSRestRequest getTDBeaconsRequest(SequenceI seq, Collection<FTSDataColumnI> wantedFields)
+  private FTSRestRequest getTDBeaconsRequest(SequenceI seq,
+          Collection<FTSDataColumnI> wantedFields)
   {
     FTSRestRequest pdbRequest = new FTSRestRequest();
     pdbRequest.setAllowEmptySeq(false);
     pdbRequest.setResponseSize(500);
     pdbRequest.setWantedFields(wantedFields);
     String query = buildQuery(seq);
-    if (query==null)  {
+    if (query == null)
+    {
       return null;
     }
     pdbRequest.setSearchTerm(query + ".json");
@@ -171,16 +174,16 @@ public class ThreeDBStructureChooserQuerySource
     return pdbRequest;
   }
 
-@Override
+  @Override
   public List<FilterOption> getAvailableFilterOptions(String VIEWS_FILTER)
   {
     List<FilterOption> filters = new ArrayList<FilterOption>();
+    filters.add(
+            new FilterOption(MessageManager.getString("label.best_quality"),
+                    "overall_quality", VIEWS_FILTER, false));
     filters.add(new FilterOption(
-            MessageManager.getString("label.best_quality"),
-            "overall_quality", VIEWS_FILTER, false));
-    filters.add(new FilterOption(
-            MessageManager.getString("label.best_resolution"),
-            "resolution", VIEWS_FILTER, false));
+            MessageManager.getString("label.best_resolution"), "resolution",
+            VIEWS_FILTER, false));
     filters.add(new FilterOption(
             MessageManager.getString("label.most_protein_chain"),
             "number_of_protein_chains", VIEWS_FILTER, false));
@@ -190,9 +193,10 @@ public class ThreeDBStructureChooserQuerySource
     filters.add(new FilterOption(
             MessageManager.getString("label.most_polymer_residues"),
             "number_of_polymer_residues", VIEWS_FILTER, true));
-  
+
     return filters;
   }
+
   /**
    * FTSRestClient specific query builder to pick top ranked entry from a
    * fetchStructuresMetaData query
@@ -215,12 +219,13 @@ public class ThreeDBStructureChooserQuerySource
 
     FTSRestResponse resultList;
     FTSRestRequest pdbRequest = getTDBeaconsRequest(seq, wantedFields);
-    if (pdbRequest == null) {
+    if (pdbRequest == null)
+    {
       return null;
     }
     pdbRequest.setResponseSize(1);
     resultList = tdbRestClient.executeRequest(pdbRequest);
-    
+
     // TODO: client side filtering - sort results and pick top one (or N)
 
     lastTdbRequest = pdbRequest;
@@ -231,25 +236,23 @@ public class ThreeDBStructureChooserQuerySource
   public PDBEntry[] collectSelectedRows(JTable restable, int[] selectedRows,
           List<SequenceI> selectedSeqsToView)
   {
-    int refSeqColIndex = restable.getColumn("Ref Sequence")
-            .getModelIndex();
+    int refSeqColIndex = restable.getColumn("Ref Sequence").getModelIndex();
 
-    PDBEntry[] pdbEntriesToView=new PDBEntry[selectedRows.length];
+    PDBEntry[] pdbEntriesToView = new PDBEntry[selectedRows.length];
     int count = 0;
     int idColumnIndex = restable.getColumn("Model id").getModelIndex();
     int urlColumnIndex = restable.getColumn("Url").getModelIndex();
     int typeColumnIndex = restable.getColumn("Provider").getModelIndex();
-    int categoryColumnIndex = restable.getColumn("Model Category").getModelIndex();
-    
+    int categoryColumnIndex = restable.getColumn("Model Category")
+            .getModelIndex();
+
     for (int row : selectedRows)
     {
       // unique id - could be a horrible hash
-      
-      String pdbIdStr = restable.getValueAt(row,idColumnIndex)
-              .toString();
-      String urlStr = restable.getValueAt(row,urlColumnIndex)
-              .toString();
-      String typeColumn = restable.getValueAt(row,typeColumnIndex)
+
+      String pdbIdStr = restable.getValueAt(row, idColumnIndex).toString();
+      String urlStr = restable.getValueAt(row, urlColumnIndex).toString();
+      String typeColumn = restable.getValueAt(row, typeColumnIndex)
               .toString();
       SequenceI selectedSeq = (SequenceI) restable.getValueAt(row,
               refSeqColIndex);
@@ -257,8 +260,7 @@ public class ThreeDBStructureChooserQuerySource
       PDBEntry pdbEntry = selectedSeq.getPDBEntry(pdbIdStr);
       if (pdbEntry == null)
       {
-        pdbEntry = getFindEntry(pdbIdStr,
-                selectedSeq.getAllPDBEntries());
+        pdbEntry = getFindEntry(pdbIdStr, selectedSeq.getAllPDBEntries());
       }
 
       if (pdbEntry == null)
@@ -277,10 +279,93 @@ public class ThreeDBStructureChooserQuerySource
     return pdbEntriesToView;
   }
 
-
   @Override
   protected FTSRestRequest getLastFTSRequest()
   {
     return lastTdbRequest;
   }
+
+  /**
+   * generate a query for PDBFTS to retrieve structure metadata
+   * 
+   * @param ftsRestRequest
+   * @param upResponse
+   * @return
+   */
+
+  public String buildPDBFTSQueryFor(FTSRestResponse upResponse)
+  {
+    List<String> pdbIds = new ArrayList<String>();
+    int idx_modelId = getLastFTSRequest().getFieldIndex("Model id");
+    int idx_provider = getLastFTSRequest().getFieldIndex("Provider");
+    for (FTSData row : upResponse.getSearchSummary())
+    {
+      String id = (String) row.getSummaryData()[idx_modelId];
+      String provider = (String) row.getSummaryData()[idx_provider];
+      if ("PDBe".equalsIgnoreCase(provider))
+      {
+        pdbIds.add(id);
+      }
+    }
+    return String.join(" OR ", pdbIds).toString();
+  }
+
+  /**
+   * query PDBe for structure metadata
+   * 
+   * @param pdbquery
+   * @param upResponse
+   * @return FTSRestResponse via PDBStructureChooserQuerySource
+   */
+  public FTSRestResponse fetchStructuresMetaDataFor(
+          PDBStructureChooserQuerySource pdbquery,
+          FTSRestResponse upResponse) throws Exception
+  {
+
+    String pdb_Query = buildPDBFTSQueryFor(upResponse);
+
+    FTSRestResponse resultList;
+    FTSRestRequest pdbRequest = new FTSRestRequest();
+    pdbRequest.setAllowEmptySeq(false);
+    pdbRequest.setResponseSize(500);
+    pdbRequest.setFieldToSearchBy("(");
+    // pdbRequest.setFieldToSortBy("pdb_id");
+    pdbRequest.setWantedFields(
+            pdbquery.getDocFieldPrefs().getStructureSummaryFields());
+    pdbRequest.setSearchTerm(pdb_Query + ")");
+    resultList = pdbquery.executePDBFTSRestRequest(pdbRequest);
+
+    lastPdbRequest = pdbRequest;
+    return resultList;
+  }
+
+  public FTSRestResponse joinResponses(FTSRestResponse upResponse,
+          FTSRestResponse pdbResponse)
+  {
+    int idx_provider = getLastFTSRequest().getFieldIndex("Provider");
+    // join on
+    int idx_modelId = getLastFTSRequest().getFieldIndex("Model id");
+    int pdbIdx = lastPdbRequest.getFieldIndex("pdb_id");
+    for (FTSData row : upResponse.getSearchSummary())
+    {
+      String id = (String) row.getSummaryData()[idx_modelId];
+      String provider = (String) row.getSummaryData()[idx_provider];
+      if ("PDBe".equalsIgnoreCase(provider))
+      {
+        for (FTSData pdbrow : pdbResponse.getSearchSummary())
+        {
+          String pdbid = (String) pdbrow.getSummaryData()[pdbIdx];
+          if (id.equalsIgnoreCase(pdbid))
+          {
+            // often multiple entries per PDB ID so we bail after first
+            // get wanted fields
+            // append to FTSRestResponse array
+          }
+        }
+      }
+    }
+    // TODO Auto-generated method stub
+    return null;
+  }
+
 }
\ No newline at end of file
index b6b4615..f492ce6 100644 (file)
 package jalview.gui.structurechooser;
 
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
 import java.util.Vector;
 
+import org.junit.Assert;
 import org.testng.AssertJUnit;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeClass;
@@ -35,8 +39,11 @@ import jalview.datamodel.PDBEntry;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
 import jalview.fts.core.FTSRestRequest;
+import jalview.fts.core.FTSRestResponse;
+import jalview.fts.service.pdb.PDBFTSRestClient;
 import jalview.fts.threedbeacons.TDBeaconsFTSRestClientTest;
 import jalview.gui.JvOptionPane;
+import jalview.jbgui.FilterOption;
 
 public class StructureChooserQuerySourceTest
 {
@@ -242,21 +249,31 @@ public class StructureChooserQuerySourceTest
   public void cascadingThreeDBandPDBQuerys()
   {
     TDBeaconsFTSRestClientTest.setMock();
-    
-    StructureChooserQuerySource scquery = StructureChooserQuerySource.getQuerySourceFor(new SequenceI[] { upSeq});
+    PDBFTSRestClient.setMock();
+    ThreeDBStructureChooserQuerySource tdbquery = new ThreeDBStructureChooserQuerySource();
+    PDBStructureChooserQuerySource pdbquery  = new PDBStructureChooserQuerySource();
+            
 
-    // query TDB for doc
-    // query PDBe for PDB entry metadata
-    // Combine
     
-    FTSRestRequest tdbQuery = new FTSRestRequest();
-    tdbQuery.setResponseSize(100);
-    tdbQuery.setFieldToSearchBy("");
-    tdbQuery.setSearchTerm(scquery.buildQuery(upSeq));
-    tdbQuery.setWantedFields(scquery.getDocFieldPrefs().getStructureSummaryFields());
-    //scquery.fetchStructuresMetaData(upSeq, null, null, false);
-    String secondaryPdbQuery;
-    //secondaryPdbQuery = ((ThreeDBStructureChooserQuerySource)scquery).buildPDBFTSquery();
+    FTSRestResponse upResponse = null;
+    FTSRestResponse pdbResponse = null;
+    
+    try {
+      upResponse = tdbquery.fetchStructuresMetaData(upSeq, tdbquery.getDocFieldPrefs().getStructureSummaryFields(),  null, false);
+      // NB Could have race condition here 
+      String pdb_Query = tdbquery.buildPDBFTSQueryFor(upResponse);
+      assertTrue(pdb_Query.trim().length()>0);
+      pdbResponse = tdbquery.fetchStructuresMetaDataFor(pdbquery, upResponse);
+      assertTrue(pdbResponse.getNumberOfItemsFound()>0);
+      FTSRestResponse joinedResp = tdbquery.joinResponses(upResponse, pdbResponse);
+      assertEquals(upResponse.getNumberOfItemsFound(),joinedResp.getNumberOfItemsFound());
+      
+    } catch (Exception x)
+    {
+      x.printStackTrace();
+      Assert.fail("Unexpected Exception");
+    }
+    StructureChooserQuerySource scquery = StructureChooserQuerySource.getQuerySourceFor(new SequenceI[] { upSeq});
 
   }