Beispiel #1
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
Beispiel #2
0
def drawCylinder(radius, ep0, ep1, **kw):
	t = vrml.Transform()
	t.translation = chimera.Point([ep0, ep1]).data()
	delta = ep1 - ep0
	height = delta.length
	axis = chimera.cross(cylAxis, delta)
	cos = (cylAxis * delta) / height
	angle = math.acos(cos)
	t.rotation = (axis[0], axis[1], axis[2], angle)
	c = vrml.Cylinder(radius=radius, height=height, **kw)
	t.addChild(c)
	return t
 def Apply(self):
     molList = chimera.openModels.list(modelTypes=[chimera.Molecule])
     selList = self.molecules.curselection()
     if len(selList) != 1:
         return
     molName, molId, molSubid = self.molList[int(selList[0])]
     for m in molList:
         if m.id == molId and m.subid == molSubid:
             mol = m
             break
     else:
         replyobj.error('No selected molecule')
         return
     base.initialize()
     wrl = vrml.Transform()
     helices = base.displayHelices(mol, self.helixColor,
                                   self.helixFixedRadius.get(),
                                   self.helixRadius.get(),
                                   self.helixSplit.get(),
                                   self.helixSplitRatio.get())
     for node in helices:
         wrl.addChild(node)
     strands = base.displayStrands(mol, self.strandColor,
                                   self.strandFixedWidth.get(),
                                   self.strandWidth.get(),
                                   self.strandFixedThickness.get(),
                                   self.strandThickness.get(),
                                   self.strandSplit.get(),
                                   self.strandSplitRatio.get())
     for node in strands:
         wrl.addChild(node)
     if self.displayTurns.get():
         turns = base.displayTurns(mol, self.turnColor,
                                   self.turnWidth.get(),
                                   self.turnThickness.get())
         for node in turns:
             wrl.addChild(node)
     base.deinitialize()
     if not helices and not strands and not turns:
         replyobj.error('No helices, sheets, nor turns found')
         return
     try:
         chimera.openModels.close(self.openModels[mol])
     except KeyError:
         pass
     mList = chimera.openModels.open(vrml.vrml(wrl),
                                     type='VRML',
                                     sameAs=mol,
                                     identifyAs='%s - Pipes and Planks' %
                                     mol.name)
     self.openModels[mol] = mList[0]
     self.openModels[mList[0]] = None
Beispiel #4
0
def showStrand(strand, color, fixedWidth, width, fixedThickness, thickness,
               split, splitRatio):
    if len(strand) < 3:
        return []
    # Find box axes, length, width and thickness
    coords, centroid, axes = findAxes(strand, ['O'])
    for c in coords:
        s, t, u = parametricVars(centroid, axes, c)
        t = math.fabs(t)
        u = math.fabs(u)
        try:
            minS = min(s, minS)
            maxS = max(s, maxS)
            sumT = sumT + t
            minU = min(u, minU)
            maxU = max(u, maxU)
            sumU = sumU + u
        except NameError:
            minS = maxS = s
            sumT = t
            minU = maxU = u
            sumU = u
    if split and maxU / minU > splitRatio:
        front, back = splitResidues(strand, ['O'])
        if back:  # successful split
            return showStrand(front, color, fixedWidth, width,
               fixedThickness, thickness,
               split, splitRatio) \
             + showStrand(back, color, fixedWidth, width,
               fixedThickness, thickness,
               split, splitRatio)
    length = maxS + -minS
    center = (maxS + minS) / 2 * axes[0] + centroid
    if not fixedWidth:
        width = sumT / len(coords) * 2
    if not fixedThickness:
        thickness = sumU / len(coords) * 2
    hl = length / 2
    s, t, u = parametricVars(center, axes, coords[0])
    if maxS - s > s - minS:
        ssMap[strand[0]] = (center - hl * axes[0], -axes[0], axes[1], axes[2])
        ssMap[strand[-1]] = (center + hl * axes[0], axes[0], axes[1], axes[2])
    else:
        ssMap[strand[0]] = (center + hl * axes[0], axes[0], axes[1], axes[2])
        ssMap[strand[-1]] = (center - hl * axes[0], -axes[0], axes[1], axes[2])

    mat = [  # Note that the X axis is mapped onto length axis
        # ... and Y is mapped onto width axis
        [axes[0][0], axes[1][0], axes[2][0]],
        [axes[0][1], axes[1][1], axes[2][1]],
        [axes[0][2], axes[1][2], axes[2][2]]
    ]
    matrixNormalize(mat)
    xf = chimera.Xform.xform(mat[0][0], mat[0][1], mat[0][2], 0, mat[1][0],
                             mat[1][1], mat[1][2], 0, mat[2][0], mat[2][1],
                             mat[2][2], 0)
    rotAxis, angle = xf.getRotation()
    angle = angle / 180.0 * math.pi

    transform = vrml.Transform()
    trans = vrml.Transform(translation=(center[0], center[1], center[2]))
    transform.addChild(trans)
    rot = vrml.Transform(rotation=(rotAxis.x, rotAxis.y, rotAxis.z, angle))
    trans.addChild(rot)
    rgba = color.get().rgba()
    box = vrml.Box(size=(length, width, thickness), color=rgba[:3])
    if rgba[3] < 1.0:
        box.transparency = 1.0 - rgba[3]
    rot.addChild(box)
    return [transform]
