Chapter 34: Migrating from TerraME/LUCCME to DisSModel¶
Part VII — Scaling, Migration & Reference
Learning Objectives¶
By the end of this chapter you will be able to:
- Translate TerraME/LUCCME concepts to their DisSModel equivalents
- Know what numerical equivalence guarantees already exist in the ecosystem
- Plan an incremental migration of an existing model, and validate it properly before trusting it
# Standard imports
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
This chapter is for one specific reader: someone who already has a working TerraME or LUCCME model, written in Lua, and is deciding whether — and how — to bring it into the ecosystem the rest of this book has spent thirty-three chapters building. Nothing here requires new code from you to follow along; it's a map, meant to be read once before a real migration starts, then kept open beside the model you're actually moving.
Why Migrate¶
TerraME is C++/Lua, its most recent release from 2020, installed through OS-specific installers. That alone is a real cost: every year since, the surrounding Python scientific ecosystem — the one this book has built fluency in since Chapter 1 — has kept moving, and a TerraME model can't import geopandas or hand its state to pandas for analysis without leaving its own language entirely first.
DisSModel's pitch is narrow and specific, not "newer is better" in the abstract: pip install, the same code in a notebook (Chapter 22) and in a recorded, repeatable experiment (Chapter 31), and — where a DisSModel port exists — measured agreement with the original TerraME output, not just "inspired by" it. That last property is the one Existing Validation Cases returns to directly, because it's the difference between a migration you can trust and one you're merely hoping matches.
The pitch has a limit worth stating as plainly. DisSModel does not yet cover everything TerraME and LuccME do — DisSLUCC implements the components of 10 of LuccME's 21 test labs (Chapter 26), and some TerraME ca and logo models have no port (Chapters 24 and 25). If your model depends on a component that is missing, the original software is still the right tool, and the archived reference outputs of Chapter 30 let you follow the agreement as the Python side grows. Migration is a choice to make model by model, not a verdict on TerraME.
General Equivalence Table¶
| TerraME/LUCCME concept | DisSModel equivalent |
|---|---|
| TerraME (the framework itself) | dissmodel |
| LuccME components (demand, potential, allocation; continuous and discrete) | disslucc (Chapter 26) |
| TerraLib (data I/O) | geopandas / rasterio (Chapters 7–8) |
cl:fill{} / filling a cellular space |
DisSCube operators in a pipeline file (Chapter 28) |
| TerraME network module (GPM), costs along a road network | DisSCube network_cost (Chapter 28; agreement still open, Chapter 30) |
| TerraView (visual inspection) | not rebuilt — disscube plot, QGIS on the exported GeoTIFF |
Agent / Society |
dissmodel-abm's AgentModel / Society (Chapter 25) |
init(self) |
setup() (Chapter 22) |
execute(self) |
execute() (Chapter 22) |
explicit past/present CellularSpace copies |
implicit, via CellularAutomaton.execute() (Chapter 24) |
Every row here has already come up once in this book, in a different context — this table's real job is just to collect them in one place, indexed by the TerraME term you'd actually search for.
Step-by-Step Incremental Migration¶
1. Identify the original model's paradigm. A TerraME CellularSpace with a per-cell rule maps onto Chapter 24's CellularAutomaton; a stock-and-flow model maps onto Chapter 23's plain Model; an Agent/Society model maps onto Chapter 25's AgentModel. A LUCCME-style continuous allocation and a CLUE-S-like discrete allocation both map onto disslucc (Chapter 26), and a coupled raster/vector domain model — BR-MANGUE's coastal dynamics being the ecosystem's own worked example — maps directly onto the SpatialModel/RasterModel pair from Chapter 22.
2. Choose the corresponding satellite package, or build directly on dissmodel.core/dissmodel.geo if none fits — exactly what dissmodel-ca and dissmodel-sysdyn themselves do. Install it as Chapter 21 showed: dissmodel, disscube and disslucc from PyPI, the paradigm extensions from their GitHub releases.
3. Map the input data. Wherever TerraME used TerraLib to read a CellularSpace's data, DisSModel uses geopandas/rasterio directly — a shapefile or GeoPackage becomes a GeoDataFrame (Chapter 7), a GeoTIFF becomes a RasterBackend (Chapter 8). If the original data needs aligning to a modeling grid first — resampling, zonal aggregation, deriving driver variables from a raw source — that step belongs to a DisSCube pipeline file (Chapter 28), not to the model executor itself; each cl:fill{} call of the original script becomes one [[derive]] block.
4. Validate outputs against the original model, before trusting the migration. Run the original model in a fixed environment (the terrame-docker image of Chapter 30), archive its outputs with their hashes, and compare the migrated model with them, cell by cell and step by step. Chapter 30 is this step done for the whole ecosystem, and its repositories are templates for your own. Never treat "the migrated model runs without an error" as evidence it's correct.
Existing Validation Cases in the Ecosystem¶
The ecosystem doesn't just claim agreement with TerraME/LuccME — it measures it, in separate benchmark repositories (Chapter 30), in two styles depending on what kind of output is being compared:
- Tolerance-based, for continuous output. A migrated model's own benchmark suite runs the DisSModel version and a TerraME/LUCCME reference dataset side by side, and asserts that the largest absolute difference between them stays below a stated tolerance (a mean error can hide a few cells that are far off; report it next to the maximum, not instead of it). This is the right bar for anything fractional — a percentage, a continuous allocation weight — whenever the two implementations do not run the same arithmetic in the same order. When they do, as for the system-dynamics models of Chapter 23, identical numbers are achievable and should be the test; Chapter 30 says how to justify each tolerance.
- Exact agreement, for categorical output. A discrete land-use allocation is compared cell by cell: the share of cells whose class matches the reference, which should be 100%. Land use is categorical: a cell is forest or it isn't, and a tolerance band doesn't mean anything for a label that has no notion of "almost correct." (Chapter 27 shows the exception that proves the rule: a categorical band that depends on a continuous one through a threshold can differ in a handful of cells for reasons that are understood.)
The rule this splits into: pick the validation style that matches your migrated variable's type, not the other way around. Forcing a categorical variable through a tolerance check hides real disagreements; forcing a continuous variable through exact-parity checking will fail on harmless floating-point noise that was never the point. In the ecosystem's benchmarks the check runs in continuous integration, against references pinned by hash — every code change is compared with the TerraME outputs again, not just once at migration time. And a tolerance is a regression guard, set just above what was measured, not a claim of equivalence beyond it.
Exercises¶
- Sketch a skeleton. Take a hypothetical TerraME model whose
CellularSpacelooks only at each cell's 4 cardinal neighbors inexecute(self). Using the equivalence table and Chapter 24'sFireModelas a reference, write the class skeleton — imports, base class, neighborhood strategy — you'd start a DisSModel port from. You don't need to implementrule()itself, just the setup. - Pick the right validation style. A colleague migrating a LUCCME model asks whether to validate with a tolerance-based benchmark or an exact-parity check. What single fact about their model's output — from Existing Validation Cases — actually answers that question?
- Where does disscube enter? Chapter 28 noted that
disscubehas no direct code dependency on the LUCC-style packages — the connection is a sharedRasterBackendcontract, not an import. If you were migrating a TerraME model whose driver variables came from a raw MapBiomas raster, at which numbered step in Step-by-Step Incremental Migration woulddisscubeactually enter the picture — and why not a step earlier or later? - Migrate or not? Your inherited LuccME model uses
PotentialDSampleBased, one of the components DisSLUCC does not implement yet. List what you would gain by migrating the rest of the model now, what you would lose, and what you would need from Chapter 30's repositories to follow the agreement later.
# Your code here
Summary¶
Key concepts introduced¶
- Migrating from TerraME/LUCCME is a mapping exercise more than a rewrite:
init/executebecomesetup/executeon the lifecycle from Chapter 22,cl:fill{}becomes a DisSCube pipeline file, and the equivalence table says where each concept goes — and the few that have no home yet - A four-step incremental migration path: identify the paradigm, choose the satellite package, map the input data (with
disscubehandling grid alignment specifically), then validate - Two validation styles, chosen by output type — a tolerance for continuous variables, exact cell agreement for categorical ones — run against archived reference outputs pinned by hash (Chapter 30)
- Migration as a choice made model by model: where a component is missing, the original software remains the right tool
- "Runs without an error" is necessary but never sufficient; the real bar is measured numerical agreement with the original TerraME/LUCCME output on a known dataset
- Even where a satellite package already exists, it may not cover every feature the original TerraME model used — Chapter 25 documented
dissmodel-abm's own gaps as one concrete example; checking a package's stated scope before assuming full coverage is part of the migration itself, not a separate step
Chapter 35 closes the book with the ecosystem's own architecture and contribution process — useful reading whether your migration surfaces a gap worth filling, or you simply want to understand how the pieces you've spent this book learning actually fit together.
Further Reading¶
- TerraME on GitHub: https://github.com/TerraME/terrame
- LuccME documentation (INPE): http://www.dpi.inpe.br/luccme/
- DisSLUCC on GitHub: https://github.com/DisSModel/disslucc; its comparison with the LuccME labs: https://github.com/LambdaGeo/disslucc-benchmark
- luccme-goldens, the archived TerraME and LuccME outputs to validate a migration against: https://github.com/LambdaGeo/luccme-goldens
- brmangue-dissmodel on GitHub: https://github.com/DisSModel/brmangue-dissmodel