Commit fd1827e0 authored by Jason Swails's avatar Jason Swails
Browse files

Add a reducePeriodicBoxVectors function, since many helpers (like the one in

mdtraj) does *not* fully reduce the vectors.

Also adds a test for this.
parent 1004e6e5
...@@ -79,6 +79,24 @@ def computePeriodicBoxVectors(a_length, b_length, c_length, alpha, beta, gamma): ...@@ -79,6 +79,24 @@ def computePeriodicBoxVectors(a_length, b_length, c_length, alpha, beta, gamma):
b = b - a*round(b[0]/a[0]) b = b - a*round(b[0]/a[0])
return (a, b, c)*nanometers return (a, b, c)*nanometers
def reducePeriodicBoxVectors(periodicBoxVectors):
""" Reduces the representation of the PBC. periodicBoxVectors is expected to
be an unpackable iterable of length-3 iterables
"""
if is_quantity(periodicBoxVectors):
a, b, c = periodicBoxVectors.value_in_unit(nanometers)
else:
a, b, c = periodicBoxVectors
a = Vec3(*a)
b = Vec3(*b)
c = Vec3(*c)
c = c - b*round(c[1]/b[1])
c = c - a*round(c[0]/a[0])
b = b - a*round(b[0]/a[0])
return (a, b, c) * nanometers
def computeLengthsAndAngles(periodicBoxVectors): def computeLengthsAndAngles(periodicBoxVectors):
"""Convert periodic box vectors to lengths and angles. """Convert periodic box vectors to lengths and angles.
......
import unittest import unittest
import math import math
from simtk.openmm import Vec3
from simtk.unit import * from simtk.unit import *
from simtk.openmm.app.internal.unitcell import computePeriodicBoxVectors from simtk.openmm.app.internal.unitcell import computePeriodicBoxVectors
from simtk.openmm.app.internal.unitcell import computeLengthsAndAngles from simtk.openmm.app.internal.unitcell import computeLengthsAndAngles
from simtk.openmm.app.internal.unitcell import reducePeriodicBoxVectors
def strip_units(x): def strip_units(x):
if is_quantity(x): return x.value_in_unit_system(md_unit_system) if is_quantity(x): return x.value_in_unit_system(md_unit_system)
...@@ -12,6 +14,25 @@ class TestAmberPrmtopFile(unittest.TestCase): ...@@ -12,6 +14,25 @@ class TestAmberPrmtopFile(unittest.TestCase):
"""Test the AmberPrmtopFile.createSystem() method.""" """Test the AmberPrmtopFile.createSystem() method."""
def testReducePBCVectors(self):
""" Checks that reducePeriodicBoxVectors properly reduces vectors """
a = Vec3(4.24388485, 0.0, 0.0)
b = Vec3(-1.4146281691908937, 4.001173048368583, 0.0)
c = Vec3(-1.4146281691908937, -2.0005862820516203, 3.4651176446201674)
vecs = reducePeriodicBoxVectors((a, b, c)*nanometers)
vecs2 = computePeriodicBoxVectors(4.24388485, 4.24388485, 4.24388485,
109.4712190*degrees, 109.4712190*degrees, 109.4712190*degrees)
# Check that the vectors are the same
a1, a2, a3 = vecs
b1, b2, b3 = vecs2
for x, y in zip(a1, b1):
self.assertAlmostEqual(strip_units(x), strip_units(y))
for x, y in zip(a2, b2):
self.assertAlmostEqual(strip_units(x), strip_units(y))
for x, y in zip(a3, b3):
self.assertAlmostEqual(strip_units(x), strip_units(y))
def testComputePBCVectors(self): def testComputePBCVectors(self):
""" Tests computing periodic box vectors """ """ Tests computing periodic box vectors """
deg90 = 90 * degrees deg90 = 90 * degrees
......
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