Commit 60b840e6 authored by peastman's avatar peastman
Browse files

Merge branch 'master' into membrane

parents 6f26c4c5 57f3be7e
......@@ -80,13 +80,11 @@ class PDBxFile(object):
# Build the topology.
atomData = block.getObj('atom_site')
atomNameCol = atomData.getAttributeIndex('label_atom_id')
atomNameCol = atomData.getAttributeIndex('auth_atom_id')
atomIdCol = atomData.getAttributeIndex('id')
resNameCol = atomData.getAttributeIndex('label_comp_id')
resIdCol = atomData.getAttributeIndex('label_seq_id')
resNameCol = atomData.getAttributeIndex('auth_comp_id')
resNumCol = atomData.getAttributeIndex('auth_seq_id')
asymIdCol = atomData.getAttributeIndex('label_asym_id')
chainIdCol = atomData.getAttributeIndex('label_entity_id')
chainIdCol = atomData.getAttributeIndex('auth_asym_id')
elementCol = atomData.getAttributeIndex('type_symbol')
altIdCol = atomData.getAttributeIndex('label_alt_id')
modelCol = atomData.getAttributeIndex('pdbx_PDB_model_num')
......@@ -95,12 +93,11 @@ class PDBxFile(object):
zCol = atomData.getAttributeIndex('Cartn_z')
lastChainId = None
lastResId = None
lastAsymId = None
atomTable = {}
atomsInResidue = set()
models = []
for row in atomData.getRowList():
atomKey = ((row[resIdCol], row[asymIdCol], row[atomNameCol]))
atomKey = ((row[resNumCol], row[chainIdCol], row[atomNameCol]))
model = ('1' if modelCol == -1 else row[modelCol])
if model not in models:
models.append(model)
......@@ -115,15 +112,13 @@ class PDBxFile(object):
if lastChainId != row[chainIdCol]:
# The start of a new chain.
chain = top.addChain(row[asymIdCol])
chain = top.addChain(row[chainIdCol])
lastChainId = row[chainIdCol]
lastResId = None
lastAsymId = None
if lastResId != row[resIdCol] or lastAsymId != row[asymIdCol] or (lastResId == '.' and row[atomNameCol] in atomsInResidue):
if lastResId != row[resNumCol] or lastChainId != row[chainIdCol] or (lastResId == '.' and row[atomNameCol] in atomsInResidue):
# The start of a new residue.
res = top.addResidue(row[resNameCol], chain, None if resNumCol == -1 else row[resNumCol])
lastResId = row[resIdCol]
lastAsymId = row[asymIdCol]
lastResId = row[resNumCol]
atomsInResidue.clear()
element = None
try:
......@@ -139,7 +134,7 @@ class PDBxFile(object):
try:
atom = atomTable[atomKey]
except KeyError:
raise ValueError('Unknown atom %s in residue %s %s for model %s' % (row[atomNameCol], row[resNameCol], row[resIdCol], model))
raise ValueError('Unknown atom %s in residue %s %s for model %s' % (row[atomNameCol], row[resNameCol], row[resNumCol], model))
if atom.index != len(self._positions[modelIndex]):
raise ValueError('Atom %s for model %s does not match the order of atoms for model %s' % (row[atomIdCol], model, models[0]))
self._positions[modelIndex].append(Vec3(float(row[xCol]), float(row[yCol]), float(row[zCol]))*0.1)
......
......@@ -183,6 +183,9 @@ class Simulation(object):
nextReport = [None]*len(self.reporters)
while self.currentStep < endStep and (endTime is None or datetime.now() < endTime):
nextSteps = endStep-self.currentStep
# Find when the next report will happen.
anyReport = False
for i, reporter in enumerate(self.reporters):
nextReport[i] = reporter.describeNextReport(self)
......@@ -198,12 +201,45 @@ class Simulation(object):
self.integrator.step(stepsToGo)
self.currentStep += nextSteps
if anyReport:
# One or more reporters are ready to generate reports. Organize them into three
# groups: ones that want wrapped positions, ones that want unwrapped positions,
# and ones that don't care about positions.
wrapped = []
unwrapped = []
either = []
for reporter, report in zip(self.reporters, nextReport):
if report[0] == nextSteps:
if len(report) > 5:
wantWrap = report[5]
if wantWrap is None:
wantWrap = self._usesPBC
else:
wantWrap = self._usesPBC
if not report[1]:
either.append((reporter, report))
elif wantWrap:
wrapped.append((reporter, report))
else:
unwrapped.append((reporter, report))
if len(wrapped) > len(unwrapped):
wrapped += either
else:
unwrapped += either
# Generate the reports.
if len(wrapped) > 0:
self._generate_reports(wrapped, True)
if len(unwrapped) > 0:
self._generate_reports(unwrapped, False)
def _generate_reports(self, reports, periodic):
getPositions = False
getVelocities = False
getForces = False
getEnergy = False
for reporter, next in zip(self.reporters, nextReport):
if next[0] == nextSteps:
for reporter, next in reports:
if next[1]:
getPositions = True
if next[2]:
......@@ -213,9 +249,8 @@ class Simulation(object):
if next[4]:
getEnergy = True
state = self.context.getState(getPositions=getPositions, getVelocities=getVelocities, getForces=getForces,
getEnergy=getEnergy, getParameters=True, enforcePeriodicBox=self._usesPBC)
for reporter, next in zip(self.reporters, nextReport):
if next[0] == nextSteps:
getEnergy=getEnergy, getParameters=True, enforcePeriodicBox=periodic)
for reporter, next in reports:
reporter.report(self, state)
def saveCheckpoint(self, file):
......
......@@ -315,6 +315,19 @@ class SwigInputBuilder:
self.fOut.write(",\n OpenMM::%s" % name)
self.fOut.write(");\n\n")
for classNode in self._orderedClassNodes:
methodList=getClassMethodList(classNode, self.skipMethods)
for items in methodList:
(shortClassName, memberNode,
shortMethDefinition, methName,
isConstructors, isDestructor, templateType, templateName) = items
if shortMethDefinition == 'TabulatedFunction& getTabulatedFunction':
self.fOut.write("%factory(OpenMM::TabulatedFunction& OpenMM::")
self.fOut.write("%s::%s" % (shortClassName, methName))
for name in sorted(tabulatedFunctionSubclassList):
self.fOut.write(",\n OpenMM::%s" % name)
self.fOut.write(");\n\n")
self.fOut.write("%factory(OpenMM::VirtualSite& OpenMM::System::getVirtualSite, OpenMM::TwoParticleAverageSite, OpenMM::ThreeParticleAverageSite, OpenMM::OutOfPlaneSite, OpenMM::LocalCoordinatesSite);\n\n")
self.fOut.write("\n")
......
......@@ -67,8 +67,9 @@ class TestPatches(unittest.TestCase):
self.assertEqual(0, patch.addedExternalBonds[0].residue)
self.assertEqual('C', patch.deletedExternalBonds[0].name)
self.assertEqual(0, patch.deletedExternalBonds[0].residue)
self.assertEqual('Test', ff._templatePatches['RES'][0][0])
self.assertEqual(0, ff._templatePatches['RES'][0][1])
patch = list(ff._templatePatches['RES'])[0]
self.assertEqual('Test', patch[0])
self.assertEqual(0, patch[1])
def testParseMultiresiduePatch(self):
"""Test parsing a <Patch> tag that affects two residues."""
......@@ -110,10 +111,12 @@ class TestPatches(unittest.TestCase):
self.assertEqual(0, patch.addedBonds[0][0].residue)
self.assertEqual('B', patch.addedBonds[0][1].name)
self.assertEqual(1, patch.addedBonds[0][1].residue)
self.assertEqual('Test', ff._templatePatches['RESA'][0][0])
self.assertEqual(0, ff._templatePatches['RESA'][0][1])
self.assertEqual('Test', ff._templatePatches['RESB'][0][0])
self.assertEqual(1, ff._templatePatches['RESB'][0][1])
patchA = list(ff._templatePatches['RESA'])[0]
self.assertEqual('Test', patchA[0])
self.assertEqual(0, patchA[1])
patchB = list(ff._templatePatches['RESB'])[0]
self.assertEqual('Test', patchB[0])
self.assertEqual(1, patchB[1])
def testApplyPatch(self):
"""Test applying a patch to a template."""
......
......@@ -133,5 +133,21 @@ class TestPdbxFile(unittest.TestCase):
self.assertEqual(bond1[0].name, bond2[0].name)
self.assertEqual(bond1[1].name, bond2[1].name)
def testMultiChain(self):
"""Test reading and writing a file that includes multiple chains"""
cif_ori = PDBxFile('systems/multichain.pdbx')
output = StringIO()
PDBxFile.writeFile(cif_ori.topology, cif_ori.positions, output, keepIds=True)
input = StringIO(output.getvalue())
cif_new = PDBxFile(input)
output.close()
input.close()
self.assertEqual(cif_ori.topology.getNumChains(), cif_new.topology.getNumChains())
for chain1, chain2 in zip(cif_ori.topology.chains(), cif_new.topology.chains()):
self.assertEqual(chain1.id, chain2.id)
if __name__ == '__main__':
unittest.main()
......@@ -157,6 +157,38 @@ class TestSimulation(unittest.TestCase):
simulation.loadState(stateFile)
self.assertEqual(velocities, simulation.context.getState(getVelocities=True).getVelocities())
def testWrappedCoordinates(self):
"""Test generating reports with and without wrapped coordinates."""
pdb = PDBFile('systems/alanine-dipeptide-explicit.pdb')
ff = ForceField('amber99sb.xml', 'tip3p.xml')
system = ff.createSystem(pdb.topology, nonbondedMethod=CutoffPeriodic, constraints=HBonds)
integrator = LangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds)
class CompareCoordinatesReporter(object):
def __init__(self, periodic):
self.periodic = periodic
self.interval = 100
def describeNextReport(self, simulation):
steps = self.interval - simulation.currentStep%self.interval
return (steps, True, False, False, False, self.periodic)
def report(self, simulation, state):
state2 = simulation.context.getState(getPositions=True, enforcePeriodicBox=self.periodic)
assert state.getPositions() == state2.getPositions()
# Create a Simulation.
simulation = Simulation(pdb.topology, system, integrator)
simulation.context.setPositions(pdb.positions)
simulation.context.setVelocitiesToTemperature(300*kelvin)
simulation.reporters.append(CompareCoordinatesReporter(False))
simulation.reporters.append(CompareCoordinatesReporter(True))
# Run for a little while and make sure the reporters don't find any problems.
simulation.step(500)
if __name__ == '__main__':
unittest.main()
# dummy file with multiple chains
# fragment of 1brs
#
data_1brs_AD
_entry.id 1brs_AD
#
loop_
_atom_site.group_PDB
_atom_site.id
_atom_site.type_symbol
_atom_site.label_atom_id
_atom_site.label_alt_id
_atom_site.label_comp_id
_atom_site.label_asym_id
_atom_site.label_entity_id
_atom_site.label_seq_id
_atom_site.pdbx_PDB_ins_code
_atom_site.Cartn_x
_atom_site.Cartn_y
_atom_site.Cartn_z
_atom_site.occupancy
_atom_site.B_iso_or_equiv
_atom_site.pdbx_formal_charge
_atom_site.auth_asym_id
_atom_site.pdbx_PDB_model_num
ATOM 1 N N . VAL A 1 3 ? 16.783 48.812 26.447 1.00 30.15 0 A 1
ATOM 2 C CA . VAL A 1 3 ? 17.591 48.101 25.416 1.00 27.93 0 A 1
ATOM 3 C C . VAL A 1 3 ? 16.643 47.160 24.676 1.00 25.52 0 A 1
ATOM 4 O O . VAL A 1 3 ? 16.213 46.129 25.220 1.00 26.86 0 A 1
ATOM 5 C CB . VAL A 1 3 ? 18.813 47.329 25.940 1.00 28.10 0 A 1
ATOM 6 C CG1 . VAL A 1 3 ? 19.512 46.623 24.799 1.00 29.27 0 A 1
ATOM 7 C CG2 . VAL A 1 3 ? 19.838 48.188 26.670 1.00 28.76 0 A 1
ATOM 8 N N . ILE A 1 4 ? 16.327 47.509 23.466 1.00 23.19 0 A 1
ATOM 9 C CA . ILE A 1 4 ? 15.435 46.625 22.666 1.00 21.26 0 A 1
ATOM 10 C C . ILE A 1 4 ? 16.364 45.902 21.716 1.00 19.99 0 A 1
ATOM 11 O O . ILE A 1 4 ? 16.847 46.590 20.823 1.00 18.74 0 A 1
ATOM 12 C CB . ILE A 1 4 ? 14.415 47.516 21.981 1.00 22.04 0 A 1
ATOM 13 C CG1 . ILE A 1 4 ? 13.710 48.294 23.129 1.00 22.39 0 A 1
ATOM 14 C CG2 . ILE A 1 4 ? 13.485 46.762 21.052 1.00 19.05 0 A 1
ATOM 15 C CD1 . ILE A 1 4 ? 12.870 49.416 22.486 1.00 23.20 0 A 1
ATOM 16 N N . LYS D 2 1 ? 48.330 40.393 9.798 1.00 29.18 0 D 1
ATOM 17 C CA . LYS D 2 1 ? 47.401 39.287 9.370 1.00 29.51 0 D 1
ATOM 18 C C . LYS D 2 1 ? 47.507 38.911 7.890 1.00 28.30 0 D 1
ATOM 19 O O . LYS D 2 1 ? 47.126 39.582 6.905 1.00 28.68 0 D 1
ATOM 20 C CB . LYS D 2 1 ? 45.995 39.632 9.817 1.00 31.06 0 D 1
ATOM 21 C CG . LYS D 2 1 ? 44.801 38.778 9.587 1.00 34.24 0 D 1
ATOM 22 C CD . LYS D 2 1 ? 44.946 37.289 9.712 1.00 37.99 0 D 1
ATOM 23 C CE . LYS D 2 1 ? 44.733 36.789 11.137 1.00 39.74 0 D 1
ATOM 24 N NZ . LYS D 2 1 ? 44.858 35.301 11.250 1.00 39.95 1 D 1
ATOM 25 N N . LYS D 2 2 ? 48.047 37.742 7.642 1.00 26.22 0 D 1
ATOM 26 C CA . LYS D 2 2 ? 48.270 37.151 6.331 1.00 25.12 0 D 1
ATOM 27 C C . LYS D 2 2 ? 47.509 35.851 6.169 1.00 24.31 0 D 1
ATOM 28 O O . LYS D 2 2 ? 47.675 35.055 7.114 1.00 25.51 0 D 1
ATOM 29 C CB . LYS D 2 2 ? 49.764 36.810 6.325 1.00 25.77 0 D 1
ATOM 30 C CG . LYS D 2 2 ? 50.121 35.923 5.159 1.00 27.71 0 D 1
ATOM 31 C CD . LYS D 2 2 ? 50.197 36.783 3.916 1.00 28.44 0 D 1
ATOM 32 C CE . LYS D 2 2 ? 50.902 36.036 2.805 1.00 30.19 0 D 1
ATOM 33 N NZ . LYS D 2 2 ? 52.379 36.102 2.952 1.00 31.01 1 D 1
HETATM 34 O O . HOH G 3 111 ? 25.978 40.412 17.662 1.00 16.91 0 A 1
HETATM 35 O O . HOH G 3 112 ? 24.196 43.521 11.471 1.00 13.10 0 A 1
HETATM 36 O O . HOH J 3 91 ? 25.995 40.067 5.614 1.00 11.53 0 D 1
HETATM 37 O O . HOH J 3 92 ? 36.372 43.366 10.462 1.00 17.15 0 D 1
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