diff --git a/.github/workflows/gh-page.yml b/.github/workflows/gh-page.yml index 1ab1e53a..fb3e1070 100644 --- a/.github/workflows/gh-page.yml +++ b/.github/workflows/gh-page.yml @@ -41,7 +41,8 @@ jobs: - name: Install dependencies (uv) run: | set -e - uv sync + # Install runtime + docs group (mkdocs, plugins, nb toolchain) + uv sync --group docs --dev if [ -n "${{ secrets.GH_TOKEN }}" ]; then uv pip install git+https://${{ secrets.GH_TOKEN }}@github.com/squidfunk/mkdocs-material-insiders.git else diff --git a/.github/workflows/test-notebooks.yml b/.github/workflows/test-notebooks.yml index 8dd7360e..c52e7734 100644 --- a/.github/workflows/test-notebooks.yml +++ b/.github/workflows/test-notebooks.yml @@ -22,7 +22,8 @@ jobs: - name: Install deps run: | - uv sync --dev + # Need docs stack to execute notebooks via mkdocs-jupyter/nbmake + uv sync --group docs --dev - name: Run nbmake env: diff --git a/CHANGELOG.md b/CHANGELOG.md index 73bc9791..bf812d59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,29 @@ # Changelog +## [0.9.0](https://github.com/SongshGeoLab/ABSESpy/compare/v0.8.5...v0.9.0) (2025-10-29) + + +### Features + +* **actor, patch:** :sparkles: Add move_to method in Actor and count_agents method in PatchModule ([11e63b2](https://github.com/SongshGeoLab/ABSESpy/commit/11e63b2a95fc72232a5ab96d840bf9ad66743b30)) +* **actor:** :sparkles: Add evaluate method to Actor for scoring candidates with rollback functionality ([bad83ac](https://github.com/SongshGeoLab/ABSESpy/commit/bad83ac22e769cafa092584414a83a603dda3c9b)) +* **agents, space:** :sparkles: Enhance agent and cell functionality with new properties and methods ([cacf3d0](https://github.com/SongshGeoLab/ABSESpy/commit/cacf3d04957ddf54d949277c86e3bc80af415dad)) +* **core:** Protocol-based architecture refactoring ([12534d8](https://github.com/SongshGeoLab/ABSESpy/commit/12534d8c93517336c57f0d86a57aaab366fb6af7)) +* **examples:** :sparkles: Remove outdated agent and analysis files, add configuration and quick start notebook ([d1fed62](https://github.com/SongshGeoLab/ABSESpy/commit/d1fed623172cdeb8cddcfe3a560f0be94c340c68)) +* **examples:** :white_check_mark: Introduce configuration file and enhance model dynamics ([1fa3e0c](https://github.com/SongshGeoLab/ABSESpy/commit/1fa3e0cc879c4c7e01f19b4040160e410006105e)) +* **patch:** :sparkles: Implement __getitem__ method for PatchModule with numpy-style indexing ([1c66edb](https://github.com/SongshGeoLab/ABSESpy/commit/1c66edb3e833d145295e0ae139e54d89340e2c18)) + + +### Bug Fixes + +* **sequences:** Fix attribute access in better() method ([2f1089f](https://github.com/SongshGeoLab/ABSESpy/commit/2f1089f40267cb2b7b5967f2d7519fec6fff3a15)) + + +### Documentation + +* **docs:** :memo: Enhance UML documentation and integrate Mermaid diagrams ([62a9cdd](https://github.com/SongshGeoLab/ABSESpy/commit/62a9cdd62715c6c72439def968a1a8a896b16aae)) +* **tutorials, docs:** :memo: Expand tutorial content and enhance documentation structure ([316c972](https://github.com/SongshGeoLab/ABSESpy/commit/316c97203b21c94c0a797bb9199d2a8ca4818c60)) + ## [0.7.5](https://github.com/SongshGeoLab/ABSESpy/compare/v0.7.4...v0.7.5) (2025-02-16) diff --git a/abses/space/patch.py b/abses/space/patch.py index 4e037866..4c1086b3 100644 --- a/abses/space/patch.py +++ b/abses/space/patch.py @@ -573,12 +573,20 @@ def _select_by_geometry( Args pass to the function `rasterasterio.mask.mask`. Returns: - A numpy array of clipped cells. + A boolean numpy 2D array mask where True indicates selected cells. """ - # TODO 研究一下为什么需要转换为整数,转换bool结果不一样了 - return self.xda.astype(np.int32, casting="safe").rio.clip( + # Use float dtype so rioxarray can represent out-of-geometry as NaN. + # Boolean selection must be based on NaN mask, not on underlying cell values + # (otherwise cells with value 0 would be incorrectly excluded). + clipped = self.xda.astype(np.float32).rio.clip( [geometry], all_touched=False, drop=False, **kwargs ) + # Convert to boolean mask: True where data is finite (inside geometry) + mask_da = np.isfinite(clipped.to_numpy()) + # Ensure 2D mask (squeeze potential band dimension) + if mask_da.ndim == 3: + mask_da = np.squeeze(mask_da, axis=0) + return mask_da def select( self, @@ -620,8 +628,9 @@ def select( mask_ = self._attr_or_array(where).reshape(self.shape2d) else: raise TypeError(f"{type(where)} is not supported for selecting cells.") - mask_ = np.nan_to_num(mask_, nan=0.0).astype(bool) - return ActorsList(self.model, self.array_cells[mask_]) + # mask_ is expected to be boolean here + mask_bool = mask_.astype(bool) + return ActorsList(self.model, self.array_cells[mask_bool]) sel = select diff --git a/pyproject.toml b/pyproject.toml index 737c7d6e..3c2f7b82 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ line_length = 79 [project] name = "abses" -version = "0.7.5" +version = "0.9.0" description = "ABSESpy makes it easier to build artificial Social-ecological systems with real GeoSpatial datasets and fully incorporate human behaviour." authors = [{name = "Shuang Song", email = "songshgeo@gmail.com"}] license = {text = "Apache 2.0 License"} @@ -41,16 +41,6 @@ dependencies = [ "numpy<2", "urllib3", "icons", - "solara", - "mkdocs>=1.6.1", - # Note: mkdocs-material-insiders requires authentication and MUST NOT be declared here - # to avoid build backend variable expansion errors (e.g. Unknown context field). - # Install locally via environment variable before building docs, e.g.: - # export MKDOCS_INSIDER=your_token - # uv pip install "git+https://${MKDOCS_INSIDER}@github.com/squidfunk/mkdocs-material-insiders.git" - "mkdocs-jupyter>=0.25.1", - "mkdocstrings>=0.30.1", - "mkdocs-static-i18n>=1.3.0", ] [project.urls] @@ -58,6 +48,31 @@ Homepage = "https://github.com/SongshGeoLab/ABSESpy" Documentation = "https://absespy.github.io/ABSESpy/" Repository = "https://github.com/SongshGeoLab/ABSESpy" +[project.optional-dependencies] +# Optional docs-related dependencies. Not required at runtime. +docs = [ + "mkdocs>=1.6.1", + "mkdocs-git-revision-date-localized-plugin>=1.2.0", + "mkdocs-minify-plugin>=0.7.1", + "mkdocs-redirects>=1.2.1", + "mkdocs-awesome-pages-plugin>=2.9.2", + "mkdocs-git-authors-plugin>=0.7.2", + "mkdocstrings>=0.30.1", + "mkdocstrings[python]>=0.24.0", + "mkdocs-bibtex>=2.11.0", + "mkdocs-macros-plugin>=1.0.4", + "mkdocs-jupyter>=0.25.1", + "mkdocs-callouts>=1.9.1", + "mkdocs-glightbox>=0.3.4", + "mkdocs-exclude>=1.0.2", + "mkdocs-simple-hooks>=0.1.5", + "mkdocs-static-i18n>=1.3.0", + "pymdown-extensions>=10.7", + "mike>=2.0.0", + "nbmake>=1.5.5", + "nbconvert>=7.16.6", +] + [project.entry-points."hydra.searchpath"] abses = "hydra_plugins.abses_searchpath_plugin:ABSESpySearchPathPlugin" @@ -89,17 +104,21 @@ dev = [ "tox>=4.11.3", "lxml>=5.2.1", "griffe>=1.14.0", - # Docs dependencies - "mkdocs>=1.5.3", +] + +# Dedicated group for docs build. Install with: uv sync --group docs +docs = [ + "mkdocs>=1.6.1", "mkdocs-git-revision-date-localized-plugin>=1.2.0", "mkdocs-minify-plugin>=0.7.1", "mkdocs-redirects>=1.2.1", "mkdocs-awesome-pages-plugin>=2.9.2", "mkdocs-git-authors-plugin>=0.7.2", + "mkdocstrings>=0.30.1", "mkdocstrings[python]>=0.24.0", "mkdocs-bibtex>=2.11.0", "mkdocs-macros-plugin>=1.0.4", - "mkdocs-jupyter>=0.24.5", + "mkdocs-jupyter>=0.25.1", "mkdocs-callouts>=1.9.1", "mkdocs-glightbox>=0.3.4", "mike>=2.0.0", diff --git a/uv.lock b/uv.lock index 2cd60b1c..5500e679 100644 --- a/uv.lock +++ b/uv.lock @@ -8,7 +8,7 @@ resolution-markers = [ [[package]] name = "abses" -version = "0.7.5" +version = "0.9.0" source = { editable = "." } dependencies = [ { name = "fiona" }, @@ -20,21 +20,39 @@ dependencies = [ { name = "loguru" }, { name = "mesa" }, { name = "mesa-geo" }, - { name = "mkdocs" }, - { name = "mkdocs-jupyter" }, - { name = "mkdocs-static-i18n" }, - { name = "mkdocstrings" }, { name = "netcdf4" }, { name = "numpy" }, { name = "pendulum" }, { name = "rioxarray" }, { name = "seaborn" }, - { name = "solara" }, { name = "typing-extensions" }, { name = "urllib3" }, { name = "xarray" }, ] +[package.optional-dependencies] +docs = [ + { name = "mike" }, + { name = "mkdocs" }, + { name = "mkdocs-awesome-pages-plugin" }, + { name = "mkdocs-bibtex" }, + { name = "mkdocs-callouts" }, + { name = "mkdocs-exclude" }, + { name = "mkdocs-git-authors-plugin" }, + { name = "mkdocs-git-revision-date-localized-plugin" }, + { name = "mkdocs-glightbox" }, + { name = "mkdocs-jupyter" }, + { name = "mkdocs-macros-plugin" }, + { name = "mkdocs-minify-plugin" }, + { name = "mkdocs-redirects" }, + { name = "mkdocs-simple-hooks" }, + { name = "mkdocs-static-i18n" }, + { name = "mkdocstrings", extra = ["python"] }, + { name = "nbconvert" }, + { name = "nbmake" }, + { name = "pymdown-extensions" }, +] + [package.dev-dependencies] dev = [ { name = "allure-pytest" }, @@ -49,6 +67,22 @@ dev = [ { name = "jupyterlab-execute-time" }, { name = "lxml" }, { name = "matplotlib" }, + { name = "mypy" }, + { name = "nbstripout" }, + { name = "pre-commit" }, + { name = "pre-commit-hooks" }, + { name = "pydocstyle" }, + { name = "pylint" }, + { name = "pytest" }, + { name = "pytest-clarity" }, + { name = "pytest-cov" }, + { name = "pytest-sugar" }, + { name = "ruff" }, + { name = "scriv" }, + { name = "sourcery" }, + { name = "tox" }, +] +docs = [ { name = "mike" }, { name = "mkdocs" }, { name = "mkdocs-awesome-pages-plugin" }, @@ -65,23 +99,9 @@ dev = [ { name = "mkdocs-simple-hooks" }, { name = "mkdocs-static-i18n" }, { name = "mkdocstrings", extra = ["python"] }, - { name = "mypy" }, { name = "nbconvert" }, { name = "nbmake" }, - { name = "nbstripout" }, - { name = "pre-commit" }, - { name = "pre-commit-hooks" }, - { name = "pydocstyle" }, - { name = "pylint" }, { name = "pymdown-extensions" }, - { name = "pytest" }, - { name = "pytest-clarity" }, - { name = "pytest-cov" }, - { name = "pytest-sugar" }, - { name = "ruff" }, - { name = "scriv" }, - { name = "sourcery" }, - { name = "tox" }, ] [package.metadata] @@ -95,20 +115,36 @@ requires-dist = [ { name = "loguru", specifier = ">=0.7" }, { name = "mesa", specifier = ">=3.1.0" }, { name = "mesa-geo", specifier = ">=0.9.1" }, - { name = "mkdocs", specifier = ">=1.6.1" }, - { name = "mkdocs-jupyter", specifier = ">=0.25.1" }, - { name = "mkdocs-static-i18n", specifier = ">=1.3.0" }, - { name = "mkdocstrings", specifier = ">=0.30.1" }, + { name = "mike", marker = "extra == 'docs'", specifier = ">=2.0.0" }, + { name = "mkdocs", marker = "extra == 'docs'", specifier = ">=1.6.1" }, + { name = "mkdocs-awesome-pages-plugin", marker = "extra == 'docs'", specifier = ">=2.9.2" }, + { name = "mkdocs-bibtex", marker = "extra == 'docs'", specifier = ">=2.11.0" }, + { name = "mkdocs-callouts", marker = "extra == 'docs'", specifier = ">=1.9.1" }, + { name = "mkdocs-exclude", marker = "extra == 'docs'", specifier = ">=1.0.2" }, + { name = "mkdocs-git-authors-plugin", marker = "extra == 'docs'", specifier = ">=0.7.2" }, + { name = "mkdocs-git-revision-date-localized-plugin", marker = "extra == 'docs'", specifier = ">=1.2.0" }, + { name = "mkdocs-glightbox", marker = "extra == 'docs'", specifier = ">=0.3.4" }, + { name = "mkdocs-jupyter", marker = "extra == 'docs'", specifier = ">=0.25.1" }, + { name = "mkdocs-macros-plugin", marker = "extra == 'docs'", specifier = ">=1.0.4" }, + { name = "mkdocs-minify-plugin", marker = "extra == 'docs'", specifier = ">=0.7.1" }, + { name = "mkdocs-redirects", marker = "extra == 'docs'", specifier = ">=1.2.1" }, + { name = "mkdocs-simple-hooks", marker = "extra == 'docs'", specifier = ">=0.1.5" }, + { name = "mkdocs-static-i18n", marker = "extra == 'docs'", specifier = ">=1.3.0" }, + { name = "mkdocstrings", marker = "extra == 'docs'", specifier = ">=0.30.1" }, + { name = "mkdocstrings", extras = ["python"], marker = "extra == 'docs'", specifier = ">=0.24.0" }, + { name = "nbconvert", marker = "extra == 'docs'", specifier = ">=7.16.6" }, + { name = "nbmake", marker = "extra == 'docs'", specifier = ">=1.5.5" }, { name = "netcdf4", specifier = ">=1.6" }, { name = "numpy", specifier = "<2" }, { name = "pendulum", specifier = ">=3.0.0" }, + { name = "pymdown-extensions", marker = "extra == 'docs'", specifier = ">=10.7" }, { name = "rioxarray", specifier = ">=0.13" }, { name = "seaborn", specifier = ">=0.13" }, - { name = "solara" }, { name = "typing-extensions", specifier = ">=4,<5" }, { name = "urllib3" }, { name = "xarray", specifier = ">=2023" }, ] +provides-extras = ["docs"] [package.metadata.requires-dev] dev = [ @@ -124,8 +160,24 @@ dev = [ { name = "jupyterlab-execute-time", specifier = ">=3.0.1" }, { name = "lxml", specifier = ">=5.2.1" }, { name = "matplotlib", specifier = ">=3.7.2" }, + { name = "mypy", specifier = ">=1.6.1" }, + { name = "nbstripout", specifier = ">=0.6.2" }, + { name = "pre-commit", specifier = ">=3.0.1" }, + { name = "pre-commit-hooks", specifier = ">=4.4.0" }, + { name = "pydocstyle", specifier = ">=6.3.0" }, + { name = "pylint", specifier = ">=3.0.1" }, + { name = "pytest", specifier = ">=7.2.1" }, + { name = "pytest-clarity" }, + { name = "pytest-cov", specifier = ">=4.1.0" }, + { name = "pytest-sugar", specifier = ">=0.9.7" }, + { name = "ruff", specifier = ">=0.1.0" }, + { name = "scriv", specifier = ">=1.2.0" }, + { name = "sourcery", specifier = ">=1.0.6" }, + { name = "tox", specifier = ">=4.11.3" }, +] +docs = [ { name = "mike", specifier = ">=2.0.0" }, - { name = "mkdocs", specifier = ">=1.5.3" }, + { name = "mkdocs", specifier = ">=1.6.1" }, { name = "mkdocs-awesome-pages-plugin", specifier = ">=2.9.2" }, { name = "mkdocs-bibtex", specifier = ">=2.11.0" }, { name = "mkdocs-callouts", specifier = ">=1.9.1" }, @@ -133,30 +185,17 @@ dev = [ { name = "mkdocs-git-authors-plugin", specifier = ">=0.7.2" }, { name = "mkdocs-git-revision-date-localized-plugin", specifier = ">=1.2.0" }, { name = "mkdocs-glightbox", specifier = ">=0.3.4" }, - { name = "mkdocs-jupyter", specifier = ">=0.24.5" }, + { name = "mkdocs-jupyter", specifier = ">=0.25.1" }, { name = "mkdocs-macros-plugin", specifier = ">=1.0.4" }, { name = "mkdocs-minify-plugin", specifier = ">=0.7.1" }, { name = "mkdocs-redirects", specifier = ">=1.2.1" }, { name = "mkdocs-simple-hooks", specifier = ">=0.1.5" }, { name = "mkdocs-static-i18n", specifier = ">=1.3.0" }, + { name = "mkdocstrings", specifier = ">=0.30.1" }, { name = "mkdocstrings", extras = ["python"], specifier = ">=0.24.0" }, - { name = "mypy", specifier = ">=1.6.1" }, { name = "nbconvert", specifier = ">=7.16.6" }, { name = "nbmake", specifier = ">=1.5.5" }, - { name = "nbstripout", specifier = ">=0.6.2" }, - { name = "pre-commit", specifier = ">=3.0.1" }, - { name = "pre-commit-hooks", specifier = ">=4.4.0" }, - { name = "pydocstyle", specifier = ">=6.3.0" }, - { name = "pylint", specifier = ">=3.0.1" }, { name = "pymdown-extensions", specifier = ">=10.7" }, - { name = "pytest", specifier = ">=7.2.1" }, - { name = "pytest-clarity" }, - { name = "pytest-cov", specifier = ">=4.1.0" }, - { name = "pytest-sugar", specifier = ">=0.9.7" }, - { name = "ruff", specifier = ">=0.1.0" }, - { name = "scriv", specifier = ">=1.2.0" }, - { name = "sourcery", specifier = ">=1.0.6" }, - { name = "tox", specifier = ">=4.11.3" }, ] [[package]]