Skip to content

Commit

Permalink
Merge pull request #128 from openmm/update-readme
Browse files Browse the repository at this point in the history
Update for openforcefield 0.7.1 toolkit release
  • Loading branch information
jchodera authored Jul 22, 2020
2 parents 10bfed9 + 2118de7 commit 9df20b5
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 35 deletions.
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

0 comments on commit 9df20b5

Please sign in to comment.