Exemplo n.º 1
0
def getMolParamIDToAtomIndex(molecule, forcefield):
    """Take a Molecule and a SMIRNOFF forcefield object and return a dictionary, keyed by parameter ID, where each entry is a tuple of ( smirks, [[atom1, ... atomN], [atom1, ... atomN]) giving the SMIRKS corresponding to that parameter ID and a list of the atom groups in that molecule that parameter is applied to.

    Parameters
    ----------
    molecule : openforcefield.topology.Molecule
        Molecule to investigate
    forcefield : ForceField
        SMIRNOFF ForceField object (obtained from an ffxml via ForceField(ffxml)) containing FF of interest.

    Returns
    -------
    param_usage : dictionary
        Dictionary, keyed by parameter ID, where each entry is a tuple of ( smirks, [[atom1, ... atomN], [atom1, ... atomN]) giving the SMIRKS corresponding to that parameter ID and a list of the atom groups in that molecule that parameter is applied to.

    """

    topology = Topology()
    topology.add_molecule(molecule)
    labels = ff.labal_molecules(topology)

    param_usage = {}
    for mol_entry in range(len(labels)):
        for force in labels[mol_entry].keys():
            for (atom_indices, pid, smirks) in labels[mol_entry][force]:
                if not pid in param_usage:
                    param_usage[pid] = (smirks, [atom_indices])
                else:
                    param_usage[pid][1].append( atom_indices )

    return param_usage
Exemplo n.º 2
0
    def test_get_virtual_site(self):
        """Test Topology.virtual_site function (get virtual site from index)"""
        topology = Topology()
        topology.add_molecule(self.ethane_from_smiles_w_vsites)
        assert topology.n_topology_virtual_sites == 2
        topology.add_molecule(self.propane_from_smiles_w_vsites)
        assert topology.n_topology_virtual_sites == 4
        with self.assertRaises(Exception) as context:
            topology_vsite = topology.virtual_site(-1)
        with self.assertRaises(Exception) as context:
            topology_vsite = topology.virtual_site(4)
        topology_vsite1 = topology.virtual_site(0)
        topology_vsite2 = topology.virtual_site(1)
        topology_vsite3 = topology.virtual_site(2)
        topology_vsite4 = topology.virtual_site(3)
        assert topology_vsite1.type == "BondChargeVirtualSite"
        assert topology_vsite2.type == "MonovalentLonePairVirtualSite"
        assert topology_vsite3.type == "BondChargeVirtualSite"
        assert topology_vsite4.type == "MonovalentLonePairVirtualSite"

        n_equal_atoms = 0
        for topology_atom in topology.topology_atoms:
            for vsite in topology.topology_virtual_sites:
                for vsite_atom in vsite.atoms:
                    if topology_atom == vsite_atom:
                        n_equal_atoms += 1

        # There are four virtual sites -- Two BondCharges with 2 atoms, and two MonovalentLonePairs with 3 atoms
        assert n_equal_atoms == 10
Exemplo n.º 3
0
 def test_n_topology_atoms(self):
     """Test n_atoms function"""
     topology = Topology()
     assert topology.n_topology_atoms == 0
     assert topology.n_topology_bonds == 0
     topology.add_molecule(self.ethane_from_smiles)
     assert topology.n_topology_atoms == 8
     assert topology.n_topology_bonds == 7
Exemplo n.º 4
0
    def test_to_from_openmm(self):
        """Test a round-trip OpenFF -> OpenMM -> OpenFF Topology."""
        from simtk.openmm.app import Aromatic

        # Create OpenFF topology with 1 ethanol and 2 benzenes.
        ethanol = Molecule.from_smiles("CCO")
        benzene = Molecule.from_smiles("c1ccccc1")
        off_topology = Topology.from_molecules(
            molecules=[ethanol, benzene, benzene])

        # Convert to OpenMM Topology.
        omm_topology = off_topology.to_openmm()

        # Check that bond orders are preserved.
        n_double_bonds = sum([b.order == 2 for b in omm_topology.bonds()])
        n_aromatic_bonds = sum(
            [b.type is Aromatic for b in omm_topology.bonds()])
        assert n_double_bonds == 6
        assert n_aromatic_bonds == 12

        # Check that there is one residue for each molecule.
        assert omm_topology.getNumResidues() == 3
        assert omm_topology.getNumChains() == 3

        # Convert back to OpenFF Topology.
        off_topology_copy = Topology.from_openmm(
            omm_topology, unique_molecules=[ethanol, benzene])

        # The round-trip OpenFF Topology is identical to the original.
        # The reference molecules are the same.
        assert (off_topology.n_reference_molecules ==
                off_topology_copy.n_reference_molecules)
        reference_molecules_copy = list(off_topology_copy.reference_molecules)
        for ref_mol_idx, ref_mol in enumerate(
                off_topology.reference_molecules):
            assert ref_mol == reference_molecules_copy[ref_mol_idx]

        # The number of topology molecules is the same.
        assert (off_topology.n_topology_molecules ==
                off_topology_copy.n_topology_molecules)

        # Check atoms.
        assert off_topology.n_topology_atoms == off_topology_copy.n_topology_atoms
        for atom_idx, atom in enumerate(off_topology.topology_atoms):
            atom_copy = off_topology_copy.atom(atom_idx)
            assert atom.atomic_number == atom_copy.atomic_number

        # Check bonds.
        for bond_idx, bond in enumerate(off_topology.topology_bonds):
            bond_copy = off_topology_copy.bond(bond_idx)
            bond_atoms = [a.atomic_number for a in bond.atoms]
            bond_atoms_copy = [a.atomic_number for a in bond_copy.atoms]
            assert bond_atoms == bond_atoms_copy
            assert bond.bond_order == bond_copy.bond_order
            assert bond.bond.is_aromatic == bond_copy.bond.is_aromatic
Exemplo n.º 5
0
    def test_to_file_units_check(self):
        """
        Checks whether writing pdb with unitless positions, Angstrom positions,
        nanometer positions, result in the same output
        """
        import filecmp
        from tempfile import NamedTemporaryFile

        from simtk.unit import nanometer

        from openforcefield.tests.test_forcefield import create_ethanol
        from openforcefield.topology import Molecule, Topology

        topology = Topology()
        mol = Molecule.from_pdb_and_smiles(
            get_data_file_path("systems/test_systems/1_ethanol.pdb"), "CCO")
        topology.add_molecule(mol)
        positions_angstrom = mol.conformers[0]
        count = 1
        # Write the molecule to PDB and ensure that the X coordinate of the first atom is 10.172
        with NamedTemporaryFile(suffix=".pdb") as iofile:
            topology.to_file(iofile.name, positions_angstrom)
            data = open(iofile.name).readlines()
            for line in data:
                if line.startswith("HETATM") and count == 1:
                    count = count + 1
                    coord = line.split()[-6]
        assert coord == "10.172"

        # Do the same check, but feed in equivalent positions measured in nanometers and ensure the PDB is still the same
        count = 1
        coord = None
        with NamedTemporaryFile(suffix=".pdb") as iofile:
            positions_nanometer = positions_angstrom.in_units_of(nanometer)
            topology.to_file(iofile.name, positions_nanometer)
            data = open(iofile.name).readlines()
            for line in data:
                if line.startswith("HETATM") and count == 1:
                    count = count + 1
                    coord = line.split()[-6]
        assert coord == "10.172"

        count = 1
        coord = "abc"
        with NamedTemporaryFile(suffix=".pdb") as iofile:
            positions_unitless = positions_angstrom._value
            topology.to_file(iofile.name, positions_unitless)
            data = open(iofile.name).readlines()
            for line in data:
                if line.startswith("HETATM") and count == 1:
                    count = count + 1
                    coord = line.split()[-6]
        assert coord == "10.172"
Exemplo n.º 6
0
def generateTopologyFromOEMol(molecule):
    """
    Generate an OpenMM Topology object from an OEMol molecule.

    Parameters
    ----------
    molecule : openeye.oechem.OEMol
        The molecule from which a Topology object is to be generated.

    Returns
    -------
    topology : simtk.openmm.app.Topology
        The Topology object generated from `molecule`.

    """
    warnings.warn(DEPRECATION_WARNING_TEXT, PendingDeprecationWarning)

    from openeye import oechem

    # Avoid manipulating the molecule
    mol = oechem.OEMol(molecule)

    # Create a Topology object with one Chain and one Residue.
    from simtk.openmm.app import Topology
    topology = Topology()
    chain = topology.addChain()
    resname = mol.GetTitle()
    residue = topology.addResidue(resname, chain)

    # Make sure the atoms have names, otherwise bonds won't be created properly below
    if any([atom.GetName() == '' for atom in mol.GetAtoms()]):
        oechem.OETriposAtomNames(mol)
    # Check names are unique; non-unique names will also cause a problem
    atomnames = [atom.GetName() for atom in mol.GetAtoms()]
    if any(atomnames.count(atom.GetName()) > 1 for atom in mol.GetAtoms()):
        raise Exception(
            "Error: Reference molecule must have unique atom names in order to create a Topology."
        )

    # Create atoms in the residue.
    for atom in mol.GetAtoms():
        name = atom.GetName()
        element = openmm.app.element.Element.getByAtomicNumber(
            atom.GetAtomicNum())
        topology.addAtom(name, element, residue)

    # Create bonds.
    atoms = {atom.name: atom for atom in topology.atoms()}
    for bond in mol.GetBonds():
        aromatic = None
        if bond.IsAromatic(): aromatic = 'Aromatic'
        # Add bond, preserving order assessed by OEChem
        topology.addBond(atoms[bond.GetBgn().GetName()],
                         atoms[bond.GetEnd().GetName()],
                         type=aromatic,
                         order=bond.GetOrder())

    return topology
