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 change_vels(self): # calculate the vel diff vector to apply diff_vel = self.target_val * self.dt diff_axis_vel2to1 = v3.scale(self.axis2to1, diff_vel) self.vel_diff = v3.dot(diff_axis_vel2to1, self.axis2to1) if self.is_first_domain_only: add_vel_to_atoms(self.atoms1, diff_axis_vel2to1) else: # apply half of vel_diff to each domain diff_axis_vel2to1 = v3.scale(diff_axis_vel2to1, 0.5) add_vel_to_atoms(self.atoms1, diff_axis_vel2to1) add_vel_to_atoms(self.atoms2, -diff_axis_vel2to1)
def change_vels(self): # calculate the vel diff vector target_axis_vel2to1 = v3.scale(self.axis2to1, self.target_val) diff_axis_vel2to1 = target_axis_vel2to1 - self.axis_vel2to1 self.vel_diff = v3.dot(diff_axis_vel2to1, self.axis2to1) # now change velocities of movable atoms self.old_kinetic_energy = kinetic_energy(self.move_atoms) if self.is_first_domain_only: add_vel_to_atoms(self.atoms1, diff_axis_vel2to1) else: # apply half of vel_diff to each domain v3.scale(diff_axis_vel2to1, 0.5) add_vel_to_atoms(self.atoms1, diff_axis_vel2to1) add_vel_to_atoms(self.atoms2, -diff_axis_vel2to1) self.kinetic_energy = kinetic_energy(self.move_atoms)
def move_back(char, m=1, fly=False): if not char['block_b']: f = char['forw'] f = v3.normalize(v3.Vec(f.x, f.y * fly, f.z)) addto(char, 'pos', v3.scale(f, -0.5 * m)) return True return False
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 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 ray(v, forwstep): backstep = v3.scale(forwstep, -0.1) for k in range(0, int(maxdist / step)): n = k * step v = v3.add(v, forwstep) b = check(L, v) if b != 0: for m in range(10): v = v3.add(v, backstep) if check(L, v) == 0: return n - m * 0.1, v, b b = check(L, v) return n, v, b return -1, v, 1
def anderson_velocity_scale(atoms, temperature, n_degree_of_freedom): """ Scales the velocity of atoms such that average energy is consistent with the temperature. """ # This is the classic Anderson approach to temperature # regulation. Whilst deterministic, can be easily trapped in # local minima. target_energy = mean_energy(temperature, n_degree_of_freedom) kin = kinetic_energy(atoms) if v3.is_similar_mag(kin, 0): gas_randomize(atoms, temperature) else: scaling_factor = math.sqrt(target_energy / kin) for atom in atoms: v3.set_vector(atom.vel, v3.scale(atom.vel, scaling_factor))
def calculate_asa_optimized(atoms, probe, n_sphere_point=960): """ Returns the accessible-surface areas of the atoms, by rolling a ball with probe radius over the atoms with their radius defined. """ sphere_points = generate_sphere_points(n_sphere_point) const = 4.0 * math.pi / len(sphere_points) areas = [] neighbor_list = adjacency_list( atoms, 2 * (probe + max(atoms, key=lambda p: p.radius).radius)) for i, atom_i in enumerate(atoms): neighbor_indices = [neig for neig in neighbor_list[i]] neighbor_indices = find_neighbor_indices_modified( atoms, neighbor_indices, probe, i) # even further narrow diapazon n_neighbor = len(neighbor_indices) j_closest_neighbor = 0 radius = probe + atom_i.radius n_accessible_point = 0 for point in sphere_points: is_accessible = True test_point = v3.scale(point, radius) + atom_i.pos cycled_indices = range(j_closest_neighbor, n_neighbor) cycled_indices.extend(range(j_closest_neighbor)) for j in cycled_indices: atom_j = atoms[neighbor_indices[j]] r = atom_j.radius + probe diff2 = v3.mag2(atom_j.pos - test_point) if diff2 < r * r: j_closest_neighbor = j is_accessible = False break if is_accessible: n_accessible_point += 1 area = const * n_accessible_point * radius * radius areas.append(area) return areas
def load_crd_or_rst_into_soup(soup, crd_or_rst): """ Loads the coordinates and velocities of .crd or .rst into the soup. """ f = open(crd_or_rst, "r") f.readline() # skip first line n_atom = int(f.readline().split()[0]) # calculate size of file based on field sizes n_crd = n_atom * 3 n_line = n_crd / 6 if n_crd % 6 > 0: n_line += 1 # read all the numbers in the coordinate section line_list = [f.readline()[:-1] for i in range(0, n_line)] s = "".join(line_list) vals = [float(s[i:i + 12]) for i in xrange(0, len(s), 12)] if len(vals) != n_crd: raise ValueError, "Improper number of coordinates in rst file." # load numbers into soup object for i, atom in enumerate(sorted(soup.atoms(), pdbatoms.cmp_atom)): v3.set_vector(atom.pos, vals[i * 3], vals[i * 3 + 1], vals[i * 3 + 2]) # if .rst file, then there will be velocity values if crd_or_rst.endswith('.rst'): line_list = [f.readline()[:-1] for i in range(0, n_line)] s = "".join(line_list) vals = [float(s[i:i + 12]) for i in xrange(0, len(s), 12)] if len(vals) != n_crd: raise ValueError, "Improper number of coordinates in rst file." # now convert amber velocities to angs/ps and load into soup convert_vel_to_angs_per_ps = 20.455 for i, atom in enumerate(sorted(soup.atoms(), pdbatoms.cmp_atom)): v3.set_vector(atom.vel, vals[i * 3], vals[i * 3 + 1], vals[i * 3 + 2]) atom.vel = v3.scale(atom.vel, convert_vel_to_angs_per_ps) f.close()
def calculate_asa_optimized(atoms, probe, n_sphere_point=960): """ Returns the accessible-surface areas of the atoms, by rolling a ball with probe radius over the atoms with their radius defined. """ sphere_points = generate_sphere_points(n_sphere_point) const = 4.0 * math.pi / len(sphere_points) areas = [] neighbor_list = adjacency_list(atoms, 2 * (probe + max(atoms, key=lambda p: p.radius).radius)) for i, atom_i in enumerate(atoms): neighbor_indices = [neig for neig in neighbor_list[i]] neighbor_indices = find_neighbor_indices_modified(atoms, neighbor_indices, probe, i) # even further narrow diapazon n_neighbor = len(neighbor_indices) j_closest_neighbor = 0 radius = probe + atom_i.radius n_accessible_point = 0 for point in sphere_points: is_accessible = True test_point = v3.scale(point, radius) + atom_i.pos cycled_indices = range(j_closest_neighbor, n_neighbor) cycled_indices.extend(range(j_closest_neighbor)) for j in cycled_indices: atom_j = atoms[neighbor_indices[j]] r = atom_j.radius + probe diff2 = v3.mag2(atom_j.pos - test_point) if diff2 < r*r: j_closest_neighbor = j is_accessible = False break if is_accessible: n_accessible_point += 1 area = const*n_accessible_point*radius*radius areas.append(area) return areas
def load_crd_or_rst_into_soup(soup, crd_or_rst): """ Loads the coordinates and velocities of .crd or .rst into the soup. """ f = open(crd_or_rst, "r") f.readline() # skip first line n_atom = int(f.readline().split()[0]) # calculate size of file based on field sizes n_crd = n_atom * 3 n_line = n_crd / 6 if n_crd % 6 > 0: n_line += 1 # read all the numbers in the coordinate section line_list = [f.readline()[:-1] for i in range(0, n_line)] s = "".join(line_list) vals = [float(s[i:i+12]) for i in xrange(0, len(s), 12)] if len(vals) != n_crd: raise ValueError, "Improper number of coordinates in rst file." # load numbers into soup object for i, atom in enumerate(sorted(soup.atoms(), pdbatoms.cmp_atom)): v3.set_vector(atom.pos, vals[i*3], vals[i*3+1], vals[i*3+2]) # if .rst file, then there will be velocity values if crd_or_rst.endswith('.rst'): line_list = [f.readline()[:-1] for i in range(0, n_line)] s = "".join(line_list) vals = [float(s[i:i+12]) for i in xrange(0, len(s), 12)] if len(vals) != n_crd: raise ValueError, "Improper number of coordinates in rst file." # now convert amber velocities to angs/ps and load into soup convert_vel_to_angs_per_ps = 20.455 for i, atom in enumerate(sorted(soup.atoms(), pdbatoms.cmp_atom)): v3.set_vector(atom.vel, vals[i*3], vals[i*3+1], vals[i*3+2]) atom.vel = v3.scale(atom.vel, convert_vel_to_angs_per_ps) f.close()
def raycast(L, pos, rot, maxdist=128, cam=v3.Vec(0.3, 0.2, 0.3), win=v3.Vec(10, 10, 0)): field = {} step = 1 forw = v3.roteuler(v3.Vec(0, 0, 1), rot) def ray(v, forwstep): backstep = v3.scale(forwstep, -0.1) for k in range(0, int(maxdist / step)): n = k * step v = v3.add(v, forwstep) b = check(L, v) if b != 0: for m in range(10): v = v3.add(v, backstep) if check(L, v) == 0: return n - m * 0.1, v, b b = check(L, v) return n, v, b return -1, v, 1 for i in range(-win.x / 2, win.x / 2): for j in range(-win.y / 2, win.y / 2): xi = i / (win.x / 2.0) * (cam.x / 2.0) yi = j / (win.y / 2.0) * (cam.y / 2.0) v = v3.Vec(xi, yi, cam.z) v = v3.roteuler(v, rot) fs = v3.scale(v3.normalize(v), step) v = v3.add(pos, v) n, p, b = ray(v, fs) field[i + win.x / 2, j + win.y / 2] = (n, b) field['size'] = win return field
def calculate_asa(atoms, probe, n_sphere_point=960): """ Returns the accessible-surface areas of the atoms, by rolling a ball with probe radius over the atoms with their radius defined. """ sphere_points = generate_sphere_points(n_sphere_point) const = 4.0 * math.pi / len(sphere_points) areas = [] for i, atom_i in enumerate(atoms): neighbor_indices = find_neighbor_indices(atoms, probe, i) n_neighbor = len(neighbor_indices) j_closest_neighbor = 0 radius = probe + atom_i.radius n_accessible_point = 0 for point in sphere_points: is_accessible = True test_point = v3.scale(point, radius) + atom_i.pos cycled_indices = range(j_closest_neighbor, n_neighbor) cycled_indices.extend(range(j_closest_neighbor)) for j in cycled_indices: atom_j = atoms[neighbor_indices[j]] r = atom_j.radius + probe diff = v3.distance(atom_j.pos, test_point) if diff*diff < r*r: j_closest_neighbor = j is_accessible = False break if is_accessible: n_accessible_point += 1 area = const*n_accessible_point*radius*radius areas.append(area) return areas
def calculate_asa(atoms, probe, n_sphere_point=960): """ Returns the accessible-surface areas of the atoms, by rolling a ball with probe radius over the atoms with their radius defined. """ sphere_points = generate_sphere_points(n_sphere_point) const = 4.0 * math.pi / len(sphere_points) areas = [] for i, atom_i in enumerate(atoms): neighbor_indices = find_neighbor_indices(atoms, probe, i) n_neighbor = len(neighbor_indices) j_closest_neighbor = 0 radius = probe + atom_i.radius n_accessible_point = 0 for point in sphere_points: is_accessible = True test_point = v3.scale(point, radius) + atom_i.pos cycled_indices = range(j_closest_neighbor, n_neighbor) cycled_indices.extend(range(j_closest_neighbor)) for j in cycled_indices: atom_j = atoms[neighbor_indices[j]] r = atom_j.radius + probe diff = v3.distance(atom_j.pos, test_point) if diff * diff < r * r: j_closest_neighbor = j is_accessible = False break if is_accessible: n_accessible_point += 1 area = const * n_accessible_point * radius * radius areas.append(area) return areas