コード例 #1
0
ファイル: setangleCommands.py プロジェクト: lisarosalina/App
class SetTorsionGUICommand(MeasureTorsionGUICommand):
    def guiCallback(self):
        self.save = self.vf.ICmdCaller.commands.value["Shift_L"]
        self.vf.setICOM(self, modifier="Shift_L", topCommand=0)
        if not hasattr(self, 'form'):
            self.buildForm()
        else:
            self.form.deiconify()

    def onAddCmdToViewer(self):
        if not hasattr(self.vf, 'GUI'):
            return
        self.undoNow = 0
        self.save = None
        from DejaVu.bitPatterns import pat3
        from DejaVu.IndexedPolygons import IndexedPolygons
        if not self.vf.commands.has_key('setICOM'):
            self.vf.loadCommand('interactiveCommands',
                                'setICOM',
                                'Pmv',
                                topCommand=0)
        if not self.vf.commands.has_key('measureTorsion'):
            self.vf.loadCommand('measureCommands',
                                'measureTorsion',
                                'Pmv',
                                topCommand=0)

        self.masterGeom = Geom('setTorsionGeom',
                               shape=(0, 0),
                               pickable=0,
                               protected=True)
        self.masterGeom.isScalable = 0
        self.vf.GUI.VIEWER.AddObject(self.masterGeom,
                                     parent=self.vf.GUI.miscGeom)
        self.lines = IndexedPolygons(
            'settorsionLine',
            materials=((0, 1, 1), ),
            inheritMaterial=0,
            stipplePolygons=1,
            protected=True,
        )
        if self.vf.userpref['Sharp Color Boundaries for MSMS'][
                'value'] == 'blur':
            self.lines.Set(
                inheritSharpColorBoundaries=False,
                sharpColorBoundaries=False,
            )
        self.lines.polygonstipple.Set(pattern=pat3)  #, tagModified=False)
        #self.lines.RenderMode(GL.GL_FILL, face=GL.GL_BACK)
        self.lines.Set(backPolyMode=GL.GL_FILL)
        self.labels = GlfLabels(name='settorsionLabel',
                                shape=(0, 3),
                                inheritMaterial=0,
                                materials=((0, 1, 1), ))
        self.spheres = Spheres(name='settorsionSpheres',
                               shape=(0, 3),
                               radii=0.2,
                               quality=15,
                               inheritMaterial=0,
                               materials=((0., 1., 1.), ),
                               protected=True)
        for item in [self.lines, self.labels, self.spheres]:
            self.vf.GUI.VIEWER.AddObject(item, parent=self.masterGeom)
        self.snakeLength = 1
        self.oldValue = None
        self.torsionType = Tkinter.StringVar()
        self.torsionType.set('1')
        self.newAngList = Tkinter.StringVar()
        self.TAHdata = None
        self.molecule = None
        #self.bondString = Tkinter.StringVar()
        self.callbackDict = {}
        self.callbackDict['measureDistanceGC'] = 'update'
        self.callbackDict['measureAngleGC'] = 'update'
        self.callbackDict['measureTorsionGC'] = 'update'

    def onRemoveObjectFromViewer(self, mol):
        lenAts = len(self.atomList)
        #if cmd has no atoms on its list, nothing to do
        if not lenAts:
            return
        #remove any atoms which are being deleted from viewer
        self.atomList = AtomSet(self.atomList) - mol.allAtoms
        #if some have been removed, do an update
        if lenAts != len(self.atomList):
            self.update()
            self.extslider.set(0)

    def __call__(self, atoms, angle=None, **kw):
        """torsion/None<-setTorsionGC(atoms, angle=None)
        the torsion is returned when the number of atoms is a multiple of 4"""
        ats = self.vf.expandNodes(atoms)
        if not len(ats): return 'ERROR'
        return apply(self.doitWrapper, (
            ats,
            angle,
        ), kw)

    def doit(self, ats, angle):
        for at in ats:
            lenAts = len(self.atomList)
            if lenAts and lenAts % 4 != 0 and at == self.atomList[-1]:
                continue
            if len(self.atomList) == 0:
                self.molecule = at.top
            if at.top == self.molecule:
                self.atomList.append(at)
            else:
                #all atoms in torsion must be in same molecule ...(?)
                s = at.full_name() + " not in " + self.molecule.full_name()
                self.warningMsg(s)
                return 'ERROR'
            if len(self.atomList) > 4 * self.snakeLength:
                self.atomList = self.atomList[4:]
            self.update()
        if len(self.atomList) == 4:
            mol = self.atomList[0].top
            at0, at1, at2, at3 = self.atomList
            self.mov_atoms = mol.subTree(at1, at2, mol.allAtoms)
            self.oldValue = self.vf.measureTorsion.doit(at0, at1, at2, at3)
            self.origValue = self.oldValue
            self.origCoords = self.mov_atoms.coords
            if hasattr(self, 'extslider'):
                self.extslider.set(self.oldValue, update=0)
            if angle:
                #angle is what you want to end up with
                deltaAngle = angle - self.oldValue
                #print 'deltaAngle=', deltaAngle, 'angle=', angle
                self.transformCoords(deltaAngle)
                if hasattr(self, 'extslider'):
                    self.extslider.set(angle, update=0)
                #s = self.atomList[2].full_name()+'--'+self.atomList[3].full_name()
                #self.bondString.set(s)
            self.updateHistory()
            ##if self.undoNow: raise 'abc'
            #return float(self.labelStrs[-1])
            return

    def update(self, forward=1, event=None):
        if not len(self.atomList):
            self.spheres.Set(vertices=[], tagModified=False)
            self.labels.Set(vertices=[], tagModified=False)
            self.lines.Set(vertices=[], tagModified=False)
            self.vf.GUI.VIEWER.Redraw()
            return
        limit = self.snakeLength
        #each time have to recalculate lineVertices
        self.lineVertices = []
        for at in self.atomList:
            c1 = self.getTransformedCoords(at)
            self.lineVertices.append(tuple(c1))
        #display spheres:
        self.spheres.Set(vertices=self.lineVertices, tagModified=False)
        self.vf.GUI.VIEWER.Redraw()
        #label with torsion
        #lines between spheres are only drawn when angle completed
        #that is, len(ats)%4=0
        if len(self.lineVertices) < 4:
            self.labels.Set(vertices=[], tagModified=False)
            self.lines.Set(vertices=[], tagModified=False)
        else:
            #rebuild labels and polygons each time
            self.labelCenters = []
            self.labelStrs = []
            #labelCenters, labelStrs,
            #this gets done lenATs/4 times
            numItems = len(self.atomList) / 4
            for i in range(numItems):
                at0, at1, at2, at3 = self.atomList[i * 4:i * 4 + 4]
                torsion = self.vf.measureTorsion.doit(at0, at1, at2, at3)
                torsionLabel = '%.3f' % torsion
                self.labelStrs.append(torsionLabel)
                c0 = self.getTransformedCoords(at0)
                c1 = self.getTransformedCoords(at3)
                newcenter = tuple((c0 + c1) / 2.0)
                self.labelCenters.append(newcenter)
        self.vf.GUI.VIEWER.Redraw()
        items = self.callbackDict.keys()
        #items = ['measureDistanceGC','measureAngleGC','measureTorsionGC']
        #checkout whether measure update needs to be called
        icomVals = self.vf.ICmdCaller.commands.value.values()
        for item in items:
            if not len(icomVals): break
            if not hasattr(self.vf, item):
                continue
            exec('cmd = self.vf.' + item)
            if cmd in icomVals:
                #cmd.update()
                s = self.callbackDict[item]
                exec('self.vf.' + item + '.' + s + '()')

    def transformCoords(self, deltaAngle):
        """ deltaAngle is NOW not final angle wanted but relative"""
        #mov_coords is the array of the coords of the atoms to be moved,
        #x2 and x3 are atoms which define the axis of the transformation
        #by deltaAngle. NB: effect is that mov_atoms.coords
        #are transformed...
        if not hasattr(self, 'mov_atoms'): return
        if not len(self.mov_atoms): return
        x1, x2, x3, x4 = self.atomList
        nc = self.vf.setRelativeTorsion.doit(x2,
                                             x3,
                                             deltaAngle,
                                             self.mov_atoms,
                                             returnVal=1)
        mol = x2.top
        #mov_atoms = mol.subTree(x2, x3, mol.allAtoms)
        for i in range(len(nc)):
            at = self.mov_atoms[i]
            at._coords[at.conformation] = nc[i].tolist()
        event = EditAtomsEvent('coords', self.mov_atoms)
        self.vf.dispatchEvent(event)
        self.update()