Exemplo n.º 7
0
    def test_box_vectors(self):
        """Test the getter and setter for box_vectors"""
        topology = Topology()
        good_box_vectors = unit.Quantity(np.array([10, 20, 30]), unit.angstrom)
        bad_box_vectors = np.array([10, 20, 30
                                    ])  # They're bad because they're unitless
        assert topology.box_vectors is None

        with self.assertRaises(ValueError) as context:
            topology.box_vectors = bad_box_vectors
        assert topology.box_vectors is None

        topology.box_vectors = good_box_vectors
        assert (topology.box_vectors == good_box_vectors).all()
def smirnoff_analyze_torsions(forcefield,off_mol):
    # Compute the coverage of all torsions in this molecule
    torsions_coverage = defaultdict(list)
    off_top = Off_Topology.from_molecules(off_mol)
    for torsion_indices, torsion_param in forcefield.label_molecules(off_top)[0]['ProperTorsions'].items():
        torsions_coverage[torsion_param].append(torsion_indices)
    return torsions_coverage
Exemplo n.º 9
0
def min_ffxml(mol, ffxml):

    # make copy of the input mol
    oe_mol = oechem.OEGraphMol(mol)

    try:
        # create openforcefield molecule ==> prone to triggering Exception
        off_mol = Molecule.from_openeye(oe_mol)

        # load in force field
        ff = ForceField(ffxml)

        # create components for OpenMM system
        topology = Topology.from_molecules(molecules=[off_mol])

        # create openmm system ==> prone to triggering Exception
        #system = ff.create_openmm_system(topology, charge_from_molecules=[off_mol])
        system = ff.create_openmm_system(topology)

    except Exception as e:
        smilabel = oechem.OEGetSDData(oe_mol, "SMILES QCArchive")
        print( ' >>> openforcefield failed to create OpenMM system: '
               f"'{oe_mol.GetTitle()}' '{smilabel}'")
        print(f"{e}\n")
        return

    print(" >>> successful OpenMM system creation for openforcefield "
         f"mol \"{oe_mol.GetTitle()}\"")
Exemplo n.º 10
0
    def test_chemical_environments_matches_RDK(self):
        """Test Topology.chemical_environment_matches"""
        from simtk.openmm import app

        toolkit_wrapper = RDKitToolkitWrapper()
        pdbfile = app.PDBFile(
            get_data_file_path(
                "systems/packmol_boxes/cyclohexane_ethanol_0.4_0.6.pdb"))
        # toolkit_wrapper = RDKitToolkitWrapper()
        # molecules = [Molecule.from_file(get_data_file_path(name)) for name in ('molecules/ethanol.mol2',
        #                                                                      'molecules/cyclohexane.mol2')]
        molecules = []
        molecules.append(Molecule.from_smiles("CCO"))
        molecules.append(Molecule.from_smiles("C1CCCCC1"))
        topology = Topology.from_openmm(pdbfile.topology,
                                        unique_molecules=molecules)
        # Count CCO matches
        matches = topology.chemical_environment_matches(
            "[C:1]-[C:2]-[O:3]", toolkit_registry=toolkit_wrapper)
        assert len(matches) == 143
        assert matches[0].topology_atom_indices == (1728, 1729, 1730)
        matches = topology.chemical_environment_matches(
            "[H][C:1]([H])([H])-[C:2]([H])([H])-[O:3][H]",
            toolkit_registry=toolkit_wrapper,
        )
        assert (len(matches) == 1716
                )  # 143 * 12 (there are 12 possible hydrogen mappings)
        assert matches[0].topology_atom_indices == (1728, 1729, 1730)
        # Search for a substructure that isn't there
        matches = topology.chemical_environment_matches(
            "[C][C:1]-[C:2]-[O:3]", toolkit_registry=toolkit_wrapper)
        assert len(matches) == 0
