From c4b7d23e10bedc48ee60879bfba4bf6f98dc59b5 Mon Sep 17 00:00:00 2001 From: Christopher Polster Date: Sun, 4 Aug 2024 22:21:36 +0200 Subject: [PATCH 1/3] src-layout, pyproject.toml and meson-python build backend All in one commit as these changes are highly interconnected. - Replace setup.py with pyproject.toml. - Moved the falwa package into a src subdirectory to isolate the local development files and make sure that tests are run on the installed package. Necessary due to the out-of-source build behavior of meson. - After the removal of numpy.disutils for Python versions >= 3.12, compilation of the Fortran extensions and packaging is now carried out with meson. - To simplify the handling in meson, the files interpolate_fields_dirinv.f90 and compute_qgpv_dirinv in src/falwa/f90_modules have been renamed with the suffix _direct_inv to match the name of the contained module. The pyproject.toml uses the meson build backend rather than setuptools and numpy.distutils. The setup.py file has been deleted. The automated tests on GitHub have been upgraded to include Python 3.12, which can now be supported, and exclude 3.9. TODO: package deployment instructions in notes/developer need to be adapted. --- .github/workflows/python-build-test.yml | 12 +-- meson.build | 16 ++++ pyproject.toml | 39 +++++++++ setup.py | 85 ------------------- {falwa => src/falwa}/__init__.py | 0 {falwa => src/falwa}/barotropic_field.py | 0 {falwa => src/falwa}/basis.py | 0 {falwa => src/falwa}/constant.py | 0 {falwa => src/falwa}/data_storage.py | 0 .../f90_modules/compute_flux_dirinv.f90 | 0 .../compute_lwa_and_barotropic_fluxes.f90 | 0 .../f90_modules/compute_lwa_only_nhn22.f90 | 0 .../falwa}/f90_modules/compute_qgpv.f90 | 0 .../f90_modules/compute_qgpv_direct_inv.f90 | 0 .../compute_qref_and_fawa_first.f90 | 0 .../f90_modules/compute_reference_states.f90 | 0 .../interpolate_fields_direct_inv.f90 | 0 .../f90_modules/matrix_after_inversion.f90 | 0 .../f90_modules/matrix_b4_inversion.f90 | 0 src/falwa/f90_modules/meson.build | 57 +++++++++++++ .../falwa}/f90_modules/upward_sweep.f90 | 0 {falwa => src/falwa}/legacy/__init__.py | 0 {falwa => src/falwa}/legacy/beta_version.py | 0 {falwa => src/falwa}/netcdf_utils.py | 0 {falwa => src/falwa}/oopinterface.py | 0 {falwa => src/falwa}/plot_utils.py | 0 {falwa => src/falwa}/preprocessing.py | 0 {falwa => src/falwa}/stat_utils.py | 0 {falwa => src/falwa}/utilities.py | 0 {falwa => src/falwa}/wrapper.py | 0 {falwa => src/falwa}/xarrayinterface.py | 0 src/meson.build | 17 ++++ 32 files changed, 133 insertions(+), 93 deletions(-) create mode 100644 meson.build create mode 100644 pyproject.toml delete mode 100644 setup.py rename {falwa => src/falwa}/__init__.py (100%) rename {falwa => src/falwa}/barotropic_field.py (100%) rename {falwa => src/falwa}/basis.py (100%) rename {falwa => src/falwa}/constant.py (100%) rename {falwa => src/falwa}/data_storage.py (100%) rename {falwa => src/falwa}/f90_modules/compute_flux_dirinv.f90 (100%) rename {falwa => src/falwa}/f90_modules/compute_lwa_and_barotropic_fluxes.f90 (100%) rename {falwa => src/falwa}/f90_modules/compute_lwa_only_nhn22.f90 (100%) rename {falwa => src/falwa}/f90_modules/compute_qgpv.f90 (100%) rename falwa/f90_modules/compute_qgpv_dirinv.f90 => src/falwa/f90_modules/compute_qgpv_direct_inv.f90 (100%) rename {falwa => src/falwa}/f90_modules/compute_qref_and_fawa_first.f90 (100%) rename {falwa => src/falwa}/f90_modules/compute_reference_states.f90 (100%) rename falwa/f90_modules/interpolate_fields_dirinv.f90 => src/falwa/f90_modules/interpolate_fields_direct_inv.f90 (100%) rename {falwa => src/falwa}/f90_modules/matrix_after_inversion.f90 (100%) rename {falwa => src/falwa}/f90_modules/matrix_b4_inversion.f90 (100%) create mode 100644 src/falwa/f90_modules/meson.build rename {falwa => src/falwa}/f90_modules/upward_sweep.f90 (100%) rename {falwa => src/falwa}/legacy/__init__.py (100%) rename {falwa => src/falwa}/legacy/beta_version.py (100%) rename {falwa => src/falwa}/netcdf_utils.py (100%) rename {falwa => src/falwa}/oopinterface.py (100%) rename {falwa => src/falwa}/plot_utils.py (100%) rename {falwa => src/falwa}/preprocessing.py (100%) rename {falwa => src/falwa}/stat_utils.py (100%) rename {falwa => src/falwa}/utilities.py (100%) rename {falwa => src/falwa}/wrapper.py (100%) rename {falwa => src/falwa}/xarrayinterface.py (100%) create mode 100644 src/meson.build diff --git a/.github/workflows/python-build-test.yml b/.github/workflows/python-build-test.yml index 431966ca..5209d69b 100644 --- a/.github/workflows/python-build-test.yml +++ b/.github/workflows/python-build-test.yml @@ -16,7 +16,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.9", "3.10", "3.11"] + python-version: ["3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v3 @@ -26,15 +26,11 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | - python -m pip install flake8 pytest + python -m pip install --upgrade pip + python -m pip install flake8 python -m pip install coverage - python -m pip install -U pytest - python -m pip install --upgrade pip setuptools wheel sudo apt-get install gfortran - python -m pip install scipy==1.11.2 - python -m pip install xarray==2024.1.1 - python -m pip install numpy==1.24.4 - python setup.py develop + python -m pip install .[test] - name: Test with pytest run: | coverage run -m pytest -k "not output_results" diff --git a/meson.build b/meson.build new file mode 100644 index 00000000..19fd8be1 --- /dev/null +++ b/meson.build @@ -0,0 +1,16 @@ +project('falwa') + +# Based on: +# - https://numpy.org/doc/stable/f2py/buildtools/meson.html +# - https://meson-python.readthedocs.io/en/stable/how-to-guides/first-project.html +# - https://github.com/jameskermode/f90wrap/blob/master/f90wrap/meson.build + +add_languages('c') +add_languages('fortran') + +# Python configuration +py = import('python').find_installation(pure: false) + +inc_root = include_directories('.') + +subdir('src') diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..8c088b51 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,39 @@ +[build-system] +build-backend = "mesonpy" +requires = ["numpy", "meson-python"] + +[project] +name = "falwa" +authors = [ + { name="Clare S. Y. Huang", email="csyhuang@uchicago.edu" }, + { name="Christopher Polster", email="cpolster@uni-mainz.de" }, +] +description = "python package to compute finite-amplitude local wave activity (Huang and Nakamura 2016, JAS)" +readme = "readme.md" +license = { file="LICENSE.txt" } +version = "1.3.0" +requires-python = ">=3.10" +classifiers = [ + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3", + "Programming Language :: Fortran", + "Intended Audience :: Science/Research", + "Topic :: Scientific/Engineering :: Atmospheric Science", +] +dependencies = [ + "numpy>=1.22", + "scipy", + "xarray" +] + +[project.optional-dependencies] +test = [ + "pytest", + "netcdf4" +] + +[project.urls] +"Documentation" = "https://hn2016-falwa.readthedocs.io/" +"Repository" = "https://github.com/csyhuang/hn2016_falwa" +"Bug Tracker" = "https://github.com/csyhuang/hn2016_falwa/issues" + diff --git a/setup.py b/setup.py deleted file mode 100644 index a663e17f..00000000 --- a/setup.py +++ /dev/null @@ -1,85 +0,0 @@ -from numpy.distutils.core import setup, Extension - -LONG_DESCRIPTION = \ - """ - falwa is a package that contains modules to compute the finite-amplitude - local wave activity (FALWA) and reference state (U_ref) in the following papers: - Huang and Nakamura (2016, JAS): http://dx.doi.org/10.1175/JAS-D-15-0194.1 - Huang and Nakamura (2017, GRL): http://onlinelibrary.wiley.com/doi/10.1002/2017GL073760/full - Nakamura and Huang (2018, Science): https://doi.org/10.1126/science.aat0721 - Neal et al (2022, GRL): https://agupubs.onlinelibrary.wiley.com/doi/full/10.1029/2021GL097699 - - The current version of the library handles calculation of FALWA in a spherical barotropic model and QGPV fields on - isobaric surfaces. - - The functions in this library can compute the tracer equivalent-latitude relationship - proposed in Nakamura (1996) (Also, see Allen and Nakamura (2003)) and the (zonal mean) - finite-amplitude wave activity in spherical geometry as in Nakamura and Solomon (2010). - - Links: - - Source code: http://github.com/csyhuang/hn2016_falwa/ - """ - - -ext1 = Extension(name='falwa.compute_qgpv', - sources=['falwa/f90_modules/compute_qgpv.f90'], - f2py_options=['--quiet']) - -ext2 = Extension(name='falwa.compute_reference_states', - sources=['falwa/f90_modules/compute_reference_states.f90'], - f2py_options=['--quiet']) - -ext3 = Extension(name='falwa.compute_lwa_and_barotropic_fluxes', - sources=['falwa/f90_modules/compute_lwa_and_barotropic_fluxes.f90'], - f2py_options=['--quiet']) - -# *** Extensions 4-9 are used by the direct inversion algorithm *** -ext4 = Extension(name='falwa.compute_qgpv_direct_inv', - sources=['falwa/f90_modules/compute_qgpv_dirinv.f90'], - f2py_options=['--quiet']) - -ext5 = Extension(name='falwa.compute_qref_and_fawa_first', - sources=['falwa/f90_modules/compute_qref_and_fawa_first.f90'], - f2py_options=['--quiet']) - -ext6 = Extension(name='falwa.matrix_b4_inversion', - sources=['falwa/f90_modules/matrix_b4_inversion.f90'], - f2py_options=['--quiet']) - -ext7 = Extension(name='falwa.matrix_after_inversion', - sources=['falwa/f90_modules/matrix_after_inversion.f90'], - f2py_options=['--quiet']) - -ext8 = Extension(name='falwa.upward_sweep', - sources=['falwa/f90_modules/upward_sweep.f90'], - f2py_options=['--quiet']) - -ext9 = Extension(name='falwa.compute_flux_dirinv', - sources=['falwa/f90_modules/compute_flux_dirinv.f90'], - f2py_options=['--quiet']) - -ext10 = Extension(name='falwa.compute_lwa_only_nhn22', - sources=['falwa/f90_modules/compute_lwa_only_nhn22.f90'], - f2py_options=['--quiet']) - -setup( - name='falwa', - version='1.3.0', - description='python package to compute finite-amplitude local wave activity (Huang and Nakamura 2016, JAS)', - long_description=LONG_DESCRIPTION, - long_description_content_type='text/markdown', - url='https://github.com/csyhuang/hn2016_falwa', - author='Clare S. Y. Huang', - author_email='csyhuang@uchicago.edu', - license='MIT', - python_requires='>=3', - packages=['falwa', 'tests', 'falwa.legacy'], - setup_requires=['numpy'], - install_requires=['numpy', 'scipy', 'xarray'], - tests_require=['pytest'], - test_suite="tests", - obsoletes_dist="hn2016_falwa", - ext_modules=[ext1, ext2, ext3, ext4, ext5, ext6, ext7, ext8, ext9, ext10], - zip_safe=False -) - diff --git a/falwa/__init__.py b/src/falwa/__init__.py similarity index 100% rename from falwa/__init__.py rename to src/falwa/__init__.py diff --git a/falwa/barotropic_field.py b/src/falwa/barotropic_field.py similarity index 100% rename from falwa/barotropic_field.py rename to src/falwa/barotropic_field.py diff --git a/falwa/basis.py b/src/falwa/basis.py similarity index 100% rename from falwa/basis.py rename to src/falwa/basis.py diff --git a/falwa/constant.py b/src/falwa/constant.py similarity index 100% rename from falwa/constant.py rename to src/falwa/constant.py diff --git a/falwa/data_storage.py b/src/falwa/data_storage.py similarity index 100% rename from falwa/data_storage.py rename to src/falwa/data_storage.py diff --git a/falwa/f90_modules/compute_flux_dirinv.f90 b/src/falwa/f90_modules/compute_flux_dirinv.f90 similarity index 100% rename from falwa/f90_modules/compute_flux_dirinv.f90 rename to src/falwa/f90_modules/compute_flux_dirinv.f90 diff --git a/falwa/f90_modules/compute_lwa_and_barotropic_fluxes.f90 b/src/falwa/f90_modules/compute_lwa_and_barotropic_fluxes.f90 similarity index 100% rename from falwa/f90_modules/compute_lwa_and_barotropic_fluxes.f90 rename to src/falwa/f90_modules/compute_lwa_and_barotropic_fluxes.f90 diff --git a/falwa/f90_modules/compute_lwa_only_nhn22.f90 b/src/falwa/f90_modules/compute_lwa_only_nhn22.f90 similarity index 100% rename from falwa/f90_modules/compute_lwa_only_nhn22.f90 rename to src/falwa/f90_modules/compute_lwa_only_nhn22.f90 diff --git a/falwa/f90_modules/compute_qgpv.f90 b/src/falwa/f90_modules/compute_qgpv.f90 similarity index 100% rename from falwa/f90_modules/compute_qgpv.f90 rename to src/falwa/f90_modules/compute_qgpv.f90 diff --git a/falwa/f90_modules/compute_qgpv_dirinv.f90 b/src/falwa/f90_modules/compute_qgpv_direct_inv.f90 similarity index 100% rename from falwa/f90_modules/compute_qgpv_dirinv.f90 rename to src/falwa/f90_modules/compute_qgpv_direct_inv.f90 diff --git a/falwa/f90_modules/compute_qref_and_fawa_first.f90 b/src/falwa/f90_modules/compute_qref_and_fawa_first.f90 similarity index 100% rename from falwa/f90_modules/compute_qref_and_fawa_first.f90 rename to src/falwa/f90_modules/compute_qref_and_fawa_first.f90 diff --git a/falwa/f90_modules/compute_reference_states.f90 b/src/falwa/f90_modules/compute_reference_states.f90 similarity index 100% rename from falwa/f90_modules/compute_reference_states.f90 rename to src/falwa/f90_modules/compute_reference_states.f90 diff --git a/falwa/f90_modules/interpolate_fields_dirinv.f90 b/src/falwa/f90_modules/interpolate_fields_direct_inv.f90 similarity index 100% rename from falwa/f90_modules/interpolate_fields_dirinv.f90 rename to src/falwa/f90_modules/interpolate_fields_direct_inv.f90 diff --git a/falwa/f90_modules/matrix_after_inversion.f90 b/src/falwa/f90_modules/matrix_after_inversion.f90 similarity index 100% rename from falwa/f90_modules/matrix_after_inversion.f90 rename to src/falwa/f90_modules/matrix_after_inversion.f90 diff --git a/falwa/f90_modules/matrix_b4_inversion.f90 b/src/falwa/f90_modules/matrix_b4_inversion.f90 similarity index 100% rename from falwa/f90_modules/matrix_b4_inversion.f90 rename to src/falwa/f90_modules/matrix_b4_inversion.f90 diff --git a/src/falwa/f90_modules/meson.build b/src/falwa/f90_modules/meson.build new file mode 100644 index 00000000..184de26e --- /dev/null +++ b/src/falwa/f90_modules/meson.build @@ -0,0 +1,57 @@ +# f2py preparation + +incdir_numpy = run_command( + py, + ['-c', 'import os; os.chdir(".."); import numpy; print(numpy.get_include())'], + check: true +).stdout().strip() + +incdir_f2py = run_command( + py, + ['-c', 'import os; os.chdir(".."); import numpy.f2py; print(numpy.f2py.get_include())'], + check : true +).stdout().strip() + +fortranobject = incdir_f2py / 'fortranobject.c' +inc_np = include_directories(incdir_numpy, incdir_f2py) + + +# Fortran extension modules + +f90_basenames = [ + 'compute_flux_dirinv', + 'compute_lwa_and_barotropic_fluxes', + 'compute_lwa_only_nhn22', + 'compute_qgpv_direct_inv', + 'compute_qgpv', + 'compute_qref_and_fawa_first', + 'compute_reference_states', + 'interpolate_fields_direct_inv', + 'matrix_after_inversion', + 'matrix_b4_inversion', + 'upward_sweep' +] + +foreach basename : f90_basenames + + name_f = files(basename + '.f90') + # Intermediate files generated by f2py + name_c = basename + 'module.c' + name_w = basename + '-f2pywrappers.f' + + f90_source = custom_target( + input: name_f, + output: [name_c, name_w], + command: [py, '-m', 'numpy.f2py', '@INPUT@', '-m', basename, '--build-dir', '@OUTDIR@', '--lower'] + ) + + py.extension_module( + basename, + [name_f, f90_source, fortranobject], + include_directories: [inc_np, inc_root], + dependencies: py.dependency(), + install: true, + subdir: 'falwa' + ) + +endforeach diff --git a/falwa/f90_modules/upward_sweep.f90 b/src/falwa/f90_modules/upward_sweep.f90 similarity index 100% rename from falwa/f90_modules/upward_sweep.f90 rename to src/falwa/f90_modules/upward_sweep.f90 diff --git a/falwa/legacy/__init__.py b/src/falwa/legacy/__init__.py similarity index 100% rename from falwa/legacy/__init__.py rename to src/falwa/legacy/__init__.py diff --git a/falwa/legacy/beta_version.py b/src/falwa/legacy/beta_version.py similarity index 100% rename from falwa/legacy/beta_version.py rename to src/falwa/legacy/beta_version.py diff --git a/falwa/netcdf_utils.py b/src/falwa/netcdf_utils.py similarity index 100% rename from falwa/netcdf_utils.py rename to src/falwa/netcdf_utils.py diff --git a/falwa/oopinterface.py b/src/falwa/oopinterface.py similarity index 100% rename from falwa/oopinterface.py rename to src/falwa/oopinterface.py diff --git a/falwa/plot_utils.py b/src/falwa/plot_utils.py similarity index 100% rename from falwa/plot_utils.py rename to src/falwa/plot_utils.py diff --git a/falwa/preprocessing.py b/src/falwa/preprocessing.py similarity index 100% rename from falwa/preprocessing.py rename to src/falwa/preprocessing.py diff --git a/falwa/stat_utils.py b/src/falwa/stat_utils.py similarity index 100% rename from falwa/stat_utils.py rename to src/falwa/stat_utils.py diff --git a/falwa/utilities.py b/src/falwa/utilities.py similarity index 100% rename from falwa/utilities.py rename to src/falwa/utilities.py diff --git a/falwa/wrapper.py b/src/falwa/wrapper.py similarity index 100% rename from falwa/wrapper.py rename to src/falwa/wrapper.py diff --git a/falwa/xarrayinterface.py b/src/falwa/xarrayinterface.py similarity index 100% rename from falwa/xarrayinterface.py rename to src/falwa/xarrayinterface.py diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 00000000..5eb12c87 --- /dev/null +++ b/src/meson.build @@ -0,0 +1,17 @@ +py.install_sources( + 'falwa/__init__.py', + 'falwa/barotropic_field.py', + 'falwa/basis.py', + 'falwa/constant.py', + 'falwa/data_storage.py', + 'falwa/oopinterface.py', + 'falwa/plot_utils.py', + 'falwa/utilities.py', + 'falwa/wrapper.py', + 'falwa/xarrayinterface.py', + 'falwa/legacy/__init__.py', + 'falwa/legacy/beta_version.py', + preserve_path: true +) + +subdir('falwa/f90_modules') From 137086ed87ca21846d66da7b4a81d5c5271123ae Mon Sep 17 00:00:00 2001 From: Christopher Polster Date: Sun, 4 Aug 2024 23:10:12 +0200 Subject: [PATCH 2/3] Replace numpy.product --- src/falwa/xarrayinterface.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/falwa/xarrayinterface.py b/src/falwa/xarrayinterface.py index b174f61e..968a85b6 100644 --- a/src/falwa/xarrayinterface.py +++ b/src/falwa/xarrayinterface.py @@ -90,7 +90,7 @@ def other_shape(self): @property def other_size(self): """Size of non-core dimensions""" - return np.product(self.other_shape) + return np.prod(self.other_shape) # numpy convenience functions @@ -358,7 +358,7 @@ def __init__(self, da_u, da_v=None, da_t=None, *, var_names=None, # fields. These dimensions are restored in the output datasets. other_dims = da_u.dims[:-3] other_shape = tuple(da_u[dim].size for dim in other_dims) - other_size = np.product(other_shape, dtype=np.int64) + other_size = np.prod(other_shape, dtype=np.int64) _shape = (other_size, *da_u.shape[-3:]) # Extract value arrays and collapse all additional dimensions u = da_u.data.reshape(_shape) From 6295a7d61166717de5addacba8070ba307489e03 Mon Sep 17 00:00:00 2001 From: csyhuang Date: Fri, 16 Aug 2024 15:08:08 -0500 Subject: [PATCH 3/3] update package version to v2.0.0 and fix broken documentation --- docs/source/conf.py | 11 +++---- docs/source/index.rst | 41 +++++++++-------------- environment.yml | 20 ++++++----- notes/developer/pip_deployment.md | 55 ++++++++++++++++++++++++++++++- pyproject.toml | 2 +- readme.md | 44 +++++++++++-------------- src/falwa/__init__.py | 2 +- 7 files changed, 106 insertions(+), 69 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 083e0f00..b3d22d42 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -19,11 +19,8 @@ import os import sys # Need to fix the issue below -sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)) + "/../../") -sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)) + "/../../falwa/") - -# import sphinx_rtd_theme - +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)) + "/../../src/") +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)) + "/../../src/falwa/") autodoc_mock_imports = [ "matplotlib", # for plot_utils.py @@ -79,9 +76,9 @@ # built documents. # # The short X.Y version. -version = u'1.3.0' +version = u'2.0.0' # The full version, including alpha/beta/rc tags. -release = u'1.3.0' +release = u'2.0.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/source/index.rst b/docs/source/index.rst index fc78100d..9ac9d79c 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -19,25 +19,25 @@ extreme weather events. It implements the finite-amplitude local wave activity a Package Installation ------------------------------ -This current version works for Python 3.x. Note that since v0.3.0, some functions have backend in Fortran. To build the package from source, you need a fortran compiler (e.g. `gfortran `_) to implement the installation. +**Attention: substantial changes took place in release v2.0.0. Installation in develop mode is no longer available.** -Since the package is still being actively developed, please use the *develop* mode for installation. +Since release v2.0.0, the F2PY modules in `falwa` is compiled with `meson` (See Issue #95 for details) to cope with the deprecation of `numpy.disutils` in python 3.12. -To install the package for the first time, clone the GitHub repo and install via `develop` mode::: +### First-time installation - git clone https://github.com/csyhuang/hn2016_falwa.git - cd falwa - python setup.py develop +1. To build the package from source, you need a fortran compiler (e.g., [gfortran](http://hpc.sourceforge.net/)) to implement the installation. +2. Clone the package repo by `git clone https://github.com/csyhuang/hn2016_falwa.git` . +3. Navigate into the repository and set up a python environment satisfying the installation requirement by `conda env create -f environment.yml`. The environment name in the file is set to be `falwa_env` (which users can change). +4. Install the package with the command `python -m pip install .` +5. If the installation is successful, you should be able to run through all unit tests in the folder `tests/` by executing `pytest tests/`. +### Get updated code from new releases -To incorporate updates, pull the new version of the code from GitHub. Remove any existing f2py modules and recompile.:: - - # Assume you are already in the falwa/ repo - git pull - rm falwa/*.so - python setup.py develop - pytest tests/ # to check if the package can be run properly - +1. To incorporate updates, first, pull the new version of the code from GitHub by `git pull`. +2. Uninstall existing version of `falwa`: `pip uninstall falwa` +3. If there is change in `environment.yml`, remove the existing environment by `conda remove --name falwa_env --all` and create the environment again from the updated YML file: `conda env create -f environment.yml`. +4. Reinstall the updated version by `python -m pip install .`. +5. Run through all unit tests in the folder `tests/` by executing `pytest tests/` to make sure the package has been properly installed. Quick start ----------------------------------------- @@ -51,21 +51,12 @@ Depending on what you want to do, the methods to be use may be different. 2. If you want to compute zonal wind reference states and wave activity fluxes in QG Formalism, look at `notebooks/nh2018_science/demo_script_for_nh2018.ipynb` for the usage of `QGField`. This notebook demonstrates how to compute wave activity and reference states presented in Nakamura and Huang (2018). To make sure the package is properly installed in your environment, run through the notebook after installation to see if there is error. -THe conda environment for running the notebook can be found in `environment.yml`. To create the conda environment, execute::: - - conda env create -f environment.yml - - - - Issues Reporting ------------------------------ -- If you are interested in using the package, please leave your contact `here `_ or email me(csyhuang@uchicago.edu) such that I can keep you updated of any changes made. - +- If you are interested in getting email message related to update of this package, please leave your contact `here `_ such that I can keep you updated of any changes made. - If you encounter *coding issues/bugs* when using the package, please create an `Issue ticket `_. - -- If you have scientific questions, please contact Clare S. Y. Huang via email(csyhuang@uchicago.edu). +- If you have scientific questions, please create a thread in the `Discussion Board `_ with the category "General" or "Q&A" according to the circumstance. Modules ======== diff --git a/environment.yml b/environment.yml index 439fef3d..f1dcd27f 100644 --- a/environment.yml +++ b/environment.yml @@ -5,16 +5,18 @@ channels: - defaults dependencies: -- python=3.10 -- numpy=1.22.3 -- scipy=1.9 +- python=3.12 +- numpy=1.26.4 +- scipy=1.14.0 +- netCDF4=1.6.5 +- cftime=1.6.2 +- xarray=2024.1.1 - pytest=7.4.0 -- xarray=2023.2.0 -- netCDF4=1.5.8 -- gridfill +- matplotlib=3.8.2 +- cartopy=0.22.0 - jupyter -- matplotlib -- twine -- cartopy +- pip +# - twine +# - gridfill # Other useful packages to visualize plots in notebooks # - cartopy \ No newline at end of file diff --git a/notes/developer/pip_deployment.md b/notes/developer/pip_deployment.md index 567c8691..3a628242 100644 --- a/notes/developer/pip_deployment.md +++ b/notes/developer/pip_deployment.md @@ -15,5 +15,58 @@ Deploy the package onto PyPI for real: ``` python3 -m twine upload dist/* ``` +# Update of deployment after using pyproject.toml - \ No newline at end of file +``` +pip install build +python -m build . --sdist +python3 -m pip install --upgrade twine +python3 -m twine upload --repository testpypi dist/* +``` + + + +```error +clare@otc:~/isolated_test/hn2016_falwa$ python3 -m pip install --index-url https://test.pypi.org/simple/ --no-deps falwa +Looking in indexes: https://test.pypi.org/simple/ +Collecting falwa + Downloading https://test-files.pythonhosted.org/packages/b1/0c/00cd0cd844c7d5c2faed03b3a1051de15e42afabe128783c1b9eb8239651/falwa-1.4.0a0.tar.gz (46.5 MB) + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 46.5/46.5 MB 625.8 kB/s eta 0:00:00 + Installing build dependencies ... error + error: subprocess-exited-with-error + + × pip subprocess to install build dependencies did not run successfully. + │ exit code: 1 + ╰─> [13 lines of output] + Looking in indexes: https://test.pypi.org/simple/ + Collecting numpy + Downloading https://test-files.pythonhosted.org/packages/d5/80/b947c574d9732e39db59203f9aa35cb4d9a5dd8a0ea2328acb89cf10d6e3/numpy-1.9.3.zip (4.5 MB) + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.5/4.5 MB 714.2 kB/s eta 0:00:00 + Preparing metadata (setup.py): started + Preparing metadata (setup.py): finished with status 'done' + Collecting meson-python + Downloading https://test-files.pythonhosted.org/packages/c9/b6/9665154ee9926317a248e2b171ea21ac2b77788adea404566eec29b84f3b/meson_python-0.13.0-py3-none-any.whl.metadata (4.1 kB) + Collecting meson>=0.63.3 (from meson-python) + Downloading https://test-files.pythonhosted.org/packages/ae/c6/e3c2fa2fc539ca99679f02b05700b56c76ffb9338c1dd62f1c64391828ba/meson-1.1.991-py3-none-any.whl.metadata (1.8 kB) + INFO: pip is looking at multiple versions of meson-python to determine which version is compatible with other requirements. This could take a while. + ERROR: Could not find a version that satisfies the requirement pyproject-metadata>=0.7.1 (from meson-python) (from versions: none) + ERROR: No matching distribution found for pyproject-metadata>=0.7.1 + [end of output] + + note: This error originates from a subprocess, and is likely not a problem with pip. +error: subprocess-exited-with-error + +× pip subprocess to install build dependencies did not run successfully. +│ exit code: 1 +╰─> See above for output. + +note: This error originates from a subprocess, and is likely not a problem with pip. +``` + +Successfully installed from `.tar.gz`: + +```bash +conda install anaconda::pip +python3 -m pip install falwa-1.4.0a0.tar.gz +pytest tests/ +``` \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 8c088b51..da9f168d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ authors = [ description = "python package to compute finite-amplitude local wave activity (Huang and Nakamura 2016, JAS)" readme = "readme.md" license = { file="LICENSE.txt" } -version = "1.3.0" +version = "2.0.0" requires-python = ">=3.10" classifiers = [ "License :: OSI Approved :: MIT License", diff --git a/readme.md b/readme.md index 193cebdc..020a8982 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,4 @@ -## Python Library: falwa (v1.3.0) +## Python Library: falwa (v2.0.0) [![Python package](https://github.com/csyhuang/hn2016_falwa/actions/workflows/python-build-test.yml/badge.svg)](https://github.com/csyhuang/hn2016_falwa/actions/workflows/python-build-test.yml)[![codecov.io](https://codecov.io/gh/csyhuang/hn2016_falwa/branch/master/graph/badge.svg)](https://codecov.io/gh/csyhuang/hn2016_falwa)[![Documentation Status](https://readthedocs.org/projects/hn2016-falwa/badge/?version=latest)](http://hn2016-falwa.readthedocs.io/en/latest/?badge=latest)[![DOI](https://zenodo.org/badge/63908662.svg)](https://zenodo.org/badge/latestdoi/63908662) @@ -15,25 +15,25 @@ Compute from gridded climate data the Finite-amplitude Local Wave Activity (FALW ## Package Installation -This current version works for Python 3.x. Note that since v0.3.0, some functions have backend in Fortran. To build the package from source, you need a fortran compiler (e.g. [gfortran](http://hpc.sourceforge.net/)) to implement the installation. +**Attention: substantial changes took place in release v2.0.0. Installation in develop mode is no longer available.** -Since the package is still being actively developed, please use the *develop* mode for installation. +Since release v2.0.0, the F2PY modules in `falwa` is compiled with `meson` (See Issue #95 for details) to cope with the deprecation of `numpy.disutils` in python 3.12. -To install the package for the first time, clone the GitHub repo and install via `develop` mode: -``` -git clone https://github.com/csyhuang/hn2016_falwa.git -cd hn2016_falwa -python setup.py develop -``` +### First-time installation -To incorporate updates, pull the new version of the code from GitHub. Remove any existing f2py modules and recompile. -``` -# Assume you are already in the hn2016_falwa/ repo -git pull -rm falwa/*.so -python setup.py develop -pytest tests/ # to check if the package can be run properly -``` +1. To build the package from source, you need a fortran compiler (e.g., [gfortran](http://hpc.sourceforge.net/)) to implement the installation. +2. Clone the package repo by `git clone https://github.com/csyhuang/hn2016_falwa.git` . +3. Navigate into the repository and set up a python environment satisfying the installation requirement by `conda env create -f environment.yml`. The environment name in the file is set to be `falwa_env` (which users can change). +4. Install the package with the command `python -m pip install .` +5. If the installation is successful, you should be able to run through all unit tests in the folder `tests/` by executing `pytest tests/`. + +### Get updated code from new releases + +1. To incorporate updates, first, pull the new version of the code from GitHub by `git pull`. +2. Uninstall existing version of `falwa`: `pip uninstall falwa` +3. If there is change in `environment.yml`, remove the existing environment by `conda remove --name falwa_env --all` and create the environment again from the updated YML file: `conda env create -f environment.yml`. +4. Reinstall the updated version by `python -m pip install .`. +5. Run through all unit tests in the folder `tests/` by executing `pytest tests/` to make sure the package has been properly installed. ## Quick start @@ -46,14 +46,8 @@ Depending on what you want to do, the methods to be use may be different. 2. If you want to compute zonal wind reference states and wave activity fluxes in QG Formalism, look at `notebooks/nh2018_science/demo_script_for_nh2018.ipynb` for the usage of `QGField`. This notebook demonstrates how to compute wave activity and reference states presented in Nakamura and Huang (2018). To make sure the package is properly installed in your environment, run through the notebook after installation to see if there is error. -THe conda environment for running the notebook can be found in `environment.yml`. To create the conda environment, execute: - -```bash -conda env create -f environment.yml -``` - ## Inquiries / Issues reporting -- If you are interested in using the package, please leave your contact [here](https://goo.gl/forms/5L8fv0mUordugq6v2) or email me(csyhuang@uchicago.edu) such that I can keep you updated of any changes made. +- If you are interested in getting email message related to update of this package, please leave your contact [here](https://goo.gl/forms/5L8fv0mUordugq6v2) such that I can keep you updated of any changes made. - If you encounter *coding issues/bugs* when using the package, please create an [Issue ticket](https://github.com/csyhuang/hn2016_falwa/issues). -- If you have scientific questions, please contact Clare S. Y. Huang via email(csyhuang@uchicago.edu). +- If you have scientific questions, please create a thread in the [Discussion Board](https://github.com/csyhuang/hn2016_falwa/discussions) with the category "General" or "Q&A" according to the circumstance. diff --git a/src/falwa/__init__.py b/src/falwa/__init__.py index 14ad30df..f6d7bccb 100644 --- a/src/falwa/__init__.py +++ b/src/falwa/__init__.py @@ -4,7 +4,7 @@ Author: Clare Huang, Christopher Polster """ -__version__ = "1.3.0" +__version__ = "2.0.0" from .compute_qgpv import compute_qgpv from .compute_qgpv_direct_inv import compute_qgpv_direct_inv from .compute_qref_and_fawa_first import compute_qref_and_fawa_first