TestAmberPrmtopFile.py 28.6 KB
Newer Older
1
import unittest
2
3
import os
import tempfile
4
from validateConstraints import *
5
6
7
8
from openmm.app import *
from openmm import *
from openmm.unit import *
import openmm.app.element as elem
9

10
inpcrd1 = AmberInpcrdFile('systems/alanine-dipeptide-explicit.inpcrd')
11
12
13
inpcrd3 = AmberInpcrdFile('systems/ff14ipq.rst7')
inpcrd4 = AmberInpcrdFile('systems/Mg_water.inpcrd')
inpcrd7 = AmberInpcrdFile('systems/18protein.rst7')
14
15
prmtop1 = AmberPrmtopFile('systems/alanine-dipeptide-explicit.prmtop')
prmtop2 = AmberPrmtopFile('systems/alanine-dipeptide-implicit.prmtop')
16
17
prmtop3 = AmberPrmtopFile('systems/ff14ipq.parm7', periodicBoxVectors=inpcrd3.boxVectors)
prmtop4 = AmberPrmtopFile('systems/Mg_water.prmtop', periodicBoxVectors=inpcrd4.boxVectors)
18
prmtop5 = AmberPrmtopFile('systems/tz2.truncoct.parm7')
19
prmtop6 = AmberPrmtopFile('systems/gaffwat.parm7')
20
prmtop7 = AmberPrmtopFile('systems/18protein.parm7', periodicBoxVectors=inpcrd7.boxVectors)
21

22
23
24
25
26
class TestAmberPrmtopFile(unittest.TestCase):

    """Test the AmberPrmtopFile.createSystem() method."""

    def test_NonbondedMethod(self):
Peter Eastman's avatar
Peter Eastman committed
27
        """Test all six options for the nonbondedMethod parameter."""
28

29
30
31
        methodMap = {NoCutoff:NonbondedForce.NoCutoff,
                     CutoffNonPeriodic:NonbondedForce.CutoffNonPeriodic,
                     CutoffPeriodic:NonbondedForce.CutoffPeriodic,
Peter Eastman's avatar
Peter Eastman committed
32
33
34
                     Ewald:NonbondedForce.Ewald,
                     PME:NonbondedForce.PME,
                     LJPME:NonbondedForce.LJPME}
35
        for method in methodMap:
36
            system = prmtop1.createSystem(nonbondedMethod=method)
37
            forces = system.getForces()
38
39
            self.assertTrue(any(isinstance(f, NonbondedForce) and
                                f.getNonbondedMethod()==methodMap[method]
40
41
                                for f in forces))

42
43
44
45
46
47
    def test_LJPME_NBFIX(self):
        """Test LJPME with NBFIX."""

        with self.assertRaisesRegex(ValueError, 'LJPME is not supported'):
            prmtop3.createSystem(nonbondedMethod=LJPME)

48
49
50
    def test_Cutoff(self):
        """Test to make sure the nonbondedCutoff parameter is passed correctly."""

Peter Eastman's avatar
Peter Eastman committed
51
        for method in [CutoffNonPeriodic, CutoffPeriodic, Ewald, PME, LJPME]:
52
53
            system = prmtop1.createSystem(nonbondedMethod=method,
                                          nonbondedCutoff=2*nanometer,
54
                                          constraints=HBonds)
55
56
57
58
59
60
61
62
63
64
            cutoff_distance = 0.0*nanometer
            cutoff_check = 2.0*nanometer
            for force in system.getForces():
                if isinstance(force, NonbondedForce):
                    cutoff_distance = force.getCutoffDistance()
            self.assertEqual(cutoff_distance, cutoff_check)

    def test_EwaldErrorTolerance(self):
        """Test to make sure the ewaldErrorTolerance parameter is passed correctly."""

Peter Eastman's avatar
Peter Eastman committed
65
        for method in [Ewald, PME, LJPME]:
66
67
            system = prmtop1.createSystem(nonbondedMethod=method,
                                          ewaldErrorTolerance=1e-6,
68
                                          constraints=HBonds)