#####Callback Functions for the Dial:
#####slideCallback

    def slideCallback(self, eventval):
        #print 'in slideCallback'
        if len(self.atomList) != 4: return
        if not hasattr(self, 'oldValue'): return
        if self.oldValue == None:
            return
        #self.setupUndoBefore(self.atomList, self.oldValue)
        try:
            newAngle = self.extslider.get()
            tT = self.torsionType.get()
            at0, at1, at2, at3 = self.atomList
            #torsion = self.vf.measureTorsion.doit(at0, at1, at2, at3)
            torsion = self.oldValue
            if tT == '1':
                #NEWdeltaAngle = newAngle
                deltaAngle = newAngle - torsion
            else:
                #NEWdeltaAngle = newAngle + torsion
                deltaAngle = newAngle
            self.transformCoords(deltaAngle)
            #print 'deltaAngle=', deltaAngle
            self.oldValue = newAngle
            #self.oldValue = newAngle
        except ValueError:
            self.vf.GUI.message("error in slideCallback\n")

    def rdSet(self, event=None):
        #"""radiobutton selection of torsionType:
        #Absolute: initial angle to be displayed in slider/entry
        #Relative: 0 is displayed """
        if self.torsionType.get() == '1':
            aL = self.atomList
            if len(aL) == 4:
                torsion = self.vf.measureTorsion.doit(aL[0], aL[1], aL[2],
                                                      aL[3])
                self.extslider.set(torsion)
        else:
            self.extslider.set(0)

    def setupUndoBefore(self, ats, angle):
        pass

    #def setupUndoBefore(self, ats, angle):
    ##no atoms, <4 atoms,
    #aSet = AtomSet(self.atomList)
    #self.undoMenuString = self.name
    #if len(self.atomList)==0:
    #undoCmd = 'self.setTorsionGC.atomList=[]; self.setTorsionGC.update()'
    #elif len(self.atomList)<4:
    ##need to step back here
    #undoCmd = 'self.setTorsionGC.atomList=self.setTorsionGC.atomList[:-1]; self.setTorsionGC.update()'
    #else:
    ##print 'self.oldValue=', self.oldValue
    #undoCmd = 'self.setTorsionGC(\''+ aSet.full_name()+ '\',' + str(self.oldValue) + ', topCommand=0)'
    ##self.oldValue = str(self.extslider.get())
    #self.vf.undo.addEntry((undoCmd), (self.name))

    def setupUndoAfter(self, ats, angle, **kw):
        #no atoms, <4 atoms,
        aSet = AtomSet(self.atomList)
        self.undoMenuString = self.name
        if len(self.atomList) == 0:
            undoCmd = 'self.setTorsionGC.atomList=[]; self.setTorsionGC.update()'
        elif len(self.atomList) < 4:
            #need to step back here
            undoCmd = 'self.setTorsionGC.atomList=self.setTorsionGC.atomList[:-1]; self.setTorsionGC.update()'
        elif self.origValue == self.oldValue:
            return
        else:
            restoreAngle = self.origValue
            self.undoNow = 1
            undoCmd = 'self.setTorsionGC(\'' + aSet.full_name() + '\',' + str(
                restoreAngle) + ', topCommand=0)'
        self.vf.undo.addEntry((undoCmd), (self.name))

    def Accept_cb(self):
        apply(self.setupUndoAfter, (self.atomList, self.oldValue), {})
        self.origValue = self.oldValue

    def Done_cb(self):
        self.vf.setICOM(self.save,
                        modifier="Shift_L",
                        mode='pick',
                        topCommand=0)
        self.stopICOM()

    def startICOM(self):
        self.vf.setIcomLevel(Atom)
        if not hasattr(self, 'form'):
            self.buildForm()
        else:
            self.form.deiconify()

    def stopICOM(self):
        if hasattr(self, 'form'):
            self.form.withdraw()
        self.atomList = []
        self.atomCenters = []
        self.labelStrs = []
        self.labelCenters = []
        self.lineVertices = []
        self.spheres.Set(vertices=[], tagModified=False)
        self.lines.Set(vertices=[], faces=[], tagModified=False)
        self.labels.Set(vertices=[], tagModified=False)
        self.vf.GUI.VIEWER.Redraw()
        #when cmd stops being icom, remove callback
        ##         ehm = self.vf.GUI.ehm
        ##         for event in ['<B2-Motion>', '<B3-Motion>']:
        ##             if ehm.eventHandlers.has_key(event) and self.update_cb in \
        ##                     ehm.eventHandlers[event]:
        ##                 ehm.RemoveCallback(event, self.update_cb)
        for event in ['<B2-Motion>', '<B3-Motion>']:
            self.vf.GUI.removeCameraCallback(event, self.update_cb)

    def repeat_transTors(self, event=None):
        deltaAngle = self.extslider.get()
        if self.torsionType.get() != '1':
            self.transformCoords(deltaAngle)
        #this is here in order to create a log message
        nc = self.vf.setRelativeTorsion(self.atomList[1],
                                        self.atomList[2],
                                        deltaAngle,
                                        self.mov_atoms,
                                        returnVal=1)
        event = EditAtomsEvent('coords', self.mov_atoms)
        self.vf.dispatchEvent(event)

    def new_Tors(self, event=0):
        self.atomList = []
        self.update()

    #when called, most recent 4 atoms are in self.atomList
    def updateHistory(self):
        """1: call TorsionHistory.getTorsion:
        make a new TorsionAngle or add current angle to angleList
        2: put TA.name_string into ListBox
        3: best if insert a tuple (string to be displayed, item itself)
        4: adjust size with self.historyList.configure(height=self.[].size)
        5: limit overall size to 4"""
        #print 'in updateHistory'
        molecule = self.atomList[-1].top
        if self.TAHdata is None:
            self.TAHdata = TorsionHistory(molecule)
        a1, a2, a3, a4 = self.atomList
        newone = self.TAHdata.getTorsion(a1, a2, a3, a4)
        #first check to see if it is in there already???
        #need to get info back from getTorsion....(???)
        if hasattr(self, 'historyList'):
            if newone.new:
                self.historyList.insert('end', newone.name_string)
                if int(self.historyList.cget('height')) < 4:
                    self.historyList.configure(height=self.historyList.size())
            if self.historyList.curselection():
                self.historyList.select_clear(self.historyList.curselection())
            newindex = self.TAHdata.getIndex(newone)
            self.historyList.select_set(newindex)
            self.historyList.see(newindex)
        #set entry to a string ==current TA's angleList
        newstring = ""
        for item in newone.angleList:
            newstring = newstring + " " + "%5.3f" % item
        self.newAngList.set(newstring)

    def HLCommand(self, event=None):
        """double-clicking selection in listbox causes curselection to be picked...
        1:self.atomList set to atoms of curselection
        2:self.mov_atoms set to atoms of curselection
        3:self.selAtom[1-4].Set(vertices=atoms.coords)
        4:reset entry +slider and init_bondAngle etc
        5.add current angle to selection's.angleList"""
        #get TA:
        if self.historyList.get(0) == '': return
        items = self.historyList.curselection()
        if type(items) == types.TupleType:
            items = items[0]
        try:
            items = map(int, items)
        except ValueError:
            pass
        thisTA = self.TAHdata.torslist[items[0]]
        #get currentAngle
        current = thisTA.getCurrentAngle()
        if not thisTA.inList(current):
            thisTA.angleList.append(current)
        newAts = AtomSet([thisTA.atom1,thisTA.atom2, thisTA.atom3,\
                    thisTA.atom4])
        #reset self.molecule
        self.atomList = []
        self.molecule = newAts[0].top
        self.doit(newAts, current)
        #self.setTorsionAngle(thisTA.atom1, thisTA.atom2, thisTA.atom3, thisTA.atom4, current, 'A')
        #self.drawTransformedAngle()
        #self.updatespheres(items[0])
        #self.update()
        self.extslider.set(current, 0)
        newstring = ""
        for item in thisTA.angleList:
            newstring = newstring + " " + "%5.3f" % item
        self.newAngList.set(newstring)

    def getAngList(self, event=None):
        items = self.historyList.curselection()
        try:
            items = map(int, items)
        except ValueError:
            pass
        thisTA = self.TAHdata.torslist[items[0]]
        thisTA.angleList = map(float, split(self.newAngList.get()))
        last = thisTA.angleList[-1]
        newAts = AtomSet([thisTA.atom1,thisTA.atom2, thisTA.atom3,\
                    thisTA.atom4])
        #reset self.molecule
        self.atomList = []
        self.molecule = newAts[0].top
        self.doit(newAts, last)
        #self.doit(thisTA.atom1, thisTA.atom2, thisTA.atom3, thisTA.atom4,last,'A')
        #self.setTorsionAngle(thisTA.atom1, thisTA.atom2, thisTA.atom3, thisTA.atom4,last,'A')
        #self.drawTransformedAngle()
        #self.updatespheres(items[0])
        self.extslider.set(last, 0)

    def stepBack(self, event=None):
        items = self.historyList.curselection()
        if len(items) == 0: return
        try:
            items = map(int, items)
        except ValueError:
            pass
        thisTA = self.TAHdata.torslist[items[0]]
        ####last angle is thisTA.angleList[-1]
        if len(thisTA.angleList) > 1:
            last = thisTA.angleList[-1]
            lastIndex = thisTA.angleList.index(last)
            thisTA.angleList = thisTA.angleList[:lastIndex]
            last = thisTA.angleList[-1]
        else:
            last = thisTA.angleList[0]
        newAts = AtomSet([thisTA.atom1,thisTA.atom2, thisTA.atom3,\
                    thisTA.atom4])
        #reset self.molecule
        self.atomList = []
        self.molecule = newAts[0].top
        self.doit(newAts, last)
        #self.doit(thisTA.atom1, thisTA.atom2, thisTA.atom3, thisTA.atom4,last,'A')
        #self.setTorsionAngle(thisTA.atom1, thisTA.atom2, thisTA.atom3, thisTA.atom4,last,'A')
        #self.drawTransformedAngle()
        #self.updatespheres(items[0])
        newstring = ""
        for item in thisTA.angleList:
            newstring = newstring + " " + "%5.3f" % item
        self.newAngList.set(newstring)
        self.extslider.set(last, 0)
        #IS THIS ENOUGH in order to create correct log?
        self.mouseUp()

    def startOver(self, event=None):
        items = self.historyList.curselection()
        if len(items) == 0: return
        try:
            items = map(int, items)
        except ValueError:
            pass
        thisTA = self.TAHdata.torslist[items[0]]
        self.resetAngle(thisTA)

    def resetAngle(self, thisTA, event=None):
        #first angle is thisTA.angleList[0]
        ang = thisTA.angleList[0]
        newAts = AtomSet([thisTA.atom1,thisTA.atom2, thisTA.atom3,\
                    thisTA.atom4])
        #reset self.molecule
        self.atomList = []
        self.molecule = newAts[0].top
        self.doit(newAts, ang)
        #self.doit(thisTA.atom1, thisTA.atom2, thisTA.atom3, thisTA.atom4,ang,'A')
        #self.setTorsionAngle(thisTA.atom1, thisTA.atom2, thisTA.atom3, thisTA.atom4,ang,'A')
        if len(thisTA.angleList) > 1:
            thisTA.angleList = thisTA.angleList[:1]
        #self.drawTransformedAngle()
        self.extslider.set(ang, 0)
        self.mouseUp()
        self.newAngList.set("%5.3f" % ang)

    def resetAll(self, event=None):
        if self.TAHdata == None: return
        for item in self.TAHdata.torslist:
            self.resetAngle(item)
        self.spheres.Set(vertices=[], tagModified=False)
        self.vf.GUI.VIEWER.Redraw()

    def buildForm(self):
        if hasattr(self, 'ifd'):
            return
        self.torsionType = Tkinter.StringVar()
        self.torsionType.set('1')
        self.ifd = ifd = InputFormDescr(title='Set Torsion Angle')
        ifd.append({
            'name': 'extLabel',
            'widgetType': Tkinter.Label,
            'wcfg': {
                'text': 'Set Angle:\n(180=trans)'
            },
            'gridcfg': {
                'sticky': Tkinter.W + Tkinter.E,
                'columnspan': 2
            }
        })
        ifd.append({
            'name': 'extslider',
            'widgetType': ExtendedSliderWidget,
            'wcfg': {
                'label': 'torsion',
                'minval': -360.,
                'maxval': 360.,
                'width': 150,
                'immediate': 1,
                'command': self.slideCallback,
                'sliderType': 'float',
                'entrypackcfg': {
                    'side': 'bottom'
                }
            },
            'gridcfg': {
                'sticky': 'we',
                'columnspan': 2
            }
        })
        ifd.append({
            'name': 'typeLabel',
            'widgetType': Tkinter.Label,
            'wcfg': {
                'text': 'Torsion Type'
            },
            'gridcfg': {
                'sticky': 'we',
                'columnspan': 2
            }
        })
        ifd.append({
            'name': 'rdbut1',
            'widgetType': Tkinter.Radiobutton,
            'wcfg': {
                'text': 'Absolute',
                'variable': self.torsionType,
                'value': 1,
                'command': self.rdSet
            },
            'gridcfg': {
                'sticky': 'we'
            }
        })
        ifd.append({
            'name': 'rdbut2',
            'widgetType': Tkinter.Radiobutton,
            'wcfg': {
                'text': 'Relative ',
                'variable': self.torsionType,
                'value': 0,
                'command': self.rdSet
            },
            'gridcfg': {
                'sticky': 'we',
                'row': -1,
                'column': 1
            }
        })
        ifd.append({
            'name': 'historyList',
            'widgetType': ListChooser,
            'wcfg': {
                'title': 'TorsionAngle\nTranformation History',
                'mode': 'single',
                'command': self.HLCommand,
                'lbwcfg': {
                    'height': 5,
                    'selectforeground': 'yellow',
                    'exportselection': 0,
                    'width': 30
                },
            },
            'gridcfg': {
                'sticky': 'we',
                'columnspan': 2
            }
        })
        ifd.append({
            'name': 'hbut1',
            'widgetType': Tkinter.Button,
            'wcfg': {
                'text': 'Step Back ',
                'command': self.stepBack
            },
            'gridcfg': {
                'sticky': 'we',
                'columnspan': 2
            }
        })
        ifd.append({
            'name': 'hbut2',
            'widgetType': Tkinter.Button,
            'wcfg': {
                'text': 'Start Over ',
                'command': self.startOver
            },
            'gridcfg': {
                'sticky': 'we',
                'columnspan': 2
            }
        })
        ifd.append({
            'name': 'hbut3',
            'widgetType': Tkinter.Button,
            'wcfg': {
                'text': 'Reset All ',
                'command': self.resetAll
            },
            'gridcfg': {
                'sticky': 'we',
                'columnspan': 2
            }
        })
        ifd.append({
            'name': 'angListEnt',
            'widgetType': Tkinter.Entry,
            'wcfg': {
                'width': 5,
                'command': self.getAngList,
                'textvariable': self.newAngList
            },
            'gridcfg': {
                'sticky': 'we',
                'columnspan': 2
            }
        })
        ifd.append({
            'name': 'hbut4',
            'widgetType': Tkinter.Button,
            'wcfg': {
                'text': 'Move',
                'command': self.repeat_transTors
            },
            'gridcfg': {
                'sticky': 'we',
                'columnspan': 2
            }
        })
        ifd.append({
            'name': 'hbut5',
            'widgetType': Tkinter.Button,
            'wcfg': {
                'text': 'New Torsion',
                'command': self.new_Tors
            },
            'gridcfg': {
                'sticky': 'we',
                'columnspan': 2
            }
        })
        #ifd.append({'name':'accept',
        #'widgetType': Tkinter.Button,
        #'wcfg':{'text' : 'Accept',
        #'command': self.Accept_cb},
        #'gridcfg':{'sticky':'we'}})
        ifd.append({
            'name': 'done',
            'widgetType': Tkinter.Button,
            'wcfg': {
                'text': 'Done',
                'command': self.Done_cb
            },
            'gridcfg': {
                'sticky': 'we',
                'columnspan': 2
            }
        })
        #'gridcfg':{'sticky':'we','column':1, 'row':-1}})
        self.form = self.vf.getUserInput(ifd, modal=0, blocking=0)
        self.form.root.protocol('WM_DELETE_WINDOW', self.Done_cb)
        self.extslider = self.ifd.entryByName['extslider']['widget']
        self.extslider.draw.bind('<ButtonRelease-1>', self.mouseUp, add='+')
        self.extslider.entry.bind('<Return>', self.mouseUp, add='+')
        self.historyList = self.ifd.entryByName['historyList']['widget'].lb
        #self.historyList.bind("<Double-Button-1>",self.HLCommand)
        self.hbut1 = self.ifd.entryByName['hbut1']['widget']
        self.hbut2 = self.ifd.entryByName['hbut2']['widget']
        self.hbut3 = self.ifd.entryByName['hbut3']['widget']
        self.angListEnt = self.ifd.entryByName['angListEnt']['widget']

    def mouseUp(self, event=None):
        #print "in mouseUp"
        #fix this: atomList length dependent
        if len(self.atomList) == 4:
            at0, at1, at2, at3 = self.atomList
            angle = self.extslider.get()
            if self.torsionType.get() == '1':
                self.vf.setTorsion(at0, at1, at2, at3, angle)
            else:
                self.vf.setRelativeTorsion(at1, at2, angle)
コード例 #2
0
class SuperimposeAtomsGUICommand(SuperimposeCommand, MVAtomICOM):
    """
    
    The SuperimposeAtomsGUICommand provides a GUI interface to the
    SuperimposeAtomsCommand. This commands allows the user to create two sets
    of atoms one reference and mobile of the same length by picking,
    by string or using the alignment editor.
    These two sets are then fed to the SuperimposeAtoms command.
    
    - For now Only two 2 sets of Atoms belonging to a ref molecule and
      a mobile molecule can be superimposed simultaneously.

    - The command provides two way of defining those two sets of atoms:
      * By picking nodes 
      * By string:
      * Using the alignment editor
    """

    # The superimposeAtomsGC provides an GU interface to allow the user to create two sets of atoms
    # which will be used to do a pairwise superimposition.
    def __init__(self, func=None):
        MVCommand.__init__(self, func)
        MVAtomICOM.__init__(self)
        self.refAtomList = []
        self.inAtomList = []
        #self.superImposedPairs = {}
        self.newPairs = {}
        self.pair = []
        self.mobMol = None
        self.refMol = None
        self.refNodes = {}
        self.mobNodes = {}
        self.filters = {
            'CA Atoms':
            lambda x: x.name == 'CA',
            'Backbone Atoms':
            lambda x: x.name in
            ['CA', 'C', 'N', 'O', 'CA@A', 'C@A', 'N@A', 'O@A'],
            'Heavy Atoms':
            lambda x: not x.element == 'H',
            'All Atoms':
            None
        }
        self.defaultFilter = 'Backbone Atoms'

##     def doit(self, refAtoms, mobAtoms, updateGeom=True, showRMSD=True):
##         """same as in SuperimposeCommand """
##         SuperimposeCommand.doit(self, refAtoms, mobAtoms, updateGeom=True, showRMSD=True)

    def onAddCmdToViewer(self):
        # Check first is any of the command that superimpose depends on are
        # already loaded.
        if not self.vf.commands.has_key('setICOM'):
            self.vf.loadCommand('interactiveCommands',
                                'setICOM',
                                'Pmv',
                                topCommand=0)
        if not self.vf.commands.has_key('superimposeAtoms'):
            self.vf.loadCommand('superImposeCommands',
                                'superimposeAtoms',
                                'Pmv',
                                topCommand=0)

        if not self.vf.commands.has_key('startContinuousPicking'):
            self.vf.loadCommand('dejaVuCommands',
                                'startContinuousPicking',
                                'ViewerFramework',
                                topCommand=0)

        if not self.vf.commands.has_key('stopContinuousPicking'):
            self.vf.loadCommand('dejaVuCommands',
                                'stopContinuousPicking',
                                'ViewerFramework',
                                topCommand=0)
        if not self.vf.commands.has_key('labelByExpression'):
            self.vf.loadCommand('labelCommands',
                                'labelByExpression',
                                'Pmv',
                                topCommand=0)

        self.sphere1 = Spheres(name='elt1',
                               radii=0.5,
                               materials=((0., 1., 0.), ),
                               protected=True)
        self.sphere2 = Spheres(name='elt2',
                               radii=0.5,
                               materials=((1., 1., 0.), ),
                               protected=True)

    def onRemoveObjectFromViewer(self, obj):
        if hasattr(self.vf, 'alignment'):
            self.vf.alnEditor.deleteSequence(obj.name)
            self.vf.alnEditor.redraw()
        if obj.name == self.refMol:
            self.refMol = None
        if obj.name == self.mobMol:
            self.mobMol = None

    ##########################################################################
    ####   BY PICKING...
    ##########################################################################
    def initICOM(self, modifier):
        # set the callback of continuousPicking to label the picked node
        # 1- get a handle on the cbManager
        cbManager = self.vf.startContinuousPicking.cbManager
        # 2- Save the existing callbacks
        #self.oldCallBacks = cbManager.callbacks
        # 3- Set to the new callback
        cbManager.SetCallback(CallBackFunction(self.labelByName))

        self.vf.startContinuousPicking()
        self.supcb = 0

    def labelByName(self, pick):
        # Continuous labeling.
        if pick is None: return
        atom = self.vf.findPickedAtoms(pick)
        if atom:
            level = self.vf.ICmdCaller.level.value
            self.vf.ICmdCaller.level.AddCallback(self.unlabelLevel)
            if level == Molecule: level = Protein
            self.node = atom.findType(level)
            funcItems = map(lambda x: x.full_name(), self.node)
            self.vf.labelByExpression(
                self.node,
                font='arial1.glf',
                location='First',
                textcolor='red',
                only=0,
                lambdaFunc=1,
                negate=0,
                function='lambda x: str(x.full_name())\n\n',
                topCommand=0)

    def unlabelLevel(self, newLevel, oldLevel):
        if not hasattr(self, 'node'): return

        if oldLevel == Molecule: oldLevel = Protein
        # need to be at the former level for all the former picked stuff
        # so take it all.
        node = self.vf.getSelection()
        nodes = node.findType(oldLevel)
        # Careful in labelByProperty fix a bug if no label should not break!
        self.vf.labelByExpression(nodes, negate=1, log=0)

    def stopICOM(self):
        # Destroy the inputForm
        #self.cmdForms['superimpose'].root.destroy()
        # Set the form to None.
        #del self.cmdForms['superimpose']

        # Set back the continuousPicking to unsolicitedPick
        cbManager = self.vf.startContinuousPicking.cbManager
        if not len(self.oldCallBacks) == 0:
            cbManager.SetCallback(self.oldCallBacks[0])
            if len(self.oldCallBacks) > 1:
                for cb in self.oldCallBacks[1:]:
                    cbManager.AddCallBack(cb)

        # Remove the unlabel callback bound to the self.vf.ICmdCaller.level
        if self.unlabelLevel in self.vf.ICmdCaller.level.callbacks:
            self.vf.ICmdCaller.level.RemoveCallback(self.unlabelLevel)

        # Unlabel whatever is labeled
        level = self.vf.ICmdCaller.level.value

        nodes = self.vf.getSelection().findType(level)
        if not nodes is None or len(nodes) != 0:
            self.vf.labelByExpression(nodes, negate=1, log=0)

        # Stop the continuous picking.
        self.vf.stopContinuousPicking()

        self.sphere1.Set(vertices=[])
        self.sphere2.Set(vertices=[])
##         self.visualFeedBack(vertices =[])

