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

Source Code for Module Pmv.sdCommands

   1  ######################################################################## 
   2  # 
   3  # Date: July 2002 Authors: Michel Sanner 
   4  # 
   5  #    sanner@scripps.edu 
   6  # 
   7  #       The Scripps Research Institute (TSRI) 
   8  #       Molecular Graphics Lab 
   9  #       La Jolla, CA 92037, USA 
  10  # 
  11  # Copyright: Michel Sanner and TSRI 
  12  # 
  13  # revision: Guillaume Vareille 
  14  # 
  15  ######################################################################### 
  16  # 
  17  # $Header: /opt/cvs/python/packages/share1.5/Pmv/sdCommands.py,v 1.74.2.1 2007/07/25 20:19:02 vareille Exp $ 
  18  # 
  19  # $Id: sdCommands.py,v 1.74.2.1 2007/07/25 20:19:02 vareille Exp $ 
  20  # 
  21   
  22  import Pmv  
  23  import Pmw 
  24  import Tkinter 
  25  import Numeric ; N = Numeric 
  26  import string 
  27  import types 
  28  import os 
  29  import tkMessageBox 
  30  from DejaVu.IndexedPolygons import IndexedPolygons 
  31  from Pmv.displayCommands import DisplayCommand 
  32  from Pmv.mvCommand import MVCommand 
  33  from mglutil.gui.InputForm.Tk.gui import InputFormDescr, CallBackFunction 
  34  from ViewerFramework.VFCommand import Command, ICOM, CommandGUI 
  35  from ViewerFramework.VF import ViewerFramework 
  36  from MolKit.molecule import Atom,AtomSet 
  37  from MolKit.protein import Residue 
  38  from opengltk.OpenGL import GL 
  39  from Pmv.colorCommands import ColorCommand 
  40  from DejaVu.colorMap import ColorMap 
  41  from DejaVu.ColormapGui import ColorMapGUI 
  42  from DejaVu.colorTool import RGBRamp 
  43  from DejaVu.Texture import Texture 
  44  from Pmv.guiTools import MoleculeChooser,CenterChooser 
  45  from Pmv.selectionCommands import MVSelectFromStringCommand 
  46  from mglutil.math import transformation,rotax,rmsd ; Transform = transformation.Transformation 
  47  from bhtree import bhtreelib 
  48  from mglutil.bhtfunctions import findNearestAtoms 
  49  from DejaVu.Geom import Geom 
  50       