69
70
71
72
73
74
75
76
77
78
79
            tolerance = 0
            tolerance_check = 1e-6
            for force in system.getForces():
                if isinstance(force, NonbondedForce):
                    tolerance = force.getEwaldErrorTolerance()
            self.assertEqual(tolerance, tolerance_check)

    def test_RemoveCMMotion(self):
        """Test both options (True and False) for the removeCMMotion parameter."""

        for b in [True, False]:
80
            system = prmtop1.createSystem(removeCMMotion=b)
81
82
83
84
85
86
            forces = system.getForces()
            self.assertEqual(any(isinstance(f, CMMotionRemover) for f in forces), b)

    def test_RigidWaterAndConstraints(self):
        """Test all eight options for the constraints and rigidWater parameters."""

87
        topology = prmtop1.topology
88
89
90
91
92
93
94
95
        for constraints in [None, HBonds, AllBonds, HAngles]:
            for rigidWater in [True, False]:
                system = prmtop1.createSystem(constraints=constraints, rigidWater=rigidWater)
                if constraints != None:
                    # Amber adds an extra "bond" between water hydrogens, so any constraint
                    # method except None is equivalent to rigidWater=True.
                    rigidWater = True
                validateConstraints(self, topology, system, constraints, rigidWater)
96
97

    def test_ImplicitSolvent(self):
98
        """Test the four types of implicit solvents using the implicitSolvent
99
100
101
        parameter.

        """
102
        for implicitSolvent_value, gbsa in zip([HCT, OBC1, OBC2, GBn], ['ACE', None, 'ACE', None]):
Evan Pretti's avatar
Evan Pretti committed
103
            system = prmtop2.createSystem(implicitSolvent=implicitSolvent_value, sasaMethod=gbsa)
104
105
106
107
108
            forces = system.getForces()
            if implicitSolvent_value in set([HCT, OBC1, GBn]):
                force_type = CustomGBForce
            else:
                force_type = GBSAOBCForce
109

110
111
112
            self.assertTrue(any(isinstance(f, force_type) for f in forces))

    def test_ImplicitSolventParameters(self):
113
114
115
        """Test that parameters are set correctly for the different types of implicit solvent."""
        methodMap = {NoCutoff:NonbondedForce.NoCutoff,
                     CutoffNonPeriodic:NonbondedForce.CutoffNonPeriodic}
116
        for implicitSolvent_value in [HCT, OBC1, OBC2, GBn]:
117
            for method in methodMap:
118
                system = prmtop2.createSystem(implicitSolvent=implicitSolvent_value,
119
120
121
122
123
124
125
126
127
128
129
130
131
                                    solventDielectric=50.0, soluteDielectric=0.9, nonbondedMethod=method)
                if implicitSolvent_value in set([HCT, OBC1, GBn]):
                    for force in system.getForces():
                        if isinstance(force, CustomGBForce):
                            self.assertEqual(force.getNonbondedMethod(), methodMap[method])
                        if isinstance(force, NonbondedForce):
                            self.assertEqual(force.getReactionFieldDielectric(), 1.0)
                            self.assertEqual(force.getNonbondedMethod(), methodMap[method])
                else:
                    for force in system.getForces():
                        if isinstance(force, GBSAOBCForce):
                            self.assertEqual(force.getNonbondedMethod(), methodMap[method])
                            if force.getSolventDielectric() == 50.0:
132
                                found_matching_solvent_dielectric = True
133
                            if force.getSoluteDielectric() == 0.9:
134
                                found_matching_solute_dielectric = True
135
136
137
                        if isinstance(force, NonbondedForce):
                            self.assertEqual(force.getReactionFieldDielectric(), 1.0)
                            self.assertEqual(force.getNonbondedMethod(), methodMap[method])
138
                    self.assertTrue(found_matching_solvent_dielectric and
139
                                    found_matching_solute_dielectric)
140

141
    def test_ImplicitSolventZeroSA(self):
Evan Pretti's avatar
Evan Pretti committed
142
        """Test that requesting sasaMethod=None yields a surface area energy of 0 when
143
           prmtop.createSystem produces a GBSAOBCForce"""
Evan Pretti's avatar
Evan Pretti committed
144
        system = prmtop2.createSystem(implicitSolvent=OBC2, sasaMethod=None)
