diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c53ebffb..defdc55d 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -105,6 +105,12 @@ jobs: working-directory: ./charmm + - name: Run docstrings + if: ${{ matrix.latest-openff-toolkit == true }} + continue-on-error: True + run: | + pytest --doctest-modules openmmforcefields --ignore=openmmforcefields/tests + - name: Upload coverage report to CodeCov uses: codecov/codecov-action@v3.1.1 if: ${{ github.repository == 'openmm/openmmforcefields' diff --git a/README.md b/README.md index 1b4960be..47eefd64 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ If you're not familiar with this approach to applying parameters to biomolecular ### Using the AMBER force fields -Once installed, the AMBER force fields will be registered in the `amber/` relative path searched by [`simtk.openmm.app.ForceField`](http://docs.openmm.org/latest/api-python/generated/simtk.openmm.app.forcefield.ForceField.html#simtk.openmm.app.forcefield.ForceField). +Once installed, the AMBER force fields will be registered in the `amber/` relative path searched by [`openmm.app.ForceField`](http://docs.openmm.org/latest/api-python/generated/openmm.app.forcefield.ForceField.html#openmm.app.forcefield.ForceField). For example, to specify the newer recommended [`ff14SB`](https://pubs.acs.org/doi/abs/10.1021/acs.jctc.5b00255) force field and accompanying recommended ions and solvent models (corresponding to force fields loaded in LEaP with `leaprc.protein.ff14SB`), prepend the `amber` prefix and the `.xml` suffix: ```python @@ -67,7 +67,7 @@ forcefield = ForceField('charmm/toppar_all36_prot_model.xml') ## Using AMBER GAFF 1.x and 2.x for small molecules -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 [GAFF](http://ambermd.org/antechamber/gaff.html) versions 1 or 2. +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/openmm.app.forcefield.ForceField.html#openmm.app.forcefield.ForceField) that automatically generates OpenMM residue templates for small molecules lacking parameters using [GAFF](http://ambermd.org/antechamber/gaff.html) versions 1 or 2. ### Cheminformatics toolkits @@ -78,7 +78,7 @@ The OpenEye toolkit is available [for free for academics for non-IP-generating a ### On-the-fly template generation for small molecules Generation of OpenMM-compatible parameters for small molecules encountered in an OpenMM `Topology` is handled through `openmmforcefields.generators.GAFFTemplateGenerator`. -Because the [OpenMM `Topology` object](http://docs.openmm.org/latest/api-python/generated/simtk.openmm.app.topology.Topology.html#simtk.openmm.app.topology.Topology) used by [the OpenMM `ForceField` class](http://docs.openmm.org/latest/api-python/generated/simtk.openmm.app.forcefield.ForceField.html#simtk.openmm.app.forcefield.ForceField) does not know the precise chemical identity of molecules represented in the topology---which contain only elements and bonds between them, without stereochemical or bond order information---it is necessary to instruct `GAFFTemplateGenerator` which small molecules it will encounter in processing the `Topology` object ahead of time; it then matches these by element and bond pattern. +Because the [OpenMM `Topology` object](http://docs.openmm.org/latest/api-python/generated/openmm.app.topology.Topology.html#openmm.app.topology.Topology) used by [the OpenMM `ForceField` class](http://docs.openmm.org/latest/api-python/generated/openmm.app.forcefield.ForceField.html#openmm.app.forcefield.ForceField) does not know the precise chemical identity of molecules represented in the topology---which contain only elements and bonds between them, without stereochemical or bond order information---it is necessary to instruct `GAFFTemplateGenerator` which small molecules it will encounter in processing the `Topology` object ahead of time; it then matches these by element and bond pattern. ### Specifying molecules @@ -112,14 +112,14 @@ molecule = Molecule.from_smiles('c1ccccc1') from openmmforcefields.generators import GAFFTemplateGenerator gaff = GAFFTemplateGenerator(molecules=molecule) # Create an OpenMM ForceField object with AMBER ff14SB and TIP3P with compatible ions -from simtk.openmm.app import ForceField +from openmm.app import ForceField forcefield = ForceField('amber/protein.ff14SB.xml', 'amber/tip3p_standard.xml', 'amber/tip3p_HFE_multivalent.xml') # Register the GAFF template generator forcefield.registerTemplateGenerator(gaff.generator) # You can now parameterize an OpenMM Topology object that contains the specified molecule. # forcefield will load the appropriate GAFF parameters when needed, and antechamber # will be used to generate small molecule parameters on the fly. -from simtk.openmm.app import PDBFile +from openmm.app import PDBFile pdbfile = PDBFile('t4-lysozyme-L99A-with-benzene.pdb') system = forcefield.createSystem(pdbfile.topology) ``` @@ -152,7 +152,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. +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/openmm.app.forcefield.ForceField.html#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](https://github.com/openforcefield/openff-forcefields). The `SMIRNOFFTemplateGenerator` residue template generator operates in a manner very similar to `GAFFTemplateGenerator`, so we only highlight its differences here. @@ -168,7 +168,7 @@ molecule = Molecule.from_smiles('c1ccccc1') from openmmforcefields.generators import SMIRNOFFTemplateGenerator smirnoff = SMIRNOFFTemplateGenerator(molecules=molecule) # Create an OpenMM ForceField object with AMBER ff14SB and TIP3P with compatible ions -from simtk.openmm.app import ForceField +from openmm.app import ForceField forcefield = ForceField('amber/protein.ff14SB.xml', 'amber/tip3p_standard.xml', 'amber/tip3p_HFE_multivalent.xml') # Register the SMIRNOFF template generator forcefield.registerTemplateGenerator(smirnoff.generator) @@ -210,7 +210,7 @@ Newly parameterized molecules will be written to the cache, saving time next tim ## Using espaloma to generate 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 can automatically generate OpenMM residue templates for small molecules lacking parameters using [espaloma](https://github.com/choderalab/espaloma) via one of its released force fields, provided `espaloma` and its dependencies are installed. +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/openmm.app.forcefield.ForceField.html#openmm.app.forcefield.ForceField) that can automatically generate OpenMM residue templates for small molecules lacking parameters using [espaloma](https://github.com/choderalab/espaloma) via one of its released force fields, provided `espaloma` and its dependencies are installed. `espaloma` uses a [graph convolutional model](https://arxiv.org/abs/2010.01196) to generate both valence parameters and fast partial charges. The `EspalomaTemplateGenerator` residue template generator operates in a manner very similar to `GAFFTemplateGenerator`, so we only highlight its differences here. @@ -228,7 +228,7 @@ molecule = Molecule.from_smiles('c1ccccc1') from openmmforcefields.generators import EspalomaTemplateGenerator espaloma = EspalomaTemplateGenerator(molecules=molecule, forcefield='espaloma-0.2.2') # Create an OpenMM ForceField object with AMBER ff14SB and TIP3P with compatible ions -from simtk.openmm.app import ForceField +from openmm.app import ForceField forcefield = ForceField('amber/protein.ff14SB.xml', 'amber/tip3p_standard.xml', 'amber/tip3p_HFE_multivalent.xml') # Register the SMIRNOFF template generator forcefield.registerTemplateGenerator(espaloma.generator) @@ -264,8 +264,8 @@ The `openmmforcefields` package provides the `openmmforcefields.generators.Syste Here's an example that uses GAFF 2.11 along with the new `ff14SB` generation of AMBER force fields (and compatible solvent models) to generate an OpenMM `System` object from an [Open Force Field `Topology`](https://open-forcefield-toolkit.readthedocs.io/en/latest/api/generated/openff.toolkit.topology.Topology.html#openff.toolkit.topology.Topology) object: ```python # 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 forcefield_kwargs = { 'constraints' : app.HBonds, 'rigidWater' : True, 'removeCMMotion' : False, 'hydrogenMass' : 4*unit.amu } # Initialize a SystemGenerator using GAFF from openmmforcefields.generators import SystemGenerator @@ -282,7 +282,7 @@ Parameters for multiple force fields can be held in the same cache file. By default, `SystemGenerator` will use `PME` for periodic systems and `NoCutoff` for non-periodic systems. You can modify this behavior with the optional `periodic_forcefield_kwargs` and `nonperiodic_forcefield_kwargs` arguments, which are used to update `forcefield_kwargs` depending on whether the system is periodic or non-periodic: ```python -from simtk.openmm import app +from openmm import app system_generator = SystemGenerator(forcefields=['amber/ff14SB.xml', 'amber/tip3p_standard.xml'], periodic_forcefield_kwargs={'nonbondedMethod' : app.LJPME}, nonperiodic_forcefield_kwargs={'nonbondedMethod' : app.CutoffNonPeriodic}) diff --git a/charmm/energy.py b/charmm/energy.py index 8819efee..d494f8ad 100644 --- a/charmm/energy.py +++ b/charmm/energy.py @@ -2,8 +2,9 @@ from __future__ import print_function import sys import parmed as pmd -from simtk import openmm as mm, unit as u -from simtk.openmm import app +import openmm as mm +from openmm import unit as u +from openmm import app import numpy as np import time import os, re diff --git a/charmm/test_charmm.py b/charmm/test_charmm.py index a761c88c..bc88332f 100644 --- a/charmm/test_charmm.py +++ b/charmm/test_charmm.py @@ -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 @@ -100,7 +100,7 @@ def write_serialized_system(filename, system): ---------- filename : str The name of the file to be written - system : simtk.openmm.System + system : openmm.System The System object to be written """ @@ -129,7 +129,7 @@ def read_box_vectors(filename): Returns ------- - box_vectors : simtk.unit.Quantity with shape [3,3] and units of Angstroms + box_vectors : openmm.unit.Quantity with shape [3,3] and units of Angstroms Box vectors """ with open(filename, 'r') as infile: @@ -162,14 +162,14 @@ def compute_potential(system, positions): Parameters ---------- - system : simtk.openmm.System + system : openmm.System System - positions : simtk.unit.Quantity of shape [nparticles,3] with units compatible with angstroms + positions : openmm.unit.Quantity of shape [nparticles,3] with units compatible with angstroms Positions Returns ------- - potential : simtk.unit.Quantity with units of kJ/mol + potential : openmm.unit.Quantity with units of kJ/mol The potential energy """ @@ -202,7 +202,7 @@ def compare_energies(system_name, pdb_filename, psf_filename, ffxml_filenames, t Keyword arguments to pass to CharmmPsfFile.createSystem() and ForceField.CreateSystem() when constructing System objects for energy comparison tolerance : float, optional, default=1e-5 Relative energy discrepancy tolerance - units : simtk.unit.Unit + units : openmm.unit.Unit Unit to use for energy comparison write_serialized_xml : bool, optional, default=False If True, will write out serialized System XML files for OpenMM systems to aid debugging. diff --git a/openmmforcefields/generators/system_generators.py b/openmmforcefields/generators/system_generators.py index fc058c81..661bf65a 100644 --- a/openmmforcefields/generators/system_generators.py +++ b/openmmforcefields/generators/system_generators.py @@ -126,10 +126,12 @@ def __init__(self, forcefields=None, small_molecule_forcefield='openff-1.0.0', f If the ``cache`` argument is specified, parameterized molecules are cached in the corresponding file. >>> cache = 'db.json' - >>> system_generator = SystemGenerator(forcefields=forcefields, small_molecule_forcefield='gaff-2.11', forcefield_kwargs=forcefield_kwargs, cache=cache) + >>> system_generator = SystemGenerator(forcefields=amber_forcefields, small_molecule_forcefield='gaff-2.11', forcefield_kwargs=forcefield_kwargs, cache=cache) # doctest: +SKIP To use a barostat, you need to define a barostat whose parameters will be copied into each system (with a different random number seed): + >>> import openmm + >>> from openmm import unit >>> pressure = 1.0 * unit.atmospheres >>> temperature = 298.0 * unit.kelvin >>> frequency = 25 # steps @@ -137,6 +139,9 @@ def __init__(self, forcefields=None, small_molecule_forcefield='openff-1.0.0', f Now, you can create an OpenMM ``System`` object from an OpenMM ``Topology`` object and a list of OpenFF ``Molecule`` objects + >>> from openff.toolkit import Molecule, Topology + >>> molecules = [Molecule.from_smiles(smiles) for smiles in ["CCO", "c1ccccc1"]] + >>> openmm_topology = Topology.from_molecules(molecules).to_openmm() >>> system = system_generator.create_system(openmm_topology, molecules=molecules) Parameters for multiple force fields can be held in the same cache file. @@ -145,7 +150,7 @@ def __init__(self, forcefields=None, small_molecule_forcefield='openff-1.0.0', f simply change the ``small_molecule_forcefield`` parameter to one of the supported ``GAFFTemplateGenerator.INSTALLED_FORCEFIELDS``: >>> small_molecule_forcefield = 'openff-1.0.0' - >>> system_generator = SystemGenerator(forcefields=forcefields, small_molecule_forcefield=small_molecule_forcefield, forcefield_kwargs=forcefield_kwargs) + >>> system_generator = SystemGenerator(forcefields=amber_forcefields, small_molecule_forcefield=small_molecule_forcefield, forcefield_kwargs=forcefield_kwargs) For debugging convenience, you can also turn _off_ specific interactions during system creation, such as particle charges: diff --git a/openmmforcefields/generators/template_generators.py b/openmmforcefields/generators/template_generators.py index 8bba043a..d3bc641a 100644 --- a/openmmforcefields/generators/template_generators.py +++ b/openmmforcefields/generators/template_generators.py @@ -101,9 +101,10 @@ def add_molecules(self, molecules=None): Add some Molecules later on after the generator has been registered: >>> from openff.toolkit.topology import Molecule - >>> mol1, mol2, mol3 = [ Molecule.from_smiles(smiles) for smiles in ('c1ccccc1', 'O=Cc1ccc(O)c(OC)c1', 'CN1CCC[C@H]1c2cccnc2') ] - >>> generator.add_oemols(mol1) - >>> generator.add_oemols([mol2, mol3]) + >>> smiles = ('c1ccccc1', 'O=Cc1ccc(O)c(OC)c1', 'CN1CCC[C@H]1c2cccnc2') + >>> mol1, mol2, mol3 = [Molecule.from_smiles(s, allow_undefined_stereo=True) for s in smiles] + >>> generator.add_molecules(mol1) # doctest: +SKIP + >>> generator.add_molecules([mol2, mol3]) # doctest: +SKIP """ # Return if empty @@ -362,7 +363,7 @@ class GAFFTemplateGenerator(SmallMoleculeTemplateGenerator): >>> from openff.toolkit.topology import Molecule >>> molecule = Molecule.from_smiles('c1ccccc1') >>> # Create the GAFF template generator - >>> from openmoltools.forcefield_generators import GAFFTemplateGenerator + >>> from openmmforcefields.generators import GAFFTemplateGenerator >>> template_generator = GAFFTemplateGenerator(molecules=molecule) >>> # Create an OpenMM ForceField >>> from openmm.app import ForceField @@ -375,11 +376,11 @@ class GAFFTemplateGenerator(SmallMoleculeTemplateGenerator): >>> molecule1 = Molecule.from_smiles('c1ccccc1') >>> molecule2 = Molecule.from_smiles('CCO') - >>> template_generator = GAFFTemplateGenerator(molecules=[molecule1, molecuel2], forcefield='gaff-2.11') + >>> template_generator = GAFFTemplateGenerator(molecules=[molecule1, molecule2], forcefield='gaff-2.11') You can also add some Molecules later on after the generator has been registered: - >>> template_generator.add_molecule(molecule) + >>> template_generator.add_molecules(molecule) >>> template_generator.add_molecules([molecule1, molecule2]) You can optionally create or use a tiny database cache of pre-parameterized molecules: @@ -424,7 +425,7 @@ def __init__(self, molecules=None, forcefield=None, cache=None): >>> from openff.toolkit.topology import Molecule >>> molecule = Molecule.from_smiles('c1ccccc1') - >>> from openmoltools.forcefield_generators import GAFFTemplateGenerator + >>> from openmmforcefields.generators import GAFFTemplateGenerator >>> gaff = GAFFTemplateGenerator(molecules=molecule) >>> from openmm.app import ForceField >>> amber_forcefields = ['amber/protein.ff14SB.xml', 'amber/tip3p_standard.xml', 'amber/tip3p_HFE_multivalent.xml'] @@ -439,12 +440,15 @@ def __init__(self, molecules=None, forcefield=None, cache=None): Create a template generator for a specific GAFF version for multiple molecules read from an SDF file: - >>> molecules = Molecule.from_file('molecules.sdf') - >>> gaff = GAFFTemplateGenerator(molecules=molecules, forcefield='gaff-2.11') + >>> molecules = Molecule.from_file('molecules.sdf') # doctest: +SKIP + >>> gaff = GAFFTemplateGenerator(molecules=molecules, forcefield='gaff-2.11') # doctest: +SKIP You can also add molecules later on after the generator has been registered: + >>> molecule = Molecule.from_smiles("CCO") >>> gaff.add_molecules(molecule) + + >>> molecule1, molecule2 = [Molecule.from_smiles(smiles) for smiles in ["CC", "c1ccccc1"]] >>> gaff.add_molecules([molecule1, molecule2]) To check which GAFF versions are supported, check the `INSTALLED_FORCEFIELDS` attribute: @@ -454,7 +458,7 @@ def __init__(self, molecules=None, forcefield=None, cache=None): You can optionally create or use a tiny database cache of pre-parameterized molecules: - >>> gaff = GAFFTemplateGenerator(cache='gaff-molecules.json', forcefield='gaff-1.80') + >>> gaff = GAFFTemplateGenerator(cache='gaff-molecules.json', forcefield='gaff-2.11') Newly parameterized molecules will be written to the cache, saving time next time! """ @@ -1157,7 +1161,7 @@ class SMIRNOFFTemplateGenerator(SmallMoleculeTemplateGenerator,OpenMMSystemMixin >>> from openff.toolkit.topology import Molecule >>> molecule = Molecule.from_smiles('c1ccccc1') >>> # Create the SMIRNOFF template generator - >>> from openmoltools.forcefield_generators import SMIRNOFFTemplateGenerator + >>> from openmmforcefields.generators import SMIRNOFFTemplateGenerator >>> template_generator = SMIRNOFFTemplateGenerator(molecules=molecule) >>> # Create an OpenMM ForceField >>> from openmm.app import ForceField @@ -1166,20 +1170,20 @@ class SMIRNOFFTemplateGenerator(SmallMoleculeTemplateGenerator,OpenMMSystemMixin >>> # Register the template generator >>> forcefield.registerTemplateGenerator(template_generator.generator) - Create a template generator for a specific pre-installed SMIRNOFF version ('openff-1.2.0') + Create a template generator for a specific pre-installed SMIRNOFF version ('openff-2.0.0') and register multiple molecules: >>> molecule1 = Molecule.from_smiles('c1ccccc1') >>> molecule2 = Molecule.from_smiles('CCO') - >>> template_generator = SMIRNOFFTemplateGenerator(molecules=[molecule1, molecule2], forcefield='openff-1.2.0') + >>> template_generator = SMIRNOFFTemplateGenerator(molecules=[molecule1, molecule2], forcefield='openff-2.0.0') Alternatively, you can specify a local .offxml file in the SMIRNOFF specification: - >>> template_generator = SMIRNOFFTemplateGenerator(molecules=[molecule1, molecule2], forcefield='mysmirnoff.offxml') + >>> template_generator = SMIRNOFFTemplateGenerator(molecules=[molecule1, molecule2], forcefield='mysmirnoff.offxml') # doctest: +SKIP You can also add some Molecules later on after the generator has been registered: - >>> template_generator.add_molecule(molecule) + >>> template_generator.add_molecules(molecule) >>> template_generator.add_molecules([molecule1, molecule2]) You can optionally create or use a tiny database cache of pre-parameterized molecules: @@ -1216,7 +1220,7 @@ def __init__(self, molecules=None, cache=None, forcefield=None): >>> from openff.toolkit.topology import Molecule >>> molecule = Molecule.from_smiles('c1ccccc1') - >>> from openmoltools.forcefield_generators import SMIRNOFFTemplateGenerator + >>> from openmmforcefields.generators import SMIRNOFFTemplateGenerator >>> smirnoff = SMIRNOFFTemplateGenerator(molecules=molecule) >>> from openmm.app import ForceField >>> amber_forcefields = ['amber/protein.ff14SB.xml', 'amber/tip3p_standard.xml', 'amber/tip3p_HFE_multivalent.xml'] @@ -1225,31 +1229,31 @@ def __init__(self, molecules=None, cache=None, forcefield=None): The latest Open Force Field Initiative release is used if none is specified. >>> smirnoff.forcefield - 'openff-1.2.0' + 'openff-2.0.0' You can check which SMIRNOFF force field filename is in use with - >>> smirnoff.smirnoff_filename - '/full/path/to/openff-1.2.0.offxml' + >>> smirnoff.smirnoff_filename # doctest:+ELLIPSIS + '/.../openff-2.0.0.offxml' Create a template generator for a specific SMIRNOFF force field for multiple molecules read from an SDF file: - >>> molecules = Molecule.from_file('molecules.sdf') - >>> smirnoff = SMIRNOFFTemplateGenerator(molecules=molecules, forcefield='smirnoff99Frosst-1.1.0') + >>> molecules = Molecule.from_file('molecules.sdf') # doctest: +SKIP + >>> smirnoff = SMIRNOFFTemplateGenerator(molecules=molecules, forcefield='openff-2.0.0') # doctest: +SKIP You can also add molecules later on after the generator has been registered: - >>> smirnoff.add_molecules(molecules) + >>> smirnoff.add_molecules(molecules) # doctest: +SKIP To check which SMIRNOFF versions are supported, check the `INSTALLED_FORCEFIELDS` attribute: - >>> print(SMIRNOFFTemplateGenerator.INSTALLED_FORCEFIELDS) + >>> print(SMIRNOFFTemplateGenerator.INSTALLED_FORCEFIELDS) # doctest: +SKIP ['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.2.0') + >>> smirnoff = SMIRNOFFTemplateGenerator(cache='smirnoff.json', forcefield='openff-2.0.0') # doctest: +SKIP Newly parameterized molecules will be written to the cache, saving time next time! """ @@ -1441,7 +1445,7 @@ class EspalomaTemplateGenerator(SmallMoleculeTemplateGenerator,OpenMMSystemMixin >>> from openff.toolkit.topology import Molecule >>> molecule = Molecule.from_smiles('c1ccccc1') >>> # Create the Espaloma template generator - >>> from openmoltools.forcefield_generators import EspalomaTemplateGenerator + >>> from openmmforcefields.generators import EspalomaTemplateGenerator >>> template_generator = EspalomaTemplateGenerator(molecules=molecule) >>> # Create an OpenMM ForceField >>> from openmm.app import ForceField @@ -1459,11 +1463,11 @@ class EspalomaTemplateGenerator(SmallMoleculeTemplateGenerator,OpenMMSystemMixin Alternatively, you can specify a local .pt parameter file for Espaloma: - >>> template_generator = EspalomaTemplateGenerator(molecules=[molecule1, molecule2], forcefield='espaloma_0.2.2.pt') + >>> template_generator = EspalomaTemplateGenerator(molecules=[molecule1, molecule2], forcefield='espaloma-0.2.2.pt') You can also add some Molecules later on after the generator has been registered: - >>> template_generator.add_molecule(molecule) + >>> template_generator.add_molecules(molecule) >>> template_generator.add_molecules([molecule1, molecule2]) You can optionally create or use a tiny database cache of pre-parameterized molecules: @@ -1505,7 +1509,7 @@ def __init__(self, molecules=None, cache=None, forcefield=None, model_cache_path >>> from openff.toolkit.topology import Molecule >>> molecule = Molecule.from_smiles('c1ccccc1') - >>> from openmoltools.forcefield_generators import EspalomaTemplateGenerator + >>> from openmmforcefields.generators import EspalomaTemplateGenerator >>> espaloma_generator = EspalomaTemplateGenerator(molecules=molecule) >>> from openmm.app import ForceField >>> amber_forcefields = ['amber/protein.ff14SB.xml', 'amber/tip3p_standard.xml', 'amber/tip3p_HFE_multivalent.xml'] @@ -1516,18 +1520,19 @@ def __init__(self, molecules=None, cache=None, forcefield=None, model_cache_path You can check which espaloma parameter set force field filename is in use with - >>> espaloma_generator.parameters_filename - '/full/path/to/espaloma-0.2.2.pt' + >>> espaloma_generator.espaloma_filename + '/.../espaloma-0.2.2.pt' Create a template generator for a specific SMIRNOFF force field for multiple - molecules read from an SDF file: + molecules read from an SDF file or list of SMILES strings: - >>> molecules = Molecule.from_file('molecules.sdf') + >>> molecules = Molecule.from_file('molecules.sdf') # doctest: +SKIP + >>> molecules = [Molecule.from_smiles(smiles) for smiles in ["CCO", "c1ccccc1"]] >>> espaloma_generator = EspalomaTemplateGenerator(molecules=molecules, forcefield='espaloma-0.2.2') You can also add molecules later on after the generator has been registered: - >>> espaloma_generator.add_molecules(molecules) + >>> espaloma_generator.add_molecules(molecules[-1]) You can optionally create or use a cache of pre-parameterized molecules: diff --git a/openmmforcefields/tests/test_template_generators.py b/openmmforcefields/tests/test_template_generators.py index 8b7d75e4..07d130d3 100644 --- a/openmmforcefields/tests/test_template_generators.py +++ b/openmmforcefields/tests/test_template_generators.py @@ -761,7 +761,6 @@ def test_INSTALLED_FORCEFIELDS(self): 'openff-1.1.0', 'openff-2.0.0', 'smirnoff99Frosst-1.1.0', - 'ff14sb_off_impropers_0.0.3', ] forbidden_force_fields = [ 'openff_unconstrained',