Пример #1
0
    def test_from_openmm_pdbfile(self, argon_ff, argon_top):
        pdb_file_path = get_test_file_path("10-argons.pdb")
        pdbfile = openmm.app.PDBFile(pdb_file_path)

        mol = Molecule.from_smiles("[#18]")
        top = Topology.from_openmm(pdbfile.topology, unique_molecules=[mol])
        box = pdbfile.topology.getPeriodicBoxVectors()
        box = box.value_in_unit(nm) * unit.nanometer

        out = argon_ff.create_openff_system(top)
        out.box = box
        out.positions = pdbfile.getPositions()

        assert np.allclose(
            out.positions.to(unit.nanometer).magnitude,
            pdbfile.getPositions().value_in_unit(nm),
        )

        get_openmm_energies(out, hard_cutoff=True).compare(
            _get_openmm_energies(
                omm_sys=argon_ff.create_openmm_system(top),
                box_vectors=pdbfile.topology.getPeriodicBoxVectors(),
                positions=pdbfile.getPositions(),
                hard_cutoff=True,
            ))
Пример #2
0
def test_from_openmm_single_mols(mol, n_mols):
    """
    Test that ForceField.create_openmm_system and System.to_openmm produce
    objects with similar energies

    TODO: Tighten tolerances
    TODO: Test periodic and non-periodic
    """

    parsley = ForceField(get_test_file_path("parsley.offxml"))

    mol = Molecule.from_smiles(mol)
    mol.generate_conformers(n_conformers=1)
    top = Topology.from_molecules(n_mols * [mol])
    mol.conformers[0] -= np.min(mol.conformers) * unit.angstrom

    top.box_vectors = np.eye(3) * np.asarray([10, 10, 10]) * unit.nanometer

    if n_mols == 1:
        positions = mol.conformers[0]
    elif n_mols == 2:
        positions = np.vstack(
            [mol.conformers[0], mol.conformers[0] + 3 * unit.nanometer])
        positions = positions * unit.angstrom

    toolkit_system = parsley.create_openmm_system(top)

    native_system = parsley.create_openff_system(topology=top).to_openmm()

    compare_system_energies(
        system1=toolkit_system,
        system2=native_system,
        positions=positions,
        box_vectors=top.box_vectors,
    )
    def test_to_force_field_to_system_parameters(self, parsley, ethanol_top,
                                                 handler_name, n_ff_terms,
                                                 n_sys_terms):
        import jax

        from openff.system.stubs import ForceField

        handler = parsley[handler_name].create_potential(topology=ethanol_top)

        p = handler.get_force_field_parameters()

        assert isinstance(p, jax.interpreters.xla.DeviceArray)
        assert np.prod(p.shape) == n_ff_terms

        q = handler.get_system_parameters()

        assert isinstance(q, jax.interpreters.xla.DeviceArray)
        assert np.prod(q.shape) == n_sys_terms

        assert jax.numpy.allclose(q, handler.parametrize(p))

        param_matrix = handler.get_param_matrix()

        ref_file = get_test_file_path(
            f"ethanol_param_{handler_name.lower()}.npy")
        ref = jax.numpy.load(ref_file)

        assert jax.numpy.allclose(ref, param_matrix)

        # TODO: Update with other handlers that can safely be assumed to follow 1:1 slot:smirks mapping
        if handler_name in ["vdW", "Bonds", "Angles"]:
            assert np.allclose(np.sum(param_matrix, axis=1),
                               np.ones(param_matrix.shape[0]))
Пример #4
0
def get_mdp_file(key: str) -> Path:
    mapping = {
        "default": "default.mdp",
        "cutoff": "cutoff.mdp",
        "cutoff_hbonds": "cutoff_hbonds.mdp",
        "cutoff_buck": "cutoff_buck.mdp",
    }

    return get_test_file_path(f"mdp/{mapping[key]}")
Пример #5
0
    def test_from_openmm_pdbfile(self, argon_ff, argon_top):
        # TODO: Host files like this here instead of grabbing from the toolkit
        pdb_file_path = get_test_file_path("10-argons.pdb")
        pdbfile = openmm.app.PDBFile(pdb_file_path)

        System(
            topology=argon_top,
            forcefield=argon_ff,
            positions=pdbfile.positions,
            box=pdbfile.topology.getPeriodicBoxVectors(),
        )