145
146
147
148
        for force in system.getForces():
            if isinstance(force, GBSAOBCForce):
                self.assertEqual(force.getSurfaceAreaEnergy(), 0*kilojoule/(nanometer**2*mole))

Evan Pretti's avatar
Evan Pretti committed
149
150
151
152
153
154
155
156
157
158
159
160
161
    def test_SASAMethodAlias(self):
        """Tests that gbsaModel is an alias for sasaMethod"""
        for method in (None, 'ACE', 'LCPO'):
            system1 = prmtop2.createSystem(implicitSolvent=OBC2, sasaMethod=method)
            system2 = prmtop2.createSystem(implicitSolvent=OBC2, gbsaModel=method)
            self.assertEqual(XmlSerializer.serialize(system1), XmlSerializer.serialize(system2))

    def test_SASAMethodDefault(self):
        """Tests that ACE is the default for sasaMethod"""
        system1 = prmtop2.createSystem(implicitSolvent=OBC2)
        system2 = prmtop2.createSystem(implicitSolvent=OBC2, sasaMethod='ACE')
        self.assertEqual(XmlSerializer.serialize(system1), XmlSerializer.serialize(system2))

162
163
    def test_HydrogenMass(self):
        """Test that altering the mass of hydrogens works correctly."""
164

165
        topology = prmtop1.topology
166
        hydrogenMass = 4*amu
167
168
        system1 = prmtop1.createSystem()
        system2 = prmtop1.createSystem(hydrogenMass=hydrogenMass)
169
170
171
        for atom in topology.atoms():
            if atom.element == elem.hydrogen:
                self.assertNotEqual(hydrogenMass, system1.getParticleMass(atom.index))
172
173
174
175
                if atom.residue.name == 'HOH':
                    self.assertEqual(system1.getParticleMass(atom.index), system2.getParticleMass(atom.index))
                else:
                    self.assertEqual(hydrogenMass, system2.getParticleMass(atom.index))
176
177
178
179
        totalMass1 = sum([system1.getParticleMass(i) for i in range(system1.getNumParticles())]).value_in_unit(amu)
        totalMass2 = sum([system2.getParticleMass(i) for i in range(system2.getNumParticles())]).value_in_unit(amu)
        self.assertAlmostEqual(totalMass1, totalMass2)

180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
    def test_NBFIX_LongRange(self):
        """Test prmtop files with NBFIX LJ modifications w/ long-range correction"""
        system = prmtop3.createSystem(nonbondedMethod=PME,
                                      nonbondedCutoff=8*angstroms)
        # Check the forces
        has_nonbond_force = has_custom_nonbond_force = False
        nonbond_exceptions = custom_nonbond_exclusions = 0
        for force in system.getForces():
            if isinstance(force, NonbondedForce):
                has_nonbond_force = True
                nonbond_exceptions = force.getNumExceptions()
            elif isinstance(force, CustomNonbondedForce):
                has_custom_nonbond_force = True
                custom_nonbond_exceptions = force.getNumExclusions()
        self.assertTrue(has_nonbond_force)
        self.assertTrue(has_custom_nonbond_force)
        self.assertEqual(nonbond_exceptions, custom_nonbond_exceptions)
        integrator = VerletIntegrator(1.0*femtoseconds)
        # Use reference platform, since it should always be present and
        # 'working', and the system is plenty small so this won't be too slow
Peter Eastman's avatar
Peter Eastman committed
200
        sim = Simulation(prmtop3.topology, system, integrator, Platform.getPlatform('Reference'))
201
202
203
204
205
206
207
        # Check that the energy is about what we expect it to be
        sim.context.setPositions(inpcrd3.positions)
        ene = sim.context.getState(getEnergy=True, enforcePeriodicBox=True).getPotentialEnergy()
        ene = ene.value_in_unit(kilocalories_per_mole)
        # Make sure the energy is relatively close to the value we get with
        # Amber using this force field.
        self.assertAlmostEqual(-7099.44989739/ene, 1, places=3)
208
209
210

    def test_NBFIX_noLongRange(self):
        """Test prmtop files with NBFIX LJ modifications w/out long-range correction"""
