def buildChainMenu(self,event=None): if not hasattr(self,'chainVar'): self.chainVar={} if not hasattr(self,'oldchainVar'): self.oldchainVar={} chMols = MoleculeSet([]) if len(self.molSet): chMols=MoleculeSet(filter(lambda x: Chain in x.levels, self.molSet)) chainIDList = [] if len(chMols): chains=chMols.findType(Chain) if chains==None: return for i in chains: chainIDList.append(i.full_name()) self.buildMenu(self.chainMB,chainIDList,self.chainVar,self.oldchainVar,self.getChainVal)
def buildChainMenu(self, event=None): if not hasattr(self, 'chainVar'): self.chainVar = {} if not hasattr(self, 'oldchainVar'): self.oldchainVar = {} chMols = MoleculeSet([]) if len(self.molSet): chMols = MoleculeSet( filter(lambda x: Chain in x.levels, self.molSet)) chainIDList = [] if len(chMols): chains = chMols.findType(Chain) if chains == None: return for i in chains: chainIDList.append(i.full_name()) self.buildMenu(self.chainMB, chainIDList, self.chainVar, self.oldchainVar, self.getChainVal)
def getObjects(self, column): # return a list of objects associated with this node and possibly # other seleted nodes. For selection we return a list for each type # ( i.e. Atom, Residue, etc..) # if the node is selected, collect object from all other selected nodes resultAtoms = AtomSet([]) resultResidues = ResidueSet([]) resultChains = ChainSet([]) resultMolecules = MoleculeSet([]) buttonValue = self.chkbtVar[column].get() if self.selected: for node in self.tree.list_selected: node.chkbtVar[column].set(buttonValue) result = node.getNodes(column) obj = result[0] if isinstance(obj, Atom): resultAtoms += result elif isinstance(obj, Residue): resultResidues += result elif isinstance(obj, Chain): resultChains += result elif isinstance(obj, Molecule) or isinstance(obj, Protein): resultMolecules += result result = [] if len(resultAtoms): result.append(resultAtoms) if len(resultResidues): result.append(resultResidues) if len(resultChains): result.append(resultChains) if len(resultMolecules): result.append(resultMolecules) return result else: return [self.getNodes(column)]
def doit(self, Klass, KlassSet=None): if type(Klass) == types.StringType: if Klass in self.levelDict.keys(): Klass = self.levelDict[Klass] else: msg = Klass + "string does not map to a valid level" self.warningMsg(msg) return "ERROR" if Klass is Protein: Klass = Molecule if len(self.vf.selection): self.vf.selection = self.vf.selection.findType(Klass).uniq() else: if Klass == Molecule: self.vf.selection = MoleculeSet([]) elif Klass == Chain: self.vf.selection = ChainSet([]) elif Klass == Residue: self.vf.selection = ResidueSet([]) elif Klass == Atom: self.vf.selection = AtomSet([]) self.vf.selectionLevel = Klass self.vf.ICmdCaller.setLevel(Klass, KlassSet=None) if self.vf.hasGui: col = self.vf.ICmdCaller.levelColors[Klass.__name__] c = (col[0] / 1.5, col[1] / 1.5, col[2] / 1.5) self.vf.GUI.pickLabel.configure(background=TkColor(c)) msg = '%d %s(s)' % (len( self.vf.selection), self.vf.selectionLevel.__name__) self.vf.GUI.pickLabel.configure(text=msg) if hasattr(self.vf, 'select'): self.vf.select.updateSelectionIcons() self.levelVar.set(self.vf.selectionLevel.__name__)
def addSetLine(self, name, set): """ add a line to the dashboard with a given molecular fragment """ from MolKit.molecule import MoleculeSet node = MoleculeSet() node.setSetAttribute('_set', set) node.setSetAttribute('name', name) node.setSetAttribute('treeNodeClass', SetWithButtons) self.onAddObjectToViewer(node)
def __init__(self, master, check=0, molSet=MoleculeSet([]), userPref='cS', vf=None, all=1, crColor=(0., 1., 0), clearButton=True, showButton=True, sets=None, **kw): if not kw.get('packCfg'): self.packCfg = {'side': 'top', 'anchor': 'w', 'fill': 'x'} self.sets = sets #all is a shortcut to use all of default values if 'all' in kw.keys(): all = 1 elif __debug__: if check: apply(checkKeywords, ('stringSelector', self.entryKeywords), kw) Tkinter.Frame.__init__(self, master) ##???? Tkinter.Pack.config(self, side='left', anchor='w') #to make a stringSelector need vf, moleculeSet, selString self.master = master self.molSet = molSet self.residueSelector = ResidueSetSelector() self.atomSelector = AtomSetSelector() self.userPref = userPref self.vf = vf if not self.vf is None: self.addGeom(crColor) else: self.showCross = None self.molCts = {} self.chainCts = {} # optsDict includes defaults for all possible widgets # in practice # user can specify which widgets to put into gui d = self.optsDict = {} #first check for menubuttons: llists = [self.entryKeywords, self.menuKeywords, self.buttonKeywords] if all: if not clearButton: self.buttonKeywords.remove("clearBut") if not showButton: self.buttonKeywords.remove("showBut") for l in llists: for key in l: d[key] = 1 else: for l in llists: for key in l: d[key] = kw.get(key) self.flexChildren = { 'mol': ['molLabel', 'molEntry'], 'chain': ['chainLabel', 'chainEntry'], 'res': ['resLabel', 'resEntry'], 'atom': ['atomLabel', 'atomEntry'], } for w in ['molWids', 'chainWids', 'resWids', 'atomWids']: if kw.get(w): lab = w[:-4] s = lab + 'Label' d[s] = 1 s1 = lab + 'Entry' d[s1] = 1 # instantiate all Tkinter variables (?) #DON"T HAVE ANY??? self.buildTkVars() # only build requested widgets(?) self.buildifdDict() # build commandDictionary self.buildCmdDict() self.buildGUI()
def go(self): msgStr = None if self.moleculeSet: self.molSet = self.getMolecules(self.moleculeSet, self.selList[0]) else: self.molSet = None return [] # return [], msgStr # SPLIT here if mol.children==Atoms # possibly: self.Mols4levels=filter(lambda x: x.childrenSetClass == ChainSet, self.molSet) # then process the others separately....????????? # eg self.Mols2levels=filter(lambda x: x.childrenSetClass == AtomSet, self.molSet) # self.Mols2levels would get fed to self.getAtoms and two results ???merged??? if not self.molSet: self.chainSet = None msgStr = str(self.selList[0]) + " selected no molecules" return [] # return [], msgStr noChainMols = MoleculeSet( [x for x in self.molSet if Chain not in x.levels]) haveChainMols = MoleculeSet( [x for x in self.molSet if Chain in x.levels]) # build the residues belonging to molecules w/ no Chains (!WEIRD!) ncrs = ResidueSet() for item in noChainMols: if Residue in item.levels: itemRes = item.allAtoms.parent.uniq() ncrs = ncrs + itemRes if ncrs: noChainResSet = self.getResidues(ncrs, self.selList[2]) if not noChainResSet: noChainResSet = ResidueSet() else: noChainResSet = ResidueSet() if len(haveChainMols): self.chainSet = self.getChains(haveChainMols.findType(Chain), self.selList[1]) if self.chainSet: haveChainResSet = self.getResidues(self.chainSet.findType(Residue), self.selList[2]) # also test noChainMols for residues if haveChainResSet: self.resSet = haveChainResSet + noChainResSet else: self.resSet = noChainResSet else: self.resSet = noChainResSet ##don't return unless selList[2]!==[''] if self.selList[1] != ['']: msgStr = str(self.selList[1]) + " selected no chains" return [] # return [], msgStr # now: if self.selList for Chain and Residue level was empty, get the Atoms from noChains if self.selList[1] == [''] and self.selList[2] == ['']: tla = AtomSet() for item in noChainMols: if Residue not in item.levels: tla = tla + item.allAtoms twoLevelAtoms = tla else: twoLevelAtoms = AtomSet() if self.resSet: resAts = self.resSet.findType(Atom) if twoLevelAtoms: resAts = resAts + twoLevelAtoms self.atomSet = self.getAtoms(resAts, self.selList[3]) else: if self.selList[2] != ['']: msgStr = str(self.selList[2]) + " selected no residues" return [] # return [], msgStr else: self.atomSet = self.getAtoms(twoLevelAtoms, self.selList[3]) selNodes = self.atomSet # find correct levelType to return # need to split atomSet into two parts: if self.atomSet: haveChainAtoms = AtomSet( [x for x in self.atomSet if x.top != x.parent]) haveNoChainAtoms = self.atomSet - haveChainAtoms if self.selList[3] == ['']: # change atoms to residues if haveChainAtoms: selNodes = haveChainAtoms.parent.uniq() else: selNodes = ResidueSet() if self.selList[2] == ['']: # change residues to chains if len(selNodes): selNodes = selNodes.parent.uniq() if self.selList[1] == ['']: # change chains to molecules if haveNoChainAtoms: noChainTops = haveNoChainAtoms.top.uniq() else: noChainTops = ProteinSet() if selNodes: selTops = selNodes.top.uniq() else: selTops = ProteinSet() selNodes = selTops + noChainTops if self.selList[0] == ['']: # change molecules to molecules(?)in the case of no strs if selNodes.__class__ != MoleculeSet: selNodes = MoleculeSet(selNodes.top.uniq()) else: msgStr = str(self.selList[3]) + " selected no atoms" for item in ['moleculeSet', 'molSet', 'chainSet', 'resSet', 'atomSet']: if hasattr(self, item): delattr(self, item) # exec('del self.'+item) return selNodes
def __init__(self, objects=None, stringRepr=None, comments="", keywords=[]): MoleculeSet.__init__(self, objects, stringRepr, comments=comments, keywords=keywords) self.elementType = Protein
def go(self): msgStr = None if self.moleculeSet: self.molSet = self.getMolecules(self.moleculeSet, self.selList[0]) else: self.molSet = None return [] #return [], msgStr #SPLIT here if mol.children==Atoms #possibly: self.Mols4levels=filter(lambda x: x.childrenSetClass == ChainSet, self.molSet) #then process the others separately....????????? #eg self.Mols2levels=filter(lambda x: x.childrenSetClass == AtomSet, self.molSet) #self.Mols2levels would get fed to self.getAtoms and two results ???merged??? if not self.molSet: self.chainSet = None msgStr = str(self.selList[0])+ " selected no molecules" return [] #return [], msgStr noChainMols=MoleculeSet(filter(lambda x: Chain not in x.levels, self.molSet)) haveChainMols=MoleculeSet(filter(lambda x: Chain in x.levels, self.molSet)) #build the residues belonging to molecules w/ no Chains (!WEIRD!) ncrs=ResidueSet() for item in noChainMols: if Residue in item.levels: itemRes=item.allAtoms.parent.uniq() ncrs= ncrs + itemRes if ncrs: noChainResSet=self.getResidues(ncrs,self.selList[2]) if not noChainResSet: noChainResSet=ResidueSet() else: noChainResSet=ResidueSet() if len(haveChainMols): self.chainSet = self.getChains(haveChainMols.findType(Chain), self.selList[1]) if self.chainSet: haveChainResSet=self.getResidues(self.chainSet.findType(Residue), self.selList[2]) #also test noChainMols for residues if haveChainResSet: self.resSet=haveChainResSet+noChainResSet else: self.resSet = noChainResSet else: self.resSet = noChainResSet ##don't return unless selList[2]!==[''] if self.selList[1]!=['']: msgStr = str(self.selList[1])+ " selected no chains" return [] #return [], msgStr #now: if self.selList for Chain and Residue level was empty, get the Atoms from noChains if self.selList[1]==[''] and self.selList[2]==['']: tla=AtomSet() for item in noChainMols: if Residue not in item.levels: tla=tla + item.allAtoms twoLevelAtoms = tla else: twoLevelAtoms=AtomSet() if self.resSet: resAts=self.resSet.findType(Atom) if twoLevelAtoms:resAts=resAts+twoLevelAtoms self.atomSet = self.getAtoms(resAts, self.selList[3]) else: if self.selList[2]!=['']: msgStr = str(self.selList[2])+ " selected no residues" return [] #return [], msgStr else: self.atomSet = self.getAtoms(twoLevelAtoms, self.selList[3]) selNodes = self.atomSet #find correct levelType to return #need to split atomSet into two parts: if self.atomSet: haveChainAtoms = AtomSet(filter(lambda x: x.top!=x.parent,self.atomSet)) haveNoChainAtoms=self.atomSet-haveChainAtoms if self.selList[3]==['']: #change atoms to residues if haveChainAtoms: selNodes = haveChainAtoms.parent.uniq() else: selNodes=ResidueSet() if self.selList[2]==['']: #change residues to chains if len(selNodes): selNodes = selNodes.parent.uniq() if self.selList[1]==['']: #change chains to molecules if haveNoChainAtoms: noChainTops=haveNoChainAtoms.top.uniq() else: noChainTops=ProteinSet() if selNodes: selTops= selNodes.top.uniq() else: selTops=ProteinSet() selNodes = selTops+noChainTops if self.selList[0]==['']: #change molecules to molecules(?)in the case of no strs if selNodes.__class__!=MoleculeSet: selNodes = MoleculeSet(selNodes.top.uniq()) else: msgStr = str(self.selList[3])+ " selected no atoms" for item in ['moleculeSet','molSet','chainSet','resSet','atomSet']: if hasattr(self, item): delattr(self, item) # exec('del self.'+item) return selNodes
msg = rec_file + " not found" assert os.path.exists(rec_file), msg recs = Read(rec_file) rec = recs[0] # locate the receptor atom css = CompoundStringSelector() rec_ats = css.select(recs, ratom_name)[0] msg = ratom_name + " did not match exactly 1 atom in " + rec_file assert len(rec_ats) == 1, msg rec_at = rec_ats[0] rec_at_coords = rec_at.coords if verbose: print("found rec_at = ", rec_at.full_name(), end=' ') print("with initial coords = ", rec_at.coords) # locate the ligand atom lig_ats = css.select(MoleculeSet([d.ligMol]), latom_name)[0] assert len(lig_ats) == 1 lig_at = lig_ats[0] print("found lig_at =>", lig_at.full_name()) print("initial coords=", lig_at.coords) init_coords = lig_at.coords #open the outputfile if os.path.exists(outputfilename): fptr = open(outputfilename, 'a') else: fptr = open(outputfilename, 'w') ostr = "run rec_at coords lig_at coords distance \n" fptr.write(ostr) print(" opened output file:", outputfilename) # set the pose to Run 1 ctr = 1
def __init__(self, title="Molecule Viewer", logMode='no', libraries=[], gui=1, resourceFile = '_pmvrc', customizer = None, master=None, guiVisible=1, withShell=1, verbose=True, trapExceptions=True): """ * title: string used as a title. * logMode: string specifying the mode of logging of mv. 'no': for no loging of commands at all 'overwrite': the log files overwrite the one from the previous session the log files = mvAll.log.py 'unique': the log file name include the date and time * libraries: list of the Python packages containing modules and commands that can be loaded in the application. Such a package needs the following files : cmdlib.py and modlib.py * gui : Flag specifying whether or not to run the application with a gui. * resourceFile: file sourced at startup and where userpreference made as default are saved (default: '.pmvrc') * customizer : file when specified is sourced at startup instead of the resourceFile * master: can be specified to run PMV withing another GUI application. * guiVisible: Flag to specify whether or not to show the GUI. - trapExceptions should be set to False when creating a ViewerFramework for testing, such that exception are seen by the testing framework """ libraries = ['Pmv', 'Volume','AutoDockTools'] + libraries _pmvrc = Find_pmvrc(resourceFile) if _pmvrc: resourceFile = _pmvrc if withShell: from traceback import print_exception def print_exception_modified(etype, value, tb, limit=None, file=None): """ Modified version of traceback.print_exception Deiconifies pyshell when Traceback is printed """ print_exception(etype, value, tb, limit, file) if hasattr(self, 'GUI'): self.GUI.pyshell.top.deiconify() if not 'Pmv' in tb.tb_frame.f_code.co_filename: return if etype == ImportError: if hasattr(value,'message'): package = value.message.split()[-1] print "Please install " +package + " to fix this problem." elif etype == AssertionError: pass else: print "Please include this Traceback in your bug report. Help --> Report a Bug in PMV/ADT." import traceback traceback.print_exception = print_exception_modified ViewerFramework.__init__(self, title, logMode, libraries, gui, resourceFile, master=master, guiVisible=guiVisible, withShell=withShell, verbose=verbose, trapExceptions=trapExceptions) #if sys.platform == 'win32': #this needed to account for camera size # geometry = '%dx%d+%d+%d' % (800,600, 30, 30) #else: # geometry = '%dx%d+%d+%d' % (800,200, 30, 30) #self.GUI.ROOT.geometry(geometry) # Establish interface to Visual Programming environment. if self.visionAPI is not None: # add Molecule, Pmv, Viewer to lookup table from Pmv.VisionInterface.PmvNodes import PmvMolecule, PmvNode, \ PmvViewer, PmvSetNode, PmvVolume self.visionAPI.addToLookup(Protein, PmvMolecule, "Molecules") self.visionAPI.addToLookup(MoleculeViewer, PmvNode, "PMV") from DejaVu import Viewer self.visionAPI.addToLookup(Viewer, PmvViewer, "PMV") self.visionAPI.addToLookup(TreeNodeSet, PmvSetNode, "Sets") # Note: Molecules are added to the interface in addMolecule() below # put Pmv instance into list of objects to be added to Vision self.visionAPI.add(self, "Pmv", kw={ 'vf':self, 'constrkw':{'vf':'masterNet.editor.vf'} } ) # put Pmv Viewer instance in list of objects to be added to Vision if self.hasGui: self.visionAPI.add(self.GUI.VIEWER, "Pmv Viewer", kw={ 'viewer':self.GUI.VIEWER, 'constrkw':{'viewer':'masterNet.editor.vf.GUI.VIEWER'} } ) self.selection = MoleculeSet() # store current selection # replace interactive command caller by MVInteractiveCmdCaller # we need the ICmdCaller even if there is no GUI because it has # the level variable used byu selection commands self.ICmdCaller = MVInteractiveCmdCaller( self ) from mvCommand import MVSetIcomLevel self.addCommand( MVSetIcomLevel(), 'setIcomLevel', None ) from mvCommand import MVSetSelectionLevel, MVSetSelectionLevelGUI self.addCommand( MVSetSelectionLevel(), 'setSelectionLevel', MVSetSelectionLevelGUI) self.setSelectionLevel(Molecule, topCommand = 0) #should this be Protein? from Pmv.displayCommands import BindGeomToMolecularFragment from Pmv.displayCommands import BindGeomToMolecularFragmentGUI self.addCommand( BindGeomToMolecularFragment(), 'bindGeomToMolecularFragment', BindGeomToMolecularFragmentGUI ) # if self.hasGui: # from Pmv.mvCommand import MVPrintNodeNames, MVCenterOnNodes # self.addCommand( MVPrintNodeNames(), 'printNodeNames ', None ) # self.addCommand( MVCenterOnNodes(), 'centerOnNodes', None ) # load out default interactive command which prints out object # names #self.ICmdCaller.setCommands( self.printNodeNames ) self.ICmdCaller.go() self.addMVBasicMenus() # load out default interactive command self.ICmdCaller.setCommands( self.printNodeNames, modifier=None ) self.ICmdCaller.setCommands( self.select, modifier='Shift_L' ) self.ICmdCaller.setCommands( self.centerOnNodes, modifier='Control_L' ) self.ICmdCaller.setCommands( self.deselect, modifier='Alt_L' ) #self.setIcomLevel(Molecule, topCommand = 0) self.setIcomLevel(Atom, topCommand = 0) self.Mols = MoleculeSet() # store the molecules read in self.objects = self.Mols from MolKit.sets import Sets self.sets = Sets() # store user-defined sets in this dict # lock needs to be acquired before volume can be added self.volumesLock = thread.allocate_lock() self.Vols = [] # list of Grid3D objects storing volumetric data if self.visionAPI is not None: from Volume.Grid3D import Grid3D self.visionAPI.addToLookup(Grid3D, PmvVolume, "Volumes") self.allAtoms = AtomSet() # set of all atoms (across molecules) #if self.hasGui: # from Pmv.controlPanelCommands import ControlPanel,ControlPanel_GUI # self.addCommand(ControlPanel(), "controlPanel",ControlPanel_GUI) choices = ['caseSensitive', 'caseInsensitive', 'caseInsensWithEscapedChars'] self.userpref.add('selectStringMatchMode', 'caseSensitive', validValues=choices, doc = """When set to caseSensitive the string match mode will be case sensitive the other possibility is to be case insensitive or case insensitive with escaped characters. """) choices = [1,0] self.userpref.add('showSelectionSpheres', 1, validValues=choices, doc = """When set to 1 the selection visual feedback which are the little yellow crosses will be displayed.""") choices = [1,0] self.userpref.add('raiseExceptionForMissingKey', 1, validValues=choices, callbackFunc = [self.setRaiseException], doc = """When set to 1 an exception will be raised is a a key is not found in a dictionnary. """) choices = [1, 0] self.userpref.add('expandNodeLogString', 0, validValues=choices, doc = """When set to 1 the log string representing the node argument of a doit will be expanded to the full name of each element of the TreeNodeSet, when set to 0 the log string representing the node argument of a doit will be 'self.getSelection()'. In the last case the command log will depend on the current selection.""") # overwrite firstObject only with firstMoleculeOnly self.userpref['centerScene']['validValues'][0] = 'firstMoleculeOnly' self.userpref.set('centerScene', 'firstMoleculeOnly') choices = ['yes','no'] self.userpref.add('useDepthCueing', 'yes', validValues=choices, doc = """ When set to 'yes' the depthCueing is turned on by default""") doc = """When set to yes a warning message is displayed when an empty selection is about to be expanded to all the molecules loaded in the application""" self.userpref.add('warnOnEmptySelection', 'no', validValues=choices, doc=doc) if self.hasGui: self.GUI.VIEWER.suspendRedraw = True self.GUI.drop_cb = self.drop_cb self.GUI.pickLabel.bind("<Button-1>",self.setSelectionLevel.guiCallback) if self.userpref['useDepthCueing']['value']=='yes': self.GUI.VIEWER.currentCamera.fog.Set(enabled=1, tagModified=False) if title != 'AutoDockTools': toolbarDict = {} toolbarDict['name'] = 'ADT' toolbarDict['type'] = 'Checkbutton' toolbarDict['icon1'] = 'adt.png' toolbarDict['balloonhelp'] = 'AutoDock Tools' toolbarDict['icon_dir'] = ICONPATH toolbarDict['index'] = 7 toolbarDict['cmdcb'] = self.Add_ADT toolbarDict['variable'] = None self.GUI.toolbarList.append(toolbarDict) self.GUI.configureToolBar(self.GUI.iconsize) # overwrite unsollicited picking with a version that prints atom names #self.GUI.VIEWER.RemovePickingCallback("unsolicitedPick") #self.GUI.VIEWER.AddPickingCallback(self.unsolicitedPick) top = self.GUI.ROOT.winfo_toplevel() geom = top.geometry() geom = geom.split('x') self.GUI.menuBars['Toolbar']._frame.update_idletasks() winfo_width = self.GUI.menuBars['Toolbar']._frame.winfo_width() if int(geom[0]) < winfo_width + 10: geom[0] = str(winfo_width + 10) top.geometry(geom[0]+'x'+geom[1]) if not trapExceptions and customizer == './.empty': top.update_idletasks() top.deiconify() #self.GUI.vwrCanvasFloating.deiconify() self.GUI.naturalSize() from Pmv.updateCommands import Update, UpdateGUI self.addCommand( Update(), 'update', UpdateGUI ) from Pmv.aboutCommands import About, AboutGUI self.addCommand( About(), 'about', AboutGUI ) self.GUI.VIEWER.suspendRedraw = False self.browseCommands('deleteCommands',package='Pmv', topCommand=0) self.GUI.ROOT.bind('<Delete>', self.deleteAtomSet.guiCallback) self.GUI.vwrCanvasFloating.bind('<Delete>', self.deleteAtomSet.guiCallback) self.browseCommands ('dashboardCommands', package='Pmv', topCommand=0) self.customize(customizer) if self.hasGui: try: import grid3DCommands self.browseCommands("grid3DCommands",package="Pmv", topCommand=0) except ImportError: print "UTpackages are not installed. Disabling grid3DCommands..." rcFile = getResourceFolderWithVersion() if rcFile: rcFile += os.sep + 'Pmv' + os.sep + "recent.pkl" if self.hasGui: fileMenu = self.GUI.menuBars['menuRoot'].menubuttons['File'].menu self.recentFiles = RecentFiles(self, fileMenu, filePath=rcFile, menuLabel = 'Recent Files') try: from DejaVu.Camera import RecordableCamera if isinstance(self.GUI.VIEWER.cameras[0], RecordableCamera): from Pmv.videoCommands import VideoCommand, VideoCommandGUI self.addCommand(VideoCommand(), 'videoCommand', VideoCommandGUI) except: pass #print "Recordable camera is not available" if len(self.dashboard.tree.columns)==0: # this warning is wrong, it appears during test_pmvscript #print "WARNING: update your _pmvrc file to load the dashboard commands" from Pmv.dashboard import loadAllColunms loadAllColunms(self)
class MoleculeViewer(ViewerFramework): """ package : Pmv module : moleculeViewer class : MoleculeViewer description: Class derived from the ViewerFramework base class. It provides a 3D molecular viewer. """ def getSelLev(self): return self.selection.elementType def setSelLev(self, value): if value==Protein: value = Molecule assert value in [Molecule, Chain, Residue, Atom] self.setSelectionLevel(value) selectionLevel = property(getSelLev, setSelLev) def __init__(self, title="Molecule Viewer", logMode='no', libraries=[], gui=1, resourceFile = '_pmvrc', customizer = None, master=None, guiVisible=1, withShell=1, verbose=True, trapExceptions=True): """ * title: string used as a title. * logMode: string specifying the mode of logging of mv. 'no': for no loging of commands at all 'overwrite': the log files overwrite the one from the previous session the log files = mvAll.log.py 'unique': the log file name include the date and time * libraries: list of the Python packages containing modules and commands that can be loaded in the application. Such a package needs the following files : cmdlib.py and modlib.py * gui : Flag specifying whether or not to run the application with a gui. * resourceFile: file sourced at startup and where userpreference made as default are saved (default: '.pmvrc') * customizer : file when specified is sourced at startup instead of the resourceFile * master: can be specified to run PMV withing another GUI application. * guiVisible: Flag to specify whether or not to show the GUI. - trapExceptions should be set to False when creating a ViewerFramework for testing, such that exception are seen by the testing framework """ libraries = ['Pmv', 'Volume','AutoDockTools'] + libraries _pmvrc = Find_pmvrc(resourceFile) if _pmvrc: resourceFile = _pmvrc if withShell: from traceback import print_exception def print_exception_modified(etype, value, tb, limit=None, file=None): """ Modified version of traceback.print_exception Deiconifies pyshell when Traceback is printed """ print_exception(etype, value, tb, limit, file) if hasattr(self, 'GUI'): self.GUI.pyshell.top.deiconify() if not 'Pmv' in tb.tb_frame.f_code.co_filename: return if etype == ImportError: if hasattr(value,'message'): package = value.message.split()[-1] print "Please install " +package + " to fix this problem." elif etype == AssertionError: pass else: print "Please include this Traceback in your bug report. Help --> Report a Bug in PMV/ADT." import traceback traceback.print_exception = print_exception_modified ViewerFramework.__init__(self, title, logMode, libraries, gui, resourceFile, master=master, guiVisible=guiVisible, withShell=withShell, verbose=verbose, trapExceptions=trapExceptions) #if sys.platform == 'win32': #this needed to account for camera size # geometry = '%dx%d+%d+%d' % (800,600, 30, 30) #else: # geometry = '%dx%d+%d+%d' % (800,200, 30, 30) #self.GUI.ROOT.geometry(geometry) # Establish interface to Visual Programming environment. if self.visionAPI is not None: # add Molecule, Pmv, Viewer to lookup table from Pmv.VisionInterface.PmvNodes import PmvMolecule, PmvNode, \ PmvViewer, PmvSetNode, PmvVolume self.visionAPI.addToLookup(Protein, PmvMolecule, "Molecules") self.visionAPI.addToLookup(MoleculeViewer, PmvNode, "PMV") from DejaVu import Viewer self.visionAPI.addToLookup(Viewer, PmvViewer, "PMV") self.visionAPI.addToLookup(TreeNodeSet, PmvSetNode, "Sets") # Note: Molecules are added to the interface in addMolecule() below # put Pmv instance into list of objects to be added to Vision self.visionAPI.add(self, "Pmv", kw={ 'vf':self, 'constrkw':{'vf':'masterNet.editor.vf'} } ) # put Pmv Viewer instance in list of objects to be added to Vision if self.hasGui: self.visionAPI.add(self.GUI.VIEWER, "Pmv Viewer", kw={ 'viewer':self.GUI.VIEWER, 'constrkw':{'viewer':'masterNet.editor.vf.GUI.VIEWER'} } ) self.selection = MoleculeSet() # store current selection # replace interactive command caller by MVInteractiveCmdCaller # we need the ICmdCaller even if there is no GUI because it has # the level variable used byu selection commands self.ICmdCaller = MVInteractiveCmdCaller( self ) from mvCommand import MVSetIcomLevel self.addCommand( MVSetIcomLevel(), 'setIcomLevel', None ) from mvCommand import MVSetSelectionLevel, MVSetSelectionLevelGUI self.addCommand( MVSetSelectionLevel(), 'setSelectionLevel', MVSetSelectionLevelGUI) self.setSelectionLevel(Molecule, topCommand = 0) #should this be Protein? from Pmv.displayCommands import BindGeomToMolecularFragment from Pmv.displayCommands import BindGeomToMolecularFragmentGUI self.addCommand( BindGeomToMolecularFragment(), 'bindGeomToMolecularFragment', BindGeomToMolecularFragmentGUI ) # if self.hasGui: # from Pmv.mvCommand import MVPrintNodeNames, MVCenterOnNodes # self.addCommand( MVPrintNodeNames(), 'printNodeNames ', None ) # self.addCommand( MVCenterOnNodes(), 'centerOnNodes', None ) # load out default interactive command which prints out object # names #self.ICmdCaller.setCommands( self.printNodeNames ) self.ICmdCaller.go() self.addMVBasicMenus() # load out default interactive command self.ICmdCaller.setCommands( self.printNodeNames, modifier=None ) self.ICmdCaller.setCommands( self.select, modifier='Shift_L' ) self.ICmdCaller.setCommands( self.centerOnNodes, modifier='Control_L' ) self.ICmdCaller.setCommands( self.deselect, modifier='Alt_L' ) #self.setIcomLevel(Molecule, topCommand = 0) self.setIcomLevel(Atom, topCommand = 0) self.Mols = MoleculeSet() # store the molecules read in self.objects = self.Mols from MolKit.sets import Sets self.sets = Sets() # store user-defined sets in this dict # lock needs to be acquired before volume can be added self.volumesLock = thread.allocate_lock() self.Vols = [] # list of Grid3D objects storing volumetric data if self.visionAPI is not None: from Volume.Grid3D import Grid3D self.visionAPI.addToLookup(Grid3D, PmvVolume, "Volumes") self.allAtoms = AtomSet() # set of all atoms (across molecules) #if self.hasGui: # from Pmv.controlPanelCommands import ControlPanel,ControlPanel_GUI # self.addCommand(ControlPanel(), "controlPanel",ControlPanel_GUI) choices = ['caseSensitive', 'caseInsensitive', 'caseInsensWithEscapedChars'] self.userpref.add('selectStringMatchMode', 'caseSensitive', validValues=choices, doc = """When set to caseSensitive the string match mode will be case sensitive the other possibility is to be case insensitive or case insensitive with escaped characters. """) choices = [1,0] self.userpref.add('showSelectionSpheres', 1, validValues=choices, doc = """When set to 1 the selection visual feedback which are the little yellow crosses will be displayed.""") choices = [1,0] self.userpref.add('raiseExceptionForMissingKey', 1, validValues=choices, callbackFunc = [self.setRaiseException], doc = """When set to 1 an exception will be raised is a a key is not found in a dictionnary. """) choices = [1, 0] self.userpref.add('expandNodeLogString', 0, validValues=choices, doc = """When set to 1 the log string representing the node argument of a doit will be expanded to the full name of each element of the TreeNodeSet, when set to 0 the log string representing the node argument of a doit will be 'self.getSelection()'. In the last case the command log will depend on the current selection.""") # overwrite firstObject only with firstMoleculeOnly self.userpref['centerScene']['validValues'][0] = 'firstMoleculeOnly' self.userpref.set('centerScene', 'firstMoleculeOnly') choices = ['yes','no'] self.userpref.add('useDepthCueing', 'yes', validValues=choices, doc = """ When set to 'yes' the depthCueing is turned on by default""") doc = """When set to yes a warning message is displayed when an empty selection is about to be expanded to all the molecules loaded in the application""" self.userpref.add('warnOnEmptySelection', 'no', validValues=choices, doc=doc) if self.hasGui: self.GUI.VIEWER.suspendRedraw = True self.GUI.drop_cb = self.drop_cb self.GUI.pickLabel.bind("<Button-1>",self.setSelectionLevel.guiCallback) if self.userpref['useDepthCueing']['value']=='yes': self.GUI.VIEWER.currentCamera.fog.Set(enabled=1, tagModified=False) if title != 'AutoDockTools': toolbarDict = {} toolbarDict['name'] = 'ADT' toolbarDict['type'] = 'Checkbutton' toolbarDict['icon1'] = 'adt.png' toolbarDict['balloonhelp'] = 'AutoDock Tools' toolbarDict['icon_dir'] = ICONPATH toolbarDict['index'] = 7 toolbarDict['cmdcb'] = self.Add_ADT toolbarDict['variable'] = None self.GUI.toolbarList.append(toolbarDict) self.GUI.configureToolBar(self.GUI.iconsize) # overwrite unsollicited picking with a version that prints atom names #self.GUI.VIEWER.RemovePickingCallback("unsolicitedPick") #self.GUI.VIEWER.AddPickingCallback(self.unsolicitedPick) top = self.GUI.ROOT.winfo_toplevel() geom = top.geometry() geom = geom.split('x') self.GUI.menuBars['Toolbar']._frame.update_idletasks() winfo_width = self.GUI.menuBars['Toolbar']._frame.winfo_width() if int(geom[0]) < winfo_width + 10: geom[0] = str(winfo_width + 10) top.geometry(geom[0]+'x'+geom[1]) if not trapExceptions and customizer == './.empty': top.update_idletasks() top.deiconify() #self.GUI.vwrCanvasFloating.deiconify() self.GUI.naturalSize() from Pmv.updateCommands import Update, UpdateGUI self.addCommand( Update(), 'update', UpdateGUI ) from Pmv.aboutCommands import About, AboutGUI self.addCommand( About(), 'about', AboutGUI ) self.GUI.VIEWER.suspendRedraw = False self.browseCommands('deleteCommands',package='Pmv', topCommand=0) self.GUI.ROOT.bind('<Delete>', self.deleteAtomSet.guiCallback) self.GUI.vwrCanvasFloating.bind('<Delete>', self.deleteAtomSet.guiCallback) self.browseCommands ('dashboardCommands', package='Pmv', topCommand=0) self.customize(customizer) if self.hasGui: try: import grid3DCommands self.browseCommands("grid3DCommands",package="Pmv", topCommand=0) except ImportError: print "UTpackages are not installed. Disabling grid3DCommands..." rcFile = getResourceFolderWithVersion() if rcFile: rcFile += os.sep + 'Pmv' + os.sep + "recent.pkl" if self.hasGui: fileMenu = self.GUI.menuBars['menuRoot'].menubuttons['File'].menu self.recentFiles = RecentFiles(self, fileMenu, filePath=rcFile, menuLabel = 'Recent Files') try: from DejaVu.Camera import RecordableCamera if isinstance(self.GUI.VIEWER.cameras[0], RecordableCamera): from Pmv.videoCommands import VideoCommand, VideoCommandGUI self.addCommand(VideoCommand(), 'videoCommand', VideoCommandGUI) except: pass #print "Recordable camera is not available" if len(self.dashboard.tree.columns)==0: # this warning is wrong, it appears during test_pmvscript #print "WARNING: update your _pmvrc file to load the dashboard commands" from Pmv.dashboard import loadAllColunms loadAllColunms(self) def drop_cb(self, files): for file in files: self.readMolecule(file) #def getSelectionLevel(self): # return self.selection.elementType def getMolFromName(self, name): mols = filter(lambda x: x.name == name, self.Mols) if len(mols): mol = mols[0] else: mol = None return mol def setRaiseException(self, name, oldval, val): import MolKit.molecule MolKit.molecule.raiseExceptionForMissingKey = val def unsolicitedPick(self, pick): """treat an unsollicited picking event""" if pick is None: return vi = self.GUI.VIEWER if vi.isShift() or vi.isControl(): vi.unsolicitedPick(pick) else: atom = self.findPickedAtoms(pick) if atom: level = self.ICmdCaller.level.value if level == Molecule: level = Protein node = atom.findType(level) for n in node: self.message( n.full_name() ) def loadMoleculeIfNeeded(self, filename): """load a molecule only if it doesn't exist yet in Pmv, else it aborts silent""" if not os.path.exists(filename): print 'Error! %s not found!'%filename return # find what name would be name = os.path.split(filename)[-1] try: spl = split(name, '.') except: spl = [name] name = spl[0] # ask if name already used if self.Mols: for mol in self.Mols.data: if name == mol.name: # break and return mol return mol # else load molecule if not hasattr(self, 'readMolecule'): self.browseCommands( 'fileCommands', commands=['readMolecule'], package='Pmv', topCommand=0) mol = self.readMolecule(filename) return mol def addMolecule(self, newmol, ask=1): """ Add a molecule to this viewer """ #IN ANY CASE: change any special characters in name to '-' from MolKit.molecule import Molecule if self.hasGui: Molecule.configureProgressBar = self.GUI.progressBarConf Molecule.updateProgressBar = self.GUI.progressBarUpd spChar=['?','*','.','$','#',':','-',','] ## spChar=['?','*','.','$','#',':','_',','] for item in spChar: newmol.name = replace(newmol.name,item,'_') ## newmol.name = replace(newmol.name,item,'-') if len(self.Mols) > 0: if newmol.name in self.Mols.name: if ask==1: from mglutil.gui.InputForm.Tk.gui import InputFormDescr idf = self.ifd = InputFormDescr(title = '') idf.append({'widgetType':Pmw.EntryField, 'name':'newmol', 'required':1, 'wcfg':{'labelpos':'w', 'label_text':'New Name: ', 'validate':None, 'value':'%s-%d'%(newmol.name, len(self.Mols))}, 'gridcfg':{'sticky':'we'}}) vals = self.getUserInput(idf) if len(vals)>0: assert not vals['newmol'] in self.Mols.name newmol.name = vals['newmol'] else: return None else: newmol.name='%s_%d'%(newmol.name,len(self.Mols)) newmol.allAtoms.setStringRepr(newmol.full_name()+':::') # provide hook for progress bar # old code: newmol.allAtoms._bndIndex_ = range(len(newmol.allAtoms)) allAtomsLen = len(newmol.allAtoms) if allAtomsLen == 0: import warnings warnings.warn("%s is empty molecule cannot add it to the viewer"%newmol.name) return None if self.hasGui: self.GUI.configureProgressBar(init=1, mode='increment', max=allAtomsLen, labeltext='add molecule to viewer') i = 0 for a in newmol.allAtoms: a._bndIndex_ = i if self.hasGui: self.GUI.updateProgressBar() i = i + 1 g = None if self.hasGui: g = MolGeomContainer( newmol, self ) # addObject calls updateProgressBar on its own self.addObject('mol%s'%len(self.Mols), newmol, g) self.Mols.setStringRepr(self.Mols.full_name()) # add object to visionAPI (to add them as nodes to Vision library) if self.visionAPI: self.visionAPI.add(newmol, newmol.name, kw={ 'molecule':newmol, 'constrkw':{ 'molecule': 'masterNet.editor.vf.expandNodes("%s")[0]'%newmol.name} } ) self.allAtoms = self.allAtoms + newmol.allAtoms self.allAtoms.setStringRepr(self.Mols.full_name()+':::') #used by cpk command to decide whether or not to compute radii newmol.unitedRadii = None # set to None to force initial radii assignment return newmol def addVolume(self, name, grid): # FIXME we need to check for name unicity and have a repalcement policy #self.volumesLock.acquire() self.Vols.append(grid) grid.name = name #self.volumesLock.release() if self.visionAPI: self.visionAPI.add(grid, name, kw={ 'grid':grid, 'constrkw':{ 'grid': 'masterNet.editor.vf.gridFromName("%s")[0]'%grid.name} } ) def getSelection(self): # FIXME why not return self.Mols always on empty selection ?? # this should speed thing up #ICmdCallerLevel = self.ICmdCaller.level.value selLevel = self.selectionLevel if len(self.selection)==0: # empty selection if self.userpref['warnOnEmptySelection']['value']=='yes': if self.askOkCancelMsg('expand empty selection to all molecules?'): #selection = self.Mols.findType(selLevel)#, uniq=1) return self.Mols #try: # selection = self.Mols.findType(selLevel)#, uniq=1) #except: # if selLevel==Molecule: # selection = self.Mols.findType(Protein) #return selection else: #selection = self.Mols.findType(selLevel)#, uniq=1) return self.Mols #try: # selection = self.Mols.findType(selLevel)#, uniq=1) #except: # if selLevel==Molecule: # selection = self.Mols.findType(Protein) #return selection else: #selection = self.Mols.findType(selLevel)#, uniq=1) return self.Mols #try: # selection = self.Mols.findType(selLevel)#, uniq=1) #except: # if selLevel==Molecule: # selection = self.Mols.findType(Protein) #return selection else: # not empty select #try: # selection = self.selection.findType(selLevel, uniq=1) #except: # if selLevel==Molecule: # selection = self.selection.findType(Protein) return self.selection #selection = self.selection.findType(selLevel, uniq=1) #return selection ## if self.userpref['warnOnEmptySelection']['value']=='yes': ## if self.askOkCancelMsg('expand empty selection to all molecules?'): ## selection = self.Mols.findType(selLevel)#, uniq=1) ## #try: ## # selection = self.Mols.findType(selLevel)#, uniq=1) ## #except: ## # if selLevel==Molecule: ## # selection = self.Mols.findType(Protein) ## return selection ## else: ## selection = self.Mols.findType(selLevel)#, uniq=1) ## #try: ## # selection = self.Mols.findType(selLevel)#, uniq=1) ## #except: ## # if selLevel==Molecule: ## # selection = self.Mols.findType(Protein) ## return selection ## else: ## selection = self.Mols.findType(selLevel)#, uniq=1) ## #try: ## # selection = self.Mols.findType(selLevel)#, uniq=1) ## #except: ## # if selLevel==Molecule: ## # selection = self.Mols.findType(Protein) ## return selection ## else: ## # not empty select ## #try: ## # selection = self.selection.findType(selLevel, uniq=1) ## #except: ## # if selLevel==Molecule: ## # selection = self.selection.findType(Protein) ## selection = self.selection.findType(selLevel, uniq=1) ## return selection def getItems(self, selString=""): """Takes a string and returns a TreeNodeSet The string can contain a series of set descriptors with operators separated by / characters. There is always a first set, followed by pairs of operators and sets. All sets have to describe nodes of the same level. example: '1crn:::CA*/+/1crn:::O*' describes the union of all CA ans all O in 1crn '1crn:::CA*/+/1crn:::O*/-/1crn::TYR29:' """ assert type(selString)==StringType return self.expandNodes(selString) def expandNodes(self, nodes): """Takes nodes as string or TreeNode or TreeNodeSet and returns a TreeNodeSet If nodes is a string it can contain a series of set descriptors with operators separated by / characters. There is always a first set, followed by pairs of operators and sets. All sets ahve to describe nodes of the same level. example: '1crn:::CA*/+/1crn:::O*' describes the union of all CA ans all O in 1crn '1crn:::CA*/+/1crn:::O*/-/1crn::TYR29:' """ if isinstance(nodes,TreeNode): result = nodes.setClass([nodes]) result.setStringRepr(nodes.full_name()) elif type(nodes)==StringType: stringRepr = nodes css = CompoundStringSelector() result = css.select(self.Mols, stringRepr)[0] ## setsStrings = stringRepr.split('/') ## getSet = self.Mols.NodesFromName ## result = getSet(setsStrings[0]) ## for i in range(1, len(setsStrings), 2): ## op = setsStrings[i] ## arg = setsStrings[i+1] ## if op=='|': # or ## result += getSet(arg) ## elif op=='-': # subtract ## result -= getSet(arg) ## elif op=='&': # intersection ## result &= getSet(arg) ## elif op=='^': # xor ## result ^= getSet(arg) ## elif op=='s': # sub select (i.e. select from previous result) ## result = result.get(arg) ## else: ## raise ValueError, '%s bad operation in selection string'%op ## result.setStringRepr(stringRepr) elif isinstance(nodes,TreeNodeSet): result = nodes else: raise ValueError, 'Could not expand nodes %s\n'%str(nodes) return result def getNodesByMolecule(self, nodes, nodeType=None): """ moleculeSet, [nodeSet, nodeSet] <- getNodesByMolecule(nodes, nodeType=None) nodes can be either: a string, a TreeNode or a TreeNodeSet. This method returns a molecule set and for each molecule a TreeNodeSet of the nodes belonging to this molecule. 'nodeType' enables a desired type of nodes to be returned for each molecule """ # special case list of complete molecules to be expanded to atoms # this also covers the case where nothing is selected if isinstance(nodes, MoleculeSet) or isinstance(nodes, ProteinSet): if nodeType is Atom: atms = [] for mol in nodes: atms.append(mol.allAtoms) return nodes, atms elif (nodeType is Protein) or (nodeType is Molecule): return nodes, nodes # if it is a string, get a bunch of nodes from the string if type(nodes)==StringType: nodes = self.expandNodes(nodes) assert issubclass(nodes.__class__, TreeNode) or \ issubclass(nodes.__class__, TreeNodeSet) # if nodes is a single TreeNode make it a singleton TreeNodeSet if issubclass(nodes.__class__, TreeNode): nodes = nodes.setClass([nodes]) nodes.setStringRepr(nodes.full_name()) if len(nodes)==0: return MoleculeSet([]), [] # catch the case when nodes is already a MoleculeSet if nodes.elementType in [Molecule, Protein]: molecules = nodes else: # get the set of molecules molecules = nodes.top.uniq() # build the set of nodes for each molecule nodeSets = [] # find out the type of the nodes we want to return searchType=0 if nodeType is None: Klass = nodes.elementType # class of objects in that set else: assert issubclass(nodeType, TreeNode) Klass = nodeType if Klass != nodes.elementType: searchType=1 for mol in molecules: # get set of nodes for this molecule mol_nodes = nodes.get(lambda x, mol=mol: x.top==mol) # get the required types of nodes if searchType: if Klass == Atom and hasattr(mol_nodes, 'allAtoms'): mol_nodes = mol_nodes.allAtoms else: mol_nodes = mol_nodes.findType( Klass ).uniq() stringRepr = nodes.getStringRepr() if stringRepr: if ':' in stringRepr: mol_nodes.setStringRepr( mol.name+stringRepr[stringRepr.index(':'):]) else: mol_nodes.setStringRepr(stringRepr) nodeSets.append( mol_nodes ) return molecules, nodeSets def addMVBasicMenus(self): from Pmv.selectionCommands import MVSelectCommand, MVDeSelectCommand from Pmv.mvCommand import MVPrintNodeNames, MVCenterOnNodes self.addCommand( MVPrintNodeNames(), 'printNodeNames' ) self.addCommand( MVSelectCommand(), 'select' ) self.addCommand( MVDeSelectCommand(), 'deselect' ) self.addCommand( MVCenterOnNodes(), 'centerOnNodes' ) def findPickedAtoms(self, pick): """ given a PickObject this function finds all corresponding atoms. Each atom in the returned set has its attribute pickedInstances set to a list of 2-tuples [(geom, instance),...]. """ allatoms = AtomSet( [] ) # loop over object, i.e. geometry objects for obj, values in pick.hits.items(): # build a list of vertices and list of instances instances = map(lambda x: x[1], values) vertInds = map(lambda x: x[0], values) # only geometry bound to molecules is packable in PMV if not hasattr(obj, 'mol') or len(vertInds)<1: continue # only vertices of geometry have a mapping to atoms # for other types we return an empty atom set if pick.type!='vertices': return allatoms g = obj.mol.geomContainer # convert vertex indices into atoms if g.geomPickToAtoms.has_key(obj.name): # the geometry obj has a function to convert to atoms # specified it he geomContainer[obj], e.g. MSMS surface func = g.geomPickToAtoms[obj.name] if func: atList = func(obj, vertInds) else: atlist = [] else: # we assume a 1 to 1 mapping of vertices with atoms # e.g. the lines geometry atList = [] allAtoms = g.atoms[obj.name] for i in vertInds: atList.append(allAtoms[int(i)]) # build a dict of atoms used to set the pickedAtomInstance # attribute for the last picking operation pickedAtoms = {} # update the pickedAtoms dict for i, atom in enumerate(atList): atomInstList = pickedAtoms.get(atom, None) if atomInstList: atomInstList.append( (obj, instances[i]) ) else: pickedAtoms[atom] = [ (obj, instances[i]) ] # FIXME atoms might appear multiple times because they were picked # in several geometries OR be cause they correspond to different # instances. In the first case (i.e. multiple geometries) # duplicates should be removed, in the latter (multiple instances) # duplicate should be kept # # Apparently we do not get duplication for multiple geoemtry objects! allatoms = allatoms + AtomSet( atList ) # loop over picked atoms and write the instance list into the atom for atom, instances in pickedAtoms.items(): atom.pickedInstances = instances #print allAtoms return allatoms def findPickedBonds(self, pick): """do a pick operation and return a 2-tuple holding (the picked bond, the picked geometry)""" allbonds = BondSet( [] ) for o, val in pick.hits.items(): #loop over geometries # loop over list of (vertices, instance) (e.g. (45, [0,0,2,0])) for instvert in val: primInd = instvert[0] if not hasattr(o, 'mol'): continue g = o.mol.geomContainer if g.geomPickToBonds.has_key(o.name): func = g.geomPickToBonds[o.name] if func: allbonds = allbonds + func(o, primInd) else: l = [] bonds = g.atoms[o.name].bonds[0] for i in range(len(primInd)): l.append(bonds[int(primInd[i])]) allbonds = allbonds + BondSet(l) return allbonds def transformedCoordinatesWithInstances(self, nodes): """ for a nodeset, this function returns transformed coordinates. This function will use the pickedInstance attribute if found. """ # nodes is a list of atoms, residues, chains, etc. where each member # has a pickedInstances attribute which is a list of 2-tuples # (object, [i,j,..]) vt = [] for node in nodes: #find all atoms and their coordinates coords = nodes.findType(Atom).coords if hasattr(node, 'pickedInstances'): # loop over the pickedInstances of this node for inst in node.pickedInstances: geom, instance = inst # inst is a tuple (object, [i,j,..]) M = geom.GetMatrix(geom.LastParentBeforeRoot(), instance[1:]) for pt in coords: ptx = M[0][0]*pt[0]+M[0][1]*pt[1]+M[0][2]*pt[2]+M[0][3] pty = M[1][0]*pt[0]+M[1][1]*pt[1]+M[1][2]*pt[2]+M[1][3] ptz = M[2][0]*pt[0]+M[2][1]*pt[1]+M[2][2]*pt[2]+M[2][3] vt.append( (ptx, pty, ptz) ) else: # no picking ==> no list of instances ==> use [0,0,0,...] g = nodes[0].top.geomContainer.geoms['master'] M = g.GetMatrix(g.LastParentBeforeRoot()) for pt in coords: ptx = M[0][0]*pt[0]+M[0][1]*pt[1]+M[0][2]*pt[2]+M[0][3] pty = M[1][0]*pt[0]+M[1][1]*pt[1]+M[1][2]*pt[2]+M[1][3] ptz = M[2][0]*pt[0]+M[2][1]*pt[1]+M[2][2]*pt[2]+M[2][3] vt.append( (ptx, pty, ptz) ) return vt def Add_ADT(self): """Adds AutoToolsBar""" if self.GUI.toolbarCheckbuttons['ADT']['Variable'].get(): #if self.GUI.menuBars.has_key('AutoTools4Bar'): # self.GUI.menuBars['AutoTools4Bar'].pack(fill='x',expand=1) if hasattr(self.GUI, 'currentADTBar'): self.GUI.menuBars[self.GUI.currentADTBar].pack(fill='x',expand=1) else: self.browseCommands('autotors4Commands', commands = None, package = 'AutoDockTools') self.browseCommands('autoflex4Commands', commands = None, package = 'AutoDockTools') self.browseCommands('autogpf4Commands', commands = None, package = 'AutoDockTools') self.browseCommands('autodpf4Commands', commands = None, package = 'AutoDockTools') self.browseCommands('autostart4Commands', commands = None, package = 'AutoDockTools') self.browseCommands('autoanalyze4Commands', commands = None, package = 'AutoDockTools') self.GUI.currentADTBar = 'AutoTools4Bar' from AutoDockTools import setADTmode setADTmode('AD4.0', self) self.GUI.adt4ModeLabel.bind("<Double-Button-1>", self.ADTSetMode.guiCallback) else: #self.GUI.menuBars['AutoToolsBar'].pack_forget() self.GUI.menuBars[self.GUI.currentADTBar].pack_forget()