Exemplo n.º 11
0
def data_generator():
    for record_name in random.sample(list(ds_qc.data.records), 10):
        try:
            print(record_name, flush=True)
            r = ds_qc.get_record(record_name, specification='default')
            if r is not None:
                traj = r.get_trajectory()
                if traj is not None:
                    for snapshot in traj:

                        mol = snapshot.get_molecule()
                        # mol = snapshot.get_molecule().dict(encoding='json')
                        
                        xyz = tf.convert_to_tensor(
                            mol.geometry * BOHR_TO_NM,
                            dtype=tf.float32)

                        qm_force = tf.convert_to_tensor(
                            snapshot.return_result\
                            * HARTREE_PER_BOHR_TO_KJ_PER_MOL_PER_NM,
                            dtype=tf.float32)

                        mol = cmiles.utils.load_molecule(mol.dict(encoding='json'))

                        top = Topology.from_molecules(Molecule.from_openeye(mol))
                        sys = FF.create_openmm_system(top)

                        yield(
                            xyz,
                            qm_force,
                            sys)
       
        except:
            pass
Exemplo n.º 12
0
    def test_to_file_no_molecules(self):
        """
        Checks if Topology.to_file() writes a file with no topology and no coordinates
        """
        from tempfile import NamedTemporaryFile

        from openforcefield.topology import Topology

        topology = Topology()
        lines = []
        with NamedTemporaryFile(suffix=".pdb") as iofile:
            topology.to_file(iofile.name, [])
            data = open(iofile.name).readlines()
            for line in data:
                lines.append(line.split())
        assert lines[1] == ["END"]
Exemplo n.º 13
0
 def test_chemical_environments_matches_OE(self):
     """Test Topology.chemical_environment_matches"""
     from simtk.openmm import app
     toolkit_wrapper = OpenEyeToolkitWrapper()
     pdbfile = app.PDBFile(
         get_data_file_path(
             'systems/packmol_boxes/cyclohexane_ethanol_0.4_0.6.pdb'))
     # toolkit_wrapper = RDKitToolkitWrapper()
     molecules = [
         Molecule.from_file(get_data_file_path(name))
         for name in ('molecules/ethanol.mol2',
                      'molecules/cyclohexane.mol2')
     ]
     topology = Topology.from_openmm(pdbfile.topology,
                                     unique_molecules=molecules)
     # Test for substructure match
     matches = topology.chemical_environment_matches(
         "[C:1]-[C:2]-[O:3]", toolkit_registry=toolkit_wrapper)
     assert len(matches) == 143
     assert tuple(i.topology_atom_index
                  for i in matches[0]) == (1728, 1729, 1730)
     # Test for whole-molecule match
     matches = topology.chemical_environment_matches(
         "[H][C:1]([H])([H])-[C:2]([H])([H])-[O:3][H]",
         toolkit_registry=toolkit_wrapper)
     assert len(
         matches
     ) == 1716  # 143 * 12 (there are 12 possible hydrogen mappings)
     assert tuple(i.topology_atom_index
                  for i in matches[0]) == (1728, 1729, 1730)
     # Search for a substructure that isn't there
     matches = topology.chemical_environment_matches(
         "[C][C:1]-[C:2]-[O:3]", toolkit_registry=toolkit_wrapper)
     assert len(matches) == 0
Exemplo n.º 14
0
    def serialise_system(self):
        """Create the OpenMM system; parametrise using frost; serialise the system."""

        # Load the molecule using openforcefield
        pdb_file = app.PDBFile(f'{self.molecule.name}.pdb')

        # Now we need the connection info try using smiles string from rdkit
        rdkit = RDKit()
        molecule = Molecule.from_smiles(
            rdkit.get_smiles(f'{self.molecule.name}.pdb'))

        # Make the openMM system
        omm_topology = pdb_file.topology
        off_topology = Topology.from_openmm(omm_topology,
                                            unique_molecules=[molecule])

        # Load the smirnoff99Frosst force field.
        forcefield = ForceField('test_forcefields/smirnoff99Frosst.offxml')

        # Parametrize the topology and create an OpenMM System.
        system = forcefield.create_openmm_system(off_topology)

        # Serialise the OpenMM system into the xml file
        with open('serialised.xml', 'w+') as out:
            out.write(XmlSerializer.serializeSystem(system))
