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

Source Code for Module Pmv.secondaryStructureCommands

   1  ############################################################################# 
   2  # 
   3  # Author: Sophie I. COON, Michel F. SANNER 
   4  # 
   5  # Copyright: M. Sanner TSRI 2000 
   6  # 
   7  ############################################################################# 
   8  # 
   9  # $Header: /opt/cvs/python/packages/share1.5/Pmv/secondaryStructureCommands.py,v 1.91.2.1 2007/09/08 00:05:55 mgltools Exp $ 
  10  # 
  11  # $Id: secondaryStructureCommands.py,v 1.91.2.1 2007/09/08 00:05:55 mgltools Exp $ 
  12  # 
  13   
  14   
  15  from Tkinter import Label, Checkbutton, Radiobutton, StringVar, IntVar 
  16  import Pmw 
  17  import types 
  18  from types import StringType, IntType 
  19   
  20  from opengltk.OpenGL import GL 
  21  from DejaVu.IndexedPolygons import IndexedPolygons 
  22  from DejaVu.Shapes import Shape2D, Triangle2D, Circle2D, Rectangle2D,\ 
  23       Square2D, Ellipse2D 
  24  from NucleicBases import Add_Nucleic_Bases 
  25  from ViewerFramework.VFCommand import CommandGUI 
  26  from mglutil.gui.InputForm.Tk.gui import InputFormDescr 
  27  from mglutil.gui.BasicWidgets.Tk.customizedWidgets import ExtendedSliderWidget, ListChooser,\ 
  28       SliderWidget 
  29  from MolKit.tree import TreeNode, TreeNodeSet 
  30  from MolKit.molecule import Atom, AtomSet, Molecule, MoleculeSet 
  31  from MolKit.protein import Protein, Residue, Chain, ResidueSet, ProteinSet 
  32  from MolKit.protein import SecondaryStructure, SecondaryStructureSet, \ 
  33       Helix, Strand, Turn, Coil 
  34  from MolKit.moleculeParser import MoleculeParser 
  35   
  36  #from ViewerFramework.drawShape import DrawShape 
  37   
  38  from Pmv.mvCommand import MVCommand 
  39  from Pmv.extruder import Sheet2D, ExtrudeSSElt, ExtrudeNA 
  40  from Pmv.displayCommands import DisplayCommand 
  41  from Pmv.colorCommands import ColorFromPalette 
  42  from Pmv.colorPalette import ColorPalette 
  43   
  44   
