From c9e24a6d1575893f09f46678e743cae0f6446042 Mon Sep 17 00:00:00 2001 From: jchodera Date: Thu, 4 Aug 2016 15:01:26 -0400 Subject: [PATCH 1/3] Replace GHMC with a version that handles NaNs correctly --- openmmtools/integrators.py | 54 ++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/openmmtools/integrators.py b/openmmtools/integrators.py index f19283f6d..77b22ca9a 100644 --- a/openmmtools/integrators.py +++ b/openmmtools/integrators.py @@ -523,25 +523,24 @@ def acceptance_rate(self): """The acceptance rate: n_accept / n_trials.""" return self.n_accept / float(self.n_trials) - -class GHMCIntegrator(mm.CustomIntegrator): +class GHMCIntegrator(openmm.CustomIntegrator): """ Generalized hybrid Monte Carlo (GHMC) integrator. """ - def __init__(self, temperature=298.0 * simtk.unit.kelvin, collision_rate=91.0 / simtk.unit.picoseconds, timestep=1.0 * simtk.unit.femtoseconds): + def __init__(self, temperature=298.0 * unit.kelvin, collision_rate=91.0 / unit.picoseconds, timestep=1.0 * unit.femtoseconds): """ Create a generalized hybrid Monte Carlo (GHMC) integrator. Parameters ---------- - temperature : numpy.unit.Quantity compatible with kelvin, default: 298*simtk.unit.kelvin + temperature : np.unit.Quantity compatible with kelvin, default: 298*unit.kelvin The temperature. - collision_rate : numpy.unit.Quantity compatible with 1/picoseconds, default: 91.0/simtk.unit.picoseconds + collision_rate : np.unit.Quantity compatible with 1/picoseconds, default: 91.0/unit.picoseconds The collision rate. - timestep : numpy.unit.Quantity compatible with femtoseconds, default: 1.0*simtk.unit.femtoseconds + timestep : np.unit.Quantity compatible with femtoseconds, default: 1.0*unit.femtoseconds The integration timestep. Notes @@ -554,16 +553,17 @@ def __init__(self, temperature=298.0 * simtk.unit.kelvin, collision_rate=91.0 / TODO ---- - Move initialization of 'sigma' to setting the per-particle variables. + * Move initialization of 'sigma' to setting the per-particle variables. + * Generalize to use MTS inner integrator. Examples -------- Create a GHMC integrator. - >>> temperature = 298.0 * simtk.unit.kelvin - >>> collision_rate = 91.0 / simtk.unit.picoseconds - >>> timestep = 1.0 * simtk.unit.femtoseconds + >>> temperature = 298.0 * unit.kelvin + >>> collision_rate = 91.0 / unit.picoseconds + >>> timestep = 1.0 * unit.femtoseconds >>> integrator = GHMCIntegrator(temperature, collision_rate, timestep) References @@ -584,8 +584,8 @@ def __init__(self, temperature=298.0 * simtk.unit.kelvin, collision_rate=91.0 / # Integrator initialization. # self.addGlobalVariable("kT", kT) # thermal energy - self.addGlobalVariable("b", numpy.exp(-gamma * timestep)) # velocity mixing parameter - self.addPerDofVariable("sigma", 0) + self.addGlobalVariable("b", np.exp(-gamma * timestep)) # velocity mixing parameter + self.addPerDofVariable("sigma", 0) # velocity standard deviation self.addGlobalVariable("ke", 0) # kinetic energy self.addPerDofVariable("vold", 0) # old velocities self.addPerDofVariable("xold", 0) # old positions @@ -598,23 +598,13 @@ def __init__(self, temperature=298.0 * simtk.unit.kelvin, collision_rate=91.0 / # # Pre-computation. - # This only needs to be done once, but it needs to be done for each degree of freedom. - # Could move this to initialization? + # This only needs to be done once. + # TODO: Change this to setPerDofVariableByName("sigma", unit.sqrt(kT / mass).value_in_unit_system(unit.md_unit_system)) # self.addComputePerDof("sigma", "sqrt(kT/m)") # - # Allow context updating here. - # - self.addUpdateContextState() - - # - # Constrain positions. - # - self.addConstrainPositions() - - # - # Velocity perturbation. + # Velocity randomization # self.addComputePerDof("v", "sqrt(b)*v + sqrt(1-b)*sigma*gaussian") self.addConstrainVelocities() @@ -622,21 +612,30 @@ def __init__(self, temperature=298.0 * simtk.unit.kelvin, collision_rate=91.0 / # # Metropolized symplectic step. # + self.addConstrainPositions() + self.addConstrainVelocities() + + # Compute initial total energy self.addComputeSum("ke", "0.5*m*v*v") self.addComputeGlobal("Eold", "ke + energy") self.addComputePerDof("xold", "x") self.addComputePerDof("vold", "v") + # Velocity Verlet step self.addComputePerDof("v", "v + 0.5*dt*f/m") self.addComputePerDof("x", "x + v*dt") self.addComputePerDof("x1", "x") self.addConstrainPositions() self.addComputePerDof("v", "v + 0.5*dt*f/m + (x-x1)/dt") self.addConstrainVelocities() + # Compute final total energy self.addComputeSum("ke", "0.5*m*v*v") self.addComputeGlobal("Enew", "ke + energy") + # Accept/reject, ensuring rejection if energy is NaN self.addComputeGlobal("accept", "step(exp(-(Enew-Eold)/kT) - uniform)") - self.addComputePerDof("x", "x*accept + xold*(1-accept)") - self.addComputePerDof("v", "v*accept - vold*(1-accept)") + self.beginIfBlock("accept != 1") + self.addComputePerDof("x", "xold") + self.addComputePerDof("v", "-vold") + self.endBlock() # # Velocity randomization @@ -650,7 +649,6 @@ def __init__(self, temperature=298.0 * simtk.unit.kelvin, collision_rate=91.0 / self.addComputeGlobal("naccept", "naccept + accept") self.addComputeGlobal("ntrials", "ntrials + 1") - class VVVRIntegrator(mm.CustomIntegrator): """ From 45cd7bac5870a6cc31bb2067a9cb069527ecc80c Mon Sep 17 00:00:00 2001 From: jchodera Date: Thu, 4 Aug 2016 15:24:30 -0400 Subject: [PATCH 2/3] Fix some name issues --- openmmtools/integrators.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/openmmtools/integrators.py b/openmmtools/integrators.py index 77b22ca9a..6b6cdf11b 100644 --- a/openmmtools/integrators.py +++ b/openmmtools/integrators.py @@ -523,24 +523,24 @@ def acceptance_rate(self): """The acceptance rate: n_accept / n_trials.""" return self.n_accept / float(self.n_trials) -class GHMCIntegrator(openmm.CustomIntegrator): +class GHMCIntegrator(mm.CustomIntegrator): """ Generalized hybrid Monte Carlo (GHMC) integrator. """ - def __init__(self, temperature=298.0 * unit.kelvin, collision_rate=91.0 / unit.picoseconds, timestep=1.0 * unit.femtoseconds): + def __init__(self, temperature=298.0 * simtk.unit.kelvin, collision_rate=91.0 / simtk.unit.picoseconds, timestep=1.0 * simtk.unit.femtoseconds): """ Create a generalized hybrid Monte Carlo (GHMC) integrator. Parameters ---------- - temperature : np.unit.Quantity compatible with kelvin, default: 298*unit.kelvin + temperature : simtk.unit.Quantity compatible with kelvin, default: 298*unit.kelvin The temperature. - collision_rate : np.unit.Quantity compatible with 1/picoseconds, default: 91.0/unit.picoseconds + collision_rate : simtk.unit.Quantity compatible with 1/picoseconds, default: 91.0/unit.picoseconds The collision rate. - timestep : np.unit.Quantity compatible with femtoseconds, default: 1.0*unit.femtoseconds + timestep : simtk.unit.Quantity compatible with femtoseconds, default: 1.0*unit.femtoseconds The integration timestep. Notes @@ -561,9 +561,9 @@ def __init__(self, temperature=298.0 * unit.kelvin, collision_rate=91.0 / unit.p Create a GHMC integrator. - >>> temperature = 298.0 * unit.kelvin - >>> collision_rate = 91.0 / unit.picoseconds - >>> timestep = 1.0 * unit.femtoseconds + >>> temperature = 298.0 * simtk.unit.kelvin + >>> collision_rate = 91.0 / simtk.unit.picoseconds + >>> timestep = 1.0 * simtk.unit.femtoseconds >>> integrator = GHMCIntegrator(temperature, collision_rate, timestep) References From b9762ad0fbd93a3e3cc6d97d8a286ddd4384a55f Mon Sep 17 00:00:00 2001 From: jchodera Date: Thu, 4 Aug 2016 15:44:59 -0400 Subject: [PATCH 3/3] Fix numpy / np --- openmmtools/integrators.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openmmtools/integrators.py b/openmmtools/integrators.py index 6b6cdf11b..e7e7c7725 100644 --- a/openmmtools/integrators.py +++ b/openmmtools/integrators.py @@ -584,7 +584,7 @@ def __init__(self, temperature=298.0 * simtk.unit.kelvin, collision_rate=91.0 / # Integrator initialization. # self.addGlobalVariable("kT", kT) # thermal energy - self.addGlobalVariable("b", np.exp(-gamma * timestep)) # velocity mixing parameter + self.addGlobalVariable("b", numpy.exp(-gamma * timestep)) # velocity mixing parameter self.addPerDofVariable("sigma", 0) # velocity standard deviation self.addGlobalVariable("ke", 0) # kinetic energy self.addPerDofVariable("vold", 0) # old velocities