def _getNormal(self,b): at1 = b.next1 at2 = b.atom1 at3 = b.atom2 pt1 = at1.coords pt2 = at2.coords pt3 = at3.coords a = Numeric.subtract(pt2,pt1) b = Numeric.subtract(pt3,pt2) p = (a[1]*b[2]-a[2]*b[1],a[2]*b[0]-a[0]*b[2],a[0]*b[1]-a[1]*b[0]) nrmsize = Numeric.sqrt(p[0]*p[0]+p[1]*p[1]+p[2]*p[2]) return (nrmsize, p)
def _getNormal(self, b): at1 = b.next1 at2 = b.atom1 at3 = b.atom2 pt1 = at1.coords pt2 = at2.coords pt3 = at3.coords a = Numeric.subtract(pt2, pt1) b = Numeric.subtract(pt3, pt2) p = (a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]) nrmsize = Numeric.sqrt(p[0] * p[0] + p[1] * p[1] + p[2] * p[2]) return (nrmsize, p)
def getVertsFromCornerPts(self, cornerPoints): # cornerPoints = (center-halfsides, center+halfsides) # cornerPoints = (pt0, pt1) x1,y1,z1=cornerPoints[1] x0,y0,z0=cornerPoints[0] self.xside = x1-x0 self.yside = y1-y0 self.zside = z1-z0 center = (x1-(x1-x0)/2., y1-(y1-y0)/2., z1-(z1-z0)/2.) self.center = center # maxCube sets box to cube with side = largest of x,y,z-side # min sets box to cube with side = smallest of x,y,z-side # maxCube has precedence over minCube if self.maxCube or self.minCube: if self.maxCube: side = max((x1-x0,y1-y0,z1-z0)) elif self.minCube: side = min((x1-x0,y1-y0,z1-z0)) self.xside = side self.yside = side self.zside = side pt1=tuple(Numeric.add(center,(side/2.,side/2,side/2))) pt0=tuple(Numeric.subtract(center,(side/2,side/2,side/2))) x1,y1,z1 = pt1 x0,y0,z0 = pt0 #built list of 8 pts ptList=((x1,y1,z0), (x0,y1,z0), (x0,y0,z0), (x1,y0,z0), (x1,y1,z1), (x0,y1,z1), (x0,y0,z1), (x1,y0,z1)) return ptList
def getVertsFromCornerPts(self, cornerPoints): # cornerPoints = (center-halfsides, center+halfsides) # cornerPoints = (pt0, pt1) x1, y1, z1 = cornerPoints[1] x0, y0, z0 = cornerPoints[0] self.xside = x1 - x0 self.yside = y1 - y0 self.zside = z1 - z0 center = (x1 - (x1 - x0) / 2., y1 - (y1 - y0) / 2., z1 - (z1 - z0) / 2.) self.center = center # maxCube sets box to cube with side = largest of x,y,z-side # min sets box to cube with side = smallest of x,y,z-side # maxCube has precedence over minCube if self.maxCube or self.minCube: if self.maxCube: side = max((x1 - x0, y1 - y0, z1 - z0)) elif self.minCube: side = min((x1 - x0, y1 - y0, z1 - z0)) self.xside = side self.yside = side self.zside = side pt1 = tuple(Numeric.add(center, (side / 2., side / 2, side / 2))) pt0 = tuple( Numeric.subtract(center, (side / 2, side / 2, side / 2))) x1, y1, z1 = pt1 x0, y0, z0 = pt0 #built list of 8 pts ptList = ((x1, y1, z0), (x0, y1, z0), (x0, y0, z0), (x1, y0, z0), (x1, y1, z1), (x0, y1, z1), (x0, y0, z1), (x1, y0, z1)) return ptList
def getVertsFromCenter(self, center): self.center = center halfSide = Numeric.multiply( Numeric.array((self.xside, self.yside, self.zside)), 0.5) pt1 = tuple(Numeric.add(center, halfSide)) pt0 = tuple(Numeric.subtract(center, halfSide)) return (pt0, pt1)
def select(self, bnds, cutoff=7.5): cutoffValue = math.cos(cutoff*math.pi/180.) #print "cutoffValue=", cutoffValue aromaticCs = AtomSet([]) atD = {} ctr = 1 aromaticBnds = BondSet() #taken from autotorsCommands ats = self.getAtoms(bnds) rf = RingFinder() rf.findRings2(ats, bnds) cyclecount = rf.ringCount aromatic_cycles = [] ct = 1 for ring in rf.rings: blist = ring['bonds'] for bnd in blist: at = bnd.atom1 #next find the other bond in this cycle with at as one of the atoms: z2 = filter(lambda x:x!=bnd and x.atom1==at or x.atom2==at, blist) bnd.nextbond = z2[0] neighbor = z2[0].atom1 if neighbor==at: neighbor = z2[0].atom2 bnd.next1 = neighbor #print "set ", bnd.atom1.name,'-', bnd.atom2.name,".next1 to ", neighbor.name #now each bond has 3 atoms specified for it: its own two and the next1 to atom1 at1 = bnd.next1 at2 = bnd.atom1 at3 = bnd.atom2 pt1 = at1.coords pt2 = at2.coords pt3 = at3.coords a1 = Numeric.subtract(pt2,pt1) b1 = Numeric.subtract(pt3,pt2) p = [a1[1]*b1[2]-a1[2]*b1[1],a1[2]*b1[0]-a1[0]*b1[2],a1[0]*b1[1]-a1[1]*b1[0]] result0 = Numeric.sqrt(p[0]*p[0]+p[1]*p[1]+p[2]*p[2]) bnd.nrmsize = result0 result1 = p bnd.nrms = result1 #next find the other bond w/atom2: z2 = filter(lambda x,bnd=bnd, at2=bnd.atom2, blist=blist:x!=bnd and x.atom1==at2 or x.atom2==at2, blist) #finally, return the other atom in this bond bnd.nextbond2 = z2[0] if bnd.nextbond2==bnd: bnd.nextbond2 = z2[1] #neighbor2 = self._getnxtAtom(b.atom2,b.nextbond2) neighbor2 = bnd.nextbond2.atom1 if neighbor2==bnd.atom2: neighbor2 = bnd.nextbond2.atom2 bnd.next2 = neighbor2 #next have to check whether the normals are parallel #check each pair in each bond, how to keep track?? #have to get normal at b's atom2: so have to get next2 for this bond: #have to loop twice to make sure neighbor has nrms for bnd in blist: p = bnd.nrms psize = bnd.nrmsize q = bnd.nextbond2.nrms qsize = bnd.nextbond2.nrmsize #theta is the critical test for planarity: #if angle between 2 nrms is 0, atoms are planar #NB>test is comparing theta,cos(angle), w/zero bnd.theta = Numeric.dot(p,q)/(psize*qsize) #NB: REPEAT STUFF FROM HERE TO THE END IF aromaticCutOff changes ct = 0 for bnd in blist: #these are values for the default 7.5degrees: #if theta>=0.997 or theta<=-0.997: #print bnd.atom1.name, '-', bnd.atom2.name, '->', bnd.theta if bnd.theta>=cutoffValue or bnd.theta<=-cutoffValue: bnd.posAromatic = 1 ct = ct + 1 else: bnd.posAromatic = 0 #print ' posAromatic=', bnd.posAromatic #after checking all the bonds in current cycle, compare #posAromatic w/number if ct==len(blist): #print ctr," cycle is aromatic" #NB: only C=C bonds are considered aromatic # could change the name and autodock_element here.... for bnd in blist: # THIS IS WRONG!!! #if bnd.atom1.element=='C' and bnd.atom2.element=='C': # aromaticBnds.append(bnd) aromaticBnds.append(bnd) ctr = ctr + 1 #print "len(aromaticBnds)=", len(aromaticBnds) #for b in aromaticBnds: # print b.atom1.name, '-', b.atom2.name return aromaticBnds
def __init__(self, name=None, check=1, **kw): self.maxCube = None self.minCube = None if not kw.get('origin') \ and not kw.get('center') \ and not kw.get('cornerPoints') \ and not kw.get('minCube'): kw['origin'] = (0, 0, 0) #set up some defaults: materials = kw.get('materials') #print 'in BOX materials kw=', materials if not materials: kw['materials'] = ((0,0,1),(0,1,0),(0,0,1),(0,1,0),(1,0,0),(1,0,0),) #print 'in BOX after test for materials, kwmaterials=', kw['materials'] vertices = kw.get('vertices') if vertices is not None: assert len(vertices)==8 pt1 = Numeric.array(vertices[2]) pt2 = Numeric.array(vertices[4]) self.center = tuple(Numeric.multiply(Numeric.add(pt1,pt2), 0.5)) self.xside, self.yside, self.zside = \ Numeric.subtract(pt2,pt1) else: #set up center center = kw.get('center') #if not center: center = (0.,0.,0.) self.center = center #set up sides side = kw.get('side') if side: self.xside = side self.yside = side self.zside = side else: xside = kw.get('xside') if not xside: xside = 1.0 self.xside = xside yside = kw.get('yside') if not yside: yside = 1.0 self.yside = yside zside = kw.get('zside') if not zside: zside = 1.0 self.zside = zside #NB faces shouldn't change self.faces=((0,3,2,1), (3,7,6,2), (7,4,5,6), (0,1,5,4), (1,2,6,5), (0,4,7,3)) self.funcs = {} fkeys = ['center', 'origin', 'centerOrigin', 'xside', \ 'yside', 'zside','maxCube', 'minCube'] fs = [self.getVertsFromCenter, self.getVertsFromOrigin, \ self.getVertsFromCenterOrigin, CallBackFunction(self.getVertsFromSide, 'xside'), CallBackFunction(self.getVertsFromSide, 'yside'), CallBackFunction(self.getVertsFromSide, 'zside'), self.setMaxCube, self.setMinCube] for i in range(len(fkeys)): self.funcs[fkeys[i]] = fs[i] self.pickableVertices = 1 kw['frontPolyMode'] = 'line' apply( IndexedPolygons.__init__, (self, name, check), kw ) self.inheritMaterial = 0 #print 'calling self.Set with ', kw.get('materials') #apply(self.Set,(), kw) # register functions to compute normals self.VertexNormalFunction(self.ComputeVertexNormals) self.vertexSet.normals.ComputeMode( viewerConst.AUTO ) self.FaceNormalFunction(self.ComputeFaceNormals) self.faceSet.normals.ComputeMode( viewerConst.AUTO ) self._PrimitiveType() self.GetNormals() self.oldFPM = GL.GL_LINE
def getVertsFromCenter(self, center): self.center = center halfSide = Numeric.multiply(Numeric.array((self.xside, self.yside, self.zside)), 0.5) pt1=tuple(Numeric.add(center,halfSide)) pt0=tuple(Numeric.subtract(center,halfSide)) return (pt0, pt1)
def Set(self, check=1, redo=1, updateOwnGui=True, **kw): """set data for this object: Set polygon's vertices, faces, normals or materials check=1 : verify that all the keywords present can be handle by this func redo=1 : append self to viewer.objectsNeedingRedo updateOwnGui=True : allow to update owngui at the end this func """ redoFlags = 0 #newKeyList is list of keys specified in call to Set newKeyList = kw.keys() # Setting both center AND origin is a special case # which sets all side lengths centerOrigin = 0 if 'center' in newKeyList and 'origin' in newKeyList: centerOrigin = 1 side= kw.get( 'side') if side: kw['xside'] = side kw['yside'] = side kw['zside'] = side newKeyList.extend(['xside','yside', 'zside']) newKeyList = uniq(newKeyList) apply(self.updateVal, (['xside','yside','zside'],),kw) #these are either 1 or None self.maxCube = kw.get('maxCube') self.minCube = kw.get('minCube') if self.minCube and self.maxCube: self.center = [ (self.minCube[0] + self.maxCube[0]) * .5 , (self.minCube[1] + self.maxCube[1]) * .5 , (self.minCube[2] + self.maxCube[2]) * .5 ] # kl used to implement this precedence: # side < [x,y,z]side < center < origin < cornerPoints < vertices # vertices are dealt with last cornerPoints = None kl = ['xside', 'yside', 'zside','minCube', 'maxCube', 'center', 'origin'] for key in kl: if key in newKeyList: newVal = kw.get(key) if not newVal: continue if key in ['center','origin'] and centerOrigin: self.center = kw.get('center') newVal = kw.get('origin') newKeyList.remove('center') newKeyList.remove('origin') f = self.funcs['centerOrigin'] else: del kw[key] f = self.funcs[key] cornerPoints = apply(f, (newVal,),{}) #if cornerPoints are specified, they override other info newcornerPoints = kw.get('cornerPoints') if newcornerPoints: cornerPoints = newcornerPoints if cornerPoints: ptList = self.getVertsFromCornerPts(cornerPoints) else: ptList = None #vertices overrides everything: set center+sides newVertices = kw.get('vertices') if newVertices is not None: assert len(newVertices)==8 pt1 = Numeric.array(newVertices[2]) pt2 = Numeric.array(newVertices[4]) self.center = tuple(Numeric.multiply(Numeric.add(pt1,pt2), 0.5)) self.xside, self.yside, self.zside = \ Numeric.subtract(pt2,pt1) redoFlags |= self._redoFlags['redoDisplayListFlag'] elif ptList: assert len(ptList)==8 kw['vertices'] = ptList redoFlags |= self._redoFlags['redoDisplayListFlag'] if kw.get('faces') is None: kw['faces'] = self.faces redoFlags |= apply( IndexedPolygons.Set, (self, check, 0), kw ) return self.redoNow(redo, updateOwnGui, redoFlags)
def select(self, bnds, cutoff=7.5): cutoffValue = math.cos(cutoff * math.pi / 180.) #print "cutoffValue=", cutoffValue aromaticCs = AtomSet([]) atD = {} ctr = 1 aromaticBnds = BondSet() #taken from autotorsCommands ats = self.getAtoms(bnds) rf = RingFinder() rf.findRings2(ats, bnds) cyclecount = rf.ringCount aromatic_cycles = [] ct = 1 for ring in rf.rings: blist = ring['bonds'] for bnd in blist: at = bnd.atom1 #next find the other bond in this cycle with at as one of the atoms: z2 = filter( lambda x: x != bnd and x.atom1 == at or x.atom2 == at, blist) bnd.nextbond = z2[0] neighbor = z2[0].atom1 if neighbor == at: neighbor = z2[0].atom2 bnd.next1 = neighbor #print "set ", bnd.atom1.name,'-', bnd.atom2.name,".next1 to ", neighbor.name #now each bond has 3 atoms specified for it: its own two and the next1 to atom1 at1 = bnd.next1 at2 = bnd.atom1 at3 = bnd.atom2 pt1 = at1.coords pt2 = at2.coords pt3 = at3.coords a1 = Numeric.subtract(pt2, pt1) b1 = Numeric.subtract(pt3, pt2) p = [ a1[1] * b1[2] - a1[2] * b1[1], a1[2] * b1[0] - a1[0] * b1[2], a1[0] * b1[1] - a1[1] * b1[0] ] result0 = Numeric.sqrt(p[0] * p[0] + p[1] * p[1] + p[2] * p[2]) bnd.nrmsize = result0 result1 = p bnd.nrms = result1 #next find the other bond w/atom2: z2 = filter(lambda x, bnd=bnd, at2=bnd.atom2, blist=blist: x != bnd and x.atom1 == at2 or x.atom2 == at2, blist) #finally, return the other atom in this bond bnd.nextbond2 = z2[0] if bnd.nextbond2 == bnd: bnd.nextbond2 = z2[1] #neighbor2 = self._getnxtAtom(b.atom2,b.nextbond2) neighbor2 = bnd.nextbond2.atom1 if neighbor2 == bnd.atom2: neighbor2 = bnd.nextbond2.atom2 bnd.next2 = neighbor2 #next have to check whether the normals are parallel #check each pair in each bond, how to keep track?? #have to get normal at b's atom2: so have to get next2 for this bond: #have to loop twice to make sure neighbor has nrms for bnd in blist: p = bnd.nrms psize = bnd.nrmsize q = bnd.nextbond2.nrms qsize = bnd.nextbond2.nrmsize #theta is the critical test for planarity: #if angle between 2 nrms is 0, atoms are planar #NB>test is comparing theta,cos(angle), w/zero bnd.theta = Numeric.dot(p, q) / (psize * qsize) #NB: REPEAT STUFF FROM HERE TO THE END IF aromaticCutOff changes ct = 0 for bnd in blist: #these are values for the default 7.5degrees: #if theta>=0.997 or theta<=-0.997: #print bnd.atom1.name, '-', bnd.atom2.name, '->', bnd.theta if bnd.theta >= cutoffValue or bnd.theta <= -cutoffValue: bnd.posAromatic = 1 ct = ct + 1 else: bnd.posAromatic = 0 #print ' posAromatic=', bnd.posAromatic #after checking all the bonds in current cycle, compare #posAromatic w/number if ct == len(blist): #print ctr," cycle is aromatic" #NB: only C=C bonds are considered aromatic # could change the name and autodock_element here.... for bnd in blist: # THIS IS WRONG!!! #if bnd.atom1.element=='C' and bnd.atom2.element=='C': # aromaticBnds.append(bnd) aromaticBnds.append(bnd) ctr = ctr + 1 #print "len(aromaticBnds)=", len(aromaticBnds) #for b in aromaticBnds: # print b.atom1.name, '-', b.atom2.name return aromaticBnds
def __init__(self, name=None, check=1, **kw): self.maxCube = None self.minCube = None if not kw.get('origin') \ and not kw.get('center') \ and not kw.get('cornerPoints') \ and not kw.get('minCube'): kw['origin'] = (0, 0, 0) #set up some defaults: materials = kw.get('materials') #print 'in BOX materials kw=', materials if not materials: kw['materials'] = ( (0, 0, 1), (0, 1, 0), (0, 0, 1), (0, 1, 0), (1, 0, 0), (1, 0, 0), ) #print 'in BOX after test for materials, kwmaterials=', kw['materials'] vertices = kw.get('vertices') if vertices is not None: assert len(vertices) == 8 pt1 = Numeric.array(vertices[2]) pt2 = Numeric.array(vertices[4]) self.center = tuple(Numeric.multiply(Numeric.add(pt1, pt2), 0.5)) self.xside, self.yside, self.zside = \ Numeric.subtract(pt2,pt1) else: #set up center center = kw.get('center') #if not center: center = (0.,0.,0.) self.center = center #set up sides side = kw.get('side') if side: self.xside = side self.yside = side self.zside = side else: xside = kw.get('xside') if not xside: xside = 1.0 self.xside = xside yside = kw.get('yside') if not yside: yside = 1.0 self.yside = yside zside = kw.get('zside') if not zside: zside = 1.0 self.zside = zside #NB faces shouldn't change self.faces = ((0, 3, 2, 1), (3, 7, 6, 2), (7, 4, 5, 6), (0, 1, 5, 4), (1, 2, 6, 5), (0, 4, 7, 3)) self.funcs = {} fkeys = ['center', 'origin', 'centerOrigin', 'xside', \ 'yside', 'zside','maxCube', 'minCube'] fs = [self.getVertsFromCenter, self.getVertsFromOrigin, \ self.getVertsFromCenterOrigin, CallBackFunction(self.getVertsFromSide, 'xside'), CallBackFunction(self.getVertsFromSide, 'yside'), CallBackFunction(self.getVertsFromSide, 'zside'), self.setMaxCube, self.setMinCube] for i in range(len(fkeys)): self.funcs[fkeys[i]] = fs[i] self.pickableVertices = 1 kw['frontPolyMode'] = 'line' apply(IndexedPolygons.__init__, (self, name, check), kw) self.inheritMaterial = 0 #print 'calling self.Set with ', kw.get('materials') #apply(self.Set,(), kw) # register functions to compute normals self.VertexNormalFunction(self.ComputeVertexNormals) self.vertexSet.normals.ComputeMode(viewerConst.AUTO) self.FaceNormalFunction(self.ComputeFaceNormals) self.faceSet.normals.ComputeMode(viewerConst.AUTO) self._PrimitiveType() self.GetNormals() self.oldFPM = GL.GL_LINE
def Set(self, check=1, redo=1, updateOwnGui=True, **kw): """set data for this object: Set polygon's vertices, faces, normals or materials check=1 : verify that all the keywords present can be handle by this func redo=1 : append self to viewer.objectsNeedingRedo updateOwnGui=True : allow to update owngui at the end this func """ redoFlags = 0 #newKeyList is list of keys specified in call to Set newKeyList = kw.keys() # Setting both center AND origin is a special case # which sets all side lengths centerOrigin = 0 if 'center' in newKeyList and 'origin' in newKeyList: centerOrigin = 1 side = kw.get('side') if side: kw['xside'] = side kw['yside'] = side kw['zside'] = side newKeyList.extend(['xside', 'yside', 'zside']) newKeyList = uniq(newKeyList) apply(self.updateVal, (['xside', 'yside', 'zside'], ), kw) #these are either 1 or None self.maxCube = kw.get('maxCube') self.minCube = kw.get('minCube') if self.minCube and self.maxCube: self.center = [(self.minCube[0] + self.maxCube[0]) * .5, (self.minCube[1] + self.maxCube[1]) * .5, (self.minCube[2] + self.maxCube[2]) * .5] # kl used to implement this precedence: # side < [x,y,z]side < center < origin < cornerPoints < vertices # vertices are dealt with last cornerPoints = None kl = [ 'xside', 'yside', 'zside', 'minCube', 'maxCube', 'center', 'origin' ] for key in kl: if key in newKeyList: newVal = kw.get(key) if not newVal: continue if key in ['center', 'origin'] and centerOrigin: self.center = kw.get('center') newVal = kw.get('origin') newKeyList.remove('center') newKeyList.remove('origin') f = self.funcs['centerOrigin'] else: del kw[key] f = self.funcs[key] cornerPoints = apply(f, (newVal, ), {}) #if cornerPoints are specified, they override other info newcornerPoints = kw.get('cornerPoints') if newcornerPoints: cornerPoints = newcornerPoints if cornerPoints: ptList = self.getVertsFromCornerPts(cornerPoints) else: ptList = None #vertices overrides everything: set center+sides newVertices = kw.get('vertices') if newVertices is not None: assert len(newVertices) == 8 pt1 = Numeric.array(newVertices[2]) pt2 = Numeric.array(newVertices[4]) self.center = tuple(Numeric.multiply(Numeric.add(pt1, pt2), 0.5)) self.xside, self.yside, self.zside = \ Numeric.subtract(pt2,pt1) redoFlags |= self._redoFlags['redoDisplayListFlag'] elif ptList: assert len(ptList) == 8 kw['vertices'] = ptList redoFlags |= self._redoFlags['redoDisplayListFlag'] if kw.get('faces') is None: kw['faces'] = self.faces redoFlags |= apply(IndexedPolygons.Set, (self, check, 0), kw) return self.redoNow(redo, updateOwnGui, redoFlags)