def test_numpy_compliance(self): # Checks that the cython functions give identical results to the numpy versions bonds = MDAnalysis.lib.distances.calc_bonds(self.a, self.b, backend=self.backend) angles = MDAnalysis.lib.distances.calc_angles(self.a, self.b, self.c, backend=self.backend) dihedrals = MDAnalysis.lib.distances.calc_dihedrals(self.a, self.b, self.c, self.d, backend=self.backend) bonds_numpy = np.array([mdamath.norm(y - x) for x, y in zip(self.a, self.b)]) vec1 = self.a - self.b vec2 = self.c - self.b angles_numpy = np.array([mdamath.angle(x, y) for x, y in zip(vec1, vec2)]) ab = self.b - self.a bc = self.c - self.b cd = self.d - self.c dihedrals_numpy = np.array([mdamath.dihedral(x, y, z) for x, y, z in zip(ab, bc, cd)]) assert_almost_equal(bonds, bonds_numpy, self.prec, err_msg="Cython bonds didn't match numpy calculations") # numpy 0 angle returns NaN rather than 0 assert_almost_equal(angles[1:], angles_numpy[1:], self.prec, err_msg="Cython angles didn't match numpy calcuations") # same issue with first two dihedrals assert_almost_equal(dihedrals[2:], dihedrals_numpy[2:], self.prec, err_msg="Cython dihedrals didn't match numpy calculations")
def pseudo_dihe_baseflip(universe, bp1, bp2, i, seg1="SYSTEM", seg2="SYSTEM", seg3="SYSTEM"): """pseudo dihedral for flipped bases. Useful only for nucleic acid base flipping The dihedral is computed based on position atoms for resid `i` .. Note:: This dihedral calculation will only work if using atom names as documented by charmm force field parameters. Parameters ---------- universe : Universe :class:`~MDAnalysis.core.universe.Universe` containing the trajectory bp1 : int resid that base pairs with `bp2` bp2 : int resid below the base that flips i : int resid of the base that flips segid1 : str (optional) segid of resid base pairing with `bp2` segid2 : str (optional) segid, same as that of segid of flipping resid `i` segid3 : str (optional) segid of resid `i` that flips Returns ------- float pseudo dihedral angle in degrees .. versionadded:: 0.8.0 """ bf1 = universe.select_atoms( " ( segid {0!s} and resid {1!s} and nucleicbase ) " "or ( segid {2!s} and resid {3!s} and nucleicbase ) ".format( seg1, bp1, seg2, bp2)) bf4 = universe.select_atoms( "(segid {0!s} and resid {1!s} and nucleicbase) ".format(seg3, i)) bf2 = universe.select_atoms( "(segid {0!s} and resid {1!s} and nucleicsugar) ".format(seg2, bp2)) bf3 = universe.select_atoms( "(segid {0!s} and resid {1!s} and nucleicsugar) ".format(seg3, i)) x = [ bf1.center_of_mass(), bf2.center_of_mass(), bf3.center_of_mass(), bf4.center_of_mass() ] pseudo = mdamath.dihedral(x[0] - x[1], x[1] - x[2], x[2] - x[3]) pseudo = np.rad2deg(pseudo) % 360 return pseudo
def pseudo_dihe_baseflip(universe, bp1, bp2, i, seg1="SYSTEM", seg2="SYSTEM", seg3="SYSTEM"): """pseudo dihedral for flipped bases. Useful only for nucleic acid base flipping The dihedral is computed based on position atoms for resid *i* .. Note:: This dihedral calculation will only work if using atom names as documented by charmm force field parameters. :Arguments: *universe* :class:`~MDAnalysis.core.AtomGroup.Universe` containing the trajectory *segid1* segid of resid base pairing with bp2 *bp1* resid that base pairs with bp2 *segid2* segid same as that of segid of flipping resid *bp2* resid below the base that flips *segid3* segid of resid that flips *i* resid of the base that flips .. versionadded:: 0.8.0 """ bf1 = universe.select_atoms( " ( segid {0!s} and resid {1!s} and nucleicbase ) " "or ( segid {2!s} and resid {3!s} and nucleicbase ) ".format( seg1, bp1, seg2, bp2)) bf4 = universe.select_atoms( "(segid {0!s} and resid {1!s} and nucleicbase) ".format(seg3, i)) bf2 = universe.select_atoms( "(segid {0!s} and resid {1!s} and nucleicsugar) ".format(seg2, bp2)) bf3 = universe.select_atoms( "(segid {0!s} and resid {1!s} and nucleicsugar) ".format(seg3, i)) x = [ bf1.center_of_mass(), bf2.center_of_mass(), bf3.center_of_mass(), bf4.center_of_mass() ] pseudo = mdamath.dihedral(x[0] - x[1], x[1] - x[2], x[2] - x[3]) pseudo = np.rad2deg(pseudo) if pseudo < 0: pseudo = pseudo + 360 return pseudo
def pseudo_dihe_baseflip(universe, bp1, bp2, i, seg1="SYSTEM", seg2="SYSTEM", seg3="SYSTEM"): """pseudo dihedral for flipped bases. Useful only for nucleic acid base flipping The dihedral is computed based on position atoms for resid `i` .. Note:: This dihedral calculation will only work if using atom names as documented by charmm force field parameters. Parameters ---------- universe : Universe :class:`~MDAnalysis.core.universe.Universe` containing the trajectory bp1 : int resid that base pairs with `bp2` bp2 : int resid below the base that flips i : int resid of the base that flips segid1 : str (optional) segid of resid base pairing with `bp2` segid2 : str (optional) segid, same as that of segid of flipping resid `i` segid3 : str (optional) segid of resid `i` that flips Returns ------- float pseudo dihedral angle in degrees .. versionadded:: 0.8.0 """ bf1 = universe.select_atoms( " ( segid {0!s} and resid {1!s} and nucleicbase ) " "or ( segid {2!s} and resid {3!s} and nucleicbase ) " .format( seg1, bp1, seg2, bp2)) bf4 = universe.select_atoms("(segid {0!s} and resid {1!s} and nucleicbase) ".format(seg3, i)) bf2 = universe.select_atoms("(segid {0!s} and resid {1!s} and nucleicsugar) ".format(seg2, bp2)) bf3 = universe.select_atoms("(segid {0!s} and resid {1!s} and nucleicsugar) ".format(seg3, i)) x = [bf1.center_of_mass(), bf2.center_of_mass(), bf3.center_of_mass(), bf4.center_of_mass()] pseudo = mdamath.dihedral(x[0] - x[1], x[1] - x[2], x[2] - x[3]) pseudo = np.rad2deg(pseudo) if pseudo < 0: pseudo = pseudo + 360 return pseudo
def pseudo_dihe_baseflip(universe, bp1, bp2, i, seg1="SYSTEM", seg2="SYSTEM", seg3="SYSTEM"): """pseudo dihedral for flipped bases. Useful only for nucleic acid base flipping The dihedral is computed based on position atoms for resid *i* .. Note:: This dihedral calculation will only work if using atom names as documented by charmm force field parameters. :Arguments: *universe* :class:`~MDAnalysis.core.AtomGroup.Universe` containing the trajectory *segid1* segid of resid base pairing with bp2 *bp1* resid that base pairs with bp2 *segid2* segid same as that of segid of flipping resid *bp2* resid below the base that flips *segid3* segid of resid that flips *i* resid of the base that flips .. versionadded:: 0.8.0 """ bf1 = universe.select_atoms( " ( segid {0!s} and resid {1!s} and nucleicbase ) " "or ( segid {2!s} and resid {3!s} and nucleicbase ) " .format( seg1, bp1, seg2, bp2)) bf4 = universe.select_atoms("(segid {0!s} and resid {1!s} and nucleicbase) ".format(seg3, i)) bf2 = universe.select_atoms("(segid {0!s} and resid {1!s} and nucleicsugar) ".format(seg2, bp2)) bf3 = universe.select_atoms("(segid {0!s} and resid {1!s} and nucleicsugar) ".format(seg3, i)) x = [bf1.center_of_mass(), bf2.center_of_mass(), bf3.center_of_mass(), bf4.center_of_mass()] pseudo = mdamath.dihedral(x[0] - x[1], x[1] - x[2], x[2] - x[3]) pseudo = np.rad2deg(pseudo) if pseudo < 0: pseudo = pseudo + 360 return pseudo
def test_numpy_compliance(self, positions, backend): a, b, c, d = positions # Checks that the cython functions give identical results to the numpy versions bonds = MDAnalysis.lib.distances.calc_bonds(a, b, backend=backend) angles = MDAnalysis.lib.distances.calc_angles(a, b, c, backend=backend) dihedrals = MDAnalysis.lib.distances.calc_dihedrals(a, b, c, d, backend=backend) bonds_numpy = np.array([mdamath.norm(y - x) for x, y in zip(a, b)]) vec1 = a - b vec2 = c - b angles_numpy = np.array( [mdamath.angle(x, y) for x, y in zip(vec1, vec2)]) ab = a - b bc = b - c cd = c - d dihedrals_numpy = np.array( [mdamath.dihedral(x, y, z) for x, y, z in zip(ab, bc, cd)]) assert_almost_equal( bonds, bonds_numpy, self.prec, err_msg="Cython bonds didn't match numpy calculations") # numpy 0 angle returns NaN rather than 0 assert_almost_equal( angles[1:], angles_numpy[1:], self.prec, err_msg="Cython angles didn't match numpy calcuations") assert_almost_equal( dihedrals, dihedrals_numpy, self.prec, err_msg="Cython dihedrals didn't match numpy calculations")
def test_dihedral(self): ab = self.e1 bc = ab + self.e2 cd = bc + self.e3 assert_almost_equal(mdamath.dihedral(ab, bc, cd), -np.pi / 2)
def testDihedral(self): ab = self.e1 bc = ab + self.e2 cd = bc + self.e3 assert_almost_equal(mdamath.dihedral(ab, bc, cd), -pi / 2)