1
2
3
4
5
6
7
8
9
10
11
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
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
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
75
76
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
91
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
105
106
107 try:
108 import stride
109 self.haveStride = 1
110 except:
111 self.haveStride = 0
112
113
114
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
120
121
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
142 for mol in molecules:
143
144 if molModes is None:
145
146 if mol.hasSS:
147
148
149 continue
150 else:
151
152
153 if mol.parser.hasSsDataInFile():
154
155
156 mode = 'From File'
157 elif self.haveStride:
158
159
160 mode='From Stride'
161 else:
162
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
168
169 if not molModes.has_key(mol.name):
170
171
172 print 'No mode has been specifyed for %s'%mol.name
173 continue
174 else:
175
176 mode = molModes[mol.name]
177
178 if mode in mol.hasSS: continue
179
180
181
182 elif mol.hasSS != []:
183 self.clean(mol)
184
185
186 if mode == 'From File':
187
188
189 if not mol.parser.hasSsDataInFile():
190
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
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
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
228
229
230
231
232 molName = mol.name
233 mol.hasSS = []
234
235
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
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
247 delattr(chain, 'secondarystructureset')
248
249
250
251 resWithSS = filter(lambda x:hasattr(x, 'secondarystructure'),
252 chain.residues)
253 resTest = map(lambda x:
254 delattr(x, 'secondarystructure'),
255 resWithSS)
256
257
258 self.onRemoveObjectFromViewer(mol)
259
260
261 for c in mol.chains:
262 if hasattr(c, 'sheet2D') and c.sheet2D.has_key('ssSheet2D'):
263 del c.sheet2D['ssSheet2D']
264
330
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
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
377
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
392
393
394
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
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
420
421
422 obj.__hasSSGeom = 0
423
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
452
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
462 geomC.atoms[name] = ResidueSet()
463
464
465 obj.__hasSSGeom = 1
466
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
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
500
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
550
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
560
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
578 for mol, residues in map(None, molecules, residueSets):
579 if not mol.hasSS:
580
581 self.vf.computeSecondaryStructure(mol, topCommand=0)
582 if not hasattr(mol,'__hasSSGeom') or not mol.__hasSSGeom:
583
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
607
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
636 ssSet.sheet2D = sd
637 if sd is None : continue
638
639
640 removeSS =[]
641
642 for SS in ssSet:
643
644
645
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
654
655
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
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
693
694
695
696
697
698 g.Set(vertices=SS.exElt.vertices,
699 faces = resfaces,
700
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
718 apply(self.vf.displayExtrudedSS,(nodes,), kw)
719
720 self.flagNucleicAcidsProperties = True
721
722
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
924
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
1014
1015
1016
1017
1018
1019
1020
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
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 """
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
1064 self.expandedNodes____ResidueSets = res
1065 self.expandedNodes____Molecules = mol
1066
1067 return self.expandedNodes____Molecules, self.expandedNodes____ResidueSets
1068
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
1088 if len(nodes)==0 : return
1089
1090 molecules, residueSets = self.getNodes(nodes)
1091
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
1099
1100
1101 set = ResidueSet()
1102 for ss in SSinMol:
1103 set = set + mol.geomContainer.atoms[ss.name+ss.chain.id]
1104 if len(set)==0:
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
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
1124 if negate: set = ResidueSet()
1125 else: set = res
1126 else:
1127
1128 if negate :
1129 set = set - res
1130
1131 else:
1132 if only:
1133 set = res
1134 else:
1135 set = res.union(set)
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153 g = mol.geomContainer.geoms[name]
1154 mol.geomContainer.atoms[name] = set
1155
1156 if not hasattr(SS, 'exElt'): return
1157 resfaces = SS.exElt.getExtrudeResidues(set)
1158 col = mol.geomContainer.getGeomColor(name)
1159
1160
1161
1162
1163
1164
1165
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
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
1220
1221
1222
1223
1224 drawResidues(ss, res, only , negate )
1225
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
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
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 """
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
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
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 """
1317
1318
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
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
1358 apply(self.doitWrapper, (nodes,), kw)
1359
1360
1361 - def doit(self, nodes, **kw):
1362
1363 apply(self.vf.computeSecondaryStructure,(nodes,), {'topCommand':False})
1364 kw['topCommand'] = 0
1365
1366
1367 apply(self.vf.extrudeSecondaryStructure,(nodes,), kw)
1368
1369
1370
1371
1372
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 """
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
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
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
1422
1423
1424
1425
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
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
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
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