diff --git a/.gitignore b/.gitignore index 9f35ac1..e86e457 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# Octave +octave-workspace + # Local tests/results/*.xlsx diff --git a/matpowercaseframes/core.py b/matpowercaseframes/core.py index a5c74b5..d3cb37e 100644 --- a/matpowercaseframes/core.py +++ b/matpowercaseframes/core.py @@ -32,18 +32,11 @@ def __init__(self, data, update_index=True): TypeError: Error input data invalid. """ # TODO: support read excel + # TODO: support Path object if isinstance(data, str): - # TYPE: str of path | str of matpower case name - if not os.path.isfile(data): - # TYPE: str of matpower case name - if MATPOWER_EXIST: - data_ = os.path.join(matpower.path_matpower, f"data/{data}") - if os.path.isfile(data_): - data = data_ - else: - raise FileNotFoundError + path = self._get_path(data) # TYPE: str of path - self._read_matpower(filepath=data) + self._read_matpower(filepath=path) elif isinstance(data, dict): # TYPE: dict | oct2py.io.Struct self._read_oct2py_struct(struct=data) @@ -64,6 +57,30 @@ def __init__(self, data, update_index=True): if update_index: self._update_index() + @staticmethod + def _get_path(path): + # TYPE: str of path | str of matpower case name + if os.path.isfile(path): + return path + + path_added_m = path + '.m' + if os.path.isfile(path_added_m): + return path_added_m + + # TYPE: str of matpower case name + if MATPOWER_EXIST: + path_added_matpower = os.path.join(matpower.path_matpower, f"data/{path}") + if os.path.isfile(path_added_matpower): + return path_added_matpower + + path_added_matpower_m = os.path.join( + matpower.path_matpower, f"data/{path_added_m}" + ) + if os.path.isfile(path_added_matpower_m): + return path_added_matpower_m + + raise FileNotFoundError + def _read_matpower(self, filepath): # ! Old attribute is not guaranted to be replaced in re-read with open(filepath) as f: @@ -259,3 +276,11 @@ def to_dict(self): else: data[attribute] = getattr(self, attribute).values.tolist() return data + + def to_mpc(self): + """ + Convert CaseFrames into matpower-compatible data, that is dictionary + + The value of the data will be in str, numeric, and list. + """ + return self.to_dict() diff --git a/notebooks/load_case16am.ipynb b/notebooks/load_case16am.ipynb new file mode 100644 index 0000000..fafec97 --- /dev/null +++ b/notebooks/load_case16am.ipynb @@ -0,0 +1,701 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext autoreload\n", + "%autoreload 2" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "from matpower import start_instance\n", + "from matpowercaseframes import CaseFrames" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "m = start_instance()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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
1120.00001.000000e-080000001-360360
2230.12021.603000e-010000001-360360
3340.12821.763000e-010000001-360360
4350.14422.885000e-010000001-360360
5560.06416.410000e-020000001-360360
6270.17631.763000e-010000001-360360
7780.12821.763000e-010000001-360360
8790.17631.763000e-010000001-360360
98100.17631.763000e-010000001-360360
108110.12821.763000e-010000001-360360
112120.17631.763000e-010000001-360360
1212130.14421.923000e-010000001-360360
1312140.12821.763000e-010000001-360360
1414150.06416.410000e-020000001-360360
\n", + "
" + ], + "text/plain": [ + " F_BUS T_BUS BR_R BR_X BR_B RATE_A RATE_B RATE_C TAP \\\n", + "1 1 2 0.0000 1.000000e-08 0 0 0 0 0 \n", + "2 2 3 0.1202 1.603000e-01 0 0 0 0 0 \n", + "3 3 4 0.1282 1.763000e-01 0 0 0 0 0 \n", + "4 3 5 0.1442 2.885000e-01 0 0 0 0 0 \n", + "5 5 6 0.0641 6.410000e-02 0 0 0 0 0 \n", + "6 2 7 0.1763 1.763000e-01 0 0 0 0 0 \n", + "7 7 8 0.1282 1.763000e-01 0 0 0 0 0 \n", + "8 7 9 0.1763 1.763000e-01 0 0 0 0 0 \n", + "9 8 10 0.1763 1.763000e-01 0 0 0 0 0 \n", + "10 8 11 0.1282 1.763000e-01 0 0 0 0 0 \n", + "11 2 12 0.1763 1.763000e-01 0 0 0 0 0 \n", + "12 12 13 0.1442 1.923000e-01 0 0 0 0 0 \n", + "13 12 14 0.1282 1.763000e-01 0 0 0 0 0 \n", + "14 14 15 0.0641 6.410000e-02 0 0 0 0 0 \n", + "\n", + " SHIFT BR_STATUS ANGMIN ANGMAX \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 \n", + "10 0 1 -360 360 \n", + "11 0 1 -360 360 \n", + "12 0 1 -360 360 \n", + "13 0 1 -360 360 \n", + "14 0 1 -360 360 " + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "CASE_NAME = f\"case16am.m\"\n", + "cf_16am = CaseFrames(CASE_NAME)\n", + "cf_16am.branch" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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
11.02.00.0000006.239253e-100.00.00.00.00.00.01.0-360.0360.0
22.03.00.0075001.000152e-020.00.00.00.00.00.01.0-360.0360.0
33.04.00.0079991.099980e-020.00.00.00.00.00.01.0-360.0360.0
43.05.00.0089971.800024e-020.00.00.00.00.00.01.0-360.0360.0
55.06.00.0039993.999361e-030.00.00.00.00.00.01.0-360.0360.0
62.07.00.0110001.099980e-020.00.00.00.00.00.01.0-360.0360.0
77.08.00.0079991.099980e-020.00.00.00.00.00.01.0-360.0360.0
87.09.00.0110001.099980e-020.00.00.00.00.00.01.0-360.0360.0
98.010.00.0110001.099980e-020.00.00.00.00.00.01.0-360.0360.0
108.011.00.0079991.099980e-020.00.00.00.00.00.01.0-360.0360.0
112.012.00.0110001.099980e-020.00.00.00.00.00.01.0-360.0360.0
1212.013.00.0089971.199808e-020.00.00.00.00.00.01.0-360.0360.0
1312.014.00.0079991.099980e-020.00.00.00.00.00.01.0-360.0360.0
1414.015.00.0039993.999361e-030.00.00.00.00.00.01.0-360.0360.0
\n", + "
" + ], + "text/plain": [ + " F_BUS T_BUS BR_R BR_X BR_B RATE_A RATE_B RATE_C TAP \\\n", + "1 1.0 2.0 0.000000 6.239253e-10 0.0 0.0 0.0 0.0 0.0 \n", + "2 2.0 3.0 0.007500 1.000152e-02 0.0 0.0 0.0 0.0 0.0 \n", + "3 3.0 4.0 0.007999 1.099980e-02 0.0 0.0 0.0 0.0 0.0 \n", + "4 3.0 5.0 0.008997 1.800024e-02 0.0 0.0 0.0 0.0 0.0 \n", + "5 5.0 6.0 0.003999 3.999361e-03 0.0 0.0 0.0 0.0 0.0 \n", + "6 2.0 7.0 0.011000 1.099980e-02 0.0 0.0 0.0 0.0 0.0 \n", + "7 7.0 8.0 0.007999 1.099980e-02 0.0 0.0 0.0 0.0 0.0 \n", + "8 7.0 9.0 0.011000 1.099980e-02 0.0 0.0 0.0 0.0 0.0 \n", + "9 8.0 10.0 0.011000 1.099980e-02 0.0 0.0 0.0 0.0 0.0 \n", + "10 8.0 11.0 0.007999 1.099980e-02 0.0 0.0 0.0 0.0 0.0 \n", + "11 2.0 12.0 0.011000 1.099980e-02 0.0 0.0 0.0 0.0 0.0 \n", + "12 12.0 13.0 0.008997 1.199808e-02 0.0 0.0 0.0 0.0 0.0 \n", + "13 12.0 14.0 0.007999 1.099980e-02 0.0 0.0 0.0 0.0 0.0 \n", + "14 14.0 15.0 0.003999 3.999361e-03 0.0 0.0 0.0 0.0 0.0 \n", + "\n", + " SHIFT BR_STATUS ANGMIN ANGMAX \n", + "1 0.0 1.0 -360.0 360.0 \n", + "2 0.0 1.0 -360.0 360.0 \n", + "3 0.0 1.0 -360.0 360.0 \n", + "4 0.0 1.0 -360.0 360.0 \n", + "5 0.0 1.0 -360.0 360.0 \n", + "6 0.0 1.0 -360.0 360.0 \n", + "7 0.0 1.0 -360.0 360.0 \n", + "8 0.0 1.0 -360.0 360.0 \n", + "9 0.0 1.0 -360.0 360.0 \n", + "10 0.0 1.0 -360.0 360.0 \n", + "11 0.0 1.0 -360.0 360.0 \n", + "12 0.0 1.0 -360.0 360.0 \n", + "13 0.0 1.0 -360.0 360.0 \n", + "14 0.0 1.0 -360.0 360.0 " + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "CASE_NAME = f\"case16am.m\"\n", + "mpc = m.loadcase(CASE_NAME)\n", + "cf_16am = CaseFrames(mpc)\n", + "cf_16am.branch" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "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.12.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/requirements-dev.txt b/requirements-dev.txt index 6931ebf..c57f1e5 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -3,8 +3,8 @@ numpy>=1.21.5 openpyxl>=3.1.2 -oct2py>=5.5.1 -matpower>=7.1.0.2.1.4 +oct2py>=5.7.0 +matpower>=7.1.0.2.1.8 pytest pytest-cov diff --git a/tests/test_read_matpower_cases.py b/tests/test_read_matpower_cases.py index 0746a16..64bb115 100644 --- a/tests/test_read_matpower_cases.py +++ b/tests/test_read_matpower_cases.py @@ -1,4 +1,4 @@ -from matpower import path_matpower +from matpower import path_matpower, start_instance from matpowercaseframes import CaseFrames @@ -25,3 +25,20 @@ def test_case118(): def test_t_case9_dcline(): CASE_NAME = f"{path_matpower}/lib/t/t_case9_dcline.m" CaseFrames(CASE_NAME) + + +def test_loadcase_case16am(): + m = start_instance() + CASE_NAME = f"case16am.m" + mpc = m.loadcase(CASE_NAME) + CaseFrames(mpc) + m.exit() + +def test_read_without_ext(): + CASE_NAME = 'case9' + cf = CaseFrames(CASE_NAME) + + CASE_NAME = 'case9.m' + cf_ext = CaseFrames(CASE_NAME) + + assert True