"plugins/amoeba/vscode:/vscode.git/clone" did not exist on "8ecf9e35e3c1f0d9fa655c7a4d869d0fdbad6f2b"
Commit 58c63b05 authored by peastman's avatar peastman Committed by GitHub
Browse files

Merge pull request #1785 from peastman/include

ForceFields can include other files
parents 9976d0ce e0462958
...@@ -2937,6 +2937,32 @@ need to be specified once for each class. The atom charges, which are different ...@@ -2937,6 +2937,32 @@ need to be specified once for each class. The atom charges, which are different
for each type, are taken from the residue template instead. for each type, are taken from the residue template instead.
Including Other Files
=====================
Sometimes it is useful to split a force field definition into multiple files,
but still be able to use the force field by specifying only a single file. You
can accomplish this with the :code:`<Include>` tag. For example:
.. code-block:: xml
<ForceField>
<Include file="definitions.xml"/>
...
</ForceField>
The :code:`file` attribute gives the path of the file to include. It may be
relative either to the directory containing the parent XML file (the one with
the :code:`<Include>` tag) or the OpenMM data directory (the one containing
built in force fields).
The included file is fully processed before any other tags in the parent file
are processed, and its definitions are added to the force field. This means the
parent file can refer to atom types defined in the included file, but not the
other way around. If there are multiple :code:`<Include>` tags, they are processed
in the order they appear in the file.
Using Multiple Files Using Multiple Files
******************** ********************
......
...@@ -205,6 +205,19 @@ class ForceField(object): ...@@ -205,6 +205,19 @@ class ForceField(object):
trees.append(tree) trees.append(tree)
# Process includes.
for parentFile, tree in zip(files, trees):
if isinstance(parentFile, str):
parentDir = os.path.dirname(parentFile)
else:
parentDir = ''
for include in tree.getroot().findall('Include'):
includeFile = include.attrib['file']
joined = os.path.join(parentDir, includeFile)
if os.path.isfile(joined):
includeFile = joined
self.loadFile(includeFile)
# Load the atom types. # Load the atom types.
......
...@@ -762,6 +762,13 @@ class TestForceField(unittest.TestCase): ...@@ -762,6 +762,13 @@ class TestForceField(unittest.TestCase):
self.assertEqual('ALA', templates[0].name) self.assertEqual('ALA', templates[0].name)
self.assertEqual('NME', templates[1].name) self.assertEqual('NME', templates[1].name)
def test_Includes(self):
"""Test using a ForceField that includes other files."""
forcefield = ForceField(os.path.join('systems', 'ff_with_includes.xml'))
self.assertTrue(len(forcefield._atomTypes) > 10)
self.assertTrue('spce-O' in forcefield._atomTypes)
self.assertTrue('HOH' in forcefield._templates)
class AmoebaTestForceField(unittest.TestCase): class AmoebaTestForceField(unittest.TestCase):
"""Test the ForceField.createSystem() method with the AMOEBA forcefield.""" """Test the ForceField.createSystem() method with the AMOEBA forcefield."""
......
<ForceField>
<Include file="test_amber_ff.xml"/>
<Include file="spce.xml"/>
</ForceField>
\ No newline at end of file
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