{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "9bac5ad8",
   "metadata": {},
   "source": [
    "# Custom matrices and indices labels\n",
    "\n",
    "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."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cc734e6f",
   "metadata": {},
   "source": [
    "## Warning: settings changes persist\n",
    "\n",
    "> `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.\n",
    "\n",
    "> 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()`.\n",
    "\n",
    "> This is why the notebook stores `previous_settings` first and restores them at the end."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "dc4aa285",
   "metadata": {},
   "outputs": [],
   "source": [
    "from copy import deepcopy\n",
    "\n",
    "import mario\n",
    "\n",
    "mario.set_log_verbosity(\"critical\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cc376f00",
   "metadata": {},
   "source": [
    "## Store the current settings\n",
    "\n",
    "Keep a copy of the active settings so the notebook can restore them at the end."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "36498e82",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'z': 'z',\n",
       " 'w': 'w',\n",
       " 'sector_aliases': ['sector', 'sectors', 'industry', 'industries']}"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "previous_settings = mario.download_settings(None)\n",
    "{\n",
    "    \"z\": previous_settings[\"nomenclature\"][\"z\"],\n",
    "    \"w\": previous_settings[\"nomenclature\"][\"w\"],\n",
    "    \"sector_aliases\": previous_settings[\"index_aliases\"][\"s\"],\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5d02e8fb",
   "metadata": {},
   "source": [
    "## Customize nomenclature and set aliases\n",
    "\n",
    "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."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "9f9ac0cb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'z': 'A',\n",
       " 'w': 'L',\n",
       " 'sector_aliases': ['sector', 'sectors', 'industry', 'industries']}"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "custom_settings = deepcopy(previous_settings)\n",
    "custom_settings[\"nomenclature\"][\"z\"] = \"A\"\n",
    "custom_settings[\"nomenclature\"][\"w\"] = \"L\"\n",
    "custom_settings[\"index_aliases\"][\"s\"] = sorted({*custom_settings[\"index_aliases\"][\"s\"], \"Industry\"})\n",
    "\n",
    "mario.upload_settings(custom_settings)\n",
    "{\n",
    "    \"z\": mario.download_settings(None)[\"nomenclature\"][\"z\"],\n",
    "    \"w\": mario.download_settings(None)[\"nomenclature\"][\"w\"],\n",
    "    \"sector_aliases\": mario.download_settings(None)[\"index_aliases\"][\"s\"],\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "40ab3f9c",
   "metadata": {},
   "source": [
    "## Load the IOT fixture"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "520e456c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "name = IOT test (standard)\n",
       "table = IOT\n",
       "scenarios = ['baseline']\n",
       "Factor of production = 3\n",
       "Satellite account = 2\n",
       "Consumption category = 1\n",
       "Region = 2\n",
       "Sector = 3"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "db = mario.load_test(\"IOT\")\n",
    "db"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5fae5125",
   "metadata": {},
   "source": [
    "## Use the new set alias\n",
    "\n",
    "Set aliases are active in the inspection API, so `Industry` resolves to the canonical `Sector` set."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "e1bce9e8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Agriculture', 'Services', 'Industry']"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "db.get_index(\"Industry\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "c462b3b9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "db.Industry == db.Sector"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "02249447",
   "metadata": {},
   "source": [
    "## Check the matrix names accepted by the runtime API\n",
    "\n",
    "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."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "d9fe21ef",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'A': {'in_available_matrices': True, 'hasattr': True},\n",
       " 'L': {'in_available_matrices': True, 'hasattr': True},\n",
       " 'z': {'in_available_matrices': False, 'hasattr': True},\n",
       " 'w': {'in_available_matrices': False, 'hasattr': True}}"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "{\n",
    "    name: {\n",
    "        \"in_available_matrices\": name in db.available_matrices(),\n",
    "        \"hasattr\": hasattr(db, name),\n",
    "    }\n",
    "    for name in [\"A\", \"L\", \"z\", \"w\"]\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "c0359eb9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'A_equals_z': True,\n",
       " 'L_equals_w': True,\n",
       " 'query_A_equals_query_z': True,\n",
       " 'query_L_equals_query_w': True}"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "{\n",
    "    \"A_equals_z\": db.A.equals(db.z),\n",
    "    \"L_equals_w\": db.L.equals(db.w),\n",
    "    \"query_A_equals_query_z\": db.query(\"A\").equals(db.query(\"z\")),\n",
    "    \"query_L_equals_query_w\": db.query(\"L\").equals(db.query(\"w\")),\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "a23d2ec9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr:last-of-type th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>Region</th>\n",
       "      <th colspan=\"3\" halign=\"left\">Reg1</th>\n",
       "      <th colspan=\"3\" halign=\"left\">Reg2</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>Level</th>\n",
       "      <th colspan=\"3\" halign=\"left\">Sector</th>\n",
       "      <th colspan=\"3\" halign=\"left\">Sector</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>Item</th>\n",
       "      <th>Agriculture</th>\n",
       "      <th>Industry</th>\n",
       "      <th>Services</th>\n",
       "      <th>Agriculture</th>\n",
       "      <th>Industry</th>\n",
       "      <th>Services</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Region</th>\n",
       "      <th>Level</th>\n",
       "      <th>Item</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">Reg1</th>\n",
       "      <th rowspan=\"3\" valign=\"top\">Sector</th>\n",
       "      <th>Agriculture</th>\n",
       "      <td>0.093346</td>\n",
       "      <td>0.100871</td>\n",
       "      <td>0.010290</td>\n",
       "      <td>0.029593</td>\n",
       "      <td>0.042325</td>\n",
       "      <td>0.004276</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Industry</th>\n",
       "      <td>0.112553</td>\n",
       "      <td>0.431001</td>\n",
       "      <td>0.101928</td>\n",
       "      <td>0.017704</td>\n",
       "      <td>0.112831</td>\n",
       "      <td>0.012555</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Services</th>\n",
       "      <td>0.189887</td>\n",
       "      <td>0.183327</td>\n",
       "      <td>0.292816</td>\n",
       "      <td>0.016302</td>\n",
       "      <td>0.023262</td>\n",
       "      <td>0.024197</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">Reg2</th>\n",
       "      <th rowspan=\"2\" valign=\"top\">Sector</th>\n",
       "      <th>Agriculture</th>\n",
       "      <td>0.000042</td>\n",
       "      <td>0.000049</td>\n",
       "      <td>0.000008</td>\n",
       "      <td>0.037102</td>\n",
       "      <td>0.025621</td>\n",
       "      <td>0.003292</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Industry</th>\n",
       "      <td>0.000691</td>\n",
       "      <td>0.002514</td>\n",
       "      <td>0.000627</td>\n",
       "      <td>0.121941</td>\n",
       "      <td>0.240282</td>\n",
       "      <td>0.066618</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "Region                           Reg1                            Reg2  \\\n",
       "Level                          Sector                          Sector   \n",
       "Item                      Agriculture  Industry  Services Agriculture   \n",
       "Region Level  Item                                                      \n",
       "Reg1   Sector Agriculture    0.093346  0.100871  0.010290    0.029593   \n",
       "              Industry       0.112553  0.431001  0.101928    0.017704   \n",
       "              Services       0.189887  0.183327  0.292816    0.016302   \n",
       "Reg2   Sector Agriculture    0.000042  0.000049  0.000008    0.037102   \n",
       "              Industry       0.000691  0.002514  0.000627    0.121941   \n",
       "\n",
       "Region                                         \n",
       "Level                                          \n",
       "Item                       Industry  Services  \n",
       "Region Level  Item                             \n",
       "Reg1   Sector Agriculture  0.042325  0.004276  \n",
       "              Industry     0.112831  0.012555  \n",
       "              Services     0.023262  0.024197  \n",
       "Reg2   Sector Agriculture  0.025621  0.003292  \n",
       "              Industry     0.240282  0.066618  "
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "db.A.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "5868cbe7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr:last-of-type th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>Region</th>\n",
       "      <th colspan=\"3\" halign=\"left\">Reg1</th>\n",
       "      <th colspan=\"3\" halign=\"left\">Reg2</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>Level</th>\n",
       "      <th colspan=\"3\" halign=\"left\">Sector</th>\n",
       "      <th colspan=\"3\" halign=\"left\">Sector</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>Item</th>\n",
       "      <th>Agriculture</th>\n",
       "      <th>Industry</th>\n",
       "      <th>Services</th>\n",
       "      <th>Agriculture</th>\n",
       "      <th>Industry</th>\n",
       "      <th>Services</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Region</th>\n",
       "      <th>Level</th>\n",
       "      <th>Item</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">Reg1</th>\n",
       "      <th rowspan=\"3\" valign=\"top\">Sector</th>\n",
       "      <th>Agriculture</th>\n",
       "      <td>1.140207</td>\n",
       "      <td>0.218134</td>\n",
       "      <td>0.048139</td>\n",
       "      <td>0.058437</td>\n",
       "      <td>0.107265</td>\n",
       "      <td>0.022977</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Industry</th>\n",
       "      <td>0.294625</td>\n",
       "      <td>1.901016</td>\n",
       "      <td>0.278625</td>\n",
       "      <td>0.108426</td>\n",
       "      <td>0.337764</td>\n",
       "      <td>0.078021</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Services</th>\n",
       "      <td>0.382674</td>\n",
       "      <td>0.551766</td>\n",
       "      <td>1.499358</td>\n",
       "      <td>0.087775</td>\n",
       "      <td>0.180144</td>\n",
       "      <td>0.081452</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">Reg2</th>\n",
       "      <th rowspan=\"2\" valign=\"top\">Sector</th>\n",
       "      <th>Agriculture</th>\n",
       "      <td>0.000139</td>\n",
       "      <td>0.000320</td>\n",
       "      <td>0.000098</td>\n",
       "      <td>1.045241</td>\n",
       "      <td>0.038248</td>\n",
       "      <td>0.008548</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Industry</th>\n",
       "      <td>0.002486</td>\n",
       "      <td>0.007343</td>\n",
       "      <td>0.002380</td>\n",
       "      <td>0.202161</td>\n",
       "      <td>1.369527</td>\n",
       "      <td>0.131244</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "Region                           Reg1                            Reg2  \\\n",
       "Level                          Sector                          Sector   \n",
       "Item                      Agriculture  Industry  Services Agriculture   \n",
       "Region Level  Item                                                      \n",
       "Reg1   Sector Agriculture    1.140207  0.218134  0.048139    0.058437   \n",
       "              Industry       0.294625  1.901016  0.278625    0.108426   \n",
       "              Services       0.382674  0.551766  1.499358    0.087775   \n",
       "Reg2   Sector Agriculture    0.000139  0.000320  0.000098    1.045241   \n",
       "              Industry       0.002486  0.007343  0.002380    0.202161   \n",
       "\n",
       "Region                                         \n",
       "Level                                          \n",
       "Item                       Industry  Services  \n",
       "Region Level  Item                             \n",
       "Reg1   Sector Agriculture  0.107265  0.022977  \n",
       "              Industry     0.337764  0.078021  \n",
       "              Services     0.180144  0.081452  \n",
       "Reg2   Sector Agriculture  0.038248  0.008548  \n",
       "              Industry     1.369527  0.131244  "
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "db.L.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3ebbd6ec",
   "metadata": {},
   "source": [
    "The current behavior is therefore:\n",
    "\n",
    "- `index_aliases` changes what users can pass to methods such as `get_index(...)` and dotted set access like `db.Industry`.\n",
    "- `nomenclature` changes the public matrix names, so `db.A` and `db.query(\"A\")` resolve the same matrix as `db.z` and `db.query(\"z\")`.\n",
    "- Existing built-in matrix names remain reserved, so relabeling one matrix to the name of another built-in matrix raises an error."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "262b0eb0",
   "metadata": {},
   "source": [
    "## Reserved names are blocked\n",
    "\n",
    "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."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b67891a4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'blocked_error': \"The nomenclature label 'f' for 'z' is blocked because 'f' is already a reserved built-in matrix name.\",\n",
       " 'restored': ('z', 'w')}"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "blocked_settings = deepcopy(previous_settings)\n",
    "blocked_settings[\"nomenclature\"][\"z\"] = \"f\"\n",
    "\n",
    "try:\n",
    "    mario.upload_settings(blocked_settings)\n",
    "except Exception as exc:\n",
    "    blocked_error = str(exc)\n",
    "\n",
    "blocked_error"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "011f620f",
   "metadata": {},
   "source": [
    "## Restore the original settings\n",
    "\n",
    "The custom labels used in this tutorial persist until they are overwritten again or reset, so the last step restores the initial configuration explicitly."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0ea34949",
   "metadata": {},
   "outputs": [],
   "source": [
    "mario.upload_settings(previous_settings)\n",
    "{\n",
    "    \"restored\": (\n",
    "        mario.download_settings(None)[\"nomenclature\"][\"z\"],\n",
    "        mario.download_settings(None)[\"nomenclature\"][\"w\"],\n",
    "    ),\n",
    "    \"sector_aliases\": mario.download_settings(None)[\"index_aliases\"][\"s\"],\n",
    "}"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "mario",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
