From 07bb431bdcc1ec4c75a5b50d1f05ca6be838632e Mon Sep 17 00:00:00 2001 From: Lee-Ping Wang Date: Fri, 24 Sep 2021 11:20:36 -0700 Subject: [PATCH 1/3] Final changes for v1.9.2 release --- bin/ForceBalance.py | 2 +- devtools/conda-recipe/meta.yaml | 2 +- doc/api_header.tex | 2 +- doc/doxygen.cfg | 2 +- doc/header.tex | 2 +- setup.py | 2 +- src/forcefield.py | 4 ++-- src/lipid.py | 2 +- src/smirnoff_hack.py | 10 +++++----- src/tests/__init__.py | 18 ++++++++++++++++++ src/tests/test_engine.py | 9 +++++---- src/tests/test_liquid.py | 3 ++- src/tests/test_openmmio.py | 28 ++++++++++++++++++---------- src/tests/test_system.py | 7 ++++--- 14 files changed, 61 insertions(+), 32 deletions(-) diff --git a/bin/ForceBalance.py b/bin/ForceBalance.py index 8f01430da..d46298864 100755 --- a/bin/ForceBalance.py +++ b/bin/ForceBalance.py @@ -60,7 +60,7 @@ def process(word, color): return Answer def main(): - printcool("Welcome to ForceBalance version 1.9.1! =D\nForce Field Optimization System\n\nAuthors:\nLee-Ping Wang\nYudong Qiu, Keri A. McKiernan\nJeffrey R. Wagner, Hyesu Jang, Simon Boothroyd\nArthur Vigil, Erik G. Brandt, John Stoppelman\nJohnny Israeli, Matt Thompson", ansi="1", bold=True, minwidth=64) + printcool("Welcome to ForceBalance version 1.9.2! =D\nForce Field Optimization System\n\nAuthors:\nLee-Ping Wang\nYudong Qiu, Keri A. McKiernan\nJeffrey R. Wagner, Hyesu Jang, Simon Boothroyd\nArthur Vigil, Erik G. Brandt, John Stoppelman\nJohnny Israeli, Matt Thompson", ansi="1", bold=True, minwidth=64) logostr = """ ,'+++ ,++++++. .:,,. diff --git a/devtools/conda-recipe/meta.yaml b/devtools/conda-recipe/meta.yaml index 25e7e4c5c..2360aff32 100644 --- a/devtools/conda-recipe/meta.yaml +++ b/devtools/conda-recipe/meta.yaml @@ -1,6 +1,6 @@ package: name: forcebalance-dev - version: !!str 1.9.1 + version: !!str 1.9.2 source: path: ../.. diff --git a/doc/api_header.tex b/doc/api_header.tex index 23cce6b27..0aad5c82e 100644 --- a/doc/api_header.tex +++ b/doc/api_header.tex @@ -57,7 +57,7 @@ \vspace*{1cm} \begin{center} -{\Large ForceBalance Developer API Guide version 1.9.1}\\ +{\Large ForceBalance Developer API Guide version 1.9.2}\\ \vspace*{2cm} {\large Generated by Doxygen 1.8.11}\\ \vspace*{2.5 cm} diff --git a/doc/doxygen.cfg b/doc/doxygen.cfg index 15a0674bd..b50a7dd0c 100644 --- a/doc/doxygen.cfg +++ b/doc/doxygen.cfg @@ -32,7 +32,7 @@ PROJECT_NAME = ForceBalance # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 1.9.1 +PROJECT_NUMBER = 1.9.2 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer diff --git a/doc/header.tex b/doc/header.tex index 192323487..e4ea19825 100644 --- a/doc/header.tex +++ b/doc/header.tex @@ -57,7 +57,7 @@ \vspace*{1cm} \begin{center} -{\Large ForceBalance version 1.9.1}\\ +{\Large ForceBalance version 1.9.2}\\ \vspace*{2cm} {\large Generated by Doxygen 1.8.11}\\ \vspace*{2.5 cm} diff --git a/setup.py b/setup.py index 58041784c..b9c63122c 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ #| doc/api_header.tex |# #| bin/ForceBalance.py |# #===================================# -__version__ = "v1.9.1" +__version__ = "v1.9.2" try: # use git to find current version git_describe = subprocess.check_output(["git", "describe"]).strip() diff --git a/src/forcefield.py b/src/forcefield.py index 52b570b45..50fdd47c7 100644 --- a/src/forcefield.py +++ b/src/forcefield.py @@ -518,7 +518,7 @@ def check_dupes(self, pid, ffname, ln, pfld): extranum += 1 def warn_or_err(*args): if self.duplicate_pnames: - logger.warn(*args) + logger.warning(*args) else: logger.error(*args) warn_or_err("Encountered an duplicate parameter ID (%s)\n" % pid_) @@ -527,7 +527,7 @@ def warn_or_err(*args): for dupfnm, dupln, dupfld in zip(dupfnms, duplns, dupflds): warn_or_err("file %s line %i field %i\n" % (dupfnm, dupln+1, dupfld)) if self.duplicate_pnames: - logger.warn("Parameter name has been changed to %s\n" % pid) + logger.warning("Parameter name has been changed to %s\n" % pid) else: raise RuntimeError return pid diff --git a/src/lipid.py b/src/lipid.py index a502be161..1cf809b62 100644 --- a/src/lipid.py +++ b/src/lipid.py @@ -192,7 +192,7 @@ def prepare_temp_directory(self): def read_data(self): # Read the 'data.csv' file. The file should contain guidelines. - with open(os.path.join(self.tgtdir,'data.csv'),'rU') as f: R0 = list(csv.reader(f)) + with open(os.path.join(self.tgtdir,'data.csv'),'r') as f: R0 = list(csv.reader(f)) # All comments are erased. R1 = [[sub('#.*$','',word) for word in line] for line in R0 if len(line[0]) > 0 and line[0][0] != "#"] # All empty lines are deleted and words are converted to lowercase. diff --git a/src/smirnoff_hack.py b/src/smirnoff_hack.py index 8f5a66f71..2734d91d4 100644 --- a/src/smirnoff_hack.py +++ b/src/smirnoff_hack.py @@ -40,11 +40,11 @@ def hash_molecule_args_and_kwargs(molecule, *args, **kwargs): if _SHOULD_CACHE: - - print( - "SMIRNOFF functions will be replaced with cached versions to improve their " - "performance." - ) + # Commented out because it is printed even for non-SMIRNOFF calculations. + # print( + # "SMIRNOFF functions will be replaced with cached versions to improve their " + # "performance." + # ) # time based on total 540s evaluation # cache for OE find_smarts_matches (save 300+ s) diff --git a/src/tests/__init__.py b/src/tests/__init__.py index 6309d610f..4a5d885e6 100644 --- a/src/tests/__init__.py +++ b/src/tests/__init__.py @@ -27,3 +27,21 @@ def setup_method(self, method): def teardown_method(self): os.chdir(self.start_directory) + +def check_for_openmm(): + try: + try: + # Try importing openmm using >=7.6 namespace + from openmm import app + import openmm as mm + from openmm import unit + except ImportError: + # Try importing openmm using <7.6 namespace + import simtk.openmm as mm + from simtk.openmm import app + from simtk import unit + return True + except ImportError: + # If OpenMM classes cannot be imported, then set this flag + # so the testing classes/functions can use to skip. + return False diff --git a/src/tests/test_engine.py b/src/tests/test_engine.py index 630a09868..e9549be94 100644 --- a/src/tests/test_engine.py +++ b/src/tests/test_engine.py @@ -7,7 +7,7 @@ from forcebalance.tinkerio import TINKER from forcebalance.openmmio import OpenMM from collections import OrderedDict -from .__init__ import ForceBalanceTestCase +from .__init__ import ForceBalanceTestCase, check_for_openmm # Set SAVEDATA to True and run the tests in order to save data # to a file for future reference. This is easier to use for troubleshooting @@ -86,12 +86,12 @@ def setup_class(cls): if gmxpath != '': cls.engines['GMX'] = GMX(coords="all.gro", gmx_top="topol.top", gmx_mdp="shot.mdp", gmxpath=gmxpath, gmxsuffix=gmxsuffix) else: - logger.warn("GROMACS cannot be found, skipping GMX tests.") + logger.warning("GROMACS cannot be found, skipping GMX tests.") # Set up TINKER engine if tinkerpath != '': cls.engines['TINKER'] = TINKER(coords="all.arc", tinker_key="alaglu.key", tinkerpath=tinkerpath) else: - logger.warn("TINKER cannot be found, skipping TINKER tests.") + logger.warning("TINKER cannot be found, skipping TINKER tests.") # Set up OpenMM engine try: try: @@ -100,7 +100,7 @@ def setup_class(cls): import simtk.openmm cls.engines['OpenMM'] = OpenMM(coords="all.gro", pdb="conf.pdb", ffxml="a99sb.xml", platname="Reference", precision="double") except: - logger.warn("OpenMM cannot be imported, skipping OpenMM tests.") + logger.warning("OpenMM cannot be imported, skipping OpenMM tests.") @classmethod def teardown_class(cls): @@ -351,6 +351,7 @@ class TestAmoebaWater6(ForceBalanceTestCase): """ @classmethod def setup_class(cls): + if not check_for_openmm(): pytest.skip("No OpenMM modules found.") super(TestAmoebaWater6, cls).setup_class() #self.logger.debug("\nBuilding options for target...\n") cls.cwd = os.path.dirname(os.path.realpath(__file__)) diff --git a/src/tests/test_liquid.py b/src/tests/test_liquid.py index 88e08df53..86308b0d9 100644 --- a/src/tests/test_liquid.py +++ b/src/tests/test_liquid.py @@ -7,10 +7,11 @@ from forcebalance.forcefield import FF from forcebalance.objective import Objective from forcebalance.optimizer import Optimizer -from .__init__ import ForceBalanceTestCase +from .__init__ import ForceBalanceTestCase, check_for_openmm class TestWaterTutorial(ForceBalanceTestCase): def setup_method(self, method): + if not check_for_openmm(): pytest.skip("No OpenMM modules found.") super(TestWaterTutorial, self).setup_method(method) self.cwd = os.path.dirname(os.path.realpath(__file__)) # copy folder 'files/test_liquid' into a new folder 'files/test_liquid.run' diff --git a/src/tests/test_openmmio.py b/src/tests/test_openmmio.py index eb95461ff..5d4ea199a 100644 --- a/src/tests/test_openmmio.py +++ b/src/tests/test_openmmio.py @@ -5,16 +5,21 @@ import numpy as np try: - # Try importing openmm using >=7.6 namespace - from openmm import app - import openmm as mm - from openmm import unit + try: + # Try importing openmm using >=7.6 namespace + from openmm import app + import openmm as mm + from openmm import unit + except ImportError: + # Try importing openmm using <7.6 namespace + import simtk.openmm as mm + from simtk.openmm import app + from simtk import unit + no_openmm = False except ImportError: - # Try importing openmm using <7.6 namespace - import simtk.openmm as mm - from simtk.openmm import app - from simtk import unit - + # If OpenMM classes cannot be imported, then set this flag + # so the testing classes/functions can use to skip. + no_openmm = True import os import shutil @@ -26,6 +31,7 @@ class TestLiquid_OpenMM(TargetTests): def setup_method(self, method): + if no_openmm: pytest.skip("No OpenMM modules found.") super(TestLiquid_OpenMM, self).setup_method(method) self.check_grad_fd = False # settings specific to this target @@ -53,6 +59,7 @@ def teardown_method(self): class TestInteraction_OpenMM(TargetTests): def setup_method(self, method): + if no_openmm: pytest.skip("No OpenMM modules found.") super(TestInteraction_OpenMM, self).setup_method(method) # TargetTests.setup_class(cls) # settings specific to this target @@ -77,9 +84,10 @@ def teardown_method(self): shutil.rmtree('temp') super(TestInteraction_OpenMM, self).teardown_method() - + def test_local_coord_sites(): """Make sure that the internal prep of vs positions matches that given by OpenMM.""" + if no_openmm: pytest.skip("No OpenMM modules found.") # make a system mol = app.PDBFile(os.path.join("files", "vs_mol.pdb")) modeller = app.Modeller(topology=mol.topology, positions=mol.positions) diff --git a/src/tests/test_system.py b/src/tests/test_system.py index 454713c19..3cd4be23e 100644 --- a/src/tests/test_system.py +++ b/src/tests/test_system.py @@ -3,7 +3,7 @@ from builtins import str import os, shutil import tarfile -from .__init__ import ForceBalanceTestCase +from .__init__ import ForceBalanceTestCase, check_for_openmm from forcebalance.parser import parse_inputs from forcebalance.forcefield import FF from forcebalance.objective import Objective @@ -181,7 +181,7 @@ def test_thermo_bromine_study(self): class TestEvaluatorBromineStudy(ForceBalanceSystemTest): def setup_method(self, method): - pytest.importorskip("evaluator") + pytest.importorskip("openff.evaluator") super(TestEvaluatorBromineStudy, self).setup_method(method) cwd = os.path.dirname(os.path.realpath(__file__)) os.chdir(os.path.join(cwd, '..', '..', 'studies', '003d_evaluator_liquid_bromine')) @@ -213,7 +213,7 @@ def test_bromine_study(self): msgX="\nCalculated objective function is outside expected range.\n If this seems reasonable, update EXPECTED_EVALUATOR_BROMINE_OBJECTIVE in test_system.py with these values" np.testing.assert_allclose(EXPECTED_EVALUATOR_BROMINE_OBJECTIVE, X, atol=120, err_msg=msgX) msgG="\nCalculated gradient is outside expected range.\n If this seems reasonable, update EXPECTED_EVALUATOR_BROMINE_GRADIENT in test_system.py with these values" - np.testing.assert_allclose(EXPECTED_EVALUATOR_BROMINE_GRADIENT, G, atol=2000, err_msg=msgG) + np.testing.assert_allclose(EXPECTED_EVALUATOR_BROMINE_GRADIENT, G, atol=4000, err_msg=msgG) class TestLipidStudy(ForceBalanceSystemTest): def setup_method(self, method): @@ -232,6 +232,7 @@ def test_lipid_study(self): class TestImplicitSolventHFEStudy(ForceBalanceSystemTest): def setup_method(self, method): + if not check_for_openmm(): pytest.skip("No OpenMM modules found.") super(TestImplicitSolventHFEStudy, self).setup_method(method) cwd = os.path.dirname(os.path.realpath(__file__)) os.chdir(os.path.join(cwd, '..', '..', 'studies', '012_implicit_solvent_hfe')) From 23c2a56257eb5c6cdf2d2b7298df186603ab54e0 Mon Sep 17 00:00:00 2001 From: Jeff Wagner Date: Fri, 24 Sep 2021 11:41:34 -0700 Subject: [PATCH 2/3] try OpenMM 7.5 CI --- devtools/conda-envs/test_env.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devtools/conda-envs/test_env.yaml b/devtools/conda-envs/test_env.yaml index 0b0bdb7d2..479814fdc 100644 --- a/devtools/conda-envs/test_env.yaml +++ b/devtools/conda-envs/test_env.yaml @@ -20,7 +20,7 @@ dependencies: - swig - future - pymbar - - openmm + - openmm =7.5 - ambertools # The following two are not compatible with python 2.7 and 3.5, so they are conditionally installed in .travis.yml #- openforcefield From 2c69c2338b910237cfd8044a8b2189c5de792181 Mon Sep 17 00:00:00 2001 From: Jeff Wagner Date: Fri, 24 Sep 2021 11:41:47 -0700 Subject: [PATCH 3/3] undo openmm pin --- devtools/conda-envs/test_env.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devtools/conda-envs/test_env.yaml b/devtools/conda-envs/test_env.yaml index 479814fdc..0b0bdb7d2 100644 --- a/devtools/conda-envs/test_env.yaml +++ b/devtools/conda-envs/test_env.yaml @@ -20,7 +20,7 @@ dependencies: - swig - future - pymbar - - openmm =7.5 + - openmm - ambertools # The following two are not compatible with python 2.7 and 3.5, so they are conditionally installed in .travis.yml #- openforcefield