211
212
213
214
215
216
217
218
219
220
221
222
        system = prmtop3.createSystem(nonbondedMethod=PME,
                                      nonbondedCutoff=8*angstroms)
        # Check the forces
        has_nonbond_force = has_custom_nonbond_force = False
        nonbond_exceptions = custom_nonbond_exclusions = 0
        for force in system.getForces():
            if isinstance(force, NonbondedForce):
                has_nonbond_force = True
                nonbond_exceptions = force.getNumExceptions()
            elif isinstance(force, CustomNonbondedForce):
                has_custom_nonbond_force = True
                custom_nonbond_exceptions = force.getNumExclusions()
223
                force.setUseLongRangeCorrection(False)
224
225
226
227
        self.assertTrue(has_nonbond_force)
        self.assertTrue(has_custom_nonbond_force)
        self.assertEqual(nonbond_exceptions, custom_nonbond_exceptions)
        integrator = VerletIntegrator(1.0*femtoseconds)
228
229
        # Use reference platform, since it should always be present and
        # 'working', and the system is plenty small so this won't be too slow
Peter Eastman's avatar
Peter Eastman committed
230
        sim = Simulation(prmtop3.topology, system, integrator, Platform.getPlatform('Reference'))
231
        # Check that the energy is about what we expect it to be
232
        sim.context.setPositions(inpcrd3.getPositions())
233
234
235
236
237
238
        ene = sim.context.getState(getEnergy=True, enforcePeriodicBox=True).getPotentialEnergy()
        ene = ene.value_in_unit(kilocalories_per_mole)
        # Make sure the energy is relatively close to the value we get with
        # Amber using this force field.
        self.assertAlmostEqual(-7042.3903307/ene, 1, places=3)

239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
    def test_HAngle(self):
        """ Test that HAngle constraints are properly handled for all hydrogens """
        system = prmtop6.createSystem(nonbondedMethod=PME,
                                      nonbondedCutoff=1*nanometers,
                                      constraints=HBonds)
        self.assertEqual(system.getForce(0).getNumBonds(), 0)
        self.assertEqual(system.getNumParticles(), 3000)
        self.assertEqual(system.getNumConstraints(), 2000)
        self.assertEqual(system.getForce(1).getNumAngles(), 1000)

        system = prmtop6.createSystem(nonbondedMethod=PME,
                                      nonbondedCutoff=1*nanometers,
                                      constraints=HAngles)
        self.assertEqual(system.getForce(0).getNumBonds(), 0)
        self.assertEqual(system.getNumParticles(), 3000)
        self.assertEqual(system.getNumConstraints(), 3000)
        self.assertEqual(system.getForce(1).getNumAngles(), 0)

257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
    def test_LJ1264(self):
        """Test prmtop with 12-6-4 vdW potential implemented"""
        system = prmtop4.createSystem(nonbondedMethod=PME,
                                      nonbondedCutoff=8*angstroms)
        # Check the forces
        has_nonbond_force = has_custom_nonbond_force = False
        nonbond_exceptions = custom_nonbond_exclusions = 0
        for force in system.getForces():
            if isinstance(force, NonbondedForce):
                has_nonbond_force = True
                nonbond_exceptions = force.getNumExceptions()
                force.setUseDispersionCorrection(False)
            elif isinstance(force, CustomNonbondedForce):
                self.assertTrue(force.getUseLongRangeCorrection())
                has_custom_nonbond_force = True
                custom_nonbond_exceptions = force.getNumExclusions()
                force.setUseLongRangeCorrection(False)
        self.assertTrue(has_nonbond_force)
        self.assertTrue(has_custom_nonbond_force)
        self.assertEqual(nonbond_exceptions, custom_nonbond_exceptions)
277
278
279
280
281
282
283
284
        # Make sure the periodic box vectors match the ones in the inpcrd file, which are different from
        # the ones in the prmtop file.
        systemBox = system.getDefaultPeriodicBoxVectors()
        topologyBox = prmtop4.topology.getPeriodicBoxVectors()
        for i in range(3):
            for j in range(3):
                self.assertEqual(inpcrd4.boxVectors[i][j], systemBox[i][j])
                self.assertEqual(inpcrd4.boxVectors[i][j], topologyBox[i][j])