51 -class MolIndexedPolygons(IndexedPolygons):
52 53 """ 54 Package : Pmv 55 Module : sdCommands 56 Class : MolIndexedPolygons 57 Command : None 58 59 Description: 60 The MolIndexedPolygons is a class derived from IndexedPolygons. It 61 has an additional method, getTriangles, which is used to assign 62 atoms to geometry vertices and vice versa when an externally 63 generated geometry is assigned to a molecule. Assignment to a 64 molecule occurs with the ReadMolIndexedPolygons command 65 66 Keywords: geometry, harmony, surfdock 67 """ 68
69 - def __init__(self, name = None, check=1, redo=1, **kw):
70 71 apply(IndexedPolygons.__init__, (self, name, check), kw) 72 #atomIndices has for each atomIndex a list of vertexIndices: 73 #the vertices for which this atom is the closest 74 self.atomIndices = {} 75 #vertexIndices has a value for each vertex which corresponds to 76 #the __surfIndex__ value for the closest atom 77 self.vertexIndices = {}
78 79
80 - def getTriangles(self, atomindices):
81 """This emulates the MSMS getTriangles method. 82 Needed for assigning vertices to atoms 83 """ 84 # get the list of vertex indices which are associated with the 85 # atom indices passed in 86 vindexList = [] 87 for a in atomindices: 88 vindexList.extend(self.atomIndices[a]) 89 vfloat = [] 90 vint = [] 91 tri = [] 92 for key in self.properties.keys(): 93 self.displayprops[key]= [] 94 #flag all vertices as _not_ in the list to be returned 95 displayFlags = -1*Numeric.ones(len(self.vertexIndices)) 96 for x in range(len(vindexList)): 97 vindex = int(vindexList[x]) 98 #get hold of the propereties for the displayed vertices and 99 #stick in the vertice.properties index for coloring purposes 100 for key in self.properties.keys(): 101 value = self.properties[key][vindex] 102 self.displayprops[key].append(value) 103 # flag the vertices being included as being returned 104 # displayFlag gives its new position in the list 105 # which can be used to update the triangles (below) 106 displayFlags[vindex]=x 107 # vfloat = (x,y,z,nx,ny,nz,sesA=0.0,sasA=0.0) 108 thisfloat = [] 109 thisfloat.extend(self.vertices[vindex].tolist()) 110 thisfloat.extend(self.vnormals[vindex].tolist()) 111 thisfloat.extend([0.0,0.0]) 112 vfloat.append(thisfloat) 113 # vint = (type=-1, closestAtomIndex, buried=0) 114 thisint = [-1] 115 thisint.append(self.vertexIndices[vindex]) 116 thisint.append(0) 117 vint.append(thisint) 118 #tri = triangles data (i,j,k,type=1,SESF_num=0) 119 for face in self.triangles: 120 #replace the vertex number with its position in the new list 121 tri0 = displayFlags[int(face[0])] 122 tri1 = displayFlags[int(face[1])] 123 tri2 = displayFlags[int(face[2])] 124 # if they are all being used, we need a triangle 125 if tri0 != -1 and tri1 != -1 and tri2 != -1: 126 thistri = [tri0,tri1,tri2] 127 thistri.extend([1,0]) 128 tri.append(thistri) 129 return N.array(vfloat,'f'),N.array(vint,'i'),N.array(tri,'i')
130 131
132 -class ReadMolIndexedPolygons(MVCommand):
133 """ 134 Package : Pmv 135 Module : sdCommands 136 Class : ReadMolIndexedPolygons 137 Command : readMolIndexedPolygons 138 139 Description: 140 Class to read two files (defining vertices and faces) to generate 141 a MolIndexedPolygons instance and assign it to a molecule. Polygon 142 vertices are assigned to atoms in the molecule and vice versa. The 143 first six columns of the vertices file contain vertex coordinates 144 and surface normals. The remaining columns contain surface 145 properties. 146 147 Synopsis: 148 None <- ReadMolIndexedPolygons(molName, vertfile, trifile, propertyList=[], name=None, **kw) 149 molName : name of the molecule to which the polygon belongs 150 vertfile : name of the file containing list of vertices and surface properties 151 trifile : file containing faces (i.e. vertex connectivity) 152 atom_index : file containing correspondence between surface points and atoms 153 (in the format output using cluster -d -a) 154 If absent, the correspondences will be calculated 155 propertyList : list of names to give the surface properties (columns 7+ of the vertex file) 156 name : name to give the geometry. Defaults to the vertex file name. 157 158 Keywords: geometry, harmony 159 """ 160 161
162 - def __init__(self):
163 MVCommand.__init__(self)
164 165
166 - def pickedVerticesToAtoms(self, geom, vertInd):
167 """Function called to convert a picked vertex into an atom""" 168 169 # this function gets called when a picking or drag select event has 170 # happened. It gets called with a geometry and the list of vertex 171 # indices of that geometry that have been selected. 172 # This function is in charge of turning these indices into an AtomSet 173 174 175 surfName = geom.userName 176 geomC = geom.mol.geomContainer 177 surfNum = geomC.molindexedpolygons[surfName][1] 178 179 180 #FIXME: bulding atomindices is done in DisplayMSMS 181 #should re-use it 182 mol = geom.mol 183 atomindices = [] 184 al = mol.geomContainer.atoms[surfName] 185 186 for a in al: 187 atomindices.append(a.__surfIndex__) 188 189 surf = geomC.molindexedpolygons[surfName][0] 190 vf, vi, f = surf.getTriangles(atomindices) 191 192 l = [] 193 allAt = mol.allAtoms 194 for i in vertInd: 195 l.append(allAt[vi[i][1]-1]) 196 return AtomSet( l )
197 198
199 - def pickedVerticesToBonds(self, geom, parts, vertex):
200 return None
201 202
203 - def atomPropToVertices(self, geom, atoms, propName, propIndex=None):
204 """Function called to map atomic properties to the vertices of the 205 geometry""" 206 if len(atoms)==0: return None 207 208 geomC = geom.mol.geomContainer 209 surfName = geom.userName 210 surf = geomC.molindexedpolygons[surfName][0] 211 surfNum = geomC.molindexedpolygons[surfName][1] 212 213 prop = [] 214 if propIndex is not None: 215 for a in geom.mol.allAtoms: 216 d = getattr(a, propName) 217 prop.append( d[propIndex] ) 218 else: 219 for a in geom.mol.allAtoms: 220 prop.append( getattr(a, propName) ) 221 222 # find indices of atoms with surface displayed 223 atomindices = [] 224 for a in atoms.data: 225 atomindices.append(a.__surfIndex__) 226 227 # get the indices of closest atoms 228 vf, vi, f = surf.getTriangles(atomindices) 229 230 # get lookup col using closest atom indicies 231 mappedprop = Numeric.take(prop, vi[:, 1]-1).astype('f') 232 233 return mappedprop
234 235
236 - def onAddObjectToViewer(self, obj):
237 """ 238 Adds the Molindexedpolygons geometry to represent the molindexedpolygons surface 239 of a molecule 240 """ 241 if not self.vf.hasGui: return 242 geomC = obj.geomContainer 243 geomC.nbMolindexedpolygons = 0 244 geomC.molindexedpolygons = {}
245 246
247 - def doit(self, molName, vertfile, trifile, atom_index=None, propertyList=[], name=None, display=1):
248 249 print "molName",molName 250 print "vertfile",vertfile 251 print "trifile",trifile 252 print "atom_index",atom_index 253 print "propertyList",propertyList 254 print "name",name 255 # first try to read the files: 256 try: 257 infile = open(vertfile,'r') 258 vertdata = infile.readlines() 259 infile.close() 260 except: 261 msg = "File '%s' does not exist" % vertfile 262 self.vf.warningMsg(msg) 263 return None 264 if trifile: 265 try: 266 infile = open(trifile,'r') 267 tridata = infile.readlines() 268 infile.close() 269 except: 270 msg = "File '%s' does not exist" % trifile 271 self.vf.warningMsg(msg) 272 return None 273 else: 274 # try to find the appropriate triangulation file 275 # can be 276 # icosohedral ( subdivision level is (nvertices-2)/10. ) 277 # dual icosohedral ( subdivision level is (nvertices/20.) ) 278 # octahedral (nfaces = 4*subdivisionlevel*8) # not done 279 # cubic # not done 280 # tetrahedral # not done 281 pname = os.path.split(vertfile)[0] 282 datapath = Pmv.__path__[0]+'/data' 283 nvertices= len(vertdata) 284 if (nvertices-2)/10. == (nvertices-2)/10: # dual icosohedral? 285 level = (nvertices-2)/10 286 trifiles = (os.path.join(datapath,'ico.%d.tri' % level), 287 os.path.join(pname,'ico.%d.tri' % level)) 288 #print "Tesselation is simple icosohedral at %d subdivision level" % level 289 elif nvertices/20. == nvertices/20: # icosohedral? 290 level = (nvertices)/20 291 trifiles = (os.path.join(datapath,'%d.poly.tri' % level), 292 os.path.join(pname,'%d.poly.tri' % level)) 293 #print "Tesselation is dual icosohedral at %d subdivision level" % level 294 else: #undetermined 295 msg = "Cannot establish subdivision level. Check %s" % vertfile 296 self.vf.warningMsg(msg) 297 return None 298 #now try to read the trifile 299 tridata=[] 300 for trifile in trifiles: 301 try: 302 infile = open(trifile) 303 tridata = infile.readlines() 304 infile.close() 305 #print "#2: Read tesselation from",trifile 306 break 307 except: 308 continue 309 if not tridata: 310 msg = "Files %s and %s cannot be found" % trifiles 311 self.vf.warningMsg(msg) 312 return 313 314 #then expand the molName to nodes 315 mol = self.vf.expandNodes(molName)[0] 316 atm = mol.allAtoms 317 geomC = mol.geomContainer 318 if name is None: 319 name = string.replace(molName,'_','') 320 name = "%ssurf%d" % (name,geomC.nbMolindexedpolygons) 321 322 # get all the atoms for the molecule 323 if name in geomC.atoms.keys(): 324 #update the old geometry 325 geomC.molindexedpolygons[name]=atm 326 geomC.atoms[name]=atm 327 g = geomC.geoms[name] 328 else: 329 #create a new geometry 330 g = MolIndexedPolygons(name,pickableVertices=1)#, protected=True) 331 g.userName = name 332 if self.vf.userpref['sharpColorBoundariesForMsms']['value'] == 'blur': 333 g.Set(inheritSharpColorBoundaries=False, sharpColorBoundaries=False) 334 geomC.addGeom(g) 335 self.managedGeometries.append(g) 336 geomC.molindexedpolygons[name]=atm 337 geomC.atoms[name]=atm 338 geomC.geomPickToAtoms[name] = self.pickedVerticesToAtoms 339 geomC.geomPickToBonds[name] = None 340 geomC.VIEWER.AddObject( g, parent = geomC.masterGeom, redo=0) 341 g.RenderMode(GL.GL_FILL, face=GL.GL_FRONT, redo=0) 342 geomC.atomPropToVertices[name] = self.atomPropToVertices 343 344 # Create the key for this dockdata for each a.colors dictionary. 345 for a in mol.allAtoms: 346 a.colors[name] = (1.,1.,1.) 347 a.opacities[name] = 1.0 348 349 i = 1 350 if not hasattr(atm[0], '__surfIndex__'): 351 #only need to set up the __surfIndex__ once 352 for a in atm.data: 353 a.__surfIndex__ = i 354 i=i+1 355 356 # construct the surface and its properties from the data 357 vertices = [] 358 vnormals = [] 359 triangles = [] 360 vertexNumber = 0 361 g.properties = properties = {} 362 g.displayprops = displayprops = {} 363 #print propertyList 364 for property in propertyList: 365 properties[property]=[] 366 displayprops[property]=[] 367 for line in vertdata: 368 numbers = string.split(line) 369 vertices.append(([float(numbers[0]), 370 float(numbers[1]), 371 float(numbers[2])])) 372 vnormals.append(([float(numbers[3]), 373 float(numbers[4]), 374 float(numbers[5])])) 375 props = map(lambda x: float(x), numbers[6:]) 376 if len(propertyList): 377 for x in range(len(propertyList)): 378 properties[propertyList[x]].append(props[x]) 379 g.vertices = Numeric.array(vertices,'f') 380 # translate and scale the unit sphere representation of the output from tmap 381 if vertfile.split(".")[-1] in ["exp","exp2"]: 382 ats = mol.allAtoms 383 cg = Numeric.average(mol.allAtoms.coords) 384 rg = map(lambda x: (x-cg)*(x-cg), mol.allAtoms.coords) 385 rg = Numeric.average(rg) 386 rg = Numeric.sum(Numeric.average(rg)) 387 rg = Numeric.sqrt(rg) 388 g.vertices = map(lambda x: x*rg + cg, g.vertices) 389 g.vnormals = Numeric.array(vnormals,'f') 390 for line in tridata: 391 numbers = string.split(line) 392 triangles.append([int(numbers[0])-1, 393 int(numbers[1])-1, 394 int(numbers[2])-1]) 395 g.triangles = triangles = Numeric.array(triangles,'i') 396 397 # If the atomIndices file is _not_ given (or not found) get the atomIndices and vertexIndices from bhtree 398 # g.vertexIndices:keys = vertexnumbers, vals = corresponding atom numbers (0-based ) 399 # g.atomIndices: keys = atom numbers: vals - list of vertexNumbers (1-based) 400 if atom_index: 401 try: 402 infile= open(atom_index) 403 atom_index = infile.readlines() 404 infile.close() 405 except: 406 atom_index = None 407 if atom_index: 408 g.vertexIndices = {} 409 g.atomIndices = {} 410 for a in range(1,len(mol.allAtoms)+1): 411 g.atomIndices[a]=[] 412 for rec in atom_index: 413 fields = rec.split() 414 a = int(fields[3]) 415 v = int(fields[4])-1 416 g.vertexIndices[v]=a 417 g.atomIndices[a].append(v) 418 else: 419 g.vertexIndices,g.atomIndices = findNearestAtoms(mol,vertices) 420 421 #create the surface and put it in the geomContainer 422 # save a pointer to the dockdata object 423 mol.geomContainer.molindexedpolygons[name] = (g, geomC.nbMolindexedpolygons) 424 geomC.nbMolindexedpolygons = geomC.nbMolindexedpolygons+1 425 426 if len(vertices): 427 # print 'setting vertices:', vertices 428 g.Set( vertices=vertices[:], vnormals=vnormals[:], faces=triangles[:], 429 visible=1 ) 430 #print 'after setting vertices:', g.vertexSet.vertices.array 431 432 if display: 433 self.vf.displaySurface(mol, name=name, topCommand=0, setupUndo=1)
434 435
436 - def guiCallback(self):
437 """ Doesn't handle property lists yet. These have to be done on the 438 command line 439 """ 440 # get the molecule for which this is being read 441 mol = MoleculeChooser(self.vf).go() 442 if not mol: 443 return None 444 molName = mol.name 445 446 # get the vertex file 447 fileTypes = [("vertex files","*vert*"),] 448 fileBrowserTitle = "Read Vertex File" 449 vertfile = self.vf.askFileOpen(types=fileTypes, 450 title=fileBrowserTitle) 451 if not vertfile: 452 return 453 #get the triangle file 454 fileTypes = [("triangle files","*tri*"),] 455 fileBrowserTitle = "Read Triangle File" 456 trifile = self.vf.askFileOpen(types=fileTypes, 457 title=fileBrowserTitle) 458 if not trifile: 459 return 460 461 self.doitWrapper(molName,vertfile,trifile)
462 463
464 - def __call__(self, molName, vertfile, trifile, atom_file=None, propertyList=[], name=None, **kw):
465 """None <- readMolIndexedPolygons(nodes, vertfile, trifile, atom_file, propertyList, name,**kw) 466 nodes : TreeNodeSet holding a molecule 467 vertfile: vertices and normals 468 trifile : one-based triangulation file 469 atom_file: (optional) output of cluster assigning atoms to vertices 470 propertyList: list of names of surface properties in the vertfile 471 """ 472 if not kw.has_key('redraw'): kw['redraw'] = 1 473 apply( self.doitWrapper, (molName, vertfile, trifile, 474 atom_file, propertyList, name), kw)
475 476
477 -class ColorMolIndexedPolygons(ColorCommand):
478 """ 479 Package : Pmv 480 Module : sdCommands 481 Class : ColorMolIndexedPolygons 482 Command : colorMolIndexedPolygons 483 484 Description: 485 The ColorMolIndexedPolygons class provides a mechanism for coloring 486 a MolIndexedPolygons instance according to its surface properties 487 (i.e. the properties listed in the vertex file used to generate 488 the MolIndexedPolygons). This command only colors a surface 489 according to _surface_ properties. To color according to 490 properties of the molecule to which the MolIndexedPolygons belongs 491 (such as atom type, chain ID etc.), use the general color commands. 492 493 Synopsis: 494 None <- colorMolIndexedPolygin(nodes, geomsToColor,property,colorMap=None,**kw): 495 nodes : any set of MolKit nodes describing molecular components 496 geomsToColor: list of MolIndexedPolygons instances to color 497 property : surface property by which to color 498 colorMap : colorMap which will translate the property values into colors 499 (default is the rgb256 colorMap) 500 501 Keywords: color, surfdock, harmony 502 """ 503
504 - def onAddCmdToViewer(self):
505 if 'rgb256' not in self.vf.colorMaps.keys(): 506 ramp = RGBRamp(256) 507 cmap = ColorMapGUI('rgb256', ramp=ramp, allowRename=False, modifyMinMax=True) 508 self.vf.addColorMap(cmap)
509 510
511 - def getPropsGUI(self, nodes, geomsToColor, showUndisplay = 0):
512 propsAvailable = [] 513 molInSel = nodes.top.uniq() 514 for mol in molInSel: 515 geomC = mol.geomContainer 516 if hasattr(geomC,'molindexedpolygons'): 517 for geom in geomsToColor: 518 if geom in geomC.geoms.keys(): 519 for key in geomC.geoms[geom].properties.keys(): 520 if key not in propsAvailable: 521 propsAvailable.append(key) 522 idf = self.idf = InputFormDescr(title = self.name) 523 idf.append({'widgetType':Pmw.RadioSelect, 524 'name':'Property', 525 'listtext':propsAvailable, 526 'defaultValue':propsAvailable[0], 527 'wcfg':{'labelpos':'n', 528 'label_text':'Select the property to color by:', 529 'orient':'vertical', 530 'buttontype':'radiobutton'}, 531 'gridcfg':{'sticky':'we','columnspan':2}}) 532 533 val = self.vf.getUserInput (self.idf) 534 if val: 535 return val['Property'] 536 else: 537 return None
538
539 - def getAvailableGeoms(self, nodes, showUndisplay = 0):
540 """Method to build a dictionary containing all the molindexedpolygons 541 geometries available in the scene.""" 542 543 if not nodes: 544 return 545 molInSel = nodes.top.uniq() 546 geomsAvailable = [] 547 for mol in molInSel: 548 geomC = mol.geomContainer 549 childGeomsName = self.getChildrenGeomsName(mol) 550 # We only put the one we are ineterested in in the list 551 # of geomsAvailable 552 for geomName in geomC.molindexedpolygons.keys(): 553 if geomName in ['master','selectionSpheres']: 554 continue 555 if geomC.atoms.has_key(geomName): 556 if geomName in childGeomsName: 557 continue 558 if showUndisplay == 0 and \ 559 geomC.atoms[geomName]==[]: 560 continue 561 if not geomName in geomsAvailable: 562 geomsAvailable.append(geomName) 563 else: 564 if not geomC.geoms[geomName].children: 565 continue 566 else: 567 empty = filter(lambda x, geomC=geomC: 568 geomC.atoms.has_key(x.name) and \ 569 geomC.atoms[x.name]==[], 570 geomC.geoms[geomName].children) 571 if len(empty)==len(geomC.geoms[geomName].children)\ 572 and showUndisplay == 0: 573 continue 574 if not geomName in geomsAvailable: 575 geomsAvailable.append(geomName) 576 return geomsAvailable
577 578
579 - def doit(self,nodes,geomsToColor,property,colorMap=None,**kw):
580 if 'rgb256' not in self.vf.colorMaps.keys(): 581 self.vf.colorMaps['rgb256'] = ColorMapGUI('rgb256', RGBRamp(256), 582 allowRename=False, modifyMinMax=True) 583 if colorMap is None: 584 if not hasattr(self,'colorMap'): 585 self.colorMap = self.vf.colorMaps['rgb256'] 586 else: 587 self.colorMap = colorMap 588 if hasattr(self.colorMap,'gui') and (self.colorMap.gui is not None): 589 self.colorMapGUI = self.colorMap.gui 590 else: 591 self.colorMapGUI = ColorMapGUI(allowRename=False, modifyMinMax=True) 592 self.colorMap.gui = self.colorMapGUI 593 molecules, atomSets = self.vf.getNodesByMolecule(nodes, Atom) 594 geometries={} 595 for mol, atm in map(None, molecules, atomSets): 596 geomC = mol.geomContainer 597 fmax = -9999.0 598 fmin = 9999.0 599 for g in geomC.geoms.values(): 600 if g.name not in geomsToColor or not hasattr(g,'properties'): 601 continue 602 if property in g.properties.keys(): 603 geometries[g.name]=g 604 if fmax < max(g.properties[property]): 605 fmax = max(g.properties[property]) 606 if fmin > min(g.properties[property]): 607 fmin = min(g.properties[property]) 608 self.colorMap.configure(mini=fmin,maxi=fmax,geoms=geometries) 609 ## if hasattr(self,'colorMapGUI'): 610 ## self.colorMapGUI.update(mini=fmin,maxi=fmax) 611 # now go through again, this time setting the colors 612 for g in geometries.values(): 613 prop = Numeric.array(g.displayprops[property]).astype('f') 614 #get rid of any other coloring 615 colors = self.colorMap.Map(prop) 616 colors = N.array(colors).astype('f') 617 g.Set(materials=colors,inheritMaterial=0) 618 ## if min(prop)<0 or max(prop)>0: 619 ## mini = min(prop) 620 ## l = max(prop)-mini 621 ## prop1 = (prop-mini) / l 622 ## prop = prop1 623 ## prop.shape = (-1,1) 624 ## tex = Numeric.array(Numeric.array(self.colorMap.ramp)*255).astype('b') 625 ## t=Texture() 626 ## t.Set(enable=1, image=tex) 627 ## g.Set(texture=t,textureCoords=colors) 628 self.vf.GUI.VIEWER.cameras[0].update() 629 self.vf.GUI.VIEWER.Redraw()
630
631 - def cleanup(self):
632 """ The attribute deleted by this method of ColorCommand aren't created 633 in this class, so skip this step. 634 """ 635 pass
636 637
638 - def __call__(self, nodes, geomsToColor,property,colorMap=None,**kw):
639 """ None <- colorHarmony(self, molName, property, **kw) 640 molName : 641 property: 642 """ 643 #molsAvailable = self.getAvailableMols() 644 #if nodes not in molsAvailable: return None 645 apply(self.doitWrapper, (nodes, geomsToColor,property,colorMap), {'redraw':1})
646 647
648 - def guiCallback(self):
649 # get the nodes to be colored 650 nodes = self.vf.getSelection() 651 if len(nodes)==0: return 652 # get the molindexedpolygons geometries to be colored for these nodes 653 val = self.showForm('geomsGUI', scrolledFrame = 1, 654 width= 500, height = 200, force=1) 655 if val: 656 geomsToColor = self.geomsToColor = val['geoms'] 657 else: 658 geomsToColor = self.geomsToColor = None 659 return 'ERROR' 660 # get the property by which the geometries will be colored 661 colorProp = self.getPropsGUI(nodes,geomsToColor) 662 if colorProp is None: 663 return 664 # set up the colorMap 665 if not hasattr(self,'colorMap'): 666 self.colorMap = self.vf.colorMaps['rgb256'] 667 if not hasattr(self.colorMap,'gui'): 668 self.colorMapGUI = ColorMapGUI(self.colorMap, allowRename=False, modifyMinMax=True) 669 self.colorMapGUI.addCallback( self.colorMapEditor_cb ) 670 self.colorMapEditor_Args = (nodes,geomsToColor,colorProp,) 671 # pass the arguments to doit 672 apply(self.doitWrapper, self.colorMapEditor_Args+(self.colorMap,), 673 {'redraw':1,'log':0,'setupUndo':0})
674 675
676 - def colorMapEditor_cb(self, colorMap):
677 apply(self.doitWrapper, self.colorMapEditor_Args, 678 {'redraw':1,'log':1})
679 680 681
682 -class ReadDockdata(ReadMolIndexedPolygons):
683 """ 684 Package : Pmv 685 Module : sdCommands 686 Class : ReadDockdata 687 Command : readDockdata 688 689 Description: 690 The ReadDockdata class is a subclass of ReadMolIndexedPolygons for 691 reading dockdata files as used by surfdock. The propertyList and 692 trifile are predefined, so only the vertex file is needed. 693 694 Synopsis: 695 None <- readDockdata(molname,vertfile,**kw) 696 molName : name of the molecule to which the polygon belongs 697 vertfile : name of the dockdatafile 698 name : name to assign to the geometry. Defaults to 699 vertfile 700 701 Keywords: harmony,surfdock,geometry 702 """ 703 704 # def __call__(self,molName,vertfile,atom_index=None,name=None, **kw): 705 # if not kw.has_key('redraw'): kw['redraw'] = 1 706 # if not name: 707 # name = os.path.split(vertfile)[1] 708 # name = name.replace('_','') 709 # 710 # propertyList = ['Area','ShapeIndex','Curvedness', 711 # 'Hydro1','Hydro2','Electro','Bval'] 712 # apply(self.doitWrapper, (molName,vertfile,atom_index,None,propertyList,name), kw) 713
714 - def __call__(self, molName, vertfile, trifile, atom_file=None, 715 propertyList=['Area','ShapeIndex','Curvedness', 716 'Hydro1','Hydro2','Electro','Bval'], 717 name=None, **kw):
718 """None <- readMolIndexedPolygons(nodes, vertfile, trifile, atom_file, propertyList, name,**kw) 719 nodes : TreeNodeSet holding a molecule 720 vertfile: vertices and normals 721 trifile : one-based triangulation file 722 atom_file: (optional) output of cluster assigning atoms to vertices 723 propertyList: list of names of surface properties in the vertfile 724 """ 725 if not kw.has_key('redraw'): kw['redraw'] = 1 726 if not name: 727 name = os.path.split(vertfile)[1] 728 name = name.replace('_','') 729 730 apply( self.doitWrapper, 731 (molName, vertfile, trifile, atom_file, propertyList, name), 732 kw )
733 734
735 - def guiCallback(self):
736 """ 737 """ 738 # get the molecule for which this is being read 739 mol = MoleculeChooser(self.vf).go() 740 if not mol: 741 return None 742 molName = mol.name 743 744 # get the dockdata file 745 fileTypes = [("dockdata files","*dockdata*"),] 746 fileBrowserTitle = "Read Dockdata File" 747 vertfile = self.vf.askFileOpen(types=fileTypes, 748 title=fileBrowserTitle) 749 if not vertfile: 750 return 751 752 name = os.path.split(vertfile)[1] 753 name = name.replace('_','') 754 propertyList = ['Area','ShapeIndex','Curvedness', 755 'Hydro1','Hydro2','Electro','Bval'] 756 atom_index= None 757 apply( self.doitWrapper, (molName,vertfile,atom_index,None,propertyList,name))
758
759 -class ReadHarmony(ReadMolIndexedPolygons):
760 """ 761 Package : Pmv 762 Module : sdCommands 763 Class : ReadHarmony 764 Command : readHarmony 765 766 Description: 767 The ReadHarmony class is a subclass of ReadMolIndexedPolygons for 768 reading files generated by the Harmony suite (usually having the 769 suffix 'field'. The propertyList and trifile are known in advance 770 for such files, so only the vertices are needed. 771 772 Synopsis: 773 None <- readHarmony(molname,vertfile,name,**kw) 774 molName : name of the molecule to which the polygon belongs 775 vertfile : name of the harmony (.field) file 776 name : name to assign to the geometry. Defaults to vertfile 777 778 Keywords: harmony,surfdock,geometry 779 """ 780
781 - def __call__(self,molName, vertfile, atom_index=None, name=None, **kw):
782 if not kw.has_key('redraw'): kw['redraw'] = 1 783 if not name: 784 name = os.path.split(vertfile)[1] 785 name = name.replace('_','') 786 787 propertyList=['Gaussian Curvature','Mean Curvature', 788 'Max Curvature','Min Curvature','Area'] 789 apply(self.doitWrapper, (molName,vertfile,atom_index, None,propertyList,name), kw)
790 791
792 - def guiCallback(self):
793 """ 794 """ 795 # get the molecule for which this is being read 796 mol = MoleculeChooser(self.vf).go() 797 if not mol: 798 return None 799 molName = mol.name 800 801 # get the dockdata file 802 fileTypes = [("harmony files","*field*"),] 803 fileBrowserTitle = "Read Harmony File" 804 vertfile = self.vf.askFileOpen(types=fileTypes, 805 title=fileBrowserTitle) 806 if not vertfile: 807 return 808 809 name = os.path.split(vertfile)[1] 810 name = name.replace('_','') 811 propertyList = ['Gaussian Curvature','Mean Curvature', 812 'Max Curvature','Min Curvature','Area'] 813 atom_index=None 814 apply( self.doitWrapper, (molName,vertfile,atom_index,None,propertyList,name))
815 816
817 -class ReadBlur(ReadMolIndexedPolygons):
818 """ 819 Package : Pmv 820 Module : sdCommands 821 Class : ReadBlur 822 Command : readBlur 823 824 Description: 825 The ReadHarmony class is a subclass of ReadMolIndexedPolygons for 826 reading files generated by the Gaussian Blur method. The triangulation 827 file is taken from the vertices file (i.e. given MOL.dockdata, it looks 828 for MOL.face). Properties are the same as for old harmony dockdata files, 829 qith kmax and kmin added at the end 830 831 Synopsis: 832 None <- readBlur(molName,vertfile,atom_index,name,**kw) 833 molName : name of the molecule to which the polygon belongs 834 vertfile : name of the blur-generated dockdatafile 835 atom_index : (optional) file containing assignment of vertices to atoms 836 name : (optional) name to assign to the geometry. 837 838 Keywords: blur,surfdock,geometry 839 """ 840
841 - def __call__(self,molName, vertfile, atom_index=None, name=None, **kw):
842 if not kw.has_key('redraw'): kw['redraw'] = 1 843 if not name: 844 name = os.path.split(vertfile)[1] 845 name = name.replace('_','') 846 847 trifile = vertfile.replace("dockdata","face") 848 try: 849 f = open(trifile) 850 f.close() 851 except: 852 raise(IOError("Cannot open %d for reading" % trifile)) 853 propertyList = ['Area','ShapeIndex','Curvedness', 854 'Hydro1','Hydro2','Electro','Bval', 855 'Kmin', 'Kmax'] 856 apply(self.doitWrapper, (molName,vertfile,trifile,atom_index,propertyList,name), kw)
857 858
859 - def guiCallback(self):
860 """ 861 """ 862 # get the molecule for which this is being read 863 mol = MoleculeChooser(self.vf).go() 864 if not mol: 865 return None 866 molName = mol.name 867 868 # get the dockdata file 869 fileTypes = [("Blur Files","*dockdata*"),] 870 fileBrowserTitle = "Read Gaussian Blur File" 871 vertfile = self.vf.askFileOpen(types=fileTypes, 872 title=fileBrowserTitle) 873 if not vertfile: 874 return 875 trifile = vertfile.replace("dockdata","face") 876 try: 877 f = open(trifile) 878 f.close() 879 except: 880 raise(IOError("Cannot open %d for reading" % trifile)) 881 name = os.path.split(vertfile)[1] 882 name = name.replace('_','') 883 propertyList = ['Area','ShapeIndex','Curvedness', 884 'Hydro1','Hydro2','Electro','Bval', 885 'Kmin', 'Kmax'] 886 atom_index=None 887 apply( self.doitWrapper, (molName,vertfile,trifile,atom_index,propertyList,name))
888 889
890 -class ReadMSMS(ReadMolIndexedPolygons):
891 """ molName, vertfile,trifile,propertyList,name,normals """ 892
893 - def __call__(self,molName, vertfile, trifile, atom_index=None, name=None, **kw):
894 if not vertfile: vertfile = molName +'.vert' 895 if not trifile: trifile = molName +'.tri' 896 if not kw.has_key('redraw'): kw['redraw'] = 1 897 if not name: 898 name = '%sMSMS' % (molName) 899 apply(self.doitWrapper, (molName,vertfile,trifile, atom_index), kw)
900 901
902 -class DisplayMolIndexedPolygons(DisplayCommand):
903 """ 904 Package : Pmv 905 Module : sdCommands 906 Class : DisplayMolIndexedPolygons 907 Command : displayMolIndexedPolygons 908 909 Description: 910 The DisplayMolIndexedPolygons is used to display MolIndexedPolygons 911 instances (or parts thereof) which are associated with the 912 selected nodes 913 914 Synopsis: 915 None <- displayMolIndexPolygons(nodes,name,only,negate,**kw) 916 nodes : nodes for which polygons will be displayed 917 name : name of the polygon to be displayed 918 only : display polygon for these atoms _only_ 919 (i.e. undisplay any other parts currently displayed) 920 negate : undisplay selected polygon for selected nodes 921 922 Keywords: harmony,surfdock,display 923 """ 924
925 - def doit(self, nodes, name = 'all', only=0, negate=0, **kw):
926 927 molecules, atomSets = self.vf.getNodesByMolecule(nodes, Atom) 928 for mol, atm in map(None, molecules, atomSets): 929 idf = InputFormDescr(title ="Display indexedpolygons for %s:"%mol.name) 930 geomC = mol.geomContainer 931 if name == 'ask': 932 for surfName in geomC.molindexedpolygons.keys(): 933 idf.append({'name':surfName, 934 'widgetType':Tkinter.Checkbutton, 935 'wcfg':{'text':surfName, 936 'variable':Tkinter.IntVar()}, 937 'gridcfg':{'sticky':'w'}}) 938 val = self.vf.getUserInput(idf) 939 940 elif name in geomC.molindexedpolygons.keys(): 941 val = {} 942 for surfName in geomC.molindexedpolygons.keys(): 943 if surfName == name: 944 val[surfName]=1 945 else: 946 val[surfName]=0 947 948 elif name == 'all': 949 val = {} 950 for surfName in geomC.molindexedpolygons.keys(): 951 val[surfName] = 1 952 953 if not val: 954 return None 955 956 for surfName in geomC.molindexedpolygons.keys(): 957 if not val[surfName]: continue 958 959 set = geomC.atoms[surfName] 960 if negate: set = set -atm 961 else: 962 if only: set = atm 963 else: set = atm.union(set) 964 965 geomC.atoms[surfName] = set 966 967 # get the surface object for that molecule 968 srf = geomC.molindexedpolygons[surfName][0] 969 970 # get the atom indices 971 surfNum = geomC.molindexedpolygons[surfName][1] 972 atomindices = [] 973 for a in set.data: 974 atomindices.append(a.__surfIndex__) 975 976 g = geomC.geoms[surfName] 977 if len(atomindices)==0: 978 g.Set(visible=0) 979 else: 980 vf, vi, f = srf.getTriangles(atomindices) 981 col = mol.geomContainer.getGeomColor(surfName)
982 # ... g.set() is commented by Qing on 8/15/2005 ... 983 # g.Set( vertices = vf[:,:3], vnormals = vf[:,3:6], 984 # faces = f[:,:3], materials=col, visible=1 ) 985
986 - def __call__(self, nodes, name ='all', only=0, negate=0, **kw):
987 """None <- displaySurface(nodes, only=0, negate=0, **kw) 988 nodes : TreeNodeSet holding the current selection 989 only : flag when set to 1 only the current selection will be 990 displayed 991 negate : flag when set to 1 undisplay the current selection""" 992 if not kw.has_key('redraw'): kw['redraw']=1 993 kw['only'] = only 994 kw['negate'] = negate 995 if type(nodes) is types.StringType: 996 self.nodeLogString = "'"+nodes+"'" 997 998 mols = self.vf.expandNodes(nodes) 999 if name == None: 1000 for mol in mols: 1001 for name in mol.geomContainer.molindexedpolygons.keys(): 1002 kw['name'] 1003 apply( self.doitWrapper, (nodes, name), kw) 1004 else: 1005 apply( self.doitWrapper, (nodes,name), kw )
1006 1007
1008 - def guiCallback(self):
1009 idf = InputFormDescr(title ="Display indexedpolygons :") 1010 idf.append({'name':'display', 1011 'widgetType':Pmw.RadioSelect, 1012 'listtext':['display','display only', 'undisplay'], 1013 'defaultValue':'display', 1014 'wcfg':{'orient':'horizontal', 1015 'buttontype':'radiobutton'}, 1016 'gridcfg':{'sticky': 'we'}}) 1017 val = self.vf.getUserInput(idf) 1018 if val: 1019 if val['display']=='display': 1020 val['only']= 0 1021 val['negate'] = 0 1022 del val['display'] 1023 elif val['display']=='display only': 1024 val['only']= 1 1025 val['negate'] = 0 1026 del val['display'] 1027 elif val['display']== 'undisplay': 1028 val['negate'] = 1 1029 val['only'] = 0 1030 del val['display'] 1031 val['redraw'] = 1 1032 val['name']='ask' 1033 if self.vf.userpref['expandNodeLogString']['value'] == 0: 1034 self.nodeLogString = "self.getSelection()" 1035 apply( self.doitWrapper, (self.vf.getSelection(),), val)
1036
1037 -class UndisplayMolIndexedPolygons(DisplayMolIndexedPolygons):
1038 - def __call__(self, nodes, name, **kw):
1039 """None <- undisplaySurface(nodes, **kw) 1040 nodes : TreeNodeSet holding the current selection (mv.getSelection()) 1041 """ 1042 kw['negate']= 1 1043 apply(self.vf.displaySurface, (nodes,name),kw)
1044 1045
1046 -class ApplyTransformations(MVSelectFromStringCommand):
1047 """ Opens up the Transformation Control GUI which allows reading in and 1048 scanning through transformations. The molecule of interest is selected via 1049 the pull-down 'Molecule List...' menu. Selecting the directory and file of 1050 interest in the Qlist menus will cause that file to be read in (to update 1051 the list of files one must hit return in the Qlist directory entry field). 1052 1053 The qlist files have the format 'score tx ty tz rx ry rz theta rank', where 1054 tx,ty,tz is the translation, rx,ry,rz the direction of the rotation axis, 1055 theta the angle of rotation (in degrees) and rank the rank in the docking. 1056 1057 On reading in a file of transformations, the default center of rotation is 1058 the molecule's center of gravity. To change this, read in the quaternions 1059 with the Center Chooser Dialog button activated. The center of rotation 1060 can then be set to the current selection, or a type-in value. The center 1061 of rotation is remembered, so for a series of files the center need only 1062 be set on reading the first file, after which the toggle can be turned off. 1063 1064 Transformations of interest can be added to and removed from the preferred 1065 list, which can be written out to a file. The rank column in such a file 1066 contains the transformation's position in the original list. 1067 1068 All the data shown in the GUI are stored as attributes of the molecule. 1069 Thus, dockings for several molecules can be shown at once, and the GUI 1070 retrieves the information when a previous molecule is reselected. 1071 """
1072 - def __init__(self):
1073 MVSelectFromStringCommand.__init__(self) 1074 self.refSetName = None 1075 self.mobSetName = None
1076
1077 - def onAddCmdToViewer(self):
1078 self.molCts={} 1079 self.vf.loadModule('fileCommands',topCommand=0) 1080 self.vf.loadModule('measureCommands',topCommand=0)
1081 1082
1083 - def __call__(self,mol,index,**kw):
1084 """ None <- applyTransformations(self, molName, index, **kw) 1085 molName: 1086 index : 1087 """ 1088 if not kw.has_key('redraw'): kw['redraw']=1 1089 apply (self.doitWrapper, (mol,index), kw)
1090 1091
1092 - def doit(self,mol,index):
1093 if not mol: 1094 return None 1095 # sort out the rmsd stuff 1096 refSetName = self.ifd[16]['widget'].get() 1097 mobSetName = self.ifd[17]['widget'].get() 1098 savedSets = self.vf.sets 1099 if refSetName and mobSetName: 1100 # make sure the sets exist. 1101 if (mobSetName in savedSets.keys() and refSetName 1102 in savedSets.keys()): 1103 #have the sets changed? 1104 if (refSetName != self.refSetName or 1105 mobSetName != self.mobSetName): 1106 refSet = savedSets[refSetName] 1107 mobSet = savedSets[mobSetName] 1108 refSet = self.vf.getNodesByMolecule(refSet, 1109 Residue)[1][0] 1110 mobSet = self.vf.getNodesByMolecule(mobSet, 1111 Residue)[1][0] 1112 refSet = refSet.uniq() 1113 mobSet = mobSet.uniq() 1114 refSet.sort() 1115 mobSet.sort() 1116 refXYZ = [] 1117 mobXYZ = [] 1118 # set up lists of coordinates for RMSD: 1119 # only use backbone atoms (incl.Cb) 1120 for x in range(len(refSet)): 1121 refRes = refSet[x] 1122 mobRes = mobSet[x] 1123 for atname in ['C','CA','CB','N','O']: 1124 if (atname in refRes.childByName.keys() 1125 and atname in mobRes.childByName.keys()): 1126 xyz = refRes.childByName[atname].coords[:] 1127 if type(xyz)!=type([]): 1128 xyz=xyz.tolist() 1129 refXYZ.append(xyz) 1130 xyz = mobRes.childByName[atname].coords[:] 1131 mobXYZ.append(xyz) 1132 map(lambda x: x.append(1.),mobXYZ) 1133 map(lambda x: x.append(1.),refXYZ) 1134 self.mobXYZ = N.array(mobXYZ,'f') 1135 self.refXYZ = N.array(refXYZ,'f') 1136 self.refMol = refSet.top.uniq()[0] 1137 self.mobMol = mobSet.top.uniq()[0] 1138 # get the reference molecule's matrix 1139 master = self.refMol.geomContainer.geoms['master'] 1140 refMatrix = (master.rotation[:12].tolist() + 1141 master.translation.tolist() + [1.]) 1142 refMatrix = N.array(refMatrix,'f') 1143 refMatrix= N.reshape(refMatrix,(4,4)) 1144 #if either of the GUI entries is not a set, delete it in the GUI 1145 #to provide a clue 1146 if mobSetName not in savedSets.keys(): 1147 mobSetName = None 1148 self.ifd.entryByName['MobSet']['widget'].setentry('') 1149 if refSetName not in savedSets.keys(): 1150 refSetName = None 1151 self.ifd.entryByName['RefSet']['widget'].setentry('') 1152 # loop through the list and display one after another 1153 validRange = range(len(mol.qlist['totaltransforms'])) 1154 for val in index: 1155 # reset values > max to max 1156 if (val-1) > validRange[-1]: 1157 val = validRange[-1]+1 1158 # input value of <=0 implies original setting, so apply reset: 1159 if val==0: 1160 self.reset() 1161 # apply transformation in valid range 1162 else: 1163 mol.currentQ = val 1164 transform = mol.qlist['totaltransforms'][val-1] 1165 score = mol.qlist['energy'][val-1] 1166 clusterSize = mol.qlist['cluster'][val-1] 1167 score = "%s, %s" % (score,clusterSize) 1168 #update the GUI 1169 self.ifd[2]['widget'].setentry(val) 1170 self.ifd[3]['widget'].setentry(score) 1171 # transform the geometries first 1172 self.transformGeoms(mol,transform) 1173 if refSetName and mobSetName: 1174 #get the mobile molecule's matrix 1175 master = self.mobMol.geomContainer.geoms['master'] 1176 mobMatrix = (master.rotation[:12].tolist() + 1177 master.translation.tolist() + [1.]) 1178 mobMatrix = N.array(mobMatrix,'f') 1179 mobMatrix= N.reshape(mobMatrix,(4,4)) 1180 #compute the transformed XYZ 1181 refXYZ = N.matrixmultiply(self.refXYZ,refMatrix) 1182 mobXYZ = N.matrixmultiply(self.mobXYZ,mobMatrix) 1183 #compute the Rmsd 1184 Rmsd = rmsd.RMSDCalculator(refXYZ).computeRMSD(mobXYZ) 1185 temp = self.ifd[3]['widget'].get() 1186 temp = "%s, %3.1f" % (temp,Rmsd) 1187 self.ifd[3]['widget'].setentry(temp) 1188 # update the viewer 1189 self.vf.GUI.VIEWER.cameras[0].update() 1190 self.vf.GUI.VIEWER.Redraw()
1191 1192 1193
1194 - def reset(self):
1195 molName = self.ifd[0]['widget'].get() 1196 mol = self.verifyMolName(molName) 1197 if mol: 1198 mol.currentQ=0 1199 transform = Transform(trans=(0.,0.,0.),quaternion=[1.,0.,0.,0.]) 1200 #reset the GUI, geometries and coordinates 1201 self.ifd[2]['widget'].setentry(mol.currentQ) 1202 self.ifd[3]['widget'].setentry('') 1203 self.transformGeoms(mol,transform) 1204 #update the viewer 1205 self.vf.GUI.VIEWER.cameras[0].update() 1206 self.vf.GUI.VIEWER.Redraw() 1207 return
1208 1209
1210 - def transformMol(self,mol,transform):
1211 # initialize the second (transformable) coordinate set at the start. 1212 atoms = mol.allAtoms 1213 if len(atoms[0]._coords)==1: 1214 mol.allAtoms.addConformation(mol.allAtoms.coords) 1215 1216 #perform the transformation on conf1 1217 atoms.setConformation(1) 1218 xyz = atoms.coords[:] 1219 xyz = transform.apply(xyz) 1220 atoms.updateCoords(xyz) 1221 #reset to conf zero before returning 1222 atoms.setConformation(0)
1223 1224
1225 - def transformGeoms(self,mol,transform):
1226 # update the transformation to the master geometry 1227 geoms = mol.geomContainer.geoms 1228 geoms['master'].SetRotation(transform.getRotMatrix(shape=(16,), 1229 transpose=1)) 1230 geoms['master'].SetTranslation(transform.getTranslation((3,))) 1231 # update the measure commands 1232 self.vf.measureDistanceGC.update()
1233 1234
1235 - def buildQlistMenu(self):
1236 # get the qlists in the directory in the qdir entryfield 1237 qdir = self.ifd[8]['widget'].get() 1238 if qdir != '': 1239 cmd = 'ls %s/*qlist*' % qdir 1240 else: 1241 cmd = 'ls ./*qlist*' 1242 try: 1243 inputlist = os.popen(cmd).readlines() 1244 except: 1245 msg = 'Problem in directory name' 1246 self.vf.warningMsg(msg) 1247 filelist = [] 1248 for name in inputlist: 1249 filename = string.split(name)[0] 1250 filename = os.path.split(filename)[1] 1251 filelist.append(filename) 1252 filelist.sort() 1253 filelist = tuple(filelist) 1254 self.ifd[9]['widget'].setlist(filelist)
1255 1256
1257 - def getMolVal(self, event=None):
1258 molWidget=self.ifd[0]['widget'] 1259 for molStr in self.molVar.keys(): 1260 #figure out which check button was just changed 1261 newVal=self.molVar[molStr].get() 1262 if newVal==self.oldmolVar[molStr]: 1263 continue 1264 else: 1265 self.oldmolVar[molStr] = newVal 1266 break 1267 # if a new molecule has been selected, put it in the entryfield 1268 curMol = molWidget.get() 1269 if newVal==1: 1270 self.increaseCts(self.molCts,molStr) 1271 if not molStr == curMol: 1272 molWidget.setentry(molStr) 1273 # or if the current molecule has been deselected, clear the entryfield 1274 else: 1275 if molStr == curMol: 1276 self.molCts[molStr]=0 1277 molWidget.setentry('') 1278 # set molVar to zero for all other molecules 1279 # is this necessary? Yes 1280 for mol in self.molVar.keys(): 1281 if mol != molStr: 1282 self.molCts[mol]=0 1283 self.oldmolVar[mol]=0 1284 self.molVar[mol].set(0) 1285 # activate the transformation if a molecule is still selected 1286 if molWidget.get() != '': 1287 molWidget.invoke() 1288 #otherwise clear the form 1289 else: 1290 self.clearForm()
1291
1292 - def buildArgs(self,displayRange=[1]):
1293 args = [] 1294 # widget zero (molecule name) 1295 if self.ifd[0]['widget'].get()=='': 1296 self.vf.warningMsg('Molecule "" does not exist') 1297 return None 1298 else: 1299 molName = self.ifd[0]['widget'].get() 1300 mol = self.vf.expandNodes(molName)[0] 1301 args.append(mol) 1302 # widget two (range) (passed from onIncrement or onChangeRange) 1303 args.append(displayRange) 1304 # widget eight (choice of origin) 1305 # args.append(self.ifd[10]['widget'].getcurselection()) 1306 return args
1307 1308
1309 - def clearForm(self):
1310 self.ifd[0]['widget'].delete(0,'end') 1311 self.ifd[2]['widget'].setentry('0') 1312 self.ifd[3]['widget'].setentry('') 1313 self.ifd[8]['widget'].setentry('') 1314 self.ifd[9]['widget'].setentry('') 1315 self.ifd[9]['widget'].setentry('') 1316 self.ifd[10]['widget'].setentry('') 1317 self.ifd[10]['widget'].setlist(()) 1318 #move cursor back to Molecule entry 1319 self.ifd[0]['widget'].focus() 1320 ###SHOULD ALL THE VARIABLES BE ZEROED HERE??? 1321 for key in self.molCts.keys(): 1322 self.molCts[key]=0 1323 if hasattr(self, 'oldmolVar'): 1324 for item in self.oldmolVar.keys(): 1325 self.oldmolVar[item] = 0 1326 if hasattr(self, 'molVar'): 1327 for item in self.molVar.keys(): 1328 self.molVar[item].set(0) 1329 if self.form: self.form.lift()
1330 1331
1332 - def guiCallback(self):
1333 if not hasattr(self, 'ifd'): 1334 ifd = self.ifd = InputFormDescr(title = 'Transformation Control') 1335 ifd.append({'widgetType':Pmw.EntryField, 1336 'name':'Molecule', 1337 'tooltip':'Select the molecule to be transformed', 1338 'wcfg':{'command':self.onChangeMolecule, 1339 'label_text':'Mobile Mol Name', 1340 'labelpos':'w'}, 1341 'gridcfg':{'sticky':Tkinter.W+Tkinter.E, 1342 'columnspan':3} }) 1343 ifd.append({'name': 'Mol List', 1344 'tooltip':'Select the molecule to be transformed', 1345 'widgetType':Tkinter.Menubutton, 1346 'text': 'Molecule List ...', 1347 'gridcfg':{'sticky':Tkinter.W, 1348 'row':-1, 1349 'columnspan':1} }) 1350 ifd.append({'widgetType':Pmw.Counter, 1351 'name':'TransformNumber', 1352 'wcfg':{'datatype':self.onIncrement, 1353 'entryfield_command':self.onChangeRange, 1354 'entryfield_value':'0', 1355 'autorepeat':0, 1356 'labelpos':Tkinter.W+Tkinter.E, 1357 'label_text':'Transform #'}, 1358 'gridcfg':{'sticky':Tkinter.W, 1359 'columnspan':2,}}) 1360 ifd.append({'name':'Score', 1361 'widgetType':Pmw.EntryField, 1362 'wcfg':{'command':None, 1363 'labelpos':'w', 1364 'label_text':'Score, Cluster Size, (Rmsd)'}, 1365 'gridcfg':{'sticky':Tkinter.W+Tkinter.E, 1366 'row':-1, 1367 'columnspan':2}}) 1368 ifd.append({'name': 'Reset', 1369 'tooltip':'Restores the current molecule to its original position', 1370 'widgetType':Tkinter.Button, 1371 'text': 'Reset', 1372 'wcfg':{'bd':6}, 1373 'gridcfg':{'sticky':Tkinter.W+Tkinter.E, 1374 'columnspan':2}, 1375 'command': self.reset}) 1376 ifd.append({'name': 'ClearForm', 1377 'widgetType':Tkinter.Button, 1378 'text': 'Clear Form', 1379 'wcfg':{'bd':6}, 1380 'gridcfg':{'sticky':Tkinter.W+Tkinter.E, 1381 'row':-1, 1382 'columnspan':2}, 1383 'command': self.clearForm}) 1384 ifd.append({'widgetType':Tkinter.Checkbutton, 1385 'name':'CenterChooser', 1386 'defaultValue':0, 1387 'text':'Choose Center', 1388 'wcfg':{'variable':Tkinter.IntVar()}, 1389 'gridcfg':{'columnspan':2}}) 1390 ifd.append({'widgetType':Tkinter.Button, 1391 'name':'Dismiss', 1392 'text':'Dismiss', 1393 'wcfg':{'bd':6}, 1394 'gridcfg':{'sticky':Tkinter.E+Tkinter.W, 1395 'row':-1, 1396 'columnspan':2}, 1397 'command': self.Dismiss_cb}) 1398 ifd.append({'widgetType':Pmw.EntryField, 1399 'name':'Qdir', 1400 'gridcfg':{'sticky':Tkinter.W+Tkinter.E, 1401 'columnspan':4}, 1402 'wcfg':{'command':self.onChangeQdir, 1403 'label_text':'Qlist Directory', 1404 'labelpos':'w'}}) 1405 ifd.append({'widgetType':Pmw.ComboBox, 1406 'name':'Qfile', 1407 'wcfg':{'label_text':'Qlist Filename', 1408 'labelpos':'w', 1409 'selectioncommand':self.onChangeQlist, 1410 'entryfield_command':self.onChangeQlist, 1411 'scrolledlist_items':()}, 1412 'gridcfg':{'sticky':Tkinter.W+Tkinter.E, 1413 'columnspan':4}}) 1414 ifd.append({'widgetType':Pmw.ComboBox, 1415 'name':'Preferred', 1416 'wcfg':{'label_text':'Preferred List', 1417 'labelpos':'w', 1418 'selectioncommand':self.selFromPref, 1419 'entryfield_command':self.onChangeQlist, 1420 'scrolledlist_items':()}, 1421 'gridcfg':{'sticky':Tkinter.W+Tkinter.E, 1422 'columnspan':2}}) 1423 ifd.append({'widgetType':Tkinter.Button, 1424 'name':'WriteList', 1425 'text':'Write List', 1426 'command':self.writeList, 1427 'wcfg':{'bd':6}, 1428 'gridcfg':{'sticky':Tkinter.W+Tkinter.E, 1429 'row':-1, 1430 'columnspan':2}}) 1431 ifd.append({'widgetType':Tkinter.Button, 1432 'name':'Add', 1433 'text':'Add to list', 1434 'wcfg':{'bd':6}, 1435 'gridcfg':{'sticky':Tkinter.W+Tkinter.E, 1436 'columnspan':2}, 1437 'command': self.addToList}) 1438 ifd.append({'widgetType':Tkinter.Button, 1439 'name':'Remove', 1440 'text':'Remove from list', 1441 'wcfg':{'bd':6}, 1442 'gridcfg':{'sticky':Tkinter.W+Tkinter.E, 1443 'row':-1, 1444 'columnspan':2}, 1445 'command': self.removeFromList}) 1446 ifd.append({'widgetType':Tkinter.Button, 1447 'name':'WritePDB', 1448 'text':'WritePDB', 1449 'command':self.writePdb, 1450 'wcfg':{'bd':6}, 1451 'gridcfg':{'sticky':Tkinter.W+Tkinter.E, 1452 'columnspan':2}}) 1453 ifd.append({'widgetType':Tkinter.Button, 1454 'name':'WritePDBQ', 1455 'text':'WritePDBQ', 1456 'command':self.writePdbq, 1457 'wcfg':{'bd':6}, 1458 'gridcfg':{'sticky':Tkinter.W+Tkinter.E, 1459 'row':-1, 1460 'columnspan':2}}) 1461 ifd.append({'widgetType':Pmw.EntryField, 1462 'name':'RefSet', 1463 'wcfg':{'label_text':'Ref Set', 1464 'labelpos':'w'}, 1465 'gridcfg':{'sticky':Tkinter.W+Tkinter.E, 1466 'columnspan':2} }) 1467 ifd.append({'widgetType':Pmw.EntryField, 1468 'name':'MobSet', 1469 'wcfg':{'label_text':'Mobile Set', 1470 'labelpos':'w'}, 1471 'gridcfg':{'sticky':Tkinter.W+Tkinter.E, 1472 'row':-1, 1473 'columnspan':2} }) 1474 1475 self.form = self.vf.getUserInput(self.ifd, modal = 0, blocking=0) 1476 self.ifd.entryByName['Mol List']['widget'].bind('<ButtonPress>', 1477 self.buildMolMenus,add='+') 1478 else: 1479 self.form.deiconify() 1480 self.form.lift() 1481 return
1482 1483
1484 - def selFromPref(self,entry):
1485 self.ifd[2]['widget'].setentry(entry) 1486 self.onChangeRange() 1487 self.ifd[10]['widget'].setentry(entry)
1488 1489
1490 - def addToList(self):
1491 molName = self.ifd[0]['widget'].get() 1492 mol = self.verifyMolName(molName) 1493 if not mol: 1494 return 1495 if not hasattr(mol,'preferredList'): 1496 mol.preferredList = [] 1497 entries = self.getRange() 1498 for entry in entries: 1499 if entry not in mol.preferredList: 1500 mol.preferredList.append(entry) 1501 self.ifd[10]['widget'].setentry(entry) 1502 mol.preferredList.sort() 1503 self.ifd[10]['widget'].setlist(mol.preferredList)
1504 1505
1506 - def removeFromList(self):
1507 molName = self.ifd[0]['widget'].get() 1508 mol = self.verifyMolName(molName) 1509 if not mol: 1510 msg = 'Please select a molecule' 1511 self.vf.warningMsg(msg) 1512 return 1513 entries = self.getRange() 1514 if hasattr(mol,'preferredList'): 1515 for entry in entries: 1516 if entry in mol.preferredList: 1517 mol.preferredList.remove(entry) 1518 self.ifd[10]['widget'].setlist(mol.preferredList) 1519 self.ifd[10]['widget'].setentry('')
1520 1521
1522 - def writeList(self):
1523 """ 1524 The preferred list is a device for remembering which docking transformations 1525 looked good. Favorable conformations can be added or removed from the list, 1526 which can be written out to a file for future reference. The `rank' record 1527 in the preferred list stores the conformations position in the original 1528 list. 1529 """ 1530 1531 molName = self.ifd[0]['widget'].get() 1532 mol = self.verifyMolName(molName) 1533 if not mol: 1534 msg = 'Please select a molecule' 1535 self.vf.warningMsg(msg) 1536 return 1537 if not hasattr(mol,'preferredList'): 1538 msg = 'The preferred list is empty' 1539 self.vf.warningMsg(msg) 1540 return 1541 if mol.preferredList ==[]: 1542 msg = 'The preferred list is empty' 1543 self.vf.warningMsg(msg) 1544 return 1545 fileTypes = [("Qlist","*qlist*"),("All","*.*"),] 1546 fileBrowserTitle = "Write Quaternion List" 1547 fileName = self.vf.askFileSave(types=fileTypes, 1548 title=fileBrowserTitle) 1549 if fileName: 1550 outfile = open(fileName,'w') 1551 else: 1552 return 1553 for x in mol.preferredList: 1554 outstring= "%s %s %s\n" % (mol.qlist['energy'][x-1], 1555 mol.qlist['rawtransforms'][x-1].output(), 1556 x) 1557 outfile.write(outstring) 1558 outfile.close()
1559 1560
1561 - def writePdb(self):
1562 """ 1563 The WritePDB and WritePDBQ buttons cause the coordinates to be updated by 1564 the current transformations applied to the geometries, and then written 1565 out. Since these transformations need not have arisen from the qlist, these 1566 commands are more generally useful: e.g. they can be used to write out the 1567 transformed coordinates resulting from the superimpose commands 1568 """ 1569 molName = self.ifd[0]['widget'].get() 1570 mol = self.verifyMolName(molName) 1571 if mol: 1572 #set to the transformed set of coordinates 1573 fileBrowserTitle='PDB files' 1574 fileName = self.vf.askFileSave(types=[("pdb","*.pdb"),], 1575 title=fileBrowserTitle) 1576 if fileName: 1577 masterG = mol.geomContainer.geoms['master'] 1578 rot = masterG.rotation 1579 trans = masterG.translation 1580 rotM = Numeric.reshape(rot,(4,4)) 1581 quat = rotax.mat_to_quat(rotM) 1582 transform = Transform(quaternion=quat,trans=trans) 1583 self.transformMol(mol,transform) 1584 mol.allAtoms.setConformation(1) 1585 self.vf.writePDB(mol, filename=fileName) 1586 #self.vf.writePDB(fileName,mol) 1587 mol.allAtoms.setConformation(0)
1588 1589
1590 - def writePdbq(self):
1591 """ 1592 The WritePDB and WritePDBQ buttons cause the coordinates to be updated by 1593 the current transformations applied to the geometries, and then written 1594 out. Since these transformations need not have arisen from the qlist, these 1595 commands are more generally useful: e.g. they can be used to write out the 1596 transformed coordinates resulting from the superimpose commands 1597 """ 1598 molName = self.ifd[0]['widget'].get() 1599 mol = self.verifyMolName(molName) 1600 if mol: 1601 #set to the transformed set of coordinates 1602 fileBrowserTitle='PDBQ files' 1603 fileName = self.vf.askFileSave(types=[("pdbq","*.pdbq"),], 1604 title=fileBrowserTitle) 1605 if fileName: 1606 masterG = mol.geomContainer.geoms['master'] 1607 rot = masterG.rotation 1608 trans = masterG.translation 1609 rotM = Numeric.reshape(rot,(4,4)) 1610 quat = rotax.mat_to_quat(rotM) 1611 transform = Transform(quaternion=quat,trans=trans) 1612 self.transformMol(mol,transform) 1613 mol.allAtoms.setConformation(1) 1614 self.vf.writePDBQ(mol, fileName) 1615 #self.vf.writePDBQ(fileName,mol) 1616 mol.allAtoms.setConformation(0)
1617 1618
1619 - def onIncrement(self,text,factor,increment):
1620 try: 1621 value = int(text) 1622 value = value + (factor*increment) 1623 if value < 0: 1624 value = 0 1625 args = self.buildArgs([value]) 1626 mol = args[0] 1627 #if not mol: 1628 # return 1629 maxval = len(mol.qlist['totaltransforms']) 1630 if value > maxval: 1631 value = maxval 1632 args = self.buildArgs([value]) 1633 apply(self.doitWrapper, tuple(args),{'redraw':1}) 1634 self.ifd[10]['widget'].setentry('') 1635 return str(value) 1636 except: 1637 msg = 'Error in range:\n %s' % text 1638 self.vf.warningMsg(msg) 1639 return text
1640 1641
1642 - def onChangeMolecule(self):
1643 #update the entry in the qlist fileName field 1644 molName = self.ifd[0]['widget'].get() 1645 mol = self.verifyMolName(molName) 1646 if mol: 1647 if hasattr(mol,'qlist'): 1648 # update the widget entryfields 1649 self.ifd[2]['widget'].setentry(mol.currentQ) 1650 if mol.currentQ > 0: 1651 score = mol.qlist['energy'][mol.currentQ] 1652 clusterSize = mol.qlist['cluster'][mol.currentQ] 1653 score = "%s, %s" % (score,clusterSize) 1654 else: 1655 score = "" 1656 self.ifd[3]['widget'].setentry(score) 1657 self.ifd[9]['widget'].setentry(mol.qfile) 1658 self.ifd[8]['widget'].setentry(mol.qdir) 1659 self.lastDir=mol.qdir 1660 else: 1661 curdir = os.getcwd() 1662 curdir = string.replace(curdir,'/tmp_mnt','') 1663 self.ifd[2]['widget'].setentry(0) 1664 self.ifd[3]['widget'].setentry('') 1665 self.ifd[8]['widget'].setentry(curdir) 1666 self.ifd[9]['widget'].setentry('') 1667 if hasattr(mol,'preferredList'): 1668 self.ifd[10]['widget'].setlist(mol.preferredList) 1669 else: 1670 self.ifd[10]['widget'].setlist([]) 1671 self.ifd[10]['widget'].setentry('') 1672 self.buildQlistMenu() 1673 #modify the molCts dictionary 1674 for key in self.molCts.keys(): 1675 if key == molName: 1676 self.molCts[key]=1 1677 else: 1678 self.molCts[key]=0 1679 else: 1680 self.clearForm()
1681 1682
1683 - def onChangeRange(self):
1684 displayRange = self.getRange() 1685 if displayRange: 1686 args = self.buildArgs(displayRange) 1687 else: 1688 return None 1689 if args: 1690 apply(self.doitWrapper, tuple(args), {'redraw':1}) 1691 self.ifd[10]['widget'].setentry('') 1692 else: 1693 return None
1694
1695 - def getRange(self):
1696 str_range = self.ifd[2]['widget'].get() 1697 if not str_range: 1698 str_range='0' 1699 self.ifd[2]['widget'].setentry(str_range) 1700 list_range = string.split(str_range,',') 1701 int_range = [] 1702 try: 1703 for item in list_range: 1704 if item: 1705 if '-' in item: 1706 item = string.split(item,'-') 1707 if item[1]!='': 1708 if int(item[1])<int(item[0]): 1709 item = range(int(item[0]),int(item[1])-1,-1) 1710 else: 1711 item = range(int(item[0]),int(item[1])+1) 1712 else: 1713 item = [int(item[0])] 1714 for x in item: 1715 int_range.append(x) 1716 else: 1717 int_range.append(int(item)) 1718 return int_range 1719 except: 1720 msg = 'Error in range:\n %s' % str_range 1721 self.vf.warningMsg(msg) 1722 return None
1723 1724 1725
1726 - def onChangeQdir(self):
1727 newdirName = self.ifd[8]['widget'].get() 1728 molName = self.ifd[0]['widget'].get() 1729 mol = self.verifyMolName(molName) 1730 if hasattr(mol,'qdir'): 1731 if mol.qdir != newdirName: 1732 self.ifd[9]['widget'].setentry('') 1733 self.buildQlistMenu()
1734
1735 - def onChangeQlist(self,entry):
1736 #update the qlist 1737 newdirName = self.ifd[8]['widget'].get() 1738 newfileName = self.ifd[9]['widget'].get() 1739 molName = self.ifd[0]['widget'].get() 1740 mol = self.verifyMolName(molName) 1741 if mol: 1742 fullName = newdirName+'/'+newfileName 1743 if self.ifd[6]['wcfg']['variable'].get(): 1744 center = 'ask' 1745 else: 1746 center = None 1747 self.vf.readTransformations(molName,fullName,center) 1748 self.ifd[8]['widget'].setentry(mol.qdir) 1749 self.ifd[9]['widget'].setentry(mol.qfile) 1750 self.ifd[10]['widget'].setlist(mol.preferredList) 1751 self.ifd[10]['widget'].setentry('') 1752 mol.qfile = newfileName 1753 mol.qdir = newdirName 1754 self.buildQlistMenu() 1755 self.reset() 1756 return None
1757
1758 - def verifyMolName(self,molName):
1759 if not molName: 1760 return None 1761 molName = string.split(molName,',') 1762 if len(molName) != 1: 1763 msg = 'You must select one molecule only' 1764 self.vf.warningMsg(msg) 1765 return None 1766 molName = molName[0] 1767 mol = self.vf.expandNodes(molName) 1768 if not mol: 1769 msg = "Molecule '%s' does not exist" % molName 1770 self.vf.warningMsg(msg) 1771 return None 1772 mol = mol[0] 1773 return mol
1774
1775 -class ReadTransformations(MVCommand):
1776 """ This command is invoked everytime the Qlist Filename entryfield is 1777 invoked. If the Center Chooser checkbutton is on, the CenterChooser 1778 popup dialog will come up to allow the center of rotation to be 1779 defined before the transformation list is read in. If this is turned 1780 off, the center of rotation defaults to either the previous center (if 1781 readTransformations has been invoked previously for this molecule), or to 1782 the molecules center of gravity. 1783 readTransformations then reads in lines from the file, which have the 1784 format 'score tx ty tz rx ry rz theta rank'. These are converted into 1785 a list of raw transformations (needed for writing out the preferred 1786 list), and also a list of total transformations (which take into 1787 account the center of rotation) 1788 """ 1789
1790 - def __call__(self,molName,fileName,center=None,**kw):
1791 mol = self.vf.expandNodes(molName)[0] 1792 if mol: 1793 if center == 'ask': 1794 center = CenterChooser(self.vf).go() 1795 apply( self.doitWrapper, (mol,fileName,center), kw)
1796 1797
1798 - def guiCallback(self):
1799 # get the molecule for which this is being read 1800 mol = MoleculeChooser(self.vf).go() 1801 if not mol: 1802 return None 1803 molName = mol.name 1804 1805 # get the center for the rotations 1806 # (default center of mass) 1807 center = CenterChooser(self.vf).go() 1808 # get the transformations file 1809 fileTypes = [("Transformation lists","*qlist*"),] 1810 fileBrowserTitle = "Read Transformation File" 1811 fileName = self.vf.askFileOpen(types=fileTypes, 1812 title=fileBrowserTitle) 1813 if not fileName: 1814 return 1815 1816 self.doitWrapper(mol,fileName,center=center)
1817 1818 1819
1820 - def doit(self,mol,fileName,center=None,**kw):
1821 #get the molecule to attach the qlist to the molecule 1822 if not mol: 1823 msg = "There is no molecule '%s'" % molName 1824 self.vf.warningMsg(msg) 1825 return None 1826 if hasattr(mol,'preferredList'): 1827 if mol.preferredList != []: 1828 msg = 'Reading in new quaternions will destroy the preferred list.' 1829 proceed = tkMessageBox.askokcancel('Read Quaternions',msg) 1830 if not proceed: 1831 return None 1832 try: 1833 file = open(fileName,'r') 1834 except: 1835 msg = 'File %s does not exist' % (fileName,) 1836 self.vf.warningMsg(msg) 1837 return 1838 mol.preferredList=[] 1839 qdata = file.readlines() 1840 file.close() 1841 qlist = {} 1842 qlist['energy']=[] 1843 qlist['totaltransforms']=[] 1844 qlist['rawtransforms']=[] 1845 qlist['cluster']=[] 1846 #sort out the center 1847 if not hasattr(mol,'centerR'): 1848 if not center: center = 'Center on Molecule' 1849 if center: 1850 if center == 'Center on Molecule': 1851 ats = mol.allAtoms 1852 mol.centerR = N.sum(ats.coords)/len(ats.coords) 1853 elif center == 'Center on Selection': 1854 sel = self.vf.getSelection() 1855 ats = self.vf.getNodesByMolecule(sel, Atom)[1] 1856 coordsum =0.0 1857 Ncoords = 0 1858 for set in ats: 1859 coordsum = coordsum + N.sum(set.coords) 1860 Ncoords = Ncoords + len(set.coords) 1861 mol.centerR = coordsum/Ncoords 1862 else: 1863 mol.centerR = N.array(center) 1864 #set up the transforms to and from the center of rotation 1865 fromCenter = Transform(trans = -mol.centerR) 1866 toCenter = fromCenter.inverse() 1867 #build the transformations list 1868 for line in qdata: 1869 numbers = string.split(line) 1870 if len(numbers) < 9: 1871 msg = 'Error in file' 1872 self.vf.warningMsg(msg) 1873 return None 1874 trans = N.array(map(lambda x: float(x), numbers[1:4]),'f') 1875 quat = N.array(map(lambda x: float(x), numbers[4:8]),'f') 1876 transl = Transform(trans = trans) 1877 rotate = Transform(quaternion = quat) 1878 RawTrans = transl*rotate 1879 Trans = transl*toCenter*rotate*fromCenter 1880 qlist['energy'].append(numbers[0]) # score 1881 qlist['totaltransforms'].append(Trans) # transformation 1882 qlist['rawtransforms'].append(RawTrans) # transform as read in 1883 qlist['cluster'].append(numbers[8]) # cluster rank 1884 #update the molecules property list 1885 mol.qlist = qlist 1886 mol.qfile = os.path.split(fileName)[1] 1887 mol.qdir = os.path.split(fileName)[0] 1888 mol.currentQ = 0 1889 self.lastDir = mol.qdir
1890 #if the applyTransformations GUI exists, update it 1891 # if hasattr(self.vf.applyTransformations,'ifd'): 1892 # applyT = self.vf.applyTransformations.ifd 1893 # applyT 1894 1895 1896
1897 -class SelectVertex(Command, ICOM):
1898 """This command allows a user to pick a vertex. 1899 """ 1900
1901 - def __init__(self, func=None):
1902 Command.__init__(self, func) 1903 ICOM.__init__(self)
1904 # self.objArgOnly = 1 1905 # self.negateKw = 1 1906 1907
1908 - def setupUndoBefore(self, obj):
1909 root = self.vf.GUI.VIEWER.rootObject 1910 piv = tuple(root.pivot) 1911 self.addUndoCall( (root, piv), {}, self.vf.centerGeom.name )
1912 1913
1914 - def doit(self, objects):
1915 # objects is pick.hist = {geom: [(vertexInd, intance),...]} 1916 vt = [] 1917 print "\nobjects clicked by left button: \n", objects 1918 for geom, values in objects.items(): 1919 # print " geom: ", geom 1920 # print " values: ", values 1921 for vert, instance in values: 1922 # print properties 1923 Area = geom.properties['Area'][vert] 1924 ShapeIndex = geom.properties['ShapeIndex'][vert] 1925 Curvedness = geom.properties['Curvedness'][vert] 1926 Hydro1 = geom.properties['Hydro1'][vert] 1927 Hydro2 = geom.properties['Hydro2'][vert] 1928 Electro = geom.properties['Electro'][vert] 1929 Bval = geom.properties['Bval'][vert] 1930 Kmin = geom.properties['Kmin'][vert] 1931 Kmax = geom.properties['Kmax'][vert] 1932 self.vf.message( '\n'+ geom.name + ' - Vertex (zero-based): %d'%( vert ) ) 1933 self.vf.message( ' Area: %.3f, ShapeIndex: %.3f, Curvedness: %.3f\n Hydro1: %.3f, Hydro2: %.3f, Electro: %.3f\n Bval: %.3f, Kmin: %.3f, Kmax: %.3f' 1934 %( Area, ShapeIndex, Curvedness, 1935 Hydro1, Hydro2, Electro, 1936 Bval, Kmin, Kmax ) ) 1937 # print original coordinates and normals 1938 pt = geom.vertices[vert] 1939 nm = geom.vnormals[vert] 1940 self.vf.message( ' Original coordinate: %.3f, %.3f, %.3f'%(pt[0], pt[1], pt[2]) ) 1941 self.vf.message( ' Original normal: %.3f, %.3f, %.3f'%(nm[0], nm[1], nm[2]) ) 1942 # print current coordinates and normals 1943 M = geom.GetMatrix(geom.LastParentBeforeRoot(), instance[1:]) 1944 ptx = M[0][0]*pt[0]+M[0][1]*pt[1]+M[0][2]*pt[2]+M[0][3] 1945 pty = M[1][0]*pt[0]+M[1][1]*pt[1]+M[1][2]*pt[2]+M[1][3] 1946 ptz = M[2][0]*pt[0]+M[2][1]*pt[1]+M[2][2]*pt[2]+M[2][3] 1947 vt.append( (ptx, pty, ptz) ) 1948 nmx = M[0][0]*nm[0]+M[0][1]*nm[1]+M[0][2]*nm[2]+M[0][3] 1949 nmy = M[1][0]*nm[0]+M[1][1]*nm[1]+M[1][2]*nm[2]+M[1][3] 1950 nmz = M[2][0]*nm[0]+M[2][1]*nm[1]+M[2][2]*nm[2]+M[2][3] 1951 self.vf.message( ' Current coordinate: %.3f, %.3f, %.3f'%(ptx, pty, ptz) ) 1952 self.vf.message( ' Current normal: %.3f, %.3f, %.3f'%(nmx, nmy, nmz) ) 1953 # print (on python shell) instance and transformation matrix applied 1954 print " instance: ", instance 1955 print " transformation matrix M applied: \n", M 1956 g = [0,0,0] 1957 i = 0 1958 for v in vt: 1959 g[0] += v[0] 1960 g[1] += v[1] 1961 g[2] += v[2] 1962 i+=1 1963 g[0] = g[0]/i 1964 g[1] = g[1]/i 1965 g[2] = g[2]/i 1966 self.vf.centerGeom( 'root', g, topCommand=0, log=1, setupUndo=1)
1967 1968
1969 - def __call__(self, nodes, **kw):
1970 # we do not want this command to log or undo itself 1971 kw['topCommand']=0 1972 kw['busyIdle']=1 1973 apply( self.doitWrapper, (nodes,), kw )
1974 1975 1976 1977 1978 ReadTransformationsGUI = CommandGUI() 1979 ReadTransformationsGUI.addMenuCommand('menuRoot', 'Surfdock', 'Read Transformation') 1980 ApplyTransformationsGUI = CommandGUI() 1981 ApplyTransformationsGUI.addMenuCommand('menuRoot', 'Surfdock', 'Apply Transformation') 1982 ReadDockdataGUI = CommandGUI() 1983 ReadDockdataGUI.addMenuCommand('menuRoot', 'Surfdock', 'Read Dockdata Surface') 1984 ReadHarmonyGUI = CommandGUI() 1985 ReadHarmonyGUI.addMenuCommand('menuRoot', 'Surfdock', 'Read Harmony Surface') 1986 ReadBlurGUI = CommandGUI() 1987 ReadBlurGUI.addMenuCommand('menuRoot', 'Surfdock', 'Read Blur Surface') 1988 DisplayMolIndexedPolygonsGUI = CommandGUI() 1989 DisplayMolIndexedPolygonsGUI.addMenuCommand('menuRoot', 'Display','Surfdock Surface') 1990 ColorMolIndexedPolygonsGUI = CommandGUI() 1991 ColorMolIndexedPolygonsGUI.addMenuCommand('menuRoot', 'Surfdock','Color Surface By Property') 1992 SelectVertexGUI = CommandGUI() 1993 SelectVertexGUI.addMenuCommand('menuRoot', 'Surfdock', 'Select A Vertex') 1994 1995