1 package jalview.gui.structurechooser;
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.HashSet;
6 import java.util.LinkedHashSet;
10 import javax.swing.JTable;
12 import jalview.datamodel.DBRefEntry;
13 import jalview.datamodel.DBRefSource;
14 import jalview.datamodel.PDBEntry;
15 import jalview.datamodel.SequenceI;
16 import jalview.fts.api.FTSData;
17 import jalview.fts.api.FTSDataColumnI;
18 import jalview.fts.api.FTSRestClientI;
19 import jalview.fts.core.FTSDataColumnPreferences;
20 import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource;
21 import jalview.fts.core.FTSRestRequest;
22 import jalview.fts.core.FTSRestResponse;
23 import jalview.fts.service.threedbeacons.TDBeaconsFTSRestClient;
24 import jalview.jbgui.FilterOption;
25 import jalview.util.MessageManager;
28 * logic for querying the 3DBeacons API for structures of sequences
32 public class ThreeDBStructureChooserQuerySource
33 extends StructureChooserQuerySource
36 private static int MAX_QLENGTH = 7820;
38 protected FTSRestRequest lastTdbRequest;
40 protected FTSRestClientI tdbRestClient;
42 private FTSRestRequest lastPdbRequest;
44 public ThreeDBStructureChooserQuerySource()
46 tdbRestClient = TDBeaconsFTSRestClient.getInstance();
47 docFieldPrefs = new FTSDataColumnPreferences(
48 PreferenceSource.STRUCTURE_CHOOSER,
49 TDBeaconsFTSRestClient.getInstance());
54 * Builds a query string for a given sequences using its DBRef entries 3d
55 * Beacons is only useful for uniprot IDs
58 * the sequences to build a query for
59 * @return the built query string
62 public String buildQuery(SequenceI seq)
64 boolean isPDBRefsFound = false;
65 boolean isUniProtRefsFound = false;
66 StringBuilder queryBuilder = new StringBuilder();
67 Set<String> seqRefs = new LinkedHashSet<>();
70 * note PDBs as DBRefEntry so they are not duplicated in query
72 Set<String> pdbids = new HashSet<>();
74 List<DBRefEntry> refs = seq.getDBRefs();
75 if (refs != null && refs.size() != 0)
77 for (int ib = 0, nb = refs.size(); ib < nb; ib++)
79 DBRefEntry dbRef = refs.get(ib);
80 if (isValidSeqName(getDBRefId(dbRef))
81 && queryBuilder.length() < MAX_QLENGTH)
83 if (dbRef.getSource().equalsIgnoreCase(DBRefSource.UNIPROT)
84 && dbRef.isCanonical())
86 // TODO: pick best Uniprot accession
87 isUniProtRefsFound = true;
88 return getDBRefId(dbRef);
98 * Ensures sequence ref names are not less than 3 characters and does not
99 * contain a database name
104 static boolean isValidSeqName(String seqName)
106 // System.out.println("seqName : " + seqName);
107 String ignoreList = "pdb,uniprot,swiss-prot";
108 if (seqName.length() < 3)
112 if (seqName.contains(":"))
116 seqName = seqName.toLowerCase();
117 for (String ignoredEntry : ignoreList.split(","))
119 if (seqName.contains(ignoredEntry))
127 static String getDBRefId(DBRefEntry dbRef)
129 String ref = dbRef.getAccessionId().replaceAll("GO:", "");
134 * FTSRestClient specific query builder to recover associated structure data
135 * records for a sequence
138 * - seq to generate a query for
139 * @param wantedFields
140 * - fields to retrieve
141 * @param selectedFilterOpt
142 * - criterion for ranking results (e.g. resolution)
144 * - sort ascending or descending
148 public FTSRestResponse fetchStructuresMetaData(SequenceI seq,
149 Collection<FTSDataColumnI> wantedFields,
150 FilterOption selectedFilterOpt, boolean b) throws Exception
152 FTSRestResponse resultList;
153 FTSRestRequest tdbRequest = getTDBeaconsRequest(seq, wantedFields);
154 resultList = tdbRestClient.executeRequest(tdbRequest);
156 lastTdbRequest = tdbRequest;
160 private FTSRestRequest getTDBeaconsRequest(SequenceI seq,
161 Collection<FTSDataColumnI> wantedFields)
163 FTSRestRequest pdbRequest = new FTSRestRequest();
164 pdbRequest.setAllowEmptySeq(false);
165 pdbRequest.setResponseSize(500);
166 pdbRequest.setWantedFields(wantedFields);
167 String query = buildQuery(seq);
172 pdbRequest.setSearchTerm(query + ".json");
173 pdbRequest.setAssociatedSequence(seq);
178 public List<FilterOption> getAvailableFilterOptions(String VIEWS_FILTER)
180 List<FilterOption> filters = new ArrayList<FilterOption>();
182 new FilterOption(MessageManager.getString("label.best_quality"),
183 "overall_quality", VIEWS_FILTER, false));
184 filters.add(new FilterOption(
185 MessageManager.getString("label.best_resolution"), "resolution",
186 VIEWS_FILTER, false));
187 filters.add(new FilterOption(
188 MessageManager.getString("label.most_protein_chain"),
189 "number_of_protein_chains", VIEWS_FILTER, false));
190 filters.add(new FilterOption(
191 MessageManager.getString("label.most_bound_molecules"),
192 "number_of_bound_molecules", VIEWS_FILTER, false));
193 filters.add(new FilterOption(
194 MessageManager.getString("label.most_polymer_residues"),
195 "number_of_polymer_residues", VIEWS_FILTER, true));
201 * FTSRestClient specific query builder to pick top ranked entry from a
202 * fetchStructuresMetaData query
205 * - seq to generate a query for
206 * @param wantedFields
207 * - fields to retrieve
208 * @param selectedFilterOpt
209 * - criterion for ranking results (e.g. resolution)
211 * - sort ascending or descending
215 public FTSRestResponse selectFirstRankedQuery(SequenceI seq,
216 Collection<FTSDataColumnI> wantedFields, String fieldToFilterBy,
217 boolean b) throws Exception
220 FTSRestResponse resultList;
221 FTSRestRequest pdbRequest = getTDBeaconsRequest(seq, wantedFields);
222 if (pdbRequest == null)
226 pdbRequest.setResponseSize(1);
227 resultList = tdbRestClient.executeRequest(pdbRequest);
229 // TODO: client side filtering - sort results and pick top one (or N)
231 lastTdbRequest = pdbRequest;
236 public PDBEntry[] collectSelectedRows(JTable restable, int[] selectedRows,
237 List<SequenceI> selectedSeqsToView)
239 int refSeqColIndex = restable.getColumn("Ref Sequence").getModelIndex();
241 PDBEntry[] pdbEntriesToView = new PDBEntry[selectedRows.length];
243 int idColumnIndex = restable.getColumn("Model id").getModelIndex();
244 int urlColumnIndex = restable.getColumn("Url").getModelIndex();
245 int typeColumnIndex = restable.getColumn("Provider").getModelIndex();
246 int categoryColumnIndex = restable.getColumn("Model Category")
249 for (int row : selectedRows)
251 // unique id - could be a horrible hash
253 String pdbIdStr = restable.getValueAt(row, idColumnIndex).toString();
254 String urlStr = restable.getValueAt(row, urlColumnIndex).toString();
255 String typeColumn = restable.getValueAt(row, typeColumnIndex)
257 SequenceI selectedSeq = (SequenceI) restable.getValueAt(row,
259 selectedSeqsToView.add(selectedSeq);
260 PDBEntry pdbEntry = selectedSeq.getPDBEntry(pdbIdStr);
261 if (pdbEntry == null)
263 pdbEntry = getFindEntry(pdbIdStr, selectedSeq.getAllPDBEntries());
266 if (pdbEntry == null)
268 pdbEntry = new PDBEntry();
269 pdbEntry.setId(pdbIdStr);
270 pdbEntry.setType(PDBEntry.Type.MMCIF);
271 if (!"PDBe".equalsIgnoreCase(typeColumn))
273 pdbEntry.setRetrievalUrl(urlStr);
275 selectedSeq.getDatasetSequence().addPDBId(pdbEntry);
277 pdbEntriesToView[count++] = pdbEntry;
279 return pdbEntriesToView;
283 protected FTSRestRequest getLastFTSRequest()
285 return lastTdbRequest;
289 * generate a query for PDBFTS to retrieve structure metadata
291 * @param ftsRestRequest
296 public String buildPDBFTSQueryFor(FTSRestResponse upResponse)
298 List<String> pdbIds = new ArrayList<String>();
299 int idx_modelId = getLastFTSRequest().getFieldIndex("Model id");
300 int idx_provider = getLastFTSRequest().getFieldIndex("Provider");
301 for (FTSData row : upResponse.getSearchSummary())
303 String id = (String) row.getSummaryData()[idx_modelId];
304 String provider = (String) row.getSummaryData()[idx_provider];
305 if ("PDBe".equalsIgnoreCase(provider))
310 return String.join(" OR ", pdbIds).toString();
314 * query PDBe for structure metadata
318 * @return FTSRestResponse via PDBStructureChooserQuerySource
320 public FTSRestResponse fetchStructuresMetaDataFor(
321 PDBStructureChooserQuerySource pdbquery,
322 FTSRestResponse upResponse) throws Exception
325 String pdb_Query = buildPDBFTSQueryFor(upResponse);
327 FTSRestResponse resultList;
328 FTSRestRequest pdbRequest = new FTSRestRequest();
329 pdbRequest.setAllowEmptySeq(false);
330 pdbRequest.setResponseSize(500);
331 pdbRequest.setFieldToSearchBy("(");
332 // pdbRequest.setFieldToSortBy("pdb_id");
333 pdbRequest.setWantedFields(
334 pdbquery.getDocFieldPrefs().getStructureSummaryFields());
335 pdbRequest.setSearchTerm(pdb_Query + ")");
336 resultList = pdbquery.executePDBFTSRestRequest(pdbRequest);
338 lastPdbRequest = pdbRequest;
342 public FTSRestResponse joinResponses(FTSRestResponse upResponse,
343 FTSRestResponse pdbResponse)
345 int idx_provider = getLastFTSRequest().getFieldIndex("Provider");
347 int idx_modelId = getLastFTSRequest().getFieldIndex("Model id");
348 int pdbIdx = lastPdbRequest.getFieldIndex("pdb_id");
349 for (FTSData row : upResponse.getSearchSummary())
351 String id = (String) row.getSummaryData()[idx_modelId];
352 String provider = (String) row.getSummaryData()[idx_provider];
353 if ("PDBe".equalsIgnoreCase(provider))
355 for (FTSData pdbrow : pdbResponse.getSearchSummary())
357 String pdbid = (String) pdbrow.getSummaryData()[pdbIdx];
358 if (id.equalsIgnoreCase(pdbid))
360 // often multiple entries per PDB ID so we bail after first
362 // append to FTSRestResponse array
367 // TODO Auto-generated method stub