Skip to content

Commit

Permalink
TST: Add tests directly comparing written parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
mattwthompson committed Apr 23, 2024
1 parent 13e2b77 commit 18d7f7f
Showing 1 changed file with 108 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,6 @@ def test_atom_names_pdb(self):
@needs_gmx
class TestGROMACS:
@pytest.mark.slow
@pytest.mark.skip("from_top is not yet refactored for new Topology API")
@pytest.mark.parametrize("reader", ["intermol", "internal"])
@pytest.mark.parametrize(
"smiles",
Expand Down Expand Up @@ -232,81 +231,6 @@ def test_simple_roundtrip(self, sage, smiles, reader):
},
)

@pytest.mark.slow
@pytest.mark.parametrize("reader", ["intermol", "internal"])
@pytest.mark.parametrize(
"smiles",
[
"CC", # Two identical carbons
"C1CCCCC1", # Identical carbons in the ring
"C1[C@@H](N)C[C@@H](N)CC1", # Identical carbons and nitrogens in the ring
],
)
def test_energies_with_merging_atom_types(self, sage, smiles, reader):
"""
Tests #962
"""
molecule = MoleculeWithConformer.from_smiles(smiles)
molecule.name = molecule.to_hill_formula()
topology = molecule.to_topology()

out = Interchange.from_smirnoff(force_field=sage, topology=topology)
out.box = [4, 4, 4]
out.positions = molecule.conformers[0]

get_gromacs_energies(out).compare(
get_gromacs_energies(out, _merge_atom_types=True),
tolerances={
"Bond": 0.002 * molecule.n_bonds * unit.kilojoule / unit.mol,
"Electrostatics": 0.05 * unit.kilojoule / unit.mol,
},
)

@pytest.mark.slow
@pytest.mark.skip("from_top is not yet refactored for new Topology API")
@pytest.mark.parametrize("reader", ["intermol", "internal"])
@pytest.mark.parametrize(
"smiles",
[
"CC", # Two identical carbons
"C1CCCCC1", # Identical carbons in the ring
"C1[C@@H](N)C[C@@H](N)CC1", # Identical carbons and nitrogens in the ring
],
)
def test_simple_roundtrip_with_merging_atom_types(self, sage, smiles, reader):
"""
Tests #962
"""
molecule = MoleculeWithConformer.from_smiles(smiles)
molecule.name = molecule.to_hill_formula()
topology = molecule.to_topology()

out = Interchange.from_smirnoff(force_field=sage, topology=topology)
out.box = [4, 4, 4]
out.positions = molecule.conformers[0]

out.to_top("out.top")
out.to_top("out_merged.top", _merge_atom_types=True)
out.to_gro("out.gro")

converted = Interchange.from_gromacs("out.top", "out.gro", reader=reader)
converted_merged = Interchange.from_gromacs(
"out_merged.top",
"out.gro",
reader=reader,
)

assert numpy.allclose(converted.positions, converted_merged.positions)
assert numpy.allclose(converted.box, converted_merged.box)

get_gromacs_energies(converted_merged).compare(
get_gromacs_energies(converted),
tolerances={
"Bond": 0.002 * molecule.n_bonds * unit.kilojoule / unit.mol,
"Electrostatics": 0.05 * unit.kilojoule / unit.mol,
},
)

@skip_if_missing("parmed")
def test_num_impropers(self, sage):
out = Interchange.from_smirnoff(
Expand Down Expand Up @@ -571,6 +495,114 @@ def test_common_boxes(self, pdb_file):
)


class TestMergeAtomTypes:
@pytest.mark.slow
@pytest.mark.parametrize(
"smiles",
[
"CC", # Two identical carbons
"C1CCCCC1", # Identical carbons in the ring
"C1[C@@H](N)C[C@@H](N)CC1", # Identical carbons and nitrogens in the ring
],
)
def test_energies_with_merging_atom_types(self, sage, smiles):
"""
Tests #962
"""
molecule = MoleculeWithConformer.from_smiles(smiles)
molecule.name = molecule.to_hill_formula()
topology = molecule.to_topology()

out = Interchange.from_smirnoff(force_field=sage, topology=topology)
out.box = [4, 4, 4]
out.positions = molecule.conformers[0]

get_gromacs_energies(out).compare(
get_gromacs_energies(out, _merge_atom_types=True),
tolerances={
"Bond": 0.002 * molecule.n_bonds * unit.kilojoule / unit.mol,
"Electrostatics": 0.05 * unit.kilojoule / unit.mol,
},
)

@pytest.mark.slow
@pytest.mark.parametrize(
"smiles",
[
"CC", # Two identical carbons
"C1CCCCC1", # Identical carbons in the ring
"C1[C@@H](N)C[C@@H](N)CC1", # Identical carbons and nitrogens in the ring
],
)
def test_simple_roundtrip_with_merging_atom_types(self, sage, smiles):
"""
Tests #962
"""
molecule = MoleculeWithConformer.from_smiles(smiles)
molecule.name = molecule.to_hill_formula()
topology = molecule.to_topology()

out = Interchange.from_smirnoff(force_field=sage, topology=topology)
out.box = [4, 4, 4]
out.positions = molecule.conformers[0]

out.to_top("out.top")
out.to_top("out_merged.top", _merge_atom_types=True)
out.to_gro("out.gro")

converted = Interchange.from_gromacs("out.top", "out.gro")
converted_merged = Interchange.from_gromacs(
"out_merged.top",
"out.gro",
)

assert numpy.allclose(converted.positions, converted_merged.positions)
assert numpy.allclose(converted.box, converted_merged.box)

get_gromacs_energies(converted_merged).compare(
get_gromacs_energies(converted),
tolerances={
"Bond": 0.002 * molecule.n_bonds * unit.kilojoule / unit.mol,
"Electrostatics": 0.05 * unit.kilojoule / unit.mol,
},
)

@pytest.mark.parametrize(
"molecule_list",
[
["CC", "CCO"],
["CC", "CCCC"],
["c1ccccc1", "CC", "CCO", "O"],
["c1ccncc1", "n1cnccc1", "[nH]1cccc1"],
],
)
def test_merge_atom_types_of_similar_molecules(
self,
molecule_list,
sage,
):
pytest.importorskip("parmed")

topology = Topology.from_molecules(
[Molecule.from_smiles(smi) for smi in molecule_list],
)

out = sage.create_interchange(topology)

for merge in [True, False]:
out.to_top(f"{merge}.top", _merge_atom_types=merge)

not_merged = parmed.load_file("False.top")
merged = parmed.load_file("True.top")

# These are (n_atoms x 1) lists of parameters, which should be
# read from [ atoms ] section and cross-referenced to [ atomtypes ]
for attr in ["sigma", "epsilon", "charge"]:
assert [getattr(atom, attr) for atom in not_merged.atoms] == [
getattr(atom, attr) for atom in merged.atoms
]


@needs_gmx
class TestGROMACSVirtualSites:
@pytest.fixture
Expand Down

0 comments on commit 18d7f7f

Please sign in to comment.