285
286
287
        integrator = VerletIntegrator(1.0*femtoseconds)
        # Use reference platform, since it should always be present and
        # 'working', and the system is plenty small so this won't be too slow
Peter Eastman's avatar
Peter Eastman committed
288
        sim = Simulation(prmtop4.topology, system, integrator, Platform.getPlatform('Reference'))
289
290
291
292
293
294
295
        # Check that the energy is about what we expect it to be
        sim.context.setPositions(inpcrd4.positions)
        ene = sim.context.getState(getEnergy=True, enforcePeriodicBox=True).getPotentialEnergy()
        ene = ene.value_in_unit(kilocalories_per_mole)
        # Make sure the energy is relatively close to the value we get with
        # Amber using this force field.
        self.assertAlmostEqual(-7307.2735621/ene, 1, places=3)
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321

    def test_triclinicParm(self):
        """ Check that triclinic unit cells work correctly """
        system = prmtop5.createSystem(nonbondedMethod=PME)
        refa = Vec3(4.48903851, 0.0, 0.0) * nanometer
        refb = Vec3(-1.4963460492639706, 4.232306137924705, 0.0) * nanometer
        refc = Vec3(-1.4963460492639706, -2.116152812842565, 3.6652847799064165) * nanometer
        a, b, c = system.getDefaultPeriodicBoxVectors()
        la = norm(a)
        lb = norm(b)
        lc = norm(c)
        diffa = a - refa
        diffb = b - refb
        diffc = c - refc
        self.assertAlmostEqual(norm(diffa)/nanometers, 0)
        self.assertAlmostEqual(norm(diffb)/nanometers, 0)
        self.assertAlmostEqual(norm(diffc)/nanometers, 0)
        self.assertAlmostEqual(dot(a, b)/la/lb, cos(109.4712190*degrees))
        self.assertAlmostEqual(dot(a, c)/la/lc, cos(109.4712190*degrees))
        self.assertAlmostEqual(dot(c, b)/lc/lb, cos(109.4712190*degrees))
        self.assertAlmostEqual(la/nanometers, 4.48903851)
        self.assertAlmostEqual(lb/nanometers, 4.48903851)
        self.assertAlmostEqual(lc/nanometers, 4.48903851)
        # Now make sure that the context builds correctly; then we can bail
        self.assertTrue(Context(system, VerletIntegrator(1*femtoseconds)))

322
323
    def test_ImplicitSolventForces(self):
        """Compute forces for different implicit solvent types, and compare them to ones generated with a previous version of OpenMM to ensure they haven't changed."""
324

325
326
327
328
329
330
331
332
        solventType = [HCT, OBC1, OBC2, GBn, GBn2]
        nonbondedMethod = [NoCutoff, CutoffNonPeriodic, CutoffNonPeriodic, NoCutoff, NoCutoff]
        salt = [0.0, 0.0, 0.5, 0.5, 0.0]*(moles/liter)
        file = ['HCT_NoCutoff', 'OBC1_NonPeriodic', 'OBC2_NonPeriodic_Salt', 'GBn_NoCutoff_Salt', 'GBn2_NoCutoff']
        pdb = PDBFile('systems/alanine-dipeptide-implicit.pdb')
        for i in range(5):
            system = prmtop2.createSystem(implicitSolvent=solventType[i], nonbondedMethod=nonbondedMethod[i], implicitSolventSaltConc=salt[i])
            integrator = VerletIntegrator(0.001)
Peter Eastman's avatar
Peter Eastman committed
333
            context = Context(system, integrator, Platform.getPlatform("Reference"))
334
335
            context.setPositions(pdb.positions)
            state1 = context.getState(getForces=True)
336
337
            with open('systems/alanine-dipeptide-implicit-forces/'+file[i]+'.xml') as infile:
                state2 = XmlSerializer.deserialize(infile.read())
338
339
340
            for f1, f2, in zip(state1.getForces().value_in_unit(kilojoules_per_mole/nanometer), state2.getForces().value_in_unit(kilojoules_per_mole/nanometer)):
                diff = norm(f1-f2)
                self.assertTrue(diff < 0.1 or diff/norm(f1) < 1e-4)
