def minimizeEnergy(inputProteinName, outputProteinName): universe = InfiniteUniverse(Amber94ForceField()) universe.protein = Protein(inputProteinName) minimizer = SteepestDescentMinimizer(universe) minimizer(steps=10) universe.protein.writeToFile(outputProteinName)
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 atomicReconstruction(ca_pdb, atomic_pdb, out_pdb): universe = InfiniteUniverse(Amber94ForceField()) universe.protein = Protein(atomic_pdb) initial = copy(universe.configuration()) final = Configuration(universe) calpha_protein = Protein(ca_pdb, model='calpha') for ichain in range(len(calpha_protein)): chain = universe.protein[ichain] ca_chain = calpha_protein[ichain] for iresidue in range(len(ca_chain)): ca = chain[iresidue].peptide.C_alpha final[ca] = ca_chain[iresidue].position() for iresidue in range(len(ca_chain)): if iresidue == 0: refs = [0, 1, 2] elif iresidue == len(ca_chain) - 1: refs = [iresidue - 2, iresidue - 1, iresidue] else: refs = [iresidue - 1, iresidue, iresidue + 1] ref = Collection() for i in refs: ref.addObject(chain[i].peptide.C_alpha) tr, rms = ref.findTransformation(initial, final) residue = chain[iresidue] residue.applyTransformation(tr) ca = residue.peptide.C_alpha residue.translateBy(final[ca] - ca.position()) for a in residue.atomList(): final[a] = a.position() minimizer = SteepestDescentMinimizer(universe) minimizer(step=1000) print "Writing configuration to file ", out_pdb universe.writeToFile(out_pdb)
m = Molecule('water', position=randomPointInBox(current_size)) while 1: s = m.boundingSphere() collision = 0 for region in excluded_regions: if s.intersectWith(region) is not None: collision = 1 break if not collision: break m.translateTo(randomPointInBox(current_size)) world.addObject(m) excluded_regions.append(s) # Reduce energy minimizer = SteepestDescentMinimizer(world, step_size=0.05 * Units.Ang) minimizer(steps=100) # Set velocities and equilibrate for a while world.initializeVelocitiesToTemperature(temperature) integrator = VelocityVerletIntegrator( world, actions=[VelocityScaler(300., 10.), TranslationRemover()]) integrator(steps=200) # Scale down the system in small steps while current_size > real_size: scale_factor = max(0.95, real_size / current_size) for object in world: object.translateTo(scale_factor * object.position())
# The gradient norm values printed by this script can thus be # used as a reference for what is normal. # from MMTK import * from MMTK.Proteins import Protein from MMTK.ForceFields import Amber99ForceField from MMTK.Minimization import SteepestDescentMinimizer from MMTK.Trajectory import StandardLogOutput # Construct system universe = InfiniteUniverse(Amber99ForceField()) universe.protein = Protein('bala1') # Minimize minimizer = SteepestDescentMinimizer(universe, actions=[StandardLogOutput(20)]) minimizer(convergence=1.e-3, steps=100) # Calculate gradients and their lengths energy, gradients = universe.energyAndGradients() gradient_lengths = gradients.length() # Make a list of all atoms sorted by decreasing gradient length atoms = sorted(universe.atomList(), key=lambda a: gradient_lengths[a], reverse=True) # Print the five atoms with the highest forces acting on them for a in atoms[:5]: print a, gradient_lengths[a]
universe.addObject(Environment.PathIntegrals(temperature, False)) #BUILD ALL OF THE FORCEFIELD COMPONENTS #ff = [] #ff.append(mbpolForceField(universe)) #universe.setForceField(CompoundForceField(*ff)) universe.setForceField(mbpolForceField(universe)) #e, g = universe.energyAndGradients() #print universe.energyTerms() #print e #gradientTest(universe) # HERE WE PERFORM AN ENERGY MINIMIZATION print "E before steepest descent minimization", universe.energy() minimizer = SteepestDescentMinimizer(universe, actions=[]) minimizer(convergence=1.e-8, steps=50) print "E after steepest descent minimization", universe.energy() # HERE WE USE NORMAL MODES TO DETERMINE THE TIME-STEP AND FRICTION # OF OUR SYSTEM universe.initializeVelocitiesToTemperature(temperature) integrator = PIGSLangevinNormalModeIntegrator(universe, delta_t=bootstrap_dt, centroid_friction=friction) integrator( steps=500, actions=[TrajectoryOutput(None, ('configuration', 'time'), 0, None, 100)])
def _ramp_T(self, T_START, T_LOW=20., normalize=False): """Ramp the temperature from T_LOW to T_START Parameters ---------- T_START : float The final temperature T_LOW : float The lowest temperature in the ramp normalize : bool If True, the ligand center of mass will be normalized """ self.log.recordStart('T_ramp') # First minimize the energy from MMTK.Minimization import SteepestDescentMinimizer # @UnresolvedImport minimizer = SteepestDescentMinimizer(self.top.universe) original_stderr = sys.stderr sys.stderr = NullDevice() # Suppresses warnings for minimization x_o = np.copy(self.top.universe.configuration().array) e_o = self.top.universe.energy() for rep in range(5000): minimizer(steps=10) x_n = np.copy(self.top.universe.configuration().array) e_n = self.top.universe.energy() diff = abs(e_o - e_n) if np.isnan(e_n) or diff < 0.05 or diff > 1000.: self.top.universe.setConfiguration( Configuration(self.top.universe, x_o)) break else: x_o = x_n e_o = e_n sys.stderr = original_stderr self.log.tee(" minimized to %.3g kcal/mol over %d steps" % (e_o, 10 * (rep + 1))) # Then ramp the energy to the starting temperature from AlGDock.Integrators.HamiltonianMonteCarlo.HamiltonianMonteCarlo \ import HamiltonianMonteCarloIntegrator sampler = HamiltonianMonteCarloIntegrator(self.top.universe) e_o = self.top.universe.energy() T_LOW = 20. T_SERIES = T_LOW * (T_START / T_LOW)**(np.arange(30) / 29.) for T in T_SERIES: delta_t = 2.0 * MMTK.Units.fs steps_per_trial = 10 attempts_left = 10 while attempts_left > 0: random_seed = int(T*10000) + attempts_left + \ int(self.top.universe.configuration().array[0][0]*10000) if self.args.random_seed == 0: random_seed += int(time.time() * 1000) random_seed = random_seed % 32767 (xs, energies, acc, ntrials, delta_t) = \ sampler(steps = 2500, steps_per_trial = 10, T=T,\ delta_t=delta_t, random_seed=random_seed) attempts_left -= 1 acc_rate = float(acc) / ntrials if acc_rate < 0.4: delta_t -= 0.25 * MMTK.Units.fs else: attempts_left = 0 if delta_t < 0.1 * MMTK.Units.fs: delta_t = 0.1 * MMTK.Units.fs steps_per_trial = max(int(steps_per_trial / 2), 1) fmt = " T = %d, delta_t = %.3f fs, steps_per_trial = %d, acc_rate = %.3f" if acc_rate < 0.01: print self.top.universe.energyTerms() self.log.tee(fmt % (T, delta_t * 1000, steps_per_trial, acc_rate)) if normalize: self.top.universe.normalizePosition() e_f = self.top.universe.energy() self.log.tee(" ramped temperature from %d to %d K in %s, "%(\ T_LOW, T_START, HMStime(self.log.timeSince('T_ramp'))) + \ "changing energy to %.3g kcal/mol\n"%(e_f))
def shrinkUniverse(universe, temperature=300.*Units.K, trajectory=None, scale_factor=0.95): """ Shrinks the universe, which must have been scaled up by :class:`~MMTK.Solvation.addSolvent`, back to its original size. The compression is performed in small steps, in between which some energy minimization and molecular dynamics steps are executed. The molecular dynamics is run at the given temperature, and an optional trajectory can be specified in which intermediate configurations are stored. :param universe: a finite universe :type universe: :class:`~MMTK.Universe.Universe` :param temperature: the temperature at which the Molecular Dynamics steps are run :type temperature: float :param trajectory: the trajectory in which the progress of the shrinking procedure is stored, or a filename :type trajectory: :class:`~MMTK.Trajectory.Trajectory` or str :param scale_factor: the factor by which the universe is scaled at each reduction step :type scale_factor: float """ # Set velocities and initialize trajectory output universe.initializeVelocitiesToTemperature(temperature) if trajectory is not None: if isinstance(trajectory, basestring): trajectory = Trajectory(universe, trajectory, "w", "solvation protocol") close_trajectory = True else: close_trajectory = False actions = [TrajectoryOutput(trajectory, ["configuration"], 0, None, 1)] snapshot = SnapshotGenerator(universe, actions=actions) snapshot() # Do some minimization and equilibration minimizer = SteepestDescentMinimizer(universe, step_size = 0.05*Units.Ang) actions = [VelocityScaler(temperature, 0.01*temperature, 0, None, 1), TranslationRemover(0, None, 20)] integrator = VelocityVerletIntegrator(universe, delta_t = 0.5*Units.fs, actions = actions) for i in range(5): minimizer(steps = 40) integrator(steps = 200) # Scale down the system in small steps i = 0 while universe.scale_factor > 1.: if trajectory is not None and i % 1 == 0: snapshot() i = i + 1 step_factor = max(scale_factor, 1./universe.scale_factor) for object in universe: object.translateTo(step_factor*object.position()) universe.scaleSize(step_factor) universe.scale_factor = universe.scale_factor*step_factor for i in range(3): minimizer(steps = 10) integrator(steps = 50) del universe.scale_factor if trajectory is not None: snapshot() if close_trajectory: trajectory.close()
def set_confs(self, confs, rmsd_threshold=0.05, period_frac_threshold=0.35, \ append=False): import time start_time = time.time() nconfs_attempted = len(confs) if append and (self.confs is not None): nconfs_o = len(self.confs) confs = confs + self.confs else: nconfs_o = 0 # Minimize configurations from MMTK.Minimization import SteepestDescentMinimizer # @UnresolvedImport minimizer = SteepestDescentMinimizer(self.universe) minimized_confs = [] minimized_energies = [] for conf in confs: self.universe.setConfiguration(Configuration(self.universe, conf)) x_o = np.copy(self.universe.configuration().array) e_o = self.universe.energy() for rep in range(50): minimizer(steps=25) x_n = np.copy(self.universe.configuration().array) e_n = self.universe.energy() diff = abs(e_o - e_n) if np.isnan(e_n) or diff < 0.05 or diff > 1000.: self.universe.setConfiguration( Configuration(self.universe, x_o)) break else: x_o = x_n e_o = e_n if not np.isnan(e_o): minimized_confs.append(x_o) minimized_energies.append(e_o) confs = minimized_confs energies = minimized_energies # Sort by increasing energy energies, confs = (list(l) \ for l in zip(*sorted(zip(energies, confs), key=lambda p:p[0]))) # Only keep configurations with energy with 12 kJ/mol of the lowest energy confs = [confs[i] for i in range(len(confs)) \ if (energies[i]-energies[0])<12.] energies = energies[:len(confs)] if self.extended: # Keep only unique configurations, using rmsd as a threshold inds_to_keep = [0] for j in range(1, len(confs)): min_rmsd = np.min([np.sqrt(np.sum(np.square(\ confs[j][self.molecule.heavy_atoms,:] - \ confs[k][self.molecule.heavy_atoms,:]))/self.molecule.nhatoms) \ for k in inds_to_keep]) if min_rmsd > rmsd_threshold: inds_to_keep.append(j) confs = [confs[i] for i in inds_to_keep] energies = [energies[i] for i in inds_to_keep] confs_BAT = [self._BAT_util.BAT(confs[n], extended=self.extended) \ for n in range(len(confs))] confs_BAT_tp = [confs_BAT[c][self._BAT_to_perturb] \ for c in range(len(confs_BAT))] if not self.extended: # Keep only unique configurations based on period fraction threshold inds_to_keep = [0] for j in range(1, len(confs)): period_fracs = np.array([np.abs(confs_BAT_tp[j] - confs_BAT_tp[k]) \ for k in inds_to_keep])/twoPi period_fracs = np.min([period_fracs, 1 - period_fracs], 0) if (np.max(period_fracs, 1) > period_frac_threshold).all(): inds_to_keep.append(j) confs = [confs[i] for i in inds_to_keep] confs_BAT = [confs_BAT[i] for i in inds_to_keep] confs_BAT_tp = [confs_BAT_tp[i] for i in inds_to_keep] energies = [energies[i] for i in inds_to_keep] confs_ha = [confs[c][self.molecule.heavy_atoms,:] \ for c in range(len(confs))] if len(confs) > 1: # Probabilty of jumping to a conformation k # is proportional to exp(-E/(R*600.)). logweight = np.array(energies) / (R * 600.) weights = np.exp(-logweight + min(logweight)) self.weights = weights / sum(weights) # self.darts[j][k] will jump from conformation j to conformation k self.darts = [[confs_BAT[j][self._BAT_to_perturb] - \ confs_BAT[k][self._BAT_to_perturb] \ for j in range(len(confs))] for k in range(len(confs))] # Finds the minimum distance between target conformations. # This is the maximum allowed distance to permit a dart. if self.extended: ssd = np.concatenate([[np.sum(np.square(confs_ha[j] - confs_ha[k])) for j in range(k+1,len(confs))] \ for k in range(len(confs))]) # Uses the minimum distance or rmsd of 0.25 A self.epsilon = min( np.min(ssd) * 3 / 4., confs_ha[0].shape[0] * 0.025 * 0.025) else: period_fracs = [[np.abs(self.darts[j][k])/twoPi \ for j in range(len(confs))] for k in range(len(confs))] period_fracs = [[np.min([period_fracs[j][k], 1-period_fracs[j][k]],0) \ for j in range(len(confs))] for k in range(len(confs))] spf = np.concatenate([[\ np.sum(period_fracs[j][k]) \ for j in range(k+1,len(confs))] for k in range(len(confs))]) self.epsilon = np.min(spf) * 3 / 4. else: self.epsilon = 0. # Set the universe to the lowest-energy configuration self.universe.setConfiguration( Configuration(self.universe, np.copy(confs[0]))) self.confs = confs self.confs_ha = confs_ha self.confs_BAT = confs_BAT self.confs_BAT_tp = confs_BAT_tp self.period_frac_threshold = period_frac_threshold from AlGDock.BindingPMF import HMStime report = " attempted %d and finished with" + \ " %d smart darting targets (eps=%.4f) in " + \ HMStime(time.time()-start_time) report = report % (nconfs_attempted, len(self.confs), self.epsilon) if len(self.confs) > 1: report += "\n the lowest %d energies are: "%(min(len(confs),10)) + \ ', '.join(['%.2f'%e for e in energies[:10]]) return report