Exemplo n.º 15
0
    def test_to_openmm_assign_unique_atom_names_some_duplicates(self):
        """
        Ensure that OFF topologies where some molecules have invalid/duplicate
        atom names have unique atom names applied while the other molecules are unaffected.
        """
        # Create OpenFF topology with 1 ethanol and 2 benzenes.
        ethanol = Molecule.from_smiles("CCO")

        # Assign duplicate atom names in ethanol (two AT0s)
        ethanol_atom_names_with_duplicates = [
            f"AT{i}" for i in range(ethanol.n_atoms)
        ]
        ethanol_atom_names_with_duplicates[1] = "AT0"
        for atom, atom_name in zip(ethanol.atoms,
                                   ethanol_atom_names_with_duplicates):
            atom.name = atom_name

        # Assign unique atom names in benzene
        benzene = Molecule.from_smiles("c1ccccc1")
        benzene_atom_names = [f"AT{i}" for i in range(benzene.n_atoms)]
        for atom, atom_name in zip(benzene.atoms, benzene_atom_names):
            atom.name = atom_name

        off_topology = Topology.from_molecules(
            molecules=[ethanol, benzene, benzene])
        omm_topology = off_topology.to_openmm()
        atom_names = set()
        for atom in omm_topology.atoms():
            atom_names.add(atom.name)

        # There should be  12 "AT#"-labeled atoms (from benzene), 2 unique Cs,
        # 1 unique O, and 6 unique Hs, for a total of 21 unique atom names
        assert len(atom_names) == 21
Exemplo n.º 16
0
    def openff(self):
        # Load the molecule (for now mol2, until charges are saved on sdf)
        molecule = Molecule.from_file(self.lig + '.mol2')
        topology = Topology.from_molecules([molecule])

        # Label using the smirnoff99Frosst force field
        self.forcefield = ForceField('smirnoff99Frosst.offxml')
        self.parameters = self.forcefield.label_molecules(topology)[0]
Exemplo n.º 17
0
def checkTorsion(smiles, torsion_indices, ff_name):
    """
    Take mollist and check if the molecules in a list match a specific torsion id

        Parameters
        ----------
        molList : List of objects
            List of oemols with datatags generated in genData function

        Returns
        -------
        molList : list of objects
            List of oemol objects that have a datatag "IDMatch" that contain the torsion id
            involved in the QCA torsion drive
    """

    matches = []
    count = 0
    mols = []
    #tid=''
    #molecule = Molecule.from_mapped_smiles(smiles)
    print(smiles)
    from openeye import oechem
    # create a new molecule
    #mol = oechem.OEGraphMol()
    # convert the SMILES string into a molecule
    #oechem.OESmilesToMol(mol,smiles)
    #molecule = Molecule.from_smiles(smiles)
    #molecule=Molecule.from_openeye(mol)

    molecule = Molecule.from_mapped_smiles(smiles)
    topology = Topology.from_molecules(molecule)
    # Let's label using the Parsley force field
    forcefield = ForceField(ff_name, allow_cosmetic_attributes=True)
    # Run the molecule labeling
    molecule_force_list = forcefield.label_molecules(topology)
    params = []
    indices = []
    # Print out a formatted description of the torsion parameters applied to this molecule
    for mol_idx, mol_forces in enumerate(molecule_force_list):
        # print(f'Forces for molecule {mol_idx}')
        for force_tag, force_dict in mol_forces.items():
            if force_tag == "ProperTorsions":
                for (atom_indices, parameter) in force_dict.items():
                    params.append(parameter.id)
                    indices.append(atom_indices)
                    #torsion_indices=tuple(torsion_indices)
                    #print(type(torsion_indices))
                    print(torsion_indices)
                    #print(type(atom_indices))
                    print(atom_indices)
                    if atom_indices == torsion_indices or tuple(
                            reversed(atom_indices)) == torsion_indices:
                        #mol.SetData("IDMatch", parameter.id)
                        tid = parameter.id
    print(params)
    print(indices)
    return tid
