From 55ea4d59b2f4ce51f8310047dd1f8898697dde0c Mon Sep 17 00:00:00 2001 From: Jim Procter Date: Thu, 26 Aug 2021 14:56:05 +0100 Subject: [PATCH] JAL-3829 3d-beacons structure chooser logic (not yet finished) --- src/jalview/datamodel/PDBEntry.java | 17 ++ src/jalview/fts/api/FTSRestClientI.java | 3 + src/jalview/fts/core/FTSDataColumnPreferences.java | 20 +- src/jalview/fts/core/FTSRestClient.java | 16 + src/jalview/fts/service/pdb/PDBFTSRestClient.java | 29 +- .../threedbeacons/TDBeaconsFTSRestClient.java | 162 ++++++---- src/jalview/gui/StructureChooser.java | 52 +--- src/jalview/gui/StructureChooserQuerySource.java | 315 -------------------- .../StructureChooserQuerySource.java | 207 +++++++++++++ test/jalview/gui/StructureChooserTest.java | 10 +- 10 files changed, 392 insertions(+), 439 deletions(-) delete mode 100644 src/jalview/gui/StructureChooserQuerySource.java create mode 100644 src/jalview/gui/structurechooser/StructureChooserQuerySource.java diff --git a/src/jalview/datamodel/PDBEntry.java b/src/jalview/datamodel/PDBEntry.java index c1dc77c..1edc94b 100755 --- a/src/jalview/datamodel/PDBEntry.java +++ b/src/jalview/datamodel/PDBEntry.java @@ -460,4 +460,21 @@ public class PDBEntry } return true; } + + + /** + * Permanent URI for retrieving the original structure data + * @param urlStr + */ + public void setRetrievalUrl(String urlStr) + { + setProperty("RETRIEVE_FROM", urlStr); + } + /** + * get the Permanent URI for retrieving the original structure data + */ + public String getRetrievalUrl() + { + return (String) getProperty("RETRIEVE_FROM"); + } } diff --git a/src/jalview/fts/api/FTSRestClientI.java b/src/jalview/fts/api/FTSRestClientI.java index 84d8e0d..31d5c7c 100644 --- a/src/jalview/fts/api/FTSRestClientI.java +++ b/src/jalview/fts/api/FTSRestClientI.java @@ -22,6 +22,7 @@ package jalview.fts.api; import jalview.fts.api.FTSDataColumnI.FTSDataColumnGroupI; +import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource; import jalview.fts.core.FTSRestRequest; import jalview.fts.core.FTSRestResponse; @@ -136,4 +137,6 @@ public interface FTSRestClientI * @return the default response page size */ public int getDefaultResponsePageSize(); + + public String[] getPreferencesColumnsFor(PreferenceSource source); } diff --git a/src/jalview/fts/core/FTSDataColumnPreferences.java b/src/jalview/fts/core/FTSDataColumnPreferences.java index c0b6d05..0335d65 100644 --- a/src/jalview/fts/core/FTSDataColumnPreferences.java +++ b/src/jalview/fts/core/FTSDataColumnPreferences.java @@ -23,6 +23,7 @@ package jalview.fts.core; import jalview.fts.api.FTSDataColumnI; import jalview.fts.api.FTSDataColumnI.FTSDataColumnGroupI; import jalview.fts.api.FTSRestClientI; +import jalview.fts.api.StructureFTSRestClientI; import jalview.fts.service.pdb.PDBFTSRestClient; import java.util.ArrayList; @@ -76,7 +77,7 @@ public class FTSDataColumnPreferences extends JScrollPane if (source.equals(PreferenceSource.STRUCTURE_CHOOSER) || source.equals(PreferenceSource.PREFERENCES)) { - structSummaryColumns = ((PDBFTSRestClient) ftsRestClient) + structSummaryColumns = ((StructureFTSRestClientI) ftsRestClient) .getAllDefaultDisplayedStructureDataColumns(); } allFTSDataColumns.addAll(ftsRestClient.getAllFTSDataColumns()); @@ -85,22 +86,7 @@ public class FTSDataColumnPreferences extends JScrollPane this.getViewport().add(tbl_FTSDataColumnPrefs); this.currentSource = source; - String[] columnNames = null; - switch (source) - { - case SEARCH_SUMMARY: - columnNames = new String[] { "", "Display", "Group" }; - break; - case STRUCTURE_CHOOSER: - columnNames = new String[] { "", "Display", "Group" }; - break; - case PREFERENCES: - columnNames = new String[] { "PDB Field", "Show in search summary", - "Show in structure summary" }; - break; - default: - break; - } + String[] columnNames = ftsRestClient.getPreferencesColumnsFor(source); Object[][] data = new Object[allFTSDataColumns.size()][3]; diff --git a/src/jalview/fts/core/FTSRestClient.java b/src/jalview/fts/core/FTSRestClient.java index 7a8a695..f651707 100644 --- a/src/jalview/fts/core/FTSRestClient.java +++ b/src/jalview/fts/core/FTSRestClient.java @@ -30,6 +30,7 @@ import java.util.Objects; import jalview.fts.api.FTSDataColumnI; import jalview.fts.api.FTSDataColumnI.FTSDataColumnGroupI; +import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource; import jalview.fts.api.FTSRestClientI; /** @@ -504,4 +505,19 @@ public abstract class FTSRestClient implements FTSRestClientI return defaultResponsePageSize; } + @Override + public String[] getPreferencesColumnsFor(PreferenceSource source) + { + String[] columnNames = null; + switch (source) + { + case SEARCH_SUMMARY: + columnNames = new String[] { "", "Display", "Group" }; + break; + default: + // non structure sources don't return any other kind of preferences columns + break; + } + return columnNames; + } } diff --git a/src/jalview/fts/service/pdb/PDBFTSRestClient.java b/src/jalview/fts/service/pdb/PDBFTSRestClient.java index dc7fe41..313f0b6 100644 --- a/src/jalview/fts/service/pdb/PDBFTSRestClient.java +++ b/src/jalview/fts/service/pdb/PDBFTSRestClient.java @@ -41,6 +41,9 @@ import jalview.datamodel.SequenceI; import jalview.fts.api.FTSData; import jalview.fts.api.FTSDataColumnI; import jalview.fts.api.FTSRestClientI; +import jalview.fts.api.StructureFTSRestClientI; +import jalview.fts.core.FTSDataColumnPreferences; +import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource; import jalview.fts.core.FTSRestClient; import jalview.fts.core.FTSRestRequest; import jalview.fts.core.FTSRestResponse; @@ -53,7 +56,7 @@ import jalview.util.Platform; * * @author tcnofoegbu */ -public class PDBFTSRestClient extends FTSRestClient +public class PDBFTSRestClient extends FTSRestClient implements StructureFTSRestClientI { private static FTSRestClientI instance = null; @@ -470,7 +473,7 @@ public static String parseJsonExceptionString(String jsonErrorResponse) } private Collection allDefaultDisplayedStructureDataColumns; - + @Override public Collection getAllDefaultDisplayedStructureDataColumns() { if (allDefaultDisplayedStructureDataColumns == null @@ -482,6 +485,24 @@ public static String parseJsonExceptionString(String jsonErrorResponse) } return allDefaultDisplayedStructureDataColumns; } - - + @Override + public String[] getPreferencesColumnsFor(PreferenceSource source) { + String[] columnNames = null; + switch (source) + { + case SEARCH_SUMMARY: + columnNames = new String[] { "", "Display", "Group" }; + break; + case STRUCTURE_CHOOSER: + columnNames = new String[] { "", "Display", "Group" }; + break; + case PREFERENCES: + columnNames = new String[] { "PDB Field", "Show in search summary", + "Show in structure summary" }; + break; + default: + break; + } + return columnNames; + } } diff --git a/src/jalview/fts/service/threedbeacons/TDBeaconsFTSRestClient.java b/src/jalview/fts/service/threedbeacons/TDBeaconsFTSRestClient.java index e956461..a57cf3b 100644 --- a/src/jalview/fts/service/threedbeacons/TDBeaconsFTSRestClient.java +++ b/src/jalview/fts/service/threedbeacons/TDBeaconsFTSRestClient.java @@ -21,25 +21,27 @@ import jalview.datamodel.SequenceI; import jalview.fts.api.FTSData; import jalview.fts.api.FTSDataColumnI; import jalview.fts.api.FTSRestClientI; +import jalview.fts.api.StructureFTSRestClientI; import jalview.fts.core.FTSRestClient; import jalview.fts.core.FTSRestRequest; import jalview.fts.core.FTSRestResponse; +import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource; import jalview.fts.service.pdb.PDBFTSRestClient; import jalview.util.JSONUtils; import jalview.util.MessageManager; import jalview.util.Platform; public class TDBeaconsFTSRestClient extends FTSRestClient + implements StructureFTSRestClientI { - private static final String DEFAULT_THREEDBEACONS_DOMAIN = - "https://wwwdev.ebi.ac.uk/pdbe/pdbe-kb/3dbeacons/api/uniprot/summary/"; - + private static final String DEFAULT_THREEDBEACONS_DOMAIN = "https://wwwdev.ebi.ac.uk/pdbe/pdbe-kb/3dbeacons/api/uniprot/summary/"; + private static FTSRestClientI instance = null; - + protected TDBeaconsFTSRestClient() - { + { } - + @SuppressWarnings("unchecked") @Override public FTSRestResponse executeRequest(FTSRestRequest tdbRestRequest) @@ -59,6 +61,7 @@ public class TDBeaconsFTSRestClient extends FTSRestClient else /** * Java only + * * @j2sIgnore */ { @@ -70,16 +73,16 @@ public class TDBeaconsFTSRestClient extends FTSRestClient .path(query); URI uri = webResource.getURI(); System.out.println(uri.toString()); - + // Execute the REST request ClientResponse clientResponse = webResource .accept(MediaType.APPLICATION_JSON).get(clientResponseClass); - + // Get the JSON string from the response object or directly from the // client (JavaScript) Map jsonObj = null; String responseString = null; - + // Check the response status and report exception if one occurs int responseStatus = clientResponse.getStatus(); switch (responseStatus) @@ -102,7 +105,8 @@ public class TDBeaconsFTSRestClient extends FTSRestClient getMessageByHTTPStatusCode(responseStatus, "3DBeacons")); } // Process the response and return the result to the caller. - return parseTDBeaconsJsonResponse(responseString, jsonObj, tdbRestRequest); + return parseTDBeaconsJsonResponse(responseString, jsonObj, + tdbRestRequest); } catch (Exception e) { String exceptionMsg = e.getMessage(); @@ -123,52 +127,59 @@ public class TDBeaconsFTSRestClient extends FTSRestClient throw e; } } - + } - - public String setSearchTerm(String term) { + + public String setSearchTerm(String term) + { return term; } - + public static FTSRestResponse parseTDBeaconsJsonResponse( String tdbJsonResponseString, FTSRestRequest tdbRestRequest) { return parseTDBeaconsJsonResponse(tdbJsonResponseString, (Map) null, tdbRestRequest); } - + @SuppressWarnings("unchecked") - public static FTSRestResponse parseTDBeaconsJsonResponse(String tdbJsonResponseString, - Map jsonObj, FTSRestRequest tdbRestRequest) + public static FTSRestResponse parseTDBeaconsJsonResponse( + String tdbJsonResponseString, Map jsonObj, + FTSRestRequest tdbRestRequest) { FTSRestResponse searchResult = new FTSRestResponse(); List result = null; - + try { if (jsonObj == null) { - jsonObj = (Map) JSONUtils.parse(tdbJsonResponseString); + jsonObj = (Map) JSONUtils + .parse(tdbJsonResponseString); } - - Object uniprot_entry = jsonObj.get("uniprot_entry"); - // TODO: decide if anything from uniprot_entry needs to be reported via the FTSRestResponse object - // Arnaud added seqLength = (Long) ((Map) jsonObj.get("uniprot_entry")).get("sequence_length"); + + Object uniprot_entry = jsonObj.get("uniprot_entry"); + // TODO: decide if anything from uniprot_entry needs to be reported via + // the FTSRestResponse object + // Arnaud added seqLength = (Long) ((Map) + // jsonObj.get("uniprot_entry")).get("sequence_length"); List structures = (List) jsonObj.get("structures"); result = new ArrayList<>(); - + int numFound = 0; - for (Iterator strucIter = structures.iterator(); strucIter.hasNext();) + for (Iterator strucIter = structures.iterator(); strucIter + .hasNext();) { - Map structure = (Map) strucIter.next(); + Map structure = (Map) strucIter + .next(); result.add(getFTSData(structure, tdbRestRequest)); numFound++; } - - searchResult.setNumberOfItemsFound(numFound); + + searchResult.setNumberOfItemsFound(numFound); searchResult.setSearchSummary(result); - + } catch (ParseException e) { e.printStackTrace(); @@ -176,20 +187,35 @@ public class TDBeaconsFTSRestClient extends FTSRestClient return searchResult; } -private static FTSData getFTSData(Map tdbJsonStructure, + private static FTSData getFTSData(Map tdbJsonStructure, FTSRestRequest tdbRequest) { - // TODO Auto-generated method stub + // TODO: consider reusing PDBFTSRestClient.getFTSData ? + String primaryKey = null; Object[] summaryRowData; + + SequenceI associatedSequence; + Collection displayFields = tdbRequest.getWantedFields(); + SequenceI associatedSeq = tdbRequest.getAssociatedSequence(); int colCounter = 0; - summaryRowData = new Object[displayFields.size()]; - - for (FTSDataColumnI field : displayFields) { - String fieldData = (tdbJsonStructure.get(field.getCode()) == null) ? " " + summaryRowData = new Object[(associatedSeq != null) + ? displayFields.size() + 1 + : displayFields.size()]; + if (associatedSeq != null) + { + associatedSequence = associatedSeq; + summaryRowData[0] = associatedSequence; + colCounter = 1; + } + + for (FTSDataColumnI field : displayFields) + { + String fieldData = (tdbJsonStructure.get(field.getCode()) == null) + ? " " : tdbJsonStructure.get(field.getCode()).toString(); - // System.out.println("Field : " + field + " Data : " + fieldData); + // System.out.println("Field : " + field + " Data : " + fieldData); if (field.isPrimaryKeyColumn()) { primaryKey = fieldData; @@ -199,7 +225,7 @@ private static FTSData getFTSData(Map tdbJsonStructure, { summaryRowData[colCounter++] = null; } - else + else { try { @@ -212,14 +238,14 @@ private static FTSData getFTSData(Map tdbJsonStructure, : fieldData; } catch (Exception e) { - //e.printStackTrace(); + // e.printStackTrace(); System.out.println("offending value:" + fieldData + fieldData); } } } final String primaryKey1 = primaryKey; final Object[] summaryRowData1 = summaryRowData; - + return new FTSData() { @@ -234,7 +260,7 @@ private static FTSData getFTSData(Map tdbJsonStructure, { return primaryKey1; } - + /** * Returns a string representation of this object; */ @@ -250,7 +276,7 @@ private static FTSData getFTSData(Map tdbJsonStructure, } return summaryFieldValues.toString(); } - + /** * Returns hash code value for this object */ @@ -268,19 +294,20 @@ private static FTSData getFTSData(Map tdbJsonStructure, }; } -// private static FTSData getFTSData(Map doc, -// FTSRestRequest tdbRestRequest) -// { -// String primaryKey = null; -// -// Object[] summaryRowData; -// -// Collection displayFields = tdbRestRequest.getWantedFields(); -// int colCounter = 0; -// summaryRowData = new Object[displayFields.size() + 1]; -// -// return null; -// } + // private static FTSData getFTSData(Map doc, + // FTSRestRequest tdbRestRequest) + // { + // String primaryKey = null; + // + // Object[] summaryRowData; + // + // Collection displayFields = + // tdbRestRequest.getWantedFields(); + // int colCounter = 0; + // summaryRowData = new Object[displayFields.size() + 1]; + // + // return null; + // } private String parseJsonExceptionString(String jsonErrorString) { @@ -293,7 +320,7 @@ private static FTSData getFTSData(Map tdbJsonStructure, { return "/fts/tdbeacons_data_columns.txt"; } - + public static FTSRestClientI getInstance() { if (instance == null) @@ -302,7 +329,7 @@ private static FTSData getFTSData(Map tdbJsonStructure, } return instance; } - + private Collection allDefaultDisplayedStructureDataColumns; public Collection getAllDefaultDisplayedStructureDataColumns() @@ -316,5 +343,26 @@ private static FTSData getFTSData(Map tdbJsonStructure, } return allDefaultDisplayedStructureDataColumns; } - + + @Override + public String[] getPreferencesColumnsFor(PreferenceSource source) + { + String[] columnNames = null; + switch (source) + { + case SEARCH_SUMMARY: + columnNames = new String[] { "", "Display", "Group" }; + break; + case STRUCTURE_CHOOSER: + columnNames = new String[] { "", "Display", "Group" }; + break; + case PREFERENCES: + columnNames = new String[] { "3DB Beacons Field", "Show in search summary", + "Show in structure summary" }; + break; + default: + break; + } + return columnNames; + } } diff --git a/src/jalview/gui/StructureChooser.java b/src/jalview/gui/StructureChooser.java index ebba2e5..ea2d50d 100644 --- a/src/jalview/gui/StructureChooser.java +++ b/src/jalview/gui/StructureChooser.java @@ -35,6 +35,8 @@ import jalview.fts.core.FTSDataColumnPreferences; import jalview.fts.core.FTSRestRequest; import jalview.fts.core.FTSRestResponse; import jalview.fts.service.pdb.PDBFTSRestClient; +import jalview.gui.structurechooser.PDBStructureChooserQuerySource; +import jalview.gui.structurechooser.StructureChooserQuerySource; import jalview.io.DataSourceType; import jalview.jbgui.GStructureChooser; import jalview.jbgui.GStructureChooser.FilterOption; @@ -102,7 +104,7 @@ public class StructureChooser extends GStructureChooser { // which FTS engine to use data = StructureChooserQuerySource - .getPDBfts(); + .getTDBfts(); initDialog(); this.ap = ap; @@ -243,6 +245,12 @@ public class StructureChooser extends GStructureChooser { resultList = data.fetchStructuresMetaData(seq, wantedFields, selectedFilterOpt, !chk_invertFilter.isSelected()); + // null response means the FTSengine didn't yield a query for this + // consider designing a special exception if we really wanted to be OOCrazy + if (resultList==null) + { + continue; + } } catch (Exception e) { e.printStackTrace(); @@ -735,36 +743,11 @@ public class StructureChooser extends GStructureChooser if (currentView == VIEWS_FILTER) { - int pdbIdColIndex = restable.getColumn("PDB Id").getModelIndex(); - int refSeqColIndex = restable.getColumn("Ref Sequence") - .getModelIndex(); int[] selectedRows = restable.getSelectedRows(); PDBEntry[] pdbEntriesToView = new PDBEntry[selectedRows.length]; - int count = 0; List selectedSeqsToView = new ArrayList<>(); - for (int row : selectedRows) - { - String pdbIdStr = restable.getValueAt(row, pdbIdColIndex) - .toString(); - SequenceI selectedSeq = (SequenceI) restable.getValueAt(row, - refSeqColIndex); - selectedSeqsToView.add(selectedSeq); - PDBEntry pdbEntry = selectedSeq.getPDBEntry(pdbIdStr); - if (pdbEntry == null) - { - pdbEntry = getFindEntry(pdbIdStr, - selectedSeq.getAllPDBEntries()); - } + pdbEntriesToView = data.collectSelectedRows(restable,selectedRows,selectedSeqsToView); - if (pdbEntry == null) - { - pdbEntry = new PDBEntry(); - pdbEntry.setId(pdbIdStr); - pdbEntry.setType(PDBEntry.Type.PDB); - selectedSeq.getDatasetSequence().addPDBId(pdbEntry); - } - pdbEntriesToView[count++] = pdbEntry; - } SequenceI[] selectedSeqs = selectedSeqsToView .toArray(new SequenceI[selectedSeqsToView.size()]); sViewer = launchStructureViewer(ssm, pdbEntriesToView, ap, @@ -872,21 +855,6 @@ public class StructureChooser extends GStructureChooser } } - private PDBEntry getFindEntry(String id, Vector pdbEntries) - { - Objects.requireNonNull(id); - Objects.requireNonNull(pdbEntries); - PDBEntry foundEntry = null; - for (PDBEntry entry : pdbEntries) - { - if (entry.getId().equalsIgnoreCase(id)) - { - return entry; - } - } - return foundEntry; - } - /** * Answers a structure viewer (new or existing) configured to superimpose * added structures or not according to the user's choice diff --git a/src/jalview/gui/StructureChooserQuerySource.java b/src/jalview/gui/StructureChooserQuerySource.java deleted file mode 100644 index 637f168..0000000 --- a/src/jalview/gui/StructureChooserQuerySource.java +++ /dev/null @@ -1,315 +0,0 @@ -package jalview.gui; - -import java.util.Collection; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Objects; -import java.util.Set; - -import javax.swing.table.TableModel; - -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; -import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource; -import jalview.fts.core.FTSRestRequest; -import jalview.fts.core.FTSRestResponse; -import jalview.fts.service.pdb.PDBFTSRestClient; -import jalview.jbgui.GStructureChooser.FilterOption; - -/** - * logic for querying sources of structural data for structures of sequences - * - * @author jprocter - * - * @param - */ -public class StructureChooserQuerySource -{ - private FTSRestRequest lastPdbRequest; - - private FTSRestClientI pdbRestClient; - - private FTSDataColumnPreferences docFieldPrefs; - - private static int MAX_QLENGTH = 7820; - - public StructureChooserQuerySource() - { - } - - public static StructureChooserQuerySource getPDBfts() - { - StructureChooserQuerySource pdbfts = new StructureChooserQuerySource(); - pdbfts.pdbRestClient = PDBFTSRestClient.getInstance(); - pdbfts.docFieldPrefs = new FTSDataColumnPreferences( - PreferenceSource.STRUCTURE_CHOOSER, - PDBFTSRestClient.getInstance()); - return pdbfts; - } - - public FTSDataColumnPreferences getDocFieldPrefs() - { - return docFieldPrefs; - } - - public void setDocFieldPrefs(FTSDataColumnPreferences docFieldPrefs) - { - this.docFieldPrefs = docFieldPrefs; - } - - /** - * Builds a query string for a given sequences using its DBRef entries - * - * @param seq - * the sequences to build a query for - * @return the built query string - */ - - String buildQuery(SequenceI seq) - { - boolean isPDBRefsFound = false; - boolean isUniProtRefsFound = false; - StringBuilder queryBuilder = new StringBuilder(); - Set seqRefs = new LinkedHashSet<>(); - - /* - * note PDBs as DBRefEntry so they are not duplicated in query - */ - Set pdbids = new HashSet<>(); - - if (seq.getAllPDBEntries() != null - && queryBuilder.length() < MAX_QLENGTH) - { - for (PDBEntry entry : seq.getAllPDBEntries()) - { - if (isValidSeqName(entry.getId())) - { - String id = entry.getId().toLowerCase(); - queryBuilder.append("pdb_id:").append(id).append(" OR "); - isPDBRefsFound = true; - pdbids.add(id); - } - } - } - - List refs = seq.getDBRefs(); - if (refs != null && refs.size() != 0) - { - for (int ib = 0, nb = refs.size(); ib < nb; ib++) - { - DBRefEntry dbRef = refs.get(ib); - if (isValidSeqName(getDBRefId(dbRef)) - && queryBuilder.length() < MAX_QLENGTH) - { - if (dbRef.getSource().equalsIgnoreCase(DBRefSource.UNIPROT)) - { - queryBuilder.append("uniprot_accession:") - .append(getDBRefId(dbRef)).append(" OR "); - queryBuilder.append("uniprot_id:").append(getDBRefId(dbRef)) - .append(" OR "); - isUniProtRefsFound = true; - } - else if (dbRef.getSource().equalsIgnoreCase(DBRefSource.PDB)) - { - - String id = getDBRefId(dbRef).toLowerCase(); - if (!pdbids.contains(id)) - { - queryBuilder.append("pdb_id:").append(id).append(" OR "); - isPDBRefsFound = true; - pdbids.add(id); - } - } - else - { - seqRefs.add(getDBRefId(dbRef)); - } - } - } - } - - if (!isPDBRefsFound && !isUniProtRefsFound) - { - String seqName = seq.getName(); - seqName = sanitizeSeqName(seqName); - String[] names = seqName.toLowerCase().split("\\|"); - for (String name : names) - { - // System.out.println("Found name : " + name); - name.trim(); - if (isValidSeqName(name)) - { - seqRefs.add(name); - } - } - - for (String seqRef : seqRefs) - { - queryBuilder.append("text:").append(seqRef).append(" OR "); - } - } - - int endIndex = queryBuilder.lastIndexOf(" OR "); - if (queryBuilder.toString().length() < 6) - { - return null; - } - String query = queryBuilder.toString().substring(0, endIndex); - return query; - } - - /** - * Remove the following special characters from input string +, -, &, !, (, ), - * {, }, [, ], ^, ", ~, *, ?, :, \ - * - * @param seqName - * @return - */ - static String sanitizeSeqName(String seqName) - { - Objects.requireNonNull(seqName); - return seqName.replaceAll("\\[\\d*\\]", "") - .replaceAll("[^\\dA-Za-z|_]", "").replaceAll("\\s+", "+"); - } - - /** - * Ensures sequence ref names are not less than 3 characters and does not - * contain a database name - * - * @param seqName - * @return - */ - static boolean isValidSeqName(String seqName) - { - // System.out.println("seqName : " + seqName); - String ignoreList = "pdb,uniprot,swiss-prot"; - if (seqName.length() < 3) - { - return false; - } - if (seqName.contains(":")) - { - return false; - } - seqName = seqName.toLowerCase(); - for (String ignoredEntry : ignoreList.split(",")) - { - if (seqName.contains(ignoredEntry)) - { - return false; - } - } - return true; - } - - static String getDBRefId(DBRefEntry dbRef) - { - String ref = dbRef.getAccessionId().replaceAll("GO:", ""); - return ref; - } - - /** - * FTSRestClient specific query builder to recover associated structure data - * records for a sequence - * - * @param seq - * - seq to generate a query for - * @param wantedFields - * - fields to retrieve - * @param selectedFilterOpt - * - criterion for ranking results (e.g. resolution) - * @param b - * - sort ascending or descending - * @return - * @throws Exception - */ - public FTSRestResponse fetchStructuresMetaData(SequenceI seq, - Collection wantedFields, - FilterOption selectedFilterOpt, boolean b) throws Exception - { - FTSRestResponse resultList; - FTSRestRequest pdbRequest = new FTSRestRequest(); - pdbRequest.setAllowEmptySeq(false); - pdbRequest.setResponseSize(500); - pdbRequest.setFieldToSearchBy("("); - pdbRequest.setFieldToSortBy(selectedFilterOpt.getValue(), b); - pdbRequest.setWantedFields(wantedFields); - pdbRequest.setSearchTerm(buildQuery(seq) + ")"); - pdbRequest.setAssociatedSequence(seq); - resultList = pdbRestClient.executeRequest(pdbRequest); - - lastPdbRequest = pdbRequest; - return resultList; - } - - /** - * FTSRestClient specific query builder to pick top ranked entry from a - * fetchStructuresMetaData query - * - * @param seq - * - seq to generate a query for - * @param wantedFields - * - fields to retrieve - * @param selectedFilterOpt - * - criterion for ranking results (e.g. resolution) - * @param b - * - sort ascending or descending - * @return - * @throws Exception - */ - public FTSRestResponse selectFirstRankedQuery(SequenceI seq, - Collection wantedFields, String fieldToFilterBy, - boolean b) throws Exception - { - - FTSRestResponse resultList; - FTSRestRequest pdbRequest = new FTSRestRequest(); - if (fieldToFilterBy.equalsIgnoreCase("uniprot_coverage")) - { - pdbRequest.setAllowEmptySeq(false); - pdbRequest.setResponseSize(1); - pdbRequest.setFieldToSearchBy("("); - pdbRequest.setSearchTerm(buildQuery(seq) + ")"); - pdbRequest.setWantedFields(wantedFields); - pdbRequest.setAssociatedSequence(seq); - pdbRequest.setFacet(true); - pdbRequest.setFacetPivot(fieldToFilterBy + ",entry_entity"); - pdbRequest.setFacetPivotMinCount(1); - } - else - { - pdbRequest.setAllowEmptySeq(false); - pdbRequest.setResponseSize(1); - pdbRequest.setFieldToSearchBy("("); - pdbRequest.setFieldToSortBy(fieldToFilterBy, b); - pdbRequest.setSearchTerm(buildQuery(seq) + ")"); - pdbRequest.setWantedFields(wantedFields); - pdbRequest.setAssociatedSequence(seq); - } - resultList = pdbRestClient.executeRequest(pdbRequest); - - lastPdbRequest = pdbRequest; - return resultList; - } - - public TableModel getTableModel( - Collection discoveredStructuresSet) - { - return FTSRestResponse.getTableModel(lastPdbRequest, - discoveredStructuresSet); - } - - public FTSDataColumnPreferences getInitialFieldPreferences() - { - // TODO Auto-generated method stub - return null; - } - -} \ No newline at end of file diff --git a/src/jalview/gui/structurechooser/StructureChooserQuerySource.java b/src/jalview/gui/structurechooser/StructureChooserQuerySource.java new file mode 100644 index 0000000..9861b1a --- /dev/null +++ b/src/jalview/gui/structurechooser/StructureChooserQuerySource.java @@ -0,0 +1,207 @@ +package jalview.gui.structurechooser; + +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.Vector; + +import javax.swing.JTable; +import javax.swing.table.TableModel; + +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; +import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource; +import jalview.fts.core.FTSRestRequest; +import jalview.fts.core.FTSRestResponse; +import jalview.fts.service.pdb.PDBFTSRestClient; +import jalview.jbgui.GStructureChooser.FilterOption; + +/** + * logic for querying sources of structural data for structures of sequences + * + * @author jprocter + * + * @param + */ +public abstract class StructureChooserQuerySource +{ + protected FTSRestRequest lastPdbRequest; + + protected FTSRestClientI pdbRestClient; + + protected FTSDataColumnPreferences docFieldPrefs; + + /** + * max length of a GET URL (probably :( ) + */ + protected static int MAX_QLENGTH = 7820; + + public StructureChooserQuerySource() + { + } + + public static StructureChooserQuerySource getPDBfts() + { + return new PDBStructureChooserQuerySource(); + } + + public static StructureChooserQuerySource getTDBfts() + { + return new ThreeDBStructureChooserQuerySource(); + } + + public FTSDataColumnPreferences getDocFieldPrefs() + { + return docFieldPrefs; + } + + public void setDocFieldPrefs(FTSDataColumnPreferences docFieldPrefs) + { + this.docFieldPrefs = docFieldPrefs; + } + + public FTSDataColumnPreferences getInitialFieldPreferences() + { + return docFieldPrefs; + } + + + /** + * Builds a query string for a given sequences using its DBRef entries + * + * @param seq + * the sequences to build a query for + * @return the built query string + */ + + public abstract String buildQuery(SequenceI seq); + + + /** + * Remove the following special characters from input string +, -, &, !, (, ), + * {, }, [, ], ^, ", ~, *, ?, :, \ + * + * @param seqName + * @return + */ + public static String sanitizeSeqName(String seqName) + { + Objects.requireNonNull(seqName); + return seqName.replaceAll("\\[\\d*\\]", "") + .replaceAll("[^\\dA-Za-z|_]", "").replaceAll("\\s+", "+"); + } + + /** + * Ensures sequence ref names are not less than 3 characters and does not + * contain a database name + * + * @param seqName + * @return + */ + static boolean isValidSeqName(String seqName) + { + // System.out.println("seqName : " + seqName); + String ignoreList = "pdb,uniprot,swiss-prot"; + if (seqName.length() < 3) + { + return false; + } + if (seqName.contains(":")) + { + return false; + } + seqName = seqName.toLowerCase(); + for (String ignoredEntry : ignoreList.split(",")) + { + if (seqName.contains(ignoredEntry)) + { + return false; + } + } + return true; + } + + static String getDBRefId(DBRefEntry dbRef) + { + String ref = dbRef.getAccessionId().replaceAll("GO:", ""); + return ref; + } + + static PDBEntry getFindEntry(String id, Vector pdbEntries) + { + Objects.requireNonNull(id); + Objects.requireNonNull(pdbEntries); + PDBEntry foundEntry = null; + for (PDBEntry entry : pdbEntries) + { + if (entry.getId().equalsIgnoreCase(id)) + { + return entry; + } + } + return foundEntry; + } + + /** + * FTSRestClient specific query builder to recover associated structure data + * records for a sequence + * + * @param seq + * - seq to generate a query for + * @param wantedFields + * - fields to retrieve + * @param selectedFilterOpt + * - criterion for ranking results (e.g. resolution) + * @param b + * - sort ascending or descending + * @return + * @throws Exception + */ + public abstract FTSRestResponse fetchStructuresMetaData(SequenceI seq, + Collection wantedFields, + FilterOption selectedFilterOpt, boolean b) throws Exception; + + /** + * FTSRestClient specific query builder to pick top ranked entry from a + * fetchStructuresMetaData query + * + * @param seq + * - seq to generate a query for + * @param wantedFields + * - fields to retrieve + * @param selectedFilterOpt + * - criterion for ranking results (e.g. resolution) + * @param b + * - sort ascending or descending + * @return + * @throws Exception + */ + public abstract FTSRestResponse selectFirstRankedQuery(SequenceI seq, + Collection wantedFields, String fieldToFilterBy, + boolean b) throws Exception; + + /** + * + * @param discoveredStructuresSet + * @return the table model for the given result set for this engine + */ + public TableModel getTableModel( + Collection discoveredStructuresSet) + { + return FTSRestResponse.getTableModel(lastPdbRequest, + discoveredStructuresSet); + } + + public abstract PDBEntry[] collectSelectedRows(JTable restable, + int[] selectedRows, List selectedSeqsToView); + +} \ No newline at end of file diff --git a/test/jalview/gui/StructureChooserTest.java b/test/jalview/gui/StructureChooserTest.java index 66e606a..31f5f8b 100644 --- a/test/jalview/gui/StructureChooserTest.java +++ b/test/jalview/gui/StructureChooserTest.java @@ -30,6 +30,8 @@ import jalview.datamodel.PDBEntry; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceI; import jalview.fts.api.FTSData; +import jalview.gui.structurechooser.PDBStructureChooserQuerySource; +import jalview.gui.structurechooser.StructureChooserQuerySource; import jalview.jbgui.GStructureChooser.FilterOption; import jalview.ws.params.InvalidArgumentException; @@ -165,17 +167,17 @@ public class StructureChooserTest public void sanitizeSeqNameTest() { String name = "ab_cdEF|fwxyz012349"; - assertEquals(name, StructureChooserQuerySource.sanitizeSeqName(name)); + assertEquals(name, PDBStructureChooserQuerySource.sanitizeSeqName(name)); // remove a [nn] substring name = "abcde12[345]fg"; - assertEquals("abcde12fg", StructureChooserQuerySource.sanitizeSeqName(name)); + assertEquals("abcde12fg", PDBStructureChooserQuerySource.sanitizeSeqName(name)); // remove characters other than a-zA-Z0-9 | or _ name = "ab[cd],.\t£$*!- \\\"@:e"; - assertEquals("abcde", StructureChooserQuerySource.sanitizeSeqName(name)); + assertEquals("abcde", PDBStructureChooserQuerySource.sanitizeSeqName(name)); name = "abcde12[345a]fg"; - assertEquals("abcde12345afg", StructureChooserQuerySource.sanitizeSeqName(name)); + assertEquals("abcde12345afg", PDBStructureChooserQuerySource.sanitizeSeqName(name)); } } -- 1.7.10.2