##########################################################################
####
##########################################################################

    def createNodesSets(self, refnodes=None, mobnodes=None):
        # Set the reference molecule and the mobile molecule....
        # 1- set the reference molecule and the mobile
        from MolKit.protein import ProteinSet
        if refnodes:
            refMols = refnodes.top.uniq()
            if refMols == self.vf.Mols:
                self.warningMsg(
                    "Reference and mobile molecules should be selected.")
                return
            if len(refMols) > 1:
                self.warningMsg(
                    "Can have one and only one reference molecule.")
                return
            self.refMol = refMols[0]

        if mobnodes:
            mobMols = mobnodes.top.uniq()
            if refMols == self.vf.Mols:
                self.warningMsg(
                    "Reference and mobile molecules should be selected.")
                return
            if len(mobMols) > 1:
                self.warningMsg("Can have one and only one mobile molecule.")
                return
            if mobMols[0] == self.refMol:
                self.warningMsg(
                    "The mobile molecule must be different from the ref molecule"
                )
                return
            self.mobMol = mobMols[0]

        # 2- Create the entries for the refNodes listChooser
        ebn = self.cmdForms['addPairs'].descr.entryByName
        if refnodes:
            reflc = ebn['refnodes']['widget']
            for rn in refnodes:
                if not rn.top == self.refMol: continue
                self.refNodes[rn.full_name()] = rn
                reflc.add((rn.full_name(), None))

        # Create the entries for  the mobNodes listChooser
        if mobnodes:
            moblc = ebn['mobnodes']['widget']
            for mn in mobnodes:
                if not mn.top == self.mobMol: continue
                self.mobNodes[mn.full_name()] = mn
                moblc.add((mn.full_name(), None))

    def createPairs(self, refnames, mobnames, slice, choice):
        # This is where the atom pairs are created
        # Get the ref atom set
        refAtms = AtomSet([])
        mobAtms = AtomSet([])
        for name in refnames:
            refnod = self.refNodes[name]
            atms = refnod.findType(Atom)
            refAtms = refAtms + atms

        for name in mobnames:
            mobnod = self.mobNodes[name]
            atms = mobnod.findType(Atom)
            mobAtms = mobAtms + atms
        # Now apply the filters to the sets
        if choice:
            refFiltAtms = refAtms.get(self.filters[choice])
            mobFiltAtms = mobAtms.get(self.filters[choice])
        if not len(refFiltAtms) == len(mobFiltAtms):
            #print 'slicing', slice
            self.warningMsg(
                "the two sets of atoms needs to be of the same length")
            return
        ebn = self.cmdForms['pairs'].descr.entryByName
        lc = ebn['newpairs']['widget']
        for refatm, mobatm in map(None, refFiltAtms, mobFiltAtms):
            #self.pairs.append((refatm, mobatm))
            pairName = refatm.full_name() + '---' + mobatm.full_name()
            self.newPairs[pairName] = (refatm, mobatm)
            lc.add((pairName, None))

    ##########################################################################
    ####   GUI CALLBACKS
    ##########################################################################
    def pick_cb(self):
        ebn = self.cmdForms['addPairs'].descr.entryByName
        cbVar = int(ebn['pick']['variable'].get())
        if cbVar:
            self.vf.setICOM(self, modifier="Shift_L", topCommand=0)
        else:
            self.stopICOM()

    def string_cb(self):
        ebn = self.cmdForms['addPairs'].descr.entryByName
        cbVar = ebn['string']['variable']
        #print cbVar.get()
        if cbVar.get():
            # if pushed show the form
            val = self.showForm('editString', modal=1, blocking=0, force=1)
            cbVar.set(0)
        if val:
            if not val['srefNodes'] and not val['smobNodes']: return
            refnodes = val['srefNodes']
            if refnodes:
                refnodes.sort()
            mobnodes = val['smobNodes']
            if mobnodes: mobnodes.sort()
            self.createNodesSets(refnodes, mobnodes)

    def setDefault(self, text):
        pass
##         self.defaultFilter = text
##         if hasattr(self, 'pair') and len(self.pair) == 2:
##             filter = self.filters[text]
##             set1 = self.pair[0]
##             set2 = self.pair[1]

##             if filter:
##                 set1 = set1.get(filter)
##                 set2 = set2.get(filter)
##             if (set1 and set2) and (len(set1) == len(set2)):
##                 self.updateChooser(set1, set2)):

    def delete_cb(self):
        ebn = self.cmdForms['pairs'].descr.entryByName
        lc = ebn['newpairs']['widget']
        lc.clear()
        self.newPairs = {}
        return

    def dismiss_cb(self):
        if self.cmdForms.has_key('pairs'): self.cmdForms['pairs'].withdraw()
        if self.cmdForms.has_key('addPairs'):
            self.cmdForms['addPairs'].withdraw()
        if self.cmdForms.has_key('editString'):
            self.cmdForms['addPairs'].withdraw()
        # Dismiss all the forms ???


##         for v in self.cmdForms.values():
##             v.withdraw()

    def continuous_cb(self):
        # Sets the continuous flag to the right value ????
        pass

    def reset_cb(self):
        # Reset the superposition put back the mob molecule to the right place..
        pass

    def superimpose_cb(self):
        refAtoms = AtomSet()
        mobAtoms = AtomSet()
        for pair in self.newPairs.values():
            refAtoms.append(pair[0])
            mobAtoms.append(pair[1])

        apply(self.doitWrapper, (refAtoms, mobAtoms), {})

    def add_cb(self):
        val = self.showForm('addPairs',
                            modal=1,
                            blocking=0,
                            force=1,
                            okCfg={'text': 'Create Pairs'})
        # need to get all the nodes... from each listchooser
        if not val: return
        # Need this for the order of the nodes in the pairs...
        ebn = self.cmdForms['addPairs'].descr.entryByName
        reflc = ebn['refnodes']['widget']
        refnames = map(lambda x: x[0], reflc.entries)
        moblc = ebn['mobnodes']['widget']
        mobnames = map(lambda x: x[0], moblc.entries)
        self.createPairs(refnames, mobnames, val['slice'][0], val['choice'][0])

    def refremove_cb(self):
        ebn = self.cmdForms['addPairs'].descr.entryByName
        lc = ebn['refnodes']['widget']
        sel = lc.get()
        if sel:
            lc.remove(sel[0])
            if sel[0] in self.refNodes:
                del self.refNodes[sel[0]]

    def mobremove_cb(self):
        ebn = self.cmdForms['addPairs'].descr.entryByName
        lc = ebn['mobnodes']['widget']
        sel = lc.get()
        if sel:
            lc.remove(sel[0])
            if sel[0] in self.refNodes:
                del self.mobNodes[sel[0]]

    def refmoveup_cb(self):
        ebn = self.cmdForms['addPairs'].descr.entryByName
        lc = ebn['refnodes']['widget']
        sel = lc.get()
        if not sel: return
        sel = sel[0]
        selIndex = lc.entries.index((sel, None))
        if selIndex == 0: return
        lc.remove(sel)
        lc.insert(selIndex - 1, sel)
        lc.select(sel)

    def mobmoveup_cb(self):
        ebn = self.cmdForms['addPairs'].descr.entryByName
        lc = ebn['mobnodes']['widget']
        sel = lc.get()
        if not sel: return
        sel = sel[0]
        selIndex = lc.entries.index((sel, None))
        if selIndex == 0: return
        lc.remove(sel)
        lc.insert(selIndex - 1, sel)
        lc.select(sel)

    def refmovedown_cb(self):
        ebn = self.cmdForms['addPairs'].descr.entryByName
        lc = ebn['refnodes']['widget']
        sel = lc.get()
        if not sel: return
        sel = sel[0]
        selIndex = lc.entries.index((sel, None))
        if selIndex == len(lc.entries) - 1: return
        lc.remove(sel)
        lc.insert(selIndex + 1, sel)
        lc.select(sel)

    def mobmovedown_cb(self):
        ebn = self.cmdForms['addPairs'].descr.entryByName
        lc = ebn['mobnodes']['widget']
        sel = lc.get()
        if not sel: return
        sel = sel[0]
        selIndex = lc.entries.index((sel, None))
        if selIndex == len(lc.entries) - 1: return
        lc.remove(sel)
        lc.insert(selIndex + 1, sel)
        lc.select(sel)

    def guiCallback(self):
        #form = self.showForm('pairs', modal=0, blocking=0)
        val = self.showForm('pairs', modal=0, blocking=0)

    def buildFormDescr(self, formName):
        if formName == 'addPairs':
            # CREATE PAIRS GROUP
            idf = InputFormDescr(title="Superimpose")
            idf.append({
                'name': "mode",
                'widgetType': Pmw.Group,
                'container': {
                    'mode': 'w.interior()'
                },
                'wcfg': {
                    'tag_text': "Create Reference Nodes and Mobile Nodes Lists"
                },
                'gridcfg': {
                    'sticky': 'wnse'
                }
            })
            idf.append({
                'widgetType': Tkinter.Label,
                'parent': 'mode',
                'wcfg': {
                    'text': 'By String'
                },
                'gridcfg': {
                    'sticky': 'we'
                }
            })
            idf.append({
                'widgetType': Tkinter.Checkbutton,
                'name': 'string',
                'parent': 'mode',
                #'tooltip':'Use the string selector to create refnode-mobnodes pairs',
                'wcfg': {
                    'text': 'on/off',
                    'command': self.string_cb
                },
                'gridcfg': {
                    'sticky': 'we',
                    'row': -1
                }
            })

            idf.append({
                'widgetType': Tkinter.Label,
                'parent': 'mode',
                'wcfg': {
                    'text': 'By Picking'
                },
                'gridcfg': {
                    'sticky': 'we',
                    'row': -1
                }
            })

            idf.append({
                'widgetType': Tkinter.Checkbutton,
                'name': 'pick',
                'tooltip':
                'Use the picking event to create refnode-mobnodes pairs',
                'parent': 'mode',
                'wcfg': {
                    'text': 'on/off',
                    'command': self.pick_cb
                },
                'gridcfg': {
                    'sticky': 'we',
                    'row': -1
                }
            })

            ###############################################################
            ## EDIT REF/MOB NODES
            ###############################################################
            idf.append({
                'name': "editnodes",
                'widgetType': Pmw.Group,
                'container': {
                    'editnodes': 'w.interior()'
                },
                'wcfg': {
                    'tag_text': "Edit Reference Nodes and Mobile Nodes Lists:"
                },
                'gridcfg': {
                    'sticky': 'wnse'
                }
            })

            idf.append({
                'name': 'refremove',
                'parent': 'editnodes',
                'widgetType': Tkinter.Button,
                'tooltip': """ Remove the selected entry from the
commands to be applied to the object when loaded in the application""",
                'wcfg': {
                    'text': 'REMOVE',
                    'width': 10,
                    'command': self.refremove_cb
                },
                'gridcfg': {
                    'sticky': 'we',
                    'row': 0,
                    'column': 0
                }
            })

            idf.append({
                'name': 'refoneup',
                'parent': 'editnodes',
                'widgetType': Tkinter.Button,
                'tooltip': """Move the selected entry up one entry""",
                'wcfg': {
                    'text': 'Move up',
                    'width': 10,
                    'command': self.refmoveup_cb
                },
                'gridcfg': {
                    'sticky': 'we',
                    'row': 1,
                    'column': 0
                }
            })

            idf.append({
                'name': 'refonedown',
                'parent': 'editnodes',
                'widgetType': Tkinter.Button,
                'tooltip': """Move the selected entry down one entry""",
                'wcfg': {
                    'text': 'Move down',
                    'width': 10,
                    'command': self.refmovedown_cb
                },
                'gridcfg': {
                    'sticky': 'we',
                    'row': 2,
                    'column': 0
                }
            })

            # RefNodes listchooser
            idf.append({
                'widgetType': ListChooser,
                'name': 'refnodes',
                'parent': 'editnodes',
                'tooltip': """list of the reference nodes""",
                'wcfg': {
                    'entries': [],
                    'mode': 'single',
                    'lbwcfg': {
                        'exportselection': 0
                    },
                    'title': 'Reference Nodes'
                },
                'gridcfg': {
                    'sticky': 'we',
                    'row': 0,
                    'column': 1,
                    'rowspan': 3
                }
            })

            # MobNodes listchooser
            idf.append({
                'widgetType': ListChooser,
                'name': 'mobnodes',
                'parent': 'editnodes',
                'tooltip': """list of the mobile nodes""",
                'wcfg': {
                    'entries': [],
                    'mode': 'single',
                    'lbwcfg': {
                        'exportselection': 0
                    },
                    'title': 'Mobile Nodes'
                },
                'gridcfg': {
                    'sticky': 'we',
                    'row': 0,
                    'column': 2,
                    'rowspan': 3
                }
            })

            idf.append({
                'name': 'mobremove',
                'parent': 'editnodes',
                'widgetType': Tkinter.Button,
                'tooltip': """ Remove the selected mobile node""",
                'wcfg': {
                    'text': 'REMOVE',
                    'width': 10,
                    'command': self.mobremove_cb
                },
                'gridcfg': {
                    'sticky': 'we',
                    'row': 0,
                    'column': 3
                }
            })

            idf.append({
                'name': 'moboneup',
                'parent': 'editnodes',
                'widgetType': Tkinter.Button,
                'tooltip': """Move the selected entry up one entry""",
                'wcfg': {
                    'text': 'Move up',
                    'width': 10,
                    'command': self.mobmoveup_cb
                },
                'gridcfg': {
                    'sticky': 'we',
                    'row': 1,
                    'column': 3
                }
            })

            idf.append({
                'name': 'mobonedown',
                'parent': 'editnodes',
                'widgetType': Tkinter.Button,
                'tooltip': """Move the selected entry down one entry""",
                'wcfg': {
                    'text': 'Move down',
                    'width': 10,
                    'command': self.mobmovedown_cb
                },
                'gridcfg': {
                    'sticky': 'we',
                    'row': 2,
                    'column': 3
                }
            })

            ###############################################################
            ## FILTERS
            ###############################################################

            idf.append({
                'name': "filter",
                'widgetType': Pmw.Group,
                'container': {
                    'filters': 'w.interior()'
                },
                'wcfg': {
                    'tag_text': "Apply Filters To The Ref/Mob nodes lists:"
                },
                'gridcfg': {
                    'sticky': 'wnse'
                }
            })

            idf.append({
                'widgetType': Pmw.ComboBox,
                'name': 'choice',
                'parent': 'filters',
                'tooltip': """This filter allows the user to choose
which atom to consider from the ref node or mob nodes sets to create the atom pairs""",
                'defaultValue': self.defaultFilter,
                'wcfg': {
                    'scrolledlist_items': self.filters.keys(),
                    'selectioncommand': self.setDefault
                },
                'gridcfg': {
                    'sticky': 'w'
                }
            })

            # If sets not of the same length:
            idf.append({
                'widgetType': Pmw.ComboBox,
                'name': 'slice',
                'parent': 'filters',
                'defaultValue': 'Beginning',
                'tooltip': """When the two sets of atoms are not of
the same length the user can chose what subset of the longest set to take,
beginning, the end or half and half""",
                'wcfg': {
                    'scrolledlist_items': ['Beginning', 'End', 'Half/Half'],
                },
                'gridcfg': {
                    'sticky': 'w',
                    'row': -1
                }
            })

            return idf

        elif formName == 'pairs':
            idf = InputFormDescr(title="Pairwise Superimposition")

            # EDIT PAIRS GROUP
            idf.append({
                'name': "edit",
                'widgetType': Pmw.Group,
                'container': {
                    'edit': 'w.interior()'
                },
                'wcfg': {
                    'tag_text': "Edit Atom Pairs"
                },
                'gridcfg': {
                    'sticky': 'wnse'
                }
            })

            entries = map(lambda x: (x, None), self.newPairs.keys())
            idf.append({
                'widgetType': ListChooser,
                'name': 'newpairs',
                'parent': 'edit',
                'wcfg': {
                    'mode': 'extended',
                    'entries': entries,
                    'lbwcfg': {
                        'exportselection': 1
                    },
                    'title': 'Reference Atoms    --    Mobile Atoms'
                },
                'gridcfg': {
                    'sticky': 'wens',
                    'columnspan': 2
                }
            })

            idf.append({
                'widgetType': Tkinter.Button,
                'name': 'delete',
                'parent': 'edit',
                'wcfg': {
                    'width': 15,
                    'text': 'Add Pairs',
                    'command': self.add_cb
                },
                'gridcfg': {
                    'sticky': 'we'
                }
            })

            idf.append({
                'widgetType': Tkinter.Button,
                'name': 'delete',
                'parent': 'edit',
                'wcfg': {
                    'width': 15,
                    'text': 'Delete Pairs',
                    'command': self.delete_cb
                },
                'gridcfg': {
                    'sticky': 'we',
                    'row': -1
                }
            })

            idf.append({
                'name': "superimpose",
                'widgetType': Pmw.Group,
                'container': {
                    'superimpose': 'w.interior()'
                },
                'wcfg': {
                    'tag_text': "Superimposation parameters"
                },
                'gridcfg': {
                    'sticky': 'wnse'
                }
            })
            # Continuous Superimposition
            idf.append({
                'widgetType': Tkinter.Checkbutton,
                'name': 'continuous',
                'parent': 'superimpose',
                'wcfg': {
                    'variable': Tkinter.IntVar(),
                    'text': 'Continuous',
                    'command': self.continuous_cb,
                    'padx': 10,
                    'pady': 10
                },
                'gridcfg': {
                    'sticky': 'w'
                }
            })

            # Reset & SuperImpose button.
            idf.append({
                'widgetType': Tkinter.Button,
                'name': 'final',
                'parent': 'superimpose',
                'wcfg': {
                    'width': 15,
                    'text': 'Superimpose',
                    'command': self.superimpose_cb
                },
                'gridcfg': {
                    'sticky': 'we',
                    'row': -1
                }
            })

            idf.append({
                'widgetType': Tkinter.Button,
                'parent': 'superimpose',
                'name': 'reset',
                'wcfg': {
                    'text': 'Reset',
                    'command': self.reset_cb
                },
                'gridcfg': {
                    'sticky': 'we',
                    'row': -1
                }
            })

            idf.append({
                'widgetType': Tkinter.Button,
                'name': 'dismiss',
                'wcfg': {
                    'text': 'DISMISS',
                    'command': self.dismiss_cb
                },
                'gridcfg': {
                    'sticky': 'we',
                    'columnspan': 2
                }
            })

            return idf

        elif formName == 'editString':

            idf = InputFormDescr(title='Get Nodes From String')

            idf.append({
                'name': "refgroup",
                'widgetType': Pmw.Group,
                'container': {
                    'refgroup': 'w.interior()'
                },
                'wcfg': {
                    'tag_text': "Reference Nodes:"
                },
                'gridcfg': {
                    'sticky': 'wnse'
                }
            })

            idf.append({
                'name': "mobgroup",
                'widgetType': Pmw.Group,
                'container': {
                    'mobgroup': 'w.interior()'
                },
                'wcfg': {
                    'tag_text': "Mobile Nodes:"
                },
                'gridcfg': {
                    'sticky': 'wnse',
                    'row': -1
                }
            })

            idf.append({
                'widgetType': StringSelectorGUI,
                'parent': 'refgroup',
                'name': 'srefNodes',
                #'defaultValue':self.vf.Mols[0].name+", , , ",
                'tooltip':
                'Please select the reference nodes set. By default the ref nodes will be the first molecule loaded in the viewer',
                'wcfg': {
                    'molSet': self.vf.Mols,
                    'vf': self.vf,
                    'all': 1,
                    'crColor': (1., 0., 0.),
                    'forceEmpty': 1,
                },
                'gridcfg': {
                    'sticky': 'we'
                }
            })

            idf.append({
                'widgetType': StringSelectorGUI,
                'parent': 'mobgroup',
                #'defaultValue':self.vf.Mols[1].name+", , , ",
                'tooltip':
                'Please select the mobile nodes set. By default the mobile nodes will be the second molecule loaded in the viewer',
                'name': 'smobNodes',
                'wcfg': {
                    'molSet': self.vf.Mols,
                    'vf': self.vf,
                    'all': 1,
                    'crColor': (0., 0., 1.),
                    'forceEmpty': 1,
                },
                'gridcfg': {
                    'row': -1,
                    'sticky': 'we'
                }
            })
            return idf
