Пример #1
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)
Пример #2
0
    def onAddObjectToViewer(self, obj):
        #print "LabelByProperties.onAddObjectToViewer", self.name
        #if not self.vf.hasGui:
        #    return
        #from DejaVu.Labels import Labels
        geomC = obj.geomContainer
        classNames = ['Atom','Residue','Chain','Protein']
        self.level = self.nameDict[self.vf.selectionLevel]
        #for item in classNames:
        for i in range(len(classNames)):
            item = classNames[i]
            #geomName = eval("'%sLabels'" %item)
            geomName = '%sLabels'%item
            for atm in obj.allAtoms:
                atm.colors[geomName] = (1.0, 1.0, 1.0)
                atm.opacities[geomName] = 1.0
            if not geomC.atoms.has_key(geomName):
                # DON'T KNOW HOW TO REPLACE THIS EVAL
                geomC.atoms[geomName]=eval("%sSet()" %item)
                geomC.atomPropToVertices[geomName] = self.atomPropToVertices

            if not geomC.geoms.has_key(geomName):
                j = i + 1
                g = GlfLabels(geomName, fontStyle='solid3d',
                      #inheritMaterial=0,
                      fontTranslation=(0,0,3.), # so the label is less hidden by the structure
                      fontScales=(j*.3,j*.3, .1), # different size for atom, res, chain, mol
                      visible=0,
                      pickable=0,
                     )
                geomC.addGeom(g, parent=geomC.masterGeom,redo=0)
                g.applyStrokes()
            else:
                g = None
                if self.vf.hasGui:
                    g = geomC.VIEWER.FindObjectByName(geomC.masterGeom.fullName+'|'+geomName)
            if g not in self.managedGeometries:
                self.managedGeometries.append(g)
Пример #3
0
    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'
Пример #4
0
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)
Пример #5
0
    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
Пример #6
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()
Пример #7
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')
Пример #8
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=[])