Skip to main content

Discrete Spatial Modeling framework for raster and vector simulations

Project description

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, cloud-native execution platform.

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, cloud, queues).
  • 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.
  • CLI + Platform โ€” the same executor runs locally via CLI and on the DisSModel Platform via API.

๐Ÿ— Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Science Layer  (Model / Salabim)                        โ”‚
โ”‚  FloodModel, AllocationCClueLike, MangroveModel, ...     โ”‚
โ”‚  โ†’ only knows math, geometry and time                    โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  Infrastructure Layer  (ModelExecutor)                   โ”‚
โ”‚  CoastalRasterExecutor, LUCCVectorExecutor, ...          โ”‚
โ”‚  โ†’ only knows URIs, MinIO, 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

# my_model.py
from dissmodel.core import SpatialModel, Environment

class ForestFireModel(SpatialModel):

    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

# 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

Running via Platform API

curl -X POST http://localhost:8000/submit_job \
  -H "X-API-Key: chave-sergio" \
  -H "Content-Type: application/json" \
  -d '{"model_name": "forest_fire", "input_dataset": "s3://inputs/forest.gpkg"}'

๐Ÿ“ฆ ExperimentRecord

Every run produces an immutable provenance record:

{
  "experiment_id":  "abc123",
  "model_commit":   "a3f9c12",
  "code_version":   "0.1.5",
  "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 platform run 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

Full implementations in examples/:

  • CA: Game of Life, Forest Fire, Snowfall, Growth
  • System Dynamics: SIR, Predator-Prey, Lorenz Attractor
  • LUCC: DisSLUCC โ€” C-CLUE on vector and raster
  • Coastal: coastal-dynamics โ€” Flood + Mangrove

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


๐Ÿ“ฆ Installation

pip install dissmodel

# Latest development version
pip install "git+https://github.com/LambdaGeo/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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dissmodel-0.4.0.tar.gz (56.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dissmodel-0.4.0-py3-none-any.whl (69.5 kB view details)

Uploaded Python 3

File details

Details for the file dissmodel-0.4.0.tar.gz.

File metadata

  • Download URL: dissmodel-0.4.0.tar.gz
  • Upload date:
  • Size: 56.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for dissmodel-0.4.0.tar.gz
Algorithm Hash digest
SHA256 1aa0bc7caf4d81a3f4ebfafb038a3c77def7c02d81f4e807e0f5581229ac5c1a
MD5 88a0315673e0b77bbccaa62500d97e33
BLAKE2b-256 fa15824f26809372118b5f2e797459fff0e42f5a3f69a3e1e04ccf7c76e9f02f

See more details on using hashes here.

File details

Details for the file dissmodel-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: dissmodel-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 69.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for dissmodel-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e10fdcdfe842b9dac9cca7b64d30f6491e3a0a7579ce1f1e6faff26c6f0a6a3f
MD5 7403ae22577b95f371930b9d02b1b139
BLAKE2b-256 08379250a6477faf44c71d83cc75da21eec48068fd0402ffeeba79308a7d5ec2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page