Custom matrices and indices labels#

This notebook shows how to customize MARIO settings for matrix nomenclature and set aliases, then inspects what changes in the current public API on the packaged IOT fixture.

Warning: settings changes persist#

mario.upload_settings(...) writes the active MARIO configuration to the current installation or environment, so the change persists across future Python sessions and future import mario calls.

In other words, relabeling z as A, relabeling w as L, or adding custom aliases is not a temporary in-memory change. It remains active until you overwrite the settings again or call mario.reset_settings().

This is why the notebook stores previous_settings first and restores them at the end.

[1]:
from copy import deepcopy

import mario

mario.set_log_verbosity("critical")

Store the current settings#

Keep a copy of the active settings so the notebook can restore them at the end.

[2]:
previous_settings = mario.download_settings(None)
{
    "z": previous_settings["nomenclature"]["z"],
    "w": previous_settings["nomenclature"]["w"],
    "sector_aliases": previous_settings["index_aliases"]["s"],
}
[2]:
{'z': 'z',
 'w': 'w',
 'sector_aliases': ['sector', 'sectors', 'industry', 'industries']}

Customize nomenclature and set aliases#

Here z is relabeled to A, w is relabeled to L, and Industry is added as an accepted alias for the Sector set in an IOT.

[3]:
custom_settings = deepcopy(previous_settings)
custom_settings["nomenclature"]["z"] = "A"
custom_settings["nomenclature"]["w"] = "L"
custom_settings["index_aliases"]["s"] = sorted({*custom_settings["index_aliases"]["s"], "Industry"})

mario.upload_settings(custom_settings)
{
    "z": mario.download_settings(None)["nomenclature"]["z"],
    "w": mario.download_settings(None)["nomenclature"]["w"],
    "sector_aliases": mario.download_settings(None)["index_aliases"]["s"],
}
[3]:
{'z': 'A',
 'w': 'L',
 'sector_aliases': ['sector', 'sectors', 'industry', 'industries']}

Load the IOT fixture#

[4]:
db = mario.load_test("IOT")
db
[4]:
name = IOT test (standard)
table = IOT
scenarios = ['baseline']
Factor of production = 3
Satellite account = 2
Consumption category = 1
Region = 2
Sector = 3

Use the new set alias#

Set aliases are active in the inspection API, so Industry resolves to the canonical Sector set.

[5]:
db.get_index("Industry")
[5]:
['Agriculture', 'Services', 'Industry']
[6]:
db.Industry == db.Sector
[6]:
True

Check the matrix names accepted by the runtime API#

Once the settings are uploaded, MARIO exposes A and L as the public matrix names while still accepting the canonical names z and w for backward compatibility.

[7]:
{
    name: {
        "in_available_matrices": name in db.available_matrices(),
        "hasattr": hasattr(db, name),
    }
    for name in ["A", "L", "z", "w"]
}
[7]:
{'A': {'in_available_matrices': True, 'hasattr': True},
 'L': {'in_available_matrices': True, 'hasattr': True},
 'z': {'in_available_matrices': False, 'hasattr': True},
 'w': {'in_available_matrices': False, 'hasattr': True}}
[8]:
{
    "A_equals_z": db.A.equals(db.z),
    "L_equals_w": db.L.equals(db.w),
    "query_A_equals_query_z": db.query("A").equals(db.query("z")),
    "query_L_equals_query_w": db.query("L").equals(db.query("w")),
}
[8]:
{'A_equals_z': True,
 'L_equals_w': True,
 'query_A_equals_query_z': True,
 'query_L_equals_query_w': True}
[9]:
db.A.head()
[9]:
Region Reg1 Reg2
Level Sector Sector
Item Agriculture Industry Services Agriculture Industry Services
Region Level Item
Reg1 Sector Agriculture 0.093346 0.100871 0.010290 0.029593 0.042325 0.004276
Industry 0.112553 0.431001 0.101928 0.017704 0.112831 0.012555
Services 0.189887 0.183327 0.292816 0.016302 0.023262 0.024197
Reg2 Sector Agriculture 0.000042 0.000049 0.000008 0.037102 0.025621 0.003292
Industry 0.000691 0.002514 0.000627 0.121941 0.240282 0.066618
[10]:
db.L.head()
[10]:
Region Reg1 Reg2
Level Sector Sector
Item Agriculture Industry Services Agriculture Industry Services
Region Level Item
Reg1 Sector Agriculture 1.140207 0.218134 0.048139 0.058437 0.107265 0.022977
Industry 0.294625 1.901016 0.278625 0.108426 0.337764 0.078021
Services 0.382674 0.551766 1.499358 0.087775 0.180144 0.081452
Reg2 Sector Agriculture 0.000139 0.000320 0.000098 1.045241 0.038248 0.008548
Industry 0.002486 0.007343 0.002380 0.202161 1.369527 0.131244

The current behavior is therefore:

  • index_aliases changes what users can pass to methods such as get_index(...) and dotted set access like db.Industry.

  • nomenclature changes the public matrix names, so db.A and db.query("A") resolve the same matrix as db.z and db.query("z").

  • Existing built-in matrix names remain reserved, so relabeling one matrix to the name of another built-in matrix raises an error.

Reserved names are blocked#

Trying to relabel z as f fails immediately because f is already a reserved built-in matrix name. This cell only shows the validation error; the settings restore is handled separately right after.

[ ]:
blocked_settings = deepcopy(previous_settings)
blocked_settings["nomenclature"]["z"] = "f"

try:
    mario.upload_settings(blocked_settings)
except Exception as exc:
    blocked_error = str(exc)

blocked_error
{'blocked_error': "The nomenclature label 'f' for 'z' is blocked because 'f' is already a reserved built-in matrix name.",
 'restored': ('z', 'w')}

Restore the original settings#

The custom labels used in this tutorial persist until they are overwritten again or reset, so the last step restores the initial configuration explicitly.

[ ]:
mario.upload_settings(previous_settings)
{
    "restored": (
        mario.download_settings(None)["nomenclature"]["z"],
        mario.download_settings(None)["nomenclature"]["w"],
    ),
    "sector_aliases": mario.download_settings(None)["index_aliases"]["s"],
}