From b3a01fea77d381718de42b635eebe400a87560fd Mon Sep 17 00:00:00 2001 From: jwhite Date: Wed, 20 Nov 2024 10:53:05 +0800 Subject: [PATCH 01/21] added realization explorer notebook --- ...standing_variograms_and_realizations.ipynb | 172 ++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 examples/understanding_variograms_and_realizations.ipynb diff --git a/examples/understanding_variograms_and_realizations.ipynb b/examples/understanding_variograms_and_realizations.ipynb new file mode 100644 index 0000000..c4f05c9 --- /dev/null +++ b/examples/understanding_variograms_and_realizations.ipynb @@ -0,0 +1,172 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "90d365d6-ad4e-4109-954c-4b1cb46f733d", + "metadata": {}, + "source": [ + "# A very simple demo to explain how the variogram effects stochastic realizations" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "78a88aba-80be-48d1-b2eb-48bd6d67551f", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import sys\n", + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "from ipywidgets import interact\n", + "sys.path.append(\"..\")\n", + "from pypestutils.pestutilslib import PestUtilsLib\n", + "lib = PestUtilsLib(logger_level=0)" + ] + }, + { + "cell_type": "markdown", + "id": "da9d0eee-ebfe-44f8-b230-e2df7ac8fc1e", + "metadata": {}, + "source": [ + "Just some definitions. We will use a 100 X 100 grid of nodes with an area of 1." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0a7ec106-37ef-42f2-a9d9-5d0cea29080b", + "metadata": {}, + "outputs": [], + "source": [ + "nrow = ncol = 100\n", + "x = np.cumsum(np.ones((nrow,ncol)),axis=1)\n", + "y = np.cumsum(np.ones((nrow,ncol)),axis=0)\n", + "area = 1\n", + "active = 1\n", + "mean = 1 #log10 HK mean\n", + "var = 0.1 #log10 HK variance\n", + "ec = x.flatten()\n", + "nc = y.flatten()\n", + "transtype = 0\n", + "vtype = 1\n", + "power = 0\n", + "nreal = 1" + ] + }, + { + "cell_type": "markdown", + "id": "d2dca882-8b41-4827-b27f-87c5138a0608", + "metadata": {}, + "source": [ + "This is the function that will generate one realization and plot it for us, given a correlation length (`aa`), an anisotropy ratio (`anis`), and a `bearing`) " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "615acaee-212d-4a08-b3ef-1c690b795307", + "metadata": {}, + "outputs": [], + "source": [ + "def plot_real(aa,anis,bearing):\n", + " lib.initialize_randgen(1123455)\n", + " arrs = lib.fieldgen2d_sva(ec,nc,area,int(active),mean,var,aa,anis,bearing,transtype,vtype,power,nreal)\n", + " fig, axes = plt.subplots(1,1,figsize=(6,5))\n", + " cb = axes.imshow(arrs[:,0].reshape((nrow,ncol)))#,vmin=-4,vmax=4,cmap=\"magma\")\n", + " plt.colorbar(cb,ax=axes,label=\"$log_{10}$ HK\")\n", + " axes.set_xticks([])\n", + " axes.set_yticks([])\n", + " axes.set_title(\"a random realization of HK\",loc=\"left\")\n", + " #axes[1].imshow(arrs[:,1].reshape((nrow,ncol)))\n", + " plt.show()\n", + " \n", + " " + ] + }, + { + "cell_type": "markdown", + "id": "cb1483d1-e062-4567-bd85-715e20f382f9", + "metadata": {}, + "source": [ + "Move these slowly so it doesnt flicker..." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ffdee08f-9202-42e0-b503-fc135c099337", + "metadata": {}, + "outputs": [], + "source": [ + "_ = interact(plot_real,aa=(1,50,1),anis=(1,10,0.5),bearing=(0,90,1))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dfb9eade-f0b0-43ac-9213-6978f95d0e72", + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 7aee043e1e8a9a8d93ebc186466ac72cc683bad8 Mon Sep 17 00:00:00 2001 From: jwhite Date: Wed, 20 Nov 2024 12:58:06 +0800 Subject: [PATCH 02/21] ldflags for meson-armmac problems --- scripts/build_lib.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/build_lib.sh b/scripts/build_lib.sh index 60e4fab..b845633 100755 --- a/scripts/build_lib.sh +++ b/scripts/build_lib.sh @@ -4,6 +4,8 @@ set -e # always run from top of repo cd $(dirname $0)/.. +export LDFLAGS="$LDFLAGS -Wl,-ld_classic" + # this needs bash case "$OSTYPE" in darwin*) libname=lib/libpestutils.dylib ;; From e73c264ed8f4f43bdf97c1fd57c45aaabe4017a4 Mon Sep 17 00:00:00 2001 From: jwhite Date: Wed, 20 Nov 2024 15:24:41 +0800 Subject: [PATCH 03/21] realization notebook --- examples/understanding_variograms_and_realizations.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/understanding_variograms_and_realizations.ipynb b/examples/understanding_variograms_and_realizations.ipynb index c4f05c9..3bf969c 100644 --- a/examples/understanding_variograms_and_realizations.ipynb +++ b/examples/understanding_variograms_and_realizations.ipynb @@ -75,7 +75,7 @@ " lib.initialize_randgen(1123455)\n", " arrs = lib.fieldgen2d_sva(ec,nc,area,int(active),mean,var,aa,anis,bearing,transtype,vtype,power,nreal)\n", " fig, axes = plt.subplots(1,1,figsize=(6,5))\n", - " cb = axes.imshow(arrs[:,0].reshape((nrow,ncol)))#,vmin=-4,vmax=4,cmap=\"magma\")\n", + " cb = axes.imshow(arrs[:,0].reshape((nrow,ncol)),vmin=0.0,vmax=2,cmap=\"magma\")\n", " plt.colorbar(cb,ax=axes,label=\"$log_{10}$ HK\")\n", " axes.set_xticks([])\n", " axes.set_yticks([])\n", From db86bba1512bd2ab92c7091bf413463692d62225 Mon Sep 17 00:00:00 2001 From: jwhite Date: Wed, 20 Nov 2024 15:37:19 +0800 Subject: [PATCH 04/21] fix --- scripts/build_lib.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/build_lib.sh b/scripts/build_lib.sh index b845633..5a67faf 100755 --- a/scripts/build_lib.sh +++ b/scripts/build_lib.sh @@ -4,11 +4,11 @@ set -e # always run from top of repo cd $(dirname $0)/.. -export LDFLAGS="$LDFLAGS -Wl,-ld_classic" + # this needs bash case "$OSTYPE" in - darwin*) libname=lib/libpestutils.dylib ;; + darwin*) libname=lib/libpestutils.dylib && export LDFLAGS="$LDFLAGS -Wl,-ld_classic";; linux*) libname=lib/libpestutils.so ;; msys* ) libname=bin/pestutils.dll ;; *) echo "unknown \$OSTYPE: $OSTYPE" && exit 1 ;; From 6b950959791d5c13098ddbe7721b72463045b2fc Mon Sep 17 00:00:00 2001 From: jwhite Date: Sun, 24 Nov 2024 20:47:24 +0800 Subject: [PATCH 05/21] more words on the variogram notebook --- ...standing_variograms_and_realizations.ipynb | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/examples/understanding_variograms_and_realizations.ipynb b/examples/understanding_variograms_and_realizations.ipynb index 3bf969c..236b321 100644 --- a/examples/understanding_variograms_and_realizations.ipynb +++ b/examples/understanding_variograms_and_realizations.ipynb @@ -5,7 +5,9 @@ "id": "90d365d6-ad4e-4109-954c-4b1cb46f733d", "metadata": {}, "source": [ - "# A very simple demo to explain how the variogram effects stochastic realizations" + "# A very simple demo to explain how the variogram effects stochastic realizations\n", + "\n", + "In this simple notebook, we exploit the speed of `PyPestUtils` to help build understanding of how the variogram parameters effect the resulting stochastic field" ] }, { @@ -31,7 +33,7 @@ "id": "da9d0eee-ebfe-44f8-b230-e2df7ac8fc1e", "metadata": {}, "source": [ - "Just some definitions. We will use a 100 X 100 grid of nodes with an area of 1." + "Just some definitions. We will use a 100 X 100 grid of nodes with delx/dely (and an area) of 1." ] }, { @@ -50,8 +52,8 @@ "var = 0.1 #log10 HK variance\n", "ec = x.flatten()\n", "nc = y.flatten()\n", - "transtype = 0\n", - "vtype = 1\n", + "transtype = 0 #not log transformed\n", + "vtype = 1 #exponential variogram\n", "power = 0\n", "nreal = 1" ] @@ -71,16 +73,21 @@ "metadata": {}, "outputs": [], "source": [ - "def plot_real(aa,anis,bearing):\n", + "\n", + "def plot_real(corrlen,anisotropy,bearing):\n", + " fig, axes = plt.subplots(1,1,figsize=(7,6))\n", + " #axes.clear()\n", + " #reset the random seed so that the underlying pseudo random numbers dont change\n", " lib.initialize_randgen(1123455)\n", - " arrs = lib.fieldgen2d_sva(ec,nc,area,int(active),mean,var,aa,anis,bearing,transtype,vtype,power,nreal)\n", - " fig, axes = plt.subplots(1,1,figsize=(6,5))\n", + " # generate one realization\n", + " arrs = lib.fieldgen2d_sva(ec,nc,area,int(active),mean,var,corrlen,anisotropy,bearing,transtype,vtype,power,nreal)\n", + " # plot\n", + " \n", " cb = axes.imshow(arrs[:,0].reshape((nrow,ncol)),vmin=0.0,vmax=2,cmap=\"magma\")\n", - " plt.colorbar(cb,ax=axes,label=\"$log_{10}$ HK\")\n", - " axes.set_xticks([])\n", - " axes.set_yticks([])\n", + " #$plt.colorbar(cb,ax=axes,label=\"$log_{10}$ HK\")\n", + " axes.set_xlabel(\"column\")\n", + " axes.set_ylabel(\"row\")\n", " axes.set_title(\"a random realization of HK\",loc=\"left\")\n", - " #axes[1].imshow(arrs[:,1].reshape((nrow,ncol)))\n", " plt.show()\n", " \n", " " @@ -91,7 +98,11 @@ "id": "cb1483d1-e062-4567-bd85-715e20f382f9", "metadata": {}, "source": [ - "Move these slowly so it doesnt flicker..." + "Move these slowly so it doesnt flicker...\n", + "\n", + " - corrlen = the correlation length of the variogram\n", + " - anisotropy = the anisotropy ratio of the primary to second axes of the anisotropy ellipse\n", + " - bearing = the angle from north of the primary axis of the anisotropy ellipse" ] }, { @@ -101,7 +112,7 @@ "metadata": {}, "outputs": [], "source": [ - "_ = interact(plot_real,aa=(1,50,1),anis=(1,10,0.5),bearing=(0,90,1))" + "_ = interact(plot_real,corrlen=(1,50,1),anisotropy=(1,10,0.5),bearing=(0,90,1))" ] }, { From f7b749ce64c001319065e42663551f1f619e4df8 Mon Sep 17 00:00:00 2001 From: jwhite Date: Tue, 10 Dec 2024 08:11:11 -0500 Subject: [PATCH 06/21] added hyper par explore to variogram notebook - yikes --- ...standing_variograms_and_realizations.ipynb | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) diff --git a/examples/understanding_variograms_and_realizations.ipynb b/examples/understanding_variograms_and_realizations.ipynb index 236b321..73227dc 100644 --- a/examples/understanding_variograms_and_realizations.ipynb +++ b/examples/understanding_variograms_and_realizations.ipynb @@ -171,6 +171,127 @@ "\n", "\n" ] + }, + { + "cell_type": "markdown", + "id": "eba1e58f-48fa-4b48-b268-f3da3d484cf8", + "metadata": {}, + "source": [ + "# These go to 11...\n", + "\n", + "Now let's explore what happens when we introduce hyper parameteres on the property variogram. In essense, we are now going to treat the bearing, anisotropy, and correlation length of the above variogram as themselves being described by variograms - wat?! Its like geostatistical inception..." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "066d8f57-6c0c-4d1f-8112-baff57fc7c9c", + "metadata": {}, + "outputs": [], + "source": [ + "nrow = 80\n", + "ncol = 50\n", + "x = np.cumsum(np.ones((nrow,ncol)),axis=1)\n", + "y = np.cumsum(np.ones((nrow,ncol)),axis=0)\n", + "area = 1\n", + "active = 1\n", + "mean = 1 #log10 HK mean\n", + "var = 0.1 #log10 HK variance\n", + "ec = x.flatten()\n", + "nc = y.flatten()\n", + "transtype = 0 #not log transformed\n", + "vtype = 1 #exponential variogram\n", + "power = 0\n", + "nreal = 1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4efe47ec-95d4-4644-893b-f240c6385e9a", + "metadata": {}, + "outputs": [], + "source": [ + "def plot_real(b_mean, b_var,b_corrlen,b_anisotropy,b_bearing,\n", + " a_mean, a_var, a_corrlen,a_anisotropy,a_bearing,\n", + " c_mean, c_var, c_corrlen,c_anisotropy,c_bearing ):\n", + " fig, axes = plt.subplots(1,4,figsize=(10,3))\n", + " #axes.clear()\n", + " #reset the random seed so that the underlying pseudo random numbers dont change\n", + " lib.initialize_randgen(1123455)\n", + " # generate one realization\n", + " barr = lib.fieldgen2d_sva(ec,nc,area,int(active),b_mean,b_var,b_corrlen,b_anisotropy,b_bearing,transtype,vtype,power,nreal)\n", + " \n", + " cb = axes[0].imshow(barr[:,0].reshape((nrow,ncol)),cmap=\"magma\")\n", + " plt.colorbar(cb,ax=axes[0])\n", + " axes[0].set_title(\"bearing\")\n", + " \n", + " aarr = lib.fieldgen2d_sva(ec,nc,area,int(active),a_mean,a_var,a_corrlen,a_anisotropy,a_bearing,transtype,vtype,power,nreal)\n", + " \n", + " cb = axes[1].imshow(aarr[:,0].reshape((nrow,ncol)),cmap=\"magma\")\n", + " axes[1].set_title(\"aniso\")\n", + " plt.colorbar(cb,ax=axes[1])\n", + " \n", + " carr = lib.fieldgen2d_sva(ec,nc,area,int(active),c_mean,c_var,c_corrlen,c_anisotropy,c_bearing,transtype,vtype,power,nreal)\n", + " \n", + " cb = axes[2].imshow(carr[:,0].reshape((nrow,ncol)),cmap=\"magma\")\n", + " axes[2].set_title(\"corrlen\")\n", + " plt.colorbar(cb,ax=axes[2])\n", + " \n", + " arrs = lib.fieldgen2d_sva(ec,nc,area,int(active),mean,var,carr[:,0],aarr[:,0],barr[:,0],transtype,vtype,power,nreal)\n", + " # plot\n", + " \n", + " cb = axes[3].imshow(arrs[:,0].reshape((nrow,ncol)),vmin=0.0,vmax=2,cmap=\"magma\")\n", + " axes[3].set_title(\"HK\")\n", + " plt.colorbar(cb,ax=axes[3])\n", + " #$plt.colorbar(cb,ax=axes,label=\"$log_{10}$ HK\")\n", + " for ax in axes:\n", + " #ax.set_xlabel(\"column\")\n", + " #ax.set_ylabel(\"row\")\n", + " #ax.set_title(\"a random realization of HK\",loc=\"left\")\n", + " ax.set_xticks([])\n", + " ax.set_yticks([])\n", + " \n", + " plt.show()\n", + " \n", + " " + ] + }, + { + "cell_type": "markdown", + "id": "77c2cc90-803f-4c6d-b857-045ce0788676", + "metadata": {}, + "source": [ + "The 'b_' prefix is the for bearing variogram, 'a_' is the anisotropy variogram, and, you guessed it, 'c_' is for the correlation length variogram...This is complex stuff, but we found that these sliders really helped us start to build some intution regarding how these hyper parameters interact...." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2c844dc6-c255-4361-addd-c8ef8e0796de", + "metadata": {}, + "outputs": [], + "source": [ + "_ = interact(plot_real,b_mean=(0,90,1), b_var=(0.1,50,1),b_corrlen=(1,100,10),b_anisotropy=(1,10,0.5),b_bearing=(0,90,1),\n", + " a_mean=(1,10,1), a_var=(0.1,10.0,0.1),a_corrlen=(10,500,10),a_anisotropy=(1,10,0.5),a_bearing=(0,90,1),\n", + " c_mean=(1,50,1), c_var=(0.1,50.0,0.1),c_corrlen=(1,1000,10),c_anisotropy=(1,50,1),c_bearing=(0,90,1),)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9d33a4ee-4706-402c-a65b-5d833da48ebb", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d85e0325-afb4-4aa1-a08c-5643017e6513", + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { From 893eb1d7c7975cb18d48a08de0dbd966a560eae9 Mon Sep 17 00:00:00 2001 From: Katie <84793890+kmarkovich@users.noreply.github.com> Date: Mon, 20 Jan 2025 16:11:22 -0700 Subject: [PATCH 07/21] Update manual build with meson steps --- BUILD.md | 1 + 1 file changed, 1 insertion(+) diff --git a/BUILD.md b/BUILD.md index 7c1fe1d..39a2473 100644 --- a/BUILD.md +++ b/BUILD.md @@ -26,6 +26,7 @@ Or manually with these steps: ```bash meson setup builddir # options meson compile -C builddir +meson install -C builddir ``` After it is compiled, install to the Python module using: From 163d82202bfda5643cf18c5a08e0c32edff359fd Mon Sep 17 00:00:00 2001 From: Mike Taves Date: Wed, 12 Feb 2025 14:02:13 +1300 Subject: [PATCH 08/21] Release 0.3.0 (#47) --- CHANGELOG.md | 17 ++++++++++++++++- pypestutils/version.py | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44d65e2..1a874be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,21 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## [Unreleased] +### Added +### Changed +### Fixed +## [0.3.0] - 2025-02-12 +### Changed +- Set minimum Python 3.9 (#36) +- Updated cibuildwheel workflow, build macos arm64 wheels from GHA (#30, #32) +- Fix finder.load() for conda and LD path search +- Fix typos (#37) +- Use ruff format, apply ruff check rules, add pre-commit (#38, #45) + +### Fixed +- Fix in `mod2obs_mf6` with different depvar names (#33) ## [0.2.1] - 2024-01-23 ### Fixed @@ -28,6 +41,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Initial pre-alpha release +[Unreleased]: https://github.com/pypest/pypestutils/compare/v0.3.0...develop +[0.3.0]: https://github.com/pypest/pypestutils/compare/v0.2.1...v0.3.0 [0.2.1]: https://github.com/pypest/pypestutils/compare/v0.2.0...v0.2.1 [0.2.0]: https://github.com/pypest/pypestutils/compare/v0.1.0...v0.2.0 [0.1.0]: https://github.com/pypest/pypestutils/releases/tag/v0.1.0 diff --git a/pypestutils/version.py b/pypestutils/version.py index 3d9eff8..d1ceb79 100644 --- a/pypestutils/version.py +++ b/pypestutils/version.py @@ -1,4 +1,4 @@ """Package version.""" # This is the only place to update version -__version__ = "0.2.1.dev0" +__version__ = "0.3.0" From 72d38991638e8465d777120ccee686a8d111cf18 Mon Sep 17 00:00:00 2001 From: Mike Taves Date: Wed, 12 Feb 2025 20:40:58 +1300 Subject: [PATCH 09/21] Post-release 0.3.0 --- pypestutils/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pypestutils/version.py b/pypestutils/version.py index d1ceb79..7ee132c 100644 --- a/pypestutils/version.py +++ b/pypestutils/version.py @@ -1,4 +1,4 @@ """Package version.""" # This is the only place to update version -__version__ = "0.3.0" +__version__ = "0.3.1.dev0" From fce124ef32e58bfca4e837d013214562924c79fd Mon Sep 17 00:00:00 2001 From: Mike Taves Date: Mon, 24 Mar 2025 15:33:36 +1300 Subject: [PATCH 10/21] BLD/CI: fix build, assuming OSTYPE may also be 'cygwin' (#48) --- .github/workflows/release.yml | 2 +- .github/workflows/tests.yml | 2 +- scripts/build_lib.sh | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0ce00f0..2eae1af 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -55,7 +55,7 @@ jobs: if: runner.os == 'Windows' uses: msys2/setup-msys2@v2 with: - msystem: MINGW64 + msystem: mingw64 path-type: inherit install: >- mingw-w64-x86_64-gcc-fortran diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index fd211b7..bc5aabf 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -29,7 +29,7 @@ jobs: if: runner.os == 'Windows' uses: msys2/setup-msys2@v2 with: - msystem: MINGW64 + msystem: mingw64 path-type: inherit install: >- mingw-w64-x86_64-gcc-fortran diff --git a/scripts/build_lib.sh b/scripts/build_lib.sh index d364245..38bec6c 100755 --- a/scripts/build_lib.sh +++ b/scripts/build_lib.sh @@ -4,11 +4,13 @@ set -e # always run from top of repo cd $(dirname $0)/.. +echo "Running $0 for \$OSTYPE=$OSTYPE ..." + # this needs bash case "$OSTYPE" in darwin*) libname=lib/libpestutils.dylib ;; linux*) libname=lib/libpestutils.so ;; - msys* ) libname=bin/pestutils.dll ;; + msys*|cygwin ) libname=bin/pestutils.dll ;; *) echo "unknown \$OSTYPE: $OSTYPE" && exit 1 ;; esac From 7cf08f36ba09c38580c0b38b08bcfbc0fdeb55bb Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 8 Apr 2025 09:32:09 +1200 Subject: [PATCH 11/21] [pre-commit.ci] pre-commit autoupdate (#49) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.9.3 → v0.11.4](https://github.com/astral-sh/ruff-pre-commit/compare/v0.9.3...v0.11.4) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0189f88..c4feca2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,7 +7,7 @@ repos: hooks: - id: check-yaml - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.9.3 + rev: v0.11.4 hooks: # Run the linter. - id: ruff From a4d7e289ddf5df59409089959adaad288e688c14 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 15 Sep 2025 23:12:53 +1200 Subject: [PATCH 12/21] [pre-commit.ci] pre-commit autoupdate (#51) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.11.4 → v0.12.2](https://github.com/astral-sh/ruff-pre-commit/compare/v0.11.4...v0.12.2) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c4feca2..4f742f6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,7 +7,7 @@ repos: hooks: - id: check-yaml - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.11.4 + rev: v0.12.2 hooks: # Run the linter. - id: ruff From 46ccd8e0a04fa6463679f68be739bcb4689713cc Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 14:11:03 +1300 Subject: [PATCH 13/21] [pre-commit.ci] pre-commit autoupdate (#54) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [pre-commit.ci] pre-commit autoupdate updates: - [github.com/pre-commit/pre-commit-hooks: v5.0.0 → v6.0.0](https://github.com/pre-commit/pre-commit-hooks/compare/v5.0.0...v6.0.0) - [github.com/astral-sh/ruff-pre-commit: v0.12.2 → v0.13.3](https://github.com/astral-sh/ruff-pre-commit/compare/v0.12.2...v0.13.3) * use new id --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Mike Taves --- .pre-commit-config.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4f742f6..074e14a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,14 +3,14 @@ ci: exclude: \.grb$ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 + rev: v6.0.0 hooks: - id: check-yaml - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.12.2 + rev: v0.13.3 hooks: - # Run the linter. - - id: ruff + # Run the linter + - id: ruff-check args: [ --fix ] - # Run the formatter. + # Run the formatter - id: ruff-format From 19477ecd26dab9b4c4a8881c8d1bf9bd093d4e41 Mon Sep 17 00:00:00 2001 From: Mike Taves Date: Wed, 29 Oct 2025 12:29:44 +1300 Subject: [PATCH 14/21] Drop Python 3.9 and Intel macOS builds, add Python 3.14 testing (#55) --- .github/workflows/release.yml | 16 ++++++---------- .github/workflows/tests.yml | 7 ++++--- .pre-commit-config.yaml | 2 +- pyproject.toml | 9 ++++----- tox.ini | 2 +- 5 files changed, 16 insertions(+), 20 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2eae1af..eba6ca8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -33,17 +33,13 @@ jobs: arch: aarch64 - os: windows-2022 arch: AMD64 - - os: macos-13 - arch: x86_64 - macosx_deployment_target: "13.0" - cmake_osx_architectures: x86_64 - os: macos-14 arch: arm64 macosx_deployment_target: "14.0" cmake_osx_architectures: arm64 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up QEMU if: runner.os == 'Linux' && matrix.arch == 'aarch64' @@ -71,7 +67,7 @@ jobs: run: bash scripts/build_lib.sh - name: Build wheels - uses: pypa/cibuildwheel@v2.22.0 + uses: pypa/cibuildwheel@v3.2.1 env: CIBW_ARCHS: ${{ matrix.arch }} CIBW_ENVIRONMENT_MACOS: @@ -79,7 +75,7 @@ jobs: MACOSX_DEPLOYMENT_TARGET='${{ matrix.macosx_deployment_target }}' CMAKE_OSX_ARCHITECTURES='${{ matrix.cmake_osx_architectures }}' - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v5 with: name: cibw-wheels-${{ matrix.os }}-${{ matrix.arch }} path: ./wheelhouse/*.whl @@ -88,12 +84,12 @@ jobs: name: Build source distribution runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Build sdist run: pipx run build --sdist - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v5 with: name: cibw-sdist path: dist/*.tar.gz @@ -108,7 +104,7 @@ jobs: # or, alternatively, upload to PyPI on every tag starting with 'v' (remove on: release above to use this) # if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') steps: - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v6 with: # unpacks all CIBW artifacts into dist/ pattern: cibw-* diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index bc5aabf..f8be6f4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -15,15 +15,16 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: ["3.9", "3.13"] # run lower and upper versions + python-version: ["3.10", "3.14"] # run lower and upper versions steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Setup Python ${{ matrix.python-version }} - uses: astral-sh/setup-uv@v5 + uses: astral-sh/setup-uv@v7 with: python-version: ${{ matrix.python-version }} + activate-environment: "true" - name: Install MinGW-w64 tools (Windows) if: runner.os == 'Windows' diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 074e14a..c81870b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,7 +7,7 @@ repos: hooks: - id: check-yaml - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.13.3 + rev: v0.14.2 hooks: # Run the linter - id: ruff-check diff --git a/pyproject.toml b/pyproject.toml index 3138831..ea80e58 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,25 +12,24 @@ authors = [ readme = "README.md" description = "PEST utilities for MODFLOW" keywords = ["PEST", "MODFLOW", "groundwater", "model"] -license = {text = "Unlicense"} +license = "Unlicense" classifiers = [ "Development Status :: 2 - Pre-Alpha", "Intended Audience :: Science/Research", - "License :: OSI Approved :: The Unlicense (Unlicense)", "Operating System :: Unix", "Operating System :: MacOS", "Operating System :: Microsoft :: Windows", "Programming Language :: Fortran", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Topic :: Scientific/Engineering :: Hydrology", ] -requires-python = ">=3.9" +requires-python = ">=3.10" dependencies = [ "numpy", "pandas", @@ -59,7 +58,7 @@ version = {attr = "pypestutils.version.__version__"} include = ["pypestutils", "pypestutils.*"] [tool.cibuildwheel] -build = "cp39-*" +build = "cp310-*" build-verbosity = 3 repair-wheel-command = "python scripts/repair_wheel.py -w {dest_dir} {wheel}" test-requires = "tox" diff --git a/tox.ini b/tox.ini index cf671ab..3986d54 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,7 @@ [tox] requires = tox>=4 -env_list = py{39,310,311,312,313} +env_list = py{310,311,312,313,314} [testenv] description = run unit tests From 96af3a11465b3350ea8b5cd59dff58d7fb16ca45 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 6 Jan 2026 11:55:17 +1300 Subject: [PATCH 15/21] [pre-commit.ci] pre-commit autoupdate (#56) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.14.2 → v0.14.10](https://github.com/astral-sh/ruff-pre-commit/compare/v0.14.2...v0.14.10) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c81870b..b6ca9e6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,7 +7,7 @@ repos: hooks: - id: check-yaml - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.14.2 + rev: v0.14.10 hooks: # Run the linter - id: ruff-check From c7ab0c284093fe10dbea0557ce225345bb398409 Mon Sep 17 00:00:00 2001 From: jwhite Date: Fri, 6 Feb 2026 12:45:20 -0700 Subject: [PATCH 16/21] fix for StringArray madness --- pypestutils/helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pypestutils/helpers.py b/pypestutils/helpers.py index ea1e9f4..27d400f 100644 --- a/pypestutils/helpers.py +++ b/pypestutils/helpers.py @@ -167,7 +167,7 @@ def mod2obs_mf6( print("WARNING: replacing existing 'totim' column in observation dataframe") obsdf.loc[:, "totim"] = obsdf.datetime.apply(lambda x: x - start_datetime).dt.days - usite = obsdf.site.unique() + usite = obsdf.site.unique().tolist() usite.sort() usite_dict = {s: c for s, c in zip(usite, np.arange(usite.shape[0], dtype=int))} obsdf.loc[:, "isite"] = obsdf.site.apply(lambda x: usite_dict[x]) From 0ae239dc025d9785c1dfc685616f581d94932bbd Mon Sep 17 00:00:00 2001 From: jwhite Date: Mon, 9 Feb 2026 08:16:33 -0700 Subject: [PATCH 17/21] trigger --- pypestutils/helpers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pypestutils/helpers.py b/pypestutils/helpers.py index 27d400f..0d12644 100644 --- a/pypestutils/helpers.py +++ b/pypestutils/helpers.py @@ -1,5 +1,6 @@ """High-level helper utilities module.""" + from __future__ import annotations import os From 644e608608372b9189e357a38d91c089403ceb83 Mon Sep 17 00:00:00 2001 From: jwhite Date: Mon, 9 Feb 2026 09:53:20 -0700 Subject: [PATCH 18/21] fix --- pypestutils/helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pypestutils/helpers.py b/pypestutils/helpers.py index 0d12644..e1b656f 100644 --- a/pypestutils/helpers.py +++ b/pypestutils/helpers.py @@ -170,7 +170,7 @@ def mod2obs_mf6( usite = obsdf.site.unique().tolist() usite.sort() - usite_dict = {s: c for s, c in zip(usite, np.arange(usite.shape[0], dtype=int))} + usite_dict = {s: c for s, c in zip(usite, np.arange(len(usite), dtype=int))} obsdf.loc[:, "isite"] = obsdf.site.apply(lambda x: usite_dict[x]) obsdf.sort_values(by=["isite", "totim"], inplace=True) From 01791d7ae692834c0c185ee7b9ffac7622f3f3e6 Mon Sep 17 00:00:00 2001 From: jwhite Date: Mon, 9 Feb 2026 12:18:22 -0700 Subject: [PATCH 19/21] fix --- examples/exploring_lowlevel_pypestutils_functions.ipynb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/exploring_lowlevel_pypestutils_functions.ipynb b/examples/exploring_lowlevel_pypestutils_functions.ipynb index 05d2a63..c15decc 100644 --- a/examples/exploring_lowlevel_pypestutils_functions.ipynb +++ b/examples/exploring_lowlevel_pypestutils_functions.ipynb @@ -446,9 +446,9 @@ "metadata": {}, "outputs": [], "source": [ - "usite = hdsdf.site.unique()\n", + "usite = hdsdf.site.unique().tolist()\n", "usite.sort()\n", - "usite_dict = {s: c for s, c in zip(usite, np.arange(usite.shape[0], dtype=int))}\n", + "usite_dict = {s: c for s, c in zip(usite, np.arange(len(usite), dtype=int))}\n", "hdsdf.loc[:, \"isite\"] = hdsdf.site.apply(lambda x: usite_dict[x])\n", "hdsdf.isite\n", "hdsdf.sort_values(by=[\"isite\", \"time\"], inplace=True)\n", From 1880b907b4ffd6ece07752553b67435e15351926 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 10 Mar 2026 19:48:06 +0000 Subject: [PATCH 20/21] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pypestutils/helpers.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pypestutils/helpers.py b/pypestutils/helpers.py index e1b656f..668fd9e 100644 --- a/pypestutils/helpers.py +++ b/pypestutils/helpers.py @@ -1,6 +1,5 @@ """High-level helper utilities module.""" - from __future__ import annotations import os From 54b754bcc0cdd595ac778740cd953c7e35f9150e Mon Sep 17 00:00:00 2001 From: jwhite Date: Thu, 9 Apr 2026 07:59:12 -0600 Subject: [PATCH 21/21] nodef --- etc/environment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/environment.yml b/etc/environment.yml index c364160..c6c351f 100644 --- a/etc/environment.yml +++ b/etc/environment.yml @@ -3,7 +3,7 @@ name: pypestutils channels: - conda-forge - - defaults + - nodefaults dependencies: - appdirs