Beispiel #1
0
    def get_parameter_handler_from_forcefield(self, parameter_handler_name,
                                              forcefield):
        """
        It returns a parameter handler from the forcefield based on its
        name.

        Parameters
        ----------
        parameter_handler_name : str
            The name of the parameter handler that is requested
        forcefield : an openforcefield.typing.engines.smirnoff.ForceField
                     object
            The forcefield from which the parameter handler will be obtained

        Returns
        -------
        parameter_handler : an openforcefield.typing.engines.smirnoff.parameters.ParameterHandler
                            object
            The ParameterHandler that was requested
        """
        from openforcefield.typing.engines.smirnoff import ForceField

        if isinstance(forcefield, str):
            forcefield = ForceField(forcefield)
        elif isinstance(forcefield, ForceField):
            pass
        else:
            raise Exception('Invalid forcefield type')

        return forcefield.get_parameter_handler(parameter_handler_name)
Beispiel #2
0
def mock_force_field(parameters: List[SMIRNOFFParameter]):
    """Mock a ForceBalance forcefield directory."""

    # Create the force field directory.
    force_field = ForceField("openff-1.2.0.offxml")

    parameters_to_fit = defaultdict(lambda: defaultdict(list))

    for parameter in parameters:
        parameters_to_fit[parameter.handler][parameter.smirks].append(
            parameter.attribute)

    for handler_name in parameters_to_fit:

        handler = force_field.get_parameter_handler(handler_name)

        for smirks in parameters_to_fit[handler_name]:
            openff_parameter = handler.parameters[smirks]
            attributes_string = ", ".join(
                parameters_to_fit[handler_name][smirks])

            openff_parameter.add_cosmetic_attribute("parameterize",
                                                    attributes_string)

    os.makedirs("forcefield", exist_ok=True)
    force_field.to_file(os.path.join("forcefield", "forcefield.offxml"))
Beispiel #3
0
def test_force_field_custom_handler(mock_entry_point_plugins):
    """Tests a force field can make use of a custom parameter handler registered
    through the entrypoint plugin system.
    """

    # Construct a simple FF which only uses the custom handler.
    force_field_contents = "\n".join([
        "<?xml version='1.0' encoding='ASCII'?>",
        "<SMIRNOFF version='0.3' aromaticity_model='OEAroModel_MDL'>",
        "  <CustomHandler version='0.3'></CustomHandler>", "</SMIRNOFF>"
    ])

    # An exception should be raised when plugins aren't allowed.
    with pytest.raises(KeyError) as error_info:
        ForceField(force_field_contents)

    assert (
        "Cannot find a registered parameter handler class for tag 'CustomHandler'"
        in error_info.value.args[0])

    # Otherwise the FF should be created as expected.
    force_field = ForceField(force_field_contents, load_plugins=True)

    parameter_handler = force_field.get_parameter_handler("CustomHandler")
    assert parameter_handler is not None
    assert parameter_handler.__class__.__name__ == "CustomHandler"
Beispiel #4
0
def test_adding_params_parameterize_flag():
    """
    Test adding new smirks patterns with cosmetic attributes.
    """

    ff = ForceFieldEditor(forcefield_name="openff-1.0.0.offxml")
    # add an atom smirks for boron
    boron = AtomSmirks(smirks="[#5:1]", parameterize={"epsilon"}, atoms={(0,)}, epsilon=0.04, rmin_half=3)
    # add boron with the flag
    ff.add_smirks(smirks=[boron, ], parameterize=True)
    with temp_directory():
        ff.forcefield.to_file(filename="boron.offxml")

        # this should fail if the flag was added
        with pytest.raises(SMIRNOFFSpecError):
            _ = ForceField("boron.offxml", allow_cosmetic_attributes=False)

        boron_ff = ForceField("boron.offxml", allow_cosmetic_attributes=True)
        # now look for the parameter we added
        boron_param = boron_ff.get_parameter_handler(
            "vdW"
        ).parameters["[#5:1]"]
        # now make sure it has the param flag
        param_dict = boron_param.__dict__
        assert param_dict["_cosmetic_attribs"] == ["parameterize"]
        assert param_dict["_parameterize"] == "epsilon"
