Esempio n. 1
0
 def __init__(self):
     parmname = get_fn('4LYT.solv10.parm7')
     rst7name = get_fn('4LYT.solv10.equil.rst7')
     self.parm = AmberParm(parmname, rst7name)
     self.system = self.parm.createSystem(nonbondedCutoff=8.0*u.angstrom,
                                          nonbondedMethod=app.PME)
     # Also load objects using the app layer
     self.parmapp = app.AmberPrmtopFile(parmname)
     self.crdapp = crd = app.AmberInpcrdFile(rst7name, loadVelocities=True,
                                             loadBoxVectors=True)
     self.systemapp = self.parmapp.createSystem(
                             nonbondedCutoff=8.0*u.angstroms,
                             nonbondedMethod=app.PME
     )
     self.systemapp.setDefaultPeriodicBoxVectors(*crd.getBoxVectors())
Esempio n. 2
0
import sys

# OpenMM Imports
import simtk.unit as u
import simtk.openmm as mm
import simtk.openmm.app as app

# ParmEd Imports
from chemistry.amber.openmmloader import OpenMMAmberParm as AmberParm
from chemistry.amber.openmmreporters import (
            AmberStateDataReporter, NetCDFReporter)

# Load the CHARMM files
print('Loading Amber files...')
ala5_gas = AmberParm('ala5_gas.parm7', 'ala5_gas.rst7')

# Create the OpenMM system
print('Creating OpenMM System')
system = ala5_gas.createSystem(nonbondedMethod=app.NoCutoff,
                               constraints=app.HBonds, implicitSolvent=app.GBn2,
                               implicitSolventSaltConc=0.1*u.moles/u.liter,
)

# Create the integrator to do Langevin dynamics
integrator = mm.LangevinIntegrator(
                        300*u.kelvin,       # Temperature of heat bath
                        1.0/u.picoseconds,  # Friction coefficient
                        2.0*u.femtoseconds, # Time step
)
Esempio n. 3
0
import sys

# OpenMM Imports
import simtk.unit as u
import simtk.openmm as mm
import simtk.openmm.app as app

# ParmEd Imports
from chemistry.amber.openmmloader import OpenMMAmberParm as AmberParm
from chemistry.charmm.parameters import CharmmParameterSet
from chemistry.amber.openmmreporters import (AmberStateDataReporter,
                                             NetCDFReporter)

# Load the CHARMM files
print('Loading AMBER files...')
ala2_solv = AmberParm('ala2_solv.parm7', 'ala2_solv.rst7')

# Create the OpenMM system
print('Creating OpenMM System')
system = ala2_solv.createSystem(nonbondedMethod=app.PME,
                                nonbondedCutoff=8.0*u.angstroms,
                                constraints=app.HBonds,
)

