Clover icon

Coverage Report

  1. Project Clover database Mon Nov 18 2024 09:38:20 GMT
  2. Package jalview.gui.structurechooser

File PDBStructureChooserQuerySource.java

 

Coverage histogram

../../../img/srcFileCovDistChart7.png
21% of files have more coverage

Code metrics

36
126
12
1
393
273
34
0.27
10.5
12
2.83

Classes

Class Line # Actions
PDBStructureChooserQuerySource 56 126 34
0.6264367762.6%
 

Contributing tests

This file is covered by 17 tests. .

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
7    * Jalview is free software: you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation, either version 3
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package jalview.gui.structurechooser;
22   
23    import java.util.Locale;
24   
25    import java.util.ArrayList;
26    import java.util.Collection;
27    import java.util.HashSet;
28    import java.util.LinkedHashSet;
29    import java.util.List;
30    import java.util.Objects;
31    import java.util.Set;
32   
33    import javax.swing.JTable;
34   
35    import jalview.datamodel.DBRefEntry;
36    import jalview.datamodel.DBRefSource;
37    import jalview.datamodel.PDBEntry;
38    import jalview.datamodel.SequenceI;
39    import jalview.fts.api.FTSData;
40    import jalview.fts.api.FTSDataColumnI;
41    import jalview.fts.api.FTSRestClientI;
42    import jalview.fts.core.FTSDataColumnPreferences;
43    import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource;
44    import jalview.fts.core.FTSRestRequest;
45    import jalview.fts.core.FTSRestResponse;
46    import jalview.fts.service.pdb.PDBFTSRestClient;
47    import jalview.jbgui.FilterOption;
48    import jalview.structure.PDBEntryUtils;
49    import jalview.util.MessageManager;
50   
51    /**
52    * logic for querying the PDBe API for structures of sequences
53    *
54    * @author jprocter
55    */
 
