CIMS–macroABM Setup Guide¶
This guide sets up the CIMS–macroABM linkage from scratch. By the end you will have three repositories cloned, three conda environments created, and a scenario ready to run.
The CIMS–macroABM workflow is independent of CIMS–COPPER–SILVER. You only need CIMS and macroABM (COPPER and SILVER are not required).
1 · Prerequisites¶
- Conda (Anaconda or Miniconda) — for the orchestrator and CIMS.
- uv — for macroABM (
pip install uv). Not needed if you chooserunner = "conda"for macroABM. - git.
- The macroABM raw input data (
raw_data/— IO tables, HFCS, exchange rates, emission factors, …). Obtain it from the macroABM maintainers if you do not already have it.
2 · Clone the repositories¶
A convenient layout is to clone the model repos under M3-linkages/dependencies/
(the same convention the GUI installer uses), but any layout works as long as
the repo_path entries in your scenario config point at them.
git clone -b cims-macro-linkage https://gitlab.com/sesit/M3-linkages.git
cd M3-linkages
mkdir dependencies
git clone -b main https://gitlab.com/sesit/cims-models-fork.git dependencies/cims-models-fork
git clone -b cims-macro-linkage https://github.com/uvic-sesit/macroabm-ca.git dependencies/macroabm-ca
:: Optional — only needed to run the LabourABM stage (see step 7)
git clone -b cims-macro-labour-branch https://gitlab.com/sesit/macrocosm/labourabm/model.git dependencies/labourabm
Place (or symlink) the macroABM raw data at
dependencies/macroabm-ca/raw_data/.
LabourABM branch. Clone the
cims-macro-labour-branch(it carries a numpy≥2 compatibility fix the stage needs). If you instead usemacrocosm-sesit, apply the equivalent.values.copy()fix inlabour_abm_canada/data_bridge/bridge.pyor the ABM will crash with "underlying array is read-only".
3 · Create the environments¶
The orchestrator and CIMS use conda environments (mirroring the
CIMS–COPPER–SILVER pattern). macroABM does not need a conda environment —
macroabm-ca is a uv-managed project, and the
default runner = "uv" resolves its environment from uv.lock automatically on
first run.
:: Orchestration environment (runs linkage_macroabm.py + the runner scripts)
conda create -n m3linkages_env python=3.11
conda activate m3linkages_env
pip install -r requirements.txt
conda deactivate
:: CIMS environment
conda create -n cims_env python=3.13
conda activate cims_env
pip install -r dependencies/cims-models-fork/requirements.txt
conda deactivate
:: macroABM — no conda env needed; just install uv once (any environment)
pip install uv
The conda environment names above must match the
env_name/base_envvalues in your scenarioconfig.toml(see Configuration Reference).
LabourABM environment (optional)¶
Like macroABM, LabourABM needs no conda environment when you use the default
runner = "uv": uv run syncs its dependencies (torch, pandas, …) into a
managed venv on first run, and the linkage runner adds h5py automatically.
Just have uv installed (already covered above).
To use a conda env instead, create one, install LabourABM editable, and set
runner = "conda" + env_name under [Models.LabourABM]:
conda create -n labourabm_env python=3.12
conda activate labourabm_env
pip install -e dependencies/labourabm
pip install h5py
conda deactivate
Prefer a conda env for macroABM instead?¶
If you would rather run macroABM in a conda env (e.g. on a cluster without uv),
create one and set runner = "conda" + env_name in the scenario config:
conda create -n macroabm_env python=3.12
conda activate macroabm_env
pip install -e dependencies/macroabm-ca[dev]
conda deactivate
4 · Configure the scenario¶
Ready-made scenario folders ship with this branch:
scenarios/MacroABM Reference/— full 2014→2050 linkage runscenarios/MacroABM Smoke/— same settings; use for quick resume/skip tests
Open scenarios/MacroABM Reference/config.toml and adjust paths and environment
names for your machine:
[General]
base_env = "m3linkages_env"
models_to_run = ["CIMS", "MacroABM"]
sim_end_year = 2050
[Models.CIMS]
repo_path = "dependencies\\cims-models-fork"
env_name = "cims_env"
base_scenario = "Reference"
warm_start = true
history_boundary_year = 2020
[Models.MacroABM]
repo_path = "dependencies\\macroabm-ca"
runner = "uv" # default; no conda env needed
python_version = "3.12"
raw_data_path = "dependencies\\macroabm-ca\\raw_data"
warm_start = true
history_boundary_year = 2020
To create a new scenario, copy this folder to scenarios/<Your Scenario>/ and
edit the config.
5 · (Automatic) CIMS results-logging template¶
The macroABM extractor needs CIMS to log new_stock and total_stock at the
technology level. You do not need to do this manually — cims_macro_runner.py
appends the two lines to dependencies/cims-models-fork/results/results_tech.txt
if missing, and prints a NOTE: when it does.
This is the only change the linkage makes to anything in the CIMS repo, and it is a data file, not code. If you re-clone or update CIMS and the file gets reset, the runner simply re-applies it next run. See the overview note.
CIMS runtime patch (Python 3.13 / pandas 3.x)¶
On some newer stacks (notably Python 3.13 with recent pandas/polars), empty CSV
cells are read as float NaN. That breaks CIMS in two ways:
Emissions_GWP— blankSub_Contextis treated as present, so model build fails withKeyError: 'year_value'.DCC_class(and similar params) — blank year cells becomeNaN, so CIMS nests the value by context and_dcc_classes()later fails withTypeError: unhashable type: 'dict'.
You do not need to fix this manually — the linkage runners apply
scripts/cims_runtime_patch.py automatically before calling CIMS.Model (via
cims_warm_restart.py when warm_start = true, or cims_scenario_runner.py
otherwise).
To verify the patch on your machine (from M3-linkages, inside cims_env):
python scripts/test_cims_runtime_patch.py
Expected output includes get_ghg_and_emissions OK (the failure mode this patch
targets). A full CIMS.Model build OK line confirms end-to-end model load.
6 · (Optional) Adjust the sector mapping¶
The CIMS↔macroABM classification is defined in two editable CSVs inside the macroABM repo:
macro_data/processing/macroabm_cims_data_processing/data/cims_macro_sector_map.csvmacro_data/processing/macroabm_cims_data_processing/data/cims_macro_region_map.csv
Edit these to change which CIMS sectors/fuels map to which macroABM industries,
which industries form the energy bundle, and which provinces aggregate into the
CIMS AT (Atlantic) region. Unmapped rows are skipped with a warning rather
than crashing the run. Column meanings are documented in the
Configuration Reference.
7 · (Optional) Enable the LabourABM stage¶
LabourABM runs once, after the CIMS–macroABM loop converges (or hits
--max_iterations), and translates the macroABM production result into
occupation-level labour-market outcomes. To enable it:
- Clone LabourABM (step 2) and have
uvinstalled (step 3). - Add
"LabourABM"tomodels_to_runand add a[Models.LabourABM]section to your scenarioconfig.toml(theMacroABM Referenceconfig ships with a ready-to-use block):
```toml [General] models_to_run = ["CIMS", "MacroABM", "LabourABM"]
[Models.LabourABM] repo_path = "dependencies\labourabm" runner = "uv" # or "conda" / "pip" python_version = "3.12" start_year = 2020 # A baseline macroABM run is needed for a meaningful labour-demand shock, # e.g. use a Reference scenario as the baseline for a Net Zero policy run: # baseline_scenario = "MacroABM Reference" # baseline_h5 = "path\to\baseline\simulation_results.h5" ```
LabourABM computes a per-industry shock as (policy − baseline) / production,
so it needs two macroABM production HDF5s: the policy run (this scenario,
used automatically) and a baseline run (baseline_scenario / baseline_h5).
With no baseline it reuses the policy file (zero shock) — fine to check the
plumbing, but set a baseline for real analysis. All keys are documented in the
Configuration Reference.
Next steps¶
Head to the Quick-start tutorial to launch a test iteration.