1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import os
17 import warnings
18
19 from NetworkEditor.items import NetworkNode
20 from Vision import UserLibBuild
21
22 from MolKit.molecule import MoleculeSet
23 from MolKit.tree import TreeNodeSet
24 from ViewerFramework.VFCommand import Command
25 from Pmv.moleculeViewer import MoleculeViewer
26 from mglutil.util.relpath import relpath
27
28
30 try:
31 from MolKit.VisionInterface.MolKitNodes import molkitlib
32 net.editor.addLibraryInstance(
33 molkitlib, 'MolKit.VisionInterface.MolKitNodes', 'molkitlib')
34 except:
35 warnings.warn(
36 'Warning! Could not import molitlib from MolKit.VisionInterface')
37
38
40 try:
41 from symserv.VisionInterface.SymservNodes import symlib
42 net.editor.addLibraryInstance(
43 symlib, 'symserv.VisionInterface.SymservNodes', 'symlib')
44 except:
45 warnings.warn(
46 'Warning! Could not import molitlib from symserv.VisionInterface.SymservNodes.py')
47
48
50 try:
51 from DejaVu.VisionInterface.DejaVuNodes import vizlib
52 net.editor.addLibraryInstance(
53 vizlib, 'DejaVu.VisionInterface.DejaVuNodes', 'vizlib')
54 except:
55 warnings.warn(
56 'Warning! Could not import vizlib from DejaVu/VisionInterface')
57
58
60 try:
61 from Volume.VisionInterface.VolumeNodes import vollib
62 net.editor.addLibraryInstance(
63 vollib, 'Volume.VisionInterface.VolumeNodes', 'vollib')
64 except:
65 warnings.warn(
66 'Warning! Could not import vollib from Volume/VisionInterface')
67
68
69 from DejaVu.VisionInterface.DejaVuNodes import Viewer
71
76
77
79 pass
80
81
83 self.vi.RemovePickingCallback(self.handlePick)
84 pass
85
86
87
89
90 - def __init__(self, vf=None, name='PMV', **kw):
91 kw['name'] = name
92 apply( NetworkNode.__init__, (self,), kw )
93
94
95 self.vf = vf
96
97 self.widgetDescr['cmdName'] = {
98 'class': 'NEComboBox', 'master':'node',
99 'choices':[''],
100 'autoList':True,
101 'entryfield_entry_width':14,
102 'labelCfg':{'text':'cmd:'},
103 }
104
105 self.widgetDescr['molecule'] = {
106 'class':'NEComboBox', 'master':'node',
107 'choices':[''],
108 'autoList':True,
109 'entryfield_entry_width':16,
110 'labelCfg':{'text':'molecules:'},
111 }
112
113 self.inputPortsDescr.append(datatype='string', required=False, name='cmdName')
114 self.inputPortsDescr.append(datatype='string', name='molecule')
115
116 self.outputPortsDescr.append(datatype='PmvInstance', name='PMV')
117 self.outputPortsDescr.append(datatype='PmvCmd', name='cmd')
118 self.outputPortsDescr.append(datatype='Molecule', name='molecule')
119 self.outputPortsDescr.append(datatype='TreeNodeSet', name='nodes')
120
121 code = """def doit(self, cmdName, molecule):
122 allCommandNames = self.vf.commands.keys()
123 allCommandNames.sort()
124 self.inputPortByName['cmdName'].widget.configure(choices=allCommandNames)
125 if cmdName and cmdName in allCommandNames:
126 obj = self.vf.commands[cmdName]
127 if obj:
128 self.outputData(cmd=obj )
129
130 allMoleculeNames = map(lambda x: x.name, self.vf.Mols)
131 w = self.inputPortByName['molecule'].widget
132 if w:
133 w.configure(choices=allMoleculeNames)
134 if molecule not in allMoleculeNames:
135 w.widget.setentry('')
136 self.outputData(molecule=None)
137 else:
138 obj = self.vf.Mols.get(molecule)
139 if obj:
140 self.outputData(molecule=obj)
141
142 if hasattr(self.vf, 'select'):
143 # output PMV's current selection
144 self.outputData(nodes=self.vf.getSelection())
145
146 self.outputData(PMV=self.vf)
147 """
148 if code:
149 self.setFunction(code)
150
151
155
156
161
162
163
165
170
171
172 - def __init__(self, grid=None, name='volume', **kw):
173 kw['name'] = name
174 apply( NetworkNode.__init__, (self,), kw )
175
176
177 self.grid = grid
178
179 code = """def doit(self):
180 self.outputData(grid=self.grid)
181 """
182 if code:
183 self.setFunction(code)
184
185 self.outputPortsDescr.append(datatype='Grid3D', name='grid')
186
187
189
190
191 - def __init__(self, molecule=None, name='Molecule', **kw):
192 self.mol = molecule
193 kw['name'] = name
194 apply( NetworkNode.__init__, (self,), kw )
195
196 code = """def doit(self):
197 self.outputData(Molecule=self.mol)
198 """
199 if code: self.setFunction(code)
200 self.outputPortsDescr.append(datatype='Molecule', name='Molecule')
201
202
206
207
210
211 """subclass baseclass method to add lines to load the molecule in
212 Pmv if it is not loaded yet"""
213
214 lines = []
215 if self.network.filename is not None:
216 lNetworkDir = os.path.dirname(os.path.abspath(self.network.filename))
217 lFileName = relpath(lNetworkDir, os.path.abspath(self.mol.parser.filename))
218 else:
219 assert False, "my guess is we don't go here"
220 lFileName = self.mol.parser.filename
221
222
223 s00 = 'import os\n'
224 s01 = 'from mglutil.util.relpath import rel2abs\n'
225 s02 = "lRelFileName = '%s'\n"%lFileName
226
227 s03 = 'lNetworkDir = os.path.dirname(os.path.abspath(%s.filename))\n'%networkName
228 s04 = 'lAbsFileName = rel2abs(lRelFileName, lNetworkDir)\n'
229
230 s1 = 'mol = %s.editor.vf.loadMoleculeIfNeeded(lAbsFileName)\n'%networkName
231 s2 = 'assert mol\n'
232 lines.append(indent+s00)
233 lines.append(indent+s01)
234 lines.append(indent+s02)
235 lines.append(indent+s03)
236 lines.append(indent+s04)
237 lines.append(indent+s1)
238 lines.append(indent+s2)
239 lines.extend(NetworkNode.getNodeDefinitionSourceCode(
240 self, networkName, indent, ignoreOriginal) )
241 return lines
242
243
245 """Handle to a Pmv Set.
246 Output: MolKit TreeNodeSet containing a set of either molecules, chains,
247 residues, or atoms that exists in Pmv"""
248
249 - def __init__(self, set=None, selString=None, name='Pmv Set', **kw):
250 self.set = set
251 self.selString = selString
252 kw['name'] = name
253 apply( NetworkNode.__init__, (self,), kw )
254
255 self.outputPortsDescr.append(datatype='Molecule', name='PmvSet')
256 self.outputPortsDescr.append(datatype='string', name='selection')
257
258 code = """def doit(self):
259 self.outputData(PmvSet=self.set, selection=self.selString)\n"""
260
261 if code: self.setFunction(code)
262
263
267
268
271
272 """subclass baseclass method to add lines to load the molecule in
273 Pmv if it is not loaded yet"""
274
275 if self.network.filename is not None:
276 lNetworkDir = os.path.dirname(os.path.abspath(self.network.filename))
277 else:
278 assert False, "my guess is we don't go here"
279
280 lines = []
281 molecules = []
282 for mol in self.set.top.uniq().data:
283
284 if self.network.filename is not None:
285 lFileName = relpath(lNetworkDir, os.path.abspath(mol.parser.filename))
286 else:
287 assert False, "my guess is we don't go here"
288 lFileName = mol.parser.filename
289 molecules.append(lFileName)
290
291
292 s0 = 'import os\n'
293 s1 = 'from mglutil.util.relpath import rel2abs\n'
294 s2 = 'lNetworkDir = os.path.dirname(os.path.abspath(%s.filename))\n'%networkName
295 s3 = 'mols = %s\n'%molecules
296 s4 = 'for m in mols:\n'
297 s5 = ' lAbsFileName = rel2abs(m, lNetworkDir)\n'
298 s6 = ' mol = %s.editor.vf.loadMoleculeIfNeeded(lAbsFileName)\n'%networkName
299 s7 = ' assert mol\n'
300 s8 = 'selString = "%s"\n'%self.selString
301 s9 = '%s.editor.vf.loadModule("selectionCommands")\n'%networkName
302 s10 = '%s.editor.vf.createSetIfNeeded(selString, "%s")\n'%(networkName, self.name)
303 s11 = 'from Pmv.selectionCommands import sets__\n'
304 lines.append(indent+s0)
305 lines.append(indent+s1)
306 lines.append(indent+s2)
307 lines.append(indent+s3)
308 lines.append(indent+s4)
309 lines.append(indent+s5)
310 lines.append(indent+s6)
311 lines.append(indent+s7)
312 lines.append(indent+s8)
313 lines.append(indent+s9)
314 lines.append(indent+s10)
315 lines.append(indent+s11)
316
317 lines.extend(NetworkNode.getNodeDefinitionSourceCode(
318 self, networkName, indent, ignoreOriginal) )
319 return lines
320
321
323
324 - def __init__(self, name='cmd chooser', **kw):
325 kw['name'] = name
326
327 apply( NetworkNode.__init__, (self,), kw )
328
329 self.widgetDescr['cmdName'] = {
330 'class': 'NEComboBox', 'master':'node',
331 'choices':[''],
332 'autoList':True,
333 'entryfield_entry_width':14,
334 'labelCfg':{'text':'cmd:'},
335 }
336
337 self.inputPortsDescr.append(datatype='PmvInstance', name='viewer')
338 self.inputPortsDescr.append(datatype='string', required=False, name='cmdName')
339 self.outputPortsDescr.append(datatype='PmvCmd', name='cmd')
340
341 code = """def doit(self, viewer, cmdName):
342 if viewer:
343 allNames = viewer.commands.keys()
344 allNames.sort()
345 self.inputPortByName['cmdName'].widget.configure(choices=allNames)
346 if cmdName and cmdName in allNames:
347 obj = viewer.commands[cmdName]
348 if obj:
349 self.outputData(cmd=obj )\n"""
350
351 self.setFunction(code)
352
353
355
356 - def __init__(self, pmvCmd, name='pmv cmd', **kw):
357 self.cmd = pmvCmd
358 kw['name'] = name
359
360 apply( NetworkNode.__init__, (self,), kw )
361
362 self.widgetDescr['log'] = {
363 'class':'NECheckButton',
364 'initialValue':1,
365 'labelCfg':{'text':'log'},
366 }
367
368 self.widgetDescr['redraw'] = {
369 'class':NECheckButton,
370 'initialValue':1,
371 'labelCfg':{'text':'redraw'},
372 }
373
374 self.widgetDescr['topCommand'] = {
375 'class':NECheckButton,
376 'initialValue':1,
377 'labelCfg':{'text':'topCommand'},
378 }
379
380 self.widgetDescr['setupUndo'] = {
381 'class':'NECheckButton',
382 'initialValue':0,
383 'labelCfg':{'text':'setupUndo'},
384 }
385
386 ip = self.inputPortsDescr
387 ip.append(datatype='int', name='log')
388 ip.append(datatype='int', name='redraw')
389 ip.append(datatype='int', name='topCommand')
390 ip.append(datatype='int', name='setupUndo')
391
392
394
395
397
398 self.posArgNames = []
399 self.posArgNamesDict = {}
400
401 for arg in args:
402 ipdescr = {'name':arg}
403 ip = apply( self.addInputPort, (), ipdescr )
404
405
407 import types
408 namelist = namedArgs.keys()
409
410 for name in namelist:
411 val = namedArgs[name]
412 dtype = 'None'
413 if type(val) is types.BooleanType:
414 dtype = 'boolean'
415 self.widgetDescr[name] = {
416 'class': 'NECheckButton',
417 'initialValue':val==True,
418 'labelGridCfg':{'sticky':'w'},
419 'labelCfg':{'text':name},
420 }
421
422 elif type(val) in [ types.IntType, types.LongType]:
423 dtype = 'int'
424 self.widgetDescr[name] = {
425 'class': 'NEDial', 'size':50,
426 'showLabel':1, 'oneTurn':1, 'type':'int',
427 'initialValue':val,
428 'labelGridCfg':{'sticky':'w'},
429 'labelCfg':{'text':name},
430 }
431
432 elif type(val) in [types.FloatType, types.FloatType]:
433 dtype = 'float'
434 self.widgetDescr[name] = {
435 'class': 'NEDial', 'size':50,
436 'showLabel':1, 'oneTurn':1, 'type':'float',
437 'initialValue':val,
438 'labelGridCfg':{'sticky':'w'},
439 'labelCfg':{'text':name},
440 }
441
442 elif type(val) is types.StringType:
443 dtype = 'string'
444 self.widgetDescr[name] = {
445 'class': 'NEEntry', 'width':10,
446 'initialValue':val,
447 'labelGridCfg':{'sticky':'w'},
448 'labelCfg':{'text':name},
449 }
450
451 ipdescr = {'name':name, 'required':False, 'datatype':dtype,
452 'balloon':'Defaults to'+str(val),
453 'singleConnection':True}
454
455 ip = apply( self.addInputPort, (), ipdescr )
456
457 if dtype != 'None':
458 ip.createWidget(descr=self.widgetDescr[name])
459
460 return namelist
461
462
463 - def __init__(self, command=None, posArgsNames=[], namedArgs={},
464 sortedArgNames=[], name='run command', **kw):
465 kw['name'] = name
466
467 apply( NetworkNode.__init__, (self,), kw )
468
469 self.command = command
470
471 self.posArgsNames = posArgsNames
472 self.namedArgs = namedArgs
473 self.sortedArgNames = sortedArgNames
474 self.defaultNamedArgs = ['log', 'redraw', 'topCommand', 'setupUndo']
475 self.defaultNamedArgsdefaults = [ True, True, True, True]
476
477 ip = self.inputPortsDescr
478 codeBeforeDisconnect = """def beforeDisconnect(self, c):
479 # upon disconnecting we want to set the attribute command to None
480 c.port2.node.command = None
481 """
482
483 ip.append(name='command', required=True, datatype='PmvCmd',
484 beforeDisconnect=codeBeforeDisconnect)
485
486 self.outputPortsDescr.append(datatype='None', name='result')
487
488 code = """def doit(self, command, *args):
489 if command is None:
490 return
491 if command is not self.command and command is not None:
492 # remember current command
493 self.command = command
494 self.rename('Run '+command.name)
495
496 # remove all ports beyond the command input port
497 for p in self.inputPorts[1:]:
498 self.deletePort(p, updateSignature=False)
499
500 # get arguments description
501 from inspect import getargspec
502 args = getargspec(command.__call__.im_func)
503 allNames = args[0][1:] # get rid of self
504 defaultValues = args[3]
505 if defaultValues is None:
506 defaultValues = []
507 nbNamesArgs = len(defaultValues)
508 if nbNamesArgs > 0:
509 self.posArgsNames = args[0][1:-nbNamesArgs]
510 else:
511 self.posArgsNames = args[0][1:]
512 d = {}
513 for name, val in zip(args[0][-nbNamesArgs:], defaultValues):
514 d[name] = val
515 for name, val in zip(self.defaultNamedArgs, self.defaultNamedArgsdefaults):
516 d[name] = val
517
518 self.namedArgs = d
519
520 # create input ports for positional arguments
521 self.createPortsForPositionalArgs(self.posArgsNames)
522
523 # create widgets and ports for named arguments
524 self.sortedArgNames = self.buildPortsForNamedArgs(self.namedArgs)
525
526 # create the constructor arguments such that when the node is restored
527 # from file it will have all the info it needs
528 self.constrkw['command'] = 'masterNet.editor.vf.%s'%command.name
529 self.constrkw['posArgsNames'] = str(self.posArgsNames)
530 self.constrkw['namedArgs'] = str(self.namedArgs)
531 self.constrkw['sortedArgNames'] = str(self.sortedArgNames)
532
533 elif self.command is not None:
534 # get all positional arguments
535 posargs = []
536 for pn in self.posArgsNames:
537 posargs.append(locals()[pn])
538
539 # build named arguments
540 kw = {}
541 for arg in self.sortedArgNames:
542 kw[arg] = locals()[arg]
543
544 # call command
545 value = apply( self.command.__call__, posargs, kw )
546
547 self.outputData(result=value)
548 """
549 if code: self.setFunction(code)
550
551
552
553
554 try:
555 from mslib import MSMS
556 msmsFound=1
557 except:
558 msmsFound=0
559 warnings.warn("could not find MSMS library")
560
562 """Get a handle to an MSMS surface geometry for a molecule loaded in PMV
563
564 Input:
565 molecule: the molecule for which we want a handle to a surface
566 surfaceName: the name of the surface we want
567 Output:
568 msmsGeom: an IndexedPolygons geometry corresponding to an MSMS surface
569 calculated in PMV
570 """
571 - def __init__(self, constrkw = {}, name='Get MSMS Geom', **kw):
572 kw['name'] = name
573 apply( NetworkNode.__init__, (self,), kw)
574
575 self.widgetDescr['surfaceName'] = {
576 'initialValue': 'MSMS-MOL', 'fixedChoices': 0,
577 'choices': ['MSMS-MOL'], 'labelGridCfg': {},
578 'master': 'node', 'widgetGridCfg': {},
579 'labelCfg': {'text': 'surface:'}, 'class': 'NEComboBox',
580 }
581
582 self.inputPortsDescr.append(name='molecule', datatype='Molecule')
583 self.inputPortsDescr.append(name='surfaceName', datatype='string')
584
585 self.outputPortsDescr.append(name='msmsGeom', datatype='geom')
586
587 code = """def doit(self, molecule, surfaceName='MSMS-MOL'):
588 if molecule:
589 allNames = molecule.geomContainer.msms.keys()
590 self.inputPorts[1].widget.configure(choices=allNames)
591 srf = molecule.geomContainer.geoms.get(surfaceName, None)
592 self.outputData(msmsGeom=srf)
593 """
594 self.setFunction(code)
595
596
602
603
605 """Set the radius of the atoms currently selected in PMV"""
606
607 - def __init__(self, name='Set radius', **kw):
608 kw['name'] = name
609
610 apply( NetworkNode.__init__, (self,), kw )
611
612 self.inputPortsDescr.append(datatype='PmvInstance',
613 balloon='Pmv instance holding the selection of atoms ',
614 name='Pmv')
615 self.inputPortsDescr.append(datatype='float', name='radius')
616
617 code = """def doit(self, Pmv, radius):
618 sel = Pmv.getSelection()
619 from MolKit.molecule import Atom
620 atsel = sel.findType(Atom)
621 for a in atsel:
622 a.radius = radius
623 Pmv.displayCPK(atsel)\n"""
624
625 self.setFunction(code)
626
627 import Numeric
628
630 """Apply (4x4) transformation matrices to all geometries associated with
631 a given molecule currently displayed in PMV.
632 Input:
633 molecule: a PMV molecule
634 matrices: (4x4) transformation matrices
635 """
636
637 - def __init__(self, name='Set Instances', **kw):
638 kw['name'] = name
639
640 apply( NetworkNode.__init__, (self,), kw )
641
642 self.inputPortsDescr.append(datatype='Molecule', name='molecule')
643 self.inputPortsDescr.append(datatype='instancemat(0)',
644 name='matrices', required=False)
645
646 code = """def doit(self, molecule, matrices=[Numeric.identity(4,'f')]):
647 if molecule:
648 assert hasattr(molecule, 'geomContainer')
649
650 geom = molecule.geomContainer.geoms['master']
651 geom.Set(instanceMatrices=matrices)
652
653 geom.viewer.Redraw()\n"""
654
655 self.setFunction(code)
656
657
663
664
666 """Returns the current selection as a TreeNodeSet.
667 Note: when the selection changes in Pmv, this node has to re-run by the user.
668
669 Input:
670 Pmv: an instance of Pmv
671
672 Output:
673 nodes: the current Pmv selection
674 """
675
676 - def __init__(self, name='Pmv Selection', **kw):
677 kw['name'] = name
678
679 apply( NetworkNode.__init__, (self,), kw )
680
681 self.inputPortsDescr.append(datatype='PmvInstance',
682 balloon='Pmv instance holding the selection of atoms',
683 name='Pmv')
684
685 self.outputPortsDescr.append(datatype='TreeNodeSet', name='nodes')
686
687 code = """def doit(self, Pmv):
688 if not Pmv:
689 return
690
691 # selection command loaded?
692 if not hasattr(Pmv, 'select'):
693 return
694
695 # output PMV's current selection
696
697 self.outputData(nodes=Pmv.getSelection())
698 """
699
700 self.setFunction(code)
701
702
706
707
709 """Provides a list of molecules currently loaded in PMV in a ComboBox
710 and lets the user select one.
711
712 Input:
713 Pmv: an instance of Pmv
714
715 Output:
716 nodes: Molecule
717 """
718
719 - def __init__(self, name='Pmv Mol. Chooser', **kw):
720 kw['name'] = name
721
722 apply( NetworkNode.__init__, (self,), kw )
723
724 self.widgetDescr['molecule'] = {
725 'class':'NEComboBox', 'master':'node',
726 'choices':[''],
727 'autoList':True,
728 'entryfield_entry_width':16,
729 'labelCfg':{'text':'molecules:'},
730 }
731
732 self.inputPortsDescr.append(
733 datatype='PmvInstance',
734 balloon='Pmv instance holding the selection of atoms',
735 name='Pmv')
736 self.inputPortsDescr.append(datatype='string', name='molecule')
737 self.outputPortsDescr.append(datatype='Molecule', name='molecule')
738
739 code = """def doit(self, Pmv, molecule):
740 assert Pmv is not None
741
742 allNames = map(lambda x: x.name, Pmv.Mols)
743 w = self.inputPortByName['molecule'].widget
744 if w:
745 w.configure(choices=allNames)
746 if molecule not in allNames:
747 w.widget.setentry('')
748 self.outputData(molecule=None)
749 else:
750 obj = Pmv.Mols.get(molecule)
751 if obj:
752 self.outputData(molecule=obj)
753 """
754
755 self.setFunction(code)
756
757
761
762
763 from Vision.VPE import NodeLibrary
764 pmvlib = NodeLibrary('Pmv', '#7A7AFF')
765
766 pmvlib.addNode(PmvChooseCommand, 'Choose Cmd', 'Filter',)
767
768 pmvlib.addNode(PmvSetCPKRadii, 'Set CPK radii', 'Mapper',)
769 pmvlib.addNode(PmvSetInstanceMatrices, 'Set Instances', 'Mapper',)
770
771 pmvlib.addNode(PmvRunCommand, 'Run Command', 'Output',)
772 pmvlib.addNode(PmvGetSelection, 'Get Selection', 'Input',)
773 pmvlib.addNode(PmvMoleculeChooser, 'Choose Molecule', 'Input',)
774
775 if msmsFound==1:
776 pmvlib.addNode(GetMSMSGeom, 'Get MSMS Geom', 'Filter')
777
778
779
780 UserLibBuild.addTypes(pmvlib, 'Pmv.VisionInterface.PmvTypes')
781
782 try:
783 UserLibBuild.addTypes(pmvlib, 'DejaVu.VisionInterface.DejaVuTypes')
784 except:
785 pass
786
787 try:
788 UserLibBuild.addTypes(pmvlib, 'MolKit.VisionInterface.MolKitTypes')
789 except:
790 pass
791