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

Source Code for Module Pmv.displayCommands

   1  ########################################################################### 
   2  # 
   3  # Author: Michel F. SANNER, Sophie COON 
   4  # 
   5  # Copyright: M. Sanner TSRI 2000 
   6  # 
   7  ############################################################################# 
   8   
   9  # 
  10  # $Header: /opt/cvs/python/packages/share1.5/Pmv/displayCommands.py,v 1.158.2.5 2007/10/15 16:51:52 rhuey Exp $ 
  11  #  
  12  # $Id: displayCommands.py,v 1.158.2.5 2007/10/15 16:51:52 rhuey Exp $ 
  13  # 
  14   
  15  import warnings 
  16  import traceback, math 
  17  from types import ListType, TupleType, StringType, IntType, FloatType, LongType, StringType 
  18  import Tkinter, Numeric, Pmw 
  19  import string 
  20  from Pmv.mvCommand import MVCommand, MVAtomICOM 
  21  from Pmv.stringSelectorGUI import StringSelectorGUI 
  22   
  23  from MolKit.tree import TreeNode, TreeNodeSet 
  24  from MolKit.molecule import Atom, AtomSet, Molecule, MoleculeSet, BondSet 
  25  from MolKit.protein import Protein, Residue, ResidueSet, Chain 
  26   
  27  from DejaVu.Cylinders import Cylinders 
  28  from DejaVu.IndexedPolylines import IndexedPolylines 
  29  from DejaVu.Spheres import Spheres 
  30  from DejaVu.Points import Points, CrossSet 
  31  from DejaVu.Geom import Geom 
  32   
  33  from ViewerFramework.VFCommand import CommandGUI 
  34  from ViewerFramework.VF import DeleteAtomsEvent, AddAtomsEvent, EditAtomsEvent 
  35  from mglutil.gui.BasicWidgets.Tk.thumbwheel import ThumbWheel 
  36   
  37  from mglutil.gui.InputForm.Tk.gui import InputFormDescr, evalString 
  38  from mglutil.util.callback import CallBackFunction 
  39  from mglutil.gui.BasicWidgets.Tk.customizedWidgets import ExtendedSliderWidget, ListChooser 
  40   
  41  import Pmv 
  42  if hasattr( Pmv, 'numOfSelectedVerticesToSelectTriangle') is False: 
  43      Pmv.numOfSelectedVerticesToSelectTriangle = 1 
  44   
  45   
46 -class DisplayCommand(MVCommand, MVAtomICOM):
47 """The DisplayCommand class is the base class from which all the display commands implemented for PMV will derive.It implements the general functionalities to display/undisplay parts of a geometry representing a molecule. 48 \nPackage : Pmv 49 \nModule : displayCommands 50 \nClass : DisplayCommand 51 """ 52
53 - def __init__(self, func=None):
54 MVCommand.__init__(self, func) 55 MVAtomICOM.__init__(self) 56 self.flag = self.flag | self.objArgOnly 57 self.flag = self.flag | self.negateKw
58 59
60 - def setLastUsedValues(self, formName=None, **kw):
61 """Special handling of display widget based on values of only and 62 negate in self.lastUsedValues 63 """ 64 form = None 65 if len(self.cmdForms): 66 if formName is None: 67 form = self.cmdForms.values()[0] 68 else: 69 form = self.cmdForms.get(formName, None) 70 71 if kw.has_key('only') and kw['only']: 72 disp = 'display only' 73 del kw['only'] 74 elif kw.has_key('negate') and kw['negate']: 75 disp = 'undisplay' 76 del kw['negate'] 77 else: 78 disp = 'display' 79 widget = form.descr.entryByName['default']['widget'] 80 widget.invoke(disp) 81 82 apply(MVCommand.setLastUsedValues, (self, formName), kw)
83 84
85 - def handleNegateOnly(self):
86 """return the values to be used for the display widget based on the 87 negate and only values in self.lastUsedValues 88 """ 89 if self.lastUsedValues['default']['only']: 90 disp = 'display only' 91 elif self.lastUsedValues['default']['negate']: 92 disp = 'undisplay' 93 else: 94 disp = 'display' 95 96 return disp
97 98
99 - def getLastUsedValues(self, formName='default', **kw):
100 """Return dictionary of last used values 101 """ 102 values = self.lastUsedValues[formName].copy() 103 return self.handleDisplayValue(values)
104 105
106 - def handleDisplayValue(self, val):
107 # creates the only and negate keywords based on the 'display' entry 108 if val.has_key('display'): 109 if val['display']=='display': 110 val['only']= False 111 val['negate'] = False 112 del val['display'] 113 elif val['display']=='display only': 114 val['only']= True 115 val['negate'] = False 116 del val['display'] 117 elif val['display']== 'undisplay': 118 val['negate'] = True 119 val['only'] = False 120 del val['display'] 121 val['redraw'] = True 122 return val
123 124
125 - def onAddCmdToViewer(self):
126 self.vf.registerListener(DeleteAtomsEvent, self.updateGeom) 127 self.vf.registerListener(AddAtomsEvent, self.updateGeom) 128 self.vf.registerListener(EditAtomsEvent, self.updateGeom)
129 130
131 - def updateGeom(self, event):
132 """Function to update geometry objects created by this command 133 upon Modification events. This function is called by the 134 the ViewerFramework.dispatchEvent command. 135 The function will compute the a set of atoms by combining 136 the atoms currently used to display the geometry (i.e. 137 adding or substracting event.objects for action =='add' or 138 'delete', then execute this command for the set of 139 atoms. 140 \nevent --- instance of a VFEvent object 141 """ 142 if isinstance(event, AddAtomsEvent): 143 action='add' 144 elif isinstance(event, DeleteAtomsEvent): 145 action='delete' 146 elif isinstance(event, EditAtomsEvent): 147 action='edit' 148 else: 149 import warnings 150 warnings.warn('Bad event %s for DisplayCommand.updateGeom'%event) 151 return 152 153 geomList = self.managedGeometries 154 155 # split event.objects into atoms sets per molecule 156 molecules, ats = self.vf.getNodesByMolecule(event.objects) 157 158 # build list of optional command arguments 159 doitoptions = self.lastUsedValues['default'] 160 doitoptions['redraw']=1 161 doitoptions['topCommand']=0 162 163 # allAts is the set of atoms for which we will invoke this command 164 allAts = AtomSet([]) 165 166 # loop over molecules to update geometry objects 167 for mol, atomSets in map(None, molecules, ats): 168 169 # loop over the geometry objects 170 for geom in geomList: 171 # get the list of atoms currently displayed with this geom 172 atoms = mol.geomContainer.atoms[geom.name] 173 if len(atoms)==0: 174 continue 175 # handle event.action 176 if action=='delete': 177 changed = atoms.inter(atomSets) 178 doitoptions['negate'] = 1 179 if len(changed): 180 apply(self.doitWrapper,(changed,), doitoptions) 181 doitoptions['negate'] = 0 182 else: 183 if action == 'add': 184 allAts = allAts + atoms + atomSets 185 elif action == 'edit': 186 if len(allAts)==0: 187 allAts = atoms 188 else: 189 allAts = allAts.union(atoms) 190 191 ## if there are atoms to be displayed in geoemtries created by this 192 ## command, invoke the command 193 if len(allAts): 194 apply(self.doitWrapper,(allAts,), doitoptions) 195 196 ## FIXME not sure we need this ! 197 try: 198 self.cleanup() 199 except: 200 pass
201 202
203 - def getNodes(self, nodes):
204 """expand nodes argument into a list of atoms sets and a list of 205 molecules.\n 206 This function is used to prevent the expansion operation to be done in both doit and setupUndoBefore The nodes.findType( Atom ) is the operation that is potentially expensive.\n 207 """ 208 if not hasattr(self, 'expandedNodes____AtomSets'): 209 mol, atms = self.vf.getNodesByMolecule(nodes, Atom) 210 self.expandedNodes____AtomSets = atms 211 self.expandedNodes____Molecules = mol 212 213 return self.expandedNodes____Molecules, \ 214 self.expandedNodes____AtomSets
215 216
217 - def buildFormDescr(self, formName='default', title=None):
218 if formName == 'default': 219 if title is None: 220 title = self.name 221 idf = InputFormDescr(title=title) 222 idf.name = formName 223 idf.append({'name':'display', 224 'widgetType':Pmw.RadioSelect, 225 'tooltip':"display only: display the selection and undisplay the non selected part of the molecule", 226 'listtext':['display','display only', 'undisplay'], 227 'defaultValue': self.handleNegateOnly(), 228 'wcfg':{'orient':'horizontal', 229 'buttontype':'radiobutton'}, 230 'gridcfg':{'sticky': 'we'}}) 231 return idf
232 233
234 - def getFormValues(self):
235 val = self.showForm() 236 237 if val: 238 if val['display']=='display': 239 val['only']= False 240 val['negate'] = False 241 del val['display'] 242 elif val['display']=='display only': 243 val['only']= True 244 val['negate'] = False 245 del val['display'] 246 elif val['display']== 'undisplay': 247 val['negate'] = True 248 val['only'] = False 249 del val['display'] 250 251 val['redraw'] = True 252 253 return val
254 255
256 - def guiCallback(self):
257 nodes = self.vf.getSelection() 258 if not nodes: return 259 val = self.getFormValues() 260 if val: 261 apply( self.doitWrapper, (nodes,), val )
262 263 264
265 -class DisplayLines(DisplayCommand):
266 """The displayLines allows the user to display/undisplay the selected nodes using a lines for bonded atoms, dots for non bonded atoms and doted lines for an aromatic ring. The number of lines when representing a bond will vary depending on the bondOrder. 267 \nPackage : Pmv 268 \nModule : displayCommands 269 \nClass : DisplayLines 270 \nCommand : displayLines 271 \nSynopsis:\n 272 None <--- displayLines(self, nodes, lineWidth=2, displayBO = 1, only = 0, 273 negate = 0, **kw)\n 274 \nRequired Arguments:\n 275 nodes --- any set of MolKit nodes describing molecular components\n 276 277 \nOptional Arguments:\n 278 lineWidth --- int specifying the width of the lines, dots or doted lines 279 representing the selection. (default = 2)\n 280 displayBO --- boolean flag specifying whether or not to display the 281 bond order (default = False)\n 282 only --- boolean flag specifying whether or not to display only the 283 current selection. (default = False)\n 284 negate --- boolean flag specifying whether or not to negate the current 285 selection. (default = False)\n 286 287 288 keywords: display wireframe, lines, bond order, non bonded atoms. 289 """ 290 291
292 - def onAddObjectToViewer(self, obj):
293 """ 294 Creates the lines, the points , the dotted lines and the bond order 295 lines geometries and add these new geometries to the 296 geomContainer.geoms of the new molecule. 297 New AtomSet are created as well and added to the geomContainer.atoms 298 """ 299 if not self.vf.hasGui: return 300 geomC = obj.geomContainer 301 vi = geomC.VIEWER 302 # lines representation needs 4 different geometries need to create 303 # a master geometrie Geom. 304 #wire = geomC.geoms['lines'] = Geom('lines', shape=(0,0)) 305 if not geomC.geoms.has_key('lines'): 306 wire = Geom('lines', 307 shape=(0,0), 308 inheritLighting=False, 309 lighting=False, 310 protected=True) 311 312 else: 313 wire = geomC.geoms['lines'] 314 geomC.addGeom(wire, parent=geomC.masterGeom, redo=0 ) 315 316 geomC.atomPropToVertices["bonded"] = self.atomPropToVertices 317 geomC.atomPropToVertices["nobnds"] = self.atomPropToVertices 318 #geomC.atomPropToVertices["sharedbonds"] = self.atomPropToVertices 319 geomC.atomPropToVertices["bondorder"] = self.atomPropToVertices 320 321 # lines: Bonded atoms are represented by IndexedPolyLines 322 l = IndexedPolylines("bonded", 323 vertices=geomC.allCoords, 324 visible=0, 325 pickableVertices=1, 326 inheritMaterial=1, 327 protected=True) 328 geomC.addGeom(l, parent=wire, redo=0) 329 self.managedGeometries.append(l) 330 331 # nobnds : Non Bonded atoms are represented by Points 332 p = Points( "nobnds", shape=(0,3), visible=0, 333 inheritMaterial=1, protected=True) 334 335 geomC.addGeom( p, parent=wire, redo=0) 336 self.managedGeometries.append(p) 337 b = IndexedPolylines('bondorder', visible=0, 338 inheritMaterial=1, protected=True) 339 340 geomC.addGeom( b, parent=wire, redo=0 ) 341 self.managedGeometries.append(b) 342 343 # shared bonds are represented by dotted lines. 344 ## a = IndexedPolylines('sharedbonds', visible=0, lineWidth=3, 345 ## inheritMaterial=0, stipleLines=1) 346 ## vi.AddObject(a, parent=wire, replace=True, redo=0) 347 ## geomC.addGeom(p) 348 ## self.managedGeometries.append(p) 349 350 351 # Create the entry 'lines' and 'nobnds' in the atom.colors dictionary 352 for atm in obj.allAtoms: 353 atm.colors['lines'] = (1.0, 1.0, 1.0)
354 355 356
357 - def atomPropToVertices(self, geom, atms, propName, propIndex=None):
358 """Function called to compute the array of properties""" 359 if atms is None or len(atms)==0 : return None 360 prop = [] 361 if propIndex == 'bondorder': 362 mol = geom.mol 363 atms = mol.geomContainer.atoms['bondorder'] 364 365 propIndex = 'lines' 366 for a in atms: 367 d = getattr(a, propName) 368 prop.append( d[propIndex] ) 369 return prop
370 371
372 - def setupUndoBefore(self, nodes, only=False, negate=False, displayBO=False, 373 lineWidth=2):
374 kw = {} 375 #kw['displayBO'] = displayBO 376 kw['lineWidth'] = self.lastUsedValues['default']['lineWidth'] 377 kw['redraw'] = True 378 geomSet = [] 379 boSet = [] 380 for mol in self.vf.Mols: 381 geomSet = geomSet + mol.geomContainer.atoms['bonded'] 382 boSet = boSet + mol.geomContainer.atoms['bondorder'].uniq() 383 if len(boSet) == 0: 384 kw['displayBO']=False 385 else: 386 kw['displayBO']=True 387 if len(geomSet) == 0: 388 # The undo of a display command is undisplay what you just 389 # displayed if nothing was displayed before. 390 kw['negate'] = True 391 kw['displayBO'] = False 392 self.addUndoCall( (nodes,), kw, self.name) 393 else: 394 # The undo of a display command is to display ONLY what was 395 # displayed before, if something was already displayed 396 kw['only'] = True 397 self.addUndoCall( (geomSet,), kw, self.name)
398 399 ## # we overwrite setupUndoBefore enven though this command implements 400 ## # the negate kw because the only kw would not be handled properly 401 ## molecules, atomSets = self.getNodes(nodes) 402 ## for mol, atm in map(None, molecules, atomSets): 403 ## # set is the atoms part of a bonds and displayed as lines and 404 ## # the atoms not part of a bond and displayed as points 405 ## set = mol.geomContainer.atoms['bonded'] 406 ## if len(set)==0: # nothing is displayed 407 ## kw = {} 408 ## kw['negate'] = True 409 ## kw['redraw'] = True 410 ## kw['displayBO'] = not displayBO 411 412 ## self.addUndoCall( (mol,), kw, self.name ) 413 ## else: 414 ## kw={} 415 ## kw['only'] = True 416 ## kw['redraw'] = True 417 ## kw['displayBO'] = not displayBO 418 ## kw['lineWidth'] = lineWidth 419 ## self.addUndoCall( (set,), kw, self.name ) 420 421
422 - def __call__(self, nodes, lineWidth=2, displayBO=False, only=False, 423 negate=False, **kw):
424 """None <- displayLinesBO(self, nodes, lineWidth=2, displayBO=False,only=False, negate=False, **kw)\n 425 \nRequired Arguments:\n 426 nodes --- any set of MolKit nodes describing molecular components\n 427 428 \nOptional Arguments:\n 429 lineWidth --- int specifying the width of the lines, dots or doted lines 430 representing the selection. (default = 2)\n 431 displayBO --- boolean flag specifying whether or not to display the 432 bond order (default = False)\n 433 only --- boolean flag specifying whether or not to display only 434 the current selection. (default = False)\n 435 negate --- boolean flag specifying whether or not to negate the 436 current selection. (default = False)\n 437 """ 438 if not (type(lineWidth) in [IntType, FloatType] and lineWidth>0): 439 return 'ERROR' 440 kw['lineWidth'] = lineWidth 441 kw['displayBO'] = displayBO 442 kw['only'] = only 443 kw['negate'] = negate 444 kw['redraw'] = True 445 if type(nodes) is StringType: 446 self.nodeLogString = "'" + nodes +"'" 447 nodes = self.vf.expandNodes(nodes) 448 if not nodes: return 449 apply(self.doitWrapper, (nodes,), kw)
450
451 - def doit(self, nodes, lineWidth=2, displayBO=False , only=False, 452 negate=False, **kw):
453 454 ################################################################### 455 def drawAtoms(mol, atm, displayBO, lineWidth, only, negate): 456 """ Function to represent the given atoms as lines if they are 457 bonded and points otherwise""" 458 ggeoms = mol.geomContainer.geoms 459 gatoms = mol.geomContainer.atoms 460 # DISPLAY BONDED ATOMS AND NOBNDS ATOMS 461 # don't need to do all the sets operation which are inefficient. 462 if len(atm) == len(mol.allAtoms): 463 if negate: 464 set = AtomSet() 465 else: 466 set = atm 467 468 else: 469 set = gatoms['bonded'] 470 setnobnds = gatoms['nobnds'] 471 if negate: #if negate, remove current atms from displayed set 472 set = set - atm 473 else: #if only, replace displayed set with current atms 474 if only: 475 set = atm 476 else: 477 set = atm.union(set) 478 479 # Update geoms lines and nobnds with new information. 480 # If no lines then donnot display bondorder. 481 if len(set)==0: 482 ggeoms['bonded'].Set(faces=[], vertices=[], tagModified=False) 483 gatoms['bonded'] = set 484 ggeoms['nobnds'].Set(vertices=[], tagModified=False) 485 gatoms['nobnds'] = set 486 return 487 # This is done only if set contains some atoms. 488 bonds, atnobnd = set.bonds 489 490 # 1st lines need to store the whole set in the 491 # mol.geomContainer.atoms['lines'] because of the picking. 492 gatoms['bonded'] = set 493 494 if len(bonds) == 0: 495 ggeoms['bonded'].Set(faces=[], vertices=[], tagModified=False) 496 else: 497 # need the indices for the indexedPolylines 498 indices = map(lambda x: (x.atom1._bndIndex_, 499 x.atom2._bndIndex_), bonds) 500 if len(indices)==0: 501 ggeoms['bonded'].Set(visible=0, tagModified=False) 502 else: 503 colors = map(lambda x: x.colors['lines'], set) 504 ggeoms['bonded'].Set( vertices=set.coords, 505 faces=indices, 506 materials = colors, 507 lineWidth=lineWidth, 508 visible=1, 509 tagModified=False) 510 # the nobnds 511 gatoms['nobnds']= atnobnd 512 if len(atnobnd)==0: 513 ggeoms['nobnds'].Set(vertices=[], tagModified=False) 514 else: 515 vertices = atnobnd.coords 516 ggeoms['nobnds'].Set(vertices=vertices, 517 pointWidth=lineWidth, 518 visible=1, 519 tagModified=False) 520 #DISPLAY BOND ORDER. 521 if not displayBO: 522 setBo = AtomSet() 523 524 else: 525 if len(atm) == len(mol.allAtoms): 526 if negate: 527 setBo = AtomSet() 528 else: 529 setBo = atm 530 531 else: 532 setBo = gatoms['bondorder'].uniq() 533 if negate: 534 # if negate, remove current atms from displayed set 535 setBo = mol.allAtoms - atm 536 else: 537 # if only, replace displayed set with 538 # current atms 539 if only: 540 setBo = atm 541 else: 542 setBo = mol.allAtoms 543 544 if len(setBo) == 0: 545 ggeoms['bondorder'].Set(vertices=[], tagModified=False) 546 gatoms['bondorder'] = setBo 547 return 548 549 bonds = setBo.bonds[0] 550 551 # Get only the bonds with a bondOrder greater than 1 552 bondsBO= BondSet(filter(lambda x: not x.bondOrder is None and \ 553 x.bondOrder>1, bonds)) 554 if not bondsBO: return 555 withVec = filter(lambda x: not hasattr( x.atom1, 'dispVec') \ 556 and not hasattr(x.atom2, 'dispVec'),bondsBO) 557 if len(withVec): 558 map(lambda x: x.computeDispVectors(), bondsBO) 559 560 vertices = [] 561 indices = [] 562 col = [] 563 i = 0 564 realSet = AtomSet([]) 565 ar = Numeric.array 566 for b in bonds: 567 bondOrder = b.bondOrder 568 if bondOrder == 'aromatic' : bondOrder = 2 569 if not bondOrder > 1: continue 570 571 at1 = b.atom1 572 at2 = b.atom2 573 if (not hasattr(at1, 'dispVec') \ 574 and not hasattr(at2, 'dispVec')): 575 continue 576 realSet.append(at1) 577 realSet.append(at2) 578 579 nc1 = ar(at1.coords) + \ 580 ar(at1.dispVec) 581 nc2 = ar(at2.coords) + \ 582 ar(at2.dispVec) 583 vertices.append(list(nc1)) 584 vertices.append(list(nc2)) 585 indices.append( (i, i+1) ) 586 i = i+2 587 gatoms['bondorder'] = realSet 588 #col = mol.geomContainer.getGeomColor('bondorder') 589 ggeoms['bondorder'].Set( vertices=vertices, 590 faces=indices, 591 visible=1, 592 lineWidth=lineWidth, 593 tagModified=False)
594 595 ################################################################## 596 molecules, atomSets = self.getNodes(nodes) 597 for mol, atms, in map(None, molecules, atomSets): 598 # Get the set of atoms currently represented as wireframe 599 geomC = mol.geomContainer 600 drawAtoms(mol, atms, displayBO, lineWidth, only, negate) 601 602 if only and len(molecules) != len(self.vf.Mols): 603 mols = self.vf.Mols - molecules 604 for mol in mols: 605 only=0 606 negate=1 607 drawAtoms(mol, mol.allAtoms, displayBO, lineWidth, only, 608 negate)
609 610
611 - def buildFormDescr(self, formName='default'):
612 if formName == 'default': 613 idf = DisplayCommand.buildFormDescr( 614 self, formName, title='Display Lines:') 615 616 defaultValues = self.lastUsedValues['default'] 617 618 idf.append({'name':'displayBO', 619 'widgetType':Tkinter.Checkbutton, 620 'defaultValue': defaultValues['displayBO'], 621 'wcfg':{'text': 'show BondOrder', 622 'variable': Tkinter.IntVar()}, 623 'gridcfg':{'sticky':'w'}}) 624 625 idf.append({'name':'lineWidth', 626 'widgetType':ExtendedSliderWidget, 627 'wcfg':{'label': 'Line Width', 628 'minval':1,'maxval':10 , 629 'init': defaultValues['lineWidth'], 630 'labelsCursorFormat':'%d', 631 'sliderType':'int', 632 'entrywcfg':{'width':4}, 633 'entrypackcfg':{'side':'right'}}, 634 'gridcfg':{'columnspan':2,'sticky':'we'}}) 635 636 637 return idf
638 639
640 - def guiCallback(self):
641 nodes = self.vf.getSelection() 642 if not nodes: return 643 val = DisplayCommand.getFormValues(self) 644 if val: 645 if val['displayBO'] == 1: val['displayBO'] = True 646 else: 647 val['displayBO'] = False 648 apply( self.doitWrapper, (nodes,), val)
649 650
651 - def onRemoveObjectFromViewer(self, mol):
652 """ Function to remove the sets able to reference a TreeNode created 653 in this command : Here remove bbDisconnactedAfter created for each 654 chains and bonds created for each elements of each level in 655 buildBondsByDistance.""" 656 657 levels = mol.levels 658 for l in levels: 659 try: 660 levelNodes = mol.findType(l) 661 for n in levelNodes: 662 if hasattr(n, 'bbDisconnectedAfter'): 663 del n.bbDisconnectedAfter 664 if hasattr(n, 'bonds'): 665 del n.bonds 666 except: 667 print "exception displayCommands line 547"
668 #del levelNodes 669
670 - def cleanup(self):
671 """ 672 Method called by afterDoit to cleanup things eventhough doit failes 673 """ 674 #print 'dl: in cleanup' 675 del self.expandedNodes____AtomSets 676 del self.expandedNodes____Molecules
677 678 679 displayLinesGuiDescr = {'widgetType':'Menu', 'menuBarName':'menuRoot', 680 'menuButtonName':'Display', 'menuEntryLabel': 681 'Lines' } 682 683 DisplayLinesGUI = CommandGUI() 684 DisplayLinesGUI.addMenuCommand('menuRoot', 'Display', 'Lines') 685 686
687 -class UndisplayLines(DisplayCommand):
688 """The undisplayLines command is a picking command allowing the user to undisplay the lines geometry representing the picked nodes.This command can also be called from the Python shell with a set of nodes. 689 \nPackage : Pmv 690 \nModule : displayCommands 691 \nClass : UnDisplayLines 692 \nCommand : undisplayLines 693 \nSynopsis:\n 694 None <- undisplayLines(nodes, **kw)\n 695 nodes --- any set of MolKit nodes describing molecular components\n 696 keywords --- undisplay, lines\n 697 """ 698
699 - def onAddCmdToViewer(self):
700 DisplayCommand.onAddCmdToViewer(self) 701 if not self.vf.hasGui: return 702 if not self.vf.commands.has_key('displayLines'): 703 self.vf.loadCommand('displayCommands', ['displayLines'], 'Pmv', 704 topCommand=0)
705
706 - def __call__(self, nodes, **kw):
707 """None <- undisplayLines(nodes, **kw) 708 nodes: TreeNodeSet holding the current selection""" 709 if not nodes: return 710 kw['negate']=1 711 kw['redraw']=1 712 if type(nodes) is StringType: 713 self.nodeLogString = "'" + nodes +"'" 714 nodes = self.vf.expandNodes(nodes) 715 if not nodes: return 716 apply(self.vf.displayLines, (nodes,), kw)
717 718
719 -class DisplayCPK(DisplayCommand):
720 """ The displayCPK command allows the user to display/undisplay the given nodes using a CPK representation, where each atom is represented with a sphere. A scale factor and the quality of the spheres are user 721 defined parameters. 722 \nPackage : Pmv 723 \nModule : displayCommands 724 \nClass : DisplayCPK 725 \nCommand : displayCPK 726 \nSynopsis:\n 727 None <- displayCPK(nodes, only=False, negate=False, 728 scaleFactor=None, quality=None, **kw)\n 729 nodes --- any set of MolKit nodes describing molecular components\n 730 only --- Boolean flag specifying whether or not to only display 731 the current selection\n 732 negate --- Boolean flag specifying whether or not to undisplay 733 the current selection\n 734 scaleFactor --- specifies a scale factor that will be applied to the atom 735 radii to compute the spheres radii. (default is 1.0)\n 736 quality --- specifies the quality of the spheres. (default 10)\n 737 keywords --- display, CPK, space filling, undisplay.\n 738 """
739 - def onAddCmdToViewer(self,):
740 DisplayCommand.onAddCmdToViewer(self) 741 if not self.vf.commands.has_key('assignAtomsRadii'): 742 self.vf.loadCommand('editCommands', 'assignAtomsRadii', 'Pmv', 743 topCommand=0)
744 745
746 - def onAddObjectToViewer(self, obj):
747 """Adds the cpk geometry and the cpk Atomset to the object's 748 geometry container 749 """ 750 if not self.vf.hasGui: return 751 obj.allAtoms.cpkScale = 1.0 752 obj.allAtoms.cpkRad = 0.0 753 geomC = obj.geomContainer 754 # CPK spheres 755 g = Spheres( "cpk", quality = 5 ,visible=0, protected=True) 756 geomC.addGeom(g, parent=geomC.masterGeom, redo=0) 757 self.managedGeometries.append(g) 758 geomC.geomPickToBonds['cpk'] = None 759 for atm in obj.allAtoms: 760 atm.colors['cpk'] = (1.0, 1.0, 1.0) 761 atm.opacities['cpk'] = 1.0
762 763
764 - def setupUndoBefore(self, nodes, only=False, negate=False, scaleFactor=1.0, 765 cpkRad=0.0, quality=0):
766 kw = {} 767 # use last used values for the undo 768 defaultValues = self.lastUsedValues['default'] 769 kw['scaleFactor'] = defaultValues['scaleFactor'] 770 kw['quality'] = defaultValues['quality'] 771 kw['cpkRad'] = defaultValues['cpkRad'] 772 kw['redraw'] = True 773 geomSet = [] 774 for mol in self.vf.Mols: 775 geomSet = geomSet + mol.geomContainer.atoms['cpk'] 776 777 if len(geomSet) == 0: 778 # If nothing was displayed before, the undo of a display 779 # command is to undisplay what you just displayed 780 kw['negate'] = True 781 self.addUndoCall( (nodes,), kw, self.name) 782 else: 783 # If the current was already displayed and only is False and negate 784 # is False then the undo is to display this set using the last used 785 # values. 786 787 # If something was already displayed, the undo of a display 788 # command is to display ONLY what was displayed before. 789 kw['only'] = True 790 self.addUndoCall( (geomSet,), kw, self.name)
791
792 - def doit(self, nodes, only=False, negate=False, 793 scaleFactor=1.0, cpkRad=0.0, quality=0):
794 795 ############################################################## 796 def drawAtoms( mol, atm, only, negate, 797 scaleFactor, cpkRad, quality): 798 atm.cpkScale = scaleFactor 799 atm.cpkRad = cpkRad 800 set = mol.geomContainer.atoms['cpk'] 801 if len(atm) == len(mol.allAtoms): 802 if negate: set = AtomSet() 803 else: set = atm 804 else: 805 ##if negate, remove current atms from displayed set 806 if negate: set = set - atm 807 808 ##if only, replace displayed set with current atms 809 else: 810 if only: set = atm 811 else: 812 set = atm.union(set) 813 814 mol.geomContainer.atoms['cpk']=set 815 816 g = mol.geomContainer.geoms['cpk'] 817 if len(set)==0: 818 g.Set(visible=0, tagModified=False) 819 else: 820 set.sort() # EXPENSIVE... 821 colors = map(lambda x: x.colors['cpk'], set) 822 cpkSF = Numeric.array(set.cpkScale) 823 atmRad = Numeric.array(set.radius) 824 cpkRad = Numeric.array(set.cpkRad) 825 sphRad = cpkRad + cpkSF*atmRad 826 sphRad = sphRad.tolist() 827 828 g.Set(vertices=set.coords, 829 materials = colors, radii=sphRad, visible=1, 830 quality=quality, tagModified=False) 831 832 # highlight selection 833 vi = self.vf.GUI.VIEWER 834 selMols, selAtms = self.vf.getNodesByMolecule(self.vf.selection, Atom) 835 for oneMol, atoms in map(None, selMols, selAtms): 836 if mol is oneMol: 837 lAtomSet = oneMol.geomContainer.atoms['cpk'] 838 if len(lAtomSet) > 0: 839 lAtomSetDict = dict(zip(lAtomSet, range(len(lAtomSet)))) 840 highlight = [-1] * len(lAtomSet) 841 for i in range(len(atoms)): 842 lIndex = lAtomSetDict.get(atoms[i], None) 843 if lIndex is not None: 844 highlight[lIndex] = lIndex 845 g.Set(highlight=highlight) 846 break
847 848 ################################################################## 849 850 molecules, atmSets = self.getNodes(nodes) 851 try: 852 radii = molecules.allAtoms.radius 853 except: 854 self.vf.assignAtomsRadii(molecules, 855 overwrite=False, topCommand=False) 856 857 if quality < 3: 858 nodeAtoms = nodes.findType(Atom) 859 if len(nodeAtoms) < 500: 860 quality = 20 861 elif len(nodeAtoms) < 5000: 862 quality = 15 863 elif len(nodeAtoms) < 10000: 864 quality = 10 865 else: 866 quality = 5 867 868 for mol, atms in map(None, molecules, atmSets): 869 drawAtoms(mol, atms, only, negate, 870 scaleFactor,cpkRad, quality) 871 if only and len(molecules)!=len(self.vf.Mols): 872 mols = self.vf.Mols - molecules 873 for mol in mols: 874 only = False 875 negate = True 876 drawAtoms(mol, mol.allAtoms, only, negate, 877 scaleFactor, cpkRad, quality)
878 879
880 - def cleanup(self):
881 del self.expandedNodes____AtomSets 882 del self.expandedNodes____Molecules
883 884
885 - def __call__(self, nodes, only=False, negate=False, 886 scaleFactor=1.0, cpkRad=0.0, quality=0, **kw):
887 """None <- displayCPK(nodes, only=False, negate=False,scaleFactor=None, cpkRad=0.0, quality=None, **kw) 888 \nnodes --- TreeNodeSet holding the current selection 889 \nonly --- Boolean flag when True only the current selection will be 890 displayed 891 \nnegate --- Boolean flag when True undisplay the current selection 892 \nscaleFactor --- value used to compute the radii of the sphere representing the atom (Sphere Radii = cpkRad + atom.radius * scaleFactor (default is 1.0) 893 \ncpkRad --- value used to compute the radii of the sphere representing the atom (Sphere Radii = cpkRad + atom.radius * scaleFactor (default 0.0) 894 \nquality --- sphere quality default value is 10""" 895 if not kw.has_key('redraw'): kw['redraw'] = True 896 if not type(scaleFactor) in [IntType, FloatType, 897 LongType]: return 'ERROR' 898 if not type(quality) is IntType and quality>=0: 899 return 'ERROR' 900 kw['only'] = only 901 kw['negate'] = negate 902 kw['scaleFactor'] = scaleFactor 903 kw['cpkRad'] = cpkRad 904 kw['quality'] = quality 905 if type(nodes) is StringType: 906 self.nodeLogString = "'" + nodes +"'" 907 nodes = self.vf.expandNodes(nodes) 908 if not nodes: return 909 apply( self.doitWrapper, (nodes,), kw)
910 911
912 - def buildFormDescr(self, formName='default'):
913 # Need to create the InputFormDescr here if there is a gui. 914 if formName == 'default': 915 idf = DisplayCommand.buildFormDescr( 916 self, formName, title ="Display CPKs:") 917 918 defaultValues = self.lastUsedValues['default'] 919 920 idf.append({'name':'cpkRad', 921 'widgetType':ThumbWheel, 922 'tooltip':'The Radii of the sphere geom representing the atom will be equal to (CPK Radii + Atom Radii * Scale Factor)', 923 'wcfg':{ 'labCfg':{'text':'CPK Radii:', 924 'font':('Helvetica',12,'bold')}, 925 'showLabel':1, 'width':100, 926 'min':0.0, 'type':float, 927 'precision':1, 928 'value': defaultValues['cpkRad'], 929 'continuous':1, 930 'oneTurn':2, 'wheelPad':2, 'height':20}, 931 'gridcfg':{'sticky':'e'}}) 932 933 idf.append({'name':'scaleFactor', 934 'widgetType':ThumbWheel, 935 'tooltip':'The Radii of the sphere geom representing the atom will be equal to (CPK Radii + Atom Radii * Scale Factor)', 936 'wcfg':{ 'labCfg':{'text':'Scale Factor:', 937 'font':('Helvetica',12,'bold')}, 938 'showLabel':1, 'width':100, 939 'min':0.1, 'max':100, 940 'increment':0.01, 'type':float, 941 'precision':1, 942 'value': defaultValues['scaleFactor'], 943 'continuous':1, 944 'oneTurn':2, 'wheelPad':2, 'height':20}, 945 'gridcfg':{'sticky':'e'}}) 946 947 idf.append({'name':'quality', 948 'widgetType':ThumbWheel, 949 'tooltip':'if quality < 3 a default value will be determined based on the number of atoms involved in the command', 950 'wcfg':{ 'labCfg':{'text':'Sphere Quality:', 951 'font':('Helvetica',12,'bold')}, 952 'showLabel':1, 'width':100, 953 'min':0, 'max':100, 'type':int, 'precision':1, 954 'value': defaultValues['quality'], 955 'continuous':1, 956 'oneTurn':10, 'wheelPad':2, 'height':20}, 957 'gridcfg':{'sticky':'e'}}) 958 return idf
959 960
961 - def guiCallback(self):
962 nodes = self.vf.getSelection() 963 if not nodes: 964 self.warningMsg("no nodes selected") 965 return 966 967 val = self.showForm() 968 if val: 969 val['redraw'] = True 970 if val['display']=='display': 971 val['only']= False 972 val['negate'] = False 973 del val['display'] 974 975 elif val['display']=='display only': 976 val['only'] = True 977 val['negate'] = False 978 del val['display'] 979 980 elif val['display']== 'undisplay': 981 val['negate'] = True 982 val['only'] = False 983 del val['display'] 984 985 val['quality'] = int(val['quality']) 986 987 apply( self.doitWrapper, (nodes,), val)
988 989 displayCPKGuiDescr = {'widgetType':'Menu', 'menuBarName':'menuRoot', 990 'menuButtonName':'Display', 'menuEntryLabel': 991 'CPK' } 992 993 DisplayCPKGUI = CommandGUI() 994 DisplayCPKGUI.addMenuCommand('menuRoot', 'Display', 'CPK') 995 996 997
998 -class DisplayCPKByProperty(DisplayCommand):
999 """ The displayCPKByProperty command allows the user to specify a property used to display/undisplay the given nodes using a CPK representation, where each atom is represented with a sphere whose radius is set by the particular value of the property for that atom. A scale factor and the quality of the spheres are also used. 1000 defined parameters. 1001 \nPackage : Pmv 1002 \nModule : displayCommands 1003 \nClass : DisplayCPKByProperty 1004 \nCommand : displayCPKByProperty 1005 \nSynopsis:\n 1006 None <- displayCPKByProperty(nodes, only=False, negate=False, 1007 scaleFactor=None, quality=None, **kw)\n 1008 nodes --- any set of MolKit nodes describing molecular components\n 1009 only --- Boolean flag specifying whether or not to only display 1010 the current selection\n 1011 negate --- Boolean flag specifying whether or not to undisplay 1012 the current selection\n 1013 scaleFactor --- specifies a scale factor that will be applied to the atom 1014 radii to compute the spheres radii. (default is 1.0)\n 1015 property --- property name of type integer or float or property defined by a 1016 function returning a list of float or int.\n 1017 quality --- specifies the quality of the spheres. (default 10)\n 1018 keywords --- display, CPK, space filling, undisplay.\n 1019 """ 1020 levelOrder = {'Atom':0 , 1021 'Residue':1, 1022 'Chain':2, 1023 'Molecule':3 } 1024 1025
1026 - def __init__(self, func=None):
1027 DisplayCommand.__init__(self, func) 1028 self.flag = self.flag & 0 1029 self.level = None # class at this level (i.e. Molecule, Residue, Atom)
1030 1031
1032 - def onAddCmdToViewer(self,):
1033 from mglutil.util.colorUtil import ToHEX 1034 DisplayCommand.onAddCmdToViewer(self) 1035 if not self.vf.commands.has_key('assignAtomsRadii'): 1036 self.vf.loadCommand('editCommands', 'assignAtomsRadii', 'Pmv', 1037 topCommand=0) 1038 from MolKit.molecule import Molecule, Atom 1039 from MolKit.protein import Protein, Residue, Chain 1040 self.molDict = {'Molecule':Molecule, 1041 'Atom':Atom, 'Residue':Residue, 'Chain':Chain} 1042 self.nameDict = {Molecule:'Molecule', Atom:'Atom', Residue:'Residue', 1043 Chain:'Chain'} 1044 1045 self.leveloption={} 1046 for name in ['Atom', 'Residue', 'Molecule', 'Chain']: 1047 col = self.vf.ICmdCaller.levelColors[name] 1048 bg = ToHEX((col[0]/1.5,col[1]/1.5,col[2]/1.5)) 1049 ag = ToHEX(col) 1050 self.leveloption[name]={'bg':bg,'activebackground':ag, 1051 'borderwidth':3} 1052 self.propValues = None 1053 self.getVal = 0 1054 self.level = self.nameDict[self.vf.selectionLevel] 1055 self.propertyLevel = self.level
1056 1057 1058
1059 - def getPropValues(self, nodes, prop, propertyLevel=None):
1060 #import pdb;pdb.set_trace() 1061 try: 1062 if propertyLevel is not None: 1063 lNodesInLevel = self.vf.getSelection().findType(self.molDict[propertyLevel]) 1064 num = len(lNodesInLevel.findType(Atom)) 1065 self.propValues = getattr(lNodesInLevel, prop) 1066 else: 1067 self.propValues = getattr(nodes, prop) 1068 except: 1069 msg= "Some nodes do not have the selected property, therefore the \ 1070 current selection cannot be colored using this function." 1071 self.warningMsg(msg) 1072 self.propValues=[]
1073 1074
1075 - def onAddObjectToViewer(self, obj):
1076 """Adds the cpkByProp geometry and the cpkByProp Atomset to the object's 1077 geometry container 1078 """ 1079 if not self.vf.hasGui: return 1080 obj.allAtoms.cpkByPropScale = 1.0 1081 obj.allAtoms.cpkByPropRad = 0.0 1082 geomC = obj.geomContainer 1083 # CPK spheres 1084 g = Spheres( "cpkByProp", quality = 5 ,visible=0, protected=True) 1085 geomC.addGeom(g, parent=geomC.masterGeom, redo=0) 1086 self.managedGeometries.append(g) 1087 geomC.geomPickToBonds['cpkByProp'] = None 1088 for atm in obj.allAtoms: 1089 atm.colors['cpkByProp'] = (1.0, 1.0, 1.0) 1090 atm.opacities['cpkByProp'] = 1.0 1091 self.managedGeometries.append(g)
1092 1093
1094 - def setupUndoBefore(self, nodes, only=False, negate=False, scaleFactor=1.0, 1095 cpkRad=0.0, quality=0, **kw):
1096 kw = {} 1097 # use last used values for the undo 1098 defaultValues = self.lastUsedValues['default'] 1099 kw['scaleFactor'] = defaultValues['scaleFactor'] 1100 kw['quality'] = defaultValues['quality'] 1101 kw['cpkRad'] = defaultValues['cpkRad'] 1102 kw['redraw'] = True 1103 geomSet = [] 1104 for mol in self.vf.Mols: 1105 geomSet = geomSet + mol.geomContainer.atoms['cpkByProp'] 1106 1107 if len(geomSet) == 0: 1108 # If nothing was displayed before, the undo of a display 1109 # command is to undisplay what you just displayed 1110 kw['negate'] = True 1111 self.addUndoCall( (nodes,), kw, self.name) 1112 else: 1113 # If the current was already displayed and only is False and negate 1114 # is False then the undo is to display this set using the last used 1115 # values. 1116 1117 # If something was already displayed, the undo of a display 1118 # command is to display ONLY what was displayed before. 1119 kw['only'] = True 1120 self.addUndoCall( (geomSet,), kw, self.name)
1121 1122
1123 - def doit(self, nodes, only=False, negate=False, 1124 scaleFactor=1.0, cpkRad=0.0, quality=0, **kw):
1125 1126 ############################################################## 1127 def drawAtoms( mol, atm, only, negate, 1128 scaleFactor, cpkRad, quality): 1129 #atm.cpkScale = scaleFactor 1130 #atm.cpkRad = cpkRad 1131 set = mol.geomContainer.atoms['cpkByProp'] 1132 if len(atm) == len(mol.allAtoms): 1133 if negate: set = AtomSet() 1134 else: set = atm 1135 else: 1136 ##if negate, remove current atms from displayed set 1137 if negate: set = set - atm 1138 1139 ##if only, replace displayed set with current atms 1140 else: 1141 if only: set = atm 1142 else: 1143 set = atm.union(set) 1144 1145 mol.geomContainer.atoms['cpkByProp']=set 1146 1147 g = mol.geomContainer.geoms['cpkByProp'] 1148 if len(set)==0: 1149 g.Set(visible=0, tagModified=False) 1150 else: 1151 set.sort() # EXPENSIVE... 1152 colors = map(lambda x: x.colors['cpkByProp'], set) 1153 #cpkSF = Numeric.array(set.cpkScale) 1154 #atmRad = Numeric.array(self.propValues) * scaleFactor 1155 #cpkRad = Numeric.array(self.propValues) 1156 #cpkRad = Numeric.array(set.cpkRad) 1157 #sphRad = cpkRad + cpkSF*atmRad 1158 #sphRad = sphRad.tolist() 1159 sphRad = Numeric.array(self.propValues) * scaleFactor 1160 g.Set(vertices=set.coords, 1161 materials = colors, radii=sphRad, visible=1, 1162 quality=quality, tagModified=False) 1163 1164 # highlight selection 1165 vi = self.vf.GUI.VIEWER 1166 selMols, selAtms = self.vf.getNodesByMolecule(self.vf.selection, Atom) 1167 for oneMol, atoms in map(None, selMols, selAtms): 1168 if mol is oneMol: 1169 lAtomSet = oneMol.geomContainer.atoms['cpkByProp'] 1170 if len(lAtomSet) > 0: 1171 lAtomSetDict = dict(zip(lAtomSet, range(len(lAtomSet)))) 1172 highlight = [-1] * len(lAtomSet) 1173 for i in range(len(atoms)): 1174 lIndex = lAtomSetDict.get(atoms[i], None) 1175 if lIndex is not None: 1176 highlight[lIndex] = lIndex 1177 g.Set(highlight=highlight) 1178 break
1179 1180 ################################################################## 1181 1182 molecules, atmSets = self.getNodes(nodes) 1183 try: 1184 radii = self.propValues 1185 except: 1186 self.vf.assignAtomsRadii(molecules, 1187 overwrite=False, topCommand=False) 1188 1189 if quality < 3: 1190 nodeAtoms = nodes.findType(Atom) 1191 if len(nodeAtoms) < 500: 1192 quality = 20 1193 elif len(nodeAtoms) < 5000: 1194 quality = 15 1195 elif len(nodeAtoms) < 10000: 1196 quality = 10 1197 else: 1198 quality = 5 1199 1200 for mol, atms in map(None, molecules, atmSets): 1201 drawAtoms(mol, atms, only, negate, 1202 scaleFactor, cpkRad, quality) 1203 if only and len(molecules)!=len(self.vf.Mols): 1204 mols = self.vf.Mols - molecules 1205 for mol in mols: 1206 only = False 1207 negate = True 1208 drawAtoms(mol, mol.allAtoms, only, negate, 1209 scaleFactor, cpkRad, quality)
1210 1211
1212 - def cleanup(self):
1213 try: 1214 del self.expandedNodes____AtomSets 1215 del self.expandedNodes____Molecules 1216 except: 1217 print 'cleanup could not find any expandedNodes____AtomSets'
1218 1219
1220 - def __call__(self, nodes, property, only=False, negate=False, 1221 scaleFactor=1.0, cpkRad=0.0, quality=0, **kw):
1222 """None <- displayCPKByProperty(nodes, property, only=False, negate=False,scaleFactor=None, cpkRad=0.0, quality=None, **kw) 1223 \nnodes --- TreeNodeSet holding the current selection 1224 \nproperty --- property used to set radii 1225 \nonly --- Boolean flag when True only the current selection will be 1226 displayed 1227 \nnegate --- Boolean flag when True undisplay the current selection 1228 \nscaleFactor --- value used to compute the radii of the sphere representing the atom (Sphere Radii = cpkRad + atom.radius * scaleFactor (default is 1.0) 1229 \ncpkRad --- value used to compute the radii of the sphere representing the atom (Sphere Radii = cpkRad + atom.radius * scaleFactor (default 0.0) 1230 \nquality --- sphere quality default value is 10""" 1231 if not kw.has_key('redraw'): kw['redraw'] = True 1232 if not type(scaleFactor) in [IntType, FloatType, 1233 LongType]: return 'ERROR' 1234 if not type(quality) is IntType and quality>=0: 1235 return 'ERROR' 1236 kw['only'] = only 1237 kw['negate'] = negate 1238 kw['scaleFactor'] = scaleFactor 1239 #kw['cpkRad'] = cpkRad 1240 kw['quality'] = quality 1241 if type(nodes) is StringType: 1242 self.nodeLogString = "'" + nodes +"'" 1243 nodes = self.vf.expandNodes(nodes) 1244 if not nodes: return 1245 apply( self.doitWrapper, (nodes,property), kw)
1246 1247
1248 - def updateLevel_cb(self, tag):
1249 #if tag != self.level: 1250 # self.level = tag 1251 if tag != self.propertyLevel: 1252 self.propertyLevel = tag 1253 1254 #if self.molDict[tag] != self.vf.ICmdCaller.level.value: 1255 #self.vf.setIcomLevel(self.molDict[tag]) 1256 #force a change of selection level too in order to get 1257 #list of property values at 'tat' level 1258 #self.vf.setSelectionLevel(self.molDict[tag]) 1259 1260 lSelection = self.vf.getSelection().uniq().findType( 1261 self.molDict[tag]).uniq() 1262 lSelection.sort() 1263 self.updateChooser(lSelection)
1264 #self.cleanup() 1265 1266
1267 - def updateChooser(self, selection):
1268 if not hasattr(self, 'properties'): self.properties = [] 1269 oldProp = self.properties 1270 self.properties = filter(lambda x: type(x[1]) is IntType \ 1271 or type(x[1]) is FloatType, 1272 selection[0].__dict__.items()) 1273 1274 # Filter out the private members starting by __. 1275 self.properties = filter(lambda x: x[0][:2]!='__', self.properties) 1276 1277 if self.cmdForms.has_key('default'): 1278 # If the list of properties changed then need to update the listbox 1279 ebn = self.cmdForms['default'].descr.entryByName 1280 widget = ebn['properties']['widget'] 1281 propertyNames = map(lambda x: (x[0],None), self.properties) 1282 propertyNames.sort() 1283 oldsel = widget.get() 1284 widget.setlist(propertyNames) 1285 if len(oldsel)>0 and (oldsel[0], None) in propertyNames: 1286 widget.set(oldsel[0])
1287 1288
1289 - def getPropValues2(self, nodes, function, lambdaFunc):
1290 try: 1291 func = evalString(function) 1292 except: 1293 self.warningMsg("Error occurred while evaluating the expression") 1294 traceback.print_exc() 1295 return 1296 1297 if lambdaFunc == 1: 1298 try: 1299 self.propValues = map(func, nodes) 1300 except KeyError: 1301 msg= "Some nodes do not have this property, therefore the current selection cannot be colored using this function." 1302 self.warningMsg(msg) 1303 self.propValues = None 1304 else: 1305 try: 1306 self.propValues = func(nodes) 1307 except: 1308 msg= "Some nodes do not have this property, therefore the current selection cannot be colored using this function." 1309 self.warningMsg(msg) 1310 self.propValues = None
1311
1312 - def updateMiniMaxi(self, cmName, event=None):
1313 # get the colorMap 1314 #cm = self.vf.colorMaps[cmName] 1315 #mini = cm.mini 1316 #maxi = cm.maxi 1317 #FIX THIS!!! 1318 mini = 0 1319 maxi = 1000 1320 ebn = self.cmdForms['default'].descr.entryByName 1321 if mini is not None: 1322 ebn["cmMin"]['widget'].setentry(mini) 1323 if maxi is not None: 1324 ebn['cmMax']['widget'].setentry(maxi)
1325 1326
1327 - def updateValMinMax(self, event=None):
1328 print "updateValMinMax" 1329 ebn = self.cmdForms['default'].descr.entryByName 1330 widget = ebn['properties']['widget'] 1331 properties = widget.get() 1332 if len(properties)==0: 1333 self.propValues=None 1334 else: 1335 self.getPropValues(self.selection, properties[0], self.propertyLevel) 1336 minEntry = ebn['valMin']['widget'] 1337 maxEntry = ebn['valMax']['widget'] 1338 self.getVal = 1 1339 if self.propValues is None : 1340 mini = 0 1341 maxi = 0 1342 else: 1343 mini = min(self.propValues) 1344 maxi = max(self.propValues) 1345 minEntry.setentry(mini) 1346 maxEntry.setentry(maxi)
1347 1348 1349 1350
1351 - def updatePropVals(self, event=None):
1352 print "updatePropVals event=", event 1353 ebn = self.cmdForms['default'].descr.entryByName 1354 widget = ebn['properties']['widget'] 1355 properties = widget.get() 1356 if len(properties)==0: 1357 self.propValues=[] 1358 return 1359 else: 1360 self.getPropValues(self.selection, properties[0], self.propertyLevel) 1361 minEntry = ebn['valMin']['widget'] 1362 maxEntry = ebn['valMax']['widget'] 1363 self.getVal = 1 1364 if self.propValues is None or self.propValues==[] : 1365 mini = 0 1366 maxi = 0 1367 else: 1368 mini = min(self.propValues) 1369 maxi = max(self.propValues) 1370 minEntry.setentry(mini) 1371 maxEntry.setentry(maxi)
1372 1373 1374 1375
1376 - def updateCM(self, event=None):
1377 ebn = self.cmdForms['default'].descr.entryByName 1378 mini = ebn['valMin']['widget'].get() 1379 maxi = ebn['valMax']['widget'].get() 1380 ebn["cmMin"]['widget'].setentry(mini) 1381 ebn['cmMax']['widget'].setentry(maxi)
1382 1383
1384 - def buildFormDescr(self, formName='default'):
1385 # Need to create the InputFormDescr here if there is a gui. 1386 if formName == 'default': 1387 idf = DisplayCommand.buildFormDescr( 1388 self, 'default', title ="Display CPK with radii set by property:") 1389 1390 defaultValues = self.lastUsedValues['default'] 1391 if len(self.properties)>0 : 1392 #val = self.nameDict[self.vf.ICmdCaller.level.value] 1393 val = self.level 1394 listoption = {'Atom':{'bg':'yellow', 1395 'activebackground':'yellow', 1396 'borderwidth':3}, 1397 'Residue':{'bg':'green', 1398 'activebackground':'green', 1399 'borderwidth':3}, 1400 'Chain':{'bg':'cyan', 1401 'activebackground':'cyan', 1402 'borderwidth':3}, 1403 'Molecule':{'bg':'red', 1404 'activebackground':'red', 1405 'borderwidth':3} 1406 } 1407 1408 idf.append({'widgetType':Pmw.RadioSelect, 1409 'name':'level', 1410 'listtext':['Atom', 'Residue', 'Chain','Molecule'], 1411 'defaultValue':val,'listoption':self.leveloption, 1412 'wcfg':{'label_text':'Change the property level:', 1413 'labelpos':'nw', 1414 'command':self.updateLevel_cb, 1415 }, 1416 'gridcfg':{'sticky':'we','columnspan':2}}) 1417 1418 propertyNames = map(lambda x: (x[0],None), self.properties) 1419 propertyNames.sort() 1420 idf.append({'name':'properties', 1421 'widgetType':ListChooser, 1422 'required':1, 1423 'wcfg':{'entries': propertyNames, 1424 'title':'Choose one property:', 1425 'lbwcfg':{'exportselection':0}, 1426 'mode':'single','withComment':0, 1427 'command':self.updatePropVals, 1428 }, 1429 'gridcfg':{'sticky':'we', 'rowspan':4, 'padx':5}}) 1430 #------------------------------------------------------------------ 1431 idf.append({'name':'minMax', 1432 'widgetType':Pmw.Group, 1433 'parent':'cmdGroup', 1434 'container':{"minMax":"w.interior()"}, 1435 'gridcfg':{'sticky':'wnse'}}) 1436 1437 idf.append({'name':'valueMiniMaxi', 1438 'widgetType':Pmw.Group, 1439 'parent':'minMax', 1440 'container':{"valminimaxi":'w.interior()'}, 1441 'wcfg':{'tag_text':"Property Values:"}, 1442 'gridcfg':{'sticky':'wnse'}}) 1443 1444 idf.append({'name':'updateCM', 1445 'parent':'minMax', 1446 'widgetType':Tkinter.Button, 1447 'tooltip':"Set cpk radii min and max values \n with the property values min\ 1448 and maxi", 1449 'wcfg':{'text':">>", 'command':self.updateCM}, 1450 'gridcfg':{'row':-1} 1451 }) 1452 1453 1454 idf.append({'name':'cmninmaxi', 1455 'widgetType':Pmw.Group, 1456 'parent':'minMax', 1457 'container':{"cmminimaxi":'w.interior()'}, 1458 'wcfg':{'tag_text':"CPK Radii:"}, 1459 'gridcfg':{'sticky':'wnse', 'row':-1}}) 1460 1461 idf.append({'name':"valMin", 1462 'widgetType':Pmw.EntryField, 1463 'parent':'valminimaxi', 1464 'wcfg':{'label_text':'Minimum', 1465 'labelpos':'w'}, 1466 }) 1467 idf.append({'name':"valMax", 1468 'widgetType':Pmw.EntryField, 1469 'parent':'valminimaxi', 1470 'wcfg':{'label_text':'Maximum', 1471 'labelpos':'w'}, 1472 }) 1473 1474 idf.append({'name':"cmMin", 1475 'widgetType':Pmw.EntryField, 1476 'parent':'cmminimaxi', 1477 'wcfg':{'label_text':'Minimum', 1478 'labelpos':'w'}, 1479 'gridcfg':{} 1480 }) 1481 1482 idf.append({'name':"cmMax", 1483 'widgetType':Pmw.EntryField, 1484 'parent':'cmminimaxi', 1485 'wcfg':{'label_text':'Maximum', 1486 'labelpos':'w'}, 1487 }) 1488 1489 #------------------------------------------------------------------ 1490 1491 idf.append({'name':'cpkRad', 1492 'widgetType':ThumbWheel, 1493 'tooltip':'The Radii of the sphere geom representing the atom will be equal to (CPK Radii + Atom Radii * Scale Factor)', 1494 'wcfg':{ 'labCfg':{'text':'CPK Radii:', 1495 'font':('Helvetica',12,'bold')}, 1496 'showLabel':1, 'width':100, 1497 'min':0.0, 'type':float, 1498 'precision':1, 1499 'value': defaultValues['cpkRad'], 1500 'continuous':1, 1501 'oneTurn':2, 'wheelPad':2, 'height':20}, 1502 'gridcfg':{'sticky':'e'}}) 1503 1504 idf.append({'name':'scaleFactor', 1505 'widgetType':ThumbWheel, 1506 'tooltip':'The Radii of the sphere geom representing the atom will be equal to (CPK Radii + Atom Radii * Scale Factor)', 1507 'wcfg':{ 'labCfg':{'text':'Scale Factor:', 1508 'font':('Helvetica',12,'bold')}, 1509 'showLabel':1, 'width':100, 1510 'min':0.1, 'max':100, 1511 'increment':0.01, 'type':float, 1512 'precision':1, 1513 'value': defaultValues['scaleFactor'], 1514 'continuous':1, 1515 'oneTurn':2, 'wheelPad':2, 'height':20}, 1516 'gridcfg':{'sticky':'e'}}) 1517 1518 idf.append({'name':'quality', 1519 'widgetType':ThumbWheel, 1520 'tooltip':'if quality < 3 a default value will be determined based on the number of atoms involved in the command', 1521 'wcfg':{ 'labCfg':{'text':'Sphere Quality:', 1522 'font':('Helvetica',12,'bold')}, 1523 'showLabel':1, 'width':100, 1524 'min':0, 'max':100, 'type':int, 'precision':1, 1525 'value': defaultValues['quality'], 1526 'continuous':1, 1527 'oneTurn':10, 'wheelPad':2, 'height':20}, 1528 'gridcfg':{'sticky':'e'}}) 1529 return idf
1530 1531
1532 - def guiCallback(self):
1533 self.propValues = [] 1534 nodes = self.vf.getSelection() 1535 if not nodes: 1536 self.warningMsg("no nodes selected") 1537 return 1538 self.selection = self.vf.getSelection().findType(self.vf.selectionLevel) 1539 if not self.selection: return 'ERROR' # to prevent logging 1540 self.level = self.nameDict[self.vf.selectionLevel] 1541 self.selection.sort() 1542 self.updateChooser(self.selection) 1543 if self.cmdForms.has_key('default'): 1544 # Check if the level is the same than the one on the menu bar 1545 ebn = self.cmdForms['default'].descr.entryByName 1546 levelwid = ebn['level']['widget'] 1547 oldlevel = levelwid.getcurselection() 1548 #if oldlevel != self.nameDict[self.vf.ICmdCaller.level.value]: 1549 # levelwid.invoke(self.nameDict[self.vf.ICmdCaller.level.value]) 1550 if oldlevel != self.level: 1551 #print 'calling levelwid.invoke with ', self.level 1552 levelwid.invoke(self.level) 1553 self.updatePropVals() 1554 val = self.showForm('default') 1555 #if val: 1556 if val=={} or not val['properties']: return 1557 property = val['properties'][0] 1558 del val['properties'] 1559 try: 1560 mini = float(val['cmMin']) 1561 val['mini'] = mini 1562 except: 1563 mini = None 1564 val['mini'] = None 1565 try: 1566 maxi = float(val['cmMax']) 1567 val['maxi'] = maxi 1568 except: 1569 maxi = None 1570 val['maxi'] = None 1571 1572 val['redraw'] = True 1573 if val['display']=='display': 1574 val['only']= False 1575 val['negate'] = False 1576 del val['display'] 1577 1578 elif val['display']=='display only': 1579 val['only'] = True 1580 val['negate'] = False 1581 del val['display'] 1582 1583 elif val['display']== 'undisplay': 1584 val['negate'] = True 1585 val['only'] = False 1586 del val['display'] 1587 1588 val['quality'] = int(val['quality']) 1589 try: 1590 del val['level'] 1591 del val['only'] 1592 except: 1593 print 'error in removing level from dict' 1594 apply( self.doitWrapper, (nodes, property), val)
1595 1596 1597 displayCPKByPropertyGuiDescr = {'widgetType':'Menu', 'menuBarName':'menuRoot', 1598 'menuButtonName':'Display', 'menuEntryLabel': 1599 'CPKByProperty' } 1600 1601 DisplayCPKByPropertyGUI = CommandGUI() 1602 DisplayCPKByPropertyGUI.addMenuCommand('menuRoot', 'Display', 'CPKByProperty') 1603 1604 1605
1606 -class UndisplayCPK(DisplayCommand):
1607 """ The undisplayCPK command is a picking command allowing the user to undisplay the CPK geometry representing the picked nodes when used as a picking command or the given nodes when called from the Python shell. 1608 \nPackage : Pmv 1609 \nModule : displayCommands 1610 \nClass : UnDisplayCPK 1611 \nCommand : undisplayCPK 1612 \nSynopsis:\n 1613 None <- undisplayCPK(nodes, **kw)\n 1614 nodes : any set of MolKit nodes describing molecular components\n 1615 keywords: undisplay, CPK\n 1616 """ 1617
1618 - def onAddCmdToViewer(self):
1619 DisplayCommand.onAddCmdToViewer(self) 1620 if not self.vf.hasGui: return 1621 if not self.vf.commands.has_key('displayCPK'): 1622 self.vf.loadCommand('displayCommands', ['displayCPK'], 'Pmv', 1623 topCommand=0)
1624
1625 - def __call__(self, nodes, **kw):
1626 """None <- undisplayCPK(nodes, **kw) 1627 nodes: TreeNodeSet holding the current selection""" 1628 kw['negate']= 1 1629 if type(nodes) is StringType: 1630 self.nodeLogString = "'" + nodes +"'" 1631 nodes = self.vf.expandNodes(nodes) 1632 if not nodes: return 1633 apply(self.vf.displayCPK, (nodes,),kw)
1634 1635 1636
1637 -class DisplaySticksAndBalls(DisplayCommand):
1638 """The displaySticksAndBalls command allows the user to display/undisplay 1639 the given nodes using the sticks and balls representation, where the bonds are 1640 represented by cylinders and the atoms by balls.The radii of the cylinders and 1641 the balls, and the quality of the spheres are user defined. The user can chose 1642 to display or not the balls. 1643 Package : Pmv 1644 Module : displayCommands 1645 Class : DisplaySticksAndBalls 1646 Command : displaySticksAndBalls 1647 Synopsis: 1648 None <--- displaySticksAndBalls(nodes, only=0, negate=0, 1649 sticksBallsLicorice='Sticks and Balls', 1650 bradii=0.4, bquality=0, cradius=0.2, 1651 absolute=1, **kw) 1652 nodes --- any set of MolKit nodes describing molecular components 1653 only --- Boolean flag specifying whether or not to only display 1654 the current selection\n 1655 negate --- Boolean flag specifying whether or not to undisplay 1656 the current selection\n 1657 sticksBallsLicorice --- String specifying the type of rendering 1658 cradius --- specifies the cylinder radius\n 1659 bradii --- specifies the radius of the balls if displayed. 1660 bquality --- specifies the quality of the balls if displayed. 1661 keywords --- display sticks and balls representation 1662 """ 1663
1664 - def onRemoveObjectFromViewer(self, mol):
1665 pass
1666 1667
1668 - def onAddObjectToViewer(self, obj):
1669 if not self.vf.hasGui: return 1670 defaultValues = self.lastUsedValues['default'] 1671 obj.allAtoms.ballRad = defaultValues['bRad'] 1672 obj.allAtoms.ballScale = defaultValues['bScale'] 1673 obj.allAtoms.cRad = defaultValues['cradius'] 1674 1675 geomC = obj.geomContainer 1676 1677 # Cylinders (sticks) 1678 g = Cylinders( "sticks", visible=0, vertices=geomC.allCoords, protected=True) 1679 geomC.addGeom(g, parent=geomC.masterGeom, redo=0) 1680 self.managedGeometries.append(g) 1681 1682 # Spheres at atomic positions (used for stick and balls) 1683 g = Spheres( "balls", vertices = geomC.allCoords, 1684 radii = 0.4, quality = 4 ,visible=0, protected=True) 1685 geomC.addGeom(g, parent=geomC.masterGeom, redo=0) 1686 self.managedGeometries.append(g) 1687 geomC.geomPickToBonds['balls'] = None 1688 1689 for atm in obj.allAtoms: 1690 atm.colors['sticks'] = (1.0, 1.0, 1.0) 1691 atm.opacities['sticks'] = 1.0 1692 atm.colors['balls'] = (1.0, 1.0, 1.0) 1693 atm.opacities['balls'] = 1.0
1694 1695
1696 - def setupUndoBefore(self, nodes, only=False, negate=False, 1697 bRad=0.3, bScale=0.0, 1698 bquality=0, cradius=0.2, cquality=0, absolute=True, 1699 sticksBallsLicorice='Sticks and Balls'):
1700 1701 ## molecules, atomSets = self.getNodes(nodes) 1702 kw={} 1703 defaultValues = self.lastUsedValues['default'] 1704 1705 kw['bRad'] = defaultValues['bRad'] 1706 kw['bScale'] = defaultValues['bScale'] 1707 kw['bquality'] = defaultValues['bquality'] 1708 kw['cradius'] = defaultValues['cradius'] 1709 kw['cquality'] = defaultValues['cquality'] 1710 kw['sticksBallsLicorice'] = defaultValues['sticksBallsLicorice'] 1711 1712 ballset = AtomSet() 1713 stickset = AtomSet() 1714 for mol in self.vf.Mols: 1715 ballset = ballset + mol.geomContainer.atoms['balls'] 1716 stickset = stickset + mol.geomContainer.atoms['sticks'] 1717 1718 if len(ballset)==0: 1719 # no balls displayed 1720 if len(stickset) == 0: # negate 1721 # no stick displayed 1722 kw['negate'] = True 1723 kw['redraw'] = True 1724 self.addUndoCall( (nodes,), kw, 1725 self.name ) 1726 else: 1727 # noballs was on 1728 kw['negate'] = False 1729 kw['redraw'] = True 1730 kw['only'] = True 1731 self.addUndoCall( (stickset,), kw, 1732 self.name ) 1733 else: 1734 1735 kw['redraw'] = True 1736 kw['only'] = True 1737 self.addUndoCall( (stickset,), kw, 1738 self.name )
1739 1740
1741 - def doit(self, nodes, only=False, negate=False, bRad=0.3, 1742 bScale=0.0, bquality=0, cradius=0.2, cquality=0, 1743 sticksBallsLicorice='Sticks and Balls', **kw):
1744 1745 if kw.get('noballs') is not None: 1746 warnings.warn("noballs is deprected, use sticksBallsLicorice='Sticks Only' instead") 1747 1748 ######################################################## 1749 1750 def drawBalls(mol, atm, only, noBalls, negate, bRad, bScale, 1751 bquality): 1752 atm.ballRad = bRad 1753 atm.ballScale = bScale 1754 set = mol.geomContainer.atoms['balls'] 1755 ## case noballs: 1756 if noBalls: 1757 if only: 1758 if len(atm) == len(mol.allAtoms): 1759 set = atm 1760 else: 1761 set = atm.union(set) 1762 mol.geomContainer.geoms['balls'].Set(visible=0, 1763 tagModified=False) 1764 mol.geomContainer.atoms['balls'] = set 1765 return 1766 else: 1767 negate = True 1768 1769 ## Then handle only and negate 1770 ##if negate, remove current atms from displayed set 1771 if len(atm) == len(mol.allAtoms): 1772 if negate: set = AtomSet([]) 1773 else: set = atm 1774 else: 1775 if negate: 1776 set = set - atm 1777 else: 1778 ##if only, replace displayed set with current atms 1779 if only: 1780 set = atm 1781 else: 1782 set = atm.union(set) 1783 if len(set) == 0: 1784 mol.geomContainer.geoms['balls'].Set(visible=0, 1785 tagModified=False) 1786 mol.geomContainer.atoms['balls'] = set 1787 return 1788 1789 mol.geomContainer.atoms['balls']=set 1790 #set.sort() 1791 bScale = Numeric.array(set.ballScale) 1792 bRad = Numeric.array(set.ballRad) 1793 aRad = Numeric.array(set.radius) 1794 1795 ballRadii = bRad + bScale * aRad 1796 ballRadii = ballRadii.tolist() 1797 1798 b = mol.geomContainer.geoms['balls'] 1799 bcolors = map(lambda x: x.colors['balls'], set) 1800 b.Set(vertices=set.coords, radii=ballRadii, 1801 materials=bcolors, 1802 visible=1, tagModified=False) 1803 if bquality and type(bquality) == IntType: 1804 b.Set(quality=bquality, tagModified=False) 1805 1806 # highlight selection 1807 vi = self.vf.GUI.VIEWER 1808 selMols, selAtms = self.vf.getNodesByMolecule(self.vf.selection, Atom) 1809 for oneMol, atoms in map(None, selMols, selAtms): 1810 if mol is oneMol: 1811 lAtomSet = oneMol.geomContainer.atoms['balls'] 1812 if len(lAtomSet) > 0: 1813 lAtomSetDict = dict(zip(lAtomSet, range(len(lAtomSet)))) 1814 highlight = [-1] * len(lAtomSet) 1815 for i in range(len(atoms)): 1816 lIndex = lAtomSetDict.get(atoms[i], None) 1817 if lIndex is not None: 1818 highlight[lIndex] = lIndex 1819 b.Set(highlight=highlight) 1820 break
1821 1822 1823 def drawSticks(mol, atm, only, negate, cradius, cquality): 1824 atm.cRad = cradius 1825 set = mol.geomContainer.atoms['sticks'] 1826 ##if negate, remove current atms from displayed set 1827 if len(atm) == len(mol.allAtoms): 1828 if negate: set = AtomSet() 1829 else: set = atm 1830 else: 1831 if negate: 1832 set = set - atm 1833 else: 1834 ## if only, replace displayed set with current atms 1835 if only: set = atm 1836 else: 1837 set = atm.union(set) 1838 1839 if len(set) == 0: 1840 mol.geomContainer.geoms['sticks'].Set(visible=0, 1841 tagModified=False) 1842 mol.geomContainer.atoms['sticks']= set 1843 return 1844 1845 bonds, atnobnd = set.bonds 1846 mol.geomContainer.atoms['sticks'] = set 1847 indices = map(lambda x: (x.atom1._bndIndex_, 1848 x.atom2._bndIndex_), bonds) 1849 g = mol.geomContainer.geoms['sticks'] 1850 if len(indices) == 0: 1851 g.Set(visible=0, tagModified=False, redo=False) 1852 else: 1853 cRad = set.cRad 1854 scolors = map(lambda x: x.colors['sticks'], set) 1855 g.Set( vertices=set.coords, faces=indices, radii=cRad, 1856 materials=scolors, visible=1, quality=cquality, 1857 tagModified=False)
1858 1859 1860 1861 1862 1863 1864 ## 1865 1866 #DISPLAY BOND ORDER. 1867 ## if len(atm) == len(mol.allAtoms): 1868 ## if negate or not displayBO: 1869 ## setBo = AtomSet() 1870 ## else: 1871 ## setBo = atm 1872 1873 ## else: 1874 ## setBo = gatoms['bondorder'].uniq() 1875 ## if negate or not displayBO: 1876 ## #if negate, remove current atms from displayed set 1877 ## setBo = setBo - atm 1878 ## else: #if only, replace displayed set with current atms 1879 ## if only: 1880 ## setBo = atm 1881 ## else: 1882 ## setBo = atm.union(setBo) 1883 1884 ## if len(setBo) == 0: 1885 ## ggeoms['bondorder'].Set(vertices = [], tagModified=False ) 1886 ## gatoms['bondorder'] = setBo 1887 ## return 1888 1889 ## bonds = setBo.bonds[0] 1890 1891 ## # Get only the bonds with a bondOrder greater than 1 1892 ## bondsBO= BondSet(filter(lambda x: not x.bondOrder is None and \ 1893 ## x.bondOrder>1, bonds)) 1894 ## if not bondsBO: return 1895 ## withVec = filter(lambda x: not hasattr( x.atom1, 'dispVec') \ 1896 ## and not hasattr(x.atom2, 'dispVec'),bondsBO) 1897 ## if len(withVec): 1898 ## map(lambda x: x.computeDispVectors(), bondsBO) 1899 1900 ## vertices = [] 1901 ## indices = [] 1902 ## col = [] 1903 ## i = 0 1904 ## realSet = AtomSet([]) 1905 ## ar = Numeric.array 1906 ## for b in bonds: 1907 ## bondOrder = b.bondOrder 1908 ## if bondOrder == 'aromatic' : bondOrder = 2 1909 ## if not bondOrder > 1: continue 1910 1911 ## at1 = b.atom1 1912 ## at2 = b.atom2 1913 ## if (not hasattr(at1, 'dispVec') \ 1914 ## and not hasattr(at2, 'dispVec')): 1915 ## continue 1916 ## realSet.append(at1) 1917 ## realSet.append(at2) 1918 1919 ## nc1 = ar(at1.coords) + \ 1920 ## ar(at1.dispVec) 1921 ## nc2 = ar(at2.coords) + \ 1922 ## ar(at2.dispVec) 1923 ## vertices.append(list(nc1)) 1924 ## vertices.append(list(nc2)) 1925 ## indices.append( (i, i+1) ) 1926 ## i = i+2 1927 ## gatoms['bondorder'] = realSet 1928 ## col = mol.geomContainer.getGeomColor('bondorder') 1929 ## ggeoms['bondorder'].Set( vertices=vertices, faces=indices, 1930 ## visible=1, lineWidth=lineWidth, 1931 ## materials=col, inheritMaterial=0, 1932 ## tagModified=False) 1933 ########################################################### 1934 1935 molecules, atomSets = self.getNodes(nodes) 1936 try: 1937 radii = molecules.allAtoms.radius 1938 except: 1939 self.vf.assignAtomsRadii(molecules, 1940 overwrite=False, 1941 united=False, 1942 topCommand=False) 1943 1944 if (cquality < 3) or (bquality < 3): 1945 nodeAtoms = nodes.findType(Atom) 1946 if cquality < 3: 1947 if len(nodeAtoms) < 500: 1948 cquality = 20 1949 elif len(nodeAtoms) < 5000: 1950 cquality = 15 1951 elif len(nodeAtoms) < 10000: 1952 cquality = 10 1953 else: 1954 cquality = 5 1955 if bquality < 3: 1956 if len(nodeAtoms) < 500: 1957 bquality = 20 1958 elif len(nodeAtoms) < 5000: 1959 bquality =