コード例 #1
0
def plane(coords, findBounds=False):
    """Compute a plane given an Nx3 Numpy array.

	   Returns a Plane whose origin is the centroid of the coords.
	   If 'findBounds' is True, returns an additional Point (the
	   furthest point projected into plane) and an additional
	   floating-point number (distance from origin to that point).
	   
	   Tip: you generally generate the input Numpy array with 
	   numpyArrayFromAtoms()
	"""
    import numpy
    from numpy.linalg import eig, svd, eigh
    centroid = coords.mean(0)
    centered = coords - centroid
    ignore, vals, vecs = svd(centered)
    normal = vecs[numpy.argmin(vals)]
    from chimera import Point, Plane, Vector
    origin = Point(*centroid)
    plane = Plane(origin, Vector(*normal))
    if findBounds:
        maxSqDist = None
        for coord in coords:
            projected = plane.nearest(Point(*coord))
            sqDist = origin.sqdistance(projected)
            if maxSqDist == None or sqDist > maxSqDist:
                maxSqDist = sqDist
                furthest = projected
        from math import sqrt
        return plane, projected, sqrt(maxSqDist)
    return plane
コード例 #2
0
 def pointDistances(self, target):
     if isinstance(target, chimera.Point):
         points = [target]
     else:
         points = target
     from chimera import cross, Plane
     dists = []
     minExt = min(self.extents)
     maxExt = max(self.extents)
     xfCenter = self.xformCenter()
     xfDirection = self.xformDirection()
     minPt = xfCenter + xfDirection * minExt
     maxPt = xfCenter + xfDirection * maxExt
     for pt in points:
         v = pt - xfCenter
         c1 = cross(v, xfDirection)
         if c1.length == 0.0:
             # colinear
             inPlane = pt
         else:
             plane = Plane(xfCenter, cross(c1, xfDirection))
             inPlane = plane.nearest(pt)
         ptExt = (inPlane - xfCenter) * xfDirection
         if ptExt < minExt:
             measurePt = minPt
         elif ptExt > maxExt:
             measurePt = maxPt
         else:
             measurePt = inPlane
         dists.append(pt.distance(measurePt))
     return dists
コード例 #3
0
def plane(coords, findBounds=False):
	"""Compute a plane given an Nx3 Numpy array.

	   Returns a Plane whose origin is the centroid of the coords.
	   If 'findBounds' is True, returns an additional Point (the
	   furthest point projected into plane) and an additional
	   floating-point number (distance from origin to that point).
	   
	   Tip: you generally generate the input Numpy array with 
	   numpyArrayFromAtoms()
	"""
	import numpy
	from numpy.linalg import eig, svd, eigh
	centroid = coords.mean(0)
	centered = coords - centroid
	ignore, vals, vecs = svd(centered)
	normal = vecs[numpy.argmin(vals)]
	from chimera import Point, Plane, Vector
	origin = Point(*centroid)
	plane = Plane(origin, Vector(*normal))
	if findBounds:
		maxSqDist = None
		for coord in coords:
			projected = plane.nearest(Point(*coord))
			sqDist = origin.sqdistance(projected)
			if maxSqDist == None or sqDist > maxSqDist:
				maxSqDist = sqDist
				furthest = projected
		from math import sqrt
		return plane, projected, sqrt(maxSqDist)
	return plane
コード例 #4
0
 def _axisDistance(self, axis, infinite=False):
     from chimera import angle, cross, Plane
     # shortest distance between lines is perpendicular to both...
     sDir = self.xformDirection()
     aDir = axis.xformDirection()
     if angle(sDir, aDir) in [0.0, 180.0]:
         # parallel
         return self._axisEndsDist(axis)
     shortDir = cross(sDir, aDir)
     # can use analytically shortest dist only if each axis
     # penetrates the plane formed by the other axis and the
     # perpendicular
     if not infinite:
         for a1, a2 in [(axis, self), (self, axis)]:
             normal = cross(a1.xformDirection(), shortDir)
             plane = Plane(a1.xformCenter(), normal)
             d1 = plane.distance(a2.xformCenter() +
                                 a2.xformDirection() * a2.extents[0])
             d2 = plane.distance(a2.xformCenter() +
                                 a2.xformDirection() * a2.extents[1])
             if cmp(d1, 0.0) == cmp(d2, 0.0):
                 # both ends on same side of plane
                 return self._axisEndsDist(axis)
     # D is perpendicular distance to origin
     d1 = Plane(self.xformCenter(), shortDir).equation()[3]
     d2 = Plane(axis.xformCenter(), shortDir).equation()[3]
     return abs(d1 - d2)
コード例 #5
0
def clip_model(m, axis, origin, offset, slab, thickness, flip):

    if origin is None:
        origin = m.clipPlane.origin.data()
    if axis is None:
        axis = (-m.clipPlane.normal).data()
        
    if flip:
        axis = tuple([-x for x in axis])

    if offset != 0:
        origin = apply_offset(origin, axis, offset)
    from chimera import Plane, Point, Vector
    p = Plane()
    p.origin = Point(*origin)
    p.normal = -Vector(*axis)
    m.clipPlane = p
    if not slab is None:
        m.useClipThickness = slab
    if not thickness is None:
        m.clipThickness = thickness
    m.useClipPlane = True
コード例 #6
0
def tetraPos(bondee,
             bonded,
             bondLen,
             toward=None,
             away=None,
             toward2=None,
             away2=None):
    newBonded = []
    curBonded = bonded[:]
    if len(curBonded) == 0:
        pos = singlePos(bondee, bondLen, toward, away)
        toward = toward2
        away = away2
        newBonded.append(pos)
        curBonded.append(pos)

    if len(curBonded) == 1:
        # add at 109.5 degree angle
        coplanar = toward or away
        if coplanar:
            coplanar = [coplanar]
        else:
            coplanar = None
        pos = anglePos(bondee, curBonded[0], bondLen, 109.5, coplanar=coplanar)
        if toward or away:
            # find the other 109.5 position in the toward/away
            # plane and the closer/farther position as appropriate
            old = bondee - curBonded[0]
            old.normalize()
            new = pos - bondee
            midpoint = bondee + old * new.length * cos705
            otherPos = pos + (midpoint - pos) * 2
            d1 = (pos - (toward or away)).sqlength()
            d2 = (otherPos - (toward or away)).sqlength()
            if toward:
                if d2 < d1:
                    pos = otherPos
            elif away and d2 > d1:
                pos = otherPos

        newBonded.append(pos)
        curBonded.append(pos)

    if len(curBonded) == 2:
        # add along anti-bisector of current bonds and raised up
        # 54.75 degrees from plane of those bonds (half of 109.5)
        v1 = curBonded[0] - bondee
        v2 = curBonded[1] - bondee
        v1.normalize()
        v2.normalize()
        antiBi = v1 + v2
        antiBi.negate()
        antiBi.normalize()
        # in order to stabilize the third and fourth tetrahedral
        # positions, cross the longer vector by the shorter
        if v1.sqlength() > v2.sqlength():
            crossV = cross(v1, v2)
        else:
            crossV = cross(v2, v1)
        crossV.normalize()

        antiBi = antiBi * cos5475 * bondLen
        crossV = crossV * sin5475 * bondLen

        pos = bondee + antiBi + crossV
        if toward or away:
            otherPos = bondee + antiBi - crossV
            d1 = (pos - (toward or away)).sqlength()
            d2 = (otherPos - (toward or away)).sqlength()
            if toward:
                if d2 < d1:
                    pos = otherPos
            elif away and d2 > d1:
                pos = otherPos
        newBonded.append(pos)
        curBonded.append(pos)

    if len(curBonded) == 3:
        unitized = []
        for cb in curBonded:
            v = cb - bondee
            v.normalize()
            unitized.append(bondee + v)
        pl = Plane(unitized)
        norm = pl.normal
        # if normal on other side of plane from bondee, we need to
        # invert the normal;  the (signed) distance from bondee
        # to the plane indicates if it is on the same side
        # (positive == same side)
        d = pl.distance(bondee)
        if d < 0.0:
            norm.negate()
        newBonded.append(bondee + norm * bondLen)
    return newBonded
