Beispiel #1
0
	def distance(self, items, **kw):
		from Axes import Axis
		from Planes import Plane
		numAxes = len([i for i in items if isinstance(i, Axis)])
		numPlanes = len([i for i in items if isinstance(i, Plane)])
		if numAxes == 2:
			axis1, axis2 = items
			dist = axis1._axisDistance(axis2, **kw)
		elif numAxes == numPlanes == 1:
			if isinstance(items[0], Axis):
				axis, plane = items
			else:
				plane, axis = items
			xformPlane = chimera.Plane(plane.xformOrigin(), plane.xformNormal())
			xc = axis.xformCenter()
			d1, d2 = [xformPlane.distance(pt)
					for pt in [xc + axis.direction * e for e in axis.extents]]
			if d1 * d2 < 0.0:
				dist = 0.0
			else:
				dist = min([abs(d) for d in (d1, d2)])
		elif numPlanes == 2:
			plane1, plane2 = items
			angle = self.angle(items)
			if angle == 0.0:
				o1 = plane1.xformOrigin()
				p2 = chimera.Plane(plane2.xformOrigin(), plane2.xformNormal())
				dist = (o1 - p2.nearest(o1)).length
			else:
				dist = 0.0
		else:
			raise ValueError("distance calculation not implemented")
		return dist
Beispiel #2
0
def orientPlanarRing(atoms, ringIndices=[], convex=True):
	r = atoms[0].residue
	if not r.fillDisplay or r.fillMode != chimera.Residue.Thick:
		# can't show orientation of thin nor aromatic ring
		return []
	pts = [a.coord() for a in atoms]
	bonds = bondsBetween(atoms)
	if chimera.Bond.Wire in [b.drawMode for b in bonds]:
		radius = 0
	else:
		radius = min([b.radius for b in bonds])
		radius *= atoms[0].molecule.stickScale
	color_kwds = _atom_color(atoms[0])
	if radius == 0:
		# can't show orientation of thin ring
		return []

	# non-zero radius
	planeEq = chimera.Plane(pts)
	offset = planeEq.normal * radius
	result = []
	for r in ringIndices:
		center = chimera.Point([pts[i] for i in r]) + offset
		t = vrml.Transform()
		t.translation = center.data()
		s = vrml.Sphere(radius=radius, **color_kwds)
		t.addChild(s)
		result.append(t)
	return result
	def pointDistances(self, target, signed=False):
		if isinstance(target, chimera.Point):
			points = [target]
		else:
			points = target
		measurePlane = chimera.Plane(self.xformOrigin(), self.xformNormal())
		if signed:
			return [measurePlane.distance(pt) for pt in points]
		return [abs(measurePlane.distance(pt)) for pt in points]
	def _restoreSession(self, planeData, fromGeom=False):
		from SimpleSession import getColor, idLookup
		maxNumber = 0
		for data, atomIDs in planeData.items():
			number, name, cmpVal, radius, thickness, colorID, origin, normal\
															= data
			atoms = [idLookup(a) for a in atomIDs]
			self._instantiatePlane(number, name, self.planeOrdinal + number,
							getColor(colorID), radius, thickness,
							self._getSourceModel(atoms), atoms,
							chimera.Plane(Point(*origin), Vector(*normal)))
			maxNumber = max(number, maxNumber)
		self.planeOrdinal += maxNumber
