Source code for schrodinger.ui.chooseligand

import sys

from schrodinger import structure
from schrodinger.Qt import QtCore
from schrodinger.Qt import QtWidgets
from schrodinger.Qt.QtCore import Qt
from schrodinger.structutils.analyze import find_ligands
from schrodinger.ui.qt import appframework

try:
    from schrodinger.maestro import maestro
except ImportError:
    maestro = None


[docs]class ChooseLigandModel(QtCore.QAbstractTableModel):
[docs] def __init__(self, parent, allLigands): self._headers = [ "Ligand#", "PDB Residue", "Residue#", "Chain", "#atoms" ] QtCore.QAbstractTableModel.__init__(self, parent) self.allLigands = allLigands
[docs] def rowCount(self, parent=QtCore.QModelIndex()): # noqa: M511 return len(self.allLigands)
[docs] def columnCount(self, parent=QtCore.QModelIndex()): # noqa: M511 return len(self._headers)
[docs] def data( self, idx=QtCore.QModelIndex(), # noqa: M511 role=Qt.DisplayRole): if role == Qt.DisplayRole: return self.allLigands[idx.row()][idx.column() + 1] return None
[docs] def headerData(self, section, orient, role=Qt.DisplayRole): if orient == Qt.Horizontal and role == Qt.DisplayRole: return self._headers[section] return QtCore.QAbstractTableModel.headerData(self, section, orient, role)
[docs]class ChooseLigandDialog(QtWidgets.QDialog):
[docs] def __init__(self, parent, complex_st, ligands_list, text=None): """ :type parent: QWidget :param parent: Parent for the dialog window. :type complex_st: `structure.Structure` object :param complex_st: Receptor/ligand complex structure. :type ligands_list: list(schrodinger.structutils.analyze.Ligand) :param ligands_list: List of ligands to choose from. :type text: str :param text: Label to show at the top of the ligands table. """ self.ligands_list = ligands_list # Convert the list of Ligand instances to the data that can be displayed: allLigands = [] for pl, l in enumerate(self.ligands_list): at = complex_st.atom[l.atom_indexes[0]] res = at.getResidue() allLigands.append([ pl, (pl + 1), res.pdbres, res.resnum, res.chain, len(l.atom_indexes), res.molecule_number ]) import copy allLigsORIG = copy.deepcopy(allLigands) allLigands.sort(key=lambda x: x[5], reverse=True) QtWidgets.QDialog.__init__(self) QtWidgets.QDialog.setModal(self, False) self.setWindowTitle("Choose Ligand") self.layoutWidget = QtWidgets.QWidget(self) self.verticalLayout = QtWidgets.QVBoxLayout(self) if text: self.verticalLayout.addWidget(QtWidgets.QLabel(text, self)) self.tableView = QtWidgets.QTableView(self.layoutWidget) self.tableView.setSelectionMode( QtWidgets.QAbstractItemView.SingleSelection) self.tableView.setSelectionBehavior( QtWidgets.QAbstractItemView.SelectRows) self.model = ChooseLigandModel(self, allLigands) self.tableView.setModel(self.model) self.selectionModel = self.tableView.selectionModel() self.tableView.verticalHeader().setVisible(False) self.verticalLayout.addWidget(self.tableView) self.buttonBox = QtWidgets.QDialogButtonBox(self.layoutWidget) self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel | QtWidgets.QDialogButtonBox.Ok) self.okButton = self.buttonBox.button(QtWidgets.QDialogButtonBox.Ok) self.verticalLayout.addWidget(self.buttonBox) self.tableView.clicked.connect(self.tableViewClicked) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) fg = parent.frameGeometry() self.setGeometry(QtCore.QRect(fg.x() + 75, fg.y() + 150, 580, 300)) self.resize(580, 300) idxs = self.selectionModel.selectedIndexes() self.okButton.setEnabled(len(idxs) > 0) self.changed_selection = False
[docs] def tableViewClicked(self, idx): idxs = self.selectionModel.selectedIndexes() if QtWidgets.QApplication.keyboardModifiers() & Qt.ControlModifier: sel = list(idxs) if len(sel) > 0: if sel[0].row() == idx.row(): if maestro: maestro.command("workspaceselectionclear") maestro.redraw() self.changed_selection = True self.tableView.clearSelection() self.okButton.setEnabled(False) return if len(idxs) > 0: r = idxs[0].row() self.changed_selection = True if maestro: maestro.command( "workspaceselectionreplace mol. %s AND NOT (res.pt \"HOH \") and not (atom.ele H and /C0-H0/)" % (self.model.allLigands[r][6])) maestro.redraw() self.tableView.selectRow(r) self.okButton.setEnabled(len(idxs) > 0)
[docs] def accept(self, *args): QtWidgets.QDialog.accept(self)
[docs] def getSelectedLigand(self): idxs = self.selectionModel.selectedIndexes() if len(idxs) > 0: r = self.model.allLigands[idxs[0].row()][0] return self.ligands_list[r] else: raise RuntimeError("FIX - no selection was made")
[docs]def choose_ligand(parent, complex_st, text=None): """ Given a Structure object and a parent window, ask the user to select a ligand from the complex (if more than one is available). If no ligands are present, ValueError is raised. If only one ligand was present, the Ligand instance for it is returned. If the user selected a ligand, the Ligand instance for that ligand is returned (See schrodinger.structutils.analyze.Ligand) If the user cancelled the dialog, None is returned. :type parent: QWidget :param parent: Parent for the dialog window. :type complex_st: `structure.Structure` object :param complex_st: Receptor/ligand complex structure. :type text: str :param text: Label to show at the top of the ligands table. """ # Returns a list of schrodinger.structutils.analyze.Ligand instances: ligands_list = find_ligands(complex_st) llig = -1 pl = 0 if len(ligands_list) == 0: raise ValueError("Given structure has no ligands") if len(ligands_list) == 1: return ligands_list[0] # If got here, more than one ligand is present dialog = ChooseLigandDialog(parent, complex_st, ligands_list, text) exret = dialog.exec() if dialog.changed_selection: if maestro: maestro.command("workspaceselectionclear") maestro.redraw() if exret: return dialog.getSelectedLigand() else: # User cancelled return None
[docs]class TestApp(appframework.AppFramework): """ Class for testing this module. """
[docs] def __init__(self): buttons = { 'start': { 'command': self.command, 'dialog': False }, 'close': { 'command': self.closePanel }, } appframework.AppFramework.__init__(self, title="Test App", buttons=buttons, inputframe={ 'support_mae': True, 'included_entry': True, 'workspace': False, 'file': True, "copyfile": False, }) interior_layout = QtWidgets.QVBoxLayout() interior_layout.setContentsMargins(0, 0, 0, 0) interior_layout.setSpacing(1) self.interior_widget = QtWidgets.QWidget(self) self.addCentralWidget(self.interior_widget) if len(sys.argv) == 2: self._if.file_text.setText(sys.argv[1])
[docs] def command(self): st = structure.Structure.read(self.getInputFile()) try: ligand = choose_ligand(self, st) except ValueError: self.warning("Structure had no ligands") else: if type(ligand) == type(None): # FIXME fix this in analyze.py self.warning("User cancelled") else: molnum = ligand.mol_num self.warning("User selected ligand with molecule number: %d" % molnum)
[docs]def test(): # For testing purposes app = TestApp() app.show()
if __name__ == "__main__": app = TestApp() app.show() app.exec() # EOF