Skip to main content

euromod-linking

Connect external economic models to EUROMOD by transforming its input microdata and run parameters.

A macro model — a CGE model, a forecasting model, a policy scenario written by hand — projects changes: employment by region and education, nominal wages, price levels. EUROMOD simulates taxes and benefits on a household survey. This package is the layer between them: it takes those projected changes as data, rewrites the microdata and run parameters so the survey population matches them, and runs baseline and counterfactual simulations that differ only by the shock.

It is a standalone library. It has no dependency on any agent, notebook or UI, and is usable directly from a script.

Scope

This library targets the JRC's EUROMOD model for the 27 EU member states, and only that model. It is not a general library for the EUROMOD software: models built on the same engine — SOUTHMOD, SWISSMOD, and national or regional models outside the EU — will not work with it.

It assumes EUROMOD's own EU-27 conventions throughout: the ils_udb_* User Database income lists, the les/les2 labour-status codings, drgn1/drgn2 read as NUTS regions, variable names such as dwt, dag, deh, yem and yivwg, the $lhw constant, and the JRC-maintained LMA add-on. Those conventions are precisely what a different model changes.

Install

pip install euromod-linking          # or: pip install -e .
pip install euromod-linking[excel]   # to ingest .xlsx/.xlsm/.xls model output

Requires Python 3.11+ and a local EUROMOD model and installation (see the euromod connector). The model is distributed by the JRC and can be requested at https://euromod-web.jrc.ec.europa.eu/download-euromod.

The canonical shock table

Every external model's output is normalised into one table before anything else happens. Six columns, one row per shock:

column meaning
channel how it acts: align (move people between states), scale (multiply a variable), constant (override a model parameter)
metric what it acts on: employment, unemployment, an input variable (yem), an income list (ils_udb_yem), or a constant name ($f_cpi)
group which people: a population cell over EUROMOD input variables — "deh=3-4;dgn=1", "" for everyone
period the external model's period label
op set | grow | mult | add
value the number

Shock tables are content-addressed (shk_…), so the same economic scenario always has the same id regardless of which file or code path produced it.

Population cells are written over real EUROMOD input variables, never invented category labels. region is the one named dimension and is NUTS-aware: coarser codes cover their subregions, and shocks defined at a finer level than the data supports are collapsed to the level it does.

Two entry points

import pandas as pd
from euromod import Model
from euromod_linking import apply_scenario, run_scenario

system = Model(r"C:\EUROMOD_RELEASES").countries["BE"].systems["BE_2025"]

scenario = {
    "country_code": "BE",
    "system_name": "BE_2025",
    "shocks": {"inline": [
        {"channel": "align", "metric": "employment", "group": "deh=0-3",
         "period": "1", "op": "grow", "value": 0.0655},
    ]},
    "params": {"period": "1"},
}

# Pure transform: returns the counterfactual input, a matched baseline, and diagnostics.
plan = apply_scenario(system, pd.read_csv(data_file, sep="\t"), scenario)

# Convenience: does the above and runs both simulations.
out = run_scenario(system, scenario, input_path=r"C:\EUROMOD_RELEASES\Input")

apply_scenario(..., validate_only=True) stops before the expensive work and returns what the scenario would do: the per-cell baseline population the shocks resolve against, the resulting targets, the implied change in people and in percentage points, and feasibility against the pool of people who can actually move. Check a shock is the size you meant before paying for two simulations.

External model output in a file is ingested through a declarative mapping spec — a YAML file under mappings/, or a dict — rather than bespoke parsing code:

scenario["shocks"] = {"file": "projections.xlsx", "mapping": "regional_projections"}

Methodologies

The transformation is never chosen by the caller. It is resolved from the shock channels and echoed back, so a scenario cannot silently be handled by a different method than the one that produced an earlier result. Their code is content-fingerprinted into the scenario id — changing the modelling invalidates cached results rather than serving stale ones.

  • lma_labour_alignment (align) — two-level hierarchical alignment to external employment/unemployment totals per cell. Level 1 sizes the labour force, level 2 splits it into employment and unemployment. Who moves is decided by ranked logit propensities, not a random draw; targets are hit exactly by splitting the boundary household's weight. New workers are given full-time earnings at their own predicted hourly wage. Labour states come from les/les2 over working age (18–65), and only genuinely inactive people are recruitable — students, pensioners, the long-term sick and conscripts are never moved.
  • scale_variables (scale) — cell-level scaling of input variables. An income-list metric is expanded extension-aware into its component variables by walking the model's DefIl definitions, so it stays correct when extensions change what a list contains.

Diagnostics

Every run reports the baseline it worked from, not just what it achieved: per-cell population and labour states, the resolved target, the change in people and percentage points, feasibility against the recruitable pool, and transitions as weighted people alongside raw row counts. An alignment grade says only that the target was hit — never that the target was right — so the baseline is always reported beside it.

Tests

pip install -e .[dev]
pytest

Licence

EUPL-1.2.

Metadata

Release files for euromod-linking 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for euromod-linking 0.1.0
File Size Uploaded Provenance
euromod_linking-0.1.0.tar.gz 112.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for euromod-linking 0.1.0
File Interpreter ABI Platform
euromod_linking-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 209.3 kB

Release files / euromod_linking-0.1.0.tar.gz

Download URL euromod_linking-0.1.0.tar.gz
Size 112.7 kB
Tags Source
SHA-256 checksum
How to use checksums
2c0908e549048aed83960318c73a2bbed25cd12323d93eee23e083c470694d24
BLAKE2b-256 checksum
How to use checksums
4090dc9bfd9b10a22856e3adea32a5f6a1bc092fa2bf481d104a8420ed597fec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release files / euromod_linking-0.1.0-py3-none-any.whl

Download URL euromod_linking-0.1.0-py3-none-any.whl
Size 96.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f89809b059e024efdd91ece468162dce49956c48dc1d483330572ed247b8a2ff
BLAKE2b-256 checksum
How to use checksums
e8f59c8562a4904c6e1f8ddb3abe672ea31f84662e25fbf7de65d76b17e912d9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Security for euromod-linking 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page