Releases: DisSModel/dissmodel
Release list
DisSModel v0.6.2
Fixed
SyncRasterModel.synchronize(): state variables loaded as temporal
(time, y, x)arrays (e.g. whenCubeClient.to_lucc_data()finds
temporal catalog entries) now correctly use the first slice as the
initial_pastsnapshot instead of copying the full 3D array, which
causedshift2dto crash withValueError: too many values to unpack._write_geotiff: casting a float array containing NaN to an integer
dtype(e.g.int16) now fills NaN/inf with the band'snodatavalue
before the cast, eliminating aRuntimeWarning: invalid value encountered in cast.
DisSModel v0.6.1
Fixed
- GeoTIFF write with mixed-dtype
band_spec(e.g. int32 categorical +
float32 continuous) silently truncated float bands to the first band's
dtype. Bands are now promoted to the common NumPy result type
(np.result_type) before writing.
Added
- Test suites for
dissmodel.io(utils, dispatch, storage, raster, vector,
convert, xarray) anddissmodel.visualization(chart, map, env detection).
Coverage: 55% → 79% (319 → 441 tests).
Notes
- GeoTIFFs containing mixed-dtype bands saved with v0.6.0 may have truncated
float bands. Re-exporting those files is recommended.
DisSModel v0.6.0
This release lands three coordinated pieces of work: a breaking fix to the
scheduler's time semantics, a new temporal raster API that underpins the
DisSCube integration, and a leaner, more verifiable installation/CI setup.
It also closes out the housekeeping items raised ahead of the JOSS review.
⚠️ Breaking Changes
-
Environment.run():end_timeis now inclusive (TerraME-style). The
simulation executes every scheduled ticktwith
start_time <= t <= end_time; a model's ownend_timeis inclusive too.Migration: if your code used
end_time=N_STEPSexpectingN_STEPS
executions starting at 0, change it toend_time=N_STEPS - 1.
✨ Added
- Temporal raster variables in
RasterBackend:set(name, arr, time=coords)/get(name, time=t)(ceiling lookup viasearchsorted,
clamped at the boundaries), plusis_temporal,time_axis,
temporal_band_names()/static_band_names().from_xarray/
to_xarraynow round-trip temporal variables with their time coordinates
preserved. This is the integration substrate for DisSCube's
CubeClient.to_lucc_data(). ExperimentRecord.period: optional(start, end)window recording
which cube time slices fed a simulation run — provenance for
temporally-aware experiments.
🐛 Fixed
ExperimentRecord.created_atno longer uses the deprecated
datetime.utcnow(); timestamps are now timezone-aware
(+00:00in ISO output).RasterBackend.from_xarray: fixed Affine transform reconstruction.- Scheduler no longer stalls when models finish before the environment's
end_time.
🔧 Changed
- Package version is now single-sourced from package metadata — no more
drift betweendissmodel.__version__,pyproject.toml,CITATION.cff,
and the README citation. - README ecosystem table now points to existing repositories and uses
pip install "git+https://…"for satellite libraries not yet on PyPI. - README/CITATION.cff citation aligned with the JOSS paper author list.
- Core dependencies are leaner:
streamlitremoved,ipywidgetsmoved to
the optionalvizextra (pip install dissmodel[viz]), and the
numpy<2.0pin relaxed to support NumPy 2. from dissmodel.geo.raster import RasterBackendand the equivalent
vector shortcut now work as documented.
🏗 Internal
mypy dissmodel --ignore-missing-importsis clean (0 errors).- CI now runs across Python 3.10–3.12, with Ruff linting, doctest checks,
and test coverage reporting.
Full Changelog: v0.5.0...v0.6.0
v0.5.0
Remove salabim dependency — lightweight pure-Python scheduler
DisSModel 0.5.0 replaces salabim with a minimal time-stepped scheduler
implemented entirely in Python, eliminating the salabim and greenlet
dependencies with zero changes to the public API.
Models continue to implement setup() / execute() as before. Two new
lifecycle hooks — pre_execute() and post_execute() — replace the salabim
process() loop for models that need per-step snapshotting (SyncRasterModel,
SyncSpatialModel).
v0.4.1
Merge pull request #125 from DisSModel/develop paper update
v0.4.0 — Load as first-class lifecycle phase + Xarray interoperability
What's new in 0.4.0
Breaking change — ModelExecutor.run signature
run(self, record) → run(self, data, record)
data is the direct return value of load(), injected by the platform.
Executors that called self.load(record) inside run() must remove that call
and receive the loaded data as the first argument instead.
Executor lifecycle orchestration
- New
dissmodel/executor/runner.pywithexecute_lifecycle— the canonical
validate → load → run → saveloop, shared by the CLI and the platform
job_runner. Each phase is timed independently and written to
record.metrics(time_load_secnow visible separately fromtime_run_sec). execute_lifecycleexported fromdissmodel.executor.ExecutorTestHarnessupdated to callload → run(data, record)in sequence
and to reject the old one-parameterrunsignature with a clear error message.
RasterBackend — Xarray interoperability
RasterBackend.to_xarray(time=None)— converts toxr.Datasetwith(y, x)
dimensions, spatial coordinates from rasterio Affine transform, and CRS as
spatial_ref(CF-1.8 / rioxarray convention).RasterBackend.from_xarray(ds)— builds a backend from anxr.Datasetor
xr.DataArray, recovering transform and CRS when available.RasterBackend.__init__now acceptstransformandcrskeyword arguments.
Tests
Full executor test suite added under tests/executor/:
test_runner, test_registry, test_cli, test_testing — with
_isolate_registry autouse fixture preventing cross-test registry pollution.
Removed
make_raster_grid()alias (deprecated since 0.3.0)regular_grid()alias (deprecated since 0.2.1)
Migration guide for executor authors:
# Before (0.3.x)
def run(self, record: ExperimentRecord):
data = self.load(record)
...
# After (0.4.0)
def run(self, data, record: ExperimentRecord):
# data injected by execute_lifecycle — no I/O here
...Full changelog: CHANGELOG.md
v0.3.0
What's Changed
Added
Sync models — automatic .past snapshot semantics (equivalent to TerraME's cs:synchronize()):
SyncSpatialModel— vector substrate, manages<col>_pastcolumns automaticallySyncRasterModel— raster substrate, manages<n>_pastarrays automatically- Both expose a public
synchronize()method
I/O — dissmodel.geo.raster.io
shapefile_to_raster_backend— load any vector file (Shapefile, GeoJSON, GPKG, ZIP) directly into aRasterBackend, with automatic"mask"bandsave_raster_backend— write arrays to GeoTIFF without aband_specload_geotiff/save_geotiffupdated with.zipsupport
RasterMap — new visualization options: scheme (equal_interval, quantiles), legend, auto_mask, save_frames
Map — headless fallback (saves PNGs), new figsize, interval, save_frames parameters
Fixed
RasterMap: multiple instances now maintain independent windows —plt.close("all")no longer closes other figuresMap:AttributeError: 'Map' object has no attribute 'fig'with StreamlitMap: no longer raisesRuntimeErrorwhen no display is availablemake_raster_grid()deprecated →raster_grid()(alias kept until v0.4.0)
Full changelog: CHANGELOG.md
v0.2.1
What's Changed
API improvements
parse_idxnow returnsGridPos(row, col)— a namedtuple that eliminates the
(col, row)vs(row, col)ambiguity. Tuple unpacking remains fully compatible,
so existing code continues to work without changes.regular_grid()renamed tovector_grid()for symmetry with the raster substrate.
The old name is kept as aDeprecationWarningalias and will be removed in v0.3.0.GridPosis now exported fromdissmodel.geo.vector.regular_grid.
Bug fixes
- Fixed
TypeError: parameter 'kwargs' not allowedinRasterModel.setup()and
RasterCellularAutomaton.setup()caused by a salabim incompatibility with**kwargs.
Documentation
- API reference split into
api/geo/vector.mdandapi/geo/raster.md. getting_started.mdexpanded with execution modes and substrate comparison table.visualization.mdupdated to coverRasterMap.core.mdexpanded with OOP modeling section and per-model time control example.CHANGELOG.mdupdated.
Upgrade notes
# before
from dissmodel.geo import regular_grid
gdf = regular_grid(dimension=(30, 30), resolution=1)
# after
from dissmodel.geo.vector.regular_grid import vector_grid
gdf = vector_grid(dimension=(30, 30), resolution=1)
# parse_idx
from dissmodel.geo.vector.regular_grid import parse_idx
pos = parse_idx("3-4")
pos.row # 3
pos.col # 4Full changelog: [CHANGELOG.md](https://github.com/lambdageo/dissmodel/blob/main/CHANGELOG.md)
Add Raster/NumPy Backend for Cellular Automata Models
This release introduces a RasterBackend that allows cellular automata models in DisSModel to run using NumPy arrays instead of iterating over GeoDataFrame rows.
The existing vector backend (GeoPandas + libpysal) remains unchanged. The raster backend is an optional execution engine behind the same API.
0.1.5
- Description:
## What's new in v0.1.5
- Consolidated all dependencies in `pyproject.toml`
- NumPy docstrings and type annotations across all modules
- All CA and SysDyn models refactored to English
- Fixed PATTERN fill ID convention (`row-col`)
- Performance: `neighbor_values()` in all CA rules
- Fixed `Environment` salabim animation crash in headless environments
- Added CLI, Streamlit and Jupyter notebook examples for all models
- MkDocs documentation with mkdocstrings
- CI workflow with pytest and mypy