Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
54 changes: 54 additions & 0 deletions .github/workflows/test_amber.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Amber conversion validation

on:
push:
branches:
- "main"
pull_request:
branches:
- "main"

defaults:
run:
shell: bash -l {0}

concurrency:
group: "${{ github.workflow }}-${{ github.ref }}"
cancel-in-progress: true

jobs:
test:
name: Test on ${{ matrix.os }}, Python ${{ matrix.python-version }}, OpenMM ${{ matrix.openmm-version }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
python-version: ["3.12"]
openmm-version: ["8.3.1"]

steps:
- uses: actions/checkout@v4

- name: Setup Conda Environment
uses: mamba-org/setup-micromamba@v2
with:
environment-file: devtools/conda-envs/test_env.yaml
create-args: >-
python=${{ matrix.python-version }}
openmm=${{ matrix.openmm-version }}

- name: Log into GitHub container registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# NOTE: Currently, testing the conversion itself is not done as the
# conversion requires multiple modifications to the internals of a
# particular version of ParmEd. But the output FFXML files do get tested:
- name: Test Amber conversion
run: |
./test_amber.py cases/* --sander --openmm-amber --openmm-ffxml
working-directory: ./amber/test/
12 changes: 11 additions & 1 deletion amber/biopolymer.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,15 @@
A Parameterization of Cholesterol for Mixed Lipid Bilayer Simulation within the Amber Lipid14 Force Field. J Phys Chem B, 2015, 119, 12424-12435.
Test:
- lipids
- Source: leaprc.lipid21
CharmmFFXMLFilename: ../openmmforcefields/ffxml/charmm/charmm36_nowaters.xml
CharmmLipid2AmberFilename: files/charmmlipid2amber.csv
Reference:
- >-
Dickson, C.J.; Walker, R.C.; Gould, I.R.
Lipid21: Complex Lipid Membrane Simulations with AMBER. J. Chem. Theory Comput., 2022, 18, 1726-1736.
Test:
- lipids
- Source: leaprc.protein.ff14SB
Prefix: protein
Options:
Expand Down Expand Up @@ -111,7 +120,7 @@
CMAPFRCMOD: files/ff19SB/frcmod.ff19SB_only_cmap
Prefix: protein
Options:
keep_types: ["P"]
keep_types: ["P", "OP"]
override_level:
HYP: 2
CHYP: 2
Expand Down Expand Up @@ -327,6 +336,7 @@
override_level:
HYP: 2
CHYP: 2
keep_types: ["OP"]
Reference:
- >-
Maier, J.A., Martinez, C., Kasavajhala, K., Wickstrom, L., Hauser, K.E., and Simmerling, C. (2015).
Expand Down
2 changes: 1 addition & 1 deletion amber/convert.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ set -e
python convert_amber_ions.py "${AMBERHOME}"
python convert_amber.py --input solvents.yaml --verbose
python convert_amber.py --input biopolymer.yaml --verbose
python convert_amber.py --input gaff.yaml --verbose
python convert_amber.py --input glycam/glycan.yaml --verbose
python convert_amber.py --combination-tests --verbose
python postprocess_amber.py
19 changes: 7 additions & 12 deletions amber/convert_amber.py
Original file line number Diff line number Diff line change
Expand Up @@ -1997,18 +1997,13 @@ def modify_glycan_ffxml(input_ffxml_path):
script = root.find("Script")
text = script.text

# Bad NH torsion
text_split = text.split("\n")
text_NH_removed = [line for line in text_split if "NH" not in line]
text = "\n".join(text_NH_removed)

# Unscaled types
pattern = re.compile("unscaled_types = set\\((\\[(.*\n)*?.*?\\])\\)")
match = pattern.search(text)
types = eval(match.group(1))
types = [(replacements[t[0]], replacements[t[1]], replacements[t[2]], replacements[t[3]]) for t in types]
types = ",\n ".join(str(t) for t in types)
script.text = pattern.sub(f"unscaled_types = set([{types}])", text)
text_lines = []
pattern = re.compile(r"(\(\s*')([^']*)('\s*,\s*')([^']*)('\s*,\s*')([^']*)('\s*,\s*')([^']*)('\s*(?:,\s*)?\)\s*:)")
for line in text.split("\n"):
if "NH" in line:
continue
text_lines.append(pattern.sub(lambda m: f"{m[1]}{replacements[m[2]]}{m[3]}{replacements[m[4]]}{m[5]}{replacements[m[6]]}{m[7]}{replacements[m[8]]}{m[9]}", line))
script.text = "\n".join(text_lines)

# Add initialization script for setting up GlycamTemplateMatcher
initialization_script = etree.SubElement(root, "InitializationScript")
Expand Down
131 changes: 0 additions & 131 deletions amber/gaff.yaml

This file was deleted.

30 changes: 30 additions & 0 deletions amber/postprocess_amber.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import io
import os
import lxml.etree as etree

FFXML_DIR = "../openmmforcefields/ffxml/amber"

def main():
"""
Apply miscellaneous fixes to generated FFXML files. It is better to do this
separately than to try to add yet another layer of complexity to the script
`convert_amber.py`. Eventually if this infrastructure can be replaced, and
such fixes are still required, the approach used in the CHARMM conversion
for patching can be employed.
"""

# Fix ACE and NME in ff03 and ff03r1:
for force_field in ("ff03", "protein.ff03.r1"):
path = os.path.join(FFXML_DIR, f"{force_field}.xml")
tree = etree.parse(path)
find_and_remove_xml_elements(tree.getroot(), tree.findall("./Residues/Residue[@name='ACE']/ExternalBond[@atomName='HH31']"))
find_and_remove_xml_elements(tree.getroot(), tree.findall("./Residues/Residue[@name='NME']/ExternalBond[@atomName='CH3']"))
tree.write(path)

def find_and_remove_xml_elements(root, target_elements):
root[:] = [child for child in root if child not in target_elements]
for child in root:
find_and_remove_xml_elements(child, target_elements)

if __name__ == "__main__":
main()
Loading
Loading