Package Pmv :: Module selectionCommands
[hide private]
[frames] | no frames]

Source Code for Module Pmv.selectionCommands

   1  ############################################################################# 
   2  # 
   3  # Author: Michel F. SANNER and Ruth HUEY 
   4  # 
   5  # Copyright: M. Sanner TSRI 2000 
   6  # 
   7  ############################################################################# 
   8   
   9   
  10  # $Header: /opt/cvs/python/packages/share1.5/Pmv/selectionCommands.py,v 1.118.4.1 2007/07/25 20:19:02 vareille Exp $ 
  11  # 
  12  # $Id: selectionCommands.py,v 1.118.4.1 2007/07/25 20:19:02 vareille Exp $ 
  13  # 
  14   
  15  import Tkinter, types, string, Pmw, os 
  16  import time 
  17  from SimpleDialog import SimpleDialog 
  18   
  19  from Pmv.mvCommand import MVCommand, MVAtomICOM 
  20  from MolKit.tree import TreeNode, TreeNodeSet 
  21  from MolKit.molecule import Atom, AtomSet, Molecule, MoleculeSet, AtomSetSelector 
  22  from MolKit.protein import Residue, Chain, ResidueSet, ChainSet, Protein, ProteinSet 
  23  from MolKit.protein import ResidueSetSelector 
  24  from MolKit.stringSelector import StringSelector 
  25   
  26  from ViewerFramework.VFCommand import CommandGUI, ICOM, ActiveObject 
  27  ##  from ViewerFramework.gui import InputFormDescr 
  28  from mglutil.gui.InputForm.Tk.gui import InputFormDescr 
  29  from mglutil.gui.BasicWidgets.Tk.thumbwheel import ThumbWheel 
  30  from mglutil.gui.BasicWidgets.Tk.customizedWidgets import ListChooser,\ 
  31                                                  ExtendedSliderWidget 
  32   
  33  from DejaVu.Spheres import Spheres 
  34  from DejaVu.IndexedPolygons import IndexedPolygons 
  35   
  36  import Pmv 
  37  if hasattr( Pmv, 'numOfSelectedVerticesToSelectTriangle') is False: 
  38      Pmv.numOfSelectedVerticesToSelectTriangle = 1 
  39   
  40   
