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

Source Code for Module Pmv.superimposeCommandsNew

   1  ############################################################################# 
   2  # 
   3  # Authors: 
   4  # Sophie I. COON, William LINDSTROM, Michel F. SANNER, Brian NORLEDGE 
   5  # 
   6  # Copyright: M. Sanner TSRI 2000 
   7  # 
   8  ############################################################################# 
   9  # 
  10  # $Header: /opt/cvs/python/packages/share1.5/Pmv/superimposeCommandsNew.py,v 1.9 2006/08/17 23:25:17 vareille Exp $ 
  11  # 
  12  # $Id: superimposeCommandsNew.py,v 1.9 2006/08/17 23:25:17 vareille Exp $ 
  13  # 
  14   
  15  import Numeric, os, Tkinter, Pmw 
  16   
  17  from Pmv.stringSelectorGUI import StringSelectorGUI 
  18  from Pmv.mvCommand import MVCommand, MVAtomICOM 
  19  from Pmv.guiTools import MoleculeChooser 
  20   
  21  from ViewerFramework.VFCommand import CommandGUI 
  22   
  23  from MolKit.molecule import Molecule, Atom, AtomSet 
  24  from MolKit.protein import Protein, Residue, Chain, ProteinSet, ResidueSet, ChainSet 
  25   
  26  from DejaVu.Spheres import Spheres 
  27  from DejaVu.IndexedPolylines import IndexedPolylines 
  28  from mglutil.alignmentEditor import AlignmentEditor 
  29   
  30   
  31  from mglutil.gui.InputForm.Tk.gui import InputFormDescr, InputForm 
  32  from mglutil.util.callback import CallBackFunction 
  33  from mglutil.gui.BasicWidgets.Tk.customizedWidgets import ListChooser 
  34  from mglutil.math.rigidFit import RigidfitBodyAligner 
  35  from SimpleDialog import SimpleDialog 
  36   
  37  from MolKit.tree import TreeNode, TreeNodeSet 
  38  from ViewerFramework.VF import EditAtomsEvent  
  39  from types import ListType, TupleType, StringType, IntType, FloatType, LongType 
  40   
  41   
