diff --git a/.codecov.yml b/.codecov.yml new file mode 100644 index 0000000..4af5eb2 --- /dev/null +++ b/.codecov.yml @@ -0,0 +1,14 @@ +coverage: + status: + project: # more options at https://docs.codecov.com/docs/commit-status + default: + target: auto # use the coverage from the base commit, fail if coverage is lower + threshold: 0% # allow the coverage to drop by + +comment: + layout: " diff, flags, files" + behavior: default + require_changes: false + require_base: false # [true :: must have a base report to post] + require_head: false # [true :: must have a head report to post] + hide_project_coverage: false # [true :: only show coverage on the git diff aka patch coverage] diff --git a/.codespell/ignore_lines.txt b/.codespell/ignore_lines.txt new file mode 100644 index 0000000..07fa7c8 --- /dev/null +++ b/.codespell/ignore_lines.txt @@ -0,0 +1,2 @@ +;; Please include filenames and explanations for each ignored line. +;; See https://docs.openverse.org/meta/codespell.html for docs. diff --git a/.codespell/ignore_words.txt b/.codespell/ignore_words.txt new file mode 100644 index 0000000..04b4fcf --- /dev/null +++ b/.codespell/ignore_words.txt @@ -0,0 +1,8 @@ +;; Please include explanations for each ignored word (lowercase). +;; See https://docs.openverse.org/meta/codespell.html for docs. + +;; abbreviation for "materials" often used in a journal title +mater + +;; Frobenius norm used in np.linalg.norm +fro diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..88077af --- /dev/null +++ b/.flake8 @@ -0,0 +1,13 @@ +# As of now, flake8 does not natively support configuration via pyproject.toml +# https://github.com/microsoft/vscode-flake8/issues/135 +[flake8] +exclude = + .git, + __pycache__, + build, + dist, + docs/source/conf.py +max-line-length = 79 +# Ignore some style 'errors' produced while formatting by 'black' +# https://black.readthedocs.io/en/stable/guides/using_black_with_other_tools.html#labels-why-pycodestyle-warnings +extend-ignore = E203 diff --git a/.github/ISSUE_TEMPLATE/bug_feature.md b/.github/ISSUE_TEMPLATE/bug_feature.md new file mode 100644 index 0000000..b3454de --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_feature.md @@ -0,0 +1,16 @@ +--- +name: Bug Report or Feature Request +about: Report a bug or suggest a new feature! +title: "" +labels: "" +assignees: "" +--- + +### Problem + + + +### Proposed solution diff --git a/.github/ISSUE_TEMPLATE/release_checklist.md b/.github/ISSUE_TEMPLATE/release_checklist.md new file mode 100644 index 0000000..56bcd01 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/release_checklist.md @@ -0,0 +1,46 @@ +--- +name: Release +about: Checklist and communication channel for PyPI and GitHub release +title: "Ready for PyPI/GitHub release" +labels: "release" +assignees: "" +--- + +### PyPI/GitHub rc-release preparation checklist: + +- [ ] 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. +- [ ] 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. + +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: + +### PyPI/GitHub full-release preparation checklist: + +- [ ] Create a new conda environment and install the rc from PyPI (`pip install ==??`) +- [ ] License information on PyPI is correct. +- [ ] Docs are deployed successfully to `https:///`. +- [ ] Successfully run all tests, tutorial examples or do functional testing. + +Please let the maintainer know that all checks are done and the package is ready for full release. + +### conda-forge release preparation checklist: + + + +- [ ] Ensure that the full release has appeared on PyPI successfully. +- [ ] 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. + +### Post-release checklist + + + +- [ ] Run tutorial examples and conduct functional testing using the installation guide in the README. Attach screenshots/results as comments. +- [ ] Documentation (README, tutorials, API references, and websites) is deployed without broken links or missing figures. diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md new file mode 100644 index 0000000..1099d86 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md @@ -0,0 +1,15 @@ +### What problem does this PR address? + + + +### What should the reviewer(s) do? + + + + diff --git a/.github/workflows/build-wheel-release-upload.yml b/.github/workflows/build-wheel-release-upload.yml new file mode 100644 index 0000000..ae0b583 --- /dev/null +++ b/.github/workflows/build-wheel-release-upload.yml @@ -0,0 +1,18 @@ +name: Release (GitHub/PyPI) and Deploy Docs + +on: + workflow_dispatch: + push: + tags: + - "*" # Trigger on all tags initially, but tag and release privilege are verified in _build-wheel-release-upload.yml + +jobs: + build-release: + uses: scikit-package/release-scripts/.github/workflows/_build-wheel-release-upload.yml@v0 + with: + project: diffpy.srxplanargui + c_extension: false + maintainer_GITHUB_username: sbillinge + secrets: + PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} + PAT_TOKEN: ${{ secrets.PAT_TOKEN }} diff --git a/.github/workflows/check-news-item.yml b/.github/workflows/check-news-item.yml new file mode 100644 index 0000000..33bc2b7 --- /dev/null +++ b/.github/workflows/check-news-item.yml @@ -0,0 +1,12 @@ +name: Check for News + +on: + pull_request_target: + branches: + - main + +jobs: + check-news-item: + uses: scikit-package/release-scripts/.github/workflows/_check-news-item.yml@v0 + with: + project: diffpy.srxplanargui 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..c1412b1 --- /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: + matrix-coverage: + uses: scikit-package/release-scripts/.github/workflows/_matrix-and-codecov-on-merge-to-main.yml@v0 + with: + project: diffpy.srxplanargui + 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..5ba4522 --- /dev/null +++ b/.github/workflows/publish-docs-on-release.yml @@ -0,0 +1,12 @@ +name: Deploy Documentation on Release + +on: + workflow_dispatch: + +jobs: + docs: + uses: scikit-package/release-scripts/.github/workflows/_publish-docs-on-release.yml@v0 + with: + project: diffpy.srxplanargui + c_extension: false + headless: false diff --git a/.github/workflows/tests-on-pr-no-codecov.yml b/.github/workflows/tests-on-pr-no-codecov.yml new file mode 100644 index 0000000..aa33e97 --- /dev/null +++ b/.github/workflows/tests-on-pr-no-codecov.yml @@ -0,0 +1,16 @@ +name: Tests on PR + +on: + pull_request: + workflow_dispatch: + +jobs: + tests-on-pr: + uses: scikit-package/release-scripts/.github/workflows/_tests-on-pr-no-codecov.yml@v0 + with: + project: diffpy.srxplanargui + c_extension: false + headless: false + run: | + conda install pre-commit + pre-commit run --all-files diff --git a/.gitignore b/.gitignore index c296211..099e294 100644 --- a/.gitignore +++ b/.gitignore @@ -1,44 +1,93 @@ +# 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/ +_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 -# version information -setup.cfg -/dpx/srxplanargui/version.cfg +# 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 diff --git a/.isort.cfg b/.isort.cfg new file mode 100644 index 0000000..ce1201a --- /dev/null +++ b/.isort.cfg @@ -0,0 +1,7 @@ +[settings] +# Keep import statement below line_length character limit +line_length = 79 +multi_line_output = 3 +include_trailing_comma = True +profile=black +skip=src/diffpy/srxplanargui/live.py,src/diffpy/srxplanargui/selectfiles.py,src/diffpy/srxplanargui/imageplot.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..0e4a84d --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,66 @@ +default_language_version: + python: python3 +ci: + autofix_commit_msg: | + [pre-commit.ci] auto fixes from pre-commit hooks + autofix_prs: true + autoupdate_branch: "pre-commit-autoupdate" + autoupdate_commit_msg: "[pre-commit.ci] pre-commit autoupdate" + autoupdate_schedule: monthly + skip: [no-commit-to-branch] + submodules: false +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 + hooks: + - id: check-yaml + - id: end-of-file-fixer + - id: trailing-whitespace + - 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: + - id: black + - repo: https://github.com/pycqa/flake8 + rev: 7.0.0 + hooks: + - id: flake8 + - repo: https://github.com/pycqa/isort + rev: 5.13.2 + hooks: + - id: isort + args: ["--profile", "black"] + - repo: https://github.com/kynan/nbstripout + rev: 0.7.1 + hooks: + - id: nbstripout + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + - id: no-commit-to-branch + name: Prevent Commit to Main Branch + args: ["--branch", "main"] + stages: [pre-commit] + - repo: https://github.com/codespell-project/codespell + rev: v2.3.0 + hooks: + - id: codespell + additional_dependencies: + - tomli + # prettier - multi formatter for .json, .yml, and .md files + - repo: https://github.com/pre-commit/mirrors-prettier + rev: f12edd9c7be1c20cfa42420fd0e6df71e42b51ea # frozen: v4.0.0-alpha.8 + hooks: + - id: prettier + additional_dependencies: + - "prettier@^3.2.4" + # docformatter - PEP 257 compliant docstring formatter + - repo: https://github.com/s-weigand/docformatter + rev: 5757c5190d95e5449f102ace83df92e7d3b06c6c + hooks: + - id: docformatter + additional_dependencies: [tomli] + args: [--in-place, --config, ./pyproject.toml] diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..aaa8889 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,13 @@ +version: 2 + +build: + os: "ubuntu-22.04" + tools: + python: "latest" + +python: + install: + - requirements: requirements/docs.txt + +sphinx: + configuration: docs/source/conf.py diff --git a/MANIFEST.in b/MANIFEST.in index 982d898..f1a78ee 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,3 +1,12 @@ -recursive-include dpx * -prune doc -exclude MANIFEST.in +graft src +graft tests +graft requirements + +include AUTHORS.rst LICENSE*.rst README.rst + +# Exclude all bytecode files and __pycache__ directories +global-exclude *.py[cod] # Exclude all .pyc, .pyo, and .pyd files. +global-exclude .DS_Store # Exclude Mac filesystem artifacts. +global-exclude __pycache__ # Exclude Python cache directories. +global-exclude .git* # Exclude git files and directories. +global-exclude .idea # Exclude PyCharm project settings. diff --git a/README.rst b/README.rst index 6cc2e20..e378d3b 100644 --- a/README.rst +++ b/README.rst @@ -1,45 +1,137 @@ -dpx.srxplanargui -======================================================================== +|Icon| |title|_ +=============== -GUI for diffpy.srxplanar +.. |title| replace:: diffpy.srxplanargui +.. _title: https://diffpy.github.io/diffpy.srxplanargui -REQUIREMENTS ------------------------------------------------------------------------- +.. |Icon| image:: https://avatars.githubusercontent.com/diffpy + :target: https://diffpy.github.io/diffpy.srxplanargui + :height: 100px -The dpx.srxplanargui requires Python 2.7 and the following software: +|PyPI| |Forge| |PythonVersion| |PR| -* ``diffpy.srxplanar`` -* ``dpx.confutils`` -* ``numpy`` -* ``scipy`` -* ``traits`` -* ``traitsui`` -* ``chaco`` +|CI| |Codecov| |Black| |Tracking| -The image integration (diffpy.srxplanargui) requires +.. |Black| image:: https://img.shields.io/badge/code_style-black-black + :target: https://github.com/psf/black -* ``fabio`` -* ``pyfai`` -* ``matplotlib`` +.. |CI| image:: https://github.com/diffpy/diffpy.srxplanargui/actions/workflows/matrix-and-codecov-on-merge-to-main.yml/badge.svg + :target: https://github.com/diffpy/diffpy.srxplanargui/actions/workflows/matrix-and-codecov-on-merge-to-main.yml -INSTALLATION ------------------------------------------------------------------------- +.. |Codecov| image:: https://codecov.io/gh/diffpy/diffpy.srxplanargui/branch/main/graph/badge.svg + :target: https://codecov.io/gh/diffpy/diffpy.srxplanargui -We are going to release conda package for all platform. For general user -please use the installation file and install software. For developor, -you can install dpx.srxplanargui using +.. |Forge| image:: https://img.shields.io/conda/vn/conda-forge/diffpy.srxplanargui + :target: https://anaconda.org/conda-forge/diffpy.srxplanargui - python setup.py install +.. |PR| image:: https://img.shields.io/badge/PR-Welcome-29ab47ff + :target: https://github.com/diffpy/diffpy.srxplanargui/pulls -Note: the dependency is not specified in the setup.py. You need to install -them yourself. You can use Anaconda or other python enviroment. +.. |PyPI| image:: https://img.shields.io/pypi/v/diffpy.srxplanargui + :target: https://pypi.org/project/diffpy.srxplanargui/ +.. |PythonVersion| image:: https://img.shields.io/pypi/pyversions/diffpy.srxplanargui + :target: https://pypi.org/project/diffpy.srxplanargui/ -CONTACTS ------------------------------------------------------------------------- +.. |Tracking| image:: https://img.shields.io/badge/issue_tracking-github-blue + :target: https://github.com/diffpy/diffpy.srxplanargui/issues -For more information on diffpy.Structure please visit the project web-page +xPDFsuite, a software for PDF transformation and visualization. -http://www.diffpy.org/ +* LONGER DESCRIPTION HERE -or email Prof. Simon Billinge at sb2896@columbia.edu. +For more information about the diffpy.srxplanargui library, please consult our `online documentation `_. + +Citation +-------- + +If you use diffpy.srxplanargui in a scientific publication, we would like you to cite this package as + + diffpy.srxplanargui Package, https://github.com/diffpy/diffpy.srxplanargui + +Installation +------------ + +The preferred method is to use `Miniconda Python +`_ +and install from the "conda-forge" channel of Conda packages. + +To add "conda-forge" to the conda channels, run the following in a terminal. :: + + conda config --add channels conda-forge + +We want to install our packages in a suitable conda environment. +The following creates and activates a new environment named ``diffpy.srxplanargui_env`` :: + + conda create -n diffpy.srxplanargui_env diffpy.srxplanargui + conda activate diffpy.srxplanargui_env + +The output should print the latest version displayed on the badges above. + +If the above does not work, you can use ``pip`` to download and install the latest release from +`Python Package Index `_. +To install using ``pip`` into your ``diffpy.srxplanargui_env`` environment, type :: + + pip install diffpy.srxplanargui + +If you prefer to install from sources, after installing the dependencies, obtain the source archive from +`GitHub `_. Once installed, ``cd`` into your ``diffpy.srxplanargui`` directory +and run the following :: + + pip install . + +This package also provides command-line utilities. To check the software has been installed correctly, type :: + + diffpy.srxplanargui --version + +You can also type the following command to verify the installation. :: + + python -c "import diffpy.srxplanargui; print(diffpy.srxplanargui.__version__)" + + +To view the basic usage and available commands, type :: + + diffpy.srxplanargui -h + +Getting Started +--------------- + +You may consult our `online documentation `_ for tutorials and API references. + +Support and Contribute +---------------------- + +If you see a bug or want to request a feature, please `report it as an issue `_ and/or `submit a fix as a PR `_. + +Feel free to fork the project and contribute. To install diffpy.srxplanargui +in a development mode, with its sources being directly used by Python +rather than copied to a package directory, use the following in the root +directory :: + + pip install -e . + +To ensure code quality and to prevent accidental commits into the default branch, please set up the use of our pre-commit +hooks. + +1. Install pre-commit in your working environment by running ``conda install pre-commit``. + +2. Initialize pre-commit (one time only) ``pre-commit install``. + +Thereafter your code will be linted by black and isort and checked against flake8 before you can commit. +If it fails by black or isort, just rerun and it should pass (black and isort will modify the files so should +pass after they are modified). If the flake8 test fails please see the error messages and fix them manually before +trying to commit again. + +Improvements and fixes are always appreciated. + +Before contributing, please read our `Code of Conduct `_. + +Contact +------- + +For more information on diffpy.srxplanargui please visit the project `web-page `_ or email Simon Billinge at sb2896@columbia.edu. + +Acknowledgements +---------------- + +``diffpy.srxplanargui`` is built and maintained with `scikit-package `_. diff --git a/pyproject.toml b/pyproject.toml index e21b5c8..e9510cc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,12 +6,12 @@ build-backend = "setuptools.build_meta" name = "diffpy.srxplanargui" dynamic=['version', 'dependencies'] authors = [ - { name="Simon J.L. Billinge group", email="simon.billinge@gmail.com" }, + { name="Simon Billinge", email="sb2896@columbia.edu" }, ] maintainers = [ - { name="Simon J.L. Billinge group", email="simon.billinge@gmail.com" }, + { name="Simon Billinge", email="sb2896@columbia.edu" }, ] -description = "xPDFsuite, a software for PDF transformation and visualization" +description = "xPDFsuite, a software for PDF transformation and visualization." keywords = ['diffpy', 'pdf', 'data interpretation'] readme = "README.rst" requires-python = ">=3.11, <3.14" @@ -32,9 +32,6 @@ classifiers = [ 'Topic :: Scientific/Engineering :: Chemistry', ] -[project.scripts] -srxgui = 'diffpy.srxplanargui.srxguiapp:main' - [project.urls] Homepage = "https://github.com/diffpy/diffpy.srxplanargui/" Issues = "https://github.com/diffpy/diffpy.srxplanargui/issues/" @@ -51,13 +48,16 @@ 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-srxplanargui = "diffpy.srxplanargui_app:main" + [tool.setuptools.dynamic] dependencies = {file = ["requirements/pip.txt"]} [tool.codespell] exclude-file = ".codespell/ignore_lines.txt" ignore-words = ".codespell/ignore_words.txt" -skip = "*.cif,*.dat,*agr" +skip = "*.cif,*.dat" [tool.docformatter] recursive = true diff --git a/requirements/build.txt b/requirements/build.txt new file mode 100644 index 0000000..e69de29 diff --git a/requirements/conda.txt b/requirements/conda.txt new file mode 100644 index 0000000..4310926 --- /dev/null +++ b/requirements/conda.txt @@ -0,0 +1,5 @@ +numpy +fabio +pyfai +matplotlib +pyface diff --git a/requirements/docs.txt b/requirements/docs.txt new file mode 100644 index 0000000..5f34c6e --- /dev/null +++ b/requirements/docs.txt @@ -0,0 +1,5 @@ +sphinx +sphinx_rtd_theme +sphinx-copybutton +doctr +m2r diff --git a/requirements/pip.txt b/requirements/pip.txt index eda5283..b667751 100644 --- a/requirements/pip.txt +++ b/requirements/pip.txt @@ -1,7 +1,7 @@ numpy -traits -traitsui chaco pyface +scipy +traits +traitsui diffpy.srxplanar -configparser diff --git a/requirements/tests.txt b/requirements/tests.txt new file mode 100644 index 0000000..a727786 --- /dev/null +++ b/requirements/tests.txt @@ -0,0 +1,6 @@ +flake8 +pytest +codecov +coverage +pytest-cov +pytest-env diff --git a/src/diffpy/__init__.py b/src/diffpy/__init__.py old mode 100755 new mode 100644 index 07795ce..f7af346 --- a/src/diffpy/__init__.py +++ b/src/diffpy/__init__.py @@ -1,18 +1,14 @@ #!/usr/bin/env python ############################################################################## # -# dpx.pdfgetxgui by Simon J. L. Billinge group -# (c) 2012 Trustees of the Columbia University -# in the City of New York. All rights reserved. +# (c) 2025 The Trustees of Columbia University in the City of New York. +# All rights reserved. # -# File coded by: Xiaohao Yang +# File coded by: Billinge Group members and community contributors. # -# See AUTHORS.txt for a list of people who contributed. -# See LICENSE.txt for license information. +# See GitHub contributions for a more detailed list of contributors. +# https://github.com/diffpy/diffpy.srxplanargui/graphs/contributors +# +# See LICENSE.rst for license information. # ############################################################################## -"""Blank namespace package.""" - -__import__("pkg_resources").declare_namespace(__name__) - -# End of file diff --git a/src/diffpy/srxplanargui/__init__.py b/src/diffpy/srxplanargui/__init__.py old mode 100755 new mode 100644 index 8d41a88..01cfd49 --- a/src/diffpy/srxplanargui/__init__.py +++ b/src/diffpy/srxplanargui/__init__.py @@ -1,19 +1,23 @@ #!/usr/bin/env python ############################################################################## # -# dpx.pdfgetxgui by Simon J. L. Billinge group -# (c) 2012 Trustees of the Columbia University -# in the City of New York. All rights reserved. +# (c) 2025 The Trustees of Columbia University in the City of New York. +# All rights reserved. # -# File coded by: Xiaohao Yang +# File coded by: Rundong Hua, Simon Billinge, Billinge Group members. # -# See AUTHORS.txt for a list of people who contributed. -# See LICENSE.txt for license information. +# See GitHub contributions for a more detailed list of contributors. +# https://github.com/diffpy/diffpy.srxplanargui/graphs/contributors +# +# See LICENSE.rst for license information. # ############################################################################## +"""XPDFsuite, a software for PDF transformation and visualization.""" +# package version +from diffpy.srxplanargui.version import __version__ # noqa -# obtain version information -# from diffpy.srxplanargui.version import __version__ +# silence the pyflakes syntax checker +assert __version__ or True # End of file diff --git a/src/diffpy/srxplanargui/calibration.py b/src/diffpy/srxplanargui/calibration.py index 5a1b986..0388596 100644 --- a/src/diffpy/srxplanargui/calibration.py +++ b/src/diffpy/srxplanargui/calibration.py @@ -16,10 +16,6 @@ import re import sys -from diffpy.srxconfutils.tools import module_exists_lower -from diffpy.srxplanar.selfcalibrate import selfCalibrate -from diffpy.srxplanar.srxplanar import SrXplanar -from diffpy.srxplanar.srxplanarconfig import checkMax from pyface.api import ImageResource from traits.api import ( Bool, @@ -38,6 +34,10 @@ from traitsui.api import Group, Handler, HGroup, Item, VGroup, View from traitsui.menu import CancelButton, OKButton +from diffpy.srxconfutils.tools import module_exists_lower +from diffpy.srxplanar.selfcalibrate import selfCalibrate +from diffpy.srxplanar.srxplanar import SrXplanar +from diffpy.srxplanar.srxplanarconfig import checkMax from diffpy.srxplanargui.srxconfig import SrXconfig ETSConfig.toolkit = "qt" diff --git a/src/diffpy/srxplanargui/imageplot.py b/src/diffpy/srxplanargui/imageplot.py index c91d351..0679bc7 100644 --- a/src/diffpy/srxplanargui/imageplot.py +++ b/src/diffpy/srxplanargui/imageplot.py @@ -101,38 +101,50 @@ class ImagePlot(HasTraits): ) avgmask = DelegatesTo( "srxconfig", - desc=("Mask the pixels too bright or too dark compared to" - " the average intensity at the similar diffraction angle"), + desc=( + "Mask the pixels too bright or too dark compared to" + " the average intensity at the similar diffraction angle" + ), ) brightpixelr = DelegatesTo( "srxconfig", - desc=("Pixels with intensity large than this relative threshold" - " (times the local environment) value will be masked"), + desc=( + "Pixels with intensity large than this relative threshold" + " (times the local environment) value will be masked" + ), ) brightpixelsize = DelegatesTo( "srxconfig", desc="Size of testing area for detecting bright pixels" ) darkpixelr = DelegatesTo( "srxconfig", - desc=("Pixels with intensity less than this relative threshold" - " (times the local environment) value will be masked"), + desc=( + "Pixels with intensity less than this relative threshold" + " (times the local environment) value will be masked" + ), ) avgmaskhigh = DelegatesTo( "srxconfig", - desc=("Comparing to the average intensity at " - "similar diffraction angle, \npixels with intensity larger than" - " avg_int*high will be masked"), + desc=( + "Comparing to the average intensity at " + "similar diffraction angle, \npixels with intensity larger than" + " avg_int*high will be masked" + ), ) avgmasklow = DelegatesTo( "srxconfig", - desc=("Comparing to the average intensity at " - "similar diffraction angle, \npixels with intensity less than " - "avg_int*low will be masked"), + desc=( + "Comparing to the average intensity at " + "similar diffraction angle, \npixels with intensity less than " + "avg_int*low will be masked" + ), ) cropedges = DelegatesTo( "srxconfig", - desc=("The number of pixels masked" - " at each edge (left, right, top, bottom)"), + desc=( + "The number of pixels masked" + " at each edge (left, right, top, bottom)" + ), ) def createPlot(self): @@ -231,7 +243,7 @@ def addPointMask(self, ndx, remove=None): """Param ndx -- (x,y) float.""" x, y = ndx r = self.pts - np.array((x, y)) - r = np.sum(r ** 2, axis=1) + r = np.sum(r**2, axis=1) mask = r < ((self.pointmaskradius + 1) ** 2) mask = mask.reshape(self.staticmask.shape) if remove: @@ -318,9 +330,11 @@ def _enableMaskEditing(self): self.plot.tools.remove(self.pan) self.plot.overlays.append(self.lstool) self.titlebak = self.plot.title - self.plot.title = ("Click: add a vertex; " - "+Click: remove a vertex; \n " - ": finish the selection") + self.plot.title = ( + "Click: add a vertex; " + "+Click: remove a vertex; \n " + ": finish the selection" + ) return def _disableMaskEditing(self): @@ -687,7 +701,7 @@ class AdvHint(HasTraits): compared to their local environment Average mask: Mask the pixels too bright or too dark compared to the average intensity at the similar diffraction angle. -Currect calibration information is required.""" +Correct calibration information is required.""" ) advhint_view = View( diff --git a/src/diffpy/srxplanargui/live.py b/src/diffpy/srxplanargui/live.py index 283b9a8..7372c31 100644 --- a/src/diffpy/srxplanargui/live.py +++ b/src/diffpy/srxplanargui/live.py @@ -16,7 +16,6 @@ import os import sys -from diffpy.srxplanar.srxplanar import SrXplanar from pyface.api import GUI, ImageResource, SplashScreen from traits.api import Any, on_trait_change from traits.etsconfig.api import ETSConfig @@ -32,6 +31,7 @@ ) from traitsui.menu import OKButton +from diffpy.srxplanar.srxplanar import SrXplanar from diffpy.srxplanargui.calibration import Calibration from diffpy.srxplanargui.help import SrXguiHelp from diffpy.srxplanargui.selectfiles import AddFiles diff --git a/src/diffpy/srxplanargui/selectfiles.py b/src/diffpy/srxplanargui/selectfiles.py index 005f364..94ee6ac 100644 --- a/src/diffpy/srxplanargui/selectfiles.py +++ b/src/diffpy/srxplanargui/selectfiles.py @@ -52,7 +52,6 @@ from diffpy.pdfgete.functs import sortKeyNumericString from diffpy.srxplanar.loadimage import openImage, saveImage - from diffpy.srxplanargui.datacontainer import DataContainer from diffpy.srxplanargui.imageplot import ImagePlot from diffpy.srxplanargui.srxconfig import SrXconfig @@ -94,7 +93,7 @@ class AddFiles(HasTraits): srxconfig = Instance(SrXconfig) - # The currenty inputdir directory being searched: + # The currently inputdir directory being searched: # inputdir = DelegatesTo('srxconfig') inputdir = Directory() # , entries = 10 ) diff --git a/src/diffpy/srxplanargui/srxconfig.py b/src/diffpy/srxplanargui/srxconfig.py index b734e44..b9ee4c6 100644 --- a/src/diffpy/srxplanargui/srxconfig.py +++ b/src/diffpy/srxplanargui/srxconfig.py @@ -17,6 +17,11 @@ import os import numpy as np +from pyface.api import ImageResource +from traits.api import Bool, Enum, Property, on_trait_change +from traits.etsconfig.api import ETSConfig +from traitsui.api import Group, Item, View + from diffpy.srxconfutils.configtraits import ConfigBaseTraits from diffpy.srxplanar.srxplanarconfig import ( _description, @@ -24,10 +29,6 @@ _optdatalist, checkMax, ) -from pyface.api import ImageResource -from traits.api import Bool, Enum, Property, on_trait_change -from traits.etsconfig.api import ETSConfig -from traitsui.api import Group, Item, View ETSConfig.toolkit = "qt" @@ -109,7 +110,7 @@ class SrXconfig(ConfigBaseTraits): _optdatalist = _optdatalist - _defaultdata = {"configfile": [], "headertitle": "SrXgui configration"} + _defaultdata = {"configfile": [], "headertitle": "SrXgui configuration"} rotation = Property( depends_on="rotationd", fget=lambda self: np.radians(self.rotationd) diff --git a/src/diffpy/srxplanargui/srxgui.py b/src/diffpy/srxplanargui/srxgui.py index d3e7d21..8f35ec8 100644 --- a/src/diffpy/srxplanargui/srxgui.py +++ b/src/diffpy/srxplanargui/srxgui.py @@ -16,7 +16,6 @@ import os import sys -from diffpy.srxplanar.srxplanar import SrXplanar from pyface.api import ImageResource from traits.api import Any, Button, File, HasTraits, Instance from traits.etsconfig.api import ETSConfig @@ -33,6 +32,7 @@ ) from traitsui.menu import CancelButton, OKButton +from diffpy.srxplanar.srxplanar import SrXplanar from diffpy.srxplanargui.calibration import Calibration from diffpy.srxplanargui.help import SrXguiHelp from diffpy.srxplanargui.selectfiles import AddFiles diff --git a/src/diffpy/srxplanargui/srxplanargui_app.py b/src/diffpy/srxplanargui/srxplanargui_app.py new file mode 100644 index 0000000..5cbd0c3 --- /dev/null +++ b/src/diffpy/srxplanargui/srxplanargui_app.py @@ -0,0 +1,34 @@ +import argparse + +from diffpy.srxplanargui.version import __version__ # noqa + + +def main(): + parser = argparse.ArgumentParser( + prog="diffpy.srxplanargui", + description=( + "xPDFsuite, a software for PDF transformation" + " and visualization.\n\n" + "For more information, visit: " + "https://github.com/diffpy/diffpy.srxplanargui/" + ), + 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.srxplanargui {__version__}") + else: + # Default behavior when no arguments are given + parser.print_help() + + +if __name__ == "__main__": + main() diff --git a/src/diffpy/srxplanargui/version.py b/src/diffpy/srxplanargui/version.py index ffac5d9..699afaa 100644 --- a/src/diffpy/srxplanargui/version.py +++ b/src/diffpy/srxplanargui/version.py @@ -1,28 +1,26 @@ #!/usr/bin/env python ############################################################################## # -# diffpy.srxplanar by DANSE Diffraction group -# Simon J. L. Billinge -# (c) 2010 Trustees of the Columbia University -# in the City of New York. All rights reserved. +# (c) 2025 The Trustees of Columbia University in the City of New York. +# All rights reserved. # -# File coded by: Xiaohao Yang +# File coded by: Rundong Hua, Simon Billinge, Billinge Group members. # -# See AUTHORS.txt for a list of people who contributed. -# See LICENSENOTICE.txt for license information. +# See GitHub contributions for a more detailed list of contributors. +# https://github.com/diffpy/diffpy.srxplanargui/graphs/contributors # noqa: E501 +# +# See LICENSE.rst for license information. # ############################################################################## -"""Definition of __version__ and __date__ for this package.""" - -# obtain version information -from pkg_resources import get_distribution +"""Definition of __version__.""" -_pkgname = __name__.rsplit(".", 1)[0] -__version__ = get_distribution(_pkgname).version +# We do not use the other three variables, but can be added back if needed. +# __all__ = ["__date__", "__git_commit__", "__timestamp__", "__version__"] -# we assume that tag_date was used and __version__ ends in YYYYMMDD -__date__ = ( - __version__[-8:-4] + "-" + __version__[-4:-2] + "-" + __version__[-2:] -) +# obtain version information +from importlib.metadata import PackageNotFoundError, version -# End of file +try: + __version__ = version("diffpy.srxplanargui") +except PackageNotFoundError: + __version__ = "unknown" diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..e3b6313 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,19 @@ +import json +from pathlib import Path + +import pytest + + +@pytest.fixture +def user_filesystem(tmp_path): + base_dir = Path(tmp_path) + home_dir = base_dir / "home_dir" + home_dir.mkdir(parents=True, exist_ok=True) + cwd_dir = base_dir / "cwd_dir" + cwd_dir.mkdir(parents=True, exist_ok=True) + + home_config_data = {"username": "home_username", "email": "home@email.com"} + with open(home_dir / "diffpyconfig.json", "w") as f: + json.dump(home_config_data, f) + + yield tmp_path diff --git a/tests/test_version.py b/tests/test_version.py new file mode 100644 index 0000000..008dab2 --- /dev/null +++ b/tests/test_version.py @@ -0,0 +1,10 @@ +"""Unit tests for __version__.py.""" + +import diffpy.srxplanargui # noqa + + +def test_package_version(): + """Ensure the package version is defined and not set to the initial + placeholder.""" + assert hasattr(diffpy.srxplanargui, "__version__") + assert diffpy.srxplanargui.__version__ != "0.0.0"