From e6c873b0f2d1f802b62be8bc7f121ad960afa8cc Mon Sep 17 00:00:00 2001 From: Matthias Baer Date: Wed, 5 Feb 2025 18:50:50 +0100 Subject: [PATCH 1/5] Issue #17 --- .gitignore | 1 + pyproject.toml | 38 +++++++++ qpimage/_version.py | 197 -------------------------------------------- setup.cfg | 2 - setup.py | 48 ----------- 5 files changed, 39 insertions(+), 247 deletions(-) create mode 100644 pyproject.toml delete mode 100644 qpimage/_version.py delete mode 100644 setup.cfg delete mode 100644 setup.py diff --git a/.gitignore b/.gitignore index dc1b60f..9743844 100644 --- a/.gitignore +++ b/.gitignore @@ -106,3 +106,4 @@ _version_save.py .pytest_cache .idea +_version.py diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..43e3b9a --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,38 @@ +[build-system] +requires = ["setuptools", "wheel", "setuptools_scm"] +build-backend = "setuptools.build_meta" + +[project] +name = "qpimage" +description = "library for manipulating quantitative phase images" +readme = "README.rst" +license = { file = "LICENSE" } +authors = [{ name = "Paul Müller", email = "dev@craban.de" }] +requires-python = ">=3.8, <4" +dependencies = [ + "h5py>=2.7.0", + "lmfit", + "nrefocus[FFTW]>=0.4.3", + "numpy>=1.9.0,<2.0", + "qpretrieve[FFTW]>=0.2.8", + "scikit-image>=0.21.0", + "scipy>=0.18.0" +] +classifiers = [ + "Operating System :: OS Independent", + "Programming Language :: Python :: 3", + "Intended Audience :: Science/Research" +] +dynamic = ["version"] + +[project.urls] +Homepage = "https://github.com/RI-imaging/qpimage" + +[tool.setuptools_scm] +write_to = "qpimage/_version.py" +version_scheme = "post-release" + +[tool.setuptools.packages.find] +where = ["."] +include = ["qpimage"] + diff --git a/qpimage/_version.py b/qpimage/_version.py deleted file mode 100644 index dcae2da..0000000 --- a/qpimage/_version.py +++ /dev/null @@ -1,197 +0,0 @@ -#!/usr/bin/env python -"""Determine package version from git repository tag - -Each time this file is imported it checks whether the package version -can be determined using `git describe`. If this fails (because either -this file is not located at the 1st level down the repository root or -it is not under version control), the version is read from the script -"_version_save.py" which is not versioned by git, but always included -in the final distribution archive (e.g. via PyPI). If the git version -does not match the saved version, then "_version_save.py" is updated. - - -Usage ------ -1. Put this file in your main module directory: - - REPO_ROOT/package_name/_version.py - -2. Add this line to REPO_ROOT/package_name/__init__.py - - from ._version import version as __version__ # noqa: F401 - -3. (Optional) Add this line to REPO_ROOT/.gitignore - - _version_save.py - -Features --------- -- supports Python 2 and 3 -- supports frozen applications (e.g. PyInstaller) -- supports installing into a virtual environment that is located in - a git repository -- saved version is located in a python file and therefore no other - files (e.g. MANIFEST.in) need be edited -- fallback version is the creation date -- excluded from code coverage via "pragma: no cover" - -Changelog ---------- -2019-11-06.2 - - use os.path.split instead of counting os.path.sep (Windows) -2019-11-06 - - remove deprecated imp dependency (replace with parser) - - check whether this file is versioned and its location is correct - - code cleanup and docs update -""" -from __future__ import print_function - -# Put the entire script into a `True` statement and add the hint -# `pragma: no cover` to ignore code coverage here. -if True: # pragma: no cover - import os - from os.path import abspath, basename, dirname, join, split - import subprocess - import sys - import time - import traceback - import warnings - - def git_describe(): - """ - Return a string describing the version returned by the - command `git describe --tags HEAD`. - If it is not possible to determine the correct version, - then an empty string is returned. - """ - # Make sure we are in a directory that belongs to the correct - # repository. - ourdir = dirname(abspath(__file__)) - - def _minimal_ext_cmd(cmd): - # Construct minimal environment - env = {} - for k in ['SYSTEMROOT', 'PATH']: - v = os.environ.get(k) - if v is not None: - env[k] = v - # LANGUAGE is used on win32 - env['LANGUAGE'] = 'C' - env['LANG'] = 'C' - env['LC_ALL'] = 'C' - pop = subprocess.Popen(cmd, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - env=env) - out = pop.communicate()[0] - return out.strip().decode('ascii', errors="ignore") - - # change directory - olddir = abspath(os.curdir) - os.chdir(ourdir) - - # Make sure that we are getting "git describe" from our own - # repository (and not from a repository where we just happen - # to be in the directory tree). - git_revision = "" - try: - # If this file is not under version control, "loc" will - # be empty. - loc = _minimal_ext_cmd(['git', 'ls-files', '--full-name', - __file__]) - # If it is under version control, it should be located - # one hierarchy down from the repository root (either - # __file__ is "docs/conf.py" or "package_name/_version.py". - if len(split(loc)) == 2: - try: - git_revision = _minimal_ext_cmd(['git', 'describe', - '--tags', 'HEAD']) - except OSError: - pass - except OSError: - pass - # Go back to original directory - os.chdir(olddir) - - return git_revision - - def load_version(versionfile): - """load version from version_save.py""" - longversion = "" - try: - with open(versionfile, "r") as fd: - data = fd.readlines() - for line in data: - if line.startswith("longversion"): - longversion = line.split("=")[1].strip().strip("'") - except BaseException: - try: - from ._version_save import longversion - except BaseException: - try: - from _version_save import longversion - except BaseException: - pass - - return longversion - - def write_version(version, versionfile): - """save version to version_save.py""" - data = "#!/usr/bin/env python\n" \ - + "# This file was created automatically\n" \ - + "longversion = '{VERSION}'\n" - try: - with open(versionfile, "w") as fd: - fd.write(data.format(VERSION=version)) - except BaseException: - if not os.path.exists(versionfile): - # Only issue a warning if the file does not exist. - msg = "Could not write package version to {}.".format( - versionfile) - warnings.warn(msg) - - hdir = dirname(abspath(__file__)) - if basename(__file__) == "conf.py" and "name" in locals(): - # This script is executed in conf.py from the docs directory - versionfile = join(join(join(hdir, ".."), - name), # noqa: F821 - "_version_save.py") - else: - # This script is imported as a module - versionfile = join(hdir, "_version_save.py") - - # Determine the accurate version - longversion = "" - - # 1. git describe - try: - # Get the version using `git describe` - longversion = git_describe() - except BaseException: - pass - - # 2. previously created version file - if longversion == "": - # Either this is not a git repository or we are in the - # wrong git repository. - # Get the version from the previously generated `_version_save.py` - longversion = load_version(versionfile) - - # 3. last resort: date - if longversion == "": - print("Could not determine version. Reason:") - print(traceback.format_exc()) - ctime = os.stat(__file__)[8] - longversion = time.strftime("%Y.%m.%d-%H-%M-%S", time.gmtime(ctime)) - print("Using creation time as version: {}".format(longversion)) - - if not hasattr(sys, 'frozen'): - # Save the version to `_version_save.py` to allow distribution using - # `python setup.py sdist`. - # This is only done if the program is not frozen (with e.g. - # pyinstaller), - if longversion != load_version(versionfile): - write_version(longversion, versionfile) - - # PEP 440-conform development version: - version = ".post".join(longversion.split("-")[:2]) diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 0c9e0fc..0000000 --- a/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[metadata] -license_file = LICENSE diff --git a/setup.py b/setup.py deleted file mode 100644 index ba5ee37..0000000 --- a/setup.py +++ /dev/null @@ -1,48 +0,0 @@ -from os.path import dirname, realpath, exists -from setuptools import setup, find_packages -import sys - - -author = u"Paul Müller" -authors = [author] -description = 'library for manipulating quantitative phase images' -name = 'qpimage' -year = "2017" - -sys.path.insert(0, realpath(dirname(__file__)) + "/" + name) -from _version import version # noqa: E402 - -setup( - name=name, - author=author, - author_email='dev@craban.de', - url='https://github.com/RI-imaging/qpimage', - version=version, - packages=find_packages(), - package_dir={name: name}, - license="MIT", - description=description, - long_description=open('README.rst').read() if exists('README.rst') else '', - install_requires=[ - "h5py>=2.7.0", - "lmfit", - "nrefocus[FFTW]>=0.4.3", # Refocus class - "numpy>=1.9.0", - "qpretrieve[FFTW]>=0.2.8", - "scikit-image>=0.21.0", - "scipy>=0.18.0", - ], - python_requires='>=3.8, <4', - keywords=["digital holographic microscopy", - "optics", - "quantitative phase imaging", - "refractive index", - "scattering", - ], - classifiers=[ - 'Operating System :: OS Independent', - 'Programming Language :: Python :: 3', - 'Intended Audience :: Science/Research' - ], - platforms=['ALL'], - ) From ea76ad4361eb5fe109dde19823cf8149b83d000f Mon Sep 17 00:00:00 2001 From: Matthias Baer Date: Wed, 5 Feb 2025 18:56:31 +0100 Subject: [PATCH 2/5] Issue #17, Try to fix actions --- .github/workflows/check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 11d815e..17fde57 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -21,7 +21,7 @@ jobs: - name: Install fftw3 libs (Linux) if: runner.os == 'Linux' run: | - sudo apt-get install -y libfftw3-dev libfftw3-3 + sudo apt-get install -y libfftw3-double3 libfftw3-single3 - name: Install fftw3 libs (macOS) if: runner.os == 'macOS' run: | From ddcfbf4197ddabb4f00f7d90ffcfaf4d6d21c941 Mon Sep 17 00:00:00 2001 From: Matthias Baer Date: Wed, 5 Feb 2025 19:06:51 +0100 Subject: [PATCH 3/5] Issue #17, Try to fix actions --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 43e3b9a..758664d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ dependencies = [ "h5py>=2.7.0", "lmfit", "nrefocus[FFTW]>=0.4.3", - "numpy>=1.9.0,<2.0", + "numpy==1.9.0", "qpretrieve[FFTW]>=0.2.8", "scikit-image>=0.21.0", "scipy>=0.18.0" From e3229b88d0b5e7dca4e09aa5d380a50f7f472456 Mon Sep 17 00:00:00 2001 From: Matthias Baer Date: Wed, 5 Feb 2025 19:09:03 +0100 Subject: [PATCH 4/5] Issue #17, Try to fix actions --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 758664d..5a6b2b9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ dependencies = [ "h5py>=2.7.0", "lmfit", "nrefocus[FFTW]>=0.4.3", - "numpy==1.9.0", + "numpy==1.26.4", "qpretrieve[FFTW]>=0.2.8", "scikit-image>=0.21.0", "scipy>=0.18.0" From 1f483b31c3d1326050e8d780b73022cb89bd6ce9 Mon Sep 17 00:00:00 2001 From: Matthias Baer Date: Wed, 5 Feb 2025 19:19:53 +0100 Subject: [PATCH 5/5] Issue #17 and #18 --- pyproject.toml | 2 +- qpimage/image_data.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 5a6b2b9..f1b5daf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ dependencies = [ "h5py>=2.7.0", "lmfit", "nrefocus[FFTW]>=0.4.3", - "numpy==1.26.4", + "numpy>=2.0", "qpretrieve[FFTW]>=0.2.8", "scikit-image>=0.21.0", "scipy>=0.18.0" diff --git a/qpimage/image_data.py b/qpimage/image_data.py index 87fe03c..dd832cf 100644 --- a/qpimage/image_data.py +++ b/qpimage/image_data.py @@ -365,7 +365,7 @@ def write_image_dataset(group, key, data, h5dtype=None): **kwargs) if group.file.driver != "core": # HDFView 3.1.1 supports visualizing float-arrays as grayscale image - dset.attrs.create('CLASS', np.string_('IMAGE')) - dset.attrs.create('IMAGE_VERSION', np.string_('1.2')) - dset.attrs.create('IMAGE_SUBCLASS', np.string_('IMAGE_GRAYSCALE')) + dset.attrs.create('CLASS', np.bytes_('IMAGE')) + dset.attrs.create('IMAGE_VERSION', np.bytes_('1.2')) + dset.attrs.create('IMAGE_SUBCLASS', np.bytes_('IMAGE_GRAYSCALE')) return dset