56    public class PDBStructureChooserQuerySource
57    extends StructureChooserQuerySource
58    {
59   
60    private static int MAX_QLENGTH = 7820;
61   
62    protected FTSRestRequest lastPdbRequest;
63   
64    protected FTSRestClientI pdbRestClient;
65   
 
66  22 toggle public PDBStructureChooserQuerySource()
67    {
68  22 pdbRestClient = PDBFTSRestClient.getInstance();
69  22 docFieldPrefs = new FTSDataColumnPreferences(
70    PreferenceSource.STRUCTURE_CHOOSER,
71    PDBFTSRestClient.getInstance());
72   
73    }
74   
75    /**
76    * Builds a query string for a given sequences using its DBRef entries
77    *
78    * @param seq
79    * the sequences to build a query for
80    * @return the built query string
81    */
82   
 
83  6 toggle public String buildQuery(SequenceI seq)
84    {
85  6 boolean isPDBRefsFound = false;
86  6 boolean isUniProtRefsFound = false;
87  6 StringBuilder queryBuilder = new StringBuilder();
88  6 Set<String> seqRefs = new LinkedHashSet<>();
89  6 SequenceI ds = seq.getDatasetSequence();
90  6 while (ds.getDatasetSequence()!=null) {
91  0 ds = ds.getDatasetSequence();
92    }
93   
94    /*
95    * note PDBs as DBRefEntry so they are not duplicated in query
96    */
97  6 Set<String> pdbids = new HashSet<>();
98  6 if (queryBuilder.length() < MAX_QLENGTH)
99    {
100  6 Set<PDBEntry> gatheredEntries = PDBEntryUtils.gatherPDBEntries(seq, true);
101  6 for (PDBEntry entry : gatheredEntries)
102    {
103  2 if (isValidSeqName(entry.getId()))
104    {
105  2 String id = entry.getId().toLowerCase(Locale.ROOT);
106  2 queryBuilder.append("pdb_id:").append(id).append(" OR ");
107  2 isPDBRefsFound = true;
108  2 pdbids.add(id);
109    }
110    }
111    }
112   
113  6 List<DBRefEntry> refs = seq.getDBRefs();
114  6 if (refs != null && refs.size() != 0)
115    {
116  24 for (int ib = 0, nb = refs.size(); ib < nb; ib++)
117    {
118  19 DBRefEntry dbRef = refs.get(ib);
119  19 if (isValidSeqName(getDBRefId(dbRef))
120    && queryBuilder.length() < MAX_QLENGTH)
121    {
122  19 if (dbRef.getSource().equalsIgnoreCase(DBRefSource.UNIPROT))
123    {
124  2 queryBuilder.append("uniprot_accession:")
125    .append(getDBRefId(dbRef)).append(" OR ");
126  2 queryBuilder.append("uniprot_id:").append(getDBRefId(dbRef))
127    .append(" OR ");
128  2 isUniProtRefsFound = true;
129    }
130  17 else if (dbRef.getSource().equalsIgnoreCase(DBRefSource.PDB))
131    {
132   
133  1 String id = getDBRefId(dbRef).toLowerCase(Locale.ROOT);
134  1 if (!pdbids.contains(id))
135    {
136  1 queryBuilder.append("pdb_id:").append(id).append(" OR ");
137  1 isPDBRefsFound = true;
138  1 pdbids.add(id);
139    }
140    }
141    else
142    {
143  16 seqRefs.add(getDBRefId(dbRef));
144    }
145    }
146    }
147    }
148   
149  6 if (!isPDBRefsFound && !isUniProtRefsFound && pdbids.isEmpty())
150    {
151  2 String seqName = seq.getName();
152  2 seqName = sanitizeSeqName(seqName);
153  2 String[] names = seqName.toLowerCase(Locale.ROOT).split("\\|");
154  2 for (String name : names)
155    {
156    // jalview.bin.Console.outPrintln("Found name : " + name);
157  8 name.trim();
158  8 if (isValidSeqName(name))
159    {
160  4 seqRefs.add(name);
161    }
162    }
163   
164  2 for (String seqRef : seqRefs)
165    {
166  6 queryBuilder.append("text:").append(seqRef).append(" OR ");
167    }
168    }
169   
170  6 int endIndex = queryBuilder.lastIndexOf(" OR ");
171  6 if (queryBuilder.toString().length() < 6)
172    {
173  0 return null;
174    }
175  6 String query = queryBuilder.toString().substring(0, endIndex);
176  6 return query;
177    }
178   
179    /**
180    * Remove the following special characters from input string +, -, &, !, (, ),
181    * {, }, [, ], ^, ", ~, *, ?, :, \
182    *
183    * @param seqName
184    * @return
185    */
 
186  10 toggle public static String sanitizeSeqName(String seqName)
187    {
188  10 Objects.requireNonNull(seqName);
189  10 return seqName.replaceAll("\\[\\d*\\]", "")
190    .replaceAll("[^\\dA-Za-z|_]", "").replaceAll("\\s+", "+");
191    }
192   
193    /**
194    * Ensures sequence ref names are not less than 3 characters and does not
195    * contain a database name
196    *
197    * @param seqName
198    * @return
199    */
 
200  29 toggle static boolean isValidSeqName(String seqName)
201    {
202    // jalview.bin.Console.outPrintln("seqName : " + seqName);
203  29 String ignoreList = "pdb,uniprot,swiss-prot";
204  29 if (seqName.length() < 3)
205    {
206  2 return false;
207    }
208  27 if (seqName.contains(":"))
209    {
210  0 return false;
211    }
212  27 seqName = seqName.toLowerCase(Locale.ROOT);
213  27 for (String ignoredEntry : ignoreList.split(","))
214    {
215  77 if (seqName.contains(ignoredEntry))
216    {
217  2 return false;
218    }
219    }
220  25 return true;
221    }
222   
 
223  40 toggle static String getDBRefId(DBRefEntry dbRef)
224    {
225  40 String ref = dbRef.getAccessionId().replaceAll("GO:", "");
226  40 return ref;
227    }
228   
229    /**
230    * FTSRestClient specific query builder to recover associated structure data
231    * records for a sequence
232    *
233    * @param seq
234    * - seq to generate a query for
235    * @param wantedFields
236    * - fields to retrieve
237    * @param selectedFilterOpt
238    * - criterion for ranking results (e.g. resolution)
239    * @param b
240    * - sort ascending or descending
241    * @return
242    * @throws Exception
243    */
 
244  2 toggle public FTSRestResponse fetchStructuresMetaData(SequenceI seq,
245    Collection<FTSDataColumnI> wantedFields,
246    FilterOption selectedFilterOpt, boolean b) throws Exception
247    {
248  2 FTSRestResponse resultList;
249  2 FTSRestRequest pdbRequest = new FTSRestRequest();
250  2 pdbRequest.setAllowEmptySeq(false);
251  2 pdbRequest.setResponseSize(500);
252  2 pdbRequest.setFieldToSearchBy("(");
253  2 pdbRequest.setFieldToSortBy(selectedFilterOpt.getValue(), b);
254  2 pdbRequest.setWantedFields(wantedFields);
255  2 pdbRequest.setSearchTerm(buildQuery(seq) + ")");
256  2 pdbRequest.setAssociatedSequence(seq);
257  2 resultList = pdbRestClient.executeRequest(pdbRequest);
258   
259  0 lastPdbRequest = pdbRequest;
260  0 return resultList;
261    }
262   
 
263  11 toggle public List<FilterOption> getAvailableFilterOptions(String VIEWS_FILTER)
264    {
265  11 List<FilterOption> filters = new ArrayList<FilterOption>();
266  11 filters.add(new FilterOption(
267    "PDBe " + MessageManager.getString("label.best_quality"),
268    "overall_quality", VIEWS_FILTER, false, this));
269  11 filters.add(new FilterOption(
270    "PDBe " + MessageManager.getString("label.best_resolution"),
271    "resolution", VIEWS_FILTER, false, this));
272  11 filters.add(new FilterOption(
273    "PDBe " + MessageManager.getString("label.most_protein_chain"),
274    "number_of_protein_chains", VIEWS_FILTER, false, this));
275  11 filters.add(new FilterOption(
276    "PDBe " + MessageManager
277    .getString("label.most_bound_molecules"),
278    "number_of_bound_molecules", VIEWS_FILTER, false, this));
279  11 filters.add(new FilterOption(
280    "PDBe " + MessageManager
281    .getString("label.most_polymer_residues"),
282    "number_of_polymer_residues", VIEWS_FILTER, true, this));
283   
284  11 return filters;
285    }
286   
 
287  0 toggle @Override
288    public boolean needsRefetch(FilterOption selectedFilterOpt)
289    {
290    // PDBe queries never need a refetch first
291  0 return false;
292    }
293   
294    /**
295    * FTSRestClient specific query builder to pick top ranked entry from a
296    * fetchStructuresMetaData query
297    *
298    * @param seq
299    * - seq to generate a query for
300    * @param wantedFields
301    * - fields to retrieve
302    * @param selectedFilterOpt
303    * - criterion for ranking results (e.g. resolution)
304    * @param b
305    * - sort ascending or descending
306    * @return
307    * @throws Exception
308    */
 
309  0 toggle public FTSRestResponse selectFirstRankedQuery(SequenceI seq,
310    Collection<FTSData> collectedResults,
311    Collection<FTSDataColumnI> wantedFields, String fieldToFilterBy,
312    boolean b) throws Exception
313    {
314   
315  0 FTSRestResponse resultList;
316  0 FTSRestRequest pdbRequest = new FTSRestRequest();
317  0 if (fieldToFilterBy.equalsIgnoreCase("uniprot_coverage"))
318    {
319  0 pdbRequest.setAllowEmptySeq(false);
320  0 pdbRequest.setResponseSize(1);
321  0 pdbRequest.setFieldToSearchBy("(");
322  0 pdbRequest.setSearchTerm(buildQuery(seq) + ")");
323  0 pdbRequest.setWantedFields(wantedFields);
324  0 pdbRequest.setAssociatedSequence(seq);
325  0 pdbRequest.setFacet(true);
326  0 pdbRequest.setFacetPivot(fieldToFilterBy + ",entry_entity");
327  0 pdbRequest.setFacetPivotMinCount(1);
328    }
329    else
330    {
331  0 pdbRequest.setAllowEmptySeq(false);
332  0 pdbRequest.setResponseSize(1);
333  0 pdbRequest.setFieldToSearchBy("(");
334  0 pdbRequest.setFieldToSortBy(fieldToFilterBy, b);
335  0 pdbRequest.setSearchTerm(buildQuery(seq) + ")");
336  0 pdbRequest.setWantedFields(wantedFields);
337  0 pdbRequest.setAssociatedSequence(seq);
338    }
339  0 resultList = pdbRestClient.executeRequest(pdbRequest);
340   
341  0 lastPdbRequest = pdbRequest;
342  0 return resultList;
343    }
344   
 
345  0 toggle @Override
346    public PDBEntry[] collectSelectedRows(JTable restable, int[] selectedRows,
347    List<SequenceI> selectedSeqsToView)
348    {
349  0 int refSeqColIndex = restable.getColumn("Ref Sequence").getModelIndex();
350   
351  0 PDBEntry[] pdbEntriesToView = new PDBEntry[selectedRows.length];
352  0 int count = 0;
353  0 int idColumnIndex = -1;
354  0 idColumnIndex = restable.getColumn("PDB Id").getModelIndex();
355   
356  0 for (int row : selectedRows)
357    {
358   
359  0 String pdbIdStr = restable.getValueAt(row, idColumnIndex).toString();
360  0 SequenceI selectedSeq = (SequenceI) restable.getValueAt(row,
361    refSeqColIndex);
362  0 selectedSeqsToView.add(selectedSeq);
363  0 PDBEntry pdbEntry = selectedSeq.getPDBEntry(pdbIdStr);
364  0 if (pdbEntry == null)
365    {
366  0 pdbEntry = getFindEntry(pdbIdStr, selectedSeq.getAllPDBEntries());
367    }
368   
369  0 if (pdbEntry == null)
370    {
371  0 pdbEntry = new PDBEntry();
372  0 pdbEntry.setId(pdbIdStr);
373  0 pdbEntry.setType(PDBEntry.Type.MMCIF);
374  0 selectedSeq.getDatasetSequence().addPDBId(pdbEntry);
375    }
376  0 pdbEntriesToView[count++] = pdbEntry;
377    }
378  0 return pdbEntriesToView;
379    }
380   
 
381  0 toggle @Override
382    protected FTSRestRequest getLastFTSRequest()
383    {
384  0 return lastPdbRequest;
385    }
386   
 
387  32 toggle public FTSRestResponse executePDBFTSRestRequest(FTSRestRequest pdbRequest)
388    throws Exception
389    {
390  32 return pdbRestClient.executeRequest(pdbRequest);
391    }
392   
393    }