45 -class ComputeSecondaryStructureCommand(MVCommand):
46 """The computeSecondaryStructure command gets the information on the secondary structure of each molecule contained in the current selection.This information is then used to create object describing the various secondary structure elements. 47 \nPackage : Pmv 48 \nModule : secondaryStructureCommands 49 \nClass : ComputeSecondaryStructureCommand 50 \nCommand name : computeSecondaryStructure 51 \nDescription:\n 52 The SS element object belonging to a chain are then grouped into sets. 53 A new level is added in the 4 level hierarchy... 54 The information is taken from the file when available or using stride when 55 available.This command can be used as an interactive command. 56 \nSynopsis:\n 57 None <--- ComputeSS(nodes, molMode={}, **kw) 58 \nRequired Arguments:\n 59 nodes --- any set for MolKit nodes describing molecular components 60 \nOptional Arguments:\n 61 \nmolmode --- dictionary key: molecule name, value : 'From File' or 'From Stride'. 62 \nRequired Packages:\n 63 MolKit, DejaVu, mglutil, OpenGL, Tkinter, Pmw, types, ViewerFramework 64 \nKnown bugs:\n 65 None 66 \nExamples:\n 67 mol = mv.Mols[0] 68 \nmv.computeSecondaryStructure(mv.getSelection()) 69 """ 70 71
72 - def __init__(self):
73 MVCommand.__init__(self) 74 self.flag = self.flag | self.objArgOnly
75 76
77 - def onRemoveObjectFromViewer(self, obj):
78 """ 79 Method to delete sets created by this command. 80 This is done to prevent circular references and memory leaks. 81 """ 82 if not hasattr(obj, 'chains'): return 83 import sys 84 for c in obj.chains: 85 if not hasattr(c, 'secondarystructureset') : 86 continue 87 if c.secondarystructureset is None: 88 delattr(c.secondarystructureset) 89 else: 90 # Cleaning up all the circular references created in this 91 # command 92 while len(c.secondarystructureset)!=0: 93 if hasattr(c.secondarystructureset[0], 'exElt'): 94 delattr(c.secondarystructureset[0], 'exElt') 95 delattr(c.secondarystructureset[0], 'children') 96 delattr(c.secondarystructureset[0], 'residues') 97 delattr(c.secondarystructureset[0], 'start') 98 delattr(c.secondarystructureset[0], 'end') 99 delattr(c.secondarystructureset[0], 'parent') 100 delattr(c.secondarystructureset[0], 'chain') 101 delattr(c.secondarystructureset[0], 'top') 102 del(c.secondarystructureset[0])
103
104 - def onAddCmdToViewer(self):
105 # Try to import stride and set the flag to 1 if succeeds and to 0 if 106 # does not 107 try: 108 import stride 109 self.haveStride = 1 110 except: 111 self.haveStride = 0 112 113 # Load the dependent commands if not already loaded in the 114 # application 115 if self.vf.hasGui and not self.vf.commands.has_key('saveSet'): 116 self.vf.loadCommand("selectionCommands", "saveSet", "Pmv", 117 topCommand=0)
118 119 ## if self.vf.hasGui and not self.vf.commands.has_key('selectSet'): 120 ## self.vf.loadCommand("selectionCommands", "selectSet", "Pmv", 121 ## topCommand=0) 122
123 - def __call__(self, nodes, molModes = None, **kw):
124 """None <--- computeSecondaryStructure(nodes, molModes = None, **kw) 125 \nnodes --- TreeNodeSet holding the current selection. 126 \nmoldMode --- dictionary {name of the protein: 'From File' or From Stride'}, 127 'From File' to get the information from the file, 128 'From Stride' to use stride. 129 """ 130 if type(nodes) is StringType: 131 self.nodeLogString = "'"+nodes+"'" 132 nodes = self.vf.expandNodes(nodes) 133 if not nodes: return 134 kw['molModes'] = molModes 135 apply(self.doitWrapper, (nodes,), kw)
136 137
138 - def doit(self, nodes, molModes = None):
139 molecules, nodeSets = self.vf.getNodesByMolecule(nodes) 140 if len(molecules)==0 : return 141 # Loop over the molecules 142 for mol in molecules: 143 # Determine what mode to use to get the information 144 if molModes is None: 145 # If no mode to get the information is specified 146 if mol.hasSS: 147 # Information has already been computed then 148 # continue 149 continue 150 else: 151 # Find out the possibilities and set the mode to 152 # one of them. 153 if mol.parser.hasSsDataInFile(): 154 # File contains information the mode will be 'From 155 # File' 156 mode = 'From File' 157 elif self.haveStride: 158 # Stride is available on the platform 159 # but no info in the file then stride will be used 160 mode='From Stride' 161 else: 162 # Nothing to be done maybe print a message to the user. 163 self.warningMsg(mol.name + \ 164 ".pdb does not contain Secondary Structure information and Stride is not available on this computer to compute the secondary structure") 165 continue 166 else: 167 # a mode to get the information has been specified 168 # for the given molecules 169 if not molModes.has_key(mol.name): 170 # if the mode has not been specified for a molecule 171 # print a message and continue 172 print 'No mode has been specifyed for %s'%mol.name 173 continue 174 else: 175 # Set the mode to the given value. 176 mode = molModes[mol.name] 177 # if this mode has already been used pass. 178 if mode in mol.hasSS: continue 179 # if secondarystructure have been computed once using another 180 # mode need to clean up first 181 182 elif mol.hasSS != []: 183 self.clean(mol) 184 185 # Then compute using the new given mode. 186 if mode == 'From File': 187 # If both modes available try file first if fails use stride 188 # instead. 189 if not mol.parser.hasSsDataInFile(): 190 # GIVE FEEDBACK TO THE USER !!!! 191 self.warningMsg("WARNING: "+mol.name + \ 192 ".pdb does not contain Secondary \ 193 Structure information.") 194 continue 195 else: 196 mol.secondaryStructureFromFile() 197 self.savesets(mol) 198 199 elif mode == 'From Stride': 200 if not self.haveStride: 201 self.warningMsg("WARNING: Stride is not available on \ 202 this computer to compute the secondary structure of "+\ 203 mol.name+".pdb") 204 continue 205 else: 206 mol.secondaryStructureFromStride() 207 self.savesets(mol)
208
209 - def savesets(self, mol):
210 for c in mol.chains: 211 if not hasattr(c, 'secondarystructureset'): continue 212 for ss in c.secondarystructureset: 213 name = "%s%s"%(ss.name, ss.chain.id) 214 self.vf.saveSet(ss.residues, mol.name+':'+name[-1] 215 +':'+name[:-1], 216 '%s-%s' %(ss.residues[0].name, 217 ss.residues[-1].name), 218 topCommand=0)
219 220
221 - def clean(self, mol):
222 """ 223 This method is called when getting the secondary structure information 224 using stride after having from file and vice versa. It is used to 225 delete all the secondary structure objects and attributes created 226 previously.""" 227 # Compute secondary structure creates the following: 228 # - Secondary structure elements 229 # - Save the secondary structure elements residues as a set 230 # - new mol attribute hasSS which is a list 231 #from Pmv.selectionCommands import sets__ 232 molName = mol.name 233 mol.hasSS = [] 234 # Here need to check if the secondary structure element have 235 # been extruded or not. If yes need to clean up that as well. 236 if hasattr(mol, '_ExtrudeSecondaryStructureCommand__hasSSGeom')\ 237 and mol._ExtrudeSecondaryStructureCommand__hasSSGeom: 238 self.vf.extrudeSecondaryStructure.onRemoveObjectFromViewer(mol) 239 240 for chain in mol.chains: 241 # delete the secondarystructureset 242 if not hasattr(chain, 'secondarystructureset'): continue 243 for ss in chain.secondarystructureset: 244 name = "%s%s"%(ss.name, ss.chain.id) 245 del self.vf.sets[mol.name+':'+name[-1]+':'+name[:-1]] 246 #del sets__[mol.name+':'+name[-1]+':'+name[:-1]] 247 delattr(chain, 'secondarystructureset') 248 249 # delete the secondarystructure attribute of the residues when 250 # existing. 251 resWithSS = filter(lambda x:hasattr(x, 'secondarystructure'), 252 chain.residues) 253 resTest = map(lambda x: 254 delattr(x, 'secondarystructure'), 255 resWithSS) 256 257 # call the onRemoveObjectFromViewer for the mol. 258 self.onRemoveObjectFromViewer(mol) 259 260 # Also need to clean up the sheet2D information. 261 for c in mol.chains: 262 if hasattr(c, 'sheet2D') and c.sheet2D.has_key('ssSheet2D'): 263 del c.sheet2D['ssSheet2D']
264
265 - def buildFormDescr(self, formName):
266 """ 267 Build the form description for the given form name. 268 """ 269 self.nodes = self.vf.getSelection() 270 molecules = self.nodes.top.uniq() 271 self.molModes = {} 272 if len(molecules)==0: return 273 idf = InputFormDescr(title="Get SS Information:") 274 275 haveStride = self.haveStride 276 for mol in molecules: 277 if not Chain in mol.levels: continue 278 haveInFile = mol.parser.hasSsDataInFile() 279 molName = mol.name + ' : ' 280 if not haveStride and not haveInFile: 281 # No Information available for that mol. 282 idf.append({ 283 'widgetType':Label, 284 'wcfg':{'text':molName}, 285 'gridcfg':{'sticky':'w'}}) 286 287 idf.append({'widgetType':Label, 288 'wcfg':{'text':'No information available'}, 289 'gridcfg':{'sticky':'w', 'row':-1}}) 290 291 elif haveStride and not haveInFile: 292 idf.append({'widgetType':Label, 293 'wcfg':{'text':molName}, 294 'gridcfg':{'sticky':'w'}}) 295 #idf.append(labelWidgetDescr) 296 idf.append({'widgetType':Label, 297 'wcfg':{'text':'From Stride'}, 298 'gridcfg':{'sticky':'w', 'row':-1}}) 299 self.molModes[mol.name]='From Stride' 300 301 elif not haveStride and haveInFile: 302 idf.append({'widgetType':Label, 303 'wcfg':{'text':molName}, 304 'gridcfg':{'sticky':'w'}}) 305 #idf.append(labelWidgetDescr) 306 idf.append({'widgetType':Label, 307 'name':'From File', 308 'wcfg': 309 {'text':'From File'}, 310 'gridcfg':{'sticky':'w', 'row':-1}}) 311 self.molModes[mol.name]='From File' 312 313 else: 314 if 'From File' in mol.hasSS: 315 defaultValue = 'From Stride' 316 else: 317 defaultValue = 'From File' 318 319 idf.append({'name':mol.name, 320 'widgetType': Pmw.RadioSelect, 321 'groupedBy':1, 322 'listtext':['From File', 'From Stride'], 323 'defaultValue': defaultValue, 324 'wcfg':{'label_text':molName, 325 'labelpos':'w' 326 }, 327 'gridcfg':{'sticky':'ew'}}) 328 329 return idf
330
331 - def guiCallback(self):
332 val = self.showForm('getSSInfo', force=1) 333 for key,value in val.items(): 334 self.molModes[key] = value 335 del val[key] 336 if self.molModes == {}: 337 return 338 val['molModes'] = self.molModes 339 apply(self.doitWrapper, (self.nodes,), val)
340 341
342 -class ExtrudeSecondaryStructureCommand(MVCommand):
343 """The ExtrudeCommand allows the user to represent the secondary structure elements by extruding 2D geometries along a 3D path.To execute this command use the entry 'extrude Secondary Structure' under the 'Compute' menu in the menu bar. 344 The panel that appears lets the user choose the 2D shapes for the extrusion. The entry 'default' in the listChooser lets do a traditional ribbon representation.nbchords represents the number of points in the path3D corresponding to one residue. The higher this parameter is the smoother the extruded geometries will look.gapBeg allows the user to introduce a gap of gapBeg points the extruded geometrie before each residues.gapEnd allows the user to introduce a gap of gapEnd points the extruded geometrie after each residues.The value of this two parameters depend on the value of the nbchords parameter and on each other's value.Once you clique OK on this panel another panel appears to let the user caracterize the chosen 2D geometry.Once the user chose all the parameters an ExtrudeSSElt object is created for each secondary structure element. The geometries associated to each secondary structure element are then updated with the new vertices and faces.Finally the displaySSCommand is executed.This command has the objArgsOnly flag. 345 \nPackage : Pmv 346 \nModule : secondaryStructureCommands 347 \nClass : ExtrudeSecondaryStructureCommand 348 \nCommand name : extrudeSecondaryStructure 349 \nSynopsis:\n 350 None <--- extrudeSecondaryStructure(nodes, shape1=None, shape2=None,frontcap=1, endcap=True, arrow=True, nbchords=4, gapBeg=False,gapEnd=False, larrow=2, display=True,**kw) 351 \nRequired Arguments:\n 352 nodes --- TreeNodeSet holding the current selection(mv.getSelection()) 353 \nOptional Arguments:\n 354 shape1 & 355 shape2 --- DejaVu.Shapes.Shape2D objects. shape1 will be used to 356 represent the helix and strand, shape2 to represent coils and 357 turns. 358 \nfrontcap & 359 endcap --- Boolean flag when set to True a cap will be added to the 360 geom either at the front or at the end 361 \narrow --- Boolean flag when set to True an arow will be added to the 362 geometry representing the strand. 363 \nnbchords --- Nb of points per residues in the smooth array 364 \ngapBeg& 365 gapEnd --- defines gap at the beginning or the end of each residue. 366 \nlarrow --- lenth of the arrow if arrow boolean flag set to 1 367 \ndisplay --- Boolean flag when set to True the displaySecondaryStructure 368 is called automatically 369 """ 370
371 - def __init__(self):
372 MVCommand.__init__(self) 373 self.flag = self.flag | self.objArgOnly 374 #this flag is used when calling Nucleic_Acids_properties.guiCallback 375 #to avoid calling it more than once for a given molecule 376 self.flagNucleicAcidsProperties = True
377
378 - def pickedVerticesToAtoms(self, geom, vertInd):
379 """ 380 This function gets called when a picking or drag select event has 381 happened. It gets called with a geometry and the list of vertex 382 indices of that geometry that have been picked. 383 This function is in charge of turning these indices into an AtomSet 384 This function takes the following arguments: 385 geom : geometry picked, instance of a class derived from DejaVu.Geom 386 (IndexedPolygons, IndexedPolylines.....) 387 vertInd: list of integer representing the indices of the picked 388 vertices in the given geometry geom. 389 """ 390 391 # this function gets called when a picking or drag select event has 392 # happened. It gets called with a geometry and the list of vertex 393 # indices of that geometry that have been selected. 394 # This function is in charge of turning these indices into an AtomSet 395 ss = geom.SS 396 l = [] 397 for vi in vertInd: 398 resInd = ss.exElt.getResIndexFromExtrudeVertex( vi ) 399 400 l.append(ss.children[int(resInd)].atoms[0]) 401 return AtomSet( AtomSet( l ) )
402
403 - def atomPropToVertices(self, geom, residues, propName, propIndex=None):
404 """Function called to compute the array of properties""" 405 if residues is None or len(residues)==0 : return None 406 propVect = [] 407 if not propIndex is None: 408 propIndex = 'secondarystructure' 409 for r in residues: 410 prop = getattr(r.atoms[0], propName) 411 if not propIndex is None: 412 propVect.append(prop[propIndex]) 413 else: 414 propVect.append(prop) 415 geom.SS.exElt.setResProperties(propVect, propName, residues) 416 properties = geom.SS.exElt.getExtrudeProperties( residues, propName ) 417 return properties
418
419 - def onAddObjectToViewer(self, obj):
420 # private flag to specify whether or not the geometries for the SS 421 # have been created. 422 obj.__hasSSGeom = 0
423
424 - def createGeometries(self, obj):
425 if obj.__hasSSGeom : 426 return 427 from DejaVu.Geom import Geom 428 geomC = obj.geomContainer 429 430 if not geomC.geoms.has_key('secondarystructure'): 431 432 t = Geom('secondarystructure', shape=(0,0), protected=True) 433 geomC.addGeom( t, parent=geomC.masterGeom, redo=0 ) 434 else: 435 t = geomC.geoms['secondarystructure'] 436 437 438 439 for a in obj.allAtoms: 440 a.colors['secondarystructure']=(1.,1.,1.) 441 a.opacities['secondarystructure']=1. 442 443 for c in obj.chains: 444 if not hasattr(c, 'secondarystructureset'): 445 continue 446 for ss in c.secondarystructureset: 447 name = "%s%s"%(ss.name, ss.chain.id) 448 g = IndexedPolygons(name, visible=0, pickableVertices=1, protected=True,) 449 if self.vf.userpref['sharpColorBoundariesForMsms']['value'] == 'blur': 450 g.Set(inheritSharpColorBoundaries=False, sharpColorBoundaries=False,) 451 #g.RenderMode(GL.GL_FILL, face=GL.GL_FRONT, redo=0) 452 #g.Set(frontPolyMode=GL.GL_FILL,redo=0) 453 454 g.SS = ss 455 456 geomC.atomPropToVertices[name] = self.atomPropToVertices 457 geomC.geomPickToAtoms[name] = self.pickedVerticesToAtoms 458 geomC.geomPickToBonds[name] = None 459 geomC.addGeom(g, parent=t, redo=0 ) 460 self.managedGeometries.append(g) 461 #geomC.addGeom(g,self,parent=t, redo=0 ) 462 geomC.atoms[name] = ResidueSet() 463 464 465 obj.__hasSSGeom = 1
466
467 - def onAddCmdToViewer(self):
468 if self.vf.hasGui and \ 469 not self.vf.commands.has_key('computeSecondaryStructure'): 470 self.vf.loadCommand("secondaryStructureCommands", 471 "computeSecondaryStructure", "Pmv", 472 topCommand = 0) 473 if self.vf.hasGui and \ 474 not self.vf.commands.has_key('displayExtrudedSS'): 475 self.vf.loadCommand("secondaryStructureCommands", 476 "displayExtrudedSS", "Pmv", 477 topCommand = 0) 478 if self.vf.hasGui and \ 479 not self.vf.commands.has_key('computeSheet2D'): 480 self.vf.loadCommand("extrusionCommands", 481 "ComputeSheet2D", "Pmv", 482 topCommand = 0) 483 484 if self.vf.hasGui and \ 485 not self.vf.commands.has_key('Nucleic_Acids_properties'): 486 self.vf.loadCommand("extrusionCommands", 487 "Nucleic_Acids_properties", "Pmv", 488 topCommand = 0)
489
490 - def onRemoveObjectFromViewer(self, obj):
491 if not hasattr(obj, 'chains'): return 492 for c in obj.chains: 493 if hasattr(c, 'residuesInSS'): 494 delattr(c, 'residuesInSS') 495 496 if not hasattr(c, 'secondarystructureset'): 497 continue 498 for ss in c.secondarystructureset: 499 # Have to remove specifically geoms.SS and geoms.mol 500 # from the geomContainer !! 501 g = obj.geomContainer.geoms[ss.name+c.id] 502 del(g.SS) 503 del(g.mol) 504 g.Set(visible=0, tagModified=False) 505 g.protected = False 506 self.vf.GUI.VIEWER.RemoveObject(g) 507 del obj.geomContainer.geoms[ss.name+c.id] 508 del obj.geomContainer.atoms[ss.name+c.id] 509 obj.__hasSSGeom=0
510
511 - def __call__(self, nodes, shape1=None, shape2=None, frontcap=True, 512 endcap=True, arrow=True, nbchords=4, gapBeg=0, gapEnd=0, 513 larrow=2, display=True,**kw):
514 """None<---extrudeSecondaryStructure(nodes,shape1=None,shape2=None,frontcap=1,endcap=True,arrow=True, nbchords=4,gapBeg=False,gapEnd=False,larrow=2,display=True,**kw) 515 \nRequired Arguments:\n 516 nodes --- TreeNodeSet holding the current selection 517 (mv.getSelection()) 518 \nOptional Arguments:\n 519 shape1 & 520 shape2 --- DejaVu.Shapes.Shape2D objects. shape1 will be used to 521 represent the helix and strand, shape2 to represent coils and 522 turns. 523 \nfrontcap & 524 endcap --- Boolean flag when set to True a cap will be added to the 525 geom either at the front or at the end 526 \narrow --- Boolean flag when set to True an arow will be added to the 527 geometry representing the strand. 528 \nnbchords --- Nb of points per residues in the smooth array 529 \ngapBeg& 530 gapEnd --- defines gap at the beginning or the end of each residue. 531 \nlarrow --- length of the arrow if arrow boolean flag set to 1 532 \ndisplay --- Boolean flag when set to True the displaySecondaryStructure 533 is called automatically """ 534 535 if type(nodes) is StringType: 536 self.nodeLogString = "'"+nodes+"'" 537 nodes = self.vf.expandNodes(nodes) 538 if not nodes: return 539 kw['shape1']=shape1 540 kw['shape2']=shape2 541 kw['frontcap'] = frontcap 542 kw['endcap'] = endcap 543 kw['arrow'] = arrow 544 kw['nbchords'] = nbchords 545 kw['gapBeg'] = gapBeg 546 kw['gapEnd'] = gapEnd 547 kw['larrow'] = larrow 548 kw['display'] = display 549 #print "kw.has_key('only')=", kw.has_key('only') 550 #print kw.get('only', 'no_value') 551 apply(self.doitWrapper, (nodes,), kw)
552 553
554 - def doit(self, nodes, shape1=None, shape2=None, frontcap=True, endcap=True, 555 arrow=True, nbchords=4, gapBeg=0, gapEnd=0, larrow = 2, 556 display=True, **kw):
557 """ nodes, shape1, shape2=None, frontcap=True, endcap=True, arrow=True, 558 nbchords=4, gapBeg=0, gapEnd=1, display=True""" 559 #print "2: kw.has_key('only')=", kw.has_key('only'), ':', 560 #print kw.get('only', 'no_value') 561 562 if not type(nbchords)==IntType: 563 print "invalid parameter nbchords:", nbchords 564 return 565 if gapEnd>len(nodes): 566 print "invalid parameter gapEnd:", gapEnd 567 return 568 if gapBeg>len(nodes): 569 print "invalid parameter gapBeg:", gapBeg 570 return 571 572 molecules, residueSets=self.vf.getNodesByMolecule(nodes, Residue) 573 if len(molecules)==0: return 574 if shape1 is None: 575 shape1 = Rectangle2D(width=1.2, height=0.2, vertDup=1) 576 shape2 = Circle2D(radius=0.1) 577 # Create a sheet2 object. 578 for mol, residues in map(None, molecules, residueSets): 579 if not mol.hasSS: 580 # Compute the secondarystructure if not there 581 self.vf.computeSecondaryStructure(mol, topCommand=0) 582 if not hasattr(mol,'__hasSSGeom') or not mol.__hasSSGeom: 583 # Need here to change 584 self.createGeometries(mol) 585 reswithss = residues.get(lambda x: 586 hasattr(x, 'secondarystructure')) 587 if reswithss is None: 588 print 'no secondary structure in that selection' 589 continue 590 591 selectionSS = reswithss.secondarystructure.uniq() 592 593 chains = residues.parent.uniq() 594 for i in range(len(chains)): 595 chain = chains[i] 596 newsheet = 0 597 if not hasattr(chain, 'sheet2D'): 598 chain.sheet2D = {} 599 600 if not hasattr(chain,'secondarystructureset'): 601 print 'no secondary structure set for chain: %s !'%chain.id 602 chain.sheet2D['ssSheet2D'] = None 603 continue 604 605 ssSet = chain.secondarystructureset 606 # 1- Check if the sheet2D for a secondary structure has been 607 # computed already. 608 if chain.sheet2D.has_key('ssSheet2D'): 609 if chain.sheet2D['ssSheet2D'] is None: 610 newsheet = 0 611 continue 612 elif chain.sheet2D['ssSheet2D'].chords != nbchords: 613 if chain.isDNA: 614 ExtrudeNA(chain) 615 else: 616 self.vf.computeSheet2D(chain, 'ssSheet2D', 617 'CA','O', buildIsHelix=1, 618 nbchords=nbchords, 619 topCommand=0,log=0) 620 newsheet = 1 621 else: 622 newsheet = 0 623 624 elif not chain.sheet2D.has_key('ssSheet2D'): 625 if chain.isDNA: 626 ExtrudeNA(chain) 627 else: 628 self.vf.computeSheet2D(chain, 'ssSheet2D', 629 'CA', 'O',buildIsHelix=1, 630 nbchords=nbchords, 631 topCommand=0,log=0) 632 newsheet = 1 633 if newsheet: 634 sd = chain.sheet2D['ssSheet2D'] 635 # then create a pointer to the sheet2D for each secondary structures. 636 ssSet.sheet2D = sd 637 if sd is None : continue 638 # Do the extrusion ONLY for the ss having a residue in the 639 # selection 640 removeSS =[] 641 #from Pmv.selectionCommands import sets__ 642 for SS in ssSet: 643 # test here if all the residues of the sselt are 644 # in the residue set used 645 # to compute the sheet2D. if not remove the ss. 646 if SS.sheet2D is None: 647 continue 648 if filter(lambda x, rs = SS.sheet2D.resInSheet: 649 not x in rs, SS.residues): 650 print "WARNING: Removing %s from secondary structure set. One or more residues \ 651 doesn't have CA and O"%SS.name 652 653 # remove the SS from the set and etc.... 654 #delattr(SS.residues, 'secondarystructure') 655 #ssSet.remove(SS) 656 removeSS.append(SS) 657 name = "%s%s"%(SS.name, SS.chain.id) 658 del self.vf.sets[mol.name+':'+name[-1]+':'+name[:-1]] 659 #del sets__[mol.name+':'+name[-1]+':'+name[:-1]] 660 continue 661 name = "%s%s"%(SS.name, SS.chain.id) 662 663 if not SS in selectionSS: 664 continue 665 if isinstance(SS, Strand): 666 arrowf = arrow 667 else: 668 arrowf = 0 669 if not shape2 is None: 670 if SS.__class__.__name__ in ['Strand', 'Helix']: 671 SS.exElt = ExtrudeSSElt(SS,shape1,gapEnd , 672 gapBeg, frontcap, endcap, 673 arrowf,larrow) 674 elif SS.__class__.__name__ in ['Coil', 'Turn']: 675 if chain.isDNA: 676 if self.flagNucleicAcidsProperties: 677 self.vf.Nucleic_Acids_properties.guiCallback() 678 self.flagNucleicAcidsProperties = False 679 NAp = self.vf.Nucleic_Acids_properties 680 sc = max(NAp.scale_pyrimidine, NAp.scale_purine) 681 shape2 = Circle2D(radius=sc/2.5) 682 SS.exElt = ExtrudeSSElt(SS,shape2, gapEnd, 683 gapBeg, frontcap, endcap, 684 arrowf) 685 686 else: 687 SS.exElt = ExtrudeSSElt(SS, shape1, gapEnd , gapBeg, 688 frontcap, endcap, arrowf, 689 larrow) 690 resfaces = SS.exElt.getExtrudeResidues(SS.residues) 691 g = mol.geomContainer.geoms[name] 692 ## # MS triangulate faces 693 ## trifaces = [] 694 ## for f in resfaces: 695 ## trifaces.append( (f[0],f[1],f[3]) ) 696 ## if f[2]!=f[3]: 697 ## trifaces.append( (f[1],f[2],f[3]) ) 698 g.Set(vertices=SS.exElt.vertices, 699 faces = resfaces, 700 ## faces=trifaces, 701 vnormals=SS.exElt.vnormals, redo=0, 702 tagModified=False) 703 if chain.isDNA: 704 geom_bases = Add_Nucleic_Bases(g, 705 self.vf.Nucleic_Acids_properties) 706 self.vf.GUI.VIEWER.AddObject(geom_bases, parent=g) 707 708 for SS in removeSS: 709 delattr(SS.residues, 'secondarystructure') 710 ssSet.remove(SS) 711 712 if display: 713 kw['topCommand'] = 0 714 if kw.get('only', 0): 715 kw['only'] = 1 716 kw['setupUndo'] = 1 717 #print "calling displayExtrudedSS with ", kw 718 apply(self.vf.displayExtrudedSS,(nodes,), kw) 719 #self.vf.displayExtrudedSS(nodes, setupUndo=1, topCommand=0) 720 self.flagNucleicAcidsProperties = True
721 722
723 - def gapValidateFunction(self, gapVal,*validateArgs):
724 """ Function to test if the value of the gap is correct. Its has 725 to take for arguments the value of the entry you are testing 726 and a list of arguments. Here the list has only one argument 727 the value number of chords.""" 728 chordVal = validateArgs[0] 729 if gapVal < int(chordVal.get())/2.: 730 return 1 731 else: 732 return 0
733
734 - def buildFormDescr(self, formName):
735 if formName == 'geomChooser': 736 nbchordEntryVar = StringVar() 737 idf = InputFormDescr(title ="Choose a shape :") 738 739 entries = [('default',None),('rectangle',None), 740 ('circle',None), ('ellipse',None), 741 ('square',None),('triangle',None), 742 #('other', None) 743 ] 744 745 idf.append({'name':'shape', 746 'widgetType':ListChooser, 747 'defaultValue':'default', 748 'wcfg':{'entries': entries, 749 'title':'Choose a shape'} 750 }) 751 752 idf.append( {'name': 'nbchords', 753 'widgetType':ExtendedSliderWidget, 754 'type':int, 755 'wcfg':{'label': 'nb. Pts Per Residue: ', 756 'minval':4,'maxval':15, 'incr': 1, 'init':4, 757 'labelsCursorFormat':'%d', 'sliderType':'int', 758 'entrywcfg':{'textvariable':nbchordEntryVar, 759 'width':4}, 760 'entrypackcfg':{'side':'right'}}, 761 'gridcfg':{'columnspan':2,'sticky':'we'} 762 }) 763 764 idf.append( {'name': 'gapBeg', 765 'widgetType':ExtendedSliderWidget, 766 'type':int, 767 'validateFunc':self.gapValidateFunction, 768 'validateArgs':(nbchordEntryVar,'GapEnd'), 769 'wcfg':{'label': 'Gap Before Residue', 770 'minval':0,'maxval':5, 'incr': 1, 'init':0, 771 'labelsCursorFormat':'%d', 'sliderType':'int', 772 'entrywcfg':{'width':4}, 773 'entrypackcfg':{'side':'right'}}, 774 'gridcfg':{'columnspan':2,'sticky':'we'} 775 }) 776 777 idf.append( {'name': 'gapEnd', 778 'widgetType':ExtendedSliderWidget,'type':int, 779 'validateFunc':self.gapValidateFunction, 780 'validateArgs':(nbchordEntryVar,'GapBeg'), 781 'wcfg':{'label': 'Gap After Residue', 782 'minval':0,'maxval':5, 'incr': 1, 'init':0 , 783 'labelsCursorFormat':'%d', 'sliderType':'int', 784 'entrywcfg':{'width':4}, 785 'entrypackcfg':{'side':'right'}}, 786 'gridcfg':{'columnspan':2,'sticky':'we'} 787 }) 788 else: 789 initRadius = 0.1 790 radiusWidgetDescr = {'name': 'radius', 791 'widgetType':ExtendedSliderWidget, 792 'wcfg':{'label': 'Radius', 793 'minval':0.05,'maxval':3.0 , 794 'init':initRadius, 795 'labelsCursorFormat':'%1.2f', 796 'sliderType':'float', 797 'entrywcfg':{'width':4}, 798 'entrypackcfg':{'side':'right'}}, 799 'gridcfg':{'columnspan':2,'sticky':'we'} 800 } 801 initWidth = 1.2 802 widthWidgetDescr = {'name': 'width', 803 'widgetType':ExtendedSliderWidget, 804 'wcfg':{'label': 'Width', 805 'minval':0.05,'maxval':3.0 , 806 'init':initWidth, 807 'labelsCursorFormat':'%1.2f', 808 'sliderType':'float', 809 'entrywcfg':{'width':4}, 810 'entrypackcfg':{'side':'right'}}, 811 'gridcfg':{'columnspan':2,'sticky':'we'} 812 } 813 initHeight = 0.2 814 heightWidgetDescr = {'name': 'height', 815 'widgetType':ExtendedSliderWidget, 816 'wcfg':{'label': 'Height', 817 'minval':0.05,'maxval':3.0 , 818 'init':initHeight, 819 'labelsCursorFormat':'%1.2f', 820 'sliderType':'float' , 821 'entrywcfg':{'width':4}, 822 'entrypackcfg':{'side':'right'}}, 823 'gridcfg':{'columnspan':2,'sticky':'we'} 824 } 825 initLarrow = 2 826 larrowWidgetDescr = {'name': 'larrow', 827 'widgetType':ExtendedSliderWidget, 828 'type':int, 829 'wcfg':{'label':'length of the arrow:', 830 'minval':0,'maxval':4, 'incr': 1, 831 'init':initLarrow, 832 'labelsCursorFormat':'%d', 833 'sliderType':'int', 834 'entrywcfg':{'width':4}, 835 'entrypackcfg':{'side':'right'}}, 836 'gridcfg':{'columnspan':2,'sticky':'we'} 837 } 838 initSide = 1.0 839 sideWidgetDescr = {'name': 'sidelength', 840 'widgetType':ExtendedSliderWidget, 841 'wcfg':{'label': 'Length of side:', 842 'minval':0.05,'maxval':3.0 , 843 'init':initSide, 844 'labelsCursorFormat':'%1.2f', 845 'sliderType':'float', 846 'entrywcfg':{'width':4}, 847 'entrypackcfg':{'side':'right'}}, 848 'gridcfg':{'columnspan':2,'sticky':'we'} 849 } 850 851 frontCapWidgetDescr = {'name':'frontcap', 852 'widgetType':Checkbutton, 853 'defaultValue':1, 854 'wcfg':{'text':'front cap', 855 'variable': IntVar()}, 856 'gridcfg':{'sticky':'we'}} 857 endCapWidgetDescr = {'name':'endcap', 858 'widgetType':Checkbutton, 859 'defaultValue':1, 860 'wcfg':{'text':'end cap ', 861 'variable': IntVar()}, 862 'gridcfg':{'sticky':'we','row':-1}} 863 864 865 if formName == 'default': 866 idf = InputFormDescr(title ="Options :") 867 idf.append(radiusWidgetDescr) 868 idf.append(widthWidgetDescr) 869 idf.append(heightWidgetDescr) 870 idf.append(larrowWidgetDescr) 871 872 elif formName == 'rectangle': 873 idf = InputFormDescr(title ="Rectangle size :") 874 idf.append(widthWidgetDescr) 875 initHeight = 0.4 876 idf.append(heightWidgetDescr) 877 larrowInit = 0 878 idf.append(larrowWidgetDescr) 879 880 elif formName == 'circle': 881 idf = InputFormDescr(title="Circle size :") 882 idf.append(radiusWidgetDescr) 883 884 elif formName == 'ellipse': 885 idf = InputFormDescr(title="Ellipse size") 886 idf.append( {'name': 'grand', 887 'widgetType':ExtendedSliderWidget, 888 'wcfg':{'label': 'demiGrandAxis', 889 'minval':0.05,'maxval':3.0 , 890 'init':0.5, 891 'labelsCursorFormat':'%1.2f', 892 'sliderType':'float', 893 'entrywcfg':{'width':4}, 894 'entrypackcfg':{'side':'right'}}, 895 'gridcfg':{'columnspan':2,'sticky':'we'} 896 }) 897 idf.append( {'name': 'small', 898 'widgetType':ExtendedSliderWidget, 899 'wcfg':{'label': 'demiSmallAxis', 900 'minval':0.05,'maxval':3.0 , 901 'init':0.2, 902 'labelsCursorFormat':'%1.2f', 903 'sliderType':'float', 904 'entrywcfg':{'width':4}, 905 'entrypackcfg':{'side':'right'}}, 906 'gridcfg':{'columnspan':2,'sticky':'we'} 907 }) 908 elif formName == 'square': 909 idf = InputFormDescr(title="Square size :") 910 idf.append(sideWidgetDescr) 911 initLarrow = 0 912 idf.append(larrowWidgetDescr) 913 914 elif formName == 'triangle': 915 idf = InputFormDescr(title="Triangle size :") 916 idf.append(sideWidgetDescr) 917 918 919 # These widgets are present in everyInputForm. 920 idf.append(frontCapWidgetDescr) 921 idf.append(endCapWidgetDescr) 922 923 return idf
924
925 - def guiCallback(self):
926 typeshape = self.showForm('geomChooser') 927 if typeshape == {} or typeshape['shape'] == []: return 928 nbchords = typeshape['nbchords'] 929 gapBeg = typeshape['gapBeg'] 930 gapEnd = typeshape['gapEnd'] 931 932 if typeshape['shape'][0]=='default': 933 val = self.showForm('default') 934 if val: 935 val['shape1'] = Rectangle2D(val['width'],val['height'], 936 vertDup=1) 937 val['shape2'] = Circle2D(radius=val['radius']) 938 del val['width'] 939 del val['height'] 940 del val['radius'] 941 942 val['frontcap'] = int(val['frontcap']) 943 val['endcap'] = int(val['endcap']) 944 945 if val['larrow']!=0: 946 val['arrow'] = 1 947 else: 948 val['arrow'] = 0 949 950 elif typeshape['shape'][0]=='rectangle': 951 val = self.showForm('rectangle') 952 if val: 953 val['shape1'] = Rectangle2D(width=val['width'], 954 height=val['height'], 955 vertDup=1) 956 del val['height'] 957 del val['width'] 958 val['shape2'] = None 959 val['frontcap'] = int(val['frontcap']) 960 val['endcap'] = int(val['endcap']) 961 if val['larrow']!=0: 962 val['arrow'] = 1 963 else: 964 val['arrow'] = 0 965 966 elif typeshape['shape'][0]=='circle': 967 val = self.showForm('circle') 968 if val: 969 val['shape1'] = Circle2D(radius=val['radius']) 970 del val['radius'] 971 val['shape2'] = None 972 973 val['frontcap'] = int(val['frontcap']) 974 val['endcap'] = int(val['endcap']) 975 val['arrow'] = 0 976 977 elif typeshape['shape'][0]=='ellipse': 978 val = self.showForm('ellipse') 979 if val: 980 val['shape1'] = Ellipse2D(demiGrandAxis= val['grand'], 981 demiSmallAxis=val['small']) 982 del val['grand'] 983 del val['small'] 984 val['shape2'] = None 985 val['frontcap'] = int(val['frontcap']) 986 val['endcap'] = int(val['endcap']) 987 val['arrow'] = 0 988 989 elif typeshape['shape'][0]=='square': 990 val = self.showForm('square') 991 if val: 992 val['shape1'] = Square2D(side=val['sidelength'], vertDup=1) 993 del val['sidelength'] 994 val['shape2'] = None 995 val['frontcap'] = int(val['frontcap']) 996 val['endcap'] = int(val['endcap']) 997 if val['larrow']!=0: 998 val['arrow'] = 1 999 else: 1000 val['arrow'] = 0 1001 1002 elif typeshape['shape'][0]=='triangle': 1003 val = self.showForm('triangle') 1004 if val: 1005 val['shape1'] = Triangle2D(side=val['sidelength'], vertDup=1) 1006 del val['sidelength'] 1007 val['shape2'] = None 1008 val['frontcap'] = int(val['frontcap']) 1009 val['endcap'] = int(val['endcap']) 1010 1011 val['arrow'] = 0 1012 1013 ## elif typeshape['shape'][0]=='other': 1014 ## draw = DrawShape(self.vf.GUI.ROOT) 1015 ## val = draw.go() 1016 ## if not val[0] or not val[1]: return 1017 ## if val: 1018 ## shape1 = Shape2D(val[0], val[1], val[2]) 1019 ## shape2 = None 1020 ## arrow, cap1, cap2 = 1, val[3], val[4] 1021 else: return 1022 1023 if val: 1024 if val.has_key('arrow') and not val['arrow']: 1025 val['larrow'] = 0 1026 else: 1027 val['larrow'] = int((val['larrow']*nbchords)/4.) 1028 val['gapBeg'] = gapBeg 1029 val['gapEnd'] = gapEnd 1030 val['nbchords'] = nbchords 1031 apply(self.doitWrapper, (self.vf.getSelection(),), val) 1032 else: return
1033 1034 1035
1036 -class DisplayExtrudedSSCommand(DisplayCommand):
1037 1038 """ The DisplaySSCommand displays the geometries representing the secondary structure elements of the current selection.To execute this command use the 'Display Secondary Structure' entry under the 'Display' menu in the menu bar. 1039 \nPackage : Pmv 1040 \nModule : secondaryStructureCommands 1041 \nClass : DisplayExtrudedSSCommand 1042 \nCommand name : displaySecondaryStructure 1043 \nSynopsis:\n 1044 None <- displaySecondaryStructure(nodes, only=False, 1045 negate=False,**kw) 1046 \nRequired Arguments:\n 1047 nodes --- TreeNodeSet holding the current selection 1048 \nOptional Arguments:\n 1049 only --- allows the user to display only the current selection when set to 1 1050 \nnegate --- allows to undisplay the current selection when set to 1. 1051 \nThis command is undoable. 1052 """
1053 - def getNodes(self, nodes):
1054 """expand nodes argument into a list of residues sets and a list of 1055 molecules. 1056 this function is used to prevent the expansion operation to be done 1057 in both doit and setupUndoBefore 1058 The nodes.findType( Residue ) is the operation that is potentially 1059 expensive""" 1060 1061 if not hasattr(self, 'expandedNodes____ResidueSets'): 1062 mol, res = self.vf.getNodesByMolecule(nodes, Residue) 1063 #if len(mol)==0: return None, None 1064 self.expandedNodes____ResidueSets = res 1065 self.expandedNodes____Molecules = mol 1066 1067 return self.expandedNodes____Molecules, self.expandedNodes____ResidueSets
1068
1069 - def onAddCmdToViewer(self):
1070 if self.vf.hasGui and \ 1071 not self.vf.commands.has_key('computeSecondaryStructure'): 1072 self.vf.loadCommand("secondaryStructureCommands", 1073 "computeSecondaryStructure", "Pmv", 1074 topCommand = 0) 1075 1076 if self.vf.hasGui and \ 1077 not self.vf.commands.has_key('computeSheet2D'): 1078 self.vf.loadCommand("extrusionCommands", 1079 "computeSheet2D", "Pmv", 1080 topCommand = 0) 1081 if self.vf.hasGui and \ 1082 not self.vf.commands.has_key('extrudeSecondaryStructure'): 1083 self.vf.loadCommand("secondaryStructureCommands", 1084 "extrudeSecondaryStructure","Pmv", 1085 topCommand = 0)
1086
1087 - def setupUndoBefore(self, nodes, only=False, negate=False):
1088 if len(nodes)==0 : return 1089 #molecules = nodes.top.uniq() 1090 molecules, residueSets = self.getNodes(nodes) 1091 #for mol, res in map(None, molecules, residueSets): 1092 for mol in molecules: 1093 resWithSS = mol.findType(Residue).get( 1094 lambda x:hasattr(x,'secondarystructure')) 1095 if resWithSS is None: 1096 continue 1097 SSinMol = resWithSS.secondarystructure.uniq() 1098 #resWithSS = res.get(lambda x: hasattr(x,'secondarystructure')) 1099 #SSinSel = resWithSS.secondarystructure.uniq() 1100 #mol.geomContainer.atoms['secondarystructure']=resWithSS.atoms 1101 set = ResidueSet() 1102 for ss in SSinMol: 1103 set = set + mol.geomContainer.atoms[ss.name+ss.chain.id] 1104 if len(set)==0: # nothing is displayed 1105 self.addUndoCall( (mol,), 1106 {'negate':True, 'redraw':True}, 1107 self.name ) 1108 else: 1109 self.addUndoCall( (set,), {'only':True, 'redraw':True}, 1110 self.name )
1111
1112 - def doit(self, nodes, only=False, negate=False ):
1113 """ displays the secondary structure for the selected treenodes """ 1114 1115 #print "in display with only=", only, " and negate=", negate 1116 ############################################################### 1117 def drawResidues(SS, res, only, negate): 1118 mol = SS.chain.parent 1119 name = '%s%s'%(SS.name, SS.chain.id) 1120 set = mol.geomContainer.atoms[name] 1121 inres = filter(lambda x, res=res: not x in res, set) 1122 if len(inres) == 0: 1123 # res and set are the same 1124 if negate: set = ResidueSet() 1125 else: set = res 1126 else: 1127 # if negate, remove current res from displayed set 1128 if negate : 1129 set = set - res 1130 1131 else: # if only, replace displayed set with current res 1132 if only: 1133 set = res 1134 else: 1135 set = res.union(set) 1136 1137 ## # if negate, remove current res from displayed set 1138 ## if negate : 1139 ## set = set - res 1140 1141 ## else: # if only, replace displayed set with current res 1142 ## if only: 1143 ## set = res 1144 ## else: 1145 ## set = res.union(set) 1146 ## # now, update the geometries: 1147 ## if len(set)==0: 1148 ## mol.geomContainer.geoms[name].Set(visible=0, tagModified=False) 1149 ## mol.geomContainer.atoms[name] = ResidueSet() 1150 ## return 1151 1152 #the rest is done only if there are some residues 1153 g = mol.geomContainer.geoms[name] 1154 mol.geomContainer.atoms[name] = set 1155 #print set 1156 if not hasattr(SS, 'exElt'): return 1157 resfaces = SS.exElt.getExtrudeResidues(set) 1158 col = mol.geomContainer.getGeomColor(name) 1159 ## # MS triangulate faces 1160 ## trifaces = [] 1161 ## for f in resfaces: 1162 ## trifaces.append( (f[0],f[1],f[3]) ) 1163 ## if f[2]!=f[3]: 1164 ## trifaces.append( (f[1],f[2],f[3]) ) 1165 ## g.Set(faces=trifaces, vnormals=SS.exElt.vnormals, 1166 1167 g.Set(faces=resfaces, vnormals=SS.exElt.vnormals, 1168 visible=1, materials=col, tagModified=False) 1169 if SS.chain.isDNA: 1170 faces = [] 1171 colors = [] 1172 for residue in set: 1173 faces.extend(residue._base_faces) 1174 colors.extend(residue._coil_colors) 1175 residue.atoms[0].colors["secondarystructure"] = residue._coil_colors[0] 1176 g.children[0].Set(faces=faces) 1177 if colors: 1178 g.Set(materials=colors) 1179 1180 if self.vf.Nucleic_Acids_properties.color_backbone: 1181 g.Set(inheritMaterial=False) 1182 1183 else: 1184 g.Set(inheritMaterial=True) 1185 mol.geomContainer.atoms['Bases'] = ResidueSet()
1186 #mol.geomContainer.atoms[name] = ResidueSet() 1187 ############################################################### 1188 1189 molecules, residueSets = self.getNodes(nodes) 1190 for mol, residues in map(None, molecules, residueSets): 1191 if not mol.hasSS: 1192 self.vf.computeSecondaryStructure(mol,topCommand=0,log=0) 1193 self.vf.extrudeSecondaryStructure(mol, topCommand=0, log=0, 1194 display=0) 1195 reswithss = residues.get(lambda x: 1196 hasattr(x,'secondarystructure')) 1197 if reswithss is None: 1198 print 'no secondary structure in that selection' 1199 continue 1200 1201 SSInSel = reswithss.secondarystructure.uniq() 1202 chainsInSel = residues.parent.uniq() 1203 for c in mol.chains: 1204 if not hasattr(c, 'secondarystructureset'): 1205 continue 1206 if not hasattr(c, 'sheet2D'): 1207 print "The chain %s doesn't have a sheet2D computed"%c.name 1208 continue 1209 elif (c.sheet2D.has_key('ssSheet2D') and \ 1210 c.sheet2D['ssSheet2D'] is None): continue 1211 SS, resInSS = self.getResiduesBySS(residues, c) 1212 for s in xrange(len(c.secondarystructureset)): 1213 ss = c.secondarystructureset[s] 1214 res = resInSS[s] 1215 if ss in SSInSel and not hasattr(ss, 'exElt') \ 1216 and negate == 0: 1217 self.vf.extrudeSecondaryStructure(res,display=0, 1218 topCommand=0) 1219 ## if computeBefore == 'yes': 1220 ## self.vf.extrudeSecondaryStructure(res,display=0, 1221 ## topCommand=0) 1222 ## elif computeBefore == 'no': 1223 ## continue 1224 drawResidues(ss, res, only , negate )
1225
1226 - def cleanup(self):
1227 """ Method called by afterDoit to clean up things eventhough the doit 1228 failes.""" 1229 del self.expandedNodes____ResidueSets 1230 del self.expandedNodes____Molecules
1231 1232
1233 - def __call__(self, nodes, only=False, negate=False,**kw):
1234 """None <- displaySecondaryStructure(nodes, only=False, 1235 negate=False,**kw) 1236 \nRequired Arguments:\n 1237 \nnodes --- TreeNodeSet holding the current selection 1238 \nOptional Arguments:\n 1239 \nonly --- flag when set to 1 only the current selection will be displayed as secondarystructures 1240 \nnegate --- flag when set to 1 undisplay the current selection""" 1241 if type(nodes) is StringType: 1242 self.nodeLogString = "'"+nodes+"'" 1243 nodes = self.vf.expandNodes(nodes) 1244 if not nodes: return 1245 if not kw.has_key('redraw'):kw['redraw']=1 1246 kw['only'] = only 1247 kw['negate'] = negate 1248 1249 apply(self.doitWrapper, (nodes,),kw)
1250
1251 - def getResiduesBySS(self, residues, chain):
1252 resWithSS = residues.get(lambda x: hasattr(x, 'secondarystructure')) 1253 residuesInSS = [] 1254 for ss in chain.secondarystructureset : 1255 res = resWithSS.get(lambda x, ss=ss:x.secondarystructure==ss) 1256 if res is None: 1257 res = ResidueSet() 1258 residuesInSS.append(res) 1259 return chain.secondarystructureset, residuesInSS
1260 1261
1262 -class UndisplayExtrudedSSCommand(DisplayCommand):
1263 """ UndisplaySSCommand is an interactive command to undisplay part of 1264 the molecule when represented as extruded secondary structure. 1265 \nPackage : Pmv 1266 \nModule : secondaryStructureCommands 1267 \nClass : UndisplayExtrudedSSCommand 1268 \nCommand name : undisplaySecondaryStructure 1269 \nSynopsis:\n 1270 None <--- undisplaySecondaryStructure(nodes, **k) 1271 \nRequired Arguments:\n 1272 nodes --- TreeNodeSet holding the current selection 1273 """
1274 - def onAddCmdToViewer(self):
1275 if not self.vf.hasGui: return 1276 if not self.vf.commands.has_key('displayExtrudedSS'): 1277 self.vf.loadCommand('secondaryStructureCommands', 1278 ['displayExtrudedSS'], 'Pmv', 1279 topCommand=0)
1280 1281
1282 - def __call__(self, nodes, **kw):
1283 """None <--- undisplaySecondaryStructure(nodes, **k) 1284 \nnodes --- TreeNodeSet holding the current selection 1285 """ 1286 if type(nodes) is StringType: 1287 self.nodeLogString = "'"+nodes+"'" 1288 nodes = self.vf.expandNodes(nodes) 1289 if not nodes: return 1290 kw['negate']= 1 1291 apply(self.vf.displayExtrudedSS, (nodes,), kw)
1292 1293 1294
1295 -class RibbonCommand(MVCommand):
1296 """ The RibbonCommand is a shortcut to visualize a traditional Ribbon 1297 representation of the current selection. It first executes getSSCommand 1298 then the extrudeSSCommand with the default values for all the parameters. 1299 This command is undoable. 1300 \nPackage : Pmv 1301 \nModule : secondaryStructureCommands 1302 \nClass : RibbonCommand 1303 \nCommand name : ribbon 1304 \nSynopsis:\n 1305 None <- ribbon(nodes, only=False, negate=False, **kw) 1306 \nRequired Arguments:\n 1307 nodes --- TreeNodeSet holding the current selection 1308 \nOptional Arguments:\n 1309 only --- flag when set to 1 only the current selection 1310 will be displayed 1311 \nnegate --- flag when set to 1 undisplay the current selection 1312 """
1313 - def __init__(self):
1314 MVCommand.__init__(self) 1315 self.flag = self.flag | self.objArgOnly 1316 self.flag = self.flag | self.negateKw
1317 1318
1319 - def onAddCmdToViewer(self):
1320 if self.vf.hasGui and \ 1321 not self.vf.commands.has_key('computeSecondaryStructure'): 1322 self.vf.loadCommand("secondaryStructureCommands", 1323 "computeSecondaryStructure", "Pmv", 1324 topCommand = 0) 1325 if self.vf.hasGui and \ 1326 not self.vf.commands.has_key('extrudeSecondaryStructure'): 1327 self.vf.loadCommand("secondaryStructureCommands", 1328 "extrudeSecondaryStructure", "Pmv", 1329 topCommand = 0) 1330 if self.vf.hasGui and \ 1331 not self.vf.commands.has_key('displayExtrudedSS'): 1332 self.vf.loadCommand("secondaryStructureCommands", 1333 "displayExtrudedSS", "Pmv", 1334 topCommand = 0)
1335
1336 - def guiCallback(self):
1337 self.doitWrapper(self.vf.getSelection(), redraw=1)
1338 1339
1340 - def __call__(self, nodes, only=False, negate=False, **kw):
1341 """None <- ribbon(nodes, only=False, negate=False, **kw) 1342 \nRequired Arguments:\n 1343 nodes --- TreeNodeSet holding the current selection 1344 \nOptional Arguments:\n 1345 only --- flag when set to 1 only the current selection 1346 will be displayed 1347 \nnegate --- flag when set to 1 undisplay the current selection 1348 """ 1349 if type(nodes) is types.StringType: 1350 self.nodeLogString = "'"+nodes+"'" 1351 1352 if not kw.has_key('redraw'): kw['redraw']=1 1353 nodes = self.vf.expandNodes(nodes) 1354 if not nodes: return 1355 kw['only']=only 1356 kw['negate']=negate 1357 #print "in ribbon with only=", only 1358 apply(self.doitWrapper, (nodes,), kw)
1359 1360
1361 - def doit(self, nodes, **kw):
1362 #print "in ribbon.doit with only=", kw['only'] 1363 apply(self.vf.computeSecondaryStructure,(nodes,), {'topCommand':False}) 1364 kw['topCommand'] = 0 1365 #kw['only'] = only 1366 #kw['negate'] = negate 1367 apply(self.vf.extrudeSecondaryStructure,(nodes,), kw)
1368 #self.vf.computeSecondaryStructure(nodes, topCommand=0) 1369 #self.vf.extrudeSecondaryStructure(nodes, topCommand=0) 1370 1371 1372
1373 -class ColorBySSElementType(ColorFromPalette):
1374 """Command to color the given geometry by secondary structure 1375 element. (Rasmol color code) 1376 \nPackage : Pmv 1377 \nModule : secondaryStructureCommands 1378 \nClass : ColorBySSElementType 1379 """
1380 - def __init__(self, func=None):
1381 ColorFromPalette.__init__(self, func=func) 1382 from Pmv.pmvPalettes import SecondaryStructureType 1383 c = 'Color palette for secondary structure element type:' 1384 self.palette = ColorPalette('SecondaryStructureType', 1385 SecondaryStructureType, 1386 info=c, 1387 lookupMember = 'structureType')
1388 - def getNodes(self, nodes, returnNodes=False):
1389 """expand nodes argument into a list of atoms and a list of 1390 molecules. 1391 this function is used to prevent the expansion operation to be done 1392 in both doit and setupUndoBefore 1393 The nodes.findType( Atom ) is the operation that is potentially 1394 expensive""" 1395 # Only get the atoms belonging to a residue with a secondary structure 1396 if not hasattr(self, 'expandedNodes____Atoms'): 1397 nodes = self.vf.expandNodes(nodes) 1398 self.expandedNodes____Nodes = nodes 1399 res = nodes.findType(Residue).uniq() 1400 resWithSS = res.get(lambda x: hasattr(x,'secondarystructure')) 1401 if resWithSS is None or len(resWithSS)==0: 1402 self.expandedNodes____Atoms = AtomSet() 1403 self.expandedNodes____Molecules = ProteinSet() 1404 else: 1405 self.expandedNodes____Atoms = resWithSS.atoms 1406 self.expandedNodes____Molecules = resWithSS.top.uniq() 1407 if returnNodes: 1408 return self.expandedNodes____Molecules, \ 1409 self.expandedNodes____Atoms, self.expandedNodes____Nodes 1410 else: 1411 return self.expandedNodes____Molecules, self.expandedNodes____Atoms
1412
1413 - def getColors(self, nodes):
1414 res = nodes.findType(Residue) 1415 resWithSS = res.get(lambda x: hasattr(x, 'secondarystructure')) 1416 if resWithSS is None: return None, None 1417 return resWithSS, self.palette.lookup(resWithSS.secondarystructure)
1418 1419
1420 - def doit(self, nodes, geomsToColor):
1421 # these commands do not require the color argument since colors are 1422 # gotten from a palette 1423 # we still can use the ColorCommand.setupUndoBefore but first we get 1424 # the colors. This also insures that the colors are not put inside the 1425 # log string for these commands 1426 molecules, atms = self.getNodes(nodes) 1427 if len(atms)==0: return 1428 resWithSS, colors = self.getColors(atms) 1429 if colors is None: return 1430 for g in geomsToColor: 1431 if len(colors)==1 or len(colors)!=len(atms): 1432 for a in atms: 1433 a.colors[g] = tuple( colors[0] ) 1434 else: 1435 for a, c in map(None, atms, colors): 1436 a.colors[g] = tuple(c) 1437 1438 updatedGeomsToColor = [] 1439 for mol in molecules: 1440 for gName in geomsToColor: 1441 if not mol.geomContainer.geoms.has_key(gName): continue 1442 geom = mol.geomContainer.geoms[gName] 1443 if geom.children != []: 1444 # get geom Name: 1445 childrenNames = map(lambda x: x.name, geom.children) 1446 updatedGeomsToColor = updatedGeomsToColor + childrenNames 1447 for childGeom in geom.children: 1448 childGeom.Set(inheritMaterial=0, redo=0, tagModified=False) 1449 else: 1450 updatedGeomsToColor.append(gName) 1451 geom.Set(inheritMaterial=0, redo=0, tagModified=False) 1452 1453 mol.geomContainer.updateColors(updatedGeomsToColor)
1454
1455 - def cleanup(self):
1456 if hasattr(self, 'expandedNodes____Molecules'): 1457 del self.expandedNodes____Molecules 1458 if hasattr(self, 'expandedNodes____Atoms'): 1459 del self.expandedNodes____Atoms 1460 if hasattr(self, 'expandedNodes____Nodes'): 1461 del self.expandedNodes____Nodes
1462 1463 1464 colorBySecondaryStructureTypeGuiDescr = {'widgetType':'Menu', 1465 'menuBarName':'menuRoot', 1466 'menuButtonName':'Color', 1467 'menuEntryLabel':'By SS Element Type'} 1468 1469 1470 ColorBySSElementTypeGUI = CommandGUI() 1471 ColorBySSElementTypeGUI.addMenuCommand('menuRoot', 'Color', 1472 'by SS Element Type') 1473 1474 computeSSGuiDescr = {'widgetType':'Menu', 'menuBarName':'menuRoot', 1475 'menuButtonName':'Compute', 1476 'menuEntryLabel':'Compute Secondary Structure', 1477 'separatorAbove':1} 1478 1479 computeSSGUI = CommandGUI() 1480 computeSSGUI.addMenuCommand('menuRoot', 'Compute', 1481 'Compute Secondary Structure', 1482 cascadeName = 'Secondary structure') 1483 1484 extrudeSSGuiDescr = {'widgetType':'Menu', 'menuBarName':'menuRoot', 1485 'menuButtonName':'Compute', 1486 'menuEntryLabel':'Extrude Secondary Structure'} 1487 1488 ExtrudeSSGUI = CommandGUI() 1489 ExtrudeSSGUI.addMenuCommand('menuRoot', 'Compute', 1490 'Extrude Secondary Structure', 1491 cascadeName = 'Secondary structure') 1492 1493 displaySSGuiDescr = {'widgetType':'Menu', 'menuBarName':'menuRoot', 1494 'menuButtonName':'Display', 1495 'menuEntryLabel':'Secondary Structure'} 1496 1497 DisplaySSGUI = CommandGUI() 1498 DisplaySSGUI.addMenuCommand('menuRoot', 'Display', 1499 'Secondary Structure') 1500 1501 ribbonGuiDescr = {'widgetType':'Menu', 'menuBarName':'menuRoot', 1502 'menuButtonName':'Compute', 1503 'menuEntryLabel':'Ribbon'} 1504 1505 RibbonGUI = CommandGUI() 1506 RibbonGUI.addMenuCommand('menuRoot', 'Compute','Ribbon', 1507 cascadeName = 'Secondary structure') 1508 1509 commandList = [ 1510 {'name': 'computeSecondaryStructure', 1511 'cmd': ComputeSecondaryStructureCommand(), 1512 'gui':computeSSGUI}, 1513 {'name': 'extrudeSecondaryStructure', 1514 'cmd': ExtrudeSecondaryStructureCommand(), 1515 'gui':ExtrudeSSGUI}, 1516 {'name': 'displayExtrudedSS', 1517 'cmd': DisplayExtrudedSSCommand(), 1518 'gui':DisplaySSGUI}, 1519 {'name': 'colorBySecondaryStructure', 1520 'cmd': ColorBySSElementType(), 1521 'gui':ColorBySSElementTypeGUI}, 1522 {'name': 'undisplayExtrudedSS', 'cmd': UndisplayExtrudedSSCommand(), 1523 'gui': None}, 1524 {'name': 'ribbon', 'cmd':RibbonCommand(), 1525 'gui':RibbonGUI}, 1526 ] 1527 1528
1529 -def initModule(viewer):
1530 """ initializes commands for secondary structure and extrusion. Also 1531 imports the commands for Secondary Structure specific coloring, and 1532 initializes these commands also. """ 1533 1534 for dict in commandList: 1535 viewer.addCommand(dict['cmd'], dict['name'], dict['gui'])
1536