Skip to content

Commit

Permalink
Raise exception when Topology.from_openmm is given virtual sites (#…
Browse files Browse the repository at this point in the history
…1667)

* Raise exception when loading virtual sites from OpenMM

* Update release history
  • Loading branch information
mattwthompson authored Jul 16, 2023
1 parent dbd3e9e commit 0e4af26
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 0 deletions.
2 changes: 2 additions & 0 deletions docs/releasehistory.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ Releases follow the `major.minor.micro` scheme recommended by [PEP440](https://w

### Bugfixes

- [PR #1667](https://github.com/openforcefield/openff-toolkit/pull/1667): A more helpful exception is now raised when `Topology.from_openmm` is given an OpenMM Topology with virtual sites.

### New features

### Improved documentation and warnings
Expand Down
18 changes: 18 additions & 0 deletions openff/toolkit/_tests/test_topology.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
MissingUniqueMoleculesError,
MoleculeNotInTopologyError,
UnassignedChemistryInPDBError,
VirtualSitesUnsupportedError,
WrongShapeError,
)

Expand Down Expand Up @@ -518,6 +519,23 @@ def test_from_openmm(self):
for omm_atom, off_atom in zip(pdbfile.topology.atoms(), topology.atoms):
assert omm_atom.name == off_atom.name

def test_from_openmm_virtual_sites(self):
from openff.toolkit import ForceField

water = Molecule.from_mapped_smiles("[O:1]([H:2])[H:3]")
opc = ForceField("opc-1.0.1.offxml")

openmm_topology = opc.create_interchange([water]).to_openmm_topology()

with pytest.raises(
VirtualSitesUnsupportedError,
match="Atom <Atom 3 \(EP\) of chain 0 residue 0 \(UNK\)>.* a virtual site",
):
Topology.from_openmm(
openmm_topology,
unique_molecules=[water],
)

def test_from_openmm_missing_reference(self):
"""Test creation of an OpenFF Topology object from an OpenMM Topology when missing a unique molecule"""
pdbfile = app.PDBFile(
Expand Down
11 changes: 11 additions & 0 deletions openff/toolkit/topology/topology.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
MissingUniqueMoleculesError,
MoleculeNotInTopologyError,
NotBondedError,
VirtualSitesUnsupportedError,
WrongShapeError,
)
from openff.toolkit.utils.serialization import Serializable
Expand Down Expand Up @@ -1285,6 +1286,12 @@ def _openmm_topology_to_networkx(openmm_topology):
# Convert all openMM mols to graphs
omm_topology_G = nx.Graph()
for atom in openmm_topology.atoms():
if atom.element is None:
raise VirtualSitesUnsupportedError(
f"Atom {atom} has element None and is probably a virtual site. Virtual sites "
"cannot be stored in `Topology` objects but can be stored in `Interchange` "
"objects produced by `ForceField`s with virtual site parameters."
)
omm_topology_G.add_node(
atom.index,
atomic_number=atom.element.atomic_number,
Expand Down Expand Up @@ -1319,6 +1326,10 @@ def from_openmm(
Hierarchy schemes are taken from the OpenMM topology, not from
``unique_molecules``.
If any virtual sites are detected in the OpenMM topology,
``VirtualSitesUnsupportedError`` is raised because the ``Topology``
object model does not store virtual sites.
Parameters
----------
openmm_topology
Expand Down
4 changes: 4 additions & 0 deletions openff/toolkit/utils/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,10 @@ class HierarchySchemeNotFoundException(OpenFFToolkitException):
that doesn't have one with the given iterator name"""


class VirtualSitesUnsupportedError(OpenFFToolkitException):
"""Exception raised when trying to store virtual sites in a `Molecule` or `Topology` object."""


class MissingIndexedAttributeError(
OpenFFToolkitException, IndexError, KeyError, AttributeError
):
Expand Down

0 comments on commit 0e4af26

Please sign in to comment.