Exemplo n.º 18
0
def get_assigned_torsion_param(tdentry, forcefield):
    """Get the OpenFF forcefield torsion parameter ultimately assigned to the
    given TorsionDrive entry's torsion dihedral.

    Parameters
    ----------
    tdentry : TDEntry
        TDEntry (TorsionDrive entry) to operate on;
        will be used to generate molecule, extract dihedral indices driven.
    forcefield : str, ForceField
        OpenFF forcefield to apply.

    Returns
    -------
    torsion_params : ProperTorsion
        Dict-like object with attributes giving the applied torsion parameters

    Examples
    --------
    Starting with TDEntries from usage of `get_torsiondrives_matching_smarts`
    (see its Example), we can get back the parameter assigned to this by, say
    `"openff-1.0.0.offxml"`:
    
    >>> from openforcefield.typing.engines.smirnoff import ForceField
    >>> tdentries = get_torsiondrives_matching_smarts(smarts, dataset, client)
    >>> ff = ForceField('openff-1.0.0.offxml')
    >>> assigned = [smarts_torsions.get_assigned_torsion_param(tdentry, ff)
                    for tdentry in tdentries]

    >>> print([t.id for t in assigned])
        ['t47', 't47', 't47', 't47', ...]

    """
    mol_smiles = tdentry.attributes["canonical_isomeric_explicit_hydrogen_mapped_smiles"]
    offmol = Molecule.from_mapped_smiles(mol_smiles)

    if isinstance(forcefield, str):
        forcefield = ForceField(forcefield)

    # apply forcefield parameters
    topology = Topology.from_molecules(offmol)
    
    # we only have one molecule by definition here, so extracting 0th
    molecule_forces = forcefield.label_molecules(topology)[0]

    # by convention, we only have one driven torsion
    # would need to revisit if we are working with 2D torsions
    dihedral_indices = tdentry.td_keywords.dihedrals[0]

    # get torsion parameters corresponding to dihedral indices
    torsions = molecule_forces["ProperTorsions"]
    torsion_params = torsions.get(dihedral_indices)

    # if None, try reversing it
    if torsion_params is None:
        torsion_params = torsions[dihedral_indices[::-1]]

    return torsion_params
Exemplo n.º 19
0
def minimise_energy_all_confs(mol, models = None, epsilon = 4, allow_undefined_stereo = True, **kwargs ):
    from simtk import unit
    from simtk.openmm import LangevinIntegrator
    from simtk.openmm.app import Simulation, HBonds, NoCutoff
    from rdkit import Chem
    from rdkit.Geometry import Point3D
    import mlddec
    import copy
    import tqdm
    mol = Chem.AddHs(mol, addCoords = True)

    if models is None:
        models  = mlddec.load_models(epsilon)
    charges = mlddec.get_charges(mol, models)

    from openforcefield.utils.toolkits import RDKitToolkitWrapper, ToolkitRegistry
    from openforcefield.topology import Molecule, Topology
    from openforcefield.typing.engines.smirnoff import ForceField
    # from openforcefield.typing.engines.smirnoff.forcefield import PME

    import parmed
    import numpy as np

    forcefield = ForceField(get_data_filename("modified_smirnoff99Frosst.offxml")) #FIXME better way of identifying file location

    tmp = copy.deepcopy(mol)
    tmp.RemoveAllConformers() #XXX workround for speed beacuse seemingly openforcefield records all conformer informations, which takes a long time. but I think this is a ill-practice

    molecule = Molecule.from_rdkit(tmp, allow_undefined_stereo = allow_undefined_stereo)
    molecule.partial_charges = unit.Quantity(np.array(charges), unit.elementary_charge)
    topology = Topology.from_molecules(molecule)
    openmm_system = forcefield.create_openmm_system(topology, charge_from_molecules= [molecule])

    structure = parmed.openmm.topsystem.load_topology(topology.to_openmm(), openmm_system)


    system = structure.createSystem(nonbondedMethod=NoCutoff, nonbondedCutoff=1*unit.nanometer, constraints=HBonds)

    integrator = LangevinIntegrator(273*unit.kelvin, 1/unit.picosecond, 0.002*unit.picoseconds)
    simulation = Simulation(structure.topology, system, integrator)

    out_mol = copy.deepcopy(mol)
    for i in tqdm.tqdm(range(out_mol.GetNumConformers())):
        conf = mol.GetConformer(i)
        structure.coordinates =  unit.Quantity(np.array([np.array(conf.GetAtomPosition(i)) for i in range(mol.GetNumAtoms())]), unit.angstroms)

        simulation.context.setPositions(structure.positions)

        simulation.minimizeEnergy()
        # simulation.step(1)

        coords = simulation.context.getState(getPositions = True).getPositions(asNumpy = True).value_in_unit(unit.angstrom)
        conf = out_mol.GetConformer(i)
        for j in range(out_mol.GetNumAtoms()):
            conf.SetAtomPosition(j, Point3D(*coords[j]))

    return out_mol