Пример #6
0
    def test_parmed_roundtrip(self):
        original = pmd.load_file(get_test_file_path("ALA_GLY/ALA_GLY.top"))
        gro = pmd.load_file(get_test_file_path("ALA_GLY/ALA_GLY.gro"))
        original.box = gro.box
        original.positions = gro.positions

        openff_sys = from_parmed(original)
        roundtrip = openff_sys.to_parmed()

        roundtrip.save("conv.gro", overwrite=True)
        roundtrip.save("conv.top", overwrite=True)

        original_energy = run_gmx_energy(
            top_file=get_test_file_path("ALA_GLY/ALA_GLY.top"),
            gro_file=get_test_file_path("ALA_GLY/ALA_GLY.gro"),
            mdp_file=get_mdp_file("cutoff_hbonds"),
        )
        internal_energy = get_gromacs_energies(openff_sys, mdp="cutoff_hbonds")

        roundtrip_energy = run_gmx_energy(
            top_file="conv.top",
            gro_file="conv.gro",
            mdp_file=get_mdp_file("cutoff_hbonds"),
        )

        # Differences in bond energies appear to be related to ParmEd's rounding
        # of the force constant and equilibrium bond length
        original_energy.compare(internal_energy)
        internal_energy.compare(
            roundtrip_energy,
            custom_tolerances={
                "Bond": 0.02 * omm_unit.kilojoule_per_mole,
            },
        )
        original_energy.compare(
            roundtrip_energy,
            custom_tolerances={
                "Bond": 0.02 * omm_unit.kilojoule_per_mole,
            },
        )
Пример #7
0
def test_water_dimer():
    from openff.system.utils import get_test_file_path

    tip3p = ForceField(get_test_file_path("tip3p.offxml"))
    water = Molecule.from_smiles("O")
    top = Topology.from_molecules(2 * [water])

    pdbfile = openmm.app.PDBFile(get_test_file_path("water-dimer.pdb"))

    positions = np.array(pdbfile.positions / omm_unit.nanometer) * unit.nanometer

    openff_sys = tip3p.create_openff_system(top)
    openff_sys.positions = positions
    openff_sys.box = [10, 10, 10] * unit.nanometer

    omm_energies = get_openmm_energies(
        openff_sys,
        hard_cutoff=True,
        electrostatics=False,
    )

    toolkit_energies = _get_openmm_energies(
        tip3p.create_openmm_system(top),
        openff_sys.box,
        openff_sys.positions,
        hard_cutoff=True,
        electrostatics=False,
    )

    omm_energies.compare(toolkit_energies)

    # TODO: Fix GROMACS energies by handling SETTLE constraints
    # gmx_energies, _ = get_gromacs_energies(openff_sys)
    # compare_gromacs_openmm(omm_energies=omm_energies, gmx_energies=gmx_energies)

    lmp_energies = get_lammps_energies(openff_sys, electrostatics=False)

    lmp_energies.compare(omm_energies)
Пример #8
0
def test_water_dimer():
    """Test that a water dimer can be written and the files can be grommp'd"""
    from openff.system.utils import get_test_file_path

    tip3p = ForceField(get_test_file_path("tip3p.offxml"))
    water = Molecule.from_smiles("O")
    top = Topology.from_molecules(2 * [water])

    from simtk import openmm
    from simtk import unit as omm_unit

    pdbfile = openmm.app.PDBFile(get_test_file_path("water-dimer.pdb"))

    positions = np.array(
        pdbfile.positions / omm_unit.nanometer) * unit.nanometer

    openff_sys = tip3p.create_openff_system(top)
    openff_sys.positions = positions
    openff_sys.box = [10, 10, 10] * unit.nanometer

    gmx_energies = get_gromacs_energies(openff_sys, writer="internal")

    assert gmx_energies is not None
Пример #9
0
def test_argon(n_mol):
    from openff.system.utils import get_test_file_path

    ar_ff = ForceField(get_test_file_path("argon.offxml"))

    mol = Molecule.from_smiles("[#18]")
    mol.add_conformer(np.array([[0, 0, 0]]) * omm_unit.angstrom)
    mol.name = "FOO"
    top = Topology.from_molecules(n_mol * [mol])

    off_sys = ar_ff.create_openff_system(top)

    mol.to_file("out.xyz", file_format="xyz")
    compound: mb.Compound = mb.load("out.xyz")
    packed_box: mb.Compound = mb.fill_box(
        compound=compound,
        n_compounds=[n_mol],
        box=mb.Box([4, 4, 4]),
    )

    positions = packed_box.xyz * unit.nanometer
    positions = np.round(positions, 3)
    off_sys.positions = positions

    box = np.asarray(packed_box.box.lengths) * unit.nanometer
    off_sys.box = box

    omm_energies = get_openmm_energies(
        off_sys, round_positions=8, hard_cutoff=True, electrostatics=False
    )
    gmx_energies = get_gromacs_energies(
        off_sys, writer="internal", electrostatics=False
    )
    lmp_energies = get_lammps_energies(off_sys)

    omm_energies.compare(lmp_energies)

    omm_energies.compare(
        gmx_energies,
        custom_tolerances={
            "Nonbonded": 2e-5 * omm_unit.kilojoule_per_mole,
        },
    )
Пример #10
0
 def ammonia_ff(self):
     """Fixture that loads an SMIRNOFF XML for ammonia"""
     return ForceField(get_test_file_path("ammonia.offxml"))
Пример #11
0
 def argon_ff(self):
     """Fixture that loads an SMIRNOFF XML for argon"""
     return ForceField(get_test_file_path("argon.offxml"))