コード例 #3
0
class AutoLigandCommand(MVCommand, MVAtomICOM):
    "GUI for AutoLigand: extends MVCommand, overwrites guiCallback"

    def __init__(self, func=None):
        MVCommand.__init__(self, func)
        MVAtomICOM.__init__(self)
        self.save = None
        self.showPlayer = False
        self.floodFile = None

    def onAddCmdToViewer(self):
        from DejaVu.Points import CrossSet
        self.startCross = CrossSet('StartCross',
                                   materials=((1., 1., 0), ),
                                   inheritMaterial=0,
                                   protected=True,
                                   offset=1.0,
                                   lineWidth=5,
                                   visible=0,
                                   pickable=0,
                                   listed=0)
        self.endCross = CrossSet('EndCross',
                                 materials=((0, 1, 1), ),
                                 inheritMaterial=0,
                                 protected=True,
                                 offset=1.0,
                                 lineWidth=5,
                                 visible=0,
                                 pickable=0,
                                 listed=0)

        from DejaVu.IndexedPolygons import IndexedPolygons
        from DejaVu.Box import Box
        from DejaVu.Spheres import Spheres
        from DejaVu import viewerConst
        from DejaVu.bitPatterns import patternList
        from opengltk.OpenGL import GL

        face = ((0, 3, 2, 1), (3, 7, 6, 2), (7, 4, 5, 6), (0, 1, 5, 4),
                (1, 2, 6, 5), (0, 4, 7, 3))
        coords = ((1, 1, -1), (-1, 1, -1), (-1, -1, -1), (1, -1, -1),
                  (1, 1, 1), (-1, 1, 1), (-1, -1, 1), (1, -1, 1))
        #new style RGB->
        materials = (
            (0, 0, 1),
            (0, 1, 0),
            (0, 0, 1),
            (0, 1, 0),
            (1, 0, 0),
            (1, 0, 0),
        )
        box = IndexedPolygons('Box',
                              materials=materials,
                              vertices=coords,
                              faces=face,
                              inheritMaterial=0,
                              visible=0,
                              protected=True,
                              listed=0)
        box.Set(frontPolyMode=GL.GL_LINE)
        box.Set(backPolyMode=GL.GL_LINE)
        box.Set(culling=GL.GL_NONE)
        box.inheritShading = 0
        box.shading = GL.GL_FLAT
        box.Set(matBind=viewerConst.PER_PART)
        box.polygonstipple.Set(pattern=patternList[0])
        box.Set(stipplePolygons=1)
        box.transparent = 0
        self.box = box
        self.spheres = Spheres('Spheres',
                               visible=0,
                               inheritMaterial=0,
                               radii=(0.3, ),
                               protected=True,
                               listed=0)
        self.halo = Spheres('Halo',
                            visible=0,
                            inheritMaterial=0,
                            radii=(0.5, ),
                            protected=True,
                            listed=0)

        from DejaVu.Geom import Geom
        AutoLigand_geoms = Geom("AutoLigand_geoms", shape=(0, 0), listed=0)
        self.vf.GUI.VIEWER.AddObject(AutoLigand_geoms,
                                     parent=self.vf.GUI.miscGeom)
        self.vf.GUI.VIEWER.AddObject(self.startCross, parent=AutoLigand_geoms)
        self.vf.GUI.VIEWER.AddObject(self.endCross, parent=AutoLigand_geoms)
        self.vf.GUI.VIEWER.AddObject(self.box, parent=AutoLigand_geoms)
        self.vf.GUI.VIEWER.AddObject(self.spheres, parent=AutoLigand_geoms)
        self.vf.GUI.VIEWER.AddObject(self.halo, parent=AutoLigand_geoms)
        self.grids = {}
        self.vf.showCitation.citations["AutoLigand"] = """
Please acknowledge the use of the AutoLigand that results
in any published work, including scientific papers, films
and videotapes, by citing the following reference:
Harris R, Olson AJ, Goodsell DS.  Proteins. (2008) 70 1506..
"""

    def guiCallback(self, event=None):
        fileList = []
        fld_list = glob.glob('*.maps.fld')
        if not fld_list:
            tkMessageBox.showinfo(
                "AutoLigand Info",
                "AutoLigand requires input AutoGrid maps. \nPlease click OK to select directory containing grid maps."
            )
            folder = tkFileDialog.askdirectory(title="Select A Folder")
            if folder:
                os.chdir(folder)
                fld_list = glob.glob('*.maps.fld')
            else:
                return

        for fld in fld_list:
            fileList.append(fld.split('.')[0])
        entryfield_value = ""
        if fileList:
            fileList.sort()
            entryfield_value = fileList[0]

        ifd = InputFormDescr(title="Run AutoLigand")

        ifd.append({
            'name': "fileName",
            'widgetType': Pmw.Group,
            'container': {
                'fileName': 'w.interior()'
            },
            'wcfg': {
                'tag_text': "Base Name for Receptor Map Files"
            },
        })
        ifd.append({
            'widgetType': Pmw.ComboBox,
            'name': 'FileBaseName',
            'parent': 'fileName',
            'tooltip':
            'FileBaseName = Just the name part from map files (i.e., FileBaseName.C.map)',
            'wcfg': {
                'dropdown': 1,
                'scrolledlist_items': fileList,
                'entryfield_value': entryfield_value,
                'selectioncommand': self.selectGrid,
                'labelpos': 'w',
            }
        })
        ifd.append({
            'name': "nGroup",
            'widgetType': Pmw.Group,
            'container': {
                'nGroup': 'w.interior()'
            },
            'tooltip':
            'Number of heavy atom for ligand or number of fill points to use.',
            'wcfg': {
                'tag_text': "Number of "
            },
        })
        ifd.append({
            'widgetType': Pmw.RadioSelect,
            'parent': 'nGroup',
            'name': 'type',
            'defaultValue': 'Points',
            'listtext': ["Heavy Atoms", "Points"],
        })
        ifd.append({
            'widgetType': Pmw.EntryField,
            'parent': 'nGroup',
            'name': 'number',
            'wcfg': {
                'labelpos': 'w',
                'value': '100',
                'validate': {
                    'validator': 'integer'
                }
            }
        })

        ifd.append({
            'widgetType':
            Pmw.NoteBook,
            'name':
            'autoligandNotebook',
            'container': {
                'Single Fill': "w.page('Single Fill')",
                'Connected Fill': "w.page('Connected Fill')",
                'Scan': "w.page('Scan')"
            },
            'componentcfg': [
                {
                    'name': 'Single Fill',
                    'cfg': {}
                },
                {
                    'name': 'Connected Fill',
                    'cfg': {}
                },
                {
                    'name': 'Scan',
                    'cfg': {}
                },
                #        {'raisecommand':self.pageChanged}
            ],
            'wcfg': {
                'raisecommand': self.pageChanged
            },
            'gridcfg': {
                'sticky': 'we'
            },
        })

        #Single Fill
        ifd.append({
            'name': "StartLoc",
            'parent': 'Single Fill',
            'widgetType': Pmw.Group,
            'container': {
                'StartLoc': 'w.interior()'
            },
            'wcfg': {
                'tag_text': "Start Location"
            },
        })
        ifd.append({
            'widgetType': ExtendedSliderWidget,
            'name': 'gridPointsX',
            'parent': 'StartLoc',
            'wcfg': {
                'label': 'X: ',
                'width': 190,
                'immediate': 1,
                'command': self.changeStartCross,
                'entrypackcfg': {
                    'side': 'left'
                },
            },
        })
        ifd.append({
            'widgetType': ExtendedSliderWidget,
            'name': 'gridPointsY',
            'parent': 'StartLoc',
            'wcfg': {
                'label': 'Y: ',
                'width': 190,
                'immediate': 1,
                'command': self.changeStartCross,
                'entrypackcfg': {
                    'side': 'left'
                },
            },
        })
        ifd.append({
            'widgetType': ExtendedSliderWidget,
            'name': 'gridPointsZ',
            'parent': 'StartLoc',
            'wcfg': {
                'label': 'Z: ',
                'width': 190,
                'immediate': 1,
                'command': self.changeStartCross,
                'entrypackcfg': {
                    'side': 'left'
                },
            },
        })

        ifd.append({
            'name': "output",
            'widgetType': Pmw.Group,
            'parent': 'Single Fill',
            'container': {
                'output': 'w.interior()'
            },
            'wcfg': {
                'tag_text': "Output Options"
            },
        })
        ifd.append({
            'name': 'pdbFile',
            'tooltip':
            """Creates PDB_fill_#Nout1.pdb file where #N is the number of fill points.""",
            'parent': 'output',
            'widgetType': Tkinter.Checkbutton,
            'defaultValue': 1,
            'wcfg': {
                'text': 'Create PDB of the Final Fill',
                'state': 'disabled',
            },
            'gridcfg': {
                'sticky': 'w'
            }
        })

        ifd.append({
            'name': 'showProgress',
            'parent': 'output',
            'tooltip':
            """Save intermediate results in a file and open flood player when AutoLigand finishes.""",
            'widgetType': Tkinter.Checkbutton,
            'defaultValue': 0,
            'wcfg': {
                'text': 'Save Intermediate Results for Movie',
                'variable': Tkinter.IntVar(),
            },
            'gridcfg': {
                'sticky': 'w'
            }
        })
        #Connected Fill
        ifd.append({
            'widgetType': Tkinter.Label,
            'name': 'label',
            'parent': 'Connected Fill',
            'wcfg': {
                'text': 'Select End Location for Connected Fill'
            }
        })
        ifd.append({
            'name': "EndLoc",
            'parent': 'Connected Fill',
            'widgetType': Pmw.Group,
            'container': {
                'EndLoc': 'w.interior()'
            },
            'wcfg': {
                'tag_text': "End Location"
            },
        })
        ifd.append({
            'widgetType': ExtendedSliderWidget,
            'name': 'gridPointsXEnd',
            'parent': 'EndLoc',
            'wcfg': {
                'label': 'X: ',
                'width': 190,
                'immediate': 1,
                'command': self.changeEndCross,
                'entrypackcfg': {
                    'side': 'left'
                },
            },
        })
        ifd.append({
            'widgetType': ExtendedSliderWidget,
            'name': 'gridPointsYEnd',
            'parent': 'EndLoc',
            'wcfg': {
                'label': 'Y: ',
                'width': 190,
                'immediate': 1,
                'command': self.changeEndCross,
                'entrypackcfg': {
                    'side': 'left'
                },
            },
        })
        ifd.append({
            'widgetType': ExtendedSliderWidget,
            'name': 'gridPointsZEnd',
            'parent': 'EndLoc',
            'wcfg': {
                'label': 'Z: ',
                'width': 190,
                'immediate': 1,
                'command': self.changeEndCross,
                'entrypackcfg': {
                    'side': 'left'
                },
            },
        })

        #Connected Fill
        #        ifd.append({'widgetType':Tkinter.Label,
        #                'name':'label',
        #                'parent':'Scan',
        #                'wcfg':{'text':"""Results from the Scan mode will
        #be available under\n"""+os.getcwd()}
        #                        })
        ifd.append({
            'widgetType': Pmw.EntryField,
            'parent': 'Scan',
            'name': 'nFills',
            'wcfg': {
                'label_text': "Number of Fills:",
                'labelpos': 'w',
                'value': '10',
                'validate': {
                    'validator': 'integer'
                }
            }
        })

        def initselect(arg):
            self.selectGrid(entryfield_value)

        self.ifd = ifd
        self.save = self.vf.ICmdCaller.commands.value["Shift_L"]
        self.vf.setICOM(self, modifier="Shift_L", topCommand=0)
        self.vf.setIcomLevel(Atom)
        self.endCross.Set(visible=0)
        val = self.vf.getUserInput(ifd,
                                   modal=0,
                                   blocking=1,
                                   initFunc=initselect)
        if self.save:
            self.vf.setICOM(self.save, modifier="Shift_L", topCommand=0)
            self.save = None

    # import pdb;pdb.set_trace()
        if val:
            if not val['FileBaseName'][0]:
                msg = "AutoGrid files are missing.\n"
                msg += "Please generate grid maps. AutoLigand requires input AutoGrid maps."
                tkMessageBox.showerror("Error!", msg)
                return
            selection = self.ifd.entryByName['autoligandNotebook'][
                'widget'].getcurselection()
            cmdString = [sys.executable, AutoLigandPath]
            cmdString.append('-r')
            cmdString.append(val['FileBaseName'][0])
            self.fileBaseName = val['FileBaseName'][0]
            if val['type'] == 'Points':
                cmdString.append('-p')
                cmdString.append(str(val['number']))
            else:
                cmdString.append('-a')
                cmdString.append(str(val['number']))
                val['number'] = 6 * int(val['number'])

            if selection in ['Single Fill', 'Connected Fill']:
                cmdString.append('-x')
                cmdString.append(str(val['gridPointsX']))
                cmdString.append('-y')
                cmdString.append(str(val['gridPointsY']))
                cmdString.append('-z')
                cmdString.append(str(val['gridPointsZ']))
                if selection == 'Connected Fill':
                    cmdString.append('-i')
                    cmdString.append(str(val['gridPointsXEnd']))
                    cmdString.append('-j')
                    cmdString.append(str(val['gridPointsYEnd']))
                    cmdString.append('-k')
                    cmdString.append(str(val['gridPointsZEnd']))
                if os.name == 'nt':  #sys.platform == "win32":
                    self.cmdTxt = subprocess.list2cmdline(cmdString)
                else:
                    self.cmdTxt = ' '.join(cmdString)
                if val['showProgress']:
                    self.cmdTxt += " -m"
                    self.showPlayer = True
                else:
                    self.showPlayer = False
                self.cmd = SysCmdInThread(self.cmdTxt, shell=True)
                self.cmd.start()
                self.checkResults()
                self.N_of_pts = val['number']
            elif selection == "Scan":
                cmdString.append('-f')
                cmdString.append(str(val['nFills']))
                if os.name == 'nt':  #sys.platform == "win32":
                    self.cmdTxt = subprocess.list2cmdline(cmdString)
                else:
                    self.cmdTxt = ' '.join(cmdString)
                    self.cmdTxt += ' &'  #run in a background

                subprocess.Popen(self.cmdTxt, shell=True)
                tkMessageBox.showinfo("Success!",
                                      """AutoLigand launched successfully.""")
        else:
            self.hideGeoms()

    def pageChanged(self, name):
        if name == 'Single Fill':
            self.startCross.Set(visible=1)
        elif name == 'Connected Fill':
            self.endCross.Set(visible=1)
        else:
            self.startCross.Set(visible=0)
            self.endCross.Set(visible=0)

    def selectGrid(self, value):
        if not value:
            return
        lines = open(value + ".maps.fld").readlines()
        if not lines: return
        for line in lines:
            if line.startswith("#SPACING"):
                spacing = float(line.split()[-1])
            if line.startswith("#NELEMENTS"):
                tmp = line.split()
                dimX = int(tmp[1])
                dimY = int(tmp[2])
                dimZ = int(tmp[3])
            if line.startswith("#CENTER"):
                tmp = line.split()
                centerX = float(tmp[1])
                centerY = float(tmp[2])
                centerZ = float(tmp[3])
        #this variables are the same used in AutoLigand.py
        self.xcent = int(dimX / 2)
        self.ycent = int(dimY / 2)
        self.zcent = int(dimZ / 2)
        self.centerx = centerX
        self.centery = centerY
        self.centerz = centerZ
        self.spacing = spacing
        c = [centerX, centerY, centerZ]
        xlen = round(spacing * dimX, 4)
        ylen = round(spacing * dimY, 4)
        zlen = round(spacing * dimZ, 4)
        self.minX = c[0] - xlen * 0.5
        self.maxX = c[0] + xlen * 0.5
        if self.grids.has_key(value):
            centerX = self.grids[value][0]
            centerY = self.grids[value][1]
            centerZ = self.grids[value][2]

        self.ifd.entryByName['gridPointsX']['widget'].configure(
            minval=self.minX,
            maxval=self.maxX,
        )
        self.ifd.entryByName['gridPointsXEnd']['widget'].configure(
            minval=self.minX,
            maxval=self.maxX,
        )

        self.minY = c[1] - ylen * 0.5
        self.maxY = c[1] + ylen * 0.5

        self.ifd.entryByName['gridPointsY']['widget'].configure(
            minval=self.minY,
            maxval=self.maxY,
        )
        self.ifd.entryByName['gridPointsYEnd']['widget'].configure(
            minval=self.minY,
            maxval=self.maxY,
        )
        self.minZ = c[2] - zlen * 0.5
        self.maxZ = c[2] + zlen * 0.5
        self.ifd.entryByName['gridPointsZ']['widget'].configure(
            minval=self.minZ,
            maxval=self.maxZ,
        )
        self.ifd.entryByName['gridPointsZEnd']['widget'].configure(
            minval=self.minY,
            maxval=self.maxY,
        )

        self.startCross.Set(vertices=((centerX, centerY, centerZ), ))
        self.ifd.entryByName['gridPointsX']['widget'].set(centerX)
        self.ifd.entryByName['gridPointsY']['widget'].set(centerY)
        self.ifd.entryByName['gridPointsZ']['widget'].set(centerZ)
        self.ifd.entryByName['gridPointsXEnd']['widget'].set(centerX + 12)
        self.ifd.entryByName['gridPointsYEnd']['widget'].set(centerY + 12)
        self.ifd.entryByName['gridPointsZEnd']['widget'].set(centerZ + 12)
        self.endCross.Set(vertices=((centerX + 12, centerY + 12,
                                     centerZ + 12), ))

        pts = [(self.maxX, self.maxY, self.minZ),
               (self.minX, self.maxY, self.minZ),
               (self.minX, self.minY, self.minZ),
               (self.maxX, self.minY, self.minZ),
               (self.maxX, self.maxY, self.maxZ),
               (self.minX, self.maxY, self.maxZ),
               (self.minX, self.minY, self.maxZ),
               (self.maxX, self.minY, self.maxZ)]

        self.box.Set(visible=1)
        #self.startCross.Set(visible=1)
        self.box.vertexSet.vertices.array[:] = pts
        self.box.RedoDisplayList()
        self.vf.GUI.VIEWER.Normalize_cb()
        self.vf.GUI.VIEWER.Redraw()

    def changeStartCross(self, val):
        centerX = self.ifd.entryByName['gridPointsX']['widget'].get()
        centerY = self.ifd.entryByName['gridPointsY']['widget'].get()
        centerZ = self.ifd.entryByName['gridPointsZ']['widget'].get()
        grid = self.ifd.entryByName['FileBaseName']['widget'].get()
        if grid:
            self.grids[grid] = [centerX, centerY, centerZ]
        self.startCross.Set(visible=1)
        self.startCross.Set(vertices=((centerX, centerY, centerZ), ))
        self.vf.GUI.VIEWER.Redraw()

    def changeEndCross(self, val):
        centerX = self.ifd.entryByName['gridPointsXEnd']['widget'].get()
        centerY = self.ifd.entryByName['gridPointsYEnd']['widget'].get()
        centerZ = self.ifd.entryByName['gridPointsZEnd']['widget'].get()
        grid = self.ifd.entryByName['FileBaseName']['widget'].get()
        #self.endCross.Set(visible=1)
        self.endCross.Set(vertices=((centerX, centerY, centerZ), ))
        self.vf.GUI.VIEWER.Redraw()

    def checkResults(self):
        """Checks the queue for results until we get one"""
        if self.cmd.ok.configure()['state'][-1] == 'normal':
            if self.showPlayer:
                self.openPklData()
            else:
                molName = "FILL_" + str(self.N_of_pts) + "out1"
                if os.path.exists(molName + ".pdb"):
                    self.vf.readMolecule(molName + ".pdb")
                    self.vf.displaySticksAndBalls(
                        molName,
                        cradius=0.0,
                        sticksBallsLicorice="Sticks and Balls")
                    self.vf.displayLines(molName, negate=True, displayBO=False)
                    self.vf.colorByAtomType(molName, ['sticks', 'balls'])
                self.vf.GUI.ROOT.after(2050, self.hideGeoms)
            return
        self.vf.GUI.ROOT.after(100, self.checkResults)

    def hideGeoms(self):
        self.box.Set(visible=0)
        self.startCross.Set(visible=0)
        self.endCross.Set(visible=0)
        self.spheres.Set(visible=0)
        self.halo.Set(visible=0)

    def __call__(self, atom, **kw):
        if not atom:
            return 'ERROR'
        atoms = self.vf.expandNodes(atom)
        if not atoms:
            return 'ERROR'
        atoms = atoms.findType(Atom)
        if not atoms:
            return 'ERROR'
        apply(self.doitWrapper, (atoms, ), kw)

    def doit(self, atoms=None):
        if len(atoms) == 0: return
        atom = atoms[0]
        if self.minX < atom.coords[0] > self.maxX:
            return
        if self.minY < atom.coords[1] > self.maxY:
            return
        if self.minZ < atom.coords[2] > self.maxZ:
            return

        selection = self.ifd.entryByName['autoligandNotebook'][
            'widget'].getcurselection()
        if selection == "Single Fill":
            self.ifd.entryByName['gridPointsX']['widget'].set(atom.coords[0])
            self.ifd.entryByName['gridPointsY']['widget'].set(atom.coords[1])
            self.ifd.entryByName['gridPointsZ']['widget'].set(atom.coords[2])
            #        self.startCross.Set(visible=1)
            self.startCross.Set(vertices=((atom.coords[0], atom.coords[1],
                                           atom.coords[2]), ))
        elif selection == "Connected Fill":
            self.ifd.entryByName['gridPointsXEnd']['widget'].set(
                atom.coords[0])
            self.ifd.entryByName['gridPointsYEnd']['widget'].set(
                atom.coords[1])
            self.ifd.entryByName['gridPointsZEnd']['widget'].set(
                atom.coords[2])
            self.endCross.Set(vertices=((atom.coords[0], atom.coords[1],
                                         atom.coords[2]), ))

        self.vf.GUI.VIEWER.Redraw()

    def openPklData(self):
        self.vf.AutoLigandMovieCommand(self.fileBaseName + '_flood.pkl')
