From 2426eb32ef4654b6eb08240d2a47854a7ebb2d2c Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Feb 2026 14:17:34 -0500 Subject: [PATCH 01/28] AUTHORS.rst --- AUTHORS.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AUTHORS.rst b/AUTHORS.rst index b2335043..68e2f2d8 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -1,7 +1,7 @@ Authors ======= -Christopher Farrow, Pavol Juhas, Simon J. L. Billinge, and members of the Billinge Group +Christopher Farrow, Pavol Juhas, Caden Myers, Simon J. L. Billinge, and members of the Billinge Group Contributors ------------ From 380a0c1d257d1bf74a5c4f24f2d851bb8b76e9d7 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Feb 2026 14:18:19 -0500 Subject: [PATCH 02/28] CODE-OF-CONDUCT.rst --- CODE-OF-CONDUCT.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODE-OF-CONDUCT.rst b/CODE-OF-CONDUCT.rst index e8199ca5..9352c6ec 100644 --- a/CODE-OF-CONDUCT.rst +++ b/CODE-OF-CONDUCT.rst @@ -67,7 +67,7 @@ Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at -sb2896@columbia.edu. All complaints will be reviewed and investigated promptly and fairly. +cjm2304@columbia.edu and sbillinge@ucsb.edu. All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the reporter of any incident. From 441f669aeabca345de5500c87fe339911a41c827 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Feb 2026 14:18:42 -0500 Subject: [PATCH 03/28] cookiecutter.json --- cookiecutter.json | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 cookiecutter.json diff --git a/cookiecutter.json b/cookiecutter.json new file mode 100644 index 00000000..46da0e2e --- /dev/null +++ b/cookiecutter.json @@ -0,0 +1,20 @@ +{ + "author_names": "Christopher Farrow, Pavol Juhas, Caden Myers, Simon J. L. Billinge", + "author_emails": "farrowch@gmail.com, pavol.juhas@gmail.com, cjm2304@columbia.edu, sbillinge@ucsb.edu", + "maintainer_names": "Caden Myers, Simon J. L. Billinge", + "maintainer_emails": "cjm2304@columbia.edu, sbillinge@ucsb.edu", + "maintainer_github_usernames": "cadenmyers13, sbillinge", + "contributors": "Christopher Farrow, Pavol Juhas, Caden Myers, Simon J. L. Billinge, and members of the DiffPy community.", + "license_holders": "The DiffPy Team", + "project_name": "diffpy.srfit", + "github_username_or_orgname": "diffpy", + "github_repo_name": "diffpy.srfit", + "conda_pypi_package_dist_name": "diffpy.srfit", + "package_dir_name": "diffpy.srfit", + "project_short_description": "Generalized code base for modeling problems.", + "project_keywords": "regression, modeling, fitting, diffraction, PDF", + "minimum_supported_python_version": "3.11", + "maximum_supported_python_version": "3.13", + "project_needs_c_code_compiled": "No", + "project_has_gui_tests": "No" +} From cd8f96eeab64163784f6078b0058ce11010be3ad Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Feb 2026 14:19:47 -0500 Subject: [PATCH 04/28] LICENSE.rst --- LICENSE.rst | 89 +++++++++-------------------------------------------- 1 file changed, 15 insertions(+), 74 deletions(-) diff --git a/LICENSE.rst b/LICENSE.rst index acbe6078..85dc311f 100644 --- a/LICENSE.rst +++ b/LICENSE.rst @@ -9,7 +9,7 @@ OPEN SOURCE LICENSE AGREEMENT - Copyright (c) 2008-2012, The Trustees of Columbia University in the City of New York - Copyright (c) 2014-2019, Brookhaven Science Associates, Brookhaven National Laboratory - Copyright (c) 2020-2025, The Trustees of Columbia University in the City of New York - +- Copyright (c) 2026-present, The DiffPy Team. The "DiffPy-CMI" is distributed subject to the following license conditions: @@ -59,76 +59,17 @@ outside your organization, if you meet all of the following conditions: (c) Modified copies and works based on the Software must carry prominent notices stating that you changed specified portions of the Software. - (d) Neither the name of Brookhaven Science Associates or Brookhaven - National Laboratory nor the names of its contributors may be used to - endorse or promote products derived from this software without specific - written permission. - - -(5) Portions of the Software resulted from work developed under a U.S. -Government contract and are subject to the following license: -The Government is granted for itself and others acting on its behalf a -paid-up, nonexclusive, irrevocable worldwide license in this computer software -to reproduce, prepare derivative works, and perform publicly and display -publicly. - - -(6) WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" WITHOUT -WARRANTY OF ANY KIND. THE COPYRIGHT HOLDERS, THEIR THIRD PARTY -LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND -THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR IMPLIED, INCLUDING -BUT NOT LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE, TITLE OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL -LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR USEFULNESS OF -THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF THE SOFTWARE WOULD NOT INFRINGE -PRIVATELY OWNED RIGHTS, (4) DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION -UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL BE CORRECTED. - - -(7) LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT HOLDERS, THEIR -THIRD PARTY LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF -ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, INCIDENTAL, -CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF ANY KIND OR NATURE, INCLUDING -BUT NOT LIMITED TO LOSS OF PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, -WHETHER SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING -NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, EVEN IF ANY OF SAID PARTIES HAS -BEEN WARNED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGES. - - -Brookhaven National Laboratory Notice -===================================== - -Acknowledgment of sponsorship ------------------------------ - -This software was produced by the Brookhaven National Laboratory, under -Contract DE-AC02-98CH10886 with the Department of Energy. - - -Government disclaimer of liability ----------------------------------- - -Neither the United States nor the United States Department of Energy, nor -any of their employees, makes any warranty, express or implied, or assumes -any legal liability or responsibility for the accuracy, completeness, or -usefulness of any data, apparatus, product, or process disclosed, or -represents that its use would not infringe privately owned rights. - - -Brookhaven disclaimer of liability ----------------------------------- - -Brookhaven National Laboratory makes no representations or warranties, -express or implied, nor assumes any liability for the use of this software. - - -Maintenance of notice ---------------------- - -In the interest of clarity regarding the origin and status of this -software, Brookhaven National Laboratory requests that any recipient of it -maintain this notice affixed to any distribution by the recipient that -contains a copy or derivative of this software. - - -END OF LICENSE +3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. From 4cebd7b61ac610fbf11d0df39439b40c0615428c Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Feb 2026 14:20:48 -0500 Subject: [PATCH 05/28] LICENSE.rst pt2 --- LICENSE.rst | 87 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 73 insertions(+), 14 deletions(-) diff --git a/LICENSE.rst b/LICENSE.rst index 85dc311f..6d222385 100644 --- a/LICENSE.rst +++ b/LICENSE.rst @@ -59,17 +59,76 @@ outside your organization, if you meet all of the following conditions: (c) Modified copies and works based on the Software must carry prominent notices stating that you changed specified portions of the Software. -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + (d) Neither the name of Brookhaven Science Associates or Brookhaven + National Laboratory nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + written permission. + + +(5) Portions of the Software resulted from work developed under a U.S. +Government contract and are subject to the following license: +The Government is granted for itself and others acting on its behalf a +paid-up, nonexclusive, irrevocable worldwide license in this computer software +to reproduce, prepare derivative works, and perform publicly and display +publicly. + + +(6) WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" WITHOUT +WARRANTY OF ANY KIND. THE COPYRIGHT HOLDERS, THEIR THIRD PARTY +LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND +THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE, TITLE OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL +LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR USEFULNESS OF +THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF THE SOFTWARE WOULD NOT INFRINGE +PRIVATELY OWNED RIGHTS, (4) DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION +UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL BE CORRECTED. + + +(7) LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT HOLDERS, THEIR +THIRD PARTY LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF +ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, INCIDENTAL, +CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF ANY KIND OR NATURE, INCLUDING +BUT NOT LIMITED TO LOSS OF PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, +WHETHER SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING +NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, EVEN IF ANY OF SAID PARTIES HAS +BEEN WARNED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGES. + + +Brookhaven National Laboratory Notice +===================================== + +Acknowledgment of sponsorship +----------------------------- + +This software was produced by the Brookhaven National Laboratory, under +Contract DE-AC02-98CH10886 with the Department of Energy. + + +Government disclaimer of liability +---------------------------------- + +Neither the United States nor the United States Department of Energy, nor +any of their employees, makes any warranty, express or implied, or assumes +any legal liability or responsibility for the accuracy, completeness, or +usefulness of any data, apparatus, product, or process disclosed, or +represents that its use would not infringe privately owned rights. + + +Brookhaven disclaimer of liability +---------------------------------- + +Brookhaven National Laboratory makes no representations or warranties, +express or implied, nor assumes any liability for the use of this software. + + +Maintenance of notice +--------------------- + +In the interest of clarity regarding the origin and status of this +software, Brookhaven National Laboratory requests that any recipient of it +maintain this notice affixed to any distribution by the recipient that +contains a copy or derivative of this software. + + +END OF LICENSE From 5da77d6082d3a2ffe3826a210719a7b246abd01f Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Feb 2026 14:22:24 -0500 Subject: [PATCH 06/28] MANIFEST.in --- MANIFEST.in | 1 - 1 file changed, 1 deletion(-) diff --git a/MANIFEST.in b/MANIFEST.in index b31fb162..c1ccccac 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -11,4 +11,3 @@ global-exclude __pycache__ # Exclude Python cache directories. global-exclude .git* # Exclude git files and directories. global-exclude .idea # Exclude PyCharm project settings. exclude .codecov.yml -exclude .coveragerc From 00f5fbac4c510328a51b772cd3473bc9b4cddc63 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Feb 2026 14:23:27 -0500 Subject: [PATCH 07/28] pyproject.toml --- pyproject.toml | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index fbbe0c3e..677cc175 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,13 +6,17 @@ build-backend = "setuptools.build_meta" name = "diffpy.srfit" dynamic=['version', 'dependencies'] authors = [ - { name="Simon Billinge", email="sb2896@columbia.edu" }, + {name='Christopher Farrow', email='farrowch@gmail.com'}, + {name='Pavol Juhas', email='pavol.juhas@gmail.com'}, + {name='Caden Myers', email='cjm2304@columbia.edu'}, + {name='Simon J. L. Billinge', email='sbillinge@ucsb.edu'}, ] maintainers = [ - { name="Simon Billinge", email="sb2896@columbia.edu" }, + {name='Caden Myers', email='cjm2304@columbia.edu'}, + {name='Simon J. L. Billinge', email='sbillinge@ucsb.edu'}, ] -description = "Configurable code for solving atomic structures." -keywords = ['regression', 'modelling', 'fitting', 'diffraction', 'PDF'] +description = "Generalized code base for modeling problems." +keywords = ['regression', 'modeling', 'fitting', 'diffraction', 'PDF'] readme = "README.rst" requires-python = ">=3.11, <3.14" classifiers = [ @@ -48,6 +52,9 @@ include = ["*"] # package names should match these glob patterns (["*"] by defa exclude = [] # exclude packages matching these glob patterns (empty by default) namespaces = false # to disable scanning PEP 420 namespaces (true by default) +[project.scripts] +diffpy-srfit = "diffpy.srfit.app:main" + [tool.setuptools.dynamic] dependencies = {file = ["requirements/pip.txt"]} @@ -56,6 +63,11 @@ exclude-file = ".codespell/ignore_lines.txt" ignore-words = ".codespell/ignore_words.txt" skip = "*.cif,*.dat" +[tool.docformatter] +recursive = true +wrap-summaries = 72 +wrap-descriptions = 72 + [tool.black] line-length = 79 include = '\.pyi?$' From 6bcccf3286697f258ee541abfe09c0e5fe9397ba Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Feb 2026 14:25:55 -0500 Subject: [PATCH 08/28] README.rst --- README.rst | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/README.rst b/README.rst index 2d4040ec..fbf4e193 100644 --- a/README.rst +++ b/README.rst @@ -25,6 +25,7 @@ :target: https://anaconda.org/conda-forge/diffpy.srfit .. |PR| image:: https://img.shields.io/badge/PR-Welcome-29ab47ff + :target: https://github.com/diffpy/diffpy.srfit/pulls .. |PyPI| image:: https://img.shields.io/pypi/v/diffpy.srfit :target: https://pypi.org/project/diffpy.srfit/ @@ -94,10 +95,6 @@ The following creates and activates a new environment named ``diffpy.srfit_env`` conda create -n diffpy.srfit_env diffpy.srfit conda activate diffpy.srfit_env -To confirm that the installation was successful, type :: - - python -c "import diffpy.srfit; print(diffpy.srfit.__version__)" - The output should print the latest version displayed on the badges above. This will install the minimal `diffpy.srfit` installation. It will often be used @@ -136,6 +133,19 @@ and run the following :: pip install . +This package also provides command-line utilities. To check the software has been installed correctly, type :: + + diffpy.srfit --version + +You can also type the following command to verify the installation. :: + + python -c "import diffpy.srfit; print(diffpy.srfit.__version__)" + + +To view the basic usage and available commands, type :: + + diffpy.srfit -h + Getting Started --------------- @@ -167,12 +177,12 @@ trying to commit again. Improvements and fixes are always appreciated. -Before contributing, please read our `Code of Conduct `_. +Before contributing, please read our `Code of Conduct `_. Contact ------- -For more information on diffpy.srfit please visit the project `web-page `_ or email Simon Billinge at sb2896@columbia.edu. +For more information on diffpy.srfit please visit the project `web-page `_ or email the maintainers ``Caden Myers (cjm2304@columbia.edu) and Simon J. L. Billinge (sbillinge@ucsb.edu)``. Acknowledgements ---------------- From 11167cb804808299c41f71dd2b242d3e83c5cbef Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Feb 2026 14:26:25 -0500 Subject: [PATCH 09/28] release_checklist.md --- .github/ISSUE_TEMPLATE/release_checklist.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/release_checklist.md b/.github/ISSUE_TEMPLATE/release_checklist.md index 6107962c..56c5fca3 100644 --- a/.github/ISSUE_TEMPLATE/release_checklist.md +++ b/.github/ISSUE_TEMPLATE/release_checklist.md @@ -11,12 +11,13 @@ assignees: "" - [ ] All PRs/issues attached to the release are merged. - [ ] All the badges on the README are passing. - [ ] License information is verified as correct. If you are unsure, please comment below. -- [ ] Locally rendered documentation contains all appropriate pages, including API references (check no modules are - missing), tutorials, and other human-written text is up-to-date with any changes in the code. +- [ ] Locally rendered documentation contains all appropriate pages, tutorials, and other human-written text is up-to-date with any changes in the code. +- [ ] All API references are included. To check this, run `conda install scikit-package` and then `package build api-doc`. Review any edits made by rerendering the docs locally. - [ ] Installation instructions in the README, documentation, and the website are updated. - [ ] Successfully run any tutorial examples or do functional testing with the latest Python version. - [ ] Grammar and writing quality are checked (no typos). - [ ] Install `pip install build twine`, run `python -m build` and `twine check dist/*` to ensure that the package can be built and is correctly formatted for PyPI release. +- [ ] Dispatch matrix testing to test the release on all Python versions and systems. If you do not have permission to run this workflow, tag the maintainer and say `@maintainer, please dispatch matrix testing workflow`. Please tag the maintainer (e.g., @username) in the comment here when you are ready for the PyPI/GitHub release. Include any additional comments necessary, such as version information and details about the pre-release here: @@ -34,7 +35,7 @@ Please let the maintainer know that all checks are done and the package is ready - [ ] Ensure that the full release has appeared on PyPI successfully. -- [ ] New package dependencies listed in `conda.txt` and `test.txt` are added to `meta.yaml` in the feedstock. +- [ ] New package dependencies listed in `conda.txt` and `tests.txt` are added to `meta.yaml` in the feedstock. - [ ] Close any open issues on the feedstock. Reach out to the maintainer if you have questions. - [ ] Tag the maintainer for conda-forge release. From 7104cf1d78a12c04d18d32bdaeb7cb813c20c33a Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Feb 2026 14:26:59 -0500 Subject: [PATCH 10/28] build-and-publish-docs-on-dispatch.yml --- .../build-and-publish-docs-on-dispatch.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/workflows/build-and-publish-docs-on-dispatch.yml diff --git a/.github/workflows/build-and-publish-docs-on-dispatch.yml b/.github/workflows/build-and-publish-docs-on-dispatch.yml new file mode 100644 index 00000000..3d7394d0 --- /dev/null +++ b/.github/workflows/build-and-publish-docs-on-dispatch.yml @@ -0,0 +1,18 @@ +name: Build and Publish Docs on Dispatch + +on: + workflow_dispatch: + +jobs: + get-python-version: + uses: scikit-package/release-scripts/.github/workflows/_get-python-version-latest.yml@v0 + with: + python_version: 0 + + docs: + uses: scikit-package/release-scripts/.github/workflows/_release-docs.yml@v0 + with: + project: diffpy.srfit + c_extension: false + headless: false + python_version: ${{ fromJSON(needs.get-python-version.outputs.latest_python_version) }} From 6510ca44aa403d66ac97ff03afe894d309814760 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Feb 2026 14:27:31 -0500 Subject: [PATCH 11/28] build-wheel-release-upload.yml --- .github/workflows/build-wheel-release-upload.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-wheel-release-upload.yml b/.github/workflows/build-wheel-release-upload.yml index 4d66f1b5..c5e92258 100644 --- a/.github/workflows/build-wheel-release-upload.yml +++ b/.github/workflows/build-wheel-release-upload.yml @@ -1,4 +1,4 @@ -name: Release (GitHub/PyPI) and Deploy Docs +name: Build Wheel, Release on GitHub/PyPI, and Deploy Docs on: workflow_dispatch: @@ -7,12 +7,12 @@ on: - "*" # Trigger on all tags initially, but tag and release privilege are verified in _build-wheel-release-upload.yml jobs: - release: + build-release: uses: scikit-package/release-scripts/.github/workflows/_build-wheel-release-upload.yml@v0 with: project: diffpy.srfit c_extension: false - maintainer_GITHUB_username: sbillinge + maintainer_GITHUB_username: cadenmyers13, sbillinge secrets: PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} PAT_TOKEN: ${{ secrets.PAT_TOKEN }} From b506e1676b1aefc299d6b4014afdccf8488b5b6b Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Feb 2026 14:27:53 -0500 Subject: [PATCH 12/28] matrix-and-codecov.yml --- .github/workflows/matrix-and-codecov.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/workflows/matrix-and-codecov.yml diff --git a/.github/workflows/matrix-and-codecov.yml b/.github/workflows/matrix-and-codecov.yml new file mode 100644 index 00000000..b9a73c69 --- /dev/null +++ b/.github/workflows/matrix-and-codecov.yml @@ -0,0 +1,21 @@ +name: Matrix and Codecov + +on: + # push: + # branches: + # - main + release: + types: + - prereleased + - published + workflow_dispatch: + +jobs: + matrix-coverage: + uses: scikit-package/release-scripts/.github/workflows/_matrix-and-codecov-on-merge-to-main.yml@v0 + with: + project: diffpy.srfit + c_extension: false + headless: false + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} From cd28445445e6fddb61855e837944301896110b92 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Feb 2026 14:30:23 -0500 Subject: [PATCH 13/28] README.rst pt2 --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index fbf4e193..00bd1dd2 100644 --- a/README.rst +++ b/README.rst @@ -39,7 +39,7 @@ diffpy.srfit ============ -Configurable code for solving atomic structures. +Generalized code base for modeling problems. The diffpy.srfit package provides the framework for building a global optimizer on the fly from components such as function calculators (that calculate From f71e1dad2a71b895e48e936384ec5852dab804cd Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Feb 2026 14:30:57 -0500 Subject: [PATCH 14/28] conf.py --- docs/source/conf.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 6f33a1b7..99dc93f6 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -32,9 +32,7 @@ sys.path.insert(0, str(Path("../../src").resolve())) # abbreviations -ab_authors = ( - "Christopher Farrow, Pavol Juhas, and members of the Billinge Group" -) +ab_authors = "Christopher Farrow, Pavol Juhas, Caden Myers, Simon J. L. Billinge, and members of the Billinge Group." # -- General configuration ------------------------------------------------ @@ -86,7 +84,7 @@ # General information about the project. project = "diffpy.srfit" -copyright = "%Y, The Trustees of Columbia University in the City of New York" +copyright = "%Y, The DiffPy Team" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -317,7 +315,7 @@ "diffpy.srfit Documentation", ab_authors, "diffpy.srfit", - "Configurable code for solving atomic structures.", + "Generalized code base for modeling problems.", "Miscellaneous", ), ] From c079ecee05209a14b74fa2c559a50de8a32a7797 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Feb 2026 14:34:49 -0500 Subject: [PATCH 15/28] index.rst --- docs/source/index.rst | 47 ++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/docs/source/index.rst b/docs/source/index.rst index ea21479d..b40360f6 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,14 +1,20 @@ -.. _developers-guide-index: +####### +|title| +####### -#################################################### -diffpy.srfit documentation -#################################################### +.. |title| replace:: diffpy.srfit documentation -diffpy.srfit - configurable code for solving atomic structures. +``diffpy.srfit`` - Generalized code base for modeling problems. -| Software version |release|. +| Software version |release| | Last updated |today|. +=============== +Getting started +=============== + +Welcome to the ``diffpy.srfit`` documentation! + The diffpy.srfit package provides the framework for building a global optimizer on the fly from components such as function calculators (that calculate different data spectra), regression algorithms and structure models. The @@ -31,9 +37,9 @@ obtain the total cost function. Additionally, diffpy.srfit is designed to be extensible, allowing the user to integrate external calculators to perform co-refinements with other techniques. -======================================== +======= Authors -======================================== +======= diffpy.srfit is developed by members of the Billinge Group at Columbia University and at Brookhaven National Laboratory including @@ -41,17 +47,23 @@ Christopher L. Farrow, Pavol Juhás, Simon J.L. Billinge. The source code in *observable.py* was derived from the 1.0 version of the Caltech "Pyre" project. - -For a detailed list of contributors see +``diffpy.srfit`` is developed by Christopher Farrow, Pavol Juhas, Caden Myers, Simon J. L. Billinge, and members of the DiffPy community. +This project is maintained by Caden Myers and Simon J. L. Billinge. For a detailed list of contributors see https://github.com/diffpy/diffpy.srfit/graphs/contributors. -====================================== +============ Installation -====================================== +============ -See the `README `_ +See the `README `_ file included with the distribution. +================ +Acknowledgements +================ + +``diffpy.srfit`` is built and maintained with `scikit-package `_. + ====================================== Where next? ====================================== @@ -62,10 +74,9 @@ Where next? examples.rst extending.rst -====================================== +================= Table of contents -====================================== - +================= .. toctree:: :titlesonly: @@ -75,9 +86,9 @@ Table of contents .. faq.rst -====================================== +======= Indices -====================================== +======= * :ref:`genindex` * :ref:`modindex` From 14790774f8b77a500761c4903b6642a44dab759a Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Feb 2026 14:36:20 -0500 Subject: [PATCH 16/28] license.rst --- docs/source/license.rst | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/source/license.rst b/docs/source/license.rst index 7d78e94f..748b63bf 100644 --- a/docs/source/license.rst +++ b/docs/source/license.rst @@ -1,3 +1,5 @@ +:tocdepth: -1 + .. index:: license License @@ -12,10 +14,11 @@ OPEN SOURCE LICENSE AGREEMENT Lawrence Berkeley National Laboratory | Copyright (c) 2014, Australian Synchrotron Research Program Inc., ("ASRP") | Copyright (c) 2006-2007, Board of Trustees of Michigan State University -| Copyright (c) 2008-2012, The Trustees of Columbia University in - the City of New York | Copyright (c) 2014-2019, Brookhaven Science Associates, Brookhaven National Laboratory +| Copyright (c) 2008-2025, The Trustees of Columbia University in + the City of New York +| Copyright (c) 2026-present, The DiffPy Team. The "DiffPy-CMI" is distributed subject to the following license conditions: From 1ef6b748e60ea3f30f2d0af72b2821ffbb868843 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Feb 2026 14:37:43 -0500 Subject: [PATCH 17/28] diffpy.srfit.rst --- docs/source/api/diffpy.srfit.rst | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/source/api/diffpy.srfit.rst b/docs/source/api/diffpy.srfit.rst index 8f840d0c..1e2925bf 100644 --- a/docs/source/api/diffpy.srfit.rst +++ b/docs/source/api/diffpy.srfit.rst @@ -1,7 +1,9 @@ :tocdepth: -1 -diffpy.srfit package -==================== +|title| +======= + +.. |title| replace:: diffpy.srfit package .. automodule:: diffpy.srfit :members: @@ -25,8 +27,10 @@ Subpackages Submodules ---------- -diffpy.srfit.exceptions module -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +|module| +-------- + +.. |module| replace:: diffpy.srfit.exceptions module .. automodule:: diffpy.srfit.exceptions :members: From 99c7aac0c49f209942772b20b2c6b93d24e93c5e Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Feb 2026 14:40:21 -0500 Subject: [PATCH 18/28] __init__.py --- src/diffpy/__init__.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/diffpy/__init__.py b/src/diffpy/__init__.py index 3254c0a6..54f1f125 100644 --- a/src/diffpy/__init__.py +++ b/src/diffpy/__init__.py @@ -4,8 +4,10 @@ # (c) 2008-2025 The Trustees of Columbia University in the City of New York. # All rights reserved. # -# File coded by: Chris Farrow and Billinge Group members and community -# contributors. +# (c) 2025-present The DiffPy Team. +# +# File coded by: Chris Farrow, Caden Myers, Billinge Group members and +# community contributors. # # See GitHub contributions for a more detailed list of contributors. # https://github.com/diffpy/diffpy.srfit/graphs/contributors From 8d4945a86b3f031163df84c6bd35a948ed8c66df Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Feb 2026 14:41:40 -0500 Subject: [PATCH 19/28] __init__.py --- src/diffpy/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/diffpy/__init__.py b/src/diffpy/__init__.py index 54f1f125..22cbdcc6 100644 --- a/src/diffpy/__init__.py +++ b/src/diffpy/__init__.py @@ -6,8 +6,8 @@ # # (c) 2025-present The DiffPy Team. # -# File coded by: Chris Farrow, Caden Myers, Billinge Group members and -# community contributors. +# File coded by: Christopher Farrow, Pavol Juhas, Caden Myers, +# Simon J. L. Billinge, and members of the DiffPy community. # # See GitHub contributions for a more detailed list of contributors. # https://github.com/diffpy/diffpy.srfit/graphs/contributors From 935f5e5ff1a3fe012cba0b92452d1bfc16b59c1c Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Feb 2026 14:42:44 -0500 Subject: [PATCH 20/28] __init__.py --- src/diffpy/srfit/__init__.py | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/src/diffpy/srfit/__init__.py b/src/diffpy/srfit/__init__.py index 0374fdcf..d8b19522 100644 --- a/src/diffpy/srfit/__init__.py +++ b/src/diffpy/srfit/__init__.py @@ -3,9 +3,10 @@ # # (c) 2008-2025 The Trustees of Columbia University in the City of New York. # All rights reserved. +# (c) 2026-present The DiffPy Team. All rights reserved. # -# File coded by: Christopher Farrow, Pavol Juhas, and members of the -# Billinge Group. +# File coded by: Christopher Farrow, Pavol Juhas, Caden Myers, +# Simon J. L. Billinge, and members of the DiffPy community. # # See GitHub contributions for a more detailed list of contributors. # https://github.com/diffpy/diffpy.srfit/graphs/contributors @@ -13,27 +14,10 @@ # See LICENSE.rst for license information. # ############################################################################## -"""Complex modeling framework for structure refinement and solution. - -SrFit is a tool for coherently combining known information about a -material to derive other properties, in particular material structure. -SrFit allows the customization and creation of structure -representations, profile calculators, constraints, restraints and file -input parsers. The customized pieces can be glued together within SrFit -to optimize a structure, or other physically relevant information from -one or more experimental profiles. Other known information about the -system of interest can be included with arbitrarily complex constraints -and restraints. In this way, the end user creates a customized fitting -application that suits the problem to the available information. - -The subpackages herein define various pieces of the SrFit framework. -Developers are encouraged to work through the examples described in the -documentation to learn how to use and customize the various parts of -SrFit. -""" +"""Generalized code base for modeling problems.""" # package version -from diffpy.srfit.version import __version__ +from diffpy.srfit.version import __version__ # noqa # silence the pyflakes syntax checker assert __version__ or True From 21f688b2d355177648d7674bdc056d79ffe92c5c Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Feb 2026 14:43:10 -0500 Subject: [PATCH 21/28] srfit_app.py --- src/diffpy/srfit/srfit_app.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/diffpy/srfit/srfit_app.py diff --git a/src/diffpy/srfit/srfit_app.py b/src/diffpy/srfit/srfit_app.py new file mode 100644 index 00000000..65b92262 --- /dev/null +++ b/src/diffpy/srfit/srfit_app.py @@ -0,0 +1,33 @@ +import argparse + +from diffpy.srfit.version import __version__ + + +def main(): + parser = argparse.ArgumentParser( + prog="diffpy.srfit", + description=( + "Generalized code base for modeling problems.\n\n" + "For more information, visit: " + "https://github.com/diffpy/diffpy.srfit/" + ), + formatter_class=argparse.RawDescriptionHelpFormatter, + ) + + parser.add_argument( + "--version", + action="store_true", + help="Show the program's version number and exit", + ) + + args = parser.parse_args() + + if args.version: + print(f"diffpy.srfit {__version__}") + else: + # Default behavior when no arguments are given + parser.print_help() + + +if __name__ == "__main__": + main() From af72c5ce26477d2c478f5168a6d13c53cb0603f6 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Feb 2026 14:43:52 -0500 Subject: [PATCH 22/28] version.py --- src/diffpy/srfit/version.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/diffpy/srfit/version.py b/src/diffpy/srfit/version.py index f0833049..c62be11e 100644 --- a/src/diffpy/srfit/version.py +++ b/src/diffpy/srfit/version.py @@ -3,9 +3,10 @@ # # (c) 2008-2025 The Trustees of Columbia University in the City of New York. # All rights reserved. +# (c) 2026-present The DiffPy Team. All rights reserved. # -# File coded by: Christopher Farrow, Pavol Juhas, and members of the -# Billinge Group. +# File coded by: Christopher Farrow, Pavol Juhas, Caden Myers, +# Simon J. L. Billinge, and members of the DiffPy community. # # See GitHub contributions for a more detailed list of contributors. # https://github.com/diffpy/diffpy.srfit/graphs/contributors @@ -19,8 +20,9 @@ # __all__ = ["__date__", "__git_commit__", "__timestamp__", "__version__"] # obtain version information -from importlib.metadata import version +from importlib.metadata import PackageNotFoundError, version -__version__ = version("diffpy.srfit") - -# End of file +try: + __version__ = version("diffpy.srfit") +except PackageNotFoundError: + __version__ = "unknown" From 87294870cf032685cb82c94cc43e44a2dee2f2cd Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Feb 2026 14:46:24 -0500 Subject: [PATCH 23/28] news --- news/update030.rst | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 news/update030.rst diff --git a/news/update030.rst b/news/update030.rst new file mode 100644 index 00000000..3ce80500 --- /dev/null +++ b/news/update030.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* Update codebase to scikit-package 0.3.0 standards. + +**Security:** + +* From 36216d84740cd7bfabaa42ccdbfb49b73ff77613 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 25 Feb 2026 19:47:16 +0000 Subject: [PATCH 24/28] [pre-commit.ci] auto fixes from pre-commit hooks --- docs/examples/debyemodel.py | 6 ++++-- docs/examples/debyemodelII.py | 3 ++- docs/examples/npintensityII.py | 3 ++- docs/examples/nppdfsas.py | 3 ++- docs/examples/threedoublepeaks.py | 3 ++- src/diffpy/srfit/equation/builder.py | 13 ++++++++----- src/diffpy/srfit/equation/literals/literal.py | 3 ++- .../srfit/equation/literals/operators.py | 9 ++++++--- src/diffpy/srfit/equation/visitors/printer.py | 3 ++- src/diffpy/srfit/equation/visitors/swapper.py | 6 ++++-- src/diffpy/srfit/fitbase/fitcontribution.py | 3 ++- src/diffpy/srfit/fitbase/fithook.py | 18 ++++++++++++------ src/diffpy/srfit/fitbase/fitrecipe.py | 11 ++++++----- src/diffpy/srfit/fitbase/fitresults.py | 9 ++++++--- src/diffpy/srfit/fitbase/profileparser.py | 6 ++++-- src/diffpy/srfit/fitbase/recipeorganizer.py | 9 ++++++--- src/diffpy/srfit/fitbase/simplerecipe.py | 3 ++- .../srfit/pdf/characteristicfunctions.py | 11 ++++++----- src/diffpy/srfit/pdf/pdfparser.py | 3 ++- src/diffpy/srfit/sas/prcalculator.py | 3 ++- src/diffpy/srfit/sas/sasparser.py | 6 ++++-- src/diffpy/srfit/sas/sasprofile.py | 3 ++- src/diffpy/srfit/structure/__init__.py | 6 +++--- src/diffpy/srfit/structure/objcrystparset.py | 9 ++++++--- src/diffpy/srfit/structure/sgconstraints.py | 3 ++- src/diffpy/srfit/util/__init__.py | 4 ++-- src/diffpy/srfit/util/argbinders.py | 3 ++- src/diffpy/srfit/util/weakrefcallable.py | 6 ++++-- tests/conftest.py | 6 ++++-- tests/test_contribution.py | 9 ++++++--- tests/test_fitrecipe.py | 10 +++++----- tests/test_objcrystparset.py | 3 ++- tests/test_profilegenerator.py | 3 ++- tests/test_sgconstraints.py | 3 ++- 34 files changed, 128 insertions(+), 74 deletions(-) diff --git a/docs/examples/debyemodel.py b/docs/examples/debyemodel.py index 758c05ef..3ec7002d 100644 --- a/docs/examples/debyemodel.py +++ b/docs/examples/debyemodel.py @@ -12,7 +12,8 @@ # See LICENSE_DANSE.txt for license information. # ######################################################################## -"""Example of fitting the Debye model to experimental Debye-Waller factors. +"""Example of fitting the Debye model to experimental Debye-Waller +factors. In this example, we build a fit recipe that uses an external function that can simulate a atomic displacement parameters using the Debye model. This serves as @@ -207,7 +208,8 @@ def main(): def debye(T, m, thetaD): - """A wrapped version of 'adps' that can handle an array of T-values.""" + """A wrapped version of 'adps' that can handle an array of + T-values.""" y = numpy.array([adps(m, thetaD, x) for x in T]) return y diff --git a/docs/examples/debyemodelII.py b/docs/examples/debyemodelII.py index 2c5602f4..5e82aaee 100644 --- a/docs/examples/debyemodelII.py +++ b/docs/examples/debyemodelII.py @@ -12,7 +12,8 @@ # See LICENSE_DANSE.txt for license information. # ######################################################################## -"""Example of fitting the Debye recipe to experimental Debye-Waller factors. +"""Example of fitting the Debye recipe to experimental Debye-Waller +factors. This is an extension of example in debyemodel.py. The recipe we create will simultaneously fit the low and high temperature parts of the experimental data diff --git a/docs/examples/npintensityII.py b/docs/examples/npintensityII.py index 44e88506..2791a1b3 100644 --- a/docs/examples/npintensityII.py +++ b/docs/examples/npintensityII.py @@ -12,7 +12,8 @@ # See LICENSE_DANSE.txt for license information. # ######################################################################## -"""Example of extracting information from multiple data sets simultaneously. +"""Example of extracting information from multiple data sets +simultaneously. This example builds on npintensitygenerator.py, and uses IntensityGenerator from that example to build a recipe that simultaneously refines two data sets diff --git a/docs/examples/nppdfsas.py b/docs/examples/nppdfsas.py index 0679e771..6626c603 100644 --- a/docs/examples/nppdfsas.py +++ b/docs/examples/nppdfsas.py @@ -38,7 +38,8 @@ def makeRecipe(ciffile, grdata, iqdata): - """Make complex-modeling recipe where I(q) and G(r) are fit simultaneously. + """Make complex-modeling recipe where I(q) and G(r) are fit + simultaneously. The fit I(q) is fed into the calculation of G(r), which provides feedback for the fit parameters of both. diff --git a/docs/examples/threedoublepeaks.py b/docs/examples/threedoublepeaks.py index 6a5b7a42..d6c70202 100644 --- a/docs/examples/threedoublepeaks.py +++ b/docs/examples/threedoublepeaks.py @@ -30,7 +30,8 @@ def makeRecipe(): - """Make a FitRecipe for fitting three double-gaussian curves to data. + """Make a FitRecipe for fitting three double-gaussian curves to + data. The separation and amplitude ratio of the double peaks follows a specific relationship. The peaks are broadend according to their diff --git a/src/diffpy/srfit/equation/builder.py b/src/diffpy/srfit/equation/builder.py index c33e0ff6..87a56b63 100644 --- a/src/diffpy/srfit/equation/builder.py +++ b/src/diffpy/srfit/equation/builder.py @@ -238,7 +238,8 @@ def registerFunction(self, name, func, argnames): return self.registerBuilder(name, opbuilder) def registerBuilder(self, name, builder): - """Register builder in this module so it can be used in makeEquation. + """Register builder in this module so it can be used in + makeEquation. If an extant builder with the given name is already registered, this will replace all instances of the old builder's literal in @@ -282,7 +283,8 @@ def deRegisterBuilder(self, name): return def wipeout(self, eq): - """Invalidate the specified equation and remove it from the factory. + """Invalidate the specified equation and remove it from the + factory. This will remove the equation from the purview of the factory and also change its formula to return NaN. This ensures that eq @@ -576,7 +578,8 @@ class ArgumentBuilder(BaseBuilder): """ def __init__(self, value=None, name=None, const=False, arg=None): - """Create an ArgumentBuilder instance, containing a new Argument. + """Create an ArgumentBuilder instance, containing a new + Argument. Parameters ---------- @@ -732,8 +735,8 @@ def getBuilder(name): def __wrap_numpy_operators(): - """Export all numpy operators as OperatorBuilder instances in the module - namespace.""" + """Export all numpy operators as OperatorBuilder instances in the + module namespace.""" for name in dir(numpy): op = getattr(numpy, name) if isinstance(op, numpy.ufunc): diff --git a/src/diffpy/srfit/equation/literals/literal.py b/src/diffpy/srfit/equation/literals/literal.py index ebdc17a9..48c48eaa 100644 --- a/src/diffpy/srfit/equation/literals/literal.py +++ b/src/diffpy/srfit/equation/literals/literal.py @@ -26,7 +26,8 @@ class Literal(Observable, LiteralABC): - """Abstract class for equation pieces, such as operators and arguments. + """Abstract class for equation pieces, such as operators and + arguments. Literal derives from Observable. See diffpy.srfit.util.observable. diff --git a/src/diffpy/srfit/equation/literals/operators.py b/src/diffpy/srfit/equation/literals/operators.py index a7863808..9b78b77c 100644 --- a/src/diffpy/srfit/equation/literals/operators.py +++ b/src/diffpy/srfit/equation/literals/operators.py @@ -141,7 +141,8 @@ def _loop_check(self, literal): class UnaryOperator(Operator): - """Abstract class for an unary operator with one input and one result. + """Abstract class for an unary operator with one input and one + result. This base class defines the `nin` and `nout` attributes. The derived concrete operator must provide the remaining abstract attributes @@ -154,7 +155,8 @@ class UnaryOperator(Operator): class BinaryOperator(Operator): - """Abstract class for a binary operator with two inputs and one result. + """Abstract class for a binary operator with two inputs and one + result. This base class defines the `nin` and `nout` attributes. The derived concrete operator must define the remaining abstract attributes @@ -359,7 +361,8 @@ def __init__(self, op): class ArrayOperator(Operator): - """Operator that will take parameters and turn them into an array.""" + """Operator that will take parameters and turn them into an + array.""" name = "array" symbol = "array" diff --git a/src/diffpy/srfit/equation/visitors/printer.py b/src/diffpy/srfit/equation/visitors/printer.py index 98cfab6a..d3aa5ee7 100644 --- a/src/diffpy/srfit/equation/visitors/printer.py +++ b/src/diffpy/srfit/equation/visitors/printer.py @@ -12,7 +12,8 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## -"""Printer visitor for printing the equation represented by a Literal tree. +"""Printer visitor for printing the equation represented by a Literal +tree. The Printer visitor creates a one-line representation of the Literal tree, which is valid as a string equivalent of the equation. diff --git a/src/diffpy/srfit/equation/visitors/swapper.py b/src/diffpy/srfit/equation/visitors/swapper.py index a6135750..c27cf85e 100644 --- a/src/diffpy/srfit/equation/visitors/swapper.py +++ b/src/diffpy/srfit/equation/visitors/swapper.py @@ -12,7 +12,8 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## -"""Swapper for replacing a Literal in an equation with another Literals.""" +"""Swapper for replacing a Literal in an equation with another +Literals.""" __all__ = ["Swapper"] @@ -20,7 +21,8 @@ class Swapper(Visitor): - """Swapper for swapping out one literal for another in a literal tree. + """Swapper for swapping out one literal for another in a literal + tree. Note that this cannot swap out a root node of a literal tree. This case must be tested for explicitly. diff --git a/src/diffpy/srfit/fitbase/fitcontribution.py b/src/diffpy/srfit/fitbase/fitcontribution.py index d6ff6ed0..21a7aed9 100644 --- a/src/diffpy/srfit/fitbase/fitcontribution.py +++ b/src/diffpy/srfit/fitbase/fitcontribution.py @@ -450,7 +450,8 @@ def residual(self): return self._reseq() def evaluate(self): - """Evaluate the contribution equation and update profile.ycalc.""" + """Evaluate the contribution equation and update + profile.ycalc.""" yc = self._eq() if self.profile is not None: self.profile.ycalc = yc diff --git a/src/diffpy/srfit/fitbase/fithook.py b/src/diffpy/srfit/fitbase/fithook.py index b5b284c5..3afa90d9 100644 --- a/src/diffpy/srfit/fitbase/fithook.py +++ b/src/diffpy/srfit/fitbase/fithook.py @@ -12,7 +12,8 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## -"""The FitHook class for inspecting the progress of a FitRecipe refinement. +"""The FitHook class for inspecting the progress of a FitRecipe +refinement. FitHooks are called by a FitRecipe during various times of the residual is evaluation. The default FitHook simply counts the number of times the @@ -54,7 +55,8 @@ def reset(self, recipe): return def precall(self, recipe): - """This is called within FitRecipe.residual, before the calculation. + """This is called within FitRecipe.residual, before the + calculation. Attributes ---------- @@ -64,7 +66,8 @@ def precall(self, recipe): return def postcall(self, recipe, chiv): - """This is called within FitRecipe.residual, after the calculation. + """This is called within FitRecipe.residual, after the + calculation. Attributes ---------- @@ -121,7 +124,8 @@ def reset(self, recipe): return def precall(self, recipe): - """This is called within FitRecipe.residual, before the calculation. + """This is called within FitRecipe.residual, before the + calculation. Attributes ---------- @@ -134,7 +138,8 @@ def precall(self, recipe): return def postcall(self, recipe, chiv): - """This is called within FitRecipe.residual, after the calculation. + """This is called within FitRecipe.residual, after the + calculation. Attributes ---------- @@ -227,7 +232,8 @@ def reset(self, recipe): return def postcall(self, recipe, chiv): - """This is called within FitRecipe.residual, after the calculation. + """This is called within FitRecipe.residual, after the + calculation. Find data and plot it. diff --git a/src/diffpy/srfit/fitbase/fitrecipe.py b/src/diffpy/srfit/fitbase/fitrecipe.py index 72946e40..c44eb6d9 100644 --- a/src/diffpy/srfit/fitbase/fitrecipe.py +++ b/src/diffpy/srfit/fitbase/fitrecipe.py @@ -1278,8 +1278,8 @@ def set_plot_defaults(self, **kwargs): self.plot_options.update(kwargs) def _set_axes_labels_from_metadata(self, meta, plot_params): - """Set axes labels based on filename suffix in profile metadata if not - already set.""" + """Set axes labels based on filename suffix in profile metadata + if not already set.""" if isinstance(meta, dict): filename = meta.get("filename") if filename: @@ -1292,8 +1292,8 @@ def _set_axes_labels_from_metadata(self, meta, plot_params): return def plot_recipe(self, ax=None, return_fig=False, **kwargs): - """Plot the observed, fit, and difference curves for each contribution - of the fit recipe. + """Plot the observed, fit, and difference curves for each + contribution of the fit recipe. If the recipe has multiple contributions, a separate plot is created for each contribution. @@ -1516,7 +1516,8 @@ def _apply_values(self, p): return def _update_configuration(self): - """Notify RecipeContainers in hierarchy of configuration change.""" + """Notify RecipeContainers in hierarchy of configuration + change.""" self._ready = False return diff --git a/src/diffpy/srfit/fitbase/fitresults.py b/src/diffpy/srfit/fitbase/fitresults.py index dabebded..e2f2a20a 100644 --- a/src/diffpy/srfit/fitbase/fitresults.py +++ b/src/diffpy/srfit/fitbase/fitresults.py @@ -12,7 +12,8 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## -"""The FitResults and ContributionResults classes for storing results of a fit. +"""The FitResults and ContributionResults classes for storing results of +a fit. The FitResults class is used to display the current state of a FitRecipe. It stores the state, and uses it to calculate useful @@ -164,7 +165,8 @@ def __init__(self, recipe, update=True, showfixed=True, showcon=False): return def update(self): - """Update the results according to the current state of the recipe.""" + """Update the results according to the current state of the + recipe.""" # Note that the order of these operations are chosen to reduce # computation time. @@ -302,7 +304,8 @@ def _calculate_jacobian(self): return jac def _calculate_metrics(self): - """Calculate chi2, cumchi2, rchi2, rw and cumrw for the recipe.""" + """Calculate chi2, cumchi2, rchi2, rw and cumrw for the + recipe.""" cumchi2 = numpy.array([], dtype=float) # total weighed denominator for the ratio in the Rw formula yw2tot = 0.0 diff --git a/src/diffpy/srfit/fitbase/profileparser.py b/src/diffpy/srfit/fitbase/profileparser.py index 32cb9669..b152164b 100644 --- a/src/diffpy/srfit/fitbase/profileparser.py +++ b/src/diffpy/srfit/fitbase/profileparser.py @@ -93,7 +93,8 @@ def getFormat(self): return self._format def parseString(self, patstring): - """Parse a string and set the _x, _y, _dx, _dy and _meta variables. + """Parse a string and set the _x, _y, _dx, _dy and _meta + variables. When _dx or _dy cannot be obtained in the data format it is set to None. @@ -110,7 +111,8 @@ def parseString(self, patstring): raise NotImplementedError() def parseFile(self, filename): - """Parse a file and set the _x, _y, _dx, _dy and _meta variables. + """Parse a file and set the _x, _y, _dx, _dy and _meta + variables. This wipes out the currently loaded data and selected bank number. diff --git a/src/diffpy/srfit/fitbase/recipeorganizer.py b/src/diffpy/srfit/fitbase/recipeorganizer.py index ca7b273b..3daf5674 100644 --- a/src/diffpy/srfit/fitbase/recipeorganizer.py +++ b/src/diffpy/srfit/fitbase/recipeorganizer.py @@ -514,7 +514,8 @@ def _remove_parameter(self, par): return def registerCalculator(self, f, argnames=None): - """Register a Calculator so it can be used within equation strings. + """Register a Calculator so it can be used within equation + strings. A Calculator is an elaborate function that can organize Parameters. This creates a function with this class that can be used within string @@ -551,7 +552,8 @@ def registerCalculator(self, f, argnames=None): return eq def registerFunction(self, f, name=None, argnames=None): - """Register a function so it can be used within equation strings. + """Register a function so it can be used within equation + strings. This creates a function with this class that can be used within string equations. The resulting equation does not require the arguments to be @@ -962,7 +964,8 @@ def clearRestraints(self, recurse=False): return def _get_constraints(self, recurse=True): - """Get the constrained Parameters for this and managed sub-objects.""" + """Get the constrained Parameters for this and managed sub- + objects.""" constraints = {} if recurse: for m in filter(_has_get_constraints, self._iter_managed()): diff --git a/src/diffpy/srfit/fitbase/simplerecipe.py b/src/diffpy/srfit/fitbase/simplerecipe.py index f3789a3a..e9da1f2c 100644 --- a/src/diffpy/srfit/fitbase/simplerecipe.py +++ b/src/diffpy/srfit/fitbase/simplerecipe.py @@ -12,7 +12,8 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## -"""Simple FitRecipe class that includes a FitContribution and Profile.""" +"""Simple FitRecipe class that includes a FitContribution and +Profile.""" from diffpy.srfit.fitbase.fitcontribution import FitContribution from diffpy.srfit.fitbase.fitrecipe import FitRecipe diff --git a/src/diffpy/srfit/pdf/characteristicfunctions.py b/src/diffpy/srfit/pdf/characteristicfunctions.py index 5d2bf15e..9846e131 100644 --- a/src/diffpy/srfit/pdf/characteristicfunctions.py +++ b/src/diffpy/srfit/pdf/characteristicfunctions.py @@ -12,7 +12,8 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## -"""Form factors (characteristic functions) used in PDF nanoshape fitting. +"""Form factors (characteristic functions) used in PDF nanoshape +fitting. These are used to calculate the attenuation of the PDF due to a finite size. For a crystal-like nanoparticle, one can calculate the PDF via @@ -202,8 +203,8 @@ def spheroidalCF2(r, psize, axrat): def lognormalSphericalCF(r, psize, psig): - """Spherical nanoparticle characteristic function with lognormal size - distribution. + """Spherical nanoparticle characteristic function with lognormal + size distribution. Attributes ---------- @@ -405,8 +406,8 @@ def __init__(self, name, model): return def __call__(self, r): - """Calculate the characteristic function from the transform of the - BaseModel.""" + """Calculate the characteristic function from the transform of + the BaseModel.""" # Determine q-values. # We want very fine r-spacing so we can properly normalize f(r). This diff --git a/src/diffpy/srfit/pdf/pdfparser.py b/src/diffpy/srfit/pdf/pdfparser.py index 445835f7..f2d32ccd 100644 --- a/src/diffpy/srfit/pdf/pdfparser.py +++ b/src/diffpy/srfit/pdf/pdfparser.py @@ -109,7 +109,8 @@ class PDFParser(ProfileParser): _format = "PDF" def parseString(self, patstring): - """Parse a string and set the _x, _y, _dx, _dy and _meta variables. + """Parse a string and set the _x, _y, _dx, _dy and _meta + variables. When _dx or _dy cannot be obtained in the data format it is set to 0. diff --git a/src/diffpy/srfit/sas/prcalculator.py b/src/diffpy/srfit/sas/prcalculator.py index 17c63de6..4030aa94 100644 --- a/src/diffpy/srfit/sas/prcalculator.py +++ b/src/diffpy/srfit/sas/prcalculator.py @@ -116,7 +116,8 @@ def _inverted(self, x, c): class CFCalculator(PrCalculator): - """A class for calculating the characteristic function (CF) from data. + """A class for calculating the characteristic function (CF) from + data. This calculator produces f(r) = P(r) / 4 pi r**2 diff --git a/src/diffpy/srfit/sas/sasparser.py b/src/diffpy/srfit/sas/sasparser.py index 1ddd48b3..12583d6b 100644 --- a/src/diffpy/srfit/sas/sasparser.py +++ b/src/diffpy/srfit/sas/sasparser.py @@ -91,7 +91,8 @@ class SASParser(ProfileParser): _format = "SAS" def parseFile(self, filename): - """Parse a file and set the _x, _y, _dx, _dy and _meta variables. + """Parse a file and set the _x, _y, _dx, _dy and _meta + variables. This wipes out the currently loaded data and selected bank number. @@ -131,7 +132,8 @@ def parseFile(self, filename): return def parseString(self, patstring): - """Parse a string and set the _x, _y, _dx, _dy and _meta variables. + """Parse a string and set the _x, _y, _dx, _dy and _meta + variables. When _dx or _dy cannot be obtained in the data format it is set to 0. diff --git a/src/diffpy/srfit/sas/sasprofile.py b/src/diffpy/srfit/sas/sasprofile.py index a5ad4225..a4b313f7 100644 --- a/src/diffpy/srfit/sas/sasprofile.py +++ b/src/diffpy/srfit/sas/sasprofile.py @@ -12,7 +12,8 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## -"""Class for adapting a sas DataInfo objects to the Profile interface.""" +"""Class for adapting a sas DataInfo objects to the Profile +interface.""" __all__ = ["SASProfile"] diff --git a/src/diffpy/srfit/structure/__init__.py b/src/diffpy/srfit/structure/__init__.py index 2a34680e..f479cf50 100644 --- a/src/diffpy/srfit/structure/__init__.py +++ b/src/diffpy/srfit/structure/__init__.py @@ -12,9 +12,9 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## -"""Modules and classes that adapt structure representations to the ParameterSet -interface and automatic structure constraint generation from space group -information.""" +"""Modules and classes that adapt structure representations to the +ParameterSet interface and automatic structure constraint generation +from space group information.""" from diffpy.srfit.structure.sgconstraints import constrainAsSpaceGroup diff --git a/src/diffpy/srfit/structure/objcrystparset.py b/src/diffpy/srfit/structure/objcrystparset.py index 8cb427b9..62995ee6 100644 --- a/src/diffpy/srfit/structure/objcrystparset.py +++ b/src/diffpy/srfit/structure/objcrystparset.py @@ -12,7 +12,8 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## -"""Wrappers for adapting pyobjcryst.crystal.Crystal to a srfit ParameterSet. +"""Wrappers for adapting pyobjcryst.crystal.Crystal to a srfit +ParameterSet. This will adapt a Crystal or Molecule object from pyobjcryst into the ParameterSet interface. The following classes are adapted. @@ -335,7 +336,8 @@ def wrapRestraints(self): return def wrapStretchModeParameters(self): - """Wrap the stretch modes implicit to the Molecule as Parameters. + """Wrap the stretch modes implicit to the Molecule as + Parameters. This will wrap StretchModeBondLengths and StretchModeBondAngles of the Molecule as Parameters. Note that this requires that the MolBondAtoms @@ -1516,7 +1518,8 @@ def getValue(self): class ObjCrystDihedralAngleParameter(StretchModeParameter): - """Class for abstracting a dihedral angle in a Molecule to a Parameter. + """Class for abstracting a dihedral angle in a Molecule to a + Parameter. This wraps up a pyobjcryst.molecule.StretchModeTorsion object so that the angle defined by four MolAtoms ([a1-a2].[a3-a4]) in a Molecule can be used diff --git a/src/diffpy/srfit/structure/sgconstraints.py b/src/diffpy/srfit/structure/sgconstraints.py index c9dbc5b9..81c71de9 100644 --- a/src/diffpy/srfit/structure/sgconstraints.py +++ b/src/diffpy/srfit/structure/sgconstraints.py @@ -814,7 +814,8 @@ def _makeconstraint(parname, formula, scatterer, idx, ns={}): def _get_float(formula): - """Get a float from a formula string, or None if this is not possible.""" + """Get a float from a formula string, or None if this is not + possible.""" try: return eval(formula) except NameError: diff --git a/src/diffpy/srfit/util/__init__.py b/src/diffpy/srfit/util/__init__.py index 023b4256..c8c9b830 100644 --- a/src/diffpy/srfit/util/__init__.py +++ b/src/diffpy/srfit/util/__init__.py @@ -18,8 +18,8 @@ def sortKeyForNumericString(s): - """Compute key for sorting strings according to their integer numeric - value. + """Compute key for sorting strings according to their integer + numeric value. Each string gets split to string and integer segments to create keys for comparison. Signs, decimal points and exponents are ignored. diff --git a/src/diffpy/srfit/util/argbinders.py b/src/diffpy/srfit/util/argbinders.py index 28cd5144..71db89b4 100644 --- a/src/diffpy/srfit/util/argbinders.py +++ b/src/diffpy/srfit/util/argbinders.py @@ -16,7 +16,8 @@ class bind2nd(object): - """Freeze second argument of a callable object to a given constant.""" + """Freeze second argument of a callable object to a given + constant.""" def __init__(self, func, arg1): """Freeze the second argument of function func to arg1.""" diff --git a/src/diffpy/srfit/util/weakrefcallable.py b/src/diffpy/srfit/util/weakrefcallable.py index 287d2e47..042e1812 100644 --- a/src/diffpy/srfit/util/weakrefcallable.py +++ b/src/diffpy/srfit/util/weakrefcallable.py @@ -69,7 +69,8 @@ def __init__(self, f, fallback=None): return def __call__(self, *args, **kwargs): - """Call the wrapped method if the weak-referenced object is alive. + """Call the wrapped method if the weak-referenced object is + alive. If that object does not exist and the fallback function is defined, call the fallback function instead. @@ -122,7 +123,8 @@ def __getstate__(self): return state def __setstate__(self, state): - """Restore the weak reference in this wrapper upon unpickling.""" + """Restore the weak reference in this wrapper upon + unpickling.""" (self._class, nm, self.fallback, mobj) = state self.function = getattr(self._class, nm) if mobj is None: diff --git a/tests/conftest.py b/tests/conftest.py index 0417ad17..62a4d0e7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -90,7 +90,8 @@ def pyobjcryst_available(): @pytest.fixture(scope="session") def datafile(): - """Fixture to load a test data file from the testdata package directory.""" + """Fixture to load a test data file from the testdata package + directory.""" def _datafile(filename): return importlib.resources.files("tests.testdata").joinpath(filename) @@ -166,7 +167,8 @@ def build_recipe_one_contribution(): @pytest.fixture() def build_recipe_two_contributions(): - """Helper to build a recipe with two physically related contributions.""" + """Helper to build a recipe with two physically related + contributions.""" profile1 = Profile() x = linspace(0, pi, 50) y1 = sin(x) # amplitude=1, freq=1 diff --git a/tests/test_contribution.py b/tests/test_contribution.py index 001eee42..ef388b6b 100644 --- a/tests/test_contribution.py +++ b/tests/test_contribution.py @@ -80,7 +80,8 @@ def test_add_profile_generator(self): return def testInteraction(self): - """Test the interaction between the profile and profile generator.""" + """Test the interaction between the profile and profile + generator.""" fc = self.fitcontribution profile = self.profile gen = self.gen @@ -178,7 +179,8 @@ def test_getResidualEquation(self): return def test_releaseOldEquations(self): - """Ensure EquationFactory does not hold to obsolete Equations.""" + """Ensure EquationFactory does not hold to obsolete + Equations.""" fc = self.fitcontribution self.assertEqual(0, len(fc._eqfactory.equations)) for i in range(5): @@ -191,7 +193,8 @@ def test_releaseOldEquations(self): return def test_registerFunction(self): - """Ensure registered function works after second set_equation call.""" + """Ensure registered function works after second set_equation + call.""" fc = self.fitcontribution fc.registerFunction(_fsquare, name="fsquare") fc.set_equation("fsquare") diff --git a/tests/test_fitrecipe.py b/tests/test_fitrecipe.py index 39af10e8..6deb1cad 100644 --- a/tests/test_fitrecipe.py +++ b/tests/test_fitrecipe.py @@ -410,9 +410,9 @@ def test_add_and_remove_parameter_set(): def test_add_contribution(capturestdout): - """Duplicated test of PrintFitHooks except addContribution method has - changed to the new add_contribution method. This is because addContribution - is deprecated. + """Duplicated test of PrintFitHooks except addContribution method + has changed to the new add_contribution method. This is because + addContribution is deprecated. Remove this test after addContribution is removed and update testPrintFitHook to use add_contribution instead of addContribution. @@ -570,8 +570,8 @@ def build_recipe_from_datafile(datafile): def build_recipe_from_datafile_deprecated(datafile): - """Duplicate of build_recipe_from_datafile to use deprecated loadParsedData - method. + """Duplicate of build_recipe_from_datafile to use deprecated + loadParsedData method. Remove in version 4.0.0. """ diff --git a/tests/test_objcrystparset.py b/tests/test_objcrystparset.py index 5150ae54..10c96ee9 100644 --- a/tests/test_objcrystparset.py +++ b/tests/test_objcrystparset.py @@ -650,7 +650,8 @@ def sgsEquivalent(self, sg1, sg2): # FIXME: only about 50% of the spacegroups pass the assertion # test disabled even if cctbx is installed def xtestCreateSpaceGroup(self): - """Check all sgtbx space groups for proper conversion to SpaceGroup.""" + """Check all sgtbx space groups for proper conversion to + SpaceGroup.""" try: from cctbx import sgtbx diff --git a/tests/test_profilegenerator.py b/tests/test_profilegenerator.py index aeacf690..e4ea0fa3 100644 --- a/tests/test_profilegenerator.py +++ b/tests/test_profilegenerator.py @@ -48,7 +48,8 @@ def testOperation(self): return def testUpdate(self): - """Update and change the profile to make sure generator is flushed.""" + """Update and change the profile to make sure generator is + flushed.""" gen = self.gen prof = self.profile diff --git a/tests/test_sgconstraints.py b/tests/test_sgconstraints.py index 4288e530..11859a9f 100644 --- a/tests/test_sgconstraints.py +++ b/tests/test_sgconstraints.py @@ -179,7 +179,8 @@ def _alltests(par): def test_constrain_as_space_group_args(pyobjcryst_available, datafile): - """Test the arguments processing of constrainAsSpaceGroup function.""" + """Test the arguments processing of constrainAsSpaceGroup + function.""" if not pyobjcryst_available: pytest.skip("pyobjcrysta package not available") From e46399686741815b6816c23f70e147169e91c81e Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Feb 2026 15:38:18 -0500 Subject: [PATCH 25/28] rm merge-to-main duplicate workflow --- .../matrix-and-codecov-on-merge-to-main.yml | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 .github/workflows/matrix-and-codecov-on-merge-to-main.yml diff --git a/.github/workflows/matrix-and-codecov-on-merge-to-main.yml b/.github/workflows/matrix-and-codecov-on-merge-to-main.yml deleted file mode 100644 index 2bd09ede..00000000 --- a/.github/workflows/matrix-and-codecov-on-merge-to-main.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: CI - -on: - release: - types: - - prereleased - - published - workflow_dispatch: - -jobs: - matrix-coverage: - uses: scikit-package/release-scripts/.github/workflows/_matrix-and-codecov-on-merge-to-main.yml@v0 - with: - project: diffpy.srfit - c_extension: false - headless: false - secrets: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} From a8334332e1c9be33ef4267f7bbbbacda71514f04 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Feb 2026 15:39:42 -0500 Subject: [PATCH 26/28] add __init__ header to README --- README.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/README.rst b/README.rst index 00bd1dd2..be8a91e4 100644 --- a/README.rst +++ b/README.rst @@ -63,6 +63,23 @@ obtain the total cost function. Additionally, diffpy.srfit is designed to be extensible, allowing the user to integrate external calculators to perform co-refinements with other techniques. + +SrFit has tools for coherently combining known information about a +material to derive other properties, in particular material structure. +SrFit allows the customization and creation of structure +representations, profile calculators, constraints, restraints and file +input parsers. The customized pieces can be glued together within SrFit +to optimize a structure, or other physically relevant information from +one or more experimental profiles. Other known information about the +system of interest can be included with arbitrarily complex constraints +and restraints. In this way, the end user creates a customized fitting +application that suits the problem to the available information. + +The subpackages herein define various pieces of the SrFit framework. +Developers are encouraged to work through the examples described in the +documentation to learn how to use and customize the various parts of +SrFit. + For more information about the diffpy.srfit library, please consult our `online documentation `_. Citation From dd9fca8fe736dfd0c674694b3747f856d4cd4009 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Feb 2026 15:53:11 -0500 Subject: [PATCH 27/28] pull PR to list branch to fix docformatter failure --- news/res-dict.rst | 23 +++++++++ src/diffpy/srfit/fitbase/fitresults.py | 42 +++++++++++++++- tests/conftest.py | 28 +++++++++++ tests/test_fitresults.py | 70 +++++++++++++++++++++++++- 4 files changed, 161 insertions(+), 2 deletions(-) create mode 100644 news/res-dict.rst diff --git a/news/res-dict.rst b/news/res-dict.rst new file mode 100644 index 00000000..6ebe11fc --- /dev/null +++ b/news/res-dict.rst @@ -0,0 +1,23 @@ +**Added:** + +* Added ``FitResults.get_results_dictionary`` in replace of ``resultsDictionary``. + +**Changed:** + +* + +**Deprecated:** + +* Deprecated ``resultsDictionary`` for removal in 4.0.0. + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/srfit/fitbase/fitresults.py b/src/diffpy/srfit/fitbase/fitresults.py index e2f2a20a..c154d018 100644 --- a/src/diffpy/srfit/fitbase/fitresults.py +++ b/src/diffpy/srfit/fitbase/fitresults.py @@ -58,6 +58,14 @@ removal_version, ) +resultsDictionary_dep_msg = build_deprecation_message( + "diffpy.srfit.fitbase", + "resultsDictionary", + "get_results_dictionary", + removal_version, + new_base="diffpy.srfit.fitbase.FitResults", +) + class FitResults(object): """Class for processing, presenting and storing results of a fit. @@ -622,6 +630,31 @@ def saveResults(self, filename, header="", footer="", update=False): self.save_results(filename, header, footer, update) return + def get_results_dictionary(self): + """Get a dictionary of results, with variable names and values, + and overall metrics. + + Returns + ------- + results_dict : dict + A dictionary containing the variable names and values, and overall + metrics, from the FitResults. + """ + parameter_names = self.varnames + parameter_values = self.varvals + results_dict = dict(zip(parameter_names, parameter_values)) + results_dict.update( + { + "Residual": self.residual, + "Contributions": self.residual - self.penalty, + "Restraints": self.penalty, + "Chi2": self.chi2, + "Reduced Chi2": self.rchi2, + "Rw": self.rw, + } + ) + return results_dict + # End class FitResults @@ -753,8 +786,15 @@ def _calculate_metrics(self): # End class ContributionResults +@deprecated(resultsDictionary_dep_msg) def resultsDictionary(results): - """Get dictionary of results from file. + """**This function has been deprecated and will be** **removed in version + 4.0.0.** + + **Please use** + **diffpy.srfit.fitbase.FitResults.get_results_dictionary instead.** + + Get dictionary of results from file. This reads the results from file and stores them in a dictionary to be returned to the caller. The dictionary may contain non-result entries. diff --git a/tests/conftest.py b/tests/conftest.py index 62a4d0e7..45c6308a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -225,4 +225,32 @@ def temp_data_files(tmp_path): cgr_file = tmp_path / "cgr_file.cgr" cgr_file.write_text("1.0 2.0\n" "1.1 2.1\n" "1.2 2.2\n") + + results_file = tmp_path / "fit_results.res" + results_file.write_text( + """ +Results written: Wed Feb 25 15:14:58 2026 +produced by cadenmyers + +Some quantities invalid due to missing profile uncertainty +Overall (Chi2 and Reduced Chi2 invalid) +------------------------------------------------------------------------------ +Residual 0.00000000 +Contributions 0.00000000 +Restraints 0.00000000 +Chi2 0.00000000 +Reduced Chi2 0.00000000 +Rw 0.00000000 + +Variables (Uncertainties invalid) +------------------------------------------------------------------------------ +amplitude 1.00000000e+00 +/- 4.82804000e-01 +phase_shift -1.61291146e-18 +/- 1.00000000e+00 +wave_number 1.00000000e+00 +/- 2.17496687e-01 + +Variable Correlations greater than 25% (Correlations invalid) +------------------------------------------------------------------------------ +No correlations greater than 25% +""" + ) yield tmp_path diff --git a/tests/test_fitresults.py b/tests/test_fitresults.py index 761a30ff..b9fb7492 100644 --- a/tests/test_fitresults.py +++ b/tests/test_fitresults.py @@ -16,11 +16,16 @@ import unittest +import numpy as np import pytest from scipy.optimize import leastsq from diffpy.srfit.fitbase.fitrecipe import FitRecipe -from diffpy.srfit.fitbase.fitresults import FitResults, initializeRecipe +from diffpy.srfit.fitbase.fitresults import ( + FitResults, + initializeRecipe, + resultsDictionary, +) # The fit results from the recipe fixture in conftest.py expected_fitresults = """\ @@ -138,6 +143,69 @@ def test_save_results(build_recipe_one_contribution, tmp_path): assert expected_var in actual_results.strip() +def test_get_results_dictionary(build_recipe_one_contribution): + # Case: user gets results dictionary after optimization + # expected: results dictionary contains expected keys and values + recipe = build_recipe_one_contribution + optimize_recipe(recipe) + results = FitResults(recipe) + actual_results_dict = results.get_results_dictionary() + expected_results_dict = { + "amplitude": 1.000000000060171, + "wave_number": 1.00000000012548, + "phase_shift": -1.6129114631049646e-18, + "Residual": 3.3284672708760557e-19, + "Contributions": 3.3284672708760557e-19, + "Restraints": 0, + "Chi2": 3.3284672708760557e-19, + "Reduced Chi2": 4.7549532441086507e-20, + "Rw": 2.7196679825449506e-10, + } + actual_values = np.round(np.array(list(actual_results_dict.values())), 5) + actual_keys = set(actual_results_dict.keys()) + expected_values = np.round( + np.array(list(expected_results_dict.values())), 5 + ) + expected_keys = set(expected_results_dict.keys()) + assert expected_keys == actual_keys + assert list(expected_values == list(actual_values)) + + +def test_resultsDictionary(temp_data_files): + # Case: user gets results dictionary from a results file + # expected: results dictionary contains expected keys and values + actual_results_dict = resultsDictionary( + temp_data_files / "fit_results.res" + ) + # bad behavior: values are stored as strings + expected_results_dict = { + "than": "25", # bad behavior: shouldn't be here + "wave_number": "1.00000000e+00", + "phase_shift": "-1.61291146e-18", + "amplitude": "1.00000000e+00", + "Rw": "0.00000000", + "Chi2": "0.00000000", + "Restraints": "0.00000000", + "Contributions": "0.00000000", + "Residual": "0.00000000", + "Feb": "25", # bad behavior: shouldn't be here + } + # convert values to float for comparison (with rounding) + for key in expected_results_dict: + expected_results_dict[key] = float(expected_results_dict[key]) + for key in actual_results_dict: + actual_results_dict[key] = float(actual_results_dict[key]) + + actual_keys = set(actual_results_dict.keys()) + actual_values = np.round(np.array(list(actual_results_dict.values())), 5) + expected_keys = set(expected_results_dict.keys()) + expected_values = np.round( + np.array(list(expected_results_dict.values())), 5 + ) + assert expected_keys == actual_keys + assert list(expected_values == list(actual_values)) + + def testInitializeFromFileName(datafile): recipe = FitRecipe("recipe") recipe.create_new_variable("A", 0) From cee67de0e4fa061e1e35449e54f458ef3fbe830f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 25 Feb 2026 20:56:14 +0000 Subject: [PATCH 28/28] [pre-commit.ci] auto fixes from pre-commit hooks --- src/diffpy/srfit/fitbase/fitresults.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/diffpy/srfit/fitbase/fitresults.py b/src/diffpy/srfit/fitbase/fitresults.py index 9812112c..c154d018 100644 --- a/src/diffpy/srfit/fitbase/fitresults.py +++ b/src/diffpy/srfit/fitbase/fitresults.py @@ -631,8 +631,8 @@ def saveResults(self, filename, header="", footer="", update=False): return def get_results_dictionary(self): - """Get a dictionary of results, with variable names and values, and - overall metrics. + """Get a dictionary of results, with variable names and values, + and overall metrics. Returns -------