def findRotamerNearest(atPos, idatmType, atom, neighbor, checkDist):
    # find atom that approaches nearest to a methyl-type rotamer
    nPos = neighbor.xformCoord()
    v = atPos - nPos
    bondLen = bondWithHLength(atom, typeInfo[idatmType].geometry)
    v.length = cos70_5 * bondLen
    center = atPos + v
    plane = chimera.Plane(center, v)
    radius = sin70_5 * bondLen
    checkDist += radius

    nearby = searchTree.searchTree(center.data(), checkDist)
    nearPos = n = nearAtom = None
    for nb in nearby:
        if nb.xformCoord() in [atPos, nPos]:
            # exclude atoms from identical-copy molecules also...
            continue
        if nb.molecule != atom.molecule \
        and nb.molecule.id == atom.molecule.id:
            # don't consider atoms in sibling submodels
            continue
        candidates = [(nb, vdwRadius(nb))]
        # only heavy atoms in tree...
        for nbb in nb.primaryNeighbors():
            if nbb.element.number != 1:
                continue
            if nbb == neighbor:
                continue
            candidates.append((nbb, Hrad))

        for candidate, aRad in candidates:
            cPos = candidate.xformCoord()
            # project into plane...
            proj = plane.nearest(cPos)

            # find nearest approach of circle...
            cv = proj - center
            if cv.length == 0.0:
                continue
            cv.length = radius
            app = center + cv
            d = (cPos - app).length - aRad
            if not nearPos or d < n:
                nearPos = cPos
                n = d
                nearAtom = candidate
    return nearPos, n, nearAtom
Beispiel #6
0
    def _align(self, refModel):
        if not refModel.useClipPlane:
            from chimera import LimitationError
            raise LimitationError("Cannot align clip planes:"
                                  " both models must have clipping on")

        matchModel = self.menu.getvalue()
        refMat = refModel.openState.xform
        matchMat = matchModel.openState.xform
        if refMat == matchMat:
            matchModel.clipPlane = refModel.clipPlane
            return
        xf = matchMat.inverse()
        xf.multiply(refMat)
        refClip = refModel.clipPlane
        matchModel.clipPlane = chimera.Plane(xf.apply(refClip.origin),
                                             xf.apply(refClip.normal))
class XS:
    def __init__(self,
                 name,
                 points=None,
                 sw=None,
                 sl=None,
                 closed=None,
                 grid=None):
        # "points" should be integer coordinates in
        # the range [0, grid].  This is necessary to
        # make the cross section displayable in the editor.
        if name is None:
            global xsId
            name = "%s%d" % (xsUnnamed, xsId)
            xsId += 1
        self.name = name
        self.points = points
        self.sw = sw
        self.sl = sl
        self.closed = closed
        self.grid = grid
        self.xs = None
        self.mode = Residue.Ribbon_Custom

    def setXS(self, xs, mode, grid):
        self.xs = xs
        self.mode = mode

        def mapToGrid(c):
            return int(round(((c / 2 + 0.5) * grid)))

        self.points = [(mapToGrid(x), mapToGrid(y)) for x, y in xs.outline]
        self.sw = xs.smoothWidth
        self.sl = xs.smoothLength
        self.closed = xs.closed
        self.grid = grid

    def setResidue(self, r):
        if self.mode == Residue.Ribbon_Custom:
            r.ribbonDrawMode = r.Ribbon_Custom
            r.ribbonXSection = self.getXS()
        else:
            r.ribbonDrawMode = self.mode
            r.ribbonXSection = None

    def getXS(self):
        if self.xs is None:
            self._makeXSection()
        return self.xs

    def _makeXSection(self):
        try:
            checkXSection(self.closed, self.points)
        except ValueError, s:
            from chimera import replyobj
            replyobj.error(s)
            return False
        xs = chimera.RibbonXSection(self.sw, self.sl, self.closed)
        # Figure out whether the points are in clockwise
        # or counterclockwise order.  Back-face culling
        # of polygons requires one particular direction.
        try:
            p = chimera.Plane([chimera.Point(x, y, 0) for x, y in self.points])
        except chimera.error:
            # probably caused by colinear points
            pass
        else:
            if p.normal.z > 0:
                self.points.reverse()
        outline = []
        g = float(self.grid)
        for x, y in self.points:
            mx = ((x / g) - 0.5) * 2.0
            my = ((y / g) - 0.5) * 2.0
            outline.append((mx, my))
        xs.outline = outline
        self.xs = xs
        xsName[xs] = (self.name, self.grid)