Beispiel #5
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))
Beispiel #6
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()}\"")
Beispiel #7
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]
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
Beispiel #9
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
Beispiel #10
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
def build_context(offxml, molfile):
    """ Build an OpenMM Context from a offxml file and a molecule file """
    forcefield = ForceField(offxml, allow_cosmetic_attributes=True)
    molecule = OffMolecule.from_file(molfile)
    system = forcefield.create_openmm_system(molecule.to_topology())
    integrator = openmm.VerletIntegrator(1.0 * unit.femtoseconds)
    platform = openmm.Platform.getPlatformByName('Reference')
    context = openmm.Context(system, integrator, platform)
    return context
Beispiel #13
0
def load_forcefield(forcefield="openff_unconstrained-1.1.0"):
    # get a forcefield
    try:
        ff = ForceField("%s.offxml" % forcefield)
    except:
        try:
            ff = ForceField("test_forcefields/%s.offxml" % forcefield)
        except:
            raise NotImplementedError
    return ff
Beispiel #14
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
Beispiel #15
0
    def update_simulation(self, **kwargs):
        """
        Create the simulation object, or update the force field
        parameters in the existing simulation object.  This should be
        run when we write a new force field XML file.
        """
        if len(kwargs) > 0:
            self.simkwargs = kwargs

        self.mod = Modeller(self.pdb.topology, self.pdb.positions)
        self.forcefield = ForceField(*self.offxml)
        # This part requires the OpenEye tools but may be replaced
        # by RDKit when that support comes online.
        oemols = []
        for fnm in self.mol2_files:
            mol = oechem.OEGraphMol()
            ifs = oechem.oemolistream(fnm)
            oechem.OEReadMolecule(ifs, mol)
            oechem.OETriposAtomNames(mol)
            oemols.append(mol)
        self.system = self.forcefield.createSystem(self.pdb.topology, oemols,
                                                   **self.mmopts)

        # Commenting out all virtual site stuff for now.
        # self.vsinfo = PrepareVirtualSites(self.system)
        self.nbcharges = np.zeros(self.system.getNumParticles())

        for i in self.system.getForces():
            if isinstance(i, NonbondedForce):
                self.nbcharges = np.array([
                    i.getParticleParameters(j)[0]._value
                    for j in range(i.getNumParticles())
                ])
                if self.SetPME:
                    i.setNonbondedMethod(i.PME)
            if isinstance(i, AmoebaMultipoleForce):
                if self.SetPME:
                    i.setNonbondedMethod(i.PME)

        #----
        # If the virtual site parameters have changed,
        # the simulation object must be remade.
        #----
        # vsprm = GetVirtualSiteParameters(self.system)
        # if hasattr(self,'vsprm') and len(self.vsprm) > 0 and np.max(np.abs(vsprm - self.vsprm)) != 0.0:
        #     if hasattr(self, 'simulation'):
        #         delattr(self, 'simulation')
        # self.vsprm = vsprm.copy()

        if hasattr(self, 'simulation'):
            UpdateSimulationParameters(self.system, self.simulation)
        else:
            self.create_simulation(**self.simkwargs)
