def GetTorsions(mol):
    """Determine torsion angle atom quartets and parameters from bond graph.
  
  Search bond graph for torsion angle quartets, and parameter tables for mm
  parameters. Use to create a new Torsion object and append to Molecule. Count
  as torsion if ij and jk and kl are bonded in quartet ijkl.
  
  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 k in mol.bond_graph[j].keys():
            if j >= k:
                continue
            at3 = mol.atoms[k]
            r_jk = mol.bond_graph[j][k]
            for i in mol.bond_graph[j].keys():
                if i == j or i == k:
                    continue
                at1 = mol.atoms[i]
                r_ij = mol.bond_graph[i][j]
                for l in mol.bond_graph[k].keys():
                    if i == l or j == l or k == l:
                        continue
                    at4 = mol.atoms[l]
                    r_kl = mol.bond_graph[k][l]
                    t_ijkl = geomcalc.GetTijkl(at1.coords, at2.coords,
                                               at3.coords, at4.coords, r_ij,
                                               r_jk, r_kl)
                    params = param.GetTorsionParam(at1.type_, at2.type_,
                                                   at3.type_, at4.type_)
                    for p in range(len(params)):
                        v_n, gamma, nfold, paths = params[p]
                        if v_n > 0.0:
                            mol.torsions.append(
                                molecule.Torsion(i, j, k, l, t_ijkl, v_n,
                                                 gamma, nfold, paths))
    mol.torsions = sorted(mol.torsions, key=lambda t: t.at4)
    mol.torsions = sorted(mol.torsions, key=lambda t: t.at3)
    mol.torsions = sorted(mol.torsions, key=lambda t: t.at2)
    mol.torsions = sorted(mol.torsions, key=lambda t: t.at1)
    mol.n_torsions = len(mol.torsions)
def _GetTorsion(mol, record):
  """Parse torsion record into a torsion object and append to molecule.
  
  Appends mmlib.molecule.Torsion object to mmlib.molecule.Molecule object.
  Contents of torsion object include (int) 4 atomic indices, (float)
  half-barrier height [kcal/mol], (float) barrier offset [degrees], (int)
  barrier frequency, (int) barrier paths, and (float) torsion angle [degrees].
  
  Args:
    mol (mmlib.molecule.Molecule): Molecule to append torsion.
    record (str*): Array of strings from line of prm file.
  """
  at1, at2, at3, at4 = [x-1 for x in list(map(int, record[1:5]))]
  v_n, gamma = list(map(float, record[5:7]))
  nfold, paths = list(map(int, record[7:9]))
  c1, c2, c3, c4 = [mol.atoms[i].coords for i in [at1, at2, at3, at4]]

  t_ijkl = geomcalc.GetTijkl(c1, c2, c3, c4)
  tors = molecule.Torsion(at1, at2, at3, at4, t_ijkl, v_n, gamma, nfold, paths)
  mol.torsions.append(tors)
def GetTorsions(records, atoms):
    """Parses torsion records into an array of Torsion objects.
  
  Args:
    records (str**): 2d array of strings from lines of prm file.
    atom (mmlib.molecule.Atom*): Array of molecule's Atom objects.

  Returns:
    torsions (mmlib.molecule.Torsion*): Array of Torsion objects with parameters
        from record.
  """
    torsions = []
    for record in records:
        if not record[0].upper() == 'TORSION':
            continue
        at1, at2, at3, at4 = [x - 1 for x in list(map(int, record[1:5]))]
        v_n, gamma = list(map(float, record[5:7]))
        nfold, paths = list(map(int, record[7:9]))
        c1, c2, c3, c4 = [atoms[i].coords for i in [at1, at2, at3, at4]]
        t_ijkl = geomcalc.GetTijkl(c1, c2, c3, c4)
        torsions.append(
            molecule.Torsion(at1, at2, at3, at4, t_ijkl, v_n, gamma, nfold,
                             paths))
    return torsions
 def testReflixe(self):
     """Asserts same value when inverting the order of points."""
     params = ARBITRARY_XYZ5, ARBITRARY_XYZ4, ARBITRARY_XYZ3, ARBITRARY_XYZ2
     self.assertAlmostEqual(geomcalc.GetTijkl(*params), 37.31802340)
 def testArbitraryPositive(self):
     """Asserts correct negative value between arbitrary 3d points."""
     params = ARBITRARY_XYZ2, ARBITRARY_XYZ3, ARBITRARY_XYZ4, ARBITRARY_XYZ5
     self.assertAlmostEqual(geomcalc.GetTijkl(*params), 37.31802340)
 def testArbitraryNegative(self):
     """Asserts correct negative value between arbitrary 3d points."""
     params = ARBITRARY_XYZ1, ARBITRARY_XYZ2, ARBITRARY_XYZ3, ARBITRARY_XYZ4
     self.assertAlmostEqual(geomcalc.GetTijkl(*params), -92.01024227)
 def testPositiveRightTorsion(self):
     """Asserts positive ninety degree torsion combination."""
     params = POSITIVE_UNIT_X, ORIGIN, POSITIVE_UNIT_Y, ARBITRARY_UNIT_XY4
     self.assertAlmostEqual(geomcalc.GetTijkl(*params), 180.0)
 def testNegativeRightTorsion(self):
     """Asserts negative ninety degree torsion combination."""
     params = POSITIVE_UNIT_X, ORIGIN, POSITIVE_UNIT_Y, POSITIVE_UNIT_Z
     self.assertAlmostEqual(geomcalc.GetTijkl(*params), -90.0)
 def testZeroTorsion(self):
     """Asserts zero torsion within the xy-plane."""
     params = POSITIVE_UNIT_X, ORIGIN, POSITIVE_UNIT_Y, ARBITRARY_UNIT_XY1
     self.assertAlmostEqual(geomcalc.GetTijkl(*params), 0.0)