def createSystem(self, nonbondedMethod=ff.NoCutoff, nonbondedCutoff=1.0 * nanometer, ewaldErrorTolerance=0.0005, removeCMMotion=True, hydrogenMass=None, OPLS=False, implicitSolvent=None, AGBNPVersion=1): """Construct an OpenMM System representing the topology described by this DMS file Parameters ---------- nonbondedMethod : object=NoCutoff The method to use for nonbonded interactions. Allowed values are NoCutoff, CutoffNonPeriodic, CutoffPeriodic, Ewald, PME, or LJPME. nonbondedCutoff : distance=1*nanometer The cutoff distance to use for nonbonded interactions ewaldErrorTolerance : float=0.0005 The error tolerance to use if nonbondedMethod is Ewald, PME, or LJPME. removeCMMotion : boolean=True If true, a CMMotionRemover will be added to the System hydrogenMass : mass=None The mass to use for hydrogen atoms bound to heavy atoms. Any mass added to a hydrogen is subtracted from the heavy atom to keep their total mass the same. OPLS : boolean=False If True, forces OPLS combining rules implicitSolvent: string=None If not None, creates implicit solvent force of the given name Allowed values are: HCT and 'AGBNP' (the corresponding tables must be present in the DMS file) AGBNPVersion: int=1 AGBNP implicit solvent version """ self._checkForUnsupportedTerms() sys = mm.System() # Build the box dimensions boxSize = self.topology.getUnitCellDimensions() if boxSize is not None: sys.setDefaultPeriodicBoxVectors( (boxSize[0], 0, 0), (0, boxSize[1], 0), (0, 0, boxSize[2])) elif nonbondedMethod in (ff.CutoffPeriodic, ff.Ewald, ff.PME, ff.LJPME): raise ValueError( 'Illegal nonbonded method for a non-periodic system') # Create all of the particles for (fcounter, conn, tables, offset) in self._localVars(): for mass in conn.execute('SELECT mass FROM particle ORDER BY id'): sys.addParticle(mass[0] * dalton) # Add all of the forces self._addBondsToSystem(sys) self._addAnglesToSystem(sys) self._addConstraintsToSystem(sys) self._addPeriodicTorsionsToSystem(sys, OPLS) self._addImproperHarmonicTorsionsToSystem(sys) self._addCMAPToSystem(sys) self._addVirtualSitesToSystem(sys) self._addPositionalHarmonicRestraints(sys) nb, cnb = self._addNonbondedForceToSystem(sys, OPLS) # Finish configuring the NonbondedForce. methodMap = { ff.NoCutoff: mm.NonbondedForce.NoCutoff, ff.CutoffNonPeriodic: mm.NonbondedForce.CutoffNonPeriodic, ff.CutoffPeriodic: mm.NonbondedForce.CutoffPeriodic, ff.Ewald: mm.NonbondedForce.Ewald, ff.PME: mm.NonbondedForce.PME, ff.LJPME: mm.NonbondedForce.LJPME } nb.setNonbondedMethod(methodMap[nonbondedMethod]) nb.setCutoffDistance(nonbondedCutoff) nb.setEwaldErrorTolerance(ewaldErrorTolerance) if cnb is not None: nb.setUseDispersionCorrection(False) if nonbondedMethod in (ff.CutoffPeriodic, ff.Ewald, ff.PME, ff.LJPME): cnb.setNonbondedMethod(methodMap[ff.CutoffPeriodic]) cnb.setCutoffDistance(nonbondedCutoff) elif nonbondedMethod == ff.CutoffNonPeriodic: cnb.setNonbondedMethod(methodMap[ff.CutoffNonPeriodic]) cnb.setCutoffDistance(nonbondedCutoff) else: cnb.setNonbondedMethod(methodMap[ff.NoCutoff]) cnb.setUseSwitchingFunction(False) cnb.setUseLongRangeCorrection(False) #add implicit solvent model. if implicitSolvent is not None: if not (implicitSolvent in (HCT, 'AGBNP', 'GVolSA', 'AGBNP3')): raise ValueError('Illegal implicit solvent method') if self._verbose: print('Adding implicit solvent ...') #with implicit solvent turn off native reaction field #However note that this does not affect the shifted Coulomb potential of the Nonbonded force #(it affects the only the energy, not the forces and equation of motion) nb.setReactionFieldDielectric(1.0) if implicitSolvent is HCT: gb_parms = self._get_gb_params() if gb_parms: if self._verbose: print('Adding HCT GB force ...') gb = GBSAHCTForce(SA='ACE') for i in range(len(gb_parms)): gb.addParticle(list(gb_parms[i])) gb.finalize() sys.addForce(gb) else: raise IOError("No HCT parameters found in DMS file") if implicitSolvent is 'AGBNP3': #load AGBNP3 plugin if available try: from AGBNP3plugin import AGBNP3Force except ImportError: raise NotImplementedError( 'AGBNP3 is not supported in this version') #sets up AGBNP3 gb_parms = self._get_agbnp2_params() if gb_parms: if self._verbose: print('Adding AGBNP3 force ...') gb = AGBNP3Force() # add particles for i in range(len(gb_parms)): p = gb_parms[i] gb.addParticle(p[0], p[1], p[2], p[3], p[4], p[5], p[6]) # connection table (from bonds) self._add_agbnp2_ct(gb) sys.addForce(gb) else: raise IOError("No AGBNP parameters found in DMS file") if implicitSolvent is 'GVolSA': #implemented as AGBNP version 0 implicitSolvent = 'AGBNP' AGBNPVersion = 0 if self._verbose: print('Using GVolSA') if implicitSolvent is 'AGBNP': #load AGBNP plugin if available try: from AGBNPplugin import AGBNPForce except ImportError: raise NotImplementedError( 'AGBNP is not supported in this version') #sets up AGBNP gb_parms = self._get_agbnp2_params() if gb_parms: gb = AGBNPForce() gb.setNonbondedMethod(methodMap[nonbondedMethod]) gb.setCutoffDistance(nonbondedCutoff) gb.setVersion(AGBNPVersion) if self._verbose: print('Using AGBNP force version %d ...' % AGBNPVersion) # add particles for i in range(len(gb_parms)): [ radiusN, chargeN, gammaN, alphaN, hbtype, hbwN, ishydrogenN ] = gb_parms[i] h_flag = ishydrogenN > 0 gb.addParticle(radiusN, gammaN, alphaN, chargeN, h_flag) sys.addForce(gb) self.gb_parms = gb_parms self.agbnp = gb else: raise IOError("No AGBNP parameters found in DMS file") # Adjust masses. if hydrogenMass is not None: for atom1, atom2 in self.topology.bonds(): if atom1.element == hydrogen: (atom1, atom2) = (atom2, atom1) if atom2.element == hydrogen and atom1.element not in ( hydrogen, None): transferMass = hydrogenMass - sys.getParticleMass( atom2.index) sys.setParticleMass(atom2.index, hydrogenMass) sys.setParticleMass( atom1.index, sys.getParticleMass(atom1.index) - transferMass) # Add a CMMotionRemover. if removeCMMotion: sys.addForce(mm.CMMotionRemover()) return sys
def createSystem(self, nonbondedMethod=ff.NoCutoff, nonbondedCutoff=1.0*nanometer, ewaldErrorTolerance=0.0005, removeCMMotion=True, hydrogenMass=None, OPLS=False, implicitSolvent=None): """Construct an OpenMM System representing the topology described by this dms file Parameters: - nonbondedMethod (object=NoCutoff) The method to use for nonbonded interactions. Allowed values are NoCutoff, CutoffNonPeriodic, CutoffPeriodic, Ewald, or PME. - nonbondedCutoff (distance=1*nanometer) The cutoff distance to use for nonbonded interactions - ewaldErrorTolerance (float=0.0005) The error tolerance to use if nonbondedMethod is Ewald or PME. - removeCMMotion (boolean=True) If true, a CMMotionRemover will be added to the System - hydrogenMass (mass=None) The mass to use for hydrogen atoms bound to heavy atoms. Any mass added to a hydrogen is subtracted from the heavy atom to keep their total mass the same. - OPLS (boolean=False) If True, force field parameters are interpreted as OPLS parameters; OPLS variants of torsional and non-bonded forces are constructed. - implicitSolvent (object=None) if not None, the implicit solvent model to use, the only allowed value is HCT """ self._checkForUnsupportedTerms() sys = mm.System() # Buld the box dimensions sys = mm.System() boxSize = self.topology.getUnitCellDimensions() if boxSize is not None: sys.setDefaultPeriodicBoxVectors((boxSize[0], 0, 0), (0, boxSize[1], 0), (0, 0, boxSize[2])) elif nonbondedMethod in (ff.CutoffPeriodic, ff.Ewald, ff.PME): raise ValueError('Illegal nonbonded method for a non-periodic system') # Create all of the particles for mass in self._conn.execute('SELECT mass FROM particle ORDER BY id'): sys.addParticle(mass[0]*dalton) # Add all of the forces self._addBondsToSystem(sys) self._addAnglesToSystem(sys) self._addConstraintsToSystem(sys) self._addPeriodicTorsionsToSystem(sys, OPLS) self._addImproperHarmonicTorsionsToSystem(sys) self._addCMAPToSystem(sys) self._addVirtualSitesToSystem(sys) nb, cnb = self._addNonbondedForceToSystem(sys, OPLS) # Finish configuring the NonbondedForce. methodMap = {ff.NoCutoff:mm.NonbondedForce.NoCutoff, ff.CutoffNonPeriodic:mm.NonbondedForce.CutoffNonPeriodic, ff.CutoffPeriodic:mm.NonbondedForce.CutoffPeriodic, ff.Ewald:mm.NonbondedForce.Ewald, ff.PME:mm.NonbondedForce.PME} nb.setNonbondedMethod(methodMap[nonbondedMethod]) nb.setCutoffDistance(nonbondedCutoff) nb.setEwaldErrorTolerance(ewaldErrorTolerance) if cnb is not None: cnb.setNonbondedMethod(methodMap[nonbondedMethod]) cnb.setCutoffDistance(nonbondedCutoff) #add implicit solvent model. Right now, only HCT model is considered. if implicitSolvent is not None: print('Adding implicit solvent ...') if implicitSolvent is HCT: gb_parms = self._get_gb_params() if gb_parms: print('Adding HCT GB force ...') gb = GBSAHCTForce(SA='ACE') for i in range(len(gb_parms)): gb.addParticle(list(gb_parms[i])) sys.addForce(gb) if implicitSolvent is 'AGBNP': #load AGBNP3 plugin if available try: from AGBNP3plugin import AGBNP3Force AGBNP3enabled = True except ImportError: AGBNP3enabled = False #sets up AGBNP3 if AGBNP3enabled: gb_parms = self._get_agbnp2_params() if gb_parms: print('Adding AGBNP3 force ...') gb = AGBNP3Force() # add particles for i in range(len(gb_parms)): p = gb_parms[i] gb.addParticle(p[0],p[1],p[2],p[3],p[4],p[5],p[6]) # connection table (from bonds) self._add_agbnp2_ct(gb) sys.addForce(gb) else: print('Warning: AGBNP is not supported in this version') if implicitSolvent is 'GVolSA': #load Gaussvol plugin if available try: from GVolplugin import GVolForce GVolEnabled = True except ImportError: GVolEnabled = False #sets up GVol if GVolEnabled: gb_parms = self._get_agbnp2_params() if gb_parms: print('Adding GVol force ...') gb = GVolForce() gb.setNonbondedMethod(methodMap[nonbondedMethod]) gb.setCutoffDistance(nonbondedCutoff) # add particles for i in range(len(gb_parms)): [radiusN,chargeN,gammaN,alphaN,hbtype,hbwN,ishydrogenN] = gb_parms[i] h_flag = ishydrogenN > 0 Roffset = 0.05; radiusN += Roffset; gb.addParticle(radiusN, gammaN, h_flag) #print "Adding", radiusN, gammaN, h_flag print "Adding GVolforce ..." sys.addForce(gb) print "Done" else: print('Warning: GVol is not supported in this version') # Adjust masses. if hydrogenMass is not None: for atom1, atom2 in self.topology.bonds(): if atom1.element == hydrogen: (atom1, atom2) = (atom2, atom1) if atom2.element == hydrogen and atom1.element not in (hydrogen, None): transferMass = hydrogenMass-sys.getParticleMass(atom2.index) sys.setParticleMass(atom2.index, hydrogenMass) sys.setParticleMass(atom1.index, sys.getParticleMass(atom1.index)-transferMass) # Add a CMMotionRemover. if removeCMMotion: sys.addForce(mm.CMMotionRemover()) return sys