From 9b46988043335f93833132760e1b7615867d63ed Mon Sep 17 00:00:00 2001 From: Zhiyi Wu Date: Mon, 12 Dec 2022 20:44:55 +0000 Subject: [PATCH] pymbar4 (#268) * fix #207 * switch from pymbar 3 to pymbar 4 (minimal requirement pymbar>=4) * remove deprecated AutoMBAR * change estimators.MBAR kwarg method from "hybr" to "robust" * docs: note pymbar 4.x for 2.0 * update tests * Update CHANGES Co-authored-by: Oliver Beckstein --- CHANGES | 13 +- devtools/conda-envs/test_env.yaml | 2 +- docs/index.rst | 6 +- environment.yml | 4 +- setup.py | 79 +++++----- src/alchemlyb/convergence/convergence.py | 13 +- src/alchemlyb/estimators/__init__.py | 4 +- src/alchemlyb/estimators/bar_.py | 5 +- src/alchemlyb/estimators/mbar_.py | 163 ++++----------------- src/alchemlyb/preprocessing/subsampling.py | 32 ++-- src/alchemlyb/tests/pytest.ini | 3 - src/alchemlyb/tests/test_convergence.py | 2 - src/alchemlyb/tests/test_fep_estimators.py | 34 +---- src/alchemlyb/tests/test_ti_estimators.py | 1 - src/alchemlyb/workflows/abfe.py | 17 +-- 15 files changed, 115 insertions(+), 263 deletions(-) delete mode 100644 src/alchemlyb/tests/pytest.ini diff --git a/CHANGES b/CHANGES index 20fb8ec3..3f9e9f9a 100644 --- a/CHANGES +++ b/CHANGES @@ -13,15 +13,24 @@ The rules for this file: * release numbers follow "Semantic Versioning" https://semver.org ------------------------------------------------------------------------------ - */*/* xiki-tempula, orbeckst * 2.0.0 +Changes + - use pymbar 4 as backend; this release is incompatible with + pymbar 3.x (issue #207, PR #268, discussion #205). + - The default for keyword argument `method` in estimators.MBAR was changed + from "hybr" to "robust" (issue #207, PR #268). + Enhancements - - Add a new Error when no file has been matched in workflow.ABFE (PR #289). + - Raise ValueError when no file has been matched in workflow.ABFE (PR #289). - In workflows, the output folder will be created if it did not exist before (PR #290). + +Removals + - The AutoMBAR estimator was removed because pymbar 4's MBAR contains + equivalent functionality. (issue #284) 12/09/2022 DrDomenicoMarson, xiki-tempula, orbeckst diff --git a/devtools/conda-envs/test_env.yaml b/devtools/conda-envs/test_env.yaml index 608b8843..63b439cc 100644 --- a/devtools/conda-envs/test_env.yaml +++ b/devtools/conda-envs/test_env.yaml @@ -5,7 +5,7 @@ dependencies: - python - numpy - pandas -- pymbar >=3.0.5,<4 +- pymbar>=4 - scipy - scikit-learn - matplotlib diff --git a/docs/index.rst b/docs/index.rst index 2532772b..fe10e410 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -14,11 +14,11 @@ These functions are simple in usage and pure in scope, and can be chained togeth **alchemlyb** seeks to be as boring and simple as possible to enable more complex work. Its components allow work at all scales, from use on small systems using a single workstation to larger datasets that require distributed computing using libraries such as `dask`_. -The library is *under active development*. However, it is used by multiple groups in a production environment. We use `semantic versioning`_ to indicate clearly what kind of changes you may expect between releases. With release 1.0.0, the API has stabilized and is guaranteed to remain backwards-compatible until a 2.0.0 release. +The library is *under active development*. However, it is used by multiple groups in a production environment. We use `semantic versioning`_ to indicate clearly what kind of changes you may expect between releases. Within any major release (1.x, 2.x, ...), the API is stable and is guaranteed to remain backwards-compatible. .. Note:: - The current 1.x release of alchemlyb *only* supports `pymbar`_ releases **>= 3.0.5, <4.0**. - A future 2.x release of alchemlyb will *only* support pymbar **>= 4.0** (see `discussion #205`_ and `issue #207`_) + The **current 2.x release** of alchemlyb *only* supports `pymbar`_ releases **>= 4.0**. + (Previous 1.x releases only support pymbar >= 3.0.5, <4.) See `discussion #205`_ and `issue #207`_. See :ref:`contact` for how to get in touch if you have questions or find problems. diff --git a/environment.yml b/environment.yml index cdc9d1e9..ddee2d3c 100644 --- a/environment.yml +++ b/environment.yml @@ -2,10 +2,10 @@ name: alchemlyb channels: - conda-forge dependencies: -- python=3.8 +- python - numpy - pandas -- pymbar >=3.0.5,<4 +- pymbar>=4 - scipy - scikit-learn - matplotlib diff --git a/setup.py b/setup.py index 81aa42e1..a1c55403 100755 --- a/setup.py +++ b/setup.py @@ -11,39 +11,46 @@ import versioneer -setup(name='alchemlyb', - version=versioneer.get_version(), - cmdclass=versioneer.get_cmdclass(), - description='the simple alchemistry library', - author='David Dotson', - author_email='dotsdl@gmail.com', - maintainer='Oliver Beckstein', - maintainer_email='orbeckst@gmail.com', - classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'Intended Audience :: Science/Research', - 'License :: OSI Approved :: BSD License', - 'Operating System :: POSIX', - 'Operating System :: MacOS :: MacOS X', - 'Operating System :: Microsoft :: Windows ', - 'Programming Language :: Python', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Topic :: Scientific/Engineering', - 'Topic :: Scientific/Engineering :: Bio-Informatics', - 'Topic :: Scientific/Engineering :: Chemistry', - 'Topic :: Software Development :: Libraries :: Python Modules', - ], - packages=find_packages('src'), - package_dir={'': 'src'}, - license='BSD', - long_description=open('README.rst').read(), - long_description_content_type='text/x-rst', - python_requires='>=3.8', - tests_require = ['pytest', 'alchemtest'], - install_requires=['numpy', 'pandas>=1.4', 'pymbar>=3.0.5,<4', - 'scipy', 'scikit-learn', 'matplotlib'] - ) +setup( + name="alchemlyb", + version=versioneer.get_version(), + cmdclass=versioneer.get_cmdclass(), + description="the simple alchemistry library", + author="David Dotson", + author_email="dotsdl@gmail.com", + maintainer="Oliver Beckstein", + maintainer_email="orbeckst@gmail.com", + classifiers=[ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: BSD License", + "Operating System :: POSIX", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows ", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Topic :: Scientific/Engineering", + "Topic :: Scientific/Engineering :: Bio-Informatics", + "Topic :: Scientific/Engineering :: Chemistry", + "Topic :: Software Development :: Libraries :: Python Modules", + ], + packages=find_packages("src"), + package_dir={"": "src"}, + license="BSD", + long_description=open("README.rst").read(), + long_description_content_type="text/x-rst", + python_requires=">=3.8", + tests_require=["pytest", "alchemtest"], + install_requires=[ + "numpy", + "pandas>=1.4", + "pymbar>=4", + "scipy", + "scikit-learn", + "matplotlib", + ], +) diff --git a/src/alchemlyb/convergence/convergence.py b/src/alchemlyb/convergence/convergence.py index a91c1d81..8758c45a 100644 --- a/src/alchemlyb/convergence/convergence.py +++ b/src/alchemlyb/convergence/convergence.py @@ -7,8 +7,7 @@ import pandas as pd from .. import concat -from ..estimators import AutoMBAR as MBAR -from ..estimators import BAR, TI, FEP_ESTIMATORS, TI_ESTIMATORS +from ..estimators import BAR, TI, MBAR, FEP_ESTIMATORS, TI_ESTIMATORS from ..postprocessors.units import to_kT estimators_dispatch = {"BAR": BAR, "TI": TI, "MBAR": MBAR} @@ -57,19 +56,13 @@ def forward_backward_convergence(df_list, estimator="MBAR", num=10, **kwargs): 9 3.044149 0.016405 3.044385 0.016402 1.0 - Note - ----- - :class:`~alchemlyb.estimators.AutoMBAR` is used when ``estimator='MBAR'``, - supply ``method`` keyword to restore the behavior of - :class:`~alchemlyb.estimators.MBAR`. - (:code:`forward_backward_convergence(u_nk, 'MBAR', num=2, method='adaptive')`) - - .. versionadded:: 0.6.0 .. versionchanged:: 1.0.0 The ``estimator`` accepts uppercase input. The default for using ``estimator='MBAR'`` was changed from :class:`~alchemlyb.estimators.MBAR` to :class:`~alchemlyb.estimators.AutoMBAR`. + .. versionchanged:: 2.0.0 + Use pymbar.MBAR instead of the AutoMBAR option. """ logger = logging.getLogger("alchemlyb.convergence." "forward_backward_convergence") diff --git a/src/alchemlyb/estimators/__init__.py b/src/alchemlyb/estimators/__init__.py index 4b4e7771..1940bbd3 100644 --- a/src/alchemlyb/estimators/__init__.py +++ b/src/alchemlyb/estimators/__init__.py @@ -1,6 +1,6 @@ from .bar_ import BAR -from .mbar_ import MBAR, AutoMBAR +from .mbar_ import MBAR from .ti_ import TI -FEP_ESTIMATORS = [MBAR.__name__, AutoMBAR.__name__, BAR.__name__] +FEP_ESTIMATORS = [MBAR.__name__, BAR.__name__] TI_ESTIMATORS = [TI.__name__] diff --git a/src/alchemlyb/estimators/bar_.py b/src/alchemlyb/estimators/bar_.py index 7bf39bc7..bb0afd4d 100644 --- a/src/alchemlyb/estimators/bar_.py +++ b/src/alchemlyb/estimators/bar_.py @@ -1,6 +1,6 @@ import numpy as np import pandas as pd -from pymbar import BAR as BAR_ +from pymbar.other_estimators import bar as BAR_ from sklearn.base import BaseEstimator from .base import _EstimatorMixOut @@ -113,7 +113,7 @@ def fit(self, u_nk): w_r = uk1.iloc[:, k] - uk1.iloc[:, k + 1] # now determine df and ddf using pymbar.BAR - df, ddf = BAR_( + out = BAR_( w_f, w_r, method=self.method, @@ -122,6 +122,7 @@ def fit(self, u_nk): verbose=self.verbose, ) + df, ddf = out["Delta_f"], out["dDelta_f"] deltas = np.append(deltas, df) d_deltas = np.append(d_deltas, ddf**2) diff --git a/src/alchemlyb/estimators/mbar_.py b/src/alchemlyb/estimators/mbar_.py index 001e85b9..ee680753 100644 --- a/src/alchemlyb/estimators/mbar_.py +++ b/src/alchemlyb/estimators/mbar_.py @@ -1,5 +1,4 @@ import logging -from warnings import warn import pandas as pd import pymbar @@ -9,7 +8,7 @@ class MBAR(BaseEstimator, _EstimatorMixOut): - """Multi-state Bennett acceptance ratio (MBAR). + r"""Multi-state Bennett acceptance ratio (MBAR). Parameters ---------- @@ -22,11 +21,12 @@ class MBAR(BaseEstimator, _EstimatorMixOut): initial_f_k : np.ndarray, float, shape=(K), optional Set to the initial dimensionless free energies to use as a - guess (default None, which sets all f_k = 0). + guess (default None, which sets all :math:`f_k = 0`). - method : str, optional, default="hybr" + method : str, optional, default="robust" The optimization routine to use. This can be any of the methods - available via scipy.optimize.minimize() or scipy.optimize.root(). + available via :func:`scipy.optimize.minimize` or + :func:`scipy.optimize.root`. verbose : bool, optional Set to ``True`` if verbose debug output from :mod:`pymbar` is desired. @@ -56,11 +56,12 @@ class MBAR(BaseEstimator, _EstimatorMixOut): See Also -------- pymbar.mbar.MBAR - AutoMBAR .. versionchanged:: 1.0.0 `delta_f_`, `d_delta_f_`, `states_` are view of the original object. + .. versionchanged:: 2.0.0 + default value for `method` was changed from "hybr" to "robust" """ def __init__( @@ -68,7 +69,7 @@ def __init__( maximum_iterations=10000, relative_tolerance=1.0e-7, initial_f_k=None, - method="hybr", + method="robust", verbose=False, ): self.maximum_iterations = maximum_iterations @@ -89,8 +90,8 @@ def fit(self, u_nk): Parameters ---------- u_nk : DataFrame - u_nk[n,k] is the reduced potential energy of uncorrelated - configuration n evaluated at state k. + ``u_nk[n, k]`` is the reduced potential energy of uncorrelated + configuration ``n`` evaluated at state ``k``. """ # sort by state so that rows from same state are in contiguous blocks @@ -103,47 +104,30 @@ def fit(self, u_nk): ] self._states_ = u_nk.columns.values.tolist() - # Prepare the solver_protocol as stated in https://github.com/choderalab/pymbar/issues/419#issuecomment-803714103 - solver_options = { - "maximum_iterations": self.maximum_iterations, - "verbose": self.verbose, - } - solver_protocol = {"method": self.method, "options": solver_options} - - self._mbar, out = self._do_MBAR(u_nk, N_k, solver_protocol) - - free_energy_differences = [ - pd.DataFrame(i, columns=self._states_, index=self._states_) for i in out - ] - - (self._delta_f_, self._d_delta_f_, self.theta_) = free_energy_differences - - self._delta_f_.attrs = u_nk.attrs - self._d_delta_f_.attrs = u_nk.attrs - - return self - - def predict(self, u_ln): - pass - - def _do_MBAR(self, u_nk, N_k, solver_protocol): - mbar = pymbar.MBAR( + self._mbar = pymbar.MBAR( u_nk.T, N_k, + maximum_iterations=self.maximum_iterations, relative_tolerance=self.relative_tolerance, + verbose=self.verbose, initial_f_k=self.initial_f_k, - solver_protocol=(solver_protocol,), + solver_protocol=self.method, + ) + out = self._mbar.compute_free_energy_differences(return_theta=True) + self._delta_f_ = pd.DataFrame( + out["Delta_f"], columns=self._states_, index=self._states_ ) - self.logger.info( - "Solved MBAR equations with method %r and " - "maximum_iterations=%d, relative_tolerance=%g", - solver_protocol["method"], - solver_protocol["options"]["maximum_iterations"], - self.relative_tolerance, + self._d_delta_f_ = pd.DataFrame( + out["dDelta_f"], columns=self._states_, index=self._states_ ) - # set attributes - out = mbar.getFreeEnergyDifferences(return_theta=True) - return mbar, out + self.theta_ = pd.DataFrame( + out["Theta"], columns=self._states_, index=self._states_ + ) + + self._delta_f_.attrs = u_nk.attrs + self._d_delta_f_.attrs = u_nk.attrs + + return self @property def overlap_matrix(self): @@ -159,93 +143,4 @@ def overlap_matrix(self): --------- pymbar.mbar.MBAR.computeOverlap """ - return self._mbar.computeOverlap()["matrix"] - - -class AutoMBAR(MBAR): - """A more robust version of Multi-state Bennett acceptance ratio (MBAR). - - Given that there isn't a single *method* that would allow :class:`MBAR` - to converge for every single use case, the :class:`AutoMBAR` estimator - iteratively tries all the available methods to obtain the converged estimate. - - The fastest method *hybr* will be tried first, followed by the most stable method - *adaptive*. If *adaptive* does not converge, *BFGS* will be used as last resort. - Although *BFGS* is not as stable as *adaptive*, it has been shown to succeed in - some cases where *adaptive* cannot. - - :class:`AutoMBAR` may be useful in high-throughput calculations where it can avoid - failures due non-converged MBAR estimates. - - Parameters - ---------- - - method : str, optional, default=None - The optimization routine to use. This parameter defaults to ``None``. - When a specific method is set, AutoMBAR will behave in the same way - as MBAR. - - .. versionadded:: 1.0.0 - - - Note - ---- - All arguments are described under :class:`MBAR` except that the solver method - is determined by :class:`AutoMBAR` as described above. - - See Also - -------- - MBAR - - - .. versionadded:: 0.6.0 - .. versionchanged:: 1.0.0 - AutoMBAR accepts the `method` argument. - .. deprecated:: 1.0.1 - Deprecate AutoMBAR in favour of MBAR for pymbar4. It will be removed - in alchemlyb 2.0.0. - """ - - def __init__( - self, - maximum_iterations=10000, - relative_tolerance=1.0e-7, - initial_f_k=None, - verbose=False, - method=None, - ): - warn( - "From version 2.0.0, this will be replaced by the default alchemlyb.estimators.MBAR.", - DeprecationWarning, - ) - super().__init__( - maximum_iterations=maximum_iterations, - relative_tolerance=relative_tolerance, - initial_f_k=initial_f_k, - verbose=verbose, - method=method, - ) - self.logger = logging.getLogger("alchemlyb.estimators.AutoMBAR") - - def _do_MBAR(self, u_nk, N_k, solver_protocol): - if solver_protocol["method"] is None: - self.logger.info( - "Initialise the automatic routine of the MBAR " "estimator." - ) - # Try the fastest method first - try: - self.logger.info("Trying the hybr method.") - solver_protocol["method"] = "hybr" - mbar, out = super()._do_MBAR(u_nk, N_k, solver_protocol) - except pymbar.utils.ParameterError: - try: - self.logger.info("Trying the adaptive method.") - solver_protocol["method"] = "adaptive" - mbar, out = super()._do_MBAR(u_nk, N_k, solver_protocol) - except pymbar.utils.ParameterError: - self.logger.info("Trying the BFGS method.") - solver_protocol["method"] = "BFGS" - mbar, out = super()._do_MBAR(u_nk, N_k, solver_protocol) - return mbar, out - else: - return super()._do_MBAR(u_nk, N_k, solver_protocol) + return self._mbar.compute_overlap()["matrix"] diff --git a/src/alchemlyb/preprocessing/subsampling.py b/src/alchemlyb/preprocessing/subsampling.py index 653adbca..a659ca09 100644 --- a/src/alchemlyb/preprocessing/subsampling.py +++ b/src/alchemlyb/preprocessing/subsampling.py @@ -4,11 +4,9 @@ import warnings import pandas as pd -from pymbar.timeseries import ( - statisticalInefficiency, - detectEquilibration, - subsampleCorrelatedData, -) +from pymbar.timeseries import detect_equilibration as _detect_equilibration +from pymbar.timeseries import statistical_inefficiency as _statistical_inefficiency +from pymbar.timeseries import subsample_correlated_data as _subsample_correlated_data from .. import pass_attrs @@ -458,7 +456,7 @@ def statistical_inefficiency( ``True`` use ``ceil(statistical_inefficiency)`` to slice the data in uniform intervals (the default). ``False`` will sample at non-uniform intervals to closely match the (fractional) statistical_inefficieny, as implemented - in :func:`pymbar.timeseries.subsampleCorrelatedData`. + in :func:`pymbar.timeseries.subsample_correlated_data`. drop_duplicates : bool Drop the duplicated lines based on time. sort : bool @@ -488,13 +486,13 @@ def statistical_inefficiency( See Also -------- - pymbar.timeseries.statisticalInefficiency : detailed background - pymbar.timeseries.subsampleCorrelatedData : used for subsampling + pymbar.timeseries.statistical_inefficiency : detailed background + pymbar.timeseries.subsample_correlated_data : used for subsampling .. versionchanged:: 0.2.0 The ``conservative`` keyword was added and the method is now using - ``pymbar.timeseries.statisticalInefficiency()``; previously, the statistical + ``pymbar.timeseries.statistical_inefficiency()``; previously, the statistical inefficiency was _rounded_ (instead of ``ceil()``) and thus one could end up with correlated data. @@ -512,10 +510,12 @@ def statistical_inefficiency( df = slicing(df, lower=lower, upper=upper, step=step) # calculate statistical inefficiency of series (could use fft=True but needs test) - statinef = statisticalInefficiency(series, fast=False) + statinef = _statistical_inefficiency(series) - # use the subsampleCorrelatedData function to get the subsample index - indices = subsampleCorrelatedData(series, g=statinef, conservative=conservative) + # use the subsample_correlated_data function to get the subsample index + indices = _subsample_correlated_data( + series, g=statinef, conservative=conservative + ) df = df.iloc[indices] else: df = slicing(df, lower=lower, upper=upper, step=step) @@ -569,8 +569,8 @@ def equilibrium_detection( See Also -------- - pymbar.timeseries.detectEquilibration : detailed background - pymbar.timeseries.subsampleCorrelatedData : used for subsampling + pymbar.timeseries.detect_equilibration : detailed background + pymbar.timeseries.subsample_correlated_data : used for subsampling .. versionchanged:: 1.0.0 @@ -586,12 +586,12 @@ def equilibrium_detection( df = slicing(df, lower=lower, upper=upper, step=step) # calculate statistical inefficiency of series, with equilibrium detection - t, statinef, Neff_max = detectEquilibration(series.values) + t, statinef, Neff_max = _detect_equilibration(series.values) series_equil = series[t:] df_equil = df[t:] - indices = subsampleCorrelatedData(series_equil, g=statinef) + indices = _subsample_correlated_data(series_equil, g=statinef) df = df_equil.iloc[indices] else: df = slicing(df, lower=lower, upper=upper, step=step) diff --git a/src/alchemlyb/tests/pytest.ini b/src/alchemlyb/tests/pytest.ini deleted file mode 100644 index fa6b641f..00000000 --- a/src/alchemlyb/tests/pytest.ini +++ /dev/null @@ -1,3 +0,0 @@ -[pytest] -filterwarnings = - ignore:From version 2.0.0, this will be replaced by the default alchemlyb.estimators.MBAR.:DeprecationWarning: \ No newline at end of file diff --git a/src/alchemlyb/tests/test_convergence.py b/src/alchemlyb/tests/test_convergence.py index fd29822a..32fa1eb9 100644 --- a/src/alchemlyb/tests/test_convergence.py +++ b/src/alchemlyb/tests/test_convergence.py @@ -1,11 +1,9 @@ import numpy as np import pandas as pd import pytest -from alchemtest.gmx import load_benzene from alchemlyb.convergence import forward_backward_convergence, fwdrev_cumavg_Rc, A_c from alchemlyb.convergence.convergence import _cummean -from alchemlyb.parsing import gmx def test_convergence_ti(gmx_benzene_Coulomb_dHdl): diff --git a/src/alchemlyb/tests/test_fep_estimators.py b/src/alchemlyb/tests/test_fep_estimators.py index c6d8e4b7..34c0728f 100644 --- a/src/alchemlyb/tests/test_fep_estimators.py +++ b/src/alchemlyb/tests/test_fep_estimators.py @@ -1,12 +1,10 @@ """Tests for all FEP-based estimators in ``alchemlyb``. """ -import numpy as np import pytest -from alchemtest.generic import load_MBAR_BGFS import alchemlyb -from alchemlyb.estimators import MBAR, BAR, AutoMBAR +from alchemlyb.estimators import MBAR, BAR class FEPestimatorMixin: @@ -52,36 +50,6 @@ def test_mbar(self, X_delta_f): self.compare_delta_f(X_delta_f) -class TestAutoMBAR(TestMBAR): - cls = AutoMBAR - - def test_autombar(self, X_delta_f): - with pytest.deprecated_call(): - self.compare_delta_f(X_delta_f) - - -class TestMBAR_fail: - def test_failback_adaptive(self, gmx_ABFE_complex_n_uk): - # The hybr will fail on this while adaptive will work - mbar = AutoMBAR().fit( - alchemlyb.concat([n_uk[:2] for n_uk in gmx_ABFE_complex_n_uk]) - ) - assert np.isclose( - mbar.d_delta_f_[(0.0, 0.0, 0.0)][(1.0, 1.0, 1.0)], 1.76832, 0.1 - ) - - -def test_AutoMBAR_BGFS(): - # A case where only BFGS would work - mbar = AutoMBAR() - u_nk = np.load(load_MBAR_BGFS()["data"]["u_nk"]) - N_k = np.load(load_MBAR_BGFS()["data"]["N_k"]) - solver_options = {"maximum_iterations": 10000, "verbose": False} - solver_protocol = {"method": None, "options": solver_options} - mbar, out = mbar._do_MBAR(u_nk.T, N_k, solver_protocol) - assert np.isclose(out[0][1][0], 12.552409, 0.1) - - class TestBAR(FEPestimatorMixin): """Tests for BAR.""" diff --git a/src/alchemlyb/tests/test_ti_estimators.py b/src/alchemlyb/tests/test_ti_estimators.py index 1fe2648b..5c644547 100644 --- a/src/alchemlyb/tests/test_ti_estimators.py +++ b/src/alchemlyb/tests/test_ti_estimators.py @@ -3,7 +3,6 @@ """ import pandas as pd import pytest -from alchemtest.gmx import load_benzene, load_ABFE import alchemlyb from alchemlyb.estimators import TI diff --git a/src/alchemlyb/workflows/abfe.py b/src/alchemlyb/workflows/abfe.py index c36423e4..7b3bff00 100644 --- a/src/alchemlyb/workflows/abfe.py +++ b/src/alchemlyb/workflows/abfe.py @@ -10,8 +10,7 @@ from .base import WorkflowBase from .. import concat from ..convergence import forward_backward_convergence -from ..estimators import AutoMBAR as MBAR -from ..estimators import BAR, TI, FEP_ESTIMATORS, TI_ESTIMATORS +from ..estimators import MBAR, BAR, TI, FEP_ESTIMATORS, TI_ESTIMATORS from ..parsing import gmx, amber from ..postprocessors.units import get_unit_converter from ..preprocessing.subsampling import decorrelate_dhdl, decorrelate_u_nk @@ -394,13 +393,6 @@ def estimate(self, estimators=("MBAR", "BAR", "TI"), **kwargs): 'MBAR']. Note that the estimators are in their original form where no unit conversion has been attempted. - Note - ----- - :class:`~alchemlyb.estimators.AutoMBAR` is used when - ``estimators='MBAR'``, supply ``method`` keyword to restore the - behavior of :class:`~alchemlyb.estimators.MBAR`. - (:code:`estimate(estimators='MBAR', method='adaptive')`) - """ # Make estimators into a tuple if isinstance(estimators, str): @@ -742,13 +734,6 @@ def check_convergence( matplotlib.axes.Axes An axes with the convergence drawn. - Note - ----- - :class:`~alchemlyb.estimators.AutoMBAR` is used when - ``estimator='MBAR'``, supply ``method`` keyword to restore the behavior - of :class:`~alchemlyb.estimators.MBAR`. - (:code:`check_convergence(10, estimator='MBAR', method='adaptive')`) - """ self.logger.info("Start convergence analysis.") self.logger.info("Checking data availability.")