From e62b1784e7516f543402c013cfd532d6003aa859 Mon Sep 17 00:00:00 2001 From: Matthew Newville Date: Sun, 4 Aug 2024 20:34:44 -0500 Subject: [PATCH 1/9] BUG: fix typo in 'create_uvars' method Closes: #962 --- lmfit/parameter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lmfit/parameter.py b/lmfit/parameter.py index a7ec9a65..243d4227 100644 --- a/lmfit/parameter.py +++ b/lmfit/parameter.py @@ -515,9 +515,9 @@ def create_uvars(self, covar=None): vindex += 1 vnames.append(par.name) vbest.append(par.value) - if getattr(par, 'sdterr', None) is None and covar is not None: + if getattr(par, 'stderr', None) is None and covar is not None: par.stderr = sqrt(covar[vindex, vindex]) - uvars[par.name] = ufloat(par.value, getattr(par, 'sdterr', 0.0)) + uvars[par.name] = ufloat(par.value, getattr(par, 'stderr', 0.0)) corr_uvars = None if covar is not None: From 7fd4e42e84b3ab8f0bdc05274aa270d4ded765bf Mon Sep 17 00:00:00 2001 From: Matthew Newville Date: Sun, 11 Aug 2024 12:40:21 -0500 Subject: [PATCH 2/9] MAINT: 'uncertainties' fails if 'stderr' is None, so set to zero --- lmfit/parameter.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lmfit/parameter.py b/lmfit/parameter.py index 243d4227..cd6d9626 100644 --- a/lmfit/parameter.py +++ b/lmfit/parameter.py @@ -517,7 +517,10 @@ def create_uvars(self, covar=None): vbest.append(par.value) if getattr(par, 'stderr', None) is None and covar is not None: par.stderr = sqrt(covar[vindex, vindex]) - uvars[par.name] = ufloat(par.value, getattr(par, 'stderr', 0.0)) + stderr = getattr(par, 'stderr', 0.0) + if stderr is None: + stderr = 0.0 + uvars[par.name] = ufloat(par.value, stderr) corr_uvars = None if covar is not None: From b812b4731805f9d85d717aff0ad34031c747d1d4 Mon Sep 17 00:00:00 2001 From: Matthew Newville Date: Sun, 11 Aug 2024 12:44:30 -0500 Subject: [PATCH 3/9] MAINT: asteval no longer raises NameError to Python - so we suppress 'asteval' expections to stderr and look for them when creating parameters --- lmfit/parameter.py | 25 +++++++++++++++++++++++-- tests/test_parameters.py | 3 +-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/lmfit/parameter.py b/lmfit/parameter.py index cd6d9626..77ba882c 100644 --- a/lmfit/parameter.py +++ b/lmfit/parameter.py @@ -27,6 +27,20 @@ def check_ast_errors(expr_eval): expr_eval.raise_exception(None) +class Writer: + """Replace 'stdout' and 'stderr' for asteval.""" + def __init__(self, **kws): + self.messages = [] + for k, v in kws.items(): + setattr(self, k, v) + + def write(self, msg): + """Internal writer.""" + o = msg.strip() + if len(o) > 0: + self.messages.append(msg) + + def asteval_with_uncertainties(*vals, obj=None, pars=None, names=None, **kwargs): """Calculate object value, given values for variables. @@ -76,8 +90,9 @@ def __init__(self, usersyms=None): """ super().__init__(self) - - self._asteval = Interpreter() + self._ast_msgs = Writer() + self._asteval = Interpreter(writer=self._ast_msgs, + err_writer=self._ast_msgs) _syms = {} _syms.update(SCIPY_FUNCTIONS) @@ -86,6 +101,9 @@ def __init__(self, usersyms=None): for key, val in _syms.items(): self._asteval.symtable[key] = val + def _writer(self, msg): + self._asteval_msgs.append(msg) + def copy(self): """Parameters.copy() should always be a deepcopy.""" return self.__deepcopy__(None) @@ -433,6 +451,9 @@ def add(self, name, value=None, vary=True, min=-inf, max=inf, expr=None, self.__setitem__(name, Parameter(value=value, name=name, vary=vary, min=min, max=max, expr=expr, brute_step=brute_step)) + if len(self._asteval.error) > 0: + err = self._asteval.error[0] + raise err.exc(err.msg) def add_many(self, *parlist): """Add many parameters, using a sequence of tuples. diff --git a/tests/test_parameters.py b/tests/test_parameters.py index 7e12b1f0..998341e3 100644 --- a/tests/test_parameters.py +++ b/tests/test_parameters.py @@ -39,8 +39,7 @@ def assert_parameter_attributes(par, expected): def test_check_ast_errors(): """Assert that an exception is raised upon AST errors.""" pars = lmfit.Parameters() - - msg = r"at expr='<_?ast.Module object at" + msg = "name 'par2' is not defined" with pytest.raises(NameError, match=msg): pars.add('par1', expr='2.0*par2') From 05fb78e8ebab8d3cc3360f3eb1ee852c8f4a7528 Mon Sep 17 00:00:00 2001 From: reneeotten Date: Fri, 16 Aug 2024 10:50:54 -0400 Subject: [PATCH 4/9] DOC: tweak 'sphinx-gallery' settings --- doc/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/conf.py b/doc/conf.py index 1a36156b..972b552b 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -167,7 +167,7 @@ 'examples_dirs': '../examples', 'gallery_dirs': 'examples', 'filename_pattern': r'(\\|/)documentation|(\\|/)example_', - 'ignore_pattern': r'(\\|/)doc_', + 'ignore_pattern': 'doc_', 'ignore_repr_types': r'matplotlib', 'image_srcset': ["3x"], } From 07d65bf8ebcf013e7b47ce0c4930aa39d7cd2cc3 Mon Sep 17 00:00:00 2001 From: reneeotten Date: Fri, 16 Aug 2024 10:51:28 -0400 Subject: [PATCH 5/9] MAINT: update pre-commit hooks --- .pre-commit-config.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ee53e906..bad4bf3f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ exclude: 'doc/conf.py' repos: - repo: https://github.com/asottile/pyupgrade - rev: v3.16.0 + rev: v3.17.0 hooks: - id: pyupgrade args: [--py38-plus] @@ -12,18 +12,18 @@ repos: hooks: - id: check-ast - id: check-builtin-literals + - id: check-docstring-first - id: check-case-conflict - id: check-merge-conflict - id: check-toml + - id: check-yaml - id: debug-statements - id: end-of-file-fixer - id: mixed-line-ending - id: trailing-whitespace - - id: fix-encoding-pragma - args: [--remove] - repo: https://github.com/PyCQA/flake8 - rev: 7.1.0 + rev: 7.1.1 hooks: - id: flake8 additional_dependencies: [flake8-deprecated, flake8-mutable, Flake8-pyproject] From 805263ddfac4f877dfd2c4e834155bd274020e3d Mon Sep 17 00:00:00 2001 From: reneeotten Date: Fri, 16 Aug 2024 10:53:22 -0400 Subject: [PATCH 6/9] CI: update to latest NumPy version --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 314d8704..01bc9d6e 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -256,7 +256,7 @@ stages: displayName: 'Install build, pip, setuptools, wheel, pybind11, and cython' - script: | export PATH=/home/vsts/.local/bin:$PATH - export numpy_version=2.0.0 + export numpy_version=2.0.1 wget https://github.com/numpy/numpy/releases/download/v${numpy_version}/numpy-${numpy_version}.tar.gz tar xzvf numpy-${numpy_version}.tar.gz cd numpy-${numpy_version} From 16f8cbd176ed5b9f5e1ac6a369c7bd75dbd5046a Mon Sep 17 00:00:00 2001 From: reneeotten Date: Fri, 16 Aug 2024 12:39:05 -0400 Subject: [PATCH 7/9] BLD: remove redundant wheel dependency --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e41e844b..9578466d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["setuptools>=45", "wheel", "setuptools_scm>=6.2"] +requires = ["setuptools>=45", "setuptools_scm>=6.2"] build-backend = "setuptools.build_meta" [project] From d6810a558887956f598d58d9876be8fe96090d6d Mon Sep 17 00:00:00 2001 From: reneeotten Date: Fri, 16 Aug 2024 18:06:34 -0400 Subject: [PATCH 8/9] DOC: update names of the documentation examples in Gallery - also rename the file doc_uvars_params.py to follow the usual naming conventions --- doc/doc_examples_to_gallery.py | 13 ++++++++----- doc/model.rst | 2 +- ...{doc_uvars_params.py => doc_parameters_uvars.py} | 4 ++-- 3 files changed, 11 insertions(+), 8 deletions(-) rename examples/{doc_uvars_params.py => doc_parameters_uvars.py} (96%) diff --git a/doc/doc_examples_to_gallery.py b/doc/doc_examples_to_gallery.py index 4cfeb5bc..49695ffd 100755 --- a/doc/doc_examples_to_gallery.py +++ b/doc/doc_examples_to_gallery.py @@ -5,7 +5,7 @@ - create a "documentation" directory within "examples" - add a README.txt file -- copy the examples from the documentation, bu remove the "doc_" from the +- copy the examples from the documentation, removing the "doc_" from the filename - add the required docstring to the files for proper rendering - copy the data files @@ -46,12 +46,15 @@ def copy_data_files(src_dir, dest_dir): ) for fn in files: + sname = fn.name[4:] + lmfit_class, *description = sname[:-3].split('_') + gallery_name = f"{lmfit_class.capitalize()} - {' '.join(description)}" script_text = fn.read_text() - gallery_file = examples_documentation_dir / fn.name[4:] - msg = "" # add optional message f - gallery_file.write_text(f'"""\n{fn.name}\n{"=" * len(fn.name)}\n\n' + gallery_file = examples_documentation_dir / sname + msg = "" # add optional message + gallery_file.write_text(f'"""\n{gallery_name}\n{"=" * len(gallery_name)}\n\n' f'{msg}\n"""\n{script_text}') # make sure the saved Models and ModelResult are available @@ -67,5 +70,5 @@ def copy_data_files(src_dir, dest_dir): os.chdir(doc_dir) -# # data files for the other Gallery examples +# data files for the other Gallery examples copy_data_files(examples_documentation_dir, doc_dir) diff --git a/doc/model.rst b/doc/model.rst index 5c8ae340..e5d6506a 100644 --- a/doc/model.rst +++ b/doc/model.rst @@ -1166,7 +1166,7 @@ that taking correlations between Parameters into account when performing calculations can have a noticeable influence on the resulting uncertainties. -.. jupyter-execute:: ../examples/doc_uvars_params.py +.. jupyter-execute:: ../examples/doc_parameters_uvars.py Note that the :meth:`Model.post_fit` does not need to be limited to this diff --git a/examples/doc_uvars_params.py b/examples/doc_parameters_uvars.py similarity index 96% rename from examples/doc_uvars_params.py rename to examples/doc_parameters_uvars.py index 124c3024..1c4f2da8 100644 --- a/examples/doc_uvars_params.py +++ b/examples/doc_parameters_uvars.py @@ -1,4 +1,4 @@ -# +# import numpy as np from lmfit.models import ExponentialModel, GaussianModel @@ -67,4 +67,4 @@ def post_fit(result): out = mod.fit(y, pars, x=x) print(out.fit_report(min_correl=0.5)) -# +# From ff436c270d07433a7ae404fe76bc9c627b4edc3f Mon Sep 17 00:00:00 2001 From: reneeotten Date: Fri, 16 Aug 2024 22:02:40 -0400 Subject: [PATCH 9/9] BLD: remove numexpr dependency (again) --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 9578466d..cacdb8a4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,7 +59,6 @@ doc = [ "matplotlib", "numdifftools", "pandas", - "numexpr", # note: Pandas appears to need numexpr to build our docs "Pillow", "pycairo;platform_system=='Windows'", "Sphinx",