Beispiel #5
0
def showHelix(helix, color, fixedRadius, radius, split, splitRatio):
    if len(helix) < 3:
        return []

    # Find cylinder axes, length and radius
    coords, centroid, axes = findAxes(helix, ['CA'])
    for c in coords:
        s, t, u = parametricVars(centroid, axes, c)
        d = math.sqrt(t * t + u * u)
        try:
            minS = min(s, minS)
            maxS = max(s, maxS)
            minD = min(d, minD)
            maxD = max(d, maxD)
            sumD = sumD + d
        except NameError:
            minS = maxS = s
            minD = maxD = d
            sumD = d
    if split and maxD / minD > splitRatio:
        front, back = splitResidues(helix, ['CA'])
        if back:  # successful split
            return showHelix(front, color, fixedRadius, radius,
               split, splitRatio) \
             + showHelix(back, color, fixedRadius, radius,
               split, splitRatio)
    if not fixedRadius:
        radius = sumD / len(coords)
    axisLength = maxS + -minS
    halfLength = axisLength / 2
    center = (maxS + minS) / 2 * axes[0] + centroid
    s, t, u = parametricVars(center, axes, coords[0])
    if maxS - s < s - minS:
        ssMap[helix[0]] = (center + halfLength * axes[0], axes[0], axes[1],
                           axes[2])
        ssMap[helix[-1]] = (center - halfLength * axes[0], -axes[0], axes[1],
                            axes[2])
    else:
        ssMap[helix[0]] = (center - halfLength * axes[0], -axes[0], axes[1],
                           axes[2])
        ssMap[helix[-1]] = (center + halfLength * axes[0], axes[0], axes[1],
                            axes[2])

    mat = [  # Note that the Y axis is mapped onto major axis
        [axes[1][0], axes[0][0], axes[2][0]],
        [axes[1][1], axes[0][1], axes[2][1]],
        [axes[1][2], axes[0][2], axes[2][2]]
    ]
    matrixNormalize(mat)
    xf = chimera.Xform.xform(mat[0][0], mat[0][1], mat[0][2], 0, mat[1][0],
                             mat[1][1], mat[1][2], 0, mat[2][0], mat[2][1],
                             mat[2][2], 0)
    rotAxis, angle = xf.getRotation()
    angle = angle / 180.0 * math.pi

    transform = vrml.Transform()
    trans = vrml.Transform(translation=(center[0], center[1], center[2]))
    transform.addChild(trans)
    rot = vrml.Transform(rotation=(rotAxis.x, rotAxis.y, rotAxis.z, angle))
    trans.addChild(rot)
    rgba = color.get().rgba()
    cylinder = vrml.Cylinder(radius=radius, height=axisLength, color=rgba[:3])
    if rgba[3] < 1.0:
        cylinder.transparency = 1.0 - rgba[3]
    rot.addChild(cylinder)
    return [transform]
Beispiel #6
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 #7
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