41 -class MVSelectCommand(MVCommand, MVAtomICOM):
42 """Class for modfying the current selection in a molecule Viewer. 43 \nselection --- a TreeNodeSet holding the current selection. Modfied by SubClasses implementing a specific selection operation 44 \nlevel --- level at which selection occurs 45 \nPackage : Pmv 46 \nModule : selectionCommands 47 \nClass : MVSelectCommand 48 \nCommand : select 49 \nSynopsis:\n 50 currentSelection <- select(nodes, negate=False, only=False, klass=None) 51 \nRequired Arguments:\n 52 nodes --- can be a string, a TreeNode or a treeNodeSet 53 \nOptional Arguments:\n 54 negate --- is 1 nodes are removed from current selection 55 \nonly --- is 1 the current selection is replaced by the nodes 56 \nklass ----is omitted class of objects in nodes is used, else 57 nodes is converted to a set of objects of type Klass and 58 current selection level is set to klass 59 """ 60 61
62 - def __init__(self, func=None):
63 MVCommand.__init__(self, func) 64 MVAtomICOM.__init__(self) 65 #self.flag = self.flag | self.objArgOnly 66 #self.flag = self.flag | self.negateKw 67 # current selection. Modfied by SubClasses implementing a specific 68 # selection operation 69 self.selection = TreeNodeSet()
70 71
72 - def setupUndoBefore(self, nodes, negate=False, 73 only=False, klass=None, xor=False, 74 intersect=False):
75 kw={} 76 #if len(self.selection): 77 if len(self.vf.selection): 78 kw['only'] = 1 79 self.addUndoCall( (self.vf.selection,), kw, self.name ) 80 else: 81 self.addUndoCall( (), {}, self.vf.clearSelection.name )
82 83 84
85 - def __call__(self, nodes, negate=False, only=False, klass=None, 86 xor=False, intersect=False, **kw):
87 """currentSelection <- select(nodes, negate=False, only=False, 88 klass=None, xor=False, intersect=False ) 89 \nRequired Arguments:\n 90 nodes --- can be a string, a TreeNode or a treeNodeSet 91 \nOptional Arguments:\n 92 negate --- is 1 nodes are removed from current selection 93 \nonly --- is 1 the current selection is replaced by the nodes 94 \nklass ----is omitted class of objects in nodes is used, else 95 nodes is converted to a set of objects of type Klass and 96 current selection level is set to klass 97 """ 98 if type(nodes) is types.StringType: 99 self.nodeLogString = "'"+nodes+"'" 100 nodes = self.vf.expandNodes(nodes) 101 #if len(nodes)==0: return self.selection 102 if len(nodes)==0: return self.vf.selection 103 if klass is None: klass = nodes[0].__class__ 104 if klass != self.vf.selectionLevel: 105 self.vf.setSelectionLevel(klass, topCommand=0, callListener=0) 106 #if klass != self.vf.ICmdCaller.level.value: 107 # self.vf.setIcomLevel(klass, busyIdle=0, log=0) 108 kw['negate']= negate 109 kw['only']= only 110 kw['xor']= xor 111 kw['intersect']= intersect 112 return apply( self.doitWrapper, (nodes,), kw )
113 114
115 - def doit(self, nodes, negate=False, only=False, xor=False, intersect=False):
116 """add/remove nodes to the current selection 117 at this point it is assumed that nodes is of the same type as the 118 current selection 119 """ 120 #print "MVSelectCommand.doit" 121 122 #if len(nodes)==0: return self.selection 123 if len(nodes)==0: return self.vf.selection 124 125 if only: 126 self.vf.selection = nodes 127 128 elif len(self.vf.selection): 129 #in this case have to make selection into nodes.__class__ 130 if self.vf.selection.__class__!= nodes.__class__: 131 self.vf.selection = nodes.__class__(self.vf.selection.data) 132 #also set the level here if necessary 133 self.vf.selectionLevel = nodes.elementType 134 if negate: 135 self.vf.selection = self.vf.selection - nodes 136 elif xor: 137 self.vf.selection = self.vf.selection ^ nodes 138 elif intersect: 139 self.vf.selection = self.vf.selection & nodes 140 else: 141 self.vf.selection = self.vf.selection | nodes 142 elif not negate: 143 self.vf.selection = nodes 144 145 # if the selection level was set on an empty selection without 146 # specifying a KlassSet we have to set the proper class here 147 #if len(self.selection) > 0: 148 #obj = self.selection[0] 149 #if self.selection.__class__ != obj: 150 #self.selection = obj.setClass(self.selection.data) 151 152 if len(self.vf.selection): 153 #remove possible duplicates 154 newVal = self.vf.selection.uniq() 155 if len(newVal)<len(self.vf.selection): 156 # in this case duplicates are removed 157 # but selection is no longer ordered 158 self.vf.selection = newVal 159 160 self.updateSelectionFeedback() 161 162 # highlight selection 163 vi = self.vf.GUI.VIEWER 164 selMols, selAtms = self.vf.getNodesByMolecule(self.vf.selection, Atom) 165 allMols = set( self.vf.Mols[:] ) 166 unselectedMols = allMols.difference(selAtms) 167 for mol in unselectedMols: 168 for geomName, lGeom in mol.geomContainer.geoms.items(): 169 if isinstance(lGeom, Spheres) \ 170 or ( isinstance(lGeom, IndexedPolygons) \ 171 and mol.geomContainer.msmsAtoms.has_key(geomName) ): 172 lGeom.Set(highlight=[]) 173 for mol, atoms in map(None, selMols, selAtms): 174 for geomName, lGeom in mol.geomContainer.geoms.items(): 175 if isinstance(lGeom, Spheres): 176 lAtomSet = mol.geomContainer.atoms[geomName] 177 if len(lAtomSet) > 0: 178 lAtomSetDict = dict(zip(lAtomSet, range(len(lAtomSet)))) 179 highlight = [-1] * len(lAtomSet) 180 for i in range(len(atoms)): 181 lIndex = lAtomSetDict.get(atoms[i], None) 182 if lIndex is not None: 183 highlight[lIndex] = lIndex 184 lGeom.Set(highlight=highlight) 185 elif ( isinstance(lGeom, IndexedPolygons) \ 186 and mol.geomContainer.msmsAtoms.has_key(geomName) ): 187 lAtomSet = mol.geomContainer.msmsAtoms[geomName] 188 if len(lAtomSet) > 0: 189 lAtomSetDict = dict(zip(lAtomSet, range(len(lAtomSet)))) 190 lAtomIndices = [] 191 for i in range(len(atoms)): 192 lIndex = lAtomSetDict.get(atoms[i], None) 193 if lIndex is not None: 194 lAtomIndices.append(lIndex) 195 lSrfMsms = mol.geomContainer.msms[geomName][0] 196 lvf, lvint, lTri = lSrfMsms.getTriangles(lAtomIndices, 197 selnum=Pmv.numOfSelectedVerticesToSelectTriangle, 198 keepOriginalIndices=1) 199 highlight = [-1] * len(lGeom.vertexSet.vertices) 200 for lThreeIndices in lTri: 201 highlight[int(lThreeIndices[0])] = lThreeIndices[0] 202 highlight[int(lThreeIndices[1])] = lThreeIndices[1] 203 highlight[int(lThreeIndices[2])] = lThreeIndices[2] 204 lGeom.Set(highlight=highlight) 205 206 return self.vf.selection
207 208 209
210 - def startICOM(self):
211 #print "in select.startICOM: mv.selectionLevel=", self.vf.selectionLevel 212 #print "mv.selection=", self.vf.selection 213 #print "in select.startICOM: mv.ICmdCaller.level.value=", self.vf.ICmdCaller.level.value 214 self.vf.setSelectionLevel( self.vf.ICmdCaller.level.value)
215 216
217 - def setLevel(self, Klass, KlassSet=None):
218 print "this method is deprecated" 219 return "ERROR"
220 #assert issubclass(Klass, TreeNode) 221 #if Klass==self.vf.ICmdCaller.level.value: 222 # return self.vf.ICmdCaller.level.value 223 #self.vf.ICmdCaller.level.Set(Klass) 224 # 225 # if len(self.selection) > 0: 226 # newsel = self.selection.findType(Klass, uniq=1) 227 # if newsel: 228 # self.selection = newsel 229 # else: 230 # s = "level %s not found for current selection" % \ 231 # Klass.__name__ 232 # self.vf.warningMsg(s) 233 # return self.vf.ICmdCaller.level.value 234 # else: 235 # if KlassSet: 236 # self.selection = KlassSet() 237 # 238 # self.updateSelectionFeedback() 239 # return self.vf.ICmdCaller.level 240 241
242 - def updateSelectionFeedback(self):
243 self.updateInfoBar() 244 self.updateSelectionIcons()
245 246
247 - def updateInfoBar(self):
248 if self.vf.selectionLevel: 249 ## msg = '\t Current selection: %d %s(s)' % ( len(self.selection), 250 ## self.vf.ICmdCaller.level.value.__name__) 251 msg = '%d %s(s)' % ( len(self.vf.selection), 252 self.vf.selectionLevel.__name__ ) 253 else: 254 msg = '0 %s(s)'% self.vf.selectionLevel__name__ 255 self.vf.GUI.pickLabel.configure( text=msg )
256 257
258 - def updateSelectionIcons(self):
259 """update selection icons""" 260 261 #if SelectionSpheres is currently turned on: 262 if self.vf.userpref['showSelectionSpheres']['value']==1: 263 # if there is no selection: turn all spheres off 264 if len(self.vf.selection)==0: 265 for mol in self.vf.Mols: 266 mol.geomContainer.geoms['selectionSpheres'].Set( 267 visible=0, tagModified=False) 268 else: 269 selMols, selAtms = self.vf.getNodesByMolecule(self.vf.selection, 270 Atom) 271 for mol, atms in map(None, selMols, selAtms): 272 g = mol.geomContainer.geoms['selectionSpheres'] 273 #need to get nodes in this mol 274 if self.vf.viewSelectionIcon=='labels': 275 lab = ('O',)*len(atms) 276 g.Set(vertices=atms.coords, labels=lab, visible=1, 277 tagModified=False) 278 else: 279 g.Set(vertices=atms.coords, visible=1, 280 tagModified=False) 281 #molecules w/ no atoms selected don't 282 nonselMols = self.vf.Mols - selMols 283 for mol in nonselMols: 284 mol.geomContainer.geoms['selectionSpheres'].Set( 285 visible=0, tagModified=False) 286 287 self.vf.GUI.VIEWER.Redraw() 288 289 #if SelectionSpheres is currently turned off: 290 # turn off all spheres and update 291 else: 292 for mol in self.vf.Mols: 293 mol.geomContainer.geoms['selectionSpheres'].Set( 294 visible=0, tagModified=False)
295 296
297 - def clear(self):
298 self.vf.selection.data = [] 299 self.updateSelectionFeedback()
300 301
302 - def dump(self):
303 for o in self.vf.selection: 304 self.message( o.full_name() )
305 306
307 -class MVAddSelectCommand(MVSelectCommand):
308 """This Command adds to the current selection 309 \nPackage : Pmv 310 \nModule : selectionCommands 311 \nClass : MVAddSelectCommand 312 \nCommand : addselect 313 \nSynopsis:\n 314 currentSelection <--- addselect(nodes, klass=None, **kw) 315 \nRequired Arguments:\n 316 nodes --- TreeNodeSet holding the current selection 317 \nklass --- if specified nodes are converted to a set of that type otherwise 318 and selection level is set to Klass. 319 """
320 - def __call__(self, nodes, klass=None, **kw):
321 """currentSelection <- addselect(nodes, klass=None, **kw) 322 \nnodes --- TreeNodeSet holding the current selection 323 \nklass --- if specified nodes are converted to a set of that type otherwise 324 and selection level is set to Klass. 325 """ 326 kw['negate']= 0 327 kw['klass'] = klass 328 apply( self.vf.select, (nodes,), kw )
329 330
331 -class MVXorSelectCommand(MVSelectCommand):
332 """This Command xors the current selection 333 \nPackage : Pmv 334 \nModule : selectionCommands 335 \nClass : MVXorSelectCommand 336 \nCommand : xorselect 337 \nSynopsis:\n 338 currentSelection <--- xorselect(nodes, klass=None, **kw) 339 \nRequired Arguments:\n 340 nodes --- TreeNodeSet holding the current selection 341 \nklass --- if specified nodes are converted to a set of that type otherwise 342 and selection level is set to Klass. 343 """
344 - def __call__(self, nodes, klass=None, **kw):
345 """currentSelection <- xorselect(nodes, klass=None, **kw) 346 \nnodes --- TreeNodeSet holding the current selection 347 \nklass --- if specified nodes are converted to a set of that type otherwise 348 and selection level is set to Klass. 349 """ 350 kw['negate']= 0 351 kw['only']= 1 352 kw['klass'] = klass 353 if len(self.vf.selection): 354 current = self.vf.selection.findType(nodes.setClass) 355 new_sel = current ^ nodes 356 else: 357 new_sel = nodes 358 apply( self.vf.select, (new_sel,), kw )
359 #apply( self.vf.select, (nodes,), kw ) 360 361 362
363 -class MVDeSelectCommand(MVSelectCommand):
364 """This Command deselects the current selection 365 \nPackage : Pmv 366 \nModule : selectionCommands 367 \nClass : MVDeSelectCommand 368 \nCommand : deselect 369 \nSynopsis:\n 370 currentSelection <--- deselect(nodes, klass=None, **kw) 371 \nRequired Arguments:\n 372 nodes --- TreeNodeSet holding the current selection 373 \nklass --- if specified nodes are converted to a set of that type otherwise 374 and selection level is set to Klass. 375 """
376 - def __call__(self, nodes, klass=None, **kw):
377 """currentSelection <- deselect(nodes, klass=None, **kw) 378 \nnodes --- TreeNodeSet holding the current selection 379 \nklass --- if specified nodes are converted to a set of that type otherwise 380 and selection level is set to Klass. 381 """ 382 kw['negate']= 1 383 kw['klass'] = klass 384 apply( self.vf.select, (nodes,), kw )
385 386 387
388 -class MVClearSelection(MVCommand):
389 """ MVClearSelect implements method to clear the current selection. 390 \nPackage : Pmv 391 \nModule : selectionCommands 392 \nClass : MVClearSelection 393 \nCommand : clearSelection 394 \nSynopsis:\n 395 None <- clearSelection(**kw) 396 """ 397
398 - def setupUndoBefore(self):
399 select = self.vf.select 400 if len(self.vf.selection): 401 self.addUndoCall( (self.vf.selection,), {}, select.name )
402 403
404 - def guiCallback(self, event=None):
405 self.doitWrapper()
406 407
408 - def doit(self):
409 self.vf.select.clear() 410 411 vi = self.vf.GUI.VIEWER 412 for mol in self.vf.Mols: 413 for geomName, lGeom in mol.geomContainer.geoms.items(): 414 if isinstance(lGeom, Spheres) \ 415 or ( isinstance(lGeom, IndexedPolygons) \ 416 and mol.geomContainer.msmsAtoms.has_key(geomName) ) : 417 lGeom.Set(highlight=[])
418 419
420 - def __call__(self, **kw):
421 """None <- clearSelection(**kw)""" 422 423 apply( self.doitWrapper, (), kw )
424 425 MVClearSelectionGUI = CommandGUI() 426 from moleculeViewer import ICONPATH 427 MVClearSelectionGUI.addToolBar('Clear', icon1 = 'eraser.gif', 428 type = 'ToolBarButton', icon_dir=ICONPATH, 429 balloonhelp = 'Clear Selection', index = 3) 430 ########################################################################## 431 ########################################################################## 432 # 433 # Support for static sets 434 # 435 ########################################################################## 436 ########################################################################## 437 438 439 sets__ = {} # name: (set,comments) 440
441 -class MVSaveSetCommand(MVCommand):
442 443 """Save a selection under a user specified name 444 \nPackage : Pmv 445 \nModule : selectionCommands 446 \nClass : MVSaveSetCommand 447 \nCommand : saveSet 448 \nSynopsis:\n 449 None <- saveSet(nodes, name, comments='No description', **kw) 450 \nRequired Arguments:\n 451 nodes --- TreeNodeSet holding the current selection 452 \nname --- name under which the selected set will be saved 453 \nOptional Arguments:\n 454 comments --- description of the saved set, default is 'No description' 455 addToDashboard --whether to add set name to dashboard historylist, default is do not add 456 """ 457
458 - def doit(self, nodes, name, comments=None, addToDashboard=False):
459 nodes = self.vf.expandNodes(nodes) 460 if len(nodes)==0: 461 return 462 if comments==None: 463 comments='No description' 464 #sets__[name] = (nodes.__class__( nodes.data), comments) 465 nodes.comments = comments 466 self.vf.sets.add(name, nodes) 467 if addToDashboard: 468 n = nodes[0].isBelow(Molecule) 469 kstr = n*':' + name 470 self.vf.dashboard.tree.selectorEntry.insert('end', kstr) 471 # if vision is started add the set to the Pmv library 472 if self.vf.visionAPI: 473 fullname = nodes.full_name() 474 self.vf.visionAPI.add(nodes, name, kw={ 475 'set':nodes, 476 'selString': fullname, 477 'constrkw':{ 478 # selString gets defined in the node's getDefinitionSourceCode 479 #'set':'masterNet.editor.vf.select(selString)', 480 'set':'masterNet.editor.vf.sets["%s"]'%(name), 481 'selString': 'selString', 482 } 483 } 484 ) 485 return name
486 487
488 - def __call__(self, nodes, name, comments='No description', **kw):
489 """ None <- saveSet(nodes, name, comments='No description', **kw) 490 \nnodes --- TreeNodeSet holding the current selection 491 \nname --- name under which the selected set will be saved 492 \ncomments --- description of the saved set, default is 'No description' 493 """ 494 #if name in sets__.keys(): 495 if name in self.vf.sets.keys(): 496 newname = name + '_' + str(len(self.vf.sets.keys())) 497 self.vf.warningMsg('set name %s already used\nrenaming it %s' % ( 498 name, newname ) ) 499 name = newname 500 501 kw['comments'] = comments 502 if type(nodes) is types.StringType: 503 self.nodeLogString = "'" + nodes +"'" 504 nodes = self.vf.expandNodes(nodes) 505 return apply( self.doitWrapper, (nodes, name), kw )
506
507 - def buildFormDescr(self, formName):
508 if formName=='saveSet': 509 idf = InputFormDescr(title = 'Set Name') 510 idf.append( { 'name': 'setname', 511 'widgetType':Tkinter.Entry,'required':1, 512 'wcfg':{'label':'Set Name'}} ) 513 idf.append( {'name': 'comments', 514 'widgetType':Tkinter.Entry, 515 'defaultValue':'No description', 516 'wcfg':{'label':'Comments'}} ) 517 self.idf = idf 518 return idf
519
520 - def guiCallback(self):
521 if len(self.vf.selection)==0: 522 self.warningMsg("No selection to be saved as a set") 523 return 524 525 ## # create the form descriptor 526 ## idf = InputFormDescr(title = 'Set Name') 527 ## idf.append( { 'name': 'setname', 528 ## 'widgetType':Tkinter.Entry,'required':1, 529 ## 'wcfg':{'label':'Set Name'}} ) 530 ## idf.append( {'name': 'comments', 531 ## 'widgetType':Tkinter.Entry, 532 ## 'defaultValue':'No description', 533 ## 'wcfg':{'label':'Comments'}} ) 534 ## ## idf.append( { 'name': 'setname', 'label':'Set Name', 535 ## ## 'widgetType':Tkinter.Entry,'required':1} ) 536 ## ## idf.append( {'name': 'comments', 'label':'Comments', 537 ## ## 'widgetType':Tkinter.Entry,'defaultValue':'No description'} ) 538 ## val = self.vf.getUserInput(idf) 539 val = self.showForm('saveSet') 540 if val: 541 while len(val)==0 or val['setname'] in self.vf.sets.keys(): 542 t = 'set name %s already used' % val['setname'] 543 d = SimpleDialog(self.vf.GUI.ROOT, text=t, 544 buttons=["Continue"], 545 default=0, title="ERROR") 546 ok=d.go() 547 val = self.vf.getUserInput(self.idf) 548 name = val['setname'] 549 del val['setname'] 550 return apply( self.doitWrapper, (self.vf.getSelection()[:], name,), val )
551 552 mvSaveSetCommandGuiDescr = {'widgetType':'Menu', 'menuBarName':'menuRoot', 553 'menuButtonName':'Select', 554 'menuEntryLabel':'Save current selection as a set'} 555 556 MVSaveSetCommandGUI = CommandGUI() 557 MVSaveSetCommandGUI.addMenuCommand('menuRoot', 'Select', 558 'Save current selection as a set') 559 560
561 -class MVCreateSetIfNeeded(MVCommand):
562 563 """create a set, but only if it does not already exist 564 \nPackage : Pmv 565 \nModule : selectionCommands 566 \nClass : MVCreateSetIfNeeded 567 \nCommand : createSetIfNeeded 568 \nSynopsis:\n 569 None <- createSetIfNeeded(nodes, name, comments='No description',**kw) 570 \nRequired Arguments:\n 571 nodes --- TreeNodeSet holding the current selection 572 \nname --- name under which the selected set will be saved 573 \nOptional Argumnets:\n 574 comments --- description of the saved set, default is 'No description' 575 """ 576
577 - def doit(self, nodes, name, comments=None):
578 579 #nodes = self.vf.expandNodes(nodes) 580 if len(nodes)==0: return 581 if comments==None: 582 comments='No description' 583 #sets__[name] = (nodes.__class__( nodes.data), comments) 584 #sets__[name] = (nodes, comments) 585 nodes.comments = comments 586 self.vf.sets.add(name, nodes) 587 if self.vf.visionAPI: 588 fullname = nodes.full_name() 589 self.vf.visionAPI.add(nodes, name, kw={ 590 'set':nodes, 591 'selString': fullname, 592 'name': name, 593 'constrkw':{ 594 'set':'masterNet.editor.vf.select("%s")'%fullname, 595 'selString': fullname, 596 'name':name} 597 } 598 ) 599 return self.vf.sets[name]
600 601
602 - def __call__(self, nodes, name, comments='No description', **kw):
603 """ None <- createSetIfNeeded(nodes, name, comments='No description',**kw) 604 \nnodes --- TreeNodeSet holding the current selection 605 \nname --- name under which the selected set will be saved 606 \ncomments --- description of the saved set, default is 'No description' 607 """ 608 if name in self.vf.sets.keys(): 609 return 610 611 kw['comments'] = comments 612 nodes = self.vf.expandNodes(nodes) 613 if type(nodes) is types.StringType: 614 self.nodeLogString = "'" + nodes +"'" 615 apply( self.doitWrapper, (nodes, name), kw )
616 617 # we do not expose this command in the menu bar 618
619 -class MVSelectSetCommand(MVCommand):
620 """This Command is used to select the saved set. 621 \nPackage : Pmv 622 \nModule : selectionCommands 623 \nClass : MVSelectSetCommand 624 \nCommand : selectSet 625 \nSynopsis:\n 626 None <- selectSet(setNames, only=False, negate=False) 627 \nRequired Arguments:\n 628 setNameStr---name 629 \nOptional Argumnets:\n 630 only=negate=0:selected set is added to the selection 631 \nonly=0,negate=1: selected set is removed from the selection 632 \nonly=1,negate=0: selected set is the only thing selected""" 633
634 - def onRemoveObjectFromViewer(self, mol):
635 if not self.vf.sets.keys(): return 636 for k in self.vf.sets.keys(): 637 nodes = self.vf.sets[k] 638 if mol in nodes.top.uniq(): 639 if len(nodes.top.uniq())==1: 640 del self.vf.sets[k] 641 else: 642 molNodes = nodes.get(lambda x, mol=mol: x.top==mol) 643 newSet = nodes - molNodes 644 newComments = self.vf.sets[k].comments + ' the elements of this set belonging to %s have been deleted with the molecule'%mol.name 645 del self.vf.sets[k] 646 newSet.comments = newComments 647 self.vf.sets.add(k, newSet) 648 del molNodes 649 del nodes
650 651
652 - def setupUndoBefore(self, name, negate=False, only=False):
653 # we overwrite setupUndoBefore enven though this command implements 654 # the negate kw because the only kw would not be handled properly 655 656 # create command to select the current selection 657 # WARNING we cannot use getSelection here since it would 658 # return everything is nothing is selected 659 select = self.vf.select 660 if len(self.vf.selection)==0: 661 self.addUndoCall( (), {}, self.vf.clearSelection.name ) 662 else: 663 self.addUndoCall( (self.vf.selection,), {},select.name )
664 665
666 - def doit(self, setNames, negate=False, only=False ):
667 """None <- selectSet(setNames, only=False, negate=False) 668 \nsetNames can be a string or a list of strings 669 \nonly=negate=0:selected set is added to the selection 670 \nonly=0, negate=1: selected set is removed from the selection 671 \nonly=1, negate=0: selected set is the only thing selected""" 672 673 if type(setNames)==types.StringType: 674 names = [setNames] 675 else: 676 try: 677 l = len(setNames) 678 except: 679 self.vf.warningMsg('Bad argument for set setNamess') 680 return 681 names = setNames 682 683 if only: 684 self.vf.clearSelection(topCommand=0) 685 686 nodes = [] 687 set_names = self.vf.sets.keys() 688 for name in names: 689 if name not in set_names: 690 msgStr='\''+name+'\'' + ' not a previously defined set!' 691 self.vf.warningMsg(msgStr) 692 else: 693 #what if nodes and specified sets are not the same level? 694 nodes = nodes + self.vf.sets[name] 695 #try: 696 # nodes = nodes + sets__[name][0] 697 #except KeyError: 698 # msgStr='\''+name+'\'' + ' not a previously defined set!' 699 # self.vf.warningMsg(msgStr) 700 #if called with non-existent set, don't try to select it 701 if nodes: 702 self.vf.select( nodes, negate=negate, topCommand=0 )
703 704
705 - def guiCallback(self):
706 idf = InputFormDescr(title ='') 707 entries = [] 708 #names = sets__.keys() 709 names = self.vf.sets.keys() 710 names.sort() 711 #for n in names: 712 for key, value in self.vf.sets.items(): 713 entries.append( (key, value.comments) ) 714 #entries.append( (n, sets__[n][1]) ) 715 716 idf.append({'name':'set', 717 'widgetType':ListChooser, 718 'wcfg':{'mode':'extended', 719 'entries': entries, 720 'title':'Choose an item: '}}) 721 idf.append({'name': 'only', 'widgetType':Tkinter.Checkbutton, 722 'wcfg':{'text': 'Select this set only', 723 'variable': Tkinter.IntVar()}, 724 'gridcfg':{'sticky': Tkinter.W}}) 725 idf.append({'name': 'negate', 'widgetType':Tkinter.Checkbutton, 726 'wcfg':{'text': 'Deselect this set', 727 'variable': Tkinter.IntVar()}, 728 'gridcfg':{'sticky': Tkinter.W}}) 729 vals = self.vf.getUserInput(idf) 730 self.ipf = idf 731 if len(vals)>0 and len(vals['set'])> 0: 732 setNames = vals['set'] 733 del vals['set'] 734 apply( self.doitWrapper, (setNames,), vals )
735 736
737 - def __call__(self, setNames, negate=False, only=False, **kw):
738 """None <- selectSet(setNames, only=0, negate=0) 739 \nsetNames can be a string or a list of strings 740 \nonly=negate=0:selected set is added to the selection 741 \nonly=0, negate=1: selected set is removed from the selection 742 \nonly=1, negate=0: selected set is the only thing selected""" 743 kw['negate'] = negate 744 kw['only'] = only 745 apply( self.doitWrapper, (setNames,), kw )
746 747 mvSelectSetCommandGuiDescr = {'widgetType':'Menu', 'menuBarName':'menuRoot', 748 'menuButtonName':'Select', 749 'menuEntryLabel':'Select a set'} 750 751 MVSelectSetCommandGUI = CommandGUI() 752 MVSelectSetCommandGUI.addMenuCommand('menuRoot', 'Select', 'Select a set', 753 separatorBelow=1 ) 754 755 ########################################################################## 756 ########################################################################## 757 # 758 # Support for other selection 759 # 760 ########################################################################## 761 ########################################################################## 762 763
764 -class MVSelectFromStringCommand(MVCommand):
765 """ molStr,chainStr,residueStr,atomStr Select items by typed-in strings: one for each level. No entry corresponds to select everything at this level. Strings are parsed as would-be regular expressions, replacing * by .*.... 766 \nPackage : Pmv 767 \nModule : selectionCommands 768 \nClass : MVSelectFromStringCommand 769 \nCommand : selectFromString 770 \nSynopsis:\n 771 None <- selectFromString(mols='', chains='', res='', atoms='', deselect=False, silent=False, **kw) 772 \nArguments:\n 773 mols, chains, res and atoms are strings. *?-, are supported 774 \nsilent --- when true, the program changes level without asking the user 775 \nnegate --- when True, the command does a deselect operation 776 """ 777
778 - def __init__(self):
779 self.form = None 780 MVCommand.__init__(self)
781 782
783 - def onAddCmdToViewer(self):
784 if self.vf.hasGui: 785 self.selPick = Tkinter.IntVar() 786 self.showSelSpheres = Tkinter.IntVar() 787 self.molCts={} 788 self.chainCts={}
789 790
791 - def setupUndoBefore(self, *args, **kw):
792 select = self.vf.select 793 oldselection = self.vf.selection 794 self.addUndoCall( (), {}, self.vf.clearSelection.name ) 795 if len(oldselection): 796 self.addUndoCall( (oldselection,), {}, select.name )
797 798
799 - def doit(self, mols='', chains='', res='', atoms='', negate=False, 800 silent=False, xor=False, intersect=False, nodes=None ):
801 802 if not len(nodes): 803 self.vf.warningMsg("no molecules in viewer") 804 return 'ERROR' 805 806 userpref = self.vf.userpref['selectStringMatchMode']['value'] 807 caseSensitive = True 808 escapeCharacters=True 809 if 'caseInsens' in userpref: 810 caseSensitive = False 811 if 'WithEscapedChars' in userpref: 812 escapeCharacters=True 813 #if userpref == 'caseInsensWithEscapedChars': 814 # newitem = 'cIWEC' 815 #elif userpref == 'caseInsensitive': 816 # newitem = 'cI' 817 #else: newitem = 'cS' 818 819 selectionList = [mols, chains, res, atoms] 820 #need to format this correctly 821 if atoms!='': 822 selectionString = string.join(selectionList, ':') 823 elif res!='': 824 selectionString = string.join(selectionList[:-1], ':') 825 elif chains!='': 826 selectionString = string.join(selectionList[:-2], ':') 827 else: 828 selectionString = mols 829 selitem, selMsg = StringSelector().select(nodes.top.uniq(), 830 selectionString, self.vf.sets, caseSensitive, 831 escapeCharacters) 832 833 if not selitem: 834 msg = 'No new selection:\n'+ selMsg 835 self.vf.warningMsg(msg) 836 return 'ERROR' 837 838 if len(selMsg): 839 self.vf.warningMsg(selMsg) 840 841 if selitem and len(selitem) > 0: 842 lev = selitem[0].__class__ 843 if lev == Protein: lev = Molecule 844 if self.vf.selectionLevel != lev: 845 self.vf.setSelectionLevel(selitem[0].__class__, busyIdle=0, log=0) 846 # if not silent: 847 # t = "Current selection level is %s\nThis set holds %s objects. Do \ 848 #you want to set the selection level to %s ?" % (self.vf.selectionLevel, 849 # lev, lev) 850 # d = SimpleDialog(self.vf.GUI.ROOT, text=t, 851 # buttons=["Yes","No"], 852 # default=0, title="change selection level") 853 # ok=d.go() 854 # if ok==0: #answer was yes 855 # self.vf.setSelectionLevel(selitem[0].__class__, busyIdle=0, log=0) 856 # #self.vf.setIcomLevel( selitem[0].__class__, log = 0, 857 # #KlassSet = selitem[0].setClass , topCommand=0) 858 # else: 859 # return 'ERROR' # prevent logging 860 # else: 861 # self.vf.setSelectionLevel(selitem[0].__class__, busyIdle=0, log=0) 862 863 self.vf.select( selitem , negate=negate, xor=xor, 864 intersect=intersect, topCommand=0) 865 #if not negate: 866 # self.vf.select( selitem , negate=negate, topCommand=0) 867 #else: 868 # #can't just deselect because SFString inherits from select 869 # old = self.vf.getSelection()[:] 870 # if len(old)==0: return 871 # else: 872 # self.vf.clearSelection(topCommand=0) 873 # if len(selitem)!=len(old): 874 # self.vf.select(old-selitem, topCommand=0) 875 if self.form: self.form.lift() 876 return self.vf.getSelection()
877 878
879 - def __call__(self, mols='', chains='', res='', atoms='', negate=False, 880 silent=True, xor=False, intersect=False, nodes=None, **kw):
881 """None <- selectFromString(nodes, mols='', chains='', res='', atoms='', deselect=False, silent=False, **kw) 882 \nmols, chains, res and atoms are strings. *?-, are supported 883 \nsilent: when true, the program changes level without asking the user 884 \nnegate: when True, the command does a deselect operation 885 \nnodes : nodes that will expand to molecules to be used to select from 886 """ 887 #print "in selectFromString.__call__ with xor=", xor 888 kw['mols'] = mols 889 kw['chains'] = chains 890 kw['res'] = res 891 kw['atoms'] = atoms 892 kw['negate'] = negate 893 kw['silent'] = silent 894 kw['xor'] = xor 895 kw['intersect'] = intersect 896 kw['log'] = False 897 if nodes is None: 898 nodes = self.vf.Mols 899 elif isinstance(nodes, TreeNode): 900 nodes = nodes.setClass([nodes]) 901 kw['nodes'] = nodes 902 return apply( self.doitWrapper, (), kw )
903 904
905 - def buildForm(self, event=None):
906 self.selPick.set(0) 907 ifd = self.ifd = InputFormDescr(title = 'Select From String') 908 ifd.append({'widgetType':Tkinter.Label, 909 'wcfg':{'text': 'Molecule'}, 910 'gridcfg':{'sticky':'w'} }) 911 ifd.append({'name':'molWid', 912 'widgetType':Tkinter.Entry, 913 'wcfg':{'highlightcolor':'white'}, 914 'gridcfg':{'sticky':'ew','row':-1, 'column':1, 'columnspan':3} }) 915 #'gridcfg':{'sticky':Tkinter.E,'columnspan':4} }) 916 ifd.append({'widgetType':Tkinter.Label, 917 'wcfg':{'text': 'Chain'}, 918 'gridcfg':{'sticky':'w'} }) 919 ifd.append({'name': 'chainWid', 920 'widgetType':Tkinter.Entry, 921 'wcfg':{'highlightcolor':'white'}, 922 'gridcfg':{'sticky':'ew','row':-1, 'column':1, 'columnspan':3} }) 923 #ifd.append({'widgetType':Tkinter.Entry, 924 # 'wcfg':{'label': 'Chain'}, 925 # 'gridcfg':{'sticky':'ew','columnspan':4} }) 926 # #'gridcfg':{'sticky':Tkinter.E, 'columnspan':4} }) 927 ifd.append({'widgetType':Tkinter.Label, 928 'wcfg':{'text': 'Residue'}, 929 'gridcfg':{'sticky':'w'} }) 930 ifd.append({'name':'resWid', 931 'widgetType':Tkinter.Entry, 932 'wcfg':{'highlightcolor':'white'}, 933 'gridcfg':{'sticky':'ew','row':-1, 'column':1, 'columnspan':3} }) 934 #ifd.append({'widgetType':Tkinter.Entry, 935 # 'wcfg':{'label': 'Residue'}, 936 # 'gridcfg':{'sticky':'ew','columnspan':4} }) 937 # #'gridcfg':{'sticky':Tkinter.E, 'columnspan':4} }) 938 ifd.append({'widgetType':Tkinter.Label, 939 'wcfg':{'text': 'Atom'}, 940 'gridcfg':{'sticky':'w'} }) 941 ifd.append({'name':'atomWid', 942 'widgetType':Tkinter.Entry, 943 'wcfg':{'highlightcolor':'white'}, 944 'gridcfg':{'sticky':'ew','row':-1, 'column':1, 'columnspan':3} }) 945 #ifd.append({'widgetType':Tkinter.Entry, 946 # 'wcfg':{'label': 'Atom'}, 947 # 'gridcfg':{'sticky':'ew','columnspan':4} }) 948 # #'gridcfg':{'sticky':Tkinter.E,'columnspan':4} }) 949 ifd.append({'name': 'Mol List', 950 'widgetType':Tkinter.Menubutton, 951 'wcfg':{ 'text': 'Molecule List ...'}, 952 'gridcfg':{'sticky':Tkinter.W,'row':-4,'column':4, 953 'columnspan':2} }) 954 ifd.append({'name': 'Chain List', 955 'widgetType':Tkinter.Menubutton, 956 'wcfg':{'text': 'Chain List ...'}, 957 'gridcfg':{'sticky':Tkinter.W, 'column':4,'row':-3, 958 'columnspan':2} }) 959 ifd.append({'name': 'Residue Sets', 960 'widgetType':Tkinter.Menubutton, 961 'wcfg':{'text': 'Residue Sets...'}, 962 'gridcfg':{'sticky':Tkinter.W, 'column':4,'row':2, 963 'columnspan':2} }) 964 ifd.append({'name': 'Atom Sets', 965 'widgetType':Tkinter.Menubutton, 966 'text': 'Atom Sets...', 967 'gridcfg':{'sticky':Tkinter.W, 'column':4,'row':3, 968 'columnspan':2} }) 969 #ifd.append({'name': 'Sets List', 970 # 'widgetType':Tkinter.Menubutton, 971 # 'wcfg':{'text': 'Sets List ...'}, 972 # 'gridcfg':{'sticky':Tkinter.W, 'column':4, 973 # 'row':3,'columnspan':2} }) 974 ifd.append({'name': 'addBut', 975 'widgetType':Tkinter.Button, 976 'wcfg':{'bd':3, 'text': 'Add', 977 'command': self.add}, 978 'gridcfg':{'sticky':Tkinter.E+Tkinter.W,'row':4, 979 'column':0, 'columnspan':1}, 980 }) 981 ifd.append({'name': 'removeBut', 982 'widgetType':Tkinter.Button, 983 'wcfg':{'bd':3, 'text': 'Remove', 984 'command': self.remove}, 985 'gridcfg':{'sticky':Tkinter.E+Tkinter.W,'row':4, 986 'column':1, 'row':-1, 'columnspan':2}, 987 }) 988 ifd.append({'name': 'xorBut', 989 'widgetType':Tkinter.Button, 990 'wcfg':{'bd':3, 'text': 'Xor', 991 'command': self.xor}, 992 'gridcfg':{'sticky':Tkinter.E+Tkinter.W,'row':4, 993 'column':3,'row':-1, 'columnspan':1}, 994 }) 995 ifd.append({'name': 'intersectBut', 996 'widgetType':Tkinter.Button, 997 'wcfg':{'bd':3, 'text': 'Intersect', 998 'command': self.intersect}, 999 'gridcfg':{'sticky':Tkinter.E+Tkinter.W,'row':4, 1000 'column':4, 'row':-1, 'columnspan':2}, 1001 }) 1002 1003 1004 # ifd.append({'name': 'Select', 1005 # 'widgetType':Tkinter.Button, 1006 # 'wcfg':{'bd':6, 'text': 'Select', 1007 # 'command': self.callDoit}, 1008 # 'gridcfg':{'sticky':Tkinter.E+Tkinter.W,'row':4, 1009 # 'column':0, 'columnspan':4}, 1010 # }) 1011 # ifd.append({'name': 'Deselect', 1012 # 'widgetType':Tkinter.Button, 1013 # 'wcfg':{'text': 'Deselect','bd':6, 1014 # 'command': self.callDontDoit}, 1015 # 'gridcfg':{'sticky':Tkinter.E+Tkinter.W, 1016 # 'row':4,'column':4, 1017 # 'columnspan':2}, 1018 # }) 1019 ifd.append({'name': 'Clear Selection', 1020 'widgetType':Tkinter.Button, 1021 'wcfg':{'text': 'Clear Selection', 1022 'borderwidth':1, 'command': self.clearSel}, 1023 'gridcfg':{'sticky':Tkinter.W+Tkinter.E, 1024 'columnspan':2}, 1025 }) 1026 ifd.append({'name': 'invertBut', 1027 'widgetType':Tkinter.Button, 1028 'wcfg':{'text': 'Invert Selection', 1029 'borderwidth':1, 'command': self.invert}, 1030 'gridcfg':{'sticky':Tkinter.W+Tkinter.E, 1031 'row':-1, 'column':2, 'columnspan':2}, 1032 }) 1033 ifd.append({'name': 'Save Selection', 1034 'widgetType':Tkinter.Button, 1035 'wcfg':{'text': 'Save Selection As A Set', 1036 'borderwidth':1, 'command': self.saveSel}, 1037 'gridcfg':{'sticky':Tkinter.W+Tkinter.E,'row':-1, 1038 'column':4,'columnspan':2}, 1039 }) 1040 ifd.append({'name': 'Clear Form', 1041 'widgetType':Tkinter.Button, 1042 'wcfg':{'text': 'Clear Form', 1043 'borderwidth':1, 1044 'command': self.clearForm}, 1045 'gridcfg':{'sticky':Tkinter.W+Tkinter.E, 1046 'column':0, 'columnspan':4}, 1047 }) 1048 #ifd.append({'name': 'Invert Selection', 1049 # 'widgetType':Tkinter.Button, 1050 # 'wcfg':{'text': 'Invert Selection', 1051 # 'borderwidth':1 }, 1052 # 'gridcfg':{'sticky':Tkinter.W+Tkinter.E,'row':-1,'column':3, 1053 # 'columnspan':3}, 1054 # 'command': self.invertSel}) 1055 #ifd.append({'name': 'Select Pick', 1056 # 'widgetType':Tkinter.Checkbutton, 1057 # 'text': 'Add to Selection String by Picking', 1058 # 'variable': self.selPick, 1059 # 'gridcfg':{'sticky':Tkinter.W,'row':7,'column':0, 1060 # 'columnspan':4}, 1061 # 'command': self.startSelPick}) 1062 ifd.append({'name': 'Show SelSpheres', 1063 'widgetType':Tkinter.Checkbutton, 1064 'wcfg':{ 'text': 'Show Selection Spheres', 1065 'variable': self.showSelSpheres, 1066 'command': self.toggleSelSpheres}, 1067 'gridcfg':{'sticky':Tkinter.W,'row':-1,'column':4}, 1068 }) 1069 ifd.append({'widgetType':Tkinter.Button, 1070 'wcfg':{'bd':4, 'text':'Dismiss', 1071 'command': self.Dismiss_cb}, 1072 'gridcfg':{'sticky':Tkinter.E+Tkinter.W, 1073 'columnspan':6}}) 1074 self.form = self.vf.getUserInput(self.ifd, modal = 0, blocking=0) 1075 self.form.root.protocol('WM_DELETE_WINDOW',self.Dismiss_cb) 1076 eD = self.ifd.entryByName 1077 eD['Mol List']['widget'].bind('<ButtonPress>',self.buildMolMenus,add='+') 1078 eD['Chain List']['widget'].bind('<ButtonPress>',self.buildChainMenus,add='+') 1079 eD['Residue Sets']['widget'].bind('<ButtonPress>',self.buildResMenus,add='+') 1080 eD['Atom Sets']['widget'].bind('<ButtonPress>',self.buildAtomMenus,add='+') 1081 #self.cb = self.ifd.entryByName['Show SelSpheres']['widget'] 1082 #self.ifd.entryByName['Atom Sets']['widget'].bind('<ButtonPress>', self.buildAtomMenus,add='+') 1083 #eD['Sets List']['widget'].bind('<ButtonPress>',self.buildSetsMenus,add='+') 1084 self.xorBut = self.ifd.entryByName['xorBut']['widget'] 1085 self.invertBut = self.ifd.entryByName['invertBut']['widget'] 1086 self.intersectBut = self.ifd.entryByName['intersectBut']['widget'] 1087 self.removeBut = self.ifd.entryByName['removeBut']['widget'] 1088 self.addBut = self.ifd.entryByName['addBut']['widget'] 1089 if not hasattr(self,'setsVar'): self.setsVar={} 1090 if not hasattr(self,'oldsetsVar'): self.oldsetsVar={} 1091 for button in [self.xorBut, self.intersectBut, self.removeBut]: 1092 if len(self.vf.selection)==0: 1093 button.config(state='disabled')
1094
1095 - def setButtonState(self, event=None):
1096 for button in [self.xorBut, self.intersectBut, self.removeBut]: 1097 if len(self.vf.selection)==0: 1098 button.config(state='disabled') 1099 else: 1100 button.config(state='active')
1101 1102
1103 - def guiCallback(self):
1104 if not hasattr(self, 'ifd'): 1105 self.buildForm() 1106 else: 1107 self.form.deiconify() 1108 self.form.lift() 1109 self.showSelSpheres.set(self.vf.userpref['showSelectionSpheres']['value'])
1110 1111
1112 - def increaseCts(self,dict, newStr):
1113 if dict.has_key(newStr): 1114 dict[newStr]=dict[newStr]+1 1115 else: 1116 dict[newStr]=1
1117 1118
1119 - def decreaseCts(self,dict,newStr):
1120 #print "decreaseCts dict=", dict 1121 #print "newStr=", newStr 1122 #print "dict.has_key(", newStr,")=", dict.has_key(newStr) 1123 if dict.has_key(newStr): 1124 currentVal=dict[newStr] 1125 #print "currentVal =", currentVal 1126 if currentVal<=1: currentVal=1 1127 dict[newStr]=currentVal-1
1128 #print "finally: dict[", newStr,"]=", dict[newStr] 1129 1130
1131 - def getMolVal(self, event=None):
1132 molWidget=self.ifd.entryByName['molWid']['widget'] 1133 #molWidget=self.ifd[0]['widget'] 1134 for molStr in self.molVar.keys(): 1135 #figure out which check button was just changed 1136 newVal=self.molVar[molStr].get() 1137 if newVal==self.oldmolVar[molStr]: continue 1138 else: 1139 self.oldmolVar[molStr]=newVal 1140 molList=string.split(molWidget.get(),',') 1141 if newVal==1: 1142 self.increaseCts(self.molCts,molStr) 1143 if not molStr in molList: 1144 if molWidget.index('end')==0: 1145 molWidget.insert('end',molStr) 1146 else: 1147 molWidget.insert('end',','+molStr) 1148 else: 1149 if molStr in molList: 1150 self.molCts[molStr]=0 1151 molList.remove(molStr) 1152 molWidget.delete(0,'end') 1153 molWidget.insert('end',string.join(molList,',')) 1154 #also turn off all of the chain checkbuttons: 1155 #chainWidget=self.ifd[1]['widget'] 1156 chainWidget=self.ifd.entryByName['chainWid']['widget'] 1157 chainList=string.split(chainWidget.get(),',') 1158 # chain menu may not have been built yet: 1159 if not hasattr(self, 'chainVar'): 1160 self.buildChainMenus() 1161 for ch in self.chainVar.keys(): 1162 if ch in ['dna', 'proteic']: continue 1163 chKeyList = string.split(ch,':') 1164 thisMolStr=chKeyList[0] 1165 thisChainStr=chKeyList[1] 1166 #if the chain is in this molecule 1167 if thisMolStr==molStr: 1168 #turn off chain checkbutton 1169 self.chainVar[ch].set(0) 1170 self.oldchainVar[ch]=0 1171 self.decreaseCts(self.chainCts,thisChainStr) 1172 if len(chKeyList)>1 and thisChainStr in chainList: 1173 chainList.remove(thisChainStr) 1174 chainWidget.delete(0,'end') 1175 chainWidget.insert('end',string.join(chainList,','))
1176 1177
1178 - def getChainVal(self, event=None):
1179 chains = self.vf.Mols.findType(Chain) 1180 molWidget=self.ifd.entryByName['molWid']['widget'] 1181 #molWidget= self.ifd[0]['widget'] 1182 chainWidget=self.ifd.entryByName['chainWid']['widget'] 1183 #chainWidget= self.ifd[1]['widget'] 1184 for item in self.chainVar.keys(): 1185 if item in ['proteic', 'dna']: 1186 newVal = self.chainVar[item].get() 1187 if newVal==self.oldchainVar[item]: 1188 continue 1189 if newVal==1: 1190 #add item to entry 1191 if chainWidget.index('end')==0: 1192 chainWidget.insert('end',item) 1193 else: 1194 chainWidget.insert('end',','+item) 1195 self.oldchainVar[item]=1 1196 else: 1197 #remove item from entry 1198 chainList=string.split(chainWidget.get(),',') 1199 if item in chainList: 1200 chainList.remove(item) 1201 chainWidget.delete(0,'end') 1202 chainWidget.insert('end',string.join(chainList,',')) 1203 self.oldchainVar[item]=0 1204 else: 1205 #process standard item 1206 molStr,chainStr = string.split(item,':') 1207 newVal=self.chainVar[item].get() 1208 1209 if newVal ==self.oldchainVar[item]: 1210 continue 1211 else: 1212 self.oldchainVar[item]=newVal 1213 molList=string.split(molWidget.get(),',') 1214 chainList=string.split(chainWidget.get(),',') 1215 if newVal==1: 1216 self.increaseCts(self.molCts,molStr) 1217 self.increaseCts(self.chainCts,chainStr) 1218 if not molStr in molList: 1219 if molWidget.index('end')==0: 1220 molWidget.insert('end',molStr) 1221 else: 1222 molWidget.insert('end',','+molStr) 1223 if not chainStr in chainList: 1224 if chainWidget.index('end')==0: 1225 chainWidget.insert('end',chainStr) 1226 else: 1227 chainWidget.insert('end',','+chainStr) 1228 if hasattr(self, 'molVar') and self.molVar.has_key(molStr): 1229 self.molVar[molStr].set(1) 1230 else: 1231 self.buildMolMenus() 1232 self.molVar[molStr].set(1) 1233 self.oldmolVar[molStr]=1 1234 else: 1235 if not self.molCts.has_key(molStr): continue 1236 if not self.chainCts.has_key(chainStr): continue 1237 self.decreaseCts(self.molCts,molStr) 1238 self.decreaseCts(self.chainCts,chainStr) 1239 chainList=string.split(chainWidget.get(),',') 1240 if chainStr in chainList: 1241 if chainStr in chainList and self.chainCts[chainStr]==0: 1242 chainList.remove(chainStr) 1243 if self.molCts[molStr]==0: 1244 if hasattr(self, 'molVar') and self.molVar.has_key(molStr): 1245 self.molVar[molStr].set(0) 1246 self.oldmolVar[molStr]=0 1247 #also remove it from Molecule entry 1248 molList=string.split(molWidget.get(),',') 1249 if molStr in molList:molList.remove(molStr) 1250 newss1=string.join(molList,',') 1251 molWidget.delete(0,'end') 1252 molWidget.insert('end',newss1) 1253 ##also have to fix the Chain entry: 1254 chainWidget.delete(0,'end') 1255 chainWidget.insert('end',string.join(chainList,','))
1256 1257
1258 - def getResSetsVal(self, event=None):
1259 w=self.ifd.entryByName['resWid']['widget'] 1260 #w=self.ifd[2]['widget'] 1261 ssList=string.split(w.get(),',') 1262 for newStr in self.ResSetsVar.keys(): 1263 if self.ResSetsVar[newStr].get()==1: 1264 if newStr not in ssList: 1265 if w.index('end')==0: 1266 w.insert('end',newStr) 1267 else: 1268 w.insert('end',',') 1269 w.insert('end',newStr) 1270 #method to remove here 1271 else: 1272 if newStr in ssList: 1273 ssList.remove(newStr) 1274 w.delete(0,'end') 1275 w.insert(0,string.join(ssList,','))
1276 1277
1278 - def getAtomSetsVal(self, event=None):
1279 w=self.ifd.entryByName['atomWid']['widget'] 1280 #w=self.ifd[3]['widget'] 1281 ssList=string.split(w.get(),',') 1282 for newStr in self.AtomSetsVar.keys(): 1283 if self.AtomSetsVar[newStr].get()==1: 1284 if newStr not in ssList: 1285 if w.index('end')==0: 1286 w.insert('end',newStr) 1287 else: 1288 w.insert('end',',') 1289 w.insert('end',newStr) 1290 #method to remove here 1291 else: 1292 if newStr in ssList: 1293 ssList.remove(newStr) 1294 w.delete(0,'end') 1295 w.insert(0,string.join(ssList,',')) 1296 1297 for i in self.setsVar.keys(): 1298 if i not in specialCases: 1299 newSet = self.vf.sets[i] 1300 #newSet = sets__[i][0] 1301 newNode0 = newSet[0] 1302 #w/ newclass Set: level here 1303 lev = newNode0.__class__ 1304 if lev == Protein: lev = Molecule 1305 self.vf.setSelectionLevel(lev, busyIdle=0, log=0) 1306 #self.vf.setIcomLevel(lev, busyIdle=0, log=0) 1307 newVal = self.setsVar[i].get()
1308 1309
1310 - def getSetsVal(self, event=None):
1311 #process 'backbone', backbone+h and sidechain separately 1312 #these 3 are hard-wired atom sets 1313 specialCases = ['backbone', 'backbone+h' , 'sidechain'] 1314 sets = self.vf.sets.keys() 1315 #sets = sets__.keys() 1316 for newStr in self.setsVar.keys(): 1317 if newStr not in specialCases: 1318 node0 = self.vf.sets[newStr][0] 1319 #node0 = sets__[newStr][0][0] 1320 #this would work only w/ 4 levels(/) 1321 nodeLevel = node0.isBelow(Protein) 1322 w=self.ifd[nodeLevel]['widget'] 1323 ssList=string.split(w.get(),',') 1324 else: 1325 #hardwired to Atom level widget 1326 w=self.ifd.entryByName['atomWid']['widget'] 1327 #w=self.ifd[3]['widget'] 1328 ssList=string.split(w.get(),',') 1329 1330 if self.setsVar[newStr].get()==1: 1331 if newStr==' ': continue 1332 if not newStr in ssList: 1333 if w.index('end')==0: 1334 w.insert('end',newStr) 1335 else: 1336 w.insert('end',',') 1337 w.insert('end',newStr) 1338 else: 1339 if newStr in ssList: 1340 ssList.remove(newStr) 1341 w.delete(0,'end') 1342 w.insert(0,string.join(ssList,','))
1343 1344
1345 - def buildMenu(self, mB, nameList, varDict, oldvarDict, cmd):
1346 if nameList: 1347 #prune non-valid entries 1348 for i in varDict.keys(): 1349 #print i, " in nameList is ", i in nameList 1350 if i not in nameList: 1351 del varDict[i] 1352 del oldvarDict[i] 1353 #add anything new 1354 for i in nameList: 1355 if i not in varDict.keys(): 1356 varDict[i]=Tkinter.IntVar() 1357 oldvarDict[i]=0 1358 else: 1359 varDict={} 1360 oldvarDict={} 1361 #start from scratch and build menu 1362 #4/24: only build and add 1 menu 1363 if hasattr(mB, 'menu'): 1364 mB.menu.delete(1,'end') 1365 else: 1366 mB.menu = Tkinter.Menu(mB) 1367 mB['menu']=mB.menu 1368 #PACK all the entries 1369 for i in varDict.keys(): 1370 mB.menu.add_checkbutton(label=i, var=varDict[i], command=cmd)
1371 1372
1373 - def buildMolMenus(self,event=None):
1374 molMenubutton = self.ifd.entryByName['Mol List']['widget'] 1375 if not hasattr(self,'molVar'): self.molVar={} 1376 if not hasattr(self,'oldmolVar'): self.oldmolVar={} 1377 molNames = self.vf.Mols.name 1378 for key in self.vf.sets.get(stype=MoleculeSet): 1379 molNames.append( key ) 1380 self.buildMenu(molMenubutton,molNames,self.molVar,self.oldmolVar,self.getMolVal)
1381 1382
1383 - def buildChainMenus(self,event=None):
1384 #selectFromString 1385 chainMenubutton = self.ifd.entryByName['Chain List']['widget'] 1386 if not hasattr(self,'chainVar'): self.chainVar={} 1387 if not hasattr(self,'oldchainVar'): self.oldchainVar={} 1388 chMols=MoleculeSet(filter(lambda x: Chain in x.levels, self.vf.Mols)) 1389 chainIDList = [] 1390 if len(chMols): 1391 chains=chMols.findType(Chain) 1392 if chains==None: return 1393 for i in chains: 1394 chainIDList.append(i.full_name()) 1395 for key in self.vf.sets.get(stype=ChainSet): 1396 chainIDList.append( key ) 1397 chainIDList.append('dna') 1398 chainIDList.append('proteic') 1399 self.buildMenu(chainMenubutton,chainIDList,self.chainVar,self.oldchainVar,self.getChainVal)
1400 1401
1402 - def buildResMenus(self,event=None):
1403 ResSetsMenubutton = self.ifd.entryByName['Residue Sets']['widget'] 1404 if not hasattr(self,'ResSetsVar'): self.ResSetsVar={} 1405 if not hasattr(self,'oldResSetsVar'): self.oldResSetsVar={} 1406 resSelector = ResidueSetSelector() 1407 ResSetsList = resSelector.residueList.keys() 1408 for key in self.vf.sets.get(stype=ResidueSet): 1409 ResSetsList.append( key ) 1410 self.buildMenu(ResSetsMenubutton,ResSetsList,self.ResSetsVar,self.oldResSetsVar,self.getResSetsVal)
1411 1412
1413 - def buildAtomMenus(self,event=None):
1414 AtomSetsMenubutton = self.ifd.entryByName['Atom Sets']['widget'] 1415 if not hasattr(self,'AtomSetsVar'): self.AtomSetsVar={} 1416 if not hasattr(self,'oldAtomSetsVar'): self.oldAtomSetsVar={} 1417 self.atomList = AtomSetSelector().atomList 1418 AtomSetsList = self.atomList.keys() 1419 for key in self.vf.sets.get(stype=AtomSet): 1420 AtomSetsList.append( key ) 1421 self.buildMenu(AtomSetsMenubutton,AtomSetsList,self.AtomSetsVar,self.oldAtomSetsVar,self.getAtomSetsVal)
1422 1423
1424 - def buildSetsMenus(self,event=None):
1425 setsMenubutton = self.ifd.entryByName['Sets List']['widget'] 1426 if not hasattr(self,'setsVar'): self.setsVar={} 1427 if not hasattr(self,'oldsetsVar'): self.oldsetsVar={} 1428 sets = ['backbone', 'backbone+h', 'sidechain'] 1429 #for k in sets__.keys(): 1430 for k in self.vf.sets.keys(): 1431 sets.append(k) 1432 #sets = sets__.keys() # 1433 self.buildMenu(setsMenubutton,sets,self.setsVar,self.oldsetsVar,self.getSetsVal)
1434 1435
1436 - def Dismiss_cb(self):
1437 self.vf.GUI.removeCameraCallback("<ButtonRelease-1>", 1438 self.getPickInfo_cb) 1439 self.form.withdraw()
1440 1441
1442 - def saveSel(self):
1443 self.vf.saveSet.guiCallback() 1444 if self.form: self.form.lift()
1445 1446
1447 - def xor(self):
1448 #print "in xor" 1449 args = self.buildArgs(xor=True) 1450 self.callIt(args) 1451 self.setButtonState()
1452 1453
1454 - def remove(self):
1455 #print "in remove" 1456 args = self.buildArgs(negate=True) 1457 self.callIt(args) 1458 self.setButtonState()
1459 1460
1461 - def add(self):
1462 #print "in add" 1463 args = self.buildArgs() 1464 self.callIt(args) 1465 self.setButtonState()
1466 1467
1468 - def intersect(self):
1469 #print "in intersect" 1470 args = self.buildArgs(intersect=True) 1471 self.callIt(args) 1472 self.setButtonState()
1473 1474
1475 - def invert(self, event=None):
1476 if len(self.vf.Mols)>1: 1477 levelNames = ['all','molecule'] 1478 # create the form descriptor 1479 idf = InputFormDescr(title = 'Set Level for Invert Selection') 1480 idf.append({ 'name': 'level', 'widgetType':Tkinter.Radiobutton, 1481 'listtext': levelNames, 1482 'gridcfg':{'sticky':Tkinter.W}}) 1483 val = self.vf.getUserInput(idf) 1484 if len(val)>0: 1485 newparam = val['level'] 1486 else: 1487 newparam='all' 1488 self.vf.invertSelection(newparam, topCommand = 0, redraw = 1) 1489 if self.form: self.form.lift() 1490 self.setButtonState()
1491 1492
1493 - def clearSel(self):
1494 self.vf.clearSelection() 1495 if self.form: self.form.lift() 1496 self.setButtonState()
1497 1498
1499 - def clearForm(self):
1500 for widName in ['molWid','chainWid', 'resWid', 'atomWid']: 1501 self.ifd.entryByName[widName]['widget'].delete(0,'end') 1502 #self.ifd[0]['widget'].delete(0,'end') 1503 #self.ifd[1]['widget'].delete(0,'end') 1504 #self.ifd[2]['widget'].delete(0,'end') 1505 #self.ifd[3]['widget'].delete(0,'end') 1506 #move cursor back to Molecule entry 1507 self.ifd.entryByName['molWid']['widget'].focus() 1508 #self.ifd[0]['widget'].focus() 1509 ###SHOULD ALL THE VARIABLES BE ZEROED HERE??? 1510 self.molCts={} 1511 if hasattr(self, 'oldmolVar'): 1512 for item in self.oldmolVar.keys(): 1513 self.oldmolVar[item]=0 1514 if hasattr(self, 'oldchainVar'): 1515 for item in self.oldchainVar.keys(): 1516 self.oldchainVar[item]=0 1517 if hasattr(self, 'molVar'): 1518 for item in self.molVar.keys(): 1519 self.molVar[item].set(0) 1520 if hasattr(self, 'chainVar'): 1521 for item in self.chainVar.keys(): 1522 self.chainVar[item].set(0) 1523 if hasattr(self, 'ResSetsVar'): 1524 for item in self.ResSetsVar.keys(): 1525 self.ResSetsVar[item].set(0) 1526 if hasattr(self, 'AtomSetsVar'): 1527 for item in self.AtomSetsVar.keys(): 1528 self.AtomSetsVar[item].set(0) 1529 if hasattr(self, 'setsVar'): 1530 for item in self.setsVar.keys(): 1531 self.setsVar[item].set(0) 1532 if self.form: self.form.lift() 1533 self.setButtonState()
1534 1535
1536 - def startSelPick(self):
1537 from Pmv.picker import AtomPicker 1538 if self.selPick.get()==1: 1539 if hasattr(self.vf,'selectButtons'): 1540 self.vf.selectButtons.radioVar.set('Off') 1541 self.vf.selectButtons.setSelect() 1542 self.ap=AtomPicker(self.vf,None,gui=0,callbacks=[self.getPickInfo_cb],immediate=1) 1543 self.ap.go(modal=0) 1544 else: 1545 self.ap.stop()
1546 1547
1548 - def toggleSelSpheres(self, event = None):
1549 if self.vf.userpref['showSelectionSpheres']['value']==1: 1550 self.vf.userpref.set('showSelectionSpheres',0) 1551 else: 1552 self.vf.userpref.set('showSelectionSpheres',1) 1553 self.showSelSpheres.set(self.vf.userpref['showSelectionSpheres']['value']) 1554 self.vf.select.updateSelectionFeedback() 1555 self.vf.GUI.VIEWER.Redraw() 1556 if self.form: self.form.lift()
1557
1558 - def getPickInfo_cb(self,atoms):
1559 if self.vf.selector.level==None: 1560 self.setMolLevel() 1561 self.selLevel.set(1) 1562 if not atoms: return 1563 for atom in atoms: 1564 atomStr = atom.full_name() 1565 atomList = string.split(atomStr,':') 1566 num = self.selLevel.get() 1567 #if 1 only do Mol, 2 do Chain and Mol etc 1568 widgetNames = ['molWid','chainWid', 'resWid', 'atomWid'] 1569 #self.ifd.entryByName['molWid']['widget'].focus() 1570 for i in range(num): 1571 widName = widgetNames[i] 1572 w = self.ifd.entryByName[widName]['widget'] 1573 #w=self.ifd[i]['widget'] 1574 newStr=atomList[i] 1575 if string.find(w.get(),newStr)==-1: 1576 if w.index('end')==0: 1577 w.insert('end',newStr) 1578 else: 1579 w.insert('end',',') 1580 w.insert('end',newStr) 1581 self.ap.clear() 1582 if self.form: self.form.lift()
1583 1584
1585 - def buildArgs(self, negate=False, xor=False, intersect=False):
1586 args = {} 1587 d = self.ifd.entryByName 1588 args['mols'] = d['molWid']['widget'].get() 1589 args['chains'] = d['chainWid']['widget'].get() 1590 args['res'] = d['resWid']['widget'].get() 1591 args['atoms'] = d['atomWid']['widget'].get() 1592 #if self.ifd[0]['widget'].get()=='': 1593 # args['mols'] = '' 1594 #else: 1595 #args['mols'] = self.ifd[0]['widget'].get() 1596 #if self.ifd[1]['widget'].get()=='': 1597 # args['chains'] = '' 1598 #else: 1599 # args['chains'] = self.ifd[1]['widget'].get() 1600 #if self.ifd[2]['widget'].get()=='': 1601 # args['res'] = '' 1602 #else: 1603 # args['res'] = self.ifd[2]['widget'].get() 1604 #if self.ifd[3]['widget'].get()=='': 1605 # args['atoms'] = '' 1606 #else: 1607 # args['atoms'] = self.ifd[3]['widget'].get() 1608 args['negate'] = negate 1609 args['xor'] = xor 1610 args['intersect'] = intersect 1611 return args
1612 1613
1614 - def callDontDoit(self):
1615 kwargs = self.buildArgs() 1616 kwargs['negate'] = 1 1617 kwargs['log']=False 1618 kw = kwargs.copy() 1619 kw['silent'] = True 1620 kwargs['nodes'] = self.vf.Mols 1621 lastCmdLog = apply( self.logString, (), kw) 1622 self.lastCmdLog.append(lastCmdLog) 1623 self.vf.message( lastCmdLog ) 1624 self.vf.log(lastCmdLog) 1625 apply(self.doitWrapper, (), kwargs)
1626 1627
1628 - def callDoit(self):
1629 kwargs = self.buildArgs() 1630 kwargs['negate'] = 0 1631 kwargs['log'] = False 1632 kw = kwargs.copy() 1633 kw['silent'] = True 1634 kwargs['nodes'] = self.vf.Mols 1635 lastCmdLog = apply( self.logString, (), kw) 1636 self.lastCmdLog.append(lastCmdLog) 1637 self.vf.message( lastCmdLog ) 1638 self.vf.log(lastCmdLog) 1639 apply(self.doitWrapper, (), kwargs)
1640 1641
1642 - def callIt(self, args):
1643 args['log'] = False 1644 kw = args.copy() 1645 kw['silent'] = True 1646 args['nodes'] = self.vf.Mols 1647 lastCmdLog = apply( self.logString, (), kw) 1648 self.lastCmdLog.append(lastCmdLog) 1649 self.vf.message( lastCmdLog ) 1650 self.vf.log(lastCmdLog) 1651 apply(self.doitWrapper, (), args)
1652 1653 1654
1655 - def updateselLevel(self,lev):
1656 #NEED TO SET LEVEL IF THERE IS ONE:lev= self.vf.selector.level 1657 #NB: currently, all items are Protein; THIS IS A PROBLEM 1658 ll = [Protein,Chain,Residue,Atom] 1659 lcoms = [self.setMolLevel,self.setChainLevel,self.setResidueLevel,self.setAtomLevel] 1660 if lev: 1661 #NB there is a problem w/Protein v Molecule 1662 if lev == Protein: lev = Molecule 1663 ind = ll.index(lev) 1664 self.selLevel.set(ind+1) 1665 lcoms[ind]() 1666 else: 1667 self.selLevel.set(1) 1668 self.setMolLevel() 1669 if self.form: self.form.lift()
1670 1671 1672 mvSelectFromStringCommandGuiDescr = {'widgetType':'Menu', 'menuBarName':'menuRoot', 1673 'menuButtonName':'Select', 1674 'menuEntryLabel':'Select From String', 1675 'separatorBelow':1} 1676 1677 1678 MVSelectFromStringCommandGUI = CommandGUI() 1679 MVSelectFromStringCommandGUI.addMenuCommand('menuRoot', 'Select', 'Select From String', separatorBelow=1 ) 1680 1681 1682
1683 -class MVDirectSelectCommand(MVSelectFromStringCommand):
1684 """This Command allows you to directly select from moleculelist,chainlist,setslist 1685 \nPackage : Pmv 1686 \nModule : selectionCommands 1687 \nClass : MVDirectSelectCommand 1688 \nCommand : directSelect 1689 \nSynopsis:\n 1690 None <- directSelect(nameStr, **kw) 1691 \nRequired Arguments:\n 1692 nameStr: name of selection from the string list 1693 """
1694 - def buildForm(self):
1695 if hasattr(self, 'ifd'): 1696 return 1697 ifd = self.ifd = InputFormDescr(title = 'Direct Select') 1698 ifd.append({'name': 'Mol List', 1699 'widgetType':Tkinter.Menubutton, 1700 'wcfg':{'text': 'Molecule List ...'}, 1701 'gridcfg':{'sticky':Tkinter.W, 'columnspan':2}}) 1702 ifd.append({'name': 'Chain List', 1703 'widgetType':Tkinter.Menubutton, 1704 'wcfg':{'text': 'Chain List ...'}, 1705 'gridcfg':{'sticky':Tkinter.W, 'columnspan':2} }) 1706 ifd.append({'name': 'Sets List', 1707 'widgetType':Tkinter.Menubutton, 1708 'wcfg':{'text': 'Sets List ...'}, 1709 'gridcfg':{'sticky':Tkinter.W, 'columnspan':2} }) 1710 ifd.append({'name': 'Show SelSpheres', 1711 'widgetType':Tkinter.Checkbutton, 1712 'wcfg':{'text': 'Show Selection Spheres', 1713 'variable': self.showSelSpheres, 1714 'command': self.toggleSelSpheres}, 1715 'gridcfg':{'sticky':Tkinter.W,'row':3,'column':0}, 1716 }) 1717 ifd.append({'widgetType':Tkinter.Button, 1718 'wcfg':{'bd':6, 'text':'Dismiss', 1719 'command': self.Dismiss_cb}, 1720 'gridcfg':{'sticky':Tkinter.E+Tkinter.W, 1721 'columnspan':6}, 1722 }) 1723 self.form = self.vf.getUserInput(self.ifd, modal = 0, blocking=0) 1724 self.form.root.protocol('WM_DELETE_WINDOW',self.Dismiss_cb) 1725 eD = self.ifd.entryByName 1726 eD['Mol List']['widget'].bind('<ButtonPress>', 1727 self.buildMolMenus,add='+') 1728 eD['Chain List']['widget'].bind('<ButtonPress>', 1729 self.buildChainMenus,add='+') 1730 eD['Sets List']['widget'].bind('<ButtonPress>', 1731 self.buildSetsMenus,add='+')
1732 1733 1734
1735 - def guiCallback(self):
1736 if not hasattr(self, 'ifd'): 1737 self.buildForm() 1738 else: 1739 self.form.deiconify() 1740 #clear all the buttons here(?) 1741 sellist = self.vf.selection 1742 for dictName in ['molVar', 'chainVar', 'setsVar']: 1743 if hasattr(self, dictName): 1744 #dict = eval('self.%s' %dictName) 1745 dict = getattr(self, dictName) 1746 if len(sellist): 1747 selnames = sellist.name 1748 for item in dict.keys(): 1749 dict[item].set(item in selnames) 1750 else: 1751 for item in dict.keys(): 1752 dict[item].set(0) 1753 else: continue 1754 self.showSelSpheres.set(self.vf.userpref['showSelectionSpheres']['value'])
1755 1756
1757 - def findItemFromName(self,itemList,someName):
1758 #should add error detection at end 1759 for i in itemList: 1760 if i.name==someName: 1761 return i
1762 1763
1764 - def findItemFromID(self,itemList,someID):
1765 #keys are "1hvr:A" 1766 for i in itemList: 1767 newStr = i.parent.name+":"+i.id 1768 if newStr == someID: 1769 return i
1770 1771
1772 - def doit(self, nameStr):
1773 chNameList =[] 1774 ch = self.vf.Mols.findType(Chain) 1775 if ch: 1776 chParents = ch.parent.name 1777 chIds=ch.id 1778 for i in range(len(chIds)): 1779 newItem=chParents[i]+':'+chIds[i] 1780 chNameList.append(newItem) 1781 if nameStr in self.vf.Mols.findType(Molecule).name: 1782 self.vf.setSelectionLevel(Protein, busyIdle=0, log=0) 1783 newMol=self.findItemFromName(self.vf.Mols, nameStr) 1784 self.vf.select(newMol, topCommand=0) 1785 elif nameStr in chNameList: 1786 self.vf.setSelectionLevel(Chain, busyIdle=0, log=0) 1787 chains = self.vf.Mols.findType(Chain) 1788 newChain=self.findItemFromID(chains, nameStr) 1789 self.vf.select(newChain, topCommand=0) 1790 elif nameStr in self.vf.sets.keys(): 1791 newSet = self.vf.sets[nameStr] 1792 newNode0 = newSet[0] 1793 lev=newNode0.__class__ 1794 self.vf.setSelectionLevel(lev, busyIdle=0, log=0) 1795 self.vf.select(newSet, topCommand=0) 1796 else: 1797 msg=nameStr + " not a Molecule, Chain or Set name" 1798 self.vf.warningMsg(msg)
1799 1800
1801 - def __call__(self, nameStr, **kw):
1802 """None <- directSelect(nameStr, **kw) 1803 \nnameStr --- name of selection from the string list""" 1804 1805 apply( self.doitWrapper, (nameStr,), kw )
1806 1807 1808
1809 - def buildMolMenus(self,event=None):
1810 molMenubutton = self.ifd.entryByName['Mol List']['widget'] 1811 if not hasattr(self,'molVar'): self.molVar={} 1812 if not hasattr(self,'oldmolVar'): self.oldmolVar={} 1813 molNames = self.vf.Mols.name 1814 if molNames: 1815 for i in molNames: 1816 if i not in self.molVar.keys(): 1817 self.molVar[i]=Tkinter.IntVar() 1818 self.oldmolVar[i]=0 1819 if len(self.vf.selection): 1820 selNames = self.vf.selection.top.uniq().name 1821 for n in self.molVar.keys(): 1822 self.molVar[n].set(n in selNames) 1823 self.oldmolVar[n] = n in selNames 1824 else: 1825 for n in self.molVar.keys(): 1826 self.molVar[n].set(0) 1827 self.oldmolVar[n] = 0 1828 self.buildMenu(molMenubutton,molNames,self.molVar,self.oldmolVar,self.getMolVal)
1829
1830 - def getMolVal(self, event=None):
1831 self.vf.setSelectionLevel(Protein, busyIdle=0, log=0) 1832 #self.vf.setIcomLevel(Protein, busyIdle=0, log=0) 1833 for i in self.molVar.keys(): 1834 newMol=self.findItemFromName(self.vf.Mols, i) 1835 newVal = self.molVar[i].get() 1836 if newVal!=self.oldmolVar[i]: 1837 if newVal==1: 1838 #select if button on 1839 self.vf.select(newMol) 1840 else: 1841 #deselect if button off 1842 self.vf.deselect(newMol) 1843 self.oldmolVar[i]=newVal
1844 1845
1846 - def buildChainMenus(self,event=None):
1847 chainMenubutton = self.ifd.entryByName['Chain List']['widget'] 1848 if not hasattr(self,'chainVar'): self.chainVar = {} 1849 if not hasattr(self,'oldchainVar'): self.oldchainVar = {} 1850 #NB this assumes there may be molecules with no chains 1851 chMols = MoleculeSet(filter(lambda x: Chain in x.levels, self.vf.Mols)) 1852 chainIDList = [] 1853 if len(chMols): 1854 chains = chMols.findType(Chain) 1855 for ch in chains: 1856 newname = ch.full_name() 1857 chainIDList.append(newname) 1858 if newname not in self.chainVar.keys(): 1859 self.chainVar[newname]=Tkinter.IntVar() 1860 self.oldchainVar[newname]=0 1861 if len(self.vf.selection): 1862 selChains = self.vf.selection.findType(Chain) 1863 else: selChains = ChainSet([]) 1864 selNames = [] 1865 if len(selChains): 1866 for ch in selChains: 1867 selNames.append(ch.full_name()) 1868 for n in self.chainVar.keys(): 1869 ans = n in selNames 1870 self.chainVar[n].set(ans) 1871 self.oldchainVar[n] = ans 1872 self.buildMenu(chainMenubutton,chainIDList,self.chainVar,self.oldchainVar,self.getChainVal)
1873 1874
1875 - def getChainVal(self, event=None):
1876 self.vf.setSelectionLevel(Chain, busyIdle=0, log=0) 1877 #self.vf.setIcomLevel(Chain, busyIdle=0, log=0) 1878 chains = self.vf.Mols.findType(Chain) 1879 for i in self.chainVar.keys(): 1880 newChain=self.findItemFromID(chains,i) 1881 newVal= self.chainVar[i].get() 1882 if newVal!=self.oldchainVar[i]: 1883 if self.chainVar[i].get()==1: 1884 #select if button on 1885 self.vf.select(newChain) 1886 else: 1887 #deselect if button off 1888 self.vf.deselect(newChain) 1889 self.oldchainVar[i]=newVal
1890 1891
1892 - def buildSetsMenus(self,event=None):
1893 setsMenubutton = self.ifd.entryByName['Sets List']['widget'] 1894 if not hasattr(self,'setsVar'): self.setsVar={} 1895 if not hasattr(self,'oldsetsVar'): self.oldsetsVar={} 1896 #cannot use this here: 1897 #sets = ['backbone', 'backbone+h', 'sidechain'] 1898 sets = [] 1899 #for k in sets__.keys(): 1900 for k in self.vf.sets.keys(): 1901 sets.append(k) 1902 #sets = sets__.keys() # 1903 self.buildMenu(setsMenubutton,sets,self.setsVar,self.oldsetsVar,self.getSetsVal)
1904 1905
1906 - def getSetsVal(self, event=None):
1907 for i in self.setsVar.keys(): 1908 #newSet = sets__[i][0] 1909 newSet = self.vf.sets[i] 1910 newNode0 = newSet[0] 1911 #w/ newclass Set: level here 1912 lev = newNode0.__class__ 1913 if lev == Protein: lev = Molecule 1914 self.vf.setSelectionLevel(lev, busyIdle=0, log=0) 1915 #self.vf.setIcomLevel(lev, busyIdle=0, log=0) 1916 newVal = self.setsVar[i].get() 1917 if newVal != self.oldsetsVar[i]: 1918 if newVal==1: 1919 #select if button on 1920 self.vf.select(newSet) 1921 else: 1922 #deselect if button off 1923 self.vf.deselect(newSet) 1924 self.oldsetsVar[i]=newVal
1925 1926 1927 mvDirectSelectCommandGuiDescr = {'widgetType':'Menu', 'menuBarName':'menuRoot', 1928 'menuButtonName':'Select', 1929 'menuEntryLabel':'Direct Select', 1930 'separatorBelow':1} 1931 1932 1933 MVDirectSelectCommandGUI = CommandGUI() 1934 MVDirectSelectCommandGUI.addMenuCommand('menuRoot', 'Select', 'Direct Select', separatorBelow=1 ) 1935 1936 1937 1938 import Numeric
1939 -class MVSelectSphericalRegion(MVCommand):
1940 """This Command selects nodes from a specified base within specified spherical region(s) 1941 \nPackage : Pmv 1942 \nModule : selectionCommands 1943 \nClass : MVSelectSphericalRegion 1944 \nCommand : selectInSphere 1945 \nSynopsis:\n 1946 None <- selectInSphere(centerList, radius, selList, **kw) 1947 \nRequired Arguments:\n 1948 centerList --- specifies the centers of the selection spheres 1949 \nradius --- radius of the selection spheres 1950 \nselList --- specifies selection base (atoms to test) 1951 possible selList values are ['all'], a list of sets or a list 1952 of molecule names. 1953 """
1954 - def onAddCmdToViewer(self):
1955 self.form = None 1956 self.radius = 5. 1957 self.centerList = None 1958 self.atar = [] 1959 self.selList = ['all'] 1960 if self.vf.hasGui: 1961 from DejaVu.Spheres import Spheres 1962 from DejaVu.Geom import Geom 1963 miscGeom = self.vf.GUI.miscGeom 1964 self.masterGeom = Geom("selectInSphereGeoms", 1965 shape=(0,0), protected=True) 1966 self.vf.GUI.VIEWER.AddObject(self.masterGeom, parent=miscGeom) 1967 self.selSph = Spheres(name='SelSphReg_selSph', 1968 materials=((1.,1.,0),), shape=(0,3), radii=5.0, 1969 quality=15, inheritMaterial=0, protected=True) 1970 from opengltk.OpenGL import GL 1971 self.selSph.frontPolyMode = GL.GL_LINE 1972 #self.selSph.frontPolyMode = GL.GL_POINT 1973 self.selSph.Set(visible=1, tagModified=False) 1974 self.selSph.pickable = 0 1975 from DejaVu.Points import CrossSet 1976 self.cenCross = CrossSet('SelSphReg_cenCross', 1977 inheritMaterial=0, materials=((1.,0.2,0),), 1978 offset=0.5,lineWidth=2, protected=True) 1979 self.cenCross.Set(visible=0, tagModified=False) 1980 self.cenCross.pickable = 0 1981 self.selLevel = Tkinter.StringVar() 1982 self.selectionBase = Tkinter.StringVar() 1983 self.selectionCenter = Tkinter.StringVar() 1984 self.vf.GUI.VIEWER.AddObject(self.selSph, redo=0, 1985 parent=self.masterGeom) 1986 self.vf.GUI.VIEWER.AddObject(self.cenCross, redo=0, 1987 parent=self.masterGeom)
1988 1989
1990 - def onAddObjectToViewer(self,obj):
1991 if not self.vf.hasGui: return 1992 if not self.form: return 1993 val =self.selectionBase.get() 1994 if val=='fromList': 1995 self.lb.insert('end',obj.name)
1996 1997
1998 - def onRemoveObjectFromViewer(self, obj):
1999 if not self.vf.hasGui: return 2000 if not self.form: return 2001 val =self.selectionBase.get() 2002 ltuple=self.lb.get(0,'end') 2003 llist=list(ltuple) 2004 if val=='fromList' and obj.name in llist: 2005 lindex=llist.index(obj.name) 2006 self.lb.delete(lindex)
2007 2008
2009 - def getTransformedCoords(self, atom):
2010 if not atom.top.geomContainer: 2011 return atom.coords 2012 g = atom.top.geomContainer.geoms['master'] 2013 coords = atom.coords 2014 pth = [coords[0], coords[1], coords[2], 1.0] 2015 #c = self.applyTransformation(atom.coords, g.GetMatrix(g)) 2016 c = Numeric.matrixmultiply(g.GetMatrix(g), pth)[:3] 2017 return c.astype('f')
2018 2019
2020 - def setupUndoBefore(self, *args, **kw):
2021 select = self.vf.select 2022 oldselection = self.vf.selection 2023 self.addUndoCall( (), {}, self.vf.clearSelection.name ) 2024 if len(oldselection): 2025 self.addUndoCall( (oldselection,), {}, select.name )
2026 2027
2028 - def __call__(self, centerList, radius, selList, **kw):
2029 """None <- selectInSphere(centerList, radius, selList, **kw) 2030 \ncenterList --- specifies the centers of the selection spheres 2031 \nradius --- radius of the selection spheres 2032 \nselList --- specifies selection base (atoms to test) 2033 possible selList values are ['all'], a list of sets or a list 2034 of molecule names. 2035 """ 2036 apply( self.doitWrapper, (centerList, radius, selList), kw )
2037 2038
2039 - def doit(self, centerList, radius, selList):
2040 """centerList, radius, selList""" 2041 #this cmd logs centerList as a list of arrays of coords 2042 #this cannot be replayed without from Numeric import array 2043 #however, in the tests self.vf has no logAllFile 2044 #hence this ugliness: -rh 8/05 2045 if hasattr(self.vf, 'logAllFile'): 2046 self.vf.logAllFile.write("from Numeric import array\n") 2047 if not centerList: 2048 t = 'no centerList specified' 2049 self.vf.warningMsg(t) 2050 return 'ERROR' 2051 if not radius: 2052 t = 'no radius specified' 2053 self.vf.warningMsg(t) 2054 return 'ERROR' 2055 if len(selList)==0: 2056 t = 'no selection base specified' 2057 self.vf.warningMsg(t) 2058 return 'ERROR' 2059 #base_nodes is an AtomSet constructed from selList 2060 base_nodes = AtomSet([]) 2061 if selList[0]=='all': 2062 base_nodes = self.vf.allAtoms 2063 elif selList[0] in self.vf.sets.keys(): 2064 #elif selList[0] in sets__.keys(): 2065 #need to get all atoms in all sets specified 2066 for item in selList: 2067 newnodes = self.vf.sets[item].findType(Atom) 2068 #newnodes = sets__[item][0].findType(Atom) 2069 base_nodes = base_nodes+newnodes 2070 else: 2071 for item in selList: 2072 mol = self.vf.Mols.NodesFromName(item)[0] 2073 newnodes = mol.findType(Atom) 2074 base_nodes = base_nodes+newnodes 2075 if len(base_nodes)==0: 2076 t = '1:no base for selection specified: selList=', selList 2077 self.vf.warningMsg(t) 2078 return 'ERROR' 2079 atar = Numeric.array(base_nodes.data) 2080 2081 #use transformed coords: 2082 tcoords = [] 2083 for at in base_nodes: 2084 tcoords.append(self.getTransformedCoords(at)) 2085 coords = Numeric.array(tcoords, 'f') 2086 2087 ats = AtomSet([]) 2088 for center in centerList: 2089 d = coords - Numeric.array(center, 'f') 2090 d = d * d 2091 d = Numeric.sum(d,1) 2092 atindex = Numeric.nonzero(Numeric.less(d, radius * radius)) 2093 newats = Numeric.take(atar, atindex) 2094 if len(newats)>0: 2095 ats = ats + AtomSet(newats) 2096 if len(ats)>0: 2097 atSet = AtomSet(list(ats)) 2098 ###FIX ME! this assumes 4 level hierarchy 2099 lev = atSet[0].__class__ 2100 if lev==Protein: 2101 lev = Molecule 2102 vflev = self.vf.selectionLevel 2103 if vflev!=lev: 2104 self.vf.setSelectionLevel(lev, busyIdle=0, log=0) 2105 self.vf.clearSelection() 2106 self.vf.select(atSet, topCommand=0) 2107 if self.form: 2108 self.form.lift()
2109 2110
2111 - def drawSphere(self):
2112 #callback to update command's geoms 2113 ##7/21: now self.centerList is a List of centers 2114 if self.centerList and self.radius: 2115 self.selSph.Set