diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 52a8f2bd..1546172f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -41,6 +41,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + fetch-depth: 0 # full history and tags, so setuptools-scm can derive the version - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index b6d3d815..7b4e9227 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ and versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - **`autoadaloc = ` is no longer discarded.** The value is the number of noise standard deviations a correlation must clear -- `nstd` inside the old code -- and it was the value of the `autoadaloc` keyword itself. Only `cutoff` was read, so a config saying `autoadaloc = 2` silently ran at the default of 0.3: no error, a different taper, a different posterior. `cutoff`, `nstd` and `autoadaloc` are all accepted, `cutoff` first. The default stays 0.3; it was 1 before the rewrite, so a block that gave `autoadaloc` as a bare flag with no value tapers differently than it used to. ### Breaking changes +- **The package version comes from the latest git tag.** `pyproject.toml` hard-coded `version = "1.0"` while the repository was tagged `v0.2`, so the two disagreed and `pet version` reported a number no release carried. setuptools-scm now derives it at build time: a tagged commit gets the tag (`v0.2` -> `0.2`), later commits a development version such as `0.3.dev4+g196c956`. Nothing creates tags automatically; release by pushing one. Installed versions therefore drop from `1.0` to `0.3.devN` until the next tag. CI checks out the full history so the tags are visible, and a build without git metadata falls back to `0.0.0`. - **`localanalysis` and the parallel update are refused while the config is read.** Both worked before the update schemes were restructured, and both need the per-subset observation machinery (`_ext_obs`, `current_state`, `pert_preddata`) that the rewrite replaced with a single `DataLayout` built once at setup. `localanalysis` previously reached a branch that left the posterior equal to the prior while still reporting a misfit, and is no longer a registered strategy; naming either now raises `ConfigError` explaining why and naming `autoadaloc` and `distance_loc` as the alternatives. Reimplementing them on the new contract is tracked separately; `analysis_tools.parallel_upd` is left in place for the dormant GIES schemes that still call it. - **`conv_crit` in the `epf` section means a penalty magnitude, not a state change.** The outer EPF loop used to stop once no control moved more than `conv_crit` relative to its previous value; it now stops once `mean(epf['penalty']) / epf['r']` falls below it. The old test asked the wrong question: it reported success whenever the inner optimizer stalled, however badly the constraints were still violated, and refused to finish while a single control kept jittering. The default is still `1e-5`, so a config written for the old criterion loads unchanged, but the number now carries the units of the objective rather than being dimensionless — check it against your penalty's scale. The objective must write `penalty` into the `epf` dict it is handed; one that does not now raises `KeyError` instead of silently converging on the step size. Ported from upstream 5358e07 and 4b8d878. - `max_iter` in the `iteration` section is the number of update iterations. It used to count the prior forecast as iteration 0, so `max_iter: 5` performed four updates; the same config now performs five. To keep an existing run as it was, lower `max_iter` by one. The run table, the convergence message and the `assimilation_result_{i}` files already numbered updates from 1 with the prior as 0, and are unchanged. diff --git a/pyproject.toml b/pyproject.toml index f6121bd6..259dd419 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,10 +1,12 @@ [build-system] -requires = ["setuptools>=61.0", "wheel"] +requires = ["setuptools>=64", "setuptools-scm>=8", "wheel"] build-backend = "setuptools.build_meta" [project] name = "PET" -version = "1.0" +# Derived from the latest git tag by setuptools-scm (v0.2 -> 0.2; +# commits after it -> 0.3.devN+g). Release by pushing a tag. +dynamic = ["version"] description = "Python Ensemble Toolbox" authors = [ { name = "Data assimilation and optimization group" } @@ -78,6 +80,10 @@ package-dir = {"" = "src"} [tool.setuptools.packages.find] where = ["src"] +[tool.setuptools_scm] +# Used when building without git metadata, e.g. from a source zip. +fallback_version = "0.0.0" + [tool.pytest.ini_options] testpaths = ["tests"] markers = [