341

Evan Pretti's avatar
Evan Pretti committed
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
    def test_LCPO(self):
        """Compute LCPO energy and compare it to a reference value from Amber."""

        prmtopLCPO = AmberPrmtopFile('systems/lcpo_test.prmtop')
        pdb = PDBFile('systems/lcpo_test.pdb')
        systemNone = prmtopLCPO.createSystem(implicitSolvent=GBn2, sasaMethod=None)
        systemLCPO = prmtopLCPO.createSystem(implicitSolvent=GBn2, sasaMethod='LCPO')
        contextNone = Context(systemNone, VerletIntegrator(0.001), Platform.getPlatformByName("Reference"))
        contextLCPO = Context(systemLCPO, VerletIntegrator(0.001), Platform.getPlatformByName("Reference"))
        contextNone.setPositions(pdb.positions)
        contextLCPO.setPositions(pdb.positions)
        energyRef = 14.1908 * kilocalorie_per_mole
        energyLCPO = contextLCPO.getState(energy=True).getPotentialEnergy() - contextNone.getState(energy=True).getPotentialEnergy()
        self.assertAlmostEqual(energyLCPO.value_in_unit(kilocalorie_per_mole), energyRef.value_in_unit(kilocalorie_per_mole), 4)

    def test_LCPOInvalid(self):
        """Check that LCPO parameter assignment fails instead of assigning incorrect parameters for unsupported atom types."""

        prmtop = AmberPrmtopFile('systems/lcpo_invalid.prmtop')
        with self.assertRaisesRegex(ValueError, 'atomic number 8.+2 bonds.+0 bonds excluding H'):
            prmtop.createSystem(implicitSolvent=GBn2, sasaMethod='LCPO')

364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
    def testSwitchFunction(self):
        """ Tests the switching function option in AmberPrmtopFile """
        system = prmtop1.createSystem(nonbondedMethod=PME,
                                      nonbondedCutoff=1*nanometer,
                                      switchDistance=0.8*nanometer)
        for force in system.getForces():
            if isinstance(force, NonbondedForce):
                self.assertTrue(force.getUseSwitchingFunction())
                self.assertEqual(force.getSwitchingDistance(), 0.8*nanometer)
                break
        else:
            assert False, 'Did not find expected nonbonded force!'

        # Check error handling
        system = prmtop1.createSystem(nonbondedMethod=PME,
                                      nonbondedCutoff=1*nanometer)
        for force in system.getForces():
            if isinstance(force, NonbondedForce):
                self.assertFalse(force.getUseSwitchingFunction())
                break
        else:
            assert False, 'Did not find expected nonbonded force!'

        self.assertRaises(ValueError, lambda:
                prmtop1.createSystem(nonbondedMethod=PME,
                    nonbondedCutoff=1*nanometer, switchDistance=-1)
        )
        self.assertRaises(ValueError, lambda:
                prmtop1.createSystem(nonbondedMethod=PME,
                    nonbondedCutoff=1*nanometer, switchDistance=1.2)
        )

kyleabeauchamp's avatar
kyleabeauchamp committed
396
397
398
399
400
401
402
403
404
405
406
    def test_with_dcd_reporter(self):
        """Check that an amber simulation like the docs example works with a DCD reporter."""

        temperature = 50*kelvin

        prmtop = prmtop4  # Mg + water
        inpcrd = inpcrd4  # Mg + water
        system = prmtop.createSystem(nonbondedMethod=PME, nonbondedCutoff=1*nanometer, constraints=HBonds)
        system.addForce(MonteCarloBarostat(1.0 * atmospheres, temperature, 1))

        integrator = LangevinIntegrator(temperature, 1.0 / picosecond, 0.0001 * picoseconds)
407

kyleabeauchamp's avatar
kyleabeauchamp committed
408
409
410
        simulation = Simulation(prmtop.topology, system, integrator)
        simulation.context.setPositions(inpcrd.positions)

411
412
        fname = tempfile.mktemp(suffix='.dcd')
        simulation.reporters.append(DCDReporter(fname, 1))  # This is an explicit test for the bugs in issue #850
