Commit 047934e2 authored by Rafal P. Wiewiora's avatar Rafal P. Wiewiora
Browse files

Merge remote-tracking branch 'upstream/master'

parents ce3a5dc0 d12c9bd1
......@@ -20,206 +20,6 @@ else:
import simtk.unit as unit
from simtk.openmm.vec3 import Vec3
class State(_object):
"""
A State object records a snapshot of the
current state of a simulation at a point
in time. You create it by calling
getState() on a Context.
When a State is created, you specify what
information should be stored in it. This
saves time and memory by only copying in
the information that you actually want.
This is especially important for forces
and energies, since they may need to be
calculated. If you query a State object
for a piece of information which is not
available (because it was not requested
when the State was created), it will
return None.
In general return values are Python Units
(https://simtk.org/home/python_units).
Among other things Python Units provides a
container class, Quantity, which holds a
value and a representation of the value's
unit. Values can be integers, floats,
lists, numarrays, etc. Quantity objects
can be used in arithmetic operation just
like number, except they also keep track
of units. To extract the value from a
quantity, us the value_in_unit() method.
For example, to extract the value from a
length quantity, in units of nanometers,
do the following:
myLengthQuantity.value_in_unit(unit.nanometer)
"""
def __init__(self,
simTime=None,
energy=None,
coordList=None,
velList=None,
forceList=None,
periodicBoxVectorsList=None,
paramMap=None):
self._simTime=simTime
self._periodicBoxVectorsList=periodicBoxVectorsList
self._periodicBoxVectorsListNumpy=None
if energy:
self._eK0=energy[0]
self._eP0=energy[1]
else:
self._eK0=None
self._eP0=None
self._coordList=coordList
self._coordListNumpy=None
self._velList=velList
self._velListNumpy=None
self._forceList=forceList
self._forceListNumpy=None
self._paramMap=paramMap
def __getstate__(self):
serializationString = XmlSerializer.serialize(self)
return serializationString
def __setstate__(self, serializationString):
dState = XmlSerializer.deserialize(serializationString)
# Safe provided no __slots__ or other weird things are used
self.__dict__.update(dState.__dict__)
def getTime(self):
"""Get the time for which this State was created."""
return self._simTime * unit.picosecond
def getPeriodicBoxVectors(self, asNumpy=False):
"""Get the three periodic box vectors if this state is from a
simulation using PBC ."""
if self._periodicBoxVectorsList is None:
raise TypeError('periodic box vectors were not available.')
if asNumpy:
if self._periodicBoxVectorsListNumpy is None:
self._periodicBoxVectorsListNumpy = \
numpy.array(self._periodicBoxVectorsList)
returnValue=self._periodicBoxVectorsListNumpy
else:
returnValue=self._periodicBoxVectorsList
returnValue = unit.Quantity(returnValue, unit.nanometers)
return returnValue
def getPeriodicBoxVolume(self):
"""Get the volume of the periodic box."""
a = self._periodicBoxVectorsList[0]
b = self._periodicBoxVectorsList[1]
c = self._periodicBoxVectorsList[2]
bcrossc = Vec3(b[1]*c[2]-b[2]*c[1], b[2]*c[0]-b[0]*c[2], b[0]*c[1]-b[1]*c[0])
return unit.Quantity(unit.dot(a, bcrossc), unit.nanometers*unit.nanometers*unit.nanometers)
def getPositions(self, asNumpy=False):
"""Get the position of each particle with units.
Raises an exception if postions where not requested in
the context.getState() call.
Returns a list of tuples, unless asNumpy is True, in
which case a Numpy array of arrays will be returned.
To remove the units, divide return value by unit.angstrom
or unit.nanometer. See the following for details:
https://simtk.org/home/python_units
"""
if self._coordList is None:
raise TypeError('Positions were not requested in getState() call, so are not available.')
if asNumpy:
if self._coordListNumpy is None:
self._coordListNumpy=numpy.array(self._coordList)
returnValue=self._coordListNumpy
else:
returnValue=self._coordList
returnValue = unit.Quantity(returnValue, unit.nanometers)
return returnValue
def getVelocities(self, asNumpy=False):
"""Get the velocity of each particle with units.
Raises an exception if velocities where not requested in
the context.getState() call.
Returns a list of tuples, unless asNumpy is True, in
which case a Numpy array of arrays will be returned.
To remove the units, you can divide the return value by
unit.angstrom/unit.picosecond or unit.meter/unit.second,
etc. See the following for details:
https://simtk.org/home/python_units
"""
if self._velList is None:
raise TypeError('Velocities were not requested in getState() call, so are not available.')
if asNumpy:
if self._velListNumpy is None:
self._velListNumpy=numpy.array(self._velList)
returnValue=self._velListNumpy
else:
returnValue=self._velList
returnValue = unit.Quantity(returnValue, unit.nanometers/unit.picosecond)
return returnValue
def getForces(self, asNumpy=False):
"""Get the force acting on each particle with units.
Raises an exception if forces where not requested in
the context.getState() call.
Returns a list of tuples, unless asNumpy is True, in
which case a Numpy array of arrays will be returned.
To remove the units, you can divide the return value by
unit.kilojoule_per_mole/unit.angstrom or
unit.calorie_per_mole/unit.nanometer, etc.
See the following for details:
https://simtk.org/home/python_units
"""
if self._forceList is None:
raise TypeError('Forces were not requested in getState() call, so are not available.')
if asNumpy:
if self._forceListNumpy is None:
self._forceListNumpy=numpy.array(self._forceList)
returnValue=self._forceListNumpy
else:
returnValue=self._forceList
returnValue = unit.Quantity(returnValue,
unit.kilojoule_per_mole/unit.nanometer)
return returnValue
def getKineticEnergy(self):
"""Get the total kinetic energy of the system with units.
To remove the units, you can divide the return value by
unit.kilojoule_per_mole or unit.calorie_per_mole, etc.
See the following for details:
https://simtk.org/home/python_units
"""
if self._eK0 is None:
raise TypeError('Energy was not requested in getState() call, so it is not available.')
return self._eK0 * unit.kilojoule_per_mole
def getPotentialEnergy(self):
"""Get the total potential energy of the system with units.
To remove the units, you can divide the return value by
unit.kilojoule_per_mole or unit.kilocalorie_per_mole, etc.
See the following for details:
https://simtk.org/home/python_units
"""
if self._eP0 is None:
raise TypeError('Energy was not requested in getState() call, so it is not available.')
return self._eP0 * unit.kilojoule_per_mole
def getParameters(self):
"""Get a map containing the values of all parameters.
"""
if self._paramMap is None:
raise TypeError('Parameters were not requested in getState() call, so are not available.')
return self._paramMap
%}
......
......@@ -186,6 +186,8 @@ class TestAPIUnits(unittest.TestCase):
self.assertTrue(force.usesPeriodicBoundaryConditions())
force.setNonbondedMethod(NonbondedForce.PME)
self.assertTrue(force.usesPeriodicBoundaryConditions())
force.setNonbondedMethod(NonbondedForce.LJPME)
self.assertTrue(force.usesPeriodicBoundaryConditions())
def testCmapForce(self):
""" Tests the CMAPTorsionForce API features """
......
......@@ -21,12 +21,14 @@ class TestAmberPrmtopFile(unittest.TestCase):
"""Test the AmberPrmtopFile.createSystem() method."""
def test_NonbondedMethod(self):
"""Test all five options for the nonbondedMethod parameter."""
"""Test all six options for the nonbondedMethod parameter."""
methodMap = {NoCutoff:NonbondedForce.NoCutoff,
CutoffNonPeriodic:NonbondedForce.CutoffNonPeriodic,
CutoffPeriodic:NonbondedForce.CutoffPeriodic,
Ewald:NonbondedForce.Ewald, PME: NonbondedForce.PME}
Ewald:NonbondedForce.Ewald,
PME:NonbondedForce.PME,
LJPME:NonbondedForce.LJPME}
for method in methodMap:
system = prmtop1.createSystem(nonbondedMethod=method)
forces = system.getForces()
......@@ -37,7 +39,7 @@ class TestAmberPrmtopFile(unittest.TestCase):
def test_Cutoff(self):
"""Test to make sure the nonbondedCutoff parameter is passed correctly."""
for method in [CutoffNonPeriodic, CutoffPeriodic, Ewald, PME]:
for method in [CutoffNonPeriodic, CutoffPeriodic, Ewald, PME, LJPME]:
system = prmtop1.createSystem(nonbondedMethod=method,
nonbondedCutoff=2*nanometer,
constraints=HBonds)
......@@ -51,7 +53,7 @@ class TestAmberPrmtopFile(unittest.TestCase):
def test_EwaldErrorTolerance(self):
"""Test to make sure the ewaldErrorTolerance parameter is passed correctly."""
for method in [Ewald, PME]:
for method in [Ewald, PME, LJPME]:
system = prmtop1.createSystem(nonbondedMethod=method,
ewaldErrorTolerance=1e-6,
constraints=HBonds)
......
......@@ -17,6 +17,52 @@ class TestDCDFile(unittest.TestCase):
for i in range(5):
dcd.writeModel([mm.Vec3(random(), random(), random()) for j in range(natom)]*unit.angstroms)
os.remove(fname)
def testLongTrajectory(self):
"""Test writing a trajectory that has more than 2^31 steps."""
fname = tempfile.mktemp(suffix='.dcd')
pdbfile = app.PDBFile('systems/alanine-dipeptide-implicit.pdb')
natom = len(list(pdbfile.topology.atoms()))
with open(fname, 'wb') as f:
dcd = app.DCDFile(f, pdbfile.topology, 0.001, interval=1000000000)
for i in range(5):
dcd.writeModel([mm.Vec3(random(), random(), random()) for j in range(natom)]*unit.angstroms)
os.remove(fname)
def testAppend(self):
"""Test appending to an existing trajectory."""
fname = tempfile.mktemp(suffix='.dcd')
pdb = app.PDBFile('systems/alanine-dipeptide-implicit.pdb')
ff = app.ForceField('amber99sb.xml', 'tip3p.xml')
system = ff.createSystem(pdb.topology)
# Create a simulation and write some frames to a DCD file.
integrator = mm.VerletIntegrator(0.001*unit.picoseconds)
simulation = app.Simulation(pdb.topology, system, integrator, mm.Platform.getPlatformByName('Reference'))
dcd = app.DCDReporter(fname, 2)
simulation.reporters.append(dcd)
simulation.context.setPositions(pdb.positions)
simulation.context.setVelocitiesToTemperature(300*unit.kelvin)
simulation.step(10)
self.assertEqual(5, dcd._dcd._modelCount)
del simulation
len1 = os.stat(fname).st_size
# Create a new simulation and have it append some more frames.
integrator = mm.VerletIntegrator(0.001*unit.picoseconds)
simulation = app.Simulation(pdb.topology, system, integrator, mm.Platform.getPlatformByName('Reference'))
dcd = app.DCDReporter(fname, 2, append=True)
simulation.reporters.append(dcd)
simulation.context.setPositions(pdb.positions)
simulation.context.setVelocitiesToTemperature(300*unit.kelvin)
simulation.step(10)
self.assertEqual(10, dcd._dcd._modelCount)
len2 = os.stat(fname).st_size
self.assertTrue(len2-len1 > 3*4*5*system.getNumParticles())
os.remove(fname)
if __name__ == '__main__':
unittest.main()
......@@ -14,12 +14,14 @@ class TestDesmondDMSFile(unittest.TestCase):
self.dms = DesmondDMSFile(path)
def test_NonbondedMethod(self):
"""Test all five options for the nonbondedMethod parameter."""
"""Test all six options for the nonbondedMethod parameter."""
methodMap = {NoCutoff:NonbondedForce.NoCutoff,
CutoffNonPeriodic:NonbondedForce.CutoffNonPeriodic,
CutoffPeriodic:NonbondedForce.CutoffPeriodic,
Ewald:NonbondedForce.Ewald, PME: NonbondedForce.PME}
Ewald:NonbondedForce.Ewald,
PME:NonbondedForce.PME,
LJPME:NonbondedForce.LJPME}
for method in methodMap:
system = self.dms.createSystem(nonbondedMethod=method)
forces = system.getForces()
......@@ -30,7 +32,7 @@ class TestDesmondDMSFile(unittest.TestCase):
def test_Cutoff(self):
"""Test to make sure the nonbondedCutoff parameter is passed correctly."""
for method in [CutoffNonPeriodic, CutoffPeriodic, Ewald, PME]:
for method in [CutoffNonPeriodic, CutoffPeriodic, Ewald, PME, LJPME]:
system = self.dms.createSystem(nonbondedMethod=method,
nonbondedCutoff=2*nanometer)
cutoff_distance = 0.0*nanometer
......@@ -43,7 +45,7 @@ class TestDesmondDMSFile(unittest.TestCase):
def test_EwaldErrorTolerance(self):
"""Test to make sure the ewaldErrorTolerance parameter is passed correctly."""
for method in [Ewald, PME]:
for method in [Ewald, PME, LJPME]:
system = self.dms.createSystem(nonbondedMethod=method,
ewaldErrorTolerance=1e-6)
tolerance = 0
......
......@@ -33,12 +33,14 @@ class TestForceField(unittest.TestCase):
def test_NonbondedMethod(self):
"""Test all five options for the nonbondedMethod parameter."""
"""Test all six options for the nonbondedMethod parameter."""
methodMap = {NoCutoff:NonbondedForce.NoCutoff,
CutoffNonPeriodic:NonbondedForce.CutoffNonPeriodic,
CutoffPeriodic:NonbondedForce.CutoffPeriodic,
Ewald:NonbondedForce.Ewald, PME: NonbondedForce.PME}
Ewald:NonbondedForce.Ewald,
PME:NonbondedForce.PME,
LJPME:NonbondedForce.LJPME}
for method in methodMap:
system = self.forcefield1.createSystem(self.pdb1.topology,
nonbondedMethod=method)
......@@ -62,7 +64,7 @@ class TestForceField(unittest.TestCase):
def test_Cutoff(self):
"""Test to make sure the nonbondedCutoff parameter is passed correctly."""
for method in [CutoffNonPeriodic, CutoffPeriodic, Ewald, PME]:
for method in [CutoffNonPeriodic, CutoffPeriodic, Ewald, PME, LJPME]:
system = self.forcefield1.createSystem(self.pdb1.topology,
nonbondedMethod=method,
nonbondedCutoff=2*nanometer,
......@@ -748,6 +750,19 @@ class TestForceField(unittest.TestCase):
expected = 0.3*ljEnergy(2.5, 1.1, 3) + 0.3*ljEnergy(3.5, sqrt(0.1), 3) + ljEnergy(3.5, 1.5, 4)
self.assertAlmostEqual(expected, context.getState(getEnergy=True).getPotentialEnergy().value_in_unit(kilojoules_per_mole))
def test_IgnoreExternalBonds(self):
"""Test the ignoreExternalBonds option"""
modeller = Modeller(self.pdb2.topology, self.pdb2.positions)
modeller.delete([next(modeller.topology.residues())])
self.assertRaises(Exception, lambda: self.forcefield2.createSystem(modeller.topology))
system = self.forcefield2.createSystem(modeller.topology, ignoreExternalBonds=True)
templates = self.forcefield2.getMatchingTemplates(modeller.topology, ignoreExternalBonds=True)
self.assertEqual(2, len(templates))
self.assertEqual('ALA', templates[0].name)
self.assertEqual('NME', templates[1].name)
class AmoebaTestForceField(unittest.TestCase):
"""Test the ForceField.createSystem() method with the AMOEBA forcefield."""
......@@ -763,7 +778,7 @@ class AmoebaTestForceField(unittest.TestCase):
def test_NonbondedMethod(self):
"""Test all five options for the nonbondedMethod parameter."""
"""Test both options for the nonbondedMethod parameter."""
methodMap = {NoCutoff:AmoebaMultipoleForce.NoCutoff,
PME:AmoebaMultipoleForce.PME}
......
import unittest
from validateConstraints import *
from simtk.openmm.app import *
from simtk.openmm import *
from simtk.unit import *
import simtk.openmm.app.element as elem
import simtk.openmm.app.forcefield as forcefield
import math
try:
from cStringIO import StringIO
except ImportError:
from io import StringIO
import os
import warnings
class TestGenerators(unittest.TestCase):
"""Test the various generators found in forcefield.py."""
def setUp(self):
# alanine dipeptide with implicit water
self.pdb1 = PDBFile('systems/alanine-dipeptide-implicit.pdb')
def test_CustomHbondGenerator(self):
"""Test the generator for CustomHbondForce."""
for bondCutoff in range(4):
xml = """
<ForceField>
<CustomHbondForce energy="a*b*distance(a1,d1)" particlesPerDonor="3" particlesPerAcceptor="2" bondCutoff="%d">
<PerDonorParameter name="a"/>
<PerAcceptorParameter name="b"/>
<Donor class1="C" class2="N" class3="H" a="3"/>
<Acceptor class1="C" class2="O" b="2"/>
<Function name="test" min="1" max="2" type="Continuous1D">
0 1 2 3 4 5
</Function>
</CustomHbondForce>
</ForceField>""" % bondCutoff
ff = ForceField('amber99sb.xml', StringIO(xml))
system = ff.createSystem(self.pdb1.topology)
hbond = [f for f in system.getForces() if isinstance(f, CustomHbondForce)][0]
self.assertEqual(1, hbond.getNumPerDonorParameters())
self.assertEqual(1, hbond.getNumPerAcceptorParameters())
self.assertEqual('a', hbond.getPerDonorParameterName(0))
self.assertEqual('b', hbond.getPerAcceptorParameterName(0))
self.assertEqual(1, hbond.getNumTabulatedFunctions())
expectedDonors = [(4,6,7), (14,16,17)]
expectedAcceptors = [(4,5,-1), (14,15,-1)]
self.assertEqual(len(expectedDonors), hbond.getNumDonors())
self.assertEqual(len(expectedAcceptors), hbond.getNumAcceptors())
for i in range(hbond.getNumDonors()):
atom1, atom2, atom3, params = hbond.getDonorParameters(i)
self.assertTrue((atom1, atom2, atom3) in expectedDonors)
self.assertEqual((3.0,), params)
for i in range(hbond.getNumAcceptors()):
atom1, atom2, atom3, params = hbond.getAcceptorParameters(i)
self.assertTrue((atom1, atom2, atom3) in expectedAcceptors)
self.assertEqual((2.0,), params)
expectedExclusions = [(0,0), (1,1)]
if bondCutoff >= 2:
expectedExclusions.append((0,1))
if bondCutoff >= 3:
expectedExclusions.append((1,0))
self.assertEqual(len(expectedExclusions), hbond.getNumExclusions())
for i in range(hbond.getNumExclusions()):
self.assertTrue(tuple(hbond.getExclusionParticles(i)) in expectedExclusions)
def test_CustomHbondGenerator2(self):
"""Test the generator for CustomHbondForce with different parameters."""
xml = """
<ForceField>
<CustomHbondForce energy="a*b*distance(a1,d1)" particlesPerDonor="2" particlesPerAcceptor="1" bondCutoff="0">
<PerDonorParameter name="a"/>
<PerAcceptorParameter name="b"/>
<Donor class1="N" class2="H" a="3"/>
<Acceptor class1="O" b="2"/>
</CustomHbondForce>
</ForceField>"""
ff = ForceField('amber99sb.xml', StringIO(xml))
system = ff.createSystem(self.pdb1.topology)
hbond = [f for f in system.getForces() if isinstance(f, CustomHbondForce)][0]
self.assertEqual(1, hbond.getNumPerDonorParameters())
self.assertEqual(1, hbond.getNumPerAcceptorParameters())
self.assertEqual('a', hbond.getPerDonorParameterName(0))
self.assertEqual('b', hbond.getPerAcceptorParameterName(0))
expectedDonors = [(6,7,-1), (16,17,-1)]
expectedAcceptors = [(5,-1,-1), (15,-1,-1)]
self.assertEqual(len(expectedDonors), hbond.getNumDonors())
self.assertEqual(len(expectedAcceptors), hbond.getNumAcceptors())
for i in range(hbond.getNumDonors()):
atom1, atom2, atom3, params = hbond.getDonorParameters(i)
self.assertTrue((atom1, atom2, atom3) in expectedDonors)
self.assertEqual((3.0,), params)
for i in range(hbond.getNumAcceptors()):
atom1, atom2, atom3, params = hbond.getAcceptorParameters(i)
self.assertTrue((atom1, atom2, atom3) in expectedAcceptors)
self.assertEqual((2.0,), params)
if __name__ == '__main__':
unittest.main()
......@@ -22,12 +22,14 @@ class TestGromacsTopFile(unittest.TestCase):
self.top2 = GromacsTopFile('systems/implicit.top')
def test_NonbondedMethod(self):
"""Test all five options for the nonbondedMethod parameter."""
"""Test all six options for the nonbondedMethod parameter."""
methodMap = {NoCutoff:NonbondedForce.NoCutoff,
CutoffNonPeriodic:NonbondedForce.CutoffNonPeriodic,
CutoffPeriodic:NonbondedForce.CutoffPeriodic,
Ewald:NonbondedForce.Ewald, PME: NonbondedForce.PME}
Ewald:NonbondedForce.Ewald,
PME:NonbondedForce.PME,
LJPME:NonbondedForce.LJPME}
for method in methodMap:
system = self.top1.createSystem(nonbondedMethod=method)
forces = system.getForces()
......@@ -52,7 +54,7 @@ class TestGromacsTopFile(unittest.TestCase):
def test_Cutoff(self):
"""Test to make sure the nonbondedCutoff parameter is passed correctly."""
for method in [CutoffNonPeriodic, CutoffPeriodic, Ewald, PME]:
for method in [CutoffNonPeriodic, CutoffPeriodic, Ewald, PME, LJPME]:
system = self.top1.createSystem(nonbondedMethod=method,
nonbondedCutoff=2*nanometer,
constraints=HBonds)
......@@ -66,7 +68,7 @@ class TestGromacsTopFile(unittest.TestCase):
def test_EwaldErrorTolerance(self):
"""Test to make sure the ewaldErrorTolerance parameter is passed correctly."""
for method in [Ewald, PME]:
for method in [Ewald, PME, LJPME]:
system = self.top1.createSystem(nonbondedMethod=method,
ewaldErrorTolerance=1e-6,
constraints=HBonds)
......
import unittest
import tempfile
from datetime import datetime, timedelta
from simtk.openmm import *
from simtk.openmm.app import *
from simtk.unit import *
import math, random
class TestIntegrators(unittest.TestCase):
"""Test Python Integrator classes"""
def testMTSIntegratorExplicit(self):
"""Test the MTS integrator on an explicit solvent system"""
# Create a periodic solvated system with PME
pdb = PDBFile('systems/alanine-dipeptide-explicit.pdb')
ff = ForceField('amber99sbildn.xml', 'tip3p.xml')
system = ff.createSystem(pdb.topology, cutoffMethod=PME)
# Split forces into groups
for force in system.getForces():
if force.__class__.__name__ == 'NonbondedForce':
force.setForceGroup(1)
force.setReciprocalSpaceForceGroup(2)
else:
force.setForceGroup(0)
# Create an integrator
integrator = MTSIntegrator(4*femtoseconds, [(2,1), (1,2), (0,8)])
# Run a few steps of dynamics
context = Context(system, integrator)
context.setPositions(pdb.positions)
integrator.step(10)
# Ensure energy is well-behaved.
state = context.getState(getEnergy=True)
if not (state.getPotentialEnergy() / kilojoules_per_mole < 0.0):
raise Exception('Potential energy of alanine dipeptide system with MTS integrator is blowing up: %s' % str(state.getPotentialEnergy()))
def testMTSIntegratorConstraints(self):
"""Test the MTS integrator energy conservation on a system of constrained particles with no inner force (just constraints)"""
# Create a constrained test system
numParticles = 8
numConstraints = 5
system = System()
force = NonbondedForce()
for i in range(numParticles):
system.addParticle(5.0 if i%2==0 else 10.0)
force.addParticle((0.2 if i%2==0 else -0.2), 0.5, 5.0);
system.addConstraint(0, 1, 1.0);
system.addConstraint(1, 2, 1.0);
system.addConstraint(2, 3, 1.0);
system.addConstraint(4, 5, 1.0);
system.addConstraint(6, 7, 1.0);
system.addForce(force)
# Create integrator where inner timestep just evaluates constraints
integrator = MTSIntegrator(1*femtoseconds, [(1,1), (0,4)])
integrator.setConstraintTolerance(1e-5);
positions = [ (i/2., (i+1)/2., 0.) for i in range(numParticles) ]
velocities = [ (random.random()-0.5, random.random()-0.5, random.random()-0.5) for i in range(numParticles) ]
# Create Context
platform = Platform.getPlatformByName('Reference')
context = Context(system, integrator, platform)
context.setPositions(positions)
context.setVelocities(velocities)
context.applyConstraints(1e-5)
# Simulate it and see whether the constraints remain satisfied.
CONSTRAINT_RELATIVE_TOLERANCE = 1.e-4 # relative constraint violation tolerance
ENERGY_RELATIVE_TOLERANCE = 1.e-2 # relative energy violation tolerance
for i in range(1000):
state = context.getState(getPositions=True, getEnergy=True)
positions = state.getPositions()
for j in range(numConstraints):
[particle1, particle2, constraint_distance] = system.getConstraintParameters(j)
current_distance = 0.0 * nanometers**2
for k in range(3):
current_distance += (positions[particle1][k] - positions[particle2][k])**2
current_distance = sqrt(current_distance)
# Fail test if outside of relative tolerance
relative_violation = (current_distance - constraint_distance) / constraint_distance
if (relative_violation > CONSTRAINT_RELATIVE_TOLERANCE):
raise Exception('Constrained distance is violated by relative tolerance of %f (constraint %s actual %s)' % (relative_violation, str(constraint_distance), str(current_distance)))
# Check total energy
total_energy = state.getPotentialEnergy() + state.getKineticEnergy()
if (i == 1):
initial_energy = total_energy
elif (i > 1):
relative_violation = abs((total_energy - initial_energy) / initial_energy)
if (relative_violation > ENERGY_RELATIVE_TOLERANCE):
raise Exception('Total energy is violated by relative tolerance of %f on step %d (initial %s final %s)' % (relative_violation, i, str(initial_energy), str(total_energy)))
# Take a step
integrator.step(1)
def testBadGroups(self):
"""Test the MTS integrator with bad force group substeps."""
# Create a periodic solvated system with PME
pdb = PDBFile('systems/alanine-dipeptide-explicit.pdb')
ff = ForceField('amber99sbildn.xml', 'tip3p.xml')
system = ff.createSystem(pdb.topology, cutoffMethod=PME)
# Split forces into groups
for force in system.getForces():
if force.__class__.__name__ == 'NonbondedForce':
force.setForceGroup(1)
force.setReciprocalSpaceForceGroup(2)
else:
force.setForceGroup(0)
with self.assertRaises(ValueError):
# Create an integrator
integrator = MTSIntegrator(4*femtoseconds, [(2,1), (1,3), (0,8)])
# Run a few steps of dynamics
context = Context(system, integrator)
context.setPositions(pdb.positions)
integrator.step(10)
if __name__ == '__main__':
unittest.main()
......@@ -59,6 +59,12 @@ class TestNumpyCompatibility(unittest.TestCase):
np.testing.assert_array_almost_equal(input.value_in_unit(unit.angstroms / unit.femtoseconds),
output.value_in_unit(unit.angstroms / unit.femtoseconds))
def test_periodicBoxVectors(self):
output = self.simulation.context.getState(getVelocities=True).getPeriodicBoxVectors(asNumpy=True)
systemBox = self.simulation.system.getDefaultPeriodicBoxVectors()
for i in range(3):
np.testing.assert_array_almost_equal(systemBox[i].value_in_unit(unit.nanometers), output[i].value_in_unit(unit.nanometers))
def test_tabulatedFunction(self):
f = mm.CustomNonbondedForce('g(r)')
......
import pickle
import sys
import unittest
from simtk.openmm.app import *
......@@ -26,6 +27,14 @@ class TestTopology(unittest.TestCase):
"""Test getters for number of atoms, residues, chains."""
self.check_pdbfile('systems/1T2Y.pdb', 271, 25, 1)
def test_bondtype_singleton(self):
""" Tests that the bond types are really singletons """
self.assertIs(Single, pickle.loads(pickle.dumps(Single)))
self.assertIs(Double, pickle.loads(pickle.dumps(Double)))
self.assertIs(Triple, pickle.loads(pickle.dumps(Triple)))
self.assertIs(Aromatic, pickle.loads(pickle.dumps(Aromatic)))
self.assertIs(Amide, pickle.loads(pickle.dumps(Amide)))
def test_residue_bonds(self):
"""Test retrieving bonds for a residue produces expected results."""
# Create a test topology
......
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