コード例 #7
0
import chimera
from chimera import Plane, Xform, cross, Vector, Point

m = chimera.openModels.list()[0]
b = chimera.selection.currentBonds()[0]
bondVec = b.atoms[0].coord() - b.atoms[1].coord()
bondVec.normalize()
axis = Vector(1.0, 0.0, 0.0)
crossProd = cross(axis, bondVec)
if crossProd.sqlength() > 0:
    from math import acos, degrees
    xform = Xform.rotation(crossProd, degrees(acos(axis * bondVec)))
    xform.invert()
else:
    xform = Xform.identity()

m.openState.xform = xform

# okay, that puts the bond parallel to the X axis, now swing the plane of
# the rest of the molecule into the xy plane...
molPlane = Plane([a.xformCoord() for a in m.atoms[:3]])
angle = chimera.angle(molPlane.normal, Vector(0, 0, -1))
xform2 = Xform.rotation(b.atoms[0].xformCoord() - b.atoms[1].xformCoord(),
                        angle)
xform2.multiply(xform)

m.openState.xform = xform2
コード例 #8
0
def tetraPos(bondee, bonded, bondLen, toward=None, away=None,
						toward2=None, away2=None):
	newBonded = []
	curBonded = bonded[:]
	if len(curBonded) == 0:
		pos = singlePos(bondee, bondLen, toward, away)
		toward = toward2
		away = away2
		newBonded.append(pos)
		curBonded.append(pos)
	
	if len(curBonded) == 1:
		# add at 109.5 degree angle
		coplanar = toward or away
		if coplanar:
			coplanar = [coplanar]
		else:
			coplanar = None
		pos = anglePos(bondee, curBonded[0], bondLen, 109.5,
							coplanar=coplanar)
		if toward or away:
			# find the other 109.5 position in the toward/away
			# plane and the closer/farther position as appropriate
			old = bondee - curBonded[0]
			old.normalize()
			new = pos - bondee
			midpoint = bondee + old * new.length * cos705
			otherPos = pos + (midpoint - pos) * 2
			d1 = (pos - (toward or away)).sqlength()
			d2 = (otherPos - (toward or away)).sqlength()
			if toward:
				if d2 < d1:
					pos = otherPos
			elif away and d2 > d1:
				pos = otherPos

		newBonded.append(pos)
		curBonded.append(pos)
	
	if len(curBonded) == 2:
		# add along anti-bisector of current bonds and raised up
		# 54.75 degrees from plane of those bonds (half of 109.5)
		v1 = curBonded[0] - bondee
		v2 = curBonded[1] - bondee
		v1.normalize()
		v2.normalize()
		antiBi = v1 + v2
		antiBi.negate()
		antiBi.normalize()
		# in order to stabilize the third and fourth tetrahedral
		# positions, cross the longer vector by the shorter
		if v1.sqlength() > v2.sqlength():
			crossV = cross(v1, v2)
		else:
			crossV = cross(v2, v1)
		crossV.normalize()

		antiBi = antiBi * cos5475 * bondLen
		crossV = crossV * sin5475 * bondLen

		pos = bondee + antiBi + crossV
		if toward or away:
			otherPos = bondee + antiBi - crossV
			d1 = (pos - (toward or away)).sqlength()
			d2 = (otherPos - (toward or away)).sqlength()
			if toward:
				if d2 < d1:
					pos = otherPos
			elif away and d2 > d1:
				pos = otherPos
		newBonded.append(pos)
		curBonded.append(pos)
	
	if len(curBonded) == 3:
		unitized = []
		for cb in curBonded:
			v = cb - bondee
			v.normalize()
			unitized.append(bondee + v)
		pl = Plane(unitized)
		norm = pl.normal
		# if normal on other side of plane from bondee, we need to
		# invert the normal;  the (signed) distance from bondee
		# to the plane indicates if it is on the same side
		# (positive == same side)
		d = pl.distance(bondee)
		if d < 0.0:
			norm.negate()
		newBonded.append(bondee + norm * bondLen)
	return newBonded