def test_topology_virtualsites_atom_indexing(self): """ Add multiple instances of the same molecule, but in a different order, and ensure that virtual site particles are indexed correctly """ topology = Topology() topology.add_molecule(create_ethanol()) topology.add_molecule(create_ethanol()) topology.add_molecule(create_reversed_ethanol()) # Add a virtualsite to the reference ethanol for ref_mol in topology.reference_molecules: atoms = [ref_mol.atoms[i] for i in [0, 1]] ref_mol._add_bond_charge_virtual_site( atoms, 0.5 * unit.angstrom, ) virtual_site_topology_atom_indices = [(0, 1), (9, 10), (26, 25)] for top_vs, expected_indices in zip( topology.topology_virtual_sites, virtual_site_topology_atom_indices): assert (tuple([at.topology_particle_index for at in top_vs.atoms]) == expected_indices) assert top_vs.atom( 0).topology_particle_index == expected_indices[0] assert top_vs.atom( 1).topology_particle_index == expected_indices[1]
def test_unsupported_mixing_rule(): molecules = [create_ethanol()] pdbfile = app.PDBFile(get_data_file_path("systems/test_systems/1_ethanol.pdb")) topology = OFFBioTop.from_openmm(pdbfile.topology, unique_molecules=molecules) topology.mdtop = md.Topology.from_openmm(topology.to_openmm()) forcefield = ForceField("test_forcefields/test_forcefield.offxml") openff_sys = Interchange.from_smirnoff(force_field=forcefield, topology=topology) openff_sys["vdW"].mixing_rule = "geometric" with pytest.raises(UnsupportedExportError, match="default NonbondedForce"): openff_sys.to_openmm(combine_nonbonded_forces=True)
def test_to_file_multi_molecule_different_order(self): """ Checks for the following if Topology.to_write maintains the order of atoms for the same molecule with different indexing """ from tempfile import NamedTemporaryFile from openff.toolkit.tests.test_forcefield import ( create_ethanol, create_reversed_ethanol, ) from openff.toolkit.topology import Molecule, Topology topology = Topology() topology.add_molecule(create_ethanol()) topology.add_molecule(create_reversed_ethanol()) mol = Molecule.from_pdb_and_smiles( get_data_file_path("systems/test_systems/1_ethanol.pdb"), "CCO") positions = mol.conformers[0] # Make up coordinates for the second ethanol by translating the first by 10 angstroms # (note that this will still be a gibberish conformation, since the atom order in the second molecule is different) positions = np.concatenate( [positions, positions + 10.0 * unit.angstrom]) element_order = [] with NamedTemporaryFile(suffix=".pdb") as iofile: topology.to_file(iofile.name, positions) data = open(iofile.name).readlines() for line in data: if line.startswith("HETATM"): element_order.append(line.strip()[-1]) assert element_order == [ "C", "C", "O", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "O", "C", "C", ]
def test_from_openmm_missing_reference(self): """Test creation of an OpenFF Topology object from an OpenMM Topology when missing a unique molecule""" from simtk.openmm import app pdbfile = app.PDBFile( get_data_file_path( "systems/packmol_boxes/cyclohexane_ethanol_0.4_0.6.pdb")) molecules = [create_ethanol()] with pytest.raises( ValueError, match="No match found for molecule C6H12") as excinfo: topology = Topology.from_openmm(pdbfile.topology, unique_molecules=molecules)
def test_openmm_nonbonded_methods(inputs): """See test_nonbonded_method_resolution in openff/toolkit/tests/test_forcefield.py""" vdw_method = inputs["vdw_method"] electrostatics_method = inputs["electrostatics_method"] periodic = inputs["periodic"] result = inputs["result"] molecules = [create_ethanol()] forcefield = ForceField("test_forcefields/test_forcefield.offxml") pdbfile = app.PDBFile(get_data_file_path("systems/test_systems/1_ethanol.pdb")) topology = Topology.from_openmm(pdbfile.topology, unique_molecules=molecules) if not periodic: topology.box_vectors = None if type(result) == int: nonbonded_method = result # The method is validated and may raise an exception if it's not supported. forcefield.get_parameter_handler("vdW", {}).method = vdw_method forcefield.get_parameter_handler( "Electrostatics", {} ).method = electrostatics_method openff_interchange = Interchange.from_smirnoff( force_field=forcefield, topology=topology ) openmm_system = openff_interchange.to_openmm(combine_nonbonded_forces=True) for force in openmm_system.getForces(): if isinstance(force, openmm.NonbondedForce): assert force.getNonbondedMethod() == nonbonded_method break else: raise Exception elif issubclass(result, (BaseException, Exception)): exception = result forcefield.get_parameter_handler("vdW", {}).method = vdw_method forcefield.get_parameter_handler( "Electrostatics", {} ).method = electrostatics_method openff_interchange = Interchange.from_smirnoff( force_field=forcefield, topology=topology ) with pytest.raises(exception): openff_interchange.to_openmm(combine_nonbonded_forces=True) else: raise Exception("uh oh")
def test_from_openmm(self): """Test creation of an OpenFF Topology object from an OpenMM Topology and component molecules""" from simtk.openmm import app pdbfile = app.PDBFile( get_data_file_path( "systems/packmol_boxes/cyclohexane_ethanol_0.4_0.6.pdb")) with pytest.raises(MissingUniqueMoleculesError, match="requires a list of Molecule objects"): Topology.from_openmm(pdbfile.topology) molecules = [create_ethanol(), create_cyclohexane()] topology = Topology.from_openmm(pdbfile.topology, unique_molecules=molecules) assert topology.n_reference_molecules == 2 assert topology.n_topology_molecules == 239