# Create the integrator to do Langevin dynamics
integrator = mm.LangevinIntegrator(
                        300*u.kelvin,       # Temperature of heat bath
                        1.0/u.picoseconds,  # Friction coefficient
                        2.0*u.femtoseconds, # Time step
)
Esempio n. 4
0
class TestPME(object):
    """
    Tests the PME implementation on HEWL, a large-ish protein solvated in water
    """
    def __init__(self):
        parmname = get_fn('4LYT.solv10.parm7')
        rst7name = get_fn('4LYT.solv10.equil.rst7')
        self.parm = AmberParm(parmname, rst7name)
        self.system = self.parm.createSystem(nonbondedCutoff=8.0*u.angstrom,
                                             nonbondedMethod=app.PME)
        # Also load objects using the app layer
        self.parmapp = app.AmberPrmtopFile(parmname)
        self.crdapp = crd = app.AmberInpcrdFile(rst7name, loadVelocities=True,
                                                loadBoxVectors=True)
        self.systemapp = self.parmapp.createSystem(
                                nonbondedCutoff=8.0*u.angstroms,
                                nonbondedMethod=app.PME
        )
        self.systemapp.setDefaultPeriodicBoxVectors(*crd.getBoxVectors())
    
    def run(self, platform, precision=None, devices=None,
            use_dispersion_correction=True):
        """
        Runs the test on the given platform with the given precision model.

        Parameters
        ----------
        platform : str
            Name of the OpenMM platform to use (CPU, Reference, CUDA, or OpenCL)

        precision : str
            Precision model to use for CUDA or OpenCL (single, double, or mixed)

        devices : int or tuple of ints
            Which GPUs to run on (a tuple will run in parallel)
        """
        if not platform in ('CPU', 'Reference', 'CUDA', 'OpenCL'):
            raise ValueError('Platform %s not recognized.' % platform)
        # Define our platform and our platform properties
        plat = mm.Platform.getPlatformByName(platform)
        properties = None
        if platform == 'CUDA':
            if not precision in ('mixed', 'double', 'single'):
                raise ValueError('You must set the precision to single, '
                                 'double, or mixed for the CUDA platform.')
            properties = dict(CudaPrecision=precision)
            if devices is not None:
                properties['CudaDeviceIndex'] = str(devices)
        elif platform == 'OpenCL':
            if not precision in ('mixed', 'double', 'single'):
                raise ValueError('You must set the precision to single, '
                                 'double, or mixed for the CUDA platform.')
            properties = dict(OpenCLPrecision=precision)
            if devices is not None:
                properties['OpenCLDeviceIndex'] = str(devices)

        # Create a new system with no charges so we can compare vdW and EEL
        # energies to Amber
        parmcopy = copy(self.parm)
        for i in range(len(parmcopy.parm_data['CHARGE'])):
            parmcopy.parm_data['CHARGE'][i] = 0.0
        system = parmcopy.createSystem(nonbondedCutoff=8.0*u.angstroms,
                                       nonbondedMethod=app.PME)
        system.setDefaultPeriodicBoxVectors(*self.parm.box_vectors)

        # Test serialization
        xmlsys = mm.XmlSerializer.deserialize(
                        mm.XmlSerializer.serialize(self.system)
        )

        # Loop through all systems and turn on or off the dispersion correction
        print 'Trying to set PME parameters...',
        succeeded = None
        for sysmod in (self.system, self.systemapp, system, xmlsys):
            for force in sysmod.getForces():
                if isinstance(force, mm.NonbondedForce):
                    force.setUseDispersionCorrection(use_dispersion_correction)
                    # See if we can set the PME parameters
                    try:
                        force.setPMEParameters(3.285326106/u.nanometers,
                                               60, 64, 60)
                        succeeded = True
                    except AttributeError:
                        # This version of OpenMM does not support setting PME
                        # parameters
                        succeeded = False
        if succeeded:
            print 'Changed.'
        elif succeeded is None:
            print 'No NonbondedForce detected.'
        else:
            print 'OpenMM is too old. Could not change PME parameters.'
        # Define some integrators
        dummyint1 = mm.VerletIntegrator(1.0e-6*u.picoseconds)
        dummyint2 = mm.VerletIntegrator(1.0e-6*u.picoseconds)
        dummyint3 = mm.VerletIntegrator(1.0e-6*u.picoseconds)
        dummyint4 = mm.VerletIntegrator(1.0e-6*u.picoseconds)
        # Define the contexts
        if properties is None:
            context1 = mm.Context(self.system, dummyint1, plat)
            context2 = mm.Context(system, dummyint2, plat)
            context3 = mm.Context(self.systemapp, dummyint3, plat)
            context4 = mm.Context(xmlsys, dummyint4, plat)
        else:
            context1 = mm.Context(self.system, dummyint1, plat, properties)
            context2 = mm.Context(system, dummyint2, plat, properties)
            context3 = mm.Context(self.systemapp, dummyint3, plat,
                                  properties)
            context4 = mm.Context(xmlsys, dummyint4, plat, properties)
        # Set the context positions
        context1.setPositions(self.parm.positions)
        context2.setPositions(self.parm.positions)
        context3.setPositions(self.crdapp.getPositions())
        context4.setPositions(self.parm.positions)
        # Get the energies
        eunit = u.kilocalories_per_mole
        state = context1.getState(getEnergy=True, getForces=True,
                                  enforcePeriodicBox=True)
        funit = eunit / u.angstrom
        forces = state.getForces().value_in_unit(funit)
        tote = state.getPotentialEnergy().value_in_unit(eunit)
        state = context3.getState(getEnergy=True, enforcePeriodicBox=True)
        toteapp = state.getPotentialEnergy().value_in_unit(eunit)
        state = context4.getState(getEnergy=True, enforcePeriodicBox=True)
        xmltote = state.getPotentialEnergy().value_in_unit(eunit)
        # Now get the decomposed energies from both the system and the
        # deserialized system to check that serialization and deserialization
        # behave as expected with these force objects and force groups
        state = context1.getState(getEnergy=True, enforcePeriodicBox=True,
                                  groups=2**self.parm.BOND_FORCE_GROUP)
        bonde = state.getPotentialEnergy().value_in_unit(eunit)
        state = context4.getState(getEnergy=True, enforcePeriodicBox=True,
                                  groups=2**self.parm.BOND_FORCE_GROUP)
        xmlbonde = state.getPotentialEnergy().value_in_unit(eunit)

        state = context1.getState(getEnergy=True, enforcePeriodicBox=True,
                                  groups=2**self.parm.ANGLE_FORCE_GROUP)
        anglee = state.getPotentialEnergy().value_in_unit(eunit)
        state = context4.getState(getEnergy=True, enforcePeriodicBox=True,
                                  groups=2**self.parm.ANGLE_FORCE_GROUP)
        xmlanglee = state.getPotentialEnergy().value_in_unit(eunit)

        state = context1.getState(getEnergy=True, enforcePeriodicBox=True,
                                  groups=2**self.parm.DIHEDRAL_FORCE_GROUP)
        dihede = state.getPotentialEnergy().value_in_unit(eunit)
        state = context4.getState(getEnergy=True, enforcePeriodicBox=True,
                                  groups=2**self.parm.DIHEDRAL_FORCE_GROUP)
        xmldihede = state.getPotentialEnergy().value_in_unit(eunit)

        state = context1.getState(getEnergy=True, enforcePeriodicBox=True,
                                  groups=2**self.parm.NONBONDED_FORCE_GROUP)
        nonbe = state.getPotentialEnergy().value_in_unit(eunit)
        state = context4.getState(getEnergy=True, enforcePeriodicBox=True,
                                  groups=2**self.parm.NONBONDED_FORCE_GROUP)
        xmlnonbe = state.getPotentialEnergy().value_in_unit(eunit)

        state = context2.getState(getEnergy=True, enforcePeriodicBox=True,
                                  groups=2**self.parm.NONBONDED_FORCE_GROUP)
        vdwe = state.getPotentialEnergy().value_in_unit(eunit)

        eele = nonbe - vdwe
        # Now get the sander forces and compare them
        traj = netcdf_file(get_fn('sander_pme.nc'), 'r')
        sander_forces = traj.variables['forces'][0]
        maxdif = [abs(ofrc-sfrc)
                  for ofrc, sfrc in zip(forces[0], sander_forces[0])]
        maxrel = [abs(ofrc-sfrc)/sfrc
                  for ofrc, sfrc in zip(forces[0], sander_forces[0])]
        avgdif = [0, 0, 0]
        avgrel = [0, 0, 0]
        n = 0
        for ofrcs, sfrcs in zip(forces, sander_forces):
            for i, sfrc in enumerate(sfrcs):
                ofrc = ofrcs[i]
                dif = abs(ofrc-sfrc)
                rel = dif/sfrc
                maxdif[i] = max(maxdif[i], dif)
                maxrel[i] = max(maxrel[i], rel)
                avgdif[i] += dif
                avgrel[i] += rel
            n += 1
        avgdif = [x/n for x in avgdif]
        avgrel = [x/n for x in avgrel]
        # The sander energies are:
