Skip to content

DisSModel/dissmodel

DisSModel 🌍

License: MIT Python 3.10+ PyPI version LambdaGeo


πŸ“– About

DisSModel is a modular Python framework for spatially explicit dynamic simulation models. Developed by the LambdaGeo group at the Federal University of MaranhΓ£o (UFMA), it provides the simulation layer that connects domain models (LUCC, coastal dynamics) to a reproducible simulation environment.

INPE / TerraME Ecosystem LambdaGeo Ecosystem Role
TerraME dissmodel Generic framework for dynamic spatial modeling
LUCCME DisSLUCC LUCC domain models built on dissmodel
β€” coastal-dynamics Coastal domain models built on dissmodel
TerraLib geopandas / rasterio Geographic data handling

🌟 Key Features

  • Dual substrate β€” same model logic runs on vector (GeoDataFrame) and raster (RasterBackend/NumPy).
  • Discrete Event Simulation β€” built on Salabim; time advances to the next relevant event, not millisecond by millisecond.
  • Executor pattern β€” strict separation between science (models) and infrastructure (I/O, CLI, reproducible execution).
  • Experiment tracking β€” every run generates an immutable ExperimentRecord with SHA-256 checksums, TOML snapshot, and full provenance.
  • Storage-agnostic I/O β€” dissmodel.io handles local paths and s3:// URIs transparently.

πŸ— Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Science Layer  (Model / Salabim)                        β”‚
β”‚  FloodModel, AllocationCClueLike, MangroveModel, ...     β”‚
β”‚  β†’ only knows math, geometry and time                    β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Infrastructure Layer  (ModelExecutor)                   β”‚
β”‚  CoastalRasterExecutor, LUCCVectorExecutor, ...          β”‚
β”‚  β†’ only knows URIs, local/S3, column_map, parameters     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Core modules                                            β”‚
β”‚  dissmodel.core      β€” Environment, SpatialModel         β”‚
β”‚  dissmodel.geo       β€” RasterBackend, neighborhoods      β”‚
β”‚  dissmodel.executor  β€” ModelExecutor ABC, ExperimentRecordβ”‚
β”‚  dissmodel.io        β€” load_dataset / save_dataset       β”‚
β”‚  dissmodel.visualization β€” Map, RasterMap, Chart         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

"A ciΓͺncia nΓ£o deve ser reescrita para ir para a produΓ§Γ£o."


πŸš€ Quick Start

Writing a model

...

πŸ“Š Performance Telemetry

Every run via the executor lifecycle generates a profiling_{id}.md alongside the output:

def setup(self, prob_spread=0.3):
    self.prob_spread = prob_spread

def execute(self):
    # Called every step by Salabim β€” only math here, no I/O
    burning = self.gdf["state"] == "burning"
    ...

env = Environment(end_time=50) ForestFireModel(gdf=gdf, prob_spread=0.4) env.run()


### Writing an executor

```python
# my_executor.py
from dissmodel.executor     import ExperimentRecord, ModelExecutor
from dissmodel.executor.cli import run_cli
from dissmodel.io           import load_dataset, save_dataset

class ForestFireExecutor(ModelExecutor):
    name = "forest_fire"

    def load(self, record: ExperimentRecord):
        gdf, checksum = load_dataset(record.source.uri)
        record.source.checksum = checksum
        return gdf

    def run(self, record: ExperimentRecord):
        from dissmodel.core import Environment
        gdf     = self.load(record)
        env     = Environment(end_time=record.parameters.get("end_time", 50))
        ForestFireModel(gdf=gdf, **record.parameters)
        env.run()
        return gdf

    def save(self, result, record: ExperimentRecord) -> ExperimentRecord:
        uri      = record.output_path or "output.gpkg"
        checksum = save_dataset(result, uri)
        record.output_path   = uri
        record.output_sha256 = checksum
        record.status        = "completed"
        return record

if __name__ == "__main__":
    run_cli(ForestFireExecutor)

Running via CLI

# Run
python my_executor.py run \
  --input  data/forest.gpkg \
  --output data/result.gpkg \
  --param  end_time=50 \
  --toml   model.toml

# Validate data contract without running
python my_executor.py validate --input data/forest.gpkg

# Show resolved parameters
python my_executor.py show --toml model.toml

πŸ“¦ ExperimentRecord

Every run produces an immutable provenance record:

{
  "experiment_id":  "abc123",
  "model_commit":   "a3f9c12",
  "code_version":   "0.4.0",
  "resolved_spec":  { "...TOML snapshot..." },
  "source":         { "uri": "s3://...", "checksum": "e3b0c44..." },
  "artifacts":      { "output": "sha256...", "profiling": "sha256..." },
  "metrics":        { "time_run_sec": 2.15, "time_total_sec": 2.34 },
  "status":         "completed"
}

Reproduce any past experiment exactly:

curl -X POST http://localhost:8000/experiments/abc123/reproduce \
  -H "X-API-Key: chave-sergio"

πŸ“Š Performance Telemetry

Every run via the executor lifecycle generates a profiling_{id}.md alongside the output:

Phase Time (s) %
Validate 0.005 0.2%
Run 2.150 92.1%
Save 0.180 7.7%
Total 2.335 100%

πŸ“– Examples & Ecosystem

DisSModel is a core framework. To maintain a clean and specialized environment, all simulation models and implementation examples are hosted in separate repositories within the LambdaGeo ecosystem.

🧩 Specialized Model Libraries

Download and install these libraries to get ready-to-use models:

  • DisSModel-CA β€” Classic Cellular Automata (Game of Life, Forest Fire, Growth, etc.).
  • DisSModel-SysDyn β€” System Dynamics (SIR, Predator-Prey, Lorenz Attractor).
  • coastal-dynamics β€” Specialized models for coastal flooding and mangrove succession.

πŸš€ Implementation Templates

Since DisSModel uses the Executor Pattern, you can find implementation templates for CLI integration in the documentation or by exploring the repositories above. Each repository demonstrates how to:

  1. Define a Model: Using SpatialModel and Environment.
  2. Wrap an Executor: Using ModelExecutor for I/O and provenance.
  3. Deploy: Running via CLI.

Documentation: https://lambdageo.github.io/dissmodel/


πŸ“¦ Installation

pip install dissmodel

# Latest development version
pip install "git+https://github.com/DisSModel/dissmodel.git@main"

πŸŽ“ Citation

Costa, S. & Santos Junior, N. (2026). DisSModel: A Discrete Spatial Modeling
Framework for Python. LambdaGeo, Federal University of MaranhΓ£o (UFMA).

βš–οΈ License

MIT Β© LambdaGeo β€” UFMA

About

A modular Python framework for spatially explicit dynamic modeling, Cellular Automata, and System Dynamics.

Topics

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors