Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update for openforcefield 0.7.1 toolkit release #128

Merged
merged 3 commits into from
Jul 22, 2020
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
21 changes: 12 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ This repository provides support for AMBER and CHARMM force fields and small mol

**CHARMM:** Non-polarizable protein, nucleic acid, and pre-parameterized small molecule force fields available in in the [Aug 2015 CHARMM36 force field release from the Mackerell website](http://mackerell.umaryland.edu/charmm_ff.shtml). *Note that this conversion has not yet been fully validated.*

**Open Force Field Initiative force fields:** All distributed [Open Force Field Initiative](http://openforcefield.org) force fields, including the `smirnoff99Frosst` series and [`openff-1.0.0` ("Parsley")](https://openforcefield.org/news/introducing-openforcefield-1.0/). *This support is experimental since it requires a development version of OpenMM 7.5.0.*
**Open Force Field Initiative force fields:** All distributed [Open Force Field Initiative](http://openforcefield.org) force fields, including the `smirnoff99Frosst` series and [`openff-1.x.y` ("Parsley")](https://openforcefield.org/news/introducing-openforcefield-1.0/) series of force fields available through the [`openforcefields`](http://github.com/openforcefield/openforcefields) repository. This is now supported in OpenMM 7.4.2 and later.

# Using the force fields

Expand Down Expand Up @@ -157,7 +157,7 @@ Newly parameterized molecules will be written to the cache, saving time next tim
## Using the Open Force Field Initiative SMIRNOFF small molecule force fields

The `openmmforcefields` package includes a [residue template generator](http://docs.openmm.org/latest/userguide/application.html#adding-residue-template-generators) for [the OpenMM `ForceField` class](http://docs.openmm.org/latest/api-python/generated/simtk.openmm.app.forcefield.ForceField.html#simtk.openmm.app.forcefield.ForceField) that automatically generates OpenMM residue templates for small molecules lacking parameters using the [Open Force Field Initiative](http://openforcefield.org) [SMIRNOFF](https://open-forcefield-toolkit.readthedocs.io/en/0.6.0/smirnoff.html) small molecule force fields.
This includes the [`openff-1.0.0` ("Parsley")](https://openforcefield.org/news/introducing-openforcefield-1.0/) small molecule force field, as well as newer versions of this force field.
This includes the [`openff-1.0.0` ("Parsley")](https://openforcefield.org/news/introducing-openforcefield-1.0/) small molecule force field, as well as [newer versions of this force field](https://github.com/openforcefield/openforcefields).

The `SMIRNOFFTemplateGenerator` residue template generator operates in a manner very similar to `GAFFTemplateGenerator`, so we only highlight its differences here.

Expand All @@ -177,7 +177,7 @@ forcefield = ForceField('amber/protein.ff14SB.xml', 'amber/tip3p_standard.xml',
# Register the SMIRNOFF template generator
forcefield.registerTemplateGenerator(smirnoff.generator)
```
The latest official Open Force Field Initiative release ([`openff-1.0.0` ("Parsley")](https://openforcefield.org/news/introducing-openforcefield-1.0/)) is used if none is specified.
The latest official Open Force Field Initiative release ([`openff-1.2.0`](https://github.com/openforcefield/openforcefields) of the ["Parsley" small molecule force field](https://openforcefield.org/news/introducing-openforcefield-1.0/)) is used if none is specified.
You can check which SMIRNOFF force field is in use with
```python
>>> smirnoff.smirnoff_filename
Expand All @@ -188,10 +188,10 @@ Create a template generator for a specific SMIRNOFF force field for multiple mol
molecules = Molecule.from_file('molecules.sdf')
# Create a SMIRNOFF residue template generator from the official openff-1.0.0 release,
# which is installed automatically
smirnoff = SMIRNOFFTemplateGenerator(molecules=molecules, forcefield='openff-1.0.0')
smirnoff = SMIRNOFFTemplateGenerator(molecules=molecules, forcefield='openff-1.2.0')
# Create a SMIRNOFF residue template generator from the official smirnoff99Frosst-1.1.0 release,
# which is installed automatically
smirnoff = SMIRNOFFTemplateGenerator(molecules=molecules, forcefield='smirnoff99Frosst-1.1.0')
smirnoff = SMIRNOFFTemplateGenerator(molecules=molecules, forcefield='smirnoff99Frosst-1.2.0')
# Use a local .offxml file instead
smirnoff = SMIRNOFFTemplateGenerator(molecules=molecules, forcefield='local-file.offxml')
```
Expand All @@ -203,11 +203,11 @@ smirnoff.add_molecules([molecule1, molecule2])
To check which SMIRNOFF force fields are automatically installed, examine the `INSTALLED_FORCEFIELDS` attribute:
```python
>>> print(SMIRNOFFTemplateGenerator.INSTALLED_FORCEFIELDS)
['smirnoff99Frosst-1.1.0', 'openff-1.0.0']
['openff-1.0.1', 'openff-1.1.1', 'openff-1.0.0-RC1', 'openff-1.2.0', 'openff-1.1.0', 'openff-1.0.0', 'openff-1.0.0-RC2', 'smirnoff99Frosst-1.0.2', 'smirnoff99Frosst-1.0.0', 'smirnoff99Frosst-1.1.0', 'smirnoff99Frosst-1.0.4', 'smirnoff99Frosst-1.0.8', 'smirnoff99Frosst-1.0.6', 'smirnoff99Frosst-1.0.3', 'smirnoff99Frosst-1.0.1', 'smirnoff99Frosst-1.0.5', 'smirnoff99Frosst-1.0.9', 'smirnoff99Frosst-1.0.7']
```
You can optionally specify a file that contains a cache of pre-parameterized molecules:
```python
smirnoff = SMIRNOFFTemplateGenerator(cache='smirnoff-molecules.json', forcefield='openff-1.0.0')
smirnoff = SMIRNOFFTemplateGenerator(cache='smirnoff-molecules.json', forcefield='openff-1.2.0')
```
Newly parameterized molecules will be written to the cache, saving time next time these molecules are encountered.

Expand Down Expand Up @@ -244,13 +244,13 @@ system_generator = SystemGenerator(forcefields=['amber/ff14SB.xml', 'amber/tip3p
nonperiodic_forcefield_kwargs={'nonbondedMethod' : app.CutoffNonPeriodic})
```

To use the [Open Force Field `openff-1.0.0` ("Parsley") force field](https://openforcefield.org/news/introducing-openforcefield-1.0/) instead of GAFF 2.11, we would have instead specified `small_molecule_forcefield='openff-1.0.0'`.
To use the [Open Force Field `openff-1.2.0`](https://github.com/openforcefield/openforcefields), an update of the [Open Force Field ("Parsley") small molecule force field](https://openforcefield.org/news/introducing-openforcefield-1.0/) instead of GAFF 2.11, we would have instead specified `small_molecule_forcefield='openff-1.2.0'`.

# Frequently Asked Questions (FAQ)

**Q:** What is the minimum version of OpenMM required to use this package?
<br>
**A:** You need at least OpenMM 7.5.0 to use the `openmmforcefields` package.
**A:** You need at least OpenMM 7.4.2 to use the `openmmforcefields` package.

**Q:** Do you support the new [Amber ff19SB protein force field](https://chemrxiv.org/articles/ff19SB_Amino-Acid_Specific_Protein_Backbone_Parameters_Trained_Against_Quantum_Mechanics_Energy_Surfaces_in_Solution/8279681/1)?
<br>
Expand All @@ -269,6 +269,9 @@ See the corresponding directories for information on how to use the provided con

# Changelog

## 0.8.0 Updates for openforcefield 0.7.1 toolkit
* [(PR #128)](https://github.com/openmm/openmmforcefields/pull/128) Update README for openff-1.2.0 and use openforcefield 0.7.1 toolkit API for identifying installed force fields

## 0.7.5 Bugfix release
* [(PR #127)](https://github.com/openmm/openmmforcefields/pull/127) Fixes a bug where the wrong path was imported for logging; improves docstrings.

Expand Down
4 changes: 2 additions & 2 deletions devtools/conda-envs/test_env.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ dependencies:
- tinydb

# openforcefield toolkit and force fields
- openforcefield >=0.6.0
- openforcefields >=1.0.0
- openforcefield >=0.7.1
- openforcefields >=1.2.0

# OpenEye toolkits are only used to speed up testing; they are not required for use
- openeye-toolkits
41 changes: 17 additions & 24 deletions openmmforcefields/generators/template_generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -895,12 +895,12 @@ class SMIRNOFFTemplateGenerator(SmallMoleculeTemplateGenerator):
>>> # Register the template generator
>>> forcefield.registerTemplateGenerator(template_generator.generator)

Create a template generator for a specific pre-installed SMIRNOFF version ('openff-1.0.0')
Create a template generator for a specific pre-installed SMIRNOFF version ('openff-1.2.0')
and register multiple molecules:

>>> molecule1 = Molecule.from_smiles('c1ccccc1')
>>> molecule2 = Molecule.from_smiles('CCO')
>>> template_generator = SMIRNOFFTemplateGenerator(molecules=[molecule1, molecule2], forcefield='openff-1.0.0')
>>> template_generator = SMIRNOFFTemplateGenerator(molecules=[molecule1, molecule2], forcefield='openff-1.2.0')

Alternatively, you can specify a local .offxml file in the SMIRNOFF specification:

Expand Down Expand Up @@ -953,13 +953,13 @@ def __init__(self, molecules=None, cache=None, forcefield=None):

The latest Open Force Field Initiative release is used if none is specified.

>>> smirnof.forcefield
'openff-1.0.0'
>>> smirnoff.forcefield
'openff-1.2.0'

You can check which SMIRNOFF force field filename is in use with

>>> smirnoff.smirnoff_filename
'/full/path/to/openff-1.0.0.offxml'
'/full/path/to/openff-1.2.0.offxml'

Create a template generator for a specific SMIRNOFF force field for multiple
molecules read from an SDF file:
Expand All @@ -974,11 +974,11 @@ def __init__(self, molecules=None, cache=None, forcefield=None):
To check which SMIRNOFF versions are supported, check the `INSTALLED_FORCEFIELDS` attribute:

>>> print(SMIRNOFFTemplateGenerator.INSTALLED_FORCEFIELDS)
['smirnoff99Frosst-1.1.0', 'openff-1.0.0']
['openff-1.0.1', 'openff-1.1.1', 'openff-1.0.0-RC1', 'openff-1.2.0', 'openff-1.1.0', 'openff-1.0.0', 'openff-1.0.0-RC2', 'smirnoff99Frosst-1.0.2', 'smirnoff99Frosst-1.0.0', 'smirnoff99Frosst-1.1.0', 'smirnoff99Frosst-1.0.4', 'smirnoff99Frosst-1.0.8', 'smirnoff99Frosst-1.0.6', 'smirnoff99Frosst-1.0.3', 'smirnoff99Frosst-1.0.1', 'smirnoff99Frosst-1.0.5', 'smirnoff99Frosst-1.0.9', 'smirnoff99Frosst-1.0.7']

You can optionally create or use a cache of pre-parameterized molecules:

>>> smirnoff = SMIRNOFFTemplateGenerator(cache='smirnoff.json', forcefield='openff-1.0.0')
>>> smirnoff = SMIRNOFFTemplateGenerator(cache='smirnoff.json', forcefield='openff-1.2.0')

Newly parameterized molecules will be written to the cache, saving time next time!
"""
Expand All @@ -987,7 +987,9 @@ def __init__(self, molecules=None, cache=None, forcefield=None):

if forcefield is None:
# Use latest supported Open Force Field Initiative release if none is specified
forcefield = self.INSTALLED_FORCEFIELDS[-1]
forcefield = 'openff-1.2.0'
# TODO: After toolkit provides date-ranked force fields,
# use latest dated version if we can sort by date, such as self.INSTALLED_FORCEFIELDS[-1]
self._forcefield = forcefield

# Track parameters by provided SMIRNOFF name
Expand Down Expand Up @@ -1032,23 +1034,14 @@ def INSTALLED_FORCEFIELDS(cls):
https://github.com/openforcefield/openforcefield/issues/477

"""
# TODO: Replace this method once there is a public API in the openforcefield toolkit for doing this
# TODO: Impose some sort of ordering by preference?

from openforcefield.utils import get_data_file_path
from openforcefield.typing.engines.smirnoff.forcefield import _get_installed_offxml_dir_paths
from glob import glob

from openforcefield.typing.engines.smirnoff import get_available_force_fields
file_names = list()
for dir_path in _get_installed_offxml_dir_paths():
file_pattern = os.path.join(dir_path, '*.offxml')
file_paths = [file_path for file_path in glob(file_pattern)]
for file_path in file_paths:
basename = os.path.basename(file_path)
root, ext = os.path.splitext(basename)
# Only add variants without '_unconstrained'
if '_unconstrained' not in root:
file_names.append(root)
for filename in get_available_force_fields(full_paths=False):
root, ext = os.path.splitext(filename)
# Only add variants without '_unconstrained'
if '_unconstrained' not in root:
file_names.append(root)

return file_names

def _search_paths(self, filename):
Expand Down