Skip to content

Commit

Permalink
Merge pull request #648 from figueroa1395/feature/metadata-enum
Browse files Browse the repository at this point in the history
Feature/metadata datatypes
  • Loading branch information
figueroa1395 authored Jul 1, 2024
2 parents 047d7f0 + f717b81 commit 7a72a69
Show file tree
Hide file tree
Showing 39 changed files with 1,230 additions and 709 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.8
1.9
1 change: 0 additions & 1 deletion code_generation/code_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ def render_dataset_class_maps(self, template_path: Path, data_path: Path, output
for component_name in component.names:
all_components[component_name] = [x.names for x in class_def.full_attributes]
all_map[f"{prefix}{dataset.name}"] = all_components

self.render_template(template_path=template_path, output_path=output_path, all_map=all_map)

def code_gen(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
#
# SPDX-License-Identifier: MPL-2.0

"""Data types for power grid model dataset and component types."""

# This file is automatically generated. DO NOT modify it manually!

{%- set dataset_types = all_map.keys() %}
{%- set components = all_map['input'].keys() %}

from enum import Enum, EnumMeta
from typing import Any, Dict, Mapping

# pylint: disable=invalid-name

# fmt: off

class _MetaEnum(EnumMeta):
def __contains__(cls, member):
"""
Check if member is part of the Enum.

Args:
member: Member to check.

Returns:
bool: True if the member is part of the Enum, False otherwise.
"""
return member in cls.__members__.keys()


class DatasetType(str, Enum, metaclass=_MetaEnum):
"""
A DatasetType is the type of a :class:`Dataset` in power grid model.

- Examples:

- DatasetType.input = "input"
- DatasetType.update = "update"
"""
{% for dataset_type in dataset_types %}
{{ dataset_type }} = "{{ dataset_type }}"
{%- endfor %}


class ComponentType(str, Enum):
"""
A ComponentType is the type of a grid component.

- Examples:

- ComponentType.node = "node"
- ComponentType.line = "line"
"""
{% for component in components %}
{{ component }} = "{{ component }}"
{%- endfor %}


# pylint: enable=invalid-name


def _str_to_datatype(data_type: Any) -> DatasetType:
"""Helper function to transform data_type str to DatasetType."""
if isinstance(data_type, str):
return DatasetType[data_type]
return data_type


def _map_to_datatypes(data: Mapping[Any, Any]) -> Dict[DatasetType, Any]:
"""Helper function to map datatype str keys to DatasetType."""
return {_str_to_datatype(key): value for key, value in data.items()}


def _str_to_component_type(component: Any) -> ComponentType:
"""Helper function to transform component str to ComponentType."""
if isinstance(component, str):
return ComponentType[component]
return component


def _map_to_component_types(data: Mapping[Any, Any]) -> Dict[ComponentType, Any]:
"""Helper function to map componenttype str keys to ComponentType."""
return {_str_to_component_type(key): value for key, value in data.items()}


# fmt: on

12 changes: 8 additions & 4 deletions docs/advanced_documentation/native-data-interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,12 @@ For example, the following update dataset will set `from_status` of the line #5
and keep the `to_status` as unchanged (change not available).

```python
from power_grid_model import power_grid_meta_data
from power_grid_model import ComponentType, DatasetType, power_grid_meta_data
import numpy as np

line_update = np.empty(shape=1, dtype=power_grid_meta_data['update']['line']['dtype'])
line_update = np.empty(shape=1, dtype=power_grid_meta_data[DatasetType.update][ComponentType.line]['dtype'])
# direct string access is supported as well:
# line_update = np.empty(shape=1, dtype=power_grid_meta_data['update']['line']['dtype'])
line_update['id'] = [5]
line_update['from_status'] = [0]
line_update['to_status'] = [-128]
Expand Down Expand Up @@ -137,9 +139,11 @@ One can import the `power_grid_meta_data` to get all the predefined `numpy.dtype
The code below creates an array which is compatible with transformer input dataset.

```python
from power_grid_model import power_grid_meta_data
from power_grid_model import ComponentType, DatasetType, power_grid_meta_data

transformer = np.empty(shape=5, dtype=power_grid_meta_data['input']['transformer']['dtype'])
transformer = np.empty(shape=5, dtype=power_grid_meta_data[DatasetType.input][ComponentType.transformer]['dtype'])
# direct string access is supported as well:
# transformer = np.empty(shape=5, dtype=power_grid_meta_data['input']['transformer']['dtype'])
```

Furthermore, there is an even more convenient function `initialize_array`
Expand Down
2 changes: 2 additions & 0 deletions docs/api_reference/python-api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ SPDX-License-Identifier: MPL-2.0
.. autoclass:: power_grid_model.data_types.BatchArray
.. autoclass:: power_grid_model.data_types.DenseBatchArray
.. autoclass:: power_grid_model.data_types.SparseBatchArray
.. autoclass:: power_grid_model.dataset_definitions.DatasetType
.. autoclass:: power_grid_model.dataset_definitions.ComponentType
```

## error types
Expand Down
64 changes: 32 additions & 32 deletions docs/examples/Asymmetric Calculation Example.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
" # suppress warning about pyarrow as future required dependency\n",
" import pandas as pd\n",
"\n",
"from power_grid_model import LoadGenType\n",
"from power_grid_model import LoadGenType, ComponentType, DatasetType\n",
"from power_grid_model import PowerGridModel, CalculationMethod, CalculationType, MeasuredTerminalType\n",
"from power_grid_model import initialize_array"
]
Expand Down Expand Up @@ -83,12 +83,12 @@
"outputs": [],
"source": [
"# node\n",
"node = initialize_array(\"input\", \"node\", 3)\n",
"node = initialize_array(DatasetType.input, ComponentType.node, 3)\n",
"node[\"id\"] = np.array([1, 2, 6])\n",
"node[\"u_rated\"] = [10.5e3, 10.5e3, 10.5e3]\n",
"\n",
"# line\n",
"line = initialize_array(\"input\", \"line\", 3)\n",
"line = initialize_array(DatasetType.input, ComponentType.line, 3)\n",
"line[\"id\"] = [3, 5, 8]\n",
"line[\"from_node\"] = [1, 2, 1]\n",
"line[\"to_node\"] = [2, 6, 6]\n",
Expand All @@ -105,7 +105,7 @@
"line[\"tan0\"] = [0, 0, 0]\n",
"\n",
"# sym load\n",
"sym_load = initialize_array(\"input\", \"sym_load\", 1)\n",
"sym_load = initialize_array(DatasetType.input, ComponentType.sym_load, 1)\n",
"sym_load[\"id\"] = [4]\n",
"sym_load[\"node\"] = [2]\n",
"sym_load[\"status\"] = [1]\n",
Expand All @@ -114,7 +114,7 @@
"sym_load[\"q_specified\"] = [5e6]\n",
"\n",
"# asym load\n",
"asym_load = initialize_array(\"input\", \"asym_load\", 1)\n",
"asym_load = initialize_array(DatasetType.input, ComponentType.asym_load, 1)\n",
"asym_load[\"id\"] = [7]\n",
"asym_load[\"node\"] = [6]\n",
"asym_load[\"status\"] = [1]\n",
Expand All @@ -123,19 +123,19 @@
"asym_load[\"q_specified\"] = [[0, 8e6, 2e6]] # the 3 phases may have different loads\n",
"\n",
"# source\n",
"source = initialize_array(\"input\", \"source\", 1)\n",
"source = initialize_array(DatasetType.input, ComponentType.source, 1)\n",
"source[\"id\"] = [10]\n",
"source[\"node\"] = [1]\n",
"source[\"status\"] = [1]\n",
"source[\"u_ref\"] = [1.0]\n",
"\n",
"# all\n",
"asym_input_data = {\n",
" \"node\": node,\n",
" \"line\": line,\n",
" \"sym_load\": sym_load,\n",
" \"asym_load\": asym_load,\n",
" \"source\": source\n",
" ComponentType.node: node,\n",
" ComponentType.line: line,\n",
" ComponentType.sym_load: sym_load,\n",
" ComponentType.asym_load: asym_load,\n",
" ComponentType.source: source\n",
"}"
]
},
Expand Down Expand Up @@ -209,9 +209,9 @@
],
"source": [
"print(\"------node voltage result------\")\n",
"print(pd.DataFrame(asym_result[\"node\"][\"u\"]))\n",
"print(pd.DataFrame(asym_result[ComponentType.node][\"u\"]))\n",
"print(\"------node angle result------\")\n",
"print(pd.DataFrame(asym_result[\"node\"][\"u_angle\"]))"
"print(pd.DataFrame(asym_result[ComponentType.node][\"u_angle\"]))"
]
},
{
Expand Down Expand Up @@ -269,15 +269,15 @@
"outputs": [],
"source": [
"# note the shape of the array, 10 scenarios, 1 objects (asymmetric load_7)\n",
"load_profile = initialize_array(\"update\", \"asym_load\", (10, 1)) \n",
"load_profile = initialize_array(DatasetType.update, ComponentType.asym_load, (10, 1)) \n",
"\n",
"# this is a scale of asym_load from 0% to 100%------------------\n",
"# the array is an (10, 1, 3) shape, which shows (scenario, object, phase).\n",
"# Users can always customize the load_profile in different ways.\n",
"load_profile[\"id\"] = [7]\n",
"load_profile[\"p_specified\"] = [10e6, 20e6 , 0] * np.linspace(0, 1, 10).reshape(-1, 1, 1)\n",
"\n",
"time_series_mutation = {\"asym_load\": load_profile}"
"time_series_mutation = {ComponentType.asym_load: load_profile}"
]
},
{
Expand Down Expand Up @@ -389,7 +389,7 @@
}
],
"source": [
"display(pd.DataFrame(output_data[\"line\"][\"p_from\"][0]))"
"display(pd.DataFrame(output_data[ComponentType.line][\"p_from\"][0]))"
]
},
{
Expand Down Expand Up @@ -519,7 +519,7 @@
}
],
"source": [
"display(pd.DataFrame(output_data[\"line\"][\"i_from\"][:,0]))"
"display(pd.DataFrame(output_data[ComponentType.line][\"i_from\"][:,0]))"
]
},
{
Expand All @@ -541,22 +541,22 @@
"outputs": [],
"source": [
"# sym voltage sensor\n",
"sym_voltage_sensor = initialize_array(\"input\", \"sym_voltage_sensor\", 2)\n",
"sym_voltage_sensor = initialize_array(DatasetType.input, ComponentType.sym_voltage_sensor, 2)\n",
"sym_voltage_sensor[\"id\"] = [11, 12]\n",
"sym_voltage_sensor[\"measured_object\"] = [1, 2]\n",
"sym_voltage_sensor[\"u_sigma\"] = [100, 10]\n",
"sym_voltage_sensor[\"u_measured\"] = [6000, 5500]\n",
"\n",
"# asym voltage sensor\n",
"asym_voltage_sensor = initialize_array(\"input\", \"asym_voltage_sensor\", 1)\n",
"asym_voltage_sensor = initialize_array(DatasetType.input, ComponentType.asym_voltage_sensor, 1)\n",
"asym_voltage_sensor[\"id\"] = [13]\n",
"asym_voltage_sensor[\"measured_object\"] = [6]\n",
"asym_voltage_sensor[\"u_sigma\"] = [100]\n",
"asym_voltage_sensor[\"u_measured\"] = [[5640, 5000, 6000]]\n",
"\n",
"\n",
"# sym power sensor\n",
"sym_power_sensor = initialize_array(\"input\", \"sym_power_sensor\", 7)\n",
"sym_power_sensor = initialize_array(DatasetType.input, ComponentType.sym_power_sensor, 7)\n",
"sym_power_sensor[\"id\"] = [14, 15, 16, 17, 18, 19, 20]\n",
"sym_power_sensor[\"measured_object\"] = [3, 3, 5, 5, 8, 8, 4]\n",
"sym_power_sensor[\"measured_terminal_type\"] = [\n",
Expand All @@ -570,7 +570,7 @@
"sym_power_sensor[\"q_measured\"] = [5e6, -7e6, 2e6, -2e6, 5e6, -5e6, 5e6]\n",
"\n",
"# asym power sensor\n",
"asym_power_sensor = initialize_array(\"input\", \"asym_power_sensor\", 1)\n",
"asym_power_sensor = initialize_array(DatasetType.input, ComponentType.asym_power_sensor, 1)\n",
"asym_power_sensor[\"id\"] = [21]\n",
"asym_power_sensor[\"measured_object\"] = [6]\n",
"asym_power_sensor[\"measured_terminal_type\"] = [MeasuredTerminalType.node]\n",
Expand All @@ -580,15 +580,15 @@
"\n",
"# all \n",
"asym_input_data = {\n",
" \"node\": node,\n",
" \"line\": line,\n",
" \"sym_load\": sym_load,\n",
" \"asym_load\": asym_load,\n",
" \"source\": source,\n",
" \"sym_voltage_sensor\": sym_voltage_sensor,\n",
" \"asym_voltage_sensor\": asym_voltage_sensor,\n",
" \"sym_power_sensor\": sym_power_sensor,\n",
" \"asym_power_sensor\": asym_power_sensor,\n",
" ComponentType.node: node,\n",
" ComponentType.line: line,\n",
" ComponentType.sym_load: sym_load,\n",
" ComponentType.asym_load: asym_load,\n",
" ComponentType.source: source,\n",
" ComponentType.sym_voltage_sensor: sym_voltage_sensor,\n",
" ComponentType.asym_voltage_sensor: asym_voltage_sensor,\n",
" ComponentType.sym_power_sensor: sym_power_sensor,\n",
" ComponentType.asym_power_sensor: asym_power_sensor,\n",
"}"
]
},
Expand Down Expand Up @@ -788,10 +788,10 @@
],
"source": [
"print(\"------node voltage result------\")\n",
"display(pd.DataFrame(asym_result[\"sym_voltage_sensor\"][\"u_residual\"]))\n",
"display(pd.DataFrame(asym_result[ComponentType.sym_voltage_sensor][\"u_residual\"]))\n",
"\n",
"print(\"------sym_load result------\")\n",
"display(pd.DataFrame(asym_result[\"sym_power_sensor\"][\"p_residual\"]))"
"display(pd.DataFrame(asym_result[ComponentType.sym_power_sensor][\"p_residual\"]))"
]
},
{
Expand Down
Loading

0 comments on commit 7a72a69

Please sign in to comment.