2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3 * Copyright (C) 2014 The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
24 import jalview.datamodel.DBRefEntry;
25 import jalview.datamodel.PDBEntry;
26 import jalview.datamodel.SequenceI;
27 import jalview.jbgui.GStructureChooser;
28 import jalview.util.MessageManager;
29 import jalview.ws.dbsources.PDBRestClient;
30 import jalview.ws.dbsources.PDBRestClient.PDBDocField;
31 import jalview.ws.uimodel.PDBRestRequest;
32 import jalview.ws.uimodel.PDBRestResponse;
33 import jalview.ws.uimodel.PDBRestResponse.PDBResponseSummary;
35 import java.awt.event.ItemEvent;
36 import java.util.ArrayList;
37 import java.util.Collection;
38 import java.util.HashSet;
39 import java.util.List;
40 import java.util.Vector;
42 import javax.swing.JCheckBox;
43 import javax.swing.JOptionPane;
44 import javax.swing.ListSelectionModel;
47 * Provides the behaviors for the Structure chooser Panel
52 @SuppressWarnings("serial")
53 public class StructureChooser extends GStructureChooser
55 private boolean structuresDiscovered = false;
57 private SequenceI selectedSequence;
59 private SequenceI[] selectedSequences;
61 private IProgressIndicator progressIndicator;
63 private Collection<PDBResponseSummary> discoveredStructuresSet = new HashSet<PDBResponseSummary>();
65 private PDBRestRequest pdbRequest;
67 private PDBRestClient pdbRestCleint;
70 public StructureChooser(SequenceI[] selectedSeqs, SequenceI selectedSeq,
74 this.selectedSequence = selectedSeq;
75 this.selectedSequences = selectedSeqs;
76 this.progressIndicator = (ap == null) ? null : ap.alignFrame;
81 * Initializes parameters used by the Structure Chooser Panel
85 Thread discoverPDBStructuresThread = new Thread(new Runnable()
90 long startTime = System.currentTimeMillis();
91 String msg = MessageManager.getString("status.fetching_db_refs");
92 updateProgressIndicator(msg, startTime);
93 fetchStructuresMetaData();
94 populateFilterComboBox();
95 updateProgressIndicator(null, startTime);
96 mainFrame.setVisible(true);
100 discoverPDBStructuresThread.start();
104 * Updates the progress indicator with the specified message
107 * displayed message for the operation
109 * unique handle for this indicator
111 public void updateProgressIndicator(String message, long id)
113 if (progressIndicator != null)
115 progressIndicator.setProgressBar(message, id);
120 * Retrieve meta-data for all the structure(s) for a given sequence(s) in a
123 public void fetchStructuresMetaData()
125 long startTime = System.currentTimeMillis();
126 List<PDBDocField> wantedFields = new ArrayList<PDBDocField>();
127 // wantedFields.add(PDBDocField.MOLECULE_TYPE);
128 wantedFields.add(PDBDocField.PDB_ID);
129 // wantedFields.add(PDBDocField.GENUS);
130 // wantedFields.add(PDBDocField.GENE_NAME);
131 wantedFields.add(PDBDocField.TITLE);
132 pdbRequest = new PDBRestRequest();
133 pdbRequest.setAllowEmptySeq(false);
134 pdbRequest.setResponseSize(500);
135 pdbRequest.setFieldToSearchBy("(text:");
136 pdbRequest.setWantedFields(wantedFields);
137 for (SequenceI seq : selectedSequences)
139 pdbRequest.setSearchTerm(buildQuery(seq) + ")");
140 pdbRequest.setAssociatedSequence(seq.getName());
141 pdbRestCleint = new PDBRestClient();
142 PDBRestResponse resultList = pdbRestCleint.executeRequest(pdbRequest);
143 if (resultList.getSearchSummary() != null
144 && !resultList.getSearchSummary().isEmpty())
146 discoveredStructuresSet.addAll(resultList.getSearchSummary());
147 updateSequenceDbRef(seq, resultList.getSearchSummary());
151 int noOfStructuresFound = 0;
152 if (discoveredStructuresSet != null
153 && !discoveredStructuresSet.isEmpty())
155 jList_FoundStructures.setModel(PDBRestResponse
156 .getListModel(discoveredStructuresSet));
157 tbl_summary.setModel(PDBRestResponse.getTableModel(pdbRequest,
158 discoveredStructuresSet));
159 // resizeColumnWidth(summaryTable);
160 structuresDiscovered = true;
161 noOfStructuresFound = discoveredStructuresSet.size();
163 String totalTime = (System.currentTimeMillis() - startTime)
165 mainFrame.setTitle("Structure Chooser - " + noOfStructuresFound
166 + " Found (" + totalTime + ")");
170 * Update the DBRef entry for a given sequence with values retrieved from
174 * the Sequence to update its DBRef entry
175 * @param responseSummaries
176 * a collection of PDBResponseSummary
178 public void updateSequenceDbRef(SequenceI seq,
179 Collection<PDBResponseSummary> responseSummaries)
181 for (PDBResponseSummary response : responseSummaries)
183 PDBEntry newEntry = new PDBEntry();
184 newEntry.setId(response.getPdbId());
185 newEntry.setType("PDB");
186 seq.getDatasetSequence().addPDBId(newEntry);
191 * Builds a query string for a given sequences using its DBRef entries
194 * the sequences to build a query for
195 * @return the built query string
197 @SuppressWarnings("unchecked")
198 public static String buildQuery(SequenceI seq)
200 String query = seq.getName();
201 StringBuilder queryBuilder = new StringBuilder();
204 if (seq.getPDBId() != null)
206 for (PDBEntry entry : (Vector<PDBEntry>) seq.getPDBId())
208 queryBuilder.append("text:").append(entry.getId()).append(" OR ");
212 if (seq.getDBRef() != null && seq.getDBRef().length != 0)
214 for (DBRefEntry dbRef : seq.getDBRef())
216 queryBuilder.append("text:")
217 .append(dbRef.getAccessionId().replaceAll("GO:", ""))
225 int endIndex = queryBuilder.lastIndexOf(" OR ");
226 query = queryBuilder.toString().substring(5, endIndex);
228 // System.out.println("Query -----> " + query);
233 * Filters a given list of discovered structures based on supplied argument
235 * @param fieldToFilterBy
236 * the field to filter by
238 public void filterResultSet(final String fieldToFilterBy)
240 Thread filterThread = new Thread(new Runnable()
247 lbl_loading.setVisible(true);
248 pdbRequest.setResponseSize(1);
249 pdbRequest.setFieldToSearchBy("(text:");
250 pdbRequest.setFieldToSortBy(fieldToFilterBy,
251 !chk_invertFilter.isSelected());
253 Collection<PDBResponseSummary> filteredResponse = new HashSet<PDBResponseSummary>();
254 for (SequenceI seq : selectedSequences)
256 pdbRequest.setSearchTerm(buildQuery(seq) + ")");
257 pdbRequest.setAssociatedSequence(seq.getName());
258 pdbRestCleint = new PDBRestClient();
259 PDBRestResponse resultList = pdbRestCleint
260 .executeRequest(pdbRequest);
261 if (resultList.getSearchSummary() != null
262 && !resultList.getSearchSummary().isEmpty())
264 filteredResponse.addAll(resultList.getSearchSummary());
268 if (filteredResponse != null)
270 int filterResponseCount = filteredResponse.size();
271 List<PDBResponseSummary> originalDiscoveredStructuresList = new ArrayList<PDBResponseSummary>(
272 discoveredStructuresSet);
273 originalDiscoveredStructuresList.removeAll(filteredResponse);
275 Collection<PDBResponseSummary> reorderedStructuresSet = new ArrayList<PDBResponseSummary>();
276 reorderedStructuresSet.addAll(filteredResponse);
277 reorderedStructuresSet.addAll(originalDiscoveredStructuresList);
279 jList_FoundStructures.setModel(PDBRestResponse
280 .getListModel(reorderedStructuresSet));
281 tbl_summary.setModel(PDBRestResponse.getTableModel(pdbRequest,
282 reorderedStructuresSet));
284 // int[] filterIndice = new int[filterResponseCount];
285 ListSelectionModel model = tbl_summary.getSelectionModel();
286 model.clearSelection();
287 for (int x = 0; x < filterResponseCount; x++)
289 // filterIndice[x] = x;
290 model.addSelectionInterval(x, x);
293 // Discard unwanted objects to make them eligible for garbage
295 originalDiscoveredStructuresList = null;
296 reorderedStructuresSet = null;
298 // jListFoundStructures.setSelectedIndices(filterIndice);
301 lbl_loading.setVisible(false);
302 } catch (Exception e)
308 filterThread.start();
312 * Determines the column index for the pdb id in the summary table. The pdb id
313 * serves as a unique identifier for a given row in the summary table
315 * @param wantedFeilds
316 * the available table columns in no particular order
317 * @return the pdb id field column index
319 public static int getPDBIdColumIndex(Collection<PDBDocField> wantedFeilds)
321 int pdbFeildIndex = 1;
322 for (PDBDocField feild : wantedFeilds)
324 if (feild.equals(PDBDocField.PDB_ID))
330 return pdbFeildIndex;
334 * Handles action event for btn_pdbFromFile
336 public void pdbFromFile_actionPerformed()
338 jalview.io.JalviewFileChooser chooser = new jalview.io.JalviewFileChooser(
339 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
340 chooser.setFileView(new jalview.io.JalviewFileView());
341 chooser.setDialogTitle(MessageManager.formatMessage(
342 "label.select_pdb_file_for", new String[]
343 { selectedSequence.getDisplayId(false) }));
344 chooser.setToolTipText(MessageManager.formatMessage(
345 "label.load_pdb_file_associate_with_sequence", new String[]
346 { selectedSequence.getDisplayId(false) }));
348 int value = chooser.showOpenDialog(null);
349 if (value == jalview.io.JalviewFileChooser.APPROVE_OPTION)
351 String choice = chooser.getSelectedFile().getPath();
352 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);
353 new AssociatePdbFileWithSeq().associatePdbWithSeq(choice,
354 jalview.io.AppletFormatAdapter.FILE, selectedSequence, true,
360 * Handles action event for btn_ok
363 public void ok_ActionPerformed()
365 int pdbIdCol = getPDBIdColumIndex(pdbRequest.getWantedFields());
366 int[] selectedRows = tbl_summary.getSelectedRows();
367 PDBEntry[] pdbEntriesToView = new PDBEntry[selectedRows.length];
369 for (int summaryRow : selectedRows)
371 String pdbIdStr = tbl_summary.getValueAt(summaryRow, pdbIdCol)
373 PDBEntry pdbEntry = new PDBEntry();
374 pdbEntry.setId(pdbIdStr);
375 pdbEntry.setType("PDB");
376 pdbEntriesToView[count++] = pdbEntry;
378 new StructureViewer(ap.getStructureSelectionManager()).viewStructures(
379 ap, pdbEntriesToView, ap.av.collateForPDB(pdbEntriesToView));
383 * Handles action event for manual entry of pdb ids
385 public void enterPDB_actionPerformed()
387 String id = JOptionPane.showInternalInputDialog(Desktop.desktop,
388 MessageManager.getString("label.enter_pdb_id"),
389 MessageManager.getString("label.enter_pdb_id"),
390 JOptionPane.QUESTION_MESSAGE);
391 if (id != null && id.length() > 0)
393 PDBEntry entry = new PDBEntry();
394 entry.setId(id.toUpperCase());
395 selectedSequence.getDatasetSequence().addPDBId(entry);
400 * Populates the filter combo-box options dynamically depending on discovered
403 protected void populateFilterComboBox()
405 if (isStructuresDiscovered())
407 cmb_filterOption.addItem(new FilterOption("Best Quality",
408 PDBDocField.OVERALL_QUALITY.getCode(), VIEWS_FILTER));
409 cmb_filterOption.addItem(new FilterOption("Best UniProt Coverage",
410 PDBDocField.UNIPROT_COVERAGE.getCode(), VIEWS_FILTER));
411 cmb_filterOption.addItem(new FilterOption("Highest Resolution",
412 PDBDocField.RESOLUTION.getCode(), VIEWS_FILTER));
413 cmb_filterOption.addItem(new FilterOption("Highest Protein Chain",
414 PDBDocField.PROTEIN_CHAIN_COUNT.getCode(), VIEWS_FILTER));
415 cmb_filterOption.addItem(new FilterOption("Highest Bound Molecules",
416 PDBDocField.BOUND_MOLECULE_COUNT.getCode(), VIEWS_FILTER));
417 cmb_filterOption.addItem(new FilterOption("Highest Polymer Residues",
418 PDBDocField.POLYMER_RESIDUE_COUNT.getCode(), VIEWS_FILTER));
420 cmb_filterOption.addItem(new FilterOption("Enter PDB Id", "-",
422 cmb_filterOption.addItem(new FilterOption("From File", "-",
427 * Updates the displayed view based on the selected filter option
429 protected void updateCurrentView()
431 FilterOption selectedOption = ((FilterOption) cmb_filterOption
433 layout_switchableViews.show(pnl_switchableViews,
434 selectedOption.getView());
435 chk_invertFilter.setEnabled(false);
436 if (selectedOption.getView() == VIEWS_FILTER)
438 chk_invertFilter.setEnabled(true);
439 filterResultSet(selectedOption.getValue());
444 * Handles the state change event for the 'filter' combo-box and 'invert'
448 protected void stateChanged(ItemEvent e)
450 if (e.getSource() instanceof JCheckBox)
456 if (e.getStateChange() == ItemEvent.SELECTED)
465 public boolean isStructuresDiscovered()
467 return structuresDiscovered;
470 public void setStructuresDiscovered(boolean structuresDiscovered)
472 this.structuresDiscovered = structuresDiscovered;
475 public Collection<PDBResponseSummary> getDiscoveredStructuresSet()
477 return discoveredStructuresSet;