コード例 #4
0
class MeasureTorsionGUICommand(MeasureGUICommand):
    """Label torsion between four atoms (color coded cyan) Accumulates picked atoms.Draws polygons and labels showing the torsion angle between groups of 4 selected atoms (color-coded cyan).Userpref 'measureTorsionSL' sets the 'snakeLength' which is how many torsion measureDisplays can be seen at the same time.When more than that number are measured, the first torsion measured is no longer labeled.
   \nPackage : Pmv
   \nModule  : measureCommands
   \nClass   : MeasureTorsionGUICommand
   \nCommand : measureTorsionGC
   \nSynopsis:\n
        torsion/None<---measureTorsionGC(atoms)
   \nRequired Argument:\n        
           atoms  --- the atom(s)
           \ntorsion --- returned when the number of atoms is a multiple of 4 
    """
    def __init__(self, func=None):
        MeasureGUICommand.__init__(self, func=func)
        self.flag = self.flag | self.objArgOnly

    def onAddCmdToViewer(self):
        from DejaVu.bitPatterns import pat3
        from DejaVu.IndexedPolygons import IndexedPolygons
        if not self.vf.commands.has_key('setICOM'):
            self.vf.loadCommand('interactiveCommands',
                                'setICOM',
                                'Pmv',
                                topCommand=0)
        if not self.vf.commands.has_key('measureAngle'):
            self.vf.loadCommand('measureCommands',
                                'measureAngle',
                                'Pmv',
                                topCommand=0)

        self.masterGeom = Geom('measureTorsionGeom',
                               shape=(0, 0),
                               pickable=0,
                               protected=True)
        self.masterGeom.isScalable = 0

        if self.vf.hasGui:
            measure_geoms = check_measure_geoms(self.vf.GUI)
            self.vf.GUI.VIEWER.AddObject(self.masterGeom, parent=measure_geoms)
        self.lines = IndexedPolygons('torsionLine',
                                     materials=((0, 1, 1), ),
                                     culling=GL.GL_NONE,
                                     inheritStipplePolygons=0,
                                     inheritMaterial=0,
                                     stipplePolygons=1,
                                     backPolyMode=GL.GL_FILL,
                                     frontPolyMode=GL.GL_FILL,
                                     protected=True,
                                     pickable=0)
        if self.vf.userpref['Sharp Color Boundaries for MSMS'][
                'value'] == 'blur':
            self.lines.Set(
                inheritSharpColorBoundaries=False,
                sharpColorBoundaries=False,
            )
        self.lines.polygonstipple.Set(pattern=pat3)
        #self.lines.polygonstipple.Set(pattern=pat3, tagModified=False)
        #self.lines.RenderMode(GL.GL_FILL)
        #self.lines.RenderMode(GL.GL_FILL, face=GL.GL_BACK)
        self.labels = GlfLabels(name='torsionLabel',
                                shape=(0, 3),
                                font='arial1.glf',
                                fontStyle='solid3d',
                                fontScales=(.5, .5, .3),
                                inheritMaterial=0,
                                materials=((0, 1, 1), ))
        self.spheres = Spheres(name='torsionSpheres',
                               shape=(0, 3),
                               inheritMaterial=0,
                               radii=0.2,
                               quality=15,
                               materials=((0., 1., 1.), ),
                               protected=True)
        if self.vf.hasGui:
            for item in [self.lines, self.labels, self.spheres]:
                self.vf.GUI.VIEWER.AddObject(item, parent=self.masterGeom)
        doc = """Number of labeled torsions displayed.
Valid values are integers>0"""
        self.vf.userpref.add('Measured Torsions',
                             4,
                             callbackFunc=[self.setLength_cb],
                             category="Molecules",
                             validateFunc=lambda x: x > 0,
                             doc=doc)
        #used after startICOM is invoked
        doc = """Continuous update of torsions if 'transformRoot only' is
turned off  and viewer's current object is not Root."""
        choices = ['yes', 'no']
        self.vf.userpref.add('Continuous Update Torsion',
                             'yes',
                             choices,
                             callbackFunc=[self.continuousUpdate_cb],
                             category="Molecules",
                             doc=doc)
        self.snakeLength = 4

    def __call__(self, atoms, **kw):
        """torsion/None<-measureTorsionGC(atoms)
        \natoms  --- the atom(s)
        \ntorsion --- returned when the number of atoms is a multiple of 4"""
        if type(atoms) is types.StringType:
            self.nodeLogString = "'" + atoms + "'"
        ats = self.vf.expandNodes(atoms)
        if not len(ats): return 'ERROR'
        return apply(self.doitWrapper, (ats, ), kw)

    def doit(self, ats):
        for at in ats:
            lenAts = len(self.atomList)
            if lenAts and lenAts % 4 != 0 and at == self.atomList[-1]:
                continue
            self.atomList.append(at)
            if len(self.atomList) > 4 * self.snakeLength:
                self.atomList = self.atomList[4:]
            self.update()
        if len(self.labelStrs) and len(self.atomList) % 4 == 0:
            return float(self.labelStrs[-1])

    def update(self, forward=1, event=None):
        if not len(self.atomList):
            self.spheres.Set(vertices=[])
            #self.spheres.Set(vertices=[], tagModified=False)
            self.labels.Set(vertices=[])
            #self.labels.Set(vertices=[], tagModified=False)
            self.lines.Set(vertices=[])
            #self.lines.Set(vertices=[], tagModified=False)
            self.vf.GUI.VIEWER.Redraw()
            return
        limit = self.snakeLength
        #each time have to recalculate lineVertices
        self.lineVertices = []
        for at in self.atomList:
            c1 = self.getTransformedCoords(at)
            self.lineVertices.append(tuple(c1))
        #display spheres:
        if len(self.lineVertices) % 4:
            self.spheres.Set(
                vertices=self.lineVertices[-(len(self.lineVertices) % 4):])
        else:
            self.spheres.Set(vertices=[])

        #self.spheres.Set(vertices=self.lineVertices, tagModified=False)
        self.vf.GUI.VIEWER.Redraw()
        #label with torsion
        #lines between spheres are only drawn when angle completed
        #that is, len(ats)%4=0
        if len(self.lineVertices) < 4:
            self.labels.Set(vertices=[])
            #self.labels.Set(vertices=[], tagModified=False)
            self.lines.Set(vertices=[])
            #self.lines.Set(vertices=[], tagModified=False)
        else:
            #rebuild labels and polygons each time
            self.labelCenters = []
            self.labelStrs = []
            #labelCenters, labelStrs,
            #this gets done lenATs/4 times
            numItems = len(self.atomList) / 4
            for i in range(numItems):
                at0 = self.atomList[i * 4]
                at1 = self.atomList[i * 4 + 1]
                at2 = self.atomList[i * 4 + 2]
                at3 = self.atomList[i * 4 + 3]
                torsion = self.vf.measureTorsion(at0,
                                                 at1,
                                                 at2,
                                                 at3,
                                                 topCommand=0)
                torsionLabel = '%.3f' % torsion
                self.labelStrs.append(torsionLabel)
                c0 = self.getTransformedCoords(at0)
                c1 = self.getTransformedCoords(at3)
                newcenter = tuple((c0 + c1) / 2.0)
                self.labelCenters.append(newcenter)
            #to reset labels, lines and fan, EACH TIME
            self.labels.Set(vertices=self.labelCenters, labels=self.labelStrs)
            #tagModified=False)
            #if len(self.lineVertices)%4!=0:
            #self.lineVertices = self.lineVertices[:numItems*4]
            #only draw lines in groups of 4
            #numItems*4
            if len(self.atomList) % 4 == 0:
                faces = range(numItems * 4)
                faces = Numeric.reshape(faces, (-1, 4))
                ###FIX THIS
                ###on undo: if you have just wrapped, undoing the next pt
                ###breaks because trying to set the vertices uses the old
                ###faces
                if not forward:
                    self.lines.Set(vertices=[], faces=[])
                    #self.lines.Set(vertices=[], faces=[], tagModified=False)
                self.lines.Set(vertices=self.lineVertices,
                               faces=faces,
                               freshape=1)
                #freshape=1, tagModified=False)
                self.vf.GUI.VIEWER.Redraw()
            else:
                #this only works going forward: undo breaks here
                if len(self.lines.faceSet.faces.array) > numItems:
                    faces = range((numItems + 1) * 4)
                    faces = Numeric.reshape(faces, (-1, 4))
                    if forward:
                        faces = faces[1:]
                    else:
                        faces = faces[:-1]
                    self.lines.Set(faces=faces)
                    self.vf.GUI.VIEWER.Redraw()
