|
#$Id: selectMolecules.py 281 2016-07-12 00:50:13Z sarkiss $
"""LigandPage.py contains the following class.
"""
import wx, os
from wx.lib.buttons import ThemedGenBitmapTextButton
from wx.lib import eventwatcher
#edit this list to add other atom types
AD_atom_types = set(['H', 'HD', 'HS', 'C', 'A', 'N', 'NA', 'NS', 'OA', 'OS', 'F', 'Mg', 'MG', 'P', 'SA', 'S',
'Cl', 'CL', 'Ca', 'CA', 'Mn', 'MN', 'Fe', 'FE', 'Zn', 'ZN', 'Br', 'BR', 'I', 'Z'])
class SelectMoleculesPage(wx.Panel):
def __init__(self, parent, checkAtomTypes=True):
wx.Panel.__init__(self, parent, -1)
self.checkAtomTypes = checkAtomTypes
mainSizer = wx.BoxSizer(wx.VERTICAL)
vSizer = wx.BoxSizer(wx.VERTICAL)
vSizer.Add(wx.StaticText(self, -1, """Select Ligand(s) and Macromolecule(s) from Navigator -> AutoDock panel.
\nUse Control and Shift buttons to select multiple Ligands.\n"""), 0, wx.ALL, 10 )
self.label = wx.StaticText(self, -1, "")
vSizer.Add(self.label, 0, wx.ALL, 10)
mainSizer.Add(vSizer, 1, wx.EXPAND)
self.forwardButton = wx.Button(self, wx.ID_FORWARD, "")
self.backButton = wx.Button(self, wx.ID_BACKWARD, "")
bitmap = wx.ArtProvider_GetBitmap(wx.ART_ADD_BOOKMARK, wx.ART_BUTTON)
ligandButton = ThemedGenBitmapTextButton(self, -1, bitmap, "Add Ligand(s)")
macromoleculeButton = ThemedGenBitmapTextButton(self, -1, bitmap, "Add Macromolecule(s)")
buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
lin = wx.StaticLine(self)
buttonSizer.Add(ligandButton)
buttonSizer.Add(macromoleculeButton)
buttonSizer.Add((150, -1), 1, flag=wx.EXPAND | wx.ALIGN_RIGHT)
buttonSizer.Add(self.backButton, 0, wx.ALIGN_RIGHT)
buttonSizer.Add(self.forwardButton, 0, wx.ALIGN_RIGHT)
mainSizer.Add(lin,0,wx.EXPAND)
mainSizer.Add(buttonSizer, 0, wx.EXPAND|wx.ALIGN_BOTTOM)
self.SetSizer(mainSizer)
self.Bind(wx.EVT_BUTTON, self.Next, self.forwardButton)
self.Bind(wx.EVT_BUTTON, self.Back, self.backButton)
self.Bind(wx.EVT_BUTTON, self.AddLigand, ligandButton)
self.Bind(wx.EVT_BUTTON, self.AddMacromolecule, macromoleculeButton)
#self.Bind(wx.EVT_SHOW, self.SetActive)
self.frame = self.TopLevelParent
self.ligandsTree = self.frame.autodockNav.autodockTree.ligandTree.tree
self.ligandsTree.Bind(wx.EVT_TREE_DELETE_ITEM, self.CheckLigands)
self.ligandsTree.Bind(wx.EVT_TREE_SEL_CHANGED, self.CheckLigands)
self.macromoleculeTree = self.frame.autodockNav.autodockTree.macromoleculeTree.tree
self.macromoleculeTree.Bind(wx.EVT_TREE_DELETE_ITEM, self.MacromoleculeEvent)
self.macromoleculeTree.Bind(wx.EVT_TREE_SEL_CHANGED, self.MacromoleculeEvent)
self.ligandTxt = " | "
self.macromoleculeTxt = ""
self.ligandPass = False
self.macromoleculePass = False
self.macromoleculePaths = []
def CheckLigands(self, event):
if not self:
return
selectionCount = len(self.ligandsTree.Selections)
if self.ligandsTree.RootItem in self.ligandsTree.Selections:
selectionCount -= 1
if selectionCount == 0:
self.forwardButton.Enable(False)
self.ligandPass = False
self.ligandTxt = "No ligand selected. | "
self.label.SetLabel(self.ligandTxt + self.macromoleculeTxt)
else:
self.ligandTxt = str(selectionCount) +" ligand(s) selected. | "
self.label.SetLabel(self.ligandTxt + self.macromoleculeTxt)
self.ligandPass = True
if self.macromoleculePass:
self.forwardButton.Enable(True)
if event: # Skip is needed continue even chain since this widgets used in Vina and AutoDock
event.Skip()
def MacromoleculeEvent(self, event):
if event:
event.Skip()
wx.CallAfter(self.CheckMacromolecule)
def CheckMacromolecule(self):
if not self: #otherwise this is called on exit and print traceback
return
selectionCount = len(self.macromoleculeTree.Selections)
self.macromoleculePaths = []
if self.macromoleculeTree.RootItem in self.macromoleculeTree.Selections:
selectionCount -= 1
if selectionCount == 0:
self.forwardButton.Enable(False)
self.macromoleculePass = False
self.macromoleculeTxt = "No macromolecule selected."
self.label.SetLabel(self.ligandTxt + self.macromoleculeTxt)
else:
for selection in self.macromoleculeTree.Selections:
if selection and selection.IsOk() and selection != self.macromoleculeTree.RootItem:
parent = self.macromoleculeTree.GetItemParent(selection)
path = self.macromoleculeTree.GetPyData(selection)
macromoleculePath = None
if os.path.isdir(path) and parent == self.macromoleculeTree.RootItem:
text = self.macromoleculeTree.GetItemText(selection)
macromoleculePath = os.path.join(path,text+'.pdbqt')
if path[-6:].lower() == '.pdbqt' and self.macromoleculeTree.GetItemParent(parent) == self.macromoleculeTree.RootItem and path.find("_out") == -1:
macromoleculePath = path
if macromoleculePath and macromoleculePath.find('_flex.pdbqt') != -1:
macromoleculePath = macromoleculePath.replace('_flex.pdbqt', '_rigid.pdbqt')
if not os.path.exists(macromoleculePath):
self.frame.log.warning("Can't find "+macromoleculePath + " required for flex docking.")
if macromoleculePath and os.path.exists(macromoleculePath):
self.macromoleculePaths.append(macromoleculePath)
if self.macromoleculePaths:
if len(self.macromoleculePaths) == 1:
self.macromoleculeTxt = self.macromoleculePaths[0]+" selected."
else:
self.macromoleculePaths = set(self.macromoleculePaths)
self.macromoleculePaths = list(self.macromoleculePaths)
self.macromoleculeTxt = str(len(self.macromoleculePaths))+" macromolecules selected."
self.label.SetLabel(self.ligandTxt + self.macromoleculeTxt)
if self.ligandPass:
self.forwardButton.Enable(True)
self.macromoleculePass = True
else:
self.forwardButton.Enable(False)
self.macromoleculePass = False
self.macromoleculeTxt = "No macromolecule selected."
self.label.SetLabel(self.ligandTxt + self.macromoleculeTxt)
def SetActive(self, event):
"This method is bound to wx.EVT_SHOW, i.e., invoked when this page is shown"
self.frame.navigator.SetSelection(1)
self.ligandsTree.Expand(self.ligandsTree.RootItem)
self.CheckLigands(None)
self.macromoleculeTree.Expand(self.macromoleculeTree.RootItem)
self.CheckMacromolecule()
def AddLigand(self, event):
mols = self.frame.OnFileOpenMenu(None)
if mols:
for mol in mols:
self.frame.molNav.item = mol.allAtoms[0].assembly.treeID
self.frame.molNav.OnMakeLigand(None)
self.ligandsTree.Expand(self.ligandsTree.RootItem)
self.frame.navigator.SetSelection(1)
self.forwardButton.Enable(True)
self.SetActive(None)
def AddMacromolecule(self, event):
mols = self.frame.OnFileOpenMenu(None)
if mols:
for mol in mols:
self.frame.molNav.item = mol.allAtoms[0].assembly.treeID
self.frame.molNav.OnMakeMacromolecule(None)
self.macromoleculeTree.Expand(self.macromoleculeTree.RootItem)
self.frame.navigator.SetSelection(1)
self.SetActive(None)
def Next(self, event):
"Goto next page"
ligands = []
selections = self.ligandsTree.Selections
self.frame.SetAllCursors(wx.StockCursor(wx.CURSOR_WAIT))
for selection in selections:
if selection != self.ligandsTree.RootItem:
path = self.ligandsTree.GetPyData(selection)
ligands.append(path)
self.frame.vsModel.ligands = ligands
if self.checkAtomTypes:
self.frame.vsModel.CreateMolDict()
self.CheckAtomTypes()
self.frame.SetAllCursors(wx.NullCursor)
if self.macromoleculePaths:
self.frame.vsModel.macromoleculePaths = self.macromoleculePaths
self.macromoleculePass = True
else:
return
if not event == None:
self.Parent.SetSelection(2)
def Back(self, event):
"Goto previous page"
self.Parent.SetSelection(0)
def CheckAtomTypes(self):
msgChoices = []
for item in self.frame.vsModel.molDict:
aElements = self.frame.vsModel.molDict[item]['autodock_element']
diffSet = aElements.difference(AD_atom_types)
if diffSet:
msg = item + " - Atoms - " + str(list(diffSet))
msgChoices.append(msg)
path = os.path.join(self.frame.vsModel.ligandsFolder, item+'.pdbqt')
self.tree.SelectItem(self.frame.autodockNav.autodockTree.ligandTree.treeDict[path], False)
self.frame.vsModel.ligands.remove(path)
self.frame.vsModel.ligand_types.difference_update(diffSet)
if msgChoices:
dlg = wx.SingleChoiceDialog(self.frame,
"No AutoDock parameter is available for the following molecule(s)\n"+
"(won't dock them without force):",
'Molecule(s) with Unknown AutoDock Elements',
msgChoices,
wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER | wx.OK |wx.CENTRE)
dlg.ShowModal()
dlg.Destroy()
|