From 33422effbbf5c44c84aece8690f94c11b23e4d5d Mon Sep 17 00:00:00 2001 From: John Chodera Date: Tue, 21 Jul 2020 15:58:31 -0700 Subject: [PATCH 1/3] Update README with openff info --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 882801a7..ad6d6e02 100644 --- a/README.md +++ b/README.md @@ -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 From 1ac495ab8e204fb31b57ba8275bedb22c8ccabbd Mon Sep 17 00:00:00 2001 From: John Chodera Date: Tue, 21 Jul 2020 17:31:28 -0700 Subject: [PATCH 2/3] Use new openforcefield 0.7.1 API for finding force fields --- README.md | 21 +++++----- devtools/conda-envs/test_env.yaml | 4 +- .../generators/template_generators.py | 41 ++++++++----------- 3 files changed, 30 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index ad6d6e02..740216b7 100644 --- a/README.md +++ b/README.md @@ -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.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. +**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 @@ -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. @@ -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 @@ -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') ``` @@ -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. @@ -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?
-**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)?
@@ -279,8 +279,9 @@ See the corresponding directories for information on how to use the provided con * [(PR #119)](https://github.com/openmm/openmmforcefields/pull/119) Handle `None` partial charges in openforcefield `Molecule` objects (needed in `openforcefield` toolkit 0.7.0) * [(PR #120)](https://github.com/openmm/openmmforcefields/pull/120) Auto-detect installed SMIRNOFF force fields -## 0.7.2 Bugfix release: More error checking; OpenMM 7.4.2 minimum version requirement +## 0.8.0 Auto-discover installed Open Force Field Initiative force fields; OpenMM 7.4.2 minimum version requirement +* Auto-discover available installed `openforcefield` force fields. * Raise a `ValueError` if `SystemGenerator` receives a `nonbondedMethod` key in `forcefield_kwargs`; these should go into `periodic_forcefield_kwargs` or `nonperiodic_forcefield_kwargs`. ## 0.7.1 Bugfix release: Fix GAFF AM1-BCC charging bug for some molecules diff --git a/devtools/conda-envs/test_env.yaml b/devtools/conda-envs/test_env.yaml index cc8e9704..593d0a51 100644 --- a/devtools/conda-envs/test_env.yaml +++ b/devtools/conda-envs/test_env.yaml @@ -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 diff --git a/openmmforcefields/generators/template_generators.py b/openmmforcefields/generators/template_generators.py index 0f6f91b1..0f55ff77 100644 --- a/openmmforcefields/generators/template_generators.py +++ b/openmmforcefields/generators/template_generators.py @@ -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: @@ -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: @@ -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! """ @@ -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 @@ -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): From 2118de75c5ae6a9fadb4881c4c222d9b0062c211 Mon Sep 17 00:00:00 2001 From: John Chodera Date: Tue, 21 Jul 2020 17:36:44 -0700 Subject: [PATCH 3/3] Update README --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 740216b7..fc5dbf76 100644 --- a/README.md +++ b/README.md @@ -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. @@ -279,9 +282,8 @@ See the corresponding directories for information on how to use the provided con * [(PR #119)](https://github.com/openmm/openmmforcefields/pull/119) Handle `None` partial charges in openforcefield `Molecule` objects (needed in `openforcefield` toolkit 0.7.0) * [(PR #120)](https://github.com/openmm/openmmforcefields/pull/120) Auto-detect installed SMIRNOFF force fields -## 0.8.0 Auto-discover installed Open Force Field Initiative force fields; OpenMM 7.4.2 minimum version requirement +## 0.7.2 Bugfix release: More error checking; OpenMM 7.4.2 minimum version requirement -* Auto-discover available installed `openforcefield` force fields. * Raise a `ValueError` if `SystemGenerator` receives a `nonbondedMethod` key in `forcefield_kwargs`; these should go into `periodic_forcefield_kwargs` or `nonperiodic_forcefield_kwargs`. ## 0.7.1 Bugfix release: Fix GAFF AM1-BCC charging bug for some molecules