From 4f3db1828cba656dbdecbb6cad07d48fc003a0dd Mon Sep 17 00:00:00 2001 From: Muhammad Yasirroni Date: Fri, 16 Jan 2026 12:10:40 +1100 Subject: [PATCH 1/6] update to use uv and pru v0.0.4 --- CONTRIBUTING.md | 5 ++--- pyproject.toml | 10 +++++----- requirements-all.txt | 8 ++++---- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4c20be2..ab189dc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,20 +5,19 @@ ```sh uv venv env --python 3.14 source env/bin/activate -uv pip install pip ``` ## packages ```sh -pip install pru +uv pip install pru pru -r requirements-all.txt ``` ## Install in development mode ```shell -pip install -e ."[dev]" +uv pip install -e ."[dev]" ``` ## Pytest diff --git a/pyproject.toml b/pyproject.toml index 1cb39d7..428e823 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,11 +46,11 @@ dev = [ "oct2py>=5.5.1", # latest support for 3.7 "openpyxl>=3.1.2", "pandas>=1.2.0", - "pre-commit>=2.21.0", - "pytest>=7.2.0", - "pytest-cov>=4.0.0", - "pytest-xdist>=3.1.0", - "ruff>=0.6.4", + "pre-commit>=3.8.0", + "pytest>=9.0.2", + "pytest-cov>=7.0.0", + "pytest-xdist>=3.8.0", + "ruff>=0.14.10", ] [project.urls] diff --git a/requirements-all.txt b/requirements-all.txt index 4513486..2950b7a 100644 --- a/requirements-all.txt +++ b/requirements-all.txt @@ -1,13 +1,13 @@ -pandas==2.3.3 -numpy==2.4.0 +pandas==3.0.0rc1 +numpy==2.4.1 openpyxl==3.1.5 oct2py==5.8.0 matpower==8.1.0.2.2.3 -pre-commit==3.8.0 -ruff==0.14.10 +pre-commit==4.5.1 +ruff==0.14.13 setuptools==80.9.0 pytest==9.0.2 From 99573345609f772cd451d99ebc0dc77caec96baa Mon Sep 17 00:00:00 2001 From: Muhammad Yasirroni Date: Fri, 16 Jan 2026 13:12:26 +1100 Subject: [PATCH 2/6] add index name --- matpowercaseframes/core.py | 17 +- notebooks/load_case9.ipynb | 1538 ++++++++++++++++++++++++++++++++++++ 2 files changed, 1552 insertions(+), 3 deletions(-) create mode 100644 notebooks/load_case9.ipynb diff --git a/matpowercaseframes/core.py b/matpowercaseframes/core.py index fa71eb1..bb7d34c 100644 --- a/matpowercaseframes/core.py +++ b/matpowercaseframes/core.py @@ -510,7 +510,7 @@ def _update_index(self, allow_any_keys=False): attribute_data.set_index(attribute_name_data, drop=False, inplace=True) except AttributeError: attribute_data.set_index( - pd.RangeIndex(1, len(attribute_data.index) + 1), + pd.RangeIndex(1, len(attribute_data.index) + 1, name=attribute), drop=False, inplace=True, ) @@ -521,7 +521,9 @@ def _update_index(self, allow_any_keys=False): self.gencost.set_index(self.gen_name, drop=False, inplace=True) else: self.gencost.set_index( - pd.RangeIndex(1, len(self.gen.index) + 1), drop=False, inplace=True + pd.RangeIndex(1, len(self.gen.index) + 1, name="gen"), + drop=False, + inplace=True, ) except AttributeError: pass @@ -537,11 +539,16 @@ def _update_index(self, allow_any_keys=False): if attribute_data.index.dtype == int: # replace the index with a new RangeIndex starting at 1 attribute_data.set_index( - pd.RangeIndex(start=1, stop=len(attribute_data) + 1), + pd.RangeIndex( + start=1, stop=len(attribute_data) + 1, name=attribute + ), drop=False, inplace=True, ) + # TODO: + # For mpc.reserves.zones, the columns use cf.gen.index. + def infer_numpy(self): """ Infer and convert data types in all DataFrames to appropriate NumPy-compatible @@ -608,6 +615,10 @@ def reset_index(self): ) self.gen["GEN_BUS"] = self.gen["GEN_BUS"].replace(bus_map) + # TODO: + # Since mpc.reserves.zones columns use cf.gen.index, don't forget to update + # the columns of mpc.reserves.zones if exists. + def add_schema_case(self, F=None): # add case to follow casefromat/schema # !WARNING: diff --git a/notebooks/load_case9.ipynb b/notebooks/load_case9.ipynb new file mode 100644 index 0000000..93f3870 --- /dev/null +++ b/notebooks/load_case9.ipynb @@ -0,0 +1,1538 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The autoreload extension is already loaded. To reload it, use:\n", + " %reload_ext autoreload\n" + ] + } + ], + "source": [ + "%load_ext autoreload\n", + "%autoreload 2" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "from matpower import start_instance\n", + "\n", + "from matpowercaseframes import CaseFrames" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "m = start_instance()" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "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", + " \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", + " \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", + " \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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
F_BUST_BUSBR_RBR_XBR_BRATE_ARATE_BRATE_CTAPSHIFTBR_STATUSANGMINANGMAX
branch
1140.00000.05760.000250250250001-360360
2450.01700.09200.158250250250001-360360
3560.03900.17000.358150150150001-360360
4360.00000.05860.000300300300001-360360
5670.01190.10080.209150150150001-360360
6780.00850.07200.149250250250001-360360
7820.00000.06250.000250250250001-360360
8890.03200.16100.306250250250001-360360
9940.01000.08500.176250250250001-360360
\n", + "
" + ], + "text/plain": [ + " F_BUS T_BUS BR_R BR_X BR_B RATE_A RATE_B RATE_C TAP \\\n", + "branch \n", + "1 1 4 0.0000 0.0576 0.000 250 250 250 0 \n", + "2 4 5 0.0170 0.0920 0.158 250 250 250 0 \n", + "3 5 6 0.0390 0.1700 0.358 150 150 150 0 \n", + "4 3 6 0.0000 0.0586 0.000 300 300 300 0 \n", + "5 6 7 0.0119 0.1008 0.209 150 150 150 0 \n", + "6 7 8 0.0085 0.0720 0.149 250 250 250 0 \n", + "7 8 2 0.0000 0.0625 0.000 250 250 250 0 \n", + "8 8 9 0.0320 0.1610 0.306 250 250 250 0 \n", + "9 9 4 0.0100 0.0850 0.176 250 250 250 0 \n", + "\n", + " SHIFT BR_STATUS ANGMIN ANGMAX \n", + "branch \n", + "1 0 1 -360 360 \n", + "2 0 1 -360 360 \n", + "3 0 1 -360 360 \n", + "4 0 1 -360 360 \n", + "5 0 1 -360 360 \n", + "6 0 1 -360 360 \n", + "7 0 1 -360 360 \n", + "8 0 1 -360 360 \n", + "9 0 1 -360 360 " + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "CASE_NAME = \"case9.m\"\n", + "cf_9 = CaseFrames(CASE_NAME)\n", + "cf_9.infer_numpy()\n", + "cf_9.branch" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "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", + " \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", + " \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", + " \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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
F_BUST_BUSBR_RBR_XBR_BRATE_ARATE_BRATE_CTAPSHIFTBR_STATUSANGMINANGMAX
branch
1140.00000.05760.000250250250001-360360
2450.01700.09200.158250250250001-360360
3560.03900.17000.358150150150001-360360
4360.00000.05860.000300300300001-360360
5670.01190.10080.209150150150001-360360
6780.00850.07200.149250250250001-360360
7820.00000.06250.000250250250001-360360
8890.03200.16100.306250250250001-360360
9940.01000.08500.176250250250001-360360
\n", + "
" + ], + "text/plain": [ + " F_BUS T_BUS BR_R BR_X BR_B RATE_A RATE_B RATE_C TAP \\\n", + "branch \n", + "1 1 4 0.0000 0.0576 0.000 250 250 250 0 \n", + "2 4 5 0.0170 0.0920 0.158 250 250 250 0 \n", + "3 5 6 0.0390 0.1700 0.358 150 150 150 0 \n", + "4 3 6 0.0000 0.0586 0.000 300 300 300 0 \n", + "5 6 7 0.0119 0.1008 0.209 150 150 150 0 \n", + "6 7 8 0.0085 0.0720 0.149 250 250 250 0 \n", + "7 8 2 0.0000 0.0625 0.000 250 250 250 0 \n", + "8 8 9 0.0320 0.1610 0.306 250 250 250 0 \n", + "9 9 4 0.0100 0.0850 0.176 250 250 250 0 \n", + "\n", + " SHIFT BR_STATUS ANGMIN ANGMAX \n", + "branch \n", + "1 0 1 -360 360 \n", + "2 0 1 -360 360 \n", + "3 0 1 -360 360 \n", + "4 0 1 -360 360 \n", + "5 0 1 -360 360 \n", + "6 0 1 -360 360 \n", + "7 0 1 -360 360 \n", + "8 0 1 -360 360 \n", + "9 0 1 -360 360 " + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "CASE_NAME = \"case9.m\"\n", + "cf_9_lc = CaseFrames(CASE_NAME, load_case_engine=m)\n", + "cf_9_lc.infer_numpy()\n", + "cf_9_lc.branch" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "MATPOWER Version 8.1, 12-Jul-2025\n", + "Power Flow -- AC-polar-power formulation\n", + "\n", + "Newton's method converged in 4 iterations.\n", + "PF successful\n", + "\n", + "Converged in 0.09 seconds\n", + "================================================================================\n", + "| System Summary |\n", + "================================================================================\n", + "\n", + "How many? How much? P (MW) Q (MVAr)\n", + "--------------------- ------------------- ------------- -----------------\n", + "Buses 9 Total Gen Capacity 820.0 -900.0 to 900.0\n", + "Generators 3 On-line Capacity 820.0 -900.0 to 900.0\n", + "Committed Gens 3 Generation (actual) 319.6 22.8\n", + "Loads 3 Load 315.0 115.0\n", + " Fixed 3 Fixed 315.0 115.0\n", + " Dispatchable 0 Dispatchable -0.0 of -0.0 -0.0\n", + "Shunts 0 Shunt (inj) -0.0 0.0\n", + "Branches 9 Losses (I^2 * Z) 4.64 48.38\n", + "Transformers 0 Branch Charging (inj) - 140.5\n", + "Inter-ties 0 Total Inter-tie Flow 0.0 0.0\n", + "Areas 1\n", + "\n", + " Minimum Maximum\n", + " ------------------------- --------------------------------\n", + "Voltage Magnitude 0.996 p.u. @ bus 9 1.040 p.u. @ bus 1\n", + "Voltage Angle -3.99 deg @ bus 9 9.28 deg @ bus 2\n", + "P Losses (I^2*R) - 2.30 MW @ line 8-9\n", + "Q Losses (I^2*X) - 15.83 MVAr @ line 8-2\n", + "\n", + "================================================================================\n", + "| Bus Data |\n", + "================================================================================\n", + " Bus Voltage Generation Load\n", + " # Mag(pu) Ang(deg) P (MW) Q (MVAr) P (MW) Q (MVAr)\n", + "----- ------- -------- -------- -------- -------- --------\n", + " 1 1.040 0.000* 71.64 27.05 - -\n", + " 2 1.025 9.280 163.00 6.65 - -\n", + " 3 1.025 4.665 85.00 -10.86 - -\n", + " 4 1.026 -2.217 - - - -\n", + " 5 1.013 -3.687 - - 90.00 30.00\n", + " 6 1.032 1.967 - - - -\n", + " 7 1.016 0.728 - - 100.00 35.00\n", + " 8 1.026 3.720 - - - -\n", + " 9 0.996 -3.989 - - 125.00 50.00\n", + " -------- -------- -------- --------\n", + " Total: 319.64 22.84 315.00 115.00\n", + "\n", + "================================================================================\n", + "| Branch Data |\n", + "================================================================================\n", + "Brnch From To From Bus Injection To Bus Injection Loss (I^2 * Z)\n", + " # Bus Bus P (MW) Q (MVAr) P (MW) Q (MVAr) P (MW) Q (MVAr)\n", + "----- ----- ----- -------- -------- -------- -------- -------- --------\n", + " 1 1 4 71.64 27.05 -71.64 -23.92 0.000 3.12\n", + " 2 4 5 30.70 1.03 -30.54 -16.54 0.166 0.90\n", + " 3 5 6 -59.46 -13.46 60.82 -18.07 1.354 5.90\n", + " 4 3 6 85.00 -10.86 -85.00 14.96 0.000 4.10\n", + " 5 6 7 24.18 3.12 -24.10 -24.30 0.088 0.75\n", + " 6 7 8 -75.90 -10.70 76.38 -0.80 0.475 4.03\n", + " 7 8 2 -163.00 9.18 163.00 6.65 0.000 15.83\n", + " 8 8 9 86.62 -8.38 -84.32 -11.31 2.300 11.57\n", + " 9 9 4 -40.68 -38.69 40.94 22.89 0.258 2.19\n", + " -------- --------\n", + " Total: 4.641 48.38\n" + ] + } + ], + "source": [ + "mpc = cf_9.to_mpc()\n", + "_ = m.runpf(mpc)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "MATPOWER Version 8.1, 12-Jul-2025\n", + "Power Flow -- AC-polar-power formulation\n", + "\n", + "Newton's method converged in 4 iterations.\n", + "PF successful\n", + "\n", + "Converged in 0.04 seconds\n", + "================================================================================\n", + "| System Summary |\n", + "================================================================================\n", + "\n", + "How many? How much? P (MW) Q (MVAr)\n", + "--------------------- ------------------- ------------- -----------------\n", + "Buses 9 Total Gen Capacity 820.0 -900.0 to 900.0\n", + "Generators 3 On-line Capacity 820.0 -900.0 to 900.0\n", + "Committed Gens 3 Generation (actual) 319.6 22.8\n", + "Loads 3 Load 315.0 115.0\n", + " Fixed 3 Fixed 315.0 115.0\n", + " Dispatchable 0 Dispatchable -0.0 of -0.0 -0.0\n", + "Shunts 0 Shunt (inj) -0.0 0.0\n", + "Branches 9 Losses (I^2 * Z) 4.64 48.38\n", + "Transformers 0 Branch Charging (inj) - 140.5\n", + "Inter-ties 0 Total Inter-tie Flow 0.0 0.0\n", + "Areas 1\n", + "\n", + " Minimum Maximum\n", + " ------------------------- --------------------------------\n", + "Voltage Magnitude 0.996 p.u. @ bus 9 1.040 p.u. @ bus 1\n", + "Voltage Angle -3.99 deg @ bus 9 9.28 deg @ bus 2\n", + "P Losses (I^2*R) - 2.30 MW @ line 8-9\n", + "Q Losses (I^2*X) - 15.83 MVAr @ line 8-2\n", + "\n", + "================================================================================\n", + "| Bus Data |\n", + "================================================================================\n", + " Bus Voltage Generation Load\n", + " # Mag(pu) Ang(deg) P (MW) Q (MVAr) P (MW) Q (MVAr)\n", + "----- ------- -------- -------- -------- -------- --------\n", + " 1 1.040 0.000* 71.64 27.05 - -\n", + " 2 1.025 9.280 163.00 6.65 - -\n", + " 3 1.025 4.665 85.00 -10.86 - -\n", + " 4 1.026 -2.217 - - - -\n", + " 5 1.013 -3.687 - - 90.00 30.00\n", + " 6 1.032 1.967 - - - -\n", + " 7 1.016 0.728 - - 100.00 35.00\n", + " 8 1.026 3.720 - - - -\n", + " 9 0.996 -3.989 - - 125.00 50.00\n", + " -------- -------- -------- --------\n", + " Total: 319.64 22.84 315.00 115.00\n", + "\n", + "================================================================================\n", + "| Branch Data |\n", + "================================================================================\n", + "Brnch From To From Bus Injection To Bus Injection Loss (I^2 * Z)\n", + " # Bus Bus P (MW) Q (MVAr) P (MW) Q (MVAr) P (MW) Q (MVAr)\n", + "----- ----- ----- -------- -------- -------- -------- -------- --------\n", + " 1 1 4 71.64 27.05 -71.64 -23.92 0.000 3.12\n", + " 2 4 5 30.70 1.03 -30.54 -16.54 0.166 0.90\n", + " 3 5 6 -59.46 -13.46 60.82 -18.07 1.354 5.90\n", + " 4 3 6 85.00 -10.86 -85.00 14.96 0.000 4.10\n", + " 5 6 7 24.18 3.12 -24.10 -24.30 0.088 0.75\n", + " 6 7 8 -75.90 -10.70 76.38 -0.80 0.475 4.03\n", + " 7 8 2 -163.00 9.18 163.00 6.65 0.000 15.83\n", + " 8 8 9 86.62 -8.38 -84.32 -11.31 2.300 11.57\n", + " 9 9 4 -40.68 -38.69 40.94 22.89 0.258 2.19\n", + " -------- --------\n", + " Total: 4.641 48.38\n" + ] + } + ], + "source": [ + "mpc = cf_9_lc.to_mpc()\n", + "_ = m.runpf(mpc)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'version'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'2'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'baseMVA'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "100" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'bus'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "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", + " \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", + " \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", + " \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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
BUS_IBUS_TYPEPDQDGSBSBUS_AREAVMVABASE_KVZONEVMAXVMIN
bus
113000011034511.10.9
222000011034511.10.9
332000011034511.10.9
441000011034511.10.9
55190300011034511.10.9
661000011034511.10.9
771100350011034511.10.9
881000011034511.10.9
991125500011034511.10.9
\n", + "
" + ], + "text/plain": [ + " BUS_I BUS_TYPE PD QD GS BS BUS_AREA VM VA BASE_KV ZONE VMAX \\\n", + "bus \n", + "1 1 3 0 0 0 0 1 1 0 345 1 1.1 \n", + "2 2 2 0 0 0 0 1 1 0 345 1 1.1 \n", + "3 3 2 0 0 0 0 1 1 0 345 1 1.1 \n", + "4 4 1 0 0 0 0 1 1 0 345 1 1.1 \n", + "5 5 1 90 30 0 0 1 1 0 345 1 1.1 \n", + "6 6 1 0 0 0 0 1 1 0 345 1 1.1 \n", + "7 7 1 100 35 0 0 1 1 0 345 1 1.1 \n", + "8 8 1 0 0 0 0 1 1 0 345 1 1.1 \n", + "9 9 1 125 50 0 0 1 1 0 345 1 1.1 \n", + "\n", + " VMIN \n", + "bus \n", + "1 0.9 \n", + "2 0.9 \n", + "3 0.9 \n", + "4 0.9 \n", + "5 0.9 \n", + "6 0.9 \n", + "7 0.9 \n", + "8 0.9 \n", + "9 0.9 " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'gen'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "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", + " \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", + " \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", + " \n", + "
GEN_BUSPGQGQMAXQMINVGMBASEGEN_STATUSPMAXPMIN...PC2QC1MINQC1MAXQC2MINQC2MAXRAMP_AGCRAMP_10RAMP_30RAMP_QAPF
gen
1172.327.03300-3001.040100125010...0000000000
22163.06.54300-3001.025100130010...0000000000
3385.0-10.95300-3001.025100127010...0000000000
\n", + "

3 rows × 21 columns

\n", + "
" + ], + "text/plain": [ + " GEN_BUS PG QG QMAX QMIN VG MBASE GEN_STATUS PMAX PMIN \\\n", + "gen \n", + "1 1 72.3 27.03 300 -300 1.040 100 1 250 10 \n", + "2 2 163.0 6.54 300 -300 1.025 100 1 300 10 \n", + "3 3 85.0 -10.95 300 -300 1.025 100 1 270 10 \n", + "\n", + " ... PC2 QC1MIN QC1MAX QC2MIN QC2MAX RAMP_AGC RAMP_10 RAMP_30 \\\n", + "gen ... \n", + "1 ... 0 0 0 0 0 0 0 0 \n", + "2 ... 0 0 0 0 0 0 0 0 \n", + "3 ... 0 0 0 0 0 0 0 0 \n", + "\n", + " RAMP_Q APF \n", + "gen \n", + "1 0 0 \n", + "2 0 0 \n", + "3 0 0 \n", + "\n", + "[3 rows x 21 columns]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'branch'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "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", + " \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", + " \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", + " \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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
F_BUST_BUSBR_RBR_XBR_BRATE_ARATE_BRATE_CTAPSHIFTBR_STATUSANGMINANGMAX
branch
1140.00000.05760.000250250250001-360360
2450.01700.09200.158250250250001-360360
3560.03900.17000.358150150150001-360360
4360.00000.05860.000300300300001-360360
5670.01190.10080.209150150150001-360360
6780.00850.07200.149250250250001-360360
7820.00000.06250.000250250250001-360360
8890.03200.16100.306250250250001-360360
9940.01000.08500.176250250250001-360360
\n", + "
" + ], + "text/plain": [ + " F_BUS T_BUS BR_R BR_X BR_B RATE_A RATE_B RATE_C TAP \\\n", + "branch \n", + "1 1 4 0.0000 0.0576 0.000 250 250 250 0 \n", + "2 4 5 0.0170 0.0920 0.158 250 250 250 0 \n", + "3 5 6 0.0390 0.1700 0.358 150 150 150 0 \n", + "4 3 6 0.0000 0.0586 0.000 300 300 300 0 \n", + "5 6 7 0.0119 0.1008 0.209 150 150 150 0 \n", + "6 7 8 0.0085 0.0720 0.149 250 250 250 0 \n", + "7 8 2 0.0000 0.0625 0.000 250 250 250 0 \n", + "8 8 9 0.0320 0.1610 0.306 250 250 250 0 \n", + "9 9 4 0.0100 0.0850 0.176 250 250 250 0 \n", + "\n", + " SHIFT BR_STATUS ANGMIN ANGMAX \n", + "branch \n", + "1 0 1 -360 360 \n", + "2 0 1 -360 360 \n", + "3 0 1 -360 360 \n", + "4 0 1 -360 360 \n", + "5 0 1 -360 360 \n", + "6 0 1 -360 360 \n", + "7 0 1 -360 360 \n", + "8 0 1 -360 360 \n", + "9 0 1 -360 360 " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'gencost'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
MODELSTARTUPSHUTDOWNNCOSTC2C1C0
gen
121500030.11005.0150
222000030.08501.2600
323000030.12251.0335
\n", + "
" + ], + "text/plain": [ + " MODEL STARTUP SHUTDOWN NCOST C2 C1 C0\n", + "gen \n", + "1 2 1500 0 3 0.1100 5.0 150\n", + "2 2 2000 0 3 0.0850 1.2 600\n", + "3 2 3000 0 3 0.1225 1.0 335" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "for attr in cf_9.attributes:\n", + " display(attr, getattr(cf_9, attr))" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [], + "source": [ + "m.exit()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "env", + "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.14.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 8a12de7e014067d71691f223b6030a9e91d677d3 Mon Sep 17 00:00:00 2001 From: Muhammad Yasirroni Date: Fri, 16 Jan 2026 17:36:41 +1100 Subject: [PATCH 3/6] add reserves in notebook --- notebooks/load_most_ex_case3a.ipynb | 1203 ++++++++++++++++++++++++ notebooks/load_t_case30_userfcns.ipynb | 878 +++++++++++++++++ 2 files changed, 2081 insertions(+) create mode 100644 notebooks/load_most_ex_case3a.ipynb create mode 100644 notebooks/load_t_case30_userfcns.ipynb diff --git a/notebooks/load_most_ex_case3a.ipynb b/notebooks/load_most_ex_case3a.ipynb new file mode 100644 index 0000000..cb7fc22 --- /dev/null +++ b/notebooks/load_most_ex_case3a.ipynb @@ -0,0 +1,1203 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "eae79aa2", + "metadata": {}, + "outputs": [], + "source": [ + "# # install octave\n", + "# !sudo apt-get -qq update\n", + "# !sudo apt-get -qq install octave octave-signal liboctave-dev\n", + "\n", + "# # install oct2py that compatible with colab\n", + "# import os\n", + "\n", + "# from pkg_resources import get_distribution\n", + "\n", + "# os.system(\n", + "# f\"pip install -qq\"\n", + "# f\" ipykernel=={get_distribution('ipykernel').version}\"\n", + "# f\" ipython=={get_distribution('ipython').version}\"\n", + "# f\" tornado=={get_distribution('tornado').version}\"\n", + "# f\" oct2py\"\n", + "# )\n", + "\n", + "# # install packages\n", + "# !pip install -qq matpower matpowercaseframes" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "5bc86ee4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "oct2py version: 5.8.0\n", + "matpower version: 8.1.0.2.2.3\n" + ] + } + ], + "source": [ + "import matpower\n", + "import oct2py\n", + "\n", + "print(f\"oct2py version: {oct2py.__version__}\")\n", + "print(f\"matpower version: {matpower.__version__}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "3116b86b", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "\n", + "import pandas as pd\n", + "from matpower import path_matpower, start_instance" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "10fd2d91", + "metadata": {}, + "outputs": [], + "source": [ + "path_most_ex_cases = os.path.join(path_matpower, \"most/examples\")" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "7e230eb0", + "metadata": {}, + "outputs": [], + "source": [ + "m = start_instance()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "6d93dd06", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'version': '2',\n", + " 'baseMVA': 100.0,\n", + " 'bus': array([[ 1. , 3. , 0. , 0. , 0. , 0. , 1. , 1. ,\n", + " 0. , 135. , 1. , 1.05, 0.95],\n", + " [ 2. , 2. , 0. , 0. , 0. , 0. , 1. , 1. ,\n", + " 0. , 135. , 1. , 1.05, 0.95],\n", + " [ 3. , 2. , 0. , 0. , 0. , 0. , 1. , 1. ,\n", + " 0. , 135. , 1. , 1.05, 0.95]]),\n", + " 'gen': array([[ 1., 125., 0., 25., -25., 1., 100., 1., 200.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 250.,\n", + " 250., 0., 0.],\n", + " [ 1., 125., 0., 25., -25., 1., 100., 1., 200.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 250.,\n", + " 250., 0., 0.],\n", + " [ 2., 200., 0., 50., -50., 1., 100., 1., 500.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 600.,\n", + " 600., 0., 0.],\n", + " [ 3., -450., 0., 0., 0., 1., 100., 1., 0.,\n", + " -450., 0., 0., 0., 0., 0., 0., 0., 500.,\n", + " 500., 0., 0.]]),\n", + " 'branch': array([[ 1.0e+00, 2.0e+00, 5.0e-03, 1.0e-02, 0.0e+00, 3.0e+02,\n", + " 3.0e+02, 3.0e+02, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 1.0e+00, 3.0e+00, 5.0e-03, 1.0e-02, 0.0e+00, 2.4e+02,\n", + " 2.4e+02, 2.4e+02, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 2.0e+00, 3.0e+00, 5.0e-03, 1.0e-02, 0.0e+00, 3.0e+02,\n", + " 3.0e+02, 3.0e+02, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02]]),\n", + " 'gencost': array([[2.e+00, 0.e+00, 0.e+00, 3.e+00, 1.e-01, 0.e+00, 0.e+00],\n", + " [2.e+00, 0.e+00, 0.e+00, 3.e+00, 1.e-01, 0.e+00, 0.e+00],\n", + " [2.e+00, 0.e+00, 0.e+00, 3.e+00, 1.e-01, 0.e+00, 0.e+00],\n", + " [2.e+00, 0.e+00, 0.e+00, 3.e+00, 0.e+00, 1.e+03, 0.e+00]]),\n", + " 'reserves': {'zones': array([[1., 1., 1., 0.]]),\n", + " 'req': 150.0,\n", + " 'cost': array([[1.],\n", + " [3.],\n", + " [5.]]),\n", + " 'qty': array([[100.],\n", + " [100.],\n", + " [200.]])}}" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# load single most example case\n", + "mpc = m.loadcase(os.path.join(path_most_ex_cases, \"ex_case3a.m\"))\n", + "mpc" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "b6bbbce4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "dict_keys(['version', 'baseMVA', 'bus', 'gen', 'branch', 'gencost', 'reserves'])" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mpc.keys()" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "ea66211a", + "metadata": {}, + "outputs": [], + "source": [ + "from matpowercaseframes.constants import COLUMNS" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "a911808f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "dict_keys(['bus', 'gen', 'branch', 'dcline', 'if', 'gencost', 'dclinecost', 'bus_name', 'branch_name', 'gen_name', 'case'])" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "COLUMNS.keys()" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "f63470e2", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'baseMVA', 'reserves', 'version'}" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mpc_keys = set(mpc.keys())\n", + "columns_keys = set(COLUMNS.keys())\n", + "missing_keys = mpc_keys - columns_keys\n", + "missing_keys" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "8577fe89", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'zones': array([[1., 1., 1., 0.]]),\n", + " 'req': 150.0,\n", + " 'cost': array([[1.],\n", + " [3.],\n", + " [5.]]),\n", + " 'qty': array([[100.],\n", + " [100.],\n", + " [200.]])}" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mpc.reserves" + ] + }, + { + "cell_type": "markdown", + "id": "f46abaea", + "metadata": {}, + "source": [ + "Reserve Data\n", + "\n", + "reserve zones, element i, j is 1 if gen j is in zone i, 0 otherwise.\n", + "dimension (zone, gen)\n", + "\n", + "```octave\n", + "mpc.reserves.zones = [\n", + "\t1\t1\t1\t0;\n", + "];\n", + "```\n", + "\n", + "Mapped to `DataFrame` with index follows zone index (from 1), and columns follows\n", + "generator index (cf.gen.index)." + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "id": "aaf701d3", + "metadata": {}, + "outputs": [], + "source": [ + "n_zones, n_gens = mpc.reserves.zones.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "id": "370d5e7c", + "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", + "
gen1234
zone
11.01.01.00.0
\n", + "
" + ], + "text/plain": [ + "gen 1 2 3 4\n", + "zone \n", + "1 1.0 1.0 1.0 0.0" + ] + }, + "execution_count": 55, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_reserves_zone = pd.DataFrame(\n", + " mpc.reserves.zones,\n", + " index=pd.RangeIndex(start=1, stop=n_zones + 1, name=\"zone\"),\n", + " columns=pd.RangeIndex(start=1, stop=n_gens + 1, name=\"gen\"),\n", + ")\n", + "df_reserves_zone" + ] + }, + { + "cell_type": "markdown", + "id": "ded7b892", + "metadata": {}, + "source": [ + "reserve requirements for each zone in MW\n", + "\n", + "```octave\n", + "mpc.reserves.req = [60; 20];\n", + "```\n", + "\n", + "or\n", + "\n", + "```octave\n", + "mpc.reserves.req = 150;\n", + "```\n", + "\n", + "Mapped to `DataFrame` with index follows zone index (from 1), and single column 'PREQ'." + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "id": "b817c54f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
PREQ
zone
1150.0
\n", + "
" + ], + "text/plain": [ + " PREQ\n", + "zone \n", + "1 150.0" + ] + }, + "execution_count": 56, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_reserves_req = pd.DataFrame(\n", + " mpc.reserves.req,\n", + " index=pd.RangeIndex(start=1, stop=n_zones + 1, name=\"zone\"),\n", + " columns=[\"PREQ\"],\n", + ")\n", + "df_reserves_req" + ] + }, + { + "cell_type": "markdown", + "id": "82107817", + "metadata": {}, + "source": [ + "reserve costs in $/MW for each gen that belongs to at least 1 zone. (same order as gens,\n", + "but skipping any gen that does not belong to any zone)\n", + "\n", + "```octave\n", + "mpc.reserves.cost = [\t1.9;\t2;\t3;\t4;\t5;\t5.5\t];\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "id": "fb21239e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "RangeIndex(start=1, stop=4, step=1, name='gen')" + ] + }, + "execution_count": 57, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_reserves_zone_sum = df_reserves_zone.sum(axis=0)\n", + "idx_gen_with_reserves = df_reserves_zone_sum[df_reserves_zone_sum > 0].index\n", + "idx_gen_with_reserves" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "id": "ebe8a6de", + "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", + "
C1
gen
11.0
23.0
35.0
\n", + "
" + ], + "text/plain": [ + " C1\n", + "gen \n", + "1 1.0\n", + "2 3.0\n", + "3 5.0" + ] + }, + "execution_count": 58, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_reserves_cost = pd.DataFrame(\n", + " mpc.reserves.cost, index=idx_gen_with_reserves, columns=[\"C1\"]\n", + ")\n", + "df_reserves_cost" + ] + }, + { + "cell_type": "markdown", + "id": "a2b1e889", + "metadata": {}, + "source": [ + "max reserve quantities for each gen that belongs to at least 1 zone. (same order as\n", + "gens, but skipping any gen that does not belong to any zone)\n", + "\n", + "```octave\n", + "mpc.reserves.qty = [\t25;\t25;\t25;\t25;\t25;\t25\t];\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "id": "4e486ee1", + "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", + "
C1
gen
1100.0
2100.0
3200.0
\n", + "
" + ], + "text/plain": [ + " C1\n", + "gen \n", + "1 100.0\n", + "2 100.0\n", + "3 200.0" + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_reserves_qty = pd.DataFrame(\n", + " mpc.reserves.qty, index=idx_gen_with_reserves, columns=[\"C1\"]\n", + ")\n", + "df_reserves_qty" + ] + }, + { + "cell_type": "markdown", + "id": "8789a89c", + "metadata": {}, + "source": [ + "> [!NOTE] \n", + "> Currently, `loadgenericdata` didn't support absolute path. This impacts various `most`\n", + "> functions. See: ." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "65bf6c72", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'CommitSched': array([[1.],\n", + " [1.],\n", + " [1.],\n", + " [1.]]),\n", + " 'InitialPg': array([[ 125.],\n", + " [ 125.],\n", + " [ 200.],\n", + " [-450.]]),\n", + " 'RampWearCostCoeff': array([[0.],\n", + " [0.],\n", + " [0.],\n", + " [0.]]),\n", + " 'PositiveActiveReservePrice': array([[5.0e+00],\n", + " [1.0e-08],\n", + " [1.5e+00],\n", + " [1.0e-08]]),\n", + " 'PositiveActiveReserveQuantity': array([[250.],\n", + " [250.],\n", + " [600.],\n", + " [800.]]),\n", + " 'NegativeActiveReservePrice': array([[1.e+01],\n", + " [2.e-08],\n", + " [3.e+00],\n", + " [2.e-08]]),\n", + " 'NegativeActiveReserveQuantity': array([[250.],\n", + " [250.],\n", + " [600.],\n", + " [800.]]),\n", + " 'PositiveActiveDeltaPrice': array([[1.e-09],\n", + " [1.e-09],\n", + " [1.e-09],\n", + " [1.e-09]]),\n", + " 'NegativeActiveDeltaPrice': array([[1.e-09],\n", + " [1.e-09],\n", + " [1.e-09],\n", + " [1.e-09]]),\n", + " 'PositiveLoadFollowReservePrice': array([[1.e-06],\n", + " [1.e-06],\n", + " [1.e+01],\n", + " [1.e-06]]),\n", + " 'PositiveLoadFollowReserveQuantity': array([[250.],\n", + " [250.],\n", + " [100.],\n", + " [800.]]),\n", + " 'NegativeLoadFollowReservePrice': array([[1.e-06],\n", + " [1.e-06],\n", + " [1.e+01],\n", + " [1.e-06]]),\n", + " 'NegativeLoadFollowReserveQuantity': array([[250.],\n", + " [250.],\n", + " [250.],\n", + " [800.]]),\n", + " 'CommitKey': array([[1.],\n", + " [1.],\n", + " [1.],\n", + " [2.]]),\n", + " 'InitialState': array([[inf],\n", + " [inf],\n", + " [inf],\n", + " [inf]]),\n", + " 'MinUp': array([[1.],\n", + " [3.],\n", + " [1.],\n", + " [1.]]),\n", + " 'MinDown': array([[1.],\n", + " [1.],\n", + " [1.],\n", + " [1.]])}" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "xgd = m.loadxgendata(\"ex_xgd_uc.m\", mpc)\n", + "xgd" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "9688f94d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[5.0,\n", + " {'version': '2',\n", + " 'baseMVA': 100.0,\n", + " 'bus': array([[ 1. , 3. , 0. , 0. , 0. , 0. , 1. , 1. ,\n", + " 0. , 135. , 1. , 1.05, 0.95],\n", + " [ 2. , 2. , 0. , 0. , 0. , 0. , 1. , 1. ,\n", + " 0. , 135. , 1. , 1.05, 0.95],\n", + " [ 3. , 2. , 0. , 0. , 0. , 0. , 1. , 1. ,\n", + " 0. , 135. , 1. , 1.05, 0.95]]),\n", + " 'gen': array([[ 1., 125., 0., 25., -25., 1., 100., 1., 200.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 250.,\n", + " 250., 0., 0.],\n", + " [ 1., 125., 0., 25., -25., 1., 100., 1., 200.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 250.,\n", + " 250., 0., 0.],\n", + " [ 2., 200., 0., 50., -50., 1., 100., 1., 500.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 600.,\n", + " 600., 0., 0.],\n", + " [ 3., -450., 0., 0., 0., 1., 100., 1., 0.,\n", + " -450., 0., 0., 0., 0., 0., 0., 0., 500.,\n", + " 500., 0., 0.],\n", + " [ 2., 0., 0., 50., -50., 1., 100., 1., 100.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 200.,\n", + " 200., 0., 0.]]),\n", + " 'branch': array([[ 1.0e+00, 2.0e+00, 5.0e-03, 1.0e-02, 0.0e+00, 3.0e+02,\n", + " 3.0e+02, 3.0e+02, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 1.0e+00, 3.0e+00, 5.0e-03, 1.0e-02, 0.0e+00, 2.4e+02,\n", + " 2.4e+02, 2.4e+02, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 2.0e+00, 3.0e+00, 5.0e-03, 1.0e-02, 0.0e+00, 3.0e+02,\n", + " 3.0e+02, 3.0e+02, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02]]),\n", + " 'gencost': array([[2.e+00, 0.e+00, 0.e+00, 3.e+00, 1.e-01, 0.e+00, 0.e+00],\n", + " [2.e+00, 0.e+00, 0.e+00, 3.e+00, 1.e-01, 0.e+00, 0.e+00],\n", + " [2.e+00, 0.e+00, 0.e+00, 3.e+00, 1.e-01, 0.e+00, 0.e+00],\n", + " [2.e+00, 0.e+00, 0.e+00, 3.e+00, 0.e+00, 1.e+03, 0.e+00],\n", + " [2.e+00, 0.e+00, 0.e+00, 2.e+00, 0.e+00, 0.e+00, 0.e+00]]),\n", + " 'reserves': {'zones': array([[1., 1., 1., 0., 0.]]),\n", + " 'req': 150.0,\n", + " 'cost': array([[1.],\n", + " [3.],\n", + " [5.]]),\n", + " 'qty': array([[100.],\n", + " [100.],\n", + " [200.]])},\n", + " 'genfuel': Cell([['unknown'],\n", + " ['unknown'],\n", + " ['unknown'],\n", + " ['unknown'],\n", + " ['wind']]),\n", + " 'iwind': 5.0},\n", + " {'CommitSched': array([[1.],\n", + " [1.],\n", + " [1.],\n", + " [1.],\n", + " [1.]]),\n", + " 'InitialPg': array([[ 125.],\n", + " [ 125.],\n", + " [ 200.],\n", + " [-450.],\n", + " [ 0.]]),\n", + " 'RampWearCostCoeff': array([[0.],\n", + " [0.],\n", + " [0.],\n", + " [0.],\n", + " [0.]]),\n", + " 'PositiveActiveReservePrice': array([[5.0e+00],\n", + " [1.0e-08],\n", + " [1.5e+00],\n", + " [1.0e-08],\n", + " [1.0e-08]]),\n", + " 'PositiveActiveReserveQuantity': array([[250.],\n", + " [250.],\n", + " [600.],\n", + " [800.],\n", + " [200.]]),\n", + " 'NegativeActiveReservePrice': array([[1.e+01],\n", + " [2.e-08],\n", + " [3.e+00],\n", + " [2.e-08],\n", + " [2.e-08]]),\n", + " 'NegativeActiveReserveQuantity': array([[250.],\n", + " [250.],\n", + " [600.],\n", + " [800.],\n", + " [200.]]),\n", + " 'PositiveActiveDeltaPrice': array([[1.e-09],\n", + " [1.e-09],\n", + " [1.e-09],\n", + " [1.e-09],\n", + " [1.e-09]]),\n", + " 'NegativeActiveDeltaPrice': array([[1.e-09],\n", + " [1.e-09],\n", + " [1.e-09],\n", + " [1.e-09],\n", + " [1.e-09]]),\n", + " 'PositiveLoadFollowReservePrice': array([[1.e-06],\n", + " [1.e-06],\n", + " [1.e+01],\n", + " [1.e-06],\n", + " [1.e-06]]),\n", + " 'PositiveLoadFollowReserveQuantity': array([[250.],\n", + " [250.],\n", + " [100.],\n", + " [800.],\n", + " [200.]]),\n", + " 'NegativeLoadFollowReservePrice': array([[1.e-06],\n", + " [1.e-06],\n", + " [1.e+01],\n", + " [1.e-06],\n", + " [1.e-06]]),\n", + " 'NegativeLoadFollowReserveQuantity': array([[250.],\n", + " [250.],\n", + " [250.],\n", + " [800.],\n", + " [200.]]),\n", + " 'CommitKey': array([[1.],\n", + " [1.],\n", + " [1.],\n", + " [2.],\n", + " [2.]]),\n", + " 'InitialState': array([[inf],\n", + " [inf],\n", + " [inf],\n", + " [inf],\n", + " [inf]]),\n", + " 'MinUp': array([[1.],\n", + " [3.],\n", + " [1.],\n", + " [1.],\n", + " [1.]]),\n", + " 'MinDown': array([[1.],\n", + " [1.],\n", + " [1.],\n", + " [1.],\n", + " [1.]])}]" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "[iwind, mpc, xgd] = m.addwind(\"ex_wind_uc\", mpc, xgd, nout=3)\n", + "[iwind, mpc, xgd]" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "676057c0", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'type': 'mpcData',\n", + " 'table': 2.0,\n", + " 'rows': 5.0,\n", + " 'col': 9.0,\n", + " 'chgtype': 2.0,\n", + " 'values': array([[0.8 ],\n", + " [0.65],\n", + " [0.6 ],\n", + " [0.82],\n", + " [1. ],\n", + " [0.7 ],\n", + " [0.5 ],\n", + " [0.85],\n", + " [1. ],\n", + " [1.1 ],\n", + " [1.06],\n", + " [0.95]])}" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "profiles = m.getprofiles(\"ex_wind_profile_d\", iwind)\n", + "profiles" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "2bcf5d64", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2x1 StructArray containing the fields:\n", + " type\n", + " table\n", + " rows\n", + " col\n", + " chgtype\n", + " values" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "profiles = m.getprofiles(\"ex_load_profile\", profiles)\n", + "profiles" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "ee0cec81", + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: example on `mdi = loadmd(mpc, transmat, xgd, [], 'ex_contab', profiles);`" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "c9726cc1", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[6.0,\n", + " {'version': '2',\n", + " 'baseMVA': 100.0,\n", + " 'bus': array([[ 1. , 3. , 0. , 0. , 0. , 0. , 1. , 1. ,\n", + " 0. , 135. , 1. , 1.05, 0.95],\n", + " [ 2. , 2. , 0. , 0. , 0. , 0. , 1. , 1. ,\n", + " 0. , 135. , 1. , 1.05, 0.95],\n", + " [ 3. , 2. , 0. , 0. , 0. , 0. , 1. , 1. ,\n", + " 0. , 135. , 1. , 1.05, 0.95]]),\n", + " 'gen': array([[ 1., 125., 0., 25., -25., 1., 100., 1., 200.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 250.,\n", + " 250., 0., 0.],\n", + " [ 1., 125., 0., 25., -25., 1., 100., 1., 200.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 250.,\n", + " 250., 0., 0.],\n", + " [ 2., 200., 0., 50., -50., 1., 100., 1., 500.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 600.,\n", + " 600., 0., 0.],\n", + " [ 3., -450., 0., 0., 0., 1., 100., 1., 0.,\n", + " -450., 0., 0., 0., 0., 0., 0., 0., 500.,\n", + " 500., 0., 0.],\n", + " [ 2., 0., 0., 50., -50., 1., 100., 1., 100.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 200.,\n", + " 200., 0., 0.],\n", + " [ 3., 0., 0., 0., 0., 1., 100., 1., 80.,\n", + " -80., 0., 0., 0., 0., 0., 0., 0., 20.,\n", + " 20., 0., 0.]]),\n", + " 'branch': array([[ 1.0e+00, 2.0e+00, 5.0e-03, 1.0e-02, 0.0e+00, 3.0e+02,\n", + " 3.0e+02, 3.0e+02, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 1.0e+00, 3.0e+00, 5.0e-03, 1.0e-02, 0.0e+00, 2.4e+02,\n", + " 2.4e+02, 2.4e+02, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 2.0e+00, 3.0e+00, 5.0e-03, 1.0e-02, 0.0e+00, 3.0e+02,\n", + " 3.0e+02, 3.0e+02, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02]]),\n", + " 'gencost': array([[2.e+00, 0.e+00, 0.e+00, 3.e+00, 1.e-01, 0.e+00, 0.e+00],\n", + " [2.e+00, 0.e+00, 0.e+00, 3.e+00, 1.e-01, 0.e+00, 0.e+00],\n", + " [2.e+00, 0.e+00, 0.e+00, 3.e+00, 1.e-01, 0.e+00, 0.e+00],\n", + " [2.e+00, 0.e+00, 0.e+00, 3.e+00, 0.e+00, 1.e+03, 0.e+00],\n", + " [2.e+00, 0.e+00, 0.e+00, 2.e+00, 0.e+00, 0.e+00, 0.e+00],\n", + " [2.e+00, 0.e+00, 0.e+00, 2.e+00, 0.e+00, 0.e+00, 0.e+00]]),\n", + " 'reserves': {'zones': array([[1., 1., 1., 0., 0., 0.]]),\n", + " 'req': 150.0,\n", + " 'cost': array([[1.],\n", + " [3.],\n", + " [5.]]),\n", + " 'qty': array([[100.],\n", + " [100.],\n", + " [200.]])},\n", + " 'genfuel': Cell([['unknown'],\n", + " ['unknown'],\n", + " ['unknown'],\n", + " ['unknown'],\n", + " ['wind'],\n", + " ['ess']]),\n", + " 'iwind': 5.0,\n", + " 'iess': 6.0},\n", + " {'CommitSched': array([[1.],\n", + " [1.],\n", + " [1.],\n", + " [1.],\n", + " [1.],\n", + " [1.]]),\n", + " 'InitialPg': array([[ 125.],\n", + " [ 125.],\n", + " [ 200.],\n", + " [-450.],\n", + " [ 0.],\n", + " [ 0.]]),\n", + " 'RampWearCostCoeff': array([[0.],\n", + " [0.],\n", + " [0.],\n", + " [0.],\n", + " [0.],\n", + " [0.]]),\n", + " 'PositiveActiveReservePrice': array([[5.0e+00],\n", + " [1.0e-08],\n", + " [1.5e+00],\n", + " [1.0e-08],\n", + " [1.0e-08],\n", + " [1.0e-08]]),\n", + " 'PositiveActiveReserveQuantity': array([[250.],\n", + " [250.],\n", + " [600.],\n", + " [800.],\n", + " [200.],\n", + " [160.]]),\n", + " 'NegativeActiveReservePrice': array([[1.e+01],\n", + " [2.e-08],\n", + " [3.e+00],\n", + " [2.e-08],\n", + " [2.e-08],\n", + " [2.e-08]]),\n", + " 'NegativeActiveReserveQuantity': array([[250.],\n", + " [250.],\n", + " [600.],\n", + " [800.],\n", + " [200.],\n", + " [160.]]),\n", + " 'PositiveActiveDeltaPrice': array([[1.e-09],\n", + " [1.e-09],\n", + " [1.e-09],\n", + " [1.e-09],\n", + " [1.e-09],\n", + " [1.e-09]]),\n", + " 'NegativeActiveDeltaPrice': array([[1.e-09],\n", + " [1.e-09],\n", + " [1.e-09],\n", + " [1.e-09],\n", + " [1.e-09],\n", + " [1.e-09]]),\n", + " 'PositiveLoadFollowReservePrice': array([[1.e-06],\n", + " [1.e-06],\n", + " [1.e+01],\n", + " [1.e-06],\n", + " [1.e-06],\n", + " [1.e-06]]),\n", + " 'PositiveLoadFollowReserveQuantity': array([[250.],\n", + " [250.],\n", + " [100.],\n", + " [800.],\n", + " [200.],\n", + " [160.]]),\n", + " 'NegativeLoadFollowReservePrice': array([[1.e-06],\n", + " [1.e-06],\n", + " [1.e+01],\n", + " [1.e-06],\n", + " [1.e-06],\n", + " [1.e-06]]),\n", + " 'NegativeLoadFollowReserveQuantity': array([[250.],\n", + " [250.],\n", + " [250.],\n", + " [800.],\n", + " [200.],\n", + " [160.]]),\n", + " 'CommitKey': array([[1.],\n", + " [1.],\n", + " [1.],\n", + " [2.],\n", + " [2.],\n", + " [2.]]),\n", + " 'InitialState': array([[inf],\n", + " [inf],\n", + " [inf],\n", + " [inf],\n", + " [inf],\n", + " [inf]]),\n", + " 'MinUp': array([[1.],\n", + " [3.],\n", + " [1.],\n", + " [1.],\n", + " [1.],\n", + " [1.]]),\n", + " 'MinDown': array([[1.],\n", + " [1.],\n", + " [1.],\n", + " [1.],\n", + " [1.],\n", + " [1.]])},\n", + " {'UnitIdx': 6.0,\n", + " 'ExpectedTerminalStorageAim': [],\n", + " 'ExpectedTerminalStorageMin': [],\n", + " 'ExpectedTerminalStorageMax': [],\n", + " 'rho': 0.0,\n", + " 'TerminalChargingPrice0': [],\n", + " 'TerminalDischargingPrice0': [],\n", + " 'TerminalChargingPriceK': [],\n", + " 'TerminalDischargingPriceK': [],\n", + " 'OutEff': 1.0,\n", + " 'InEff': 1.0,\n", + " 'LossFactor': 1e-05,\n", + " 'InitialStorage': 0.0,\n", + " 'InitialStorageLowerBound': 0.0,\n", + " 'InitialStorageUpperBound': 200.0,\n", + " 'InitialStorageCost': 45.166667,\n", + " 'TerminalStoragePrice': 45.166667,\n", + " 'MinStorageLevel': 0.0,\n", + " 'MaxStorageLevel': 200.0}]" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "[iess, mpc, xgd, sd] = m.addstorage(\"ex_storage\", mpc, xgd, nout=4)\n", + "[iess, mpc, xgd, sd]" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "159b9137", + "metadata": {}, + "outputs": [], + "source": [ + "# m.exit()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "35fe9966", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "env", + "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.14.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/load_t_case30_userfcns.ipynb b/notebooks/load_t_case30_userfcns.ipynb new file mode 100644 index 0000000..39b125b --- /dev/null +++ b/notebooks/load_t_case30_userfcns.ipynb @@ -0,0 +1,878 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "eae79aa2", + "metadata": {}, + "outputs": [], + "source": [ + "# # install octave\n", + "# !sudo apt-get -qq update\n", + "# !sudo apt-get -qq install octave octave-signal liboctave-dev\n", + "\n", + "# # install oct2py that compatible with colab\n", + "# import os\n", + "\n", + "# from pkg_resources import get_distribution\n", + "\n", + "# os.system(\n", + "# f\"pip install -qq\"\n", + "# f\" ipykernel=={get_distribution('ipykernel').version}\"\n", + "# f\" ipython=={get_distribution('ipython').version}\"\n", + "# f\" tornado=={get_distribution('tornado').version}\"\n", + "# f\" oct2py\"\n", + "# )\n", + "\n", + "# # install packages\n", + "# !pip install -qq matpower matpowercaseframes" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "5bc86ee4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "oct2py version: 5.8.0\n", + "matpower version: 8.1.0.2.2.3\n" + ] + } + ], + "source": [ + "import matpower\n", + "import oct2py\n", + "\n", + "print(f\"oct2py version: {oct2py.__version__}\")\n", + "print(f\"matpower version: {matpower.__version__}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "3116b86b", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "\n", + "import pandas as pd\n", + "from matpower import path_matpower, start_instance" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "10fd2d91", + "metadata": {}, + "outputs": [], + "source": [ + "path_t_cases = os.path.join(path_matpower, \"lib/t\")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "7e230eb0", + "metadata": {}, + "outputs": [], + "source": [ + "m = start_instance()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "6d93dd06", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'version': '2',\n", + " 'baseMVA': 100.0,\n", + " 'bus': array([[1.00e+00, 3.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00,\n", + " 1.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.05e+00,\n", + " 9.50e-01],\n", + " [2.00e+00, 2.00e+00, 2.17e+01, 1.27e+01, 0.00e+00, 0.00e+00,\n", + " 1.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.10e+00,\n", + " 9.50e-01],\n", + " [3.00e+02, 1.00e+00, 2.40e+00, 1.20e+00, 0.00e+00, 0.00e+00,\n", + " 1.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.05e+00,\n", + " 9.50e-01],\n", + " [4.00e+00, 1.00e+00, 7.60e+00, 1.60e+00, 0.00e+00, 0.00e+00,\n", + " 1.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.05e+00,\n", + " 9.50e-01],\n", + " [5.00e+00, 1.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, 1.90e-01,\n", + " 1.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.05e+00,\n", + " 9.50e-01],\n", + " [6.00e+00, 1.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00,\n", + " 1.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.05e+00,\n", + " 9.50e-01],\n", + " [7.00e+00, 1.00e+00, 2.28e+01, 1.09e+01, 0.00e+00, 0.00e+00,\n", + " 1.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.05e+00,\n", + " 9.50e-01],\n", + " [8.00e+00, 1.00e+00, 3.00e+01, 3.00e+01, 0.00e+00, 0.00e+00,\n", + " 1.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.05e+00,\n", + " 9.50e-01],\n", + " [9.00e+00, 1.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00,\n", + " 1.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.05e+00,\n", + " 9.50e-01],\n", + " [1.00e+01, 1.00e+00, 5.80e+00, 2.00e+00, 0.00e+00, 0.00e+00,\n", + " 3.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.05e+00,\n", + " 9.50e-01],\n", + " [1.10e+01, 1.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00,\n", + " 1.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.05e+00,\n", + " 9.50e-01],\n", + " [1.20e+01, 1.00e+00, 1.12e+01, 7.50e+00, 0.00e+00, 0.00e+00,\n", + " 2.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.05e+00,\n", + " 9.50e-01],\n", + " [1.30e+01, 2.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00,\n", + " 2.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.10e+00,\n", + " 9.50e-01],\n", + " [1.40e+01, 1.00e+00, 6.20e+00, 1.60e+00, 0.00e+00, 0.00e+00,\n", + " 2.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.05e+00,\n", + " 9.50e-01],\n", + " [1.50e+01, 1.00e+00, 8.20e+00, 2.50e+00, 0.00e+00, 0.00e+00,\n", + " 2.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.05e+00,\n", + " 9.50e-01],\n", + " [1.60e+01, 1.00e+00, 3.50e+00, 1.80e+00, 0.00e+00, 0.00e+00,\n", + " 2.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.05e+00,\n", + " 9.50e-01],\n", + " [1.70e+01, 1.00e+00, 9.00e+00, 5.80e+00, 0.00e+00, 0.00e+00,\n", + " 2.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.05e+00,\n", + " 9.50e-01],\n", + " [1.80e+01, 1.00e+00, 3.20e+00, 9.00e-01, 0.00e+00, 0.00e+00,\n", + " 2.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.05e+00,\n", + " 9.50e-01],\n", + " [1.90e+01, 1.00e+00, 9.50e+00, 3.40e+00, 0.00e+00, 0.00e+00,\n", + " 2.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.05e+00,\n", + " 9.50e-01],\n", + " [2.00e+01, 1.00e+00, 2.20e+00, 7.00e-01, 0.00e+00, 0.00e+00,\n", + " 2.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.05e+00,\n", + " 9.50e-01],\n", + " [2.10e+01, 1.00e+00, 1.75e+01, 1.12e+01, 0.00e+00, 0.00e+00,\n", + " 3.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.05e+00,\n", + " 9.50e-01],\n", + " [2.20e+01, 2.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00,\n", + " 3.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.10e+00,\n", + " 9.50e-01],\n", + " [2.30e+01, 2.00e+00, 3.20e+00, 1.60e+00, 0.00e+00, 0.00e+00,\n", + " 2.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.10e+00,\n", + " 9.50e-01],\n", + " [2.40e+01, 1.00e+00, 8.70e+00, 6.70e+00, 0.00e+00, 4.00e-02,\n", + " 3.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.05e+00,\n", + " 9.50e-01],\n", + " [2.50e+01, 1.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00,\n", + " 3.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.05e+00,\n", + " 9.50e-01],\n", + " [2.60e+01, 1.00e+00, 3.50e+00, 2.30e+00, 0.00e+00, 0.00e+00,\n", + " 3.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.05e+00,\n", + " 9.50e-01],\n", + " [2.70e+01, 2.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00,\n", + " 3.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.10e+00,\n", + " 9.50e-01],\n", + " [2.80e+01, 1.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00,\n", + " 1.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.05e+00,\n", + " 9.50e-01],\n", + " [2.90e+01, 1.00e+00, 2.40e+00, 9.00e-01, 0.00e+00, 0.00e+00,\n", + " 3.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.05e+00,\n", + " 9.50e-01],\n", + " [3.00e+01, 1.00e+00, 1.06e+01, 1.90e+00, 0.00e+00, 0.00e+00,\n", + " 3.00e+00, 1.00e+00, 0.00e+00, 1.35e+02, 1.00e+00, 1.05e+00,\n", + " 9.50e-01]]),\n", + " 'gen': array([[ 1. , 23.54, 0. , 150. , -20. , 1. , 100. , 1. ,\n", + " 80. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ],\n", + " [ 2. , 60.97, 0. , 60. , -20. , 1. , 100. , 1. ,\n", + " 80. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ],\n", + " [ 22. , 21.59, 0. , 62.5 , -15. , 1. , 100. , 1. ,\n", + " 50. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ],\n", + " [ 27. , 26.91, 0. , 48.7 , -15. , 1. , 100. , 1. ,\n", + " 55. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ],\n", + " [ 23. , 19.2 , 0. , 40. , -10. , 1. , 100. , 1. ,\n", + " 30. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ],\n", + " [ 13. , 37. , 0. , 44.7 , -15. , 1. , 100. , 1. ,\n", + " 40. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ]]),\n", + " 'branch': array([[ 1.0e+00, 2.0e+00, 2.0e-02, 6.0e-02, 3.0e-02, 1.3e+02,\n", + " 1.3e+02, 1.3e+02, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 1.0e+00, 3.0e+02, 5.0e-02, 1.9e-01, 2.0e-02, 1.3e+02,\n", + " 1.3e+02, 1.3e+02, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 2.0e+00, 4.0e+00, 6.0e-02, 1.7e-01, 2.0e-02, 6.5e+01,\n", + " 6.5e+01, 6.5e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 3.0e+02, 4.0e+00, 1.0e-02, 4.0e-02, 0.0e+00, 1.3e+02,\n", + " 1.3e+02, 1.3e+02, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 2.0e+00, 5.0e+00, 5.0e-02, 2.0e-01, 2.0e-02, 1.3e+02,\n", + " 1.3e+02, 1.3e+02, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 2.0e+00, 6.0e+00, 6.0e-02, 1.8e-01, 2.0e-02, 6.5e+01,\n", + " 6.5e+01, 6.5e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 4.0e+00, 6.0e+00, 1.0e-02, 4.0e-02, 0.0e+00, 9.0e+01,\n", + " 9.0e+01, 9.0e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 5.0e+00, 7.0e+00, 5.0e-02, 1.2e-01, 1.0e-02, 7.0e+01,\n", + " 7.0e+01, 7.0e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 6.0e+00, 7.0e+00, 3.0e-02, 8.0e-02, 1.0e-02, 1.3e+02,\n", + " 1.3e+02, 1.3e+02, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 6.0e+00, 8.0e+00, 1.0e-02, 4.0e-02, 0.0e+00, 3.2e+01,\n", + " 3.2e+01, 3.2e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 6.0e+00, 9.0e+00, 0.0e+00, 2.1e-01, 0.0e+00, 6.5e+01,\n", + " 6.5e+01, 6.5e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 6.0e+00, 1.0e+01, 0.0e+00, 5.6e-01, 0.0e+00, 3.2e+01,\n", + " 3.2e+01, 3.2e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 9.0e+00, 1.1e+01, 0.0e+00, 2.1e-01, 0.0e+00, 6.5e+01,\n", + " 6.5e+01, 6.5e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 9.0e+00, 1.0e+01, 0.0e+00, 1.1e-01, 0.0e+00, 6.5e+01,\n", + " 6.5e+01, 6.5e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 4.0e+00, 1.2e+01, 0.0e+00, 2.6e-01, 0.0e+00, 6.5e+01,\n", + " 6.5e+01, 6.5e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 1.2e+01, 1.3e+01, 0.0e+00, 1.4e-01, 0.0e+00, 6.5e+01,\n", + " 6.5e+01, 6.5e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 1.2e+01, 1.4e+01, 1.2e-01, 2.6e-01, 0.0e+00, 3.2e+01,\n", + " 3.2e+01, 3.2e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 1.2e+01, 1.5e+01, 7.0e-02, 1.3e-01, 0.0e+00, 3.2e+01,\n", + " 3.2e+01, 3.2e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 1.2e+01, 1.6e+01, 9.0e-02, 2.0e-01, 0.0e+00, 3.2e+01,\n", + " 3.2e+01, 3.2e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 1.4e+01, 1.5e+01, 2.2e-01, 2.0e-01, 0.0e+00, 1.6e+01,\n", + " 1.6e+01, 1.6e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 1.6e+01, 1.7e+01, 8.0e-02, 1.9e-01, 0.0e+00, 1.6e+01,\n", + " 1.6e+01, 1.6e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 1.5e+01, 1.8e+01, 1.1e-01, 2.2e-01, 0.0e+00, 1.6e+01,\n", + " 1.6e+01, 1.6e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 1.8e+01, 1.9e+01, 6.0e-02, 1.3e-01, 0.0e+00, 1.6e+01,\n", + " 1.6e+01, 1.6e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 1.9e+01, 2.0e+01, 3.0e-02, 7.0e-02, 0.0e+00, 3.2e+01,\n", + " 3.2e+01, 3.2e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 1.0e+01, 2.0e+01, 9.0e-02, 2.1e-01, 0.0e+00, 3.2e+01,\n", + " 3.2e+01, 3.2e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 1.0e+01, 1.7e+01, 3.0e-02, 8.0e-02, 0.0e+00, 3.2e+01,\n", + " 3.2e+01, 3.2e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 1.0e+01, 2.1e+01, 3.0e-02, 7.0e-02, 0.0e+00, 3.2e+01,\n", + " 3.2e+01, 3.2e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 1.0e+01, 2.2e+01, 7.0e-02, 1.5e-01, 0.0e+00, 3.2e+01,\n", + " 3.2e+01, 3.2e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 2.1e+01, 2.2e+01, 1.0e-02, 2.0e-02, 0.0e+00, 3.2e+01,\n", + " 3.2e+01, 3.2e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 1.5e+01, 2.3e+01, 1.0e-01, 2.0e-01, 0.0e+00, 1.6e+01,\n", + " 1.6e+01, 1.6e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 2.2e+01, 2.4e+01, 1.2e-01, 1.8e-01, 0.0e+00, 1.6e+01,\n", + " 1.6e+01, 1.6e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 2.3e+01, 2.4e+01, 1.3e-01, 2.7e-01, 0.0e+00, 1.6e+01,\n", + " 1.6e+01, 1.6e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 2.4e+01, 2.5e+01, 1.9e-01, 3.3e-01, 0.0e+00, 1.6e+01,\n", + " 1.6e+01, 1.6e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 2.5e+01, 2.6e+01, 2.5e-01, 3.8e-01, 0.0e+00, 1.6e+01,\n", + " 1.6e+01, 1.6e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 2.5e+01, 2.7e+01, 1.1e-01, 2.1e-01, 0.0e+00, 1.6e+01,\n", + " 1.6e+01, 1.6e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 2.8e+01, 2.7e+01, 0.0e+00, 4.0e-01, 0.0e+00, 6.5e+01,\n", + " 6.5e+01, 6.5e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 2.7e+01, 2.9e+01, 2.2e-01, 4.2e-01, 0.0e+00, 1.6e+01,\n", + " 1.6e+01, 1.6e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 2.7e+01, 3.0e+01, 3.2e-01, 6.0e-01, 0.0e+00, 1.6e+01,\n", + " 1.6e+01, 1.6e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 2.9e+01, 3.0e+01, 2.4e-01, 4.5e-01, 0.0e+00, 1.6e+01,\n", + " 1.6e+01, 1.6e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 8.0e+00, 2.8e+01, 6.0e-02, 2.0e-01, 2.0e-02, 3.2e+01,\n", + " 3.2e+01, 3.2e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02],\n", + " [ 6.0e+00, 2.8e+01, 2.0e-02, 6.0e-02, 1.0e-02, 3.2e+01,\n", + " 3.2e+01, 3.2e+01, 0.0e+00, 0.0e+00, 1.0e+00, -3.6e+02,\n", + " 3.6e+02]]),\n", + " 'gencost': array([[2. , 0. , 0. , 3. , 0.02 , 2. , 0. ],\n", + " [2. , 0. , 0. , 3. , 0.0175 , 1.75 , 0. ],\n", + " [2. , 0. , 0. , 3. , 0.0625 , 1. , 0. ],\n", + " [2. , 0. , 0. , 3. , 0.00834, 3.25 , 0. ],\n", + " [2. , 0. , 0. , 3. , 0.025 , 3. , 0. ],\n", + " [2. , 0. , 0. , 3. , 0.025 , 3. , 0. ]]),\n", + " 'reserves': {'zones': array([[1., 1., 1., 1., 1., 1.],\n", + " [0., 0., 0., 0., 1., 1.]]),\n", + " 'req': array([[60.],\n", + " [20.]]),\n", + " 'cost': array([[1.9],\n", + " [2. ],\n", + " [3. ],\n", + " [4. ],\n", + " [5. ],\n", + " [5.5]]),\n", + " 'qty': array([[25.],\n", + " [25.],\n", + " [25.],\n", + " [25.],\n", + " [25.],\n", + " [25.]])},\n", + " 'if': {'map': array([[ 1., -12.],\n", + " [ 1., -14.],\n", + " [ 1., -15.],\n", + " [ 1., -36.],\n", + " [ 2., 15.],\n", + " [ 2., 25.],\n", + " [ 2., 26.],\n", + " [ 2., -32.],\n", + " [ 3., 12.],\n", + " [ 3., 14.],\n", + " [ 3., -25.],\n", + " [ 3., -26.],\n", + " [ 3., 32.],\n", + " [ 3., 36.]]),\n", + " 'lims': array([[ 1., -15., 25.],\n", + " [ 2., -10., 20.]])}}" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# load single most example case\n", + "mpc = m.loadcase(os.path.join(path_t_cases, \"t_case30_userfcns.m\"))\n", + "mpc" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "b6bbbce4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "dict_keys(['version', 'baseMVA', 'bus', 'gen', 'branch', 'gencost', 'reserves', 'if'])" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mpc.keys()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "ea66211a", + "metadata": {}, + "outputs": [], + "source": [ + "from matpowercaseframes.constants import COLUMNS" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "a911808f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "dict_keys(['bus', 'gen', 'branch', 'dcline', 'if', 'gencost', 'dclinecost', 'bus_name', 'branch_name', 'gen_name', 'case'])" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "COLUMNS.keys()" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "f63470e2", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'baseMVA', 'reserves', 'version'}" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mpc_keys = set(mpc.keys())\n", + "columns_keys = set(COLUMNS.keys())\n", + "missing_keys = mpc_keys - columns_keys\n", + "missing_keys" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "8577fe89", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'zones': array([[1., 1., 1., 1., 1., 1.],\n", + " [0., 0., 0., 0., 1., 1.]]),\n", + " 'req': array([[60.],\n", + " [20.]]),\n", + " 'cost': array([[1.9],\n", + " [2. ],\n", + " [3. ],\n", + " [4. ],\n", + " [5. ],\n", + " [5.5]]),\n", + " 'qty': array([[25.],\n", + " [25.],\n", + " [25.],\n", + " [25.],\n", + " [25.],\n", + " [25.]]),\n", + " 'getdoc': {}}" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mpc.reserves" + ] + }, + { + "cell_type": "markdown", + "id": "f46abaea", + "metadata": {}, + "source": [ + "Reserve Data\n", + "reserve zones, element i, j is 1 if gen j is in zone i, 0 otherwise.\n", + "dimension (zone, gen)\n", + "\n", + "```octave\n", + "mpc.reserves.zones = [\n", + "\t1\t1\t1\t0;\n", + "];\n", + "```\n", + "\n", + "Mapped to `DataFrame` with index follows zone index (from 1), and columns follows\n", + "generator index (cf.gen.index)." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "370d5e7c", + "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", + " \n", + "
gen123456
zone
11.01.01.01.01.01.0
20.00.00.00.01.01.0
\n", + "
" + ], + "text/plain": [ + "gen 1 2 3 4 5 6\n", + "zone \n", + "1 1.0 1.0 1.0 1.0 1.0 1.0\n", + "2 0.0 0.0 0.0 0.0 1.0 1.0" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "reserves_zone = mpc.reserves.zones\n", + "n_zones, n_gens = reserves_zone.shape\n", + "df_reserves_zone = pd.DataFrame(\n", + " reserves_zone,\n", + " index=pd.RangeIndex(start=1, stop=n_zones + 1, name=\"zone\"),\n", + " columns=pd.RangeIndex(start=1, stop=n_gens + 1, name=\"gen\"),\n", + ")\n", + "df_reserves_zone" + ] + }, + { + "cell_type": "markdown", + "id": "765a409f", + "metadata": {}, + "source": [ + "reserve requirements for each zone in MW\n", + "\n", + "```octave\n", + "mpc.reserves.req = [60; 20];\n", + "```\n", + "\n", + "or\n", + "\n", + "```octave\n", + "mpc.reserves.req = 150;\n", + "```\n", + "\n", + "Mapped to `DataFrame` with index follows zone index (from 1), and single column 'PREQ'." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "b817c54f", + "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", + "
PREQ
zone
160.0
220.0
\n", + "
" + ], + "text/plain": [ + " PREQ\n", + "zone \n", + "1 60.0\n", + "2 20.0" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "reserves_req = mpc.reserves.req\n", + "df_reserves_req = pd.DataFrame(\n", + " reserves_req,\n", + " index=pd.RangeIndex(start=1, stop=n_zones + 1, name=\"zone\"),\n", + " columns=[\"PREQ\"],\n", + ")\n", + "df_reserves_req" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "227155ed", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "RangeIndex(start=1, stop=7, step=1, name='gen')" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_reserves_zone_sum = df_reserves_zone.sum(axis=0)\n", + "idx_gen_with_reserves = df_reserves_zone_sum[df_reserves_zone_sum > 0].index\n", + "idx_gen_with_reserves" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "8c5f69a2", + "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", + "
C1
gen
11.9
22.0
33.0
44.0
55.0
65.5
\n", + "
" + ], + "text/plain": [ + " C1\n", + "gen \n", + "1 1.9\n", + "2 2.0\n", + "3 3.0\n", + "4 4.0\n", + "5 5.0\n", + "6 5.5" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "reserves_cost = mpc.reserves.cost\n", + "df_reserves_cost = pd.DataFrame(\n", + " reserves_cost, index=idx_gen_with_reserves, columns=[\"C1\"]\n", + ")\n", + "df_reserves_cost" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "6bda4dbb", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'map': array([[ 1., -12.],\n", + " [ 1., -14.],\n", + " [ 1., -15.],\n", + " [ 1., -36.],\n", + " [ 2., 15.],\n", + " [ 2., 25.],\n", + " [ 2., 26.],\n", + " [ 2., -32.],\n", + " [ 3., 12.],\n", + " [ 3., 14.],\n", + " [ 3., -25.],\n", + " [ 3., -26.],\n", + " [ 3., 32.],\n", + " [ 3., 36.]]),\n", + " 'lims': array([[ 1., -15., 25.],\n", + " [ 2., -10., 20.]])}" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# TODO: mpc.if (need to use mpc['if'])\n", + "mpc[\"if\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "159b9137", + "metadata": {}, + "outputs": [], + "source": [ + "# m.exit()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "35fe9966", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "env", + "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.14.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 7b8f4f9342f5389a9156c157e938c355d7ceeb56 Mon Sep 17 00:00:00 2001 From: Muhammad Yasirroni Date: Fri, 16 Jan 2026 17:52:47 +1100 Subject: [PATCH 4/6] add reserves_to_dataframes in notebook --- notebooks/load_most_ex_case3a.ipynb | 386 ++++++++++++++++++++++--- notebooks/load_t_case30_userfcns.ipynb | 152 ++++++++-- 2 files changed, 472 insertions(+), 66 deletions(-) diff --git a/notebooks/load_most_ex_case3a.ipynb b/notebooks/load_most_ex_case3a.ipynb index cb7fc22..5aba7c2 100644 --- a/notebooks/load_most_ex_case3a.ipynb +++ b/notebooks/load_most_ex_case3a.ipynb @@ -53,7 +53,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 3, "id": "3116b86b", "metadata": {}, "outputs": [], @@ -86,7 +86,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 6, "id": "6d93dd06", "metadata": {}, "outputs": [ @@ -136,7 +136,7 @@ " [200.]])}}" ] }, - "execution_count": 19, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -149,7 +149,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 7, "id": "b6bbbce4", "metadata": {}, "outputs": [ @@ -159,7 +159,7 @@ "dict_keys(['version', 'baseMVA', 'bus', 'gen', 'branch', 'gencost', 'reserves'])" ] }, - "execution_count": 20, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -170,7 +170,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 8, "id": "ea66211a", "metadata": {}, "outputs": [], @@ -180,7 +180,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 9, "id": "a911808f", "metadata": {}, "outputs": [ @@ -190,7 +190,7 @@ "dict_keys(['bus', 'gen', 'branch', 'dcline', 'if', 'gencost', 'dclinecost', 'bus_name', 'branch_name', 'gen_name', 'case'])" ] }, - "execution_count": 22, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -201,7 +201,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 10, "id": "f63470e2", "metadata": {}, "outputs": [ @@ -211,7 +211,7 @@ "{'baseMVA', 'reserves', 'version'}" ] }, - "execution_count": 40, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -225,7 +225,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 11, "id": "8577fe89", "metadata": {}, "outputs": [ @@ -242,7 +242,7 @@ " [200.]])}" ] }, - "execution_count": 41, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -273,7 +273,7 @@ }, { "cell_type": "code", - "execution_count": 54, + "execution_count": 12, "id": "aaf701d3", "metadata": {}, "outputs": [], @@ -283,7 +283,7 @@ }, { "cell_type": "code", - "execution_count": 55, + "execution_count": 13, "id": "370d5e7c", "metadata": {}, "outputs": [ @@ -339,7 +339,7 @@ "1 1.0 1.0 1.0 0.0" ] }, - "execution_count": 55, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -375,7 +375,7 @@ }, { "cell_type": "code", - "execution_count": 56, + "execution_count": 14, "id": "b817c54f", "metadata": {}, "outputs": [ @@ -422,7 +422,7 @@ "1 150.0" ] }, - "execution_count": 56, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -451,7 +451,7 @@ }, { "cell_type": "code", - "execution_count": 57, + "execution_count": 15, "id": "fb21239e", "metadata": {}, "outputs": [ @@ -461,7 +461,7 @@ "RangeIndex(start=1, stop=4, step=1, name='gen')" ] }, - "execution_count": 57, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -474,7 +474,7 @@ }, { "cell_type": "code", - "execution_count": 58, + "execution_count": 16, "id": "ebe8a6de", "metadata": {}, "outputs": [ @@ -531,7 +531,7 @@ "3 5.0" ] }, - "execution_count": 58, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -558,7 +558,7 @@ }, { "cell_type": "code", - "execution_count": 59, + "execution_count": 17, "id": "4e486ee1", "metadata": {}, "outputs": [ @@ -583,7 +583,7 @@ " \n", " \n", " \n", - " C1\n", + " PQTY\n", " \n", " \n", " gen\n", @@ -608,25 +608,333 @@ "" ], "text/plain": [ - " C1\n", + " PQTY\n", "gen \n", "1 100.0\n", "2 100.0\n", "3 200.0" ] }, - "execution_count": 59, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_reserves_qty = pd.DataFrame(\n", - " mpc.reserves.qty, index=idx_gen_with_reserves, columns=[\"C1\"]\n", + " mpc.reserves.qty, index=idx_gen_with_reserves, columns=[\"PQTY\"]\n", ")\n", "df_reserves_qty" ] }, + { + "cell_type": "code", + "execution_count": 25, + "id": "5389d132", + "metadata": {}, + "outputs": [], + "source": [ + "def reserves_to_dataframes(reserves):\n", + " \"\"\"\n", + " Convert all mpc.reserves data to DataFrames.\n", + "\n", + " Args:\n", + " reserves: mpc.reserves object from MATPOWER\n", + "\n", + " Returns:\n", + " Dictionary containing:\n", + " - 'zones': Reserve zones DataFrame\n", + " - 'req': Reserve requirements DataFrame\n", + " - 'cost': Reserve costs DataFrame (if exists)\n", + " - 'qty': Reserve quantities DataFrame (if exists)\n", + " \"\"\"\n", + " dfs = {}\n", + " n_zones, n_gens = reserves.zones.shape\n", + " dfs[\"zones\"] = pd.DataFrame(\n", + " reserves.zones,\n", + " index=pd.RangeIndex(start=1, stop=n_zones + 1, name=\"zone\"),\n", + " columns=pd.RangeIndex(start=1, stop=n_gens + 1, name=\"gen\"),\n", + " )\n", + " zone_sum = dfs[\"zones\"].sum(axis=0)\n", + " idx_gen_with_reserves = zone_sum[zone_sum > 0].index\n", + " dfs[\"req\"] = pd.DataFrame(\n", + " reserves.req,\n", + " index=pd.RangeIndex(start=1, stop=n_zones + 1, name=\"zone\"),\n", + " columns=[\"PREQ\"],\n", + " )\n", + " if hasattr(reserves, \"cost\"):\n", + " dfs[\"cost\"] = pd.DataFrame(\n", + " reserves.cost, index=idx_gen_with_reserves, columns=[\"C1\"]\n", + " )\n", + " if hasattr(reserves, \"qty\"):\n", + " dfs[\"qty\"] = pd.DataFrame(\n", + " reserves.qty, index=idx_gen_with_reserves, columns=[\"PQTY\"]\n", + " )\n", + "\n", + " return dfs" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "a686e0ab", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "zones\n" + ] + }, + { + "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", + "
gen123456
zone
11.01.01.00.00.00.0
\n", + "
" + ], + "text/plain": [ + "gen 1 2 3 4 5 6\n", + "zone \n", + "1 1.0 1.0 1.0 0.0 0.0 0.0" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "req\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
PREQ
zone
1150.0
\n", + "
" + ], + "text/plain": [ + " PREQ\n", + "zone \n", + "1 150.0" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "cost\n" + ] + }, + { + "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", + "
C1
gen
11.0
23.0
35.0
\n", + "
" + ], + "text/plain": [ + " C1\n", + "gen \n", + "1 1.0\n", + "2 3.0\n", + "3 5.0" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "qty\n" + ] + }, + { + "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", + "
PQTY
gen
1100.0
2100.0
3200.0
\n", + "
" + ], + "text/plain": [ + " PQTY\n", + "gen \n", + "1 100.0\n", + "2 100.0\n", + "3 200.0" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "dfs = reserves_to_dataframes(mpc.reserves)\n", + "for key, value in dfs.items():\n", + " print(key)\n", + " display(value)" + ] + }, { "cell_type": "markdown", "id": "8789a89c", @@ -639,7 +947,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 18, "id": "65bf6c72", "metadata": {}, "outputs": [ @@ -716,7 +1024,7 @@ " [1.]])}" ] }, - "execution_count": 7, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -728,7 +1036,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 19, "id": "9688f94d", "metadata": {}, "outputs": [ @@ -874,7 +1182,7 @@ " [1.]])}]" ] }, - "execution_count": 8, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -886,7 +1194,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 20, "id": "676057c0", "metadata": {}, "outputs": [ @@ -912,7 +1220,7 @@ " [0.95]])}" ] }, - "execution_count": 9, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } @@ -924,7 +1232,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 21, "id": "2bcf5d64", "metadata": {}, "outputs": [ @@ -940,7 +1248,7 @@ " values" ] }, - "execution_count": 10, + "execution_count": 21, "metadata": {}, "output_type": "execute_result" } @@ -952,7 +1260,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 22, "id": "ee0cec81", "metadata": {}, "outputs": [], @@ -962,7 +1270,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 23, "id": "c9726cc1", "metadata": {}, "outputs": [ @@ -1150,7 +1458,7 @@ " 'MaxStorageLevel': 200.0}]" ] }, - "execution_count": 12, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } @@ -1162,12 +1470,12 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 24, "id": "159b9137", "metadata": {}, "outputs": [], "source": [ - "# m.exit()" + "m.exit()" ] }, { diff --git a/notebooks/load_t_case30_userfcns.ipynb b/notebooks/load_t_case30_userfcns.ipynb index 39b125b..39d9b92 100644 --- a/notebooks/load_t_case30_userfcns.ipynb +++ b/notebooks/load_t_case30_userfcns.ipynb @@ -66,7 +66,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 4, "id": "10fd2d91", "metadata": {}, "outputs": [], @@ -76,7 +76,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "id": "7e230eb0", "metadata": {}, "outputs": [], @@ -86,7 +86,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 6, "id": "6d93dd06", "metadata": {}, "outputs": [ @@ -366,7 +366,7 @@ " [ 2., -10., 20.]])}}" ] }, - "execution_count": 8, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -379,7 +379,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 7, "id": "b6bbbce4", "metadata": {}, "outputs": [ @@ -389,7 +389,7 @@ "dict_keys(['version', 'baseMVA', 'bus', 'gen', 'branch', 'gencost', 'reserves', 'if'])" ] }, - "execution_count": 9, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -400,7 +400,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 8, "id": "ea66211a", "metadata": {}, "outputs": [], @@ -410,7 +410,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 9, "id": "a911808f", "metadata": {}, "outputs": [ @@ -420,7 +420,7 @@ "dict_keys(['bus', 'gen', 'branch', 'dcline', 'if', 'gencost', 'dclinecost', 'bus_name', 'branch_name', 'gen_name', 'case'])" ] }, - "execution_count": 11, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -431,7 +431,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 10, "id": "f63470e2", "metadata": {}, "outputs": [ @@ -441,7 +441,7 @@ "{'baseMVA', 'reserves', 'version'}" ] }, - "execution_count": 22, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -455,7 +455,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 11, "id": "8577fe89", "metadata": {}, "outputs": [ @@ -477,11 +477,10 @@ " [25.],\n", " [25.],\n", " [25.],\n", - " [25.]]),\n", - " 'getdoc': {}}" + " [25.]])}" ] }, - "execution_count": 23, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -511,7 +510,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 12, "id": "370d5e7c", "metadata": {}, "outputs": [ @@ -583,7 +582,7 @@ "2 0.0 0.0 0.0 0.0 1.0 1.0" ] }, - "execution_count": 24, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -621,7 +620,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 13, "id": "b817c54f", "metadata": {}, "outputs": [ @@ -673,7 +672,7 @@ "2 20.0" ] }, - "execution_count": 25, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -690,7 +689,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 14, "id": "227155ed", "metadata": {}, "outputs": [ @@ -700,7 +699,7 @@ "RangeIndex(start=1, stop=7, step=1, name='gen')" ] }, - "execution_count": 37, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -713,7 +712,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 15, "id": "8c5f69a2", "metadata": {}, "outputs": [ @@ -785,7 +784,7 @@ "6 5.5" ] }, - "execution_count": 39, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -798,9 +797,108 @@ "df_reserves_cost" ] }, + { + "cell_type": "markdown", + "id": "8be24e2e", + "metadata": {}, + "source": [ + "max reserve quantities for each gen that belongs to at least 1 zone. (same order as\n", + "gens, but skipping any gen that does not belong to any zone)\n", + "\n", + "```octave\n", + "mpc.reserves.qty = [\t25;\t25;\t25;\t25;\t25;\t25\t];\n", + "```" + ] + }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 16, + "id": "bd64557b", + "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", + "
PQTY
gen
125.0
225.0
325.0
425.0
525.0
625.0
\n", + "
" + ], + "text/plain": [ + " PQTY\n", + "gen \n", + "1 25.0\n", + "2 25.0\n", + "3 25.0\n", + "4 25.0\n", + "5 25.0\n", + "6 25.0" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_reserves_qty = pd.DataFrame(\n", + " mpc.reserves.qty, index=idx_gen_with_reserves, columns=[\"PQTY\"]\n", + ")\n", + "df_reserves_qty" + ] + }, + { + "cell_type": "code", + "execution_count": 17, "id": "6bda4dbb", "metadata": {}, "outputs": [ @@ -825,7 +923,7 @@ " [ 2., -10., 20.]])}" ] }, - "execution_count": 45, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -837,12 +935,12 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 18, "id": "159b9137", "metadata": {}, "outputs": [], "source": [ - "# m.exit()" + "m.exit()" ] }, { From 777c28e3fbaa969ec29fc4c02490ad9faaaf4d84 Mon Sep 17 00:00:00 2001 From: Muhammad Yasirroni Date: Fri, 16 Jan 2026 18:31:03 +1100 Subject: [PATCH 5/6] support reserves --- matpowercaseframes/constants.py | 6 + matpowercaseframes/core.py | 116 ++++++++-- notebooks/load_most_ex_case3a.ipynb | 334 +++++++++++++++++++++++++++- 3 files changed, 434 insertions(+), 22 deletions(-) diff --git a/matpowercaseframes/constants.py b/matpowercaseframes/constants.py index 7fe3012..9ebf361 100644 --- a/matpowercaseframes/constants.py +++ b/matpowercaseframes/constants.py @@ -15,6 +15,7 @@ "dcline", "dclinecost", "case", + "reserves", ) COLUMNS = { @@ -112,6 +113,11 @@ "MU_QMINT", "MU_QMAXT", ], + "reserves": { + "req": ["PREQ"], + "cost": ["C1"], + "qty": ["PQTY"], + }, "if": { # negative 'BRANCHIDX' defines opposite direction "map": ["IFNUM", "BRANCHIDX"], diff --git a/matpowercaseframes/core.py b/matpowercaseframes/core.py index bb7d34c..11f5517 100644 --- a/matpowercaseframes/core.py +++ b/matpowercaseframes/core.py @@ -20,6 +20,38 @@ MATPOWER_EXIST = False +class ReservesFrames: + """A struct-like container for reserves data, similar to CaseFrames.""" + + def __init__(self, data=None): + """ + Initialize ReservesFrames with optional data. + + Args: + data (dict, optional): Dictionary containing reserves DataFrames. + Expected keys: 'zones', 'req', 'cost', 'qty' + """ + self._attributes = [] + + if data is not None: + if isinstance(data, dict): + for key, value in data.items(): + self.setattr(key, value) + else: + raise TypeError(f"ReservesFrames data must be a dict, got {type(data)}") + + def setattr(self, name, value): + """Set attribute and track it in _attributes list.""" + if name not in self._attributes: + self._attributes.append(name) + self.__setattr__(name, value) + + @property + def attributes(self): + """List of attributes in this ReservesFrames object.""" + return self._attributes + + class CaseFrames: def __init__( self, @@ -281,6 +313,9 @@ def _read_oct2py_struct(self, struct, allow_any_keys=False): value = list_ elif attribute in ["bus_name", "branch_name", "gen_name"]: value = pd.Index([name[0] for name in list_], name=attribute) + elif attribute in ["reserves"]: + dfs = reserves_data_to_dataframes(list_) + value = ReservesFrames(dfs) else: # bus, branch, gen, gencost, dcline, dclinecost list_ = np.atleast_2d(list_) n_cols = list_.shape[1] @@ -516,6 +551,7 @@ def _update_index(self, allow_any_keys=False): ) # gencost is optional + # NOTE: try except is better than checking hasattr for common possitive try: if "gen_name" in self._attributes: self.gencost.set_index(self.gen_name, drop=False, inplace=True) @@ -526,28 +562,35 @@ def _update_index(self, allow_any_keys=False): inplace=True, ) except AttributeError: + # for when self.gencost doesn't exist pass + # NOTE: try hasattr is better than try except for common negative + if hasattr(self, "reserves"): + self.reserves.zones.columns = pd.RangeIndex( + start=1, stop=len(self.gen.index) + 1, name="gen" + ) + # other attributes if allow_any_keys: - for attribute in self._attributes: - if attribute in ["bus", "branch", "gen", "gencost"]: - continue - attribute_data = getattr(self, attribute) - if isinstance(attribute_data, (pd.DataFrame, pd.Series)): - # check if index is a RangeIndex - if attribute_data.index.dtype == int: - # replace the index with a new RangeIndex starting at 1 - attribute_data.set_index( - pd.RangeIndex( - start=1, stop=len(attribute_data) + 1, name=attribute - ), - drop=False, - inplace=True, - ) + self._update_index_any() - # TODO: - # For mpc.reserves.zones, the columns use cf.gen.index. + def _update_index_any(self): + for attribute in self._attributes: + if attribute in ["bus", "branch", "gen", "gencost", "reserves"]: + continue + attribute_data = getattr(self, attribute) + if isinstance(attribute_data, (pd.DataFrame, pd.Series)): + # check if index is a RangeIndex + if attribute_data.index.dtype == int: + # replace the index with a new RangeIndex starting at 1 + attribute_data.set_index( + pd.RangeIndex( + start=1, stop=len(attribute_data) + 1, name=attribute + ), + drop=False, + inplace=True, + ) def infer_numpy(self): """ @@ -817,3 +860,42 @@ def to_schema(self, path, prefix="", suffix=""): if "case" not in self._attributes: self.add_schema_case() self.to_csv(path, prefix=prefix, suffix=suffix) + + +def reserves_data_to_dataframes(reserves): + """ + Convert all mpc.reserves struct data to DataFrames. + + Args: + reserves: Octave struct or dictionary of mpc.reserves object from MATPOWER + + Returns: + Dictionary containing: + - 'zones': Reserve zones DataFrame + - 'req': Reserve requirements DataFrame + - 'cost': Reserve costs DataFrame (if exists) + - 'qty': Reserve quantities DataFrame (if exists) + """ + dfs = {} + n_zones, n_gens = reserves.zones.shape + dfs["zones"] = pd.DataFrame( + reserves.zones, + index=pd.RangeIndex(start=1, stop=n_zones + 1, name="zone"), + columns=pd.RangeIndex(start=1, stop=n_gens + 1, name="gen"), + ) + zone_sum = dfs["zones"].sum(axis=0) + idx_gen_with_reserves = zone_sum[zone_sum > 0].index + dfs["req"] = pd.DataFrame( + reserves.req, + index=pd.RangeIndex(start=1, stop=n_zones + 1, name="zone"), + columns=["PREQ"], + ) + if hasattr(reserves, "cost"): + dfs["cost"] = pd.DataFrame( + reserves.cost, index=idx_gen_with_reserves, columns=["C1"] + ) + if hasattr(reserves, "qty"): + dfs["qty"] = pd.DataFrame( + reserves.qty, index=idx_gen_with_reserves, columns=["PQTY"] + ) + return dfs diff --git a/notebooks/load_most_ex_case3a.ipynb b/notebooks/load_most_ex_case3a.ipynb index 5aba7c2..126ee8e 100644 --- a/notebooks/load_most_ex_case3a.ipynb +++ b/notebooks/load_most_ex_case3a.ipynb @@ -61,7 +61,9 @@ "import os\n", "\n", "import pandas as pd\n", - "from matpower import path_matpower, start_instance" + "from matpower import path_matpower, start_instance\n", + "\n", + "from matpowercaseframes import CaseFrames" ] }, { @@ -629,12 +631,12 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": null, "id": "5389d132", "metadata": {}, "outputs": [], "source": [ - "def reserves_to_dataframes(reserves):\n", + "def reserves_data_to_dataframes(reserves):\n", " \"\"\"\n", " Convert all mpc.reserves data to DataFrames.\n", "\n", @@ -676,7 +678,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": null, "id": "a686e0ab", "metadata": {}, "outputs": [ @@ -929,12 +931,334 @@ } ], "source": [ - "dfs = reserves_to_dataframes(mpc.reserves)\n", + "dfs = reserves_data_to_dataframes(mpc.reserves)\n", "for key, value in dfs.items():\n", " print(key)\n", " display(value)" ] }, + { + "cell_type": "code", + "execution_count": 10, + "id": "87bc9631", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "zones\n" + ] + }, + { + "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", + "
gen1234
zone
11.01.01.00.0
\n", + "
" + ], + "text/plain": [ + "gen 1 2 3 4\n", + "zone \n", + "1 1.0 1.0 1.0 0.0" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "req\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
PREQ
zone
1150.0
\n", + "
" + ], + "text/plain": [ + " PREQ\n", + "zone \n", + "1 150.0" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "cost\n" + ] + }, + { + "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", + "
C1
gen
11.0
23.0
35.0
\n", + "
" + ], + "text/plain": [ + " C1\n", + "gen \n", + "1 1.0\n", + "2 3.0\n", + "3 5.0" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "qty\n" + ] + }, + { + "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", + "
PQTY
gen
1100.0
2100.0
3200.0
\n", + "
" + ], + "text/plain": [ + " PQTY\n", + "gen \n", + "1 100.0\n", + "2 100.0\n", + "3 200.0" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "cf = CaseFrames(os.path.join(path_most_ex_cases, \"ex_case3a.m\"), load_case_engine=m)\n", + "for attribute in cf.reserves._attributes:\n", + " print(attribute)\n", + " display(getattr(cf.reserves, attribute))" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "71fd2c3b", + "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", + "
gen1234
zone
11.01.01.00.0
\n", + "
" + ], + "text/plain": [ + "gen 1 2 3 4\n", + "zone \n", + "1 1.0 1.0 1.0 0.0" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cf.reserves.zones" + ] + }, { "cell_type": "markdown", "id": "8789a89c", From 51b7398def3fd5fdb42ab8f4cb35077eec7348af Mon Sep 17 00:00:00 2001 From: Muhammad Yasirroni Date: Fri, 16 Jan 2026 18:39:30 +1100 Subject: [PATCH 6/6] test start from 3.10 only --- .github/workflows/build.yml | 2 +- .github/workflows/publish.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 788fa95..37602b0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -26,7 +26,7 @@ jobs: build: strategy: matrix: - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.14"] platform: [octave] os: [ubuntu-latest] diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 339c39a..0d16d05 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -7,7 +7,7 @@ jobs: build: strategy: matrix: - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] platform: [octave] os: [ubuntu-latest]