From 4c132f699a63741fb217a2509bc8afba80f63863 Mon Sep 17 00:00:00 2001 From: "Matthew W. Thompson" Date: Thu, 29 Aug 2024 10:37:20 -0500 Subject: [PATCH 01/11] Test against `openff-interchange-0.4.0beta1` Updates for Interchange 0.4.0/Pydantic v2 Update BRD4 notebook cosmetic commit to kick CI Revert --- devtools/conda-envs/conda.yaml | 1 + devtools/conda-envs/conda_oe.yaml | 1 + devtools/conda-envs/installer.yaml | 1 + devtools/conda-envs/openeye-examples.yaml | 5 +- devtools/conda-envs/openeye.yaml | 5 +- devtools/conda-envs/rdkit-examples.yaml | 5 +- devtools/conda-envs/rdkit.yaml | 5 +- devtools/conda-envs/release-build.yaml | 1 + devtools/conda-envs/test_env.yaml | 5 +- .../.gitignore | 1 + .../BRD4_inhibitor_benchmark.ipynb | 89 ++++++++----------- openff/toolkit/_tests/test_forcefield.py | 7 +- .../typing/engines/smirnoff/forcefield.py | 8 +- 13 files changed, 63 insertions(+), 71 deletions(-) diff --git a/devtools/conda-envs/conda.yaml b/devtools/conda-envs/conda.yaml index 0c64bc009..a41a64a96 100644 --- a/devtools/conda-envs/conda.yaml +++ b/devtools/conda-envs/conda.yaml @@ -1,5 +1,6 @@ name: latest-deployment channels: + - conda-forge/label/openff-interchange_rc - conda-forge dependencies: # Base depends diff --git a/devtools/conda-envs/conda_oe.yaml b/devtools/conda-envs/conda_oe.yaml index ad491db0a..d4077595b 100644 --- a/devtools/conda-envs/conda_oe.yaml +++ b/devtools/conda-envs/conda_oe.yaml @@ -1,5 +1,6 @@ name: latest-deployment channels: + - conda-forge/label/openff-interchange_rc - conda-forge - openeye dependencies: diff --git a/devtools/conda-envs/installer.yaml b/devtools/conda-envs/installer.yaml index 93374e815..69a98fb96 100644 --- a/devtools/conda-envs/installer.yaml +++ b/devtools/conda-envs/installer.yaml @@ -1,6 +1,7 @@ name: constructor channels: + - conda-forge/label/openff-interchange_rc - defaults - conda-forge diff --git a/devtools/conda-envs/openeye-examples.yaml b/devtools/conda-envs/openeye-examples.yaml index f4673198a..593f2f854 100644 --- a/devtools/conda-envs/openeye-examples.yaml +++ b/devtools/conda-envs/openeye-examples.yaml @@ -1,11 +1,12 @@ name: openeye-examples channels: + - conda-forge/label/openff-interchange_rc - openeye - conda-forge dependencies: # Base depends - python - - pydantic =1 + - pydantic - packaging - numpy - networkx @@ -19,7 +20,7 @@ dependencies: - openff-amber-ff-ports >=0.0.3 - openff-units =0.2.0 - openff-utilities >=0.1.5 - - openff-interchange-base >=0.3.19 + - openff-interchange-base >=0.4.0beta1 - openff-nagl-base ~=0.4.0 - openff-nagl-models ==0.3.0 - typing_extensions diff --git a/devtools/conda-envs/openeye.yaml b/devtools/conda-envs/openeye.yaml index 56c35b51a..8e1f7c92a 100644 --- a/devtools/conda-envs/openeye.yaml +++ b/devtools/conda-envs/openeye.yaml @@ -1,11 +1,12 @@ name: openff-toolkit-test-openeye channels: + - conda-forge/label/openff-interchange_rc - openeye - conda-forge dependencies: # Base depends - python - - pydantic =1 + - pydantic - packaging - numpy - networkx @@ -19,7 +20,7 @@ dependencies: - openff-units =0.2.0 - openff-amber-ff-ports - openff-utilities >=0.1.5 - - openff-interchange-base >=0.3.19 + - openff-interchange-base >=0.4.0beta1 - openff-nagl-base ~=0.4.0 - openff-nagl-models ==0.3.0 - typing_extensions diff --git a/devtools/conda-envs/rdkit-examples.yaml b/devtools/conda-envs/rdkit-examples.yaml index 34d3a933e..97e97114c 100644 --- a/devtools/conda-envs/rdkit-examples.yaml +++ b/devtools/conda-envs/rdkit-examples.yaml @@ -1,10 +1,11 @@ name: rdkit-examples channels: + - conda-forge/label/openff-interchange_rc - conda-forge dependencies: # Base depends - python - - pydantic =1 + - pydantic - packaging - numpy - networkx @@ -18,7 +19,7 @@ dependencies: - openff-amber-ff-ports >=0.0.3 - openff-units =0.2.0 - openff-utilities >=0.1.5 - - openff-interchange-base >=0.3.19 + - openff-interchange-base >=0.4.0beta1 - openff-nagl-base ~=0.4.0 - openff-nagl-models ==0.3.0 - typing_extensions diff --git a/devtools/conda-envs/rdkit.yaml b/devtools/conda-envs/rdkit.yaml index 5ff1e2b5f..7d5be8559 100644 --- a/devtools/conda-envs/rdkit.yaml +++ b/devtools/conda-envs/rdkit.yaml @@ -1,10 +1,11 @@ name: openff-toolkit-test-rdkit channels: + - conda-forge/label/openff-interchange_rc - conda-forge dependencies: # Base depends - python - - pydantic =1 + - pydantic - packaging - numpy - networkx @@ -18,7 +19,7 @@ dependencies: - openff-units =0.2.0 - openff-amber-ff-ports - openff-utilities >=0.1.5 - - openff-interchange-base >=0.3.19 + - openff-interchange-base >=0.4.0beta1 - openff-nagl-base ~=0.4.0 - openff-nagl-models ==0.3.0 - typing_extensions diff --git a/devtools/conda-envs/release-build.yaml b/devtools/conda-envs/release-build.yaml index fe496f143..c48e275d0 100644 --- a/devtools/conda-envs/release-build.yaml +++ b/devtools/conda-envs/release-build.yaml @@ -1,5 +1,6 @@ name: release-build channels: + - conda-forge/label/openff-interchange_rc - conda-forge dependencies: diff --git a/devtools/conda-envs/test_env.yaml b/devtools/conda-envs/test_env.yaml index 881211c47..0ce0126f4 100644 --- a/devtools/conda-envs/test_env.yaml +++ b/devtools/conda-envs/test_env.yaml @@ -1,5 +1,6 @@ name: openff-toolkit-test channels: + - conda-forge/label/openff-interchange_rc - openeye - conda-forge dependencies: @@ -19,7 +20,7 @@ dependencies: - openff-units =0.2.0 - openff-amber-ff-ports - openff-utilities >=0.1.5 - - openff-interchange-base >=0.3.19 + - openff-interchange-base >=0.4.0beta1 - openff-nagl-base ~=0.4.0 - openff-nagl-models ==0.3.0 # Toolkit-specific @@ -47,7 +48,7 @@ dependencies: - nomkl - mypy - typing_extensions - - pydantic =1 + - pydantic - pip: - types-setuptools - types-toml diff --git a/examples/using_smirnoff_with_amber_protein_forcefield/.gitignore b/examples/using_smirnoff_with_amber_protein_forcefield/.gitignore index 2b077ccab..8bf74f582 100644 --- a/examples/using_smirnoff_with_amber_protein_forcefield/.gitignore +++ b/examples/using_smirnoff_with_amber_protein_forcefield/.gitignore @@ -1,4 +1,5 @@ complex.* +complex_pointenergy.mdp receptor.* ligand.* protein.pdb diff --git a/examples/using_smirnoff_with_amber_protein_forcefield/BRD4_inhibitor_benchmark.ipynb b/examples/using_smirnoff_with_amber_protein_forcefield/BRD4_inhibitor_benchmark.ipynb index 3d3d247d3..04eabe05e 100644 --- a/examples/using_smirnoff_with_amber_protein_forcefield/BRD4_inhibitor_benchmark.ipynb +++ b/examples/using_smirnoff_with_amber_protein_forcefield/BRD4_inhibitor_benchmark.ipynb @@ -24,10 +24,11 @@ "repo_url = (\n", " \"https://raw.githubusercontent.com/MobleyLab/benchmarksets/master/input_files/\"\n", ")\n", + "\n", "sources = {\n", - " \"receptor.pdb\": repo_url + \"BRD4/pdb/BRD4.pdb\",\n", - " \"ligand.pdb\": repo_url + \"BRD4/pdb/ligand-1.pdb\",\n", - " \"ligand.sdf\": repo_url + \"BRD4/sdf/ligand-1.sdf\",\n", + " \"receptor.pdb\": f\"{repo_url}BRD4/pdb/BRD4.pdb\",\n", + " \"ligand.pdb\": f\"{repo_url}BRD4/pdb/ligand-1.pdb\",\n", + " \"ligand.sdf\": f\"{repo_url}BRD4/sdf/ligand-1.sdf\",\n", "}\n", "for filename, url in sources.items():\n", " r = requests.get(url)\n", @@ -40,36 +41,12 @@ "metadata": {}, "outputs": [], "source": [ - "from openff.toolkit import ForceField, Molecule, Topology" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Later we will use `Interchange.__add__`, which is an experimental feature. It needs to be turned on by setting the environment variable below, and by doing so we accept [some stability and accuracy risks](https://docs.openforcefield.org/projects/interchange/en/stable/using/experimental.html)." + "from openff.toolkit import ForceField, Molecule, Quantity, Topology" ] }, { "cell_type": "code", "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "env: INTERCHANGE_EXPERIMENTAL=1\n" - ] - } - ], - "source": [ - "%env INTERCHANGE_EXPERIMENTAL=1" - ] - }, - { - "cell_type": "code", - "execution_count": 4, "metadata": { "tags": [] }, @@ -77,7 +54,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "2f3b86c392c24705b86721395cf43ea4", + "model_id": "48226cb62a2849029c42d579843ef0f7", "version_major": 2, "version_minor": 0 }, @@ -90,8 +67,8 @@ "name": "stderr", "output_type": "stream", "text": [ - "/Users/jeffreywagner/projects/OpenForceField/openff-interchange/openff/interchange/_experimental.py:35: UserWarning: Interchange object combination is experimental and likely to produce strange results. Any workflow using this method is not guaranteed to be suitable for production. Use with extreme caution and thoroughly validate results!\n", - " return func(*args, **kwargs)\n" + "/Users/mattthompson/micromamba/envs/openff-toolkit-test/lib/python3.10/site-packages/openff/interchange/operations/_combine.py:52: InterchangeCombinationWarning: Interchange object combination is complex and likely to produce strange results outside of a limited set of use cases it has been tested in. Any workflow using this method is not guaranteed to be suitable for production or stable between versions. Use with extreme caution and thoroughly validate results!\n", + " warnings.warn(\n" ] } ], @@ -107,32 +84,32 @@ "\n", "receptor = ff14sb.create_interchange(topology=receptor_topology)\n", "\n", - "complex_system = receptor.combine(ligand)\n", - "\n", - "# TODO\n", - "# complex.box = pdbfile box vectors ...\n", - "# complex.positions = np.vstack([receptor.positions, ligand.positions])" + "# Interchange.combine works nicely for some cases but hasn't been tested for all - use caution\n", + "# if adapting this for more novel workflows!\n", + "complex_system = receptor.combine(ligand)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Export to OpenMM" + "### Export to OpenMM\n", + "\n", + "See [docs](https://docs.openforcefield.org/projects/interchange/en/stable/using/output.html#openmm) for more options." ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - " >" + " >" ] }, - "execution_count": 5, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -147,31 +124,35 @@ "tags": [] }, "source": [ - "### Export to Amber" + "### Export to Amber\n", + "\n", + "See [docs](https://docs.openforcefield.org/projects/interchange/en/stable/using/output.html#amber) for more options." ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ - "# TODO: Fix inferring residue information with mixed topology\n", - "if False:\n", - " complex_system.to_inpcrd(\"complex.inpcrd\")\n", - " complex_system.to_prmtop(\"complex.prmtop\")" + "complex_system.to_inpcrd(\"complex.inpcrd\")\n", + "complex_system.to_prmtop(\"complex.prmtop\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Export to GROMACS" + "### Export to GROMACS\n", + "\n", + "See [docs](https://docs.openforcefield.org/projects/interchange/en/stable/using/output.html#gromacs) for more options.\n", + "\n", + "GROMACS does not support vacuum simulations. In this example, we didn't add solvent and the original PDB file didn't have box vectors. We'll just arbitrarily add a 4 nm cubic box around the receptor-ligand complex." ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "metadata": { "tags": [] }, @@ -180,14 +161,16 @@ "name": "stderr", "output_type": "stream", "text": [ - "/Users/jeffreywagner/projects/OpenForceField/openff-interchange/openff/interchange/interop/gromacs/export/_export.py:48: UserWarning: WARNING: System defined with no box vectors, which GROMACS does not offically support in versions 2020 or newer (see https://gitlab.com/gromacs/gromacs/-/issues/3526). Setting box vectors to a 5 nm cube.\n", - " self._write_gro(gro, decimal)\n" + "/Users/mattthompson/micromamba/envs/openff-toolkit-test/lib/python3.10/site-packages/openff/interchange/components/mdconfig.py:471: UserWarning: Ambiguous failure while processing constraints. Constraining h-bonds as a stopgap.\n", + " warnings.warn(\n" ] } ], "source": [ - "complex_system.to_gro(\"complex.gro\")\n", - "complex_system.to_top(\"complex.top\")" + "complex_system.box = Quantity([4, 4, 4], \"nanometer\")\n", + "\n", + "# This step might be slow, writing some large proteins is not yet optimized\n", + "complex_system.to_gromacs(\"complex\")" ] } ], @@ -208,7 +191,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.10" + "version": "3.10.14" } }, "nbformat": 4, diff --git a/openff/toolkit/_tests/test_forcefield.py b/openff/toolkit/_tests/test_forcefield.py index 278ea6c4c..d2e925634 100644 --- a/openff/toolkit/_tests/test_forcefield.py +++ b/openff/toolkit/_tests/test_forcefield.py @@ -15,6 +15,7 @@ from openff.units.openmm import from_openmm, to_openmm from openmm import NonbondedForce, Platform, XmlSerializer, app from openmm import unit as openmm_unit +from pydantic import ValidationError from openff.toolkit import unit from openff.toolkit._tests.create_molecules import ( @@ -4028,15 +4029,11 @@ def test_fractional_bondorder_invalid_interpolation_method(self): # This error will be either from v1 of the package (if v1 is installed) # or the faked v1 API (if v2 is installed). Ensure the v1 error or a # mimick of it is imported - try: - from pydantic.v1 import ValidationError - except ImportError: - from pydantic import ValidationError # If important, this can be a custom exception instead of a verbose ValidationError with pytest.raises( ValidationError, - match="given=invalid method name", + match="Input should be 'linear'.*input_value='invalid method name'", ): forcefield.create_openmm_system( topology, diff --git a/openff/toolkit/typing/engines/smirnoff/forcefield.py b/openff/toolkit/typing/engines/smirnoff/forcefield.py index 4bfb40529..574f6e39f 100644 --- a/openff/toolkit/typing/engines/smirnoff/forcefield.py +++ b/openff/toolkit/typing/engines/smirnoff/forcefield.py @@ -1399,7 +1399,7 @@ def get_partial_charges(self, molecule: "Molecule", **kwargs: Any) -> Quantity: """ from openff.interchange import Interchange - from openff.toolkit import Molecule, unit + from openff.toolkit import Molecule if not isinstance(molecule, Molecule): raise ValueError( @@ -1412,9 +1412,11 @@ def get_partial_charges(self, molecule: "Molecule", **kwargs: Any) -> Quantity: c.m for c in Interchange.from_smirnoff( force_field=self, topology=[molecule], **kwargs - )["Electrostatics"].charges.values() + )["Electrostatics"] + ._get_charges() + .values() ], - unit.elementary_charge, + "elementary_charge", ) def __getitem__(self, val: Union[str, ParameterHandler]) -> ParameterHandler: From bbbf2d89ce478f1f908a51a7703d3dc7c8594f02 Mon Sep 17 00:00:00 2001 From: "Matthew W. Thompson" Date: Mon, 30 Sep 2024 15:10:49 -0500 Subject: [PATCH 02/11] Test against branch --- devtools/conda-envs/openeye-examples.yaml | 2 ++ devtools/conda-envs/openeye.yaml | 2 ++ devtools/conda-envs/rdkit-examples.yaml | 2 ++ devtools/conda-envs/rdkit.yaml | 2 ++ devtools/conda-envs/test_env.yaml | 1 + 5 files changed, 9 insertions(+) diff --git a/devtools/conda-envs/openeye-examples.yaml b/devtools/conda-envs/openeye-examples.yaml index 593f2f854..a46214665 100644 --- a/devtools/conda-envs/openeye-examples.yaml +++ b/devtools/conda-envs/openeye-examples.yaml @@ -44,3 +44,5 @@ dependencies: - pdbfixer - openmmforcefields >=0.11.2 - gromacs >=2023.3 + - pip: + - git+https://github.com/openforcefield/openff-interchange.git@fix-1052 diff --git a/devtools/conda-envs/openeye.yaml b/devtools/conda-envs/openeye.yaml index 8e1f7c92a..3b4c4a66d 100644 --- a/devtools/conda-envs/openeye.yaml +++ b/devtools/conda-envs/openeye.yaml @@ -41,3 +41,5 @@ dependencies: - mdtraj - nglview - parmed =3 + - pip: + - git+https://github.com/openforcefield/openff-interchange.git@fix-1052 diff --git a/devtools/conda-envs/rdkit-examples.yaml b/devtools/conda-envs/rdkit-examples.yaml index 97e97114c..32d7c76e5 100644 --- a/devtools/conda-envs/rdkit-examples.yaml +++ b/devtools/conda-envs/rdkit-examples.yaml @@ -46,3 +46,5 @@ dependencies: - pdbfixer - openmmforcefields >=0.11.2 - gromacs >=2023.3 + - pip: + - git+https://github.com/openforcefield/openff-interchange.git@fix-1052 diff --git a/devtools/conda-envs/rdkit.yaml b/devtools/conda-envs/rdkit.yaml index 7d5be8559..e0380634a 100644 --- a/devtools/conda-envs/rdkit.yaml +++ b/devtools/conda-envs/rdkit.yaml @@ -40,3 +40,5 @@ dependencies: - qcportal >=0.50 - qcengine - nglview + - pip: + - git+https://github.com/openforcefield/openff-interchange.git@fix-1052 diff --git a/devtools/conda-envs/test_env.yaml b/devtools/conda-envs/test_env.yaml index 0ce0126f4..1a51f8148 100644 --- a/devtools/conda-envs/test_env.yaml +++ b/devtools/conda-envs/test_env.yaml @@ -57,3 +57,4 @@ dependencies: - types-xmltodict - types-cachetools - mongo-types + - git+https://github.com/openforcefield/openff-interchange.git@fix-1052 From 9d86ba4909345636216d531b1ffa743b7ec8870f Mon Sep 17 00:00:00 2001 From: "Matthew W. Thompson" Date: Mon, 30 Sep 2024 15:11:44 -0500 Subject: [PATCH 03/11] Undo change --- openff/toolkit/typing/engines/smirnoff/forcefield.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/openff/toolkit/typing/engines/smirnoff/forcefield.py b/openff/toolkit/typing/engines/smirnoff/forcefield.py index 87aa81c3d..9bab02acf 100644 --- a/openff/toolkit/typing/engines/smirnoff/forcefield.py +++ b/openff/toolkit/typing/engines/smirnoff/forcefield.py @@ -1398,9 +1398,7 @@ def get_partial_charges(self, molecule: "Molecule", **kwargs: Any) -> Quantity: c.m for c in Interchange.from_smirnoff( force_field=self, topology=[molecule], **kwargs - )["Electrostatics"] - ._get_charges() - .values() + )["Electrostatics"].charges.values() ], "elementary_charge", ) From e1d9491046af63958c6dc304dabde431cd18b19b Mon Sep 17 00:00:00 2001 From: "Matthew W. Thompson" Date: Tue, 1 Oct 2024 08:27:17 -0500 Subject: [PATCH 04/11] Revert some changes for simpler diff --- .../.gitignore | 1 - .../BRD4_inhibitor_benchmark.ipynb | 89 +++++++++++-------- .../typing/engines/smirnoff/forcefield.py | 4 +- 3 files changed, 55 insertions(+), 39 deletions(-) diff --git a/examples/using_smirnoff_with_amber_protein_forcefield/.gitignore b/examples/using_smirnoff_with_amber_protein_forcefield/.gitignore index 8bf74f582..2b077ccab 100644 --- a/examples/using_smirnoff_with_amber_protein_forcefield/.gitignore +++ b/examples/using_smirnoff_with_amber_protein_forcefield/.gitignore @@ -1,5 +1,4 @@ complex.* -complex_pointenergy.mdp receptor.* ligand.* protein.pdb diff --git a/examples/using_smirnoff_with_amber_protein_forcefield/BRD4_inhibitor_benchmark.ipynb b/examples/using_smirnoff_with_amber_protein_forcefield/BRD4_inhibitor_benchmark.ipynb index 04eabe05e..3d3d247d3 100644 --- a/examples/using_smirnoff_with_amber_protein_forcefield/BRD4_inhibitor_benchmark.ipynb +++ b/examples/using_smirnoff_with_amber_protein_forcefield/BRD4_inhibitor_benchmark.ipynb @@ -24,11 +24,10 @@ "repo_url = (\n", " \"https://raw.githubusercontent.com/MobleyLab/benchmarksets/master/input_files/\"\n", ")\n", - "\n", "sources = {\n", - " \"receptor.pdb\": f\"{repo_url}BRD4/pdb/BRD4.pdb\",\n", - " \"ligand.pdb\": f\"{repo_url}BRD4/pdb/ligand-1.pdb\",\n", - " \"ligand.sdf\": f\"{repo_url}BRD4/sdf/ligand-1.sdf\",\n", + " \"receptor.pdb\": repo_url + \"BRD4/pdb/BRD4.pdb\",\n", + " \"ligand.pdb\": repo_url + \"BRD4/pdb/ligand-1.pdb\",\n", + " \"ligand.sdf\": repo_url + \"BRD4/sdf/ligand-1.sdf\",\n", "}\n", "for filename, url in sources.items():\n", " r = requests.get(url)\n", @@ -41,12 +40,36 @@ "metadata": {}, "outputs": [], "source": [ - "from openff.toolkit import ForceField, Molecule, Quantity, Topology" + "from openff.toolkit import ForceField, Molecule, Topology" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Later we will use `Interchange.__add__`, which is an experimental feature. It needs to be turned on by setting the environment variable below, and by doing so we accept [some stability and accuracy risks](https://docs.openforcefield.org/projects/interchange/en/stable/using/experimental.html)." ] }, { "cell_type": "code", "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "env: INTERCHANGE_EXPERIMENTAL=1\n" + ] + } + ], + "source": [ + "%env INTERCHANGE_EXPERIMENTAL=1" + ] + }, + { + "cell_type": "code", + "execution_count": 4, "metadata": { "tags": [] }, @@ -54,7 +77,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "48226cb62a2849029c42d579843ef0f7", + "model_id": "2f3b86c392c24705b86721395cf43ea4", "version_major": 2, "version_minor": 0 }, @@ -67,8 +90,8 @@ "name": "stderr", "output_type": "stream", "text": [ - "/Users/mattthompson/micromamba/envs/openff-toolkit-test/lib/python3.10/site-packages/openff/interchange/operations/_combine.py:52: InterchangeCombinationWarning: Interchange object combination is complex and likely to produce strange results outside of a limited set of use cases it has been tested in. Any workflow using this method is not guaranteed to be suitable for production or stable between versions. Use with extreme caution and thoroughly validate results!\n", - " warnings.warn(\n" + "/Users/jeffreywagner/projects/OpenForceField/openff-interchange/openff/interchange/_experimental.py:35: UserWarning: Interchange object combination is experimental and likely to produce strange results. Any workflow using this method is not guaranteed to be suitable for production. Use with extreme caution and thoroughly validate results!\n", + " return func(*args, **kwargs)\n" ] } ], @@ -84,32 +107,32 @@ "\n", "receptor = ff14sb.create_interchange(topology=receptor_topology)\n", "\n", - "# Interchange.combine works nicely for some cases but hasn't been tested for all - use caution\n", - "# if adapting this for more novel workflows!\n", - "complex_system = receptor.combine(ligand)" + "complex_system = receptor.combine(ligand)\n", + "\n", + "# TODO\n", + "# complex.box = pdbfile box vectors ...\n", + "# complex.positions = np.vstack([receptor.positions, ligand.positions])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Export to OpenMM\n", - "\n", - "See [docs](https://docs.openforcefield.org/projects/interchange/en/stable/using/output.html#openmm) for more options." + "### Export to OpenMM" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - " >" + " >" ] }, - "execution_count": 4, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -124,35 +147,31 @@ "tags": [] }, "source": [ - "### Export to Amber\n", - "\n", - "See [docs](https://docs.openforcefield.org/projects/interchange/en/stable/using/output.html#amber) for more options." + "### Export to Amber" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ - "complex_system.to_inpcrd(\"complex.inpcrd\")\n", - "complex_system.to_prmtop(\"complex.prmtop\")" + "# TODO: Fix inferring residue information with mixed topology\n", + "if False:\n", + " complex_system.to_inpcrd(\"complex.inpcrd\")\n", + " complex_system.to_prmtop(\"complex.prmtop\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Export to GROMACS\n", - "\n", - "See [docs](https://docs.openforcefield.org/projects/interchange/en/stable/using/output.html#gromacs) for more options.\n", - "\n", - "GROMACS does not support vacuum simulations. In this example, we didn't add solvent and the original PDB file didn't have box vectors. We'll just arbitrarily add a 4 nm cubic box around the receptor-ligand complex." + "### Export to GROMACS" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": { "tags": [] }, @@ -161,16 +180,14 @@ "name": "stderr", "output_type": "stream", "text": [ - "/Users/mattthompson/micromamba/envs/openff-toolkit-test/lib/python3.10/site-packages/openff/interchange/components/mdconfig.py:471: UserWarning: Ambiguous failure while processing constraints. Constraining h-bonds as a stopgap.\n", - " warnings.warn(\n" + "/Users/jeffreywagner/projects/OpenForceField/openff-interchange/openff/interchange/interop/gromacs/export/_export.py:48: UserWarning: WARNING: System defined with no box vectors, which GROMACS does not offically support in versions 2020 or newer (see https://gitlab.com/gromacs/gromacs/-/issues/3526). Setting box vectors to a 5 nm cube.\n", + " self._write_gro(gro, decimal)\n" ] } ], "source": [ - "complex_system.box = Quantity([4, 4, 4], \"nanometer\")\n", - "\n", - "# This step might be slow, writing some large proteins is not yet optimized\n", - "complex_system.to_gromacs(\"complex\")" + "complex_system.to_gro(\"complex.gro\")\n", + "complex_system.to_top(\"complex.top\")" ] } ], @@ -191,7 +208,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.10" } }, "nbformat": 4, diff --git a/openff/toolkit/typing/engines/smirnoff/forcefield.py b/openff/toolkit/typing/engines/smirnoff/forcefield.py index 9bab02acf..7f4af0ecb 100644 --- a/openff/toolkit/typing/engines/smirnoff/forcefield.py +++ b/openff/toolkit/typing/engines/smirnoff/forcefield.py @@ -30,7 +30,7 @@ from packaging.version import Version -from openff.toolkit import Quantity +from openff.toolkit import Quantity, unit from openff.toolkit.typing.engines.smirnoff.io import ParameterIOHandler from openff.toolkit.typing.engines.smirnoff.parameters import ParameterHandler from openff.toolkit.typing.engines.smirnoff.plugins import load_handler_plugins @@ -1400,7 +1400,7 @@ def get_partial_charges(self, molecule: "Molecule", **kwargs: Any) -> Quantity: force_field=self, topology=[molecule], **kwargs )["Electrostatics"].charges.values() ], - "elementary_charge", + unit.elementary_charge, ) def __getitem__(self, val: Union[str, ParameterHandler]) -> ParameterHandler: From 94bac50af7576ce7b2de0114a7f0be9e57f8f870 Mon Sep 17 00:00:00 2001 From: "Matthew W. Thompson" Date: Tue, 1 Oct 2024 08:39:47 -0500 Subject: [PATCH 05/11] Another simplification --- openff/toolkit/typing/engines/smirnoff/forcefield.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/openff/toolkit/typing/engines/smirnoff/forcefield.py b/openff/toolkit/typing/engines/smirnoff/forcefield.py index 7f4af0ecb..9f3492bcc 100644 --- a/openff/toolkit/typing/engines/smirnoff/forcefield.py +++ b/openff/toolkit/typing/engines/smirnoff/forcefield.py @@ -30,7 +30,7 @@ from packaging.version import Version -from openff.toolkit import Quantity, unit +from openff.toolkit import Quantity from openff.toolkit.typing.engines.smirnoff.io import ParameterIOHandler from openff.toolkit.typing.engines.smirnoff.parameters import ParameterHandler from openff.toolkit.typing.engines.smirnoff.plugins import load_handler_plugins @@ -1383,9 +1383,7 @@ def get_partial_charges(self, molecule: "Molecule", **kwargs: Any) -> Quantity: charge calculation to be cached. """ - from openff.interchange import Interchange - - from openff.toolkit import Molecule + from openff.toolkit import Molecule, unit if not isinstance(molecule, Molecule): raise ValueError( @@ -1396,8 +1394,8 @@ def get_partial_charges(self, molecule: "Molecule", **kwargs: Any) -> Quantity: return Quantity( [ c.m - for c in Interchange.from_smirnoff( - force_field=self, topology=[molecule], **kwargs + for c in self.create_interchange( + topology=molecule.to_topology(), **kwargs, )["Electrostatics"].charges.values() ], unit.elementary_charge, From 67756364bbaedcc290eeeb83a939cdc9a781bd19 Mon Sep 17 00:00:00 2001 From: "Matthew W. Thompson" Date: Thu, 29 Aug 2024 10:37:20 -0500 Subject: [PATCH 06/11] Test against `openff-interchange-0.4.0beta1` Updates for Interchange 0.4.0/Pydantic v2 Update BRD4 notebook cosmetic commit to kick CI Revert --- devtools/conda-envs/conda.yaml | 1 + devtools/conda-envs/conda_oe.yaml | 1 + devtools/conda-envs/installer.yaml | 1 + devtools/conda-envs/openeye-examples.yaml | 5 +- devtools/conda-envs/openeye.yaml | 5 +- devtools/conda-envs/rdkit-examples.yaml | 5 +- devtools/conda-envs/rdkit.yaml | 5 +- devtools/conda-envs/release-build.yaml | 1 + devtools/conda-envs/test_env.yaml | 5 +- .../.gitignore | 1 + .../BRD4_inhibitor_benchmark.ipynb | 89 ++++++++----------- openff/toolkit/_tests/test_forcefield.py | 7 +- .../typing/engines/smirnoff/forcefield.py | 8 +- 13 files changed, 63 insertions(+), 71 deletions(-) diff --git a/devtools/conda-envs/conda.yaml b/devtools/conda-envs/conda.yaml index 0c64bc009..a41a64a96 100644 --- a/devtools/conda-envs/conda.yaml +++ b/devtools/conda-envs/conda.yaml @@ -1,5 +1,6 @@ name: latest-deployment channels: + - conda-forge/label/openff-interchange_rc - conda-forge dependencies: # Base depends diff --git a/devtools/conda-envs/conda_oe.yaml b/devtools/conda-envs/conda_oe.yaml index ad491db0a..d4077595b 100644 --- a/devtools/conda-envs/conda_oe.yaml +++ b/devtools/conda-envs/conda_oe.yaml @@ -1,5 +1,6 @@ name: latest-deployment channels: + - conda-forge/label/openff-interchange_rc - conda-forge - openeye dependencies: diff --git a/devtools/conda-envs/installer.yaml b/devtools/conda-envs/installer.yaml index 93374e815..69a98fb96 100644 --- a/devtools/conda-envs/installer.yaml +++ b/devtools/conda-envs/installer.yaml @@ -1,6 +1,7 @@ name: constructor channels: + - conda-forge/label/openff-interchange_rc - defaults - conda-forge diff --git a/devtools/conda-envs/openeye-examples.yaml b/devtools/conda-envs/openeye-examples.yaml index f4673198a..593f2f854 100644 --- a/devtools/conda-envs/openeye-examples.yaml +++ b/devtools/conda-envs/openeye-examples.yaml @@ -1,11 +1,12 @@ name: openeye-examples channels: + - conda-forge/label/openff-interchange_rc - openeye - conda-forge dependencies: # Base depends - python - - pydantic =1 + - pydantic - packaging - numpy - networkx @@ -19,7 +20,7 @@ dependencies: - openff-amber-ff-ports >=0.0.3 - openff-units =0.2.0 - openff-utilities >=0.1.5 - - openff-interchange-base >=0.3.19 + - openff-interchange-base >=0.4.0beta1 - openff-nagl-base ~=0.4.0 - openff-nagl-models ==0.3.0 - typing_extensions diff --git a/devtools/conda-envs/openeye.yaml b/devtools/conda-envs/openeye.yaml index 56c35b51a..8e1f7c92a 100644 --- a/devtools/conda-envs/openeye.yaml +++ b/devtools/conda-envs/openeye.yaml @@ -1,11 +1,12 @@ name: openff-toolkit-test-openeye channels: + - conda-forge/label/openff-interchange_rc - openeye - conda-forge dependencies: # Base depends - python - - pydantic =1 + - pydantic - packaging - numpy - networkx @@ -19,7 +20,7 @@ dependencies: - openff-units =0.2.0 - openff-amber-ff-ports - openff-utilities >=0.1.5 - - openff-interchange-base >=0.3.19 + - openff-interchange-base >=0.4.0beta1 - openff-nagl-base ~=0.4.0 - openff-nagl-models ==0.3.0 - typing_extensions diff --git a/devtools/conda-envs/rdkit-examples.yaml b/devtools/conda-envs/rdkit-examples.yaml index 34d3a933e..97e97114c 100644 --- a/devtools/conda-envs/rdkit-examples.yaml +++ b/devtools/conda-envs/rdkit-examples.yaml @@ -1,10 +1,11 @@ name: rdkit-examples channels: + - conda-forge/label/openff-interchange_rc - conda-forge dependencies: # Base depends - python - - pydantic =1 + - pydantic - packaging - numpy - networkx @@ -18,7 +19,7 @@ dependencies: - openff-amber-ff-ports >=0.0.3 - openff-units =0.2.0 - openff-utilities >=0.1.5 - - openff-interchange-base >=0.3.19 + - openff-interchange-base >=0.4.0beta1 - openff-nagl-base ~=0.4.0 - openff-nagl-models ==0.3.0 - typing_extensions diff --git a/devtools/conda-envs/rdkit.yaml b/devtools/conda-envs/rdkit.yaml index 5ff1e2b5f..7d5be8559 100644 --- a/devtools/conda-envs/rdkit.yaml +++ b/devtools/conda-envs/rdkit.yaml @@ -1,10 +1,11 @@ name: openff-toolkit-test-rdkit channels: + - conda-forge/label/openff-interchange_rc - conda-forge dependencies: # Base depends - python - - pydantic =1 + - pydantic - packaging - numpy - networkx @@ -18,7 +19,7 @@ dependencies: - openff-units =0.2.0 - openff-amber-ff-ports - openff-utilities >=0.1.5 - - openff-interchange-base >=0.3.19 + - openff-interchange-base >=0.4.0beta1 - openff-nagl-base ~=0.4.0 - openff-nagl-models ==0.3.0 - typing_extensions diff --git a/devtools/conda-envs/release-build.yaml b/devtools/conda-envs/release-build.yaml index fe496f143..c48e275d0 100644 --- a/devtools/conda-envs/release-build.yaml +++ b/devtools/conda-envs/release-build.yaml @@ -1,5 +1,6 @@ name: release-build channels: + - conda-forge/label/openff-interchange_rc - conda-forge dependencies: diff --git a/devtools/conda-envs/test_env.yaml b/devtools/conda-envs/test_env.yaml index 881211c47..0ce0126f4 100644 --- a/devtools/conda-envs/test_env.yaml +++ b/devtools/conda-envs/test_env.yaml @@ -1,5 +1,6 @@ name: openff-toolkit-test channels: + - conda-forge/label/openff-interchange_rc - openeye - conda-forge dependencies: @@ -19,7 +20,7 @@ dependencies: - openff-units =0.2.0 - openff-amber-ff-ports - openff-utilities >=0.1.5 - - openff-interchange-base >=0.3.19 + - openff-interchange-base >=0.4.0beta1 - openff-nagl-base ~=0.4.0 - openff-nagl-models ==0.3.0 # Toolkit-specific @@ -47,7 +48,7 @@ dependencies: - nomkl - mypy - typing_extensions - - pydantic =1 + - pydantic - pip: - types-setuptools - types-toml diff --git a/examples/using_smirnoff_with_amber_protein_forcefield/.gitignore b/examples/using_smirnoff_with_amber_protein_forcefield/.gitignore index 2b077ccab..8bf74f582 100644 --- a/examples/using_smirnoff_with_amber_protein_forcefield/.gitignore +++ b/examples/using_smirnoff_with_amber_protein_forcefield/.gitignore @@ -1,4 +1,5 @@ complex.* +complex_pointenergy.mdp receptor.* ligand.* protein.pdb diff --git a/examples/using_smirnoff_with_amber_protein_forcefield/BRD4_inhibitor_benchmark.ipynb b/examples/using_smirnoff_with_amber_protein_forcefield/BRD4_inhibitor_benchmark.ipynb index 3d3d247d3..04eabe05e 100644 --- a/examples/using_smirnoff_with_amber_protein_forcefield/BRD4_inhibitor_benchmark.ipynb +++ b/examples/using_smirnoff_with_amber_protein_forcefield/BRD4_inhibitor_benchmark.ipynb @@ -24,10 +24,11 @@ "repo_url = (\n", " \"https://raw.githubusercontent.com/MobleyLab/benchmarksets/master/input_files/\"\n", ")\n", + "\n", "sources = {\n", - " \"receptor.pdb\": repo_url + \"BRD4/pdb/BRD4.pdb\",\n", - " \"ligand.pdb\": repo_url + \"BRD4/pdb/ligand-1.pdb\",\n", - " \"ligand.sdf\": repo_url + \"BRD4/sdf/ligand-1.sdf\",\n", + " \"receptor.pdb\": f\"{repo_url}BRD4/pdb/BRD4.pdb\",\n", + " \"ligand.pdb\": f\"{repo_url}BRD4/pdb/ligand-1.pdb\",\n", + " \"ligand.sdf\": f\"{repo_url}BRD4/sdf/ligand-1.sdf\",\n", "}\n", "for filename, url in sources.items():\n", " r = requests.get(url)\n", @@ -40,36 +41,12 @@ "metadata": {}, "outputs": [], "source": [ - "from openff.toolkit import ForceField, Molecule, Topology" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Later we will use `Interchange.__add__`, which is an experimental feature. It needs to be turned on by setting the environment variable below, and by doing so we accept [some stability and accuracy risks](https://docs.openforcefield.org/projects/interchange/en/stable/using/experimental.html)." + "from openff.toolkit import ForceField, Molecule, Quantity, Topology" ] }, { "cell_type": "code", "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "env: INTERCHANGE_EXPERIMENTAL=1\n" - ] - } - ], - "source": [ - "%env INTERCHANGE_EXPERIMENTAL=1" - ] - }, - { - "cell_type": "code", - "execution_count": 4, "metadata": { "tags": [] }, @@ -77,7 +54,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "2f3b86c392c24705b86721395cf43ea4", + "model_id": "48226cb62a2849029c42d579843ef0f7", "version_major": 2, "version_minor": 0 }, @@ -90,8 +67,8 @@ "name": "stderr", "output_type": "stream", "text": [ - "/Users/jeffreywagner/projects/OpenForceField/openff-interchange/openff/interchange/_experimental.py:35: UserWarning: Interchange object combination is experimental and likely to produce strange results. Any workflow using this method is not guaranteed to be suitable for production. Use with extreme caution and thoroughly validate results!\n", - " return func(*args, **kwargs)\n" + "/Users/mattthompson/micromamba/envs/openff-toolkit-test/lib/python3.10/site-packages/openff/interchange/operations/_combine.py:52: InterchangeCombinationWarning: Interchange object combination is complex and likely to produce strange results outside of a limited set of use cases it has been tested in. Any workflow using this method is not guaranteed to be suitable for production or stable between versions. Use with extreme caution and thoroughly validate results!\n", + " warnings.warn(\n" ] } ], @@ -107,32 +84,32 @@ "\n", "receptor = ff14sb.create_interchange(topology=receptor_topology)\n", "\n", - "complex_system = receptor.combine(ligand)\n", - "\n", - "# TODO\n", - "# complex.box = pdbfile box vectors ...\n", - "# complex.positions = np.vstack([receptor.positions, ligand.positions])" + "# Interchange.combine works nicely for some cases but hasn't been tested for all - use caution\n", + "# if adapting this for more novel workflows!\n", + "complex_system = receptor.combine(ligand)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Export to OpenMM" + "### Export to OpenMM\n", + "\n", + "See [docs](https://docs.openforcefield.org/projects/interchange/en/stable/using/output.html#openmm) for more options." ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - " >" + " >" ] }, - "execution_count": 5, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -147,31 +124,35 @@ "tags": [] }, "source": [ - "### Export to Amber" + "### Export to Amber\n", + "\n", + "See [docs](https://docs.openforcefield.org/projects/interchange/en/stable/using/output.html#amber) for more options." ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ - "# TODO: Fix inferring residue information with mixed topology\n", - "if False:\n", - " complex_system.to_inpcrd(\"complex.inpcrd\")\n", - " complex_system.to_prmtop(\"complex.prmtop\")" + "complex_system.to_inpcrd(\"complex.inpcrd\")\n", + "complex_system.to_prmtop(\"complex.prmtop\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Export to GROMACS" + "### Export to GROMACS\n", + "\n", + "See [docs](https://docs.openforcefield.org/projects/interchange/en/stable/using/output.html#gromacs) for more options.\n", + "\n", + "GROMACS does not support vacuum simulations. In this example, we didn't add solvent and the original PDB file didn't have box vectors. We'll just arbitrarily add a 4 nm cubic box around the receptor-ligand complex." ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "metadata": { "tags": [] }, @@ -180,14 +161,16 @@ "name": "stderr", "output_type": "stream", "text": [ - "/Users/jeffreywagner/projects/OpenForceField/openff-interchange/openff/interchange/interop/gromacs/export/_export.py:48: UserWarning: WARNING: System defined with no box vectors, which GROMACS does not offically support in versions 2020 or newer (see https://gitlab.com/gromacs/gromacs/-/issues/3526). Setting box vectors to a 5 nm cube.\n", - " self._write_gro(gro, decimal)\n" + "/Users/mattthompson/micromamba/envs/openff-toolkit-test/lib/python3.10/site-packages/openff/interchange/components/mdconfig.py:471: UserWarning: Ambiguous failure while processing constraints. Constraining h-bonds as a stopgap.\n", + " warnings.warn(\n" ] } ], "source": [ - "complex_system.to_gro(\"complex.gro\")\n", - "complex_system.to_top(\"complex.top\")" + "complex_system.box = Quantity([4, 4, 4], \"nanometer\")\n", + "\n", + "# This step might be slow, writing some large proteins is not yet optimized\n", + "complex_system.to_gromacs(\"complex\")" ] } ], @@ -208,7 +191,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.10" + "version": "3.10.14" } }, "nbformat": 4, diff --git a/openff/toolkit/_tests/test_forcefield.py b/openff/toolkit/_tests/test_forcefield.py index 5a3cd4e98..d9615a4ab 100644 --- a/openff/toolkit/_tests/test_forcefield.py +++ b/openff/toolkit/_tests/test_forcefield.py @@ -15,6 +15,7 @@ from openff.units.openmm import from_openmm, to_openmm from openmm import NonbondedForce, Platform, XmlSerializer, app from openmm import unit as openmm_unit +from pydantic import ValidationError from openff.toolkit import unit from openff.toolkit._tests.create_molecules import ( @@ -4028,15 +4029,11 @@ def test_fractional_bondorder_invalid_interpolation_method(self): # This error will be either from v1 of the package (if v1 is installed) # or the faked v1 API (if v2 is installed). Ensure the v1 error or a # mimick of it is imported - try: - from pydantic.v1 import ValidationError - except ImportError: - from pydantic import ValidationError # If important, this can be a custom exception instead of a verbose ValidationError with pytest.raises( ValidationError, - match="given=invalid method name", + match="Input should be 'linear'.*input_value='invalid method name'", ): forcefield.create_openmm_system( topology, diff --git a/openff/toolkit/typing/engines/smirnoff/forcefield.py b/openff/toolkit/typing/engines/smirnoff/forcefield.py index 731c1cbd1..87aa81c3d 100644 --- a/openff/toolkit/typing/engines/smirnoff/forcefield.py +++ b/openff/toolkit/typing/engines/smirnoff/forcefield.py @@ -1385,7 +1385,7 @@ def get_partial_charges(self, molecule: "Molecule", **kwargs: Any) -> Quantity: """ from openff.interchange import Interchange - from openff.toolkit import Molecule, unit + from openff.toolkit import Molecule if not isinstance(molecule, Molecule): raise ValueError( @@ -1398,9 +1398,11 @@ def get_partial_charges(self, molecule: "Molecule", **kwargs: Any) -> Quantity: c.m for c in Interchange.from_smirnoff( force_field=self, topology=[molecule], **kwargs - )["Electrostatics"].charges.values() + )["Electrostatics"] + ._get_charges() + .values() ], - unit.elementary_charge, + "elementary_charge", ) def __getitem__(self, val: Union[str, ParameterHandler]) -> ParameterHandler: From adbee90109eaf35e43bef5b74602661d9bee3387 Mon Sep 17 00:00:00 2001 From: "Matthew W. Thompson" Date: Mon, 30 Sep 2024 15:10:49 -0500 Subject: [PATCH 07/11] Test against branch --- devtools/conda-envs/openeye-examples.yaml | 2 ++ devtools/conda-envs/openeye.yaml | 2 ++ devtools/conda-envs/rdkit-examples.yaml | 2 ++ devtools/conda-envs/rdkit.yaml | 2 ++ devtools/conda-envs/test_env.yaml | 1 + 5 files changed, 9 insertions(+) diff --git a/devtools/conda-envs/openeye-examples.yaml b/devtools/conda-envs/openeye-examples.yaml index 593f2f854..a46214665 100644 --- a/devtools/conda-envs/openeye-examples.yaml +++ b/devtools/conda-envs/openeye-examples.yaml @@ -44,3 +44,5 @@ dependencies: - pdbfixer - openmmforcefields >=0.11.2 - gromacs >=2023.3 + - pip: + - git+https://github.com/openforcefield/openff-interchange.git@fix-1052 diff --git a/devtools/conda-envs/openeye.yaml b/devtools/conda-envs/openeye.yaml index 8e1f7c92a..3b4c4a66d 100644 --- a/devtools/conda-envs/openeye.yaml +++ b/devtools/conda-envs/openeye.yaml @@ -41,3 +41,5 @@ dependencies: - mdtraj - nglview - parmed =3 + - pip: + - git+https://github.com/openforcefield/openff-interchange.git@fix-1052 diff --git a/devtools/conda-envs/rdkit-examples.yaml b/devtools/conda-envs/rdkit-examples.yaml index 97e97114c..32d7c76e5 100644 --- a/devtools/conda-envs/rdkit-examples.yaml +++ b/devtools/conda-envs/rdkit-examples.yaml @@ -46,3 +46,5 @@ dependencies: - pdbfixer - openmmforcefields >=0.11.2 - gromacs >=2023.3 + - pip: + - git+https://github.com/openforcefield/openff-interchange.git@fix-1052 diff --git a/devtools/conda-envs/rdkit.yaml b/devtools/conda-envs/rdkit.yaml index 7d5be8559..e0380634a 100644 --- a/devtools/conda-envs/rdkit.yaml +++ b/devtools/conda-envs/rdkit.yaml @@ -40,3 +40,5 @@ dependencies: - qcportal >=0.50 - qcengine - nglview + - pip: + - git+https://github.com/openforcefield/openff-interchange.git@fix-1052 diff --git a/devtools/conda-envs/test_env.yaml b/devtools/conda-envs/test_env.yaml index 0ce0126f4..1a51f8148 100644 --- a/devtools/conda-envs/test_env.yaml +++ b/devtools/conda-envs/test_env.yaml @@ -57,3 +57,4 @@ dependencies: - types-xmltodict - types-cachetools - mongo-types + - git+https://github.com/openforcefield/openff-interchange.git@fix-1052 From 0e605948b3e102defbf4f9d60fc3737c669f8bd9 Mon Sep 17 00:00:00 2001 From: "Matthew W. Thompson" Date: Mon, 30 Sep 2024 15:11:44 -0500 Subject: [PATCH 08/11] Undo change --- openff/toolkit/typing/engines/smirnoff/forcefield.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/openff/toolkit/typing/engines/smirnoff/forcefield.py b/openff/toolkit/typing/engines/smirnoff/forcefield.py index 87aa81c3d..9bab02acf 100644 --- a/openff/toolkit/typing/engines/smirnoff/forcefield.py +++ b/openff/toolkit/typing/engines/smirnoff/forcefield.py @@ -1398,9 +1398,7 @@ def get_partial_charges(self, molecule: "Molecule", **kwargs: Any) -> Quantity: c.m for c in Interchange.from_smirnoff( force_field=self, topology=[molecule], **kwargs - )["Electrostatics"] - ._get_charges() - .values() + )["Electrostatics"].charges.values() ], "elementary_charge", ) From 3b06e516604f9c3b541b9a7280e057b43b742aa8 Mon Sep 17 00:00:00 2001 From: "Matthew W. Thompson" Date: Tue, 1 Oct 2024 08:27:17 -0500 Subject: [PATCH 09/11] Revert some changes for simpler diff --- .../.gitignore | 1 - .../BRD4_inhibitor_benchmark.ipynb | 89 +++++++++++-------- .../typing/engines/smirnoff/forcefield.py | 4 +- 3 files changed, 55 insertions(+), 39 deletions(-) diff --git a/examples/using_smirnoff_with_amber_protein_forcefield/.gitignore b/examples/using_smirnoff_with_amber_protein_forcefield/.gitignore index 8bf74f582..2b077ccab 100644 --- a/examples/using_smirnoff_with_amber_protein_forcefield/.gitignore +++ b/examples/using_smirnoff_with_amber_protein_forcefield/.gitignore @@ -1,5 +1,4 @@ complex.* -complex_pointenergy.mdp receptor.* ligand.* protein.pdb diff --git a/examples/using_smirnoff_with_amber_protein_forcefield/BRD4_inhibitor_benchmark.ipynb b/examples/using_smirnoff_with_amber_protein_forcefield/BRD4_inhibitor_benchmark.ipynb index 04eabe05e..3d3d247d3 100644 --- a/examples/using_smirnoff_with_amber_protein_forcefield/BRD4_inhibitor_benchmark.ipynb +++ b/examples/using_smirnoff_with_amber_protein_forcefield/BRD4_inhibitor_benchmark.ipynb @@ -24,11 +24,10 @@ "repo_url = (\n", " \"https://raw.githubusercontent.com/MobleyLab/benchmarksets/master/input_files/\"\n", ")\n", - "\n", "sources = {\n", - " \"receptor.pdb\": f\"{repo_url}BRD4/pdb/BRD4.pdb\",\n", - " \"ligand.pdb\": f\"{repo_url}BRD4/pdb/ligand-1.pdb\",\n", - " \"ligand.sdf\": f\"{repo_url}BRD4/sdf/ligand-1.sdf\",\n", + " \"receptor.pdb\": repo_url + \"BRD4/pdb/BRD4.pdb\",\n", + " \"ligand.pdb\": repo_url + \"BRD4/pdb/ligand-1.pdb\",\n", + " \"ligand.sdf\": repo_url + \"BRD4/sdf/ligand-1.sdf\",\n", "}\n", "for filename, url in sources.items():\n", " r = requests.get(url)\n", @@ -41,12 +40,36 @@ "metadata": {}, "outputs": [], "source": [ - "from openff.toolkit import ForceField, Molecule, Quantity, Topology" + "from openff.toolkit import ForceField, Molecule, Topology" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Later we will use `Interchange.__add__`, which is an experimental feature. It needs to be turned on by setting the environment variable below, and by doing so we accept [some stability and accuracy risks](https://docs.openforcefield.org/projects/interchange/en/stable/using/experimental.html)." ] }, { "cell_type": "code", "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "env: INTERCHANGE_EXPERIMENTAL=1\n" + ] + } + ], + "source": [ + "%env INTERCHANGE_EXPERIMENTAL=1" + ] + }, + { + "cell_type": "code", + "execution_count": 4, "metadata": { "tags": [] }, @@ -54,7 +77,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "48226cb62a2849029c42d579843ef0f7", + "model_id": "2f3b86c392c24705b86721395cf43ea4", "version_major": 2, "version_minor": 0 }, @@ -67,8 +90,8 @@ "name": "stderr", "output_type": "stream", "text": [ - "/Users/mattthompson/micromamba/envs/openff-toolkit-test/lib/python3.10/site-packages/openff/interchange/operations/_combine.py:52: InterchangeCombinationWarning: Interchange object combination is complex and likely to produce strange results outside of a limited set of use cases it has been tested in. Any workflow using this method is not guaranteed to be suitable for production or stable between versions. Use with extreme caution and thoroughly validate results!\n", - " warnings.warn(\n" + "/Users/jeffreywagner/projects/OpenForceField/openff-interchange/openff/interchange/_experimental.py:35: UserWarning: Interchange object combination is experimental and likely to produce strange results. Any workflow using this method is not guaranteed to be suitable for production. Use with extreme caution and thoroughly validate results!\n", + " return func(*args, **kwargs)\n" ] } ], @@ -84,32 +107,32 @@ "\n", "receptor = ff14sb.create_interchange(topology=receptor_topology)\n", "\n", - "# Interchange.combine works nicely for some cases but hasn't been tested for all - use caution\n", - "# if adapting this for more novel workflows!\n", - "complex_system = receptor.combine(ligand)" + "complex_system = receptor.combine(ligand)\n", + "\n", + "# TODO\n", + "# complex.box = pdbfile box vectors ...\n", + "# complex.positions = np.vstack([receptor.positions, ligand.positions])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Export to OpenMM\n", - "\n", - "See [docs](https://docs.openforcefield.org/projects/interchange/en/stable/using/output.html#openmm) for more options." + "### Export to OpenMM" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - " >" + " >" ] }, - "execution_count": 4, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -124,35 +147,31 @@ "tags": [] }, "source": [ - "### Export to Amber\n", - "\n", - "See [docs](https://docs.openforcefield.org/projects/interchange/en/stable/using/output.html#amber) for more options." + "### Export to Amber" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ - "complex_system.to_inpcrd(\"complex.inpcrd\")\n", - "complex_system.to_prmtop(\"complex.prmtop\")" + "# TODO: Fix inferring residue information with mixed topology\n", + "if False:\n", + " complex_system.to_inpcrd(\"complex.inpcrd\")\n", + " complex_system.to_prmtop(\"complex.prmtop\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Export to GROMACS\n", - "\n", - "See [docs](https://docs.openforcefield.org/projects/interchange/en/stable/using/output.html#gromacs) for more options.\n", - "\n", - "GROMACS does not support vacuum simulations. In this example, we didn't add solvent and the original PDB file didn't have box vectors. We'll just arbitrarily add a 4 nm cubic box around the receptor-ligand complex." + "### Export to GROMACS" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": { "tags": [] }, @@ -161,16 +180,14 @@ "name": "stderr", "output_type": "stream", "text": [ - "/Users/mattthompson/micromamba/envs/openff-toolkit-test/lib/python3.10/site-packages/openff/interchange/components/mdconfig.py:471: UserWarning: Ambiguous failure while processing constraints. Constraining h-bonds as a stopgap.\n", - " warnings.warn(\n" + "/Users/jeffreywagner/projects/OpenForceField/openff-interchange/openff/interchange/interop/gromacs/export/_export.py:48: UserWarning: WARNING: System defined with no box vectors, which GROMACS does not offically support in versions 2020 or newer (see https://gitlab.com/gromacs/gromacs/-/issues/3526). Setting box vectors to a 5 nm cube.\n", + " self._write_gro(gro, decimal)\n" ] } ], "source": [ - "complex_system.box = Quantity([4, 4, 4], \"nanometer\")\n", - "\n", - "# This step might be slow, writing some large proteins is not yet optimized\n", - "complex_system.to_gromacs(\"complex\")" + "complex_system.to_gro(\"complex.gro\")\n", + "complex_system.to_top(\"complex.top\")" ] } ], @@ -191,7 +208,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.10" } }, "nbformat": 4, diff --git a/openff/toolkit/typing/engines/smirnoff/forcefield.py b/openff/toolkit/typing/engines/smirnoff/forcefield.py index 9bab02acf..7f4af0ecb 100644 --- a/openff/toolkit/typing/engines/smirnoff/forcefield.py +++ b/openff/toolkit/typing/engines/smirnoff/forcefield.py @@ -30,7 +30,7 @@ from packaging.version import Version -from openff.toolkit import Quantity +from openff.toolkit import Quantity, unit from openff.toolkit.typing.engines.smirnoff.io import ParameterIOHandler from openff.toolkit.typing.engines.smirnoff.parameters import ParameterHandler from openff.toolkit.typing.engines.smirnoff.plugins import load_handler_plugins @@ -1400,7 +1400,7 @@ def get_partial_charges(self, molecule: "Molecule", **kwargs: Any) -> Quantity: force_field=self, topology=[molecule], **kwargs )["Electrostatics"].charges.values() ], - "elementary_charge", + unit.elementary_charge, ) def __getitem__(self, val: Union[str, ParameterHandler]) -> ParameterHandler: From 684e2c9821d054a79825f0b40bdad4591c159b62 Mon Sep 17 00:00:00 2001 From: "Matthew W. Thompson" Date: Tue, 1 Oct 2024 08:39:47 -0500 Subject: [PATCH 10/11] Another simplification --- openff/toolkit/typing/engines/smirnoff/forcefield.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/openff/toolkit/typing/engines/smirnoff/forcefield.py b/openff/toolkit/typing/engines/smirnoff/forcefield.py index 7f4af0ecb..9f3492bcc 100644 --- a/openff/toolkit/typing/engines/smirnoff/forcefield.py +++ b/openff/toolkit/typing/engines/smirnoff/forcefield.py @@ -30,7 +30,7 @@ from packaging.version import Version -from openff.toolkit import Quantity, unit +from openff.toolkit import Quantity from openff.toolkit.typing.engines.smirnoff.io import ParameterIOHandler from openff.toolkit.typing.engines.smirnoff.parameters import ParameterHandler from openff.toolkit.typing.engines.smirnoff.plugins import load_handler_plugins @@ -1383,9 +1383,7 @@ def get_partial_charges(self, molecule: "Molecule", **kwargs: Any) -> Quantity: charge calculation to be cached. """ - from openff.interchange import Interchange - - from openff.toolkit import Molecule + from openff.toolkit import Molecule, unit if not isinstance(molecule, Molecule): raise ValueError( @@ -1396,8 +1394,8 @@ def get_partial_charges(self, molecule: "Molecule", **kwargs: Any) -> Quantity: return Quantity( [ c.m - for c in Interchange.from_smirnoff( - force_field=self, topology=[molecule], **kwargs + for c in self.create_interchange( + topology=molecule.to_topology(), **kwargs, )["Electrostatics"].charges.values() ], unit.elementary_charge, From 62b36763e87f4c12fc96d5b0731c02b9a5ecb7ad Mon Sep 17 00:00:00 2001 From: "Matthew W. Thompson" Date: Tue, 1 Oct 2024 08:40:49 -0500 Subject: [PATCH 11/11] Simplify --- openff/toolkit/_tests/test_forcefield.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/openff/toolkit/_tests/test_forcefield.py b/openff/toolkit/_tests/test_forcefield.py index d9615a4ab..4f8702d9d 100644 --- a/openff/toolkit/_tests/test_forcefield.py +++ b/openff/toolkit/_tests/test_forcefield.py @@ -15,7 +15,6 @@ from openff.units.openmm import from_openmm, to_openmm from openmm import NonbondedForce, Platform, XmlSerializer, app from openmm import unit as openmm_unit -from pydantic import ValidationError from openff.toolkit import unit from openff.toolkit._tests.create_molecules import ( @@ -4016,6 +4015,8 @@ def test_fractional_bondorder_invalid_interpolation_method(self): Ensure that requesting an invalid interpolation method leads to a FractionalBondOrderInterpolationMethodUnsupportedError """ + from pydantic import ValidationError + mol = create_ethanol() forcefield = ForceField( @@ -4026,10 +4027,6 @@ def test_fractional_bondorder_invalid_interpolation_method(self): )._fractional_bondorder_interpolation = "invalid method name" topology = Topology.from_molecules([mol]) - # This error will be either from v1 of the package (if v1 is installed) - # or the faked v1 API (if v2 is installed). Ensure the v1 error or a - # mimick of it is imported - # If important, this can be a custom exception instead of a verbose ValidationError with pytest.raises( ValidationError,