r2x-sienna 0.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. r2x_sienna-0.0.0/LICENSE.txt +28 -0
  2. r2x_sienna-0.0.0/PKG-INFO +88 -0
  3. r2x_sienna-0.0.0/README.md +26 -0
  4. r2x_sienna-0.0.0/pyproject.toml +97 -0
  5. r2x_sienna-0.0.0/src/r2x_sienna/__init__.py +26 -0
  6. r2x_sienna-0.0.0/src/r2x_sienna/config.py +70 -0
  7. r2x_sienna-0.0.0/src/r2x_sienna/exporter.py +152 -0
  8. r2x_sienna-0.0.0/src/r2x_sienna/logger.py +16 -0
  9. r2x_sienna-0.0.0/src/r2x_sienna/models/__init__.py +180 -0
  10. r2x_sienna-0.0.0/src/r2x_sienna/models/attributes.py +68 -0
  11. r2x_sienna-0.0.0/src/r2x_sienna/models/base.py +134 -0
  12. r2x_sienna-0.0.0/src/r2x_sienna/models/branch.py +964 -0
  13. r2x_sienna-0.0.0/src/r2x_sienna/models/core.py +39 -0
  14. r2x_sienna-0.0.0/src/r2x_sienna/models/costs.py +203 -0
  15. r2x_sienna-0.0.0/src/r2x_sienna/models/enums.py +206 -0
  16. r2x_sienna-0.0.0/src/r2x_sienna/models/generators.py +1526 -0
  17. r2x_sienna-0.0.0/src/r2x_sienna/models/getters.py +93 -0
  18. r2x_sienna-0.0.0/src/r2x_sienna/models/load.py +228 -0
  19. r2x_sienna-0.0.0/src/r2x_sienna/models/named_tuples.py +54 -0
  20. r2x_sienna-0.0.0/src/r2x_sienna/models/py.typed +0 -0
  21. r2x_sienna-0.0.0/src/r2x_sienna/models/services.py +130 -0
  22. r2x_sienna-0.0.0/src/r2x_sienna/models/topology.py +108 -0
  23. r2x_sienna-0.0.0/src/r2x_sienna/parser.py +456 -0
  24. r2x_sienna-0.0.0/src/r2x_sienna/plugin.py +23 -0
  25. r2x_sienna-0.0.0/src/r2x_sienna/py.pyted +2 -0
  26. r2x_sienna-0.0.0/src/r2x_sienna/serialization.py +188 -0
  27. r2x_sienna-0.0.0/src/r2x_sienna/units.py +75 -0
  28. r2x_sienna-0.0.0/src/r2x_sienna/upgrader/__init__.py +13 -0
  29. r2x_sienna-0.0.0/src/r2x_sienna/upgrader/data_upgrader.py +76 -0
  30. r2x_sienna-0.0.0/src/r2x_sienna/upgrader/upgrade_steps.py +316 -0
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2025, PCM
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,88 @@
1
+ Metadata-Version: 2.3
2
+ Name: r2x-sienna
3
+ Version: 0.0.0
4
+ Summary: Sienna model plugin
5
+ Keywords: Sienna
6
+ Author: mcllerena, pesap
7
+ Author-email: mcllerena <mcllerena@users.noreply.github.com>, pesap <pesap@users.noreply.github.com>
8
+ License: BSD 3-Clause License
9
+
10
+ Copyright (c) 2025, PCM
11
+
12
+ Redistribution and use in source and binary forms, with or without
13
+ modification, are permitted provided that the following conditions are met:
14
+
15
+ 1. Redistributions of source code must retain the above copyright notice, this
16
+ list of conditions and the following disclaimer.
17
+
18
+ 2. Redistributions in binary form must reproduce the above copyright notice,
19
+ this list of conditions and the following disclaimer in the documentation
20
+ and/or other materials provided with the distribution.
21
+
22
+ 3. Neither the name of the copyright holder nor the names of its
23
+ contributors may be used to endorse or promote products derived from
24
+ this software without specific prior written permission.
25
+
26
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
30
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
34
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
+ Classifier: Development Status :: 4 - Beta
37
+ Classifier: Intended Audience :: Developers
38
+ Classifier: Intended Audience :: Science/Research
39
+ Classifier: License :: OSI Approved :: BSD License
40
+ Classifier: Topic :: Software Development :: Build Tools
41
+ Classifier: Programming Language :: Python
42
+ Classifier: Programming Language :: Python :: 3
43
+ Classifier: Programming Language :: Python :: 3 :: Only
44
+ Classifier: Programming Language :: Python :: 3.11
45
+ Classifier: Programming Language :: Python :: 3.12
46
+ Classifier: Programming Language :: Python :: 3.13
47
+ Classifier: License :: OSI Approved :: BSD License
48
+ Classifier: Natural Language :: English
49
+ Classifier: Operating System :: OS Independent
50
+ Classifier: Topic :: File Formats :: JSON
51
+ Classifier: Topic :: Scientific/Engineering
52
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
53
+ Classifier: Topic :: Scientific/Engineering :: Interface Engine/Protocol Translator
54
+ Classifier: Topic :: Software Development :: Build Tools
55
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
56
+ Classifier: Typing :: Typed
57
+ Requires-Dist: r2x-core>=0.1.1,<1.0.0
58
+ Maintainer: mcllerena, pesap
59
+ Maintainer-email: mcllerena <mcllerena@users.noreply.github.com>, pesap <pesap@users.noreply.github.com>
60
+ Requires-Python: >=3.11, <3.14
61
+ Description-Content-Type: text/markdown
62
+
63
+ # R2X-Sienna
64
+
65
+ > A plugin for the R2X framework that enables translation from Sienna (PowerSystems.jl) data formats to PLEXOS models.
66
+ >
67
+ > [![image](https://img.shields.io/pypi/v/r2x.svg)](https://pypi.python.org/pypi/r2x-sienna)
68
+ > [![image](https://img.shields.io/pypi/l/r2x.svg)](https://pypi.python.org/pypi/r2x-sienna)
69
+ > [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
70
+
71
+ ## Overview
72
+
73
+ R2X-Sienna provides seamless integration between Sienna and PLEXOS through the R2X translation framework. This plugin allows users to:
74
+
75
+ - Parse Sienna JSON/h5 system files
76
+ - Convert Sienna components to PLEXOS format
77
+ - Export complete PLEXOS XML databases
78
+ - Maintain data integrity during translation
79
+
80
+ ## Quick Start
81
+
82
+ ```bash
83
+ pip install r2x-sienna
84
+ ```
85
+
86
+ ## License
87
+
88
+ This project is licensed under a BSD 3-Clause License.
@@ -0,0 +1,26 @@
1
+ # R2X-Sienna
2
+
3
+ > A plugin for the R2X framework that enables translation from Sienna (PowerSystems.jl) data formats to PLEXOS models.
4
+ >
5
+ > [![image](https://img.shields.io/pypi/v/r2x.svg)](https://pypi.python.org/pypi/r2x-sienna)
6
+ > [![image](https://img.shields.io/pypi/l/r2x.svg)](https://pypi.python.org/pypi/r2x-sienna)
7
+ > [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
8
+
9
+ ## Overview
10
+
11
+ R2X-Sienna provides seamless integration between Sienna and PLEXOS through the R2X translation framework. This plugin allows users to:
12
+
13
+ - Parse Sienna JSON/h5 system files
14
+ - Convert Sienna components to PLEXOS format
15
+ - Export complete PLEXOS XML databases
16
+ - Maintain data integrity during translation
17
+
18
+ ## Quick Start
19
+
20
+ ```bash
21
+ pip install r2x-sienna
22
+ ```
23
+
24
+ ## License
25
+
26
+ This project is licensed under a BSD 3-Clause License.
@@ -0,0 +1,97 @@
1
+ [project]
2
+ name = "r2x-sienna"
3
+ version = "0.0.0"
4
+ readme = "README.md"
5
+ description = "Sienna model plugin"
6
+ license = {file = "LICENSE.txt"}
7
+ authors = [
8
+ { name = "mcllerena", email = "mcllerena@users.noreply.github.com" },
9
+ { name = "pesap", email = "pesap@users.noreply.github.com" },
10
+ ]
11
+ maintainers = [
12
+ { name = "mcllerena", email = "mcllerena@users.noreply.github.com" },
13
+ { name = "pesap", email = "pesap@users.noreply.github.com" },
14
+ ]
15
+ requires-python = ">=3.11, <3.14"
16
+ dependencies = [
17
+ "r2x-core>=0.1.1,<1.0.0",
18
+ ]
19
+
20
+ keywords=["Sienna"]
21
+ classifiers = [
22
+ "Development Status :: 4 - Beta",
23
+ "Intended Audience :: Developers",
24
+ "Intended Audience :: Science/Research",
25
+ "License :: OSI Approved :: BSD License",
26
+ "Topic :: Software Development :: Build Tools",
27
+ "Programming Language :: Python",
28
+ "Programming Language :: Python :: 3",
29
+ "Programming Language :: Python :: 3 :: Only",
30
+ "Programming Language :: Python :: 3.11",
31
+ "Programming Language :: Python :: 3.12",
32
+ "Programming Language :: Python :: 3.13",
33
+ "License :: OSI Approved :: BSD License",
34
+ "Natural Language :: English",
35
+ "Operating System :: OS Independent",
36
+ "Topic :: File Formats :: JSON",
37
+ "Topic :: Scientific/Engineering",
38
+ "Topic :: Scientific/Engineering :: Information Analysis",
39
+ "Topic :: Scientific/Engineering :: Interface Engine/Protocol Translator",
40
+ "Topic :: Software Development :: Build Tools",
41
+ "Topic :: Software Development :: Libraries :: Python Modules",
42
+ "Typing :: Typed",
43
+ ]
44
+
45
+ [project.entry-points."r2x_plugin"]
46
+ sienna = "r2x_sienna.plugin:manifest"
47
+
48
+ [build-system]
49
+ requires = ["uv_build>=0.8.22,<0.9.0"]
50
+ build-backend = "uv_build"
51
+
52
+ [tool.mypy]
53
+ exclude = [
54
+ 'plugins',
55
+ ]
56
+ ignore_missing_imports=true
57
+
58
+
59
+ [dependency-groups]
60
+ dev = [
61
+ "ipython>=9.2.0",
62
+ "mypy>=1.15.0",
63
+ "pre-commit>=4.2.0",
64
+ "pytest>=8.3.5",
65
+ "pytest-coverage>=0.0",
66
+ "ruff>=0.11.5",
67
+ ]
68
+
69
+ [tool.ruff]
70
+ line-length = 110
71
+ extend-exclude = [
72
+ ".venv",
73
+ "venv",
74
+ "build",
75
+ "dist",
76
+ "*.egg-info",
77
+ ]
78
+
79
+ [tool.pytest.ini_options]
80
+ pythonpath = [
81
+ "src"
82
+ ]
83
+
84
+ filterwarnings = [
85
+ "ignore::DeprecationWarning:infrasys.*",
86
+ "ignore::pydantic._internal._generate_schema.UnsupportedFieldAttributeWarning",
87
+ ]
88
+
89
+ [tool.commitizen]
90
+ name = "cz_conventional_commits"
91
+ tag_format = "$version"
92
+ version_scheme = "pep440"
93
+ version_provider = "uv"
94
+ major_version_zero = true
95
+
96
+ [tool.uv]
97
+ prerelease = "allow"
@@ -0,0 +1,26 @@
1
+ """R2X Sienna Plugin.
2
+ A plugin for parsing Sienna model data into the R2X framework using infrasys components.
3
+ """
4
+
5
+ from importlib.metadata import version
6
+
7
+ from loguru import logger
8
+
9
+ from .config import SiennaConfig
10
+ from .exporter import SiennaExporter
11
+ from .parser import SiennaParser
12
+
13
+ __version__ = version("r2x_sienna")
14
+
15
+
16
+ # Disable default loguru handler for library usage
17
+ # Applications using this library should configure their own handlers
18
+ logger.disable("r2x_sienna")
19
+
20
+
21
+ __all__ = [
22
+ "SiennaConfig",
23
+ "SiennaParser",
24
+ "SiennaExporter",
25
+ "__version__",
26
+ ]
@@ -0,0 +1,70 @@
1
+ """Configuration for Sienna parser."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Annotated
6
+
7
+ from pydantic import Field
8
+ from r2x_core.plugin_config import PluginConfig
9
+
10
+
11
+ class SiennaConfig(PluginConfig):
12
+ """Configuration for Sienna model parser.
13
+
14
+ This configuration class defines all parameters needed to parse
15
+ Sienna model data, including year information and model-specific settings.
16
+ Model-specific defaults and constants should be loaded using the
17
+ `load_defaults()` class method and used in parser logic.
18
+
19
+ Parameters
20
+ ----------
21
+ model_year : int | list[int]
22
+ Model solve year(s) (e.g., 2030, [2030, 2040, 2050])
23
+ system_name : str, optional
24
+ Name of the power system
25
+ scenario : str, optional
26
+ Scenario identifier
27
+ system_base_power : float, optional
28
+ System base power in MVA for per-unit calculations
29
+ skip_validation : bool, optional
30
+ Whether to skip validation during parsing
31
+
32
+ Examples
33
+ --------
34
+ Single year with custom base power:
35
+
36
+ >>> config = SiennaConfig(
37
+ ... model_year=2030,
38
+ ... system_name="EI_Sys",
39
+ ... system_base_power=100.0,
40
+ ... skip_validation=True,
41
+ ... )
42
+
43
+ Multiple years:
44
+
45
+ >>> config = SiennaConfig(
46
+ ... model_year=[2030, 2040, 2050],
47
+ ... system_name="Case5_PJM",
48
+ ... skip_validation=False,
49
+ ... )
50
+
51
+ See Also
52
+ --------
53
+ r2x_core.plugin_config.PluginConfig : Base configuration class
54
+ r2x_sienna.parser.SiennaParser : Parser that uses this configuration
55
+ load_defaults : Class method to load default constants from JSON
56
+ """
57
+
58
+ model_year: Annotated[
59
+ int | list[int] | None,
60
+ Field(description="Model solve year(s) - automatically converted to list"),
61
+ ] = None
62
+ system_name: Annotated[str | None, Field(default=None, description="Power system name")] = None
63
+ json_path: Annotated[str | None, Field(default=None, description="Path to JSON data file")] = None
64
+ scenario: Annotated[str, Field(default="base", description="Scenario identifier")] = "base"
65
+ system_base_power: Annotated[
66
+ float, Field(default=100.0, description="System base power in MVA for per-unit calculations")
67
+ ] = 100.0
68
+ skip_validation: Annotated[
69
+ bool, Field(default=False, description="Whether to skip validation during parsing")
70
+ ] = False
@@ -0,0 +1,152 @@
1
+ from pathlib import Path
2
+ from typing import Any
3
+ from uuid import uuid4
4
+
5
+ import orjson
6
+ from infrasys import TimeSeriesStorageType
7
+ from loguru import logger
8
+ from r2x_core.exceptions import ExporterError
9
+ from r2x_core.exporter import BaseExporter
10
+ from r2x_core.result import Err, Ok, Result
11
+
12
+ from r2x_sienna.serialization import serialize_component_to_psy
13
+
14
+ PARAMETRIZED_OUTPUT_TYPES = {"value_curve", "function_data", "loss"}
15
+ OUTPUT_METADATA = {"__metadata__", "internal"}
16
+ PARAMETRIZED_FIELDS = {"direction"}
17
+
18
+
19
+ class SiennaExporter(BaseExporter):
20
+ def __init__(
21
+ self,
22
+ config,
23
+ system,
24
+ /,
25
+ *,
26
+ data_store=None,
27
+ system_data=None,
28
+ output_path=None,
29
+ export_time_series=True,
30
+ **kwargs,
31
+ ):
32
+ self.should_export_time_series = export_time_series
33
+ self.system_data = system_data or {}
34
+ self.output_path = output_path
35
+ self.output_json = {}
36
+
37
+ # Pass filtered kwargs to parent to avoid overwriting methods
38
+ # Remove any kwargs that might conflict with our methods or attributes
39
+ filtered_kwargs = {
40
+ k: v for k, v in kwargs.items() if k not in {"export_time_series", "system_data", "output_path"}
41
+ }
42
+ super().__init__(config, system, data_store=data_store, **filtered_kwargs)
43
+
44
+ def setup_configuration(self) -> Result[None, ExporterError]:
45
+ if self.output_path is None:
46
+ return Err(ExporterError("output_path is required"))
47
+
48
+ if not isinstance(self.output_path, Path):
49
+ self.output_path = Path(self.output_path)
50
+
51
+ if not self.output_path.parent.exists():
52
+ try:
53
+ self.output_path.parent.mkdir(parents=True, exist_ok=True)
54
+ except Exception as e:
55
+ return Err(ExporterError(f"Failed to create output directory: {e}"))
56
+
57
+ return Ok(None)
58
+
59
+ def prepare_export(self) -> Result[None, ExporterError]:
60
+ try:
61
+ system_information = self.system_data.get(
62
+ "system_information", self._default_system_information()
63
+ )
64
+ self.output_json = {**system_information}
65
+ self.output_json["data"] = self.system_data.get("data_information", {})
66
+
67
+ components = []
68
+ for component in self.system._component_mgr.iter_all():
69
+ serialized = serialize_component_to_psy(component)
70
+ if serialized is not None:
71
+ components.append(serialized)
72
+
73
+ self.output_json["data"]["components"] = components
74
+ self.output_json["data"]["subsystems"] = {}
75
+ self.output_json["data"]["masked_components"] = {}
76
+
77
+ dumped_data = orjson.dumps(self.output_json)
78
+ with open(self.output_path, "wb") as f:
79
+ f.write(dumped_data)
80
+
81
+ return Ok(None)
82
+ except Exception as e:
83
+ logger.error("Failed to export system: {}", e)
84
+ return Err(ExporterError(f"Export failed: {e}"))
85
+
86
+ def export_time_series(self) -> Result[None, ExporterError]:
87
+ if not self.should_export_time_series:
88
+ logger.debug("Time series export disabled, skipping")
89
+ return Ok(None)
90
+
91
+ try:
92
+ self.system.convert_storage(time_series_storage_type=TimeSeriesStorageType.HDF5)
93
+
94
+ storage_file_path = f"{self.output_path.stem}_time_series_storage.h5"
95
+ full_storage_path = self.output_path.parent / storage_file_path
96
+
97
+ import os
98
+
99
+ if os.path.exists(full_storage_path):
100
+ os.remove(full_storage_path)
101
+ logger.debug(f"Removed existing storage file: {full_storage_path}")
102
+
103
+ self.system._time_series_mgr.serialize({}, full_storage_path, db_name=self.system.DB_FILENAME)
104
+
105
+ self.output_json["data"]["time_series_storage_type"] = (
106
+ "InfrastructureSystems.Hdf5TimeSeriesStorage"
107
+ )
108
+ self.output_json["data"]["time_series_storage_file"] = storage_file_path
109
+ self.output_json["data"]["internal"] = {
110
+ "uuid": {"value": str(uuid4())},
111
+ "ext": {},
112
+ "units_info": None,
113
+ }
114
+
115
+ dumped_data = orjson.dumps(self.output_json)
116
+ with open(self.output_path, "wb") as f:
117
+ f.write(dumped_data)
118
+
119
+ return Ok(None)
120
+ except Exception as e:
121
+ logger.error("Failed to export time series: {}", e)
122
+ return Err(ExporterError(f"Time series export failed: {e}"))
123
+
124
+ def _default_system_information(self) -> dict[str, Any]:
125
+ return {
126
+ "internal": {
127
+ "uuid": {"value": str(uuid4())},
128
+ "ext": {},
129
+ "units_info": None,
130
+ },
131
+ "units_settings": {
132
+ "base_value": 100.0,
133
+ "unit_system": "NATURAL_UNITS",
134
+ "__metadata__": {"module": "InfrastructureSystems", "type": "SystemUnitsSettings"},
135
+ },
136
+ "frequency": 60.0,
137
+ "runchecks": True,
138
+ "metadata": {
139
+ "name": None,
140
+ "description": None,
141
+ "__metadata__": {"module": "PowerSystems", "type": "SystemMetadata"},
142
+ },
143
+ "data_format_version": "4.0.0",
144
+ }
145
+
146
+
147
+ def to_psy(config, system, system_data, filename, /, *, write_year=None, **kwargs):
148
+ exporter = SiennaExporter(config, system, system_data=system_data, output_path=filename, **kwargs)
149
+ result = exporter.export()
150
+ if result.is_err():
151
+ raise Exception(f"Export failed: {result.error}")
152
+ return result
@@ -0,0 +1,16 @@
1
+ import time
2
+
3
+ from loguru import logger
4
+
5
+
6
+ def timeit(func):
7
+ """Time function."""
8
+
9
+ def wrapper(*args, **kwargs):
10
+ start_time = time.time()
11
+ result = func(*args, **kwargs)
12
+ end_time = time.time()
13
+ logger.debug(f"Function {func.__name__} executed in {end_time - start_time:.4f} seconds")
14
+ return result
15
+
16
+ return wrapper
@@ -0,0 +1,180 @@
1
+ from .attributes import GeographicInfo, GeometricDistributionForcedOutage, ImpedanceCorrectionData
2
+ from .branch import (
3
+ ACBranch,
4
+ AreaInterchange,
5
+ Branch,
6
+ DCBranch,
7
+ DiscreteControlledACBranch,
8
+ Line,
9
+ MonitoredLine,
10
+ PhaseShiftingTransformer,
11
+ PhaseShiftingTransformer3W,
12
+ TapTransformer,
13
+ ThreeWindingTransformer,
14
+ TModelHVDCLine,
15
+ Transformer2W,
16
+ Transformer3W,
17
+ TwoTerminalGenericHVDCLine,
18
+ TwoTerminalLCCLine,
19
+ TwoTerminalVSCLine,
20
+ TwoWindingTransformer,
21
+ )
22
+ from .core import ReserveMap, Service, TransmissionInterfaceMap
23
+ from .costs import (
24
+ HydroGenerationCost,
25
+ HydroReservoirCost,
26
+ RenewableGenerationCost,
27
+ StorageCost,
28
+ ThermalGenerationCost,
29
+ )
30
+ from .enums import (
31
+ DiscreteControlledBranchStatus,
32
+ DiscreteControlledBranchType,
33
+ FACTSOperationModes,
34
+ HydroTurbineType,
35
+ ImpedanceCorrectionTransformerControlMode,
36
+ PrimeMoversType,
37
+ PumpHydroStatus,
38
+ ReserveDirection,
39
+ ReserveType,
40
+ ReservoirDataType,
41
+ ReservoirLocation,
42
+ ThermalFuels,
43
+ TransformerControlObjective,
44
+ WindingCategory,
45
+ WindingGroupNumber,
46
+ )
47
+ from .generators import (
48
+ EnergyReservoirStorage,
49
+ HybridSystem,
50
+ HydroDispatch,
51
+ HydroEnergyReservoir,
52
+ HydroGen,
53
+ HydroPumpedStorage,
54
+ HydroPumpTurbine,
55
+ HydroReservoir,
56
+ HydroTurbine,
57
+ RenewableDispatch,
58
+ RenewableGen,
59
+ RenewableNonDispatch,
60
+ SynchronousCondenser,
61
+ ThermalMultiStart,
62
+ ThermalStandard,
63
+ )
64
+ from .load import (
65
+ FACTSControlDevice,
66
+ FixedAdmittance,
67
+ InterruptiblePowerLoad,
68
+ PowerLoad,
69
+ StandardLoad,
70
+ SwitchedAdmittance,
71
+ )
72
+ from .named_tuples import (
73
+ Complex,
74
+ FromTo_ToFrom,
75
+ GeoLocation,
76
+ InputOutput,
77
+ MinMax,
78
+ StartShut,
79
+ StartTimeLimits,
80
+ StartUpStages,
81
+ UpDown,
82
+ )
83
+ from .services import Reserve, TransmissionInterface, VariableReserve
84
+ from .topology import ACBus, Arc, Area, Bus, DCBus, LoadZone
85
+
86
+ __all__ = [
87
+ # enums
88
+ "DiscreteControlledBranchStatus",
89
+ "DiscreteControlledBranchType",
90
+ "TransformerControlObjective",
91
+ "FACTSOperationModes",
92
+ "WindingGroupNumber",
93
+ "ImpedanceCorrectionTransformerControlMode",
94
+ "WindingCategory",
95
+ "PumpHydroStatus",
96
+ "ReservoirLocation",
97
+ "ReservoirDataType",
98
+ "HydroTurbineType",
99
+ "PrimeMoversType",
100
+ "ThermalFuels",
101
+ # attributes
102
+ "GeographicInfo",
103
+ "ImpedanceCorrectionData",
104
+ "GeometricDistributionForcedOutage",
105
+ # branch
106
+ "ACBranch",
107
+ "AreaInterchange",
108
+ "Branch",
109
+ "DCBranch",
110
+ "Line",
111
+ "MonitoredLine",
112
+ "PhaseShiftingTransformer",
113
+ "DiscreteControlledACBranch",
114
+ "TapTransformer",
115
+ "TModelHVDCLine",
116
+ "Transformer3W",
117
+ "ThreeWindingTransformer",
118
+ "PhaseShiftingTransformer3W",
119
+ "TwoWindingTransformer",
120
+ "Transformer2W",
121
+ "TwoTerminalGenericHVDCLine",
122
+ "TwoTerminalLCCLine",
123
+ "TwoTerminalVSCLine",
124
+ # core
125
+ "ReserveType",
126
+ "ReserveDirection",
127
+ "ReserveMap",
128
+ "Service",
129
+ "TransmissionInterfaceMap",
130
+ # costs
131
+ "HydroGenerationCost",
132
+ "HydroReservoirCost",
133
+ "RenewableGenerationCost",
134
+ "StorageCost",
135
+ "ThermalGenerationCost",
136
+ # generators
137
+ "SynchronousCondenser",
138
+ "EnergyReservoirStorage",
139
+ "HybridSystem",
140
+ "HydroDispatch",
141
+ "HydroEnergyReservoir",
142
+ "HydroGen",
143
+ "HydroPumpedStorage",
144
+ "HydroReservoir",
145
+ "HydroTurbine",
146
+ "RenewableDispatch",
147
+ "RenewableGen",
148
+ "RenewableNonDispatch",
149
+ "ThermalMultiStart",
150
+ "ThermalStandard",
151
+ "HydroPumpTurbine",
152
+ # load
153
+ "FixedAdmittance",
154
+ "SwitchedAdmittance",
155
+ "InterruptiblePowerLoad",
156
+ "FACTSControlDevice",
157
+ "PowerLoad",
158
+ "StandardLoad",
159
+ # named_tuples
160
+ "Complex",
161
+ "FromTo_ToFrom",
162
+ "GeoLocation",
163
+ "InputOutput",
164
+ "MinMax",
165
+ "StartShut",
166
+ "StartUpStages",
167
+ "StartTimeLimits",
168
+ "UpDown",
169
+ # services
170
+ "Reserve",
171
+ "TransmissionInterface",
172
+ "VariableReserve",
173
+ # topology
174
+ "ACBus",
175
+ "Arc",
176
+ "Area",
177
+ "Bus",
178
+ "DCBus",
179
+ "LoadZone",
180
+ ]