コード例 #5
0
ファイル: bondsCommands.py プロジェクト: lisarosalina/App
class AddBondsGUICommand(MVCommand, MVAtomICOM):
    """
    The AddBondGUICommand provides an interactive way of creating bonds between two given atoms by picking on them. To use this command you need first to load it into PMV. Then you can find the entry 'addBonds' under the Edit menu. To add bonds  you just need to pick on the 2 atoms you want to bind. If you drag select  a bunch of atoms, the command will buildBondsByDistance between them.This command is undoable.
   \nPackage : Pmv
   \nModule  : bondsCommands
   \nClass   : AddBondsGUICommand
   \nCommand : addBondsGC
   \nSynopsis:\n
        None<-addBondsGC(atoms)\n
    \nRequired Arguments:\n    
        atoms  : atom(s)\n
    """
    def __init__(self, func=None):
        MVCommand.__init__(self, func)
        MVAtomICOM.__init__(self)
        self.atomList = AtomSet([])
        self.undoAtList = AtomSet([])
        self.labelStrs = []

    def onRemoveObjectFromViewer(self, obj):
        removeAts = AtomSet([])
        for at in self.atomList:
            if at in obj.allAtoms:
                removeAts.append(at)
        self.atomList = self.atomList - removeAts
        removeAts = AtomSet([])
        for at in self.undoAtList:
            if at in obj.allAtoms:
                removeAts.append(at)
        self.undoAtList = self.undoAtList - removeAts
        self.update()

    def onAddCmdToViewer(self):
        if not self.vf.commands.has_key('setICOM'):
            self.vf.loadCommand('interactiveCommands',
                                'setICOM',
                                'Pmv',
                                topCommand=0)
        if not self.vf.commands.has_key('addBonds'):
            self.vf.loadCommand('bondsCommands',
                                'addBonds',
                                'Pmv',
                                topCommand=0)
        if not self.vf.commands.has_key('removeBondsGC'):
            self.vf.loadCommand('bondsCommands',
                                'removeBondsGC',
                                'Pmv',
                                topCommand=0)
        self.masterGeom = Geom('addBondsGeom',
                               shape=(0, 0),
                               pickable=0,
                               protected=True)
        self.masterGeom.isScalable = 0
        self.spheres = Spheres(name='addBondsSpheres',
                               shape=(0, 3),
                               inheritMaterial=0,
                               radii=0.2,
                               quality=15,
                               materials=((1., 1., 0.), ),
                               protected=True)
        if not self.vf.commands.has_key('labelByExpression'):
            self.vf.loadCommand('labelCommands', [
                'labelByExpression',
            ],
                                'Pmv',
                                topCommand=0)
        if self.vf.hasGui:
            miscGeom = self.vf.GUI.miscGeom
            self.vf.GUI.VIEWER.AddObject(self.masterGeom, parent=miscGeom)
            self.vf.GUI.VIEWER.AddObject(self.spheres, parent=self.masterGeom)

    def __call__(self, atoms, **kw):
        """None<-addBondsGC(atoms)
           \natoms  : atom(s)"""
        if type(atoms) is StringType:
            self.nodeLogString = "'" + atoms + "'"
        ats = self.vf.expandNodes(atoms)
        if not len(ats): return 'ERROR'
        return apply(self.doitWrapper, (ats, ), kw)

    def doit(self, ats):
        if len(ats) > 2:
            if len(self.atomList):
                atSet = ats + self.atomList
            else:
                atSet = ats
            parent = atSet[0].parent
            parent.buildBondsByDistanceOnAtoms(atSet)
            self.atomList = AtomSet([])
            self.update(True)
        else:
            lenAts = len(self.atomList)
            last = None
            if lenAts:
                last = self.atomList[-1]
                top = self.atomList[0].top
            for at in ats:
                #check for repeats of same atom
                if lenAts and at == last:
                    continue
                #lenAts = len(self.atomList)
                #if lenAts and at==self.atomList[-1]:
                #    continue
                if lenAts and at.top != self.atomList[-1].top:
                    msg = "intermolecular bond to %s disallowed" % (
                        at.full_name())
                    self.warningMsg(msg)
                self.atomList.append(at)
                self.undoAtList.append(at)
                lenAts = len(self.atomList)
            self.update(True)
            #if only have one atom, there is nothing else to do
            if lenAts < 2: return
            #now build bonds between pairs of atoms
            atSet = self.atomList
            if lenAts % 2 != 0:
                atSet = atSet[:-1]
                #all pairs of atoms will be bonded
                #so keep only the last one
                self.atomList = atSet[-1:]
                lenAts = lenAts - 1
            else:
                self.vf.labelByExpression(self.atomList,
                                          negate=1,
                                          topCommand=0)
                self.atomList = AtomSet([])
            for i in range(0, lenAts, 2):
                at1 = atSet[i]
                at2 = atSet[i + 1]
                self.vf.addBonds(at1, at2, origin='UserDefined', topCommand=0)
        self.update(True)

    def applyTransformation(self, pt, mat):
        pth = [pt[0], pt[1], pt[2], 1.0]
        return Numeric.dot(mat, pth)[:3]

    def getTransformedCoords(self, atom):
        if not atom.top.geomContainer:
            return atom.coords
        g = atom.top.geomContainer.geoms['master']
        c = self.applyTransformation(atom.coords, g.GetMatrix(g))
        return c.astype('f')

    def update(self, event=None):
        if not len(self.atomList):
            self.spheres.Set(vertices=[], tagModified=False)
            self.vf.labelByExpression(self.atomList, negate=1, topCommand=0)
            if self.vf.hasGui:
                self.vf.GUI.VIEWER.Redraw()
            return
        self.lineVertices = []
        #each time have to recalculate lineVertices
        for at in self.atomList:
            c1 = self.getTransformedCoords(at)
            self.lineVertices.append(tuple(c1))

        if event:
            self.spheres.Set(vertices=self.lineVertices, tagModified=False)
            self.vf.labelByExpression(self.atomList,
                                      function='lambda x: x.full_name()',
                                      lambdaFunc=1,
                                      textcolor='yellow',
                                      format='',
                                      negate=0,
                                      location='Last',
                                      log=0,
                                      font='arial1.glf',
                                      only=1,
                                      topCommand=0)
        #setting spheres doesn't trigger redraw so do it explicitly
        if self.vf.hasGui:
            self.vf.GUI.VIEWER.Redraw()

    def guiCallback(self, event=None):
        self.save = self.vf.ICmdCaller.commands.value["Shift_L"]
        self.vf.setICOM(self, modifier="Shift_L", topCommand=0)

    def setupUndoAfter(self, ats, **kw):

        lenUndoAts = len(self.undoAtList)
        lenAts = len(ats)
        if lenAts == 1:
            #after adding 1 self.atomList would be 1 or 0
            if len(self.atomList) == 1:
                s = '0'
                ustr = '"c=self.addBondsGC; self.labelByExpression(c.atomList, negate=1, topCommand=0);c.atomList=c.atomList[:' + s + '];c.undoAtList=c.undoAtList[:-1];c.update()"'
            else:
                self.vf.undoCmdStack.remove(self.prev_undoCmds)
                ind = str(lenUndoAts - 2)
                ustr = '"c=self.addBondsGC;nodes=self.expandNodes(' + '\'' + self.undoAtList[
                    -2:].full_name(
                    ) + '\'' + '); bonds=nodes.bonds[0];self.removeBondsGC(bonds, topCommand=0);c.atomList=nodes[:1];c.undoAtList=c.undoAtList[:' + ind + '];c.update()"'
        elif lenUndoAts > lenAts:
            ustr = '"c=self.addBondsGC;nodes=self.expandNodes(' + '\'' + ats.full_name(
            ) + '\'' + ');bonds = nodes.bonds[0];self.removeBondsGC(bonds, topCommand=0);c.undoAtList=c.undoAtList[:' + str(
                lenAts) + ']"'
        else:
            ustr = '"c=self.addBondsGC;nodes=self.expandNodes(' + '\'' + ats.full_name(
            ) + '\'' + ');bonds = nodes.bonds[0];self.removeBondsGC(bonds, topCommand=0);c.undoAtList=c.undoAtList[:0]"'
        if len(self.atomList) and lenAts > 1:
            atStr = self.atomList.full_name()
            estr = ';nodes=self.expandNodes(' + '\'' + self.atomList.full_name(
            ) + '\'' + ');c.atomList=nodes;c.update()"'
            ustr = ustr + estr
        self.undoCmds = "exec(" + ustr + ")"
        self.prev_undoCmds = (self.undoCmds, "addBondsGC")

    def startICOM(self):
        self.vf.setIcomLevel(Atom, topCommand=0)

    def stopICOM(self):
        if len(self.atomList) != 0:
            self.vf.labelByExpression(self.atomList, negate=1, topCommand=0)
        del self.atomList[:]
        self.labelStrs = []
        self.spheres.Set(vertices=[], tagModified=False)
        self.vf.GUI.VIEWER.Redraw()
        self.save = None
コード例 #6
0
class MeasureAngleGUICommand(MeasureGUICommand):
    """Accumulates picked atoms.Draws fans, lines and labels labelling the angle between trios of selected atoms (color-coded orange).Userpref 'measureAngleSL' sets the 'snakeLength' which is how many angle measureDisplays can be seen at the same time.When more than that number are measured, the first angle measured is no longer labeled.
   \nPackage : Pmv
   \nModule  : measureCommands
   \nClass   : MeasureAngleGUICommand
   \nCommand : measureAngleGC
   \nSynopsis:\n
        angle/None<---measureAngleGC(atoms)
   \nRequired Argument:\n        
        atoms --- atom(s)
        \nangle --- returned when the number of atoms is a multiple of 3
    """
    def __init__(self, func=None):
        MeasureGUICommand.__init__(self, func=func)
        self.flag = self.flag | self.objArgOnly

    def onAddCmdToViewer(self):
        from DejaVu.Arcs3D import Fan3D
        from DejaVu.bitPatterns import pat3
        self.arcNormals = []
        self.arcVectors = []
        self.arcCenters = []
        if not self.vf.commands.has_key('setICOM'):
            self.vf.loadCommand('interactiveCommands',
                                'setICOM',
                                'Pmv',
                                topCommand=0)
        if not self.vf.commands.has_key('measureAngle'):
            self.vf.loadCommand('measureCommands',
                                'measureAngle',
                                'Pmv',
                                topCommand=0)

        self.masterGeom = Geom('measureAngleGeom',
                               shape=(0, 0),
                               pickable=0,
                               protected=True)
        self.masterGeom.isScalable = 0

        if self.vf.hasGui:
            measure_geoms = check_measure_geoms(self.vf.GUI)
            self.vf.GUI.VIEWER.AddObject(self.masterGeom, parent=measure_geoms)

        self.lines = IndexedPolylines('angleLine',
                                      materials=((1, .5, 0), ),
                                      inheritMaterial=0,
                                      lineWidth=3,
                                      stippleLines=1,
                                      protected=True,
                                      pickable=0)
        self.fan = Fan3D('angles',
                         materials=((1, .5, 0), ),
                         culling=GL.GL_NONE,
                         inheritMaterial=0,
                         stipplePolygons=1,
                         radii=(1., ),
                         inheritStipplePolygons=0,
                         backPolyMode=GL.GL_FILL,
                         pickable=0)
        self.fan.polygonstipple.Set(pattern=pat3)
        #self.fan.polygonstipple.Set(pattern=pat3, tagModified=False)
        #self.fan.RenderMode(GL.GL_FILL)
        #self.fan.RenderMode(GL.GL_FILL, face=GL.GL_BACK)
        self.labels = GlfLabels(name='angleLabel',
                                shape=(0, 3),
                                font='arial1.glf',
                                fontStyle='solid3d',
                                fontScales=(.5, .5, .3),
                                inheritMaterial=0,
                                materials=((1., .5, 0.), ))
        self.spheres = Spheres(name='angleSpheres',
                               shape=(0, 3),
                               inheritMaterial=0,
                               radii=0.2,
                               quality=15,
                               materials=((1., .5, 0.), ),
                               protected=True)
        if self.vf.hasGui:
            for item in [self.lines, self.labels, self.spheres, self.fan]:
                self.vf.GUI.VIEWER.AddObject(item, parent=self.masterGeom)
        doc = """Number of labeled angles displayed.
Valid values are integers>0"""
        self.vf.userpref.add('Number of Measure Angles',
                             4,
                             callbackFunc=[self.setLength_cb],
                             category="Molecules",
                             validateFunc=lambda x: x > 0,
                             doc=doc)
        #used after startICOM is invoked
        doc = """Continuous update of angles if 'transformRoot only' is
turned off  and viewer's current object is not Root."""
        choices = ['yes', 'no']
        self.vf.userpref.add('Continuous Update Angle',
                             'yes',
                             choices,
                             callbackFunc=[self.continuousUpdate_cb],
                             category="Molecules",
                             doc=doc)
        self.snakeLength = 4

    def __call__(self, atoms, **kw):
        """angle/None<---measureAngleGC(atoms)
           \natoms --- atom(s)
           \nangle --- returned when the number of atoms is a multiple of 3"""
        if type(atoms) is types.StringType:
            self.nodeLogString = "'" + atoms + "'"
        ats = self.vf.expandNodes(atoms)
        if not len(ats): return 'ERROR'
        return apply(self.doitWrapper, (ats, ), kw)

    def doit(self, ats):
        for at in ats:
            lenAts = len(self.atomList)
            if lenAts and lenAts % 3 != 0 and at == self.atomList[-1]:
                continue
            self.atomList.append(at)
            l = len(self.atomList)
            #for this command, reset after every 3
            #wrap when len(atoms)=3*self.snakeLength+1
            if l > 3 * self.snakeLength:
                self.atomList = self.atomList[3:]
            self.update()
        if len(self.labelStrs) and len(self.atomList) % 3 == 0:
            return float(self.labelStrs[-1])

    def update(self, forward=1, event=None):
        if not len(self.atomList):
            self.spheres.Set(vertices=[])
            #self.spheres.Set(vertices=[], tagModified=False)
            self.labels.Set(vertices=[])
            #self.labels.Set(vertices=[], tagModified=False)
            self.lines.Set(vertices=[])
            #self.lines.Set(vertices=[], tagModified=False)
            self.vf.GUI.VIEWER.Redraw()
            return
        limit = self.snakeLength
        #each time have to recalculate lineVertices
        self.lineVertices = []
        for at in self.atomList:
            c1 = self.getTransformedCoords(at)
            self.lineVertices.append(tuple(c1))

        #display spheres:
        if len(self.lineVertices) % 3:
            self.spheres.Set(
                vertices=self.lineVertices[-(len(self.lineVertices) % 3):])
        else:
            self.spheres.Set(vertices=[])

        #self.spheres.Set(vertices=self.lineVertices, tagModified=False)
        self.vf.GUI.VIEWER.Redraw()
        #label with angle
        #lines between spheres are only drawn when angle completed
        #that is, len(ats)%3=0
        if len(self.lineVertices) < 3:
            self.labels.Set(vertices=[])
            #self.labels.Set(vertices=[], tagModified=False)
            self.fan.Set(vertices=[])
            #self.fan.Set(vertices=[], tagModified=False)
            self.lines.Set(vertices=[])
            #self.lines.Set(vertices=[], tagModified=False)
        else:
            #should all of these be reset?
            self.arcNormals = []
            self.arcVectors = []
            self.arcCenters = []
            self.labelCenters = []
            self.labelStrs = []
            #rebuild arcNormals, arcVectors, arcCenters
            #labelCenters, labelStrs,
            #this gets done lenATs/3 times
            numItems = len(self.atomList) / 3
            for i in range(numItems):
                at0 = self.atomList[i * 3]
                at1 = self.atomList[i * 3 + 1]
                at2 = self.atomList[i * 3 + 2]
                ang = self.vf.measureAngle(at0, at1, at2, topCommand=0)
                v, n = self.normal(at0, at1, at2)
                self.arcNormals.append(n)
                #self.arcNormals = self.arcNormals[-limit:]
                self.arcVectors.append(v)
                #self.arcVectors = self.arcVectors[-limit:]
                self.arcCenters.append(self.getTransformedCoords(at1))
                #self.arcCenters = self.arcCenters[-limit:]
                angLabel = '%.3f' % ang
                self.labelStrs.append(angLabel)
                c0 = self.getTransformedCoords(at0)
                c1 = self.getTransformedCoords(at2)
                newcenter = tuple((c0 + c1) / 2.0)
                self.labelCenters.append(newcenter)
            #to reset labels, lines and fan, EACH TIME
            self.labels.Set(vertices=self.labelCenters, labels=self.labelStrs)
            #tagModified=False)
            faces = range(numItems * 3)
            faces = Numeric.reshape(faces, (-1, 3))
            self.lines.Set(vertices=self.lineVertices,
                           type=GL.GL_LINE_STRIP,
                           faces=faces,
                           freshape=1)
            #faces=faces, freshape=1, tagModified=False)
            self.fan.angles = map(float, self.labelStrs)
            self.fan.vectors = self.arcVectors
            self.fan.Set(vertices=self.arcCenters, vnormals=self.arcNormals)
            #tagModified=False)

    def normal(self, at0, at1, at2):
        c0 = self.getTransformedCoords(at0)
        c1 = self.getTransformedCoords(at1)
        c2 = self.getTransformedCoords(at2)
        v1 = c1 - c0
        v2 = c1 - c2
        l1 = math.sqrt(Numeric.sum(v1 * v1))
        l2 = math.sqrt(Numeric.sum(v2 * v2))
        #FIXME
        #protect against divide by 0
        n = self.vvmult(v1 / l1, v2 / l2)
        n = n / math.sqrt(Numeric.sum(n * n))
        return -v2 / l2, n.astype('f')
