Database.update_trade_mix(
shares_by_destination,
*,
items,
scenario: str = 'baseline',
clone_from: str | None = None,
rescale: bool = False,
level: str | None = None,
commodities=None,
column_sectors=None,
column_categories=None,
year: int | None = None,
entsoe_path: str | PathLike[str] | None = None,
api_key=None,
fill_uncovered_domestic: bool = False,
) → None#

Update the regional sourcing mix of one traded item per destination market.

The trade mix is the dual of the supply mix: instead of redistributing several labels within one region, it redistributes one item across its origin regions inside the columns of each destination region, preserving every selected column total. Each buyer therefore keeps its total input of the item; only the sourcing split changes.

Electricity mode#

Passing shares_by_destination="electricity" derives the mix from an ENTSO-E electricity import-mix snapshot (the trade-side companion of update_supply_mix("electricity"), which reads EMBER generation). The mix is a first-order net commercial decomposition – what each market net-sources from its adjacent neighbours on scheduled commercial exchanges (ENTSO-E A09), not cross-border flows.

The trade mix uses ENTSO-E, not Ember (the mirror image of the supply mix): ENTSO-E is the source with bilateral cross-border exchanges, which is what a trade mix needs – and those only exist for the European synchronous area anyway. Ember has global coverage but no bilateral trade, so it drives the supply (generation) mix instead.

Caveats: ENTSO-E (European) area only – non-ENTSO-E regions (US, CN, JP, … and RoW aggregates) are near-isolated can be set domestic-only (see fill_uncovered_domestic) or left unchanged. The basis was validated against Electricity Maps, whose data is proprietary and cannot be redistributed. ENTSO-E is not always right though: non-EU zones with poor coverage can be unreliable and are kept as-is.

The blocks rewritten depend on where the table stores trade:

  • IOT (Isard) — the bundle rows are (origin, Sector, item) and the rewritten columns are the destination region’s z and Y columns.

  • SUT, Commodity level (Isard, e.g. raw EXIOBASE) — the bundle rows are (origin, Commodity, item) and the rewritten columns are the destination’s u and Yc columns.

  • SUT, Activity level (pooled / Chenery-Moses layouts) — the bundle rows are (origin, Activity, item) (e.g. one "... - supply" pass-through activity) and the rewritten columns are the destination market columns of s selected by commodities=... (e.g. the "... - need" commodity).

param shares_by_destination:

Mapping destination_region -> {origin_region: share}. The domestic share is one origin like any other: include the destination itself to rewrite it, omit it to preserve it. Origins that are not listed keep their current share: the provided shares (summing to one) are rescaled onto the combined share currently held by the listed origins, so partial updates (e.g. only the intra-EU sourcing) are well defined.

param items:

One item label or an iterable of labels naming what is traded. All items must live on the same classification level; the mix is applied to each item independently (each item’s per-column totals are preserved separately).

param scenario:

Scenario to update in place. When it does not exist yet, provide clone_from=... to create it first.

param clone_from:

Optional existing source scenario to clone when scenario does not exist yet.

param rescale:

When True, rescale each destination-level vector to sum to one even when the provided values are totals or otherwise do not already form a near-unit mix.

param level:

Classification of items. Optional on SUT databases when the labels resolve unambiguously to Activities or Commodities; required when one label exists in both classifications. IOT databases always operate on Sectors.

param commodities:

SUT Activity-level mixes only: the commodity market column(s) of s rewritten in each destination region.

param column_sectors:

Isard cases only: restrict the rewritten buyer columns to these labels (sectors of z on IOT, activities of u on SUT). Final-demand blocks have no such columns and follow the destination region and column_categories.

param column_categories:

Isard cases only: restrict the final-demand redistribution to these consumption categories (the Y block on IOT, Yc on SUT). None (default) means all categories. Not accepted for Activity-level mixes, which rewrite no final-demand block.

param year:

Electricity mode only: the ENTSO-E vintage to read from the snapshot. When omitted, the latest year available is used; a year absent from the snapshot falls back to the nearest available one with a warning.

param entsoe_path:

Electricity mode only: optional path to an ENTSO-E import-mix snapshot CSV (flat destination, origin, share[, year], as written by nxbase entsoe_pull.py or an nxbase query). When omitted (and no api_key), MARIO uses the packaged snapshot at mario/settings/entsoe_electricity_import_mix.csv – which also doubles as a copyable template for the format, the reliable fallback when a live fetch is unavailable. Mirrors ember_path on the supply side.

param api_key:

Electricity mode only: a one-entry mapping naming a live data provider, {"entsoe": "<key>"} – MARIO fetches the mix from the ENTSO-E Transparency Platform for year (the path for users without an nxbase snapshot). Pass just "entsoe" (or {"entsoe": None}) to use a key configured globally via mario.set_api_keys(), the ENTSOE_API_KEY env var, or mario/settings/api_keys.yaml. {"nxbase": "<key>"} is reserved for the hosted nxbase (not available yet). Mutually exclusive with entsoe_path; requires an explicit year. The same api_key interface is shared with update_supply_mix() ({"ember": ...} there).

param fill_uncovered_domestic:

Electricity mode only: when True, database regions the mix does not cover (non-ENTSO-E: US, CN, JP, …, RoW) are set domestic-only (100% self), the near-isolation simplification. False (default) leaves them on their original table sourcing – the mix only rewrites the regions it actually observed.

returns:

The selected scenario is updated in place.

rtype:

None

Notes

Applying one destination-level mix to every buyer column imposes the Chenery-Moses hypothesis of uniform sourcing on the selected columns of an Isard table: after the update, each rewritten buyer shares the same origin profile. Use column_sectors to keep selected buyers on their original (heterogeneous) sourcing.

With regional classifications, each item must exist in every explicitly listed origin, including origins assigned zero weight. Missing pairs raise WrongInput; weights are not silently renormalized over the available origins. A destination does not need a local node for the origin item: its actual buyer or market columns receive the imports. Column selectors filter actual columns, and sparse inputs remain sparse. No missing production nodes are added.

The method resets the target scenario to coefficient-side storage internally before applying the redistribution, so callers do not need an extra reset_to_coefficients(...) around this operation.