def apply_restraints(swarm_centers, receptor_restraints, distance_cutoff, translation, swarms_per_restraint=10): """Filter out swarm centers which are not close to the given restraints""" closer_swarms = [] for i, residue in enumerate(receptor_restraints): distances = {} # We will use CA in case of protein, P in case of DNA ca = residue.get_calpha() if not ca: ca = residue.get_atom('P') # Calculate the euclidean distance between swarm center and given atom/bead for swarm_id, center in enumerate(swarm_centers): distances[swarm_id] = cdistance(ca.x + translation[0], ca.y + translation[1], ca.z + translation[2], center[0], center[1], center[2]) sorted_distances = sorted(list(distances.items()), key=operator.itemgetter(1)) swarms_considered = 0 for swarm in sorted_distances: swarm_id, distance = swarm[0], swarm[1] if distance <= distance_cutoff: closer_swarms.append(swarm_id) swarms_considered += 1 if swarms_considered == swarms_per_restraint: break # Unique swarm ids closer_swarm_ids = sorted(list(set(closer_swarms))) # Final filtered list of swarms new_swarm_centers = [swarm_centers[i] for i in closer_swarm_ids] return new_swarm_centers
def populate_poses(to_generate, center, radius, number_generator, rec_translation, lig_translation, rng_nm=None, rec_nm=0, lig_nm=0, receptor_restraints=None, ligand_restraints=None, ligand_diameter=1.): """Creates new poses around a given center and a given radius""" new_poses = [] # Flatten if necessary receptor_restraints if receptor_restraints: try: receptor_restraints = receptor_restraints[ 'active'] + receptor_restraints['passive'] except TypeError: pass # Calculate closest residue restraints closest_residues = [] if receptor_restraints: distances = [] for i, residue in enumerate(receptor_restraints): ca = residue.get_calpha() if not ca: ca = residue.get_atom('P') distances.append( (i, cdistance(ca.x, ca.y, ca.z, center[0], center[1], center[2]))) distances.sort(key=lambda tup: tup[1]) closest_residues = [x[0] for x in distances[:10]] for _ in range(to_generate): # First calculate a random translation within the swarm sphere x, y, z = get_random_point_within_sphere(number_generator, radius) tx = center[0] + x ty = center[1] + y tz = center[2] + z # Restraints in both partners if receptor_restraints and ligand_restraints: # We select one of the closest residue restraints to point the quaternion rec_residue = receptor_restraints[closest_residues[ number_generator.randint(0, len(closest_residues) - 1)]] # Random restraint on the ligand to use for pre-orientation lig_residue = ligand_restraints[number_generator.randint( 0, len(ligand_restraints) - 1)] # Calculate the quaternion which rotates the ligand to point to the given receptor restraint q = get_quaternion_for_restraint(rec_residue, lig_residue, tx, ty, tz, rec_translation, lig_translation) # Only restraints in the ligand partner elif ligand_restraints and not receptor_restraints: # The strategy is similar to previous but for the receptor side we will use a simulated point # over the receptor surface to point out the quaternion coef = norm(center) / ligand_diameter if coef > 1.0: raise LightDockWarning( 'Found wrong coefficient on calculating poses with restraints' ) # It is important to keep the coordinates as in the original complex without # moving to the center of coordinates (applying translation) rec_residue = Residue.dummy(center[0] * coef - rec_translation[0], center[1] * coef - rec_translation[1], center[2] * coef - rec_translation[2]) lig_residue = ligand_restraints[number_generator.randint( 0, len(ligand_restraints) - 1)] q = get_quaternion_for_restraint(rec_residue, lig_residue, tx, ty, tz, rec_translation, lig_translation) # No restraints at all else: q = Quaternion.random(number_generator) # Glowworm's optimization vector op_vector = [tx, ty, tz, q.w, q.x, q.y, q.z] # If ANM is enabled, we need to create random components for the extents if rng_nm: if rec_nm > 0: op_vector.extend([rng_nm() for _ in range(rec_nm)]) if lig_nm > 0: op_vector.extend([rng_nm() for _ in range(lig_nm)]) new_poses.append(op_vector) return new_poses
def apply_restraints(swarm_centers, receptor_restraints, blocking_restraints, distance_cutoff, translation, swarms_per_restraint=10): """Filter out swarm centers which are not close to the given restraints or too close to blocking residues""" closer_swarms = [] for i, residue in enumerate(receptor_restraints): distances = {} # We will use CA in case of protein, P in case of DNA ca = residue.get_calpha() if not ca: ca = residue.get_atom('P') # Calculate the euclidean distance between swarm center and given atom/bead for swarm_id, center in enumerate(swarm_centers): distances[swarm_id] = cdistance(ca.x + translation[0], ca.y + translation[1], ca.z + translation[2], center[0], center[1], center[2]) sorted_distances = sorted(list(distances.items()), key=operator.itemgetter(1)) swarms_considered = 0 for swarm in sorted_distances: swarm_id, distance = swarm[0], swarm[1] if distance <= distance_cutoff: closer_swarms.append(swarm_id) swarms_considered += 1 if swarms_considered == swarms_per_restraint: break # Unique swarm ids closer_swarm_ids = sorted(list(set(closer_swarms))) # Final filtered list of swarms new_swarm_centers = [swarm_centers[i] for i in closer_swarm_ids] if not blocking_restraints: return new_swarm_centers else: # We need to distinguish between two cases: if len(closer_swarm_ids) > 0: # We have a list of closer swarms to passive and active restraints, we need # to filter out from this list of closer swarms the ones closed to blocking # restraints centers_list = new_swarm_centers else: # From the total list of swarms, we will need to filter out the ones closed to # the blocking residues. This is basically the same as the code for calculating # closer_swarms centers_list = swarm_centers for i, residue in enumerate(blocking_restraints): # We will use CA in case of protein, P in case of DNA ca = residue.get_calpha() if not ca: ca = residue.get_atom('P') to_remove = [] for center_id, center in enumerate(centers_list): d = cdistance(ca.x + translation[0], ca.y + translation[1], ca.z + translation[2], center[0], center[1], center[2]) # Using ligand radius minus 5 Angstroms (10A is the swarm radius) if d <= distance_cutoff - 5.: to_remove.append(center_id) to_remove = list(set(to_remove)) centers_list = [ centers_list[c] for c in range(len(centers_list)) if not c in to_remove ] return centers_list
def distance(self, other): return cdistance(self.x, self.y, self.z, other.x, other.y, other.z)