"platforms/cuda2/tests/TestCudaCustomIntegrator.cpp" did not exist on "a566a07487053f5eaee59cac0a0938b790697a65"
Commit 51e51c3b authored by John Chodera (MSKCC)'s avatar John Chodera (MSKCC)
Browse files

Merge remote-tracking branch 'upstream/master'

parents bc240d4a 373c3878
...@@ -13,7 +13,7 @@ Copyright (c) 2014 the Authors ...@@ -13,7 +13,7 @@ Copyright (c) 2014 the Authors
Author: Jason Deckman Author: Jason Deckman
Contributors: Jason M. Swails Contributors: Jason M. Swails
Date: April 19, 2014 Date: June 6, 2014
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
...@@ -105,7 +105,7 @@ class CharmmCrdFile(object): ...@@ -105,7 +105,7 @@ class CharmmCrdFile(object):
self.resname.append(line[2]) self.resname.append(line[2])
self.attype.append(line[3]) self.attype.append(line[3])
pos = Vec3(float(line[4]), float(line[5]), float(line[6])) pos = Vec3(float(line[4]), float(line[5]), float(line[6]))
self.positions.append(pos * u.angstroms) self.positions.append(pos)
self.segid.append(line[7]) self.segid.append(line[7])
self.resid.append(int(line[8])) self.resid.append(int(line[8]))
self.weighting.append(float(line[9])) self.weighting.append(float(line[9]))
...@@ -120,6 +120,10 @@ class CharmmCrdFile(object): ...@@ -120,6 +120,10 @@ class CharmmCrdFile(object):
except (ValueError, IndexError), e: except (ValueError, IndexError), e:
raise CharmmFileError('Error parsing CHARMM coordinate file') raise CharmmFileError('Error parsing CHARMM coordinate file')
# Apply units to the positions now. Do it this way to allow for
# (possible) numpy functionality in the future.
self.positions = u.Quantity(self.positions, u.angstroms)
class CharmmRstFile(object): class CharmmRstFile(object):
""" """
Reads and parses data, velocities and coordinates from a CHARMM restart Reads and parses data, velocities and coordinates from a CHARMM restart
...@@ -209,8 +213,9 @@ class CharmmRstFile(object): ...@@ -209,8 +213,9 @@ class CharmmRstFile(object):
self.velocities = [v * ONE_TIMESCALE for v in self.velocities] self.velocities = [v * ONE_TIMESCALE for v in self.velocities]
# Add units to positions and velocities # Add units to positions and velocities
self.positions *= u.angstroms self.positions = u.Quantity(self.positions, u.angstroms)
self.velocities *= u.angstroms / u.picoseconds self.positionsold = u.Quantity(self.positionsold, u.angstroms)
self.velocities = u.Quantity(self.velocities, u.angstroms/u.picoseconds)
def _scan(self, handle, str, r=0): # read lines in file until str is found def _scan(self, handle, str, r=0): # read lines in file until str is found
scanning = True scanning = True
......
...@@ -241,6 +241,10 @@ class CharmmParameterSet(object): ...@@ -241,6 +241,10 @@ class CharmmParameterSet(object):
if line.startswith('HBOND'): if line.startswith('HBOND'):
section = None section = None
continue continue
# It seems like files? sections? can be terminated with 'END'
if line.startswith('END'): # should this be case-insensitive?
section = None
continue
# If we have no section, skip # If we have no section, skip
if section is None: continue if section is None: continue
# Now handle each section specifically # Now handle each section specifically
......
...@@ -90,6 +90,7 @@ class CharmmPsfFile(object): ...@@ -90,6 +90,7 @@ class CharmmPsfFile(object):
- bond_list - bond_list
- angle_list - angle_list
- dihedral_list - dihedral_list
- dihedral_parameter_list
- improper_list - improper_list
- cmap_list - cmap_list
- donor_list # hbonds donors? - donor_list # hbonds donors?
...@@ -349,6 +350,7 @@ class CharmmPsfFile(object): ...@@ -349,6 +350,7 @@ class CharmmPsfFile(object):
self.bond_list = bond_list self.bond_list = bond_list
self.angle_list = angle_list self.angle_list = angle_list
self.dihedral_list = dihedral_list self.dihedral_list = dihedral_list
self.dihedral_parameter_list = TrackedList()
self.improper_list = improper_list self.improper_list = improper_list
self.cmap_list = cmap_list self.cmap_list = cmap_list
self.donor_list = donor_list self.donor_list = donor_list
...@@ -599,9 +601,9 @@ class CharmmPsfFile(object): ...@@ -599,9 +601,9 @@ class CharmmPsfFile(object):
central atoms in impropers) and see if that matches. Wild-cards central atoms in impropers) and see if that matches. Wild-cards
will apply ONLY if specific parameters cannot be found. will apply ONLY if specific parameters cannot be found.
- This method will expand the dihedral_list attribute by adding a - This method will expand the dihedral_parameter_list attribute by
separate Dihedral object for each term for types that have a adding a separate Dihedral object for each term for types that
multi-term expansion have a multi-term expansion
""" """
# First load the atom types # First load the atom types
types_are_int = False types_are_int = False
...@@ -643,12 +645,9 @@ class CharmmPsfFile(object): ...@@ -643,12 +645,9 @@ class CharmmPsfFile(object):
self.urey_bradley_list.append(ub) self.urey_bradley_list.append(ub)
except KeyError: except KeyError:
raise MissingParameter('Missing angle type for %r' % ang) raise MissingParameter('Missing angle type for %r' % ang)
# Next load all of the dihedrals. This is a little trickier since we # Next load all of the dihedrals.
# need to back up the existing dihedral list and replace it with a self.dihedral_parameter_list = TrackedList()
# longer one that has only one Fourier term per Dihedral instance. for dih in self.dihedral_list:
dihedral_list = self.dihedral_list
self.dihedral_list = TrackedList()
for dih in dihedral_list:
# Store the atoms # Store the atoms
a1, a2, a3, a4 = dih.atom1, dih.atom2, dih.atom3, dih.atom4 a1, a2, a3, a4 = dih.atom1, dih.atom2, dih.atom3, dih.atom4
at1, at2, at3, at4 = a1.attype, a2.attype, a3.attype, a4.attype at1, at2, at3, at4 = a1.attype, a2.attype, a3.attype, a4.attype
...@@ -662,14 +661,14 @@ class CharmmPsfFile(object): ...@@ -662,14 +661,14 @@ class CharmmPsfFile(object):
'%r' % dih) '%r' % dih)
dtlist = parmset.dihedral_types[key] dtlist = parmset.dihedral_types[key]
for i, dt in enumerate(dtlist): for i, dt in enumerate(dtlist):
self.dihedral_list.append(Dihedral(a1, a2, a3, a4, dt)) self.dihedral_parameter_list.append(Dihedral(a1,a2,a3,a4,dt))
# See if we include the end-group interactions for this # See if we include the end-group interactions for this
# dihedral. We do IFF it is the last or only dihedral term and # dihedral. We do IFF it is the last or only dihedral term and
# it is NOT in the angle/bond partners # it is NOT in the angle/bond partners
if i != len(dtlist) - 1: if i != len(dtlist) - 1:
self.dihedral_list[-1].end_groups_active = False self.dihedral_parameter_list[-1].end_groups_active = False
elif a1 in a4.bond_partners or a1 in a4.angle_partners: elif a1 in a4.bond_partners or a1 in a4.angle_partners:
self.dihedral_list[-1].end_groups_active = False self.dihedral_parameter_list[-1].end_groups_active = False
# Now do the impropers # Now do the impropers
for imp in self.improper_list: for imp in self.improper_list:
# Store the atoms # Store the atoms
...@@ -755,6 +754,12 @@ class CharmmPsfFile(object): ...@@ -755,6 +754,12 @@ class CharmmPsfFile(object):
- alpha, beta, gamma (floats, optional) : Angles between the - alpha, beta, gamma (floats, optional) : Angles between the
periodic cells. periodic cells.
""" """
try:
# Since we are setting the box, delete the cached box lengths if we
# have them to make sure they are recomputed if desired.
del self._boxLengths
except AttributeError:
pass
self.box_vectors = _box_vectors_from_lengths_angles(a, b, c, self.box_vectors = _box_vectors_from_lengths_angles(a, b, c,
alpha, beta, gamma) alpha, beta, gamma)
# If we already have a _topology instance, then we have possibly changed # If we already have a _topology instance, then we have possibly changed
...@@ -952,8 +957,6 @@ class CharmmPsfFile(object): ...@@ -952,8 +957,6 @@ class CharmmPsfFile(object):
- flexibleConstraints (bool=True) Are our constraints flexible or not? - flexibleConstraints (bool=True) Are our constraints flexible or not?
- verbose (bool=False) Optionally prints out a running progress report - verbose (bool=False) Optionally prints out a running progress report
""" """
# back up the dihedral list
dihedral_list = self.dihedral_list
# Load the parameter set # Load the parameter set
self.loadParameters(params.condense()) self.loadParameters(params.condense())
hasbox = self.topology.getUnitCellDimensions() is not None hasbox = self.topology.getUnitCellDimensions() is not None
...@@ -1103,7 +1106,7 @@ class CharmmPsfFile(object): ...@@ -1103,7 +1106,7 @@ class CharmmPsfFile(object):
if verbose: print('Adding torsions...') if verbose: print('Adding torsions...')
force = mm.PeriodicTorsionForce() force = mm.PeriodicTorsionForce()
force.setForceGroup(self.DIHEDRAL_FORCE_GROUP) force.setForceGroup(self.DIHEDRAL_FORCE_GROUP)
for tor in self.dihedral_list: for tor in self.dihedral_parameter_list:
force.addTorsion(tor.atom1.idx, tor.atom2.idx, tor.atom3.idx, force.addTorsion(tor.atom1.idx, tor.atom2.idx, tor.atom3.idx,
tor.atom4.idx, tor.dihedral_type.per, tor.atom4.idx, tor.dihedral_type.per,
tor.dihedral_type.phase*pi/180, tor.dihedral_type.phase*pi/180,
...@@ -1235,7 +1238,7 @@ class CharmmPsfFile(object): ...@@ -1235,7 +1238,7 @@ class CharmmPsfFile(object):
# Add 1-4 interactions # Add 1-4 interactions
excluded_atom_pairs = set() # save these pairs so we don't zero them out excluded_atom_pairs = set() # save these pairs so we don't zero them out
sigma_scale = 2**(-1/6) sigma_scale = 2**(-1/6)
for tor in self.dihedral_list: for tor in self.dihedral_parameter_list:
# First check to see if atoms 1 and 4 are already excluded because # First check to see if atoms 1 and 4 are already excluded because
# they are 1-2 or 1-3 pairs (would happen in 6-member rings or # they are 1-2 or 1-3 pairs (would happen in 6-member rings or
# fewer). Then check that they're not already added as exclusions # fewer). Then check that they're not already added as exclusions
...@@ -1355,9 +1358,6 @@ class CharmmPsfFile(object): ...@@ -1355,9 +1358,6 @@ class CharmmPsfFile(object):
# Cache our system for easy access # Cache our system for easy access
self._system = system self._system = system
# Restore the dihedral list to allow reparametrization later
self.dihedral_list = dihedral_list
return system return system
@property @property
...@@ -1422,9 +1422,30 @@ class CharmmPsfFile(object): ...@@ -1422,9 +1422,30 @@ class CharmmPsfFile(object):
@property @property
def boxLengths(self): def boxLengths(self):
""" Return tuple of 3 units """ """ Return tuple of 3 units """
try:
# See if we have a cached version
return self._boxLengths
except AttributeError:
pass
if self.box_vectors is not None: if self.box_vectors is not None:
return (self.box_vectors[0][0], self.box_vectors[0][1], # Get the lengths of each vector
self.box_vectors[0][2]) if u.is_quantity(self.box_vectors):
# Unlikely -- each vector is like a quantity
vecs = self.box_vectors.value_in_unit(u.nanometers)
elif u.is_quantity(self.box_vectors[0]):
# Assume all box vectors are quantities
vecs = [x.value_in_unit(u.nanometers) for x in self.box_vectors]
else:
# Assume nanometers
vecs = self.box_vectors
a = sqrt(vecs[0][0]*vecs[0][0] + vecs[0][1]*vecs[0][1] +
vecs[0][2]*vecs[0][2])
b = sqrt(vecs[1][0]*vecs[1][0] + vecs[1][1]*vecs[1][1] +
vecs[1][2]*vecs[1][2])
c = sqrt(vecs[2][0]*vecs[2][0] + vecs[2][1]*vecs[2][1] +
vecs[2][2]*vecs[2][2])
self._boxLengths = (a, b, c) * u.nanometers
return self._boxLengths
return None return None
@boxLengths.setter @boxLengths.setter
...@@ -1440,6 +1461,12 @@ class CharmmPsfFile(object): ...@@ -1440,6 +1461,12 @@ class CharmmPsfFile(object):
@boxVectors.setter @boxVectors.setter
def boxVectors(self, stuff): def boxVectors(self, stuff):
""" Sets the box vectors """ """ Sets the box vectors """
try:
# We may be changing the box, so delete the cached box lengths to
# make sure they are recomputed if desired
del self._boxLengths
except AttributeError:
pass
self.box_vectors = stuff self.box_vectors = stuff
def deleteCmap(self): def deleteCmap(self):
......
This diff is collapsed.
This diff is collapsed.
<ForceField>
<Info>
<DateGenerated>2014-05-28</DateGenerated>
<Reference>Lee-Ping Wang, Todd J. Martinez and Vijay S. Pande. Building force fields - an automatic, systematic and reproducible approach. Journal of Physical Chemistry Letters, 2014, 5, pp 1885-1891. DOI:10.1021/jz500737m</Reference>
</Info>
<AtomTypes>
<Type name="tip3p-fb-O" class="OW" element="O" mass="15.99943"/>
<Type name="tip3p-fb-H" class="HW" element="H" mass="1.007947"/>
</AtomTypes>
<Residues>
<Residue name="HOH">
<Atom name="O" type="tip3p-fb-O"/>
<Atom name="H1" type="tip3p-fb-H"/>
<Atom name="H2" type="tip3p-fb-H"/>
<Bond from="0" to="1"/>
<Bond from="0" to="2"/>
</Residue>
</Residues>
<HarmonicBondForce>
<Bond class1="OW" class2="HW" length="0.101181082494" k="462750.4"/>
</HarmonicBondForce>
<HarmonicAngleForce>
<Angle class1="HW" class2="OW" class3="HW" angle="1.88754640288" k="836.8"/>
</HarmonicAngleForce>
<NonbondedForce coulomb14scale="0.833333" lj14scale="0.5">
<Atom type="tip3p-fb-O" charge="-0.848448690103" sigma="0.317796456355" epsilon="0.652143528104" />
<Atom type="tip3p-fb-H" charge="0.4242243450515" sigma="1" epsilon="0" />
</NonbondedForce>
</ForceField>
<ForceField>
<Info>
<DateGenerated>2014-05-28</DateGenerated>
<Reference>Lee-Ping Wang, Todd J. Martinez and Vijay S. Pande. Building force fields - an automatic, systematic and reproducible approach. Journal of Physical Chemistry Letters, 2014, 5, pp 1885-1891. DOI:10.1021/jz500737m</Reference>
</Info>
<AtomTypes>
<Type name="tip4p-fb-O" class="OW" element="O" mass="15.99943"/>
<Type name="tip4p-fb-H" class="HW" element="H" mass="1.007947"/>
<Type name="tip4p-fb-M" class="MW" mass="0"/>
</AtomTypes>
<Residues>
<Residue name="HOH">
<Atom name="O" type="tip4p-fb-O"/>
<Atom name="H1" type="tip4p-fb-H"/>
<Atom name="H2" type="tip4p-fb-H"/>
<Atom name="M" type="tip4p-fb-M"/>
<VirtualSite type="average3" index="3" atom1="0" atom2="1" atom3="2" weight1="8.203146574531e-01" weight2="8.984267127345e-02" weight3="8.984267127345e-02" />
<Bond from="0" to="1"/>
<Bond from="0" to="2"/>
</Residue>
</Residues>
<HarmonicBondForce>
<Bond class1="OW" class2="HW" length="0.09572" k="462750.4"/>
</HarmonicBondForce>
<HarmonicAngleForce>
<Angle class1="HW" class2="OW" class3="HW" angle="1.82421813418" k="836.8"/>
</HarmonicAngleForce>
<NonbondedForce coulomb14scale="0.833333" lj14scale="0.5">
<Atom type="tip4p-fb-O" charge="0" sigma="3.165552430462e-01" epsilon="7.492790213533e-01" />
<Atom type="tip4p-fb-H" charge="5.258681106763e-01" sigma="1" epsilon="0" />
<Atom type="tip4p-fb-M" charge="-1.0517362213526e+00" sigma="1" epsilon="0" />
</NonbondedForce>
</ForceField>
...@@ -6,7 +6,7 @@ Simbios, the NIH National Center for Physics-Based Simulation of ...@@ -6,7 +6,7 @@ Simbios, the NIH National Center for Physics-Based Simulation of
Biological Structures at Stanford, funded under the NIH Roadmap for Biological Structures at Stanford, funded under the NIH Roadmap for
Medical Research, grant U54 GM072970. See https://simtk.org. Medical Research, grant U54 GM072970. See https://simtk.org.
Portions copyright (c) 2012-2013 Stanford University and the Authors. Portions copyright (c) 2012-2014 Stanford University and the Authors.
Authors: Peter Eastman, Mark Friedrichs Authors: Peter Eastman, Mark Friedrichs
Contributors: Contributors:
...@@ -1485,6 +1485,104 @@ class CustomTorsionGenerator: ...@@ -1485,6 +1485,104 @@ class CustomTorsionGenerator:
parsers["CustomTorsionForce"] = CustomTorsionGenerator.parseElement parsers["CustomTorsionForce"] = CustomTorsionGenerator.parseElement
## @private
class CustomNonbondedGenerator:
"""A CustomNonbondedGenerator constructs a CustomNonbondedForce."""
def __init__(self, energy, bondCutoff):
self.energy = energy
self.bondCutoff = bondCutoff
self.typeMap = {}
self.globalParams = {}
self.perParticleParams = []
self.functions = []
@staticmethod
def parseElement(element, ff):
generator = CustomNonbondedGenerator(element.attrib['energy'], int(element.attrib['bondCutoff']))
ff._forces.append(generator)
for param in element.findall('GlobalParameter'):
generator.globalParams[param.attrib['name']] = float(param.attrib['defaultValue'])
for param in element.findall('PerParticleParameter'):
generator.perParticleParams.append(param.attrib['name'])
for atom in element.findall('Atom'):
types = ff._findAtomTypes(atom, 1)
if None not in types:
values = [float(atom.attrib[param]) for param in generator.perParticleParams]
for t in types[0]:
generator.typeMap[t] = values
def createForce(self, sys, data, nonbondedMethod, nonbondedCutoff, args):
methodMap = {NoCutoff:mm.CustomNonbondedForce.NoCutoff,
CutoffNonPeriodic:mm.CustomNonbondedForce.CutoffNonPeriodic,
CutoffPeriodic:mm.CustomNonbondedForce.CutoffPeriodic}
if nonbondedMethod not in methodMap:
raise ValueError('Illegal nonbonded method for CustomNonbondedForce')
force = mm.CustomNonbondedForce(self.energy)
for param in self.globalParams:
force.addGlobalParameter(param, self.globalParams[param])
for param in self.perParticleParams:
force.addPerParticleParameter(param)
for (name, type, values, params) in self.functions:
if type == 'Continuous1D':
force.addTabulatedFunction(name, mm.Continuous1DFunction(values, params['min'], params['max']))
elif type == 'Continuous2D':
force.addTabulatedFunction(name, mm.Continuous2DFunction(params['xsize'], params['ysize'], values, params['xmin'], params['xmax'], params['ymin'], params['ymax']))
elif type == 'Continuous3D':
force.addTabulatedFunction(name, mm.Continuous2DFunction(params['xsize'], params['ysize'], params['zsize'], values, params['xmin'], params['xmax'], params['ymin'], params['ymax'], params['zmin'], params['zmax']))
elif type == 'Discrete1D':
force.addTabulatedFunction(name, mm.Discrete1DFunction(values))
elif type == 'Discrete2D':
force.addTabulatedFunction(name, mm.Discrete2DFunction(params['xsize'], params['ysize'], values))
elif type == 'Discrete3D':
force.addTabulatedFunction(name, mm.Discrete2DFunction(params['xsize'], params['ysize'], params['zsize'], values))
for atom in data.atoms:
t = data.atomType[atom]
if t in self.typeMap:
values = self.typeMap[t]
force.addParticle(self.typeMap[t])
else:
raise ValueError('No CustomNonbonded parameters defined for atom type '+t)
force.setNonbondedMethod(methodMap[nonbondedMethod])
force.setCutoffDistance(nonbondedCutoff)
sys.addForce(force)
def postprocessSystem(self, sys, data, args):
# Create exceptions based on bonds, virtual sites, and Drude particles.
if self.bondCutoff == 0:
return
bondIndices = []
for bond in data.bonds:
bondIndices.append((bond.atom1, bond.atom2))
for i in range(sys.getNumParticles()):
if sys.isVirtualSite(i):
site = sys.getVirtualSite(i)
for j in range(site.getNumParticles()):
bondIndices.append((i, site.getParticle(j)))
drude = [f for f in sys.getForces() if isinstance(f, mm.DrudeForce)]
if len(drude) > 0:
drude = drude[0]
# For purposes of creating exceptions, a Drude particle is "bonded" to anything
# its parent atom is bonded to.
drudeMap = {}
for i in range(drude.getNumParticles()):
params = drude.getParticleParameters(i)
drudeMap[params[1]] = params[0]
for atom1, atom2 in bondIndices:
drude1 = drudeMap[atom1] if atom1 in drudeMap else None
drude2 = drudeMap[atom2] if atom2 in drudeMap else None
if drude1 is not None:
bondIndices.append((drude1, atom2))
if drude2 is not None:
bondIndices.append((drude1, drude2))
if drude2 is not None:
bondIndices.append((atom1, drude2))
nonbonded = [f for f in sys.getForces() if isinstance(f, mm.CustomNonbondedForce)][0]
nonbonded.createExclusionsFromBonds(bondIndices, self.bondCutoff)
parsers["CustomNonbondedForce"] = CustomNonbondedGenerator.parseElement
## @private ## @private
class CustomGBGenerator: class CustomGBGenerator:
"""A CustomGBGenerator constructs a CustomGBForce.""" """A CustomGBGenerator constructs a CustomGBForce."""
...@@ -1493,7 +1591,6 @@ class CustomGBGenerator: ...@@ -1493,7 +1591,6 @@ class CustomGBGenerator:
self.typeMap = {} self.typeMap = {}
self.globalParams = {} self.globalParams = {}
self.perParticleParams = [] self.perParticleParams = []
self.paramValues = []
self.computedValues = [] self.computedValues = []
self.energyTerms = [] self.energyTerms = []
self.functions = [] self.functions = []
...@@ -2517,6 +2614,7 @@ class AmoebaTorsionTorsionGenerator: ...@@ -2517,6 +2614,7 @@ class AmoebaTorsionTorsionGenerator:
gridRow.append(float(gridEntry.attrib['angle1'])) gridRow.append(float(gridEntry.attrib['angle1']))
gridRow.append(float(gridEntry.attrib['angle2'])) gridRow.append(float(gridEntry.attrib['angle2']))
gridRow.append(float(gridEntry.attrib['f'])) gridRow.append(float(gridEntry.attrib['f']))
if 'fx' in gridEntry.attrib:
gridRow.append(float(gridEntry.attrib['fx'])) gridRow.append(float(gridEntry.attrib['fx']))
gridRow.append(float(gridEntry.attrib['fy'])) gridRow.append(float(gridEntry.attrib['fy']))
gridRow.append(float(gridEntry.attrib['fxy'])) gridRow.append(float(gridEntry.attrib['fxy']))
......
...@@ -6,7 +6,7 @@ Simbios, the NIH National Center for Physics-Based Simulation of ...@@ -6,7 +6,7 @@ Simbios, the NIH National Center for Physics-Based Simulation of
Biological Structures at Stanford, funded under the NIH Roadmap for Biological Structures at Stanford, funded under the NIH Roadmap for
Medical Research, grant U54 GM072970. See https://simtk.org. Medical Research, grant U54 GM072970. See https://simtk.org.
Portions copyright (c) 2012-2013 Stanford University and the Authors. Portions copyright (c) 2012-2014 Stanford University and the Authors.
Authors: Peter Eastman Authors: Peter Eastman
Contributors: Contributors:
...@@ -745,6 +745,12 @@ class GromacsTopFile(object): ...@@ -745,6 +745,12 @@ class GromacsTopFile(object):
atom1params = nb.getParticleParameters(baseAtomIndex+atoms[0]) atom1params = nb.getParticleParameters(baseAtomIndex+atoms[0])
atom2params = nb.getParticleParameters(baseAtomIndex+atoms[1]) atom2params = nb.getParticleParameters(baseAtomIndex+atoms[1])
exceptions.append((baseAtomIndex+atoms[0], baseAtomIndex+atoms[1], atom1params[0]*atom2params[0]*fudgeQQ, params[0], params[1])) exceptions.append((baseAtomIndex+atoms[0], baseAtomIndex+atoms[1], atom1params[0]*atom2params[0]*fudgeQQ, params[0], params[1]))
for fields in moleculeType.exclusions:
atoms = [int(x)-1 for x in fields]
for atom in atoms[1:]:
if atom > atoms[0]:
exceptions.append((baseAtomIndex+atoms[0], baseAtomIndex+atom, 0, 0, 0))
# Create nonbonded exceptions. # Create nonbonded exceptions.
......
...@@ -421,8 +421,10 @@ class ResidueList(list): ...@@ -421,8 +421,10 @@ class ResidueList(list):
if self._last_residue is None: if self._last_residue is None:
res = self._last_residue = Residue(resname, resnum) res = self._last_residue = Residue(resname, resnum)
list.append(self, res) list.append(self, res)
elif self._last_residue != (resname, resnum): elif (self._last_residue != (resname, resnum) or
if self._last_residue.idx == resnum: system != self._last_residue.system):
if (self._last_residue.idx == resnum and
system == self._last_residue.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),
...@@ -1063,7 +1065,6 @@ class TrackedList(list): ...@@ -1063,7 +1065,6 @@ class TrackedList(list):
__delitem__ = _tracking(list.__delitem__) __delitem__ = _tracking(list.__delitem__)
append = _tracking(list.append) append = _tracking(list.append)
extend = _tracking(list.extend) extend = _tracking(list.extend)
__delslice__ = _tracking(list.__delslice__)
__setitem__ = _tracking(list.__setitem__) __setitem__ = _tracking(list.__setitem__)
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
......
...@@ -263,7 +263,7 @@ class Modeller(object): ...@@ -263,7 +263,7 @@ class Modeller(object):
- positiveIon (string='Na+') the type of positive ion to add. Allowed values are 'Cs+', 'K+', 'Li+', 'Na+', and 'Rb+' - positiveIon (string='Na+') the type of positive ion to add. Allowed values are 'Cs+', 'K+', 'Li+', 'Na+', and 'Rb+'
- negativeIon (string='Cl-') the type of negative ion to add. Allowed values are 'Cl-', 'Br-', 'F-', and 'I-'. Be aware - negativeIon (string='Cl-') the type of negative ion to add. Allowed values are 'Cl-', 'Br-', 'F-', and 'I-'. Be aware
that not all force fields support all ion types. that not all force fields support all ion types.
- ionicString (concentration=0*molar) the total concentration of ions (both positive and negative) to add. This - ionicStrength (concentration=0*molar) the total concentration of ions (both positive and negative) to add. This
does not include ions that are added to neutralize the system. does not include ions that are added to neutralize the system.
""" """
# Pick a unit cell size. # Pick a unit cell size.
...@@ -952,14 +952,14 @@ class Modeller(object): ...@@ -952,14 +952,14 @@ class Modeller(object):
# This is a virtual site. Compute its position by the correct rule. # This is a virtual site. Compute its position by the correct rule.
if site.type == 'average2': if site.type == 'average2':
position = site.weights[0]*templateAtomPositions[index+site.atoms[0]] + site.weights[1]*templateAtomPositions[index+site.atoms[1]] position = site.weights[0]*templateAtomPositions[site.atoms[0]] + site.weights[1]*templateAtomPositions[site.atoms[1]]
elif site.type == 'average3': elif site.type == 'average3':
position = site.weights[0]*templateAtomPositions[index+site.atoms[0]] + site.weights[1]*templateAtomPositions[index+site.atoms[1]] + site.weights[2]*templateAtomPositions[index+site.atoms[2]] position = site.weights[0]*templateAtomPositions[site.atoms[0]] + site.weights[1]*templateAtomPositions[site.atoms[1]] + site.weights[2]*templateAtomPositions[site.atoms[2]]
elif site.type == 'outOfPlane': elif site.type == 'outOfPlane':
v1 = templateAtomPositions[index+site.atoms[1]] - templateAtomPositions[index+site.atoms[0]] v1 = templateAtomPositions[site.atoms[1]] - templateAtomPositions[site.atoms[0]]
v2 = templateAtomPositions[index+site.atoms[2]] - templateAtomPositions[index+site.atoms[0]] v2 = templateAtomPositions[site.atoms[2]] - templateAtomPositions[site.atoms[0]]
cross = Vec3(v1[1]*v2[2]-v1[2]*v2[1], v1[2]*v2[0]-v1[0]*v2[2], v1[0]*v2[1]-v1[1]*v2[0]) cross = Vec3(v1[1]*v2[2]-v1[2]*v2[1], v1[2]*v2[0]-v1[0]*v2[2], v1[0]*v2[1]-v1[1]*v2[0])
position = templateAtomPositions[index+site.atoms[0]] + site.weights[0]*v1 + site.weights[1]*v2 + site.weights[2]*cross position = templateAtomPositions[site.atoms[0]] + site.weights[0]*v1 + site.weights[1]*v2 + site.weights[2]*cross
if position is None and atom.type in drudeTypeMap: if position is None and atom.type in drudeTypeMap:
# This is a Drude particle. Put it on top of its parent atom. # This is a Drude particle. Put it on top of its parent atom.
......
...@@ -272,7 +272,7 @@ UNITS = { ...@@ -272,7 +272,7 @@ UNITS = {
("AmoebaPiTorsionForce", "getPiTorsionParameters") : ( None, (None, None, None, None, None, None, 'unit.kilojoule_per_mole')), ("AmoebaPiTorsionForce", "getPiTorsionParameters") : ( None, (None, None, None, None, None, None, 'unit.kilojoule_per_mole')),
("AmoebaStretchBendForce", "getNumStretchBends") : ( None, ()), ("AmoebaStretchBendForce", "getNumStretchBends") : ( None, ()),
("AmoebaStretchBendForce", "getStretchBendParameters") : ( None, (None, None, None, 'unit.nanometer', 'unit.nanometer', 'unit.radian', 'unit.kilojoule_per_mole/unit.nanometer')), ("AmoebaStretchBendForce", "getStretchBendParameters") : ( None, (None, None, None, 'unit.nanometer', 'unit.nanometer', 'unit.radian', 'unit.kilojoule_per_mole/unit.nanometer/unit.degree')),
("AmoebaTorsionTorsionForce", "getNumTorsionTorsions") : ( None, ()), ("AmoebaTorsionTorsionForce", "getNumTorsionTorsions") : ( None, ()),
("AmoebaTorsionTorsionForce", "getNumTorsionTorsionGrids") : ( None, ()), ("AmoebaTorsionTorsionForce", "getNumTorsionTorsionGrids") : ( None, ()),
......
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
def compareByElement(array1, array2, cmp):
for x, y in zip(array1, array2):
cmp(x, y)
class TestAmberInpcrdFile(unittest.TestCase):
"""Test the Amber inpcrd file parser"""
def test_CrdVelBox(self):
""" Test parsing ASCII restarts with crds, vels, and box """
cmp = self.assertAlmostEqual
inpcrd = AmberInpcrdFile('systems/crds_vels_box.rst7')
self.assertEqual(len(inpcrd.positions), 2101)
compareByElement(inpcrd.positions[-1].value_in_unit(angstroms),
[3.5958082, 8.4176792, -8.2954064], cmp)
compareByElement(inpcrd.velocities[-1].value_in_unit(angstroms/picoseconds),
[0.3091332*20.455, 0.7355925*20.455, -0.1206961*20.455], cmp)
compareByElement(inpcrd.boxVectors[0].value_in_unit(angstroms),
[30.2642725, 0.0, 0.0], cmp)
def test_NetCDF(self):
""" Test NetCDF restart file parsing """
cmp = self.assertAlmostEqual
try:
from scipy.io import netcdf
except ImportError:
print('Not testing NetCDF file parser... scipy cannot be found')
else:
inpcrd = AmberInpcrdFile('systems/amber.ncrst')
self.assertEqual(len(inpcrd.positions), 2101)
compareByElement(inpcrd.positions[0].value_in_unit(angstroms),
[6.82122492718229, 6.6276250662042, -8.51668999892245],
cmp)
compareByElement(inpcrd.velocities[-1].value_in_unit(angstroms/picosecond),
[0.349702202733541*20.455, 0.391525333168534*20.455,
0.417941679767662*20.455], cmp)
self.assertAlmostEqual(inpcrd.boxVectors[0][0].value_in_unit(angstroms),
30.2642725, places=6)
def test_CrdBox(self):
""" Test parsing ASCII restarts with only crds and box """
inpcrd = AmberInpcrdFile('systems/crds_box.rst7')
self.assertEqual(len(inpcrd.positions), 18660)
self.assertTrue(inpcrd.velocities is None)
self.assertTrue(inpcrd.boxVectors is not None)
def test_CrdVel(self):
inpcrd = AmberInpcrdFile('systems/crds_vels.rst7')
self.assertTrue(inpcrd.boxVectors is None)
self.assertTrue(inpcrd.velocities is not None)
def test_CrdOnly(self):
inpcrd = AmberInpcrdFile('systems/crdsonly.rst7')
self.assertTrue(inpcrd.boxVectors is None)
self.assertTrue(inpcrd.velocities is None)
if __name__ == '__main__':
unittest.main()
This diff is collapsed.
ACE
28 0.1100000E+05
6.9962325 7.1345361 -3.9713983 7.4756482 6.1688310 -3.8111566
8.5024408 6.3930528 -3.5221598 7.4708173 5.7449547 -4.8153505
6.8002949 5.4664470 -2.6846071 7.1210336 4.3039353 -2.4099316
5.8138412 6.2015113 -2.0369948 5.6437332 7.0956281 -2.4748521
4.9765730 5.7180343 -0.9552686 5.5952335 5.0377318 -0.3699927
4.5105579 6.8291112 0.0795226 5.4196673 7.2692444 0.4892821
3.8405864 7.5537576 -0.3832260 3.7600399 6.2095975 1.2450279
3.0614461 7.0866468 2.0205499 3.9472641 4.9020081 1.4914431
3.4219922 4.6877864 2.2659097 3.7335795 4.9588789 -1.4954454
2.9265073 5.7168640 -2.1242842 4.4787994 4.4294475 0.8466484
2.5980237 6.7854333 2.8054767 3.2160253 7.9534080 1.6378901
3.5172878 3.6766505 -1.2008776 4.1472250 3.2061006 -0.5669477
2.4677851 2.8846866 -1.7794578 2.8829398 2.5139385 -2.7166333
2.3438054 2.0729996 -1.0625940 1.5440133 3.4553999 -1.8744943
0.3799223 0.0175576 1.1999574 0.3523292 -0.2043193 0.0353460
1.1942188 -1.4410315 -1.7982354 -0.5852708 -0.9087781 0.3223661
0.1459748 0.0526223 0.2682160 -0.0465667 -0.1870169 0.1459932
-0.2892203 0.0015456 -0.0112940 0.1854616 -0.2737819 -0.7785389
-0.2392158 0.1749611 -0.1239180 -0.3400171 0.0531231 -0.1587713
-0.4704835 -0.1493877 -0.2567553 -0.6101138 -0.0392770 -0.0635170
0.5715057 0.1942655 -1.2772686 -0.1237689 -0.3449472 0.2714899
-0.0185239 -0.0150607 0.0391274 -0.1280282 -0.0046097 -0.1994271
-0.3155035 0.3668607 -0.2215361 0.1294219 -0.1747917 -0.0917708
0.0742998 0.1509489 -0.2851266 0.4923665 -1.0386246 1.0229978
-0.8227836 1.0624132 0.0013427 -0.0778814 -0.1859122 -0.3774084
0.2098003 0.1213628 -0.2466628 -0.1936209 -0.2478820 -0.1148687
0.0315637 0.2866246 -0.0746640 -0.5854400 -0.8935872 0.0990994
0.6063127 -0.1110186 -0.4168450 -0.8390447 -1.1240213 -0.3891693
This diff is collapsed.
ACE
28
1.8662825 1.2455949 0.6672110 1.9626006 2.1938026 0.1396779
1.2497428 2.9104392 0.5454310 1.7619492 2.0427757 -0.9201889
3.3659937 2.7323333 0.3106630 4.1907627 2.1039510 0.9734519
3.6273756 3.8949435 -0.2849918 2.8777368 4.3392797 -0.7950028
4.9163808 4.5976032 -0.2534247 5.4756521 4.2709258 0.6250439
5.7163632 4.2049342 -1.5101182 5.8371260 3.1200826 -1.5317512
5.1471196 4.4947601 -2.3959905 7.1055802 4.8539661 -1.5508595
7.9498622 4.6375603 -0.4939507 7.4316586 5.6201081 -2.6386852
8.3150784 5.9901727 -2.5863945 4.7269796 6.1275619 -0.1377803
3.7336230 6.6808666 -0.6238468 6.7262793 5.6692474 -3.2868494
8.7967113 5.0771061 -0.5933179 7.5650193 4.0788360 0.1842201
5.6831501 6.8163892 0.4999151 6.4763527 6.2959896 0.8529456
5.6745238 8.2651257 0.7063732 4.7905547 8.5573927 1.2769756
6.5663801 8.5705282 1.2568739 5.6602885 8.7808127 -0.2560452
...@@ -1054,7 +1054,7 @@ BLA BLA BLA BLA BLA BLA BLA BLA ...@@ -1054,7 +1054,7 @@ BLA BLA BLA BLA BLA BLA BLA BLA
3 3 3 3 3 3 3 3 3 3 3 3
%FLAG BOX_DIMENSIONS %FLAG BOX_DIMENSIONS
%FORMAT(5E16.8) %FORMAT(5E16.8)
5.15661795E+03 1.87743490E+01 1.87743490E+01 1.87743490E+01 9.00000000E+01 1.87743490E+01 1.87743490E+01 1.87743490E+01
%FLAG RADIUS_SET %FLAG RADIUS_SET
%FORMAT(1a80) %FORMAT(1a80)
modified Bondi radii (mbondi) modified Bondi radii (mbondi)
......
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