def bounding_xray_map_symmetry(atoms, pad, volume): # Get atom positions. from _multiscale import get_atom_coordinates xyz = get_atom_coordinates(atoms, transformed = True) # Transform atom coordinates to volume ijk indices. from Matrix import multiply_matrices, xform_matrix tf = multiply_matrices(volume.data.xyz_to_ijk_transform, xform_matrix(volume.model_transform().inverse())) from _contour import affine_transform_vertices affine_transform_vertices(xyz, tf) ijk = xyz # Find integer bounds. from math import floor, ceil ijk_min = [int(floor(i-pad)) for i in ijk.min(axis=0)] ijk_max = [int(ceil(i+pad)) for i in ijk.max(axis=0)] #gather information about unit cell and symmetry ijk_cell_size = getattr(volume.data, 'unit_cell_size', volume.data.size) syms = volume.data.symmetries step = volume.data.step from VolumeFilter import cover cg = cover.map_covering_box(volume, ijk_min, ijk_max, ijk_cell_size, syms, step) from VolumeViewer import volume_from_grid_data v = volume_from_grid_data(cg, show_data = False) v.copy_settings_from(volume, copy_region = False) return v
def center_of_atoms(atoms): from _multiscale import get_atom_coordinates xyz = get_atom_coordinates(atoms) from numpy import sum center = tuple(sum(xyz, axis=0) / len(xyz)) return center
def grid_sas_surface(atoms, probe_radius=1.4, grid_spacing=0.5): """ Stripped from Chimera's Surface.gridsurf """ xyz = get_atom_coordinates(atoms, transformed=False) radii = np.array([a.radius for a in atoms], np.float32) # Compute bounding box for atoms xyz_min, xyz_max = bounding_box(xyz) pad = 2 * probe_radius + radii.max() origin = [x - pad for x in xyz_min] # Create 3d grid for computing distance map s = grid_spacing shape = [ int(ceil((xyz_max[a] - xyz_min[a] + 2 * pad) / s)) for a in (2, 1, 0) ] matrix = np.empty(shape, np.float32) max_index_range = 2 matrix[:, :, :] = max_index_range # Transform centers and radii to grid index coordinates xyz_to_ijk_tf = ((1.0 / s, 0, 0, -origin[0] / s), (0, 1.0 / s, 0, -origin[1] / s), (0, 0, 1.0 / s, -origin[2] / s)) ijk = xyz.copy() transform_points(ijk, xyz_to_ijk_tf) probed_radii = radii.copy() probed_radii += probe_radius probed_radii /= s # Compute distance map from surface of spheres, positive outside. sphere_surface_distance(ijk, probed_radii, max_index_range, matrix) # Get the SAS surface as a contour surface of the distance map return contour_surface(matrix, 0, cap_faces=False, calculate_normals=False)
def center_of_atoms(atoms): from _multiscale import get_atom_coordinates xyz = get_atom_coordinates(atoms) from numpy import sum center = tuple(sum(xyz, axis=0) / len(xyz)) return center
def molecule_center(molecule): from _multiscale import get_atom_coordinates xyz = get_atom_coordinates(molecule.atoms) if len(xyz) == 0: return (0,0,0) c = tuple(xyz.mean(axis = 0)) return c
def atom_coordinates(atoms, xform): from _multiscale import get_atom_coordinates xyz = get_atom_coordinates(atoms, transformed = True) from Matrix import xform_matrix tf = xform_matrix(xform.inverse()) from _contour import affine_transform_vertices affine_transform_vertices(xyz, tf) return xyz
def path_points(atoms, bonds, xform_to_surface, bond_point_spacing=None): points = get_atom_coordinates(atoms, xform_to_surface) from bondzone import bond_points, concatenate_points bpoints = bond_points(bonds, xform_to_surface, bond_point_spacing) if len(bpoints) > 0: points = concatenate_points(points, bpoints) return points
def atoms_outside_map(atoms, dr, contour_level): from _multiscale import get_atom_coordinates xyz = get_atom_coordinates(atoms, transformed = True) from chimera import Xform values = dr.interpolated_values(xyz, Xform()) from numpy import compress aolist = list(compress(values < contour_level, atoms)) return aolist
def atoms_outside_map(atoms, dr, contour_level): from _multiscale import get_atom_coordinates xyz = get_atom_coordinates(atoms, transformed=True) from chimera import Xform values = dr.interpolated_values(xyz, Xform()) from numpy import compress aolist = list(compress(values < contour_level, atoms)) return aolist
def get_atom_coordinates(atoms, xform): from _multiscale import get_atom_coordinates xyz = get_atom_coordinates(atoms, transformed = True) from _contour import affine_transform_vertices from Matrix import xform_matrix affine_transform_vertices(xyz, xform_matrix(xform)) return xyz
def path_points(atoms, bonds, xform_to_surface, bond_point_spacing = None): points = get_atom_coordinates(atoms, xform_to_surface) from bondzone import bond_points, concatenate_points bpoints = bond_points(bonds, xform_to_surface, bond_point_spacing) if len(bpoints) > 0: points = concatenate_points(points, bpoints) return points
def atom_positions(atoms, xform = None): import _multiscale xyz = _multiscale.get_atom_coordinates(atoms, transformed = True) if xform: from Matrix import xform_matrix tf = xform_matrix(xform.inverse()) from _contour import affine_transform_vertices affine_transform_vertices(xyz, tf) return xyz
def get_atom_coordinates(atoms, xform): from _multiscale import get_atom_coordinates xyz = get_atom_coordinates(atoms, transformed=True) from _contour import affine_transform_vertices from Matrix import xform_matrix affine_transform_vertices(xyz, xform_matrix(xform)) return xyz
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 chimeracoords2numpy(molecule): """ Parameters ---------- molecule : chimera.molecule Returns ------- numpy.array with molecule.atoms coordinates """ return get_atom_coordinates(molecule.atoms, transformed=False)
def colorEsp(surf, colors, vals, dielectric=4.0, distDep=True, surfDist=1.4, hisScheme="HID"): from chimera import MaterialColor if isinstance(colors[0], MaterialColor): colors = [mc.rgba() for mc in colors] if len(colors) != len(vals) and len(colors) != len(vals) + 2: raise ValueError("Number of colors (%d) must be the same as" " number of values or number of values +2 (%d, %d)" % (len(colors), len(vals), len(vals) + 2)) # are charges available? # don't use checkNoCharges() since that may add hydrogens and # therefore change surface atoms = surf.atoms try: # are charges missing or None? [a.charge + 1.0 for a in atoms] except (AttributeError, TypeError): _chargeAtoms(atoms, hisScheme) replyobj.status("Computing electrostatics") from _multiscale import get_atom_coordinates coords = get_atom_coordinates(atoms) import numpy charges = numpy.array([a.charge for a in atoms]) from _esp import computeEsp piece = surf.surface_piece vertices, triangles = piece.geometry normals = piece.normals potentials = computeEsp(vertices, normals, coords, charges, dielectric=dielectric, distDep=distDep, surfDist=surfDist) belowColor = colors[0] aboveColor = colors[-1] if len(colors) == len(vals) + 2: colors = colors[1:-1] from SurfaceColor import interpolate_colormap rgbas = interpolate_colormap(potentials, vals, colors, aboveColor, belowColor) from Surface import set_coloring_method set_coloring_method('ESP coloring', surf, None) replyobj.status("Coloring surface") surf.surface_piece.vertexColors = rgbas surf.surface_piece.using_surface_coloring = True replyobj.status("Surface colored")
def molecule_atom_set(ma): m, atoms = ma from _multiscale import get_atom_coordinates xyz = get_atom_coordinates(atoms) from Matrix import xform_matrix transform = xform_matrix(m.openState.xform) aset = Atom_Set(xyz, transform, atoms) return aset
def chain_atom_subset(ca): cp, atoms = ca from _multiscale import get_atom_coordinates xyz = get_atom_coordinates(atoms) # transform = chain_transform(cp) from Matrix import xform_matrix transform = xform_matrix(cp.surface_model().openState.xform) aset = Atom_Set(xyz, transform, atoms, cp) return aset
def molecule_grid_data(atoms, resolution, step, pad, cutoff_range, sigma_factor): from _multiscale import get_atom_coordinates, bounding_box xyz = get_atom_coordinates(atoms, transformed=True) # Transform coordinates to local coordinates of the molecule containing # the first atom. This handles multiple unaligned molecules. from Matrix import xform_matrix m0 = atoms[0].molecule tf = xform_matrix(m0.openState.xform.inverse()) from _contour import affine_transform_vertices affine_transform_vertices(xyz, tf) xyz_min, xyz_max = bounding_box(xyz) origin = [x - pad for x in xyz_min] ijk = (xyz - origin) / step anum = [a.element.number for a in atoms] sdev = sigma_factor * resolution / step from numpy import zeros, float32 sdevs = zeros((len(atoms), 3), float32) sdevs[:] = sdev from math import pow, pi, ceil normalization = pow(2 * pi, -1.5) * pow(sdev * step, -3) shape = [ int(ceil((xyz_max[a] - xyz_min[a] + 2 * pad) / step)) for a in (2, 1, 0) ] matrix = zeros(shape, float32) from _gaussian import sum_of_gaussians sum_of_gaussians(ijk, anum, sdevs, cutoff_range, matrix) matrix *= normalization molecules = set([a.molecule for a in atoms]) if len(molecules) > 1: name = 'molmap res %.3g' % (resolution, ) else: name = 'molmap %s res %.3g' % (m0.name, resolution) from VolumeData import Array_Grid_Data grid = Array_Grid_Data(matrix, origin, (step, step, step), name=name) return grid, molecules
def set_atom_volume_values(molecule, volume_data_region, attribute_name): atoms = molecule.atoms from _multiscale import get_atom_coordinates xyz = get_atom_coordinates(atoms) # Untransformed coordinates xyz_xform = molecule.openState.xform dr = volume_data_region values, outside = dr.interpolated_values(xyz, xyz_xform, out_of_bounds_list = True) n = len(atoms) for a in range(n): v = float(values[a]) # Use float otherwise get a NumPy scalar. setattr(atoms[a], attribute_name, v) for a in outside: setattr(atoms[a], attribute_name, 0)
def set_atom_volume_values(molecule, volume_data_region, attribute_name): atoms = molecule.atoms from _multiscale import get_atom_coordinates xyz = get_atom_coordinates(atoms) # Untransformed coordinates xyz_xform = molecule.openState.xform dr = volume_data_region values, outside = dr.interpolated_values(xyz, xyz_xform, out_of_bounds_list=True) n = len(atoms) for a in range(n): v = float(values[a]) # Use float otherwise get a NumPy scalar. setattr(atoms[a], attribute_name, v) for a in outside: setattr(atoms[a], attribute_name, 0)
def molecule_grid_data(atoms, resolution, step, pad, cutoff_range, sigma_factor): from _multiscale import get_atom_coordinates, bounding_box xyz = get_atom_coordinates(atoms, transformed = True) # Transform coordinates to local coordinates of the molecule containing # the first atom. This handles multiple unaligned molecules. from Matrix import xform_matrix m0 = atoms[0].molecule tf = xform_matrix(m0.openState.xform.inverse()) from _contour import affine_transform_vertices affine_transform_vertices(xyz, tf) xyz_min, xyz_max = bounding_box(xyz) origin = [x-pad for x in xyz_min] ijk = (xyz - origin) / step anum = [a.element.number for a in atoms] sdev = sigma_factor * resolution / step from numpy import zeros, float32 sdevs = zeros((len(atoms),3), float32) sdevs[:] = sdev from math import pow, pi, ceil normalization = pow(2*pi,-1.5)*pow(sdev*step,-3) shape = [int(ceil((xyz_max[a] - xyz_min[a] + 2*pad) / step)) for a in (2,1,0)] matrix = zeros(shape, float32) from _gaussian import sum_of_gaussians sum_of_gaussians(ijk, anum, sdevs, cutoff_range, matrix) matrix *= normalization molecules = set([a.molecule for a in atoms]) if len(molecules) > 1: name = 'molmap res %.3g' % (resolution,) else: name = 'molmap %s res %.3g' % (m0.name, resolution) from VolumeData import Array_Grid_Data grid = Array_Grid_Data(matrix, origin, (step,step,step), name = name) return grid, molecules
def contacting_transforms(mol, csys, tflist, cdist): from _multiscale import get_atom_coordinates points = get_atom_coordinates(mol.atoms) pxf = mol.openState.xform pxf.premultiply(csys.openState.xform.inverse()) from Matrix import xform_matrix, identity_matrix from numpy import array, float32 point_tf = xform_matrix(pxf) from _contour import affine_transform_vertices affine_transform_vertices(points, point_tf) # points in reference coords ident = array(identity_matrix(),float32) from _closepoints import find_close_points_sets, BOXES_METHOD ctflist = [tf for tf in tflist if len(find_close_points_sets(BOXES_METHOD, [(points, ident)], [(points, array(tf,float32))], cdist)[0][0]) > 0] return ctflist
def contacting_transforms(mol, csys, tflist, cdist): from _multiscale import get_atom_coordinates points = get_atom_coordinates(mol.atoms) pxf = mol.openState.xform pxf.premultiply(csys.openState.xform.inverse()) from Matrix import xform_matrix, identity_matrix from numpy import array, float32 point_tf = xform_matrix(pxf) from _contour import affine_transform_vertices affine_transform_vertices(points, point_tf) # points in reference coords ident = array(identity_matrix(), float32) from _closepoints import find_close_points_sets, BOXES_METHOD ctflist = [ tf for tf in tflist if len( find_close_points_sets(BOXES_METHOD, [(points, ident)], [( points, array(tf, float32))], cdist)[0][0]) > 0 ] return ctflist
def inertia_ellipsoid(m): atoms = m.atoms n = len(atoms) from _multiscale import get_atom_coordinates xyz = get_atom_coordinates(atoms) anum = [a.element.number for a in atoms] from numpy import array, dot, outer, argsort, linalg wxyz = array(anum).reshape((n, 1)) * xyz mass = sum(anum) c = wxyz.sum(axis=0) / mass # Center of mass v33 = dot(xyz.transpose(), wxyz) / mass - outer(c, c) eval, evect = linalg.eigh(v33) # Sort by eigenvalue size. order = argsort(eval) seval = eval[order] sevect = evect[:, order] return sevect, seval, c
def atom_coordinates(atoms): from _multiscale import get_atom_coordinates xyz = get_atom_coordinates(atoms) return xyz
def atom_coordinates(atoms): from _multiscale import get_atom_coordinates xyz = get_atom_coordinates(atoms) return xyz
from VolumeViewer import Volume vols = chimera.openModels.list(modelTypes = [Volume]) if len(vols) == 0 : print " - no volumes loaded" exit(0) dmap = vols[0] print " - volume: %s" % dmap.name from chimera import Molecule mols = chimera.openModels.list(modelTypes = [Molecule]) if len(mols) == 0 : print " - no molecules loaded" exit(0) for mi, mol in enumerate (mols) : print "" print "Model %d/%d: %s" % (mi+1, len(mols), mol.name) mapq.mapq.SetBBAts ( mol ) ats = [at for at in mol.atoms if not at.element.name == "H"] points = _multiscale.get_atom_coordinates ( ats, transformed = False ) print " - search tree: %d/%d ats" % ( len(ats), len(mol.atoms) ) allAtTree = AdaptiveTree ( points.tolist(), ats, 1.0) #allAtTree = None mapq.mapq.CalcQp ( mol, None, dmap, allAtTree=allAtTree )
def detectClash(testAtoms, test="others", clashThreshold=clashDef, hbondAllowance=hbondDef, assumedMaxVdw=2.1, bondSeparation=bondSepDef, intraRes=False, interSubmodel=False): """Detect steric clashes 'testAtoms' should be a list of atoms. If 'test' is 'others' then non-bonded clashes between atoms in 'testAtoms' and non-'testAtoms' atoms will be found. If 'test' is 'model' then the same clashes as 'others' will be found, but inter-model clashes will be eliminated. If 'test' is 'self' then non-bonded clashes within 'testAtoms' atoms will be found. Otherwise 'test' should be a list of atoms to test against. The "clash value" is the sum of the VDW radii minus the distance, keeping only the maximal clash (which must exceed 'clashThreshold'). 'hbondAllowance' is how much the clash value is reduced if one atom is a donor and the other an acceptor. Atom pairs are eliminated from consideration if they are less than or equal to 'bondSeparation' bonds apart. Intra-residue clashes are ignored unless intraRes is True. Inter-submodel clashes are ignored unless interSubmodel is True. Returns a dictionary keyed on atoms, with values that are dictionaries keyed on clashing atom with value being the clash value. """ # use the fast _closepoints module to cut down candidate atoms if we # can (since _closepoints doesn't know about "non-bonded" it isn't as # useful as it might otherwise be) if test in ("others", "model"): mList = chimera.openModels.list(modelTypes=[chimera.Molecule]) testSet = set(testAtoms) from numpy import array testList = array(testAtoms) otherAtoms = [a for m in mList for a in m.atoms if a not in testSet] otherAtoms = array(otherAtoms) if len(otherAtoms) == 0: from chimera import UserError raise UserError("All atoms are in test set: no others" " available to test against") from _multiscale import get_atom_coordinates tPoints = get_atom_coordinates(testList, transformed = True) oPoints = get_atom_coordinates(otherAtoms, transformed = True) cutoff = 2.0 * assumedMaxVdw - clashThreshold from _closepoints import find_close_points, BOXES_METHOD tClose, oClose = find_close_points(BOXES_METHOD, tPoints, oPoints, cutoff) testAtoms = testList.take(tClose) searchAtoms = otherAtoms.take(oClose) elif not isinstance(test, basestring): searchAtoms = test else: searchAtoms = testAtoms from chimera.misc import atomSearchTree tree = atomSearchTree(list(searchAtoms)) clashes = {} for a in testAtoms: cutoff = a.radius + assumedMaxVdw - clashThreshold nearby = tree.searchTree(a.xformCoord().data(), cutoff) if not nearby: continue needExpansion = a.allLocations() exclusions = set(needExpansion) for i in range(bondSeparation): nextNeed = [] for expand in needExpansion: for n in expand.neighbors: if n in exclusions: continue exclusions.add(n) nextNeed.append(n) needExpansion = nextNeed for nb in nearby: if nb in exclusions: continue if not intraRes and a.residue == nb.residue: continue if a in clashes and nb in clashes[a]: continue if not interSubmodel \ and a.molecule.id == nb.molecule.id \ and a.molecule.subid != nb.molecule.subid: continue if test == "model" and a.molecule != nb.molecule: continue clash = a.radius + nb.radius - a.xformCoord().distance( nb.xformCoord()) if hbondAllowance: if (_donor(a) and _acceptor(nb)) or ( _donor(nb) and _acceptor(a)): clash -= hbondAllowance if clash < clashThreshold: continue clashes.setdefault(a, {})[nb] = clash clashes.setdefault(nb, {})[a] = clash return clashes
def detectClash(testAtoms, test="others", clashThreshold=clashDef, hbondAllowance=hbondDef, assumedMaxVdw=2.1, bondSeparation=bondSepDef, intraRes=False, interSubmodel=False): """Detect steric clashes 'testAtoms' should be a list of atoms. If 'test' is 'others' then non-bonded clashes between atoms in 'testAtoms' and non-'testAtoms' atoms will be found. If 'test' is 'model' then the same clashes as 'others' will be found, but inter-model clashes will be eliminated. If 'test' is 'self' then non-bonded clashes within 'testAtoms' atoms will be found. Otherwise 'test' should be a list of atoms to test against. The "clash value" is the sum of the VDW radii minus the distance, keeping only the maximal clash (which must exceed 'clashThreshold'). 'hbondAllowance' is how much the clash value is reduced if one atom is a donor and the other an acceptor. Atom pairs are eliminated from consideration if they are less than or equal to 'bondSeparation' bonds apart. Intra-residue clashes are ignored unless intraRes is True. Inter-submodel clashes are ignored unless interSubmodel is True. Returns a dictionary keyed on atoms, with values that are dictionaries keyed on clashing atom with value being the clash value. """ # use the fast _closepoints module to cut down candidate atoms if we # can (since _closepoints doesn't know about "non-bonded" it isn't as # useful as it might otherwise be) if test in ("others", "model"): mList = chimera.openModels.list(modelTypes=[chimera.Molecule]) testSet = set(testAtoms) from numpy import array testList = array(testAtoms) otherAtoms = [a for m in mList for a in m.atoms if a not in testSet] otherAtoms = array(otherAtoms) if len(otherAtoms) == 0: from chimera import UserError raise UserError("All atoms are in test set: no others" " available to test against") from _multiscale import get_atom_coordinates tPoints = get_atom_coordinates(testList, transformed=True) oPoints = get_atom_coordinates(otherAtoms, transformed=True) cutoff = 2.0 * assumedMaxVdw - clashThreshold from _closepoints import find_close_points, BOXES_METHOD tClose, oClose = find_close_points(BOXES_METHOD, tPoints, oPoints, cutoff) testAtoms = testList.take(tClose) searchAtoms = otherAtoms.take(oClose) elif not isinstance(test, basestring): searchAtoms = test else: searchAtoms = testAtoms from chimera.misc import atomSearchTree tree = atomSearchTree(list(searchAtoms)) clashes = {} for a in testAtoms: cutoff = a.radius + assumedMaxVdw - clashThreshold nearby = tree.searchTree(a.xformCoord().data(), cutoff) if not nearby: continue needExpansion = a.allLocations() exclusions = set(needExpansion) for i in range(bondSeparation): nextNeed = [] for expand in needExpansion: for n in expand.neighbors: if n in exclusions: continue exclusions.add(n) nextNeed.append(n) needExpansion = nextNeed for nb in nearby: if nb in exclusions: continue if not intraRes and a.residue == nb.residue: continue if a in clashes and nb in clashes[a]: continue if not interSubmodel \ and a.molecule.id == nb.molecule.id \ and a.molecule.subid != nb.molecule.subid: continue if test == "model" and a.molecule != nb.molecule: continue clash = a.radius + nb.radius - a.xformCoord().distance( nb.xformCoord()) if hbondAllowance: if (_donor(a) and _acceptor(nb)) or (_donor(nb) and _acceptor(a)): clash -= hbondAllowance if clash < clashThreshold: continue clashes.setdefault(a, {})[nb] = clash clashes.setdefault(nb, {})[a] = clash return clashes
def atoms_inertia(atoms): from _multiscale import get_atom_coordinates xyz = get_atom_coordinates(atoms, transformed = True) weights = [a.element.mass for a in atoms] return moments_of_inertia([(xyz,weights)])
def atoms_inertia(atoms): from _multiscale import get_atom_coordinates xyz = get_atom_coordinates(atoms, transformed=True) weights = [a.element.mass for a in atoms] return moments_of_inertia([(xyz, weights)])
def compute_chain_atom_xyz(self, chain_id): alist = self.chain_atoms(chain_id) from _multiscale import get_atom_coordinates xyz = get_atom_coordinates(alist) return xyz
def atom_coordinates(atoms): from _multiscale import get_atom_coordinates points = get_atom_coordinates(atoms, transformed = True) return points
def xyz(self, transformed=True): return get_atom_coordinates(self.compound.mol.atoms, transformed=transformed)