2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ 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.bin.Jalview;
25 import jalview.datamodel.DBRefEntry;
26 import jalview.datamodel.DBRefSource;
27 import jalview.datamodel.PDBEntry;
28 import jalview.datamodel.SequenceI;
29 import jalview.fts.api.FTSData;
30 import jalview.fts.api.FTSDataColumnI;
31 import jalview.fts.api.FTSRestClientI;
32 import jalview.fts.core.FTSRestRequest;
33 import jalview.fts.core.FTSRestResponse;
34 import jalview.fts.service.pdb.PDBFTSRestClient;
35 import jalview.io.DataSourceType;
36 import jalview.jbgui.GStructureChooser;
37 import jalview.structure.StructureMapping;
38 import jalview.structure.StructureSelectionManager;
39 import jalview.util.MessageManager;
40 import jalview.ws.DBRefFetcher;
41 import jalview.ws.sifts.SiftsSettings;
43 import java.awt.event.ItemEvent;
44 import java.util.ArrayList;
45 import java.util.Collection;
46 import java.util.HashSet;
47 import java.util.LinkedHashSet;
48 import java.util.List;
49 import java.util.Objects;
51 import java.util.Vector;
53 import javax.swing.JCheckBox;
54 import javax.swing.JComboBox;
55 import javax.swing.JLabel;
56 import javax.swing.JTable;
57 import javax.swing.table.AbstractTableModel;
60 * Provides the behaviors for the Structure chooser Panel
65 @SuppressWarnings("serial")
66 public class StructureChooser extends GStructureChooser
67 implements IProgressIndicator
69 private static int MAX_QLENGTH = 7820;
71 private SequenceI selectedSequence;
73 private SequenceI[] selectedSequences;
75 private IProgressIndicator progressIndicator;
77 private Collection<FTSData> discoveredStructuresSet;
79 private FTSRestRequest lastPdbRequest;
81 private FTSRestClientI pdbRestCleint;
83 private String selectedPdbFileName;
85 private boolean isValidPBDEntry;
87 private boolean cachedPDBExists;
89 public StructureChooser(SequenceI[] selectedSeqs, SequenceI selectedSeq,
93 this.selectedSequence = selectedSeq;
94 this.selectedSequences = selectedSeqs;
95 this.progressIndicator = (ap == null) ? null : ap.alignFrame;
100 * Initializes parameters used by the Structure Chooser Panel
104 if (!Jalview.isHeadlessMode())
106 progressBar = new ProgressBar(this.statusPanel, this.statusBar);
109 // ensure a filter option is in force for search
110 populateFilterComboBox(true, cachedPDBExists);
111 Thread discoverPDBStructuresThread = new Thread(new Runnable()
116 long startTime = System.currentTimeMillis();
117 updateProgressIndicator(MessageManager
118 .getString("status.loading_cached_pdb_entries"), startTime);
119 loadLocalCachedPDBEntries();
120 updateProgressIndicator(null, startTime);
121 updateProgressIndicator(MessageManager.getString(
122 "status.searching_for_pdb_structures"), startTime);
123 fetchStructuresMetaData();
124 // revise filter options if no results were found
125 populateFilterComboBox(isStructuresDiscovered(), cachedPDBExists);
126 updateProgressIndicator(null, startTime);
127 mainFrame.setVisible(true);
131 discoverPDBStructuresThread.start();
135 * Updates the progress indicator with the specified message
138 * displayed message for the operation
140 * unique handle for this indicator
142 public void updateProgressIndicator(String message, long id)
144 if (progressIndicator != null)
146 progressIndicator.setProgressBar(message, id);
151 * Retrieve meta-data for all the structure(s) for a given sequence(s) in a
154 public void fetchStructuresMetaData()
156 long startTime = System.currentTimeMillis();
157 pdbRestCleint = PDBFTSRestClient.getInstance();
158 Collection<FTSDataColumnI> wantedFields = pdbDocFieldPrefs
159 .getStructureSummaryFields();
161 discoveredStructuresSet = new LinkedHashSet<>();
162 HashSet<String> errors = new HashSet<>();
163 for (SequenceI seq : selectedSequences)
165 FTSRestRequest pdbRequest = new FTSRestRequest();
166 pdbRequest.setAllowEmptySeq(false);
167 pdbRequest.setResponseSize(500);
168 pdbRequest.setFieldToSearchBy("(");
169 FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption
171 pdbRequest.setFieldToSortBy(selectedFilterOpt.getValue(),
172 !chk_invertFilter.isSelected());
173 pdbRequest.setWantedFields(wantedFields);
174 pdbRequest.setSearchTerm(buildQuery(seq) + ")");
175 pdbRequest.setAssociatedSequence(seq);
176 FTSRestResponse resultList;
179 resultList = pdbRestCleint.executeRequest(pdbRequest);
180 } catch (Exception e)
183 errors.add(e.getMessage());
186 lastPdbRequest = pdbRequest;
187 if (resultList.getSearchSummary() != null
188 && !resultList.getSearchSummary().isEmpty())
190 discoveredStructuresSet.addAll(resultList.getSearchSummary());
194 int noOfStructuresFound = 0;
195 String totalTime = (System.currentTimeMillis() - startTime)
197 if (discoveredStructuresSet != null
198 && !discoveredStructuresSet.isEmpty())
200 getResultTable().setModel(FTSRestResponse
201 .getTableModel(lastPdbRequest, discoveredStructuresSet));
202 noOfStructuresFound = discoveredStructuresSet.size();
203 mainFrame.setTitle(MessageManager.formatMessage(
204 "label.structure_chooser_no_of_structures",
205 noOfStructuresFound, totalTime));
209 mainFrame.setTitle(MessageManager
210 .getString("label.structure_chooser_manual_association"));
211 if (errors.size() > 0)
213 StringBuilder errorMsg = new StringBuilder();
214 for (String error : errors)
216 errorMsg.append(error).append("\n");
218 JvOptionPane.showMessageDialog(this, errorMsg.toString(),
219 MessageManager.getString("label.pdb_web-service_error"),
220 JvOptionPane.ERROR_MESSAGE);
225 public void loadLocalCachedPDBEntries()
227 ArrayList<CachedPDB> entries = new ArrayList<>();
228 for (SequenceI seq : selectedSequences)
230 if (seq.getDatasetSequence() != null
231 && seq.getDatasetSequence().getAllPDBEntries() != null)
233 for (PDBEntry pdbEntry : seq.getDatasetSequence()
236 if (pdbEntry.getFile() != null)
238 entries.add(new CachedPDB(seq, pdbEntry));
243 cachedPDBExists = !entries.isEmpty();
244 PDBEntryTableModel tableModelx = new PDBEntryTableModel(entries);
245 tbl_local_pdb.setModel(tableModelx);
249 * Builds a query string for a given sequences using its DBRef entries
252 * the sequences to build a query for
253 * @return the built query string
256 public static String buildQuery(SequenceI seq)
258 boolean isPDBRefsFound = false;
259 boolean isUniProtRefsFound = false;
260 StringBuilder queryBuilder = new StringBuilder();
261 Set<String> seqRefs = new LinkedHashSet<>();
263 if (seq.getAllPDBEntries() != null
264 && queryBuilder.length() < MAX_QLENGTH)
266 for (PDBEntry entry : seq.getAllPDBEntries())
268 if (isValidSeqName(entry.getId()))
270 queryBuilder.append("pdb_id:").append(entry.getId().toLowerCase())
272 isPDBRefsFound = true;
277 if (seq.getDBRefs() != null && seq.getDBRefs().length != 0)
279 for (DBRefEntry dbRef : seq.getDBRefs())
281 if (isValidSeqName(getDBRefId(dbRef))
282 && queryBuilder.length() < MAX_QLENGTH)
284 if (dbRef.getSource().equalsIgnoreCase(DBRefSource.UNIPROT))
286 queryBuilder.append("uniprot_accession:")
287 .append(getDBRefId(dbRef)).append(" OR ");
288 queryBuilder.append("uniprot_id:").append(getDBRefId(dbRef))
290 isUniProtRefsFound = true;
292 else if (dbRef.getSource().equalsIgnoreCase(DBRefSource.PDB))
295 queryBuilder.append("pdb_id:")
296 .append(getDBRefId(dbRef).toLowerCase()).append(" OR ");
297 isPDBRefsFound = true;
301 seqRefs.add(getDBRefId(dbRef));
307 if (!isPDBRefsFound && !isUniProtRefsFound)
309 String seqName = seq.getName();
310 seqName = sanitizeSeqName(seqName);
311 String[] names = seqName.toLowerCase().split("\\|");
312 for (String name : names)
314 // System.out.println("Found name : " + name);
316 if (isValidSeqName(name))
322 for (String seqRef : seqRefs)
324 queryBuilder.append("text:").append(seqRef).append(" OR ");
328 int endIndex = queryBuilder.lastIndexOf(" OR ");
329 if (queryBuilder.toString().length() < 6)
333 String query = queryBuilder.toString().substring(0, endIndex);
338 * Remove the following special characters from input string +, -, &, !, (, ),
339 * {, }, [, ], ^, ", ~, *, ?, :, \
344 static String sanitizeSeqName(String seqName)
346 Objects.requireNonNull(seqName);
347 return seqName.replaceAll("\\[\\d*\\]", "")
348 .replaceAll("[^\\dA-Za-z|_]", "").replaceAll("\\s+", "+");
352 * Ensures sequence ref names are not less than 3 characters and does not
353 * contain a database name
358 public static boolean isValidSeqName(String seqName)
360 // System.out.println("seqName : " + seqName);
361 String ignoreList = "pdb,uniprot,swiss-prot";
362 if (seqName.length() < 3)
366 if (seqName.contains(":"))
370 seqName = seqName.toLowerCase();
371 for (String ignoredEntry : ignoreList.split(","))
373 if (seqName.contains(ignoredEntry))
381 public static String getDBRefId(DBRefEntry dbRef)
383 String ref = dbRef.getAccessionId().replaceAll("GO:", "");
388 * Filters a given list of discovered structures based on supplied argument
390 * @param fieldToFilterBy
391 * the field to filter by
393 public void filterResultSet(final String fieldToFilterBy)
395 Thread filterThread = new Thread(new Runnable()
400 long startTime = System.currentTimeMillis();
401 pdbRestCleint = PDBFTSRestClient.getInstance();
402 lbl_loading.setVisible(true);
403 Collection<FTSDataColumnI> wantedFields = pdbDocFieldPrefs
404 .getStructureSummaryFields();
405 Collection<FTSData> filteredResponse = new HashSet<>();
406 HashSet<String> errors = new HashSet<>();
408 for (SequenceI seq : selectedSequences)
410 FTSRestRequest pdbRequest = new FTSRestRequest();
411 if (fieldToFilterBy.equalsIgnoreCase("uniprot_coverage"))
413 pdbRequest.setAllowEmptySeq(false);
414 pdbRequest.setResponseSize(1);
415 pdbRequest.setFieldToSearchBy("(");
416 pdbRequest.setSearchTerm(buildQuery(seq) + ")");
417 pdbRequest.setWantedFields(wantedFields);
418 pdbRequest.setAssociatedSequence(seq);
419 pdbRequest.setFacet(true);
420 pdbRequest.setFacetPivot(fieldToFilterBy + ",entry_entity");
421 pdbRequest.setFacetPivotMinCount(1);
425 pdbRequest.setAllowEmptySeq(false);
426 pdbRequest.setResponseSize(1);
427 pdbRequest.setFieldToSearchBy("(");
428 pdbRequest.setFieldToSortBy(fieldToFilterBy,
429 !chk_invertFilter.isSelected());
430 pdbRequest.setSearchTerm(buildQuery(seq) + ")");
431 pdbRequest.setWantedFields(wantedFields);
432 pdbRequest.setAssociatedSequence(seq);
434 FTSRestResponse resultList;
437 resultList = pdbRestCleint.executeRequest(pdbRequest);
438 } catch (Exception e)
441 errors.add(e.getMessage());
444 lastPdbRequest = pdbRequest;
445 if (resultList.getSearchSummary() != null
446 && !resultList.getSearchSummary().isEmpty())
448 filteredResponse.addAll(resultList.getSearchSummary());
452 String totalTime = (System.currentTimeMillis() - startTime)
454 if (!filteredResponse.isEmpty())
456 final int filterResponseCount = filteredResponse.size();
457 Collection<FTSData> reorderedStructuresSet = new LinkedHashSet<>();
458 reorderedStructuresSet.addAll(filteredResponse);
459 reorderedStructuresSet.addAll(discoveredStructuresSet);
460 getResultTable().setModel(FTSRestResponse
461 .getTableModel(lastPdbRequest, reorderedStructuresSet));
463 FTSRestResponse.configureTableColumn(getResultTable(),
464 wantedFields, tempUserPrefs);
465 getResultTable().getColumn("Ref Sequence").setPreferredWidth(120);
466 getResultTable().getColumn("Ref Sequence").setMinWidth(100);
467 getResultTable().getColumn("Ref Sequence").setMaxWidth(200);
468 // Update table selection model here
469 getResultTable().addRowSelectionInterval(0,
470 filterResponseCount - 1);
471 mainFrame.setTitle(MessageManager.formatMessage(
472 "label.structure_chooser_filter_time", totalTime));
476 mainFrame.setTitle(MessageManager.formatMessage(
477 "label.structure_chooser_filter_time", totalTime));
478 if (errors.size() > 0)
480 StringBuilder errorMsg = new StringBuilder();
481 for (String error : errors)
483 errorMsg.append(error).append("\n");
485 JvOptionPane.showMessageDialog(null, errorMsg.toString(),
486 MessageManager.getString("label.pdb_web-service_error"),
487 JvOptionPane.ERROR_MESSAGE);
491 lbl_loading.setVisible(false);
493 validateSelections();
496 filterThread.start();
500 * Handles action event for btn_pdbFromFile
503 public void pdbFromFile_actionPerformed()
505 jalview.io.JalviewFileChooser chooser = new jalview.io.JalviewFileChooser(
506 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
507 chooser.setFileView(new jalview.io.JalviewFileView());
508 chooser.setDialogTitle(
509 MessageManager.formatMessage("label.select_pdb_file_for",
510 selectedSequence.getDisplayId(false)));
511 chooser.setToolTipText(MessageManager.formatMessage(
512 "label.load_pdb_file_associate_with_sequence",
513 selectedSequence.getDisplayId(false)));
515 int value = chooser.showOpenDialog(null);
516 if (value == jalview.io.JalviewFileChooser.APPROVE_OPTION)
518 selectedPdbFileName = chooser.getSelectedFile().getPath();
519 jalview.bin.Cache.setProperty("LAST_DIRECTORY", selectedPdbFileName);
520 validateSelections();
525 * Populates the filter combo-box options dynamically depending on discovered
528 protected void populateFilterComboBox(boolean haveData,
529 boolean cachedPDBExist)
532 * temporarily suspend the change listener behaviour
534 cmb_filterOption.removeItemListener(this);
536 cmb_filterOption.removeAllItems();
539 cmb_filterOption.addItem(new FilterOption(
540 MessageManager.getString("label.best_quality"),
541 "overall_quality", VIEWS_FILTER, false));
542 cmb_filterOption.addItem(new FilterOption(
543 MessageManager.getString("label.best_resolution"),
544 "resolution", VIEWS_FILTER, false));
545 cmb_filterOption.addItem(new FilterOption(
546 MessageManager.getString("label.most_protein_chain"),
547 "number_of_protein_chains", VIEWS_FILTER, false));
548 cmb_filterOption.addItem(new FilterOption(
549 MessageManager.getString("label.most_bound_molecules"),
550 "number_of_bound_molecules", VIEWS_FILTER, false));
551 cmb_filterOption.addItem(new FilterOption(
552 MessageManager.getString("label.most_polymer_residues"),
553 "number_of_polymer_residues", VIEWS_FILTER, true));
555 cmb_filterOption.addItem(
556 new FilterOption(MessageManager.getString("label.enter_pdb_id"),
557 "-", VIEWS_ENTER_ID, false));
558 cmb_filterOption.addItem(
559 new FilterOption(MessageManager.getString("label.from_file"),
560 "-", VIEWS_FROM_FILE, false));
564 FilterOption cachedOption = new FilterOption(
565 MessageManager.getString("label.cached_structures"),
566 "-", VIEWS_LOCAL_PDB, false);
567 cmb_filterOption.addItem(cachedOption);
568 cmb_filterOption.setSelectedItem(cachedOption);
571 cmb_filterOption.addItemListener(this);
575 * Updates the displayed view based on the selected filter option
577 protected void updateCurrentView()
579 FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption
581 layout_switchableViews.show(pnl_switchableViews,
582 selectedFilterOpt.getView());
583 String filterTitle = mainFrame.getTitle();
584 mainFrame.setTitle(frameTitle);
585 chk_invertFilter.setVisible(false);
586 if (selectedFilterOpt.getView() == VIEWS_FILTER)
588 mainFrame.setTitle(filterTitle);
589 chk_invertFilter.setVisible(true);
590 filterResultSet(selectedFilterOpt.getValue());
592 else if (selectedFilterOpt.getView() == VIEWS_ENTER_ID
593 || selectedFilterOpt.getView() == VIEWS_FROM_FILE)
595 mainFrame.setTitle(MessageManager
596 .getString("label.structure_chooser_manual_association"));
597 idInputAssSeqPanel.loadCmbAssSeq();
598 fileChooserAssSeqPanel.loadCmbAssSeq();
600 validateSelections();
604 * Validates user selection and activates the view button if all parameters
608 public void validateSelections()
610 FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption
612 btn_view.setEnabled(false);
613 String currentView = selectedFilterOpt.getView();
614 if (currentView == VIEWS_FILTER)
616 if (getResultTable().getSelectedRows().length > 0)
618 btn_view.setEnabled(true);
621 else if (currentView == VIEWS_LOCAL_PDB)
623 if (tbl_local_pdb.getSelectedRows().length > 0)
625 btn_view.setEnabled(true);
628 else if (currentView == VIEWS_ENTER_ID)
630 validateAssociationEnterPdb();
632 else if (currentView == VIEWS_FROM_FILE)
634 validateAssociationFromFile();
639 * Validates inputs from the Manual PDB entry panel
641 public void validateAssociationEnterPdb()
643 AssociateSeqOptions assSeqOpt = (AssociateSeqOptions) idInputAssSeqPanel
644 .getCmb_assSeq().getSelectedItem();
645 lbl_pdbManualFetchStatus.setIcon(errorImage);
646 lbl_pdbManualFetchStatus.setToolTipText("");
647 if (txt_search.getText().length() > 0)
649 lbl_pdbManualFetchStatus.setToolTipText(JvSwingUtils.wrapTooltip(true,
650 MessageManager.formatMessage("info.no_pdb_entry_found_for",
651 txt_search.getText())));
654 if (errorWarning.length() > 0)
656 lbl_pdbManualFetchStatus.setIcon(warningImage);
657 lbl_pdbManualFetchStatus.setToolTipText(
658 JvSwingUtils.wrapTooltip(true, errorWarning.toString()));
661 if (selectedSequences.length == 1 || !assSeqOpt.getName()
662 .equalsIgnoreCase("-Select Associated Seq-"))
664 txt_search.setEnabled(true);
667 btn_view.setEnabled(true);
668 lbl_pdbManualFetchStatus.setToolTipText("");
669 lbl_pdbManualFetchStatus.setIcon(goodImage);
674 txt_search.setEnabled(false);
675 lbl_pdbManualFetchStatus.setIcon(errorImage);
680 * Validates inputs for the manual PDB file selection options
682 public void validateAssociationFromFile()
684 AssociateSeqOptions assSeqOpt = (AssociateSeqOptions) fileChooserAssSeqPanel
685 .getCmb_assSeq().getSelectedItem();
686 lbl_fromFileStatus.setIcon(errorImage);
687 if (selectedSequences.length == 1 || (assSeqOpt != null && !assSeqOpt
688 .getName().equalsIgnoreCase("-Select Associated Seq-")))
690 btn_pdbFromFile.setEnabled(true);
691 if (selectedPdbFileName != null && selectedPdbFileName.length() > 0)
693 btn_view.setEnabled(true);
694 lbl_fromFileStatus.setIcon(goodImage);
699 btn_pdbFromFile.setEnabled(false);
700 lbl_fromFileStatus.setIcon(errorImage);
705 public void cmbAssSeqStateChanged()
707 validateSelections();
711 * Handles the state change event for the 'filter' combo-box and 'invert'
715 protected void stateChanged(ItemEvent e)
717 if (e.getSource() instanceof JCheckBox)
723 if (e.getStateChange() == ItemEvent.SELECTED)
731 public void selectStructure(String...pdbids)
733 FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption
735 String currentView = selectedFilterOpt.getView();
736 JTable restable = (currentView == VIEWS_FILTER) ? getResultTable()
739 if (currentView == VIEWS_FILTER)
742 int pdbIdColIndex = restable.getColumn("PDB Id")
744 for (int r = 0; r < restable.getRowCount(); r++)
746 for (int p=0;p<pdbids.length;p++)
748 if (String.valueOf(restable.getValueAt(r, pdbIdColIndex))
749 .equalsIgnoreCase(pdbids[p]))
751 restable.setRowSelectionInterval(r, r);
758 * Handles action event for btn_ok
761 public void ok_ActionPerformed()
763 final StructureSelectionManager ssm = ap.getStructureSelectionManager();
765 final int preferredHeight = pnl_filter.getHeight();
767 new Thread(new Runnable()
772 FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption
774 String currentView = selectedFilterOpt.getView();
775 JTable restable = (currentView == VIEWS_FILTER) ? getResultTable()
778 if (currentView == VIEWS_FILTER)
780 int pdbIdColIndex = restable.getColumn("PDB Id")
782 int refSeqColIndex = restable.getColumn("Ref Sequence")
784 int[] selectedRows = restable.getSelectedRows();
785 PDBEntry[] pdbEntriesToView = new PDBEntry[selectedRows.length];
787 List<SequenceI> selectedSeqsToView = new ArrayList<>();
788 for (int row : selectedRows)
790 String pdbIdStr = restable
791 .getValueAt(row, pdbIdColIndex).toString();
792 SequenceI selectedSeq = (SequenceI) restable
793 .getValueAt(row, refSeqColIndex);
794 selectedSeqsToView.add(selectedSeq);
795 PDBEntry pdbEntry = selectedSeq.getPDBEntry(pdbIdStr);
796 if (pdbEntry == null)
798 pdbEntry = getFindEntry(pdbIdStr,
799 selectedSeq.getAllPDBEntries());
802 if (pdbEntry == null)
804 pdbEntry = new PDBEntry();
805 pdbEntry.setId(pdbIdStr);
806 pdbEntry.setType(PDBEntry.Type.PDB);
807 selectedSeq.getDatasetSequence().addPDBId(pdbEntry);
809 pdbEntriesToView[count++] = pdbEntry;
811 SequenceI[] selectedSeqs = selectedSeqsToView
812 .toArray(new SequenceI[selectedSeqsToView.size()]);
813 launchStructureViewer(ssm, pdbEntriesToView, ap, selectedSeqs);
815 else if (currentView == VIEWS_LOCAL_PDB)
817 int[] selectedRows = tbl_local_pdb.getSelectedRows();
818 PDBEntry[] pdbEntriesToView = new PDBEntry[selectedRows.length];
820 int pdbIdColIndex = tbl_local_pdb.getColumn("PDB Id")
822 int refSeqColIndex = tbl_local_pdb.getColumn("Ref Sequence")
824 List<SequenceI> selectedSeqsToView = new ArrayList<>();
825 for (int row : selectedRows)
827 PDBEntry pdbEntry = (PDBEntry) tbl_local_pdb.getValueAt(row,
829 pdbEntriesToView[count++] = pdbEntry;
830 SequenceI selectedSeq = (SequenceI) tbl_local_pdb
831 .getValueAt(row, refSeqColIndex);
832 selectedSeqsToView.add(selectedSeq);
834 SequenceI[] selectedSeqs = selectedSeqsToView
835 .toArray(new SequenceI[selectedSeqsToView.size()]);
836 launchStructureViewer(ssm, pdbEntriesToView, ap, selectedSeqs);
838 else if (currentView == VIEWS_ENTER_ID)
840 SequenceI userSelectedSeq = ((AssociateSeqOptions) idInputAssSeqPanel
841 .getCmb_assSeq().getSelectedItem()).getSequence();
842 if (userSelectedSeq != null)
844 selectedSequence = userSelectedSeq;
846 String pdbIdStr = txt_search.getText();
847 PDBEntry pdbEntry = selectedSequence.getPDBEntry(pdbIdStr);
848 if (pdbEntry == null)
850 pdbEntry = new PDBEntry();
851 if (pdbIdStr.split(":").length > 1)
853 pdbEntry.setId(pdbIdStr.split(":")[0]);
854 pdbEntry.setChainCode(pdbIdStr.split(":")[1].toUpperCase());
858 pdbEntry.setId(pdbIdStr);
860 pdbEntry.setType(PDBEntry.Type.PDB);
861 selectedSequence.getDatasetSequence().addPDBId(pdbEntry);
864 PDBEntry[] pdbEntriesToView = new PDBEntry[] { pdbEntry };
865 launchStructureViewer(ssm, pdbEntriesToView, ap,
867 { selectedSequence });
869 else if (currentView == VIEWS_FROM_FILE)
871 SequenceI userSelectedSeq = ((AssociateSeqOptions) fileChooserAssSeqPanel
872 .getCmb_assSeq().getSelectedItem()).getSequence();
873 if (userSelectedSeq != null)
875 selectedSequence = userSelectedSeq;
877 PDBEntry fileEntry = new AssociatePdbFileWithSeq()
878 .associatePdbWithSeq(selectedPdbFileName,
879 DataSourceType.FILE, selectedSequence, true,
882 launchStructureViewer(ssm, new PDBEntry[] { fileEntry }, ap,
884 { selectedSequence });
886 closeAction(preferredHeight);
892 private PDBEntry getFindEntry(String id, Vector<PDBEntry> pdbEntries)
894 Objects.requireNonNull(id);
895 Objects.requireNonNull(pdbEntries);
896 PDBEntry foundEntry = null;
897 for (PDBEntry entry : pdbEntries)
899 if (entry.getId().equalsIgnoreCase(id))
907 private void launchStructureViewer(StructureSelectionManager ssm,
908 final PDBEntry[] pdbEntriesToView,
909 final AlignmentPanel alignPanel, SequenceI[] sequences)
911 long progressId = sequences.hashCode();
912 setProgressBar(MessageManager
913 .getString("status.launching_3d_structure_viewer"), progressId);
914 final StructureViewer sViewer = new StructureViewer(ssm);
915 setProgressBar(null, progressId);
917 if (SiftsSettings.isMapWithSifts())
919 List<SequenceI> seqsWithoutSourceDBRef = new ArrayList<>();
921 // TODO: skip PDBEntry:Sequence pairs where PDBEntry doesn't look like a
922 // real PDB ID. For moment, we can also safely do this if there is already
923 // a known mapping between the PDBEntry and the sequence.
924 for (SequenceI seq : sequences)
926 PDBEntry pdbe = pdbEntriesToView[p++];
927 if (pdbe != null && pdbe.getFile() != null)
929 StructureMapping[] smm = ssm.getMapping(pdbe.getFile());
930 if (smm != null && smm.length > 0)
932 for (StructureMapping sm : smm)
934 if (sm.getSequence() == seq)
941 if (seq.getPrimaryDBRefs().size() == 0)
943 seqsWithoutSourceDBRef.add(seq);
947 if (!seqsWithoutSourceDBRef.isEmpty())
949 int y = seqsWithoutSourceDBRef.size();
950 setProgressBar(MessageManager.formatMessage(
951 "status.fetching_dbrefs_for_sequences_without_valid_refs",
953 SequenceI[] seqWithoutSrcDBRef = new SequenceI[y];
955 for (SequenceI fSeq : seqsWithoutSourceDBRef)
957 seqWithoutSrcDBRef[x++] = fSeq;
960 DBRefFetcher dbRefFetcher = new DBRefFetcher(seqWithoutSrcDBRef);
961 dbRefFetcher.fetchDBRefs(true);
963 setProgressBar("Fetch complete.", progressId); // todo i18n
966 if (pdbEntriesToView.length > 1)
968 setProgressBar(MessageManager.getString(
969 "status.fetching_3d_structures_for_selected_entries"),
971 sViewer.viewStructures(pdbEntriesToView, sequences, alignPanel);
975 setProgressBar(MessageManager.formatMessage(
976 "status.fetching_3d_structures_for",
977 pdbEntriesToView[0].getId()),progressId);
978 sViewer.viewStructures(pdbEntriesToView[0], sequences, alignPanel);
980 setProgressBar(null, progressId);
984 * Populates the combo-box used in associating manually fetched structures to
985 * a unique sequence when more than one sequence selection is made.
988 public void populateCmbAssociateSeqOptions(
989 JComboBox<AssociateSeqOptions> cmb_assSeq,
990 JLabel lbl_associateSeq)
992 cmb_assSeq.removeAllItems();
994 new AssociateSeqOptions("-Select Associated Seq-", null));
995 lbl_associateSeq.setVisible(false);
996 if (selectedSequences.length > 1)
998 for (SequenceI seq : selectedSequences)
1000 cmb_assSeq.addItem(new AssociateSeqOptions(seq));
1005 String seqName = selectedSequence.getDisplayId(false);
1006 seqName = seqName.length() <= 40 ? seqName : seqName.substring(0, 39);
1007 lbl_associateSeq.setText(seqName);
1008 lbl_associateSeq.setVisible(true);
1009 cmb_assSeq.setVisible(false);
1013 public boolean isStructuresDiscovered()
1015 return discoveredStructuresSet != null
1016 && !discoveredStructuresSet.isEmpty();
1019 public Collection<FTSData> getDiscoveredStructuresSet()
1021 return discoveredStructuresSet;
1025 protected void txt_search_ActionPerformed()
1032 errorWarning.setLength(0);
1033 isValidPBDEntry = false;
1034 if (txt_search.getText().length() > 0)
1036 String searchTerm = txt_search.getText().toLowerCase();
1037 searchTerm = searchTerm.split(":")[0];
1038 // System.out.println(">>>>> search term : " + searchTerm);
1039 List<FTSDataColumnI> wantedFields = new ArrayList<>();
1040 FTSRestRequest pdbRequest = new FTSRestRequest();
1041 pdbRequest.setAllowEmptySeq(false);
1042 pdbRequest.setResponseSize(1);
1043 pdbRequest.setFieldToSearchBy("(pdb_id:");
1044 pdbRequest.setWantedFields(wantedFields);
1045 pdbRequest.setSearchTerm(searchTerm + ")");
1046 pdbRequest.setAssociatedSequence(selectedSequence);
1047 pdbRestCleint = PDBFTSRestClient.getInstance();
1048 wantedFields.add(pdbRestCleint.getPrimaryKeyColumn());
1049 FTSRestResponse resultList;
1052 resultList = pdbRestCleint.executeRequest(pdbRequest);
1053 } catch (Exception e)
1055 errorWarning.append(e.getMessage());
1059 validateSelections();
1061 if (resultList.getSearchSummary() != null
1062 && resultList.getSearchSummary().size() > 0)
1064 isValidPBDEntry = true;
1067 validateSelections();
1073 public void tabRefresh()
1075 if (selectedSequences != null)
1077 Thread refreshThread = new Thread(new Runnable()
1082 fetchStructuresMetaData();
1084 ((FilterOption) cmb_filterOption.getSelectedItem())
1088 refreshThread.start();
1092 public class PDBEntryTableModel extends AbstractTableModel
1094 String[] columns = { "Ref Sequence", "PDB Id", "Chain", "Type",
1097 private List<CachedPDB> pdbEntries;
1099 public PDBEntryTableModel(List<CachedPDB> pdbEntries)
1101 this.pdbEntries = new ArrayList<>(pdbEntries);
1105 public String getColumnName(int columnIndex)
1107 return columns[columnIndex];
1111 public int getRowCount()
1113 return pdbEntries.size();
1117 public int getColumnCount()
1119 return columns.length;
1123 public boolean isCellEditable(int row, int column)
1129 public Object getValueAt(int rowIndex, int columnIndex)
1131 Object value = "??";
1132 CachedPDB entry = pdbEntries.get(rowIndex);
1133 switch (columnIndex)
1136 value = entry.getSequence();
1139 value = entry.getPdbEntry();
1142 value = entry.getPdbEntry().getChainCode() == null ? "_"
1143 : entry.getPdbEntry().getChainCode();
1146 value = entry.getPdbEntry().getType();
1149 value = entry.getPdbEntry().getFile();
1156 public Class<?> getColumnClass(int columnIndex)
1158 return columnIndex == 0 ? SequenceI.class : PDBEntry.class;
1161 public CachedPDB getPDBEntryAt(int row)
1163 return pdbEntries.get(row);
1168 private class CachedPDB
1170 private SequenceI sequence;
1172 private PDBEntry pdbEntry;
1174 public CachedPDB(SequenceI sequence, PDBEntry pdbEntry)
1176 this.sequence = sequence;
1177 this.pdbEntry = pdbEntry;
1180 public SequenceI getSequence()
1185 public PDBEntry getPdbEntry()
1192 private IProgressIndicator progressBar;
1195 public void setProgressBar(String message, long id)
1197 progressBar.setProgressBar(message, id);
1201 public void registerHandler(long id, IProgressIndicatorHandler handler)
1203 progressBar.registerHandler(id, handler);
1207 public boolean operationInProgress()
1209 return progressBar.operationInProgress();