def GetGDirTorsion(coords1, coords2, coords3, coords4, r_12=None, r_23=None, r_34=None): """Calculate direction of energy gradients between torsion atoms. Args: coords1 (float*): 3 cartesian coordinates [Angstrom] of atom1. coords2 (float*): 3 cartesian coordinates [Angstrom] of atom2. coords3 (float*): 3 cartesian coordinates [Angstrom] of atom3. coords4 (float*): 3 cartesian coordinates [Angstrom] of atom4. r_12 (float): Distance between atom1 and atom2 (default None). r_23 (float): Distance between atom2 and atom3 (default None). r_34 (float): Distance between atom3 and atom4 (default None). Returns: gdir1 (float*), gdir2 (float*), gdir3 (float*), gdir4 (float*): Vectors in the direction of max increasing torsion angle. """ u_21 = geomcalc.GetUij(coords2, coords1, r_12) u_34 = geomcalc.GetUij(coords3, coords4, r_34) u_23 = geomcalc.GetUij(coords2, coords3, r_23) u_32 = -1.0 * u_23 a_123 = geomcalc.GetAijk(coords1, coords2, coords3, r_12, r_23) a_432 = geomcalc.GetAijk(coords4, coords3, coords2, r_34, r_23) s_123 = math.sin(const.DEG2RAD * a_123) s_432 = math.sin(const.DEG2RAD * a_432) c_123 = math.cos(const.DEG2RAD * a_123) c_432 = math.cos(const.DEG2RAD * a_432) gdir1 = geomcalc.GetUcp(u_21, u_23) / (r_12*s_123) gdir4 = geomcalc.GetUcp(u_34, u_32) / (r_34*s_432) gdir2 = (r_12/r_23*c_123 - 1.0)*gdir1 - (r_34/r_23*c_432)*gdir4 gdir3 = (r_34/r_23*c_432 - 1.0)*gdir4 - (r_12/r_23*c_123)*gdir1 return gdir1, gdir2, gdir3, gdir4
def GetAngles(mol): """Determine bond angle atom triplets from bond graph and get parameters. Search bond graph for bond angle triplets, and parameter tables for mm parameters. Use to create a new Angle object and append to Molecule. Count as angle if ij and jk are bonded in triplet ijk. Args: mol (mmlib.molecule.Molecule): Molecule object with bond graph of atom pairs within covalent radius cutoff threshold. """ for j in range(mol.n_atoms): at2 = mol.atoms[j] for i in mol.bond_graph[j].keys(): at1 = mol.atoms[i] r_ij = mol.bond_graph[i][j] for k in mol.bond_graph[j].keys(): if i >= k: continue at3 = mol.atoms[k] r_jk = mol.bond_graph[j][k] a_ijk = geomcalc.GetAijk(at1.coords, at2.coords, at3.coords, r_ij, r_jk) k_a, a_eq = param.GetAngleParam(at1.type_, at2.type_, at3.type_) if k_a > 0.0: mol.angles.append(molecule.Angle(i, j, k, a_ijk, a_eq, k_a)) mol.angles = sorted(mol.angles, key=lambda a: a.at3) mol.angles = sorted(mol.angles, key=lambda a: a.at2) mol.angles = sorted(mol.angles, key=lambda a: a.at1) mol.n_angles = len(mol.angles)
def GetAngles(atoms, bond_graph): """Determine bond angle atom triplets from bond graph and get parameters. Search bond graph for bond angle triplets, and parameter tables for mm parameters. Use to create a new Angle object and append to Molecule. Count as angle if ij and jk are bonded in triplet ijk. Args: atoms (mmlib.molecule.Atom*): Array of molecule's Atom objects. bond_graph (int:(int:float)): Dictionary of bond connectivity. Returns: angles (mmlib.molecule.Angle*): Array of molecule's Angle objects. """ angles = [] for j, at2 in enumerate(atoms): for i, k in itertools.combinations(bond_graph[j], 2): if i > k: continue at1, at3 = atoms[i], atoms[k] a_ijk = geomcalc.GetAijk(at1.coords, at2.coords, at3.coords) k_a, a_eq = param.GetAngleParam(at1.type_, at2.type_, at3.type_) if k_a: angles.append(molecule.Angle(i, j, k, k_a, a_eq, a_ijk)) angles.sort(key=lambda a: (a.at1, a.at2, a.at3)) return angles
def UpdateAngles(angles): """Update all bond angles [degrees] within a molecule object. Args: angles (mmlib.molecule.Angle*): Array of molecule's Angle objects. """ for angle in mol.angles: r12 = mol.bond_graph[angle.at1][angle.at2] r23 = mol.bond_graph[angle.at2][angle.at3] c1 = mol.atoms[angle.at1].coords c2 = mol.atoms[angle.at2].coords c3 = mol.atoms[angle.at3].coords angle.a_ijk = geomcalc.GetAijk(c1, c2, c3, r12, r23)
def UpdateAngles(mol): """Update all bond angles [degrees] within a molecule object. Args: mol (mmlib.molecule.Molecule): Molecule object with angle data. """ for p in range(mol.n_angles): a = mol.angles[p] r12 = mol.bond_graph[a.at1][a.at2] r23 = mol.bond_graph[a.at2][a.at3] c1 = mol.atoms[a.at1].coords c2 = mol.atoms[a.at2].coords c3 = mol.atoms[a.at3].coords a.a_ijk = geomcalc.GetAijk(c1, c2, c3, r12, r23)
def UpdateAngles(angles, atoms, bond_graph): """Update all bond angles [degrees] within a molecule object. Args: angles (mmlib.molecule.Angle*): Array of molecule's Angle objects. atoms (mmlib.molecule.Atom*): Array of molecule's Atom objects. bond_graph (int:(int:float)): Dictionary of bond connectivity. """ for angle in angles: r12 = bond_graph[angle.at1][angle.at2] r23 = bond_graph[angle.at2][angle.at3] c1 = atoms[angle.at1].coords c2 = atoms[angle.at2].coords c3 = atoms[angle.at3].coords angle.a_ijk = geomcalc.GetAijk(c1, c2, c3, r12, r23)
def GetAngleFromPrm(record, atoms): """Parses angle record into an Angle object. Args: record (str*): Array of strings from line of prm file. atoms (mmlib.molecule.Atom*): Array of molecule's Atom objects. Returns: angle (mmlib.molecule.Angle): Angle object with attributes from record. """ at1, at2, at3 = (x - 1 for x in (map(int, record[1:4]))) k_a, a_eq = tuple(map(float, record[4:6])) c1, c2, c3 = (atoms[i].coords for i in (at1, at2, at3)) a_ijk = geomcalc.GetAijk(c1, c2, c3) return molecule.Angle(at1, at2, at3, a_ijk, a_eq, k_a)
def GetGdirOutofplane(coords1, coords2, coords3, coords4, oop, r_31=None, r_32=None, r_34=None): """Calculate direction of energy gradients between outofplane atoms. Args: coords1 (float*): 3 cartesian coordinates [Angstrom] of atom1. coords2 (float*): 3 cartesian coordinates [Angstrom] of atom2. coords3 (float*): 3 cartesian coordinates [Angstrom] of atom3. coords4 (float*): 3 cartesian coordinates [Angstrom] of atom4. oop (float): Out-of-plane angles bewteen atoms 1, 2, 3, and 4. r_31 (float): Distance between atom3 and atom1 (default None). r_32 (float): Distance between atom3 and atom2 (default None). r_34 (float): Distance between atom3 and atom4 (default None). Returns: gdir1 (float*), gdir2 (float*), gdir3 (float*), gdir4 (float*): Vectors in the direction of max increasing outofplane angle. """ if r_31 is not None: r_31 = geomcalc.GetRij(coords3, coords1) if r_32 is not None: r_32 = geomcalc.GetRij(coords3, coords2) if r_34 is not None: r_34 = geomcalc.GetRij(coords3, coords4) u_31 = geomcalc.GetUij(coords3, coords1, r_31) u_32 = geomcalc.GetUij(coords3, coords2, r_32) u_34 = geomcalc.GetUij(coords3, coords4, r_34) cp_3234 = geomcalc.GetCp(u_32, u_34) cp_3431 = geomcalc.GetCp(u_34, u_31) cp_3132 = geomcalc.GetCp(u_31, u_32) a_132 = geomcalc.GetAijk(coords1, coords3, coords2) s_132 = math.sin(const.DEG2RAD * a_132) c_132 = math.cos(const.DEG2RAD * a_132) c_oop = math.cos(const.DEG2RAD * oop) t_oop = math.tan(const.DEG2RAD * oop) gdir1 = ((1.0 / r_31) * (cp_3234 / (c_oop * s_132) - (t_oop / s_132**2) * (u_31 - c_132 * u_32))) gdir2 = ((1.0 / r_32) * (cp_3431 / (c_oop * s_132) - (t_oop / s_132**2) * (u_32 - c_132 * u_31))) gdir4 = ((1.0 / r_34) * (cp_3132 / (c_oop * s_132) - (t_oop * u_34))) gdir3 = -1.0 * (gdir1 + gdir2 + gdir4) return gdir1, gdir2, gdir3, gdir4
def _GetAngle(mol, record): """Parse angle record into an angle object and append to molecule. Appends mmlib.molecule.Angle object to mmlib.molecule.Molecule object. Contents of angle object include (int) 3 atomic indices, (float) spring constant [kcal/(mol*radian^2)], (float) equilibrium bond angle [degrees], and (float) bond angle [degrees]. Args: mol (mmlib.molecule.Molecule): Molecule to append angle. record (str*): Array of strings from line of prm file. """ at1, at2, at3 = [x-1 for x in list(map(int, record[1:4]))] k_a, a_eq = list(map(float, record[4:6])) c1, c2, c3 = [mol.atoms[i].coords for i in [at1, at2, at3]] a_ijk = geomcalc.GetAijk(c1, c2, c3) angle = molecule.Angle(at1, at2, at3, a_ijk, a_eq, k_a) mol.angles.append(angle)
def GetAngles(records, atoms): """Parses angle records into an array of Angle objects. Args: records (str**): 2d array of strings from lines of prm file. atom (mmlib.molecule.Atom*): Array of molecule's Atom objects. Returns: angles (mmlib.molecule.Angle): Array of Angle objects with parameters from records. """ angles = [] for record in records: if not record[0].upper() == 'ANGLE': continue at1, at2, at3 = [x - 1 for x in list(map(int, record[1:4]))] k_a, a_eq = list(map(float, record[4:6])) c1, c2, c3 = [atoms[i].coords for i in [at1, at2, at3]] a_ijk = geomcalc.GetAijk(c1, c2, c3) angles.append(molecule.Angle(at1, at2, at3, a_ijk, a_eq, k_a)) return angles
def testZeroAngle(self): """Asserts zero angle between identical vectors.""" params = ORIGIN, NEGATIVE_UNIT_Z, ORIGIN self.assertAlmostEqual(geomcalc.GetAijk(*params), 0.0)
def testStraightAngle(self): """Asserts 180 degree angle between oppositie vectors.""" params = POSITIVE_UNIT_Z, ORIGIN, NEGATIVE_UNIT_Z self.assertAlmostEqual(geomcalc.GetAijk(*params), 180.0)
def testReflexive(self): """Asserts same value when inverting the order of points.""" params = ARBITRARY_XYZ4, ARBITRARY_XYZ3, ARBITRARY_XYZ2 self.assertAlmostEqual(geomcalc.GetAijk(*params), 97.75040394)
def testRightAngle(self): """Asserts ninety degree angle between orthogonal vectors.""" params = POSITIVE_UNIT_X, ORIGIN, POSITIVE_UNIT_Y self.assertAlmostEqual(geomcalc.GetAijk(*params), 90.0)
def testArbitraryObtuse(self): """Asserts correct value between arbitrary obtuse 3d points.""" params = ARBITRARY_XYZ2, ARBITRARY_XYZ3, ARBITRARY_XYZ4 self.assertAlmostEqual(geomcalc.GetAijk(*params), 97.75040394)
def testArbitraryAcute(self): """Asserts correct value between arbitrary acute 3d points.""" params = ARBITRARY_XYZ1, ARBITRARY_XYZ2, ARBITRARY_XYZ3 self.assertAlmostEqual(geomcalc.GetAijk(*params), 82.37365716)
def testInPlaneYZ(self): """Asserts correct value within the yz-plane.""" params = ARBITRARY_YZ1, ARBITRARY_YZ2, ARBITRARY_YZ3 self.assertAlmostEqual(geomcalc.GetAijk(*params), 23.05201986)
def testInPlaneXZ(self): """Asserts correct value within the xz-plane.""" params = ARBITRARY_XZ1, ARBITRARY_XZ2, ARBITRARY_XZ3 self.assertAlmostEqual(geomcalc.GetAijk(*params), 42.14774907)
def testInPlaneXY(self): """Asserts correct value within the xy-plane.""" params = ARBITRARY_XY1, ARBITRARY_XY2, ARBITRARY_XY3 self.assertAlmostEqual(geomcalc.GetAijk(*params), 29.07348364)