Source code for molsysmt.third_party.openmm.reporters.tqdm

from tqdm.auto import tqdm
import time

[docs] class TQDMReporter(object): """OpenMM reporter that displays progress via tqdm."""
[docs] def __init__(self, reportInterval, total_n_steps, potential_energy=True, temperature=True, volume=False): import openmm as mm from openmm import unit self._pbar = None self._report_interval = reportInterval if self._report_interval==0: self._report_interval=1 self._total_n_steps = total_n_steps self._with_potential_energy = potential_energy self._potential_energy = None self._with_temperature = temperature self._temperature = None self._with_volume = volume self._volume = None self._needs_positions = False self._needs_velocities = False self._needs_forces = False self._needs_energy = (potential_energy or temperature) self._initialized = False self._dof = 0 self._U = 0.0 * unit.kilojoules_per_mole self._U2 = 0.0 * unit.kilojoules_per_mole**2 self._T = 0.0 * unit.kelvin self._T2 = 0.0 * unit.kelvin**2 self._V = 0.0 * unit.nanometers**3 self._V2 = 0.0 * unit.nanometers**6 self._iters = 0 self._start_time = None self._end_time = None self._start_md_time = None self._end_md_time = None self._md_time_step = None
def _initialize(self, simulation): import openmm as mm from openmm import unit self._start_time = time.time() self._pbar = tqdm(total=self._total_n_steps, position=0, leave=True) post_fix_dict={} if self._with_potential_energy: post_fix_dict['potential_energy'] = None if self._with_temperature: post_fix_dict['temperature'] = None if self._with_volume: post_fix_dict['volume'] = None self._pbar.set_postfix(post_fix_dict) if self._with_temperature: frclist = simulation.system.getForces() dof = 0 for i in range(simulation.system.getNumParticles()): if simulation.system.getParticleMass(i) > 0.0*unit.dalton: dof += 3 dof -= simulation.system.getNumConstraints() if any(isinstance(frc, mm.CMMotionRemover) for frc in frclist): dof -= 3 self._dof = dof initial_state = simulation.context.getState(getPositions=self._needs_positions, getVelocities=self._needs_velocities, getForces=self._needs_forces, getEnergy=self._needs_energy) self._start_md_time = initial_state.getTime() self._md_time_step = simulation.integrator.getStepSize() self.report(simulation, initial_state) del(initial_state) self._initialized = True def describeNextReport(self, simulation): if not self._initialized: self._initialize(simulation) steps_left = simulation.currentStep % self._report_interval steps = self._report_interval - steps_left return (steps, self._needs_positions, self._needs_velocities, self._needs_forces, self._needs_energy) def report(self, simulation, state): from openmm import unit post_fix_dict={} if self._with_potential_energy: aux = state.getPotentialEnergy() self._U += aux self._U2 += aux**2 post_fix_dict['potential_energy'] = aux.format("%.2f") if self._with_temperature: aux = 2 * state.getKineticEnergy() / (self._dof * unit.MOLAR_GAS_CONSTANT_R) self._T += aux self._T2 += aux**2 post_fix_dict['temperature'] = aux.format("%.2f") if self._with_volume: aux = state.getPeriodicBoxVolume() self._V += aux self._V2 += aux**2 post_fix_dict['volume'] = aux.format("%.2f") self._iters +=1 self._pbar.set_postfix(post_fix_dict) if simulation.currentStep == 0: self._pbar.update(0) else: self._pbar.update(self._report_interval) if (self._total_n_steps - simulation.currentStep) < self._report_interval: self.finalize(state) def finalize(self, state): from openmm import unit self._pbar.close() self._end_md_time = state.getTime() self._end_time = time.time() execution_time = self._end_time - self._start_time days, remainder = divmod(execution_time, 86400) hours, remainder = divmod(remainder, 3600) minutes, seconds = divmod(remainder, 60) days = int(days) hours = int(hours) minutes = int(minutes) seconds = round(seconds,2) nanoseconds_md = (self._end_md_time-self._start_md_time).in_units_of(unit.nanoseconds) nanoseconds_per_hour = (nanoseconds_md._value / execution_time)*3600*24 nanoseconds_per_hour = round(nanoseconds_per_hour,3) print('') if self._with_potential_energy: mean = self._U / self._iters std = (self._U2 / self._iters - mean**2)**0.5 print(f'Potential energy: {mean.format("%.2f")} ± {std.format("%.2f")}') if self._with_temperature: mean = self._T / self._iters std = (self._T2 / self._iters - mean**2)**0.5 print(f'Temperature: {mean.format("%.2f")} ± {std.format("%.2f")}') if self._with_volume: mean = self._V / self._iters std = (self._V2 / self._iters - mean**2)**0.5 print(f'Volume: {mean.format("%.2f")} ± {std.format("%.2f")}') print('') print(f'Execution time: {days} days, {hours} hours, {minutes} minutes, and {seconds} seconds ({nanoseconds_per_hour} ns/day).') print('') pass