Beispiel #16
0
    def convert(self):
        # Set OEMol
        ifs = oemolistream()
        ifs.SetFlavor(OEFormat_MOL2, OEIFlavor_MOL2_Forcefield)
        ifs.open(self.mol2_file)

        # Read in molecules
        for i, mol in enumerate(ifs.GetOEMols()):
            if i > 0:
                raise Exception(
                    'Only single residue molecules are currently supported')
            OETriposAtomNames(mol)
            self.molecules.append(OEMol(mol))

        # Set topology
        self.mol2_topo = pmd.load_file(self.mol2_file, structure=True)

        # Parameterize
        ff = ForceField('forcefield/smirnoff99Frosst.offxml')
        self.labels = ff.labelMolecules(self.molecules, verbose=False)
        self.off_system = ff.createSystem(self.mol2_topo.topology,
                                          self.molecules,
                                          nonbondedCutoff=1.1 * unit.nanometer,
                                          ewaldErrorTolerance=1e-4)

        # Load into Parmed
        self.pmd_system = pmd.openmm.topsystem.load_topology(
            self.mol2_topo.topology, self.off_system, self.mol2_topo.positions)

        # Convert to AmberParm
        self.parm = pmd.amber.AmberParm.from_structure(self.pmd_system)

        # HACKY PART!!
        # Amber specifies that the third atom in an improper is the central
        # atom, but smirnoff currently specifies the second atom. A check for
        # impropers was conducted during pmd.openmm.topsystem.load_topology(),
        # but that looked at the third atom, so we'll recheck the second atom.
        for i, dihedral in enumerate(cnvs.parm.dihedrals):
            a1 = dihedral.atom1
            a2 = dihedral.atom2
            a3 = dihedral.atom3
            a4 = dihedral.atom4
            if a1 in a2.bond_partners and a3 in a2.bond_partners and a4 in a2.bond_partners:
                (dihedral.atom1, dihedral.atom2, dihedral.atom3,
                 dihedral.atom4) = (a3, a4, a2, a1)
                dihedral.improper = True

        # Create unique atom types
        unique_types = aimtools.unique_types.create_unique_type_list(self.parm)

        # Write AMBER mol2 and frcmod
        aimtools.unique_types.write_unique_frcmod_mol2s(
            self.parm, unique_types, names=self.output_prefix)
Beispiel #17
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
def test_sort_smirnoff_dict():
    from collections import OrderedDict

    from openforcefield.typing.engines.smirnoff import ForceField
    from openforcefield.utils.utils import sort_smirnoff_dict

    forcefield = ForceField("test_forcefields/smirnoff99Frosst.offxml")
    smirnoff_dict = forcefield._to_smirnoff_data()

    # Ensure data is not created or destroyed
    # dict.__eq__ does not check order
    assert smirnoff_dict == OrderedDict(
        sort_smirnoff_dict(forcefield._to_smirnoff_data()))
Beispiel #19
0
def test_update_parameters(smirks_data):
    """
    Test updating the smirks parameters using openff types.
    """
    smirk, result = smirks_data
    # load a forcefield
    ff = ForceField("openff-1.0.0.offxml")
    # all input smirks have parameters set to 0
    off_parameter = ff.get_parameter_handler(
        smirk.type).parameters[smirk.smirks]
    smirk.update_parameters(off_smirk=off_parameter)
    for param, value in result.items():
        assert getattr(smirk, param) == value
Beispiel #20
0
def create_openmm_system_from_smiles(conversion, smiles):
    """
    Create an OpenMM system using SMILES and force field file.
    """

    molecule = Molecule.from_smiles(smiles)
    topology = Topology.from_molecules([molecule])
    ff = ForceField(conversion.ff)
    system = ff.create_openmm_system(topology)

    molecule.generate_conformers(n_conformers=1)

    return topology, system
