From f5fd955781f5bcbfb5e881256ab1649a81099a62 Mon Sep 17 00:00:00 2001 From: ekatef Date: Mon, 12 Aug 2024 00:32:24 +0200 Subject: [PATCH] Add a notebook to investigate the reasons of the objectives difference --- .../workflow_testing/compare_networks.ipynb | 904 ++++++++++++++++++ 1 file changed, 904 insertions(+) create mode 100644 notebooks/workflow_testing/compare_networks.ipynb diff --git a/notebooks/workflow_testing/compare_networks.ipynb b/notebooks/workflow_testing/compare_networks.ipynb new file mode 100644 index 0000000..610f590 --- /dev/null +++ b/notebooks/workflow_testing/compare_networks.ipynb @@ -0,0 +1,904 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "~/opt/miniconda3/envs/pypsa-earth-old3/lib/python3.10/site-packages/pypsa/networkclustering.py:16: UserWarning: The namespace `pypsa.networkclustering` is deprecated and will be removed in PyPSA v0.24. Please use `pypsa.clustering.spatial instead`. \n", + " warnings.warn(\n" + ] + } + ], + "source": [ + "import pypsa\n", + "import pandas as pd" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "old_netw_path = \"KZ_base_main/networks/\"\n", + "new_netw_path = \"KZ_pypsa_vnom_fix/networks/\"\n", + "\n", + "n_name = \"elec_s_10_ec_lcopt_Co2L-3H.nc\"\n", + "\n", + "# it can make sense to investigate outputs of the workflow step-by-step\n", + "# to locate the point from where the discrepancies originate\n", + "# n_name = \"base.nc\"\n", + "# n_name = \"elec.nc\"\n", + "# n_name = \"elec_s.nc\"\n", + "# n_name = \"elec_s_10.nc\"\n", + "#n_name = \"elec_s_10_ec_lcopt_Co2L-3H.nc\"\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "~/opt/miniconda3/envs/pypsa-earth-old3/lib/python3.10/site-packages/pypsa/components.py:318: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value '[]' has dtype incompatible with float64, please explicitly cast to a compatible dtype first.\n", + " attrs.loc[bool_b, \"default\"] = attrs.loc[bool_b].isin({True, \"True\"})\n", + "~/opt/miniconda3/envs/pypsa-earth-old3/lib/python3.10/site-packages/pypsa/components.py:318: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value '[]' has dtype incompatible with float64, please explicitly cast to a compatible dtype first.\n", + " attrs.loc[bool_b, \"default\"] = attrs.loc[bool_b].isin({True, \"True\"})\n", + "~/opt/miniconda3/envs/pypsa-earth-old3/lib/python3.10/site-packages/pypsa/components.py:318: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value '[]' has dtype incompatible with float64, please explicitly cast to a compatible dtype first.\n", + " attrs.loc[bool_b, \"default\"] = attrs.loc[bool_b].isin({True, \"True\"})\n", + "~/opt/miniconda3/envs/pypsa-earth-old3/lib/python3.10/site-packages/pypsa/components.py:318: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value '[]' has dtype incompatible with float64, please explicitly cast to a compatible dtype first.\n", + " attrs.loc[bool_b, \"default\"] = attrs.loc[bool_b].isin({True, \"True\"})\n", + "INFO:pypsa.io:Imported network elec_s_10_ec_lcopt_Co2L-3H.nc has buses, carriers, generators, global_constraints, lines, links, loads, storage_units, stores\n", + "~/opt/miniconda3/envs/pypsa-earth-old3/lib/python3.10/site-packages/pypsa/components.py:318: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value '[]' has dtype incompatible with float64, please explicitly cast to a compatible dtype first.\n", + " attrs.loc[bool_b, \"default\"] = attrs.loc[bool_b].isin({True, \"True\"})\n", + "~/opt/miniconda3/envs/pypsa-earth-old3/lib/python3.10/site-packages/pypsa/components.py:318: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value '[]' has dtype incompatible with float64, please explicitly cast to a compatible dtype first.\n", + " attrs.loc[bool_b, \"default\"] = attrs.loc[bool_b].isin({True, \"True\"})\n", + "~/opt/miniconda3/envs/pypsa-earth-old3/lib/python3.10/site-packages/pypsa/components.py:318: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value '[]' has dtype incompatible with float64, please explicitly cast to a compatible dtype first.\n", + " attrs.loc[bool_b, \"default\"] = attrs.loc[bool_b].isin({True, \"True\"})\n", + "~/opt/miniconda3/envs/pypsa-earth-old3/lib/python3.10/site-packages/pypsa/components.py:318: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value '[]' has dtype incompatible with float64, please explicitly cast to a compatible dtype first.\n", + " attrs.loc[bool_b, \"default\"] = attrs.loc[bool_b].isin({True, \"True\"})\n", + "INFO:pypsa.io:Imported network elec_s_10_ec_lcopt_Co2L-3H.nc has buses, carriers, generators, global_constraints, lines, links, loads, storage_units, stores\n" + ] + } + ], + "source": [ + "old_network = pypsa.Network(old_netw_path + n_name)\n", + "new_network = pypsa.Network(new_netw_path + n_name)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Setup comparison" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Define the columns to compare across the component dataframes:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "#gen_cols_to_compare = [\"p_nom\", \"marginal_cost\"]\n", + "\n", + "gen_cols_to_compare = [\"p_nom_opt\"]\n", + "\n", + "#['p_nom_min', 'p_nom',\n", + "# 'efficiency', 'marginal_cost', 'capital_cost', 'build_year', 'lifetime',\n", + "# 'p_nom_max', 'weight', 'control', 'type', 'p_min_pu', 'p_max_pu',\n", + "# 'p_set']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Evaluate the differences across the components:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "gen_diff_df = (\n", + " new_network.generators[gen_cols_to_compare] - old_network.generators[gen_cols_to_compare]\n", + ")\n", + "#lin_diff_df = (\n", + "# new_network.lines[gen_cols_to_compare] - old_network.lines[gen_cols_to_compare] > 0\n", + "#)\n", + "#bus_diff_df = (\n", + "# new_network.buses[gen_cols_to_compare] - old_network.buses[gen_cols_to_compare] > 0\n", + "#)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Investigate differences in components structure" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The differences are possible as PyPSA has different clustering behaviour in different versions, which also related dropping some columns" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['lat', 'lon', 'tag_area', 'tag_substation'], dtype='object')" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "new_network.buses.columns.symmetric_difference(old_network.buses.columns)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['bounds', 'country', 'dc', 'geometry', 'i_nom', 'tag_frequency',\n", + " 'tag_type', 'under_construction', 'underground', 'underwater_fraction'],\n", + " dtype='object')" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "new_network.lines.columns.symmetric_difference(old_network.lines.columns)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Index([], dtype='object')" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "old_network.lines.columns.difference(new_network.lines.columns)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['bounds', 'country', 'dc', 'geometry', 'i_nom', 'tag_frequency',\n", + " 'tag_type', 'under_construction', 'underground', 'underwater_fraction'],\n", + " dtype='object')" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "new_network.lines.columns.difference(old_network.lines.columns)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Check spartial correspondance" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
xy
Bus
KZ0 070.84778752.451315
KZ0 176.82782043.618933
KZ0 265.29460046.024153
KZ0 370.47022542.780110
KZ0 480.18198849.990818
\n", + "
" + ], + "text/plain": [ + " x y\n", + "Bus \n", + "KZ0 0 70.847787 52.451315\n", + "KZ0 1 76.827820 43.618933\n", + "KZ0 2 65.294600 46.024153\n", + "KZ0 3 70.470225 42.780110\n", + "KZ0 4 80.181988 49.990818" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "old_network.buses[[\"x\", \"y\"]].head(5)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
xy
Bus
KZ0 070.84778752.451315
KZ0 176.82782043.618933
KZ0 265.29460046.024153
KZ0 370.47022542.780110
KZ0 480.18198849.990818
\n", + "
" + ], + "text/plain": [ + " x y\n", + "Bus \n", + "KZ0 0 70.847787 52.451315\n", + "KZ0 1 76.827820 43.618933\n", + "KZ0 2 65.294600 46.024153\n", + "KZ0 3 70.470225 42.780110\n", + "KZ0 4 80.181988 49.990818" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "new_network.buses[[\"x\", \"y\"]].head(5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Check columns values" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([380., 1.])" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "new_network.buses[\"v_nom\"].unique()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array(['Al/St 240/40 4-bundle 380.0'], dtype=object)" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "new_network.lines[\"type\"].unique()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([380.])" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "new_network.lines[\"v_nom\"].unique()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Evaluate differences by components" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "length -2.268877e-16\n", + "dtype: float64" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(\n", + " old_network.lines[[\"length\"]].sum() \n", + " - new_network.lines[[\"length\"]].sum()\n", + ")/old_network.lines[[\"length\"]].sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "capital_cost 0.000088\n", + "dtype: float64" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(\n", + " old_network.lines[[\"capital_cost\"]].sum() \n", + " - new_network.lines[[\"capital_cost\"]].sum()\n", + ")/old_network.lines[[\"capital_cost\"]].sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "s_nom_opt 2.755005e-16\n", + "dtype: float64" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(\n", + " old_network.lines[[\"s_nom_opt\"]].sum() \n", + " - new_network.lines[[\"s_nom_opt\"]].sum()\n", + ")/old_network.lines[[\"s_nom_opt\"]].sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "s_nom -1.377502e-16\n", + "dtype: float64" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(\n", + " old_network.lines[[\"s_nom\"]].sum() \n", + " - new_network.lines[[\"s_nom\"]].sum()\n", + ")/old_network.lines[[\"s_nom\"]].sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "s_nom -1.455192e-11\n", + "dtype: float64" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(\n", + " old_network.lines[[\"s_nom\"]].sum() \n", + " - new_network.lines[[\"s_nom\"]].sum()\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Sometimes, it can be handy to compare the sums (e.g. if there are some issues with the spartial correspondance):" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "s_nom_opt 105639.857\n", + "dtype: float64" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "old_network.lines[[\"s_nom_opt\"]].sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "s_nom_opt 2.755005e-16\n", + "dtype: float64" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(\n", + " old_network.lines[[\"s_nom_opt\"]].sum() \n", + " - new_network.lines[[\"s_nom_opt\"]].sum()\n", + ")/old_network.lines[[\"s_nom_opt\"]].sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "p_nom_opt 5.248590e-08\n", + "dtype: float64" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(\n", + " old_network.generators[[\"p_nom_opt\"]].sum() \n", + " - new_network.generators[[\"p_nom_opt\"]].sum()\n", + ")/old_network.generators[[\"p_nom_opt\"]].sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "capital_cost 0.007295\n", + "dtype: float64" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(\n", + " old_network.generators[[\"capital_cost\"]].sum() \n", + " - new_network.generators[[\"capital_cost\"]].sum()\n", + ")/old_network.generators[[\"capital_cost\"]].sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "marginal_cost 0.000008\n", + "dtype: float64" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(\n", + " old_network.generators[[\"marginal_cost\"]].sum() \n", + " - new_network.generators[[\"marginal_cost\"]].sum()\n", + ")/old_network.generators[[\"marginal_cost\"]].sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.0" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "old_network.stores.p_set.sum() " + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.0" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "new_network.stores.p_set.sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-0.42572341171129463" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(\n", + " old_network.stores.e_nom_opt.sum() \n", + " - new_network.stores.e_nom_opt.sum()\n", + ")/old_network.stores.e_nom_opt.sum() " + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "450100.0493011138" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "old_network.stores.capital_cost.sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-0.004478008285199519" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(\n", + " old_network.stores.marginal_cost.sum() \n", + " - new_network.stores.marginal_cost.sum()\n", + ")/old_network.stores.marginal_cost.sum() " + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.0" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(\n", + " old_network.stores.capital_cost.sum() \n", + " - new_network.stores.capital_cost.sum()\n", + ")/old_network.stores.capital_cost.sum() " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A more detailed assesment may be needed to investigate the source of the identified differences:" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "capital_cost 15103.536874\n", + "dtype: float64" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(\n", + " old_network.generators[old_network.generators.carrier.isin([\"offwind-ac\"])][[\"capital_cost\"]]\n", + " - new_network.generators[new_network.generators.carrier.isin([\"offwind-ac\"])][[\"capital_cost\"]]\n", + ").sum()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "pypsa-earth-old", + "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.10.14" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}