Beispiel #8
0
def fill5Ring(atoms, c5p=None):
	pts = [a.coord() for a in atoms]
	bonds = bondsBetween(atoms)
	if chimera.Bond.Wire in [b.drawMode for b in bonds]:
		radius = 0
	else:
		radius = min([b.radius for b in bonds])
		radius *= atoms[0].molecule.stickScale
	color_kwds = _atom_color(atoms[0])

	# see how planar ring is
	indices = (0, 1, 2, 3, 4, 0, 1, 2, 3, 4)
	distC5p = None
	fake_bonds = [(0, 5), (1, 5), (2, 5), (3, 5), (4, 5)]
	for i in range(5):
		atoms[i].pucker = 'plane'

	# Find twist plane.  Note: due to floating point limitations,
	# dist3 and dist4 will virtually never be zero.
	for i in range(5):
		planeEq = chimera.Plane([pts[indices[j]] for j in range(i, i + 3)])
		dist3 = planeEq.distance(pts[indices[i + 3]])
		dist4 = planeEq.distance(pts[indices[i + 4]])
		if c5p:
			distC5p = planeEq.distance(c5p.coord())
		if dist3 == 0 or dist4 == 0 \
		or (dist3 < 0 and dist4 > 0) or (dist3 > 0 and dist4 < 0):
			break

	abs_dist3 = abs(dist3)
	abs_dist4 = abs(dist4)
	if abs_dist3 < planar_cutoff and abs_dist4 < planar_cutoff:
		# planar, new_vertex is centroid of pts
		new_vertex = chimera.Point(pts)
	elif abs_dist3 < abs_dist4 and abs_dist4 / abs_dist3 >= envelope_ratio:
		# envelope, new_vertex is mid-point of separating edge
		new_vertex = chimera.Point([pts[indices[i]], pts[indices[i + 3]]])
		atoms[indices[i + 4]].pucker = 'envelope'
		del fake_bonds[indices[i + 4]]
	elif abs_dist4 < abs_dist3 and abs_dist3 / abs_dist4 >= envelope_ratio:
		# envelope, new_vertex is mid-point of separating edge
		new_vertex = chimera.Point([pts[indices[i + 2]], pts[indices[i + 4]]])
		atoms[indices[i + 3]].pucker = 'envelope'
		del fake_bonds[indices[i + 3]]
	else: # if (dist3 < 0 and dist4 > 0) or (dist3 > 0 and dist4 < 0):
		# twist, new_vertex is placed in twist plane near twist pts
		centroid = chimera.Point([
			pts[indices[i + 1]],
			pts[indices[i + 3]],
			pts[indices[i + 4]]
		])
		new_vertex = planeEq.nearest(centroid)
		del fake_bonds[indices[i + 1]]
		if cmp(dist3, 0) == cmp(distC5p, 0):
			atoms[indices[i + 3]].pucker = 'endo'
		else:
			atoms[indices[i + 3]].pucker = 'exo'
		if cmp(dist4, 0) == cmp(distC5p, 0):
			atoms[indices[i + 4]].pucker = 'endo'
		else:
			atoms[indices[i + 4]].pucker = 'exo'
	pts.append(new_vertex)		# new_vertex has index 5
	triangles = ((0, 1, 5), (1, 2, 5), (2, 3, 5), (3, 4, 5), (4, 0, 5))

	if radius == 0:
		f = TriangleNode(solid=False,
			coordList=[p.data() for p in pts],
			coordIndices=triangles,
			colorPerVertex=False, **color_kwds
		)
		return [f]

	# non-zero radius
	f = vrml.Faces(**color_kwds)
	for t in triangles:
		# t is a list of 3 indices
		t = [pts[i] for i in t]
		# t is a list of 3 Points
		planeEq = chimera.Plane(t)
		offset = planeEq.normal * radius
		top = [(p + offset).data() for p in t]
		bot = [(p - offset).data() for p in t]
		f.addFace(top)
		if 1:
			# STL wants manifold objects
			for i in range(len(t) - 1):
				f.addFace([top[i], bot[i], bot[i + 1], top[i + 1]])
			f.addFace([top[-1], bot[-1], bot[0], top[0]])
		bot.reverse()
		f.addFace(bot)
	result = [f]
	for b in fake_bonds:
		node = drawCylinder(radius, pts[b[0]], pts[b[1]], **color_kwds)
		result.append(node)
	t = vrml.Transform()
	t.translation = pts[5].data()
	s = vrml.Sphere(radius=radius, **color_kwds)
	t.addChild(s)
	result.append(t)
	return result
