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)
#!/bin/env python from openforcefield.utils import * from openforcefield.typing.engines.smirnoff import get_molecule_parameterIDs, ForceField # Create an oemol mol = OEMol() OEParseSmiles(mol, 'CCC') OEAddExplicitHydrogens(mol) ff = ForceField(get_data_filename('forcefield/Frosst_AlkEthOH.ffxml')) labels = ff.labelMolecules([mol], verbose=True) print labels for mol_entry in range(len(labels)): for force in labels[mol_entry].keys(): print("\n%s:" % force) for (atom_indices, pid, smirks) in labels[mol_entry][force]: atomstr = '' for idx in atom_indices: atomstr += '%6s' % idx print("%s : %s \t smirks %s" % (atomstr, pid, smirks))
#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) for v in val: anames = '-'.join([pdbatoms[i].name for i in v[0]]) anums = '-'.join([str(i) for i in v[0]]) print("%20s %20s %5s %-s" % (anames, anums, v[1], v[2])) # The rest of this is not needed. sys.exit() # Create the OpenMM system system = forcefield.createSystem(pdb.topology, [mol], nonbondedMethod=PME, nonbondedCutoff=1.0 * unit.nanometers, rigidWater=True)
def get_molecule_parameterIDs(oemols, ffxml): """Process a list of oemols with a specified SMIRNOFF ffxml file and determine which parameters are used by which molecules, returning collated results. Parameters ---------- oemols : list List of OpenEye OEChem molecules to parse; must have explicit hydrogens. Returns ------- parameters_by_molecule : dict Parameter IDs used in each molecule, keyed by isomeric SMILES generated from provided OEMols. Each entry in the dict is a list which does not necessarily have unique entries; i.e. parameter IDs which are used more than once will occur multiple times. parameters_by_ID : dict Molecules in which each parameter ID occur, keyed by parameter ID. Each entry in the dict is a set of isomeric SMILES for molecules in which that parameter occurs. No frequency information is stored. """ # Create storage parameters_by_molecule = {} parameters_by_ID = {} # Generate isomeric SMILES isosmiles = list() for mol in oemols: smi = oechem.OECreateIsoSmiString(mol) if not smi in isosmiles: isosmiles.append(smi) # If the molecule is already here, raise exception else: raise ValueError( "Error: get_molecule_parameterIDs has been provided a list of oemols which contains the same molecule, having isomeric smiles %s, more than once." % smi) # Label molecules ff = ForceField(ffxml) labels = ff.labelMolecules(oemols) # Organize labels into output dictionary by looping over all molecules/smiles for idx in range(len(isosmiles)): # Pull smiles, initialize storage smi = isosmiles[idx] parameters_by_molecule[smi] = [] # Organize data for this molecule data = labels[idx] for force_type in data.keys(): for (atom_indices, pid, smirks) in data[force_type]: # Store pid to molecule parameters_by_molecule[smi].append(pid) # Store which molecule this pid occurred in if pid not in parameters_by_ID: parameters_by_ID[pid] = set() parameters_by_ID[pid].add(smi) else: parameters_by_ID[pid].add(smi) return parameters_by_molecule, parameters_by_ID
# 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) for v in val: anames = '-'.join([pdbatoms[i].name for i in v[0]]) anums = '-'.join([str(i) for i in v[0]]) print("%20s %20s %5s %-s" % (anames, anums, v[1], v[2])) # The rest of this is not needed. sys.exit() # Create the OpenMM system system = forcefield.createSystem(pdb.topology, [mol], nonbondedMethod=PME, nonbondedCutoff=1.0*unit.nanometers, rigidWater=True) # Set up an OpenMM simulation integrator = openmm.LangevinIntegrator(temperature, friction, time_step)