def get_pdb_transform(pdb, center_res, top_res): """ Returns a transformation matrix that centers pdb to center_res on the z-axis and moves top_res above center_res on the y-axis """ soup = pdbatoms.Soup(pdb) atoms = soup.atoms() soup_center = pdbatoms.get_center(atoms) translation = v3.translation(-soup_center) soup.transform(translation) result = translation center_atom = find_ca_of_resname(soup.atoms(), center_res) view = v3.vector(0, 0, 1) axis = v3.cross(view, center_atom.pos) angle = v3.vec_dihedral(view, axis, center_atom.pos) rotation = v3.rotation(axis, angle) soup.transform(rotation) result = v3.combine(rotation, result) top_atom = find_ca_of_resname(soup.atoms(), top_res) top_dir = v3.vector(0, 1, 0) axis = view.copy() angle = v3.vec_dihedral(top_dir, axis, top_atom.pos) rotation2 = v3.rotation(axis, angle) result = v3.combine(rotation2, result) del soup return result
def __init__(self, grid_spacing, width, center): self.width = float(width) half_width = self.width / 2.0 self.center = v3.vector(center) self.spacing = float(grid_spacing) self.inv_spacing = 1.0 / self.spacing self.n = 1 cover = 0 self.low = v3.vector() while cover < half_width: self.n += 1 half_n_point = int(self.n / 2) self.low[0] = self.center[0] - half_n_point * self.spacing self.low[1] = self.center[1] - half_n_point * self.spacing self.low[2] = self.center[2] - half_n_point * self.spacing width_1 = abs(self.center[0] - self.low[0]) high_x = self.low[0] + self.n * self.spacing width_2 = abs(high_x - self.center[0]) cover = min(width_1, width_2) self.actual_width = self.n * self.spacing self.total_volume = self.actual_width**3 self.total_point = self.n**3 self.array = array.array('b') for i in xrange(self.total_point): self.array.append(0) self.n_sq = self.n**2 self.x = [self.low[0] + i * self.spacing for i in xrange(self.n)] self.y = [self.low[1] + j * self.spacing for j in xrange(self.n)] self.z = [self.low[2] + k * self.spacing for k in xrange(self.n)]
def __init__(self, grid_spacing, width, center): self.width = float(width) half_width = self.width / 2.0 self.center = v3.vector(center) self.spacing = float(grid_spacing) self.inv_spacing = 1.0 / self.spacing self.n = 1 cover = 0 self.low = v3.vector() while cover < half_width: self.n += 1 half_n_point = int(self.n / 2) self.low[0] = self.center[0] - half_n_point*self.spacing self.low[1] = self.center[1] - half_n_point*self.spacing self.low[2] = self.center[2] - half_n_point*self.spacing width_1 = abs(self.center[0] - self.low[0]) high_x = self.low[0] + self.n*self.spacing width_2 = abs(high_x - self.center[0]) cover = min(width_1, width_2) self.actual_width = self.n*self.spacing self.total_volume = self.actual_width**3 self.total_point = self.n**3 self.array = array.array('b') for i in xrange(self.total_point): self.array.append(0) self.n_sq = self.n**2 self.x = [self.low[0] + i*self.spacing for i in xrange(self.n)] self.y = [self.low[1] + j*self.spacing for j in xrange(self.n)] self.z = [self.low[2] + k*self.spacing for k in xrange(self.n)]
def exclude_sphere(self, pos, r): low = v3.vector(pos[0] - r, pos[1] - r, pos[2] - r) low_i, low_j, low_k = self.indices(low) high = v3.vector(pos[0] + r, pos[1] + r, pos[2] + r) high_i, high_j, high_k = self.indices(high) r_sq = r*r for i in self.int_range(low_i, high_i): for j in self.int_range(low_j, high_j): for k in self.int_range(low_k, high_k): l = i*self.n_sq + j*self.n + k if self.array[l] == 0: if self.is_grid_point_near_sphere(i, j, k, pos, r_sq): self.array[l] = 1
def exclude_sphere(self, pos, r): low = v3.vector(pos[0] - r, pos[1] - r, pos[2] - r) low_i, low_j, low_k = self.indices(low) high = v3.vector(pos[0] + r, pos[1] + r, pos[2] + r) high_i, high_j, high_k = self.indices(high) r_sq = r * r for i in self.int_range(low_i, high_i): for j in self.int_range(low_j, high_j): for k in self.int_range(low_k, high_k): l = i * self.n_sq + j * self.n + k if self.array[l] == 0: if self.is_grid_point_near_sphere(i, j, k, pos, r_sq): self.array[l] = 1
def __init__(self): self.is_hetatm = False self.pos = v3.vector() self.vel = v3.vector() self.mass = 0.0 self.type = "" self.element = "" self.chain_id = " " self.res_type = "" self.res_num = "" self.res_insert = "" self.bfactor = 0.0 self.occupancy = 0.0 self.num = 0
def get_center(atoms): """ Returns the geometric center position vector of atoms. """ center = v3.vector() for atom in atoms: center += atom.pos result = v3.scale(center, 1.0/float(len(atoms))) return result
def average_vel(atoms): """ Returns the mass-averaged velocity of atoms. """ momentum = v3.vector() mass = 0.0 for a in atoms: momentum += v3.scale(a.vel, a.mass) mass += a.mass return v3.scale(momentum, 1.0 / mass)
def average_vel(atoms): """ Returns the mass-averaged velocity of atoms. """ momentum = v3.vector() mass = 0.0 for a in atoms: momentum += v3.scale(a.vel, a.mass) mass += a.mass return v3.scale(momentum, 1.0/mass)
def __init__(self, pos=None, atom_type="", res_num=None): """ Normally initialized as an empty container, and filled up progressively as fields are read by parsers. """ self.is_hetatm = False self.pos = v3.vector() if pos is None else pos self.vel = v3.vector() self.mass = 0.0 self.charge = 0.0 self.type = "" self.element = "" self.chain_id = " " self.res_type = "" self.res_num = "" self.res_insert = "" self.bfactor = 0.0 self.occupancy = 0.0 self.num = 0 self.alt_conform = " "
def generate_sphere_points(n): """ Returns list of coordinates on a sphere using the Golden- Section Spiral algorithm. """ points = [] inc = math.pi * (3 - math.sqrt(5)) offset = 2 / float(n) for k in range(int(n)): y = k * offset - 1 + (offset / 2) r = math.sqrt(1 - y * y) phi = k * inc points.append(v3.vector(math.cos(phi) * r, y, math.sin(phi) * r)) return points
def generate_sphere_points(n): """ Returns list of coordinates on a sphere using the Golden- Section Spiral algorithm. """ points = [] inc = math.pi * (3 - math.sqrt(5)) offset = 2 / float(n) for k in range(int(n)): y = k * offset - 1 + (offset / 2) r = math.sqrt(1 - y*y) phi = k * inc points.append(v3.vector(math.cos(phi)*r, y, math.sin(phi)*r)) return points
def add_rotational_velocity(atoms, rot_vel, axis, anchor): """ Adds the rot_vel to the vel vector of atoms with respect to the rotation around axis and attached to anchor. """ for atom in atoms: r_perp = v3.perpendicular(atom.pos - anchor, axis) v_tang_dir = v3.cross(axis, r_perp) v_tang_dir_len = v3.mag(v_tang_dir) if v3.is_similar_mag(v_tang_dir_len, 0): v_tang = v3.vector() else: v_new_len = rot_vel * v3.mag(r_perp) v_tang = v3.scale(v_tang_dir, v_new_len/v_tang_dir_len) atom.vel += v_tang
def add_rotational_velocity(atoms, rot_vel, axis, anchor): """ Adds the rot_vel to the vel vector of atoms with respect to the rotation around axis and attached to anchor. """ for atom in atoms: r_perp = v3.perpendicular(atom.pos - anchor, axis) v_tang_dir = v3.cross(axis, r_perp) v_tang_dir_len = v3.mag(v_tang_dir) if v3.is_similar_mag(v_tang_dir_len, 0): v_tang = v3.vector() else: v_new_len = rot_vel * v3.mag(r_perp) v_tang = v3.scale(v_tang_dir, v_new_len / v_tang_dir_len) atom.vel += v_tang
def soup_from_psf(psf): """ Returns a Soup from a .psf file """ soup = pdbatoms.Soup() curr_res_num = None is_header = True for line in open(psf): if is_header: if "NATOM" in line: n_atom = int(line.split()[0]) is_header = False continue words = line.split() atom_num = int(words[0]) chain_id = words[1] res_num = int(words[2]) res_type = words[3] atom_type = words[4] charge = float(words[6]) mass = float(words[7]) if chain_id.startswith('WT') or chain_id.startswith('ION'): is_hetatm = True chain_id = " " else: is_hetatm = False chain_id = chain_id[0] if curr_res_num != res_num: res = pdbatoms.Residue(res_type, chain_id, res_num) soup.append_residue(res) curr_res_num = res_num atom = pdbatoms.Atom() atom.vel = v3.vector() atom.chain_id = chain_id atom.is_hetatm = is_hetatm atom.num = atom_num atom.res_num = res_num atom.res_type = res_type atom.type = atom_type atom.mass = mass atom.charge = charge atom.element = data.guess_element(res_type, atom_type) soup.insert_atom(-1, atom) if len(soup.atoms()) == n_atom: break convert_to_pdb_atom_names(soup) return soup
def soup_from_topology(topology): """ Returns a Soup from a topology dictionary. """ soup = pdbatoms.Soup() chain_id = '' n_res = topology['NRES'] n_atom = topology['NATOM'] for i_res in range(n_res): res_type = topology['RESIDUE_LABEL'][i_res].strip() if res_type == "WAT": res_type = "HOH" res = pdbatoms.Residue(res_type, chain_id, i_res+1) soup.append_residue(res) res = soup.residue(i_res) i_atom_start = topology['RESIDUE_POINTER'][i_res] - 1 if i_res == n_res-1: i_atom_end = n_atom else: i_atom_end = topology['RESIDUE_POINTER'][i_res+1] - 1 for i_atom in range(i_atom_start, i_atom_end): atom = pdbatoms.Atom() atom.vel = v3.vector() atom.num = i_atom+1 atom.res_num = i_res+1 atom.res_type = res_type atom.type = topology['ATOM_NAME'][i_atom].strip() atom.mass = topology['MASS'][i_atom] atom.charge = topology['CHARGE'][i_atom]/sqrt_of_k atom.element = data.guess_element( atom.res_type, atom.type) soup.insert_atom(-1, atom) convert_to_pdb_atom_names(soup) if topology['IFBOX'] > 0: # create dummy dimension to ensure box dimension recognized soup.box_dimension_str = "1.000000 1.0000000 1.000000" return soup
def soup_from_topology(topology): """ Returns a Soup from a topology dictionary. """ soup = pdbatoms.Soup() chain_id = '' n_res = topology['NRES'] n_atom = topology['NATOM'] for i_res in range(n_res): res_type = topology['RESIDUE_LABEL'][i_res].strip() if res_type == "WAT": res_type = "HOH" res = pdbatoms.Residue(res_type, chain_id, i_res + 1) soup.append_residue(res) res = soup.residue(i_res) i_atom_start = topology['RESIDUE_POINTER'][i_res] - 1 if i_res == n_res - 1: i_atom_end = n_atom else: i_atom_end = topology['RESIDUE_POINTER'][i_res + 1] - 1 for i_atom in range(i_atom_start, i_atom_end): atom = pdbatoms.Atom() atom.vel = v3.vector() atom.num = i_atom + 1 atom.res_num = i_res + 1 atom.res_type = res_type atom.type = topology['ATOM_NAME'][i_atom].strip() atom.mass = topology['MASS'][i_atom] atom.charge = topology['CHARGE'][i_atom] / sqrt_of_k atom.element = data.guess_element(atom.res_type, atom.type) soup.insert_atom(-1, atom) convert_to_pdb_atom_names(soup) if topology['IFBOX'] > 0: # create dummy dimension to ensure box dimension recognized soup.box_dimension_str = "1.000000 1.0000000 1.000000" return soup
def get_center(atoms): center = v3.vector() for atom in atoms: center += atom.pos return center / float(len(atoms))
def pos(self, i, j, k): return v3.vector(self.x[i], self.y[j], self.z[k])
def get_center(atoms): center = v3.vector() for atom in atoms: center += atom.pos return center/float(len(atoms))