コード例 #7
0
class MeasureDistanceGUICommand(MeasureGUICommand):
    """
    This command measures distance between atoms.
    Lines are drawn between pairs of consecutively picked atoms and labels
    are display showing the distance.

   \nPackage : Pmv
   \nModule  : measureCommands
   \nClass   : MeasureDistanceGUICommand
   \nCommand : measureDistanceGC
   \nSynopsis:\n
        distance/None<---measureDistanceGC(atoms)
   \nRequired Argument:\n        
           atoms --- atom(s)
    """
    def __init__(self, func=None):
        MeasureGUICommand.__init__(self, func=func)
        self.flag = self.flag | self.objArgOnly

    def guiCallback(self, event=None):
        MeasureGUICommand.guiCallback(self, event)
        self.vf.setICOM(self.vf.measureDistGUI,
                        modifier='Control_L',
                        topCommand=0)

    def onAddCmdToViewer(self):
        if not self.vf.commands.has_key('setICOM'):
            self.vf.loadCommand('interactiveCommands',
                                'setICOM',
                                'Pmv',
                                topCommand=0)
        if not self.vf.commands.has_key('measureDistance'):
            self.vf.loadCommand('measureCommands',
                                'measureDistance',
                                'Pmv',
                                topCommand=0)

        self.masterGeom = Geom('measureDistGeom', shape=(0, 0), pickable=0)
        self.masterGeom.isScalable = 0

        if self.vf.hasGui:
            measure_geoms = check_measure_geoms(self.vf.GUI)
            self.vf.GUI.VIEWER.AddObject(self.masterGeom, parent=measure_geoms)

        self.lines = IndexedPolylines('distLine',
                                      materials=((1, 1, 0), ),
                                      inheritMaterial=0,
                                      lineWidth=3.,
                                      stippleLines=1,
                                      pickable=0)
        self.labels = GlfLabels(name='distLabel',
                                shape=(0, 3),
                                font='arial1.glf',
                                fontStyle='solid3d',
                                fontScales=(.5, .5, .3),
                                inheritMaterial=0,
                                materials=((1, 1, 0), ))
        self.spheres = Spheres(name='distSpheres',
                               shape=(0, 3),
                               inheritMaterial=0,
                               radii=0.2,
                               quality=15,
                               materials=((1., 1., 0.), ))
        if self.vf.hasGui:
            for item in [self.lines, self.labels, self.spheres]:
                self.vf.GUI.VIEWER.AddObject(item, parent=self.masterGeom)

    def __call__(self, atoms, **kw):
        """distance/None<---measureDistanceGC(atoms)
        \natoms --- atom(s)"""
        if type(atoms) is types.StringType:
            self.nodeLogString = "'" + atoms + "'"
        ats = self.vf.expandNodes(atoms)
        if not len(ats): return 'ERROR'
        return self.doitWrapper(*(ats, ), **kw)

    def doit(self, ats):
        for at in ats:
            lenAts = len(self.atomList)
            if lenAts and at == self.atomList[-1]:
                continue
            self.atomList.append(at)
            self.update()
        if len(self.labelStrs):
            return float(self.labelStrs[-1])

    def update(self, forward=1, event=None):
        if not len(self.atomList):
            self.spheres.Set(vertices=[])
            #self.spheres.Set(vertices=[], tagModified=False)
            self.labels.Set(vertices=[])
            #self.labels.Set(vertices=[], tagModified=False)
            self.lines.Set(vertices=[])
            #self.lines.Set(vertices=[], tagModified=False)
            return
        self.lineVertices = []
        #each time have to recalculate lineVertices
        for at in self.atomList:
            c1 = self.getTransformedCoords(at)
            self.lineVertices.append(tuple(c1))

        if len(self.lineVertices) % 2:
            self.spheres.Set(vertices=[self.lineVertices[-1]])
        else:
            self.spheres.Set(vertices=[])

        #self.spheres.Set(vertices=self.lineVertices, tagModified=False)
        #setting spheres doesn't trigger redraw so do it explicitly
        self.vf.GUI.VIEWER.Redraw()
        #each time have to recalculate labelCenters and labelStrs
        if len(self.lineVertices) > 1:
            self.labelCenters = []
            self.labelStrs = []
            self.faces = []
            numLabels = len(self.lineVertices) - 1
            for i in range(0, numLabels, 2):
                c0 = Numeric.array(self.lineVertices[i])
                c1 = Numeric.array(self.lineVertices[i + 1])
                newCenter = tuple((c1 + c0) / 2.0)
                self.labelCenters.append(newCenter)
                at1 = self.atomList[i]
                at2 = self.atomList[i + 1]
                d = self.vf.measureDistance(at1, at2, topCommand=0)
                dLabel = '%.3f' % d
                self.labelStrs.append(dLabel)
                self.faces.append([i, i + 1])
            #correct length of labels here
            self.labels.Set(vertices=self.labelCenters, labels=self.labelStrs)
            #tagModified=False)
            self.lines.Set(vertices=self.lineVertices,
                           type=GL.GL_LINE_STRIP,
                           faces=self.faces,
                           freshape=1)
            #tagModified=False)

        elif len(self.lineVertices) == 1 and len(self.labelCenters) == 1:
            #this fixes case of stepping back over 1st label
            self.labels.Set(vertices=[])
            #self.labels.Set(vertices=[], tagModified=False)
            self.lines.Set(vertices=[])
コード例 #8
0
class SuperImposeAtomsGUICommand(MVCommand, MVAtomICOM):
    """
    The SuperImposeAtomsGUICommand provides a GUI interface to the  SuperImposeAtomsCommand.
    - For now Only two 2 sets of Atoms belonging to a ref molecule and a mobile molecule
    can be superimposed simultaneously.

    - The command provides two way of defining those two sets of atoms:
    
      * By picking nodes at the different levels (Molecule, Chain, Residue, Atom) the first pick
      will define the reference set and the second the mobile set. The picking process will have
      be done later on the same way and defines a list of pairs of atoms.
      If the user drags a box only the first node will be considered. Nodes are then converted into
      an set of Atoms. The 'Edit Atoms Pairs' allows the user to see the pairs but also to alter those
      sets. For example only the backbone atoms can be considered or all atoms etc. The user can also
      create his own filter by typing a lambda function in the entry of the combobox.
      If the 2 sets are not of the same length the extra atoms can be removed either from the beginning,
      the end or half and half of the longest set allowing a bit more flexibility.
      If the resulting 2 sets are None then the superimposition cannot be computed. You can reset the
      process and start over or alter your set using the tools described above.

      * By string: If the user knows the set of nodes of respectively the reference molecule and mobile
      molecule to be use for the computation two string selector widgets allows him to proceed more
      efficiently.

    - Known bug:
      * If the reference molecule is transformed independently of the mobile molecule the mobile
      molecule will be superimposed onto the original location of the reference molecule. (Working on it)
      * Cannot superimpose simultaneously multiple sets of molecule.
      * And probably many more ....
    """
    
    def __init__(self, func=None):
        MVCommand.__init__(self, func)
        MVAtomICOM.__init__(self)
        self.refAtomList = []
        self.inAtomList = []
        #self.superImposedPairs = {}
        self.newPairs = {}
        self.pair = []
        self.mobMolName = None
        self.refMolName = None
        self.filters = {'CA Atoms':lambda x: x.name == 'CA',
                        'Backbone Atoms': lambda x: x.name in ['CA', 'C',
                                                               'N', 'O',
                                                               'CA@A','C@A',
                                                               'N@A','O@A'],
                        'Heavy Atoms': lambda x: not x.element == 'H',
                        'All Atoms': None}
        self.defaultFilter = 'Backbone Atoms'


    def onAddCmdToViewer(self):
        # Check first is any of the command that superimpose depends on are
        # already loaded.
        if not self.vf.commands.has_key('setICOM'):
            self.vf.loadCommand('interactiveCommands', 'setICOM', 'Pmv',
                                topCommand = 0)
        if not self.vf.commands.has_key('superimposeAtoms'):
            self.vf.loadCommand('superImposeCommands', 'superimposeAtoms',
                                'Pmv', topCommand = 0)
            
        if not self.vf.commands.has_key('startContinuousPicking'):
            self.vf.loadCommand('dejaVuCommands','startContinuousPicking',
                                'ViewerFramework', topCommand = 0)

        if not self.vf.commands.has_key('stopContinuousPicking'):
            self.vf.loadCommand('dejaVuCommands','stopContinuousPicking',
                                'ViewerFramework', topCommand = 0)
        if not self.vf.commands.has_key('labelByExpression'):
            self.vf.loadCommand('labelCommands', 'labelByExpression', 'Pmv',
                                topCommand = 0)

        self.sphere1 = Spheres(name='elt1', radii=0.5,
                               materials = ( (0.,1.,0.),), protected=True)
        self.sphere2 = Spheres(name = 'elt2', radii=0.5, 
                               materials = ( (1.,1.,0.),), protected=True)

        #self.form = None

    def onRemoveObjectFromViewer(self,obj):
        if hasattr(self.vf,'alignment'):
            self.vf.alnEditor.deleteSequence(obj.name)
            self.vf.alnEditor.redraw()
        if obj.name == self.refMolName:
            self.refMolName=None
        if obj.name == self.mobMolName:
            self.mobMolName=None
            
    def guiCallback(self):
        self.vf.setICOM(self, modifier="Shift_L",  topCommand=0)

    def buildFormDescr(self, formName):
        if formName == 'superimpose':
            idf = InputFormDescr(title="Set Superimposition Parameters")

            idf.append( {'widgetType':Tkinter.Label,
                         'wcfg': {'text':'Get Nodes:'},
                         'gridcfg':{'sticky':'w'}})

            self.typeVar = Tkinter.StringVar()
            self.typeVar.set('By Picking')

            idf.append( {'widgetType':Tkinter.Radiobutton,
                         'name': 'string',
                         'wcfg':{'variable':self.typeVar,
                                 'text': 'From String',
                                 'value':'From String',
                                 'command':self.string_cb,
                                 },
                         'gridcfg':{'sticky':'w', 'columnspan':3}})

            idf.append( {'widgetType':Tkinter.Radiobutton,
                         'name': 'string',
                         'wcfg':{'variable':self.typeVar,
                                 'text': 'From Alignment',
                                 'value':'From Alignment',
                                 'command':self.alignment_cb,
                                 },
                         'gridcfg':{'sticky':'w', 'columnspan':3}})

            idf.append( {'widgetType':Tkinter.Radiobutton,
                         'name': 'refPicking',
                         'wcfg':{'variable':self.typeVar,
                                 'text': 'By Picking',
                                 'value':'By Picking',
                                 },
                         'gridcfg':{'sticky':'w'} })

            idf.append( {'widgetType':Tkinter.Label,
                         'wcfg': {'text':'Reference nodes:'},
                         'gridcfg':{'sticky':'w'}})

            idf.append( {'widgetType':Tkinter.Label,
                         'wcfg': {'text':'Mobile nodes:'},
                         'gridcfg':{'sticky':'e', 'row':-1}})


            idf.append({'widgetType':Tkinter.Label,
                        'name':'firstNode',
                        'wcfg':{ 'text':''},
                        'gridcfg':{'sticky':'we'}})

            idf.append({'widgetType': Tkinter.Label,
                        'name':'secondNode',
                        'wcfg':{ 'text':''},
                        'gridcfg':{'sticky':'we', 'row':-1}})

            idf.append({'widgetType':Tkinter.Button,
                        'name':'editPairs',
                        'wcfg':{'text':'Edit Ref Atom -- Mob Atom Pairs',
                                'command':self.editPairs_cb,},
                        'gridcfg':{'sticky':'we','columnspan':3}
                        })

            # Continuous Superimposition
            idf.append({'widgetType':Tkinter.Checkbutton,
                        'name':'continuous',
                        'wcfg':{'variable':Tkinter.IntVar(),
                                'text':'Continuous Superimposition',
                                'command':self.continuous_cb,
                                'padx':10,'pady':10},
                        'gridcfg':{'sticky':'w'}})

            # Reset & SuperImpose button.
            idf.append({'widgetType':Tkinter.Button,
                        'name':'final',
                        'wcfg':{'width':15,'text':'Superimpose',
                                'command':self.superimpose_cb},
                        'gridcfg':{'sticky':'we', 'row':-1}})

            idf.append({'widgetType':Tkinter.Button,
                        'name':'reset',
                        'wcfg':{'text':'Reset', 'command':self.reset_cb},
                        'gridcfg':{'sticky':'we', 'row':-1}})

        elif formName == 'editPair':
            idf = InputFormDescr(title='Edit Reference Atom - Mobile Atom Pairs')
            idf.append({'widgetType':Pmw.ComboBox,
                        'name':'choice',
                        'defaultValue':self.defaultFilter,
                        'wcfg':
                        {'label_text':'Atoms to be consider for superimposition:',
                         'labelpos':'n','label_padx':10,'label_pady':10,
                         'scrolledlist_items': self.filters.keys(),
                         'selectioncommand':self.setDefault},
                        'gridcfg':{'sticky':'w'}})
        
            # If sets not of the same length:
            idf.append({'widgetType':Pmw.ComboBox,
                        'name':'slice',
                        'defaultValue':'Beginning',
                        'wcfg':
                        {'label_text':'Sets not of the same length',
                         'labelpos':'n','label_padx':10,'label_pady':10,
                         'scrolledlist_items':['Beginning',
                                               'End',
                                               'Half/Half']
                         },
                        'gridcfg':{'sticky':'w', 'row':-1}})
            
            entries = map(lambda x: (x, None), self.newPairs.keys())
            idf.append({'widgetType':ListChooser,
                        'name':'newpairs',
                        'wcfg':{'mode':'extended',
                                'entries':entries,
                                'lbwcfg':{'exportselection':1},
                                'title':'Reference Atoms    --    Mobile Atoms'},
                        'gridcfg':{'sticky':'wens', 'columnspan':2}})
            

            idf.append({'widgetType':Tkinter.Button,
                        'name': 'delete',
                        'wcfg':{'width':15,'text': 'Delete Pairs',
                                'command':self.delete_cb},
                        'gridcfg':{'sticky':'we', 'columnspan':2}})
            
            idf.append({'widgetType':Tkinter.Button,
                        'name': 'dismiss',
                        'wcfg':{'text': 'DISMISS',
                                'command':self.dismiss_cb},
                        'gridcfg':{'sticky':'we', 'columnspan':2}})


        elif formName == 'editString':
            idf = InputFormDescr(title = 'Get Nodes From String')
            idf.append({'widgetType':Tkinter.Label,
                        'wcfg':{'text':'Reference Nodes: '},
                        'gridcfg':{'sticky':'w'}})

            idf.append({'widgetType':Tkinter.Label,
                        'wcfg':{'text':'Mobile Nodes: '},
                        'gridcfg':{'sticky':'w', 'row':-1}})

            idf.append({'widgetType':Tkinter.Label,
                        'wcfg':{'text':' '},
                        'gridcfg':{'columnspan':2, 'sticky':'w'}})

            idf.append({ 'widgetType':StringSelectorGUI,
                         'name':'refNodes','required':1,
                         'wcfg':{ 'molSet': self.vf.Mols,
                                  'vf': self.vf,
                                  'all':1,
                                  'crColor':(1.,0.,0.),
                                  },
                         'gridcfg':{'sticky':'we' }})

            idf.append({ 'widgetType':StringSelectorGUI,
                         'name':'mobNodes','required':1,
                         'wcfg':{ 'molSet': self.vf.Mols,
                                  'vf': self.vf,
                                  'all':1,
                                  'crColor':(0.,0.,1.),
                                  },
                         'gridcfg':{'row':-1, 'sticky':'we' }})

        return idf
    
    def initICOM(self, modifier):
        # Create the form if not existing yet
        form = self.showForm(formName = 'superimpose', modal=0, blocking=0)
        self.firstLabel = form.descr.entryByName['firstNode']['widget']
        self.secondLabel = form.descr.entryByName['secondNode']['widget']

        self.contVar = form.descr.entryByName['continuous']['wcfg']['variable']
        self.pairForm = None

        # set the callback of continuousPicking to label the picked node
        # 1- get a handle on the cbManager
        cbManager  = self.vf.startContinuousPicking.cbManager
        # 2- Save the existing callbacks
        self.oldCallBacks = cbManager.callbacks
        # 3- Set to the new callback
        cbManager.SetCallback(CallBackFunction(self.labelByName))
        
        self.vf.startContinuousPicking()
        self.supcb = 0


    def setDefault(self, text):
        self.defaultFilter = text
        if hasattr(self, 'pair') and len(self.pair) == 2:
            filter = self.filters[text]
            set1 = self.pair[0]
            set2 = self.pair[1]
            
            if filter:
                set1 = set1.get(filter)
                set2 = set2.get(filter)
            if (set1 and set2) and (len(set1) == len(set2)):
                self.updateChooser(set1, set2)
            
    def editPairs_cb(self, event=None):
        pairForm = self.showForm('editPair', force = 1, modal=0, blocking=0,
                                 onDestroy= self.dismiss_cb)
        # show panel with the listchooser of the panel and 
        # Choose the atoms to do the superimposition
        
        self.chooser = pairForm.descr.entryByName['newpairs']['widget']

    def dismiss_cb(self, event=None):
        if self.cmdForms.has_key('editPair'):
            self.cmdForms['editPair'].destroy()
            del self.cmdForms['editPair']

    def string_cb(self, event=None):
        #get rid of the alignment GUI
        if hasattr(self.vf,'alnEditor'):
            self.vf.alnEditor.exit()
        val = self.showForm('editString')
        print val
        if not val == {} or (val.has_key('refNodes') and val.has_key('mobNodes')):
            apply(self.doitWrapper, (val['refNodes'],), {'log':0})
            apply(self.doitWrapper, (val['mobNodes'],), {'log':0})
            self.typeVar.set('By Picking')


    def continuous_cb(self, event=None):
        #get rid of the alignment GUI
        if hasattr(self.vf,'alnEditor'):
            self.vf.alnEditor.exit()
        form = self.cmdForms['superimpose']
        supButton = form.descr.entryByName['final']['widget']
        if self.contVar.get() == 1:
            supButton.configure(state=Tkinter.DISABLED)
            if len(self.newPairs)>=4:
                self.superimpose_cb()
        else:
            supButton.configure(state=Tkinter.NORMAL)


    def labelByName(self, pick):
        # Continuous labeling.
        if pick is None: return
        atom = self.vf.findPickedAtoms(pick)
        if atom:
            level = self.vf.ICmdCaller.level.value
            self.vf.ICmdCaller.level.AddCallback(self.unlabelLevel)
            if level == Molecule : level = Protein
            self.node = atom.findType(level)
            funcItems = map(lambda x: x.full_name(), self.node)
            self.vf.labelByExpression(self.node,
                                      font = 'arial1.glf',
                                      location = 'First', 
                                      textcolor = 'red', only = 1,
                                      lambdaFunc = 1,negate=0,
                                      function = 'lambda x: str(x.full_name())\n\n',
                                      topCommand=0,
                                      )
            
    def unlabelLevel(self, newLevel, oldLevel):
        if not hasattr(self, 'node'): return

        if oldLevel == Molecule: oldLevel = Protein
        # need to be at the former level for all the former picked stuff
        # so take it all.
        node = self.vf.getSelection()
        nodes = node.findType(oldLevel)
        # Careful in labelByProperty fix a bug if no label should not break! 
        self.vf.labelByExpression(nodes, negate=1, log=0)
        
    def stopICOM(self):
        # Destroy the inputForm
        self.cmdForms['superimpose'].root.destroy()
        # Set the form to None.
        del self.cmdForms['superimpose']

        # Set back the continuousPicking to unsolicitedPick
        cbManager  = self.vf.startContinuousPicking.cbManager
        if not len(self.oldCallBacks) == 0:
            cbManager.SetCallback(self.oldCallBacks[0])
            if len(self.oldCallBacks)>1:
                for cb in self.oldCallBacks[1:]:
                    cbManager.AddCallBack(cb)

        # Remove the unlabel callback bound to the self.vf.ICmdCaller.level
        if self.unlabelLevel in  self.vf.ICmdCaller.level.callbacks:
            self.vf.ICmdCaller.level.RemoveCallback(self.unlabelLevel)

        # Unlabel whatever is labeled
        level = self.vf.ICmdCaller.level.value
        
        nodes = self.vf.getSelection().findType(level)
        if not nodes is None or len(nodes)!=0:
            self.vf.labelByExpression(nodes, negate=1, log=0)

        # Stop the continuous picking.
        self.vf.stopContinuousPicking()

        self.sphere1.Set(vertices=[], tagModified=False)
        self.sphere2.Set(vertices=[], tagModified=False)