kyleabeauchamp's avatar
kyleabeauchamp committed
413
        simulation.step(5)
414
        del simulation
415
        os.remove(fname)
416
417

    def testChamber(self):
418
419
420
421
422
423
424
        """Test a prmtop file created with Chamber."""
        prmtop = AmberPrmtopFile('systems/ala3_solv.parm7')
        crd = CharmmCrdFile('systems/ala3_solv.crd')
        system = prmtop.createSystem()
        for i,f in enumerate(system.getForces()):
            f.setForceGroup(i)
        integrator = VerletIntegrator(0.001)
Peter Eastman's avatar
Peter Eastman committed
425
        context = Context(system, integrator, Platform.getPlatform('Reference'))
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
        context.setPositions(crd.positions)
        
        # Compare to energies computed with pytraj.energy_decomposition()
        
        energy = context.getState(getEnergy=True).getPotentialEnergy().value_in_unit(kilocalories_per_mole)
        self.assertAlmostEqual(energy, -7806.981602, delta=5e-4*abs(energy))
        components = {}
        for i,f in enumerate(system.getForces()):
            components[f.getName()] = context.getState(getEnergy=True, groups={i}).getPotentialEnergy().value_in_unit(kilocalories_per_mole)
        self.assertAlmostEqual(components['HarmonicBondForce'], 1.13242125)
        self.assertAlmostEqual(components['HarmonicAngleForce'], 1.06880188)
        self.assertAlmostEqual(components['UreyBradleyForce'], 0.06142407)
        self.assertAlmostEqual(components['PeriodicTorsionForce'], 7.81143025)
        self.assertAlmostEqual(components['ImproperTorsionForce'], 2.66453526e-14, delta=1e-6)
        self.assertAlmostEqual(components['CMAPTorsionForce'], 0.12679003)
        self.assertAlmostEqual(components['CustomNonbondedForce'], 909.28136359)
        self.assertAlmostEqual(components['NonbondedForce'], -9007.16903192+277.35152722+3.35367163, delta=5e-4*abs(components['NonbondedForce']))
kyleabeauchamp's avatar
kyleabeauchamp committed
443

444
445
    def testGBneckRadii(self):
        """ Tests that GBneck radii limits are correctly enforced """
446
        from openmm.app.internal.customgbforces import GBSAGBnForce
447
448
449
450
451
452
        f = GBSAGBnForce()
        # Make sure legal parameters do not raise
        f.addParticle([0, 0.1, 0.5])
        f.addParticle([0, 0.2, 0.5])
        f.addParticle([0, 0.15, 0.5])
        # Now make sure that out-of-range parameters *do* raise
Jason Swails's avatar
Jason Swails committed
453
454
        self.assertRaises(ValueError, lambda: f.addParticle([0, 0.9, 0.5]))
        self.assertRaises(ValueError, lambda: f.addParticle([0, 0.21, 0.5]))
Jeff Wagner's avatar
Jeff Wagner committed
455

456
457
458
459
460
461
    def testNucleicGBParametes(self):
        """Test that correct GB parameters are used for nucleic acids."""
        prmtop = AmberPrmtopFile('systems/DNA_mbondi3.prmtop')
        inpcrd = AmberInpcrdFile('systems/DNA_mbondi3.inpcrd')
        sanderEnergy = [-19223.87993545, -19527.40433175, -19788.1070698]
        for solvent, expectedEnergy in zip([OBC2, GBn, GBn2], sanderEnergy):
Evan Pretti's avatar
Evan Pretti committed
462
            system = prmtop.createSystem(implicitSolvent=solvent, sasaMethod=None)
463
464
465
466
            for f in system.getForces():
                if isinstance(f, CustomGBForce) or isinstance(f, GBSAOBCForce):
                    f.setForceGroup(1)
            integrator = VerletIntegrator(0.001)
Peter Eastman's avatar
Peter Eastman committed
467
            context = Context(system, integrator, Platform.getPlatform('Reference'))
468
469
470
471
            context.setPositions(inpcrd.positions)
            energy = context.getState(getEnergy=True, groups={1}).getPotentialEnergy().value_in_unit(kilojoules_per_mole)
            self.assertAlmostEqual(energy, expectedEnergy, delta=5e-4*abs(energy))

