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
def surface_center_axis(surf, center, axis, csys): if center is None: have_box, box = surf.bbox() if have_box: c = box.center() else: from chimera import Point c = Point(0,0,0) elif csys: sixf = surf.openState.xform.inverse() c = sixf.apply(csys.xform.apply(center)) else: c = center if axis is None: from chimera import Vector a = Vector(0,0,1) elif csys: sixf = surf.openState.xform.inverse() a = sixf.apply(csys.xform.apply(axis)) else: a = axis return c.data(), a.data()
def apply_transform(self, xf): # Apply transform to models. from chimera import viewer, openModels as om, Point oslist = list(set([m.openState for m in om.list()])) # Activate inactive models in fly mode or all models mode. ialist = [] if self.fly_mode or self.all_models: ialist = [ os for os in set([m.openState for m in om.list()]) if not os.active ] for os in ialist: os.active = True if self.fly_mode: m, c = om.cofrMethod, om.cofr om.cofrMethod = om.Fixed view = 0 # TODO: use center between eyes for stereo e = Point(*viewer.camera.eyePos(view)) om.cofr = e # Rotate about eye position om.applyXform(xf.inverse()) om.cofr = c # Restore center of rotation om.cofrMethod = m else: om.applyXform(xf) for os in ialist: os.active = False
def report_correlations_with_rotation(v1, v2, aboveThreshold, axis, center, angleRange, plot): from chimera import Vector, Point, replyobj # Convert axis and center to v1 local coordinates so transformation # is still valid if user rotates entire scene. xf = v1.openState.xform.inverse() axis = xf.apply(Vector(*axis)).data() center = xf.apply(Point(*center)).data() import FitMap, Matrix replyobj.info('Correlation between %s and %s\n' % (v1.name, v2.name) + 'Rotation\tCorrelation\n') a0, a1, astep = angleRange angle = a0 clist = [] from Matrix import multiply_matrices, xform_matrix, rotation_transform, chimera_xform while angle < a1: tf = multiply_matrices(xform_matrix(v1.openState.xform), rotation_transform(axis, angle, center), xform_matrix(v1.openState.xform.inverse())) xf = chimera_xform(tf) olap, cor = FitMap.map_overlap_and_correlation(v1, v2, aboveThreshold, xf) replyobj.status('angle = %.4g, correlation = %.4g\n' % (angle, cor)) replyobj.info('%.4g\t%.4g\n' % (angle, cor)) clist.append((angle, cor)) angle += astep if plot: angles = [a for a, c in clist] corr = [c for a, c in clist] plot_correlation(angles, corr, v1, v2, axis, center)
def setBondLength(bond, bondLength, movingSide="smaller side", status=None): bond.molecule.idatmValid = False try: br = chimera.BondRot(bond) except ValueError, v: if "already used" in str(v): if status: status( "Cannot change length of active" " bond rotation\nDeactivate rotation" " and try again", color="red") return if "cycle" not in str(v): raise if status: status( "Bond involved in ring/cycle\n" "Moved bonded atoms (only) equally", color="blue") mid = Point([a.coord() for a in bond.atoms]) for a in bond.atoms: v = a.coord() - mid v.length = bondLength / 2 a.setCoord(mid + v) return
def _vmd_trans_angle(a, b, c, delta): """ Simulates VMD's `trans angle` command """ ZERO = Point(0, 0, 0) xf = chimera.Xform.translation(b - ZERO) xf.rotate(cross(a - b, b - c), delta) xf.translate(ZERO - b) return xf
def placeFragment(fragment, resName, model="scratch", position=None): """place a Fragment (see Fragment.py) 'resName' is the name of the new residue that will contain the fragment. (It will be in the 'het' chain.) 'model' can either be a chimera.Molecule instance or a string. If the latter, then a new model is created with the string as its .name attribute. 'position' can either be a chimera.Point or None. If None, then the fragment is positioned at the center of the view. """ if isinstance(model, basestring): model = _newModel(model) r = _newResidue(model, resName) needFocus = False if position is None: if len(chimera.openModels.list()) == 1: needFocus = True xf = model.openState.xform position = xf.inverse().apply(Point(*chimera.viewer.camera.center)) # find fragment center x = y = z = 0.0 for element, xyz in fragment.atoms: x += xyz[0] y += xyz[1] z += xyz[2] numAtoms = len(fragment.atoms) fragCenter = Point(x / numAtoms, y / numAtoms, z / numAtoms) correction = position - fragCenter from chimera.molEdit import addAtom, genAtomName atoms = [] for element, xyz in fragment.atoms: atoms.append( addAtom(genAtomName(element, r), Element(element), r, Point(*xyz) + correction)) for indices, depict in fragment.bonds: r.molecule.newBond(atoms[indices[0]], atoms[indices[1]]) if needFocus: chimera.runCommand("focus") return r
def singlePos(bondee, bondLen, toward=None, away=None): if toward: v = toward - bondee v.normalize() return bondee + v * bondLen elif away: v = bondee - away v.normalize() return bondee + v * bondLen return Point(bondee.x + bondLen, bondee.y, bondee.z)
def transform_atom_positions(atoms, tf, from_atoms = None): if from_atoms is None: from_atoms = atoms import _multiscale xyz = _multiscale.get_atom_coordinates(from_atoms, transformed = False) from _contour import affine_transform_vertices affine_transform_vertices(xyz, tf) from chimera import Point for i,a in enumerate(atoms): a.setCoord(Point(*xyz[i]))
def mark_zero(): from VolumePath import place_marker, show_volume_path_dialog from chimera import selection as s, Point mlist = s.currentGraphs() if len(mlist) == 0: place_marker((0, 0, 0)) else: for m in mlist: m0 = m.openState.xform.apply(Point(0, 0, 0)).data() place_marker(m0) show_volume_path_dialog()
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 restoreRemainder(): from SimpleSession.versions.v65 import restoreWindowSize, \ restoreOpenStates, restoreSelections, restoreFontInfo, \ restoreOpenModelsAttrs, restoreModelClip, restoreSilhouettes curSelIds = [] savedSels = [] openModelsAttrs = {'cofrMethod': 0} from chimera import Point openModelsAttrs['cofr'] = Point(-2.32628, -0.573985, 3.59536) windowSize = (1864, 872) xformMap = { 0: (((0.24085045920787, -0.88643853394015, -0.39524395231983), 31.611106929862), (-5.2556544062118, 0.24110915283208, 5.6843595710697), True), 1: (((-0.21724896247622, -0.52207222470775, 0.82476874364376), 155.76893615651), (-1.2842808932621, 1.6062919677941, 4.0957949649428), True), 2: (((0.28162879842346, -0.039178497638975, 0.95872324746056), 66.883398971617), (-0.868129924858, -1.6236021110072, -3.4048091153303), True) } fontInfo = {'face': ('Sans Serif', 'Normal', 16)} clipPlaneInfo = {} silhouettes = {0: True, 1: True, 2: True, 41: True} replyobj.status("Restoring window...", blankAfter=0, secondary=True) restoreWindowSize(windowSize) replyobj.status("Restoring open states...", blankAfter=0, secondary=True) restoreOpenStates(xformMap) replyobj.status("Restoring font info...", blankAfter=0, secondary=True) restoreFontInfo(fontInfo) replyobj.status("Restoring selections...", blankAfter=0, secondary=True) restoreSelections(curSelIds, savedSels) replyobj.status("Restoring openModel attributes...", blankAfter=0, secondary=True) restoreOpenModelsAttrs(openModelsAttrs) replyobj.status("Restoring model clipping...", blankAfter=0, secondary=True) restoreModelClip(clipPlaneInfo) replyobj.status("Restoring per-model silhouettes...", blankAfter=0, secondary=True) restoreSilhouettes(silhouettes) replyobj.status("Restoring remaining extension info...", blankAfter=0, secondary=True)
def _restoreSession(self, axisData, fromGeom=False): from SimpleSession import getColor, idLookup for i, data in enumerate(axisData.keys()): atomIDs = axisData[data] try: number, name, cmpVal, radius, colorID, extents, center,\ direction = data except ValueError: number = i + 1 name, cmpVal, radius, colorID, extents, center,\ direction = data atoms = [idLookup(a) for a in atomIDs] self._instantiateAxis(number, name, getColor(colorID), radius, self._getSourceModel(atoms), atoms, Point(*center), Vector(*direction), extents)
def parse_center_axis(center, axis, csys, cmdname): from Commands import parseCenterArg, parse_axis if isinstance(center, (tuple, list)): from chimera import Point center = Point(*center) ccs = csys elif center: center, ccs = parseCenterArg(center, cmdname) else: ccs = None if isinstance(axis, (tuple, list)): from chimera import Vector axis = Vector(*axis) axis_point = None acs = csys elif axis: axis, axis_point, acs = parse_axis(axis, cmdname) else: axis_point = None acs = None if not center and axis_point: # Use axis point if no center specified. center = axis_point ccs = acs # If no coordinate system specified use axis or center coord system. cs = (ccs or acs) if csys is None and cs: csys = cs xf = cs.xform.inverse() if center and not ccs: center = xf.apply(center) if axis and not acs: axis = xf.apply(axis) # Convert axis and center to requested coordinate system. if csys: xf = csys.xform.inverse() if center and ccs: center = xf.apply(ccs.xform.apply(center)) if axis and acs: axis = xf.apply(acs.xform.apply(axis)) return center, axis, csys
def addDihedralBond(a1, a2, length, angleInfo, dihedInfo): """Make bond between two models. The models will be combined and the originals closed. The new model will be opened in the same id/subid as the non-moving model. a1/a2 are atoms in different models. a2 and atoms in its model will be moved to form the bond. 'length' is the bond length. 'angleInfo' is a two-tuple of sequence of three atoms and an angle that the three atoms should form. 'dihedInfo' is like 'angleInfo', but 4 atoms. angleInfo/dihedInfo can be None if insufficient atoms """ if a1.molecule == a2.molecule: raise ValueError("Atoms to be bonded must be in different models") # first, get the distance correct from chimera import Xform, cross, angle, Point dvector = a1.xformCoord() - a2.xformCoord() dvector.length = dvector.length + length openState = a2.molecule.openState openState.globalXform(Xform.translation(dvector)) # then angle if angleInfo: atoms, angleVal = angleInfo p1, p2, p3 = [a.xformCoord() for a in atoms] axis = cross(p1 - p2, p2 - p3) curAngle = angle(p1, p2, p3) delta = angleVal - curAngle v2 = p2 - Point(0.0, 0.0, 0.0) trans1 = Xform.translation(v2) v2.negate() trans2 = Xform.translation(v2) trans1.multiply(Xform.rotation(axis, delta)) trans1.multiply(trans2) openState.globalXform(trans1)
def getPhiPlaneParams(acceptor, bonded1, bonded2): ap = acceptor.xformCoord() if bonded2: # two principal bonds phiPlane = [ap] midPoint = Vector(0.0, 0.0, 0.0) for bonded in [bonded1, bonded2]: pt = bonded.xformCoord() phiPlane.append(pt) midPoint = midPoint + pt.toVector() midPoint = midPoint / 2.0 phiBasePos = Point(midPoint.x, midPoint.y, midPoint.z) elif bonded1: # one principal bond phiBasePos = bonded1.xformCoord() grandBonded = bonded1.primaryNeighbors() for al in acceptor.allLocations(): if al in grandBonded: grandBonded.remove(al) break else: raise ValueError("No locations of acceptor %s found" " in bond list of %s" % (acceptor, bonded1)) if len(grandBonded) == 1: phiPlane = [ap, bonded1.xformCoord(), grandBonded[0].xformCoord()] elif len(grandBonded) == 2: phiPlane = [ap] for gb in grandBonded: phiPlane.append(gb.xformCoord()) elif len(grandBonded) == 0: # e.g. O2 phiPlane = None else: raise ConnectivityError("Wrong number of grandchild" " atoms for phi/psi acceptor %s" % acceptor.oslIdent()) else: return None, None return phiPlane, phiBasePos
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
def clip_models(models, axis, origin, coord, offset, stagger, flip, slab, thickness): if origin == 'center' or origin is None: screen_origin = center_of_models(models) elif coord == 'screen': screen_origin = origin else: screen_origin = None for m in models: default_plane = (tuple(m.clipPlane.normal.data()) == (0,0,0)) if origin is None and not default_plane: o = None elif screen_origin: xfinv = m.openState.xform.inverse() from chimera import Point o = xfinv.apply(Point(*screen_origin)).data() else: o = origin if axis is None: if default_plane: a = (0,0,1) else: a = None elif coord == 'screen': xfinv = m.openState.xform.inverse() from chimera import Vector a = xfinv.apply(Vector(*axis)).data() else: a = axis clip_model(m, a, o, offset, slab, thickness, flip) if not stagger is None: offset += stagger
def placeHelium(resName, model="scratch", position=None): """place a new helium atom 'resName' is the name of the new residue that will contain the helium. (It will be in the 'het' chain.) 'model' can either be a chimera.Molecule instance or a string. If the latter, then a new model is created with the string as its .name attribute. 'position' can either be a chimera.Point or None. If None, then the helium is positioned at the center of the view. """ if isinstance(model, basestring): model = _newModel(model) r = _newResidue(model, resName) if position is None: xf = model.openState.xform position = xf.inverse().apply(Point(*chimera.viewer.camera.center)) from chimera.molEdit import addAtom return addAtom('He1', Element('He'), r, position)
def bestLine(coords, weights=None): import numpy from numpy.linalg import eig, svd, eigh if weights != None: n = len(coords) matWeights = weights.reshape((n, 1)) wcoords = matWeights * coords wsum = weights.sum() centroid = wcoords.sum(0) / wsum centered = coords - centroid # Tom Goddard's method too subtle for me! #v33 = numpy.dot(coords.transpose(), wcoords) / wsum \ # - numpy.outer(centroid, centroid) #vals, vecs = eigh(v33) ignore, vals, vecs = svd(matWeights * centered) else: centroid = coords.mean(0) centered = coords - centroid ignore, vals, vecs = svd(centered) normLineVec = vecs[numpy.argmax(vals)] from chimera import Point, Vector return Point(*centroid), Vector(*normLineVec), centroid, normLineVec, \ centered, vals, vecs
def anglePos(atomPos, bondPos, bondLength, degrees, coplanar=None): if coplanar: # may have one or two coplanar positions specified, # if two, compute both resultant positions and average # (the up vector has to be negated for the second one) xforms = [] if len(coplanar) > 2: raise ValueError, \ "More than 2 coplanar positions specified!" for cpos in coplanar: up = cpos - atomPos if xforms: up.negate() xform = Xform.lookAt(atomPos, bondPos, up) # lookAt puts ref point opposite that of zAlign, so # rotate 180 degrees around y axis xform.premultiply(Xform.yRotation(180)) xforms.append(xform) else: xforms = [Xform.zAlign(atomPos, bondPos)] points = [] for xform in xforms: radians = pi * degrees / 180.0 angle = Point(0.0, bondLength * sin(radians), bondLength * cos(radians)) xform.invert() points.append(xform.apply(angle)) if len(points) > 1: midpoint = points[0] + (points[1] - points[0]) / 2.0 v = midpoint - atomPos v.length = bondLength return atomPos + v return points[0]
def findPt(n1, n2, n3, dist, angle, dihed): # cribbed from Midas addgrp command v12 = n2 - n1 v13 = n3 - n1 v12.normalize() x = cross(v13, v12) x.normalize() y = cross(v12, x) y.normalize() mat = [0.0] * 12 for i in range(3): mat[i * 4] = x[i] mat[1 + i * 4] = y[i] mat[2 + i * 4] = v12[i] mat[3 + i * 4] = n1[i] xform = Xform.xform(*mat) radAngle = pi * angle / 180.0 tmp = dist * sin(radAngle) radDihed = pi * dihed / 180.0 pt = Point(tmp * sin(radDihed), tmp * cos(radDihed), dist * cos(radAngle)) return xform.apply(pt)
def restoreMolecules(molInfo, resInfo, atomInfo, bondInfo, crdInfo): items = [] sm = globals.sessionMap res2mol = [] atom2mol = [] openModelsArgs = {} for ids, name, cid, display, lineWidth, pointSize, stickScale, \ pdbHeaders, surfaceOpacity, ballScale, vdwDensity, autochain, \ ribbonHidesMainchain in zip( expandSummary(molInfo['ids']), expandSummary(molInfo['name']), expandSummary(molInfo['color']), expandSummary(molInfo['display']), expandSummary(molInfo['lineWidth']), expandSummary(molInfo['pointSize']), expandSummary(molInfo['stickScale']), molInfo['pdbHeaders'], expandSummary(molInfo['surfaceOpacity']), expandSummary(molInfo['ballScale']), expandSummary(molInfo['vdwDensity']), expandSummary(molInfo['autochain']), expandSummary(molInfo['ribbonHidesMainchain']) ): m = chimera.Molecule() sm[len(items)] = m items.append(m) m.name = name from SimpleSession import modelMap, modelOffset chimera.openModels.add([m], baseId=ids[0] + modelOffset, subid=ids[1]) modelMap.setdefault(ids, []).append(m) m.color = getColor(cid) m.display = display m.lineWidth = lineWidth m.pointSize = pointSize m.stickScale = stickScale m.setAllPDBHeaders(pdbHeaders) m.surfaceOpacity = surfaceOpacity m.ballScale = ballScale m.vdwDensity = vdwDensity m.autochain = autochain m.ribbonHidesMainchain = ribbonHidesMainchain for mid, name, chain, pos, insert, rcid, lcid, ss, ribbonDrawMode, \ ribbonDisplay, label in zip( expandSummary(resInfo['molecule']), expandSummary(resInfo['name']), expandSummary(resInfo['chain']), resInfo['position'], expandSummary(resInfo['insert']), expandSummary(resInfo['ribbonColor']), expandSummary(resInfo['labelColor']), expandSummary(resInfo['ss']), expandSummary(resInfo['ribbonDrawMode']), expandSummary(resInfo['ribbonDisplay']), expandSummary(resInfo['label']) ): m = idLookup(mid) r = m.newResidue(name, chain, pos, insert) sm[len(items)] = r items.append(r) r.ribbonColor = getColor(rcid) r.labelColor = getColor(lcid) r.isHelix, r.isStrand, r.isTurn = ss r.ribbonDrawMode = ribbonDrawMode r.ribbonDisplay = ribbonDisplay r.label = label for rid, name, element, cid, vcid, lcid, scid, drawMode, display, \ label, surfaceDisplay, surfaceCategory, surfaceOpacity, radius, vdw, \ bfactor, occupancy, charge, idatmType in zip( expandSummary(atomInfo['residue']), expandSummary(atomInfo['name']), expandSummary(atomInfo['element']), expandSummary(atomInfo['color']), expandSummary(atomInfo['vdwColor']), expandSummary(atomInfo['labelColor']), expandSummary(atomInfo['surfaceColor']), expandSummary(atomInfo['drawMode']), expandSummary(atomInfo['display']), expandSummary(atomInfo['label']), expandSummary(atomInfo['surfaceDisplay']), expandSummary(atomInfo['surfaceCategory']), expandSummary(atomInfo['surfaceOpacity']), expandSummary(atomInfo['radius']), expandSummary(atomInfo['vdw']), expandSummary(atomInfo['bfactor']), expandSummary(atomInfo['occupancy']), expandSummary(atomInfo['charge']), expandSummary(atomInfo['idatmType']) ): r = idLookup(rid) a = r.molecule.newAtom(name, chimera.Element(element)) sm[len(items)] = a items.append(a) r.addAtom(a) a.color = getColor(cid) a.vdwColor = getColor(vcid) a.labelColor = getColor(lcid) a.surfaceColor = getColor(scid) a.drawMode = drawMode a.display = display a.label = label a.surfaceDisplay = surfaceDisplay a.surfaceCategory = surfaceCategory a.surfaceOpacity = surfaceOpacity a.radius = radius a.vdw = vdw if bfactor is not None: a.bfactor = bfactor if occupancy is not None: a.occupancy = occupancy if charge is not None: a.charge = charge if idatmType: a.idatmType = idatmType for atoms, drawMode, display in zip(bondInfo['atoms'], expandSummary(bondInfo['drawMode']), expandSummary(bondInfo['display'])): a1, a2 = [idLookup(a) for a in atoms] b = a1.molecule.newBond(a1, a2) sm[len(items)] = b items.append(b) b.drawMode = drawMode b.display = display from chimera import Point for mid, crdSets in crdInfo.items(): m = idLookup(mid) active = crdSets.pop('active') for key, crds in crdSets.items(): coordSet = m.newCoordSet(key, len(crds)) for aid, crdString in crds: idLookup(aid).setCoord( Point(*tuple([float(c) for c in crdString.split()])), coordSet) if key == active: m.activeCoordSet = coordSet
def axis(coords, findBounds=False, findRadius=False, iterate=True, weights=None): """Compute an axis given an Nx3 Numpy array. Returns a Point (centroid) and a Vector (unit direction vector). If 'findBounds' is True, returns two additional floating point values -- the scaling factors for the vector to reach the approximate bounds of the axis defined by the array values. If 'findRadius' is True, returns yet another floating-point value: the average coord-axis distance. 'weights' is a numpy array used to weight the 'coords'; typicaly used for mass weighting. Tip: you generally generate the input Numpy array with numpyArrayFromAtoms() """ if weights != None and iterate: raise ValueError("'iterate' does not consider 'weights'") import numpy from chimera import Point, Vector def reshapeTo(source, target): scalings = numpy.repeat(source, 3) scalings.shape = len(target), 3 return scalings pt, longVec, centroid, normLineVec, centered, vals, vecs = bestLine( coords, weights=weights) # for short helices, best axis not necessarily longest normLineVec = vecs[numpy.argmin([axisEval(v, centered) for v in vecs])] vec = Vector(*normLineVec) best = None while iterate: # nearest point on line ts = numpy.tensordot(normLineVec, centered, (0, 1)) \ / numpy.dot(normLineVec, normLineVec) linePts = numpy.outer(ts, normLineVec) # distance temp = (centered - linePts) dists = numpy.sqrt((temp * temp).sum(-1)) avgDist = dists.mean(0) diffs = dists - avgDist val = (diffs * diffs).sum() if best == None or val < best: best = val oldPt = pt oldVec = vec oldCentered = centered oldLineVec = normLineVec else: pt = oldPt vec = oldVec centered = oldCentered normLineVec = oldLineVec break # find the point that is 1/3 from the current distance to # the average distance and correct line and centroid based # on that point nonzero = dists > 0.0001 if not len(nonzero): break nzCentered = centered.compress(nonzero, 0) nzLinePts = linePts.compress(nonzero, 0) nzDists = dists.compress(nonzero, 0) correctionTargets = linePts + (nzCentered - linePts) * reshapeTo( (2 + avgDist / nzDists) / 3.0, nzCentered) # centroid motion #centroid += (correctionTargets - nzLinePts).mean(0) # vector correction corrVecs = correctionTargets dots = (corrVecs * normLineVec).sum(1) corrVecs[dots < 0] *= -1 normLineVec = corrVecs.mean(0) normLineVec /= numpy.sqrt((normLineVec * normLineVec).sum()) centered = coords - centroid pt = Point(*centroid) vec = Vector(*normLineVec) retVals = (pt, vec) if findBounds: dotted = numpy.dot(centered, normLineVec) retVals += (dotted.min(), dotted.max()) if findRadius: dists = axisDists(normLineVec, centered) retVals += (dists.mean(0), ) return retVals
def Apply(self): savePaths = self.getPaths() if not savePaths: replyobj.error("No save file specified\n") return from OpenSave import osOpen saveFile = osOpen(savePaths[0], "w") mols = chimera.openModels.list(modelTypes=[chimera.Molecule]) for mol in mols: print>>saveFile, "Model %s is %s" % (mol.oslIdent(), mol.name) sm = self.structMeasure selected = self.saveTypes.getcurselection() if DISTANCES in selected: print>>saveFile, "\nDistance information" output = {} for d in sm.distances: a1, a2 = d.atoms distID = d.id if d.distance[-1].isdigit(): dval = d.distance else: # omit angstrom character dval = d.distance[:-1] output[distID] = "%2d %s <-> %s: %s" % ( distID, sm.atomLabel(a1), sm.atomLabel(a2), dval) ids = output.keys() ids.sort() for distID in ids: print>>saveFile, output[distID] if ANGLES in selected: print>>saveFile, "\nAngles/Torsions" printables = [] maxLabel = 0 for atoms in sm.angleInfo: labelArgs = tuple([sm.atomLabel(a) for a in atoms]) if len(atoms) == 3: label = "%s -> %s -> %s" % labelArgs func = chimera.angle else: label = "%s -> %s -> %s -> %s" \ % labelArgs func = chimera.dihedral maxLabel = max(maxLabel, len(label)) printables.append((label, "%8.3f" % func(*tuple([a.xformCoord() for a in atoms])))) format = "%%%ds: %%s" % maxLabel for printArgs in printables: print>>saveFile, format % printArgs if BONDROTS in selected: print>>saveFile, "\nBond rotations" printables = [] maxLabel = 0 for br in sm.rotations: na, fa = sm.dihedEndAtoms(br) label = "%s -> %s -> %s -> %s" % ( sm.atomLabel(na), sm.atomLabel(br.atoms[0]), sm.atomLabel(br.atoms[1]), sm.atomLabel(fa)) maxLabel = max(maxLabel, len(label)) printables.append((label, "%8.3f" % sm.dihedral(br), "%8.3f" % br.get())) format = "%%%ds: %%s (delta: %%s)" % maxLabel for printArgs in printables: print>>saveFile, format % printArgs if GEOMETRIES in selected: print>>saveFile, "\nAxes" print>>saveFile, "axis name, length, center, direction" from Axes import axisManager axes = axisManager.axes axes.sort(lambda a1, a2: cmp(a1.name, a2.name)) nameSize = max([0] + [len(a.name) for a in axes]) from chimera import Point for axis in axes: ends = [axis.direction * ext + axis.center for ext in axis.extents] cx, cy, cz = Point(ends) dx, dy, dz = axis.direction print>>saveFile, "%*s: %6.3f (%7.3f, %7.3f," \ " %7.3f) (%6.3f, %6.3f, %6.3f)" % ( nameSize, axis.name, abs(axis.extents[0] - axis.extents[1]), cx, cy, cz, dx, dy, dz) print>>saveFile, "\nPlanes" print>>saveFile, "plane name, center, normal, radius" from Planes import planeManager planes = planeManager.planes planes.sort(lambda p1, p2: cmp(p1.name, p2.name)) nameSize = max([0] + [len(pl.name) for pl in planes]) for plane in planes: ox, oy, oz = plane.plane.origin nx, ny, nz = plane.plane.normal print>>saveFile, "%*s: (%7.3f, %7.3f, %7.3f)" \ " (%6.3f, %6.3f, %6.3f) %.3f" % (nameSize, plane.name, ox, oy, oz, nx, ny, nz, plane.radius) saveFile.close()
def xform_xyz(xyz, from_xform=None, to_xform=None): from chimera import Point p = Point(*tuple(xyz)) p1 = from_xform.apply(p) if from_xform else p p2 = to_xform.inverse().apply(p1) if to_xform else p1 return (p2.x, p2.y, p2.z)
from chimera import runCommand from chimera import openModels, Molecule from os import chdir, listdir import chimera from WriteMol2 import writeMol2 import sys file = open("com.txt") for line in file: if line.find("centroid has center") != -1: #print "OPENED:%s" % line word = line.split() #print word x = float(word[3]) y = float(word[4]) z = float(word[5]) + 16 center = Point(x, y, z) runCommand("open " + sys.argv[1]) model0 = openModels.list(id=0, modelTypes=[Molecule])[0] c = BuildStructure.placeHelium('com', model=model0, position=center) runCommand("select He") runCommand("namesel helium") runCommand("select helium za>10") runCommand("del sel") runCommand("del helium") writeMol2(chimera.openModels.list(modelTypes=[chimera.Molecule]), sys.argv[1][:-4] + ".mol2") runCommand("close all")
def placePeptide(sequence, phiPsis, model="scratch", position=None, rotlib=None, chainID='A'): """place a peptide sequence 'sequence' contains the (upper case) sequence 'phiPsis' is a list of phi/psi tuples, one per residue 'model' can either be a chimera.Molecule instance or a string. If the latter, then a new model is created with the string as its .name attribute. 'position' can either be a chimera.Point or None. If None, then the fragment is positioned at the center of the view. """ if not sequence: raise ValueError("No sequence supplied") sequence = sequence.upper() if not sequence.isupper(): raise ValueError("Sequence contains non-alphabetic characters") from chimera.resCode import protein1to3 for c in sequence: if c not in protein1to3: raise ValueError("Unrecognized protein 1-letter code:" " %s" % c) if len(sequence) != len(phiPsis): raise ValueError("Number of phi/psis not equal to" " sequence length") if isinstance(model, basestring): model = _newModel(model) needFocus = False if position is None: if len(chimera.openModels.list()) == 1: needFocus = True xf = model.openState.xform position = xf.inverse().apply(Point(*chimera.viewer.camera.center)) prev = [None] * 3 pos = 1 from Midas.addAA import DIST_N_C, DIST_CA_N, DIST_C_CA, DIST_C_O from chimera.molEdit import findPt, addAtom, addDihedralAtom serialNumber = None residues = [] for c, phiPsi in zip(sequence, phiPsis): phi, psi = phiPsi while model.findResidue(chimera.MolResId(chainID, pos)): pos += 1 r = model.newResidue(protein1to3[c], chainID, pos, ' ') residues.append(r) for backbone, dist, angle, dihed in (('N', DIST_N_C, 116.6, psi), ('CA', DIST_CA_N, 121.9, 180.0), ('C', DIST_C_CA, 110.1, phi)): if prev[0] == None: pt = Point(0.0, 0.0, 0.0) elif prev[1] == None: pt = Point(dist, 0.0, 0.0) elif prev[2] == None: pt = findPt(prev[0].coord(), prev[1].coord(), Point(0.0, 1.0, 0.0), dist, angle, 0.0) else: pt = findPt(prev[0].coord(), prev[1].coord(), prev[2].coord(), dist, angle, dihed) a = addAtom(backbone, Element(backbone[0]), r, pt, serialNumber=serialNumber, bondedTo=prev[0]) serialNumber = a.serialNumber + 1 prev = [a] + prev[:2] o = addDihedralAtom("O", Element("O"), prev[0], prev[1], prev[2], DIST_C_O, 120.4, 180.0 + psi, bonded=True) # C terminus O/OXT at different angle than mainchain O model.deleteAtom(o) addDihedralAtom("O", Element("O"), prev[0], prev[1], prev[2], DIST_C_O, 117.0, 180.0 + psi, bonded=True) addDihedralAtom("OXT", Element("O"), prev[0], prev[1], prev[2], DIST_C_O, 117.0, psi, bonded=True) from Rotamers import useBestRotamers # have to process one by one, otherwise side-chain clashes will occur kw = {} if rotlib: kw['lib'] = rotlib for r in residues: useBestRotamers("same", [r], criteria="cp", log=False, **kw) # find peptide center coords = [] for r in residues: coords.extend([a.coord() for a in r.atoms]) center = Point(coords) correction = position - center for r in residues: for a in r.atoms: a.setCoord(a.coord() + correction) from Midas import ksdssp ksdssp([model]) if needFocus: chimera.runCommand("focus") return residues
def restoreMolecules(molInfo, resInfo, atomInfo, bondInfo, crdInfo): from SimpleSession import registerAttribute items = [] sm = globals.sessionMap res2mol = [] atom2mol = [] for ids, name, cid, display, lineWidth, pointSize, stickScale, \ pdbHeaders, surfaceOpacity, ballScale, vdwDensity, autochain, \ ribbonHidesMainchain, riCID, aromaticCID, aromaticDisplay, \ aromaticLineType, aromaticMode, hidden in zip( expandSummary(molInfo['ids']), expandSummary(molInfo['name']), expandSummary(molInfo['color']), expandSummary(molInfo['display']), expandSummary(molInfo['lineWidth']), expandSummary(molInfo['pointSize']), expandSummary(molInfo['stickScale']), molInfo['pdbHeaders'], expandSummary(molInfo['surfaceOpacity']), expandSummary(molInfo['ballScale']), expandSummary(molInfo['vdwDensity']), expandSummary(molInfo['autochain']), expandSummary(molInfo['ribbonHidesMainchain']), expandSummary(molInfo['ribbonInsideColor']), expandSummary(molInfo['aromaticColor']), expandSummary(molInfo['aromaticDisplay']), expandSummary(molInfo['aromaticLineType']), expandSummary(molInfo['aromaticMode']), expandSummary(molInfo['hidden']) ): m = chimera.Molecule() sm[len(items)] = m items.append(m) m.name = name from SimpleSession import modelMap, modelOffset chimera.openModels.add([m], baseId=ids[0] + modelOffset, subid=ids[1], hidden=hidden) modelMap.setdefault(ids, []).append(m) m.color = getColor(cid) m.display = display m.lineWidth = lineWidth m.pointSize = pointSize m.stickScale = stickScale m.setAllPDBHeaders(pdbHeaders) m.surfaceOpacity = surfaceOpacity m.ballScale = ballScale m.vdwDensity = vdwDensity m.autochain = autochain m.ribbonHidesMainchain = ribbonHidesMainchain m.ribbonInsideColor = getColor(riCID) m.aromaticColor = getColor(aromaticCID) m.aromaticDisplay = aromaticDisplay m.aromaticLineType = aromaticLineType m.aromaticMode = aromaticMode if molInfo['optional']: for attrName, info in molInfo['optional'].items(): hashable, sv = info registerAttribute(chimera.Molecule, attrName, hashable=hashable) vals = expandSummary(sv, hashable=hashable) for m, val in zip(items, vals): if val is not None: setattr(m, attrName, val) resStart = len(items) for mid, name, chain, pos, insert, rcid, lcid, ss, ssId, ribbonDrawMode, \ ribbonDisplay, label, labelOffset, isHet, fillDisplay, fillMode in zip( expandSummary(resInfo['molecule']), expandSummary(resInfo['name']), expandSummary(resInfo['chain']), expandSequentialSummary(resInfo['position']), expandSummary(resInfo['insert']), expandSummary(resInfo['ribbonColor']), expandSummary(resInfo['labelColor']), expandSummary(resInfo['ss']), expandSummary(resInfo['ssId']), expandSummary(resInfo['ribbonDrawMode']), expandSummary(resInfo['ribbonDisplay']), expandSummary(resInfo['label']), expandSummary(resInfo['labelOffset']), expandSummary(resInfo['isHet']), expandSummary(resInfo['fillDisplay']), expandSummary(resInfo['fillMode']), ): m = idLookup(mid) r = m.newResidue(name, chain, pos, insert) sm[len(items)] = r items.append(r) r.ribbonColor = getColor(rcid) r.labelColor = getColor(lcid) r.isHelix, r.isStrand, r.isTurn = ss r.ssId = ssId r.ribbonDrawMode = ribbonDrawMode r.ribbonDisplay = ribbonDisplay r.label = label if labelOffset is not None: r.labelOffset = labelOffset r.isHet = isHet r.fillDisplay = fillDisplay r.fillMode = fillMode if resInfo['optional']: residues = items[resStart:] for attrName, info in resInfo['optional'].items(): hashable, sv = info registerAttribute(chimera.Residue, attrName, hashable=hashable) vals = expandSummary(sv, hashable=hashable) for r, val in zip(residues, vals): if val is not None: setattr(r, attrName, val) atomStart = len(items) for rid, name, element, cid, vcid, lcid, scid, drawMode, display, \ label, labelOffet, surfaceDisplay, surfaceCategory, surfaceOpacity, \ radius, vdw, idatmType, altLoc in zip( expandSummary(atomInfo['residue']), expandSummary(atomInfo['name']), expandSummary(atomInfo['element']), expandSummary(atomInfo['color']), expandSummary(atomInfo['vdwColor']), expandSummary(atomInfo['labelColor']), expandSummary(atomInfo['surfaceColor']), expandSummary(atomInfo['drawMode']), expandSummary(atomInfo['display']), expandSummary(atomInfo['label']), expandSummary(atomInfo['labelOffset']), expandSummary(atomInfo['surfaceDisplay']), expandSummary(atomInfo['surfaceCategory']), expandSummary(atomInfo['surfaceOpacity']), expandSummary(atomInfo['radius']), expandSummary(atomInfo['vdw']), expandSummary(atomInfo['idatmType']), expandSummary(atomInfo['altLoc']) ): r = idLookup(rid) a = r.molecule.newAtom(name, chimera.Element(element)) sm[len(items)] = a items.append(a) r.addAtom(a) a.color = getColor(cid) a.vdwColor = getColor(vcid) a.labelColor = getColor(lcid) a.surfaceColor = getColor(scid) a.drawMode = drawMode a.display = display a.label = label if labelOffset is not None: a.labelOffset = labelOffset a.surfaceDisplay = surfaceDisplay a.surfaceCategory = surfaceCategory a.surfaceOpacity = surfaceOpacity a.radius = radius a.vdw = vdw if idatmType: a.idatmType = idatmType a.altLoc = altLoc if atomInfo['optional']: atoms = items[atomStart:] for attrName, info in atomInfo['optional'].items(): hashable, sv = info registerAttribute(chimera.Atom, attrName, hashable=hashable) vals = expandSummary(sv, hashable=hashable) for a, val in zip(atoms, vals): if val is not None: setattr(a, attrName, val) bondStart = len(items) for atoms, drawMode, display, label, labelOffset, radius in zip( bondInfo['atoms'], expandSummary(bondInfo['drawMode']), expandSummary(bondInfo['display']), expandSummary(bondInfo['label']), expandSummary(bondInfo['labelOffset']), expandSummary(bondInfo['radius'])): a1, a2 = [idLookup(a) for a in atoms] b = a1.molecule.newBond(a1, a2) sm[len(items)] = b items.append(b) b.drawMode = drawMode b.display = display b.label = label if labelOffset is not None: b.labelOffset = labelOffset b.radius = radius if bondInfo.get('optional', {}): bonds = items[bondStart:] for attrName, info in bondInfo['optional'].items(): hashable, sv = info registerAttribute(chimera.Bond, attrName, hashable=hashable) vals = expandSummary(sv, hashable=hashable) for b, val in zip(bonds, vals): if val is not None: setattr(b, attrName, val) from chimera import Point for mid, crdSets in crdInfo.items(): m = idLookup(mid) active = crdSets.pop('active') for key, crds in crdSets.items(): coordSet = m.newCoordSet(key, len(crds)) for aid, crdString in crds: idLookup(aid).setCoord( Point(*tuple([float(c) for c in crdString.split()])), coordSet) if key == active: m.activeCoordSet = coordSet
def restoreRemainder(): from SimpleSession.versions.v65 import restoreWindowSize, \ restoreOpenStates, restoreSelections, restoreFontInfo, \ restoreOpenModelsAttrs, restoreModelClip, restoreSilhouettes curSelIds = [] savedSels = [] openModelsAttrs = {'cofrMethod': 0} from chimera import Point openModelsAttrs['cofr'] = Point(54.1036, 9.4266, 4.26939) windowSize = (904, 945) xformMap = { 0: (((-0.30580948052178, 0.30245992253846, 0.90277270499336), 116.52999621315), (75.916893346571, -22.475613343026, 33.625921716357), True), 1: (((-0.30580948052178, 0.30245992253846, 0.90277270499336), 116.52999621315), (75.916893346571, -22.475613343026, 33.625921716357), True), 2: (((-0.30580948052178, 0.30245992253846, 0.90277270499336), 116.52999621315), (75.916893346571, -22.475613343026, 33.625921716357), True), 3: (((-0.30580948052178, 0.30245992253846, 0.90277270499336), 116.52999621315), (75.916893346571, -22.475613343026, 33.625921716357), True), 4: (((-0.30580948052178, 0.30245992253846, 0.90277270499336), 116.52999621315), (75.916893346571, -22.475613343026, 33.625921716357), True), 5: (((-0.30580948052178, 0.30245992253846, 0.90277270499336), 116.52999621315), (75.916893346571, -22.475613343026, 33.625921716357), True) } fontInfo = {'face': (u'Fixed', u'Bold', 24)} clipPlaneInfo = {} silhouettes = { 0: True, 1: True, 2: True, 3: True, 4: True, 5: True, 374: True } replyobj.status("Restoring window...", blankAfter=0, secondary=True) restoreWindowSize(windowSize) replyobj.status("Restoring open states...", blankAfter=0, secondary=True) restoreOpenStates(xformMap) replyobj.status("Restoring font info...", blankAfter=0, secondary=True) restoreFontInfo(fontInfo) replyobj.status("Restoring selections...", blankAfter=0, secondary=True) restoreSelections(curSelIds, savedSels) replyobj.status("Restoring openModel attributes...", blankAfter=0, secondary=True) restoreOpenModelsAttrs(openModelsAttrs) replyobj.status("Restoring model clipping...", blankAfter=0, secondary=True) restoreModelClip(clipPlaneInfo) replyobj.status("Restoring per-model silhouettes...", blankAfter=0, secondary=True) restoreSilhouettes(silhouettes) replyobj.status("Restoring remaining extension info...", blankAfter=0, secondary=True)