def _generate_ffxmls(): import os print(os.getcwd()) print("Parameterizing T4 inhibitors") from perses.tests.testsystems import T4LysozymeInhibitorsTestSystem from openmoltools import forcefield_generators testsystem_t4 = T4LysozymeInhibitorsTestSystem() smiles_list_t4 = testsystem_t4.molecules oemols_t4 = [generate_molecule_from_smiles(smiles, idx=i) for i, smiles in enumerate(smiles_list_t4)] ffxml_str_t4, failed_list = forcefield_generators.generateForceFieldFromMolecules(oemols_t4, ignoreFailures=True) ffxml_out_t4 = open('/Users/grinawap/T4-inhibitors.xml','w') ffxml_out_t4.write(ffxml_str_t4) ffxml_out_t4.close() if failed_list: print("Failed some T4 inhibitors") _print_failed_SMILES(failed_list) print("Parameterizing kinase inhibitors") from perses.tests.testsystems import KinaseInhibitorsTestSystem testsystem_kinase = KinaseInhibitorsTestSystem() smiles_list_kinase = testsystem_kinase.molecules oemols_kinase = [generate_molecule_from_smiles(smiles, idx=i) for i, smiles in enumerate(smiles_list_kinase)] ffxml_str_kinase, failed_kinase_list = forcefield_generators.generateForceFieldFromMolecules(oemols_kinase, ignoreFailures=True) ffxml_out_kinase = open("/Users/grinawap/kinase-inhibitors.xml",'w') ffxml_out_kinase.write(ffxml_str_kinase) ffxml_out_t4.close()
def test_generate_ffxml_from_molecules(): """ Test generation of single ffxml file from a list of molecules """ # Create a test set of molecules. molecules = [createOEMolFromIUPAC(name) for name in IUPAC_molecule_names] # Create an ffxml file. from openmoltools.forcefield_generators import generateForceFieldFromMolecules ffxml = generateForceFieldFromMolecules(molecules) # Create a ForceField. gaff_xml_filename = utils.get_data_filename("parameters/gaff.xml") forcefield = ForceField(gaff_xml_filename) try: forcefield.loadFile(StringIO(ffxml)) except Exception as e: msg = str(e) msg += "ffxml contents:\n" for (index, line) in enumerate(ffxml.split('\n')): msg += 'line %8d : %s\n' % (index, line) raise Exception(msg) # Parameterize the molecules. from openmoltools.forcefield_generators import generateTopologyFromOEMol for molecule in molecules: # Create topology from molecule. topology = generateTopologyFromOEMol(molecule) # Create system with forcefield. system = forcefield.createSystem(topology) # Check potential is finite. positions = extractPositionsFromOEMOL(molecule) check_potential_is_finite(system, positions)
def test_generate_ffxml_from_molecules(): """ Test generation of single ffxml file from a list of molecules """ # Create a test set of molecules. molecules = [createOEMolFromIUPAC(name) for name in IUPAC_molecule_names] # Create an ffxml file. from openmoltools.forcefield_generators import generateForceFieldFromMolecules ffxml = generateForceFieldFromMolecules(molecules) # Create a ForceField. gaff_xml_filename = utils.get_data_filename("parameters/gaff.xml") forcefield = ForceField(gaff_xml_filename) try: forcefield.loadFile(StringIO(ffxml)) except Exception as e: msg = str(e) msg += "ffxml contents:\n" for (index, line) in enumerate(ffxml.split("\n")): msg += "line %8d : %s\n" % (index, line) raise Exception(msg) # Parameterize the molecules. from openmoltools.forcefield_generators import generateTopologyFromOEMol for molecule in molecules: # Create topology from molecule. topology = generateTopologyFromOEMol(molecule) # Create system with forcefield. system = forcefield.createSystem(topology) # Check potential is finite. positions = extractPositionsFromOEMOL(molecule) check_potential_is_finite(system, positions)
def write_xml(topology, file_name): residues = [residue for residue in topology.residues()] residue = residues[0] molOE = generateOEMolFromTopologyResidue(residue, geometry=False, tripos_atom_names=True) molOE.SetTitle('MOL') ffxml = generateForceFieldFromMolecules([molOE]) f = open(file_name, 'w') f.write(ffxml) f.close()
def generate_ffxml(pdb_filename): from simtk.openmm.app import PDBFile, Modeller pdbfile = PDBFile(pdb_filename) residues = [ residue for residue in pdbfile.topology.residues() ] residue = residues[0] from openmoltools.forcefield_generators import generateForceFieldFromMolecules, generateOEMolFromTopologyResidue molecule = generateOEMolFromTopologyResidue(residue, geometry=False, tripos_atom_names=True) molecule.SetTitle('MOL') molecules = [molecule] ffxml = generateForceFieldFromMolecules(molecules) outfile = open('imatinib.xml', 'w') outfile.write(ffxml) outfile.close()
def generate_ffxml(pdb_filename): from simtk.openmm.app import PDBFile, Modeller pdbfile = PDBFile(pdb_filename) residues = [residue for residue in pdbfile.topology.residues()] residue = residues[0] from openmoltools.forcefield_generators import generateForceFieldFromMolecules, generateOEMolFromTopologyResidue molecule = generateOEMolFromTopologyResidue(residue, geometry=False, tripos_atom_names=True) molecule.SetTitle('MOL') molecules = [molecule] ffxml = generateForceFieldFromMolecules(molecules) outfile = open('imatinib.xml', 'w') outfile.write(ffxml) outfile.close()
def generate_forcefield(molecule_file, outfile): ifs = oechem.oemolistream() ifs.open(molecule_file) # get the list of molecules mol_list = [normalize_molecule(oechem.OEMol(mol)) for mol in ifs.GetOEMols()] # TODO: HORRIBLE HACK ; WILL DIE AT > 999 RESIDUES! for idx, mol in enumerate(mol_list): mol.SetTitle("%03d" % idx) ffxml = forcefield_generators.generateForceFieldFromMolecules(mol_list, normalize=False) with open(outfile, 'w') as output_file: output_file.write(ffxml)
def generate_forcefield(molecule_file, outfile): ifs = oechem.oemolistream() ifs.open(molecule_file) # get the list of molecules mol_list = [ normalize_molecule(oechem.OEMol(mol)) for mol in ifs.GetOEMols() ] # TODO: HORRIBLE HACK ; WILL DIE AT > 999 RESIDUES! for idx, mol in enumerate(mol_list): mol.SetTitle("%03d" % idx) ffxml = forcefield_generators.generateForceFieldFromMolecules( mol_list, normalize=False) with open(outfile, 'w') as output_file: output_file.write(ffxml)
#!/usr/bin/env python """ Generate ffxml files for ligands in a multi-mole mol2. """ mol2_filename = 'Imatinib-epik-charged.mol2' ffxml_filename = 'Imatinib-epik-charged.ffxml' # Read mol2 file containing protonation states and extract canonical isomeric SMILES from this. print("Reading molecules") from openeye import oechem ifs = oechem.oemolistream(mol2_filename) mol = oechem.OEMol() molecules = list() while oechem.OEReadMolecule(ifs, mol): molecules.append(oechem.OEMol(mol)) print("Generating forcefield parameters...") from openmoltools.forcefield_generators import generateForceFieldFromMolecules ffxml = generateForceFieldFromMolecules(molecules, ignoreFailures=False, generateUniqueNames=True) print("Writing forcefield to '%s'..." % ffxml_filename) outfile = open(ffxml_filename, 'w') outfile.write(ffxml) outfile.close()
#!/usr/bin/env python """ Generate ffxml files for ligands in a multi-mole mol2. """ import openeye import openmoltools mol2_filename = 'Imatinib-epik-charged.mol2' ffxml_filename = 'Imatinib-epik-charged.ffxml' # Read mol2 file containing protonation states and extract canonical isomeric SMILES from this. print("Reading molecules") from openeye import oechem ifs = oechem.oemolistream(mol2_filename) mol = oechem.OEMol() molecules = list() while oechem.OEReadMolecule(ifs, mol): molecules.append(oechem.OEMol(mol)) print("Generating forcefield parameters...") from openmoltools.forcefield_generators import generateForceFieldFromMolecules ffxml = generateForceFieldFromMolecules(molecules, ignoreFailures=False, generateUniqueNames=True) print("Writing forcefield to '%s'..." % ffxml_filename) outfile = open(ffxml_filename, 'w') outfile.write(ffxml) outfile.close()
def generate_solvated_hybrid_test_topology(current_mol_name="naphthalene", proposed_mol_name="benzene", current_mol_smiles=None, proposed_mol_smiles=None, vacuum=False, render_atom_mapping=False): """ This function will generate a topology proposal, old positions, and new positions with a geometry proposal (either vacuum or solvated) given a set of input iupacs or smiles. The function will (by default) read the iupac names first. If they are set to None, then it will attempt to read a set of current and new smiles. An atom mapping pdf will be generated if specified. Arguments ---------- current_mol_name : str, optional name of the first molecule proposed_mol_name : str, optional name of the second molecule current_mol_smiles : str (default None) current mol smiles proposed_mol_smiles : str (default None) proposed mol smiles vacuum: bool (default False) whether to render a vacuum or solvated topology_proposal render_atom_mapping : bool (default False) whether to render the atom map of the current_mol_name and proposed_mol_name Returns ------- topology_proposal : perses.rjmc.topology_proposal The topology proposal representing the transformation current_positions : np.array, unit-bearing The positions of the initial system new_positions : np.array, unit-bearing The positions of the new system """ import simtk.openmm.app as app from openmoltools import forcefield_generators from openeye import oechem from openmoltools.openeye import iupac_to_oemol, generate_conformers, smiles_to_oemol from openmoltools import forcefield_generators import perses.utils.openeye as openeye from perses.utils.data import get_data_filename from perses.rjmc.topology_proposal import TopologyProposal, SystemGenerator, SmallMoleculeSetProposalEngine import simtk.unit as unit from perses.rjmc.geometry import FFAllAngleGeometryEngine if current_mol_name != None and proposed_mol_name != None: try: old_oemol, new_oemol = iupac_to_oemol( current_mol_name), iupac_to_oemol(proposed_mol_name) old_smiles = oechem.OECreateSmiString( old_oemol, oechem.OESMILESFlag_DEFAULT | oechem.OESMILESFlag_Hydrogens) new_smiles = oechem.OECreateSmiString( new_oemol, oechem.OESMILESFlag_DEFAULT | oechem.OESMILESFlag_Hydrogens) except: raise Exception( f"either {current_mol_name} or {proposed_mol_name} is not compatible with 'iupac_to_oemol' function!" ) elif current_mol_smiles != None and proposed_mol_smiles != None: try: old_oemol, new_oemol = smiles_to_oemol( current_mol_smiles), smiles_to_oemol(proposed_mol_smiles) old_smiles = oechem.OECreateSmiString( old_oemol, oechem.OESMILESFlag_DEFAULT | oechem.OESMILESFlag_Hydrogens) new_smiles = oechem.OECreateSmiString( new_oemol, oechem.OESMILESFlag_DEFAULT | oechem.OESMILESFlag_Hydrogens) except: raise Exception(f"the variables are not compatible") else: raise Exception( f"either current_mol_name and proposed_mol_name must be specified as iupacs OR current_mol_smiles and proposed_mol_smiles must be specified as smiles strings." ) old_oemol, old_system, old_positions, old_topology = openeye.createSystemFromSMILES( old_smiles, title="MOL") #correct the old positions old_positions = openeye.extractPositionsFromOEMol(old_oemol) old_positions = old_positions.in_units_of(unit.nanometers) new_oemol, new_system, new_positions, new_topology = openeye.createSystemFromSMILES( new_smiles, title="NEW") ffxml = forcefield_generators.generateForceFieldFromMolecules( [old_oemol, new_oemol]) old_oemol.SetTitle('MOL') new_oemol.SetTitle('MOL') old_topology = forcefield_generators.generateTopologyFromOEMol(old_oemol) new_topology = forcefield_generators.generateTopologyFromOEMol(new_oemol) if not vacuum: nonbonded_method = app.PME barostat = openmm.MonteCarloBarostat(1.0 * unit.atmosphere, 300.0 * unit.kelvin, 50) else: nonbonded_method = app.NoCutoff barostat = None gaff_xml_filename = get_data_filename("data/gaff.xml") system_generator = SystemGenerator( [gaff_xml_filename, 'amber99sbildn.xml', 'tip3p.xml'], barostat=barostat, forcefield_kwargs={ 'removeCMMotion': False, 'nonbondedMethod': nonbonded_method, 'constraints': app.HBonds, 'hydrogenMass': 4.0 * unit.amu }) system_generator._forcefield.loadFile(StringIO(ffxml)) proposal_engine = SmallMoleculeSetProposalEngine([old_smiles, new_smiles], system_generator, residue_name='MOL') geometry_engine = FFAllAngleGeometryEngine(metadata=None, use_sterics=False, n_bond_divisions=1000, n_angle_divisions=180, n_torsion_divisions=360, verbose=True, storage=None, bond_softening_constant=1.0, angle_softening_constant=1.0, neglect_angles=False) if not vacuum: #now to solvate modeller = app.Modeller(old_topology, old_positions) hs = [ atom for atom in modeller.topology.atoms() if atom.element.symbol in ['H'] and atom.residue.name not in ['MOL', 'OLD', 'NEW'] ] modeller.delete(hs) modeller.addHydrogens(forcefield=system_generator._forcefield) modeller.addSolvent(system_generator._forcefield, model='tip3p', padding=9.0 * unit.angstroms) solvated_topology = modeller.getTopology() solvated_positions = modeller.getPositions() solvated_positions = unit.quantity.Quantity(value=np.array([ list(atom_pos) for atom_pos in solvated_positions.value_in_unit_system(unit.md_unit_system) ]), unit=unit.nanometers) solvated_system = system_generator.build_system(solvated_topology) #now to create proposal top_proposal = proposal_engine.propose( current_system=solvated_system, current_topology=solvated_topology, current_mol=old_oemol, proposed_mol=new_oemol) new_positions, _ = geometry_engine.propose(top_proposal, solvated_positions, beta) if render_atom_mapping: from perses.utils.smallmolecules import render_atom_mapping print( f"new_to_old: {proposal_engine.non_offset_new_to_old_atom_map}" ) render_atom_mapping(f"{old_smiles}to{new_smiles}.png", old_oemol, new_oemol, proposal_engine.non_offset_new_to_old_atom_map) return top_proposal, solvated_positions, new_positions else: vacuum_system = system_generator.build_system(old_topology) top_proposal = proposal_engine.propose(current_system=vacuum_system, current_topology=old_topology, current_mol=old_oemol, proposed_mol=new_oemol) new_positions, _ = geometry_engine.propose(top_proposal, old_positions, beta) if render_atom_mapping: from perses.utils.smallmolecules import render_atom_mapping print(f"new_to_old: {top_proposal._new_to_old_atom_map}") render_atom_mapping(f"{old_smiles}to{new_smiles}.png", old_oemol, new_oemol, top_proposal._new_to_old_atom_map) return top_proposal, old_positions, new_positions
def __init__(self, protein_pdb_filename, ligand_file, old_ligand_index, new_ligand_index, forcefield_files, pressure=1.0 * unit.atmosphere, temperature=300.0 * unit.kelvin, solvent_padding=9.0 * unit.angstroms): """ Initialize a NonequilibriumFEPSetup object Parameters ---------- protein_pdb_filename : str The name of the protein pdb file ligand_file : str the name of the ligand file (any openeye supported format) ligand_smiles : list of two str The SMILES strings representing the two ligands forcefield_files : list of str The list of ffxml files that contain the forcefields that will be used pressure : Quantity, units of pressure Pressure to use in the barostat temperature : Quantity, units of temperature Temperature to use for the Langevin integrator solvent_padding : Quantity, units of length The amount of padding to use when adding solvent """ self._protein_pdb_filename = protein_pdb_filename self._pressure = pressure self._temperature = temperature self._barostat_period = 50 self._padding = solvent_padding self._ligand_file = ligand_file self._old_ligand_index = old_ligand_index self._new_ligand_index = new_ligand_index self._old_ligand_oemol = self.load_sdf(self._ligand_file, index=self._old_ligand_index) self._new_ligand_oemol = self.load_sdf(self._ligand_file, index=self._new_ligand_index) self._old_ligand_positions = extractPositionsFromOEMOL( self._old_ligand_oemol) ffxml = forcefield_generators.generateForceFieldFromMolecules( [self._old_ligand_oemol, self._new_ligand_oemol]) self._old_ligand_oemol.SetTitle("MOL") self._new_ligand_oemol.SetTitle("MOL") self._new_ligand_smiles = oechem.OECreateSmiString( self._new_ligand_oemol, oechem.OESMILESFlag_DEFAULT | oechem.OESMILESFlag_Hydrogens) #self._old_ligand_smiles = '[H]c1c(c(c(c(c1N([H])c2nc3c(c(n2)OC([H])([H])C4(C(C(C(C(C4([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])[H])nc(n3[H])[H])[H])[H])S(=O)(=O)C([H])([H])[H])[H]' self._old_ligand_smiles = oechem.OECreateSmiString( self._old_ligand_oemol, oechem.OESMILESFlag_DEFAULT | oechem.OESMILESFlag_Hydrogens) print(self._new_ligand_smiles) print(self._old_ligand_smiles) self._old_ligand_topology = forcefield_generators.generateTopologyFromOEMol( self._old_ligand_oemol) self._old_ligand_md_topology = md.Topology.from_openmm( self._old_ligand_topology) self._new_ligand_topology = forcefield_generators.generateTopologyFromOEMol( self._new_ligand_oemol) self._new_liands_md_topology = md.Topology.from_openmm( self._new_ligand_topology) protein_pdbfile = open(self._protein_pdb_filename, 'r') pdb_file = app.PDBFile(protein_pdbfile) protein_pdbfile.close() self._protein_topology_old = pdb_file.topology self._protein_md_topology_old = md.Topology.from_openmm( self._protein_topology_old) self._protein_positions_old = pdb_file.positions self._forcefield = app.ForceField(*forcefield_files) self._forcefield.loadFile(StringIO(ffxml)) print("Generated forcefield") self._complex_md_topology_old = self._protein_md_topology_old.join( self._old_ligand_md_topology) self._complex_topology_old = self._complex_md_topology_old.to_openmm() n_atoms_complex_old = self._complex_topology_old.getNumAtoms() n_atoms_protein_old = self._protein_topology_old.getNumAtoms() self._complex_positions_old = unit.Quantity(np.zeros( [n_atoms_complex_old, 3]), unit=unit.nanometers) self._complex_positions_old[: n_atoms_protein_old, :] = self._protein_positions_old self._complex_positions_old[ n_atoms_protein_old:, :] = self._old_ligand_positions if pressure is not None: barostat = openmm.MonteCarloBarostat(self._pressure, self._temperature, self._barostat_period) self._system_generator = SystemGenerator( forcefield_files, barostat=barostat, forcefield_kwargs={'nonbondedMethod': app.PME}) else: self._system_generator = SystemGenerator(forcefield_files) #self._complex_proposal_engine = TwoMoleculeSetProposalEngine(self._old_ligand_smiles, self._new_ligand_smiles, self._system_generator, residue_name="MOL") self._complex_proposal_engine = TwoMoleculeSetProposalEngine( self._old_ligand_oemol, self._new_ligand_oemol, self._system_generator, residue_name="MOL") self._geometry_engine = FFAllAngleGeometryEngine() self._complex_topology_old_solvated, self._complex_positions_old_solvated, self._complex_system_old_solvated = self._solvate_system( self._complex_topology_old, self._complex_positions_old) self._complex_md_topology_old_solvated = md.Topology.from_openmm( self._complex_topology_old_solvated) print(self._complex_proposal_engine._smiles_list) beta = 1.0 / (kB * temperature) self._complex_topology_proposal = self._complex_proposal_engine.propose( self._complex_system_old_solvated, self._complex_topology_old_solvated) self._complex_positions_new_solvated, _ = self._geometry_engine.propose( self._complex_topology_proposal, self._complex_positions_old_solvated, beta) #now generate the equivalent objects for the solvent phase. First, generate the ligand-only topologies and atom map self._solvent_topology_proposal, self._old_solvent_positions = self._generate_ligand_only_topologies( self._complex_positions_old_solvated, self._complex_positions_new_solvated) self._new_solvent_positions, _ = self._geometry_engine.propose( self._solvent_topology_proposal, self._old_solvent_positions, beta)