Beispiel #21
0
def checkTorsion(molList, 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 = []
    for mol in molList:
        molecule = Molecule.from_mapped_smiles(mol.GetData("cmiles"))
        topology = Topology.from_molecules(molecule)
        # Let's label using the Parsley force field
        forcefield = ForceField(ff_name)
        # Run the molecule labeling
        molecule_force_list = forcefield.label_molecules(topology)
        params = []
        # 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)
                        if atom_indices == mol.GetData("TDindices") or tuple(
                            reversed(atom_indices)
                        ) == mol.GetData("TDindices"):
                            count += 1
                            mol.SetData("IDMatch", parameter.id)
                            mols.append(mol)
    print(
        "Out of "
        + str(len(molList))
        + " molecules, "
        + str(count)
        + " were processed with checkTorsion()"
    )

    return mols
Beispiel #22
0
def run_validate_single_point(ffxml, data_folder):
    forcefield = ForceField(ffxml, allow_cosmetic_attributes=True)
    ff_name = os.path.basename(ffxml)
    # read molecules from the data folder
    bench_mol_folders = sorted(os.listdir(data_folder))
    print(f'\n*** Single point benchmark on QM and MM minimized geometries ***')
    print(f"- Number of molecules: {len(bench_mol_folders)}")
    print(f"- Test forcefield : {ff_name}")
    print(f"- Start Time      : {time.ctime()}")
    print(f"- Unit            : kcal/mol \n")
    print(f'{"":5s} | {"":15s} | {"QM Geometry":^47s} | {"MM Geometry":^47s}')
    print(f'{"#":>5s} | {"Molecule ID":15s} | {"E_release":>15s} {"E_test":>15s} {"Diff":>15s} | {"E_release":>15s} {"E_test":>15s} {"Diff":>15s}')
    for i, mol_fol in enumerate(bench_mol_folders):
        folder_path = os.path.join(data_folder, mol_fol)
        # read bench data from folder
        with open(os.path.join(folder_path, 'bench_data.pickle'), 'rb') as pfile:
            bench_data = pickle.load(pfile)
        mol2_path = os.path.join(folder_path, bench_data['mol2_fnm'])
        pdb_path = os.path.join(folder_path, bench_data['pdb_fnm'])
        positions_list = [bench_data['geo1_qm'], bench_data['geo2_mm']]
        ref_energies = [bench_data['energy_geo1'], bench_data['energy_geo2']]
        eval_energies = eval_single_point_energies(forcefield, bench_data['partial_charges'], mol2_path, pdb_path, positions_list)
        e_ref_geo1 = ref_energies[0].value_in_unit(unit.kilocalorie_per_mole)
        e_ref_geo2 = ref_energies[1].value_in_unit(unit.kilocalorie_per_mole)
        e_test_geo1 = eval_energies[0].value_in_unit(unit.kilocalorie_per_mole)
        e_test_geo2 = eval_energies[1].value_in_unit(unit.kilocalorie_per_mole)
        print(f'{i:5d} | {mol_fol:15s} | {e_ref_geo1:15.3f} {e_test_geo1:15.3f} {e_test_geo1-e_ref_geo1:15.3f} | {e_ref_geo2:15.3f} {e_test_geo2:15.3f} {e_test_geo2-e_ref_geo2:15.3f}')
Beispiel #23
0
def generateSMIRNOFFStructure(molecule):
    """
    Given an OpenEye molecule (oechem.OEMol), create an OpenMM System and use to
    generate a ParmEd structure using the SMIRNOFF forcefield parameters.
    """
    from openforcefield.typing.engines.smirnoff import ForceField
    from openforcefield.typing.engines.smirnoff.forcefield_utils import create_system_from_molecule

    ff = get_data_filename('forcefield/smirnoff99Frosst.ffxml')
    with open(ff) as ffxml:
        mol_ff = ForceField(ffxml)

    if not checkCharges(molecule):
        from openmoltools.openeye import get_charges
        print("Assigning charges to molecule.")
        charged_molecule = get_charges(molecule)
    else:
        charged_molecule = molecule
    mol_top, mol_sys, mol_pos = create_system_from_molecule(
        mol_ff, charged_molecule)
    molecule_structure = parmed.openmm.load_topology(mol_top,
                                                     mol_sys,
                                                     xyz=mol_pos)

    return molecule_structure
Beispiel #24
0
def main():
    import argparse
    import pickle
    parser = argparse.ArgumentParser()
    parser.add_argument("dataset",
                        help='Name of the OptimizationDataset on QCFractal')
    parser.add_argument(
        "-l",
        "--load_pickle",
        help='Load downloaded torsiondrive data from pickle file')
    parser.add_argument(
        "-t",
        "--test_ff_fnm",
        required=True,
        help=
        "Provide an offxml for testing the molecules created, skip the ones that failed"
    )
    args = parser.parse_args()

    # step 1: download dataset from server
    if args.load_pickle:
        with open(args.load_pickle, 'rb') as pfile:
            hessian_data = pickle.load(pfile)
            print(
                f"{len(hessian_data)} hessian data entries loaded from {args.load_pickle}"
            )
    else:
        hessian_data = download_hessian_data(args.dataset)
    # step 2: filter the dataset, keep one lowest energy for each molecule
    hessian_data = filter_hessian_data(hessian_data)

    # create a ForceField object for testing
    test_ff = ForceField(args.test_ff_fnm)
    # step 3: generate one target for each data entry
    make_vib_freq_target(args.dataset, hessian_data, test_ff=test_ff)
Beispiel #25
0
def main():
    import argparse
    import pickle
    parser = argparse.ArgumentParser()
    parser.add_argument("dataset",
                        help='Name of the OptimizationDataset on QCFractal')
    parser.add_argument(
        "-l",
        "--load_pickle",
        help='Load downloaded torsiondrive data from pickle file')
    parser.add_argument(
        "-t",
        "--test_ff_fnm",
        required=True,
        help=
        "Provide an offxml for testing the molecules created, skip the ones that failed"
    )
    args = parser.parse_args()

    if args.load_pickle:
        with open(args.load_pickle, 'rb') as pfile:
            torsiondrive_data = pickle.load(pfile)
    else:
        torsiondrive_data = download_torsiondrive_data(args.dataset)

    # require the test_ff for metadata
    test_ff = ForceField(args.test_ff_fnm)
    make_torsiondrive_target(args.dataset, torsiondrive_data, test_ff=test_ff)
Beispiel #26
0
def min_ffxml(mol, ofs, ffxml):
    """
    Minimize the mol with force field input from FFXML file.

    Parameters
    ----------
    mol : OpenEye single-conformer molecule
    ofs : OpenEye output filestream
    ffxml : string
        name of FFXML file

    """

    # 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}: {e}')
        return

    positions = structure.extractPositionsFromOEMol(oe_mol)

    # minimize structure with ffxml
    newpos, energy = run_openmm(topology, system, positions)

    # save geometry, save energy as tag, write mol to file
    oe_mol.SetCoords(oechem.OEFloatArray(newpos))
    oechem.OESetSDData(oe_mol, "Energy FFXML", str(energy))
    oechem.OEWriteConstMolecule(ofs, oe_mol)

    return
Beispiel #27
0
def make_optgeo_target(dataset_name,
                       final_molecules,
                       size=None,
                       test_ff_fnm=None):
    # create the ff for testing
    if test_ff_fnm != None:
        from openforcefield.typing.engines.smirnoff import ForceField
        test_ff = ForceField(test_ff_fnm, allow_cosmetic_attributes=True)
    else:
        test_ff = None
    n_molecules = len(final_molecules)
    if n_molecules == 0:
        print("No molecules found")
        return
    # create and cd into targets folder
    if not os.path.exists('targets'):
        os.mkdir('targets')
    os.chdir('targets')
    if size is None or n_molecules <= size:
        # put all molecules into one target
        target_name = 'optgeo_' + dataset_name.replace(' ', '_')
        n_success = create_target(target_name, final_molecules)
        target_names = [target_name]
    else:
        assert size > 0 and isinstance(size,
                                       int), 'size should be positive int'
        n_groups = (n_molecules + size - 1) // size
        # put molecules into separate targets
        all_molelcule_idxs = list(final_molecules.keys())
        target_names = []
        idx_fmt_string = get_int_fmt_string(n_groups)
        n_success = 0
        for i_g in range(n_groups):
            group_molecule_idxs = all_molelcule_idxs[i_g * size:(i_g + 1) *
                                                     size]
            molecules_data = {
                m_index: final_molecules[m_index]
                for m_index in group_molecule_idxs
            }
            target_name = 'optgeo_' + dataset_name.replace(
                ' ', '_') + '-' + idx_fmt_string.format(i_g)
            this_n_success = create_target(target_name,
                                           molecules_data,
                                           test_ff=test_ff,
                                           start_idx=i_g * size)
            if this_n_success > 0:
                target_names.append(target_name)
                n_success += this_n_success
    print(f"Successfully created targets with total {n_success} molecules")
    # write a targets.in file
    target_in_fnm = f"targets.in.{dataset_name.replace(' ', '_')}"
    with open(target_in_fnm, 'w') as outfile:
        for target_name in target_names:
            outfile.write(target_opts.format(name=target_name))
    os.chdir('..')
    print(f"Targets generation finished!")
    print(
        f"You can copy contents in {os.path.join('targets', target_in_fnm)} to your ForceBalance input file."
    )
Beispiel #28
0
def main():
    import pickle
    forcefield = ForceField('result.offxml', allow_cosmetic_attributes=True)

    tid_molecules_list, failed_smi = list_matching_torsions(
        smi_file='smiles-to-keep.smi', forcefield=forcefield)
    pickle.dump(tid_molecules_list, open('tid_molecules_list.p', 'wb'))
    gen_pdf(tid_molecules_list, output_path='tid_molecules_list.pdf')
Beispiel #29
0
    def _rdkit_parameteriser(cls, mol, **kwargs):
        from rdkit import Chem
        from openforcefield.utils.toolkits import RDKitToolkitWrapper, ToolkitRegistry
        """
        Creates a parameterised system from rdkit molecule

        Parameters
        ----------
        mol : rdkit.Chem.Mol
        """

        try:
            forcefield = ForceField('test_forcefields/smirnoff99Frosst.offxml')
            molecule = Molecule.from_rdkit(
                mol, allow_undefined_stereo=cls.allow_undefined_stereo)
            if hasattr(cls, "_ddec_charger"):
                molecule.partial_charges = unit.Quantity(
                    np.array(cls._ddec_charger(mol, cls.rf)),
                    unit.elementary_charge)
            else:
                from openforcefield.utils.toolkits import AmberToolsToolkitWrapper
                molecule.compute_partial_charges_am1bcc(
                    toolkit_registry=AmberToolsToolkitWrapper())

            topology = Topology.from_molecules(molecule)
            openmm_system = forcefield.create_openmm_system(
                topology, charge_from_molecules=[molecule])

            ligand_pmd = parmed.openmm.topsystem.load_topology(
                topology.to_openmm(), openmm_system, molecule._conformers[0])
        except Exception as e:
            raise ValueError("Parameterisation Failed : {}".format(e))  #TODO

        ligand_pmd.title = cls.smiles

        for i in ligand_pmd.residues:
            i.name = 'LIG'

        tmp_dir = tempfile.mkdtemp()
        # We need all molecules as both pdb files (as packmol input)
        # and mdtraj.Trajectory for restoring bonds later.
        pdb_filename = tempfile.mktemp(suffix=".pdb", dir=tmp_dir)
        Chem.MolToPDBFile(mol, pdb_filename)
        cls.pdb_filename = pdb_filename
        cls.ligand_pmd = ligand_pmd
Beispiel #30
0
def getForceField(*ffpaths):
    hasher = hashlib.md5()
    for path in ffpaths:
        with open(path, 'rb') as f:
            hasher.update(f.read())
    cache_key = hasher.hexdigest()
    if cache_key not in SMIRNOFF_FORCE_FIELD_CACHE:
        SMIRNOFF_FORCE_FIELD_CACHE[cache_key] = ForceField(*ffpaths, allow_cosmetic_attributes=True)
    return SMIRNOFF_FORCE_FIELD_CACHE[cache_key]
Beispiel #31
0
mol_filename = 'mol1.mol2'

# Define a few simulation parameters
time_step = 2*unit.femtoseconds # simulation timestep
temperature = 300*unit.kelvin # simulation temperature
friction = 1/unit.picosecond # collision rate
num_steps = 1000000 # number of steps to run
trj_freq = 1000 # number of steps per written trajectory frame
data_freq = 1000 # number of steps per written simulation statistics

# Load molecule and create pdb object
pdb = PDBFile(pdb_filename)

# Load a SMIRNOFF forcefield
#forcefield = ForceField(get_data_filename('forcefield/Frosst_AlkEthOH_parmAtFrosst.offxml'))
forcefield = ForceField(get_data_filename('forcefield/smirnoff99Frosst.offxml'))

# Load molecule using OpenEye tools
mol = oechem.OEGraphMol()
ifs = oechem.oemolistream(mol_filename)
# LPW: I don't understand the meaning of these lines.
# flavor = oechem.OEIFlavor_Generic_Default | oechem.OEIFlavor_MOL2_Default | oechem.OEIFlavor_MOL2_Forcefield
# ifs.SetFlavor( oechem.OEFormat_MOL2, flavor)
oechem.OEReadMolecule(ifs, mol)
oechem.OETriposAtomNames(mol)

pdbatoms = list(pdb.topology.atoms())

labels = forcefield.labelMolecules([mol])[0]
for key, val in labels.items():
    print(key)