"vscode:/vscode.git/clone" did not exist on "d59b03734b8838314ece418d583a80fcf00af2d6"
Commit c82a8dca authored by Jason Swails's avatar Jason Swails
Browse files

Merge branch 'master' into feature/cuda-docker

parents beb589ad b71e92d9
......@@ -352,9 +352,11 @@ class PDBFile(object):
resName = res.name
if keepIds and len(res.id) < 5:
resId = res.id
resIC = res.insertionCode
else:
resId = "%4d" % ((resIndex+1)%10000)
if len(res.insertionCode) == 1:
resIC = res.insertionCode
else:
resIC = " "
if res.name in nonHeterogens:
recordName = "ATOM "
......
from __future__ import print_function
"""
simulatedtempering.py: Implements simulated tempering
This is part of the OpenMM molecular simulation toolkit originating from
Simbios, the NIH National Center for Physics-Based Simulation of
Biological Structures at Stanford, funded under the NIH Roadmap for
Medical Research, grant U54 GM072970. See https://simtk.org.
Portions copyright (c) 2015 Stanford University and the Authors.
Authors: Peter Eastman
Contributors:
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
"""
__author__ = "Peter Eastman"
__version__ = "1.0"
import simtk.unit as unit
import math
import random
from sys import stdout
try:
import bz2
have_bz2 = True
except: have_bz2 = False
try:
import gzip
have_gzip = True
except: have_gzip = False
class SimulatedTempering(object):
"""SimulatedTempering implements the simulated tempering algorithm for accelerated sampling.
It runs a simulation while allowing the temperature to vary. At high temperatures, it can more easily cross
energy barriers to explore a wider area of conformation space. At low temperatures, it can thoroughly
explore each local region. For details, see Marinari, E. and Parisi, G., Europhys. Lett. 19(6). pp. 451-458 (1992).
The set of temperatures to sample can be specified in two ways. First, you can explicitly provide a list
of temperatures by using the "temperatures" argument. Alternatively, you can specify the minimum and
maximum temperatures, and the total number of temperatures to use. The temperatures are chosen spaced
exponentially between the two extremes. For example,
st = SimulatedTempering(simulation, numTemperatures=15, minTemperature=300*kelvin, maxTemperature=450*kelvin)
After creating the SimulatedTempering object, call step() on it to run the simulation.
Transitions between temperatures are performed at regular intervals, as specified by the "tempChangeInterval"
argument. For each transition, a new temperature is selected using the independence sampling method, as
described in Chodera, J. and Shirts, M., J. Chem. Phys. 135, 194110 (2011).
Simulated tempering requires a "weight factor" for each temperature. Ideally, these should be chosen so
the simulation spends equal time at every temperature. You can specify the list of weights to use with the
optional "weights" argument. If this is omitted, weights are selected automatically using the Wang-Landau
algorithm as described in Wang, F. and Landau, D. P., Phys. Rev. Lett. 86(10), pp. 2050-2053 (2001).
To properly analyze the results of the simulation, it is important to know the temperature and weight factors
at every point in time. The SimulatedTempering object functions as a reporter, writing this information
to a file or stdout at regular intervals (which should match the interval at which you save frames from the
simulation). You can specify the output file and reporting interval with the "reportFile" and "reportInterval"
arguments.
"""
def __init__(self, simulation, temperatures=None, numTemperatures=None, minTemperature=None, maxTemperature=None, weights=None, tempChangeInterval=25, reportInterval=1000, reportFile=stdout):
"""Create a new SimulatedTempering.
Parameters
----------
simulation: Simulation
The Simulation defining the System, Context, and Integrator to use
temperatures: list
The list of temperatures to use for tempering, in increasing order
numTemperatures: int
The number of temperatures to use for tempering. If temperatures is not None, this is ignored.
minTemperature: temperature
The minimum temperature to use for tempering. If temperatures is not None, this is ignored.
maxTemperature: temperature
The maximum temperature to use for tempering. If temperatures is not None, this is ignored.
weights: list
The weight factor for each temperature. If none, weights are selected automatically.
tempChangeInterval: int
The interval (in time steps) at which to attempt transitions between temperatures
reportInterval: int
The interval (in time steps) at which to write information to the report file
reportFile: string or file
The file to write reporting information to, specified as a file name or file object
"""
self.simulation = simulation
if temperatures is None:
if unit.is_quantity(minTemperature):
minTemperature = minTemperature.value_in_unit(unit.kelvin)
if unit.is_quantity(maxTemperature):
maxTemperature = maxTemperature.value_in_unit(unit.kelvin)
self.temperatures = [minTemperature*((float(maxTemperature)/minTemperature)**(i/float(numTemperatures-1))) for i in range(numTemperatures)]*unit.kelvin
else:
numTemperatures = len(temperatures)
self.temperatures = [(t.value_in_unit(unit.kelvin) if unit.is_quantity(t) else t)*unit.kelvin for t in temperatures]
if any(self.temperatures[i] >= self.temperatures[i+1] for i in range(numTemperatures-1)):
raise ValueError('The temperatures must be in strictly increasing order')
self.tempChangeInterval = tempChangeInterval
self.reportInterval = reportInterval
self.inverseTemperatures = [1.0/(unit.MOLAR_GAS_CONSTANT_R*t) for t in self.temperatures]
# If necessary, open the file we will write reports to.
self._openedFile = isinstance(reportFile, str)
if self._openedFile:
# Detect the desired compression scheme from the filename extension
# and open all files unbuffered
if reportFile.endswith('.gz'):
if not have_gzip:
raise RuntimeError("Cannot write .gz file because Python could not import gzip library")
self._out = gzip.GzipFile(fileobj=open(reportFile, 'wb', 0))
elif reportFile.endswith('.bz2'):
if not have_bz2:
raise RuntimeError("Cannot write .bz2 file because Python could not import bz2 library")
self._out = bz2.BZ2File(reportFile, 'w', 0)
else:
self._out = open(reportFile, 'w', 1)
else:
self._out = reportFile
# Initialize the weights.
if weights is None:
self._weights = [0.0]*numTemperatures
self._updateWeights = True
self._weightUpdateFactor = 1.0
self._histogram = [0]*numTemperatures
self._hasMadeTransition = False
else:
self._weights = weights
self._updateWeights = False
# Select the initial temperature.
self.currentTemperature = 0
self.simulation.integrator.setTemperature(self.temperatures[self.currentTemperature])
# Add a reporter to the simulation which will handle the updates and reports.
class STReporter(object):
def __init__(self, st):
self.st = st
def describeNextReport(self, simulation):
st = self.st
steps1 = st.tempChangeInterval - simulation.currentStep%st.tempChangeInterval
steps2 = st.reportInterval - simulation.currentStep%st.reportInterval
steps = min(steps1, steps2)
isUpdateAttempt = (steps1 == steps)
return (steps, False, isUpdateAttempt, False, isUpdateAttempt)
def report(self, simulation, state):
st = self.st
if simulation.currentStep%st.tempChangeInterval == 0:
st._attemptTemperatureChange(state)
if simulation.currentStep%st.reportInterval == 0:
st._writeReport()
simulation.reporters.append(STReporter(self))
# Write out the header line.
headers = ['Steps', 'Temperature (K)']
for t in self.temperatures:
headers.append('%gK Weight' % t.value_in_unit(unit.kelvin))
print('#"%s"' % ('"\t"').join(headers), file=self._out)
def __del__(self):
if self._openedFile:
self._out.close()
@property
def weights(self):
return [x-self._weights[0] for x in self._weights]
def step(self, steps):
"""Advance the simulation by integrating a specified number of time steps."""
self.simulation.step(steps)
def _attemptTemperatureChange(self, state):
"""Attempt to move to a different temperature."""
# Compute the probability for each temperature. This is done in log space to avoid overflow.
logProbability = [(self._weights[i]-self.inverseTemperatures[i]*state.getPotentialEnergy()) for i in range(len(self._weights))]
maxLogProb = max(logProbability)
offset = maxLogProb + math.log(sum(math.exp(x-maxLogProb) for x in logProbability))
probability = [math.exp(x-offset) for x in logProbability]
r = random.random()
for j in range(len(probability)):
if r < probability[j]:
if j != self.currentTemperature:
# Rescale the velocities.
scale = math.sqrt(self.temperatures[j]/self.temperatures[self.currentTemperature])
velocities = [v*scale for v in state.getVelocities().value_in_unit(unit.nanometers/unit.picoseconds)]
self.simulation.context.setVelocities(velocities)
# Select this temperature.
self._hasMadeTransition = True
self.currentTemperature = j
self.simulation.integrator.setTemperature(self.temperatures[j])
if self._updateWeights:
# Update the weight factors.
self._weights[j] -= self._weightUpdateFactor
self._histogram[j] += 1
minCounts = min(self._histogram)
if minCounts > 20 and minCounts >= 0.2*sum(self._histogram)/len(self._histogram):
# Reduce the weight update factor and reset the histogram.
self._weightUpdateFactor *= 0.5
self._histogram = [0]*len(self.temperatures)
self._weights = [x-self._weights[0] for x in self._weights]
elif not self._hasMadeTransition and probability[self.currentTemperature] > 0.99:
# Rapidly increase the weight update factor at the start of the simulation to find
# a reasonable starting value.
self._weightUpdateFactor *= 2.0
self._histogram = [0]*len(self.temperatures)
return
r -= probability[j]
def _writeReport(self):
"""Write out a line to the report."""
temperature = self.temperatures[self.currentTemperature].value_in_unit(unit.kelvin)
values = [temperature]+self.weights
print(('%d\t' % self.simulation.currentStep) + '\t'.join('%g' % v for v in values), file=self._out)
......@@ -127,6 +127,14 @@ class TestAmberPrmtopFile(unittest.TestCase):
self.assertTrue(found_matching_solvent_dielectric and
found_matching_solute_dielectric)
def test_ImplicitSolventZeroSA(self):
"""Test that requesting gbsaModel=None yields a surface area energy of 0 when
prmtop.createSystem produces a GBSAOBCForce"""
system = prmtop2.createSystem(implicitSolvent=OBC2, gbsaModel=None)
for force in system.getForces():
if isinstance(force, GBSAOBCForce):
self.assertEqual(force.getSurfaceAreaEnergy(), 0*kilojoule/(nanometer**2*mole))
def test_HydrogenMass(self):
"""Test that altering the mass of hydrogens works correctly."""
......
......@@ -93,12 +93,10 @@ class TestCharmmFiles(unittest.TestCase):
def test_NBFIX(self):
"""Tests CHARMM systems with NBFIX Lennard-Jones modifications"""
warnings.filterwarnings('ignore', category=CharmmPSFWarning)
psf = CharmmPsfFile('systems/ala3_solv.psf')
psf = CharmmPsfFile('systems/ala3_solv.psf', unitCellDimensions=Vec3(32.7119500, 32.9959600, 33.0071500)*angstroms)
crd = CharmmCrdFile('systems/ala3_solv.crd')
params = CharmmParameterSet('systems/par_all36_prot.prm',
'systems/toppar_water_ions.str')
# Box dimensions (found from bounding box)
psf.setBox(32.7119500*angstroms, 32.9959600*angstroms, 33.0071500*angstroms)
# Turn off charges so we only test the Lennard-Jones energies
for a in psf.atom_list:
......@@ -114,7 +112,7 @@ class TestCharmmFiles(unittest.TestCase):
state = con.getState(getEnergy=True, enforcePeriodicBox=True)
ene = state.getPotentialEnergy().value_in_unit(kilocalories_per_mole)
self.assertAlmostEqual(ene, 15490.0033559, delta=0.05)
self.assertAlmostEqual(ene, 15559.71602, delta=0.05)
def test_Drude(self):
"""Test CHARMM systems with Drude force field"""
......@@ -127,14 +125,14 @@ class TestCharmmFiles(unittest.TestCase):
# Now compute the full energy
plat = Platform.getPlatformByName('Reference')
system = psf.createSystem(params, nonbondedMethod=PME)
system = psf.createSystem(params, nonbondedMethod=PME, ewaldErrorTolerance=0.00005)
integrator = DrudeLangevinIntegrator(300*kelvin, 1.0/picosecond, 1*kelvin, 10/picosecond, 0.001*picoseconds)
con = Context(system, integrator, plat)
con.setPositions(crd.positions)
state = con.getState(getEnergy=True, enforcePeriodicBox=True)
ene = state.getPotentialEnergy().value_in_unit(kilocalories_per_mole)
self.assertAlmostEqual(ene, -1831.54, delta=0.5)
self.assertAlmostEqual(ene, -1788.36644, delta=1.0)
def test_Lonepair(self):
"""Test the lonepair facilities, in particular the colinear type of lonepairs"""
......@@ -169,12 +167,11 @@ class TestCharmmFiles(unittest.TestCase):
def testSystemOptions(self):
""" Test various options in CharmmPsfFile.createSystem """
warnings.filterwarnings('ignore', category=CharmmPSFWarning)
psf = CharmmPsfFile('systems/ala3_solv.psf')
psf = CharmmPsfFile('systems/ala3_solv.psf',
periodicBoxVectors=(Vec3(32.7119500, 0, 0)*angstroms, Vec3(0, 32.9959600, 0)*angstroms, Vec3(0, 0, 33.0071500)*angstroms))
crd = CharmmCrdFile('systems/ala3_solv.crd')
params = CharmmParameterSet('systems/par_all36_prot.prm',
'systems/toppar_water_ions.str')
# Box dimensions (found from bounding box)
psf.setBox(32.7119500*angstroms, 32.9959600*angstroms, 33.0071500*angstroms)
# Check some illegal options
self.assertRaises(ValueError, lambda:
......@@ -275,6 +272,58 @@ class TestCharmmFiles(unittest.TestCase):
dtheta = math.pi-angle
self.assertAlmostEqual(energy, dtheta**2, delta=1e-5)
def test_Residues(self):
"""Test that residues are read correctly, even if they have the same RESID while being in separate segments."""
m14 = (["C{}".format(i) for i in range(1,14)]
+ ["H{}".format(i) for i in range(1,12)]
+ ["N{}".format(i) for i in range(1,4)]
)
tip3 = ["OH2", "H1", "H2"]
pot = ["POT"]
cla = ["CLA"]
psf = CharmmPsfFile('systems/charmm-solvated/isa_wat.3_kcl.m14.psf')
for residue in psf.topology.residues():
atoms = [atom.name for atom in residue.atoms()]
if residue.name == "M14":
self.assertEqual(sorted(m14), sorted(atoms))
elif residue.name == "TIP3":
self.assertEqual(sorted(tip3), sorted(atoms))
elif residue.name == "POT":
self.assertEqual(sorted(pot), sorted(atoms))
elif residue.name == "CLA":
self.assertEqual(sorted(cla), sorted(atoms))
else:
self.assertTrue(False)
def test_NoLongRangeCorrection(self):
"""Test that long range correction is disabled."""
parameters = CharmmParameterSet(
'systems/charmm-solvated/envi.str',
'systems/charmm-solvated/m14.rtf',
'systems/charmm-solvated/m14.prm'
)
psf = CharmmPsfFile('systems/charmm-solvated/isa_wat.3_kcl.m14.psf')
psf.setBox(3.0584*nanometers,3.0584*nanometers,3.0584*nanometers)
system = psf.createSystem(parameters, nonbondedMethod=PME)
for force in system.getForces():
if isinstance(force, CustomNonbondedForce):
self.assertFalse(force.getUseLongRangeCorrection())
if isinstance(force, NonbondedForce):
self.assertFalse(force.getUseDispersionCorrection())
def test_NoPsfWarning(self):
"""Test that PSF warning is not thrown."""
parameters = CharmmParameterSet(
'systems/charmm-solvated/envi.str',
'systems/charmm-solvated/m14.rtf',
'systems/charmm-solvated/m14.prm'
)
with warnings.catch_warnings():
warnings.simplefilter("error", CharmmPSFWarning)
psf = CharmmPsfFile('systems/charmm-solvated/isa_wat.3_kcl.m14.psf')
psf.setBox(3.0584*nanometers,3.0584*nanometers,3.0584*nanometers)
psf.createSystem(parameters, nonbondedMethod=PME)
if __name__ == '__main__':
unittest.main()
......
......@@ -6,6 +6,7 @@ from simtk.unit import *
import simtk.openmm.app.element as elem
import simtk.openmm.app.forcefield as forcefield
import math
import textwrap
try:
from cStringIO import StringIO
except ImportError:
......@@ -50,16 +51,77 @@ class TestForceField(unittest.TestCase):
for f in forces))
def test_DispersionCorrection(self):
"""Test to make sure the nonbondedCutoff parameter is passed correctly."""
for useDispersionCorrection in [True, False]:
system = self.forcefield1.createSystem(self.pdb1.topology,
nonbondedCutoff=2*nanometer,
useDispersionCorrection=useDispersionCorrection)
"""Test to make sure that the dispersion/long-range correction is set properly."""
top = Topology()
chain = top.addChain()
for lrc in (True, False):
xml = textwrap.dedent(
"""
<ForceField>
<LennardJonesForce lj14scale="0.3" useDispersionCorrection="{lrc}">
<Atom type="A" sigma="1" epsilon="0.1"/>
<Atom type="B" sigma="2" epsilon="0.2"/>
<NBFixPair type1="A" type2="B" sigma="2.5" epsilon="1.1"/>
</LennardJonesForce>
<NonbondedForce coulomb14scale="0.833333" lj14scale="0.5" useDispersionCorrection="{lrc2}">
<Atom type="A" sigma="0.315" epsilon="0.635"/>
</NonbondedForce>
</ForceField>
"""
)
ff = ForceField(StringIO(xml.format(lrc=lrc, lrc2=lrc)))
system = ff.createSystem(top)
checked_nonbonded = False
checked_custom = False
for force in system.getForces():
if isinstance(force, NonbondedForce):
self.assertEqual(useDispersionCorrection, force.getUseDispersionCorrection())
self.assertEqual(force.getUseDispersionCorrection(), lrc)
checked_nonbonded = True
elif isinstance(force, CustomNonbondedForce):
self.assertEqual(force.getUseLongRangeCorrection(), lrc)
checked_custom = True
self.assertTrue(checked_nonbonded and checked_custom)
# check that the keyword argument overwrites xml input
lrc_kwarg = not lrc
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
system2 = ff.createSystem(top, useDispersionCorrection=lrc_kwarg)
self.assertTrue(len(w) == 2)
assert "conflict" in str(w[-1].message).lower()
checked_nonbonded = False
checked_custom = False
for force in system2.getForces():
if isinstance(force, NonbondedForce):
self.assertEqual(force.getUseDispersionCorrection(), lrc_kwarg)
checked_nonbonded = True
elif isinstance(force, CustomNonbondedForce):
self.assertEqual(force.getUseLongRangeCorrection(), lrc_kwarg)
checked_custom = True
self.assertTrue(checked_nonbonded and checked_custom)
# check that no warning is generated when useDispersionCorrection is not in the xml file
xml = textwrap.dedent(
"""
<ForceField>
<LennardJonesForce lj14scale="0.3">
<Atom type="A" sigma="1" epsilon="0.1"/>
<Atom type="B" sigma="2" epsilon="0.2"/>
<NBFixPair type1="A" type2="B" sigma="2.5" epsilon="1.1"/>
</LennardJonesForce>
<NonbondedForce coulomb14scale="0.833333" lj14scale="0.5">
<Atom type="A" sigma="0.315" epsilon="0.635"/>
</NonbondedForce>
</ForceField>
"""
)
ff = ForceField(StringIO(xml))
system = ff.createSystem(top)
for lrc_kwarg in [True, False]:
with warnings.catch_warnings():
warnings.simplefilter("error")
system2 = ff.createSystem(top, useDispersionCorrection=lrc_kwarg)
def test_Cutoff(self):
"""Test to make sure the nonbondedCutoff parameter is passed correctly."""
......@@ -227,7 +289,7 @@ class TestForceField(unittest.TestCase):
angles = forcefield.HarmonicAngleGenerator(ff)
angles.registerAngle({'class1':'HW', 'class2':'OW', 'class3':'HW', 'angle':1.82421813418*radians, 'k':836.8*kilojoules_per_mole/radian})
ff.registerGenerator(angles)
nonbonded = forcefield.NonbondedGenerator(ff, 0.833333, 0.5)
nonbonded = forcefield.NonbondedGenerator(ff, 0.833333, 0.5, True)
nonbonded.registerAtom({'type':'tip3p-O', 'charge':-0.834, 'sigma':0.31507524065751241*nanometers, 'epsilon':0.635968*kilojoules_per_mole})
nonbonded.registerAtom({'type':'tip3p-H', 'charge':0.417, 'sigma':1*nanometers, 'epsilon':0*kilojoules_per_mole})
ff.registerGenerator(nonbonded)
......@@ -712,7 +774,7 @@ class TestForceField(unittest.TestCase):
<Atom name="SOD" type="SOD"/>
</Residue>
</Residues>
<LennardJonesForce lj14scale="1.0">
<LennardJonesForce lj14scale="1.0" useDispersionCorrection="False">
<Atom type="CLA" sigma="0.404468018036" epsilon="0.6276"/>
<Atom type="SOD" sigma="0.251367073323" epsilon="0.1962296"/>
<NBFixPair type1="CLA" type2="SOD" sigma="0.33239431" epsilon="0.350933"/>
......@@ -940,5 +1002,6 @@ class AmoebaTestForceField(unittest.TestCase):
diff = norm(f1-f2)
self.assertTrue(diff < 0.1 or diff/norm(f1) < 1e-3)
if __name__ == '__main__':
unittest.main()
import unittest
from simtk.openmm import *
from simtk.openmm.app import *
from simtk.unit import *
class TestMetadynamics(unittest.TestCase):
"""Test the Metadynamics class"""
def testHarmonicOscillator(self):
"""Test running metadynamics on a harmonic oscillator."""
system = System()
system.addParticle(1.0)
system.addParticle(1.0)
force = HarmonicBondForce()
force.addBond(0, 1, 1.0, 100000.0)
system.addForce(force)
cv = CustomBondForce('r')
cv.addBond(0, 1)
bias = BiasVariable(cv, 0.94, 1.06, 0.02)
meta = Metadynamics(system, [bias], 300*kelvin, 2.0, 5.0, 10)
integrator = LangevinIntegrator(300*kelvin, 10/picosecond, 0.001*picosecond)
topology = Topology()
chain = topology.addChain()
residue = topology.addResidue('H2', chain)
topology.addAtom('H1', element.hydrogen, residue)
topology.addAtom('H2', element.hydrogen, residue)
simulation = Simulation(topology, system, integrator, Platform.getPlatformByName('Reference'))
simulation.context.setPositions([Vec3(0, 0, 0), Vec3(1, 0, 0)])
meta.step(simulation, 200000)
fe = meta.getFreeEnergy()
center = bias.gridWidth//2
fe -= fe[center]
# Energies should be reasonably well converged over the central part of the range.
for i in range(center-3, center+4):
r = bias.minValue + i*(bias.maxValue-bias.minValue)/(bias.gridWidth-1)
e = 0.5*100000.0*(r-1.0)**2*kilojoules_per_mole
assert abs(fe[i]-e) < 1.0*kilojoules_per_mole
\ No newline at end of file
import unittest
from simtk.openmm import *
from simtk.openmm.app import *
from simtk.unit import *
class TestSimulatedTempering(unittest.TestCase):
"""Test the SimulatedTempering class"""
def testHarmonicOscillator(self):
"""Test running simulated tempering on a harmonic oscillator."""
system = System()
system.addParticle(1.0)
system.addParticle(1.0)
force = HarmonicBondForce()
force.addBond(0, 1, 1.0, 1000.0)
system.addForce(force)
integrator = LangevinIntegrator(300*kelvin, 10/picosecond, 0.001*picosecond)
topology = Topology()
chain = topology.addChain()
residue = topology.addResidue('H2', chain)
topology.addAtom('H1', element.hydrogen, residue)
topology.addAtom('H2', element.hydrogen, residue)
simulation = Simulation(topology, system, integrator, Platform.getPlatformByName('Reference'))
st = SimulatedTempering(simulation, numTemperatures=10, minTemperature=200*kelvin, maxTemperature=400*kelvin, tempChangeInterval=5, reportInterval=10000)
self.assertEqual(10, len(st.temperatures))
self.assertEqual(200*kelvin, st.temperatures[0])
self.assertEqual(400*kelvin, st.temperatures[-1])
simulation.context.setPositions([Vec3(0, 0, 0), Vec3(1, 0, 0)])
# Run for a little while to let the weights stabilize.
st.step(10000)
# Run for a while and record the temperatures and distances.
distances = [[] for i in range(10)]
count = 0
for i in range(7000):
st.step(5)
pos = simulation.context.getState(getPositions=True).getPositions().value_in_unit(nanometers)
r = norm(pos[0]-pos[1])
distances[st.currentTemperature].append(r)
count += 1
# Check that it spent roughly equal time at each temperature, and that the distributions
# are correct.
for d, t in zip(distances, st.temperatures):
n = len(d)
assert count/20 < n < count/5
meanDist = sum(d)/n
assert 0.97 < meanDist < 1.03
meanEnergy = sum([0.5*1000*(r-1)**2 for r in d])/n
expectedEnergy = (0.5*MOLAR_GAS_CONSTANT_R*t).value_in_unit(kilojoules_per_mole)
self.assertAlmostEqual(expectedEnergy, meanEnergy, delta=expectedEnergy*0.3)
\ No newline at end of file
* STREAM FILE FOR ENVIRONMENT
*
set nat ?NATC
set app
!We're exploiting what is arguably a bug in the parser. On the left hand side,
!the quotes have priority, so NAT is correctly substituted. On the right hand
!side, the ? has priority and NATC" (sic) is not a valid substitution...
if "@NAT" ne "?NATC" if @nat ne 0 set app append
READ RTF CARD @{app}
* Constructed Based on Stream File from CGenff
*
36 1
MASS -1 CCX2 12.01100 C
MASS -1 HCX2 1.00800 H
MASS -1 OCX1 15.99940 O
MASS -1 HOX1 1.00800 H
MASS -1 CCX3 12.01100 C
MASS -1 HCX3 1.00800 H
MASS -1 HT 1.00800 H
MASS -1 OT 15.99940 O
MASS -1 CLA 35.45000 CL
MASS -1 POT 39.09830 K
DEFA FIRS NONE LAST NONE
AUTO ANGLES DIHE DRUDE
RESI OCOH 0.000 ! PARAM_PENALTY=0.0000 ; CHARGE_PENALTY=0.0000
GROUP ! CHARGE CH_PENALTY
ATOM C1 CCX2 0.050 ! 0.000
ATOM H11 HCX2 0.090 ! 0.000
ATOM H12 HCX2 0.090 ! 0.000
ATOM O1 OCX1 -0.649 ! 0.000
ATOM HO1 HOX1 0.420 ! 0.000
ATOM C2 CCX2 -0.181 ! 0.000
ATOM H21 HCX2 0.090 ! 0.000
ATOM H22 HCX2 0.090 ! 0.000
ATOM C3 CCX2 -0.180 ! 0.000
ATOM H31 HCX2 0.090 ! 0.000
ATOM H32 HCX2 0.090 ! 0.000
ATOM C4 CCX2 -0.180 ! 0.000
ATOM H41 HCX2 0.090 ! 0.000
ATOM H42 HCX2 0.090 ! 0.000
ATOM C5 CCX2 -0.180 ! 0.000
ATOM H51 HCX2 0.090 ! 0.000
ATOM H52 HCX2 0.090 ! 0.000
ATOM C6 CCX2 -0.180 ! 0.000
ATOM H61 HCX2 0.090 ! 0.000
ATOM H62 HCX2 0.090 ! 0.000
ATOM C7 CCX2 -0.180 ! 0.000
ATOM H71 HCX2 0.090 ! 0.000
ATOM H72 HCX2 0.090 ! 0.000
ATOM C8 CCX3 -0.270 ! 0.000
ATOM H81 HCX3 0.090 ! 0.000
ATOM H82 HCX3 0.090 ! 0.000
ATOM H83 HCX3 0.090 ! 0.000
BOND H12 C1
BOND H31 C3
BOND H51 C5
BOND H71 C7
BOND H42 C4
BOND H22 C2
BOND H62 C6
BOND H82 C8
BOND C1 H11
BOND C1 C2
BOND C1 O1
BOND C3 C2
BOND C3 C4
BOND C3 H32
BOND C5 C4
BOND C5 C6
BOND C5 H52
BOND C7 C6
BOND C7 C8
BOND C7 H72
BOND H83 C8
BOND C2 H21
BOND C4 H41
BOND C6 H61
BOND C8 H81
BOND HO1 O1
RESI TIP3 0.000
GROUP
ATOM OH2 OT -0.834
ATOM H1 HT 0.417
ATOM H2 HT 0.417
BOND OH2 H1 OH2 H2 H1 H2 ! the last bond is needed for shake
ANGLE H1 OH2 H2 ! required
DONOR H1 OH2
DONOR H2 OH2
ACCEPTOR OH2
PATCHING FIRS NONE LAST NONE
RESI POT 1.00 ! Potassium Ion
GROUP
ATOM POT POT 1.00
PATCHING FIRST NONE LAST NONE
RESI CLA -1.00 ! Chloride Ion
GROUP
ATOM CLA CLA -1.00
PATCHING FIRST NONE LAST NONE
END
READ PARA CARD FLEX @{APP}
* PARAMETERS FOR ENVIR
*
ATOMS
MASS -1 CCX2 12.01100 ! CGENFF_PRM
MASS -1 HCX2 1.00800 ! CGENFF_PRM
MASS -1 OCX1 15.99940 ! CGENFF_PRM
MASS -1 HOX1 1.00800 ! CGENFF_PRM
MASS -1 CCX3 12.01100 ! CGENFF_PRM
MASS -1 HCX3 1.00800 ! CGENFF_PRM
MASS -1 HT 1.00800 ! CGENFF_PRM
MASS -1 OT 15.99940 ! CGENFF_PRM
MASS -1 CLA 35.45000 ! CGENFF_PRM
MASS -1 POT 39.09830 ! CGENFF_PRM
BONDS
CCX2 CCX2 222.500 1.5300 ! CGENFF_PRM
CCX2 CCX3 222.500 1.5280 ! CGENFF_PRM
CCX2 OCX1 428.000 1.4200 ! CGENFF_PRM
CCX2 HCX2 309.000 1.1110 ! CGENFF_PRM
CCX3 HCX3 322.000 1.1110 ! CGENFF_PRM
OCX1 HOX1 545.000 0.9600 ! CGENFF_PRM
HT HT 0.0 1.5139 ! CGENFF_PRM
HT OT 450.000 0.9572 ! CGENFF_PRM
ANGLES
CCX2 CCX2 CCX2 58.350 113.6000 11.160 2.5610 ! CGENFF_PRM
CCX2 CCX2 CCX3 58.000 115.0000 8.000 2.5610 ! CGENFF_PRM
CCX2 CCX2 OCX1 75.700 110.1000 ! CGENFF_PRM
CCX2 CCX2 HCX2 26.500 110.1000 22.530 2.1790 ! CGENFF_PRM
CCX3 CCX2 HCX2 34.600 110.1000 22.530 2.1790 ! CGENFF_PRM
OCX1 CCX2 HCX2 45.900 108.8900 ! CGENFF_PRM
HCX2 CCX2 HCX2 35.500 109.0000 5.400 1.8020 ! CGENFF_PRM
CCX2 CCX3 HCX3 34.600 110.1000 22.530 2.1790 ! CGENFF_PRM
HCX3 CCX3 HCX3 35.500 108.4000 5.400 1.8020 ! CGENFF_PRM
CCX2 OCX1 HOX1 50.000 106.0000 ! CGENFF_PRM
HT OT HT 55.000 104.5200 ! CGENFF_PRM
DIHEDRALS
CCX2 CCX2 CCX2 CCX2 0.0645 2 0.00 ! CGENFF_PRM
CCX2 CCX2 CCX2 CCX2 0.1497 3 180.00 ! CGENFF_PRM
CCX2 CCX2 CCX2 CCX2 0.0946 4 0.00 ! CGENFF_PRM
CCX2 CCX2 CCX2 CCX2 0.1125 5 0.00 ! CGENFF_PRM
CCX2 CCX2 CCX2 CCX3 0.1505 2 0.00 ! CGENFF_PRM
CCX2 CCX2 CCX2 CCX3 0.0813 3 180.00 ! CGENFF_PRM
CCX2 CCX2 CCX2 CCX3 0.1082 4 0.00 ! CGENFF_PRM
CCX2 CCX2 CCX2 CCX3 0.2039 5 0.00 ! CGENFF_PRM
CCX2 CCX2 CCX2 OCX1 0.1950 3 0.00 ! CGENFF_PRM
CCX2 CCX2 CCX2 HCX2 0.1950 3 0.00 ! CGENFF_PRM
CCX3 CCX2 CCX2 HCX2 0.1800 3 0.00 ! CGENFF_PRM
OCX1 CCX2 CCX2 HCX2 0.1950 3 0.00 ! CGENFF_PRM
HCX2 CCX2 CCX2 HCX2 0.2200 3 0.00 ! CGENFF_PRM
CCX2 CCX2 CCX3 HCX3 0.1600 3 0.00 ! CGENFF_PRM
HCX2 CCX2 CCX3 HCX3 0.1600 3 0.00 ! CGENFF_PRM
CCX2 CCX2 OCX1 HOX1 1.1300 1 0.00 ! CGENFF_PRM
CCX2 CCX2 OCX1 HOX1 0.1400 2 0.00 ! CGENFF_PRM
CCX2 CCX2 OCX1 HOX1 0.2400 3 0.00 ! CGENFF_PRM
HCX2 CCX2 OCX1 HOX1 0.1800 3 0.00 ! CGENFF_PRM
IMPROPERS
NONBONDED nbxmod 5 atom cdiel fshift vatom vdistance vfswitch -
cutnb 14.0 ctofnb 12.0 ctonnb 10.0 eps 1.0 e14fac 1.0 wmin 1.5
CCX2 0.0 -0.0560 2.0100 0.0 -0.0100 1.9000 ! CGENFF_PRM
HCX2 0.0 -0.0350 1.3400 ! CGENFF_PRM
OCX1 0.0 -0.1921 1.7650 ! CGENFF_PRM
HOX1 0.0 -0.0460 0.2245 ! CGENFF_PRM
CCX3 0.0 -0.0780 2.0500 0.0 -0.0100 1.9000 ! CGENFF_PRM
HCX3 0.0 -0.0240 1.3400 ! CGENFF_PRM
HT 0.0 -0.0460 0.2245 ! CGENFF_PRM
OT 0.0 -0.1521 1.7682 ! CGENFF_PRM
POT 0.0 -0.0870 1.76375 ! CGENFF_PRM
CLA 0.0 -0.1500 2.27 ! CGENFF_PRM
NBFIX
POT CLA -0.114236 4.081 ! CGENFF_PRM
HBOND CUTHB 0.5
END
This source diff could not be displayed because it is too large. You can view the blob instead.
* PRM File generated from CGenFF STR
*
ATOMS
MASS -1 NG2S3 14.00700 ! CGENFF_PRM
MASS -1 CG2R61 12.01100 ! CGENFF_PRM
MASS -1 CG2RC0 12.01100 ! CGENFF_PRM
MASS -1 NG2R50 14.00700 ! CGENFF_PRM
MASS -1 CG2R53 12.01100 ! CGENFF_PRM
MASS -1 NG2R51 14.00700 ! CGENFF_PRM
MASS -1 HGP4 1.00800 ! CGENFF_PRM
MASS -1 HGR61 1.00800 ! CGENFF_PRM
MASS -1 HGR52 1.00800 ! CGENFF_PRM
BONDS
CG2R53 NG2R50 400.000 1.3200 ! CGENFF_PRM
CG2R53 NG2R51 320.000 1.3740 ! CGENFF_PRM
CG2R53 HGR52 340.000 1.0900 ! CGENFF_PRM
CG2R61 CG2R61 305.000 1.3750 ! CGENFF_PRM
CG2R61 CG2RC0 300.000 1.3600 ! CGENFF_PRM
CG2R61 NG2R51 400.000 1.4200 ! CGENFF_PRM
CG2R61 NG2S3 400.000 1.3900 ! CGENFF_PRM
CG2R61 HGR61 340.000 1.0800 ! CGENFF_PRM
CG2RC0 CG2RC0 360.000 1.3850 ! CGENFF_PRM
CG2RC0 NG2R50 310.000 1.3650 ! CGENFF_PRM
CG2RC0 NG2R51 300.000 1.3750 ! CGENFF_PRM
NG2S3 HGP4 488.000 1.0000 ! CGENFF_PRM
ANGLES
NG2R50 CG2R53 NG2R51 100.000 113.0000 ! CGENFF_PRM
NG2R50 CG2R53 HGR52 39.000 124.8000 ! CGENFF_PRM
NG2R51 CG2R53 HGR52 40.000 122.2000 ! CGENFF_PRM
CG2R61 CG2R61 CG2R61 40.000 120.0000 35.000 2.4162 ! CGENFF_PRM
CG2R61 CG2R61 CG2RC0 50.000 120.0000 ! CGENFF_PRM
CG2R61 CG2R61 NG2R51 60.000 121.0000 ! CGENFF_PRM
CG2R61 CG2R61 NG2S3 60.000 121.0000 ! CGENFF_PRM
CG2R61 CG2R61 HGR61 30.000 120.0000 22.000 2.1525 ! CGENFF_PRM
CG2RC0 CG2R61 HGR61 30.000 120.0000 22.000 2.1460 ! CGENFF_PRM
CG2R61 CG2RC0 CG2RC0 50.000 120.0000 ! CGENFF_PRM
CG2R61 CG2RC0 NG2R50 130.000 130.0000 ! CGENFF_PRM
CG2R61 CG2RC0 NG2R51 130.000 132.6000 ! CGENFF_PRM
CG2RC0 CG2RC0 NG2R50 100.000 110.0000 ! CGENFF_PRM
CG2RC0 CG2RC0 NG2R51 100.000 105.7000 ! CGENFF_PRM
CG2R53 NG2R50 CG2RC0 120.000 103.8000 ! CGENFF_PRM
CG2R53 NG2R51 CG2R61 40.000 127.0000 ! PENALTY= 2.5
CG2R53 NG2R51 CG2RC0 100.000 107.2000 ! CGENFF_PRM
CG2R61 NG2R51 CG2RC0 40.000 127.0000 ! PENALTY= 1.0
CG2R61 NG2S3 HGP4 60.000 111.6000 ! CGENFF_PRM
HGP4 NG2S3 HGP4 31.000 117.0000 ! CGENFF_PRM
DIHEDRALS
NG2R51 CG2R53 NG2R50 CG2RC0 14.0000 2 180.00 ! CGENFF_PRM
HGR52 CG2R53 NG2R50 CG2RC0 5.2000 2 180.00 ! CGENFF_PRM
NG2R50 CG2R53 NG2R51 CG2R61 6.0000 2 180.00 ! PENALTY= 47.5
NG2R50 CG2R53 NG2R51 CG2RC0 6.0000 2 180.00 ! CGENFF_PRM
HGR52 CG2R53 NG2R51 CG2R61 0.0000 2 180.00 ! PENALTY= 32.0
HGR52 CG2R53 NG2R51 CG2RC0 5.6000 2 180.00 ! CGENFF_PRM
CG2R61 CG2R61 CG2R61 CG2R61 3.1000 2 180.00 ! CGENFF_PRM
CG2R61 CG2R61 CG2R61 CG2RC0 3.0000 2 180.00 ! CGENFF_PRM
CG2R61 CG2R61 CG2R61 NG2R51 5.0000 2 180.00 ! CGENFF_PRM
CG2R61 CG2R61 CG2R61 NG2S3 5.0000 2 180.00 ! CGENFF_PRM
CG2R61 CG2R61 CG2R61 HGR61 4.2000 2 180.00 ! CGENFF_PRM
CG2RC0 CG2R61 CG2R61 NG2S3 5.0000 2 180.00 ! PENALTY= 1.5
CG2RC0 CG2R61 CG2R61 HGR61 3.0000 2 180.00 ! CGENFF_PRM
NG2R51 CG2R61 CG2R61 HGR61 2.4000 2 180.00 ! CGENFF_PRM
NG2S3 CG2R61 CG2R61 HGR61 2.4000 2 180.00 ! CGENFF_PRM
HGR61 CG2R61 CG2R61 HGR61 2.4000 2 180.00 ! CGENFF_PRM
CG2R61 CG2R61 CG2RC0 CG2RC0 3.0000 2 180.00 ! CGENFF_PRM
CG2R61 CG2R61 CG2RC0 NG2R50 1.5000 2 180.00 ! CGENFF_PRM
CG2R61 CG2R61 CG2RC0 NG2R51 3.0000 2 180.00 ! CGENFF_PRM
HGR61 CG2R61 CG2RC0 CG2RC0 3.0000 2 180.00 ! CGENFF_PRM
HGR61 CG2R61 CG2RC0 NG2R50 0.8000 2 180.00 ! CGENFF_PRM
HGR61 CG2R61 CG2RC0 NG2R51 3.0000 2 180.00 ! CGENFF_PRM
CG2R61 CG2R61 NG2R51 CG2R53 0.2000 1 0.00 ! PENALTY= 2.5
CG2R61 CG2R61 NG2R51 CG2R53 1.1000 2 180.00 ! PENALTY= 2.5
CG2R61 CG2R61 NG2R51 CG2R53 0.6000 3 0.00 ! PENALTY= 2.5
CG2R61 CG2R61 NG2R51 CG2RC0 0.2000 1 0.00 ! PENALTY= 1.0
CG2R61 CG2R61 NG2R51 CG2RC0 1.1000 2 180.00 ! PENALTY= 1.0
CG2R61 CG2R61 NG2R51 CG2RC0 0.6000 3 0.00 ! PENALTY= 1.0
CG2R61 CG2R61 NG2S3 HGP4 1.3500 2 180.00 ! CGENFF_PRM
CG2R61 CG2RC0 CG2RC0 CG2R61 3.0000 2 180.00 ! CGENFF_PRM
CG2R61 CG2RC0 CG2RC0 NG2R50 1.5000 2 180.00 ! CGENFF_PRM
CG2R61 CG2RC0 CG2RC0 NG2R51 1.5000 2 180.00 ! CGENFF_PRM
NG2R50 CG2RC0 CG2RC0 NG2R51 10.0000 2 180.00 ! CGENFF_PRM
CG2R61 CG2RC0 NG2R50 CG2R53 15.0000 2 180.00 ! CGENFF_PRM
CG2RC0 CG2RC0 NG2R50 CG2R53 6.0000 2 180.00 ! CGENFF_PRM
CG2R61 CG2RC0 NG2R51 CG2R53 19.0000 2 180.00 ! CGENFF_PRM
CG2R61 CG2RC0 NG2R51 CG2R61 0.5000 2 180.00 ! PENALTY= 47.5
CG2RC0 CG2RC0 NG2R51 CG2R53 6.0000 2 180.00 ! CGENFF_PRM
CG2RC0 CG2RC0 NG2R51 CG2R61 1.5000 2 180.00 ! PENALTY= 49.0
IMPROPERS
NG2S3 HGP4 HGP4 CG2R61 -2.5000 0 0.00 ! CGENFF_PRM
NONBONDED nbxmod 5 atom cdiel fshift vatom vdistance vfswitch -
cutnb 14.0 ctofnb 12.0 ctonnb 10.0 eps 1.0 e14fac 1.0 wmin 1.5
NG2S3 0.0 -0.2000 1.8500 ! CGENFF_PRM
CG2R61 0.0 -0.0700 1.9924 ! CGENFF_PRM
CG2RC0 0.0 -0.0990 1.8600 ! CGENFF_PRM
NG2R50 0.0 -0.2000 1.8500 ! CGENFF_PRM
CG2R53 0.0 -0.0200 2.2000 ! CGENFF_PRM
NG2R51 0.0 -0.2000 1.8500 ! CGENFF_PRM
HGP4 0.0 -0.0460 0.2245 ! CGENFF_PRM
HGR61 0.0 -0.0300 1.3582 ! CGENFF_PRM
HGR52 0.0 -0.0460 0.9000 ! CGENFF_PRM
NBFIX
HBOND CUTHB 0.5
END
\ No newline at end of file
* Constructed Based on Stream File from CGenff
*
36 1
MASS -1 NG2S3 14.00700 N
MASS -1 CG2R61 12.01100 C
MASS -1 CG2RC0 12.01100 C
MASS -1 NG2R50 14.00700 N
MASS -1 CG2R53 12.01100 C
MASS -1 NG2R51 14.00700 N
MASS -1 HGP4 1.00800 H
MASS -1 HGR61 1.00800 H
MASS -1 HGR52 1.00800 H
DEFA FIRS NONE LAST NONE
AUTO ANGLES DIHE DRUDE
RESI M14 0.000 ! PARAM_PENALTY=49.0000 ; CHARGE_PENALTY=28.5710
GROUP ! CHARGE CH_PENALTY
ATOM N1 NG2S3 -0.838 ! 0.620
ATOM C1 CG2R61 0.004 ! 0.598
ATOM C2 CG2R61 -0.190 ! 0.000
ATOM C3 CG2R61 -0.328 ! 21.664
ATOM C4 CG2RC0 0.099 ! 21.730
ATOM C5 CG2RC0 0.474 ! 1.670
ATOM N2 NG2R50 -0.717 ! 2.375
ATOM C6 CG2R53 0.130 ! 25.244
ATOM N3 NG2R51 0.090 ! 28.571
ATOM C7 CG2R61 0.109 ! 27.814
ATOM C8 CG2R61 -0.116 ! 0.851
ATOM C9 CG2R61 -0.115 ! 0.000
ATOM C10 CG2R61 -0.115 ! 0.000
ATOM C11 CG2R61 -0.115 ! 0.000
ATOM C12 CG2R61 -0.116 ! 0.851
ATOM C13 CG2R61 -0.367 ! 0.598
ATOM H1 HGP4 0.382 ! 0.000
ATOM H2 HGP4 0.382 ! 0.000
ATOM H3 HGR61 0.196 ! 0.000
ATOM H4 HGR61 0.195 ! 0.000
ATOM H5 HGR52 0.131 ! 12.362
ATOM H6 HGR61 0.115 ! 0.000
ATOM H7 HGR61 0.115 ! 0.000
ATOM H8 HGR61 0.115 ! 0.000
ATOM H9 HGR61 0.115 ! 0.000
ATOM H10 HGR61 0.115 ! 0.000
ATOM H11 HGR61 0.250 ! 0.000
BOND N1 C1
BOND N1 H1
BOND N1 H2
BOND C1 C13
BOND C1 C2
BOND C2 C3
BOND C2 H3
BOND C3 C4
BOND C3 H4
BOND C4 N3
BOND C4 C5
BOND C5 N2
BOND C5 C13
BOND N2 C6
BOND C6 H5
BOND C6 N3
BOND N3 C7
BOND C7 C8
BOND C7 C12
BOND C8 H6
BOND C8 C9
BOND C9 H7
BOND C9 C10
BOND C10 H8
BOND C10 C11
BOND C11 C12
BOND C11 H9
BOND C12 H10
BOND C13 H11
IMPR N1 H2 H1 C1
END
CRYST1 12.009 12.338 11.510 90.00 90.00 90.00 P 1
ATOM 1 SOD SOD I 1 -5.844 1.432 3.239 1.00 0.00 ION NA
ATOM 2 CLA CLA I 2 -5.605 -3.153 1.213 1.00 0.00 ION CL
ATOM 2 CLA CLA I 2 -5.605 -1.153 1.213 1.00 0.00 ION CL
END
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment