euromod_linking.scenarios¶
Running a linking scenario: validate, transform, (optionally) simulate.
Two entry points:
apply_scenario(system, data, scenario)The core. Turns external-model shocks into transformed EUROMOD input — the counterfactual and, when the methodology restructures rows, a matching baseline built on the same rows. Executes nothing.
run_scenario(system, scenario, input_path=...)Convenience: loads the dataset, applies the scenario and runs both halves through
System.run().
Applications that need caching, retries or their own response envelope build on apply_scenario and run the frames themselves; that is why nothing here knows about caches or run ids.
The API exposes shocks, not methodologies: the transformation methodology is
resolved from the shock table’s channels/metrics and reported back. An optional
methodology pin exists only for exact reproduction or disambiguation.
Constants semantics:
scenario
constantsare context, applied to BOTH runs, so the delta isolates the shock;shock records with
channel: constantare part of the shock and apply to the COUNTERFACTUAL only (metric = constant name, period = constant group, op must beset). A constants-only shock table needs no methodology.
Errors are exceptions (ScenarioError carrying .problems, RunError), not error dicts — callers that need a machine-readable envelope build it themselves.
Exceptions¶
The methodology transformed the input but the engine produced identical |
|
A scenario cannot be applied. |
Functions¶
|
Transform input microdata according to a scenario. Executes nothing. |
|
Weighted people matched by each distinct shock cell. |
|
Validate everything that does not need the model or the data. |
|
Canonical scenario hash for a result-cache key. Shocks are represented by |
|
Add-ons and extension switches the run needs: the methodology's own |
|
Apply a scenario and run both halves through |
Module Contents¶
- exception euromod_linking.scenarios.NoEffectError[source]¶
The methodology transformed the input but the engine produced identical output — the run is invalid.
Emphatically not “the reform has no impact”: it means the model never acted on the transformation (typically a required add-on or switch is not available for this country/system).
- exception euromod_linking.scenarios.ScenarioError(problems: list[str])[source]¶
A scenario cannot be applied.
.problemslists every problem found, not just the first, so one call surfaces everything to fix.- problems¶
- euromod_linking.scenarios.apply_scenario(system, data, scenario: dict, *, dataset_name: str | None = None, validate_only: bool = False) dict[source]¶
Transform input microdata according to a scenario. Executes nothing.
Returns a dict with:
counterfactual the transformed input baseline the matching baseline (same rows) when the methodology restructures rows, else None — run the untouched `data` diagnostics the methodology's account of what it did methodology the resolved reference, e.g. "lma_labour_alignment" constants {(name, group): value} for the counterfactual run context_constants ... applied to BOTH runs addons, extensions what the runs must activate compatibility what the methodology needs from the model and whether this model has it (a CompatibilityReport), or None when the model could not be inspectedRaises ScenarioError (with .problems) when the scenario cannot be applied.
- euromod_linking.scenarios.cell_population(data, population_shocks) dict[source]¶
Weighted people matched by each distinct shock cell.
Surfacing this before a run is what turns a mistyped cell (
deh=34) into a visible zero rather than a shock that silently hits nobody.
- euromod_linking.scenarios.check_scenario(scenario: dict) dict[source]¶
Validate everything that does not need the model or the data.
Structure, shock resolution, methodology dispatch, declared params and the methodology’s contract. Separated so a caller can reject a malformed scenario without paying to load a model. Raises ScenarioError with .problems; returns the resolved pieces for apply_scenario.
- euromod_linking.scenarios.fingerprint(scenario: dict, shock_table_id: str, methodology: str, code_fingerprint: str = '') str[source]¶
Canonical scenario hash for a result-cache key. Shocks are represented by the table’s content id, so inline vs stored vs re-ingested identical shocks hit the same cache entry. Excludes the free-text ‘name’ label.
- euromod_linking.scenarios.run_arguments(scenario: dict, spec) tuple[list, list][source]¶
Add-ons and extension switches the run needs: the methodology’s own requirements (with
{cc}resolved) plus anything the scenario adds.
- euromod_linking.scenarios.run_scenario(system, scenario: dict, *, input_path: str, paired_baseline: bool = False) dict[source]¶
Apply a scenario and run both halves through
System.run().paired_baselineruns the baseline on the counterfactual’s own rows, so the two outputs are observation-paired — needed by any baseline-vs-reform comparison that works row by row, such as one applying a fixed poverty line or baseline-defined decile groups.Returns the apply_scenario dict with
baseline_outputandcounterfactual_outputframes added. Raises NoEffectError when the methodology changed people but the outputs are identical.