##         self.visualFeedBack(vertices =[])


    def updateChooser(self, set1, set2):
        for elt1, elt2 in map(None, set1, set2):
            key = elt1.full_name() + '--' + elt2.full_name()
            self.newPairs[key] = (elt1, elt2)
            if not self.pairForm is None:
                entry = (key, None)
                self.chooser.add(entry)
        
    
    def reset_cb(self, event=None):
        """Button to reset the superimposition and the list of pairs."""
        # Reset the chooser and the lists of pairs
        if self.newPairs == {}: return 
        if not self.pairForm is None:
            self.chooser.clear()
        self.newPairs = {}
        # Reset the geometry.
        vi = self.vf.GUI.VIEWER
        geom = self.mobileMol.geomContainer.masterGeom
        oldCurrent = vi.currentObject
        vi.SetCurrentObject(geom)
        # transform only the given geometry.
        if vi.redirectTransformToRoot == 1:
            old = vi.redirectTransformToRoot
            vi.TransformRootOnly(0)
        else:
            old = 0
        # Right now reset all the transformations applied to the mobile object.
        # Maybe should separate from the superimposition and only reset these.
        vi.ResetCurrentObject()
        # Put everything back like it was before.
        if old == 1:
            vi.TransformRootOnly(1)
        vi.SetCurrentObject(oldCurrent)
        
        self.sphere1.Set(vertices=[], tagModified=False)
        self.sphere2.Set(vertices=[], tagModified=False)
        self.firstLabel.configure(text='')
        self.secondLabel.configure(text='')
        
##         self.visualFeedBack.Set(vertices=[], tagModified=False)

        
    def delete_cb(self, event = None):
        # Delete the selected pair from the listchooser and from the pairlist
        selectedNewPairs = self.chooser.get()
        # Undisplay the label (Maybe only if the last pair is being deleted )
        self.firstLabel.configure(text='')
        self.secondLabel.configure(text='')
        for pair in selectedNewPairs:
            if len(self.chooser.entries) >=4:
                self.chooser.remove(pair)
                del self.newPairs[pair]
                if self.contVar.get()==1 or self.supcb==1:
                    self.superimpose_cb()

    def superimpose_cb(self, event=None):
        if len(self.newPairs) >= 4 :
            # Need at least 4 pairs of atoms to do the superimposition
            setAtm1 = AtomSet(map(lambda x: x[0],
                                  self.newPairs.values()))
            setAtm2 = AtomSet(map(lambda x: x[1],
                                  self.newPairs.values()))
            if len(setAtm1) != len(setAtm2):
                message = ' ERROR: the 2 sets of atoms are not of the length\nthe superimposition cannot be performed. ' 
                self.warningMsg(msg)
                return

            self.vf.superimposeAtoms(setAtm1, setAtm2)
            self.supcb = 1
##             self.visualFeedBack.Set(vertices=self.visualVertices,
##                                     tagModified=False)

    def __call__(self, atoms, **kw):
        ats = self.vf.expandNodes(atoms)
        if not len(ats): return 'ERROR'
        kw['redraw']=1
        kw['log']=0
        return apply(self.doitWrapper, (ats,), kw)
        

    def doit(self, nodes):
        """
        Create the 2 sets of atom that will be used to do the superimposition.
        Then call the superImposeCommand with these 2 sets.
        If continuous is on then the superimposition will be updated each time
        a pair of atoms is added otherwise the superimposition will be updated
        every 4 pairs of atoms.
        """

        # Get the ICOM level
        icomLevel = self.vf.ICmdCaller.level.value
        # Not doing anything if no nodes picked:
        if not nodes: return

        if self.typeVar.get() == 'By Picking':
            # only take the first node picked.
            node = nodes[0]
            nodeMol = node.top

        elif self.typeVar.get() == 'From String':
            node = nodes
            molecules = nodes.top.uniq()
            if len(molecules)>1:
                # nodes need to belong to only one molecule
                return
            else: nodeMol = molecules[0]
        
        elif self.typeVar.get() == 'From Alignment':
            node = nodes
            molecules = nodes.top.uniq()
            if len(molecules)>1:
                # nodes need to belong to only one molecule
                return
            else: nodeMol = molecules[0]
        
        # 2- Get the atoms from the chosen nodes
        atms = node.findType(Atom)

        # First set of nodes == defines the first set of 1st elt in the pairs
        if len(self.pair) == 0 :
            self.secondLabel.configure(text ='')
            # Defines reference molecule:
            if self.newPairs == {}:
                self.refMol = nodeMol
                # Draw the feedBack sphere.
                mGeom = self.refMol.geomContainer.masterGeom
                self.vf.GUI.VIEWER.AddObject(self.sphere1, parent = mGeom)

            if nodeMol != self.refMol:
                self.firstLabel.configure(text ='')
                # if the node belongs to the another molecule return.
                # The pairs are defined allways in the same order.
                return

            self.pair.append(atms)
            #self.pair.append(node)
            if self.typeVar.get() == 'By Picking':
                self.firstLabel.configure(text=node.full_name())

        elif len(self.pair) == 1 :
            # Creates Second set of elt in the pair.
            if self.newPairs=={}:
                if nodeMol != self.refMol:
                    # set the mobile molecule and finish the first pair
                    self.mobileMol = nodeMol
                    mGeom = self.mobileMol.geomContainer.masterGeom
                    self.vf.GUI.VIEWER.AddObject(self.sphere2,
                                                 parent = mGeom)

            if nodeMol != self.mobileMol:
                return
            self.pair.append(atms)
            #self.pair.append(node)
            if self.typeVar.get() == 'By Picking':
                self.secondLabel.configure(text=node.full_name())

            # Now we have the two set of elts to create pairs:
            # 1- Check if the 2 sets have the same length:
            set1 = self.pair[0]
            set1.sort()
            set2 = self.pair[1]
            set2.sort()
            if not set1 or not set2:
                print "ERROR: One of the sets is None"
                return
            elif len(set1) != len(set2):
                if node.__class__ == Atom:
                    print 'ERROR: the 2 sets of atoms are not of the same size'
                    return

            set1,set2
            if node.__class__ in [Protein,ProteinSet, Residue, ResidueSet,  Chain, ChainSet]:
                filter = self.defaultFilter
                if self.filters.has_key(filter):
                    set1 = self.pair[0].get(self.filters[filter])
                    set2 = self.pair[1].get(self.filters[filter])
                if not set1 or not set2:
                    print 'ERROR: cannot compute the superimposition'
                    print 'not set1 or not set2'
                    return
                
                elif len(set1) != len(set2):
                    print 'ERROR: cannot compute the superimposition'
                    print 'len(set1) != len(set2)'
                    return

            #print 'set1', set1
            #print 'set2', set2
            self.updateChooser(set1, set2)
            self.pair = []

        if len(self.newPairs)>=4 and self.contVar.get() == 1:
            # Continuous picking is on and superimposition can be done if
            # there are more than 4 pairs.
            self.superimpose_cb()
            
    def alignment_cb(self, event=None):
        if not hasattr(self.vf,'alignment'):
            self.vf.alignment = Alignment()
        if not hasattr(self.vf,'alnEditor'):
            self.vf.alnEditor = PmvAlignmentEditor(vf=self.vf)
            self.vf.alnEditor.alignment = self.vf.alignment
        else:
            self.vf.alnEditor.redraw()
            self.vf.alnEditor.master.deiconify()
        for mol in self.vf.Mols:
            if mol.name not in self.vf.alignment.seqNames:
                self.vf.alnEditor.getSequence(mol)
コード例 #9
0
ファイル: povray3.py プロジェクト: lisarosalina/App
                else:
                    r1 = r2 = radii[0] / 2.

                self.entries.append('\t%s, %f, %s, %f\n' % (self.coord3(
                    v[f[i][j]]), r1, self.coord3(v[f[i][j + 1]]), r2))

                if fp:
                    col = c[f[i][j]][:3]
                else:
                    col = (1., 1., 1.)
                self.entries.append(
                    "\tpigment { color rgb<%6.3f, %6.3f, %6.3f> }\n" %
                    tuple(col))
                self.entries.append(
                    "\tfinish { specular 1 roughness 0.001 ambient 0.3 }\n")
                self.endShape()

if __name__ == '__main__':
    from DejaVu import Viewer
    vi = Viewer()
    from DejaVu.Spheres import Spheres
    s = Spheres('test', centers=((0.0, 0., 0.), (3., 0., 0.)))
    s.Set(quality=4)
    vi.AddObject(s)
    from DejaVu.povray3 import PovRay
    p = PovRay()
    p.addCamera(vi.cameras[0])
    p.addLight(vi.lights[0])
    p.addGeom(s)
    p.write('test.pov')
コード例 #10
0
ファイル: gelato.py プロジェクト: lisarosalina/App
                if fp:
                    col = c[f[i][j]][:3]
                    alpha = c[f[i][j]][3]
                else:
                    col = (1., 1., 1.)
                    alpha = 1.0
                self.entries.append(
                    self.addOneCylinder(v[f[i][j]], v[f[i][j + 1]], col))
                self.entries.append(
                    self.addOneCylinder(v[f[i][j + 1]], v[f[i][j]], col))
                #self.entries.append("\tpigment { color rgb<%6.3f, %6.3f, %6.3f> }\n"% tuple(col))
                #self.entries.append("\tfinish { specular 1 roughness 0.001 ambient 0.3 }\n")
                #self.endShape()


#########From blendergelato.py#############################

if __name__ == '__main__':
    from DejaVu import Viewer
    vi = Viewer()
    from DejaVu.Spheres import Spheres
    s = Spheres('test', centers=((0.0, 0., 0.), (3., 0., 0.)))
    s.Set(quality=15)
    vi.AddObject(s)
    from DejaVu.povray3 import PovRay
    p = PovRay()
    p.addCamera(vi.cameras[0])
    p.addLight(vi.lights[0])
    p.addGeom(s)
    p.write('test.pov')