Commit c7aa1d00 authored by kyleabeauchamp's avatar kyleabeauchamp
Browse files

Merge remote-tracking branch 'upstream/master' into vagrant

parents aea4e454 f7127d33
...@@ -47,7 +47,6 @@ class CharmmFile(object): ...@@ -47,7 +47,6 @@ class CharmmFile(object):
""" """
def __init__(self, fname, mode='r'): def __init__(self, fname, mode='r'):
self.closed = False
if mode not in ('r', 'w'): if mode not in ('r', 'w'):
raise ValueError('Cannot open CharmmFile with mode "%s"' % mode) raise ValueError('Cannot open CharmmFile with mode "%s"' % mode)
if mode == 'r': if mode == 'r':
...@@ -58,6 +57,7 @@ class CharmmFile(object): ...@@ -58,6 +57,7 @@ class CharmmFile(object):
self._handle = open(fname, mode) self._handle = open(fname, mode)
except IOError, e: except IOError, e:
raise CharmmFileError(str(e)) raise CharmmFileError(str(e))
self.closed = False
self.line_number = 0 self.line_number = 0
def write(self, *args, **kwargs): def write(self, *args, **kwargs):
......
...@@ -42,6 +42,32 @@ TINY = 1e-8 ...@@ -42,6 +42,32 @@ TINY = 1e-8
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def _tracking(fcn):
""" Decorator to indicate the list has changed """
def new_fcn(self, *args):
self.changed = True
return fcn(self, *args)
return new_fcn
class TrackedList(list):
"""
This creates a list type that allows you to see if anything has changed
"""
def __init__(self, arg=[]):
self.changed = False
list.__init__(self, arg)
__delitem__ = _tracking(list.__delitem__)
append = _tracking(list.append)
extend = _tracking(list.extend)
__setitem__ = _tracking(list.__setitem__)
# Python 3 does not have __delslice__, but make sure we override it for Python 2
if hasattr(TrackedList, '__delslice__'):
TrackedList.__delslice__ = _tracking(TrackedList.__delslice__)
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class AtomType(object): class AtomType(object):
""" """
Atom types can either be compared by indexes or names. Can be assigned with Atom types can either be compared by indexes or names. Can be assigned with
...@@ -61,6 +87,9 @@ class AtomType(object): ...@@ -61,6 +87,9 @@ class AtomType(object):
- _member_number (int, private) : The order in which this atom type - _member_number (int, private) : The order in which this atom type
was 'added' this is used to make sure that atom types added was 'added' this is used to make sure that atom types added
last have priority in assignment in the generated hash tables last have priority in assignment in the generated hash tables
- nbfix (dict) : Dictionary that maps nbfix terms with other atom types.
Dict entries are (rmin, epsilon) -- precombined values
for that particular atom pair
Example: Example:
>>> at = AtomType('HA', 1, 1.008, 1) >>> at = AtomType('HA', 1, 1.008, 1)
>>> at.name, at.number >>> at.name, at.number
...@@ -93,6 +122,9 @@ class AtomType(object): ...@@ -93,6 +122,9 @@ class AtomType(object):
self.atomic_number = atomic_number self.atomic_number = atomic_number
# We have no LJ parameters as of yet # We have no LJ parameters as of yet
self.epsilon = self.rmin = self.epsilon_14 = self.rmin_14 = None self.epsilon = self.rmin = self.epsilon_14 = self.rmin_14 = None
# Store each NBFIX term as a dict with the atom type string matching to
# a 2-element tuple that is rmin, epsilon
self.nbfix = dict()
def __eq__(self, other): def __eq__(self, other):
""" """
...@@ -123,6 +155,12 @@ class AtomType(object): ...@@ -123,6 +155,12 @@ class AtomType(object):
""" The integer representation of an AtomType is its index """ """ The integer representation of an AtomType is its index """
return self.number return self.number
def add_nbfix(self, typename, rmin, epsilon, rmin14, epsilon14):
""" Adds a new NBFIX exclusion for this atom """
if rmin14 is None: rmin14 = rmin
if epsilon14 is None: epsilon14 = epsilon
self.nbfix[typename] = (rmin, epsilon, rmin14, epsilon14)
def __str__(self): def __str__(self):
return self.name return self.name
...@@ -311,7 +349,7 @@ class Atom(object): ...@@ -311,7 +349,7 @@ class Atom(object):
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class AtomList(list): class AtomList(TrackedList):
""" A list of Atom instances. """ """ A list of Atom instances. """
def unmark(self): def unmark(self):
...@@ -424,7 +462,7 @@ class ResidueList(list): ...@@ -424,7 +462,7 @@ class ResidueList(list):
elif (self._last_residue != (resname, resnum) or elif (self._last_residue != (resname, resnum) or
system != self._last_residue.system): system != self._last_residue.system):
if (self._last_residue.idx == resnum and if (self._last_residue.idx == resnum and
system == self._last_residue.system): self._last_residue.system == system):
lresname = self._last_residue.resname lresname = self._last_residue.resname
warnings.warn('Residue %d split into separate residues %s ' warnings.warn('Residue %d split into separate residues %s '
'and %s' % (resnum, lresname, resname), 'and %s' % (resnum, lresname, resname),
...@@ -1047,28 +1085,6 @@ class _CmapGrid(object): ...@@ -1047,28 +1085,6 @@ class _CmapGrid(object):
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def _tracking(fcn):
""" Decorator to indicate the list has changed """
def new_fcn(self, *args):
self.changed = True
return fcn(self, *args)
return new_fcn
class TrackedList(list):
"""
This creates a list type that allows you to see if anything has changed
"""
def __init__(self, arg=[]):
self.changed = False
list.__init__(self, arg)
__delitem__ = _tracking(list.__delitem__)
append = _tracking(list.append)
extend = _tracking(list.extend)
__setitem__ = _tracking(list.__setitem__)
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if __name__ == '__main__': if __name__ == '__main__':
import doctest import doctest
doctest.testmod() doctest.testmod()
This diff is collapsed.
This diff is collapsed.
...@@ -100,6 +100,33 @@ class TestCharmmFiles(unittest.TestCase): ...@@ -100,6 +100,33 @@ class TestCharmmFiles(unittest.TestCase):
totalMass2 = sum([system2.getParticleMass(i) for i in range(system2.getNumParticles())]).value_in_unit(amu) totalMass2 = sum([system2.getParticleMass(i) for i in range(system2.getNumParticles())]).value_in_unit(amu)
self.assertAlmostEqual(totalMass1, totalMass2) self.assertAlmostEqual(totalMass1, totalMass2)
def test_NBFIX(self):
"""Tests CHARMM systems with NBFIX Lennard-Jones modifications"""
import warnings
warnings.filterwarnings('ignore', category=CharmmPSFWarning)
psf = CharmmPsfFile('systems/ala3_solv.psf')
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:
a.charge = 0.0
# Now compute the full energy
plat = Platform.getPlatformByName('Reference')
system = psf.createSystem(params, nonbondedMethod=PME,
nonbondedCutoff=8*angstroms)
con = Context(system, VerletIntegrator(2*femtoseconds), plat)
con.setPositions(crd.positions)
state = con.getState(getEnergy=True, enforcePeriodicBox=True)
ene = state.getPotentialEnergy().value_in_unit(kilocalories_per_mole)
self.assertAlmostEqual(ene, 15490.0033559, delta=0.05)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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