kyw220's avatar
kyw220 committed
472
    def testAmberCMAP(self):
473
        """Check that CMAP energy calculation compared to AMber."""
kyw220's avatar
kyw220 committed
474
475
        temperature = 50*kelvin
        conversion = 4.184 # 4.184 kJ/mol
476
        sander_CMAP_E = 8.2864 # CMAP energy calculated by Amber, unit kcal/mol
kyw220's avatar
kyw220 committed
477
478
479
480
481
482
483
484
485

        prmtop = prmtop7  # systems/18protein.parm7
        inpcrd = inpcrd7  # systems/18protein.rst7

        system = prmtop.createSystem(nonbondedMethod=PME, nonbondedCutoff=1.2)
        integrator = LangevinIntegrator(temperature, 1.0 / picosecond, 0.002 * picoseconds)

        simulation = Simulation(prmtop.topology, system, integrator)
        simulation.context.setPositions(inpcrd.positions)
486

kyw220's avatar
kyw220 committed
487
488
489
490
491
492
493
494
495
496
497
        for i, force in enumerate(system.getForces()):
            force.setForceGroup(i)
            
        simulation.context.reinitialize(True)

        for i in range(system.getNumForces()):
            if i == 3: # 3 indicates CMAP force
#                print(simulation.context.getState(getEnergy=True, groups=1<<i).getPotentialEnergy().value_in_unit(kilojoules_per_mole))
                OpenMM_CMAP_E = simulation.context.getState(getEnergy=True, groups=1<<i).getPotentialEnergy().value_in_unit(kilojoules_per_mole)/conversion
                self.assertAlmostEqual(OpenMM_CMAP_E, sander_CMAP_E, places=4)

498
499
500
501
502
503
504
    def testEPConstraints(self):
        """Test different types of constraints when using extra particles"""
        prmtop = AmberPrmtopFile('systems/peptide_with_tip4p.prmtop')
        for constraints in (HBonds, AllBonds):
            system = prmtop.createSystem(constraints=constraints)
            integrator = VerletIntegrator(0.001*picoseconds)
            # If a constraint was added to a massless particle, this will throw an exception.
Peter Eastman's avatar
Peter Eastman committed
505
            context = Context(system, integrator, Platform.getPlatform('Reference'))
506

507
508
509
510
511
512
513
514
515
516
517
    def testWaterBonds(self):
        """Test that water molecules have the right set of bonds"""
        top = prmtop1.topology
        for residue in top.residues():
            if residue.name == 'HOH':
                bonds = list(residue.bonds())
                self.assertEqual(2, len(bonds))
                for a1, a2 in bonds:
                    self.assertTrue(a1.element == elem.oxygen or a2.element == elem.oxygen)
                    self.assertTrue(a1.element == elem.hydrogen or a2.element == elem.hydrogen)

518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
    def testFlexibleConstraints(self):
        """Test the flexibleConstraints option"""
        energies = {}
        forces = {}
        for flexibleConstraints in [False, True]:
            system = prmtop1.createSystem(nonbondedMethod=PME, constraints=HAngles, flexibleConstraints=flexibleConstraints)
            for i, f in enumerate(system.getForces()):
                f.setForceGroup(i)
            integrator = VerletIntegrator(1.0*femtoseconds)
            sim = Simulation(prmtop1.topology, system, integrator, Platform.getPlatform('Reference'))
            sim.context.setPositions(inpcrd1.positions)
            energies[flexibleConstraints] = {}
            for i, f in enumerate(system.getForces()):
                forces[i] = f
                energies[flexibleConstraints][i] = sim.context.getState(getEnergy=True, groups={i}).getPotentialEnergy().value_in_unit(kilojoules_per_mole)
        for i, f in forces.items():
            delta = 1e-5*abs(energies[True][i])
            if isinstance(f, HarmonicBondForce) or isinstance(f, HarmonicAngleForce):
                self.assertNotAlmostEqual(energies[True][i], energies[False][i], delta=delta)
            else:
                self.assertAlmostEqual(energies[True][i], energies[False][i], delta=delta)

540
541
if __name__ == '__main__':
    unittest.main()