def paramUsage(smilesList, offxml):
    """
    Description -
    Reads in list of smiles and returns a dictionary of .offxml style parameters as keys
    and smiles of molecules as items

    Input -
    smilesList: A list of smiles
    offxml: The .offxml format force field that the parameters will be used with

    Return -
    anglebondDict: A dictionary of .offxml style parameters as keys and smiles of molecules that utilize
    parameters. The returned dictionary is only for bond and angle parameters e.g. 'a1', 'b2', etc.
    Note: The function can be modified to return a dictionary of torsion parameters.
    """

    # Initialize storage
    torsionDict = dict()
    anglebondDict = dict()


    # Let's label using our RC force field
    forcefield = ForceField(offxml)

    # Loop over smiles
    for smi in smilesList:

        # Create a simple molecule from SMILES and turn it into a topology.
        molecule = Molecule.from_smiles(smi, allow_undefined_stereo = True)
        topology = Topology.from_molecules([molecule])

        # Run the molecule labeling
        molecule_force_list = forcefield.label_molecules(topology)


        # Print out a formatted description of the parameters applied to this molecule
        for mol_idx, mol_forces in enumerate(molecule_force_list):
            for force_tag, force_dict in mol_forces.items():
                for (atom_indices, parameter) in force_dict.items():
                    pid = parameter.id

                    #create two seperate parameter usage dictionaries for (1) angle and bonds and (2) torsions
                    if "a" in pid or "b" in pid:
                        if not pid in anglebondDict:
                            anglebondDict[pid] = set()
                        anglebondDict[pid].add(smi)

                    #Uncomment this for torsion dictionary
                    #if "t" in pid:
                    #    if not pid in torsionDict:
                    #        torsionDict[pid] = set()
                    #    torsionDict[pid].add(smi)

    #Write out the angle and bond dictionary to "anglebond.p" file
    pickle.dump(anglebondDict, open( "anglebond.p", "wb" ) )

    return anglebondDict
Exemplo n.º 21
0
    def _execute(self, directory, available_resources):

        from openforcefield.topology import Molecule, Topology

        pdb_file = app.PDBFile(self.coordinate_file_path)

        force_field_source = ForceFieldSource.from_json(self.force_field_path)

        if not isinstance(force_field_source, SmirnoffForceFieldSource):
            raise ValueError(
                "Only SMIRNOFF force fields are supported by this protocol.")

        force_field = force_field_source.to_force_field()

        unique_molecules = []
        charged_molecules = []

        if self.apply_known_charges:
            charged_molecules = self._generate_known_charged_molecules()

        # Load in any additional, user specified charged molecules.
        for charged_molecule_path in self.charged_molecule_paths:

            charged_molecule = Molecule.from_file(charged_molecule_path,
                                                  "MOL2")
            charged_molecules.append(charged_molecule)

        for component in self.substance.components:

            molecule = Molecule.from_smiles(smiles=component.smiles)

            if molecule is None:
                raise ValueError(
                    f"{component} could not be converted to a Molecule")

            unique_molecules.append(molecule)

        topology = Topology.from_openmm(pdb_file.topology,
                                        unique_molecules=unique_molecules)

        if len(charged_molecules) > 0:
            system = force_field.create_openmm_system(
                topology, charge_from_molecules=charged_molecules)
        else:
            system = force_field.create_openmm_system(topology)

        if system is None:

            raise RuntimeError(
                "Failed to create a system from the specified topology and molecules."
            )

        system_xml = openmm.XmlSerializer.serialize(system)
        self.system_path = os.path.join(directory, "system.xml")

        with open(self.system_path, "w") as file:
            file.write(system_xml)
Exemplo n.º 22
0
def make_off_system(mol, ID):  ##Now over to OpenForceField:
    drug_pdbfile = PDBFile('./processed_data/aligned_drugs/drug_' + str(ID) +
                           '.pdb')
    drug_mol = Molecule.from_smiles(Chem.MolToSmiles(mol))
    off_topology = Topology.from_openmm(openmm_topology=drug_pdbfile.topology,
                                        unique_molecules=[drug_mol])

    #actual parameterizing step:
    drug_system = ff.create_openmm_system(off_topology)

    return drug_system
Exemplo n.º 23
0
 def test_empty(self):
     """Test creation of empty topology"""
     topology = Topology()
     assert topology.n_reference_molecules == 0
     assert topology.n_topology_molecules == 0
     assert topology.n_topology_atoms == 0
     assert topology.n_topology_bonds == 0
     assert topology.n_topology_particles == 0
     assert topology.n_topology_virtual_sites == 0
     assert topology.box_vectors is None
     assert len(topology.constrained_atom_pairs.items()) == 0
Exemplo n.º 24
0
def create_openmm_system(conversion, molecules):
    """
    Create an OpenMM system using the input MOL2 file and force field file.
    """

    molecule = Molecule.from_openeye(molecules[0])
    topology = Topology.from_molecules([molecule])
    ff = ForceField(conversion.ff)
    system = ff.create_openmm_system(topology)

    return topology, system
Exemplo n.º 25
0
    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 openforcefield.tests.test_forcefield import (
            create_ethanol,
            create_reversed_ethanol,
        )
        from openforcefield.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",
        ]
Exemplo n.º 26
0
    def test_to_file_vsites(self):
        """
        Checks that Topology.to_file() doesn't write vsites
        """
        from tempfile import NamedTemporaryFile

        from openforcefield.topology import Molecule, Topology

        mol = Molecule.from_pdb_and_smiles(
            get_data_file_path("systems/test_systems/1_ethanol.pdb"), "CCO")
        carbons = [atom for atom in mol.atoms if atom.atomic_number == 6]
        positions = mol.conformers[0]
        mol.add_bond_charge_virtual_site(
            (carbons[0], carbons[1]),
            0.1 * unit.angstrom,
            charge_increments=[0.1, 0.05] * unit.elementary_charge,
        )
        topology = Topology()
        topology.add_molecule(mol)
        count = 0
        # The file should be printed out with 9 atoms and 0 virtualsites, so we check to ensure that thtere are only 9 HETATM entries
        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"):
                    count = count + 1
        assert count == 9
Exemplo n.º 27
0
    def test_topology_virtualsites_atom_indexing(self):
        """
        Add multiple instances of the same molecule, but in a different
        order, and ensure that virtualsite atoms 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:
            ref_mol._add_bond_charge_virtual_site(
                [0, 1],
                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]
Exemplo n.º 28
0
def _create_impropers_only_system(
    smiles: str = "CC1=C(C(=O)C2=C(C1=O)N3CC4C(C3(C2COC(=O)N)OC)N4)N",
) -> mm.System:
    """Create a simulation that contains only improper torsion terms,
    by parameterizing with openff-1.2.0 and deleting  all terms but impropers
    """

    molecule = Molecule.from_smiles(smiles, allow_undefined_stereo=True)
    g = esp.Graph(molecule)

    topology = Topology.from_molecules(molecule)
    forcefield = ForceField("openff-1.2.0.offxml")
    openmm_system = forcefield.create_openmm_system(topology)

    # delete all forces except PeriodicTorsionForce
    is_torsion = (
        lambda force: "PeriodicTorsionForce" in force.__class__.__name__)
    for i in range(openmm_system.getNumForces())[::-1]:
        if not is_torsion(openmm_system.getForce(i)):
            openmm_system.removeForce(i)
    assert openmm_system.getNumForces() == 1
    torsion_force = openmm_system.getForce(0)
    assert is_torsion(torsion_force)

    # set k = 0 for any torsion that's not an improper
    indices = set(
        map(
            tuple,
            esp.graphs.utils.offmol_indices.improper_torsion_indices(molecule),
        ))
    num_impropers_retained = 0
    for i in range(torsion_force.getNumTorsions()):
        (
            p1,
            p2,
            p3,
            p4,
            periodicity,
            phase,
            k,
        ) = torsion_force.getTorsionParameters(i)

        if (p1, p2, p3, p4) in indices:
            num_impropers_retained += 1
        else:
            torsion_force.setTorsionParameters(i, p1, p2, p3, p4, periodicity,
                                               phase, 0.0)

    assert (num_impropers_retained > 0
            )  # otherwise this molecule is not a useful test case!

    return openmm_system, topology, g
Exemplo n.º 29
0
    def test_from_openmm_missing_reference(self):
        """Test creation of an openforcefield 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)
Exemplo n.º 30
0
    def test_box_vectors(self):
        """Test the getter and setter for box_vectors"""
        topology = Topology()
        good_box_vectors = unit.Quantity(np.eye(3) * 20 * unit.angstrom)
        one_dim_vectors = unit.Quantity(np.ones(3) * 20 * unit.angstrom)
        bad_shape_vectors = unit.Quantity(np.ones(2) * 20 * unit.angstrom)
        bad_units_vectors = unit.Quantity(np.ones(3) * 20 * unit.year)
        unitless_vectors = np.array([10, 20, 30])
        assert topology.box_vectors is None

        for bad_vectors in [
                bad_shape_vectors,
                bad_units_vectors,
                unitless_vectors,
        ]:
            with self.assertRaises(InvalidBoxVectorsError):
                topology.box_vectors = bad_vectors
            assert topology.box_vectors is None

        for good_vectors in [good_box_vectors, one_dim_vectors]:
            topology.box_vectors = good_vectors
            assert (topology.box_vectors == good_vectors * np.eye(3)).all()