def ClosestAtom(): """ask for 2 molecules, compute for each atom the distance to the closest atom in the other molecule. After execution, each atom has a new attribute 'closest' holding the distance""" # it would be better to ask for the attribute's name also from Pmv.guiTools import MoleculeChooser p = MoleculeChooser(self, 'extended', 'Choose 2 molecules') mols = p.go(modal=1) mol1Atoms = mols[0].allAtoms mol2Atoms = mols[1].allAtoms def distanceToClosestPoint(point, setOfPoints): """computes the shortest distance between point and setOfPoints""" diff = Numeric.array(point) - Numeric.array(setOfPoints) diff = diff*diff len = Numeric.sqrt(Numeric.sum(diff,1)) return min(len) for a in mol1Atoms: a.closest = distanceToClosestPoint( a.coords, mol2Atoms.coords) for a in mol2Atoms: a.closest = distanceToClosestPoint( a.coords, mol1Atoms.coords)
def ClosestAtom(): """ask for 2 molecules, compute for each atom the distance to the closest atom in the other molecule. After execution, each atom has a new attribute 'closest' holding the distance""" # it would be better to ask for the attribute's name also from Pmv.guiTools import MoleculeChooser p = MoleculeChooser(self, 'extended', 'Choose 2 molecules') mols = p.go(modal=1) mol1Atoms = mols[0].allAtoms mol2Atoms = mols[1].allAtoms def distanceToClosestPoint(point, setOfPoints): """computes the shortest distance between point and setOfPoints""" diff = Numeric.array(point) - Numeric.array(setOfPoints) diff = diff * diff len = Numeric.sqrt(Numeric.sum(diff, 1)) return min(len) for a in mol1Atoms: a.closest = distanceToClosestPoint(a.coords, mol2Atoms.coords) for a in mol2Atoms: a.closest = distanceToClosestPoint(a.coords, mol1Atoms.coords)
class DeleteMolecule(MVCommand): """Command to delete a molecule from the MoleculeViewer \nPackage : Pmv \nModule : deleteCommands \nClass : DeleteMolecule \nCommand : deleteMolecule \nSynopsis:\n None<---deleteMol(nodes, **kw) \nRequired Arguments:\n nodes --- TreeNodeSet holding the current selection It resets the undo stack automatically.\n """ def onAddCmdToViewer(self): self.vf._deletedLevels = [] if not self.vf.commands.has_key('select'): self.vf.loadCommand("selectionCommands", "select", "Pmv", topCommand=0) if not self.vf.commands.has_key('clearSelection'): self.vf.loadCommand("selectionCommands", "clearSelection", "Pmv", topCommand=0) def onAddObjectToViewer(self, obj): if hasattr(self, 'chooser')\ and self.chooser is not None \ and self.form.root.winfo_exists(): w = self.chooser.form.descr.entryByName['Molecule']['widget'] molParser = obj.parser molStr = molParser.getMoleculeInformation() w.add((obj.name, molStr)) def deleteMolecule_cb(self): """called each time the 'Delete Molecule' button is pressed""" mols = self.chooser.getMolSet() if mols is not None and len(mols): if self.vf.undoCmdStack == []: self.doitWrapper(mols, redraw=0) else: text = """WARNING: This command cannot be undone. if you choose to continue the undo list will be reset. The hide Button will make the molecule disappear without resetting the Undo list. Do you want to continue?""" if not hasattr(self, 'idf'): self.idf = InputFormDescr(title="WARNING") self.idf.append({'widgetType':Tkinter.Label, 'wcfg':{'text':text}, 'gridcfg':{'columnspan':3,'sticky':'w'}}) self.idf.append({'name': 'Continue Button', 'widgetType':Tkinter.Button, 'wcfg':{'text':'CONTINUE', 'command':self.continue_cb}, 'gridcfg':{'sticky':'we'}}) self.idf.append({'name': 'Cancel Button', 'widgetType':Tkinter.Button, 'wcfg':{'text':'CANCEL', 'command':self.cancel_cb}, 'gridcfg':{'row':-1,'sticky':'we'}}) self.idf.append({'name': 'Hide Button', 'widgetType':Tkinter.Button, 'wcfg':{'text':'HIDE', 'command':self.hide_cb}, 'gridcfg':{'row':-1,'sticky':'we'}}) form = self.vf.getUserInput(self.idf, okcancel=0) self.form.root.protocol('WM_DELETE_WINDOW',self.cancel_cb) def hide_cb(self): if hasattr(self, 'chooser'): if self.chooser.ipf.form is not None: mols = self.chooser.getMolSet() self.vf.showMolecules(mols.name, negate=1, topCommand=0) self.chooser.done_cb() self.idf.form.destroy() def continue_cb(self): if hasattr(self, 'chooser'): if self.chooser.ipf.form is not None: mols = self.chooser.getMolSet() self.vf.resetUndo(topCommand=0) self.doitWrapper(mols, redraw=0) self.idf.form.destroy() def cancel_cb(self): self.idf.form.destroy() def guiCallback(self): if len(self.vf.Mols) == 0: return self.chooser = MoleculeChooser(self.vf,mode = 'extended', title='Choose Molecules to delete' ) self.chooser.ipf.append({'name':'Delete Button', 'widgetType':Tkinter.Button, 'text':'Delete Molecule', 'wcfg':{'bd':6}, 'gridcfg':{'sticky':Tkinter.E+Tkinter.W}, 'command': self.deleteMolecule_cb}) self.form = self.chooser.go(modal=0, blocking=0) def deleteMol(self, mol): """ Function to delete all the references to each elements of a molecule and then these elements and the molecule to free the memory space.""" # Call the removeObject function for all the command having an # onRemoveMol function self.vf.removeObject(mol) # Maybe do that in moleculeViewer ??? # also need to clean up selector.selection: nodes = self.vf.getSelection() mol.__class__._numberOfDeletedNodes = 0 node = mol while len(node.children): node = node.children # Initialize the variable _numberOfDeletedNodes at 0 node[0].__class__._numberOfDeletedNodes = 0 sslevels = [Coil, Helix, Strand, Turn] # Initialize the variable _numberOfDeletedNodes for each secondary # structure to 0. for sl in sslevels: # Initialize the variable _numberOfDeletedNodes at 0 sl._numberOfDeletedNodes = 0 # but only change selection if there is any if nodes is not None and len(nodes)>0: setClass = nodes.__class__ thisMolNodes = setClass(nodes.get(lambda x, mol=mol: x.top==mol)) #only change selection if this molecule has any nodes in it if len(thisMolNodes)>0: nodes = nodes-thisMolNodes self.vf.clearSelection(topCommand=0) if nodes is not None: self.vf.select(nodes) #self.vf.selector.select(nodes) if hasattr(self, 'chooser') and self.form.root.winfo_exists(): # update the listChooser lc = self.chooser.ipf.entryByName['Molecule']['widget'] lc.remove(mol.name) #lc.clearComments() #check for any possible reference in self.vf.GUI.VIEWER.lastPick if self.vf.hasGui and self.vf.GUI.VIEWER.lastPick: for key in self.vf.GUI.VIEWER.lastPick.hits.keys(): if hasattr(key,'mol'): if mol==key.mol: del self.vf.GUI.VIEWER.lastPick.hits[key] # Remove the atoms of the molecule you are deleting from the # the AtomSet self.vf.allAtoms self.vf.allAtoms = self.vf.allAtoms - mol.allAtoms # Delete all the reference to the atoms you want to delete if hasattr(mol.allAtoms, 'bonds'): bnds = mol.allAtoms.bonds[0] for b in bnds: b.__dict__.clear() del(b) mol.allAtoms.__dict__.clear() del mol.allAtoms if self.vf.hasGui and hasattr(mol, 'geomContainer'): for g in mol.geomContainer.geoms.values(): if hasattr(g, 'mol'): delattr(g, 'mol') mol.geomContainer.geoms.clear() mol.geomContainer.atoms.clear() delattr(mol.geomContainer, 'mol') del mol.geomContainer if hasattr(mol, 'atmNum'): mol.atmNum.clear() del mol.atmNum if hasattr(mol, 'childByName'): mol.childByName.clear() del mol.childByName if hasattr(mol, 'parser') and hasattr(mol.parser, 'mol'): delattr(mol.parser,'mol') del mol.parser # delete molecule from Vision, if Vision is running if self.vf.visionAPI: self.vf.visionAPI.remove(mol) if len(mol.children): deletedLevels = mol.deleteSubTree() else: deletedLevels = [] # then delete all the refences to the molecule del mol.top # Then delete the molecule deletedLevels.insert(0, mol.__class__) mol.__dict__.clear() del mol self.vf._deletedLevels = deletedLevels if len(self.vf.Mols) == 0 and hasattr(self, 'chooser') \ and self.form.root.winfo_exists(): self.chooser.done_cb() def getFreeMemoryInformation(self): """Store how many TreeNodes have been actually free'ed during the last delete operation in a dictionary""" memoryInformation = {} #print 'self.vf._deletedLevels=', self.vf._deletedLevels for d in self.vf._deletedLevels: #print 'checking ', d, ' for deletedNodes' memoryInformation[d.__name__] = d._numberOfDeletedNodes sslevels = [Coil, Helix, Strand, Turn] ## geomslevels = [IndexedPolylines, IndexedPolygons] # Have to loop on the known secondarystructure because our # Data structure doesn't support multiple children and parents. for sl in sslevels: if sl._numberOfDeletedNodes!=0: memoryInformation[sl.__name__] = sl._numberOfDeletedNodes ## for sg in geomslevels: ## if sl._numberOfDeletedNodes!=0: ## memoryInformation[sl.__name__] = sl._numberOfDeletedNodes return memoryInformation def doit(self, nodes): #if called with no selection, just return molecules, nodeSets = self.vf.getNodesByMolecule(nodes) for mol in molecules: self.deleteMol(mol) def __call__(self, nodes, **kw): """None <- deleteMol(nodes, **kw) \nnodes: TreeNodeSet holding the current selection. \nIt resets the undo stack automatically. """ if type(nodes) is types.StringType: self.nodeLogString = "'"+nodes+"'" self.vf.resetUndo(topCommand=0) apply ( self.doitWrapper, (nodes,), kw )
class DeleteMolecule(MVCommand): """Command to delete a molecule from the MoleculeViewer \nPackage : Pmv \nModule : deleteCommands \nClass : DeleteMolecule \nCommand : deleteMolecule \nSynopsis:\n None<---deleteMol(nodes, **kw) \nRequired Arguments:\n nodes --- TreeNodeSet holding the current selection It resets the undo stack automatically.\n """ def onAddCmdToViewer(self): self.vf._deletedLevels = [] if not self.vf.commands.has_key('select'): self.vf.loadCommand("selectionCommands", "select", "Pmv", topCommand=0) if not self.vf.commands.has_key('clearSelection'): self.vf.loadCommand("selectionCommands", "clearSelection", "Pmv", topCommand=0) def onAddObjectToViewer(self, obj): if hasattr(self, 'chooser')\ and self.chooser is not None \ and self.form.root.winfo_exists(): w = self.chooser.form.descr.entryByName['Molecule']['widget'] molParser = obj.parser molStr = molParser.getMoleculeInformation() w.add((obj.name, molStr)) def deleteMolecule_cb(self): """called each time the 'Delete Molecule' button is pressed""" mols = self.chooser.getMolSet() if mols is not None and len(mols): if self.vf.undoCmdStack == []: undoable = self.undoableVar.get() for mol in mols: self.doitWrapper(mol, redraw=0, undoable=undoable) else: self.continue_cb() def hide_cb(self): if hasattr(self, 'chooser'): if self.chooser.ipf.form is not None: mols = self.chooser.getMolSet() self.vf.showMolecules(mols.name, negate=1, topCommand=0) self.chooser.done_cb() self.idf.form.destroy() def continue_cb(self): if hasattr(self, 'chooser'): if self.chooser.ipf.form is not None: mols = self.chooser.getMolSet() undoable = self.undoableVar.get() if not undoable: self.vf.resetUndo(topCommand=0) for mol in mols: self.doitWrapper(mol, redraw=0, undoable=undoable) #self.idf.form.destroy() def cancel_cb(self): self.idf.form.destroy() def guiCallback(self): if len(self.vf.Mols) == 0: return self.chooser = MoleculeChooser(self.vf, mode='extended', title='Choose Molecules to delete') self.undoableVar = Tkinter.IntVar() self.undoableVar.set(1) self.chooser.ipf.append({ 'name': 'Undo', 'widgetType': Tkinter.Checkbutton, 'wcfg': { 'text': ' Undoable Delete', 'variable': self.undoableVar }, 'gridcfg': { 'sticky': Tkinter.E + Tkinter.W } }) self.chooser.ipf.append({ 'name': 'Delete Button', 'widgetType': Tkinter.Button, 'text': 'Delete Molecule', 'wcfg': { 'bd': 6 }, 'gridcfg': { 'sticky': Tkinter.E + Tkinter.W }, 'command': self.deleteMolecule_cb }) self.form = self.chooser.go(modal=0, blocking=0) def deleteMol(self, mol, undoable=False): """ Function to delete all the references to each elements of a molecule and then these elements and the molecule to free the memory space.""" # Call the removeObject function for all the command having an # onRemoveMol function self.vf.removeObject(mol, undoable=undoable) # Maybe do that in moleculeViewer ??? # also need to clean up selector.selection: nodes = self.vf.getSelection() mol.__class__._numberOfDeletedNodes = 0 node = mol while len(node.children): node = node.children # Initialize the variable _numberOfDeletedNodes at 0 node[0].__class__._numberOfDeletedNodes = 0 sslevels = [Coil, Helix, Strand, Turn] # Initialize the variable _numberOfDeletedNodes for each secondary # structure to 0. for sl in sslevels: # Initialize the variable _numberOfDeletedNodes at 0 sl._numberOfDeletedNodes = 0 # but only change selection if there is any if nodes is not None and len(nodes) > 0: setClass = nodes.__class__ thisMolNodes = setClass(nodes.get(lambda x, mol=mol: x.top == mol)) #only change selection if this molecule has any nodes in it if len(thisMolNodes) > 0: nodes = nodes - thisMolNodes self.vf.clearSelection(topCommand=0) if nodes is not None: self.vf.select(nodes) #self.vf.selector.select(nodes) if hasattr(self, 'chooser') and self.form.root.winfo_exists(): # update the listChooser lc = self.chooser.ipf.entryByName['Molecule']['widget'] lc.remove(mol.name) #lc.clearComments() #check for any possible reference in self.vf.GUI.VIEWER.lastPick if self.vf.hasGui and self.vf.GUI.VIEWER.lastPick: for key in self.vf.GUI.VIEWER.lastPick.hits.keys(): if hasattr(key, 'mol'): if mol == key.mol: del self.vf.GUI.VIEWER.lastPick.hits[key] # Remove the atoms of the molecule you are deleting from the # the AtomSet self.vf.allAtoms self.vf.allAtoms = self.vf.allAtoms - mol.allAtoms if not undoable: # Delete all the reference to the atoms you want to delete if hasattr(mol.allAtoms, 'bonds'): bnds = mol.allAtoms.bonds[0] for b in bnds: b.__dict__.clear() del (b) mol.allAtoms.__dict__.clear() del mol.allAtoms if self.vf.hasGui and hasattr(mol, 'geomContainer'): for g in mol.geomContainer.geoms.values(): if hasattr(g, 'mol'): delattr(g, 'mol') mol.geomContainer.geoms.clear() mol.geomContainer.atoms.clear() delattr(mol.geomContainer, 'mol') del mol.geomContainer if hasattr(mol, 'atmNum'): mol.atmNum.clear() del mol.atmNum if hasattr(mol, 'childByName'): mol.childByName.clear() del mol.childByName if hasattr(mol, 'parser') and hasattr(mol.parser, 'mol'): delattr(mol.parser, 'mol') del mol.parser # delete molecule from Vision, if Vision is running if self.vf.visionAPI: self.vf.visionAPI.remove(mol) if not undoable: if len(mol.children): deletedLevels = mol.deleteSubTree() else: deletedLevels = [] # then delete all the refences to the molecule del mol.top # Then delete the molecule deletedLevels.insert(0, mol.__class__) mol.__dict__.clear() del mol self.vf._deletedLevels = deletedLevels if len(self.vf.Mols) == 0 and hasattr(self, 'chooser') \ and self.form.root.winfo_exists(): self.chooser.done_cb() def getFreeMemoryInformation(self): """Store how many TreeNodes have been actually free'ed during the last delete operation in a dictionary""" memoryInformation = {} #print 'self.vf._deletedLevels=', self.vf._deletedLevels for d in self.vf._deletedLevels: #print 'checking ', d, ' for deletedNodes' memoryInformation[d.__name__] = d._numberOfDeletedNodes sslevels = [Coil, Helix, Strand, Turn] ## geomslevels = [IndexedPolylines, IndexedPolygons] # Have to loop on the known secondarystructure because our # Data structure doesn't support multiple children and parents. for sl in sslevels: if sl._numberOfDeletedNodes != 0: memoryInformation[sl.__name__] = sl._numberOfDeletedNodes ## for sg in geomslevels: ## if sl._numberOfDeletedNodes!=0: ## memoryInformation[sl.__name__] = sl._numberOfDeletedNodes return memoryInformation def doit(self, nodes, undoable=False): #if called with no selection, just return molecules, nodeSets = self.vf.getNodesByMolecule(nodes) event = BeforeDeleteMoleculesEvent(molecules) self.vf.dispatchEvent(event) for mol in molecules: self.deleteMol(mol, undoable) if self.vf.hasGui: self.vf.GUI.VIEWER.SetCurrentObject(self.vf.GUI.VIEWER.rootObject) if not undoable: self.vf.resetUndo(topCommand=0) def __call__(self, nodes, undoable=False, **kw): """None <- deleteMol(nodes, **kw) \nnodes: TreeNodeSet holding the current selection. """ if type(nodes) is types.StringType: self.nodeLogString = "'" + nodes + "'" kw['undoable'] = undoable self.doitWrapper(*(nodes, ), **kw) def setupUndoBefore(self, molecule, undoable=False): if undoable: if type(molecule) is types.StringType: molecules, nodeSets = self.vf.getNodesByMolecule(molecule) if not len(molecules): return molecule = molecules[0] molecule.code = self.vf.getStateCodeForMolecule(molecule) self.addUndoCall([molecule], {}, self.name) def undo(self): """Undo for DeleteMolecule: We use self.vf.getStateCodeForMolecule from setupUndoBefore to restore the state of the molecule. """ mol = self.undoStack.pop() mol = mol[0][0] self.vf.addMolecule(mol) exec(mol.code, {'self': self.vf})