diff --git a/.github/workflows/check-news-item.yml b/.github/workflows/check-news-item.yml new file mode 100644 index 0000000..960756f --- /dev/null +++ b/.github/workflows/check-news-item.yml @@ -0,0 +1,12 @@ +name: Check for News + +on: + pull_request_target: + branches: + - main + +jobs: + build: + uses: Billingegroup/release-scripts/.github/workflows/_check-news-item.yml@v0 + with: + project: diffpy.srmise diff --git a/.github/workflows/matrix-and-codecov-on-merge-to-main.yml b/.github/workflows/matrix-and-codecov-on-merge-to-main.yml new file mode 100644 index 0000000..f4ad74a --- /dev/null +++ b/.github/workflows/matrix-and-codecov-on-merge-to-main.yml @@ -0,0 +1,21 @@ +name: CI + +on: + push: + branches: + - main + release: + types: + - prereleased + - published + workflow_dispatch: + +jobs: + coverage: + uses: Billingegroup/release-scripts/.github/workflows/_matrix-and-codecov-on-merge-to-main.yml@v0 + with: + project: diffpy.srmise + c_extension: false + headless: false + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/publish-docs-on-release.yml b/.github/workflows/publish-docs-on-release.yml new file mode 100644 index 0000000..665ec6e --- /dev/null +++ b/.github/workflows/publish-docs-on-release.yml @@ -0,0 +1,14 @@ +name: Build and Deploy Docs + +on: + release: + types: + - published + workflow_dispatch: + +jobs: + docs: + uses: Billingegroup/release-scripts/.github/workflows/_publish-docs-on-release.yml@v0 + with: + project: diffpy.srmise + c_extension: false diff --git a/.github/workflows/tests-on-pr.yml b/.github/workflows/tests-on-pr.yml new file mode 100644 index 0000000..0988b48 --- /dev/null +++ b/.github/workflows/tests-on-pr.yml @@ -0,0 +1,16 @@ +name: Tests on PR + +on: + push: + branches: + - main + pull_request: + workflow_dispatch: + +jobs: + validate: + uses: Billingegroup/release-scripts/.github/workflows/_tests-on-pr.yml@v0 + with: + project: diffpy.srmise + c_extension: false + headless: false diff --git a/.gitignore b/.gitignore index 39d6656..a25212e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,44 +1,99 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ *.py[cod] +*$py.class # C extensions *.so -# Packages -*.egg -*.egg-info -dist -build -eggs -parts -bin -var -sdist -temp -develop-eggs +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +venv/ +*.egg-info/ .installed.cfg -lib -lib64 -tags +*.egg +bin/ +temp/ +tags/ errors.err +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + # Installer logs pip-log.txt +pip-delete-this-directory.txt MANIFEST # Unit test / coverage reports +htmlcov/ +.tox/ .coverage -.tox +.coverage.* +.cache nosetests.xml +coverage.xml +*,cover +.hypothesis/ # Translations *.mo +*.pot # Mr Developer .mr.developer.cfg .project .pydevproject -.settings + +# Django stuff: +*.log + +# Sphinx documentation +docs/build/ +docs/source/generated/ + +# pytest +.pytest_cache/ + +# PyBuilder +target/ + +# Editor files +# mac +.DS_Store +*~ + +# vim +*.swp +*.swo + +# pycharm +.idea/ + +# VSCode +.vscode/ + +# Ipython Notebook +.ipynb_checkpoints # version information setup.cfg -/diffpy/srmise/version.cfg +/src/diffpy/*/version.cfg + +# Rever +rever/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c458806..3070e19 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,10 @@ repos: - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace - exclude: '\.(rst|txt)$' + - id: check-case-conflict + - id: check-merge-conflict + - id: check-toml + - id: check-added-large-files - repo: https://github.com/psf/black rev: 24.4.2 hooks: diff --git a/doc/manual/source/extending.rst b/doc/manual/source/extending.rst index 202c6cf..43951b9 100644 --- a/doc/manual/source/extending.rst +++ b/doc/manual/source/extending.rst @@ -27,14 +27,14 @@ subpackges, as shown below. * .. py:class:: BaseFunction + .. py:class:: BaselineFunction - + - .. py:class:: FromSequence - .. py:class:: NanoSpherical - .. py:class:: Polynomial - *etc.* - + + .. py:class:: PeakFunction - + - .. py:class:: Gaussian - .. py:class:: GaussianOverR - *etc.* @@ -57,7 +57,7 @@ for examples. .. py:method:: estimate_parameters(r, y) Return a Numpy array of parameters estimated from the data. - + :param r: Grid on which the data are defined. :param y: The data. :type r: `Sequence` @@ -69,9 +69,9 @@ for examples. .. py:method:: _jacobian_raw(pars, r, free) - + Return Jacobian for parameters evaluated over `r`. - + :param pars: The parameters of the baseline. :param r: Scalar or grid on which to calculate the Jacobian. :param free: Boolean values indicating if corresponding parameter is free (True) or fixed (False). @@ -84,7 +84,7 @@ for examples. .. py:method:: _transform_derivativesraw(pars, in_format, out_format) Return the gradient matrix of `pars` represented in format 'out_format'. - + :param pars: The parameters of the baseline. :param in_format: The format of `pars`. :param out_format: The desired format of `pars`. @@ -97,7 +97,7 @@ for examples. .. py:method:: _transform_parametersraw(pars, in_format, out_format) Return parameters transformed into format 'out_format'. - + :param pars: The parameters of the baseline. :param in_format: The format of `pars`. :param out_format: The desired format of `pars`. @@ -106,11 +106,11 @@ for examples. :type out_format: `str` :returns: The transformed parameters. :rtype: `numpy.ndarray` - + .. py:method:: _valueraw(pars, r) Return value of baseline with given parameters at r. - + :param pars: The parameters of the baseline. :param r: Scalar or grid on which to calculate the baseline. :type pars: `Sequence(float)` @@ -130,12 +130,12 @@ following differences: 1) The ``estimate_parameters`` method is required. 2) The "position" key must be defined in the ``parameterdict`` class member. 3) Peak functions must implement the additional method ``scale_at``. - + .. py:method:: scale_at(pars, r, scale) Return peak parameters such that the value at ``r`` is scaled by ``scale`` while the position of the peak's maxima remains unchanged. - + :param pars: The parameters of the peak. :param r: Position where the peak will be rescaled. :param scale: A scale factor > 0. diff --git a/doc/manual/source/index.rst b/doc/manual/source/index.rst index 75ee33e..5ca43fe 100644 --- a/doc/manual/source/index.rst +++ b/doc/manual/source/index.rst @@ -10,38 +10,38 @@ Last updated |today|. Tool for unbiased peak extraction from atomic pair distribution functions. -The diffpy.srmise package is an implementation of the `ParSCAPE algorithm -`_ for peak extraction from -atomic pair distribution functions (PDFs). It is designed to function even -when *a priori* knowledge of the physical sample is limited, utilizing the -Akaike Information Criterion (AIC) to estimate whether peaks are -statistically justified relative to alternate models. Three basic use cases -are anticipated for diffpy.srmise. The first is peak fitting a user-supplied -collections of peaks. The second is peak extraction from a PDF with no (or -only partial) user-supplied peaks. The third is an AIC-driven multimodeling -analysis where the output of multiple diffpy.srmise trials are ranked. - -The framework for peak extraction defines peak-like clusters within the data, -extracts a single peak within each cluster, and iteratively combines nearby -clusters while performing a recursive search on the residual to identify -occluded peaks. Eventually this results in a single global cluster -containing many peaks fit over all the data. Over- and underfitting are -discouraged by use of the AIC when adding or removing (during a pruning step) -peaks. Termination effects, which can lead to physically spurious peaks in -the PDF, are incorporated in the mathematical peak model and the pruning step -attempts to remove peaks which are fit better as termination ripples due to -another peak. - -Where possible, diffpy.srmise provides physically reasonable default values -for extraction parameters. However, the PDF baseline should be estimated by -the user before extraction, or by performing provisional peak extraction with -varying baseline parameters. The package defines a linear (crystalline) -baseline, arbitrary polynomial baseline, a spherical nanoparticle baseline, -and an arbitrary baseline interpolated from a list of user-supplied values. -In addition, PDFs with accurate experimentally-determined uncertainties are -necessary to provide the most reliable results, but historically such PDFs -are rare. In the absence of accurate uncertainties an ad hoc uncertainty -must be specified. +The diffpy.srmise package is an implementation of the `ParSCAPE algorithm +`_ for peak extraction from +atomic pair distribution functions (PDFs). It is designed to function even +when *a priori* knowledge of the physical sample is limited, utilizing the +Akaike Information Criterion (AIC) to estimate whether peaks are +statistically justified relative to alternate models. Three basic use cases +are anticipated for diffpy.srmise. The first is peak fitting a user-supplied +collections of peaks. The second is peak extraction from a PDF with no (or +only partial) user-supplied peaks. The third is an AIC-driven multimodeling +analysis where the output of multiple diffpy.srmise trials are ranked. + +The framework for peak extraction defines peak-like clusters within the data, +extracts a single peak within each cluster, and iteratively combines nearby +clusters while performing a recursive search on the residual to identify +occluded peaks. Eventually this results in a single global cluster +containing many peaks fit over all the data. Over- and underfitting are +discouraged by use of the AIC when adding or removing (during a pruning step) +peaks. Termination effects, which can lead to physically spurious peaks in +the PDF, are incorporated in the mathematical peak model and the pruning step +attempts to remove peaks which are fit better as termination ripples due to +another peak. + +Where possible, diffpy.srmise provides physically reasonable default values +for extraction parameters. However, the PDF baseline should be estimated by +the user before extraction, or by performing provisional peak extraction with +varying baseline parameters. The package defines a linear (crystalline) +baseline, arbitrary polynomial baseline, a spherical nanoparticle baseline, +and an arbitrary baseline interpolated from a list of user-supplied values. +In addition, PDFs with accurate experimentally-determined uncertainties are +necessary to provide the most reliable results, but historically such PDFs +are rare. In the absence of accurate uncertainties an ad hoc uncertainty +must be specified. =================== @@ -81,7 +81,7 @@ Where next? tutorial/index.rst extending.rst - + ====================================== API ====================================== diff --git a/doc/source/api/diffpy.srmise.example_package.rst b/doc/source/api/diffpy.srmise.example_package.rst new file mode 100644 index 0000000..8c7f6ad --- /dev/null +++ b/doc/source/api/diffpy.srmise.example_package.rst @@ -0,0 +1,31 @@ +.. _example_package documentation: + +|title| +======= + +.. |title| replace:: diffpy.srmise.example_package package + +.. automodule:: diffpy.srmise.example_package + :members: + :undoc-members: + :show-inheritance: + +|foo| +----- + +.. |foo| replace:: diffpy.srmise.example_package.foo module + +.. automodule:: diffpy.srmise.example_package.foo + :members: + :undoc-members: + :show-inheritance: + +|bar| +----- + +.. |bar| replace:: diffpy.srmise.example_package.bar module + +.. automodule:: diffpy.srmise.example_package.foo + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/license.rst b/doc/source/license.rst index cfab61c..9ae52a9 100644 --- a/doc/source/license.rst +++ b/doc/source/license.rst @@ -9,9 +9,9 @@ OPEN SOURCE LICENSE AGREEMENT ============================= BSD 3-Clause License -Copyright (c) 2024, The Trustees of Columbia University in +Copyright (c) 2024, The Trustees of Columbia University in the City of New York. -All Rights Reserved. +All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/tests/test_version.py b/tests/test_version.py new file mode 100644 index 0000000..1bc10c2 --- /dev/null +++ b/tests/test_version.py @@ -0,0 +1,10 @@ +"""Unit tests for __version__.py +""" + +import diffpy.srmise + + +def test_package_version(): + """Ensure the package version is defined and not set to the initial placeholder.""" + assert hasattr(diffpy.srmise, "__version__") + assert diffpy.srmise.__version__ != "0.0.0"