Beispiel #9
0
def drawSlab(residue, style, thickness, orient, shape, showGly):
	try:
		t = residue.type
		if t in ('PSU', 'P'):
			n = 'P'
		elif t in ('NOS', 'I'):
			n = 'I'
		else:
			n = nucleic3to1[t]
	except KeyError:
		return None
	standard = standard_bases[n]
	ring_atom_names = standard["ring atom names"]
	atoms = getRing(residue, ring_atom_names)
	if not atoms:
		return None
	plane = chimera.Plane([a.coord() for a in atoms])
	info = findStyle(style)
	type = standard['type']
	slab_corners = info[type]
	origin = residue.findAtom(anchor(info[ANCHOR], type)).coord()
	origin = plane.nearest(origin)

	pts = [plane.nearest(a.coord()) for a in atoms[0:2]]
	yAxis = pts[0] - pts[1]
	yAxis.normalize()
	xAxis = chimera.cross(yAxis, plane.normal)
	xf = chimera.Xform.xform(
		xAxis[0], yAxis[0], plane.normal[0], origin[0],
		xAxis[1], yAxis[1], plane.normal[1], origin[1],
		xAxis[2], yAxis[2], plane.normal[2], origin[2]
	)
	xf.multiply(standard["adjust"])

	color_kwds = _atom_color(atoms[0])

	na = vrml.Transform()
	na.translation = xf.getTranslation().data()
	axis, angle = xf.getRotation()
	na.rotation = (axis[0], axis[1], axis[2], math.radians(angle))
	#xf.invert()	# invert so xf maps residue space to standard space

	halfThickness = thickness / 2.0

	t = vrml.Transform()
	na.addChild(t)
	llx, lly = slab_corners[0]
	urx, ury = slab_corners[1]
	t.translation = (llx + urx) / 2.0, (lly + ury) / 2.0, 0
	if shape == 'box':
		b = vrml.Box(size=(urx - llx, ury - lly, 2.0 * halfThickness),
				**color_kwds)
	elif shape == 'tube':
		radius = (urx - llx) / 2
		t.scale = 1, 1, halfThickness / radius
		b = vrml.Cylinder(radius=radius, height=(ury - lly),
				**color_kwds)
	elif shape == 'ellipsoid':
		# need to reach anchor atom
		t.scale = ((urx - llx) / 20 * _SQRT2, (ury - lly) / 20 * _SQRT2,
							.1 * halfThickness)
		b = vrml.Sphere(radius=10, **color_kwds)
	t.addChild(b)

	if showGly:
		c1p = residue.findAtom("C1'")
		ba = residue.findAtom(anchor(info[ANCHOR], type))
		if c1p and ba:
			c1p.hide = False
			ba.hide = False

	if not orient:
		return na

	# show slab orientation by putting "bumps" on surface
	if standard['type'] == PYRIMIDINE:
		t = vrml.Transform()
		na.addChild(t)
		t.translation = (llx + urx) / 2.0, (lly + ury) / 2, halfThickness
		t.addChild(vrml.Sphere(radius=halfThickness, **color_kwds))
	else:
		# purine
		t = vrml.Transform()
		na.addChild(t)
		t.translation = (llx + urx) / 2.0, lly + (ury - lly) / 3, halfThickness
		t.addChild(vrml.Sphere(radius=halfThickness, **color_kwds))
		t = vrml.Transform()
		na.addChild(t)
		t.translation = (llx + urx) / 2.0, lly + (ury - lly) * 2 / 3, halfThickness
		t.addChild(vrml.Sphere(radius=halfThickness, **color_kwds))
	return na