42 -class SuperimposeCommand(MVCommand):
43 """ superimpose two equal-length AtomSets """ 44
45 - def onAddCmdToViewer(self):
46 self.rigidfitAligner = RigidfitBodyAligner()
47
48 - def doit(self, refAtoms, mobAtoms, updateGeom=True, showRMSD=True):
49 """ 50 The SuperImposeAtomsCommand takes two set of Atoms of the same length 51 compute the rotation and translation matrices to superimpose the 52 mobAtoms onto the refAtoms using rigidFit module and then transform the 53 corresponding geometry. 54 55 updateGeom = True : transform the masterGeom of mobAtoms. 56 showRMSD = True : print and return RMSD 57 """ 58 59 if refAtoms is None or mobAtoms is None: return 60 assert isinstance(refAtoms, TreeNodeSet) 61 assert isinstance(mobAtoms, TreeNodeSet) 62 63 refAtoms = refAtoms.findType(Atom) 64 mobAtoms = mobAtoms.findType(Atom) 65 # validate the inputs 66 if len(refAtoms) !=len(mobAtoms): 67 print "The two atomSet are not of equal length" 68 return 69 if len(refAtoms) < 3 : 70 print "At least three atoms are needed for superimposition" 71 return 72 73 refCoords = refAtoms.coords 74 mobCoords = mobAtoms.coords 75 76 rigidfitAligner = RigidfitBodyAligner() 77 rigidfitAligner.setRefCoords(refCoords) 78 rigidfitAligner.rigidFit(mobCoords) 79 80 if updateGeom: 81 rotMat = Numeric.identity(4).astype('d') 82 rotMat[:3,:3] = rigidfitAligner.rotationMatrix 83 transMat = Numeric.array(rigidfitAligner.translationMatrix) 84 rotMat[3,:3] = transMat 85 #print rotMat # the matrix 86 mGeom = mobAtoms[0].top.geomContainer.masterGeom 87 mGeom.SetRotation(Numeric.reshape(rotMat, (16,)).astype('f')) 88 mGeom.viewer.Redraw() 89 90 if showRMSD: 91 rmsd=rigidfitAligner.rmsdAfterSuperimposition(mobCoords) 92 print "RMSD = ", rmsd 93 return rmsd 94 else: 95 return
96 97
98 - def __call__(self, refAtoms, mobAtoms, updateGeom=True, showRMSD=True,**kw):
99 """ 100 None <- superimposeAtoms(refAtoms, mobAtoms,updateGeom=True, showRMSD=True, **kw) 101 """ 102 if type(refAtoms) is StringType: 103 self.nodeLogString = "'" + refAtoms +"'" 104 refAtoms = self.vf.expandNodes(refAtoms) 105 if type(mobAtoms) is StringType: 106 self.nodeLogString = "'" + mobAtoms +"'" 107 mobAtoms = self.vf.expandNodes(mobAtoms) 108 109 if not mobAtoms or not refAtoms: return 110 if not kw.has_key('redraw'): kw['redraw'] = 1 111 res=apply(self.doitWrapper, (refAtoms, mobAtoms, updateGeom, showRMSD), kw) 112 return res
113 114
115 -class TransformAtomsCommand(MVCommand):
116 """ This command transforms an AtomSet object by a given matrix, without changing the coords 117 """ 118
119 - def doit(self, mat, mobAtoms):
120 """ 121 mat: tranformation matrix, in (4,4) Numeric array 122 mobAtoms: AtomSet where the matrix is applied to """ 123 124 # fixme: need checking for mat (matrix) and mobAtoms 125 sh=mat.shape 126 if sh!=(4,4) and sh !=(16,): 127 print "Need a 4x4 matrix or flatted (16,) list" 128 return 129 130 mGeom = mobAtoms[0].top.geomContainer.masterGeom 131 132 if sh ==(4,4): 133 mGeom.SetRotation(Numeric.reshape(mat, (16,)).astype('f')) 134 else: 135 mGeom.SetRotation( mat ) 136 137 mGeom.viewer.Redraw() 138 return
139 140
141 - def __call__(self, mat, nodes, **kw):
142 """ 143 None <- transformAtoms(mat, nodes, **kw) 144 """ 145 146 if type(nodes) is StringType: 147 self.nodeLogString = "'" + nodes +"'" 148 nodes = self.vf.expandNodes(nodes) 149 if not nodes: return 150 151 if not kw.has_key('redraw'): kw['redraw'] = 1 152 apply(self.doitWrapper, (mat, nodes), kw)
153 154 155 156
157 -class FreezeAtomsCommand(MVCommand):
158 """ Freeze the Atoms, store the coordinates as shown in masterGeom """ 159
160 - def doit(self,mobAtoms):
161 """ 162 mobAtoms: AtomSet that is being frozen. 163 Assuming the AtomSet are from same molecule 164 """ 165 166 # fixme: need checking for mat (matrix) and mobAtoms 167 geomContainer = mobAtoms[0].top.geomContainer 168 mGeom = geomContainer.masterGeom 169 mat = mGeom.rotation 170 mat = Numeric.reshape(mat, (4,4)) 171 172 # update coords 173 mobAtoms = mobAtoms.findType(Atom) 174 coords = mobAtoms.coords 175 hCoords = Numeric.concatenate((coords,Numeric.ones((len(coords),1),\ 176 'd')), 1) 177 tCoords = Numeric.matrixmultiply(hCoords, mat)[:,:3] 178 tCoords = tCoords.tolist() 179 mobAtoms.updateCoords(tCoords, 0) # overwritten the original coords 180 181 # reset the rotation matrix of masterGeom 182 identity = Numeric.identity(4,'f').flat 183 mGeom.SetRotation(Numeric.identity(4,'f').flat ) 184 185 event = EditAtomsEvent('coords', mobAtoms) 186 self.vf.dispatchEvent(event) 187 188 mGeom.viewer.Redraw() 189 190 return
191 192
193 - def __call__(self, nodes, **kw):
194 """ 195 None <- transformAtoms(mat, nodes, **kw) 196 """ 197 if type(nodes) is StringType: 198 self.nodeLogString = "'" + nodes +"'" 199 nodes = self.vf.expandNodes(nodes) 200 if not nodes: return 201 202 if not kw.has_key('redraw'): kw['redraw'] = 1 203 apply(self.doitWrapper, (nodes, ), kw)
204 205 206 207
208 -class SuperimposeAtomsCommand(MVCommand):
209
210 - def onAddCmdToViewer(self):
211 self.rigidfitAligner = RigidfitBodyAligner()
212
213 - def doit(self, refAtoms, mobAtoms):
214 """ 215 The SuperImposeAtomsCommand takes two set of Atoms of the same length 216 compute the rotation and translation matrices to superimpose the 217 mobAtoms onto the refAtoms using rigidFit module and then transform the 218 corresponding geometry. 219 """ 220 221 refCoords = refAtoms.coords 222 mobCoords = mobAtoms.coords 223 224 self.rigidfitAligner.setRefCoords(refCoords) 225 226 # Nothing can be done if the two sets of coords are not of the same 227 # size 228 if not len(refCoords) == len(mobCoords): 229 print " ERROR: Cannot perform the superimposition because the 2 \ 230 mv.lsets of Atoms are not of the same length" 231 return 232 233 # Get the rotation and the translation ysing mglutil.math.rigidFit 234 self.rigidfitAligner.rigidFit(mobCoords) 235 #rotation, translation= rigidFit.rigid_fit( refCoords, inCoords) 236 rotMat = Numeric.identity(4).astype('d') 237 rotMat[:3,:3] = self.rigidfitAligner.rotationMatrix 238 239 transMat = Numeric.array(self.rigidfitAligner.translationMatrix) 240 241 # transform the geometry representing the atoms only if a gui has been 242 # created: 243 if not self.vf.hasGui: 244 return 245 246 # build the geometry name: 247 mobMol = mobAtoms.top.uniq()[0] 248 mob = mobMol.geomContainer.masterGeom 249 #gName = 'root|'+ mobMol[0].name 250 vi = self.vf.GUI.VIEWER 251 252 oldCurrent = vi.currentObject 253 vi.SetCurrentObject(mob) 254 255 # transform only the given geometry. 256 if vi.redirectTransformToRoot == 1: 257 old = vi.redirectTransformToRoot 258 vi.TransformRootOnly(0) 259 else: 260 old = 0 261 262 263 # apply the rotation to the masterGeom of the inMol 264 mob.SetRotation(Numeric.reshape(rotMat, (16,))) 265 # apply the translation to the masterGeom of the inMol 266 mob.SetTranslation(transMat) 267 268 269 ## refMol = refAtoms.top.uniq()[0] 270 ## refmg = refMol.geomContainer.masterGeom 271 272 ## refmg = refAtoms.top.uniq()[0].geomContainer.masterGeom 273 ## mat = refmg.GetMatrix(refmg) 274 ## tmat = Numeric.transpose(mat) 275 276 ## rot, trans, scale = refmg.Decompose4x4(Numeric.reshape(tmat, (16,))) 277 ## rot_1 = refmg.rotation 278 ## trans_1 = refmg.translation 279 ## print 'rot',rot 280 ## print 'trans',trans 281 ## print 'rot_1',rot_1 282 ## print 'trans_1',trans_1 283 284 ## mobPivot = list(mob.pivot) 285 ## mobPivot.append(1.) 286 ## transfo = Numeric.identity(4).astype('d') 287 ## transfo[:3,:3] = rotMat[:3,:3] 288 ## transfo[3, :3] = transMat 289 ## hc = Numeric.array(mobPivot) 290 ## tPivot = Numeric.matrixmultiply(hc, transfo) 291 ## print tPivot[:3] 292 ## mob.SetPivot(tPivot[:3]) 293 294 #self.vf.centerOnNodes(refMol) 295 #mob.ConcatRotationRelative(Numeric.reshape(rot, (16,))) 296 #mob.ConcatTranslation(trans_1) 297 298 if old == 1: 299 vi.TransformRootOnly(1) 300 vi.SetCurrentObject(oldCurrent)
301 302 # Not sure to put that here ? 303 # Need to concatenate with the transformation of the reference molecule 304 # to have the two molecule aligned: 305 # - Get the transformatiom matrix of the ref molecule and decompose it 306 307 ## refmg = refAtoms.top.uniq()[0].geomContainer.masterGeom 308 ## mat = refmg.GetMatrix(refmg) 309 ## tmat = Numeric.transpose(mat) 310 311 ## rot, trans, scale = refmg.Decompose4x4(Numeric.reshape(tmat, (16,))) 312 313 ## self.vf.transformObject('rot', gName, rot) 314 ## self.vf.transformObject('tra', gName, trans) 315 ## #self.vf.transformObject('sca', gName, scale) 316 317
318 - def __call__(self, refAtoms, mobAtoms, **kw):
319 """ 320 None <- superimposeAtoms(refAtoms, mobAtoms, **kw) 321 """ 322 if not kw.has_key('redraw'): kw['redraw'] = 1 323 apply(self.doitWrapper, (refAtoms, mobAtoms), kw)
324 325 326 #class SuperimposeAtomsGUICommand(MVCommand, MVAtomICOM):
327 -class SuperimposeAtomsGUICommand(SuperimposeCommand, MVAtomICOM):
328 """ 329 330 The SuperimposeAtomsGUICommand provides a GUI interface to the 331 SuperimposeAtomsCommand. This commands allows the user to create two sets 332 of atoms one reference and mobile of the same length by picking, 333 by string or using the alignment editor. 334 These two sets are then fed to the SuperimposeAtoms command. 335 336 - For now Only two 2 sets of Atoms belonging to a ref molecule and 337 a mobile molecule can be superimposed simultaneously. 338 339 - The command provides two way of defining those two sets of atoms: 340 * By picking nodes 341 * By string: 342 * Using the alignment editor 343 """ 344 # The superimposeAtomsGC provides an GU interface to allow the user to create two sets of atoms 345 # which will be used to do a pairwise superimposition.
346 - def __init__(self, func=None):
347 MVCommand.__init__(self, func) 348 MVAtomICOM.__init__(self) 349 self.refAtomList = [] 350 self.inAtomList = [] 351 #self.superImposedPairs = {} 352 self.newPairs = {} 353 self.pair = [] 354 self.mobMol = None 355 self.refMol = None 356 self.refNodes = {} 357 self.mobNodes = {} 358 self.filters = {'CA Atoms':lambda x: x.name == 'CA', 359 'Backbone Atoms': lambda x: x.name in ['CA', 'C', 360 'N', 'O', 361 'CA@A','C@A', 362 'N@A','O@A'], 363 'Heavy Atoms': lambda x: not x.element == 'H', 364 'All Atoms': None} 365 self.defaultFilter = 'Backbone Atoms'
366 367 368 ## def doit(self, refAtoms, mobAtoms, updateGeom=True, showRMSD=True): 369 ## """same as in SuperimposeCommand """ 370 ## SuperimposeCommand.doit(self, refAtoms, mobAtoms, updateGeom=True, showRMSD=True) 371 372
373 - def onAddCmdToViewer(self):
374 # Check first is any of the command that superimpose depends on are 375 # already loaded. 376 if not self.vf.commands.has_key('setICOM'): 377 self.vf.loadCommand('interactiveCommands', 'setICOM', 'Pmv', 378 topCommand = 0) 379 if not self.vf.commands.has_key('superimposeAtoms'): 380 self.vf.loadCommand('superImposeCommands', 'superimposeAtoms', 381 'Pmv', topCommand = 0) 382 383 if not self.vf.commands.has_key('startContinuousPicking'): 384 self.vf.loadCommand('dejaVuCommands','startContinuousPicking', 385 'ViewerFramework', topCommand = 0) 386 387 if not self.vf.commands.has_key('stopContinuousPicking'): 388 self.vf.loadCommand('dejaVuCommands','stopContinuousPicking', 389 'ViewerFramework', topCommand = 0) 390 if not self.vf.commands.has_key('labelByExpression'): 391 self.vf.loadCommand('labelCommands', 'labelByExpression', 'Pmv', 392 topCommand = 0) 393 394 self.sphere1 = Spheres(name='elt1', radii=0.5, vertices = [], 395 materials = ( (0.,1.,0.),), protected=True) 396 self.sphere2 = Spheres(name = 'elt2', radii=0.5, vertices =[], 397 materials = ( (1.,1.,0.),), protected=True)
398 399
400 - def onRemoveObjectFromViewer(self,obj):
401 if hasattr(self.vf,'alignment'): 402 self.vf.alnEditor.deleteSequence(obj.name) 403 self.vf.alnEditor.redraw() 404 if obj.name == self.refMol: 405 self.refMol=None 406 if obj.name == self.mobMol: 407 self.mobMol=None
408 409 410 ########################################################################## 411 #### BY PICKING... 412 ##########################################################################
413 - def initICOM(self, modifier):
414 # set the callback of continuousPicking to label the picked node 415 # 1- get a handle on the cbManager 416 cbManager = self.vf.startContinuousPicking.cbManager 417 # 2- Save the existing callbacks 418 #self.oldCallBacks = cbManager.callbacks 419 # 3- Set to the new callback 420 cbManager.SetCallback(CallBackFunction(self.labelByName)) 421 422 self.vf.startContinuousPicking() 423 self.supcb = 0
424
425 - def labelByName(self, pick):
426 # Continuous labeling. 427 if pick is None: return 428 atom = self.vf.findPickedAtoms(pick) 429 if atom: 430 level = self.vf.ICmdCaller.level.value 431 self.vf.ICmdCaller.level.AddCallback(self.unlabelLevel) 432 if level == Molecule : level = Protein 433 self.node = atom.findType(level) 434 funcItems = map(lambda x: x.full_name(), self.node) 435 self.vf.labelByExpression(self.node, 436 font = 'arial1.glf', 437 location = 'First', 438 textcolor = 'red', only = 0, 439 lambdaFunc = 1,negate=0, 440 function = 'lambda x: str(x.full_name())\n\n', 441 topCommand=0)
442
443 - def unlabelLevel(self, newLevel, oldLevel):
444 if not hasattr(self, 'node'): return 445 446 if oldLevel == Molecule: oldLevel = Protein 447 # need to be at the former level for all the former picked stuff 448 # so take it all. 449 node = self.vf.getSelection() 450 nodes = node.findType(oldLevel) 451 # Careful in labelByProperty fix a bug if no label should not break! 452 self.vf.labelByExpression(nodes, negate=1, log=0)
453
454 - def stopICOM(self):
455 # Destroy the inputForm 456 #self.cmdForms['superimpose'].root.destroy() 457 # Set the form to None. 458 #del self.cmdForms['superimpose'] 459 460 # Set back the continuousPicking to unsolicitedPick 461 cbManager = self.vf.startContinuousPicking.cbManager 462 if not len(self.oldCallBacks) == 0: 463 cbManager.SetCallback(self.oldCallBacks[0]) 464 if len(self.oldCallBacks)>1: 465 for cb in self.oldCallBacks[1:]: 466 cbManager.AddCallBack(cb) 467 468 # Remove the unlabel callback bound to the self.vf.ICmdCaller.level 469 if self.unlabelLevel in self.vf.ICmdCaller.level.callbacks: 470 self.vf.ICmdCaller.level.RemoveCallback(self.unlabelLevel) 471 472 # Unlabel whatever is labeled 473 level = self.vf.ICmdCaller.level.value 474 475 nodes = self.vf.getSelection().findType(level) 476 if not nodes is None or len(nodes)!=0: 477 self.vf.labelByExpression(nodes, negate=1, log=0) 478 479 # Stop the continuous picking. 480 self.vf.stopContinuousPicking() 481 482 self.sphere1.Set(vertices=[]) 483 self.sphere2.Set(vertices=[])
484 ## self.visualFeedBack(vertices =[]) 485 486 ########################################################################## 487 #### 488 ##########################################################################
489 - def createNodesSets(self, refnodes=None, mobnodes=None):
490 # Set the reference molecule and the mobile molecule.... 491 # 1- set the reference molecule and the mobile 492 from MolKit.protein import ProteinSet 493 if not self.refMol and refnodes: 494 refMols = refnodes.top.uniq() 495 if len(refMols) > 1: 496 self.warningMsg("Can only have one reference molecule.") 497 return 498 self.refMol = refMols[0] 499 500 if not self.mobMol and mobnodes: 501 mobMols = mobnodes.top.uniq() 502 if len(mobMols) > 1: 503 self.warningMsg("Can only have one mobile molecule.") 504 return 505 if mobMols[0] == self.refMol: 506 self.warningMsg("The mobile molecule must be different from the ref molecule") 507 return 508 self.mobMol = mobMols[0] 509 510 # 2- Create the entries for the refNodes listChooser 511 ebn = self.cmdForms['addPairs'].descr.entryByName 512 if refnodes: 513 reflc = ebn['refnodes']['widget'] 514 for rn in refnodes: 515 if not rn.top == self.refMol: continue 516 self.refNodes[rn.full_name()] = rn 517 reflc.add((rn.full_name(), None)) 518 519 # Create the entries for the mobNodes listChooser 520 if mobnodes: 521 moblc = ebn['mobnodes']['widget'] 522 for mn in mobnodes: 523 if not mn.top == self.mobMol: continue 524 self.mobNodes[mn.full_name()] = mn 525 moblc.add((mn.full_name(), None))
526 527
528 - def createPairs(self, refnames, mobnames, slice, choice):
529 # This is where the atom pairs are created 530 # Get the ref atom set 531 refAtms = AtomSet([]) 532 mobAtms = AtomSet([]) 533 for name in refnames: 534 refnod = self.refNodes[name] 535 atms = refnod.findType(Atom) 536 refAtms = refAtms + atms 537 538 for name in mobnames: 539 mobnod = self.mobNodes[name] 540 atms = mobnod.findType(Atom) 541 mobAtms = mobAtms + atms 542 # Now apply the filters to the sets 543 if choice: 544 refFiltAtms = refAtms.get(self.filters[choice]) 545 mobFiltAtms = mobAtms.get(self.filters[choice]) 546 if not len(refFiltAtms) == len(mobFiltAtms): 547 #print 'slicing', slice 548 self.warningMsg("the two sets of atoms needs to be of the same length") 549 return 550 ebn = self.cmdForms['pairs'].descr.entryByName 551 lc = ebn['newpairs']['widget'] 552 for refatm, mobatm in map(None, refFiltAtms, mobFiltAtms): 553 #self.pairs.append((refatm, mobatm)) 554 pairName = refatm.full_name() + '---' + mobatm.full_name() 555 self.newPairs[pairName]=(refatm,mobatm) 556 lc.add((pairName, None))
557 558 559 ########################################################################## 560 #### GUI CALLBACKS 561 ##########################################################################
562 - def pick_cb(self):
563 ebn = self.cmdForms['addPairs'].descr.entryByName 564 cbVar = int(ebn['pick']['variable'].get()) 565 if cbVar: 566 self.vf.setICOM(self, topCommand=0) 567 else: 568 self.stopICOM()
569
570 - def string_cb(self):
571 ebn = self.cmdForms['addPairs'].descr.entryByName 572 cbVar = ebn['string']['variable'] 573 #print cbVar.get() 574 if cbVar.get(): 575 # if pushed show the form 576 val= self.showForm('editString',modal=1, blocking=0) 577 cbVar.set(0) 578 if val: 579 if not val['srefNodes'] and not val['smobNodes']: return 580 refnodes = val['srefNodes'] 581 if refnodes: 582 refnodes.sort() 583 mobnodes = val['smobNodes'] 584 if mobnodes: mobnodes.sort() 585 self.createNodesSets(refnodes,mobnodes)
586
587 - def setDefault(self, text):
588 pass
589 ## self.defaultFilter = text 590 ## if hasattr(self, 'pair') and len(self.pair) == 2: 591 ## filter = self.filters[text] 592 ## set1 = self.pair[0] 593 ## set2 = self.pair[1] 594 595 ## if filter: 596 ## set1 = set1.get(filter) 597 ## set2 = set2.get(filter) 598 ## if (set1 and set2) and (len(set1) == len(set2)): 599 ## self.updateChooser(set1, set2)): 600
601 - def delete_cb(self):
602 ebn = self.cmdForms['pairs'].descr.entryByName 603 lc = ebn['newpairs']['widget'] 604 lc.clear() 605 self.newPairs ={} 606 return
607 608
609 - def dismiss_cb(self):
610 if self.cmdForms.has_key('pairs'):self.cmdForms['pairs'].withdraw() 611 if self.cmdForms.has_key('addPairs'): 612 self.cmdForms['addPairs'].withdraw() 613 if self.cmdForms.has_key('editString'): 614 self.cmdForms['addPairs'].withdraw()
615 # Dismiss all the forms ??? 616 ## for v in self.cmdForms.values(): 617 ## v.withdraw() 618
619 - def continuous_cb(self):
620 # Sets the continuous flag to the right value ???? 621 pass
622
623 - def reset_cb(self):
624 # Reset the superposition put back the mob molecule to the right place.. 625 pass
626 - def superimpose_cb(self):
627 refAtoms = AtomSet() 628 mobAtoms = AtomSet() 629 for pair in self.newPairs.values(): 630 refAtoms.append(pair[0]) 631 mobAtoms.append(pair[1]) 632 633 apply( self.doitWrapper, (refAtoms,mobAtoms), {} )
634 635
636 - def add_cb(self):
637 val = self.showForm('addPairs', modal=1, blocking=0, 638 okCfg={'text':'Create Pairs'}) 639 # need to get all the nodes... from each listchooser 640 if not val: return 641 # Need this for the order of the nodes in the pairs... 642 ebn = self.cmdForms['addPairs'].descr.entryByName 643 reflc = ebn['refnodes']['widget'] 644 refnames = map(lambda x: x[0], reflc.entries) 645 moblc = ebn['mobnodes']['widget'] 646 mobnames = map(lambda x: x[0], moblc.entries) 647 self.createPairs(refnames, mobnames, val['slice'][0], val['choice'][0])
648
649 - def refremove_cb(self):
650 ebn = self.cmdForms['addPairs'].descr.entryByName 651 lc = ebn['refnodes']['widget'] 652 sel = lc.get() 653 if sel: 654 lc.remove(sel[0]) 655 del self.refNodes[sel[0]]
656
657 - def mobremove_cb(self):
658 ebn = self.cmdForms['addPairs'].descr.entryByName 659 lc = ebn['mobnodes']['widget'] 660 sel = lc.get() 661 if sel: 662 lc.remove(sel[0]) 663 del self.mobNodes[sel[0]]
664 - def refmoveup_cb(self):
665 ebn = self.cmdForms['addPairs'].descr.entryByName 666 lc = ebn['refnodes']['widget'] 667 sel = lc.get() 668 if not sel: return 669 sel = sel[0] 670 selIndex = lc.entries.index((sel,None)) 671 if selIndex == 0: return 672 lc.remove(sel) 673 lc.insert(selIndex-1, sel) 674 lc.select(sel)
675
676 - def mobmoveup_cb(self):
677 ebn = self.cmdForms['addPairs'].descr.entryByName 678 lc = ebn['mobnodes']['widget'] 679 sel = lc.get() 680 if not sel: return 681 sel = sel[0] 682 selIndex = lc.entries.index((sel,None)) 683 if selIndex == 0: return 684 lc.remove(sel) 685 lc.insert(selIndex-1, sel) 686 lc.select(sel)
687
688 - def refmovedown_cb(self):
689 ebn = self.cmdForms['addPairs'].descr.entryByName 690 lc = ebn['refnodes']['widget'] 691 sel = lc.get() 692 if not sel: return 693 sel = sel[0] 694 selIndex = lc.entries.index((sel,None)) 695 if selIndex == len(lc.entries)-1: return 696 lc.remove(sel) 697 lc.insert(selIndex+1, sel) 698 lc.select(sel)
699
700 - def mobmovedown_cb(self):
701 ebn = self.cmdForms['addPairs'].descr.entryByName 702 lc = ebn['mobnodes']['widget'] 703 sel = lc.get() 704 if not sel: return 705 sel = sel[0] 706 selIndex = lc.entries.index((sel,None)) 707 if selIndex == len(lc.entries)-1: return 708 lc.remove(sel) 709 lc.insert(selIndex+1, sel) 710 lc.select(sel)
711 712
713 - def guiCallback(self):
714 #form = self.showForm('pairs', modal=0, blocking=0) 715 val = self.showForm('pairs', modal=0, blocking=0)
716 717
718 - def buildFormDescr(self, formName):
719 if formName=='addPairs': 720 # CREATE PAIRS GROUP 721 idf = InputFormDescr(title="Superimpose") 722 idf.append({'name':"mode", 723 'widgetType':Pmw.Group, 724 'container':{'mode':'w.interior()'}, 725 'wcfg':{'tag_text':"Create Reference Nodes and Mobile Nodes Lists"}, 726 'gridcfg':{'sticky':'wnse'} 727 }) 728 idf.append({'widgetType':Tkinter.Label, 729 'parent':'mode', 730 'wcfg':{'text':'By String'}, 731 'gridcfg':{'sticky':'we'}} 732 ) 733 idf.append({'widgetType':Tkinter.Checkbutton, 734 'name':'string', 735 'parent':'mode', 736 #'tooltip':'Use the string selector to create refnode-mobnodes pairs', 737 'wcfg':{'text':'on/off','command':self.string_cb}, 738 'gridcfg':{'sticky':'we','row':-1}}) 739 740 idf.append({'widgetType':Tkinter.Label, 741 'parent':'mode', 742 'wcfg':{'text':'By Picking'}, 743 'gridcfg':{'sticky':'we', 'row':-1}} 744 ) 745 746 idf.append({'widgetType':Tkinter.Checkbutton, 747 'name':'pick', 748 'tooltip':'Use the picking event to create refnode-mobnodes pairs', 749 'parent':'mode', 750 'wcfg':{'text':'on/off','command':self.pick_cb}, 751 'gridcfg':{'sticky':'we','row':-1}}) 752 753 754 ############################################################### 755 ## EDIT REF/MOB NODES 756 ############################################################### 757 idf.append({'name':"editnodes", 758 'widgetType':Pmw.Group, 759 'container':{'editnodes':'w.interior()'}, 760 'wcfg':{'tag_text':"Edit Reference Nodes and Mobile Nodes Lists:"}, 761 'gridcfg':{'sticky':'wnse'} 762 }) 763 764 idf.append({'name':'refremove', 765 'parent':'editnodes', 766 'widgetType':Tkinter.Button, 767 'tooltip':""" Remove the selected entry from the 768 commands to be applied to the object when loaded in the application""", 769 'wcfg':{'text':'REMOVE','width':10, 770 'command':self.refremove_cb}, 771 'gridcfg':{'sticky':'we', 'row':0, 'column':0}}) 772 773 idf.append({'name':'refoneup', 774 'parent':'editnodes', 775 'widgetType':Tkinter.Button, 776 'tooltip':"""Move the selected entry up one entry""", 777 'wcfg':{'text':'Move up','width':10, 778 'command':self.refmoveup_cb}, 779 'gridcfg':{'sticky':'we', 'row':1, 'column':0}}) 780 781 idf.append({'name':'refonedown', 782 'parent':'editnodes', 783 'widgetType':Tkinter.Button, 784 'tooltip':"""Move the selected entry down one entry""", 785 'wcfg':{'text':'Move down','width':10, 786 'command':self.refmovedown_cb}, 787 'gridcfg':{'sticky':'we', 'row':2, 'column':0}}) 788 789 790 791 # RefNodes listchooser 792 idf.append({'widgetType':ListChooser, 793 'name':'refnodes', 794 'parent':'editnodes', 795 'tooltip':"""list of the reference nodes""", 796 'wcfg':{'entries':[], 797 'mode':'single', 798 'lbwcfg':{'exportselection':0}, 799 'title':'Reference Nodes'}, 800 'gridcfg':{'sticky':'we', 801 'row':0, 'column':1,'rowspan':3}}) 802 803 804 # MobNodes listchooser 805 idf.append({'widgetType':ListChooser, 806 'name':'mobnodes', 807 'parent':'editnodes', 808 'tooltip':"""list of the mobile nodes""", 809 'wcfg':{'entries':[], 810 'mode':'single', 811 'lbwcfg':{'exportselection':0}, 812 'title':'Mobile Nodes'}, 813 'gridcfg':{'sticky':'we', 814 'row':0, 'column':2, 'rowspan':3}}) 815 816 817 idf.append({'name':'mobremove', 818 'parent':'editnodes', 819 'widgetType':Tkinter.Button, 820 'tooltip':""" Remove the selected mobile node""", 821 'wcfg':{'text':'REMOVE','width':10, 822 'command':self.mobremove_cb}, 823 'gridcfg':{'sticky':'we','row':0, 'column':3}}) 824 825 idf.append({'name':'moboneup', 826 'parent':'editnodes', 827 'widgetType':Tkinter.Button, 828 'tooltip':"""Move the selected entry up one entry""", 829 'wcfg':{'text':'Move up','width':10, 830 'command':self.mobmoveup_cb}, 831 'gridcfg':{'sticky':'we','row':1, 'column':3}}) 832 833 idf.append({'name':'mobonedown', 834 'parent':'editnodes', 835 'widgetType':Tkinter.Button, 836 'tooltip':"""Move the selected entry down one entry""", 837 'wcfg':{'text':'Move down','width':10, 838 'command':self.mobmovedown_cb}, 839 'gridcfg':{'sticky':'we','row':2, 'column':3}}) 840 841 ############################################################### 842 ## FILTERS 843 ############################################################### 844 845 idf.append({'name':"filter", 846 'widgetType':Pmw.Group, 847 'container':{'filters':'w.interior()'}, 848 'wcfg':{'tag_text':"Apply Filters To The Ref/Mob nodes lists:"}, 849 'gridcfg':{'sticky':'wnse'} 850 }) 851 852 idf.append({'widgetType':Pmw.ComboBox, 853 'name':'choice', 854 'parent':'filters', 855 'tooltip':"""This filter allows the user to choose 856 which atom to consider from the ref node or mob nodes sets to create the atom pairs""", 857 'defaultValue':self.defaultFilter, 858 'wcfg':{ 'scrolledlist_items': self.filters.keys(), 859 'selectioncommand':self.setDefault}, 860 'gridcfg':{'sticky':'w'}}) 861 862 863 # If sets not of the same length: 864 idf.append({'widgetType':Pmw.ComboBox, 865 'name':'slice', 866 'parent':'filters', 867 'defaultValue':'Beginning', 868 'tooltip':"""When the two sets of atoms are not of 869 the same length the user can chose what subset of the longest set to take, 870 beginning, the end or half and half""", 871 'wcfg':{'scrolledlist_items':['Beginning', 872 'End', 873 'Half/Half'], 874 }, 875 'gridcfg':{'sticky':'w', 'row':-1}}) 876 877 878 return idf 879 880 elif formName == 'pairs': 881 idf = InputFormDescr(title="Pairwise Superimposition") 882 883 884 # EDIT PAIRS GROUP 885 idf.append({'name':"edit", 886 'widgetType':Pmw.Group, 887 'container':{'edit':'w.interior()'}, 888 'wcfg':{'tag_text':"Edit Atom Pairs"}, 889 'gridcfg':{'sticky':'wnse'} 890 }) 891 892 893 entries = map(lambda x: (x, None), self.newPairs.keys()) 894 idf.append({'widgetType':ListChooser, 895 'name':'newpairs', 896 'parent':'edit', 897 'wcfg':{'mode':'extended', 898 'entries':entries, 899 'lbwcfg':{'exportselection':1}, 900 'title':'Reference Atoms -- Mobile Atoms'}, 901 'gridcfg':{'sticky':'wens', 'columnspan':2}}) 902 903 904 idf.append({'widgetType':Tkinter.Button, 905 'name': 'delete', 906 'parent':'edit', 907 'wcfg':{'width':15,'text': 'Add Pairs', 908 'command':self.add_cb}, 909 'gridcfg':{'sticky':'we'}}) 910 911 idf.append({'widgetType':Tkinter.Button, 912 'name': 'delete', 913 'parent':'edit', 914 'wcfg':{'width':15,'text': 'Delete Pairs', 915 'command':self.delete_cb}, 916 'gridcfg':{'sticky':'we', 'row':-1}}) 917 918 idf.append({'name':"superimpose", 919 'widgetType':Pmw.Group, 920 'container':{'superimpose':'w.interior()'}, 921 'wcfg':{'tag_text':"Superimposation parameters"}, 922 'gridcfg':{'sticky':'wnse'} 923 }) 924 # Continuous Superimposition 925 idf.append({'widgetType':Tkinter.Checkbutton, 926 'name':'continuous', 927 'parent':'superimpose', 928 'wcfg':{'variable':Tkinter.IntVar(), 929 'text':'Continuous', 930 'command':self.continuous_cb, 931 'padx':10,'pady':10}, 932 'gridcfg':{'sticky':'w'}}) 933 934 935 # Reset & SuperImpose button. 936 idf.append({'widgetType':Tkinter.Button, 937 'name':'final', 938 'parent':'superimpose', 939 'wcfg':{'width':15,'text':'Superimpose', 940 'command':self.superimpose_cb}, 941 'gridcfg':{'sticky':'we', 'row':-1}}) 942 943 idf.append({'widgetType':Tkinter.Button, 944 'parent':'superimpose', 945 'name':'reset', 946 'wcfg':{'text':'Reset', 'command':self.reset_cb}, 947 'gridcfg':{'sticky':'we', 'row':-1}}) 948 949 950 idf.append({'widgetType':Tkinter.Button, 951 'name': 'dismiss', 952 'wcfg':{'text': 'DISMISS', 953 'command':self.dismiss_cb}, 954 'gridcfg':{'sticky':'we', 'columnspan':2}}) 955 956 957 return idf 958 959 elif formName == 'editString': 960 961 idf = InputFormDescr(title = 'Get Nodes From String') 962 963 idf.append({'name':"refgroup", 964 'widgetType':Pmw.Group, 965 'container':{'refgroup':'w.interior()'}, 966 'wcfg':{'tag_text':"Reference Nodes:"}, 967 'gridcfg':{'sticky':'wnse'} 968 }) 969 970 idf.append({'name':"mobgroup", 971 'widgetType':Pmw.Group, 972 'container':{'mobgroup':'w.interior()'}, 973 'wcfg':{'tag_text':"Mobile Nodes:"}, 974 'gridcfg':{'sticky':'wnse', 'row':-1} 975 }) 976 977 978 idf.append({ 'widgetType':StringSelectorGUI, 979 'parent':'refgroup', 980 'name':'srefNodes', 981 #'defaultValue':self.vf.Mols[0].name+", , , ", 982 'tooltip':'Please select the reference nodes set. By default the ref nodes will be the first molecule loaded in the viewer', 983 'wcfg':{ 'molSet': self.vf.Mols, 984 'vf': self.vf, 985 'all':1, 986 'crColor':(1.,0.,0.), 987 'forceEmpty':1, 988 }, 989 'gridcfg':{'sticky':'we' }}) 990 991 idf.append({ 'widgetType':StringSelectorGUI, 992 'parent':'mobgroup', 993 #'defaultValue':self.vf.Mols[1].name+", , , ", 994 'tooltip':'Please select the mobile nodes set. By default the mobile nodes will be the second molecule loaded in the viewer', 995 'name':'smobNodes', 996 'wcfg':{ 'molSet': self.vf.Mols, 997 'vf': self.vf, 998 'all':1, 999 'crColor':(0.,0.,1.),'forceEmpty':1, 1000 }, 1001 'gridcfg':{'row':-1, 'sticky':'we' }}) 1002 return idf
1003 1004 SuperimposeAtomsCommandGUI = CommandGUI() 1005 ## SuperimposeAtomsGUICommandGUI.addMenuCommand('menuRoot', 'Compute', 1006 ## 'superimpose Atom Pairs', 1007 ## cascadeName = "Superimpose") 1008 SuperimposeAtomsCommandGUI.addMenuCommand('menuRoot', 'Compute', 1009 'superimpose Atom Pairs') 1010 1011 1012 commandList = [ 1013 {'name':'superimposeAtoms', 'cmd':SuperimposeAtomsCommand(), 1014 'gui':None}, 1015 ## {'name':'superimposeAtomsGC2', 'cmd':SuperimposeAtomsGUICommand(), 1016 ## 'gui':SuperimposeAtomsCommandGUI}, 1017 {'name':'superimposeGUI', 'cmd':SuperimposeAtomsGUICommand(), 1018 'gui':SuperimposeAtomsCommandGUI}, 1019 1020 {'name':'superimpose', 'cmd':SuperimposeCommand(), 1021 'gui':None}, 1022 1023 {'name':'transformAtoms', 'cmd':TransformAtomsCommand(), 1024 'gui':None}, 1025 {'name':'freezeAtoms', 'cmd':FreezeAtomsCommand(), 1026 'gui':None}, 1027 1028 1029 ] 1030
1031 -def initModule(viewer):
1032 for dict in commandList: 1033 viewer.addCommand(dict['cmd'], dict['name'], dict['gui'])
1034