Skip to content

New Structure, regions & parallelization - #15

Open
jnnsbrr wants to merge 10 commits into
pik-copan:mainfrom
jnnsbrr:regions
Open

New Structure, regions & parallelization#15
jnnsbrr wants to merge 10 commits into
pik-copan:mainfrom
jnnsbrr:regions

Conversation

@jnnsbrr

@jnnsbrr jnnsbrr commented Feb 10, 2026

Copy link
Copy Markdown
Collaborator

Implementation of regions (countries) into InSEEDS and parallelization based on countries

... for more information

Structural changes in InSEEDS structure:

  • realisations folder instead of models
  • component.py has been moved entirely to each realisation for more explicit control of model wiring
  • flat (no nested) structure of each component (farming, etc.)

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR restructures InSEEDS “models” into “realisations”, introduces a country/region (3-level) hierarchy intended to enable country-level parallelization, and updates tests + CI to match the new structure and output collection approach.

Changes:

  • Added new regenerative_tillage_regions realisation (Model/main/config) with country-level entities and parallelization settings.
  • Migrated regenerative_tillage to the new realisations/ structure and adjusted model update/output collection flow.
  • Expanded/rewrote tests + pytest fixtures, and enhanced CI workflows (coverage, build checks) plus a new release workflow.

Reviewed changes

Copilot reviewed 44 out of 48 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
inseeds/realisations/regenerative_tillage_regions/model.py New regions-aware model wiring (World/Country/Cell/Farmer) and per-year update flow
inseeds/realisations/regenerative_tillage_regions/main.py New entry point using pycopanlpjml.run.run_simulation
inseeds/realisations/regenerative_tillage_regions/config.yaml Adds parallelization/output configuration for regions run
inseeds/realisations/regenerative_tillage/model.py Updates model to use lpjml.Model, new init/update/output collection behavior
inseeds/realisations/regenerative_tillage/main.py Updates imports to the new realisations location
inseeds/components/farming/* Adds Region/Country mixins, updates World.update, refactors tillage farmer base class usage
inseeds/components/base/* Removes local output-writing logic; migrates to pycopanlpjml output mixins/classes
tests/conftest.py Reworks fixtures to cache LPJmL pickles and create/run models once per session
tests/test_regenerative_tillage.py Updates tests for new structure/output comparison approach
tests/test_regenerative_tillage_regions.py New test suite for 3-level hierarchy and compatibility checks
tests/test_components_base.py / tests/test_components_farming.py / tests/test_main.py Adds unit/import/entry-point tests
.github/workflows/check.yml Updates CI: newer setup-python, coverage scope, build + twine checks
.github/workflows/release.yml Adds automated release pipeline (tests, lint, build, PyPI publish, GH release)
CITATION.cff Updates cited version metadata
README.md Updates documentation to refer to realisations/ structure
scripts/* and tests/data/write_testdata.py Updates script paths and LPJmL run helper usage for new layout
Comments suppressed due to low confidence (1)

inseeds/realisations/regenerative_tillage/model.py:121

  • has_crops is an xarray DataArray comparison, so if not has_crops: will raise (DataArray has no truth value). Convert to a Python bool/scalar first (e.g., use .item() / .values.item() after the reduction) before using it in the if condition.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +20 to +23
# 'mpi' = reuse LPJmL's MPI processes (recommended if LPJmL uses MPI)
# 'serial' = force serial execution
mode: 'dask' # 'auto'

Copilot AI Feb 10, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This config hard-codes parallelization mode: 'dask'. If Dask isn't installed/available in the target environment, runs will fail even though auto/serial would work. Consider defaulting to auto (as in the non-regions config) and documenting how to opt into Dask explicitly.

Copilot uses AI. Check for mistakes.
Comment thread CITATION.cff Outdated
type: software
title: 'Model of integrated social-ecological resilient land systems (InSEEDS)'
version: 0.2.8
version: 1.2.0

Copilot AI Feb 10, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pyproject.toml still declares the package version as 0.2.8, but CITATION.cff is updated to 1.2.0. Align these versions (or document why they intentionally differ) so packaging, releases, and citation metadata stay consistent.

Suggested change
version: 1.2.0
version: 0.2.8

Copilot uses AI. Check for mistakes.
Comment on lines +125 to +129
self.countries = []
print(
"Warning: No country data available. "
"Running without country-level structure."
)

Copilot AI Feb 10, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Library code prints a warning directly during model initialization. This is hard to control for downstream users and test runners; prefer warnings.warn(...) or the project logger so callers can filter/redirect it.

Copilot uses AI. Check for mistakes.
Comment on lines +13 to +29
# @property
# def farmers(self):
# """Return the set of all farmers."""
# farmers = {
# farmer
# for farmer in self.individuals
# if farmer.__class__.__name__ == "Farmer" # noqa
# }
# return farmers

@property
def farmer(self):
"""Return the first farmer."""
farmers = self.farmers
if len(farmers) == 0:
return None
return list(farmers)[0]
# @property
# def farmer(self):
# """Return the first farmer."""
# farmers = self.farmers
# if len(farmers) == 0:
# return None
# return list(farmers)[0]

Copilot AI Feb 10, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file comments out the farmers/farmer properties rather than removing them or keeping them implemented. Consider deleting the dead commented code (or reintroducing the properties if still part of the public API) to keep the module clean and avoid confusion.

Copilot uses AI. Check for mistakes.
Comment on lines +141 to +143
has_crops = cell.from_earth.cftfrac.sum("band") > 0
if not has_crops:
continue

Copilot AI Feb 10, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

has_crops is an xarray DataArray comparison, so if not has_crops: will raise (DataArray has no truth value). Convert to a Python bool/scalar first (e.g., use .item() / .values.item() after the reduction) before using it in the if condition.

Copilot uses AI. Check for mistakes.
build:
runs-on: ubuntu-latest
permissions:
contents: write

Copilot AI Feb 10, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This workflow grants contents: write, but it only checks out code, runs tests/lint/build, and uploads coverage. Reduce to least-privilege (typically contents: read) to avoid unnecessarily broad repository write permissions for PRs.

Suggested change
contents: write
contents: read

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants