def test_optimize_geometry(lines):
    """
    Tests if the geometry optimizer performs correct optimization
    of simple geometries. This guards against changes in scipy
    optimize that might effect optimization.
    """
    lines = textwrap.dedent(lines).splitlines()
    force_field = vermouth.forcefield.ForceField(name='test_ff')
    polyply.src.polyply_parser.read_polyply(lines, force_field)
    block = force_field.blocks['test']
    init_coords = _expand_inital_coords(block)
    status, coords = optimize_geometry(block, init_coords)

    assert status

    for bond in itertools.chain(block.interactions["bonds"],
                                block.interactions["constraints"]):
        ref = float(bond.parameters[1])
        dist = np.linalg.norm(coords[bond.atoms[0]] - coords[bond.atoms[1]])
        assert np.isclose(dist, ref, atol=0.05)

    for inter in block.interactions["angles"]:
        ref = float(inter.parameters[1])
        ang = angle(coords[inter.atoms[0]], coords[inter.atoms[1]],
                    coords[inter.atoms[2]])
        assert np.isclose(ang, ref, atol=2)

    for virtual_site in block.interactions["virtual_sitesn"]:
        ref_coord = construct_vs("virtual_sitesn", virtual_site, coords)
        vs_coords = coords[virtual_site.atoms[0]]
        assert np.allclose(ref_coord, vs_coords)
      def test_expand_inital_coords():
        lines = """
        [ moleculetype ]
        GLY 1

        [ atoms ]
        1 P4 1 ALA BB 1
        2 P3 1 ALA SC1 2
        3 P2 1 ALA SC2 3
        4 VS 1 ALA SC3 3

        [ bonds ]
        1 2 1 0.2 100
        2 3 1 0.6 700

        [ virtual_sitesn ]
        4 2 3 1
        """
        lines = textwrap.dedent(lines).splitlines()
        ff = vermouth.forcefield.ForceField(name='test_ff')
        polyply.src.polyply_parser.read_polyply(lines, ff)
        block = ff.blocks['GLY']
        coords = _expand_inital_coords(block)
        assert len(coords) == 4
        for pos in coords.values():
            assert len(pos) == 3
      def test_compute_volume():
          lines = """
          [ moleculetype ]
          GLY 1

          [ atoms ]
          1 P1 1 ALA BB 1
          2 P1 1 ALA SC1 2
          3 P1 1 ALA SC2 3
          4 P1 1 ALA SC3 3

          [ bonds ]
          1 2 1 0.2 100
          2 3 1 0.6 700
          3 4 1 0.2 700
          """
          meta_mol = polyply.MetaMolecule()
          nonbond_params = {frozenset(["P1", "P1"]): {"nb1": 0.47, "nb2":0.5}}

          lines = textwrap.dedent(lines).splitlines()
          ff = vermouth.forcefield.ForceField(name='test_ff')
          polyply.src.polyply_parser.read_polyply(lines, ff)
          block = ff.blocks['GLY']
          coords = _expand_inital_coords(block)
          vol = compute_volume(meta_mol, block, coords, nonbond_params)
          assert vol > 0.
def test_optimize_geometry(lines):
    """
    Tests if the geometry optimizer performs correct optimization
    of simple geometries. This guards against changes in scipy
    optimize that might effect optimization.
    """
    lines = textwrap.dedent(lines).splitlines()
    force_field = vermouth.forcefield.ForceField(name='test_ff')
    polyply.src.polyply_parser.read_polyply(lines, force_field)
    block = force_field.blocks['test']
    for _iteration in range(0, 10):
        init_coords = _expand_inital_coords(block)
        success, coords = optimize_geometry(block, init_coords,
                                            ["bonds", "constraints", "angles"])
        success, coords = optimize_geometry(
            block, coords, ["bonds", "constraints", "angles", "dihedrals"])
        if success:
            break
    else:
        print(_iteration)

    # sanity check
    assert success

    # this part checks that the tolarances are actually obayed in the minimizer
    for bond in itertools.chain(block.interactions["bonds"],
                                block.interactions["constraints"]):
        ref = float(bond.parameters[1])
        dist = np.linalg.norm(coords[bond.atoms[0]] - coords[bond.atoms[1]])
        assert np.isclose(dist, ref, atol=0.05)

    for inter in block.interactions["angles"]:
        ref = float(inter.parameters[1])
        ang = angle(coords[inter.atoms[0]], coords[inter.atoms[1]],
                    coords[inter.atoms[2]])
        assert np.isclose(ang, ref, atol=5)

    # only improper dihedrals
    for inter in block.interactions["dihedrals"]:
        if inter.parameters[0] == "2":
            ref = float(inter.parameters[1])
            ang = dih(coords[inter.atoms[0]], coords[inter.atoms[1]],
                      coords[inter.atoms[2]], coords[inter.atoms[3]])
            assert np.isclose(ang, ref, atol=5)

    for virtual_site in block.interactions["virtual_sitesn"]:
        ref_coord = construct_vs("virtual_sitesn", virtual_site, coords)
        vs_coords = coords[virtual_site.atoms[0]]
        assert np.allclose(ref_coord, vs_coords)
 def test_map_from_CoG():
    lines = """
    [ moleculetype ]
    GLY 1
    [ atoms ]
    1 P4 1 ALA BB 1
    2 P3 1 ALA SC1 2
    3 P2 1 ALA SC2 3
    4 P2 1 ALA SC3 3
    [ bonds ]
    1 2 1 0.2 100
    2 3 1 0.6 700
    3 4 1 0.2 700
    """
    lines = textwrap.dedent(lines).splitlines()
    ff = vermouth.forcefield.ForceField(name='test_ff')
    polyply.src.polyply_parser.read_polyply(lines, ff)
    block = ff.blocks['GLY']
    coords = _expand_inital_coords(block)
    points = np.array(list(coords.values()))
    CoG = center_of_geometry(points)
    new_coords = map_from_CoG(coords)
    for coord in coords:
        coords[coord] == new_coords[coord] + CoG