def add_bond(a, a1, a2, conn, d_max): ''' If distance between atoms a1 and a2 is less than d_max (neighboring atoms), add atoms a1 and a2 in adjacency list conn to each other ''' atom1 = a[a1] atom2 = a[a2] if v3.mag2(atom1.pos - atom2.pos) <= d_max * d_max: # connected conn[a1].append(a2) conn[a2].append(a1)
def find_neighbor_indices_modified(atoms, indices, probe, k): """ Returns list of indices of atoms within probe distance to atom k. """ neighbor_indices = [] atom_k = atoms[k] radius = atom_k.radius + probe + probe for i in indices: if i == k: continue atom_i = atoms[i] dist2 = v3.mag2(atom_k.pos - atom_i.pos) # ToAn if dist2 < (radius + atom_i.radius) ** 2: # ToAn neighbor_indices.append(i) return neighbor_indices
def find_neighbor_indices_modified(atoms, indices, probe, k): """ Returns list of indices of atoms within probe distance to atom k. """ neighbor_indices = [] atom_k = atoms[k] radius = atom_k.radius + probe + probe for i in indices: if i == k: continue atom_i = atoms[i] dist2 = v3.mag2(atom_k.pos - atom_i.pos) # ToAn if dist2 < (radius + atom_i.radius)**2: # ToAn neighbor_indices.append(i) return neighbor_indices
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 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