def test_angle_between_three(self): """ TestPoint: Test that the angle between three points is computed. """ assert angle_between_three_points( Point(coords=np.array([1, 0, 0])), Point(coords=np.array([0, 0, 0])), Point(coords=np.array([0, 0, 1]))) == np.pi / 2
def test_project_point(self): """ TestPoint: Test that projection onto plane works. """ # First test with projection onto xy-plane value = project_point_onto_plane(Point(coords=np.array([1, 2, 3])), [0, 0, 1, 0]) assert np.array_equal(value.as_array(), np.array([1, 2, 0])) # Now test projection onto plane z = 4 value = project_point_onto_plane(Point(coords=np.array([1, 2, 3])), [0, 0, 1, 4]) assert np.array_equal(value.as_array(), np.array([1, 2, 4]))
def test_normalized_point(self): """ TestPoint: Test that points are normalized. """ assert np.array_equal( normalized_vector(Point(coords=np.array([2, 0, 0]))).as_array(), np.array([1, 0, 0]))
def test_metallic_charges(self): """ TestPDB: Verify that non-protein charges are assigned properly. """ # Test metallic ion charge. magnesium_pdb = PDB() magnesium_atom = Atom(element="MG", coordinates=Point(coords=np.array([0, 0, 0]))) magnesium_pdb.add_new_non_protein_atom(magnesium_atom) metallic_charges = magnesium_pdb.identify_metallic_charges() assert len(metallic_charges) == 1
def setUp(self): """ Instantiates a pair of atom objects for tests. """ self.empty_atom = Atom() self.trial_atom = Atom() self.trial_atom.atomname = "C" self.trial_atom.coordinates = Point(coords=np.array([1, 2, 3])) self.trial_atom.charge = 0. self.trial_atom.element = "C" self.trial_atom.residue = "CYS" # TODO(bramsundar): Fill in a non-junk value for chain. self.trial_atom.chain = "FF" self.trial_atom.indices_of_atoms_connecting = [4, 5, 6]
def setUp(self): """ Instantiate local points for tests. """ self.point_a = Point(coords=np.array([1, 2, 3])) self.point_b = Point(coords=np.array([-1, -2, -3]))
class TestPoint(unittest.TestCase): """ Test point class. """ def setUp(self): """ Instantiate local points for tests. """ self.point_a = Point(coords=np.array([1, 2, 3])) self.point_b = Point(coords=np.array([-1, -2, -3])) def test_copy_of(self): """ TestPoint: Verify that copy_of copies x,y,z correctly. """ copy_point = self.point_a.copy_of() assert np.array_equal(np.array([1, 2, 3]), copy_point.as_array()) def test_average_point(self): """ TestPoint: Verify that averaging works. """ avg_point = average_point([self.point_a, self.point_b]) assert np.array_equal(np.array([0, 0, 0]), avg_point.as_array()) def test_dist_to(self): """ TestPoint: Verify that dist_to implements L2-distance. """ ## || point_a - point_b ||_2 = ||(1,2,3) - (-1,-2,-3)||_2 ## = ||(2,4,6)||_2 ## = sqrt(4 + 16 + 36) ## = sqrt(56) assert self.point_a.dist_to(self.point_b) == np.sqrt(56) def test_magnitude(self): """ TestPoint: Verify that magnitude implements L2-Norm. """ ## || (1, 2, 3) ||_2 = || (-1, -2, -3) ||_2 ## = sqrt(1 + 4 + 9) ## = sqrt(14) assert self.point_a.magnitude() == np.sqrt(14) assert self.point_b.magnitude() == np.sqrt(14) def test_vector_subtraction(self): """ TestPoint: Test that point subtraction works. """ assert np.array_equal(vector_subtraction(self.point_a, self.point_b).as_array(), np.array([2, 4, 6])) def test_cross_product(self): """ TestPoint: Test that cross product works. """ assert np.array_equal(cross_product(self.point_a, self.point_b).as_array(), np.array([0, 0, 0])) def test_vector_scalar(self): """ TestPoint: Test that scalar multiplication works. """ assert np.array_equal(vector_scalar_multiply(self.point_a, 2).as_array(), np.array([2, 4, 6])) def test_dot_prodcut(self): """ TestPoint: Test that dot product works. """ assert dot_product(self.point_a, self.point_b) == -14 def test_angle_between_three(self): """ TestPoint: Test that the angle between three points is computed. """ assert ( angle_between_three_points( Point(coords=np.array([1, 0, 0])), Point(coords=np.array([0, 0, 0])), Point(coords=np.array([0, 0, 1])) ) == np.pi / 2 ) def test_angle_between_points(self): """ TestPoint: Test that the angle between two points is computed correctly. """ assert angle_between_points(self.point_a, self.point_b) == np.pi def test_normalized_point(self): """ TestPoint: Test that points are normalized. """ assert np.array_equal(normalized_vector(Point(coords=np.array([2, 0, 0]))).as_array(), np.array([1, 0, 0])) def test_project_point(self): """ TestPoint: Test that projection onto plane works. """ # First test with projection onto xy-plane value = project_point_onto_plane(Point(coords=np.array([1, 2, 3])), [0, 0, 1, 0]) assert np.array_equal(value.as_array(), np.array([1, 2, 0])) # Now test projection onto plane z = 4 value = project_point_onto_plane(Point(coords=np.array([1, 2, 3])), [0, 0, 1, 4]) assert np.array_equal(value.as_array(), np.array([1, 2, 4]))
def compute_pi_pi_stacking(ligand, receptor): """ Computes pi-pi interactions. Returns a dictionary with keys of form STACKING_${STRUCTURE} where STRUCTURE is "ALPHA" or "BETA" or "OTHER". Values are counts of the number of such stacking interactions. Parameters ---------- ligand: PDB Object. small molecule to dock. receptor: PDB Object protein to dock agains. """ pi_stacking = { 'STACKING_ALPHA': 0, 'STACKING_BETA': 0, 'STACKING_OTHER': 0 } for lig_aromatic in ligand.aromatic_rings: for rec_aromatic in receptor.aromatic_rings: dist = lig_aromatic.center.dist_to(rec_aromatic.center) if dist < PI_PI_CUTOFF: # so there could be some pi-pi interactions. Now, let's # check for stacking interactions. Are the two pi's roughly # parallel? lig_aromatic_norm_vector = Point(coords=np.array([ lig_aromatic.plane_coeff[0], lig_aromatic.plane_coeff[1], lig_aromatic.plane_coeff[2] ])) rec_aromatic_norm_vector = Point(coords=np.array([ rec_aromatic.plane_coeff[0], rec_aromatic.plane_coeff[1], rec_aromatic.plane_coeff[2] ])) angle_between_planes = (angle_between_points( lig_aromatic_norm_vector, rec_aromatic_norm_vector) * 180.0 / math.pi) if (math.fabs(angle_between_planes - 0) < 30.0 or math.fabs(angle_between_planes - 180) < 30.0): # so they're more or less parallel, it's probably pi-pi # stacking now, since pi-pi are not usually right on # top of each other. They're often staggered. So I don't # want to just look at the centers of the rings and # compare. Let's look at each of the atoms. do atom of # the atoms of one ring, when projected onto the plane of # the other, fall within that other ring? # start by assuming it's not a pi-pi stacking interaction pi_pi = False for ligand_ring_index in lig_aromatic.indices: # project the ligand atom onto the plane of the receptor ring pt_on_receptor_plane = project_point_onto_plane( ligand.all_atoms[ligand_ring_index].coordinates, rec_aromatic.plane_coeff) if (pt_on_receptor_plane.dist_to(rec_aromatic.center) <= rec_aromatic.radius + PI_PADDING): pi_pi = True break # TODO(rbharath): This if-else is confusing. if pi_pi == False: for receptor_ring_index in rec_aromatic.indices: # project the ligand atom onto the plane of the receptor ring pt_on_ligand_plane = project_point_onto_plane( receptor.all_atoms[receptor_ring_index]. coordinates, lig_aromatic.plane_coeff) if (pt_on_ligand_plane.dist_to(lig_aromatic.center) <= lig_aromatic.radius + PI_PADDING): pi_pi = True break if pi_pi == True: structure = receptor.all_atoms[ rec_aromatic.indices[0]].structure if structure == "": # since it could be interacting with a cofactor or something structure = "OTHER" key = "STACKING_" + structure hashtable_entry_add_one(pi_stacking, key) return pi_stacking
def compute_pi_t(ligand, receptor): """ Computes T-shaped pi-pi interactions. Returns a dictionary with keys of form T-SHAPED_${STRUCTURE} where STRUCTURE is "ALPHA" or "BETA" or "OTHER". Values are counts of the number of such stacking interactions. Parameters ---------- ligand: PDB Object. small molecule to dock. receptor: PDB Object protein to dock agains. """ pi_t = {'T-SHAPED_ALPHA': 0, 'T-SHAPED_BETA': 0, 'T-SHAPED_OTHER': 0} for lig_aromatic in ligand.aromatic_rings: for rec_aromatic in receptor.aromatic_rings: lig_aromatic_norm_vector = Point(coords=np.array([ lig_aromatic.plane_coeff[0], lig_aromatic.plane_coeff[1], lig_aromatic.plane_coeff[2] ])) rec_aromatic_norm_vector = Point(coords=np.array([ rec_aromatic.plane_coeff[0], rec_aromatic.plane_coeff[1], rec_aromatic.plane_coeff[2] ])) angle_between_planes = (angle_between_points( lig_aromatic_norm_vector, rec_aromatic_norm_vector) * 180.0 / math.pi) if (math.fabs(angle_between_planes - 90) < 30.0 or math.fabs(angle_between_planes - 270) < 30.0): # so they're more or less perpendicular, it's probably a # pi-edge interaction having looked at many structures, I # noticed the algorithm was identifying T-pi reactions # when the two rings were in fact quite distant, often # with other atoms in between. Eye-balling it, requiring # that at their closest they be at least 5 A apart seems # to separate the good T's from the bad min_dist = 100.0 for ligand_ind in lig_aromatic.indices: ligand_at = ligand.all_atoms[ligand_ind] for receptor_ind in rec_aromatic.indices: receptor_at = receptor.all_atoms[receptor_ind] dist = ligand_at.coordinates.dist_to( receptor_at.coordinates) if dist < min_dist: min_dist = dist if min_dist <= 5.0: # so at their closest points, the two rings come within # 5 A of each other. # okay, is the ligand pi pointing into the receptor # pi, or the other way around? first, project the # center of the ligand pi onto the plane of the # receptor pi, and vs. versa # This could be directional somehow, like a hydrogen # bond. pt_on_receptor_plane = project_point_onto_plane( lig_aromatic.center, rec_aromatic.plane_coeff) pt_on_ligand_plane = project_point_onto_plane( rec_aromatic.center, lig_aromatic.plane_coeff) # now, if it's a true pi-T interaction, this projected # point should fall within the ring whose plane it's # been projected into. if ((pt_on_receptor_plane.dist_to(rec_aromatic.center) <= rec_aromatic.radius + PI_PADDING) or (pt_on_ligand_plane.dist_to(lig_aromatic.center) <= lig_aromatic.radius + PI_PADDING)): # so it is in the ring on the projected plane. structure = receptor.all_atoms[ rec_aromatic.indices[0]].structure if structure == "": # since it could be interacting with a cofactor or something structure = "OTHER" key = "T-SHAPED_" + structure hashtable_entry_add_one(pi_t, key) return pi_t
class TestPoint(unittest.TestCase): """ Test point class. """ def setUp(self): """ Instantiate local points for tests. """ self.point_a = Point(coords=np.array([1, 2, 3])) self.point_b = Point(coords=np.array([-1, -2, -3])) def test_copy_of(self): """ TestPoint: Verify that copy_of copies x,y,z correctly. """ copy_point = self.point_a.copy_of() assert np.array_equal(np.array([1, 2, 3]), copy_point.as_array()) def test_average_point(self): """ TestPoint: Verify that averaging works. """ avg_point = average_point([self.point_a, self.point_b]) assert np.array_equal(np.array([0, 0, 0]), avg_point.as_array()) def test_dist_to(self): """ TestPoint: Verify that dist_to implements L2-distance. """ ## || point_a - point_b ||_2 = ||(1,2,3) - (-1,-2,-3)||_2 ## = ||(2,4,6)||_2 ## = sqrt(4 + 16 + 36) ## = sqrt(56) assert self.point_a.dist_to(self.point_b) == np.sqrt(56) def test_magnitude(self): """ TestPoint: Verify that magnitude implements L2-Norm. """ ## || (1, 2, 3) ||_2 = || (-1, -2, -3) ||_2 ## = sqrt(1 + 4 + 9) ## = sqrt(14) assert self.point_a.magnitude() == np.sqrt(14) assert self.point_b.magnitude() == np.sqrt(14) def test_vector_subtraction(self): """ TestPoint: Test that point subtraction works. """ assert np.array_equal( vector_subtraction(self.point_a, self.point_b).as_array(), np.array([2, 4, 6])) def test_cross_product(self): """ TestPoint: Test that cross product works. """ assert np.array_equal( cross_product(self.point_a, self.point_b).as_array(), np.array([0, 0, 0])) def test_vector_scalar(self): """ TestPoint: Test that scalar multiplication works. """ assert np.array_equal( vector_scalar_multiply(self.point_a, 2).as_array(), np.array([2, 4, 6])) def test_dot_prodcut(self): """ TestPoint: Test that dot product works. """ assert dot_product(self.point_a, self.point_b) == -14 def test_angle_between_three(self): """ TestPoint: Test that the angle between three points is computed. """ assert angle_between_three_points( Point(coords=np.array([1, 0, 0])), Point(coords=np.array([0, 0, 0])), Point(coords=np.array([0, 0, 1]))) == np.pi / 2 def test_angle_between_points(self): """ TestPoint: Test that the angle between two points is computed correctly. """ assert angle_between_points(self.point_a, self.point_b) == np.pi def test_normalized_point(self): """ TestPoint: Test that points are normalized. """ assert np.array_equal( normalized_vector(Point(coords=np.array([2, 0, 0]))).as_array(), np.array([1, 0, 0])) def test_project_point(self): """ TestPoint: Test that projection onto plane works. """ # First test with projection onto xy-plane value = project_point_onto_plane(Point(coords=np.array([1, 2, 3])), [0, 0, 1, 0]) assert np.array_equal(value.as_array(), np.array([1, 2, 0])) # Now test projection onto plane z = 4 value = project_point_onto_plane(Point(coords=np.array([1, 2, 3])), [0, 0, 1, 4]) assert np.array_equal(value.as_array(), np.array([1, 2, 4]))