def start_universe(pdb_file): """ pdb_file: str, pdb file name return MMTK.Universe """ universe = InfiniteUniverse() molecules = _get_molecules(pdb_file) universe.addObject(molecules) return universe
from MMTK import Molecule from MMTK.ParticleProperties import Configuration from MMTK.ForceFields import Amber12SBForceField from MMTK import Universe, InfiniteUniverse from MMTK import Units R = 8.3144621*Units.J/Units.mol/Units.K import CDHMC parm_dir = '/share/apps/amber/16/dat/leap/parm/' # Amber parameters directory newmol = Molecule(mol_FN) mol_frcmod = os.path.join(mol_dir, 'ligand.frcmod') gaff_FN = os.path.join(mol_dir,'gaff2.dat') universe = InfiniteUniverse(Amber12SBForceField(parameter_file=gaff_FN, mod_files=['frcmod.ff12SB', mol_frcmod])) universe.addObject(newmol) universe.configuration(); configuration = universe.configuration().array CDIntegrator = CDHMC.CDHMCIntegrator(universe, mol_dir, parm_dir) (confs, Es_MM, acc, ntrials, dt) = CDIntegrator.Call(10000, 10, 300, 0.0015, random.randint(1,300), 0, 1, 0.5) print "GC: ", Es_MM CDIntegrator.Clear()
from MMTK import Universe, InfiniteUniverse from MMTK import Units from VelocityVerlet import VelocityVerletIntegrator import GCHMC R = 8.3144621*Units.J/Units.mol/Units.K mol_name = "ligand" gaff_FN = 'gaff.dat' parm_dir = './' mol_dir = '2but' newmol = Molecule('2but') mol_frcmod = os.path.join(mol_dir, 'ligand.frcmod') universe = InfiniteUniverse(Amber12SBForceField(parameter_file=gaff_FN, mod_files=['frcmod.ff12SB', mol_frcmod])) universe.addObject(newmol) universe.configuration(); configuration = universe.configuration().array VVintegrator = VelocityVerletIntegrator(universe) print "VV constructed" GCintegrator = GCHMC.GCHMCIntegrator(universe, mol_dir, parm_dir + gaff_FN) print "GCHMC constructed" (confs, KEs_MM, Es_MM, acc, ntrials, dt) = VVintegrator(steps=200, steps_per_trial=50, T=300.0, delta_t=0.0015, \ normalize=False, adapt=False, random_seed=random.randint(1,300)) print "Velocity Verlet finished" (confs, Es_MM, acc, ntrials, dt) = GCintegrator.Call(30, 10, 300, 0.0015, random.randint(1,300), 0, 1, 0.5) print "GC: ", Es_MM
class MMTKinter: def __init__(self, mols, nogui=False, addhyd=True, ljOptions=None, esOptions=None, callback=None): # MMTK lengths are in nm while Chimera ones are in Angstroms # so we need a scale factor when converting if not mols: raise ValueError("No molecules specified") self.tempDir = None self.molId = 0 self.ljOptions = ljOptions self.esOptions = esOptions self.callback = callback self.mols = mols self._getParameters(mols, nogui, addhyd) def _finishInit(self): timestamp("_finishInit") self.molecules = [] self.atomMap = {} try: for m in self.mols: self.molecules.append(self._makeMolecule(m)) self._makeUniverse() if self.callback: self.callback(self) del self.callback finally: self._removeTempDir() def _makeUniverse(self): import os.path parmDir = os.path.dirname(__file__) timestamp("_makeUniverse") from MMTK import InfiniteUniverse from MMTK.ForceFields.Amber import AmberData from MMTK.ForceFields.Amber.AmberForceField import readAmber99 from MMTK.ForceFields.MMForceField import MMForceField # # GAFF uses lower case atom types to distinguish # from Amber atom types. MMTK, however, normalizes # all atom types to upper case. So we hack MMTK # and temporarily replace _normalizeName function # with ours while reading our parameter files. # (We have to reread the parameter file each time # because we potentially have different frcmod files # for the different universes.) # saveNormalizeName = AmberData._normalizeName AmberData._normalizeName = simpleNormalizeName modFiles = [m.frcmod for m in self.molecules if m.frcmod is not None] parameters = readAmber99(os.path.join(parmDir, "parm", "gaff.dat"), modFiles) self._mergeAmber99(parameters) bondedScaleFactor = 1.0 ff = MMForceField("Amber99/GAFF", parameters, self.ljOptions, self.esOptions, bondedScaleFactor) AmberData._normalizeName = saveNormalizeName timestamp("Made forcefield") self.universe = InfiniteUniverse(ff) timestamp("Made universe") for mm in self.molecules: self.universe.addObject(mm) timestamp("Added model %s" % mm.name) timestamp("end _makeUniverse") def _getParameters(self, mols, nogui, addhyd): timestamp("_getParameters") import DockPrep import chimera self.originalAtoms = set([]) for m in mols: self.originalAtoms.update(m.atoms) from AddCharge import AMBER99SB kw = { "doneCB": self._finishDockPrep, "gaffType": True, "chargeModel": AMBER99SB } if nogui or chimera.nogui: if not addhyd: kw["addHFunc"] = None DockPrep.prep(mols, nogui=nogui, **kw) else: from DockPrep.gui import DockPrepDialog from chimera import dialogs d = dialogs.display(DockPrepDialog.name, wait=True) d.addHydVar.set(addhyd) d.applyKeywords = kw d.molListBox.setvalue(mols) d.writeMol2Var.set(False) """ d = DockPrep.memoryPrep("Minimize", "use", mols, nogui=nogui, **kw) if d: d.addHydVar.set(addhyd) d.writeMol2Var.set(False) """ def _finishDockPrep(self): timestamp("end _getParameters") from chimera import selection selectedAtoms = set(selection.currentAtoms()) addSelected = [] numAdded = 0 for m in self.mols: for a in m.atoms: if a in self.originalAtoms: continue numAdded += 1 # This atom was added. If it was added to # a selected atom, then we add this atom # into the current selection as well. for b in a.bonds: oa = a.bonds[0].otherAtom(a) if oa in selectedAtoms: addSelected.append(a) break del self.originalAtoms if addSelected: selection.addCurrent(addSelected) #from chimera import replyobj #replyobj.info("%d atoms added, %d selected\n" # % (numAdded, len(addSelected))) self._finishInit() def _mergeAmber99(self, parm): "Merge MMTK Amber99 parameters into our parameters" from MMTK.ForceFields.Amber.AmberForceField import readAmber99 parm99 = readAmber99() parm.atom_types.update(parm99.atom_types) parm.bonds.update(parm99.bonds) parm.bond_angles.update(parm99.bond_angles) parm.dihedrals.update(parm99.dihedrals) parm.dihedrals_2.update(parm99.dihedrals_2) parm.impropers.update(parm99.impropers) parm.impropers_1.update(parm99.impropers_1) parm.impropers_2.update(parm99.impropers_2) parm.hbonds.update(parm99.hbonds) parm.lj_equivalent.update(parm99.lj_equivalent) for name, ljpar_set99 in parm99.ljpar_sets.iteritems(): try: ljpar_set = parm.ljpar_sets[name] except KeyError: parm.ljpar_sets[name] = ljpar_set99 else: if ljpar_set.type != ljpar_set99.type: print "incompatible ljpar_set" print " GAFF type:", ljpar_set.type print " AMBER99 type:", ljpar_set99.type ljpar_set.entries.update(ljpar_set99.entries) def _makeMolecule(self, m): timestamp("_makeMolecule %s" % m.name) mm = MMTKChimeraModel(m, self.molId, self) self.molId += 1 timestamp("end _makeMolecule") return mm def setFixed(self, which): from chimera import selection if which == "none" or selection.currentEmpty(): for ma in self.universe.atomList(): ma.fixed = False elif which == "selected": import chimera for ma in self.universe.atomList(): ma.fixed = False for a in selection.currentAtoms(): if a.molecule in self.mols: ma = self.atomMap[a] ma.fixed = True else: import chimera for ma in self.universe.atomList(): ma.fixed = True for a in selection.currentAtoms(): if a.molecule in self.mols: ma = self.atomMap[a] ma.fixed = False def loadMMTKCoordinates(self): "Load MMTK coordinates from Chimera models" import chimera from Scientific.Geometry import Vector from MMTK import Units s = Units.Ang for ma in self.universe.atomList(): try: ca = ma.getAtomProperty(ma, "chimera_atom") except AttributeError: pass else: c = ca.coord() p = Vector(c[0] * s, c[1] * s, c[2] * s) ma.setPosition(p) def saveMMTKCoordinates(self): "Save MMTK coordinates into Chimera models" import chimera from chimera import Coord from MMTK import Units s = Units.Ang sum = 0.0 count = 0 for ma in self.universe.atomList(): if ma.fixed: continue ca = ma.getAtomProperty(ma, "chimera_atom") p = ma.position() c = Coord(p[0] / s, p[1] / s, p[2] / s) dsq = (c - ca.coord()).sqlength() ca.setCoord(c) #print "%.6f" % dsq sum += dsq count += 1 import math if count > 0: print "Updated", count, "atoms. RMSD: %.6f" \ % math.sqrt(sum / count) else: print "No atoms updated." def minimize(self, nsteps, stepsize=0.02, interval=None, action=None, **kw): from chimera import replyobj timestamp("_minimize") from MMTK import Units from MMTK.ForceFields.Amber import AmberData from MMTK.Minimization import SteepestDescentMinimizer from MMTK.Trajectory import LogOutput import sys if not interval: actions = [] else: actions = [ LogOutput(sys.stdout, ["energy"], interval, None, interval) ] kw["step_size"] = stepsize * Units.Ang minimizer = SteepestDescentMinimizer(self.universe, actions=actions, **kw) if action is None or not interval: interval = None msg = "Initial energy: %f" % self.universe.energy() replyobj.status(msg) replyobj.info(msg) saveNormalizeName = AmberData._normalizeName AmberData._normalizeName = simpleNormalizeName remaining = nsteps while remaining > 0: timestamp(" minimize interval") if interval is None: realSteps = remaining else: realSteps = min(remaining, interval) minimizer(steps=realSteps) remaining -= realSteps if action is not None: action(self) timestamp(" finished %d steps" % realSteps) msg = "Finished %d of %d minimization steps" % (nsteps - remaining, nsteps) replyobj.status(msg) replyobj.info(msg) replyobj.info("\n") AmberData._normalizeName = saveNormalizeName timestamp("end _minimize") def getTempDir(self): if self.tempDir: return self.tempDir from tempfile import mkdtemp self.tempDir = mkdtemp() #self.tempDir = "." return self.tempDir def _removeTempDir(self): if not self.tempDir: return if True: import os, os.path for filename in os.listdir(self.tempDir): os.remove(os.path.join(self.tempDir, filename)) os.rmdir(self.tempDir) else: print "Did not clean up temp dir", self.tempDir self.tempDir = None
class MMTKinter: def __init__(self, mols, nogui=False, addhyd=True, ljOptions=None, esOptions=None, callback=None): # MMTK lengths are in nm while Chimera ones are in Angstroms # so we need a scale factor when converting if not mols: raise ValueError("No molecules specified") self.tempDir = None self.molId = 0 self.ljOptions = ljOptions self.esOptions = esOptions self.callback = callback self.mols = mols self._getParameters(mols, nogui, addhyd) def _finishInit(self): timestamp("_finishInit") self.molecules = [] self.atomMap = {} try: for m in self.mols: self.molecules.append(self._makeMolecule(m)) self._makeUniverse() if self.callback: self.callback(self) del self.callback finally: self._removeTempDir() def _makeUniverse(self): import os.path parmDir = os.path.dirname(__file__) timestamp("_makeUniverse") from MMTK import InfiniteUniverse from MMTK.ForceFields.Amber import AmberData from MMTK.ForceFields.Amber.AmberForceField import readAmber99 from MMTK.ForceFields.MMForceField import MMForceField # # GAFF uses lower case atom types to distinguish # from Amber atom types. MMTK, however, normalizes # all atom types to upper case. So we hack MMTK # and temporarily replace _normalizeName function # with ours while reading our parameter files. # (We have to reread the parameter file each time # because we potentially have different frcmod files # for the different universes.) # saveNormalizeName = AmberData._normalizeName AmberData._normalizeName = simpleNormalizeName modFiles = [ m.frcmod for m in self.molecules if m.frcmod is not None] parameters = readAmber99(os.path.join(parmDir, "parm", "gaff.dat"), modFiles) self._mergeAmber99(parameters) bondedScaleFactor = 1.0 ff = MMForceField("Amber99/GAFF", parameters, self.ljOptions, self.esOptions, bondedScaleFactor) AmberData._normalizeName = saveNormalizeName timestamp("Made forcefield") self.universe = InfiniteUniverse(ff) timestamp("Made universe") for mm in self.molecules: self.universe.addObject(mm) timestamp("Added model %s" % mm.name) timestamp("end _makeUniverse") def _getParameters(self, mols, nogui, addhyd): timestamp("_getParameters") import DockPrep import chimera self.originalAtoms = set([]) for m in mols: self.originalAtoms.update(m.atoms) from AddCharge import AMBER99SB kw = { "doneCB": self._finishDockPrep, "gaffType": True, "chargeModel": AMBER99SB } if nogui or chimera.nogui: if not addhyd: kw["addHFunc"] = None DockPrep.prep(mols, nogui=nogui, **kw) else: from DockPrep.gui import DockPrepDialog from chimera import dialogs d = dialogs.display(DockPrepDialog.name, wait=True) d.addHydVar.set(addhyd) d.applyKeywords = kw d.molListBox.setvalue(mols) d.writeMol2Var.set(False) """ d = DockPrep.memoryPrep("Minimize", "use", mols, nogui=nogui, **kw) if d: d.addHydVar.set(addhyd) d.writeMol2Var.set(False) """ def _finishDockPrep(self): timestamp("end _getParameters") from chimera import selection selectedAtoms = set(selection.currentAtoms()) addSelected = [] numAdded = 0 for m in self.mols: for a in m.atoms: if a in self.originalAtoms: continue numAdded += 1 # This atom was added. If it was added to # a selected atom, then we add this atom # into the current selection as well. for b in a.bonds: oa = a.bonds[0].otherAtom(a) if oa in selectedAtoms: addSelected.append(a) break del self.originalAtoms if addSelected: selection.addCurrent(addSelected) #from chimera import replyobj #replyobj.info("%d atoms added, %d selected\n" # % (numAdded, len(addSelected))) self._finishInit() def _mergeAmber99(self, parm): "Merge MMTK Amber99 parameters into our parameters" from MMTK.ForceFields.Amber.AmberForceField import readAmber99 parm99 = readAmber99() parm.atom_types.update(parm99.atom_types) parm.bonds.update(parm99.bonds) parm.bond_angles.update(parm99.bond_angles) parm.dihedrals.update(parm99.dihedrals) parm.dihedrals_2.update(parm99.dihedrals_2) parm.impropers.update(parm99.impropers) parm.impropers_1.update(parm99.impropers_1) parm.impropers_2.update(parm99.impropers_2) parm.hbonds.update(parm99.hbonds) parm.lj_equivalent.update(parm99.lj_equivalent) for name, ljpar_set99 in parm99.ljpar_sets.iteritems(): try: ljpar_set = parm.ljpar_sets[name] except KeyError: parm.ljpar_sets[name] = ljpar_set99 else: if ljpar_set.type != ljpar_set99.type: print "incompatible ljpar_set" print " GAFF type:", ljpar_set.type print " AMBER99 type:", ljpar_set99.type ljpar_set.entries.update(ljpar_set99.entries) def _makeMolecule(self, m): timestamp("_makeMolecule %s" % m.name) mm = MMTKChimeraModel(m, self.molId, self) self.molId += 1 timestamp("end _makeMolecule") return mm def setFixed(self, which): from chimera import selection if which == "none" or selection.currentEmpty(): for ma in self.universe.atomList(): ma.fixed = False elif which == "selected": import chimera for ma in self.universe.atomList(): ma.fixed = False for a in selection.currentAtoms(): if a.molecule in self.mols: ma = self.atomMap[a] ma.fixed = True else: import chimera for ma in self.universe.atomList(): ma.fixed = True for a in selection.currentAtoms(): if a.molecule in self.mols: ma = self.atomMap[a] ma.fixed = False def loadMMTKCoordinates(self): "Load MMTK coordinates from Chimera models" import chimera from Scientific.Geometry import Vector from MMTK import Units s = Units.Ang for ma in self.universe.atomList(): try: ca = ma.getAtomProperty(ma, "chimera_atom") except AttributeError: pass else: c = ca.coord() p = Vector(c[0] * s, c[1] * s, c[2] * s) ma.setPosition(p) def saveMMTKCoordinates(self): "Save MMTK coordinates into Chimera models" import chimera from chimera import Coord from MMTK import Units s = Units.Ang sum = 0.0 count = 0 for ma in self.universe.atomList(): if ma.fixed: continue ca = ma.getAtomProperty(ma, "chimera_atom") p = ma.position() c = Coord(p[0] / s, p[1] / s, p[2] / s) dsq = (c - ca.coord()).sqlength() ca.setCoord(c) #print "%.6f" % dsq sum += dsq count += 1 import math if count > 0: print "Updated", count, "atoms. RMSD: %.6f" \ % math.sqrt(sum / count) else: print "No atoms updated." def minimize(self, nsteps, stepsize=0.02, interval=None, action=None, **kw): from chimera import replyobj timestamp("_minimize") from MMTK import Units from MMTK.ForceFields.Amber import AmberData from MMTK.Minimization import SteepestDescentMinimizer from MMTK.Trajectory import LogOutput import sys if not interval: actions = [] else: actions = [ LogOutput(sys.stdout, ["energy"], interval, None, interval) ] kw["step_size"] = stepsize * Units.Ang minimizer = SteepestDescentMinimizer(self.universe, actions=actions, **kw) if action is None or not interval: interval = None msg = "Initial energy: %f" % self.universe.energy() replyobj.status(msg) replyobj.info(msg) saveNormalizeName = AmberData._normalizeName AmberData._normalizeName = simpleNormalizeName remaining = nsteps while remaining > 0: timestamp(" minimize interval") if interval is None: realSteps = remaining else: realSteps = min(remaining, interval) minimizer(steps=realSteps) remaining -= realSteps if action is not None: action(self) timestamp(" finished %d steps" % realSteps) msg = "Finished %d of %d minimization steps" % ( nsteps - remaining, nsteps) replyobj.status(msg) replyobj.info(msg) replyobj.info("\n") AmberData._normalizeName = saveNormalizeName timestamp("end _minimize") def getTempDir(self): if self.tempDir: return self.tempDir from tempfile import mkdtemp self.tempDir = mkdtemp() #self.tempDir = "." return self.tempDir def _removeTempDir(self): if not self.tempDir: return if True: import os, os.path for filename in os.listdir(self.tempDir): os.remove(os.path.join(self.tempDir, filename)) os.rmdir(self.tempDir) else: print "Did not clean up temp dir", self.tempDir self.tempDir = None