# Etot   =    -69285.4160  EKtot   =         0.0000  EPtot      =    -69285.4160
# BOND   =       404.9439  ANGLE   =      1003.4499  DIHED      =      2231.7367
# 1-4 NB =       440.7084  1-4 EEL =      3818.2959  VDWAALS    =      8271.5191
# EELEC  =    -85456.0701  EHBOND  =         0.0000  RESTRAINT  =         0.0000
        sander = dict(bond=404.9439, angle=1003.4499, dihedral=2231.7367,
                      vdw=8271.5191+440.7084, eel=-85456.0701+3818.2959,
                      total=-69285.4160)
        if not use_dispersion_correction:
            # Without the long-range dispersion correction, VDWAALS = 8943.8420
            sander['total'] -= sander['vdw']
            sander['vdw'] = 8943.8420 + 440.7084
            sander['total'] += sander['vdw']
        bonddif = bonde - sander['bond']
        angledif = anglee - sander['angle']
        diheddif = dihede - sander['dihedral']
        vdwdif = vdwe - sander['vdw'] # includes 1-4 also
        eeldif = eele - sander['eel'] # Includes 1-4 also
        totaldif = tote - sander['total']
        appdif = tote - toteapp
        print 'Energy differences compared to sander/Amber (kcal/mol)'
        print '             Absolute     Relative    sander'
        print '------------------------------------------------------'
        print 'Bond     =', colorize_error(bonddif), \
              colorize_error(bonddif/sander['bond'], 1e-6), \
              '%12.4f'%sander['bond']
        print 'Angle    =', colorize_error(angledif), \
              colorize_error(angledif/sander['angle'], 1e-6), \
              '%12.4f'%sander['angle']
        print 'Dihedral =', colorize_error(diheddif), \
              colorize_error(diheddif/sander['dihedral'], 1e-6), \
              '%12.4f'%sander['dihedral']
        if use_dispersion_correction:
            # The dispersion correction in Amber neglects the repulsive part of
            # the correction, but OpenMM does not. Therefore, when we are using
            # the dispersion correction we should allow for a slightly larger
            # energy difference.
            print 'vdWaals  =', colorize_error(vdwdif, 1.0), \
                   colorize_error(vdwdif/sander['vdw'], 1e-4), \
                   '%12.4f'%sander['vdw']
        else:
            print 'vdWaals  =', colorize_error(vdwdif, 1e-2), \
                   colorize_error(vdwdif/sander['vdw'], 1e-6), \
                   '%12.4f'%sander['vdw']
        print 'Elec     =', colorize_error(eeldif, 4e0), \
               colorize_error(eeldif/sander['eel'], 1e-3), '%12.4f'%sander['eel']
        print 'Total    =', colorize_error(totaldif, 4e0), \
               colorize_error(totaldif/sander['total'], 1e-3), \
               '%12.4f'%sander['total']
        print ''
        print 'Difference b/w ParmEd and OpenMM App layer'
        print '------------------------------------------'
        print 'Total    =', colorize_error(appdif, tolerance=5e-3)
        print ''
        print 'Difference b/w sander and OpenMM forces'
        print '---------------------------------------'
        print 'Maximum deviation = [%12s, %12s, %12s]' % colorize_list(maxdif,2e0)
        print 'Maximum rel. dev. = [%12s, %12s, %12s]' % colorize_list(maxrel,2e0)
        print 'Average deviation = [%12s, %12s, %12s]' % colorize_list(avgdif,1e-1)
        print 'Average rel. dev. = [%12s, %12s, %12s]' % colorize_list(avgrel,5e-1)

        # Now test serialization
        CUTOFF = 1e-5
        CUTOFFNB = 1e-2
        print ''
        print 'Serialization tests'
        print '-------------------'
        print 'Bond........',
        if abs(xmlbonde - bonde) < CUTOFF:
            print green('OK')
        else:
            dif = xmlbonde - bonde
            print red('off by %.4e (%f%%)' % (dif, 100*dif/(bonde or xmlbonde)))
        print 'Angle.......',
        if abs(xmlanglee - anglee) < CUTOFF:
            print green('OK')
        else:
            dif = xmlanglee - anglee
            print red('off by %.4e (%f%%)' % (dif,100*dif/(anglee or xmlanglee)))
        print 'Dihedral....',
        if abs(xmldihede - dihede) < CUTOFF:
            print green('OK')
        else:
            dif = xmldihede - dihede
            print red('off by %.4e (%f%%)' % (dif,100*dif/(dihede or xmldihede)))
        print 'Nonbonded...',
        if abs(xmlnonbe - nonbe) < CUTOFFNB:
            print green('OK')
        else:
            dif = xmlnonbe - nonbe
            print red('off by %.4e (%f%%)' % (dif,100*dif/(nonbe or xmlnonbe)))