Commit 95711b88 authored by huangj's avatar huangj
Browse files

Add a test case for the colinear lonepair facility in CHARMM psf parser.

parent cbbc7911
...@@ -714,7 +714,8 @@ class CharmmPsfFile(object): ...@@ -714,7 +714,8 @@ class CharmmPsfFile(object):
if atom.type is not None: if atom.type is not None:
# This is the most reliable way of determining the element # This is the most reliable way of determining the element
atomic_num = atom.type.atomic_number atomic_num = atom.type.atomic_number
elem = element.Element.getByAtomicNumber(atomic_num) if atomic_num != 0:
elem = element.Element.getByAtomicNumber(atomic_num)
else: else:
# Figure it out from the mass # Figure it out from the mass
elem = element.Element.getByMass(atom.mass) elem = element.Element.getByMass(atom.mass)
...@@ -911,33 +912,34 @@ class CharmmPsfFile(object): ...@@ -911,33 +912,34 @@ class CharmmPsfFile(object):
bond.bond_type.req*length_conv) bond.bond_type.req*length_conv)
# Add virtual sites # Add virtual sites
if verbose: print('Adding lonepairs...') if hasattr(self, 'lonepair_list'):
for lpsite in self.lonepair_list: if verbose: print('Adding lonepairs...')
index=lpsite[0] for lpsite in self.lonepair_list:
atom1=lpsite[1] index=lpsite[0]
atom2=lpsite[2] atom1=lpsite[1]
atom3=lpsite[3] atom2=lpsite[2]
if atom3 > 0: atom3=lpsite[3]
if lpsite[4] > 0 : # relative lonepair type if atom3 > 0:
r = lpsite[4] /10.0 # in nanometer if lpsite[4] > 0 : # relative lonepair type
xweights = [-1.0, 0.0, 1.0] r = lpsite[4] /10.0 # in nanometer
elif lpsite[4] < 0: # bisector lonepair type xweights = [-1.0, 0.0, 1.0]
r = lpsite[4] / (-10.0) elif lpsite[4] < 0: # bisector lonepair type
xweights = [-1.0, 0.5, 0.5] r = lpsite[4] / (-10.0)
theta = lpsite[5] * pi / 180.0 xweights = [-1.0, 0.5, 0.5]
phi = (180.0 - lpsite[6]) * pi / 180.0 theta = lpsite[5] * pi / 180.0
p = [r*cos(theta), r*sin(theta)*cos(phi), r*sin(theta)*sin(phi)] phi = (180.0 - lpsite[6]) * pi / 180.0
p = [x if abs(x) > 1e-10 else 0 for x in p] # Avoid tiny numbers caused by roundoff error p = [r*cos(theta), r*sin(theta)*cos(phi), r*sin(theta)*sin(phi)]
system.setVirtualSite(index, mm.LocalCoordinatesSite(atom1, atom3, atom2, mm.Vec3(1.0, 0.0, 0.0), mm.Vec3(xweights[0],xweights[1],xweights[2]), mm.Vec3(0.0, -1.0, 1.0), mm.Vec3(p[0],p[1],p[2]))) p = [x if abs(x) > 1e-10 else 0 for x in p] # Avoid tiny numbers caused by roundoff error
else: # colinear lonepair type system.setVirtualSite(index, mm.LocalCoordinatesSite(atom1, atom3, atom2, mm.Vec3(1.0, 0.0, 0.0), mm.Vec3(xweights[0],xweights[1],xweights[2]), mm.Vec3(0.0, -1.0, 1.0), mm.Vec3(p[0],p[1],p[2])))
# find a real atom to be the third one for LocalCoordinatesSite else: # colinear lonepair type
for bond in self.bond_list: # find a real atom to be the third one for LocalCoordinatesSite
if (bond.atom1.idx == atom2 and bond.atom2.idx != atom1): for bond in self.bond_list:
a3=bond.atom2.idx if (bond.atom1.idx == atom2 and bond.atom2.idx != atom1):
elif (bond.atom2.idx == atom2 and bond.atom1.idx != atom1): a3=bond.atom2.idx
a3=bond.atom1.idx elif (bond.atom2.idx == atom2 and bond.atom1.idx != atom1):
r = lpsite[4] / 10.0 # in nanometer a3=bond.atom1.idx
system.setVirtualSite(index, mm.LocalCoordinatesSite(atom1, atom2, a3, mm.Vec3(1.0, 0.0, 0.0), mm.Vec3(1.0,-1.0, 0.0), mm.Vec3(0.0, -1.0, 1.0), mm.Vec3(r,0.0,0.0))) r = lpsite[4] / 10.0 # in nanometer
system.setVirtualSite(index, mm.LocalCoordinatesSite(atom1, atom2, a3, mm.Vec3(1.0, 0.0, 0.0), mm.Vec3(1.0,-1.0, 0.0), mm.Vec3(0.0, -1.0, 1.0), mm.Vec3(r,0.0,0.0)))
# Add Bond forces # Add Bond forces
if verbose: print('Adding bonds...') if verbose: print('Adding bonds...')
force = mm.HarmonicBondForce() force = mm.HarmonicBondForce()
......
...@@ -141,17 +141,20 @@ class TestCharmmFiles(unittest.TestCase): ...@@ -141,17 +141,20 @@ class TestCharmmFiles(unittest.TestCase):
warnings.filterwarnings('ignore', category=CharmmPSFWarning) warnings.filterwarnings('ignore', category=CharmmPSFWarning)
psf = CharmmPsfFile('systems/chlb_cgenff.psf') psf = CharmmPsfFile('systems/chlb_cgenff.psf')
crd = CharmmCrdFile('systems/chlb_cgenff.crd') crd = CharmmCrdFile('systems/chlb_cgenff.crd')
# move the position of the lonepair on Cholride params = CharmmParameterSet('systems/top_all36_cgenff.rtf',
params = CharmmParameterSet('systems/par_all36_cgenff.prm', 'systems/par_all36_cgenff.prm')
'systems/top_all36_cgenff.rtf')
# Box dimensions (found from bounding box)
plat = Platform.getPlatformByName('Reference') plat = Platform.getPlatformByName('Reference')
system = psf.createSystem(params, nonbondedMethod=PME, system = psf.createSystem(params)
nonbondedCutoff=8*angstroms)
con = Context(system, VerletIntegrator(2*femtoseconds), plat) con = Context(system, VerletIntegrator(2*femtoseconds), plat)
con.setPositions(crd.positions) con.setPositions(crd.positions)
init_coor = con.getState(getPositions=True).getPositions()
# move the position of the lonepair and recompute its coordinates
crd.positions[12] = Vec3(0.5, 1.0, 1.5) * angstrom
con.setPositions(crd.positions)
con.computeVirtualSites()
new_coor = con.getState(getPositions=True).getPositions()
self.assertEqual(init_coor, new_coor)
def test_InsCode(self): def test_InsCode(self):
""" Test the parsing of PSF files that contain insertion codes in their residue numbers """ """ Test the parsing of PSF files that contain insertion codes in their residue numbers """
......
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