Skip to content
Merged
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,12 @@ See the corresponding directories for information on how to use the provided con

# Changelog

## 0.10.0 Updates for OpenMM 7.6 and AMBER GLYCAM addition
This release adds support for the AMBER GLYCAM force field supporting glycans and updates imports for OpenMM 7.6.

* [(PR #156)](https://github.com/openmm/openmmforcefields/pull/156) Add support for GLYCAM
* [(PR #173)](https://github.com/openmm/openmmforcefields/pull/173) Update to OpenMM 7.6 imports

## 0.9.0 Updates for openforcefield 0.9.0 toolkit
This release utilizes the new [openforcefield 0.9.0 toolkit](https://open-forcefield-toolkit.readthedocs.io/en/0.9.0/) now distributed through [conda-forge](https://conda-forge.org/).

Expand Down
26 changes: 13 additions & 13 deletions amber/convert_amber.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
from __future__ import print_function, division
from io import StringIO
import parmed
from simtk import openmm
import simtk.openmm.app as app
import simtk.unit as u
import simtk
from parmed.utils.six import iteritems
from parmed.utils.six.moves import StringIO, zip
import openmm.app as app
import openmm.unit as u
import os
import sys
import re
Expand Down Expand Up @@ -380,7 +380,7 @@ def convert_yaml(yaml_name, ffxml_dir, ignore=ignore):
for source_file in source_files:
if MODE == 'LEAPRC':
if os.path.exists(source_file):
_filename = os.path.join('./', source_file)
_filename = os.path.join('./', source_file)
else:
_filename = os.path.join(AMBERHOME, 'dat/leap/cmd', source_file)
elif MODE == 'RECIPE':
Expand Down Expand Up @@ -621,7 +621,7 @@ def add_prefix_to_ffxml(ffxml_filename, prefix):

def assert_energies_glyco_protein(prmtop, inpcrd, ffxml, tolerance=1e-1):
import math

# Get AMBER system
parm_amber = parmed.load_file(prmtop, inpcrd)
system_amber = parm_amber.createSystem()
Expand Down Expand Up @@ -660,7 +660,7 @@ def compute_potential_components(system, positions, beta=beta):
system = deepcopy(system)
for index in range(system.getNumForces()):
force = system.getForce(index)
force.setForceGroup(index)
force.setForceGroup(index)
integrator = openmm.VerletIntegrator(1.0*u.femtosecond)
platform = openmm.Platform.getPlatformByName('Reference')
context = openmm.Context(system, integrator, platform)
Expand Down Expand Up @@ -710,7 +710,7 @@ def assert_energies(prmtop, inpcrd, ffxml, system_name='unknown', tolerance=2.5e
system_omm = parm_omm.createSystem(splitDihedrals=True)
omm_energies = parmed.openmm.energy_decomposition_system(parm_omm,
system_omm, nrg=units, platform='Reference')

# calc rel energies and assert
energies = []
rel_energies = []
Expand Down Expand Up @@ -1399,9 +1399,9 @@ def modify_glycan_ffxml(input_ffxml_path):
bond.attrib['type1'] = bond.attrib['class1']
bond.attrib['type2'] = bond.attrib['class2']
del bond.attrib['class1']
del bond.attrib['class2']
del bond.attrib['class2']

# Fix prefixes
# Fix prefixes
types = [bond.get('type1'), bond.get('type2')]
if any(t in glycam_types for t in types):
bond.set('type1', replacements[types[0]])
Expand Down Expand Up @@ -1446,7 +1446,7 @@ def modify_glycan_ffxml(input_ffxml_path):
del torsion.attrib['class4']
if torsion.attrib['type1'] == 'NH' and torsion.attrib['type2'] == 'Cg' and torsion.attrib['type3'] == 'Cg' and torsion.attrib['type4'] == 'Sm':
force.remove(torsion)
continue
continue

# Fix prefixes
types = [torsion.get('type1'), torsion.get('type2'), torsion.get('type3'), torsion.get('type4')]
Expand All @@ -1465,7 +1465,7 @@ def modify_glycan_ffxml(input_ffxml_path):
# Change attributes from class to type
atom.attrib['type'] = atom.attrib['class']
del atom.attrib['class']

# Fix prefixes
type = atom.get('type')
if type in glycam_types:
Expand Down Expand Up @@ -1493,7 +1493,7 @@ def modify_glycan_ffxml(input_ffxml_path):

# Add initialization script for setting up GlycamTemplateMatcher
initialization_script = etree.SubElement(root, 'InitializationScript')
initialization_script.text = """
initialization_script.text = """
class GlycamTemplateMatcher(object):
def __init__(self, glycam_residues):
self.glycam_residues = glycam_residues
Expand Down
6 changes: 3 additions & 3 deletions charmm/convert_charmm.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
from collections import OrderedDict
import hashlib
import os
import simtk.openmm.app as app
import simtk.openmm as mm
import simtk.unit as u
import openmm.app as app
import openmm as mm
import openmm.unit as u
import argparse
import csv
import logging
Expand Down
2 changes: 1 addition & 1 deletion devtools/conda-envs/test_env.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ dependencies:
- codecov

# Requirements for converted force field installer
- openmm >=7.4.2
- openmm >=7.6.0

# Requirements for conversion tools
- pyyaml
Expand Down
30 changes: 15 additions & 15 deletions openmmforcefields/generators/system_generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import logging
_logger = logging.getLogger("openmmforcefields.system_generators")

from simtk.openmm import app
from openmm import app

################################################################################
# System generator base class
Expand Down Expand Up @@ -42,19 +42,19 @@ class SystemGenerator(object):

Parameters
----------
forcefield : simtk.openmm.app.ForceField
forcefield : openmm.app.ForceField
The ForceField object used to create new System objects.
New ffxml files can be read in at any time.
forcefield_kwargs : dict
Keyword arguments fed to ``simtk.openmm.app.ForceField.createSystem()`` during System generation.
Keyword arguments fed to ``openmm.app.ForceField.createSystem()`` during System generation.
These keyword arguments can be modified at any time.
periodic_forcefield_kwargs : dict
Keyword arguments fed to ``simtk.openmm.app.ForceField.createSystem()`` during System generation for periodic systems.
Keyword arguments fed to ``openmm.app.ForceField.createSystem()`` during System generation for periodic systems.
These keyword arguments can be modified at any time.
nonperiodic_forcefield_kwargs : dict
Keyword arguments fed to ``simtk.openmm.app.ForceField.createSystem()`` during System generation for non-periodic systems.
Keyword arguments fed to ``openmm.app.ForceField.createSystem()`` during System generation for non-periodic systems.
These keyword arguments can be modified at any time.
barostat : simtk.openmm.MonteCarloBarostat
barostat : openmm.MonteCarloBarostat
If not None, this container holds the barostat parameters to use for newly created System objects.
molecules : openff.toolkit.topology.Molecule or list, optional, default=None
Can alternatively be an object (such as an OpenEye OEMol or RDKit Mol or SMILES string) that can be used to construct a Molecule.
Expand Down Expand Up @@ -85,12 +85,12 @@ def __init__(self, forcefields=None, small_molecule_forcefield='openff-1.0.0', f
Supported SMIRNOFF force fields include: [`openff-1.0.0`, `smirnoff99Frosst-1.1.0`]
(See ``SMIRNOFFTemplateGenerator.INSTALLED_FORCEFIELDS`` for a complete list.)
forcefield_kwargs : dict, optional, default=None
Keyword arguments to be passed to ``simtk.openmm.app.ForceField.createSystem()`` during ``System`` object creation.
Keyword arguments to be passed to ``openmm.app.ForceField.createSystem()`` during ``System`` object creation.
nonperiodic_forcefield_kwargs : dict, optional, default={'nonbondedMethod' : NoCutoff}
Keyword arguments added to forcefield_kwargs when the Topology is non-periodic.
periodic_forcefield_kwargs : NonbondedMethod, optional, default={'nonbondedMethod' : PME}
Keyword arguments added to forcefield_kwargs when the Topology is periodic.
barostat : simtk.openmm.MonteCarloBarostat, optional, default=None
barostat : openmm.MonteCarloBarostat, optional, default=None
If not None, a new ``MonteCarloBarostat`` with matching parameters (but a different random number seed) will be created and
added to each newly created ``System``.
molecules : openff.toolkit.topology.Molecule or list, optional, default=None
Expand All @@ -111,12 +111,12 @@ def __init__(self, forcefields=None, small_molecule_forcefield='openff-1.0.0', f
`Open Force Field Topology <https://open-forcefield-toolkit.readthedocs.io/en/latest/api/generated/openff.toolkit.topology.Topology.html#openff.toolkit.topology.Topology>`_ object:

>>> # Define the keyword arguments to feed to ForceField
>>> from simtk import unit
>>> from simtk.openmm import app
>>> from openmm import unit
>>> from openmm import app
>>> # Define standard OpenMM biopolymer and solvent force fields to use

To initialize the ``SystemGenerator``, we specify the OpenMM force fields, the small molecule force field, and any ``kwargs`` to be fed
to the OpenMM ``simtk.openmm.app.ForceField.createSystem()`` method:
to the OpenMM ``openmm.app.ForceField.createSystem()`` method:

>>> from openmmforcefields.generators import SystemGenerator
>>> amber_forcefields = ['amber/protein.ff14SB.xml', 'amber/tip3p_standard.xml', 'amber/tip3p_HFE_multivalent.xml']
Expand Down Expand Up @@ -173,7 +173,7 @@ def __init__(self, forcefields=None, small_molecule_forcefield='openff-1.0.0', f

# Create OpenMM ForceField object
forcefields = forcefields if (forcefields is not None) else list()
from simtk.openmm import app
from openmm import app
self.forcefield = app.ForceField(*forcefields)

# Cache force fields and settings to use
Expand Down Expand Up @@ -244,7 +244,7 @@ def _modify_forces(self, system):
# Add barostat if requested.
if self.barostat is not None:
import numpy as np
from simtk import openmm
import openmm
MAXINT = np.iinfo(np.int32).max

# Determine pressure, temperature, and frequency
Expand Down Expand Up @@ -304,7 +304,7 @@ def create_system(self, topology, molecules=None):

Returns
-------
system : simtk.openmm.System
system : openmm.System
A system object generated from the topology

"""
Expand Down Expand Up @@ -363,7 +363,7 @@ def create_system(self, topology, **kwargs):

Returns
-------
system : simtk.openmm.System
system : openmm.System
The System object

"""
Expand Down
40 changes: 20 additions & 20 deletions openmmforcefields/generators/template_generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def _match_residue(residue, molecule_template):

Parameters
----------
residue : simtk.openmm.app.topology.Residue
residue : openmm.app.topology.Residue
The residue to check
molecule_template : openff.toolkit.topology.Molecule
The Molecule template to compare it to
Expand Down Expand Up @@ -218,7 +218,7 @@ def _molecule_has_user_charges(self, molecule):

"""
import numpy as np
from simtk import unit
from openmm import unit
zeros = np.zeros([molecule.n_particles])
if (molecule.partial_charges is None) or (np.allclose(molecule.partial_charges / unit.elementary_charge, zeros)):
charges_are_zero = True
Expand All @@ -244,13 +244,13 @@ def _generate_unique_atom_names(self, molecule):

def generator(self, forcefield, residue):
"""
Residue template generator method to register with simtk.openmm.app.ForceField
Residue template generator method to register with openmm.app.ForceField

Parameters
----------
forcefield : simtk.openmm.app.ForceField
forcefield : openmm.app.ForceField
The ForceField object to which residue templates and/or parameters are to be added.
residue : simtk.openmm.app.Topology.Residue
residue : openmm.app.Topology.Residue
The residue topology for which a template is to be generated.

Returns
Expand Down Expand Up @@ -355,7 +355,7 @@ class GAFFTemplateGenerator(SmallMoleculeTemplateGenerator):
>>> from openmoltools.forcefield_generators import GAFFTemplateGenerator
>>> template_generator = GAFFTemplateGenerator(molecules=molecule)
>>> # Create an OpenMM ForceField
>>> from simtk.openmm.app import ForceField
>>> from openmm.app import ForceField
>>> amber_forcefields = ['amber/protein.ff14SB.xml', 'amber/tip3p_standard.xml', 'amber/tip3p_HFE_multivalent.xml']
>>> forcefield = ForceField(*amber_forcefields)
>>> # Register the template generator
Expand Down Expand Up @@ -416,7 +416,7 @@ def __init__(self, molecules=None, forcefield=None, cache=None):
>>> molecule = Molecule.from_smiles('c1ccccc1')
>>> from openmoltools.forcefield_generators import GAFFTemplateGenerator
>>> gaff = GAFFTemplateGenerator(molecules=molecule)
>>> from simtk.openmm.app import ForceField
>>> from openmm.app import ForceField
>>> amber_forcefields = ['amber/protein.ff14SB.xml', 'amber/tip3p_standard.xml', 'amber/tip3p_HFE_multivalent.xml']
>>> forcefield = ForceField(*amber_forcefields)
>>> forcefield.registerTemplateGenerator(gaff)
Expand Down Expand Up @@ -462,7 +462,7 @@ def __init__(self, molecules=None, forcefield=None, cache=None):
# Store user-specified GAFF version
self._forcefield = forcefield
import re
result = re.match('^gaff-(?P<major_version>\d+)\.(?P<minor_version>\d+)$', forcefield)
result = re.match(r'^gaff-(?P<major_version>\d+)\.(?P<minor_version>\d+)$', forcefield)
if result is None:
msg = "'forcefield' must be of form 'gaff-X.Y', where X and Y denote major and minor version\n"
msg += f"Provided 'forcefield' argument was '{forcefield}'\n"
Expand Down Expand Up @@ -509,13 +509,13 @@ def gaff_xml_filename(self):

def generator(self, forcefield, residue):
"""
Residue template generator method to register with simtk.openmm.app.ForceField
Residue template generator method to register with openmm.app.ForceField

Parameters
----------
forcefield : simtk.openmm.app.ForceField
forcefield : openmm.app.ForceField
The ForceField object to which residue templates and/or parameters are to be added.
residue : simtk.openmm.app.Topology.Residue
residue : openmm.app.Topology.Residue
The residue topology for which a template is to be generated.

Returns
Expand Down Expand Up @@ -570,7 +570,7 @@ def generate_residue_template(self, molecule, residue_atoms=None):

# Compute net formal charge
net_charge = molecule.total_charge
from simtk import unit
from openmm import unit
if type(net_charge) != unit.Quantity:
# openforcefield toolkit < 0.7.0 did not return unit-bearing quantity
net_charge = float(net_charge) * unit.elementary_charge
Expand Down Expand Up @@ -621,7 +621,7 @@ def generate_residue_template(self, molecule, residue_atoms=None):
# or pure numbers.
_logger.debug(f'Fixing partial charges...')
_logger.debug(f'{molecule.partial_charges}')
from simtk import unit
from openmm import unit
residue_charge = 0.0 * unit.elementary_charge
total_charge = unit.sum(molecule.partial_charges)
sum_of_absolute_charge = unit.sum(abs(molecule.partial_charges))
Expand Down Expand Up @@ -889,7 +889,7 @@ class SMIRNOFFTemplateGenerator(SmallMoleculeTemplateGenerator):
>>> from openmoltools.forcefield_generators import SMIRNOFFTemplateGenerator
>>> template_generator = SMIRNOFFTemplateGenerator(molecules=molecule)
>>> # Create an OpenMM ForceField
>>> from simtk.openmm.app import ForceField
>>> from openmm.app import ForceField
>>> amber_forcefields = ['amber/protein.ff14SB.xml', 'amber/tip3p_standard.xml', 'amber/tip3p_HFE_multivalent.xml']
>>> forcefield = ForceField(*amber_forcefields)
>>> # Register the template generator
Expand Down Expand Up @@ -947,7 +947,7 @@ def __init__(self, molecules=None, cache=None, forcefield=None):
>>> molecule = Molecule.from_smiles('c1ccccc1')
>>> from openmoltools.forcefield_generators import SMIRNOFFTemplateGenerator
>>> smirnoff = SMIRNOFFTemplateGenerator(molecules=molecule)
>>> from simtk.openmm.app import ForceField
>>> from openmm.app import ForceField
>>> amber_forcefields = ['amber/protein.ff14SB.xml', 'amber/tip3p_standard.xml', 'amber/tip3p_HFE_multivalent.xml']
>>> forcefield = ForceField(*amber_forcefields)

Expand Down Expand Up @@ -1099,7 +1099,7 @@ def get_openmm_system(self, molecule):

Returns
-------
system : simtk.openmm.System or None
system : openmm.System or None
If the Molecule object has already been parameterized by this instance, this molecule is returned.
Otherwise, None is returned.
"""
Expand Down Expand Up @@ -1161,13 +1161,13 @@ def generate_residue_template(self, molecule, residue_atoms=None):
root = etree.Element("ForceField")

def as_attrib(quantity):
"""Format simtk.unit.Quantity as XML attribute."""
"""Format openmm.unit.Quantity as XML attribute."""
if isinstance(quantity, str):
return quantity
elif isinstance(quantity, float) or isinstance(quantity, int):
return str(quantity)
else:
from simtk import unit
from openmm import unit
return str(quantity.value_in_unit_system(unit.md_unit_system))

# Append unique type names to atoms
Expand Down Expand Up @@ -1208,7 +1208,7 @@ def classes(particle_indices):

# Round parameters using strings for ease of comparison
# DEBUG
#from simtk import unit
#from openmm import unit
#def round_quantity(quantity):
# NDECIMALS = 3
# value = quantity.value_in_unit_system(unit.md_unit_system)
Expand Down Expand Up @@ -1288,7 +1288,7 @@ def torsion_tag(particle_indices):

# Create residue definitions
# TODO: Handle non-Atom particles too (virtual sites)
from simtk import unit
from openmm import unit
residues = etree.SubElement(root, "Residues")
residue = etree.SubElement(residues, "Residue", name=smiles)
for particle_index, particle in enumerate(molecule.particles):
Expand Down
Loading