diff --git a/.claude/settings.local.json b/.claude/settings.local.json index c46dcc84..91f108d2 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -1,7 +1,14 @@ { "permissions": { "allow": [ - "Bash(pip install:*)" + "Bash(conda activate esapp*)", + "Bash(C:/Users/wyatt/.conda/envs/esapp/python.exe*)", + "Bash(C:/Users/wyatt/.conda/envs/esapp/Scripts/pytest*)", + "Bash(C:/Users/wyatt/.conda/envs/esapp/Scripts/flake8*)", + "Bash(C:/Users/wyatt/.conda/envs/esapp/Scripts/pip*)" ] + }, + "env": { + "PATH": "C:\\Users\\wyatt\\.conda\\envs\\esapp;C:\\Users\\wyatt\\.conda\\envs\\esapp\\Scripts;${env:PATH}" } } diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..4864d333 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,103 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +ESA++ (`esapp`) is a Python toolkit for power system automation, providing a high-performance interface to PowerWorld Simulator's Automation Server (SimAuto) via COM on Windows. It requires Windows with PowerWorld Simulator installed. + +## Environment Setup + +This project uses a **conda environment** named `esapp` located at `C:\Users\wyatt\.conda\envs\esapp` (Python 3.11). All commands (pytest, pip, flake8, etc.) should be run using this environment. + +```bash +# Activate the environment +conda activate esapp +``` + +## Common Commands + +```bash +# Install for development +pip install -e ".[test]" + +# Run all tests +pytest + +# Run only unit tests (no PowerWorld needed) +pytest -m unit + +# Run only integration tests (requires PowerWorld + case file) +pytest -m integration + +# Run a single test file +pytest tests/test_helpers_unit.py + +# Run a single test +pytest tests/test_helpers_unit.py::TestClassName::test_name + +# Run with coverage +pytest --cov=esapp --cov-report=term-missing --cov-report=html:htmlcov + +# Lint (CI uses flake8 for syntax errors and undefined names) +flake8 . --select=E9,F63,F7,F82 --show-source + +# Regenerate auto-generated component definitions from PWRaw schema +cd esapp/components && python generate_components.py + +# Build docs +cd docs && sphinx-build -b html . _build +``` + +## Test Configuration + +Integration tests require a PowerWorld case file path, configured via: +1. Environment variable `SAW_TEST_CASE`, or +2. `tests/config_test.py` (user-created, not committed) + +Tests without PowerWorld access should use `-m unit`. The `--maxfail=5` default stops early on failures. + +## Architecture + +### Entry Point: `PowerWorld` ([workbench.py](esapp/workbench.py)) +The main user-facing class. Creates a SAW connection, provides high-level grid analysis methods, and hosts embedded application modules (`network`, `gic`). + +### SAW (SimAuto Wrapper): [esapp/saw/](esapp/saw/) +`SAW` class in [saw.py](esapp/saw/saw.py) is composed via **mixin pattern** from ~18 focused modules: +- **SAWBase** ([base.py](esapp/saw/base.py)) - Core COM interface, case management, generic data retrieval +- **PowerflowMixin** - Power flow solvers (Newton-Raphson, Gauss-Seidel, DC, etc.) +- **ContingencyMixin** - Contingency analysis +- **MatrixMixin** - Y-bus, Jacobian, GIC conductance matrix extraction +- **TransientMixin** - Transient stability simulation +- **SensitivityMixin** - PTDF, LODF, shift factors +- Other mixins: `GeneralMixin`, `ModifyMixin`, `TopologyMixin`, `GICMixin`, `OPFMixin`, `PVMixin`, `QVMixin`, `ATCMixin`, `FaultMixin`, `RegionsMixin`, `CaseActionsMixin`, `ScheduledActionsMixin`, `TimeStepMixin`, `WeatherMixin` + +### Indexable Interface ([indexable.py](esapp/indexable.py)) +Pythonic `__getitem__` access for grid data: `pw[Bus, ["BusNum", "BusName"]]` returns a DataFrame. Both `PowerWorld` and `SAW` implement this. + +### Component Definitions: [esapp/components/](esapp/components/) +- **grid.py** (auto-generated, ~13MB) - `GObject` subclasses for all PowerWorld object types (Bus, Gen, Load, Branch, etc.) +- **ts_fields.py** (auto-generated) - Transient stability field constants for IDE autocomplete +- **gobject.py** - Base `GObject` class +- **generate_components.py** - Regeneration script reading from `PWRaw` schema file +- Do not manually edit `grid.py` or `ts_fields.py`; regenerate them instead. + +### Utility Modules: [esapp/utils/](esapp/utils/) +Embedded analysis applications accessible from `PowerWorld`: +- **GIC** ([gic.py](esapp/utils/gic.py)) - Geomagnetically Induced Currents analysis, G-matrix, E-field Jacobians +- **Network** ([network.py](esapp/utils/network.py)) - Incidence matrices, Laplacians, bus mapping +- **Dynamics** ([dynamics.py](esapp/utils/dynamics.py)) - Transient stability result monitoring +- **Contingency** ([contingency.py](esapp/utils/contingency.py)) - Programmatic contingency definition +- **B3D** ([b3d.py](esapp/utils/b3d.py)) - Binary 3D electric field file I/O + +### Helpers and Types +- **_helpers.py** - Data conversion (Windows paths, COM variants, AUX files), TS result processing +- **_enums.py** - Type-safe enumerations (`SolverMethod`, `LinearMethod`, `FileFormat`, `ObjectType`, filter keywords like `SELECTED`, `ALL`) +- **_exceptions.py** - Exception hierarchy rooted at `PowerWorldError` with analysis-specific subtypes (`PowerFlowException`, `DivergenceException`, `GICException`, etc.) + +## Key Constraints + +- **Windows-only**: Depends on `pywin32` for COM interop with PowerWorld +- **numpy < 2.0**: Pinned in dependencies +- **Python >= 3.7**: Minimum supported version +- CI runs on Python 3.9, 3.10, 3.11 diff --git a/README.rst b/README.rst index fb2f9885..69ca30e9 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,5 @@ ESA++ -==================================== +===== .. image:: https://img.shields.io/badge/License-Apache%202.0-blue.svg :target: https://opensource.org/licenses/Apache-2.0 @@ -13,94 +13,66 @@ ESA++ :target: https://esapp.readthedocs.io/ :alt: Documentation -.. image:: https://img.shields.io/badge/coverage-90%25-brightgreen.svg - :alt: Coverage 90% +.. image:: https://img.shields.io/badge/coverage-98%25-brightgreen.svg + :alt: Coverage 98% -An open-source Python toolkit for power system automation, providing a high-performance "syntax-sugar" fork of Easy SimAuto (ESA). This library streamlines interaction with PowerWorld's Simulator Automation Server (SimAuto), transforming complex COM calls into intuitive, Pythonic operations. +An open-source Python toolkit for power system automation, providing a +high-performance wrapper for PowerWorld's Simulator Automation Server +(SimAuto). Transforms complex COM calls into intuitive, Pythonic operations. -Key Features ------------- - -- **Intuitive Indexing Syntax**: Access and modify grid components using a unique indexing system (e.g., ``wb[Bus, "BusPUVolt"]``) that feels like native Python. -- **Comprehensive SimAuto Wrapper**: Full coverage of PowerWorld's API through the ``SAW`` class, organized into modular mixins for power flow, contingencies, transients, and more. -- **High-Level Adapter Interface**: A collection of simplified "one-liner" functions for common tasks like GIC calculation, fault analysis, and voltage violation detection. -- **Native Pandas Integration**: Every data retrieval operation returns a Pandas DataFrame or Series, enabling immediate analysis, filtering, and visualization. -- **Advanced Analysis Apps**: Built-in specialized modules for Network topology analysis, Geomagnetically Induced Currents (GIC), and Forced Oscillation detection. +- **Intuitive Indexing** -- Access grid data with ``pw[Bus, "BusPUVolt"]`` syntax +- **Full SimAuto Coverage** -- All PowerWorld API functions through modular mixins +- **Pandas Integration** -- Every query returns a DataFrame +- **Pythonic Settings** -- Solver and GIC options as descriptor attributes (``pw.max_iterations = 250``) +- **Convenience Methods** -- Flows, overloads, PTDF/LODF, snapshot context manager, case summary +- **Transient Stability** -- Fluent API with ``TS`` field intellisense +- **Analysis Utilities** -- Built-in GIC, network topology, and contingency tools Installation ------------ -The ESA++ package is available on `PyPI `_ +Requires Windows with PowerWorld Simulator (SimAuto enabled) and Python 3.9+. .. code-block:: bash pip install esapp - -Documentation -------------- - -For a comprehensive tutorial, usage guides, and the full API reference, please visit our `documentation website `_. - -Usage Example +Quick Example ------------- -Here is a quick example of how ESA++ simplifies data access and power flow analysis. - .. code-block:: python - from esapp import GridWorkBench - from esapp.grid import * + from esapp import PowerWorld + from esapp.components import * - # Open Case - wb = GridWorkBench("path/to/case.pwb") + pw = PowerWorld("path/to/case.pwb") - # Retrieve data - bus_data = wb[Bus, ["BusName", "BusPUVolt"]] + # Read data + bus_data = pw[Bus, ["BusName", "BusPUVolt"]] # Solve power flow - V = wb.pflow() - - # Do some action, write to PW - violations = wb.find_violations(v_min=0.95) - wb[Gen, "GenMW"] = 100.0 - - # Save case - wb.save() + V = pw.pflow() -Why ESA++? ----------- + # Inspect and modify + violations = pw.violations(v_min=0.95) + pw[Gen, "GenMW"] = 100.0 -Traditional automation of PowerWorld Simulator often involves verbose COM calls and manual data parsing. ESA++ abstracts these complexities: - -* **Speed**: Optimized data transfer between Python and SimAuto. -* **Clarity**: Code that reads like the engineering operations it performs. -* **Ecosystem**: Built on top of the proven ESA library, adding modern Python features and better integration with the SciPy stack. - - -More Examples +Documentation ------------- -The `docs/examples/ `_ directory contains a gallery of demonstrations, including: - -- **Object Field Access**: Reduce the time you spend searching for field names with ESA++ IDE typehints for objects and fields. -- **Matrix Extraction**: Retrieving Y-Bus, Jacobian, and GIC conductance matrices for external mathematical modeling. +Full tutorials, API reference, and examples at `esapp.readthedocs.io `_. Testing ------- -ESA++ includes an extensive test suite covering both offline mocks and live PowerWorld connections. To run the tests, install the test dependencies and execute pytest: - .. code-block:: bash pip install .[test] - pytest tests/test_saw.py + pytest tests/ Citation -------- -If you use this toolkit in your research or industrial projects, please cite the original ESA work and this fork: - .. code-block:: bibtex @article{esa2020, @@ -112,10 +84,10 @@ If you use this toolkit in your research or industrial projects, please cite the Authors ------- -Luke Lowery developed this module during his PhD studies at Texas A&M University. You can learn more on his `research page `_ or view his publications on `Google Scholar `_. - -ESA++ is maintained by **Luke Lowery** and **Adam Birchfield** at Texas A&M University. You can explore more of our research at the `Birchfield Research Group `_. +Developed by **Luke Lowery** and **Adam Birchfield** at Texas A&M University +(`Birchfield Research Group `_). License ------- + Distributed under the `Apache License 2.0 `_. diff --git a/VERSION b/VERSION index 17e51c38..8294c184 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.1.1 +0.1.2 \ No newline at end of file diff --git a/docs/_ext/grid_list.py b/docs/_ext/grid_list.py new file mode 100644 index 00000000..92f26052 --- /dev/null +++ b/docs/_ext/grid_list.py @@ -0,0 +1,256 @@ +"""Sphinx extension that renders compact lists of grid components and TS fields. + +Parses ``esapp/components/grid.py`` and ``esapp/components/ts_fields.py`` with the +:mod:`ast` module (no import required) and generates multi-column HTML/LaTeX tables +via the ``.. grid-component-list::`` and ``.. ts-field-list::`` directives. +""" + +import ast +import os +import re + +from docutils import nodes +from docutils.parsers.rst import Directive +from sphinx.application import Sphinx + + +def _extract_class_names(grid_path: str): + """Return a sorted list of class names defined in *grid_path*.""" + with open(grid_path, encoding="utf-8") as f: + tree = ast.parse(f.read(), filename=grid_path) + return sorted( + node.name + for node in ast.walk(tree) + if isinstance(node, ast.ClassDef) + ) + + +def _extract_ts_fields(ts_fields_path: str): + """Extract TS field information from ts_fields.py. + + Returns a dict mapping category names to lists of (field_name, pw_name, description) tuples. + """ + with open(ts_fields_path, encoding="utf-8") as f: + tree = ast.parse(f.read(), filename=ts_fields_path) + + categories = {} + + for node in ast.walk(tree): + if isinstance(node, ast.ClassDef) and node.name == "TS": + # Find nested classes inside TS + for child in node.body: + if isinstance(child, ast.ClassDef): + category_name = child.name + fields = [] + for item in child.body: + if isinstance(item, ast.Assign): + for target in item.targets: + if isinstance(target, ast.Name): + field_name = target.id # ast.Name uses 'id' not 'name' + # Extract TSField arguments + if isinstance(item.value, ast.Call): + call_args = item.value.args + pw_name = "" + description = "" + if len(call_args) >= 1 and isinstance(call_args[0], ast.Constant): + pw_name = call_args[0].value + if len(call_args) >= 2 and isinstance(call_args[1], ast.Constant): + description = call_args[1].value + fields.append((field_name, pw_name, description)) + if fields: + categories[category_name] = sorted(fields, key=lambda x: x[0]) + return categories + + +def _build_compact_table(items, n_cols, table_class, is_monospace=False): + """Build a compact multi-column table node. + + Args: + items: List of strings to display in cells + n_cols: Number of columns + table_class: CSS class for the table + is_monospace: If True, use literal nodes for monospace display + + Returns: + A docutils table node + """ + rows = [items[i : i + n_cols] for i in range(0, len(items), n_cols)] + # Pad the last row + if rows and len(rows[-1]) < n_cols: + rows[-1].extend([""] * (n_cols - len(rows[-1]))) + + table = nodes.table() + table["classes"].append(table_class) + tgroup = nodes.tgroup(cols=n_cols) + table += tgroup + + for _ in range(n_cols): + tgroup += nodes.colspec(colwidth=1) + + tbody = nodes.tbody() + tgroup += tbody + + for row_data in rows: + row_node = nodes.row() + for cell_text in row_data: + entry = nodes.entry() + if cell_text: + if is_monospace: + entry += nodes.paragraph("", "", nodes.literal(text=cell_text)) + else: + entry += nodes.paragraph(text=cell_text) + else: + entry += nodes.paragraph(text="") + row_node += entry + tbody += row_node + + return table + + +class GridComponentList(Directive): + """Render all grid component class names as a compact table.""" + + has_content = False + required_arguments = 0 + optional_arguments = 0 + + def run(self): + # Locate esapp/components/grid.py relative to the docs/ directory + docs_dir = os.path.dirname(self.state.document.settings.env.app.srcdir) + grid_path = os.path.join(docs_dir, "esapp", "components", "grid.py") + + if not os.path.isfile(grid_path): + error = self.state_machine.reporter.error( + f"grid_list: cannot find {grid_path}", + nodes.literal_block(self.block_text, self.block_text), + line=self.lineno, + ) + return [error] + + names = _extract_class_names(grid_path) + table = _build_compact_table(names, n_cols=4, table_class="grid-component-table") + + # Add a count note above the table + count_para = nodes.paragraph() + count_para += nodes.strong(text=f"{len(names)} component types available") + return [count_para, table] + + +class TSFieldList(Directive): + """Render TS field constants as compact tables organized by category.""" + + has_content = False + required_arguments = 0 + optional_arguments = 0 + option_spec = { + "category": lambda x: x, # Optional: filter to single category + } + + def run(self): + # Locate esapp/components/ts_fields.py relative to the docs/ directory + docs_dir = os.path.dirname(self.state.document.settings.env.app.srcdir) + ts_path = os.path.join(docs_dir, "esapp", "components", "ts_fields.py") + + if not os.path.isfile(ts_path): + error = self.state_machine.reporter.error( + f"ts_field_list: cannot find {ts_path}", + nodes.literal_block(self.block_text, self.block_text), + line=self.lineno, + ) + return [error] + + categories = _extract_ts_fields(ts_path) + filter_category = self.options.get("category") + + result_nodes = [] + total_fields = 0 + + # Sort categories for consistent output + cat_order = ["Area", "Branch", "Bus", "Gen", "InjectionGroup", "Load", "Shunt", "Substation", "System"] + sorted_cats = [c for c in cat_order if c in categories] + # Add any remaining categories not in the predefined order + sorted_cats.extend([c for c in sorted(categories.keys()) if c not in cat_order]) + + for cat_name in sorted_cats: + if filter_category and cat_name != filter_category: + continue + + fields = categories[cat_name] + total_fields += len(fields) + + # Create a container for this category (rubric keeps it + # out of the TOC while still looking like a heading) + section = nodes.container() + section["ids"].append(f"ts-{cat_name.lower()}-fields") + + # Add heading (rubric = visual heading, not in TOC) + heading = nodes.rubric(text=f"TS.{cat_name}") + section += heading + + # Build a 3-column table: Field, PowerWorld Name, Description + table = nodes.table() + table["classes"].append("ts-field-table") + table["classes"].append("longtable") + tgroup = nodes.tgroup(cols=3) + table += tgroup + + # Column specs - give description more space + tgroup += nodes.colspec(colwidth=10) + tgroup += nodes.colspec(colwidth=15) + tgroup += nodes.colspec(colwidth=75) + + # Header + thead = nodes.thead() + tgroup += thead + header_row = nodes.row() + for header_text in ["Field", "PowerWorld Name", "Description"]: + entry = nodes.entry() + entry += nodes.paragraph(text=header_text) + header_row += entry + thead += header_row + + # Body + tbody = nodes.tbody() + tgroup += tbody + + for field_name, pw_name, description in fields: + row = nodes.row() + + # Field name (monospace) + entry1 = nodes.entry() + entry1 += nodes.paragraph("", "", nodes.literal(text=field_name)) + row += entry1 + + # PowerWorld name (monospace, smaller) + entry2 = nodes.entry() + entry2 += nodes.paragraph("", "", nodes.literal(text=pw_name)) + row += entry2 + + # Description - clean up DSC:: prefixes + entry3 = nodes.entry() + desc_clean = description + if desc_clean.startswith("DSC::"): + desc_clean = desc_clean[5:] # Remove DSC:: prefix + entry3 += nodes.paragraph(text=desc_clean if desc_clean else "—") + row += entry3 + + tbody += row + + section += table + result_nodes.append(section) + + # Add summary at the top + summary = nodes.paragraph() + summary += nodes.strong(text=f"{total_fields} TS field constants across {len(sorted_cats)} categories") + + return [summary] + result_nodes + + +def setup(app: Sphinx): + app.add_directive("grid-component-list", GridComponentList) + app.add_directive("ts-field-list", TSFieldList) + + # Add custom CSS for better table rendering + app.add_css_file("custom_tables.css") + + return {"version": "0.2", "parallel_read_safe": True} diff --git a/docs/_static/custom.css b/docs/_static/custom.css new file mode 100644 index 00000000..82e953d1 --- /dev/null +++ b/docs/_static/custom.css @@ -0,0 +1,23 @@ +/* Compact API layout — tighten spacing around method/function entries */ +dl.py.method, +dl.py.function, +dl.py.attribute { + margin-bottom: 12px; +} + +dl.field-list > dt { + margin-top: 4px; +} + +dl.field-list > dd { + margin-bottom: 4px; +} + +dl.field-list > dd > ul { + margin-top: 0; +} + +/* Reduce heading gap inside API pages */ +.rst-content .section > .section { + margin-top: 12px; +} diff --git a/docs/_static/custom_tables.css b/docs/_static/custom_tables.css new file mode 100644 index 00000000..3da02d1f --- /dev/null +++ b/docs/_static/custom_tables.css @@ -0,0 +1,97 @@ +/* Custom table styling for grid component and TS field tables */ + +/* Grid component table - compact multi-column layout */ +.grid-component-table { + width: 100%; + font-size: 0.9em; +} + +.grid-component-table td { + padding: 4px 8px; + white-space: nowrap; +} + +/* TS field table - structured 3-column layout */ +.ts-field-table { + width: 100%; + font-size: 0.85em; + table-layout: fixed; +} + +.ts-field-table th { + background-color: #f0f0f0; + font-weight: bold; + padding: 6px 8px; + text-align: left; + border-bottom: 2px solid #ccc; +} + +.ts-field-table td { + padding: 4px 8px; + vertical-align: top; + border-bottom: 1px solid #eee; +} + +/* First column: Field name - keep narrow, no wrap */ +.ts-field-table td:first-child { + white-space: nowrap; + width: 10%; +} + +/* Second column: PowerWorld name - allow minimal wrap */ +.ts-field-table td:nth-child(2) { + width: 15%; + word-break: break-word; + font-size: 0.85em; +} + +/* Third column: Description - allow wrapping, wider */ +.ts-field-table td:nth-child(3) { + width: 75%; + word-wrap: break-word; +} + +/* Code/literal styling in tables */ +.ts-field-table code, +.ts-field-table .literal { + font-size: 0.9em; + padding: 1px 3px; + background-color: #f5f5f5; + border-radius: 2px; +} + +/* Alternating row colors for readability */ +.ts-field-table tbody tr:nth-child(even) { + background-color: #fafafa; +} + +.ts-field-table tbody tr:hover { + background-color: #f0f7ff; +} + +/* PDF-specific adjustments via print media query */ +@media print { + .ts-field-table { + font-size: 8pt; + } + + .ts-field-table td { + padding: 2px 4px; + } + + .ts-field-table td:first-child { + width: 15%; + } + + .ts-field-table td:nth-child(2) { + width: 25%; + } + + .ts-field-table td:nth-child(3) { + width: 60%; + } + + .grid-component-table { + font-size: 9pt; + } +} diff --git a/docs/api/apps.rst b/docs/api/apps.rst deleted file mode 100644 index d12968a5..00000000 --- a/docs/api/apps.rst +++ /dev/null @@ -1,17 +0,0 @@ -Specialized Applications -======================== - -The ``apps`` package exposes focused helpers (network topology, GIC, etc.) surfaced on ``GridWorkBench``. -For direct SAW access use ``wb.esa``; for higher-level helpers use the modules below. This page lists the -API members only. - -.. rubric:: App Modules - -.. autosummary:: - :toctree: generated/ - - esapp.apps.dynamics - esapp.apps.gic - esapp.apps.modes - esapp.apps.network - esapp.apps.static diff --git a/docs/api/comps.rst b/docs/api/comps.rst index 2a413e2a..713d472f 100644 --- a/docs/api/comps.rst +++ b/docs/api/comps.rst @@ -1,7 +1,49 @@ Objects & Fields ================ -The ``esapp.gobject`` module provides the base classes for defining grid component schemas. +The ``esapp.components`` module provides the base classes for defining grid component schemas +and transient stability field constants. -.. automodule:: esapp.gobject - :members: \ No newline at end of file +GObject Base Class +------------------ + +.. automodule:: esapp.components.gobject + :members: + +Transient Stability Fields +-------------------------- + +The ``TS`` class provides IDE intellisense for transient stability result fields, organized +by object type. Use these constants with ``TSWatch.watch()`` to specify which fields to record +during simulation. + +.. code-block:: python + + from esapp import TS + from esapp.components import Gen, Bus + from esapp.utils import TSWatch + + tsw = TSWatch() + + # Watch generator fields + tsw.watch(Gen, [TS.Gen.P, TS.Gen.W, TS.Gen.Delta]) + + # Watch bus fields + tsw.watch(Bus, [TS.Bus.VPU, TS.Bus.Freq]) + +TS Field Reference +------------------ + +The following tables list all available transient stability field constants by category. +Access fields using ``TS..`` syntax (e.g., ``TS.Gen.P``, ``TS.Bus.VPU``). + +.. ts-field-list:: + +Available Grid Object Types +---------------------------- + +The following component types are available in ``esapp.components``. +Each class represents a PowerWorld object type that can be used with +the :class:`~esapp.PowerWorld` indexing syntax (e.g., ``pw[Bus, "BusNum"]``). + +.. grid-component-list:: diff --git a/docs/api/index.rst b/docs/api/index.rst index 9c2cbde5..4a5d6e2b 100644 --- a/docs/api/index.rst +++ b/docs/api/index.rst @@ -4,10 +4,13 @@ API Reference This section provides a detailed reference for the ESA++ API, partitioned by functional module. .. toctree:: - :maxdepth: 2 + :maxdepth: 1 workbench - saw - apps utils comps + +.. toctree:: + :maxdepth: 2 + + saw diff --git a/docs/api/saw.rst b/docs/api/saw.rst index 0a7edfb0..f56965f9 100644 --- a/docs/api/saw.rst +++ b/docs/api/saw.rst @@ -1,45 +1,676 @@ SimAuto Wrapper (SAW) ===================== -The ``SAW`` (SimAuto Wrapper) class exposes the full PowerWorld API. It is organized into mixins -corresponding to PowerWorld functional areas (power flow, contingencies, optimization, sensitivity, -transient, GIC, ATC, topology, voltage analysis, data management). Use ``wb.esa`` to access SAW from -``GridWorkBench``. This page lists the complete API. - -API Documentation ------------------- +The ``SAW`` (SimAuto Wrapper) class provides complete access to PowerWorld's SimAuto API. +It is organized into functional mixins for power flow, contingencies, optimization, sensitivity, +transient stability, GIC, ATC, topology, and data management. Access SAW through ``pw.esa`` +from ``PowerWorld``. .. currentmodule:: esapp.saw .. autoclass:: SAW :show-inheritance: + :no-members: + +General Program Actions +----------------------- + +.. autoclass:: esapp.saw.base.SAWBase + :members: + :noindex: + +.. autoclass:: esapp.saw.general.GeneralMixin + :members: + :noindex: + +Data Interaction +---------------- + +.. autoclass:: esapp.saw.data.DataMixin + :members: + :noindex: + +Case Actions +------------ + +.. autoclass:: esapp.saw.case_actions.CaseActionsMixin + :members: + :noindex: + +Modify Case Objects +------------------- + +.. autoclass:: esapp.saw.modify.ModifyMixin + :members: + :noindex: + +.. autoclass:: esapp.saw.topology.TopologyMixin + :members: + :noindex: + +Power Flow +---------- + +.. autoclass:: esapp.saw.powerflow.PowerflowMixin + :members: + :noindex: + +.. autoclass:: esapp.saw.matrices.MatrixMixin :members: - :undoc-members: + :noindex: -Mixin Modules +Sensitivity Calculations +------------------------ + +.. autoclass:: esapp.saw.sensitivity.SensitivityMixin + :members: + :noindex: + +Contingency Analysis +-------------------- + +.. autoclass:: esapp.saw.contingency.ContingencyMixin + :members: + :noindex: + +Fault Analysis -------------- -.. autosummary:: - :toctree: generated/ - - atc - base - case_actions - contingency - fault - general - gic - matrices - modify - oneline - opf - powerflow - pv - qv - regions - scheduled - sensitivity - timestep - topology - transient - weather \ No newline at end of file +.. autoclass:: esapp.saw.fault.FaultMixin + :members: + :noindex: + +ATC (Available Transfer Capability) +------------------------------------ + +.. autoclass:: esapp.saw.atc.ATCMixin + :members: + :noindex: + +GIC (Geomagnetically Induced Current) +-------------------------------------- + +.. autoclass:: esapp.saw.gic.GICMixin + :members: + :noindex: + +OPF (Optimal Power Flow) and SCOPF +----------------------------------- + +.. autoclass:: esapp.saw.opf.OPFMixin + :members: + :noindex: + +PV Analysis +----------- + +.. autoclass:: esapp.saw.pv.PVMixin + :members: + :noindex: + +QV Analysis +----------- + +.. autoclass:: esapp.saw.qv.QVMixin + :members: + :noindex: + +Regions +------- + +.. autoclass:: esapp.saw.regions.RegionsMixin + :members: + :noindex: + +TS (Transient Stability) +------------------------ + +.. autoclass:: esapp.saw.transient.TransientMixin + :members: + :noindex: + +Scheduled Actions +----------------- + +.. autoclass:: esapp.saw.scheduled.ScheduledActionsMixin + :members: + :noindex: + +Time Step Simulation +-------------------- + +.. autoclass:: esapp.saw.timestep.TimeStepMixin + :members: + :noindex: + +Weather +------- + +.. autoclass:: esapp.saw.weather.WeatherMixin + :members: + :noindex: + +Type-Safe Enumerations +---------------------- + +ESA++ provides enumeration types for common PowerWorld string parameters. Using these +enums instead of raw strings provides IDE autocomplete, type checking, and prevents typos. + +.. code-block:: python + + from esapp.saw import SolverMethod, FilterKeyword, LinearMethod + + # Use enums for type-safe parameters + saw.SolvePowerFlow(SolverMethod.RECTNEWT) + saw.GetParametersMultipleElement("Bus", ["BusNum", "BusPUVolt"], FilterKeyword.ALL) + +**SolverMethod** - Power flow solution algorithms + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Value + - Description + * - ``RECTNEWT`` + - Rectangular Newton-Raphson (default) + * - ``POLARNEWT`` + - Polar Newton-Raphson + * - ``GAUSSSEIDEL`` + - Gauss-Seidel iterative method + * - ``FASTDEC`` + - Fast Decoupled method + * - ``ROBUST`` + - Robust solver for difficult cases + * - ``DC`` + - DC power flow (linear approximation) + +**LinearMethod** - Sensitivity analysis methods (PTDF, LODF, shift factors) + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Value + - Description + * - ``DC`` + - DC linear method (most common default) + * - ``AC`` + - AC linear method + * - ``DCPS`` + - DC linear with post-solution adjustment + +**JacobianForm** - Jacobian matrix coordinate forms + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Value + - Description + * - ``RECTANGULAR`` + - AC Jacobian in Rectangular coordinates ("R") + * - ``POLAR`` + - AC Jacobian in Polar coordinates ("P") + * - ``DC`` + - B' matrix / DC approximation + +**FilterKeyword** - Special filter keywords (passed unquoted) + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Value + - Description + * - ``ALL`` + - Select all objects of the type + * - ``SELECTED`` + - Only objects currently selected in PowerWorld + * - ``AREAZONE`` + - Objects in the active area/zone filter + +**YesNo** - Boolean flags for PowerWorld commands + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Value + - Description + * - ``YES`` + - Affirmative / enable option + * - ``NO`` + - Negative / disable option + +Use ``YesNo.from_bool(value)`` to convert Python booleans. + +**ObjectType** - PowerWorld object type identifiers + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Value + - Description + * - ``BUS`` + - Bus/node + * - ``BRANCH`` + - Branch (line or transformer) + * - ``GEN`` + - Generator + * - ``LOAD`` + - Load + * - ``SHUNT`` + - Shunt device + * - ``AREA`` + - Control area + * - ``ZONE`` + - Zone + * - ``OWNER`` + - Owner + * - ``INTERFACE`` + - Interface (flowgate) + * - ``INJECTIONGROUP`` + - Injection group + * - ``BUSSHUNT`` + - Bus shunt + * - ``SUPERBUS`` + - Super bus (aggregated) + * - ``TRANSFORMER`` + - Transformer specifically + * - ``LINE`` + - Transmission line specifically + * - ``SUPERAREA`` + - Super area (aggregated) + +**KeyFieldType** - Result output key field types + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Value + - Description + * - ``PRIMARY`` + - Primary key fields (e.g., BusNum) + * - ``SECONDARY`` + - Secondary key fields (e.g., BusName) + * - ``LABEL`` + - Label-based identification + +**FileFormat** - Import/export file formats + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Value + - Description + * - ``CSV`` + - Comma-separated values + * - ``CSVCOLHEADER`` + - CSV with column headers + * - ``CSVNOHEADER`` + - CSV without headers + * - ``AUX`` + - PowerWorld auxiliary format + * - ``AUXCSV`` + - Hybrid auxiliary/CSV format + * - ``TAB`` + - Tab-separated format + * - ``PTI`` + - PTI/PSS-E format + * - ``TXT`` + - Text format + * - ``PWB`` + - PowerWorld case format + * - ``AXD`` + - Oneline diagram format + * - ``GE`` + - GE EPC format + * - ``CF`` + - Custom format + * - ``UCTE`` + - UCTE format + * - ``AREVAHDB`` + - AREVA HDB format + * - ``OPENNETEMS`` + - OPENNET EMS format + +**ObjectIDHandling** - Contingency export object ID modes + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Value + - Description + * - ``NO`` + - Standard object references + * - ``YES_MS_3W`` + - Include multi-section and 3-winding IDs + +**BranchDistanceMeasure** - Distance metrics for topology analysis + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Value + - Description + * - ``REACTANCE`` + - Use reactance (X) as distance measure + * - ``IMPEDANCE`` + - Use impedance magnitude (Z) as distance measure + +**BranchFilterMode** - Branch filter modes for topology traversal + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Value + - Description + * - ``ALL`` + - All branches + * - ``SELECTED`` + - Only selected branches + * - ``CLOSED`` + - Only closed branches + +**IslandReference** - Island reference options + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Value + - Description + * - ``EXISTING`` + - Use existing island configuration + * - ``NO`` + - No area reference + +**ScalingBasis** - Load/generation scaling basis + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Value + - Description + * - ``MW`` + - Absolute MW/MVAR values + * - ``FACTOR`` + - Multiplier factor + +**InterfaceLimitSetting** - Interface limit configuration + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Value + - Description + * - ``AUTO`` + - Automatic limit calculation + * - ``NONE`` + - No limit applied + +**ShuntModel** - Shunt model types for line tapping + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Value + - Description + * - ``CAPACITANCE`` + - Capacitive shunt model + * - ``INDUCTANCE`` + - Inductive shunt model + +**BranchDeviceType** - Branch device types for bus splitting + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Value + - Description + * - ``Line`` + - Transmission line + * - ``Breaker`` + - Circuit breaker + +**StarBusHandling** - Star bus handling for case append + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Value + - Description + * - ``NEAR`` + - Map to nearest bus (default) + * - ``MAX`` + - Map to maximum impedance bus + +**MultiSectionLineHandling** - Multi-section line handling for case append + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Value + - Description + * - ``MAINTAIN`` + - Maintain multisection line structure (default) + * - ``EQUIVALENCE`` + - Convert to equivalent circuits + +**OnelineLinkMode** - Oneline diagram linking modes + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Value + - Description + * - ``LABELS`` + - Link objects by labels (default) + * - ``NUMBERS`` + - Link objects by numbers + +**RatingSetPrecedence** - Rating set precedence for weather-based ratings + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Value + - Description + * - ``NORMAL`` + - Use normal rating set + * - ``CTG`` + - Use contingency rating set + +**RatingSet** - Rating set identifiers (A-O, DEFAULT, NO) + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Value + - Description + * - ``DEFAULT`` + - Use default rating + * - ``NO`` + - Don't update rating + * - ``A`` - ``O`` + - Rating sets A through O + +**FieldListColumn** - Column names for ``GetFieldList`` results + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Value + - Description + * - ``KEY_FIELD`` + - Whether the field is a key field + * - ``INTERNAL_FIELD_NAME`` + - PowerWorld internal field name + * - ``FIELD_DATA_TYPE`` + - Data type of the field + * - ``DESCRIPTION`` + - Human-readable description + * - ``DISPLAY_NAME`` + - Display name in PowerWorld UI + * - ``ENTERABLE`` + - Whether the field can be edited + +**SpecificFieldListColumn** - Column names for ``GetSpecificFieldList`` results + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Value + - Description + * - ``VARIABLENAME_LOCATION`` + - Variable name with location + * - ``FIELD`` + - Field identifier + * - ``COLUMN_HEADER`` + - Column header label + * - ``FIELD_DESCRIPTION`` + - Human-readable description + * - ``ENTERABLE`` + - Whether the field can be edited + +**TSGetResultsMode** - Transient stability results save mode + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Value + - Description + * - ``SINGLE`` + - Single combined output file + * - ``SEPARATE`` + - Separate files per object + * - ``JSIS`` + - JSIS format output + +Helper Functions +---------------- + +**Filter formatting:** + +.. autofunction:: esapp.saw.format_filter + +.. autofunction:: esapp.saw.format_filter_selected_only + +.. autofunction:: esapp.saw.format_filter_areazone + +**Data conversion:** + +.. autofunction:: esapp.saw.df_to_aux + +.. autofunction:: esapp.saw.create_object_string + +.. autofunction:: esapp.saw.convert_to_windows_path + +.. autofunction:: esapp.saw.convert_list_to_variant + +.. autofunction:: esapp.saw.convert_df_to_variant + +.. autofunction:: esapp.saw.convert_nested_list_to_variant + +.. autofunction:: esapp.saw.get_temp_filepath + +.. autofunction:: esapp.saw.format_list + +.. autofunction:: esapp.saw.format_optional + +.. autofunction:: esapp.saw.format_optional_numeric + +Exceptions +---------- + +Exception classes for handling PowerWorld and COM errors. + +.. list-table:: + :header-rows: 1 + :widths: 30 70 + + * - Exception + - Description + * - ``Error`` + - Base class for all ESA++ exceptions + * - ``PowerWorldError`` + - Generic error from PowerWorld following a SimAuto call. Parses error messages to extract source and details. + * - ``SimAutoFeatureError`` + - Raised when a SimAuto feature is not supported for the given object or context (e.g., object types that don't support ``GetParameters``) + * - ``PowerWorldPrerequisiteError`` + - Raised when a command fails due to missing prerequisite data (e.g., no contingencies defined for ``CTGSolve``) + * - ``PowerWorldAddonError`` + - Raised when a command requires an unlicensed PowerWorld add-on (e.g., TransLineCalc) + * - ``COMError`` + - Raised when COM communication fails (SimAuto crash, unresponsive, or invalid function call) + * - ``CommandNotRespectedError`` + - Raised when PowerWorld silently ignores a command (e.g., setting a value outside allowed limits) + * - ``GridObjDNE`` + - Raised when a grid object data query fails (object does not exist in the case) + * - ``FieldDataException`` + - Raised when there is an issue with field data retrieval or parsing + * - ``AuxParseException`` + - Raised when parsing an auxiliary file fails + * - ``ContainerDeletedException`` + - Raised when attempting to access a container that has been deleted + * - ``PowerFlowException`` + - Base class for power flow solution errors + * - ``BifurcationException`` + - Raised when voltage bifurcation is suspected during power flow + * - ``DivergenceException`` + - Raised when the power flow solution diverges + * - ``GeneratorLimitException`` + - Raised when a generator has exceeded a limit during power flow + * - ``GICException`` + - Raised when a GIC analysis error occurs + +.. code-block:: text + + Exception + └── Error (base for all ESA++ exceptions) + ├── COMError + ├── GridObjDNE + ├── FieldDataException + ├── AuxParseException + ├── ContainerDeletedException + ├── GICException + ├── PowerFlowException + │ ├── BifurcationException + │ ├── DivergenceException + │ └── GeneratorLimitException + └── PowerWorldError + ├── SimAutoFeatureError + ├── PowerWorldPrerequisiteError + ├── PowerWorldAddonError + └── CommandNotRespectedError + +.. code-block:: python + + from esapp.saw import SAW, PowerWorldError, PowerWorldPrerequisiteError + + try: + saw.CTGSolveAll() + except PowerWorldPrerequisiteError: + print("No contingencies defined - add contingencies first") + except PowerWorldError as e: + print(f"PowerWorld error: {e.message}") + print(f"Source: {e.source}") diff --git a/docs/api/utils.rst b/docs/api/utils.rst index fe35ace9..d5313cbf 100644 --- a/docs/api/utils.rst +++ b/docs/api/utils.rst @@ -1,16 +1,74 @@ -Utilities -========= - -ESA++ includes a variety of utility modules for mathematical operations, geographic analysis, and debugging. - -.. autosummary:: - :toctree: generated/ - - esapp.utils.b3d - esapp.utils.decorators - esapp.utils.exceptions - esapp.utils.map - esapp.utils.mathtools - esapp.utils.mesh - esapp.utils.misc - esapp.utils.plotwavelet +Utilities & Analysis +==================== + +The ``esapp.utils`` package provides analysis modules, visualization tools, and general helpers. + +Contingency Builder +------------------- + +Fluent API for defining transient stability contingencies. + +.. currentmodule:: esapp.utils.contingency + +.. autoclass:: ContingencyBuilder + :members: + +.. autoclass:: SimAction + :members: + +GIC Analysis +------------ + +Geomagnetically Induced Current (GIC) analysis tools. + +.. currentmodule:: esapp.utils.gic + +.. autoclass:: GIC + :members: + :show-inheritance: + +Network Topology +---------------- + +Network graph analysis including incidence matrices, Laplacians, and path calculations. + +.. currentmodule:: esapp.utils.network + +.. autoclass:: Network + :members: + :show-inheritance: + +.. autoclass:: BranchType + :members: + +Dynamics +-------- + +Transient stability simulation utilities for field-watching and result processing. + +.. currentmodule:: esapp.utils.dynamics + +.. autoclass:: TSWatch + :members: + +.. autofunction:: get_ts_results + +.. autofunction:: process_ts_results + +B3D File Format +--------------- + +Binary 3D electric field data I/O. + +.. currentmodule:: esapp.utils.b3d + +.. automodule:: esapp.utils.b3d + :members: + +General Helpers +--------------- + +.. currentmodule:: esapp.utils.misc + +.. automodule:: esapp.utils.misc + :members: diff --git a/docs/api/workbench.rst b/docs/api/workbench.rst index eb9f1143..70a97119 100644 --- a/docs/api/workbench.rst +++ b/docs/api/workbench.rst @@ -1,11 +1,24 @@ -GridWorkBench +PowerWorld ============= -The ``GridWorkBench`` is the high-level entry point for interacting with PowerWorld via ESA++. It wraps -SimAuto with a Pythonic interface for case management, data access, and analysis helpers. For concepts and -usage patterns, see :doc:`../guide/usage`. This page lists the full API surface. +The ``PowerWorld`` is the high-level entry point for interacting with PowerWorld via ESA++. It wraps +SimAuto with a Pythonic interface for case management, data access, and analysis helpers. .. currentmodule:: esapp.workbench -.. autoclass:: GridWorkBench +.. autoclass:: PowerWorld + :members: + +Descriptors +----------- + +Lightweight descriptor classes that map Python attributes to PowerWorld option fields. +Used by ``PowerWorld`` for solver options and by ``GIC`` for GIC analysis options. + +.. currentmodule:: esapp._descriptors + +.. autoclass:: SolverOption + :members: + +.. autoclass:: GICOption :members: diff --git a/docs/conf.py b/docs/conf.py index 9cec354d..8392b428 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -2,8 +2,9 @@ import sys import importlib.metadata -# Ensure the project root is in the path +# Ensure the project root and extensions dir are in the path sys.path.insert(0, os.path.abspath("..")) +sys.path.insert(0, os.path.abspath("_ext")) extensions = [ "sphinx.ext.autodoc", @@ -17,9 +18,14 @@ "sphinx.ext.napoleon", "sphinx_copybutton", "nbsphinx", + "grid_list", ] autosummary_generate = True +autosummary_imported_members = False + +# Exclude ts_fields module from autosummary stub generation +autosummary_mock_imports = ["esapp.components.ts_fields"] autodoc_default_options = { "members": True, @@ -27,11 +33,24 @@ "member-order": "groupwise", } +# Skip TS class and TSField from autodoc - we use custom tables instead +def autodoc_skip_member(app, what, name, obj, skip, options): + # Skip the TS class and all its nested classes + if name in ("TS", "TSField"): + return True + # Skip nested TS category classes (Area, Branch, Bus, Gen, etc.) + if hasattr(obj, "__module__") and "ts_fields" in str(getattr(obj, "__module__", "")): + return True + return skip + +def setup(app): + app.connect("autodoc-skip-member", autodoc_skip_member) + autodoc_preserve_defaults = True todo_include_todos = True autosectionlabel_prefix_document = True -autoclass_content = "both" +autoclass_content = "init" autodoc_typehints = "none" add_module_names = False @@ -44,8 +63,8 @@ napoleon_google_docstring = False napoleon_numpy_docstring = True napoleon_include_init_with_doc = False -napoleon_use_param = True -napoleon_use_rtype = True +napoleon_use_param = False +napoleon_use_rtype = False napoleon_preprocess_types = True napoleon_type_aliases = { "np": "numpy", @@ -74,7 +93,24 @@ ] nbsphinx_execute = 'never' +nbsphinx_allow_errors = True html_sourcelink_suffix = '' + +# nbsphinx styling configuration +nbsphinx_input_prompt = 'In [%s]:' +nbsphinx_output_prompt = 'Out[%s]:' +nbsphinx_prompt_width = '0pt' # Hide prompt in PDF for cleaner look + +# Custom CSS classes for notebook cells (used by nbsphinx) +nbsphinx_prolog = r""" +{% set docname = env.doc2path(env.docname, base=None) %} + +.. only:: html + + .. role:: raw-html(raw) + :format: html + +""" master_doc = "index" project = "ESA++" @@ -91,6 +127,8 @@ html_theme_options = { "navigation_depth": 2, } +html_static_path = ["_static"] +html_css_files = ["custom.css", "custom_tables.css"] autodoc_mock_imports = [ "win32com", @@ -102,13 +140,172 @@ "pyproj", ] +latex_documents = [ + (master_doc, "esapp.tex", "ESA++ Documentation", author, "manual"), +] + latex_elements = { + "pointsize": "10pt", + "fncychap": r"\usepackage[Bjornstrup]{fncychap}", + "fontpkg": r""" +\usepackage{charter} +\usepackage[scaled=0.9]{inconsolata} +""", "preamble": r""" +\setcounter{tocdepth}{3} \usepackage{mathrsfs} \usepackage{breakurl} \usepackage{booktabs} \usepackage{longtable} \usepackage{multirow} -\sloppy +\usepackage{enumitem} +\usepackage{microtype} +\usepackage{xcolor} +\usepackage{array} +\usepackage{tabularx} +\usepackage{tcolorbox} +\tcbuselibrary{skins,breakable} + +% Define a modern color palette +\definecolor{linkblue}{RGB}{0, 83, 155} +\definecolor{codebackground}{RGB}{250, 250, 252} +\definecolor{codeborder}{RGB}{220, 220, 230} +\definecolor{headingblue}{RGB}{30, 60, 114} +\definecolor{noteblue}{RGB}{232, 244, 253} +\definecolor{noteborder}{RGB}{66, 165, 245} +\definecolor{warningyellow}{RGB}{255, 249, 230} +\definecolor{warningborder}{RGB}{255, 183, 77} +\definecolor{tipgreen}{RGB}{232, 245, 233} +\definecolor{tipborder}{RGB}{102, 187, 106} + +% Sphinx code-block styling +\sphinxsetup{ + verbatimwithframe=false, + VerbatimColor={RGB}{250,250,252}, + VerbatimBorderColor={RGB}{220,220,230}, + InnerLinkColor={RGB}{0,83,155}, + OuterLinkColor={RGB}{0,83,155}, + noteBgColor={RGB}{232,244,253}, + noteBorderColor={RGB}{66,165,245}, + warningBgColor={RGB}{255,249,230}, + warningBorderColor={RGB}{255,183,77}, + importantBgColor={RGB}{255,243,224}, + importantBorderColor={RGB}{255,152,0}, + tipBgColor={RGB}{232,245,233}, + tipBorderColor={RGB}{102,187,106}, + hintBgColor={RGB}{232,245,233}, + hintBorderColor={RGB}{102,187,106} +} + +% Modern admonition styling - override Sphinx defaults +\renewenvironment{sphinxnote}[1]{% + \begin{tcolorbox}[ + enhanced, + breakable, + colback=noteblue, + colframe=noteborder, + boxrule=0pt, + leftrule=3pt, + arc=0pt, + outer arc=0pt, + left=10pt, + right=10pt, + top=8pt, + bottom=8pt, + before skip=10pt, + after skip=10pt + ] + \textbf{\sffamily\textcolor{noteborder}{#1}}\par\smallskip +}{\end{tcolorbox}} + +\renewenvironment{sphinxwarning}[1]{% + \begin{tcolorbox}[ + enhanced, + breakable, + colback=warningyellow, + colframe=warningborder, + boxrule=0pt, + leftrule=3pt, + arc=0pt, + outer arc=0pt, + left=10pt, + right=10pt, + top=8pt, + bottom=8pt, + before skip=10pt, + after skip=10pt + ] + \textbf{\sffamily\textcolor{warningborder}{#1}}\par\smallskip +}{\end{tcolorbox}} + +\renewenvironment{sphinxhint}[1]{% + \begin{tcolorbox}[ + enhanced, + breakable, + colback=tipgreen, + colframe=tipborder, + boxrule=0pt, + leftrule=3pt, + arc=0pt, + outer arc=0pt, + left=10pt, + right=10pt, + top=8pt, + bottom=8pt, + before skip=10pt, + after skip=10pt + ] + \textbf{\sffamily\textcolor{tipborder}{#1}}\par\smallskip +}{\end{tcolorbox}} + +\renewenvironment{sphinxtip}[1]{% + \begin{tcolorbox}[ + enhanced, + breakable, + colback=tipgreen, + colframe=tipborder, + boxrule=0pt, + leftrule=3pt, + arc=0pt, + outer arc=0pt, + left=10pt, + right=10pt, + top=8pt, + bottom=8pt, + before skip=10pt, + after skip=10pt + ] + \textbf{\sffamily\textcolor{tipborder}{#1}}\par\smallskip +}{\end{tcolorbox}} + +% Compact lists with slight breathing room +\setlist{nosep, itemsep=2pt} +\setlength{\parskip}{0.4em} +\setlength{\parindent}{0pt} + +% Table styling +\renewcommand{\arraystretch}{1.25} +\setlength{\tabcolsep}{5pt} + +% Modern header/footer with clean lines +\usepackage{fancyhdr} +\pagestyle{fancy} +\fancyhf{} +\fancyhead[L]{\small\textcolor{gray}{\nouppercase{\leftmark}}} +\fancyhead[R]{\small\textcolor{gray}{\thepage}} +\fancyfoot[C]{\footnotesize\textcolor{gray}{ESA++ Documentation}} +\renewcommand{\headrulewidth}{0.5pt} +\renewcommand{\footrulewidth}{0pt} + +% Style the head rule +\renewcommand{\headrule}{\vspace{-4pt}\hbox to\headwidth{\color{codeborder}\leaders\hrule height 0.5pt\hfill}} + +% Style for DataFrame/table output in notebooks +\renewcommand{\sphinxstyletheadfamily}{\sffamily\bfseries\small} """, + "figure_align": "H", + "sphinxsetup": "hmargin={1in,1in}, vmargin={1in,1in}", } + +# Disable the module index in PDF (it's not useful) +latex_domain_indices = False diff --git a/docs/dev/components.rst b/docs/dev/components.rst index 62c2d077..a342a56e 100644 --- a/docs/dev/components.rst +++ b/docs/dev/components.rst @@ -1,279 +1,134 @@ -Development -=========== - -This section covers the internal maintenance and extension of the ESA++ toolkit, specifically focusing on how the library maintains its structured representation of PowerWorld objects to facilitate ObjectField access. - -Component Architecture ----------------------- - -ESA++ uses a sophisticated class generation system to represent all PowerWorld objects and their fields. -This architecture provides: - -Type Safety - IDE autocompletion and type hints for all components -Automatic Synchronization - Stays compatible with new PowerWorld versions automatically -Maintainability - No manual class definitions needed -Documentation - Docstrings auto-generated from PowerWorld metadata - -The System -~~~~~~~~~~ - -The component system consists of: - -1. **GObject Base Class** (``esapp/gobject.py``) - - A metaclass-based foundation that provides: - - - Field definition collection from class attributes - - Primary key information management - - Field priority marking (required, optional) - - Informative string representations - -2. **Field Definitions** (``esapp/grid.py``) - - Auto-generated classes defining all PowerWorld objects: - - .. code-block:: python - - class Bus(GObject): - """A power system bus/node""" - BusNum = (FieldPriority.PRIMARY_KEY, np.int32) - BusName = (FieldPriority.OPTIONAL, str) - BusPUVolt = (FieldPriority.OPTIONAL, np.float64) - -3. **Generation Script** (``esapp/dev/generate_components.py``) - - Python script that: - - Parses PowerWorld field export (PWRaw format) - - Generates component class definitions - - Handles field name sanitization - - Assigns priority levels automatically - -4. **Indexable Mixin** (``esapp/indexable.py``) - - Translates Python indexing syntax into SimAuto calls: - - .. code-block:: python - - buses = wb[Bus, ["BusNum", "BusPUVolt"]] - - .. note:: - Translates to ``SimAuto.GetDataRaw("Bus", None, ["BusNum", "BusPUVolt"])`` - -Updating Component Definitions -------------------------------- - -When PowerWorld adds new fields or a new version is released, component definitions must be updated. - -Step 1: Export the Field List from PowerWorld -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -1. Open PowerWorld Simulator -2. Navigate to the **Window** ribbon -3. Click **Export Case Object Fields** -4. Save the resulting tab-delimited text file (typically named Export.txt or similar) - -Step 2: Prepare the Raw Data -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -1. Rename the exported file to ``PWRaw`` -2. Place it in the ``esapp/dev/`` folder, overwriting the existing one - -The PWRaw file format is tab-delimited with columns: - -.. code-block:: text - - ObjectType FieldName DataType KeyType Description - Bus BusNum Integer PRIMARY_KEY Bus number identifier - Bus BusName String OPTIONAL Bus name - Bus BusPUVolt Double OPTIONAL Bus voltage in per-unit - ... - -Step 3: Run the Generation Script -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Execute the generation script from the project root: +Component System +================ -.. code-block:: bash +ESA++ auto-generates Python classes from PowerWorld's field metadata, providing type-safe +access to all SimAuto objects with IDE autocompletion. - python esapp/dev/generate_components.py +Architecture Overview +--------------------- -The script will: +.. list-table:: + :widths: 25 75 + :header-rows: 0 -1. Parse the PWRaw file -2. Generate Python class definitions -3. Assign field priorities based on PowerWorld metadata: - - - **PRIMARY_KEY**: Component identifier (e.g., BusNum for Bus objects) - - **REQUIRED**: Must be specified when creating new objects - - **OPTIONAL**: Can be read/written but not required - -4. Create ``esapp/grid.py`` with all component classes -5. Print progress to console including any warnings or excluded fields + * - ``gobject.py`` + - Base class using Enum mechanics to build component schemas at class creation + * - ``grid.py`` + - Auto-generated GObject subclasses for all PowerWorld object types + * - ``ts_fields.py`` + - Auto-generated TS field constants for transient stability intellisense + * - ``generate_components.py`` + - Script that parses PWRaw export and generates the above files + * - ``indexable.py`` + - Translates ``pw[Bus, "field"]`` syntax into SimAuto calls -Step 4: Verify the Changes -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +GObject Base Class +~~~~~~~~~~~~~~~~~~ -1. Check console output for errors or excluded objects/fields: +Each component is an Enum subclass where members define fields. A single-argument +member (``ObjectString``) sets the PowerWorld object type, while 3-tuple members +define fields with ``(PowerWorld name, data type, priority flags)``: - .. code-block:: text +.. code-block:: python - Processed 150 object types with 5247 total fields - Excluded: 12 fields due to naming conflicts - Component definitions updated successfully + class Bus(GObject): + BusNum = ("BusNum", int, FieldPriority.PRIMARY) + """Number""" + BusName = ("BusName", str, FieldPriority.SECONDARY | FieldPriority.REQUIRED | FieldPriority.EDITABLE) + """Name""" + # ... more fields ... -2. Run unit tests to verify component generation: + ObjectString = 'Bus' # Sets Bus.TYPE — must be last member - .. code-block:: bash +The base class collects these into queryable properties: - pytest tests/test_grid_components.py -v +.. code-block:: python -3. Run integration tests if PowerWorld is available: + Bus.TYPE # 'Bus' - PowerWorld object type (from ObjectString) + Bus.keys # ['BusNum'] - primary key fields + Bus.fields # all field names + Bus.secondary # alternate identifier fields + Bus.editable # user-modifiable fields - .. code-block:: bash +Field Priority Flags +~~~~~~~~~~~~~~~~~~~~ - pytest tests/test_integration_workbench.py -v +See :class:`~esapp.components.gobject.FieldPriority` in the +:doc:`API reference ` for the full list of flags and their meanings. -Generation Script Behavior -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Updating Components +------------------- -The ``generate_components.py`` script handles several important tasks: +When PowerWorld releases new versions or adds fields, regenerate the component definitions. -**Field Name Sanitization** +**Step 1: Export Field List** -Colons - ``Bus:Num`` → ``Bus__Num`` (stored as ``Bus:Num`` internally) -Spaces - ``Line Name`` → ``Line_Name`` -Identifiers - Converts to valid Python identifiers +In PowerWorld Simulator: **Window** → **Export Case Object Fields** → Save as tab-delimited text. -**Priority Assignment** +**Step 2: Replace PWRaw** -PRIMARY_KEY - Fields marked as KeyType="KEY" in PWRaw -REQUIRED - Fields marked as KeyType="REQUIRED" -OPTIONAL - Remaining fields +Copy the exported file to ``esapp/components/PWRaw``, overwriting the existing one. -**Conflict Resolution** - - Fields with invalid names are excluded (rare) - - Duplicate field names are logged - - Output includes summary of excluded fields +**Step 3: Run Generator** -**Component Class Generation** - - Creates class for each ObjectType in PWRaw - - Adds docstring with description - - Defines field tuple ``(priority, data_type)`` for each field - - Adds special attributes like ``_object_type``, ``_fields``, ``_keys`` +.. code-block:: bash -Example Generated Component -~~~~~~~~~~~~~~~~~~~~~~~~~~~ + python esapp/components/generate_components.py -A generated component class looks like: +**Step 4: Verify** -.. code-block:: python +.. code-block:: bash - class Bus(GObject): - """A power system bus/node - represents a point of electrical connection""" - - BusNum = (FieldPriority.PRIMARY_KEY, np.int32) - BusName = (FieldPriority.OPTIONAL, str) - BusPUVolt = (FieldPriority.OPTIONAL, np.float64) - BusAngle = (FieldPriority.OPTIONAL, np.float64) - AreaNum = (FieldPriority.OPTIONAL, np.int32) - ZoneNum = (FieldPriority.OPTIONAL, np.int32) - - _object_type = "Bus" - _fields = ["BusNum", "BusName", "BusPUVolt", ...] - _keys = ["BusNum"] - -Using Generated Components -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -In user code, components are used for type-safe data access: + pytest tests/test_grid_components.py -v + pytest tests/test_integration_workbench.py -v # if PowerWorld available -.. code-block:: python +The script sanitizes field names (``Bus:Num`` → ``Bus__Num``, spaces → underscores) and +logs any excluded fields due to naming conflicts. - from esapp.grid import Bus - - data = wb[Bus, [Bus.BusNum, Bus.BusName, Bus.BusPUVolt]] - data = wb[Bus, ["BusNum", "BusName", "BusPUVolt"]] +Usage Examples +-------------- -.. note:: - IDE provides autocompletion for all fields when using class attributes. +.. code-block:: python -Maintenance Recommendations -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + from esapp.components import * -**After PowerWorld Upgrade:** - - Export new field list immediately - - Run generation script to update components - - Run full test suite to verify compatibility - - Commit updated components file to version control + # Data access with component classes + data = pw[Bus, [Bus.BusNum, Bus.BusName, Bus.BusPUVolt]] -**Periodic Cleanup:** - - Monitor for excluded fields (usually rare) - - Review field name sanitization for any issues - - Update version requirements if significant changes occur + # Check field properties + Bus.is_editable('BusName') # True + Bus.is_settable('BusNum') # True (it's a key) -**Documentation:** - - Keep README updated with supported PowerWorld versions - - Document any known field limitations or quirks - - Maintain changelog of compatibility updates + # Transient stability fields + tsw = TSWatch() + tsw.watch(Gen, [TS.Gen.P, TS.Gen.W, TS.Gen.Delta]) Extending ESA++ --------------- -**Adding New Analysis Methods** - -To add a new analysis capability to GridWorkBench: +**New Analysis Methods** -1. Create a new mixin in ``esapp/saw/`` (e.g., ``custom_analysis.py``) -2. Implement method using SAW interface +1. Create mixin in ``esapp/saw/`` (e.g., ``custom_analysis.py``) +2. Implement using SAW interface 3. Add mixin to SAW class in ``esapp/saw/saw.py`` -4. Add convenience method to GridWorkBench if commonly used - -**Adding Helper Functions** +4. Add convenience wrapper to PowerWorld if commonly used -New utility functions should go in: +**New Utilities** -- ``esapp/utils/`` for general utilities -- ``esapp/saw/_helpers.py`` for SAW-specific helpers -- ``esapp/apps/`` for domain-specific analysis +- General utilities → ``esapp/utils/`` +- SAW-specific helpers → ``esapp/saw/_helpers.py`` +- Domain analysis → ``esapp/utils/`` (GIC, Network, ContingencyBuilder) +- Example applications → ``examples/`` (Statics, Dynamics) **Contributing Tests** -When adding features: - -1. Add unit tests to ``tests/`` -2. Add integration tests if PowerWorld interaction -3. Update test documentation -4. Run full test suite before submitting +Add unit tests to ``tests/``, integration tests for PowerWorld interactions, +and run the full suite before submitting. API Stability -~~~~~~~~~~~~~ - -ESA++ maintains semantic versioning: - -- **MAJOR**: Breaking changes to public API -- **MINOR**: New features, backwards compatible -- **PATCH**: Bug fixes - -The public API includes: - -- GridWorkBench class and all public methods -- Component classes in ``esapp.grid`` -- Exception types in ``esapp.saw.exceptions`` - -Internal APIs (subject to change): +------------- -- SAW mixin implementations -- Indexable internals -- GObject metaclass details +ESA++ uses semantic versioning: -Generally, this is the only step required to keep ESA++ compatible with new PowerWorld releases regarding data access and modification. \ No newline at end of file +- **Public API** (stable): PowerWorld, component classes, exception types +- **Internal API** (may change): SAW mixins, Indexable internals, GObject metaclass diff --git a/docs/dev/index.rst b/docs/dev/index.rst index 06c61855..bb0d8798 100644 --- a/docs/dev/index.rst +++ b/docs/dev/index.rst @@ -1,8 +1,10 @@ Development =========== +Internal documentation for maintaining and extending ESA++. + .. toctree:: - :maxdepth: 2 + :maxdepth: 1 components tests diff --git a/docs/dev/tests.rst b/docs/dev/tests.rst index ab086506..976f0732 100644 --- a/docs/dev/tests.rst +++ b/docs/dev/tests.rst @@ -1,71 +1,79 @@ Testing Suite ============= -One suite covers everything: fast unit tests that run without PowerWorld and integration tests that exercise -live Simulator cases. Configure once, run anywhere. +The test suite includes unit tests (no PowerWorld required) and integration tests +(requires PowerWorld Simulator with a valid case file). -Test map --------- +Test Coverage +------------- + +**Unit Tests** — Run without PowerWorld .. list-table:: + :widths: 35 65 :header-rows: 1 - :widths: 30 50 20 * - File - - What it covers - - PowerWorld? - * - test_grid_components.py - - Component definitions, field metadata, GObject behavior - - No - * - test_exceptions.py - - Exception hierarchy and messaging - - No - * - test_indexable_data_access.py - - Indexing reads/writes on mock data - - No - * - test_saw_core_methods.py - - SAW core calls with mocked COM responses - - No - * - test_integration_saw_powerworld.py - - Power flow, contingencies, file ops against real cases - - **Yes** - * - test_integration_workbench.py - - GridWorkBench data access on a live case - - **Yes** + - Coverage + * - ``test_gobject.py`` + - GObject base class, FieldPriority flags, repr/str methods + * - ``test_grid_components.py`` + - Field collection, key/editable/settable classification + * - ``test_indexing.py`` + - Indexable data access syntax, broadcast, bulk update + * - ``test_helpers_unit.py`` + - SAW helpers: df_to_aux, path conversion, formatting, GICOption descriptor mechanics + * - ``test_dynamics.py`` + - Dynamics module: ContingencyBuilder, SimAction enum + * - ``test_utils.py`` + - Utility modules: timing decorator, B3D file format + +**Integration Tests** — Require PowerWorld -Configure integration tests (one-time) --------------------------------------- +.. list-table:: + :widths: 35 65 + :header-rows: 1 + + * - File + - Coverage + * - ``test_integration_saw_core.py`` + - Core SAW operations, file I/O, data retrieval + * - ``test_integration_workbench.py`` + - PowerWorld data access, indexing, solver option descriptors, convenience features (flows, overloads, snapshot, PTDF, LODF, properties, summary) + * - ``test_integration_saw_powerflow.py`` + - Power flow, matrices (Ybus, Jacobian), PTDF/LODF + * - ``test_integration_saw_contingency.py`` + - Contingency auto-insertion, solving, OTDF + * - ``test_integration_network.py`` + - Network topology, incidence matrices, graph analysis + * - ``test_integration_saw_gic.py`` + - GIC analysis, calculations, GIC option descriptors, G-matrix comparison + * - ``test_integration_saw_modify.py`` + - Case modification and data manipulation + * - ``test_integration_saw_operations.py`` + - Scheduled actions, weather, OPF, extended methods + * - ``test_integration_saw_transient.py`` + - Transient stability simulation + +Configuration +------------- 1. Copy ``tests/config_test.example.py`` to ``tests/config_test.py`` -2. Set an absolute path to a PowerWorld case: ``SAW_TEST_CASE = r"C:\Path\To\Your\Case.pwb"`` -3. Keep the file alongside the tests; pytest will auto-detect it +2. Set ``SAW_TEST_CASE = r"C:\Path\To\Your\Case.pwb"`` -How to run ----------- +Running Tests +------------- .. code-block:: bash - # Full suite - pytest tests/ - - # Unit only (skip PowerWorld) - pytest tests/ -m "not online" - - # Specific file - pytest tests/test_grid_components.py -v - - # With coverage - pytest tests/ --cov=esapp --cov-report=html - -VS Code -------- - -Open the Testing view (beaker icon); tests are discovered automatically. You can run by file or class, and -debug individual tests from the UI. + pytest tests/ # Full suite + pytest tests/ -m unit # Unit only + pytest tests/ -m integration # Integration only + pytest tests/ --cov=esapp --cov-report=html # With coverage Troubleshooting --------------- -- PowerWorld not found: ensure ``tests/config_test.py`` exists and the path is correct -- Online tests slow: run ``pytest -m "not online"`` for unit-only -- Import errors: install in editable mode ``pip install -e .`` \ No newline at end of file +- **PowerWorld not found**: Ensure ``tests/config_test.py`` exists with valid case path +- **Integration tests slow**: Use ``pytest -m "not integration"`` for unit-only runs +- **Import errors**: Install in editable mode with ``pip install -e .`` diff --git a/docs/examples/01_basic_data_access.ipynb b/docs/examples/01_basic_data_access.ipynb deleted file mode 100644 index 52f0596b..00000000 --- a/docs/examples/01_basic_data_access.ipynb +++ /dev/null @@ -1,661 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Basic Data Access\n", - "\n", - "Demonstrates opening a case and retrieving component data using indexing." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The primary way to open a case is to instantiate a `GridWorkBench` object. For these examples, a `case_path` variable is created in a hidden cell that reads from `case.txt`. The code below shows the syntax used for initialization.\n", - "\n", - "```python\n", - "from esapp import GridWorkBench\n", - "from esapp.grid import *\n", - "\n", - "wb = GridWorkBench(case_path)\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "hide-input" - ] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "'open' took: 3.1134 sec\n" - ] - } - ], - "source": [ - "# This cell is hidden in the documentation.\n", - "# It performs the actual case loading for the example.\n", - "from esapp import GridWorkBench\n", - "from esapp.grid import *\n", - "import ast\n", - "\n", - "with open('case.txt', 'r') as f:\n", - " case_path = ast.literal_eval(f.read().strip())\n", - "\n", - "wb = GridWorkBench(case_path)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Retrieve Component Data\n", - "\n", - "The primary interface for accessing power system data is through the indexing syntax `wb[ComponentType, fields]`, which returns a pandas DataFrame. This provides a flexible way to extract and analyze component parameters." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "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", - "
BusNumBusPUVolt
010.993545
120.991225
230.984548
340.978800
450.988985
\n", - "
" - ], - "text/plain": [ - " BusNum BusPUVolt\n", - "0 1 0.993545\n", - "1 2 0.991225\n", - "2 3 0.984548\n", - "3 4 0.978800\n", - "4 5 0.988985" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "bus_voltages = wb[Bus, \"BusPUVolt\"]\n", - "bus_voltages.head()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Retrieve multiple fields at once and filter the results. Here we get all online generators with their power output:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "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", - "
BusNumGenIDGenMWGenStatus
0212.500000Closed
1222.500000Closed
2232.500000Closed
3242.500000Closed
423169.274741Closed
\n", - "
" - ], - "text/plain": [ - " BusNum GenID GenMW GenStatus\n", - "0 2 1 2.500000 Closed\n", - "1 2 2 2.500000 Closed\n", - "2 2 3 2.500000 Closed\n", - "3 2 4 2.500000 Closed\n", - "4 23 1 69.274741 Closed" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "gens = wb[Gen, [\"GenMW\", \"GenStatus\"]]\n", - "online_gens = gens[gens[\"GenStatus\"] == \"Closed\"]\n", - "online_gens.head()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Modify Component Data\n", - "\n", - "Use the indexing syntax to update component parameters. Setting a field to a scalar value broadcasts it to all components of that type:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "wb[Gen, \"GenMW\"] = 100.0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Verify Modification\n", - "\n", - "Read the modified values to confirm the update:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "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", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
BusNumGenIDGenMW
021100.0
122100.0
223100.0
324100.0
4231100.0
52310100.0
6232100.0
7233100.0
8234100.0
9235100.0
10236100.0
11237100.0
12238100.0
13239100.0
14261100.0
15262100.0
16271100.0
17272100.0
18281100.0
19282100.0
20331100.0
21341100.0
22342100.0
23343100.0
24344100.0
25345100.0
26346100.0
27351100.0
28352100.0
293530.0
30354100.0
31355100.0
323560.0
33357100.0
34358100.0
35361100.0
36362100.0
37363100.0
38364100.0
393710.0
403720.0
41373100.0
423740.0
43375100.0
443760.0
\n", - "
" - ], - "text/plain": [ - " BusNum GenID GenMW\n", - "0 2 1 100.0\n", - "1 2 2 100.0\n", - "2 2 3 100.0\n", - "3 2 4 100.0\n", - "4 23 1 100.0\n", - "5 23 10 100.0\n", - "6 23 2 100.0\n", - "7 23 3 100.0\n", - "8 23 4 100.0\n", - "9 23 5 100.0\n", - "10 23 6 100.0\n", - "11 23 7 100.0\n", - "12 23 8 100.0\n", - "13 23 9 100.0\n", - "14 26 1 100.0\n", - "15 26 2 100.0\n", - "16 27 1 100.0\n", - "17 27 2 100.0\n", - "18 28 1 100.0\n", - "19 28 2 100.0\n", - "20 33 1 100.0\n", - "21 34 1 100.0\n", - "22 34 2 100.0\n", - "23 34 3 100.0\n", - "24 34 4 100.0\n", - "25 34 5 100.0\n", - "26 34 6 100.0\n", - "27 35 1 100.0\n", - "28 35 2 100.0\n", - "29 35 3 0.0\n", - "30 35 4 100.0\n", - "31 35 5 100.0\n", - "32 35 6 0.0\n", - "33 35 7 100.0\n", - "34 35 8 100.0\n", - "35 36 1 100.0\n", - "36 36 2 100.0\n", - "37 36 3 100.0\n", - "38 36 4 100.0\n", - "39 37 1 0.0\n", - "40 37 2 0.0\n", - "41 37 3 100.0\n", - "42 37 4 0.0\n", - "43 37 5 100.0\n", - "44 37 6 0.0" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "wb[Gen, \"GenMW\"]" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "esaplus", - "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.11.14" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/docs/examples/02_power_flow_analysis.ipynb b/docs/examples/02_power_flow_analysis.ipynb deleted file mode 100644 index da1c004a..00000000 --- a/docs/examples/02_power_flow_analysis.ipynb +++ /dev/null @@ -1,178 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Power Flow Analysis\n", - "\n", - "Solves the AC power flow and inspects system voltages for violations." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "tags": [ - "hide-input" - ] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "'open' took: 2.9621 sec\n" - ] - } - ], - "source": [ - "# This cell is hidden in the documentation.\n", - "# It performs the actual case loading for the example.\n", - "from esapp import GridWorkBench\n", - "from esapp.grid import *\n", - "import ast\n", - "\n", - "with open('case.txt', 'r') as f:\n", - " case_path = ast.literal_eval(f.read().strip())\n", - "\n", - "wb = GridWorkBench(case_path)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Import the case and instantiate the `GridWorkBench`.\n", - "\n", - "```python\n", - "from esapp import GridWorkBench\n", - "from esapp.grid import *\n", - "\n", - "wb = GridWorkBench(case_path)\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 0.993355-0.019419j\n", - "1 0.988897-0.067891j\n", - "2 0.981193-0.081206j\n", - "3 0.973882-0.097994j\n", - "4 0.988339-0.035719j\n", - "dtype: complex128" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "V = wb.pflow()\n", - "V.head()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Analyze Results\n", - "\n", - "The `pflow()` method returns a Series of complex bus voltages. Extract voltage magnitudes and check for violations:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Find buses with voltage below 0.98 per-unit:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "3 0.973882-0.097994j\n", - "7 0.973776-0.097237j\n", - "10 0.968600-0.110751j\n", - "11 0.971614-0.105523j\n", - "12 0.973420-0.103939j\n", - "14 0.973217-0.102800j\n", - "16 0.968262-0.118577j\n", - "17 0.968432-0.120988j\n", - "20 0.975803-0.089976j\n", - "dtype: complex128" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "low_v = V[abs(V) < 0.98]\n", - "low_v" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Get the minimum voltage magnitude in the system:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0.9749114967028367" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "min_voltage = abs(V).min()\n", - "min_voltage" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "esaplus", - "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.11.14" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/docs/examples/03_contingency_analysis.ipynb b/docs/examples/03_contingency_analysis.ipynb deleted file mode 100644 index d5c43000..00000000 --- a/docs/examples/03_contingency_analysis.ipynb +++ /dev/null @@ -1,324 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Contingency Analysis\n", - "\n", - "Automating N-1 contingency analysis and retrieving results." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Import the case and instantiate the `GridWorkBench`.\n", - "\n", - "```python\n", - "from esapp import GridWorkBench\n", - "from esapp.grid import *\n", - "\n", - "wb = GridWorkBench(case_path)\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "tags": [ - "hide-input" - ] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "'open' took: 3.0129 sec\n" - ] - } - ], - "source": [ - "# This cell is hidden in the documentation.\n", - "# It performs the actual case loading for the example.\n", - "from esapp import GridWorkBench\n", - "from esapp.grid import *\n", - "import ast\n", - "\n", - "with open('case.txt', 'r') as f:\n", - " case_path = ast.literal_eval(f.read().strip())\n", - "\n", - "wb = GridWorkBench(case_path)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Automated N-1 Contingency Analysis\n", - "\n", - "ESAplus provides built-in support for N-1 contingency analysis through the SAW interface. First, create and solve contingencies for all branches:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "wb.pflow() # Solve base case first\n", - "wb.auto_insert_contingencies() # Create N-1 contingencies\n", - "wb.solve_contingencies() # Solve all contingency scenarios" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Retrieve Violations\n", - "\n", - "After solving contingencies, retrieve all violations found during the analysis:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "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", - "
AggrMVAOverloadAggrPercentOverloadAllLabelsAreaNameAreaName:1AreaName:2AreaName:3AreaName:4AreaName:5AreaNum...ZoneNameZoneName:1ZoneName:2ZoneName:3ZoneName:4ZoneName:5ZoneNumZoneNum:1ZoneNum:2ZoneNum:3
00.6751150.673096Oahu1OahuOahuOahuOahu1...1111111111
10.6751150.673096Oahu1OahuOahuOahuOahu1...1111111111
20.6751150.673096Oahu1OahuOahuOahuOahu1...1111111111
30.6751150.673096Oahu1OahuOahuOahuOahu1...1111111111
40.6751150.673096Oahu1OahuOahuOahuOahu1...1111111111
\n", - "

5 rows × 394 columns

\n", - "
" - ], - "text/plain": [ - " AggrMVAOverload AggrPercentOverload AllLabels AreaName AreaName:1 \\\n", - "0 0.675115 0.673096 Oahu 1 \n", - "1 0.675115 0.673096 Oahu 1 \n", - "2 0.675115 0.673096 Oahu 1 \n", - "3 0.675115 0.673096 Oahu 1 \n", - "4 0.675115 0.673096 Oahu 1 \n", - "\n", - " AreaName:2 AreaName:3 AreaName:4 AreaName:5 AreaNum ... ZoneName \\\n", - "0 Oahu Oahu Oahu Oahu 1 ... 1 \n", - "1 Oahu Oahu Oahu Oahu 1 ... 1 \n", - "2 Oahu Oahu Oahu Oahu 1 ... 1 \n", - "3 Oahu Oahu Oahu Oahu 1 ... 1 \n", - "4 Oahu Oahu Oahu Oahu 1 ... 1 \n", - "\n", - " ZoneName:1 ZoneName:2 ZoneName:3 ZoneName:4 ZoneName:5 ZoneNum ZoneNum:1 \\\n", - "0 1 1 1 1 1 1 1 \n", - "1 1 1 1 1 1 1 1 \n", - "2 1 1 1 1 1 1 1 \n", - "3 1 1 1 1 1 1 1 \n", - "4 1 1 1 1 1 1 1 \n", - "\n", - " ZoneNum:2 ZoneNum:3 \n", - "0 1 1 \n", - "1 1 1 \n", - "2 1 1 \n", - "3 1 1 \n", - "4 1 1 \n", - "\n", - "[5 rows x 394 columns]" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "violations = wb[ViolationCTG, :]\n", - "violations.head()" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "esaplus", - "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.11.14" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/docs/examples/04_gic_analysis.ipynb b/docs/examples/04_gic_analysis.ipynb deleted file mode 100644 index ea95f630..00000000 --- a/docs/examples/04_gic_analysis.ipynb +++ /dev/null @@ -1,228 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# GIC Analysis\n", - "\n", - "Calculating Geomagnetically Induced Currents (GIC) for a uniform electric field." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Import the case and instantiate the `GridWorkBench`.\n", - "\n", - "```python\n", - "from esapp import GridWorkBench\n", - "from esapp.grid import *\n", - "\n", - "wb = GridWorkBench(case_path)\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "tags": [ - "hide-input" - ] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "'open' took: 3.0404 sec\n" - ] - } - ], - "source": [ - "# This cell is hidden in the documentation.\n", - "# It performs the actual case loading for the example.\n", - "from esapp import GridWorkBench\n", - "from esapp.grid import *\n", - "import ast\n", - "\n", - "with open('case.txt', 'r') as f:\n", - " case_path = ast.literal_eval(f.read().strip())\n", - "\n", - "wb = GridWorkBench(case_path)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Calculate GIC Response\n", - "\n", - "Compute geomagnetically induced currents for a uniform electric field. This calculates harmonic currents in transformers due to a 1.0 V/km electric field oriented at 90 degrees:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "wb.calculate_gic(max_field=1.0, direction=90.0)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Retrieve GIC Results\n", - "\n", - "Extract GIC neutral currents from the transformers to identify which components experience the largest impacts:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "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", - "
BusNum3WBusNum3W:1BusNum3W:2GICXFNeutralAmps
01200.753270
11200.753270
21200.753270
356013.443257
4910015.439837
\n", - "
" - ], - "text/plain": [ - " BusNum3W BusNum3W:1 BusNum3W:2 GICXFNeutralAmps\n", - "0 1 2 0 0.753270\n", - "1 1 2 0 0.753270\n", - "2 1 2 0 0.753270\n", - "3 5 6 0 13.443257\n", - "4 9 10 0 15.439837" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "gics = wb[GICXFormer, \"GICXFNeutralAmps\"]\n", - "gics.head()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Find the maximum GIC current in any transformer:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "BusNum3W 25.000000\n", - "BusNum3W:1 26.000000\n", - "BusNum3W:2 0.000000\n", - "GICXFNeutralAmps 15.439837\n", - "dtype: float64" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "max_gic = gics.max()\n", - "max_gic" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "esaplus", - "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.11.14" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/docs/examples/05_matrix_extraction.ipynb b/docs/examples/05_matrix_extraction.ipynb deleted file mode 100644 index 182db294..00000000 --- a/docs/examples/05_matrix_extraction.ipynb +++ /dev/null @@ -1,159 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Matrix Extraction\n", - "\n", - "Extracting system matrices (Y-Bus and Jacobian) for external mathematical analysis." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "tags": [ - "hide-input" - ] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "'open' took: 3.3408 sec\n" - ] - } - ], - "source": [ - "# This cell is hidden in the documentation.\n", - "# It performs the actual case loading for the example.\n", - "from esapp import GridWorkBench\n", - "from esapp.grid import *\n", - "import ast\n", - "\n", - "with open('case.txt', 'r') as f:\n", - " case_path = ast.literal_eval(f.read().strip())\n", - "\n", - "wb = GridWorkBench(case_path)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Import the case and instantiate the `GridWorkBench`.\n", - "\n", - "```python\n", - "from esapp import GridWorkBench\n", - "from esapp.grid import *\n", - "\n", - "wb = GridWorkBench(case_path)\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Admittance Matrix (Y-Bus)\n", - "\n", - "Extract the sparse Y-Bus admittance matrix for the power system. This matrix is commonly used in power flow calculations and network analysis:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(37, 37)" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "Y = wb.ybus()\n", - "Y.shape" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Which is of the form $(n_\\text{vert}, n_\\text{vert})$." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Network Topology\n", - "\n", - "The `Network` app provides graph-based representations of the system topology. Extract the incidence matrix (branches × buses):" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The incidence matrix represents branches as rows and buses as columns. Each row has entries of +1 and -1 indicating the sending and receiving buses of the branch:" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(89, 37)" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "A = wb.network.incidence()\n", - "A.shape" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Which is of the form $(n_\\text{edge}, n_\\text{vert})$." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "esaplus", - "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.11.14" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/docs/examples/06_exporting.ipynb b/docs/examples/06_exporting.ipynb deleted file mode 100644 index 9d396484..00000000 --- a/docs/examples/06_exporting.ipynb +++ /dev/null @@ -1,135 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Exporting Data\n", - "\n", - "This example demonstrates how to use functions to generate custom reports and export data directly to Microsoft Excel, leveraging PowerWorld's built-in reporting actions." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "hide-input" - ] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "'open' took: 2.7900 sec\n" - ] - } - ], - "source": [ - "# This cell is hidden in the documentation.\n", - "# It performs the actual case loading for the example.\n", - "from esapp import GridWorkBench\n", - "from esapp.grid import *\n", - "import os\n", - "import ast\n", - "\n", - "with open('case.txt', 'r') as f:\n", - " case_path = ast.literal_eval(f.read().strip())\n", - "\n", - "wb = GridWorkBench(case_path)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Import the case and instantiate the `GridWorkBench`.\n", - "\n", - "```python\n", - "from esapp import GridWorkBench\n", - "from esapp.grid import *\n", - "import os\n", - "\n", - "wb = GridWorkBench(case_path)\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Export Data to CSV\n", - "\n", - "Generate a custom report using PowerWorld's built-in export capability and save bus data to CSV:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "\n", - "report_path = os.path.abspath(\"system_health_report.csv\")\n", - "wb.esa.SaveDataWithExtra(\n", - " filename=report_path,\n", - " filetype=\"CSVCOLHEADER\",\n", - " objecttype=\"Bus\",\n", - " fieldlist=[\"BusNum\", \"BusName\", \"BusPUVolt\", \"BusAngle\"],\n", - " header_list=[\"Report_Generated_By\"],\n", - " header_value_list=[\"ESAplus\"]\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Export Data to Excel\n", - "\n", - "Use the advanced Excel export functionality to write branch loading data directly to a new Excel workbook with a custom worksheet name:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fieldlist = [\"BusNum\", \"BusNum:1\", \"LineCircuit\", \"LineMVA\", \"LineLimit\", \"LinePercent\"]\n", - "\n", - "excel_path = os.path.abspath(\"branch_loading_report.xlsx\")\n", - "wb.esa.SendToExcelAdvanced(\n", - " objecttype=\"Branch\",\n", - " fieldlist=fieldlist,\n", - " filter_name=\"\",\n", - " worksheet=\"Branch Loading Report\",\n", - " workbook=excel_path\n", - ")" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "esaplus", - "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.11.14" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/docs/examples/07_network_expansion.ipynb b/docs/examples/07_network_expansion.ipynb deleted file mode 100644 index 741e5e38..00000000 --- a/docs/examples/07_network_expansion.ipynb +++ /dev/null @@ -1,249 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Network Expansion and Topology Modification\n", - "\n", - "Demonstrates how to programmatically modify system topology by tapping existing lines and splitting buses. This is essential for planning studies where new substations or interconnections are evaluated." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Import the case and instantiate the `GridWorkBench`.\n", - "\n", - "```python\n", - "from esapp import GridWorkBench\n", - "from esapp.grid import *\n", - "from esapp.saw._helpers import create_object_string\n", - "\n", - "wb = GridWorkBench(case_path)\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "tags": [ - "hide-input" - ] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "'open' took: 2.8668 sec\n" - ] - } - ], - "source": [ - "# This cell is hidden in the documentation.\n", - "# It performs the actual case loading for the example.\n", - "from esapp import GridWorkBench\n", - "from esapp.grid import *\n", - "from esapp.saw._helpers import create_object_string\n", - "import ast\n", - "\n", - "with open('case.txt', 'r') as f:\n", - " case_path = ast.literal_eval(f.read().strip())\n", - "\n", - "wb = GridWorkBench(case_path)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Tap Existing Transmission Lines\n", - "\n", - "Select a branch to tap and insert a new bus at the midpoint. First, identify the branch parameters:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "from esapp.saw._helpers import create_object_string\n", - "\n", - "branches = wb[Branch]\n", - "b = branches.iloc[10]\n", - "tobus = b['BusNum']\n", - "frombus = b['BusNum:1']\n", - "circuit = b['LineCircuit']\n", - "branch_str = create_object_string(\"Branch\", tobus, frombus, circuit)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Tap the transmission line at 50% of its length and create a new bus at the tap point:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "ename": "PowerWorldError", - "evalue": "RunScriptCommand: Error in script statements definition: Error: invalid identifier character found: \"\n\".", - "output_type": "error", - "traceback": [ - "\u001b[31m---------------------------------------------------------------------------\u001b[39m", - "\u001b[31mPowerWorldError\u001b[39m Traceback (most recent call last)", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[3]\u001b[39m\u001b[32m, line 3\u001b[39m\n\u001b[32m 1\u001b[39m new_bus_num = wb[Bus, \u001b[33m\"\u001b[39m\u001b[33mBusNum\u001b[39m\u001b[33m\"\u001b[39m].max() + \u001b[32m100\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m3\u001b[39m \u001b[43mwb\u001b[49m\u001b[43m.\u001b[49m\u001b[43mesa\u001b[49m\u001b[43m.\u001b[49m\u001b[43mTapTransmissionLine\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 4\u001b[39m \u001b[43m \u001b[49m\u001b[43mbranch_str\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\n\u001b[32m 5\u001b[39m \u001b[43m \u001b[49m\u001b[32;43m50.0\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;66;43;03m# 50% down the line\u001b[39;49;00m\n\u001b[32m 6\u001b[39m \u001b[43m \u001b[49m\u001b[43mnew_bus_num\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 7\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mCAPACITANCE\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;66;43;03m# Shunt model type\u001b[39;49;00m\n\u001b[32m 8\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\n\u001b[32m 9\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mTapped_Substation\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\n\u001b[32m 10\u001b[39m \u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m~\\Documents\\GitHub\\ESAplus\\esapp\\saw\\modify.py:875\u001b[39m, in \u001b[36mModifyMixin.TapTransmissionLine\u001b[39m\u001b[34m(self, element, pos_along_line, new_bus_number, shunt_model, treat_as_ms_line, update_onelines, new_bus_name)\u001b[39m\n\u001b[32m 873\u001b[39m ms = \u001b[33m\"\u001b[39m\u001b[33mYES\u001b[39m\u001b[33m\"\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m treat_as_ms_line \u001b[38;5;28;01melse\u001b[39;00m \u001b[33m\"\u001b[39m\u001b[33mNO\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 874\u001b[39m uo = \u001b[33m\"\u001b[39m\u001b[33mYES\u001b[39m\u001b[33m\"\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m update_onelines \u001b[38;5;28;01melse\u001b[39;00m \u001b[33m\"\u001b[39m\u001b[33mNO\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m--> \u001b[39m\u001b[32m875\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mRunScriptCommand\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 876\u001b[39m \u001b[43m \u001b[49m\u001b[33;43mf\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mTapTransmissionLine(\u001b[39;49m\u001b[38;5;132;43;01m{\u001b[39;49;00m\u001b[43melement\u001b[49m\u001b[38;5;132;43;01m}\u001b[39;49;00m\u001b[33;43m, \u001b[39;49m\u001b[38;5;132;43;01m{\u001b[39;49;00m\u001b[43mpos_along_line\u001b[49m\u001b[38;5;132;43;01m}\u001b[39;49;00m\u001b[33;43m, \u001b[39;49m\u001b[38;5;132;43;01m{\u001b[39;49;00m\u001b[43mnew_bus_number\u001b[49m\u001b[38;5;132;43;01m}\u001b[39;49;00m\u001b[33;43m, \u001b[39;49m\u001b[38;5;132;43;01m{\u001b[39;49;00m\u001b[43mshunt_model\u001b[49m\u001b[38;5;132;43;01m}\u001b[39;49;00m\u001b[33;43m, \u001b[39;49m\u001b[38;5;132;43;01m{\u001b[39;49;00m\u001b[43mms\u001b[49m\u001b[38;5;132;43;01m}\u001b[39;49;00m\u001b[33;43m, \u001b[39;49m\u001b[38;5;132;43;01m{\u001b[39;49;00m\u001b[43muo\u001b[49m\u001b[38;5;132;43;01m}\u001b[39;49;00m\u001b[33;43m, \u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[38;5;132;43;01m{\u001b[39;49;00m\u001b[43mnew_bus_name\u001b[49m\u001b[38;5;132;43;01m}\u001b[39;49;00m\u001b[33;43m\"\u001b[39;49m\u001b[33;43m);\u001b[39;49m\u001b[33;43m'\u001b[39;49m\n\u001b[32m 877\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m~\\Documents\\GitHub\\ESAplus\\esapp\\saw\\base.py:1160\u001b[39m, in \u001b[36mSAWBase.RunScriptCommand\u001b[39m\u001b[34m(self, Statements)\u001b[39m\n\u001b[32m 1142\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mRunScriptCommand\u001b[39m(\u001b[38;5;28mself\u001b[39m, Statements):\n\u001b[32m 1143\u001b[39m \u001b[38;5;250m \u001b[39m\u001b[33;03m\"\"\"Executes one or more PowerWorld script statements.\u001b[39;00m\n\u001b[32m 1144\u001b[39m \n\u001b[32m 1145\u001b[39m \u001b[33;03m Parameters\u001b[39;00m\n\u001b[32m (...)\u001b[39m\u001b[32m 1158\u001b[39m \u001b[33;03m If any of the script commands fail.\u001b[39;00m\n\u001b[32m 1159\u001b[39m \u001b[33;03m \"\"\"\u001b[39;00m\n\u001b[32m-> \u001b[39m\u001b[32m1160\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_call_simauto\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mRunScriptCommand\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mStatements\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m~\\Documents\\GitHub\\ESAplus\\esapp\\saw\\base.py:1353\u001b[39m, in \u001b[36mSAWBase._call_simauto\u001b[39m\u001b[34m(self, func, *args)\u001b[39m\n\u001b[32m 1351\u001b[39m \u001b[38;5;28;01mpass\u001b[39;00m\n\u001b[32m 1352\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[33m\"\u001b[39m\u001b[33mNo data\u001b[39m\u001b[33m\"\u001b[39m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m output[\u001b[32m0\u001b[39m]:\n\u001b[32m-> \u001b[39m\u001b[32m1353\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m PowerWorldError.from_message(output[\u001b[32m0\u001b[39m])\n\u001b[32m 1354\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[32m 1355\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[33m\"\u001b[39m\u001b[33mis not subscriptable\u001b[39m\u001b[33m\"\u001b[39m \u001b[38;5;129;01min\u001b[39;00m e.args[\u001b[32m0\u001b[39m]:\n", - "\u001b[31mPowerWorldError\u001b[39m: RunScriptCommand: Error in script statements definition: Error: invalid identifier character found: \"\n\"." - ] - } - ], - "source": [ - "new_bus_num = wb[Bus, \"BusNum\"].max() + 100\n", - "\n", - "wb.esa.TapTransmissionLine(\n", - " branch_str, \n", - " 50.0, # 50% down the line\n", - " new_bus_num,\n", - " \"CAPACITANCE\", # Shunt model type\n", - " False, False, \n", - " \"Tapped_Substation\"\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Split a Bus\n", - "\n", - "Split an existing bus into two buses connected by a tie-line:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Split Bus 1 to create Bus 138\n" - ] - } - ], - "source": [ - "target_bus = 1\n", - "split_bus_num = wb[Bus, 'BusNum'].max() + 1\n", - "\n", - "wb.esa.SplitBus(\n", - " create_object_string(\"Bus\", target_bus), \n", - " split_bus_num, \n", - " insert_tie=True, \n", - " line_open=False, \n", - " branch_device_type=\"Breaker\"\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Validate Network Changes\n", - "\n", - "After modifying the network topology, validate the changes by solving the power flow on the modified system:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 0.993355-0.019419j\n", - "1 0.988897-0.067891j\n", - "2 0.981193-0.081206j\n", - "3 0.973882-0.097994j\n", - "4 0.988339-0.035719j\n", - "5 0.976643-0.094524j\n", - "6 0.975783-0.096903j\n", - "7 0.973776-0.097237j\n", - "8 0.985792-0.043874j\n", - "9 0.976172-0.096608j\n", - "10 0.968600-0.110751j\n", - "11 0.971614-0.105523j\n", - "12 0.973420-0.103939j\n", - "13 0.982291-0.053822j\n", - "14 0.973217-0.102800j\n", - "15 0.975958-0.110438j\n", - "16 0.968262-0.118577j\n", - "17 0.968432-0.120988j\n", - "18 0.989440-0.060763j\n", - "19 0.989079-0.033916j\n", - "20 0.975803-0.089976j\n", - "21 0.996289-0.014687j\n", - "22 0.999325-0.036749j\n", - "23 0.991324-0.064225j\n", - "24 0.996572-0.009197j\n", - "25 0.993144-0.062429j\n", - "26 1.003133+0.023863j\n", - "27 0.999992+0.004085j\n", - "28 0.995382-0.001690j\n", - "29 0.995771-0.007340j\n", - "30 0.994545-0.036499j\n", - "31 0.990953-0.022854j\n", - "32 0.994241-0.052982j\n", - "33 0.999338-0.036369j\n", - "34 0.999978+0.006569j\n", - "35 0.994644-0.061972j\n", - "36 0.999990+0.004388j\n", - "37 0.981414-0.082958j\n", - "38 0.993355-0.019419j\n", - "dtype: complex128" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "V = wb.pflow()\n", - "V.tail()" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "esaplus", - "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.11.14" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/docs/examples/08_scopf_analysis.ipynb b/docs/examples/08_scopf_analysis.ipynb deleted file mode 100644 index c3d3dbb1..00000000 --- a/docs/examples/08_scopf_analysis.ipynb +++ /dev/null @@ -1,177 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Security Constrained OPF (SCOPF)\n", - "\n", - "Finds least-cost dispatch satisfying base-case and N-1 constraints." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Import the case and instantiate the `GridWorkBench`.\n", - "\n", - "```python\n", - "from esapp import GridWorkBench\n", - "from esapp.grid import *\n", - "\n", - "wb = GridWorkBench(case_path)\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "tags": [ - "hide-input" - ] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "'open' took: 3.0936 sec\n" - ] - } - ], - "source": [ - "# This cell is hidden in the documentation.\n", - "# It performs the actual case loading for the example.\n", - "from esapp import GridWorkBench\n", - "from esapp.grid import *\n", - "import ast\n", - "\n", - "with open('case.txt', 'r') as f:\n", - " case_path = ast.literal_eval(f.read().strip())\n", - "\n", - "wb = GridWorkBench(case_path)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Setup SCOPF Optimization\n", - "\n", - "Initialize the solver and prepare contingency constraints for the security-constrained problem:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The Primal LP solver is PowerWorld's optimization engine. Auto-insert N-1 contingencies to make the optimization security-constrained:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "wb.esa.InitializePrimalLP()\n", - "wb.auto_insert_contingencies()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Solve SCOPF\n", - "\n", - "Execute the security-constrained optimization to minimize generation cost while satisfying all contingency constraints:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The SCOPF finds the least-cost generation dispatch that maintains feasibility under all contingency scenarios:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
AreaNumGenProdCost
014186.802154
\n", - "
" - ], - "text/plain": [ - " AreaNum GenProdCost\n", - "0 1 4186.802154" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "wb.esa.SolveFullSCOPF()\n", - "\n", - "production_cost = wb[Area, \"GenProdCost\"]\n", - "production_cost" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "esaplus", - "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.11.14" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/docs/examples/09_atc_analysis.ipynb b/docs/examples/09_atc_analysis.ipynb deleted file mode 100644 index 299fb292..00000000 --- a/docs/examples/09_atc_analysis.ipynb +++ /dev/null @@ -1,111 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Available Transfer Capability (ATC) Studies\n", - "\n", - "Determining the maximum power that can be transferred between two areas without violating system limits, considering N-1 contingencies." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Import the case and instantiate the `GridWorkBench`.\n", - "\n", - "```python\n", - "from esapp import GridWorkBench\n", - "from esapp.grid import *\n", - "from esapp.saw._helpers import create_object_string\n", - "\n", - "wb = GridWorkBench(case_path)\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "tags": [ - "hide-input" - ] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "'open' took: 3.0197 sec\n" - ] - } - ], - "source": [ - "# This cell is hidden in the documentation.\n", - "# It performs the actual case loading for the example.\n", - "from esapp import GridWorkBench\n", - "from esapp.grid import *\n", - "from esapp.saw._helpers import create_object_string\n", - "import ast\n", - "\n", - "with open('case.txt', 'r') as f:\n", - " case_path = ast.literal_eval(f.read().strip())\n", - "\n", - "wb = GridWorkBench(case_path)" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "areas = wb[Area, ['AreaNum', 'AreaName']]\n", - "if len(areas) >= 2:\n", - " seller = create_object_string(\"Area\", areas.iloc[0]['AreaNum'])\n", - " buyer = create_object_string(\"Area\", areas.iloc[1]['AreaNum'])\n", - " \n", - " wb.esa.SetData(\"ATC_Options\", [\"Method\"], [\"IteratedLinearThenFull\"])\n", - " wb.esa.DetermineATC(seller, buyer, do_distributed=False, do_multiple_scenarios=False)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "results = wb.esa.GetATCResults([\"MaxFlow\", \"LimitingContingency\", \"LimitingElement\"])\n", - "\n", - "if results is not None and not results.empty:\n", - " atc_results = results.iloc[0]\n", - " atc_val = atc_results['MaxFlow']\n", - " limit_ctg = atc_results['LimitingContingency']\n", - " limit_el = atc_results['LimitingElement']\n", - " atc_results" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "esaplus", - "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.11.14" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/docs/examples/case.txt b/docs/examples/case.txt deleted file mode 100644 index a14264c4..00000000 --- a/docs/examples/case.txt +++ /dev/null @@ -1 +0,0 @@ -r"C:\Users\wyattluke.lowery\OneDrive - Texas A&M University\Research\Cases\Hawaii 37\Hawaii40_20231026.pwb" \ No newline at end of file diff --git a/docs/examples/examples.rst b/docs/examples/examples.rst deleted file mode 100644 index 5332db61..00000000 --- a/docs/examples/examples.rst +++ /dev/null @@ -1,17 +0,0 @@ -Examples -======== - -This section provides a gallery of examples for common use cases of ESA++. - -.. toctree:: - :maxdepth: 1 - - 01_basic_data_access.ipynb - 02_power_flow_analysis.ipynb - 03_contingency_analysis.ipynb - 04_gic_analysis.ipynb - 05_matrix_extraction.ipynb - 06_exporting.ipynb - 07_network_expansion.ipynb - 08_scopf_analysis.ipynb - 09_atc_analysis.ipynb diff --git a/docs/examples/getting_started/01_reading_data.ipynb b/docs/examples/getting_started/01_reading_data.ipynb new file mode 100644 index 00000000..3d8b42ba --- /dev/null +++ b/docs/examples/getting_started/01_reading_data.ipynb @@ -0,0 +1,622 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "title", + "metadata": {}, + "source": [ + "# Reading Data\n", + "\n", + "ESA++ uses an **indexable interface** to read grid data using Python's\n", + "bracket notation. The idea is simple: pass a component type (like `Bus`\n", + "or `Gen`) and optionally a field name, and you get back a pandas\n", + "DataFrame. Primary-key columns are always included automatically so\n", + "you can join or filter results without extra bookkeeping.\n", + "\n", + "```python\n", + "from esapp import PowerWorld\n", + "from esapp.components import *\n", + "\n", + "pw = PowerWorld(\"path/to/case.pwb\")\n", + "```\n", + "\n", + "Importing `*` from `esapp.components` brings in all component types\n", + "(`Bus`, `Gen`, `Load`, `Branch`, `Shunt`, `Area`, `Zone`, etc.) so\n", + "they're available directly in your code." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "hidden-setup", + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "'open' took: 11.9927 sec\n" + ] + } + ], + "source": [ + "from esapp import PowerWorld\n", + "from esapp.components import *\n", + "import numpy as np\n", + "import pandas as pd\n", + "import ast\n", + "\n", + "with open('../../../examples/data/case.txt', 'r') as f:\n", + " case_path = ast.literal_eval(f.read().strip())\n", + "\n", + "pw = PowerWorld(case_path)" + ] + }, + { + "cell_type": "markdown", + "id": "patterns-md", + "metadata": {}, + "source": [ + "## Read Patterns\n", + "\n", + "There are four ways to read data, ranging from just the keys to\n", + "every available field:\n", + "\n", + "| Syntax | Returns |\n", + "|---|---|\n", + "| `pw[Bus]` | Key columns only (e.g. `BusNum`) |\n", + "| `pw[Bus, \"BusPUVolt\"]` | Keys + one field |\n", + "| `pw[Bus, [\"BusPUVolt\", \"BusAngle\"]]` | Keys + multiple fields |\n", + "| `pw[Bus, :]` | Keys + **every** defined field |\n", + "\n", + "Let's walk through each one." + ] + }, + { + "cell_type": "markdown", + "id": "keys-md", + "metadata": {}, + "source": [ + "Passing just the component type returns its primary-key columns.\n", + "Buses have a single key (`BusNum`); generators have a compound key\n", + "(`BusNum`, `GenID`)." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "keys-bus", + "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", + "
BusNum
01
12
23
34
45
\n", + "
" + ], + "text/plain": [ + " BusNum\n", + "0 1\n", + "1 2\n", + "2 3\n", + "3 4\n", + "4 5" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pw[Bus].head()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "keys-gen", + "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", + "
BusNumGenID
021
122
223
324
4231
\n", + "
" + ], + "text/plain": [ + " BusNum GenID\n", + "0 2 1\n", + "1 2 2\n", + "2 2 3\n", + "3 2 4\n", + "4 23 1" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pw[Gen].head()" + ] + }, + { + "cell_type": "markdown", + "id": "single-md", + "metadata": {}, + "source": [ + "Adding a field name retrieves that column alongside the keys. You\n", + "can pass a single string or a list of strings for multiple columns.\n", + "Field names can also be specified as component enum attributes\n", + "(e.g. `Bus.BusPUVolt`) for IDE autocomplete and typo protection." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "single", + "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", + "
BusNumBusPUVolt
010.993545
120.991225
230.984548
340.978800
450.988985
\n", + "
" + ], + "text/plain": [ + " BusNum BusPUVolt\n", + "0 1 0.993545\n", + "1 2 0.991225\n", + "2 3 0.984548\n", + "3 4 0.978800\n", + "4 5 0.988985" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pw[Bus, \"BusPUVolt\"].head()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "multi", + "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", + "
BusNumGenIDGenMVRGenMWGenStatus
0210.800002.500000Closed
1220.800002.500000Closed
2230.800002.500000Closed
3240.800002.500000Closed
42310.0440869.274741Closed
\n", + "
" + ], + "text/plain": [ + " BusNum GenID GenMVR GenMW GenStatus\n", + "0 2 1 0.80000 2.500000 Closed\n", + "1 2 2 0.80000 2.500000 Closed\n", + "2 2 3 0.80000 2.500000 Closed\n", + "3 2 4 0.80000 2.500000 Closed\n", + "4 23 1 0.04408 69.274741 Closed" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pw[Gen, [\"GenMW\", \"GenMVR\", \"GenStatus\"]].head()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "enum", + "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", + "
BusAngleBusNameBusNumBusPUVolt
0-1.119907ALOHA13810.993545
1-3.927372ALOHA6920.991225
2-4.731145FLOWER6930.984548
3-5.745870WAVE6940.978800
4-2.069792HONOLULU13850.988985
\n", + "
" + ], + "text/plain": [ + " BusAngle BusName BusNum BusPUVolt\n", + "0 -1.119907 ALOHA138 1 0.993545\n", + "1 -3.927372 ALOHA69 2 0.991225\n", + "2 -4.731145 FLOWER69 3 0.984548\n", + "3 -5.745870 WAVE69 4 0.978800\n", + "4 -2.069792 HONOLULU138 5 0.988985" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Same query using enum attributes instead of strings:\n", + "pw[Bus, [Bus.BusName, Bus.BusPUVolt, Bus.BusAngle]].head()" + ] + }, + { + "cell_type": "markdown", + "id": "all-md", + "metadata": {}, + "source": [ + "The slice syntax `pw[Bus, :]` retrieves every defined field at once.\n", + "This is handy for exploration, though it can produce wide DataFrames." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "all-fields", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(37, 581)" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pw[Bus, :].shape" + ] + }, + { + "cell_type": "markdown", + "id": "pandas-md", + "metadata": {}, + "source": [ + "## Working with Results\n", + "\n", + "Every result is a standard pandas DataFrame, so all the usual\n", + "filtering, grouping, and aggregation operations work directly.\n", + "There's no need to convert or reshape anything before using pandas\n", + "tools you already know." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "filter", + "metadata": {}, + "outputs": [], + "source": [ + "# Filter generators by status\n", + "gens = pw[Gen, [\"GenMW\", \"GenMVR\", \"GenStatus\"]]\n", + "online = gens[gens[\"GenStatus\"] == \"Closed\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "agg", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "LoadMW 1136.290004\n", + "LoadMVR 0.000000\n", + "dtype: float64" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Aggregate load totals\n", + "loads = pw[Load, [\"LoadMW\", \"LoadMVR\"]]\n", + "loads[[\"LoadMW\", \"LoadMVR\"]].sum()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "esapp", + "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.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/examples/getting_started/02_writing_data.ipynb b/docs/examples/getting_started/02_writing_data.ipynb new file mode 100644 index 00000000..d5d4b909 --- /dev/null +++ b/docs/examples/getting_started/02_writing_data.ipynb @@ -0,0 +1,206 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "title", + "metadata": {}, + "source": [ + "# Writing Data\n", + "\n", + "The same bracket syntax used for reading also supports writes.\n", + "Assignments are sent to PowerWorld immediately — there's no\n", + "intermediate buffer or commit step. This makes it straightforward\n", + "to script parameter sweeps, contingency setups, or any other\n", + "case modification workflow.\n", + "\n", + "```python\n", + "from esapp import PowerWorld\n", + "from esapp.components import *\n", + "\n", + "pw = PowerWorld(\"path/to/case.pwb\")\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "hidden-setup", + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "'open' took: 14.8907 sec\n" + ] + } + ], + "source": [ + "from esapp import PowerWorld\n", + "from esapp.components import *\n", + "import numpy as np\n", + "import pandas as pd\n", + "import ast\n", + "\n", + "with open('../../../examples/data/case.txt', 'r') as f:\n", + " case_path = ast.literal_eval(f.read().strip())\n", + "\n", + "pw = PowerWorld(case_path)" + ] + }, + { + "cell_type": "markdown", + "id": "patterns-md", + "metadata": {}, + "source": [ + "## Write Patterns\n", + "\n", + "There are four write patterns, each useful in different situations:\n", + "\n", + "| Syntax | Behavior |\n", + "|---|---|\n", + "| `pw[Gen, \"GenMW\"] = 100.0` | Broadcast a **scalar** to every object |\n", + "| `pw[Gen, \"GenMW\"] = [100, 150, ...]` | Set **per-element** values (length must match) |\n", + "| `pw[Gen, [\"GenMW\", \"GenStatus\"]] = [100, \"Closed\"]` | Broadcast to **multiple fields** at once |\n", + "| `pw[Bus] = df` | **Bulk update** from a DataFrame (must include key columns) |\n", + "\n", + "Let's look at each one." + ] + }, + { + "cell_type": "markdown", + "id": "scalar-md", + "metadata": {}, + "source": [ + "**Scalar broadcast** applies a single value to every object of that type.\n", + "This is useful for resetting all generators to the same output, for example." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "scalar", + "metadata": {}, + "outputs": [], + "source": [ + "pw[Gen, \"GenMW\"] = 100.0" + ] + }, + { + "cell_type": "markdown", + "id": "array-md", + "metadata": {}, + "source": [ + "**Per-element values** — a list or array whose length matches the number\n", + "of objects sets each one individually." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "array", + "metadata": {}, + "outputs": [], + "source": [ + "pw[Gen, \"GenMW\"] = np.linspace(50, 200, len(pw[Gen]))" + ] + }, + { + "cell_type": "markdown", + "id": "multifield-md", + "metadata": {}, + "source": [ + "**Multiple fields** — pass a list of field names and a matching list\n", + "of values to set several columns at once." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "multifield", + "metadata": {}, + "outputs": [], + "source": [ + "pw[Gen, [\"GenMW\", \"GenStatus\"]] = [100.0, \"Closed\"]" + ] + }, + { + "cell_type": "markdown", + "id": "df-md", + "metadata": {}, + "source": [ + "## DataFrame Updates\n", + "\n", + "For targeted updates to specific objects, build a DataFrame that\n", + "includes the primary-key columns and the fields you want to change.\n", + "Only the rows present in the DataFrame are modified — everything\n", + "else stays untouched." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "df-write", + "metadata": {}, + "outputs": [], + "source": [ + "updates = pd.DataFrame({\n", + " \"BusNum\": pw[Bus][\"BusNum\"].head(3),\n", + " \"BusPUVolt\": [1.02, 1.01, 0.99]\n", + "})\n", + "pw[Bus] = updates" + ] + }, + { + "cell_type": "markdown", + "id": "rmw-md", + "metadata": {}, + "source": [ + "## Read-Modify-Write\n", + "\n", + "A common workflow is to read existing values, transform them in\n", + "pandas, and write the result back. This is the natural way to do\n", + "things like scaling loads, adjusting setpoints, or applying any\n", + "vectorized transformation. Here we scale all loads by 10%." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "rmw", + "metadata": {}, + "outputs": [], + "source": [ + "loads = pw[Load, [\"LoadMW\", \"LoadMVR\"]]\n", + "loads[\"LoadMW\"] *= 1.10\n", + "loads[\"LoadMVR\"] *= 1.10\n", + "pw[Load] = loads" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "esapp", + "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.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/examples/getting_started/03_components_and_fields.ipynb b/docs/examples/getting_started/03_components_and_fields.ipynb new file mode 100644 index 00000000..c841c2d9 --- /dev/null +++ b/docs/examples/getting_started/03_components_and_fields.ipynb @@ -0,0 +1,242 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "title", + "metadata": {}, + "source": [ + "# Components & Fields\n", + "\n", + "Every PowerWorld object type is represented by a **component class**\n", + "(e.g. `Bus`, `Gen`, `Branch`). These classes carry metadata about\n", + "their fields — which ones are primary keys, which are editable,\n", + "and what the full set of available columns looks like. This metadata\n", + "drives the indexable interface and provides IDE autocomplete.\n", + "\n", + "The `TS` class provides constants for transient stability result\n", + "fields, organized by object type.\n", + "\n", + "```python\n", + "from esapp.components import *\n", + "from esapp import TS\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "hidden-setup", + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [], + "source": [ + "from esapp.components import *\n", + "from esapp import TS\n", + "from esapp.components import TSField" + ] + }, + { + "cell_type": "markdown", + "id": "keys-md", + "metadata": {}, + "source": [ + "## Keys and Field Categories\n", + "\n", + "Primary keys uniquely identify an object in PowerWorld. They're\n", + "always included in query results and required when writing a\n", + "DataFrame back. Different object types have different key\n", + "structures:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "keys", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(['BusNum'],\n", + " ['BusNum', 'GenID'],\n", + " ['BusName_NomVolt:1', 'BusNum', 'LineCircuit', 'BusNum:1'])" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Bus.keys, Gen.keys, Branch.keys" + ] + }, + { + "cell_type": "markdown", + "id": "identifiers-md", + "metadata": {}, + "source": [ + "Beyond primary keys, each component has several field categories:\n", + "\n", + "- **Identifiers** — the union of primary and secondary keys (like\n", + " `BusName` or `AreaNum`). Secondary keys help PowerWorld resolve\n", + " which object you mean during writes.\n", + "- **Editable** — fields you can modify (generation setpoints, voltage\n", + " targets, load values, etc.). Writing to a read-only field raises\n", + " a `ValueError`.\n", + "- **Settable** — identifiers plus editable fields, i.e. everything\n", + " allowed in a write operation.\n", + "- **Fields** — the complete set of all known fields, including\n", + " read-only calculated results." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "identifiers", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'AreaNum', 'BusName', 'BusName_NomVolt', 'BusNomVolt', 'BusNum', 'ZoneNum'}" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Bus.identifiers" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "counts", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(111, 113, 581)" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(Bus.editable), len(Bus.settable), len(Bus.fields)" + ] + }, + { + "cell_type": "markdown", + "id": "ts-md", + "metadata": {}, + "source": [ + "## Transient Stability Fields\n", + "\n", + "The `TS` class provides constants for transient stability result\n", + "fields, organized by object type — `TS.Gen`, `TS.Bus`, `TS.Branch`,\n", + "`TS.Load`, etc. Each field is a `TSField` with a `name` and\n", + "`description`. Typing `TS.Gen.` in your IDE autocompletes every\n", + "available generator result field.\n", + "\n", + "Some fields are indexed (e.g. multiple input signals on a bus).\n", + "Use bracket notation like `TS.Bus.Input[1]` to create the indexed\n", + "variant. Use `dir()` to list all available fields for a given\n", + "object type." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "ts-fields", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(TSField('TSGenP'), TSField('TSGenQ'), TSField('TSGenDelta'))" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "TS.Gen.P, TS.Gen.Q, TS.Gen.Delta" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "ts-desc", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Rotor Angle relative to angle reference (degrees)'" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "TS.Gen.Delta.description" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "ts-indexed", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(TSField('TSBusInput:1'), TSField('TSBusInput:2'))" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "TS.Bus.Input[1], TS.Bus.Input[2]" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "esapp", + "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.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/examples/getting_started/04_creating_objects.ipynb b/docs/examples/getting_started/04_creating_objects.ipynb new file mode 100644 index 00000000..f34f2d7c --- /dev/null +++ b/docs/examples/getting_started/04_creating_objects.ipynb @@ -0,0 +1,507 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "title", + "metadata": {}, + "source": [ + "# Creating Objects\n", + "\n", + "The same bracket-write syntax used for modifying existing data can\n", + "also **create new objects** in PowerWorld. When you assign a\n", + "DataFrame containing primary keys that don't match any existing\n", + "objects, ESA++ automatically falls back to a row-by-row insertion\n", + "path that creates them.\n", + "\n", + "This is the primary way to programmatically add buses, generators,\n", + "loads, branches, and any other PowerWorld object type from Python.\n", + "\n", + "```python\n", + "from esapp import PowerWorld\n", + "from esapp.components import *\n", + "\n", + "pw = PowerWorld(\"path/to/case.pwb\")\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "hidden-setup", + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "'open' took: 13.2343 sec\n" + ] + } + ], + "source": [ + "from esapp import PowerWorld\n", + "from esapp.components import *\n", + "import pandas as pd\n", + "import ast\n", + "\n", + "with open('../../../examples/data/case.txt', 'r') as f:\n", + " case_path = ast.literal_eval(f.read().strip())\n", + "\n", + "pw = PowerWorld(case_path)" + ] + }, + { + "cell_type": "markdown", + "id": "prereqs-md", + "metadata": {}, + "source": [ + "## Prerequisites\n", + "\n", + "PowerWorld must be in **EDIT mode** before you can add new objects. Call `pw.edit_mode()` to enter it, and `pw.run_mode()` when you're done.\n", + "\n", + "The DataFrame you write should include all **identifier** fields\n", + "for the object type — that's the union of primary keys and\n", + "secondary keys. You can inspect these with `Bus.identifiers`,\n", + "`Gen.identifiers`, etc. Primary keys uniquely identify the object;\n", + "secondary keys provide the additional context PowerWorld needs to\n", + "fully define it (nominal voltage, area, zone, limits, etc.)." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "show-keys", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Bus identifiers: {'BusNum', 'BusName_NomVolt', 'BusName', 'ZoneNum', 'BusNomVolt', 'AreaNum'}\n", + "Gen identifiers: {'GenMVRMax', 'GenMvrSetPoint', 'GenID', 'GenMWSetPoint', 'GenStatus', 'GenVoltSet', 'GenMVRMin', 'GenMWMax', 'BusNum', 'GenMWMin', 'GenAGCAble', 'BusName_NomVolt', 'GenAVRAble'}\n", + "Load identifiers: {'LoadSMW', 'BusNum', 'BusName_NomVolt', 'LoadStatus', 'LoadSMVR', 'LoadID'}\n" + ] + } + ], + "source": [ + "# Identifier fields needed for creation\n", + "print(\"Bus identifiers:\", Bus.identifiers)\n", + "print(\"Gen identifiers:\", Gen.identifiers)\n", + "print(\"Load identifiers:\", Load.identifiers)" + ] + }, + { + "cell_type": "markdown", + "id": "creating-buses-md", + "metadata": {}, + "source": [ + "## Creating Buses\n", + "\n", + "Buses have a single primary key (`BusNum`) but several secondary\n", + "identifier fields that PowerWorld uses to fully define the bus.\n", + "The full set of bus identifiers is:\n", + "\n", + "- `BusNum` — bus number (primary key)\n", + "- `BusName` — bus name\n", + "- `BusNomVolt` — nominal voltage in kV\n", + "- `BusName_NomVolt` — combined name and voltage label\n", + "- `AreaNum` — area number the bus belongs to\n", + "- `ZoneNum` — zone number the bus belongs to\n", + "\n", + "Include all of these when creating buses so PowerWorld has the\n", + "complete definition." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "create-buses", + "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", + "
AreaNumBusNameBusNomVoltBusNumZoneNum
371NewBus_138138.0900011
381NewBus_230230.0900021
391NewBus_500500.0900031
\n", + "
" + ], + "text/plain": [ + " AreaNum BusName BusNomVolt BusNum ZoneNum\n", + "37 1 NewBus_138 138.0 90001 1\n", + "38 1 NewBus_230 230.0 90002 1\n", + "39 1 NewBus_500 500.0 90003 1" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Record the original bus count\n", + "n_before = pw.n_bus\n", + "\n", + "# Build a DataFrame with all identifier fields\n", + "new_buses = pd.DataFrame({\n", + " \"BusNum\": [90001, 90002, 90003],\n", + " \"BusName\": [\"NewBus_138\", \"NewBus_230\", \"NewBus_500\"],\n", + " \"BusNomVolt\": [138.0, 230.0, 500.0],\n", + " \"BusName_NomVolt\": [\"NewBus_138 138.00\", \"NewBus_230 230.00\", \"NewBus_500 500.00\"],\n", + " \"AreaNum\": [1, 1, 1],\n", + " \"ZoneNum\": [1, 1, 1],\n", + "})\n", + "\n", + "# Enter edit mode, create the buses, return to run mode\n", + "pw.edit_mode()\n", + "pw[Bus] = new_buses\n", + "pw.run_mode()\n", + "\n", + "# Verify they exist\n", + "assert pw.n_bus == n_before + 3\n", + "created = pw[Bus, [\"BusName\", \"BusNomVolt\", \"AreaNum\", \"ZoneNum\"]]\n", + "created[created[\"BusNum\"].isin([90001, 90002, 90003])]" + ] + }, + { + "cell_type": "markdown", + "id": "creating-gens-md", + "metadata": {}, + "source": [ + "## Creating Generators\n", + "\n", + "Generators have a compound primary key (`BusNum` + `GenID`) and\n", + "a larger set of secondary identifiers that define their operating\n", + "characteristics. The bus must already exist. The full set of\n", + "generator identifiers includes:\n", + "\n", + "- `BusNum`, `GenID` — primary keys\n", + "- `BusName_NomVolt` — bus label\n", + "- `GenMWSetPoint`, `GenMWMax`, `GenMWMin` — MW output and limits\n", + "- `GenMvrSetPoint`, `GenMVRMax`, `GenMVRMin` — Mvar setpoint and limits\n", + "- `GenVoltSet` — voltage setpoint (pu)\n", + "- `GenStatus` — \"Open\" or \"Closed\"\n", + "- `GenAGCAble`, `GenAVRAble` — AGC/AVR availability (\"YES\"/\"NO\")" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "create-gens", + "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", + "
BusNumGenIDGenMWMaxGenMWSetPointGenStatus
45900011200.0100.0Closed
46900021500.0250.0Closed
\n", + "
" + ], + "text/plain": [ + " BusNum GenID GenMWMax GenMWSetPoint GenStatus\n", + "45 90001 1 200.0 100.0 Closed\n", + "46 90002 1 500.0 250.0 Closed" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "n_gen_before = pw.n_gen\n", + "\n", + "new_gens = pd.DataFrame({\n", + " \"BusNum\": [90001, 90002],\n", + " \"GenID\": [\"1\", \"1\"],\n", + " \"BusName_NomVolt\": [\"NewBus_138 138.00\", \"NewBus_230 230.00\"],\n", + " \"GenMWSetPoint\": [100.0, 250.0],\n", + " \"GenMWMax\": [200.0, 500.0],\n", + " \"GenMWMin\": [0.0, 50.0],\n", + " \"GenMvrSetPoint\": [0.0, 0.0],\n", + " \"GenMVRMax\": [100.0, 200.0],\n", + " \"GenMVRMin\": [-50.0, -100.0],\n", + " \"GenVoltSet\": [1.0, 1.0],\n", + " \"GenStatus\": [\"Closed\", \"Closed\"],\n", + " \"GenAGCAble\": [\"YES\", \"YES\"],\n", + " \"GenAVRAble\": [\"YES\", \"YES\"],\n", + "})\n", + "\n", + "pw.edit_mode()\n", + "pw[Gen] = new_gens\n", + "pw.run_mode()\n", + "\n", + "assert pw.n_gen == n_gen_before + 2\n", + "gens = pw[Gen, [\"GenMWSetPoint\", \"GenMWMax\", \"GenStatus\"]]\n", + "gens[gens[\"BusNum\"].isin([90001, 90002])]" + ] + }, + { + "cell_type": "markdown", + "id": "creating-loads-md", + "metadata": {}, + "source": [ + "## Creating Loads\n", + "\n", + "Loads follow the same pattern with primary keys `BusNum` and\n", + "`LoadID`. Their secondary identifiers define the constant-power\n", + "MW and Mvar components and status:\n", + "\n", + "- `BusNum`, `LoadID` — primary keys\n", + "- `BusName_NomVolt` — bus label\n", + "- `LoadSMW` — constant-power MW\n", + "- `LoadSMVR` — constant-power Mvar\n", + "- `LoadStatus` — \"Open\" or \"Closed\"" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "create-loads", + "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", + "
BusNumLoadIDLoadSMVRLoadSMWLoadStatus
2790002120.00000075.0Closed
2890003140.000001150.0Closed
\n", + "
" + ], + "text/plain": [ + " BusNum LoadID LoadSMVR LoadSMW LoadStatus\n", + "27 90002 1 20.000000 75.0 Closed\n", + "28 90003 1 40.000001 150.0 Closed" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "new_loads = pd.DataFrame({\n", + " \"BusNum\": [90002, 90003],\n", + " \"LoadID\": [\"1\", \"1\"],\n", + " \"BusName_NomVolt\": [\"NewBus_230 230.00\", \"NewBus_500 500.00\"],\n", + " \"LoadSMW\": [75.0, 150.0],\n", + " \"LoadSMVR\": [20.0, 40.0],\n", + " \"LoadStatus\": [\"Closed\", \"Closed\"],\n", + "})\n", + "\n", + "pw.edit_mode()\n", + "pw[Load] = new_loads\n", + "pw.run_mode()\n", + "\n", + "loads = pw[Load, [\"LoadSMW\", \"LoadSMVR\", \"LoadStatus\"]]\n", + "loads[loads[\"BusNum\"].isin([90002, 90003])]" + ] + }, + { + "cell_type": "markdown", + "id": "how-it-works-md", + "metadata": {}, + "source": [ + "## How It Works\n", + "\n", + "Under the hood, `pw[ObjectType] = df` first tries the fast\n", + "batch-update path (`ChangeParametersMultipleElementRect`). If\n", + "PowerWorld reports that some objects were \"not found\", ESA++\n", + "checks that all primary key columns are present in the DataFrame\n", + "and falls back to a row-by-row path\n", + "(`ChangeParametersMultipleElement`) that creates missing objects.\n", + "\n", + "This means the same syntax works for both updating and creating:\n", + "\n", + "- If the objects **already exist**, their fields are updated.\n", + "- If they **don't exist**, they're created with the values you\n", + " provided.\n", + "- A **mixed** DataFrame (some rows exist, some don't) also works\n", + " — existing rows are updated and new rows are created.\n", + "\n", + "If primary keys are missing from the DataFrame, ESA++ raises a\n", + "`ValueError` immediately rather than silently failing." + ] + }, + { + "cell_type": "markdown", + "id": "tips-md", + "metadata": {}, + "source": [ + "## Tips\n", + "\n", + "- **Always enter edit mode** before creating objects and return\n", + " to run mode afterward. Forgetting this is the most common\n", + " cause of creation failures.\n", + "\n", + "- **Include all identifier fields** when creating objects. Use\n", + " `ComponentType.identifiers` to see the full set of primary and\n", + " secondary key fields. PowerWorld needs these to fully define\n", + " the object — omitting them may cause unexpected defaults or\n", + " creation failures.\n", + "\n", + "- **The broadcast syntax does not create objects.** Only the\n", + " DataFrame assignment path (`pw[Type] = df`) can create new\n", + " objects. The field-broadcast path\n", + " (`pw[Type, \"Field\"] = value`) only modifies existing ones." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "esapp", + "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.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/examples/getting_started/05_workbench_overview.ipynb b/docs/examples/getting_started/05_workbench_overview.ipynb new file mode 100644 index 00000000..39700441 --- /dev/null +++ b/docs/examples/getting_started/05_workbench_overview.ipynb @@ -0,0 +1,539 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "title", + "metadata": {}, + "source": [ + "# Workbench Quick Reference\n", + "\n", + "Beyond the indexable interface, `PowerWorld` provides convenience\n", + "methods that wrap common workflows into single calls. These cover\n", + "data retrieval shortcuts, power flow, voltage analysis, matrix\n", + "extraction, sensitivity factors, and case control — so you spend\n", + "less time assembling field lists and more time on analysis.\n", + "\n", + "```python\n", + "from esapp import PowerWorld\n", + "from esapp.components import *\n", + "\n", + "pw = PowerWorld(\"path/to/case.pwb\")\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "hidden-setup", + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "'open' took: 7.0825 sec\n" + ] + } + ], + "source": [ + "from esapp import PowerWorld\n", + "from esapp.components import *\n", + "import numpy as np\n", + "import ast\n", + "\n", + "with open('../../../examples/data/case.txt', 'r') as f:\n", + " case_path = ast.literal_eval(f.read().strip())\n", + "\n", + "pw = PowerWorld(case_path)" + ] + }, + { + "cell_type": "markdown", + "id": "shortcuts-md", + "metadata": {}, + "source": [ + "## Data Shortcuts\n", + "\n", + "These methods return DataFrames of common object types with their\n", + "most useful fields pre-selected. They're thin wrappers around the\n", + "indexable interface — `pw.gens()` is equivalent to\n", + "`pw[Gen, [\"GenMW\", \"GenMVR\", \"GenStatus\"]]` but shorter to type.\n", + "\n", + "| Method | Returns |\n", + "|---|---|\n", + "| `pw.gens()` | Generator MW, Mvar, and status |\n", + "| `pw.loads()` | Load MW, Mvar, and status |\n", + "| `pw.shunts()` | Switched shunt MW, Mvar, and status |\n", + "| `pw.lines()` | All transmission lines |\n", + "| `pw.transformers()` | All transformers |\n", + "| `pw.areas()` | All areas |\n", + "| `pw.zones()` | All zones |" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "gens", + "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", + "
BusNumGenIDGenMVRGenMWGenStatus
0210.800002.500000Closed
1220.800002.500000Closed
2230.800002.500000Closed
3240.800002.500000Closed
42310.0440869.274741Closed
\n", + "
" + ], + "text/plain": [ + " BusNum GenID GenMVR GenMW GenStatus\n", + "0 2 1 0.80000 2.500000 Closed\n", + "1 2 2 0.80000 2.500000 Closed\n", + "2 2 3 0.80000 2.500000 Closed\n", + "3 2 4 0.80000 2.500000 Closed\n", + "4 23 1 0.04408 69.274741 Closed" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pw.gens().head()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "loads", + "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", + "
BusNumLoadIDLoadMVRLoadMWLoadStatus
0210.060.699999Closed
1310.059.390002Closed
2410.022.470000Closed
3610.027.460000Closed
4710.037.009999Closed
\n", + "
" + ], + "text/plain": [ + " BusNum LoadID LoadMVR LoadMW LoadStatus\n", + "0 2 1 0.0 60.699999 Closed\n", + "1 3 1 0.0 59.390002 Closed\n", + "2 4 1 0.0 22.470000 Closed\n", + "3 6 1 0.0 27.460000 Closed\n", + "4 7 1 0.0 37.009999 Closed" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pw.loads().head()" + ] + }, + { + "cell_type": "markdown", + "id": "q1zjorq7a", + "metadata": {}, + "source": [ + "## Power Flow & Voltage Analysis\n", + "\n", + "`pflow()` solves the AC power flow and returns complex bus voltages.\n", + "After solving, all data accessed through the indexable interface\n", + "reflects the updated system state. You can specify the solution\n", + "method explicitly or use the default (Polar Newton-Raphson).\n", + "\n", + "```python\n", + "V = pw.pflow() # default: Polar Newton-Raphson\n", + "V = pw.pflow(method=\"POLARNEWT\") # explicit method selection\n", + "```\n", + "\n", + "Several methods provide quick access to voltage and power data\n", + "without having to assemble field lists manually:\n", + "\n", + "| Method | Returns |\n", + "|---|---|\n", + "| `pw.voltage()` | Complex bus voltages (per-unit) |\n", + "| `pw.voltage(complex=False)` | Magnitude and angle as separate Series |\n", + "| `pw.set_voltages(V)` | Set bus voltages from a complex array |\n", + "| `pw.mismatch()` | Bus active/reactive power mismatches |\n", + "| `pw.netinj()` | Net power injection at each bus |\n", + "| `pw.violations(v_min, v_max)` | Buses outside a voltage band |" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "voltage", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "count 37.000000\n", + "mean 0.988868\n", + "std 0.008708\n", + "min 0.974911\n", + "25% 0.980583\n", + "50% 0.991217\n", + "75% 0.995798\n", + "max 1.003416\n", + "dtype: float64" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "V = pw.voltage()\n", + "np.abs(V).describe()" + ] + }, + { + "cell_type": "markdown", + "id": "matrix-md", + "metadata": {}, + "source": [ + "## Matrices & Topology\n", + "\n", + "System matrices are returned as scipy sparse arrays by default,\n", + "with an option for dense numpy arrays. The bus map provides the\n", + "mapping between PowerWorld bus numbers and matrix row/column indices.\n", + "\n", + "| Method | Returns |\n", + "|---|---|\n", + "| `pw.ybus()` | System admittance matrix (sparse) |\n", + "| `pw.ybus(dense=True)` | Dense admittance matrix |\n", + "| `pw.jacobian()` | Power flow Jacobian |\n", + "| `pw.jacobian(form=\"P\")` | Polar-form Jacobian |\n", + "| `pw.jacobian(form=\"DC\")` | DC Jacobian |\n", + "| `pw.busmap()` | Bus number to matrix index mapping |\n", + "| `pw.buscoords()` | Bus latitude/longitude from substation data |" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "ybus", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(37, 37)" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Y = pw.ybus()\n", + "Y.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "jacobian", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(74, 74)" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "J = pw.jacobian()\n", + "J.shape" + ] + }, + { + "cell_type": "markdown", + "id": "case-md", + "metadata": {}, + "source": [ + "## Case Control & Solver Options\n", + "\n", + "Basic case management methods handle saving, closing, and resetting\n", + "the case state. Solver options are exposed as Python descriptors on\n", + "`PowerWorld`, letting you read and write simulation settings as\n", + "regular attributes rather than calling dedicated getter/setter methods.\n", + "\n", + "| Method | Purpose |\n", + "|---|---|\n", + "| `pw.save()` | Save the case |\n", + "| `pw.save(\"new.pwb\")` | Save to a new file |\n", + "| `pw.close()` | Close the current case |\n", + "| `pw.flatstart()` | Reset to 1.0 pu / 0 deg |\n", + "| `pw.edit_mode()` | Enter edit mode |\n", + "| `pw.run_mode()` | Enter run mode |\n", + "| `pw.log(msg)` | Add a message to the PowerWorld log |\n", + "\n", + "Solver settings are accessed directly as attributes:\n", + "\n", + "```python\n", + "pw.max_iterations = 250 # set max Newton iterations\n", + "pw.flat_start = True # enable flat start\n", + "pw.convergence_tol = 1e-5 # set convergence tolerance\n", + "pw.do_one_iteration = True # single iteration mode\n", + "pw.dc_mode = True # DC approximation\n", + "```\n", + "\n", + "See the :doc:`API Reference ` for the full list of\n", + "solver option descriptors." + ] + }, + { + "cell_type": "markdown", + "id": "branch-switch-md", + "metadata": {}, + "source": [ + "## Convenience Features\n", + "\n", + "Several methods wrap multi-step workflows into single calls.\n", + "\n", + "**Branch flows and overloads** — `flows()` retrieves MW, MVR, MVA,\n", + "and percent loading for every branch. `overloads()` filters to\n", + "branches exceeding a threshold.\n", + "\n", + "| Method | Returns |\n", + "|---|---|\n", + "| `pw.flows()` | Branch MW, MVR, MVA, and % loading |\n", + "| `pw.overloads(threshold=100)` | Branches exceeding a loading threshold |\n", + "\n", + "**Sensitivity factors** — `ptdf()` and `lodf()` compute Power\n", + "Transfer Distribution Factors and Line Outage Distribution Factors,\n", + "respectively. Both call the underlying SAW sensitivity commands and\n", + "return the results as a DataFrame.\n", + "\n", + "| Method | Returns |\n", + "|---|---|\n", + "| `pw.ptdf(seller, buyer)` | Power Transfer Distribution Factors |\n", + "| `pw.lodf(branch)` | Line Outage Distribution Factors |\n", + "\n", + "**Snapshot** — a context manager that saves the current case state\n", + "on entry and restores it on exit, even if an exception occurs.\n", + "Useful for \"what-if\" analyses where you want to modify the case\n", + "temporarily without losing the original state.\n", + "\n", + "```python\n", + "with pw.snapshot():\n", + " pw[Gen, \"GenMW\"] = modified_gen\n", + " pw.pflow()\n", + " v = pw.voltage()\n", + "# state automatically restored here\n", + "```\n", + "\n", + "**Quick properties** provide case-level counts and the system MVA\n", + "base without having to query and count manually. `summary()`\n", + "aggregates these into a single dict along with generation/load\n", + "totals and the voltage range.\n", + "\n", + "| Property / Method | Returns |\n", + "|---|---|\n", + "| `pw.n_bus` | Number of buses |\n", + "| `pw.n_branch` | Number of branches |\n", + "| `pw.n_gen` | Number of generators |\n", + "| `pw.sbase` | System MVA base (float) |\n", + "| `pw.summary()` | Dict with counts, totals, and voltage range |" + ] + }, + { + "cell_type": "markdown", + "id": "utils-md", + "metadata": {}, + "source": [ + "## Utility Modules\n", + "\n", + "`PowerWorld` embeds specialized analysis modules as attributes.\n", + "These provide domain-specific functionality built on top of the\n", + "indexable interface and SAW commands.\n", + "\n", + "| Attribute | Module | Capabilities |\n", + "|---|---|---|\n", + "| `pw.network` | Network topology | Incidence matrices, Laplacians, bus coordinates |\n", + "| `pw.gic` | GIC analysis | G-matrix, E-field Jacobians, storm simulation |\n", + "\n", + "Like the solver options on `PowerWorld`, GIC analysis options are\n", + "also exposed as descriptors on `pw.gic`:\n", + "\n", + "```python\n", + "pw.gic.pf_include = True # enable GIC in power flow\n", + "pw.gic.calc_mode = 'SnapShot' # set calculation mode\n", + "pw.gic.configure() # apply sensible defaults\n", + "```\n", + "\n", + "See the :doc:`API Reference ` for full documentation\n", + "of each module." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "esapp", + "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.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/examples/getting_started/06_settings_and_options.ipynb b/docs/examples/getting_started/06_settings_and_options.ipynb new file mode 100644 index 00000000..c4582ec0 --- /dev/null +++ b/docs/examples/getting_started/06_settings_and_options.ipynb @@ -0,0 +1,462 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "title", + "metadata": {}, + "source": [ + "# Settings & Options\n", + "\n", + "PowerWorld has many simulation settings — solver iteration limits,\n", + "convergence tolerances, control flags, GIC parameters, and more.\n", + "Traditionally these require verbose getter/setter calls through\n", + "the SimAuto API. ESA++ exposes the most commonly used settings as\n", + "**Python attributes** on `PowerWorld` and `pw.gic`, so reading or\n", + "changing a setting is as simple as reading or assigning a variable.\n", + "\n", + "```python\n", + "from esapp import PowerWorld\n", + "from esapp.components import *\n", + "\n", + "pw = PowerWorld(\"path/to/case.pwb\")\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "hidden-setup", + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "'open' took: 7.1384 sec\n" + ] + } + ], + "source": [ + "from esapp import PowerWorld\n", + "from esapp.components import *\n", + "import ast\n", + "\n", + "with open('../../../examples/data/case.txt', 'r') as f:\n", + " case_path = ast.literal_eval(f.read().strip())\n", + "\n", + "pw = PowerWorld(case_path)" + ] + }, + { + "cell_type": "markdown", + "id": "solver-md", + "metadata": {}, + "source": [ + "## Solver Options\n", + "\n", + "Solver options control how the Newton-Raphson power flow behaves.\n", + "They live directly on the `PowerWorld` object as Python attributes —\n", + "just read or assign them like normal variables. Boolean options\n", + "use `True`/`False`; numeric options use `int` or `float`.\n", + "Changes take effect immediately in PowerWorld." + ] + }, + { + "cell_type": "code", + "id": "solver-read", + "metadata": {}, + "source": [ + "# Read current settings\n", + "pw.max_iterations, pw.convergence_tol, pw.flat_start, pw.dc_mode" + ], + "execution_count": null, + "outputs": [ + { + "data": { + "text/plain": [ + "(50, 1e-07, False, False)" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ] + }, + { + "cell_type": "code", + "id": "solver-write", + "metadata": {}, + "source": [ + "# Change numeric settings\n", + "pw.max_iterations = 200\n", + "pw.convergence_tol = 1e-5\n", + "\n", + "# Toggle boolean settings\n", + "pw.dc_mode = True\n", + "assert pw.dc_mode is True\n", + "pw.dc_mode = False\n", + "\n", + "pw.max_iterations, pw.convergence_tol, pw.dc_mode" + ], + "execution_count": null, + "outputs": [ + { + "data": { + "text/plain": [ + "(200, 1e-05, False)" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ] + }, + { + "cell_type": "markdown", + "id": "solver-ref-md", + "metadata": {}, + "source": [ + "### Solver option reference\n", + "\n", + "**Iteration & convergence:**\n", + "\n", + "| Attribute | Type | Description |\n", + "|---|---|---|\n", + "| `max_iterations` | int | Maximum Newton-Raphson iterations |\n", + "| `max_vcl_iterations` | int | Maximum voltage-constrained loop iterations |\n", + "| `convergence_tol` | float | Power flow convergence tolerance |\n", + "| `min_volt_i_load` | float | Minimum voltage for constant-current loads (pu) |\n", + "| `min_volt_s_load` | float | Minimum voltage for constant-impedance loads (pu) |\n", + "\n", + "**Boolean controls:**\n", + "\n", + "| Attribute | Description |\n", + "|---|---|\n", + "| `do_one_iteration` | Solve only one Newton iteration per call |\n", + "| `disable_opt_mult` | Disable optimal multiplier acceleration |\n", + "| `flat_start` | Start from flat voltage profile (1.0 pu, 0 deg) |\n", + "| `dc_mode` | Enable DC power flow approximation |\n", + "| `inner_ss_check` | Check switched shunt controls in inner loop |\n", + "| `disable_gen_mvr_check` | Disable generator MVR limit checking |\n", + "| `inner_check_gen_vars` | Check generator VAR limits in inner loop |\n", + "| `inner_backoff_gen_vars` | Back off generator VAR limits in inner loop |\n", + "| `check_taps` | Check transformer tap adjustments |\n", + "| `check_shunts` | Check switched shunt adjustments |\n", + "| `check_phase_shifters` | Check phase shifter adjustments |\n", + "| `prevent_oscillations` | Prevent control oscillations |\n", + "| `disable_angle_rotation` | Disable automatic angle rotation to slack |\n", + "| `allow_mult_islands` | Allow multiple island solutions |\n", + "| `eval_solution_island` | Evaluate solution quality per island |\n", + "| `enforce_gen_mw_limits` | Enforce generator MW output limits |" + ] + }, + { + "cell_type": "markdown", + "id": "gic-md", + "metadata": {}, + "source": [ + "## GIC Options\n", + "\n", + "GIC options are accessed through `pw.gic` and work the same way —\n", + "read by accessing the attribute, write by assigning to it." + ] + }, + { + "cell_type": "code", + "id": "gic-read", + "metadata": {}, + "source": [ + "# Read GIC settings\n", + "pw.gic.pf_include, pw.gic.ts_include, pw.gic.calc_mode" + ], + "execution_count": null, + "outputs": [ + { + "data": { + "text/plain": [ + "(False, False, 'SnapShot')" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ] + }, + { + "cell_type": "code", + "id": "gic-write", + "metadata": {}, + "source": [ + "# Change GIC settings\n", + "pw.gic.pf_include = True\n", + "pw.gic.efield_angle = 90.0\n", + "pw.gic.efield_mag = 1.0\n", + "\n", + "pw.gic.pf_include, pw.gic.efield_angle, pw.gic.efield_mag" + ], + "execution_count": null, + "outputs": [ + { + "data": { + "text/plain": [ + "(True, '90', '1')" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ] + }, + { + "cell_type": "markdown", + "id": "configure-md", + "metadata": {}, + "source": [ + "`configure()` sets multiple GIC options at once with sensible\n", + "defaults. With no arguments it enables GIC in power flow with\n", + "snapshot mode." + ] + }, + { + "cell_type": "code", + "id": "configure", + "metadata": {}, + "source": [ + "pw.gic.configure() # defaults: pf_include=True, ts_include=False, calc_mode=\"SnapShot\"\n", + "pw.gic.pf_include, pw.gic.ts_include, pw.gic.calc_mode" + ], + "execution_count": null, + "outputs": [ + { + "data": { + "text/plain": [ + "(True, False, 'SnapShot')" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ] + }, + { + "cell_type": "markdown", + "id": "settings-md", + "metadata": {}, + "source": [ + "`settings()` returns every GIC option as a DataFrame, including\n", + "options without a dedicated attribute." + ] + }, + { + "cell_type": "code", + "id": "settings", + "metadata": {}, + "source": [ + "pw.gic.settings().head(10)" + ], + "execution_count": null, + "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", + "
VariableNameValueField
0AutoXFMaxTurnsRatio4
1BusNoSubNone (Ungrounded)
2CalcInducedDCVoltEquivNO
3CalcInducedDCVoltLength1
4CalcInducedDCVoltLowRNO
5CalcMaxDirectionYES
6CalcModeSnapShot
7DistXFConfigDefaultGWye
8EField3dFileMergeYES
9EField3dFileMultLoad0
\n", + "
" + ], + "text/plain": [ + " VariableName ValueField\n", + "0 AutoXFMaxTurnsRatio 4\n", + "1 BusNoSub None (Ungrounded)\n", + "2 CalcInducedDCVoltEquiv NO\n", + "3 CalcInducedDCVoltLength 1\n", + "4 CalcInducedDCVoltLowR NO\n", + "5 CalcMaxDirection YES\n", + "6 CalcMode SnapShot\n", + "7 DistXFConfigDefault GWye\n", + "8 EField3dFileMerge YES\n", + "9 EField3dFileMultLoad 0" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ] + }, + { + "cell_type": "markdown", + "id": "gic-ref-md", + "metadata": {}, + "source": [ + "### Available GIC options\n", + "\n", + "**Core:**\n", + "\n", + "| Attribute | Type | Description |\n", + "|---|---|---|\n", + "| `pf_include` | bool | Include GIC effects in power flow |\n", + "| `ts_include` | bool | Include GIC effects in transient stability |\n", + "| `calc_mode` | str | Calculation mode (SnapShot, TimeVarying, etc.) |\n", + "\n", + "**Electric field:**\n", + "\n", + "| Attribute | Type | Description |\n", + "|---|---|---|\n", + "| `efield_angle` | float | Storm direction in degrees |\n", + "| `efield_mag` | float | Field magnitude in V/distance |\n", + "| `calc_max_direction` | bool | Auto-calculate maximum E-field direction |\n", + "\n", + "**Calculation controls:**\n", + "\n", + "| Attribute | Type | Description |\n", + "|---|---|---|\n", + "| `update_line_volts` | bool | Auto-update line DC voltages |\n", + "| `skip_equiv_lines` | bool | Skip DC voltage on equivalent lines |\n", + "| `skip_low_r_lines` | bool | Skip DC voltage on low-R lines |\n", + "| `min_kv` | float | Minimum nominal kV to include GIC effects |\n", + "| `segment_length_km` | float | Max line segment length (km) |\n", + "| `bus_no_sub` | str | Auto-insert option for buses without substations |\n", + "| `hotspot_include` | bool | Include hotspot calculations |" + ] + }, + { + "cell_type": "markdown", + "id": "how-it-works-md", + "metadata": {}, + "source": [ + "## Under the Hood\n", + "\n", + "These attributes are Python [descriptors](https://docs.python.org/3/howto/descriptor.html)\n", + "defined in `esapp._descriptors`. Each one maps a Python name to a\n", + "PowerWorld option field. Boolean options stored as `\"YES\"`/`\"NO\"`\n", + "in PowerWorld are automatically converted to/from `True`/`False`.\n", + "You can inspect the mapping at the class level:" + ] + }, + { + "cell_type": "code", + "id": "descriptor-introspect", + "metadata": {}, + "source": [ + "desc = type(pw).max_iterations\n", + "desc.key, desc.is_bool" + ], + "execution_count": null, + "outputs": [ + { + "data": { + "text/plain": [ + "('MaxItr', False)" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "esapp", + "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.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/examples/index.rst b/docs/examples/index.rst new file mode 100644 index 00000000..38e6955b --- /dev/null +++ b/docs/examples/index.rst @@ -0,0 +1,15 @@ +Examples +======== + +Introductory examples covering the indexable interface, power flow, and +workbench utilities. + +.. toctree:: + :maxdepth: 1 + + getting_started/01_reading_data + getting_started/02_writing_data + getting_started/03_components_and_fields + getting_started/04_creating_objects + getting_started/05_workbench_overview + getting_started/06_settings_and_options diff --git a/docs/examples/system_health_report.csv b/docs/examples/system_health_report.csv deleted file mode 100644 index 965016b0..00000000 --- a/docs/examples/system_health_report.csv +++ /dev/null @@ -1,39 +0,0 @@ -Bus -Report_Generated_By,Number,Name,PU Volt,Angle (Deg) -ESA++,1,ALOHA138,0.993545,-1.119907 -ESA++,2,ALOHA69,0.991225,-3.927372 -ESA++,3,FLOWER69,0.984548,-4.731145 -ESA++,4,WAVE69,0.978800,-5.745870 -ESA++,5,HONOLULU138,0.988985,-2.069792 -ESA++,6,HONOLULU69,0.981206,-5.528160 -ESA++,7,SURF69,0.980583,-5.671337 -ESA++,8,KANEOHE69,0.978619,-5.702381 -ESA++,9,TURTLE138,0.986768,-2.548359 -ESA++,10,TURTLE69,0.980941,-5.651960 -ESA++,11,MAHALO69,0.974911,-6.522955 -ESA++,12,LYCHEE69,0.977327,-6.198354 -ESA++,13,COCONUT69,0.978953,-6.094816 -ESA++,14,KAILUA138,0.983764,-3.136205 -ESA++,15,KAILUA69,0.978631,-6.029763 -ESA++,16,PALM69,0.982187,-6.456032 -ESA++,17,WAIMANALO69,0.975496,-6.981904 -ESA++,18,VOLCANO69,0.975960,-7.121150 -ESA++,19,PEARL CITY69,0.991304,-3.514221 -ESA++,20,MILILANI69,0.989660,-1.963951 -ESA++,21,AIEA69,0.979942,-5.268157 -ESA++,22,WAIPAHU138,0.996397,-0.844548 -ESA++,23,WAIPAHU69,1.000000,-2.106015 -ESA++,24,KAPOLEI69,0.993402,-3.706851 -ESA++,25,EWA BEACH138,0.996614,-0.528763 -ESA++,26,EWA BEACH69,0.995105,-3.596866 -ESA++,27,KAHUKU69,1.003416,1.362694 -ESA++,28,HALEIWA69,1.000000,0.234055 -ESA++,29,LAIE69,0.995383,-0.097274 -ESA++,30,WAHIAWA69,0.995798,-0.422344 -ESA++,31,WAIALUA69,0.995215,-2.101776 -ESA++,32,HAUULA69,0.991217,-1.321157 -ESA++,33,WAIANAE69,0.995652,-3.050368 -ESA++,34,SCHOFIELD69,1.000000,-2.084231 -ESA++,35,KALAELOA138,1.000000,0.376390 -ESA++,36,COGEN69,0.996572,-3.565242 -ESA++,37,KAHE138,1.000000,0.251430 diff --git a/docs/guide/examples.rst b/docs/guide/examples.rst deleted file mode 100644 index f3786cca..00000000 --- a/docs/guide/examples.rst +++ /dev/null @@ -1,18 +0,0 @@ -Examples -================ - -These examples demonstrate the core functionality of ESA++ using Jupyter Notebooks. - -.. toctree:: - :maxdepth: 1 - - ../examples/01_basic_data_access - ../examples/02_power_flow_analysis - ../examples/03_contingency_analysis - ../examples/04_gic_analysis - ../examples/05_matrix_extraction - ../examples/06_exporting - ../examples/07_network_expansion - ../examples/08_scopf_analysis - ../examples/09_atc_analysis - ../examples/10_transient_stability_cct \ No newline at end of file diff --git a/docs/guide/index.rst b/docs/guide/index.rst deleted file mode 100644 index dbc48cd5..00000000 --- a/docs/guide/index.rst +++ /dev/null @@ -1,9 +0,0 @@ -User Guide -========== - -.. toctree:: - :maxdepth: 2 - - install - usage - examples diff --git a/docs/guide/install.rst b/docs/guide/install.rst deleted file mode 100644 index 29fedbfd..00000000 --- a/docs/guide/install.rst +++ /dev/null @@ -1,37 +0,0 @@ -Install -======= - -Prerequisites -------------- -- PowerWorld Simulator with SimAuto (COM interface) enabled -- Python 3.10+ and ``pip`` available on your path - -Install the package -------------------- - -Use the latest published package: - -.. code-block:: bash - - python -m pip install esapp - -For development against this repository: - -.. code-block:: bash - - python -m pip install -e . - -Verify the installation ------------------------ - -.. code-block:: python - - from esapp import GridWorkBench - wb = GridWorkBench("path/to/your/case.pwb") - print(wb) - -Next steps ----------- -- Continue to the :doc:`usage` guide for indexing and API basics -- See :doc:`examples` for end-to-end notebooks -- Review :doc:`../api/api` for full reference diff --git a/docs/guide/usage.rst b/docs/guide/usage.rst deleted file mode 100644 index b2bf2d5b..00000000 --- a/docs/guide/usage.rst +++ /dev/null @@ -1,149 +0,0 @@ -Usage Guide -=========== - -This guide explains the core mechanics of ESA++—how to index, read, and write fields and when to drop down -to SAW. If you want goal-driven, end-to-end scripts, head to :doc:`examples`. Think of this page as the -reference for everyday interactions: get data, filter it, push edits back, and call lower-level SAW features -when you need to. - -Quick start ------------ - -Create a workbench, import the grid components you care about, and you are ready to query or modify the -case. Keep paths absolute when launching PowerWorld so SimAuto can resolve the file cleanly. - -.. code-block:: python - - from esapp import GridWorkBench - from esapp.grid import Bus, Gen, Branch - - wb = GridWorkBench("path/to/case.pwb") - -Indexing basics ---------------- - -Indexing always follows the same pattern: component class first, then the fields you want. Leaving the -second slot as ``:`` returns every available field for that component. Use specific fields for small payloads -and ``:`` when you need the full shape of the object. - -**Primary keys only** - -.. code-block:: python - - bus_keys = wb[Bus] - -**Specific fields** - -.. code-block:: python - - voltages = wb[Bus, "BusPUVolt"] - bus_info = wb[Bus, ["BusName", "BusPUVolt"]] - gen_info = wb[Gen, ["GenMW", "GenStatus"]] - -**All fields** - -.. code-block:: python - - branches = wb[Branch, :] - -**Field attributes for autocomplete** - -.. code-block:: python - - bus_data = wb[Bus, [Bus.BusName, Bus.BusPUVolt, Bus.BusAngle]] - -Filtering and slicing ---------------------- - -Returned objects are Pandas DataFrames or Series, so filter and slice with normal Pandas operations. Keep -the heavy lifting in Pandas, then write only the results you need back to PowerWorld. - -.. code-block:: python - - buses = wb[Bus, ["BusNum", "AreaNum", "BusPUVolt"]] - area_1 = buses[buses["AreaNum"] == 1] - low_v = buses[buses["BusPUVolt"] < 0.95] - -Writing data ------------- - -Writes mirror reads: same indexing form, but assign on the right-hand side. Broadcasting works for scalars; -bulk operations use DataFrames that include primary keys. Start with small, targeted updates before applying -wider changes. - -**Broadcast a scalar** - -.. code-block:: python - - wb[Bus, "BusPUVolt"] = 1.05 - wb[Gen, "GenStatus"] = "Closed" - -**Update multiple fields** - -.. code-block:: python - - wb[Gen, ["GenMW", "GenMVR"]] = [120.0, 25.0] - -**Bulk update with DataFrame** - -.. code-block:: python - - import pandas as pd - - updates = pd.DataFrame({ - "BusNum": [1, 2, 5], - "BusPUVolt": [1.02, 1.01, 0.99] - }) - - wb[Bus] = updates - -.. note:: - Include primary key columns (e.g., ``BusNum``) in bulk updates. - -Convenience helpers -------------------- - -Shortcuts for common edits when you do not want to assemble DataFrames or craft SAW calls: - -.. code-block:: python - - wb.set_gen(bus=5, id="1", mw=150.0, mvar=40.0, status="Closed") - wb.set_load(bus=10, id="1", mw=90.0, mvar=25.0, status="Closed") - - wb.open_branch(from_bus=1, to_bus=2, id="1") - wb.close_branch(from_bus=1, to_bus=2, id="1") - - wb.scale_gen(scale_factor=1.05) - wb.scale_load(scale_factor=0.95) - -Calling SAW directly --------------------- - -Access the full SimAuto interface when you need lower-level operations or features not surfaced on the -workbench helpers. Prefer the helpers for routine tasks; reach for SAW when you need the complete API. - -.. code-block:: python - - saw = wb.esa - saw.SolveAC_OPF() - saw.RunScriptCommand("SolvePowerFlow(RECTNEWT);") - -Matrices and topology ---------------------- - -Extract matrices and mappings without building a full study workflow. Use these as building blocks for -linearized studies, external analytics, or custom contingency logic. - -.. code-block:: python - - Y = wb.ybus() - A = wb.network.incidence() - busmap = wb.network.busmap() - from esapp.apps.network import Network - L = wb.network.laplacian(weights=Network.BranchType.LENGTH) - -Where to go next ----------------- -- End-to-end scripts: :doc:`examples` -- Full API reference: :doc:`../api/api` -- Development and tests: :doc:`../dev/tests` \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index b26821ad..6cee5c99 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,12 +1,10 @@ -ESA++ Documentation -=================== +ESA++ +===== .. toctree:: :maxdepth: 2 - :caption: Contents overview - guide/index - examples/examples + examples/index api/index - dev/index \ No newline at end of file + dev/index diff --git a/docs/overview.rst b/docs/overview.rst index e055c692..e5a844e9 100644 --- a/docs/overview.rst +++ b/docs/overview.rst @@ -1,5 +1,5 @@ -ESA++ -==================================== +Getting Started +=============== .. image:: https://img.shields.io/badge/License-Apache%202.0-blue.svg :target: https://opensource.org/licenses/Apache-2.0 @@ -13,103 +13,52 @@ ESA++ :target: https://esapp.readthedocs.io/ :alt: Documentation -.. image:: https://img.shields.io/badge/coverage-90%25-brightgreen.svg - :alt: Coverage 90% +ESA++ is an open-source Python toolkit for power system automation, providing a high-performance +wrapper for PowerWorld's Simulator Automation Server (SimAuto). It transforms complex COM calls +into intuitive, Pythonic operations. -An open-source Python toolkit for power system automation, providing a high-performance "syntax-sugar" fork of Easy SimAuto (ESA). This library streamlines interaction with PowerWorld's Simulator Automation Server (SimAuto), transforming complex COM calls into intuitive, Pythonic operations. +- **Intuitive Indexing** — Access grid data with ``pw[Bus, "BusPUVolt"]`` syntax +- **Full SimAuto Coverage** — All PowerWorld API functions through modular mixins +- **Pandas Integration** — Every query returns a DataFrame +- **Pythonic Settings** — Solver and GIC options as descriptor attributes (``pw.max_iterations = 250``) +- **Convenience Methods** — Flows, overloads, PTDF/LODF, snapshot context manager, case summary +- **Transient Stability** — Fluent API with ``TS`` field intellisense +- **Analysis Utilities** — Built-in GIC, network topology, and contingency tools -Key Features ------------- -- **Intuitive Indexing Syntax**: Access and modify grid components using a unique indexing system (e.g., ``wb[Bus, "BusPUVolt"]``) that feels like native Python. -- **Comprehensive SimAuto Wrapper**: Full coverage of PowerWorld's API through the ``SAW`` class, organized into modular mixins for power flow, contingencies, transients, and more. -- **High-Level Adapter Interface**: A collection of simplified "one-liner" functions for common tasks like GIC calculation, fault analysis, and voltage violation detection. -- **Native Pandas Integration**: Every data retrieval operation returns a Pandas DataFrame or Series, enabling immediate analysis, filtering, and visualization. -- **Advanced Analysis Apps**: Built-in specialized modules for Network topology analysis, Geomagnetically Induced Currents (GIC), and Forced Oscillation detection. +Developed by **Luke Lowery** and **Adam Birchfield** at Texas A&M University +(`Birchfield Research Group `_). +Licensed under `Apache 2.0 `_. + +If you use ESA++ in research, please cite: + +.. code-block:: bibtex + + @article{esa2020, + title={Easy SimAuto (ESA): A Python Package for PowerWorld Simulator Automation}, + author={Mao, Zeyu and Thayer, Brandon and Liu, Yijing and Birchfield, Adam}, + year={2020} + } Installation ------------ -The ESA++ package is available on `PyPI `_ +Requires PowerWorld Simulator with SimAuto enabled and Python 3.9+. .. code-block:: bash pip install esapp -Usage Example +Quick Example ------------- -Here is a quick example of how ESA++ simplifies data access and power flow analysis. - .. code-block:: python - from esapp import GridWorkBench - from esapp.grid import * - - # Open Case - wb = GridWorkBench("path/to/case.pwb") - - # Retrieve data - bus_data = wb[Bus, ["BusName", "BusPUVolt"]] - - # Solve power flow - V = wb.pflow() - - # Do some action, write to PW - violations = wb.find_violations(v_min=0.95) - wb[Gen, "GenMW"] = 100.0 - - # Save case - wb.save() - -Why ESA++? ----------- - -Traditional automation of PowerWorld Simulator often involves verbose COM calls and manual data parsing. ESA++ abstracts these complexities: - -* **Speed**: Optimized data transfer between Python and SimAuto. -* **Clarity**: Code that reads like the engineering operations it performs. -* **Ecosystem**: Built on top of the proven ESA library, adding modern Python features and better integration with the SciPy stack. - - -More Examples -------------- - -The `docs/examples/ `_ directory contains a gallery of demonstrations, including: - -- **Object Field Access**: Reduce the time you spend searching for field names with ESA++ IDE typehints for objects and fields. -- **Matrix Extraction**: Retrieving Y-Bus, Jacobian, and GIC conductance matrices for external mathematical modeling. - -Testing -------- - -ESA++ includes an extensive test suite covering both offline mocks and live PowerWorld connections. To run the tests, install the test dependencies and execute pytest: - -.. code-block:: bash - - pip install .[test] - pytest tests/test_saw.py - -Citation --------- - -If you use this toolkit in your research or industrial projects, please cite the original ESA work and this fork: - -.. code-block:: bibtex - - @article{esa2020, - title={Easy SimAuto (ESA): A Python Package for PowerWorld Simulator Automation}, - author={Mao, Zeyu and Thayer, Brandon and Liu, Yijing and Birchfield, Adam}, - year={2020} - } - -Authors -------- - -Luke Lowery developed this module during his PhD studies at Texas A&M University. You can learn more on his `research page `_ or view his publications on `Google Scholar `_. + from esapp import PowerWorld + from esapp.components import * -ESA++ is maintained by **Luke Lowery** and **Adam Birchfield** at Texas A&M University. You can explore more of our research at the `Birchfield Research Group `_. + pw = PowerWorld("path/to/case.pwb") + voltages = pw[Bus, "BusPUVolt"] -License -------- -Distributed under the `Apache License 2.0 `_. +See the :doc:`examples ` for walkthroughs of reading data, +writing data, power flow, and workbench utilities. diff --git a/docs/requirements.txt b/docs/requirements.txt index 1f4b7e49..a72235de 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -2,6 +2,7 @@ sphinx sphinx-rtd-theme sphinx-copybutton nbsphinx +nbconvert numpy<2.0 ipykernel matplotlib \ No newline at end of file diff --git a/esapp/__init__.py b/esapp/__init__.py index b82de866..c9ccb9fe 100644 --- a/esapp/__init__.py +++ b/esapp/__init__.py @@ -7,7 +7,7 @@ to simplify common power systems analysis tasks by providing a more Pythonic and user-friendly API. -The main entry point is the :class:`~.GridWorkBench` class. +The main entry point is the :class:`~.PowerWorld` class. """ # Please keep the docstring above up to date with all the imports. @@ -22,5 +22,8 @@ PowerWorldAddonError, ) -# Main Grid Work Bench Class -from .workbench import GridWorkBench +# Main PowerWorld Interface Class +from .workbench import PowerWorld + +# Transient Stability Field Constants for Intellisense +from .components import TS, TSField diff --git a/esapp/_descriptors.py b/esapp/_descriptors.py new file mode 100644 index 00000000..2c93cd3a --- /dev/null +++ b/esapp/_descriptors.py @@ -0,0 +1,68 @@ +""" +Descriptors for PowerWorld settings. + +Provides lightweight, Pythonic attribute access to PowerWorld option flags +without repetitive boilerplate setter/getter methods. +""" + +from .components import Sim_Solution_Options, GIC_Options_Value +from .saw._enums import YesNo + + +class SolverOption: + """Descriptor mapping a Python attribute to a Sim_Solution_Options field.""" + + def __init__(self, key: str, is_bool: bool = True): + self.key = key + self.is_bool = is_bool + + def __set_name__(self, owner, name): + self.name = name + + def __get__(self, obj, objtype=None): + if obj is None: + return self + val = obj[Sim_Solution_Options, self.key][self.key].iloc[0] + if self.is_bool: + return val == YesNo.YES + return val + + def __set__(self, obj, value): + if self.is_bool: + obj[Sim_Solution_Options, self.key] = YesNo.from_bool(value) + else: + obj[Sim_Solution_Options, self.key] = value + + +class GICOption: + """Descriptor mapping a Python attribute to a GIC_Options_Value entry.""" + + def __init__(self, key: str, is_bool: bool = True): + self.key = key + self.is_bool = is_bool + + def __set_name__(self, owner, name): + self.name = name + + def __get__(self, obj, objtype=None): + if obj is None: + return self + df = obj._pw[GIC_Options_Value, "ValueField"] + row = df[df['VariableName'] == self.key] + if row.empty: + return None + val = row['ValueField'].iloc[0] + if self.is_bool: + return val == YesNo.YES + return val + + def __set__(self, obj, value): + if self.is_bool: + value = YesNo.from_bool(value) + obj._pw.esa.EnterMode("EDIT") + obj._pw.esa.SetData( + 'GIC_Options_Value', + ['VariableName', 'ValueField'], + [self.key, value] + ) + obj._pw.esa.EnterMode("RUN") diff --git a/esapp/apps/__init__.py b/esapp/apps/__init__.py deleted file mode 100644 index efadcba8..00000000 --- a/esapp/apps/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -""" -Specialized Applications (:mod:`esapp.apps`) -============================================ - -This package contains higher-level, specialized tools for advanced power -systems analysis tasks built on top of the core ``esapp`` components. -""" - -# Applications -from .gic import GIC -from .network import Network, BranchType -from .modes import ForcedOscillation - -__all__ = [ - "GIC", - "Network", - "BranchType", - "ForcedOscillation", -] \ No newline at end of file diff --git a/esapp/apps/dynamics.py b/esapp/apps/dynamics.py deleted file mode 100644 index ee31936f..00000000 --- a/esapp/apps/dynamics.py +++ /dev/null @@ -1,135 +0,0 @@ -from numpy import nan, float32 -from pandas import DataFrame, concat - -# WorkBench Imports -from ..grid import TSContingency -from ..indexable import Indexable - - -class Dynamics(Indexable): - """ - Research-focused transient stability simulation application. - - This class provides specialized functions for dynamic simulation, - transient stability contingency solving, and result extraction. - These functions are intentionally untested as they are for highly - specific research and data analysis. - """ - - def fields(self, metric): - '''Get TS Formatted Fields for Requested Objects''' - objs = self[metric["Type"]] # TODO I don't need to retrieve from PW I have it local. Will Speed up - os = objs['ObjectID'] - flist = [f"{str(os.loc[i])} | {metric['Dynamic']}" for i in range(len(os))] - return flist - - # Set Run Time for list of contingencies - def setRuntime(self, sec): - ctgs = self[TSContingency] - ctgs["StartTime"] = 0 - ctgs["EndTime"] = sec - self[TSContingency] = ctgs - - # Create 'SimOnly' contingency if it does not exist - # TODO Add TSCtgElement that closes an already closed gen at t=0 - def simonly(self): - try: - self.esa.change_and_confirm_params_multiple_element( - ObjectType="TSContingency", - command_df=DataFrame({"TSCTGName": ["SimOnly"]}), - ) - except CommandNotRespectedError: - print("Failure to create 'SimOnly' Contingency") - else: - print("Contingency 'SimOnly' Initialized") - - def solve(self, ctgs: list[str] = None): - # Unique List of Fields to Request From PW - - # Prepare Memory - self.esa.clearram() - - # Gen Obj Field list and Mark Fields for RAM storage - objFields = [] - flatFields = [] - for objects, fields in self.retrieve: - self.esa.saveinram(objects, fields) - for id in objects['ObjectID']: - objFields += [f"{id} | {f}" for f in fields] - flatFields += fields - - # Sim Only (No Contingency) - if ctgs is None: - self.simonly() - ctgs = ["SimOnly"] - # Cast To List - if not isinstance(ctgs, list): - ctgs = [ctgs] - - # Only Sims Requested - self.esa.skipallbut(ctgs) - - # Set Runtime for Simulation - self.setRuntime(self.runtime) - - # Execute Dynamic Simulation for Specified CTGs - High Compute Time - self.esa.TSSolveAll() - - # Get Results - meta, df = (None, None) - for ctg in ctgs: - # Extract incoming Dataframe - metaSim, dfSim = self.esa.TSGetContingencyResults(ctg, objFields) - # Weird ESA bug where if items at end are open, they don't return data :( - # Happened Again, if last column is zero valued it removes the column. Awful - - # Proposed Fix: Will Fill in any floating columns not present in data but in meta - fillIdx = metaSim.index[~metaSim.index.isin(dfSim.columns)] - dfSim[fillIdx] = 0.0 - - # Custom Fields, Add CTG, Append to Main - metaSim.drop(columns=["Label", "ColHeader"], inplace=True) - metaSim.rename( - columns={ - "ObjectType": "Object", - "PrimaryKey": "ID-A", - "SecondaryKey": "ID-B", - 'VariableName': "Metric" - }, - inplace=True, - ) - metaSim['Metric'] = flatFields - metaSim["Contingency"] = ctg - meta = concat( - [metaSim] if meta is None else [meta, metaSim], - axis=0, - ignore_index=True, - ) - - # Won't work if first result is bad - if len(dfSim.columns) < 2: - dfSim = DataFrame(nan, columns=metaSim.index, index=[0]) - dfSim.index.name = "time" - else: - # Trim Data Size, Index by Time, Append to Main - dfSim = dfSim.astype(float32) - dfSim.set_index("time", inplace=True) - - #if df is not None: - #print(df.join(dfSim,how='outer')) - #TODO only working for same types of ctgs - df = concat( - [dfSim] if df is None else [df, dfSim], axis=1, ignore_index=True - ) - - # Clean Up ------------------------------------------------------- - - # Hard Copy Before Wiping RAM - meta: DataFrame = meta.copy(deep=True) - df: DataFrame = df.copy(deep=True) - - # Clear RAM in PW - self.esa.clearram() - - # Return as meta/data tuple - return (meta, df) diff --git a/esapp/apps/gic.py b/esapp/apps/gic.py deleted file mode 100644 index 619aa2f9..00000000 --- a/esapp/apps/gic.py +++ /dev/null @@ -1,1178 +0,0 @@ -from numpy import array, zeros,ones_like, diagflat, arange, eye -from numpy import min, max, sign, nan, pi, sqrt, abs, sin, cos, isnan -from numpy import unique, concatenate, sort, diag_indices, diff, expand_dims, repeat -from numpy import where, argwhere -from numpy import errstate, vectorize -from numpy.linalg import inv -from numpy import concatenate as conc -import numpy as np # TODO there is so much usage just import whole module - -from pandas import DataFrame, read_csv, MultiIndex -from scipy.sparse import coo_matrix, lil_matrix, hstack, vstack, diags -from enum import Enum, auto - -# WorkBench Imports -from ..grid import GIC_Options_Value, GICInputVoltObject -from ..grid import GICXFormer, Branch, Substation, Bus, Gen -from ..indexable import Indexable -from ..utils.b3d import B3D - - -from scipy.sparse.linalg import inv as sinv - -fcmd = lambda obj, fields, data: f"SetData({obj}, {fields}, {data})".replace("'","") -gicoption = lambda option, choice: fcmd("GIC_Options_Value",['VariableName', 'ValueField'], [option, choice]) - -def jac_decomp(jac): - '''Returns the sub-matricies of the jacobian in the following order: - (dP/dTheta, dP/dV, dQ/dTheta, dQ/dV) - ''' - - dim = jac.shape[0] - nbus = int(dim/2) - - yield jac[:nbus, :nbus] # dP/dT - yield jac[:nbus, nbus:] # dP/dV - yield jac[nbus:, :nbus] # dQ/dT - yield jac[nbus:, nbus:] # dQ/dV - - -class GICModel: - - '''A model class that holds all associated GIC matricies. Model instantiation requires proper - data input format. If using ESA, use GIC.model() to automatically generate an instance.''' - - def __init__(self, subs: DataFrame, buses: DataFrame, lines: DataFrame, xfmrs: DataFrame, gens: DataFrame) -> None: - - # Helper Functions & Constants - MOHM = 1e6 - iv = lambda A: sinv(A.tocsc()) - - # Manifest Node IDs - self.nbus, self.nsubs, self.nlines, self.nxfmr, self.ngens = len(buses), len(subs), len(lines), len(xfmrs), len(gens) - - # High and Low Winding, Line, GUS, and Substation Conductance - GH , GL, Gline, Ggen, RSUB = xfmrs['HighG'].to_numpy(), xfmrs['LowG'].to_numpy(), lines['G'].to_numpy(), gens['G'].to_numpy(), subs['SubR'].to_numpy() - - # Wiring Configuration and Device-Based Indexers - HWYE, LWYE = xfmrs['CFGHigh']=='Gwye', xfmrs['CFGLow']=='Gwye' - AUTO, BD = xfmrs['Auto'].to_numpy(bool), xfmrs['BD'].to_numpy(bool) - - ''' INCIDENCE MAPPING ''' - - def nodeperm(data, field, mount): - obj = subs if mount=='SubNum' else buses - m, n = len(data), len(obj) - idx = obj.reset_index().set_index(mount).loc[data[field], 'index'].to_numpy() - return coo_matrix((np.ones(m), (np.arange(m), idx)), shape=(m, n)) - - # Line and GSU Incidence Matrix - Aline = hstack([ - lil_matrix((self.nlines, self.nsubs)), - nodeperm(lines, 'FromBus', 'BusNum') - nodeperm(lines, 'ToBus', 'BusNum') - ]) - Agen = hstack([nodeperm(gens, 'BusNum', 'SubNum'), -nodeperm(gens, 'BusNum', 'BusNum')]) - - # Determine Wnd Map (Substation, High and Low Bus Mounts) - SUB, BH, BL = nodeperm(xfmrs, 'SubNum', 'SubNum'), nodeperm(xfmrs, 'HighBus', 'BusNum'), nodeperm(xfmrs, 'LowBus', 'BusNum') - - # Gwye (From B -> Sub Nuet.) Auto - High (High Bus -> Low Bus), Low (Low Bus -> Sub Nuet.) - A_WYE_HIGH , A_WYE_LOW = hstack([-SUB, BH]).tolil(), hstack([-SUB , BL]).tolil() - A_AUTO_HIGH, A_AUTO_LOW = hstack([lil_matrix((self.nxfmr, self.nsubs)), BH-BL]).tolil(), hstack([SUB, -BL]).tolil() - - # Merge Wiring Configurations - A_WYE_HIGH[~HWYE|AUTO], A_WYE_LOW[~LWYE|AUTO] = 0, 0 - A_AUTO_HIGH[~AUTO] , A_AUTO_LOW[~AUTO] = 0, 0 - AH, AL = A_WYE_HIGH + A_AUTO_HIGH, A_WYE_LOW + A_AUTO_LOW - - # Create Total Incidence (High Wnd, Low Wnd, Lines/Other Branches) - A = vstack([AH, AL, Aline, Agen]) - - ''' BRANCH CONDUCTANCE ''' - - # GIC Blocking Device (1 Mega Ohm in Series) - GH[BD&~AUTO], GL[BD], Gline[Gline==0], Ggen[Ggen==0], RSUB[RSUB==0] = 1/MOHM, 1/MOHM, 1/MOHM, 1/MOHM, MOHM - - # Total Branch Conductances (3-phase) & Substation Grounding Conductance - Gd, Gs = 3*diags(conc([GH, GL, Gline, Ggen])), diags(1/conc([RSUB, MOHM*np.ones(self.nbus)])) - - ''' EFFECTIVE GICS, PER-UNIT, LOSSES ''' - - # Determine Effective GIC extraction, Equivilent to (Ph + N^(-1) Pl) - Eff = hstack([ - eye(self.nxfmr), - diags(xfmrs['TurnsRatio']), - lil_matrix((self.nxfmr, self.nlines)) - ]) - - # DC Current Base & K model values - base = diags(1e3 * xfmrs['MVA'] * np.sqrt(2/3) / xfmrs['HighV']) - K, Px = diags(xfmrs['K']), nodeperm(xfmrs, 'FromBus', 'BusNum').T # Bus Assignment for PF modeling - - ''' FORMATTED CALCULATIONS ''' - - # Conductance Laplacian & Hmatrix - G = A.T@Gd@A + Gs - H = Eff@(Gd-Gd@A@iv(G)@A.T@Gd)/3 - zeta = K@iv(base)@H - - # User Retrieval & Cache for other functions - # TODO eliminate dimensions where it is not needed (i.e. at the end when getting windings) - self._A, self._G, self._H = A, G, H - self._eff, self._base = Eff, base - self._zeta, self._Px = zeta, Px - self._Gd = Gd - - @property - def A(self): - ''' - The General incidence Matrix of the GIC Network. The first N columns are substation nuetral buses, and - the remaining M are bus nodes. The first 2X rows are High and Low Windings, and the remaining are non-winding branches. - - Returns: - (N+M)x(N+M) sparse matrix - ''' - return self._A - - @property - def G(self): - ''' - Conductance Laplacian of the GIC Network. The first N nodes are substation nuetral buses, and - the remaining M nodes are bus nodes. - - Returns: - (N+M)x(N+M) sparse matrix - ''' - return self._G - - @property - def H(self): - ''' - Linear GIC Function Matrix. This matrix maps induced line voltages to (signed) effective transformer GICs. - Actual Current, not in per-unit. - Returns: - XXX - ''' - return self._H - - @property - def zeta(self): - ''' - Linear GIC Model. Returns the constant-current load (prior to absolute value) in per unit, for eahc bus. - This matrix is provided as the fastest option to model GICs in power flow. - - In Per-Unit. - - Returns: - XXX - ''' - # TODO multiply by K and do per-unit - return self._zeta - - @property - def Px(self): - ''' - Permutation matrix mapping each transformer to the bus used to model losses (default: from-bus) - ''' - return self._Px - - @property - def eff(self): - ''' - Effective GIC operator matrix. Calculates the effective transformer GICs when applied to the vector of branch GICs. - (This includes non-winding branches, trim the dimension for a quicker product). - - Returns: - XXX - ''' - # TODO multiply by K and do per-unit - return self._eff - -class GICFactory: - - '''A helper class to assist in loading data for the GIC model. Mostly intended for use when not using Power World. - - If a Power World case is being used, we recommend you use the GIC.model() function.''' - - def __init__(self) -> None: - - self.subdf = DataFrame(columns=['SubNum', 'SubR', 'Long', 'Lat']) - self.busdf = DataFrame(columns=['BusNum', 'NomVolt', 'SubNum']) - self.linedf = DataFrame(columns=['FromBus', 'ToBus', 'G']) - self.xfmrdf = DataFrame(columns=['SubNum', 'FromBus', 'ToBus', 'CFG1', 'CFG2', 'G1', 'G2', 'BD', 'Auto', 'MVA', 'K']) - self.gendf = DataFrame(columns=['BusNum', 'G']) - - def substation(self, subnum, subR, long, lat) -> None: - '''Substation ID, Earth Resistance, Longitude, Latitude''' - self.subdf.loc[len(self.subdf)] = [subnum, subR, long, lat] - - def bus(self, busnum, nomvolt, subnum) -> None: - self.busdf.loc[len(self.busdf)] = [busnum, nomvolt, subnum] - - def line(self, fbus, tbus, g) -> None: - self.linedf.loc[len(self.linedf)] = [fbus, tbus, g] - - def xfmr(self, subnum, fbus, tbus, cfg1, cfg2, g1, g2, blocked, isauto, mva=100, k=1) -> None: - self.xfmrdf.loc[len(self.xfmrdf)] = [subnum, fbus, tbus, cfg1, cfg2, g1, g2, blocked, isauto, mva, k] - - def gen(self, busnum, g) -> None: - self.gendf.loc[len(self.gendf)] = [busnum, g] - - def make(self) -> GICModel: - '''Execute the passed data and synthesize a GIC model.''' - - self.subdf = self.subdf.astype({ - 'SubNum':'int64', - 'SubR':'float64', - 'Long':'float64', - 'Lat':'float64', - }) - self.busdf = self.busdf.astype({ - 'BusNum':'int64', - 'NomVolt':'float64', - 'SubNum':'int64', - }) - self.linedf = self.linedf.astype({ - 'FromBus':'int64', - 'ToBus':'int64', - 'G':'float64' - }) - self.xfmrdf = self.xfmrdf.astype({ - 'SubNum':'int64', - 'FromBus':'int64', - 'ToBus':'int64', - 'CFG1':'string', - 'CFG2':'string', - 'G1': 'float64', - 'G2':'float64', - 'BD':'boolean', - 'Auto':'boolean', - 'MVA':'float64', - 'K':'float64' - }) - self.gendf = self.gendf.astype({ - 'BusNum':'int64', - 'G':'float64' - }) - - b, x = self.busdf, self.xfmrdf - - # Determine High/Low Windings and Turns Ratio - getBusV = lambda terminal: b.set_index('BusNum').loc[x[terminal],'NomVolt'].reset_index(drop=True) - x['FromV'], x['ToV'] = getBusV('FromBus'), getBusV('ToBus') - fromIsHigh = x['FromV']>x['ToV'] - x['HighV'] = x[['FromV', 'ToV']].max(axis=1) - x['LowV'] = x[['FromV', 'ToV']].min(axis=1) - x['TurnsRatio'] = x['HighV']/x['LowV'] - x['HighBus'] = np.where(fromIsHigh , x['FromBus'], x['ToBus']) - x['LowBus'] = np.where(~fromIsHigh, x['FromBus'], x['ToBus']) - x['CFGHigh'] = np.where(fromIsHigh , x['CFG1'] , x['CFG2']) - x['CFGLow'] = np.where(~fromIsHigh, x['CFG1'] , x['CFG2']) - x['HighG'] = np.where(fromIsHigh , x['G1'] , x['G2']) - x['LowG'] = np.where(~fromIsHigh, x['G1'] , x['G2']) - - return GICModel(self.subdf.copy(), b.copy(), self.linedf.copy(), x.copy(), self.gendf.copy()) - -# GWB App -class GIC(Indexable): - """ - Research-focused GIC (Geomagnetically Induced Current) analysis application. - - This class provides specialized functions for advanced GIC modeling, - sensitivity analysis, and matrix generation for research purposes. - These functions are intentionally untested as they are for highly - specific research and data analysis. - - For general-purpose GIC functions, use GridWorkBench methods: - - wb.gic_storm() for uniform electric field calculations - - wb.gic_clear() to clear GIC calculations - - wb.gic_load_b3d() to load B3D electric field files - - wb.calculate_gic() for basic GIC calculations - """ - - def gictool(self, calc_all_windings = False): - '''Returns a new instance of GICTool, which creates various matricies and metrics regarding GICs. - Don't set calc_all_windings=True unless you must - ''' - - gicxfmrs = self[GICXFormer,:] - branches = self[Branch,:] - gens = self[Gen,:] - subs = self[Substation,:] - buses = self[Bus,:] - - return GICTool(gicxfmrs, branches, gens, subs, buses, customcalcs=calc_all_windings) - - def storm(self, maxfield: float, direction: float, solvepf=True) -> None: - '''Configure Synthetic Storm with uniform Electric Field to be used in power flow. - - Parameters - maxfield: Maximum Electric Field magnitude in Volts/km - direction: Storm direction in Degrees (0-360) - solvepf: Use produced results in Power Flow - ''' - - self.esa.RunScriptCommand(f"GICCalculate({maxfield}, {direction}, {'YES' if solvepf else 'NO'})") - - def cleargic(self): - '''Clear the Power World Manual GIC Calculations. ''' - self.esa.RunScriptCommand(f"GICClear;") - - def loadb3d(self, ftype, fname, setuponload=True): - '''Load B3D File for an Electric Field''' - b = "YES" if setuponload else "NO" - self.esa.RunScriptCommand(f"GICLoad3DEfield({ftype},{fname},{b})") - - def minkv(self, kv): - '''Set the minimum KV of lines to contribute to GIC Calculations''' - pass - - def dBounddI(self, eta, PX, J, V): - ''' Interface Sensitivity w.r.t Transformer GIC Currents. - Parameters: - - eta: (nx1) Numpy Vector of Injection - - PX: (nxm) Transformer to loaded-bus mapping - - J: (nxn) Full AC Powerflow Jacobian at Boundary - - V: (nx1) Bus Voltage Magnitudes - Returns: - - (1xn) Numpy Array of Sensitivites - ''' - - # Category Selectors - buscat = self[Bus,['BusCat']]['BusCat'] - slk = buscat=='Slack' - pv = buscat=='PV' - pq = ~(slk | pv) # I think this is the best way - dPdT, dPdV, dQdT, dQdV = jac_decomp(J) - - # P & Q Equations ( Include Slack in row just for dimensionality - Techniqly should not be included) - A = hstack([dPdT[:,~slk], dPdV[:,pq]]) - B = hstack([dQdT[pq][:,~slk], dQdV[pq][:,pq]]) - - # PQ Voltage Diagonal - Vdiag = diagflat(V[pq]) - - # Psuedo Inverse (for eta and B) Sensitivity (N Buses) x (N XFMRs) - return (1/(eta.T@eta))@eta.T@A@B.T@sinv((B@B.T).tocsc())@Vdiag@PX[pq] - - # Without eta Psuedo - #return eta.T@A@B.T@sinv((B@B.T).tocsc())@Vdiag@PX[pq] - - - # NOTE Part of me thinks I can just DO this with the jacobian at the base case.... That would be powerful - # NOTE Then I could do multiple interfaces AT THE SAME TIME - # NOTE It would be like 'Trasporting' the solution down an interface without increasing any active power - - #return eta.T@dPdQ@diagflat(V[1:]) - - def dIdE(self, H, E=None, i=None): - ''' - Compute the Jacobean between a mesh Efield - and (absolute) Transformer GICs - - Pass H and one other parameter: - - Electric field OR Signed Nuetral XFMR Currents - - Return Jacobean (Rows -> i, Cols -> E) - ''' - - # E passed - if E is not None: - if i is None: i = H@E - else: print('(E) and (i) passed. Using (i) only.') - - # E not passed - else: - if i is None: raise Exception - - # Piece Wise Emulator - F = self.signdiag(i) - - return F@H - - def signdiag(self, x): - '''Return a diagonal matrix of the sign of a vector''' - return np.diagflat(np.sign(x)) - - - def dIdEOLD(dBdI, PX, Hx, Hy, Ex, Ey): - '''Returns tuple (Ex Sensitivities, Ey Sensitivities) w.r.t Bus GIC load model - which is presumed to be constant reactive current. Differential 1-Form - Parameters: - - dBdI: (nx1) Interface Sensitivity to Bus GIC Loads - - Px: (ixn) Permutation Matrix Mapping XFMRs to GIC-Bearing Bus - - Hx: (nxk) Flattened Tessalized Ex -> Signed XFMR GIC Matrix - - Hy: (nxk) Flattened Tessalized Ey -> Signed XFMR GIC Matrix - - Ex: (kx1) Flattened Tessalized Ex Magnitudes - - Ey: (kx1) Flattened Tessalized Ey Magnitudes - Returns: - - ((1xn) , (1xn)) Tuple of sensitivities of XFMR GICs to Ex and Ey - ''' - - ''' - Old, do not modify - sf0 = sign(Hx@Ex + Hy@Ey) - signBound = sign(dBdI@Px).T - F = diagflat(sf0*signBound) - return (dBdI@Px@F@Hx).T, (dBdI@Px@F@Hy).T - ''' - - # The sign of function inside absolute value at this solution point - sf0 = sign(Hx@Ex + Hy@Ey) # NOTE possible issue here ahhhh I need the individual signs of Ex and Ey - - # dBound/dXFMR Signs - g0 = dBdI@PX - signBound = sign(g0).T - - # Sign flipper for abs (flip if gradient and function sign disagree) - F = diagflat(sf0*signBound) - - # 1-Form Differential as tuple - return (g0@F@Hx).T, (g0@F@Hy).T - - # BELOW IS FOR ADVANCED SETTINGS - - def settings(self, value=None): - '''View Settings or pass a DF to Change Settings''' - if value is None: - return self.esa.GetParametersMultipleElement( - GIC_Options_Value.TYPE, - GIC_Options_Value.fields - )[['VariableName', 'ValueField']] - else: - self.upload({GIC_Options_Value: value}) - - def calc_mode(self, mode: str): - """GIC Calculation Mode (Either SnapShot, TimeVarying, - NonUniformTimeVarying, or SpatiallyUniformTimeVarying)""" - - self.esa.RunScriptCommand(gicoption("CalcMode",mode)) - - def pf_include(self, include=True): - '''Enable GIC for Power Flow Calculations''' - self.esa.RunScriptCommand(gicoption("IncludeInPowerFlow",include)) - - def ts_include(self, include=True): - '''Enable GIC for Time Domain''' - self.esa.RunScriptCommand(gicoption("IncludeTimeDomain",include)) - - def timevary_csv(self, fpath): - '''Pass a CSV filepath to upload Time Varying - Series Voltage Inputs for GIC - - Format Example - - Time In Seconds, 1, 2, 3 - Branch '1' '2' '1', 0.1, 0.11, 0.14 - Branch '1' '2' '2', 0.1, 0.11, 0.14 - Branch '1' '2' '3', 0.1, 0.11, 0.14 - - ''' - - # Get CSV Data - csv = read_csv(fpath, header=None) - - # Format for PW - obj = GICInputVoltObject.TYPE - fields = ['WhoAmI'] + [f'GICObjectInputDCVolt:{i+1}' for i in range(csv.columns.size-1)] - - # Send Field Data - for row in csv.to_records(False): - cmd = fcmd(obj, fields, list(row)).replace("'", "") - self.esa.RunScriptCommand(cmd) - - print("GIC Time Varying Data Uploaded") - - def model(self) -> GICModel: - '''Generate the common linear GIC model with Power World Data.''' - - # If done with a 'Direct' approach this iterative method would not be necessary. However, it is fast regardless - # and done so that users with non Power World data can easily use GICModel. - - gicsubs = self[Substation, ["SubNum", "GICSubGroundOhms", "Longitude", "Latitude"]] - gicbus = self[Bus,["BusNum", "BusNomVolt", "SubNum"]] - - linefields = ["BusNum", "BusNum:1", "GICConductance"] - xfmrfields = ["SubNum", "BusNum", "BusNum:1", "XFConfiguration", "GICCoilRFrom", "GICCoilRTo", 'GICBlockDevice', 'XFIsAutoXF', 'XFMVABase', 'GICModelKUsed'] - - branches = self[Branch,linefields+xfmrfields+['BranchDeviceType']] - isXFMR = branches['BranchDeviceType']=='Transformer' - gicbranch = branches.loc[~isXFMR,linefields] - gicxfmr = branches.loc[isXFMR,xfmrfields] - - gf = GICFactory() - - # Feed Substation Data - for rec in gicsubs.to_records(): - i, *data = rec - gf.substation(*data) - - # Feed Bus Data - for rec in gicbus.to_records(): - i, *data = rec - gf.bus(*data) - - # Feed Branch (Not Transformers !) Data - for rec in gicbranch.to_records(): - i, *data = rec - gf.line(*data) - - # Feed Transformer Data - for rec in gicxfmr.to_records(): - i, subnum, fbus, tbus, config, g1, g2, isblocked, isauto, mva, k = rec - gf.xfmr(subnum, fbus, tbus, *config.split(" - "), 1/g1, 1/g2, isblocked=='YES', isauto=='Yes', mva, k) - - return gf.make() - - -''' -TODO - REMOVE ALL OF THE BELOW, bad practices and clunky. GICModel class to be used in future. -The following three classes are helper-classes to help create GIC data. Not ideal formatting, but it works. Do not touch. -''' - - -class XFWiringType(Enum): - GWYE = auto() - WYE = auto() - DELTA = auto() - - @staticmethod - def from_str(label): - label = label.lower() - if label in ('gwye'): - return XFWiringType.GWYE - elif label in ('wye'): - return XFWiringType.WYE - elif label in ('delta'): - return XFWiringType.DELTA - else: - raise NotImplementedError - -# Custom Winding Class -class Winding: - - def __init__(self, busnum: int, subnum: int, R: float, cfg, nomvolt: float): - - # Winding Resistance and Conductance - self.R = R - self.G = 1/R - - # Substation Number and Bus Number (Convert to int if string) - self.subnum = int(subnum) - self.busnum = int(busnum) - - # Wiring - self.wiring = self.__ascfg(cfg) - - # Voltage kV - self.nomvolt = nomvolt - - - def __ascfg(self, val): - - if type(val) is XFWiringType: - return val - else: - return XFWiringType.from_str(val) - -class ParsingXFMR: - - def __init__(self, id, hv_winding: Winding, lv_winding: Winding, isauto, isblocked, mvabase, kparam, primarybus, secondarybus): - - self.id = id - - self.hv_winding = hv_winding - self.lv_winding = lv_winding - - self.highnomv = hv_winding.nomvolt - self.tapratio = hv_winding.nomvolt/lv_winding.nomvolt - - self.isauto = self.__asbool(isauto) - self.isblocked = self.__asbool(isblocked) - - self.mvabase = mvabase - self.kparam = kparam - - self.primarybus = primarybus - self.secondarybus = secondarybus - - def __asbool(self, val): - - vtype = type(val) - - if vtype is bool: - return val - elif vtype is str: - return val.lower()=='yes' - else: - return 0 - -# TODO -# - More General Implementation of Below -# - I want to give this to people for general use - -class GICTool: - '''Generatic GIC Helper Object that creates common matricies and calculations''' - - # TODO branch removal if un-needed - - def __init__(self, gicxfmrs, branches, gens, substations, buses, customcalcs=False) -> None: - - # Now Return Incidence and branch info - self.gicxfmrs: DataFrame = gicxfmrs.copy() - self.branches: DataFrame = branches - self.gens: DataFrame = gens - self.subs: DataFrame = substations - self.buses: DataFrame = buses - - # Self-Calculate Windings: - # It works but no gaurentee on reliability - self.customcalcs = customcalcs - - # Bus mapping only for final loss assignment - busmap = {n: i for i, n in enumerate(buses['BusNum'])} - self.busmap = vectorize(lambda n: busmap[n]) - self.nallbus = len(busmap) - - # Formatted in Managable Way - self.cleaned_xfmrs: list[ParsingXFMR] = self.init_xfmr_data() - - # Go Through windings and 'turn them into' branches - self.winding_data = self.init_windings() - - # Extract (Line, Series Cap, etc) Non XFMR data - self.line_data = self.init_normal_branches(branches) - - # Generator Stepup conductance - self.gen_stepup_data = self.init_genstepup() - - # Incidence matrix! - self.init_incidence() - - # Tap Ratios, Bases, Etc - self.init_xfmr_params() - - # Branch Permutation selector for low and high XFMR flows - self.init_PLH() - - # Get Relevant Substation Grounding - self.init_substation() - - # Create Full Conductance matrix - self.init_gmatrix() - - def init_xfmr_data(self): - - # Will Calculate GIC Coils if needed - if self.customcalcs: - self.init_calc_windings() - - # Divide R by 3 to get the 3-phase resistance - self.gicxfmrs['GICXFCoilR1'] /= 3 # HV Resistance - self.gicxfmrs['GICXFCoilR1:1'] /= 3 # LV Resistance - - - '''Cleans Transformer Data for GIC use''' - - winding_fields = ['BusNum3W', - 'SubNum', - 'GICXFCoilR1', - 'XFConfiguration', - 'BusNomVolt'] - common_fields = ['XFIsAutoXF', - 'GICBlockDevice', - 'GICXFMVABase', - 'GICModelKUsed', - 'BusNum3W:4', - 'BusNum3W:5' - ] - - hv_fields = winding_fields - lv_fields = [f + ':1' for f in winding_fields] - - - - # Iterate Through Transformers - formatted_xfmrs = [] - for index, xfmr in self.gicxfmrs.iterrows(): - - # Create HV and LV Windings - hw = Winding(*xfmr[hv_fields]) - lw = Winding(*xfmr[lv_fields]) - - # Create XFMR - formatted_xfmrs.append(ParsingXFMR(index, hw, lw,*xfmr[common_fields])) - - self.nxfmrs = len(formatted_xfmrs) - - return formatted_xfmrs - - def init_calc_windings(self): - '''Manual Winding Calculations - Redundant but helps with PW verification''' - - # The following calculates winding resistances for transformers with no manual GIC data - isXFMR = self.branches['BranchDeviceType']=='Transformer' - xfmrs = self.branches[isXFMR].copy() - - fromV = xfmrs['BusNomVolt'] - toV = xfmrs['BusNomVolt:1'] - hv = max([fromV, toV],axis=0) - lv = min([fromV, toV],axis=0) - - xfmrs['N'] = hv/lv - xfmrs['LowBase'] = lv**2/xfmrs['XFMVABase'] - xfmrs['HighBase'] = hv**2/xfmrs['XFMVABase'] - - - # HV Assignment (Where equal, use primary/FROM) - xfmrs.loc[:,'BusNum3W'] = where(fromV>toV, xfmrs['BusNum'], xfmrs['BusNum:1']) - xfmrs.loc[fromV==toV,'BusNum3W'] = xfmrs.loc[fromV==toV,'BusNum'] - - # LV Assignment (Where voltages equal, use secondary/TO) - xfmrs.loc[:,'BusNum3W:1'] = where(fromV=toV, xfmrs['FromBus'], xfmrs['ToBus']) - xfmrs['BusNum3W:1'] = where(fromV0]) - - nsubs = len(subIDs) - nbus = len(busIDs) - nnodes = nsubs + nbus - nbranchtot= len(wFrom) + len(lFrom) + len(genFrom) - - # Node Map to new Index (Substations are first, then buses) - nodemap = {n: i for i, n in enumerate(subIDs)} - for i, n in enumerate(busIDs): - nodemap[n] = i+nsubs - vec_nodemap = vectorize(lambda n: nodemap[n]) - - # Merge XFMR and Lines and use new mapping - # NOTE ORDER: Windings, GSU, Lines - branchIDs = arange(nbranchtot) - fromNodes = vec_nodemap(concatenate([wFrom, genFrom, lFrom])) - toNodes = vec_nodemap(concatenate([wTo, genTo, lTo])) - - # Branch Diagonal Matrix Values (3x for single phase equivilent) - self.GbranchDiag= diagflat(concatenate([wG, genG, lG])) #Hmmmmmmmmm the 3* is not consistant - - # Incidence Matrix (Without Floating Removal) - self.Ainc = lil_matrix((nbranchtot, nnodes)) - self.Ainc[branchIDs,fromNodes] = 1 - self.Ainc[branchIDs,toNodes] = -1 - - # Add to Object - self.nwinds = len(wG) - self.ngsu = len(genG) - self.nsubs = nsubs - self.nbus = nbus - self.subIDs = subIDs - self.busIDs = busIDs - self.subIDX = vec_nodemap(subIDs) - self.busIDX = vec_nodemap(busIDs) - - self.nbranchtot = nbranchtot - - def init_substation(self): - - # Get Ground Conductance - subG = self.subs[['SubNum', 'GICSubGroundOhms']].copy().set_index('SubNum') - subG = 1/subG - - # Get Only values usedDs) - self.subG = subG.loc[-self.subIDs]['GICSubGroundOhms'] - - def init_gmatrix(self): - - # Laplacian Branches - A = self.Ainc - G = self.GbranchDiag - GLap = A.T@G@A - - # Add Self Loops - di = diag_indices(len(self.subIDs)) - GLap[di] += self.subG - - self.GLap = GLap - - def init_PLH(self): - - shp = (self.nxfmrs,self.nbranchtot) - - x, y, data = self.LVMap - self.PL = coo_matrix((data,(x,y)), shape=shp) - - x, y, data = self.HVMap - self.PH = coo_matrix((data,(x,y)), shape=shp) - - def init_xfmr_params(self): - - # Tap Ratios - tr = [xfmr.tapratio for xfmr in self.cleaned_xfmrs] - self.TR = diagflat(tr) - - # DC Current Base - bases = [xfmr.mvabase * 1e3 * sqrt(2/3) /xfmr.highnomv for xfmr in self.cleaned_xfmrs] - self.Ibase = diagflat(bases) - - # K model values - k = [xfmr.kparam for xfmr in self.cleaned_xfmrs] - self.Kdiag = diagflat(k) - - # Map XFMR Loss to Buses (From for XFMRS) - self.fromIDX = self.busmap(self.mapFrom['FromBus']) - self.xfmrIDs = arange(self.nxfmrs) - ONE = ones_like(self.xfmrIDs) - - shp = (self.nallbus, self.nxfmrs) - self.PX = coo_matrix((ONE, (self.fromIDX,self.xfmrIDs)), shape=shp).tolil() - - # Below are accessing tools (Don't know best way yet) - # Final step causes some problems, summing on busses - - def Hmat(self, reduceXFMR=True): - ''' - Returns H Matrix, which maps line voltages to transformer GICS scaled by K (pre-absolute value) - If the induced XFMR winginds are zero due to no length we can reduce matrix''' - - Gd = self.GbranchDiag - A = self.Ainc - Gmat = self.GLap - Gi = inv(Gmat) - PL = self.PL # Low Flow Selector - PH = self.PH # High Flow Selector - TRi = inv(self.TR) # Tap Ratios Inverse - Ibasei = inv(self.Ibase) - K = self.Kdiag - - H = K@Ibasei@(PH + TRi@PL)@(Gd@A@Gi@A.T@Gd - Gd)/3 - if reduceXFMR: - H = H[:,-self.nlines:] - - return H.A - - def IeffMat(self, reduceXFMR=True): - ''' - Returns a matrix, which maps line voltages to per-unit transformer effective currents (pre-absolute value) - ''' - - Gd = self.GbranchDiag - A = self.Ainc - Gmat = self.GLap - Gi = inv(Gmat) - PL = self.PL # Low Flow Selector - PH = self.PH # High Flow Selector - TRi = inv(self.TR) # Tap Ratios Inverse - Ibasei = inv(self.Ibase) - - M = Ibasei@(PH + TRi@PL)@(Gd@A@Gi@A.T@Gd - Gd)/3 - if reduceXFMR: - M = M[:,-self.nlines:] - - return M.A - - def inputvec(self, include_all=False): - '''Returns vector with default induced voltages (lines only unless specified)''' - - if include_all: - vec = zeros((self.GbranchDiag.shape[0],1)) - vec[-self.nlines:,0] = self.lines['GICObjectInputDCVolt'] - else: - vec = zeros((self.nlines,1)) - vec[:,0] = self.lines['GICObjectInputDCVolt'] - return vec - - def tesselations(self, tilewidth=0.5, num_spacers=1): - '''Return Tessalized forms of the H matrix for Ex and Ey.''' - - line_km = self.line_km - line_ang = self.line_ang - - # Seperated by X, Y - cX = self.lines[['Longitude', 'Longitude:1']].copy().to_numpy() - cY = self.lines[['Latitude', 'Latitude:1']].copy().to_numpy() - - # Generate Tile Intervals - W = tilewidth - margin = num_spacers*W - X = arange(cX.min(axis=None) -margin, cX.max(axis=None)+W+margin, W) - Y = arange(cY.min(axis=None) -margin, cY.max(axis=None)+W+margin, W) # TODO Change to be one extra cell in x and y direction for SLACK VARIABLE IN E FIELD during optimization - - # Save for reference if needed - self.tile_info = X, Y, W - self.tile_count = len(X)-1, len(Y)-1, (len(X)-1)*(len(Y)-1) - - '''Tile Segment Assignment Matrix''' - - # Store X/Y length in line by line - # Dim0: X or Y data , Dim 1: Line ID, Dim 2: X Tile, Dim 3: Y Tile - R = zeros((2, self.lines.index.size, X.size-1, Y.size-1)) - - # Approximation of Coords -> KM conversion - LX = abs(sin(line_ang)*line_km) # 0 is north so sin() is X - LY = abs(cos(line_ang)*line_km) - - # 'Length' in coordinates - CLX, CLY = diff(cX), diff(cY) - - # Intentional -> 'Right' and 'Up' should be positive direction, Converts coords to KM - with errstate(divide='ignore', invalid='ignore'): - coord_to_km = concatenate([[LX/CLX[:,0]], [LY/CLY[:,0]]],axis=0) - coord_to_km[isnan(coord_to_km)] = 0 - coord_to_km = expand_dims(coord_to_km,axis=2) - - # Spanned Area of Line - lminx = cX.min(axis=1,keepdims=True) - lmaxx = cX.max(axis=1,keepdims=True) - lminy = cY.min(axis=1,keepdims=True) - lmaxy = cY.max(axis=1,keepdims=True) - - # Calculate points of line & tile intersection - Vx = repeat([X],lminx.size,axis=0) - Vx[(Vx<=lminx) | (Vx>=lmaxx)] = nan - with errstate(divide='ignore', invalid='ignore'): - Vy = CLY/CLX*(Vx-cX[:,[0]]) + cY[:,[0]] - - Hy = repeat([Y],lminx.size,axis=0) - Hy[(Hy<=lminy) | (Hy >= lmaxy)] = nan - with errstate(divide='ignore', invalid='ignore'): - Hx = (Hy-cY[:,[0]])*CLX/CLY + cX[:,[0]] - - # All Segment Points per Line - pntsX = concatenate([cX, Vx, Hx],axis=1) - pntsY = concatenate([cY, Vy, Hy],axis=1) - - # Sort Points so segments can be calculated - sortSeg = pntsX.argsort(axis=1) - sortLine = arange(lminx.size).reshape(-1,1) - pntsX = pntsX[sortLine,sortSeg] - pntsY = pntsY[sortLine,sortSeg] - - # Take line segments and determine tile assignemnt - allpnts = concatenate([[pntsX],[pntsY]],axis=0) - mdpnts = (allpnts[:,:,1:] +allpnts[:,:,:-1])/2 # Midpoints of each segment - isData = argwhere(~isnan(mdpnts)) # Data Cleaning - refpnt = array([X.min(),Y.min()]).reshape(2,1,1) # Grid ref point - tile_ids = (mdpnts-refpnt)//W # Tile Index Floor Divide - self.tile_ids = tile_ids - seg_lens = coord_to_km*abs(diff(allpnts,axis=2)) # Length in Tile - - # Final Data Format (Unpack operator in subscript requires Python 3.11 or newer) - tile_idx = tile_ids[:,isData[1][:],isData[2][:]].astype(int) - R[isData[0], isData[1], tile_idx[0], tile_idx[1]] = seg_lens[isData[0], isData[1], isData[2]] - R = R.reshape((2, R.shape[1], R.shape[2]*R.shape[3]), order='F') - - # Ex and Ey Flattened Tile -> Xfmr Matrix - Rx = R[0] - Ry = R[1] - - # God Tier H-Matrix - H = self.Hmat() - self.Hx, self.Hy = H@Rx, H@Ry - - # Return Tessalised matricies - return self.Hx, self.Hy # TODO slow, use sparse matricies? - - def tesselation_as_df(self): - '''GICTool.tesselations() must have already been called. Get Index DF Version of Hx, Hy''' - - X, Y, W = self.tile_info - tile_cols = MultiIndex.from_product( - [arange(len(X)-1), arange(len(Y)-1)], - names=['TileX', 'TileY'] - ) - Xdf = DataFrame(self.Hx, columns = tile_cols) - Ydf = DataFrame(self.Hy, columns = tile_cols) - Xdf.index.name = 'XFMR' - Ydf.index.name = 'XFMR' - return Xdf, Ydf - - def to_b3d(self, EX, EY): - '''Convert Electric Field data associated with a tesselation to a B3D Object.''' - X, Y, W = self.tile_info - return B3D.from_mesh(X[:-1]+W/2, Y[:-1]+W/2, EX, EY) diff --git a/esapp/apps/modes.py b/esapp/apps/modes.py deleted file mode 100644 index 91a18348..00000000 --- a/esapp/apps/modes.py +++ /dev/null @@ -1,35 +0,0 @@ -from ..indexable import Indexable - -import numpy as np - -# Constructing Network Matricies and other metrics -class ForcedOscillation(Indexable): - - # Need to make a DEF folder - - def sgwt_def(self, WS): - ''' - Description - Performs DEF integration on SGWT coefficient signal - Parameters - WS: Complex Wavelet Coefficients (Buses x Time x Scale) - Returns - Ed: Real-Valued Integrated DEF (Buses x Time x Scale) - ''' - - # Time Derivative - dS = np.diff(WS,axis=1,n=1) - - # Squared Magnitude of coefficients - dS = np.abs(dS)**2 - - # Integrate over time - Ediss = np.cumsum(dS, axis=1) - - return Ediss - - def orthodox_def(self): - - pass - - diff --git a/esapp/apps/network.py b/esapp/apps/network.py deleted file mode 100644 index 48f5e018..00000000 --- a/esapp/apps/network.py +++ /dev/null @@ -1,376 +0,0 @@ -from ..grid import Branch, Bus, DCTransmissionLine -from ..indexable import Indexable - -from scipy.sparse import diags, lil_matrix, csc_matrix -import numpy as np -from pandas import Series, concat -from enum import Enum - - -# Types of support branch weights -class BranchType(Enum): - LENGTH = 1 - RES_DIST = 2 # Resistance Distance - DELAY = 3 - - - -# Constructing Network Matricies and other metrics -class Network(Indexable): - - - A = None - - - def busmap(self): - ''' - Returns a Pandas Series indexed by BusNum to the positional value of each bus. - - Useful for mapping bus numbers to matrix indices. - - Returns - ------- - pd.Series - Mapping from BusNum to matrix index. - ''' - busNums = self[Bus] - return Series(busNums.index, busNums["BusNum"]) - - def incidence(self, remake=True, hvdc=False): - ''' - Returns the sparse incidence matrix of the branch network. - - Parameters - ---------- - remake : bool, optional - If True, recalculates the matrix even if cached. Defaults to True. - hvdc : bool, optional - If True, includes HVDC lines. Defaults to False. - - Returns - ------- - scipy.sparse.lil_matrix - Sparse Incidence Matrix of the branch network (Branches x Buses). - ''' - - # If already made, don't remake - if self.A is not None and not remake: - return self.A - - - - # Retrieve - fields = ["BusNum", "BusNum:1"] - branches = self[Branch][fields] - - if hvdc: - hvdc_branches = self[DCTransmissionLine,fields][fields] - branches = concat([branches,hvdc_branches], ignore_index=True) - - # Column Positions - bmap = self.busmap() - fromBus = branches["BusNum"].map(bmap).to_numpy() - toBus = branches["BusNum:1"].map(bmap).to_numpy() - - # Lengths and indexers - nbranches = len(branches) - branchIDs = np.arange(nbranches) - - # Sparse Arc-Incidence Matrix - # TODO crerate with COO for better performance - A = lil_matrix((nbranches,len(bmap))) - A[branchIDs, fromBus] = -1 - A[branchIDs, toBus] = 1 - A = csc_matrix(A) - - self.A = A - - return A - - def laplacian(self, weights: BranchType, longer_xfmr_lens=True, len_thresh=0.01, hvdc=False): - ''' - Uses the systems incident matrix and creates a laplacian with branch weights. - - Parameters - ---------- - weights : BranchType - Type of weights to use (LENGTH, RES_DIST, DELAY). - longer_xfmr_lens : bool, optional - If True, uses fictitious lengths for transformers. Defaults to True. - len_thresh : float, optional - Threshold for short lines in km. Defaults to 0.01. - hvdc : bool, optional - If True, includes HVDC lines. Defaults to False. - - Returns - ------- - scipy.sparse.csc_matrix - Sparse Laplacian matrix. - ''' - - if weights == BranchType.LENGTH: # m^-2 - W = 1/self.lengths(longer_xfmr_lens, len_thresh, hvdc)**2 - elif weights == BranchType.RES_DIST: # ohms^-2 - W = 1/self.zmag(hvdc) - elif weights == BranchType.DELAY: - W = 1/self.delay()**2 # 1/s^2 - else: - W = weights - - A = self.incidence(hvdc=hvdc) - - LAP = A.T@diags(W)@A - - return LAP.tocsc() - - ''' Branch Weights ''' - - - def lengths(self, longer_xfmr_lens=False, length_thresh_km = 0.01,hvdc=False): - ''' - Returns lengths of each branch in kilometers. - - Parameters - ---------- - longer_xfmr_lens : bool, optional - Use a ficticious length for transformers. Defaults to False. - length_thresh_km : float, optional - Minimum length threshold in km. Defaults to 0.01. - hvdc : bool, optional - If True, includes HVDC lines. Defaults to False. - - Returns - ------- - pd.Series - Lengths of branches. - ''' - - # This is distance in kilometers - # Just found out that this can be EITHER?? so have to figure - # out which to use. Porbably prefer first field - field = ["LineLengthByParameters", "LineLengthByParameters:2"] - ell = self[Branch,field][field] - - ell_user = ell["LineLengthByParameters"] - ell.loc[ell_user>0,"LineLengthByParameters:2"] = ell.loc[ell_user>0,"LineLengthByParameters"] - ell = ell["LineLengthByParameters:2"] - - if hvdc: - field = "LineLengthByParameters" - hvdc_ell = self[DCTransmissionLine,field][field] - ell = concat([ell, hvdc_ell], ignore_index=True) - - # Calculate the equivilent distance if same admittance of a line - if longer_xfmr_lens: - - fields = ["LineX:2", "LineR:2"] - branches = self[Branch, fields][fields] - - isLongLine = ell > length_thresh_km - lines = branches.loc[isLongLine] - xfmrs = branches.loc[~isLongLine] - - lineZ = np.abs(lines["LineR:2"] + 1j*lines["LineX:2"]) - xfmrZ = np.abs(xfmrs["LineR:2"] + 1j*xfmrs["LineX:2"]) - - # Average Ohms per km for lines - ZperKM = (lineZ/ell).mean() - - # BUG Mean is probably a bad way, since the line lengths are very diverse. - - # Impedence Magnitude of Transformers - psuedoLength = (xfmrZ/ZperKM).to_numpy() - - - ell.loc[~isLongLine] = psuedoLength - - # Assume XFMR 10 meter long - else: - ell.loc[ell==0] = 0.01 - - return ell - - def zmag(self, hvdc=False): - ''' - Steady-state phase delays of the branches, approximated as the angle of the complex value. - - Parameters - ---------- - hvdc : bool, optional - If True, includes HVDC lines. Defaults to False. - - Returns - ------- - pd.Series - Phase delays (radians). - ''' - Y = self.ybranch(hvdc=hvdc) - - return 1/np.abs(Y) - - def ybranch(self, asZ=False, hvdc=False): - ''' - Return Admittance (or Impedance) of Lines in Complex Form. - - Parameters - ---------- - asZ : bool, optional - If True, returns Impedance (Z). If False, returns Admittance (Y). Defaults to False. - hvdc : bool, optional - If True, includes HVDC lines. Defaults to False. - - Returns - ------- - pd.Series - Complex admittance or impedance. - ''' - - branches = self[Branch, ["LineR:2", "LineX:2"]] - - - - R = branches["LineR:2"] - X = branches["LineX:2"] - Z = R + 1j*X - - if hvdc: # Just add small impedence for HVDC - cnt = len(self[DCTransmissionLine]) - Zdc = Z[:cnt].copy() - Zdc[:] = 0.001 - Z = concat([Z, Zdc], ignore_index=True) - - if asZ: - return Z - return 1/Z - - def yshunt(self): - ''' - Return Shunt Admittance of Lines in Complex Form. - - Returns - ------- - pd.Series - Complex shunt admittance. - ''' - - branches = self[Branch, ["LineG", "LineC"]] - G = branches["LineG"] - B = branches["LineC"] - - return G + 1j*B - - def gamma(self): - ''' - Returns approximation of propagation constants for each branch. - - Returns - ------- - pd.Series - Propagation constants. - ''' - - # Length (Set Xfmr to 1 meter) - ell = self.lengths() - - # Series Parameters - Z = self.ybranch(asZ=True) - Y = self.yshunt() - - - # Correct Zero-Values - Z[Z==0] = 0.000446+ 0.002878j - Y[Y==0] = 0.000463j - - # By Length TODO check the mult/division order here. - Z /= ell # Series Value - Y /= ell # Shunt Value - - - # Propagation Parameter - return np.sqrt(Y*Z) - - - def delay(self, min_delay=10e-4): - r''' - Return the effective propagation delay (beta) of network branches. - - This method calculates the lossless propagation delay used to construct - the Delay Graph Laplacian :math:`\mathscr{L} = \mathbf{A}^\top \mathbf{T}^{-2} \mathbf{A}`. - It derives effective branch parameters by aggregating nodal shunt - admittances and series impedances. - - Mathematical Derivation - ----------------------- - The branch inductance is derived from the imaginary component of the - series branch impedance :math:`Z_{ij}`: - - .. math:: \omega L_{ij} = \text{Im}(Z^{br}_{ij}) - - The effective branch capacitance :math:`C_{ij}` accounts for capacitor - banks and constant impedance reactive loads by averaging the net nodal - capacitances :math:`C_n` at the branch terminals (using a :math:`\pi`-model - assumption): - - .. math:: C_{ij} = \frac{1}{2}(C_i + C_j) - - where :math:`\omega C_n = \text{Im}(Y^{sh}_n)`. The propagation delay - :math:`\tau_{ij}` is then computed via the propagation constant - :math:`\gamma = \sqrt{Z_{ij}Y_{ij}}`: - - .. math:: \omega_{base}\tau_{ij} = \text{Im}(\sqrt{Z_{ij}Y_{ij}}) = \beta_{ij} - - Parameters - ---------- - min_delay : float, optional - Minimum delay value permitted to prevent precision overflow during - Laplacian inversion (:math:`\mathbf{T}^{-2}`). Defaults to 10e-4. - - Returns - ------- - pd.Series - Effective propagation parameter (:math:`\beta`) for each branch, - enforced by the `min_delay` lower bound. - - Notes - ----- - For numerical stability and to avoid precision overflow when calculating - :math:`1/\tau^2`, the returned value is currently the phase constant - :math:`\beta` rather than :math:`\tau = \beta/\omega`. - ''' - - - w = 2*np.pi*60 - - # EDGE SERIES RESISTANCE & INDUCTANCE - Z = self.ybranch(asZ=True) - - # EFFECTIVE EDGE SHUNT ADMITTANCE - Ybus = self.esa.get_ybus() - SUM = np.ones(Ybus.shape[0]) - AVG = np.abs(self.incidence())/2 - Y = AVG@Ybus@SUM - - # NOTE Do I need to make G =0? - - # Propagation Constant - gam = np.sqrt(Z*Y) - beta = np.imag(gam) - - - - # NOTE The issue I am seeing is that this value tau - # is very very small in most cases. Dividing it by w - # makes it even smaller. - # So when it 1/t^2 is calculated, there is an overflow of precision. - # Therefore here (for now) we will actually just use beta - # for stability purposes - - # EFFECTIVE DELAY - tau = beta#/w - - # Enforce lower bound - tau[tau None: - - # TODO don't need to read ALL of this! - gens = self[Gen, ['GenMVRMin', 'GenMVRMax']] - buses = self[Bus] - - zipfields = ['LoadSMW', 'LoadSMVR','LoadIMW', 'LoadIMVR','LoadZMW', 'LoadZMVR'] - - # Gen Q Limits - self.genqmax = gens['GenMVRMax'] - self.genqmin = gens['GenMVRMin'] - - # Gen P Limits - self.genpmax = gens['GenMWMax'] - self.genpmin = gens['GenMWMin'] - - # Create DF that stores manipultable loads for all buses - l = buses[['BusNum', 'BusName_NomVolt']].copy() - l.loc[:,zipfields] = 0.0 - l['LoadID'] = 99 # NOTE Random Large ID so that it does not interfere - l['LoadStatus'] = 'Closed' - l = l.fillna(0) - - # Send to PW - self[Load] = l - - # Smaller DF just for updating Constant Power at Buses for Injection Interface Functions - self.DispatchPQ = l[['BusNum', 'LoadID'] + zipfields].copy() - - - - load_nom = None - load_df = None - - def randload(self, scale=1, sigma=0.1): - '''Temporarily Change the Load with random variation and scale''' - - if self.load_nom is None or self.load_df is None: - self.load_df = self[Load, 'LoadMW'] - self.load_nom = self.load_df['LoadMW'] - - self[Load, 'LoadMW'] = scale*self.load_nom* exp(sigma*random(len(self.load_nom))) - - - def solve(self, ctgs: list[Contingency] = None): - - - return "Depricated functions used." - - # Cast to List - if ctgs is None: - ctgs = ["SimOnly"] - if not isinstance(ctgs, list): - ctgs: list[Contingency] = [ctgs] - - # Prepare Data Fields - gtype = self.metric["Type"] - field = self.metric["Static"] - keyFields = self.keys(gtype) - - # Get Keys OR Values - def get(field: str = None) -> DataFrame: - if field is None: - data = self.get(gtype) - else: - self.pflow() - data = self.get(gtype, [field]) - data.rename(columns={field: "Value"}, inplace=True) - data.drop(columns=keyFields, inplace=True) - - return data - - # Initialize DFs - meta = DataFrame(columns=["Object", "ID-A", "ID-B", "Metric", "Contingency"]) - df = DataFrame(columns=["Value", "Reference"]) - keys = get() - - # Add All Meta Records - for ctg in ctgs: - ctgMeta = DataFrame( - { - "Object": gtype, - "ID-A": keys.iloc[:, 0], - "ID-B": keys.iloc[:, 1] if len(keys.columns) > 1 else nan, - "Metric": self.metric["Units"], - "Contingency": ctg, - } - ) - meta = concat([meta, ctgMeta], ignore_index=True) - - # If Base Case Does not Solve, Return N/A vals - try: - refSol = get(field) - - # Set Reference (i.e. No CTG) and Solve - self.esa.RunScriptCommand(f"CTGSetAsReference;") - except: - print("Loading Does Not Converge.") - df = DataFrame( - nan, index=["Value", "Reference"], columns=range(len(ctgs)) - ) - return (meta, df) - - # For Each CTG - for ctg in ctgs: - # Empty DF - data = DataFrame(columns=["Value", "Reference"]) - - # Apply CTG - if ctg != "SimOnly": - self.esa.RunScriptCommand(f"CTGApply({ctg})") - - # Solve, Drop Keys - try: - data["Value"] = get(field) - except: - data["Value"] = nan - - # Set Reference Values - data["Reference"] = refSol - - # Un-Apply CTG - self.esa.RunScriptCommand(f"CTGRestoreReference;") - - # Add Data to Main - df = concat([df, data], ignore_index=True) - - return (meta, df.T) - - def gensAbovePMax(self, p=None, isClosed=None, tol=0.001): - '''Returns True if any CLOSED gens are outside P limits. Active function.''' - if p is None: - p = self[Gen, 'GenMW']['GenMW'] - - isHigh = p > self.genpmax + tol - isLow = p < self.genpmin - tol - if isClosed is None: - isClosed = self[Gen, 'GenStatus']['GenStatus'] =='Closed' - violation = isClosed & (isHigh | isLow) - - return any(violation) - #return any(p > self.genpmax + tol) or any(p < self.genpmin - tol) - - def gensAboveQMax(self, q=None, isClosed=None, tol=0.001): - '''Returns True if any CLOSED gens are outside Q limits. Active function.''' - if q is None: - q = self[Gen, 'GenMVR']['GenMVR'] - - isHigh = q > self.genqmax + tol - isLow = q < self.genqmin - tol - if isClosed is None: - isClosed = self[Gen, 'GenStatus']['GenStatus'] =='Closed' - violation = isClosed & (isHigh | isLow) - - return any(violation) - #return any(q > self.genqmax + tol) or any(q < self.genqmin - tol) - - # TODO The only thing I have to do is switch slack bus to an interface bus - # NOTE This is because we are interested in maximum POSSIBLE injection of MW. - # So then if all gens are at max but injection buses, one of them needs to be slack bus - # if we want the flow values to be realistic - def continuation_pf(self, interface, initialmw = 0, minstep=1, maxstep=50, maxiter=200, nrtol=0.0001, verbose=False, boundary_func=None, restore_when_done=False, qlimtol=0, plimtol=None, bifur_check=True): - ''' - Continuation Power Flow. Will Find the maximum INjection MW through an interface. As an iterator, the last element will be the boundary value. - The continuation will begin from the state - params: - -minstep: Accuracy in Max Injection MW - -maxstep: largest jump in MW - -initial_mw: starting interface MW. Could speed up convergence if you know a lower limit - -nrtol: Newton rhapston MVA tolerance - -boundary_func: Optional, pass a callable object to be called at boundary. Return of callable will be put into obj.X - -qlim_tol: Tolerance on detecting if a generator is above its Q limits (None = Do not check) - -plimtol: Tolerance on detecting if a generator is above its P Limits (None = Do not check) - returns: - - iterator with elements being the magnitude of interface injection. The last element is the CPF solution. - ''' - - # Helper Function since this is common - def log(x,**kwargs): - if verbose: print(x,**kwargs) - - # 1. Solved -> Last Solved Solution, 2. Stable -> Known HV Solution - if restore_when_done: - self.save_state('BACKUP') - - # Initialize Stability State Chain - self.chain() - self.pushstate() - self.pushstate() - - # For solution Continuity - self.save_state('PREV') - - # Set NR Tolerance in MVA - self.set_mva_tol(nrtol) - - log(f'Starting Injection at: {initialmw:.4f} MW ') - - # Misc Iteration Tracking - backstepPercent=0.25 - pnow, step = initialmw, maxstep # Current Interface MW, Step Size in MW - pstable, pprev = initialmw, initialmw - qstable, qprev = -inf, -inf - qmax, pmax = -inf, initialmw # Maximum Observed Sum MVAR - laststableindex = 0 - - - # Continuation Loop - for i in arange(maxiter): - - # Set Injection for this iteration - self.setload(SP=-pnow*interface) - - try: - - # Do Power Flow - log(f'\nPF: {pnow:>12.4f} MW', end='\t') - self.pflow() - - # Fail if slack is at max - qall = self[Gen, ['GenMVR','GenStatus']] - qclosed = qall['GenStatus']=='Closed' - - # Check Max Reactive Output - if qlimtol is not None and self.gensAboveQMax(qall['GenMVR'], qclosed,tol=qlimtol): - log(' Q+ ', end=' ') - raise GeneratorLimitException - - # Check Max Power Output (Rarer but happens) - # Need to be enabled by user because they might not care about slack - if plimtol is not None and self.gensAbovePMax(None, qclosed, tol=plimtol): - log(' P+ ', end=' ') - raise GeneratorLimitException - - # Indicator Data - qsum = qall['GenMVR'].sum() - - # Stability Indicator - # 0 - Atleast 1 previous solution - # 1 - Net Q of generators risen above a previous stable solution - # 3 - Net Q of generators risen above a known maximum - # 2 - MW Injection at detected Q drop is less than MW of previous known solution - # (Does not actually gaurentee stable - but the previous is DEFINITLY stable) - isStable = (i > 0) and (qsum > qstable) and (qsum > qmax) and (pnow > pstable) and (pnow > pmax) - - - ''' STATE SAVE DETERMINATION - Criteria: Stability''' - - # Stable Solution Candidate Actions - if isStable: - - log(' ST ', end=' ') - self.pushstate() # Push in Stable Chain - - # Don't yield on first stable - if laststableindex > 0: - self.irestore(1) - yield pprev - self.irestore(0) - - laststableindex = i - pstable, qstable = pprev, qprev - - # Bifurcation Action - if bifur_check: - - # After so many unstable solutions we can quit and assume bifurcation - if i - laststableindex > 4: - log(f' SL+ ', end=' ') - raise BifurcationException - - - # Store as solved solution - but not stable - self.save_state('PREV') - - pmax, qmax = max(pnow, pprev), max(qsum, qprev) - pprev, qprev = pnow, qsum - - - - # Yield Stable Solutions - #if pstable is not None: - #yield pprev # NOTE I thought should be yeilding stable but this gives the clearly more correct answer - - except BifurcationException as e: - - pnow = pstable - pprev = pstable - qprev = qstable - step *= backstepPercent - self.irestore(1) - - # Catch Fails, then backstep injection - except (Exception, GeneratorLimitException) as e: - - log('XXX', end=' ') - - # Failure on first iteration - return and restore the state the function was called in - if i==0: - log('First Injection Failed. This could be due to a LV Solution, or it is already past the boundary.') - #self.irestore(0) - self.restore_state('PREV') - log(f'-----------EXIT-----------\n\n') - return - - # Non-Bifurcative Failure, backstep binary search - pnow = pprev - #pnow, pprev = pstable, pstable - #qprev = qstable - step *= backstepPercent - if pprev!=0: - self.irestore(1) - #self.restore_state('PREV') - - # Terminating Condition - if step12.4f} MW\t ! ') - log(f'Calling Boundary Function...') - boundary_func.X = boundary_func() - - # Set Dispatch SMW to Zero - self.setload(SP=0*interface) - - # TODO delete states that were saved - - # Restore to before CPF Regardless of everything - if restore_when_done: - self.restore_state('BACKUP') - log(f'-----------EXIT-----------\n\n') - - ''' - The following functions probably deserve their own object or atleast be relocated - ''' - - def chain(self, maxstates=2): - '''Initiate a state-chain for iterative functions that require state restoration. The data of n states will be tracked and - managed as a queue. - ''' - self.maxstates = maxstates - self.stateidx = -1 - - # TODO delete old states when this is called - - def pushstate(self, verbose=False): - '''Update the PF chain queue with the current state. The n-th state will be forgotten.''' - - # Each line represents a call to push() with nmax = 3 - # 0* <- push() State 0 added (sidx = 0) - # 0 1* <- push() State 1 added (sidx = 1) - # 0 1 2* <- push() State 2 added (sidx = 2) - # 1 2 3* <- push() State 3 added (sidx = 3) and 0 was deleted - # 2 3 4* <- push() State 4 added (sidx = 4) and 1 was deleted - - # Save current state on the right of the queue - self.stateidx += 1 - self.save_state(f'GWBState{self.stateidx}') - - if verbose: print(f'Pushed States -> {self.stateidx}, Delete -> {self.stateidx-self.maxstates}') - - # Try and delete the state (nmax) behind this one - if self.stateidx >= self.maxstates: - self.delete_state(f'GWBState{self.stateidx-self.maxstates}') - - def istore(self, n:int=0, verbose=False): - ''' - Instead of pushing a new state to the save chain, this will update the nth state in the chain. - - # Each line represents a call to push() with nmax = 3 - # 0* <- push() State 0 added (sidx = 0) - # 0 1* <- push() State 1 added (sidx = 1) - # 0 1 2* <- push() State 2 added (sidx = 2) - # 1 2 3* <- push() State 3 added (sidx = 3) and 0 was deleted - # 2 3 4* <- push() State 4 added (sidx = 4) and 1 was deleted - # 2 3 4' <- assign(0) modifies State 4 - # 3 4' 5 <- push() State 5 added (sidx = 5) - ''' - - # Can only go back number of states - if n > self.maxstates or n > self.stateidx: - raise Exception - - if verbose: print(f'Restore -> {self.stateidx-n}') - - # Restore - self.save_state(f'GWBState{self.stateidx-n}') - - def irestore(self, n:int=1, verbose=False): - ''' - Regress backward in the saved states. Consecutive calls do not affect which state is restored. - Example: - back(1) # Loads 2 states ago - back(0) # Will load the same state - - # Each line represents a call to push() with nmax = 3 - # 0* <- push() State 0 added (sidx = 0) - # 0 1* <- push() State 1 added (sidx = 1) - # 0 1 2* <- push() State 2 added (sidx = 2) - # 1 2 3* <- push() State 3 added (sidx = 3) and 0 was deleted - # 2 3 4* <- push() State 4 added (sidx = 4) and 1 was deleted - # 2 3* 4 <- back(1) State 3 is restored - # 2* 3 4 <- back(2) State 2 is restored - # 2 3 4* <- back(0) State 4 is restored - - ''' - # Can only go back number of states - if n > self.maxstates or n > self.stateidx: - if verbose: print(f'Restoration Failure') - raise Exception - - if verbose: print(f'Restore -> {self.stateidx-n}') - - # Restore - self.restore_state(f'GWBState{self.stateidx-n}') - - def setload(self, SP=None, SQ=None, IP=None, IQ=None, ZP=None, ZQ=None): - - '''Set ZIP loads by bus. Vector of loads must include every bus. - The loads set by this function are independent of existing loads. - This serves as a functional and fast way to apply 'deltas' to base case bus loads. - Load ID 99 is used so that it does not interfere with existing loads. - This is a TEMPORARY load. Functions in GWB can and will override any Load ID 99. - params: - SP: Constant Active Power - SQ: Constant Reactive Power - IP: Constant Real Current - IQ: Constant Reactive Current - ZP: Constant Resistance - ZQ: Constant Reactance''' - - fields = ['BusNum', 'LoadID'] - - if SP is not None: - fields.append('LoadSMW') - self.DispatchPQ.loc[:,'LoadSMW'] = SP - if SQ is not None: - fields.append('LoadSMVR') - self.DispatchPQ.loc[:,'LoadSMVR'] = SQ - if IP is not None: - fields.append('LoadIMW') - self.DispatchPQ.loc[:,'LoadIMW'] = IP - if IQ is not None: - fields.append('LoadIMVR') - self.DispatchPQ.loc[:,'LoadIMVR'] = IQ - if ZP is not None: - fields.append('LoadZMW') - self.DispatchPQ.loc[:,'LoadZMW'] = ZP - if ZQ is not None: - fields.append('LoadZMVR') - self.DispatchPQ.loc[:,'LoadZMVR'] = ZQ - - self[Load] = self.DispatchPQ.loc[:,fields] - - def clearloads(self): - ''' - Clears the script-applied load of the context - ''' - - zipfields = ['LoadSMW', 'LoadSMVR','LoadIMW', 'LoadIMVR','LoadZMW', 'LoadZMVR'] - self.DispatchPQ.loc[:, zipfields] = 0 - - self[Load] = self.DispatchPQ \ No newline at end of file diff --git a/esapp/dev/PWRaw b/esapp/components/PWRaw similarity index 100% rename from esapp/dev/PWRaw rename to esapp/components/PWRaw diff --git a/esapp/dev/README.md b/esapp/components/README.md similarity index 80% rename from esapp/dev/README.md rename to esapp/components/README.md index 0c9d83a9..79667556 100644 --- a/esapp/dev/README.md +++ b/esapp/components/README.md @@ -1,3 +1,52 @@ +# Component Generation Scripts + +This folder contains tools for generating the Python class definitions used by ESApp +from PowerWorld's schema definition file. + +## Overview + +The `esapp/components/` module contains auto-generated Python code that defines: +- **grid.py** - GObject subclasses for all PowerWorld object types (Bus, Gen, Load, Branch, etc.) +- **ts_fields.py** - Transient Stability field constants for IDE autocomplete (TS, TSField) + +These files are generated by parsing the `PWRaw` schema file exported from PowerWorld. + +## Files in This Directory + +| File | Description | +|------|-------------| +| `generate_components.py` | Python script that parses PWRaw and generates grid.py and ts_fields.py | +| `PWRaw` | Tab-separated schema file exported from PowerWorld containing all object/field definitions | + +## Running the Generator + +To regenerate the component files after updating the PWRaw schema: + +```bash +cd esapp/components +python generate_components.py +``` + +This will regenerate: +- `grid.py` - All GObject subclasses +- `ts_fields.py` - TS field constants + +## Usage in Code + +After generation, import components from the `esapp.components` module: + +```python +from esapp.components import Bus, Gen, Load, Branch, TS, TSField + +# Use grid components +df = wb[Bus, Bus.BusNum, Bus.BusName, Bus.BusPUVolt] + +# Use TS fields for dynamics simulation +wb.dyn.watch(Gen, [TS.Gen.P, TS.Gen.Speed, TS.Gen.Delta]) +``` + +--- + # PWRaw File Schema Description **File Format:** Tab-Separated Values (TSV) @@ -54,6 +103,8 @@ How the symbols in **Column 3** combine to form unique keys for common objects: * **Real:** Floating-point numbers (e.g., Voltage, MW, Resistance). * **String:** Text (e.g., Names, "Yes/No", Labels). +--- + # SubData SubData sections store nested/hierarchical data that belongs to a parent object. They appear in AUX files immediately after the parent record and are NOT available through CSV exports. @@ -111,4 +162,4 @@ for _, row in df.iterrows(): To find which SubData sections are available for an object type: 1. Check Column 2 ("SUBDATA") in `PWRaw.tsv` - objects with `Yes` support SubData 2. Export the object to AUX format and inspect the file -3. Refer to PowerWorld's Auxiliary File Format documentation \ No newline at end of file +3. Refer to PowerWorld's Auxiliary File Format documentation diff --git a/esapp/components/__init__.py b/esapp/components/__init__.py new file mode 100644 index 00000000..b7982f08 --- /dev/null +++ b/esapp/components/__init__.py @@ -0,0 +1,28 @@ +""" +esapp.components: PowerWorld Component Definitions +=================================================== + +This module contains Python class definitions for PowerWorld Simulator objects +and Transient Stability field constants. + +Contents: + - ``grid``: GObject subclasses for all PowerWorld object types (Bus, Gen, Load, etc.) + - ``ts_fields``: Transient Stability field constants for IDE intellisense (TS, TSField) + - ``gobject``: Base GObject class and FieldPriority enum + +Usage: + >>> from esapp.components import Bus, Gen, Load, Branch + >>> from esapp.components import TS, TSField + +Note: + grid.py and ts_fields.py are auto-generated by ``generate_components.py`` + using the PWRaw schema file. Do not edit these files directly. +""" + +from .gobject import GObject + +# Re-export all GObject subclasses from grid.py +from .grid import * + +# Re-export TS intellisense classes from ts_fields.py +from .ts_fields import TS, TSField diff --git a/esapp/components/generate_components.py b/esapp/components/generate_components.py new file mode 100644 index 00000000..9d949ded --- /dev/null +++ b/esapp/components/generate_components.py @@ -0,0 +1,450 @@ +""" +Parses the PowerWorld 'Case Objects Fields' Text File and generates a Python +module (components.py) containing the structured data. +""" +import os +import re +from collections import OrderedDict, defaultdict +from dataclasses import dataclass, field +from enum import Flag, auto +from typing import Optional, List, Dict, Set + + +class FieldRole(Flag): + """Maps to PWRaw Key/Required column symbols.""" + STANDARD = 0 + PRIMARY_KEY = auto() # * + ALTERNATE_KEY = auto() # *A* + COMPOSITE_KEY_1 = auto() # *1* + COMPOSITE_KEY_2 = auto() # *2* + COMPOSITE_KEY_3 = auto() # *3* + SECONDARY_ID = auto() # *2B* + CIRCUIT_ID = auto() # *4B* + BASE_VALUE = auto() # ** + STANDARD_FIELD = auto() # < + + +@dataclass +class FieldDefinition: + """Represents a single field/variable within a PowerWorld object type.""" + variable_name: str + python_name: str + concise_name: str + data_type: str + description: str + role: FieldRole + enterable: bool + available_list: str = "" + + @property + def is_primary(self) -> bool: + return bool(self.role & ( + FieldRole.PRIMARY_KEY | FieldRole.COMPOSITE_KEY_1 | + FieldRole.COMPOSITE_KEY_2 | FieldRole.COMPOSITE_KEY_3 | + FieldRole.SECONDARY_ID | FieldRole.CIRCUIT_ID + )) + + @property + def is_secondary(self) -> bool: + return bool(self.role & ( + FieldRole.ALTERNATE_KEY | FieldRole.BASE_VALUE + )) + + @property + def is_base_value(self) -> bool: + return bool(self.role & FieldRole.BASE_VALUE) + + +@dataclass +class ObjectTypeDefinition: + """Represents a PowerWorld object type (e.g., Gen, Bus, Load).""" + name: str + subdata_allowed: bool + fields: list = field(default_factory=list) + + +@dataclass +class TSFieldDefinition: + """Represents a Transient Stability result field.""" + pw_field_name: str # Full PowerWorld field name (e.g., "TSBusVPU") + concise_name: str # Short display name (e.g., "TSVpu") + description: str # Human-readable description + python_attr: str # Python-safe attribute name (e.g., "VPU") + object_type: str # Which GObject it belongs to (e.g., "Bus") + + +class ComponentGenerator: + """Handles parsing of PowerWorld export files and generation of Python modules.""" + + EXCLUDE_OBJECTS = { + 'AlarmOptions', 'GenMWMaxMin_GenMWMaxMinXYCurve', + 'GenMWMax_SolarPVBasic1', 'GenMWMax_SolarPVBasic2', + 'GenMWMax_TemperatureBasic1', 'GenMWMax_WindBasic', + 'GenMWMax_WindClass1', 'GenMWMax_WindClass2', 'GenMWMax_WindClass3', + 'GenMWMax_WindClass4', 'GICGeographicRegionSet', 'GIC_Options', + 'LPOPFMarginalControls', 'MvarMarginalCostValues', 'MWMarginalCostValues', + 'NEMGroupBranch', 'NEMGroupGroup', 'NEMGroupNode', 'PieSizeColorOptions', + 'PWBranchDataObject', 'RT_Study_Options', 'SchedSubscription', + 'TSFreqSummaryObject', 'TSModalAnalysisObject', 'TSSchedule', + 'Exciter_Generic', 'Governor_Generic', + 'InjectionGroupModel_GenericInjectionGroup', 'LoadCharacteristic_Generic', + 'WeatherPathPoint', 'TSTimePointSolutionDetails' + } + + EXCLUDE_FIELDS = { + 'BusMarginalControl', 'BusMCMVARValue', 'BusMCMWValue', 'LoadGrounded', + 'GEDateIn', 'GEDateOut' + } + + # Manual field definitions for fields not properly defined in PWRaw + # Format: {ObjectType: [FieldDefinition, ...]} + MANUAL_FIELDS = { + 'Substation': [ + FieldDefinition( + variable_name='GICUsedSubGroundOhms', + python_name='GICUsedSubGroundOhms', + concise_name='RgroundUsed', + data_type='Real', + description='Substation grounding ohms actually used in the geomagnetic induced current calculations.', + role=FieldRole.STANDARD, + enterable=False + ), + ], + } + + DTYPE_MAP = {"String": "str", "Real": "float", "Integer": "int"} + + TS_OBJECT_MAPPING = { + 'TSBus': 'Bus', + 'TSGen': 'Gen', + 'TSACLine': 'Branch', + 'TSLoad': 'Load', + 'TSShunt': 'Shunt', + 'TSArea': 'Area', + 'TSSub': 'Substation', + 'TSSystem': 'System', + 'TSInjectionGroup': 'InjectionGroup', + } + + def __init__(self, raw_file_path: str): + self.raw_file_path = raw_file_path + self.objects: OrderedDict[str, ObjectTypeDefinition] = OrderedDict() + self.ts_fields: Dict[str, List[TSFieldDefinition]] = {} + + def parse(self) -> None: + """Parses the raw file and populates internal structures.""" + self._parse_components() + self._extract_ts_fields() + + def _parse_components(self) -> None: + """Parses object definitions for components.py.""" + current_obj: Optional[ObjectTypeDefinition] = None + + with open(self.raw_file_path, 'r', encoding='utf-8') as f: + next(f, None) # Skip header + + for line in f: + line = line.rstrip('\n') + if not line.strip(): + continue + + parts = line.split('\t') + + if not line.startswith('\t'): + obj_name = parts[0].strip() + + if not obj_name or len(obj_name) <= 1 or obj_name in self.EXCLUDE_OBJECTS: + current_obj = None + continue + + subdata = self._get_column(parts, 1).lower() == 'yes' + current_obj = ObjectTypeDefinition(name=obj_name, subdata_allowed=subdata) + self.objects[obj_name] = current_obj + + elif current_obj is not None: + var_name = self._get_column(parts, 3) + if not var_name or var_name in self.EXCLUDE_FIELDS or '/' in var_name: + continue + + key_str = self._get_column(parts, 2) + enterable = self._parse_enterable(self._get_column(parts, 8)) + + field_def = FieldDefinition( + variable_name=var_name, + python_name=self._sanitize_for_python(var_name), + concise_name=self._get_column(parts, 4), + data_type=self._get_column(parts, 5), + description=self._get_column(parts, 6, strip_q=True), + role=self._parse_key_symbol(key_str), + enterable=enterable, + available_list=self._get_column(parts, 7, strip_q=True) + ) + current_obj.fields.append(field_def) + + def _extract_ts_fields(self) -> None: + """Extracts TS fields for ts_fields.py.""" + # Track seen python attributes per object type to avoid duplicates (e.g. from indexed fields) + seen_attrs: Dict[str, Set[str]] = defaultdict(set) + + with open(self.raw_file_path, 'r', encoding='utf-8') as f: + next(f, None) + + for line in f: + line = line.rstrip('\n') + if not line.strip() or not line.startswith('\t'): + continue + + parts = line.split('\t') + var_name = self._get_column(parts, 3) + if not var_name: + continue + + # Identify Object Type + matched_type = None + for prefix, obj_type in self.TS_OBJECT_MAPPING.items(): + if var_name.startswith(prefix): + matched_type = obj_type + break + + if not matched_type: + continue + + if 'TSSave' in var_name or 'TSResult' in var_name: + continue + + # Handle Indexed Fields (e.g. TSBusInput:1 -> TSBusInput) + # We strip the index to create a base field. + # The generated TSField class will support indexing. + base_var_name = re.sub(r':\d+$', '', var_name) + + # Determine Python Attribute Name + # Remove prefix (e.g. TSBus) + prefix_len = len([p for p in self.TS_OBJECT_MAPPING.keys() if base_var_name.startswith(p)][0]) + python_attr = base_var_name[prefix_len:] + python_attr = self._sanitize_for_python(python_attr) + + if not python_attr: + continue + + if python_attr in seen_attrs[matched_type]: + continue + + seen_attrs[matched_type].add(python_attr) + + concise_name = self._get_column(parts, 4) + description = self._get_column(parts, 6, strip_q=True) + + field_def = TSFieldDefinition( + pw_field_name=base_var_name, + concise_name=concise_name, + description=description, + python_attr=python_attr, + object_type=matched_type + ) + + if matched_type not in self.ts_fields: + self.ts_fields[matched_type] = [] + self.ts_fields[matched_type].append(field_def) + + def generate_components(self, output_path: str) -> None: + """Writes grid.py to the components module.""" + preamble = """# +# -*- coding: utf-8 -*- +# This file is auto-generated by esapp/components/generate_components.py. +# Do not edit this file manually, as your changes will be overwritten. + +from .gobject import * +""" + + with open(output_path, 'w', encoding='utf-8') as f: + f.write(preamble) + + for obj_name, obj_def in self.objects.items(): + cls_name = self._sanitize_for_python(obj_name.split(" ")[0]) + f.write(f'\n\nclass {cls_name}(GObject):') + + # Inject manual fields for this object type + if obj_name in self.MANUAL_FIELDS: + for manual_field in self.MANUAL_FIELDS[obj_name]: + obj_def.fields.append(manual_field) + + obj_def.fields.sort(key=self._get_sort_key) + + for field_def in obj_def.fields: + dtype = self.DTYPE_MAP.get(field_def.data_type, "str") + pw_name = self._fix_pw_string(field_def.python_name) + flags = self._build_field_priority_flags(field_def) + safe_desc = self._sanitize_description(field_def.description) + + f.write(f'\n\t{field_def.python_name} = ("{pw_name}", {dtype}, {flags})') + f.write(f'\n\t"""{safe_desc}"""') + + f.write(f"\n\n\tObjectString = '{obj_name}'\n") + + def generate_ts_fields(self, output_path: str) -> None: + """Writes ts_fields.py to the components module.""" + preamble = '''# +# -*- coding: utf-8 -*- +# This file is auto-generated by esapp/components/generate_components.py. +# Do not edit this file manually, as your changes will be overwritten. +# +# Transient Stability Field Constants for IDE Intellisense +# +# Usage: +# from esapp.components import TS, Gen +# pw.dyn.watch(Gen, [TS.Gen.P, TS.Gen.Speed]) +# + +from dataclasses import dataclass + + +@dataclass(frozen=True) +class TSField: + """ + Represents a Transient Stability result field. + + Attributes: + name: The PowerWorld field name string + description: Human-readable description of the field + + """ + name: str + description: str = "" + + def __str__(self) -> str: + return self.name + + def __repr__(self) -> str: + return f"TSField({self.name!r})" + + def __getitem__(self, index: int) -> "TSField": + """Allows accessing indexed fields like TS.Bus.Input[1].""" + return TSField(f"{self.name}:{index}", self.description) + + +class TS: + """ + Transient Stability Field Constants for Intellisense. + + Provides IDE autocomplete for all available TS result fields organized + by object type (Bus, Gen, Branch, Load, Shunt, Area, etc.). + + Example: + >>> from esapp.components import TS, Gen + >>> pw.dyn.watch(Gen, [TS.Gen.P, TS.Gen.Speed, TS.Gen.Delta]) + """ +''' + with open(output_path, 'w', encoding='utf-8') as f: + f.write(preamble) + + for obj_type in sorted(self.ts_fields.keys()): + fields = self.ts_fields[obj_type] + + f.write(f'\n class {obj_type}:\n') + f.write(f' """TS result fields for {obj_type} objects."""\n') + + for field_def in sorted(fields, key=lambda x: x.python_attr): + safe_desc = self._sanitize_description(field_def.description) + f.write(f' {field_def.python_attr} = TSField("{field_def.pw_field_name}", "{safe_desc}")\n') + + f.write('\n') + + total_fields = sum(len(v) for v in self.ts_fields.values()) + print(f"Generated {output_path} with {total_fields} TS fields") + + # --- Helpers --- + + @staticmethod + def _get_column(parts: list, index: int, strip_q: bool = False) -> str: + value = parts[index].strip() if index < len(parts) else "" + if strip_q and value.startswith("'") and value.endswith("'"): + return value[1:-1] + return value + + @staticmethod + def _sanitize_for_python(name: str) -> str: + new_name = name.replace(":", "__") + new_name = new_name.replace(" ", "___") + if new_name and new_name[0].isdigit(): + new_name = 'Three' + new_name[1:] if new_name.startswith('3') else '_' + new_name + return new_name + + @staticmethod + def _fix_pw_string(name: str) -> str: + new_name = "3" + name[5:] if name.startswith("Three") else name + new_name = new_name.replace('__', ':') + new_name = new_name.replace('___', ' ') + if new_name.startswith('_') and name.startswith('_') and not name.startswith('__'): + # Revert leading underscore added for digit + new_name = new_name[1:] + return new_name + + @staticmethod + def _sanitize_description(desc: str) -> str: + desc = desc.replace("\\", "/") + desc = desc.replace('"""', r'\"\"\"') + desc = desc.replace('"', r'\"') + return desc + + @staticmethod + def _parse_key_symbol(symbol: str) -> FieldRole: + symbol = symbol.strip() + role = FieldRole.STANDARD + if '*1*' in symbol: role |= FieldRole.COMPOSITE_KEY_1 + elif '*2B*' in symbol: role |= FieldRole.SECONDARY_ID + elif '*4B*' in symbol: role |= FieldRole.CIRCUIT_ID + elif '*2*' in symbol: role |= FieldRole.COMPOSITE_KEY_2 + elif '*3*' in symbol: role |= FieldRole.COMPOSITE_KEY_3 + elif '*A*' in symbol: role |= FieldRole.ALTERNATE_KEY + elif '**' in symbol: role |= FieldRole.BASE_VALUE + elif '*' in symbol: role |= FieldRole.PRIMARY_KEY + if '<' in symbol: role |= FieldRole.STANDARD_FIELD + return role + + @staticmethod + def _parse_enterable(value: str) -> bool: + value = value.strip().lower() + if value.startswith("'") and value.endswith("'"): + value = value[1:-1] + return value in ('yes', 'edit mode only') + + @staticmethod + def _get_sort_key(field_def: FieldDefinition) -> int: + role = field_def.role + if role & FieldRole.COMPOSITE_KEY_1 or role & FieldRole.PRIMARY_KEY: return 0 + if role & FieldRole.COMPOSITE_KEY_2: return 1 + if role & FieldRole.COMPOSITE_KEY_3: return 2 + if role & FieldRole.ALTERNATE_KEY: return 3 + if role & FieldRole.SECONDARY_ID or role & FieldRole.CIRCUIT_ID: return 4 + if role & FieldRole.BASE_VALUE: return 5 + return 10 + + @staticmethod + def _build_field_priority_flags(field_def: FieldDefinition) -> str: + flags = [] + if field_def.is_primary: flags.append('FieldPriority.PRIMARY') + elif field_def.is_secondary: flags.append('FieldPriority.SECONDARY') + else: flags.append('FieldPriority.OPTIONAL') + if field_def.is_base_value: flags.append('FieldPriority.REQUIRED') + if field_def.enterable: flags.append('FieldPriority.EDITABLE') + return ' | '.join(flags) + + +if __name__ == "__main__": + RAW_IN = 'PWRaw' + + script_dir = os.path.dirname(os.path.abspath(__file__)) + + RAW_FILE_PATH = os.path.join(script_dir, RAW_IN) + OUTPUT_PY_PATH = os.path.join(script_dir, 'grid.py') + TS_OUTPUT_PATH = os.path.join(script_dir, 'ts_fields.py') + + generator = ComponentGenerator(RAW_FILE_PATH) + generator.parse() + print(f"\nParsing complete.\n") + + generator.generate_components(OUTPUT_PY_PATH) + print(f"Successfully generated -> grid.py\n") + + generator.generate_ts_fields(TS_OUTPUT_PATH) + print(f"Successfully generated -> ts_fields.py\n") \ No newline at end of file diff --git a/esapp/gobject.py b/esapp/components/gobject.py similarity index 100% rename from esapp/gobject.py rename to esapp/components/gobject.py diff --git a/esapp/grid.py b/esapp/components/grid.py similarity index 99% rename from esapp/grid.py rename to esapp/components/grid.py index 4fd1ace5..29e599c5 100644 --- a/esapp/grid.py +++ b/esapp/components/grid.py @@ -1,6 +1,6 @@ # # -*- coding: utf-8 -*- -# This file is auto-generated by generate_components.py. +# This file is auto-generated by esapp/components/generate_components.py. # Do not edit this file manually, as your changes will be overwritten. from .gobject import * @@ -15,7 +15,7 @@ class ThreeWXFormer(GObject): """Tertiary bus identifier using the format described by the case information option for which key fields to use.""" BusName_NomVolt__4 = ("BusName_NomVolt:4", str, FieldPriority.SECONDARY) """Bus identifiers: Primary Secondary Tertiary""" - LineCircuit = ("LineCircuit", str, FieldPriority.SECONDARY) + LineCircuit = ("LineCircuit", str, FieldPriority.PRIMARY) """Circuit""" BusIdentifier__3 = ("BusIdentifier:3", str, FieldPriority.SECONDARY | FieldPriority.REQUIRED | FieldPriority.EDITABLE) """Star bus identifier using the format described by the case information option for which key fields to use. Also, when using this field as part of creating a three-winding transformer from an AUX file additional magic strings are available. (1) Number : enter an unused bus number and Simulator will create this bus as part of creating the three-winding transformer.; (2) STAR : enter this and Simulator will create a star bus by starting at the primary bus number and incrementing by 1 until a unique number is found.; (3) STARMAX : enter this and Simulator will create a star bus with a number equal to the maximum bus number plus 1.; (4) STAR98765 : enter this and Simulator will create a star bus by starting at the number given after STAR and incrementing by 1 until a unique number is found.; Syntax Note: You may optionally put a spaces between \"STAR MAX\" or \"STAR 98765\". If the string starts with STAR but doesn't match this syntax we default to treating it as though it said STAR only.""" @@ -742,7 +742,7 @@ class AerodynamicModel_WTARA1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -921,7 +921,7 @@ class AerodynamicModel_WTGAR_A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -1102,7 +1102,7 @@ class AGCController_AGCBradley(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -1299,7 +1299,7 @@ class AGCController_AGCPulseRate(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -1490,7 +1490,7 @@ class AGCController_AGCSetpoint(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -2780,7 +2780,7 @@ class AreaContingencyReserveBid(GObject): """The number of the area""" AreaName = ("AreaName", str, FieldPriority.SECONDARY) """The name of the area""" - GenericMW = ("GenericMW", float, FieldPriority.SECONDARY | FieldPriority.EDITABLE) + GenericMW = ("GenericMW", float, FieldPriority.PRIMARY | FieldPriority.EDITABLE) """MW""" GenericCostMWh = ("GenericCostMWh", float, FieldPriority.SECONDARY | FieldPriority.REQUIRED | FieldPriority.EDITABLE) """$/MWh""" @@ -2793,7 +2793,7 @@ class AreaOperatingReserveBid(GObject): """The number of the area""" AreaName = ("AreaName", str, FieldPriority.SECONDARY) """The name of the area""" - GenericMW = ("GenericMW", float, FieldPriority.SECONDARY | FieldPriority.EDITABLE) + GenericMW = ("GenericMW", float, FieldPriority.PRIMARY | FieldPriority.EDITABLE) """MW""" GenericCostMWh = ("GenericCostMWh", float, FieldPriority.SECONDARY | FieldPriority.REQUIRED | FieldPriority.EDITABLE) """$/MWh""" @@ -2806,7 +2806,7 @@ class AreaRegulatingReserveBid(GObject): """The number of the area""" AreaName = ("AreaName", str, FieldPriority.SECONDARY) """The name of the area""" - GenericMW = ("GenericMW", float, FieldPriority.SECONDARY | FieldPriority.EDITABLE) + GenericMW = ("GenericMW", float, FieldPriority.PRIMARY | FieldPriority.EDITABLE) """MW""" GenericCostMWh = ("GenericCostMWh", float, FieldPriority.SECONDARY | FieldPriority.REQUIRED | FieldPriority.EDITABLE) """$/MWh""" @@ -3160,7 +3160,7 @@ class ATCFlowValue(GObject): class ATCGeneratorChange(GObject): BusNum = ("BusNum", int, FieldPriority.PRIMARY) """Number of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" BusName = ("BusName", str, FieldPriority.OPTIONAL) """Name of the bus""" @@ -7184,7 +7184,7 @@ class BusModel_REPC_D(GObject): """Number""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV""" - ElementID = ("ElementID", str, FieldPriority.SECONDARY) + ElementID = ("ElementID", str, FieldPriority.PRIMARY) """Device ID (characters id which allows multiple devices of the same type)""" BusName = ("BusName", str, FieldPriority.OPTIONAL) """Name""" @@ -20981,7 +20981,7 @@ class Exciter_AC10C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -21270,7 +21270,7 @@ class Exciter_AC11C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -21539,7 +21539,7 @@ class Exciter_AC1C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -21776,7 +21776,7 @@ class Exciter_AC2C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -22017,7 +22017,7 @@ class Exciter_AC3C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -22268,7 +22268,7 @@ class Exciter_AC4C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -22481,7 +22481,7 @@ class Exciter_AC5C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -22714,7 +22714,7 @@ class Exciter_AC6A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -22949,7 +22949,7 @@ class Exciter_AC6C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -23194,7 +23194,7 @@ class Exciter_AC7B(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -23435,7 +23435,7 @@ class Exciter_AC7C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -23702,7 +23702,7 @@ class Exciter_AC8B(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -23931,7 +23931,7 @@ class Exciter_AC8C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -24184,7 +24184,7 @@ class Exciter_AC9C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -24465,7 +24465,7 @@ class Exciter_BBSEX1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -24674,7 +24674,7 @@ class Exciter_BPA_EA(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -24885,7 +24885,7 @@ class Exciter_BPA_EB(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -25100,7 +25100,7 @@ class Exciter_BPA_EC(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -25311,7 +25311,7 @@ class Exciter_BPA_ED(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -25524,7 +25524,7 @@ class Exciter_BPA_EE(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -25731,7 +25731,7 @@ class Exciter_BPA_EF(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -25940,7 +25940,7 @@ class Exciter_BPA_EG(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -26141,7 +26141,7 @@ class Exciter_BPA_EJ(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -26346,7 +26346,7 @@ class Exciter_BPA_EK(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -26557,7 +26557,7 @@ class Exciter_BPA_FA(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -26776,7 +26776,7 @@ class Exciter_BPA_FB(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -26995,7 +26995,7 @@ class Exciter_BPA_FC(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -27218,7 +27218,7 @@ class Exciter_BPA_FD(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -27435,7 +27435,7 @@ class Exciter_BPA_FE(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -27646,7 +27646,7 @@ class Exciter_BPA_FF(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -27881,7 +27881,7 @@ class Exciter_BPA_FG(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -28092,7 +28092,7 @@ class Exciter_BPA_FH(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -28325,7 +28325,7 @@ class Exciter_BPA_FJ(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -28540,7 +28540,7 @@ class Exciter_BPA_FK(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -28755,7 +28755,7 @@ class Exciter_BPA_FL(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -28982,7 +28982,7 @@ class Exciter_BPA_FM(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -29227,7 +29227,7 @@ class Exciter_BPA_FN(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -29472,7 +29472,7 @@ class Exciter_BPA_FO(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -29717,7 +29717,7 @@ class Exciter_BPA_FP(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -29962,7 +29962,7 @@ class Exciter_BPA_FQ(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -30207,7 +30207,7 @@ class Exciter_BPA_FR(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -30452,7 +30452,7 @@ class Exciter_BPA_FS(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -30697,7 +30697,7 @@ class Exciter_BPA_FT(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -30942,7 +30942,7 @@ class Exciter_BPA_FU(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -31165,7 +31165,7 @@ class Exciter_BPA_FV(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -31388,7 +31388,7 @@ class Exciter_CELIN(GObject): """Number of Bus: """ BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of Bus: """ - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """ID: """ AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """Labels All: """ @@ -31665,7 +31665,7 @@ class Exciter_DC1C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -31894,7 +31894,7 @@ class Exciter_DC2C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -32123,7 +32123,7 @@ class Exciter_DC3A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -32334,7 +32334,7 @@ class Exciter_DC4B(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -32561,7 +32561,7 @@ class Exciter_DC4C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -32806,7 +32806,7 @@ class Exciter_EMAC1T(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -33039,7 +33039,7 @@ class Exciter_ESAC1A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -33266,7 +33266,7 @@ class Exciter_ESAC2A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -33499,7 +33499,7 @@ class Exciter_ESAC3A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -33732,7 +33732,7 @@ class Exciter_ESAC4A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -33939,7 +33939,7 @@ class Exciter_ESAC5A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -34158,7 +34158,7 @@ class Exciter_ESAC6A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -34393,7 +34393,7 @@ class Exciter_ESAC7B(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -34636,7 +34636,7 @@ class Exciter_ESAC8B_GE(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -34865,7 +34865,7 @@ class Exciter_ESAC8B_PTI(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -35082,7 +35082,7 @@ class Exciter_ESDC1A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -35305,7 +35305,7 @@ class Exciter_ESDC2A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -35528,7 +35528,7 @@ class Exciter_ESDC3A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -35741,7 +35741,7 @@ class Exciter_ESDC4B(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -35970,7 +35970,7 @@ class Exciter_ESST1A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -36197,7 +36197,7 @@ class Exciter_ESST1A_GE(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -36424,7 +36424,7 @@ class Exciter_ESST2A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -36643,7 +36643,7 @@ class Exciter_ESST3A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -36872,7 +36872,7 @@ class Exciter_ESST4B(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -37095,7 +37095,7 @@ class Exciter_ESST5B(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -37318,7 +37318,7 @@ class Exciter_ESST6B(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -37539,7 +37539,7 @@ class Exciter_ESST7B(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -37760,7 +37760,7 @@ class Exciter_ESURRY(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -37989,7 +37989,7 @@ class Exciter_EWTGFC(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -38232,7 +38232,7 @@ class Exciter_EX2000(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -38511,7 +38511,7 @@ class Exciter_EXAC1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -38734,7 +38734,7 @@ class Exciter_EXAC1A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -38957,7 +38957,7 @@ class Exciter_EXAC2(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -39192,7 +39192,7 @@ class Exciter_EXAC3(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -39427,7 +39427,7 @@ class Exciter_EXAC3A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -39662,7 +39662,7 @@ class Exciter_EXAC4(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -39869,7 +39869,7 @@ class Exciter_EXAC6A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -40102,7 +40102,7 @@ class Exciter_EXAC8B(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -40325,7 +40325,7 @@ class Exciter_EXBAS(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -40554,7 +40554,7 @@ class Exciter_EXBBC(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -40765,7 +40765,7 @@ class Exciter_EXDC1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -40984,7 +40984,7 @@ class Exciter_EXDC2A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -41203,7 +41203,7 @@ class Exciter_EXDC2_GE(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -41422,7 +41422,7 @@ class Exciter_EXDC2_PTI(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -41641,7 +41641,7 @@ class Exciter_EXDC4(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -41850,7 +41850,7 @@ class Exciter_EXELI(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -42069,7 +42069,7 @@ class Exciter_EXIVO(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -42300,7 +42300,7 @@ class Exciter_EXPIC1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -42535,7 +42535,7 @@ class Exciter_EXST1_GE(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -42760,7 +42760,7 @@ class Exciter_EXST1_PTI(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -42971,7 +42971,7 @@ class Exciter_EXST2(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -43188,7 +43188,7 @@ class Exciter_EXST2A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -43405,7 +43405,7 @@ class Exciter_EXST3(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -43630,7 +43630,7 @@ class Exciter_EXST3A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -43853,7 +43853,7 @@ class Exciter_EXST4B(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -44074,7 +44074,7 @@ class Exciter_EXWTG1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -44277,7 +44277,7 @@ class Exciter_EXWTGE(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -44540,7 +44540,7 @@ class Exciter_IEEET1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -44757,7 +44757,7 @@ class Exciter_IEEET2(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -44972,7 +44972,7 @@ class Exciter_IEEET3(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -45183,7 +45183,7 @@ class Exciter_IEEET4(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -45392,7 +45392,7 @@ class Exciter_IEEET5(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -45599,7 +45599,7 @@ class Exciter_IEEEX1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -45818,7 +45818,7 @@ class Exciter_IEEEX2(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -46037,7 +46037,7 @@ class Exciter_IEEEX3(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -46248,7 +46248,7 @@ class Exciter_IEEEX4(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -46457,7 +46457,7 @@ class Exciter_IEET1A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -46670,7 +46670,7 @@ class Exciter_IEET5A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -46883,7 +46883,7 @@ class Exciter_IEEX2A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -47100,7 +47100,7 @@ class Exciter_IVOEX(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -47329,7 +47329,7 @@ class Exciter_MEXS(GObject): """Number of Bus: """ BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of Bus: """ - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """ID: """ AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """Labels All: """ @@ -47522,7 +47522,7 @@ class Exciter_PLAYINEX(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -47713,7 +47713,7 @@ class Exciter_PV1E(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -47956,7 +47956,7 @@ class Exciter_REECA1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -48247,7 +48247,7 @@ class Exciter_REECB1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -48496,7 +48496,7 @@ class Exciter_REECC1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -48785,7 +48785,7 @@ class Exciter_REEC_A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -49074,7 +49074,7 @@ class Exciter_REEC_B(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -49321,7 +49321,7 @@ class Exciter_REEC_C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -49608,7 +49608,7 @@ class Exciter_REEC_D(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -49963,7 +49963,7 @@ class Exciter_REEC_E(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -50326,7 +50326,7 @@ class Exciter_REXS(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -50591,7 +50591,7 @@ class Exciter_REXSY1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -50844,7 +50844,7 @@ class Exciter_REXSYS(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -51093,7 +51093,7 @@ class Exciter_SCRX(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -51296,7 +51296,7 @@ class Exciter_SEXS_GE(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -51505,7 +51505,7 @@ class Exciter_SEXS_PTI(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -51704,7 +51704,7 @@ class Exciter_ST10C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -51951,7 +51951,7 @@ class Exciter_ST1C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -52182,7 +52182,7 @@ class Exciter_ST2C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -52415,7 +52415,7 @@ class Exciter_ST3C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -52660,7 +52660,7 @@ class Exciter_ST4C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -52899,7 +52899,7 @@ class Exciter_ST5B(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -53122,7 +53122,7 @@ class Exciter_ST5C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -53353,7 +53353,7 @@ class Exciter_ST6B(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -53574,7 +53574,7 @@ class Exciter_ST6C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -53815,7 +53815,7 @@ class Exciter_ST6C_PTI(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -54060,7 +54060,7 @@ class Exciter_ST7B(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -54279,7 +54279,7 @@ class Exciter_ST7C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -54502,7 +54502,7 @@ class Exciter_ST8C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -54745,7 +54745,7 @@ class Exciter_ST9C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -54976,7 +54976,7 @@ class Exciter_TEXS(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -55197,7 +55197,7 @@ class Exciter_URST5T(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -55404,7 +55404,7 @@ class Exciter_WT2E(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -55627,7 +55627,7 @@ class Exciter_WT2E1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -55826,7 +55826,7 @@ class Exciter_WT3E(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -56081,7 +56081,7 @@ class Exciter_WT3E1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -56338,7 +56338,7 @@ class Exciter_WT4E(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -56567,7 +56567,7 @@ class Exciter_WT4E1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -57117,7 +57117,7 @@ class Gen(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" GenAGCAble = ("GenAGCAble", str, FieldPriority.SECONDARY | FieldPriority.REQUIRED | FieldPriority.EDITABLE) """Set to YES or NO to specify whether or not generator is available for AGC""" @@ -58320,7 +58320,7 @@ class GenBid(GObject): """MW""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" GenericCostMWh = ("GenericCostMWh", float, FieldPriority.SECONDARY | FieldPriority.REQUIRED | FieldPriority.EDITABLE) """$/MWh""" @@ -58333,7 +58333,7 @@ class GenMWMax_WindGeneral(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -58696,7 +58696,7 @@ class GenOtherModel_Generic(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -60348,7 +60348,7 @@ class Governor_BBGOV1(GObject): """Number of Bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of Bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """ID""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """Labels All""" @@ -60559,7 +60559,7 @@ class Governor_BPA_GG(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -60752,7 +60752,7 @@ class Governor_BPA_GH(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -60949,7 +60949,7 @@ class Governor_BPA_GIGATB(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -61214,7 +61214,7 @@ class Governor_BPA_GJGATB(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -61461,7 +61461,7 @@ class Governor_BPA_GKGATB(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -61710,7 +61710,7 @@ class Governor_BPA_GLTB(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -61923,7 +61923,7 @@ class Governor_BPA_GSTA(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -62122,7 +62122,7 @@ class Governor_BPA_GSTB(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -62331,7 +62331,7 @@ class Governor_BPA_GSTC(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -62542,7 +62542,7 @@ class Governor_BPA_GWTW(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -62733,7 +62733,7 @@ class Governor_CCBT1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -63056,7 +63056,7 @@ class Governor_CRCMGV(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -63267,7 +63267,7 @@ class Governor_DEGOV(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -63464,7 +63464,7 @@ class Governor_DEGOV1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -63667,7 +63667,7 @@ class Governor_DEGOV1D(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -63876,7 +63876,7 @@ class Governor_G2WSCC(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -64117,7 +64117,7 @@ class Governor_GAST2A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -64356,7 +64356,7 @@ class Governor_GAST2AD(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -64599,7 +64599,7 @@ class Governor_GAST2A_AIR(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AirTemp = ("AirTemp", float, FieldPriority.OPTIONAL | FieldPriority.EDITABLE) """Ambient Air Temperature""" @@ -64844,7 +64844,7 @@ class Governor_GASTD(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -65045,7 +65045,7 @@ class Governor_GASTWD(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -65286,7 +65286,7 @@ class Governor_GASTWDD(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -65531,7 +65531,7 @@ class Governor_GASTWD_AIR(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AirTemp = ("AirTemp", float, FieldPriority.OPTIONAL | FieldPriority.EDITABLE) """Ambient Air Temperature""" @@ -65778,7 +65778,7 @@ class Governor_GAST_GE(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -66025,7 +66025,7 @@ class Governor_GAST_PTI(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -66220,7 +66220,7 @@ class Governor_GGOV1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -66467,7 +66467,7 @@ class Governor_GGOV1D(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -66714,7 +66714,7 @@ class Governor_GGOV2(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -67003,7 +67003,7 @@ class Governor_GGOV3(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -67286,7 +67286,7 @@ class Governor_GPWSCC(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -67527,7 +67527,7 @@ class Governor_H6E(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -67826,7 +67826,7 @@ class Governor_HGBLEM(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -68207,7 +68207,7 @@ class Governor_HRSGSimple(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -68412,7 +68412,7 @@ class Governor_HYG3(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -68661,7 +68661,7 @@ class Governor_HYGOV(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -68918,7 +68918,7 @@ class Governor_HYGOV2(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -69127,7 +69127,7 @@ class Governor_HYGOV2D(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -69342,7 +69342,7 @@ class Governor_HYGOV4(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -69597,7 +69597,7 @@ class Governor_HYGOVD(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -69804,7 +69804,7 @@ class Governor_HYGOVR(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -70063,7 +70063,7 @@ class Governor_HYGOVR1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -70292,7 +70292,7 @@ class Governor_HYPID(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -70549,7 +70549,7 @@ class Governor_IEEEG1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -70800,7 +70800,7 @@ class Governor_IEEEG1D(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -71025,7 +71025,7 @@ class Governor_IEEEG1PID(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -71264,7 +71264,7 @@ class Governor_IEEEG1_GE(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -71515,7 +71515,7 @@ class Governor_IEEEG2(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -71706,7 +71706,7 @@ class Governor_IEEEG3D(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -71917,7 +71917,7 @@ class Governor_IEEEG3_GE(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -72154,7 +72154,7 @@ class Governor_IEEEG3_PTI(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -72359,7 +72359,7 @@ class Governor_IEESGO(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -72558,7 +72558,7 @@ class Governor_IEESGOD(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -72763,7 +72763,7 @@ class Governor_ISOGOV1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -72958,7 +72958,7 @@ class Governor_PIDGOV(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -73179,7 +73179,7 @@ class Governor_PIDGOVD(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -73404,7 +73404,7 @@ class Governor_PLAYINGOV(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -73585,7 +73585,7 @@ class Governor_TGOV1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -73778,7 +73778,7 @@ class Governor_TGOV1D(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -73975,7 +73975,7 @@ class Governor_TGOV2(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -74174,7 +74174,7 @@ class Governor_TGOV3(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -74413,7 +74413,7 @@ class Governor_TGOV3D(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -74632,7 +74632,7 @@ class Governor_TGOV5(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -74909,7 +74909,7 @@ class Governor_TURCZT(GObject): """Number of Bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of Bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """ID""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """Labels All""" @@ -75132,7 +75132,7 @@ class Governor_UCBGT(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -75393,7 +75393,7 @@ class Governor_UCCPSS(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -75704,7 +75704,7 @@ class Governor_UHRSG(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -75943,7 +75943,7 @@ class Governor_URGS3T(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -76186,7 +76186,7 @@ class Governor_W2301(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -76391,7 +76391,7 @@ class Governor_WEHGOV(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -76668,7 +76668,7 @@ class Governor_WESGOV(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -76863,7 +76863,7 @@ class Governor_WESGOVD(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -77064,7 +77064,7 @@ class Governor_WNDTGE(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -77333,7 +77333,7 @@ class Governor_WNDTRB(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -77524,7 +77524,7 @@ class Governor_WPIDHY(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -77743,7 +77743,7 @@ class Governor_WPIDHYD(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -77968,7 +77968,7 @@ class Governor_WSHYDD(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -78205,7 +78205,7 @@ class Governor_WSHYGP(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -78442,7 +78442,7 @@ class Governor_WSIEG1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -78689,7 +78689,7 @@ class Governor_WT12T1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -78876,7 +78876,7 @@ class Governor_WT1T(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -79065,7 +79065,7 @@ class Governor_WT2T(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -79252,7 +79252,7 @@ class Governor_WT3T(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -79445,7 +79445,7 @@ class Governor_WT3T1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -79638,7 +79638,7 @@ class Governor_WT4T(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -79831,7 +79831,7 @@ class Governor_WTDTA1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -80018,7 +80018,7 @@ class Governor_WTGT_A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -80207,7 +80207,7 @@ class Governor_WTGT_B(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -81273,7 +81273,7 @@ class InterfaceElement(GObject): """Interface Name""" IntNum = ("IntNum", int, FieldPriority.SECONDARY) """Interface Number""" - IntElementDesc__1 = ("IntElementDesc:1", str, FieldPriority.SECONDARY) + IntElementDesc__1 = ("IntElementDesc:1", str, FieldPriority.PRIMARY) """Interface Element Description (File Format)""" AreaName__100 = ("AreaName:100", str, FieldPriority.OPTIONAL) """Area Name at Near Bus""" @@ -89173,7 +89173,7 @@ class Load(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - LoadID = ("LoadID", str, FieldPriority.SECONDARY) + LoadID = ("LoadID", str, FieldPriority.PRIMARY) """2 character load identification field. Used to identify multiple loads at a single bus""" LoadSMVR = ("LoadSMVR", float, FieldPriority.SECONDARY | FieldPriority.REQUIRED | FieldPriority.EDITABLE) """Constant power portion of the Mvar load""" @@ -89734,7 +89734,7 @@ class LoadBid(GObject): """MW""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - LoadID = ("LoadID", str, FieldPriority.SECONDARY) + LoadID = ("LoadID", str, FieldPriority.PRIMARY) """2 character load identification field. Used to identify multiple loads at a single bus""" GenericCostMWh = ("GenericCostMWh", float, FieldPriority.SECONDARY | FieldPriority.REQUIRED | FieldPriority.EDITABLE) """$/MWh""" @@ -100154,7 +100154,7 @@ class MachineModel_BPASVC(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -100361,7 +100361,7 @@ class MachineModel_CBEST(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -100560,7 +100560,7 @@ class MachineModel_CIMTR1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -100761,7 +100761,7 @@ class MachineModel_CIMTR2(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -100960,7 +100960,7 @@ class MachineModel_CIMTR3(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -101161,7 +101161,7 @@ class MachineModel_CIMTR4(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -101362,7 +101362,7 @@ class MachineModel_CSTATT(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -101565,7 +101565,7 @@ class MachineModel_CSVGN1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -101760,7 +101760,7 @@ class MachineModel_CSVGN3(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -101957,7 +101957,7 @@ class MachineModel_CSVGN4(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -102156,7 +102156,7 @@ class MachineModel_CSVGN5(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -102361,7 +102361,7 @@ class MachineModel_CSVGN6(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -102580,7 +102580,7 @@ class MachineModel_DER_A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -102851,7 +102851,7 @@ class MachineModel_GENCC(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -103068,7 +103068,7 @@ class MachineModel_GENCLS(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -103255,7 +103255,7 @@ class MachineModel_GENCLS_PLAYBACK(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -103456,7 +103456,7 @@ class MachineModel_GENDCO(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -103663,7 +103663,7 @@ class MachineModel_Generic(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -103838,7 +103838,7 @@ class MachineModel_GENIND(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -104045,7 +104045,7 @@ class MachineModel_GENPWFluxDecay(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -104240,7 +104240,7 @@ class MachineModel_GENPWTwoAxis(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -104433,7 +104433,7 @@ class MachineModel_GENQEC(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -104650,7 +104650,7 @@ class MachineModel_GENQEJ(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -104867,7 +104867,7 @@ class MachineModel_GENROE(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -105076,7 +105076,7 @@ class MachineModel_GENROU(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -105285,7 +105285,7 @@ class MachineModel_GENSAE(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -105490,7 +105490,7 @@ class MachineModel_GENSAL(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -105695,7 +105695,7 @@ class MachineModel_GENTPF(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -105908,7 +105908,7 @@ class MachineModel_GENTPJ(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -106123,7 +106123,7 @@ class MachineModel_GENTRA(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -106318,7 +106318,7 @@ class MachineModel_GENWRI(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -106515,7 +106515,7 @@ class MachineModel_GEN_BPA_MMG2(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -106700,7 +106700,7 @@ class MachineModel_GEN_BPA_MMG3(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -106893,7 +106893,7 @@ class MachineModel_GEN_BPA_MMG4(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -107088,7 +107088,7 @@ class MachineModel_GEN_BPA_MMG5(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -107287,7 +107287,7 @@ class MachineModel_GEN_BPA_MMG6(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -107486,7 +107486,7 @@ class MachineModel_GEWTG(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -107695,7 +107695,7 @@ class MachineModel_GVABES(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -108088,7 +108088,7 @@ class MachineModel_InfiniteBusSignalGen(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -108317,7 +108317,7 @@ class MachineModel_MOTOR1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -108532,7 +108532,7 @@ class MachineModel_PLAYINGEN(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -108717,7 +108717,7 @@ class MachineModel_PV1G(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -108912,7 +108912,7 @@ class MachineModel_PVD1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -109141,7 +109141,7 @@ class MachineModel_REGC_A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -109346,7 +109346,7 @@ class MachineModel_REGC_B(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -109543,7 +109543,7 @@ class MachineModel_REGC_C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -109752,7 +109752,7 @@ class MachineModel_REGFM_A1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -109971,7 +109971,7 @@ class MachineModel_REGFM_B1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -110212,7 +110212,7 @@ class MachineModel_REGFM_C1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -110465,7 +110465,7 @@ class MachineModel_STCON(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -110672,7 +110672,7 @@ class MachineModel_SVCWSC(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -110939,7 +110939,7 @@ class MachineModel_VWSCC(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -111154,7 +111154,7 @@ class MachineModel_WT1G(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -111353,7 +111353,7 @@ class MachineModel_WT1G1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -111548,7 +111548,7 @@ class MachineModel_WT2G(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -111741,7 +111741,7 @@ class MachineModel_WT2G1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -111954,7 +111954,7 @@ class MachineModel_WT3G(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -112155,7 +112155,7 @@ class MachineModel_WT3G1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -112342,7 +112342,7 @@ class MachineModel_WT3G2(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -112545,7 +112545,7 @@ class MachineModel_WT4G(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -112744,7 +112744,7 @@ class MachineModel_WT4G1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -117279,7 +117279,7 @@ class OverExcitationLimiter_BASOEL2(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -117488,7 +117488,7 @@ class OverExcitationLimiter_MAXEX1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -117687,7 +117687,7 @@ class OverExcitationLimiter_MAXEX2(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -117888,7 +117888,7 @@ class OverExcitationLimiter_OEL1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -118085,7 +118085,7 @@ class OverExcitationLimiter_OEL1B(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -118278,7 +118278,7 @@ class OverExcitationLimiter_OEL2C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -118543,7 +118543,7 @@ class OverExcitationLimiter_OEL3C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -118746,7 +118746,7 @@ class OverExcitationLimiter_OEL4C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -118935,7 +118935,7 @@ class OverExcitationLimiter_OEL5C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -119510,7 +119510,7 @@ class PauxController_PAUXSS1A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -119715,7 +119715,7 @@ class PauxController_PLAYINPAUX(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -119894,7 +119894,7 @@ class PauxController_PROBOOST(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -120075,7 +120075,7 @@ class PauxController_WTGIBFFR_A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -120344,7 +120344,7 @@ class PlantController_PF1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -120543,7 +120543,7 @@ class PlantController_PF2(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -120732,7 +120732,7 @@ class PlantController_PLAYINREF(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -120913,7 +120913,7 @@ class PlantController_REPCA1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -121152,7 +121152,7 @@ class PlantController_REPCGFM_C1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -121449,7 +121449,7 @@ class PlantController_REPCTA1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -121688,7 +121688,7 @@ class PlantController_REPC_A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -121929,7 +121929,7 @@ class PlantController_REPC_B(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -122568,7 +122568,7 @@ class PlantController_REPC_B100(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -123607,7 +123607,7 @@ class PlantController_REPC_C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -123954,7 +123954,7 @@ class PlantController_VAR1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -124153,7 +124153,7 @@ class PlantController_VAR2(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -124666,7 +124666,7 @@ class PrefController_LCFB1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -124865,7 +124865,7 @@ class PrefController_LCFB1_PTI(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -125060,7 +125060,7 @@ class PrefController_WTGTRQ_A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -125267,7 +125267,7 @@ class PrefController_WTGWGO_A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -125458,7 +125458,7 @@ class PrefController_WTTQA1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -128781,7 +128781,7 @@ class QVCurve(GObject): """Number""" BusIdentifier = ("BusIdentifier", str, FieldPriority.SECONDARY) """""" - CaseName = ("CaseName", str, FieldPriority.SECONDARY) + CaseName = ("CaseName", str, FieldPriority.PRIMARY) """Scenario name either 'BASECASE' or the name of a contingency.""" ABCPhaseAngle = ("ABCPhaseAngle", float, FieldPriority.OPTIONAL) """Volt Phase Angle A""" @@ -130126,7 +130126,7 @@ class QVCurvePoint(GObject): """Number of the bus for which the curve point was recorded.""" BusIdentifier = ("BusIdentifier", str, FieldPriority.SECONDARY) """Identifier of the bus for which the curve point was recorded. This can be Number, Name_NomKV, or label of the bus. """ - CaseName = ("CaseName", str, FieldPriority.SECONDARY) + CaseName = ("CaseName", str, FieldPriority.PRIMARY) """Scenario name - either 'BASECASE' or the name of a contingency.""" CustomExpression = ("CustomExpression", float, FieldPriority.OPTIONAL) """Any number of expressions may be defined for an object. This represents Expression 1 It will be blank if no expression specified""" @@ -130157,7 +130157,7 @@ class QVCurveTrackedValue(GObject): """Field of the device that is being tracked.""" BusIdentifier = ("BusIdentifier", str, FieldPriority.SECONDARY) """Identifier of the bus for which the QV curve was studied. This can be Number, Name_NomKV, or label of the bus. """ - CaseName = ("CaseName", str, FieldPriority.SECONDARY) + CaseName = ("CaseName", str, FieldPriority.PRIMARY) """Name of contingency for this scenario. \"Base Case\" will appear for the base case scenario.""" CustomExpression = ("CustomExpression", float, FieldPriority.OPTIONAL) """Any number of expressions may be defined for an object. This represents Expression 1 It will be blank if no expression specified""" @@ -130492,7 +130492,7 @@ class ReactiveCapability(GObject): """Generator's present MW output of the generator""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus of the generator""" GenMVRMax = ("GenMVRMax", float, FieldPriority.SECONDARY | FieldPriority.REQUIRED | FieldPriority.EDITABLE) """Generator's maximum Mvar limit of the generator""" @@ -131494,7 +131494,7 @@ class RelayModel_ATRRELAY(GObject): """Number of Bus: """ BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of Bus: """ - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """ID: """ AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """Labels All: """ @@ -131701,7 +131701,7 @@ class RelayModel_FRQDCAT(GObject): """Model Instance""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of Bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """ID""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """Labels All""" @@ -131890,7 +131890,7 @@ class RelayModel_FRQTPAT(GObject): """Model Instance""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of Bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """ID""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """Labels All""" @@ -132077,7 +132077,7 @@ class RelayModel_GENOF(GObject): """Number of Bus: """ BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of Bus: """ - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """ID: """ AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """Labels All: """ @@ -132262,7 +132262,7 @@ class RelayModel_GENOOS(GObject): """Number of Bus: """ BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of Bus: """ - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """ID: """ AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """Labels All: """ @@ -132457,7 +132457,7 @@ class RelayModel_GP1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -132664,7 +132664,7 @@ class RelayModel_GP2(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -132873,7 +132873,7 @@ class RelayModel_GP3(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -133104,7 +133104,7 @@ class RelayModel_GVPHZFT(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -133289,7 +133289,7 @@ class RelayModel_GVPHZIT(GObject): """Number of Bus: """ BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of Bus: """ - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """ID: """ AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """Labels All: """ @@ -133474,7 +133474,7 @@ class RelayModel_LHFRT(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -133695,7 +133695,7 @@ class RelayModel_LHSRT(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -133912,7 +133912,7 @@ class RelayModel_LHVRT(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -134133,7 +134133,7 @@ class RelayModel_VPERHZ1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -134342,7 +134342,7 @@ class RelayModel_VTGDCAT(GObject): """Model Instance""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of Bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """ID""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """Labels All""" @@ -134531,7 +134531,7 @@ class RelayModel_VTGTPAT(GObject): """Model Instance""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of Bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """ID""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """Labels All""" @@ -134978,7 +134978,7 @@ class Removed3WXFormer(GObject): """Bus Identifier Tertiary""" BusName_NomVolt__4 = ("BusName_NomVolt:4", str, FieldPriority.SECONDARY) """Bus Identifiers All: Primary Secondary Tertiary""" - LineCircuit = ("LineCircuit", str, FieldPriority.SECONDARY) + LineCircuit = ("LineCircuit", str, FieldPriority.PRIMARY) """Circuit""" ThreeWXFMagnetizingB = ("3WXFMagnetizingB", float, FieldPriority.OPTIONAL) """Impedance/Magnetizing B""" @@ -137261,7 +137261,7 @@ class RemovedGen(GObject): """Number of Bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of Bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """ID""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -138215,7 +138215,7 @@ class RemovedInterfaceElement(GObject): """Interface Name""" IntNum = ("IntNum", int, FieldPriority.SECONDARY) """Interface Number""" - IntElementDesc__1 = ("IntElementDesc:1", str, FieldPriority.SECONDARY) + IntElementDesc__1 = ("IntElementDesc:1", str, FieldPriority.PRIMARY) """Interface Element Description (File Format)""" DataMaintainer = ("DataMaintainer", str, FieldPriority.OPTIONAL) """Indicates who the Data Maintainer of this object is. This who is responsible for maintaining the input data for this record""" @@ -138488,7 +138488,7 @@ class RemovedLoad(GObject): """Number of Bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of Bus""" - LoadID = ("LoadID", str, FieldPriority.SECONDARY) + LoadID = ("LoadID", str, FieldPriority.PRIMARY) """ID""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -140142,7 +140142,7 @@ class RemovedReactiveCapability(GObject): """MW Output/MW of Gen""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of Bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """ID of Gen""" BusName = ("BusName", str, FieldPriority.OPTIONAL) """Name of Bus""" @@ -140169,7 +140169,7 @@ class RemovedShunt(GObject): """Number of Bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of Bus""" - ShuntID = ("ShuntID", str, FieldPriority.SECONDARY) + ShuntID = ("ShuntID", str, FieldPriority.PRIMARY) """ID""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -142608,7 +142608,7 @@ class ScheduledAction(GObject): """The action applied to the device""" Name__1 = ("Name:1", str, FieldPriority.PRIMARY) """Identifier of device affected by this action""" - FieldName = ("FieldName", str, FieldPriority.SECONDARY) + FieldName = ("FieldName", str, FieldPriority.PRIMARY) """The field affected by the action""" ActionRDFID = ("ActionRDFID", str, FieldPriority.OPTIONAL | FieldPriority.EDITABLE) """Action RDFID""" @@ -143721,7 +143721,7 @@ class Shunt(GObject): """Number of the terminal bus to which the switched shunt is attached.""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - ShuntID = ("ShuntID", str, FieldPriority.SECONDARY) + ShuntID = ("ShuntID", str, FieldPriority.PRIMARY) """2 character switched shunt identification field. Used to identify multiple switched shunts at a single bus""" SSCMode = ("SSCMode", str, FieldPriority.SECONDARY | FieldPriority.REQUIRED | FieldPriority.EDITABLE) """Control Mode: Fixed, Discrete, Continuous, Bus Shunt, or SVC. Note: Bus Shunt is the same as Fixed inside the software. It is only supported for read/write compatibility with other file formats""" @@ -144716,7 +144716,7 @@ class Stabilizer_BPA_SF(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -144919,7 +144919,7 @@ class Stabilizer_BPA_SG(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -145122,7 +145122,7 @@ class Stabilizer_BPA_SI(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -145343,7 +145343,7 @@ class Stabilizer_BPA_SP(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -145546,7 +145546,7 @@ class Stabilizer_BPA_SS(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -145749,7 +145749,7 @@ class Stabilizer_Generic(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -145924,7 +145924,7 @@ class Stabilizer_IEE2ST(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -146139,7 +146139,7 @@ class Stabilizer_IEEEST(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -146354,7 +146354,7 @@ class Stabilizer_IVOST(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -146571,7 +146571,7 @@ class Stabilizer_PFQRG(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -146756,7 +146756,7 @@ class Stabilizer_PSS1A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -146961,7 +146961,7 @@ class Stabilizer_PSS2A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -147190,7 +147190,7 @@ class Stabilizer_PSS2B(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -147431,7 +147431,7 @@ class Stabilizer_PSS2C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -147678,7 +147678,7 @@ class Stabilizer_PSS3B(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -147895,7 +147895,7 @@ class Stabilizer_PSS3C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -148122,7 +148122,7 @@ class Stabilizer_PSS4B(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -148451,7 +148451,7 @@ class Stabilizer_PSS4C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -148818,7 +148818,7 @@ class Stabilizer_PSS5C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -149035,7 +149035,7 @@ class Stabilizer_PSS6C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -149280,7 +149280,7 @@ class Stabilizer_PSS7C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -149531,7 +149531,7 @@ class Stabilizer_PSSSB(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -149766,7 +149766,7 @@ class Stabilizer_PSSSH(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -149969,7 +149969,7 @@ class Stabilizer_PTIST1(GObject): """""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """""" @@ -150168,7 +150168,7 @@ class Stabilizer_PTIST3(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -150413,7 +150413,7 @@ class Stabilizer_SIGNALSTAB(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -150622,7 +150622,7 @@ class Stabilizer_ST2CUT(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -150837,7 +150837,7 @@ class Stabilizer_STAB1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -151026,7 +151026,7 @@ class Stabilizer_STAB2A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -151217,7 +151217,7 @@ class Stabilizer_STAB3(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -151402,7 +151402,7 @@ class Stabilizer_STAB4(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -151599,7 +151599,7 @@ class Stabilizer_STBSVC(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -151806,7 +151806,7 @@ class Stabilizer_WSCCST(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -152041,7 +152041,7 @@ class Stabilizer_WT12A1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -152234,7 +152234,7 @@ class Stabilizer_WT1P(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -152429,7 +152429,7 @@ class Stabilizer_WT1P_B(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -152632,7 +152632,7 @@ class Stabilizer_WT2P(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -152827,7 +152827,7 @@ class Stabilizer_WT3P(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -153020,7 +153020,7 @@ class Stabilizer_WT3P1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -153213,7 +153213,7 @@ class Stabilizer_WTGPT_A(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -153410,7 +153410,7 @@ class Stabilizer_WTGPT_B(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -153615,7 +153615,7 @@ class Stabilizer_WTPTA1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -153810,7 +153810,7 @@ class StatorCurrentLimiter_SCL1C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -154021,7 +154021,7 @@ class StatorCurrentLimiter_SCL2C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -155223,6 +155223,8 @@ class Substation(GObject): """Custom earth resistivity region hotspot scaling for the substation; set to -1 to use the default region value""" GICGeoMagGraphicScalar = ("GICGeoMagGraphicScalar", float, FieldPriority.OPTIONAL) """Product of the geomagnetic latitude and earth resistivity region scalars for the substation's location""" + GICUsedSubGroundOhms = ("GICUsedSubGroundOhms", float, FieldPriority.OPTIONAL) + """Substation grounding ohms actually used in the geomagnetic induced current calculations.""" ObjectString = 'Substation' @@ -156210,7 +156212,7 @@ class SwitchedShuntModel_ABBSVC1(GObject): """Number of Bus: """ BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of Bus: """ - ShuntID = ("ShuntID", str, FieldPriority.SECONDARY) + ShuntID = ("ShuntID", str, FieldPriority.PRIMARY) """ID: """ AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """Labels All: """ @@ -156513,7 +156515,7 @@ class SwitchedShuntModel_CAPRELAY(GObject): """Number of the terminal bus to which the switched shunt is attached.""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - ShuntID = ("ShuntID", str, FieldPriority.SECONDARY) + ShuntID = ("ShuntID", str, FieldPriority.PRIMARY) """2 character switched shunt identification field. Used to identify multiple switched shunts at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -156686,7 +156688,7 @@ class SwitchedShuntModel_CHSVCT(GObject): """Number of Bus: """ BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of Bus: """ - ShuntID = ("ShuntID", str, FieldPriority.SECONDARY) + ShuntID = ("ShuntID", str, FieldPriority.PRIMARY) """ID: """ AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """Labels All: """ @@ -156889,7 +156891,7 @@ class SwitchedShuntModel_CSSCST(GObject): """Number of the terminal bus to which the switched shunt is attached.""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - ShuntID = ("ShuntID", str, FieldPriority.SECONDARY) + ShuntID = ("ShuntID", str, FieldPriority.PRIMARY) """2 character switched shunt identification field. Used to identify multiple switched shunts at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -157058,7 +157060,7 @@ class SwitchedShuntModel_CSTCNT(GObject): """Number of Bus: """ BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of Bus: """ - ShuntID = ("ShuntID", str, FieldPriority.SECONDARY) + ShuntID = ("ShuntID", str, FieldPriority.PRIMARY) """ID: """ AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """Labels All: """ @@ -157239,7 +157241,7 @@ class SwitchedShuntModel_FACRI_SS(GObject): """Number of the terminal bus to which the switched shunt is attached.""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - ShuntID = ("ShuntID", str, FieldPriority.SECONDARY) + ShuntID = ("ShuntID", str, FieldPriority.PRIMARY) """2 character switched shunt identification field. Used to identify multiple switched shunts at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -157438,7 +157440,7 @@ class SwitchedShuntModel_GenericSwitchedShunt(GObject): """Number of the terminal bus to which the switched shunt is attached.""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - ShuntID = ("ShuntID", str, FieldPriority.SECONDARY) + ShuntID = ("ShuntID", str, FieldPriority.PRIMARY) """2 character switched shunt identification field. Used to identify multiple switched shunts at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -157587,7 +157589,7 @@ class SwitchedShuntModel_MSC1(GObject): """Number of the terminal bus to which the switched shunt is attached.""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - ShuntID = ("ShuntID", str, FieldPriority.SECONDARY) + ShuntID = ("ShuntID", str, FieldPriority.PRIMARY) """2 character switched shunt identification field. Used to identify multiple switched shunts at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -157754,7 +157756,7 @@ class SwitchedShuntModel_MSR1(GObject): """Number of the terminal bus to which the switched shunt is attached.""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - ShuntID = ("ShuntID", str, FieldPriority.SECONDARY) + ShuntID = ("ShuntID", str, FieldPriority.PRIMARY) """2 character switched shunt identification field. Used to identify multiple switched shunts at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -157919,7 +157921,7 @@ class SwitchedShuntModel_MSS1(GObject): """Number of the terminal bus to which the switched shunt is attached.""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - ShuntID = ("ShuntID", str, FieldPriority.SECONDARY) + ShuntID = ("ShuntID", str, FieldPriority.PRIMARY) """2 character switched shunt identification field. Used to identify multiple switched shunts at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -158088,7 +158090,7 @@ class SwitchedShuntModel_MSS2(GObject): """Number of the terminal bus to which the switched shunt is attached.""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - ShuntID = ("ShuntID", str, FieldPriority.SECONDARY) + ShuntID = ("ShuntID", str, FieldPriority.PRIMARY) """2 character switched shunt identification field. Used to identify multiple switched shunts at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -158257,7 +158259,7 @@ class SwitchedShuntModel_SVCALS(GObject): """Number of the terminal bus to which the switched shunt is attached.""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - ShuntID = ("ShuntID", str, FieldPriority.SECONDARY) + ShuntID = ("ShuntID", str, FieldPriority.PRIMARY) """2 character switched shunt identification field. Used to identify multiple switched shunts at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -158530,7 +158532,7 @@ class SwitchedShuntModel_SVSMO1(GObject): """Number of the terminal bus to which the switched shunt is attached.""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - ShuntID = ("ShuntID", str, FieldPriority.SECONDARY) + ShuntID = ("ShuntID", str, FieldPriority.PRIMARY) """2 character switched shunt identification field. Used to identify multiple switched shunts at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -158775,7 +158777,7 @@ class SwitchedShuntModel_SVSMO1_AK_A(GObject): """Number of Bus: """ BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of Bus: """ - ShuntID = ("ShuntID", str, FieldPriority.SECONDARY) + ShuntID = ("ShuntID", str, FieldPriority.PRIMARY) """ID: """ AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """Labels All: """ @@ -159056,7 +159058,7 @@ class SwitchedShuntModel_SVSMO1_AK_B(GObject): """Number of Bus: """ BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of Bus: """ - ShuntID = ("ShuntID", str, FieldPriority.SECONDARY) + ShuntID = ("ShuntID", str, FieldPriority.PRIMARY) """ID: """ AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """Labels All: """ @@ -159279,7 +159281,7 @@ class SwitchedShuntModel_SVSMO2(GObject): """Number of the terminal bus to which the switched shunt is attached.""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - ShuntID = ("ShuntID", str, FieldPriority.SECONDARY) + ShuntID = ("ShuntID", str, FieldPriority.PRIMARY) """2 character switched shunt identification field. Used to identify multiple switched shunts at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -159526,7 +159528,7 @@ class SwitchedShuntModel_SVSMO3(GObject): """Number of the terminal bus to which the switched shunt is attached.""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - ShuntID = ("ShuntID", str, FieldPriority.SECONDARY) + ShuntID = ("ShuntID", str, FieldPriority.PRIMARY) """2 character switched shunt identification field. Used to identify multiple switched shunts at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -159767,7 +159769,7 @@ class SwitchedShuntModel_SWSHNT(GObject): """Number of the terminal bus to which the switched shunt is attached.""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - ShuntID = ("ShuntID", str, FieldPriority.SECONDARY) + ShuntID = ("ShuntID", str, FieldPriority.PRIMARY) """2 character switched shunt identification field. Used to identify multiple switched shunts at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -159932,7 +159934,7 @@ class SwitchedShuntStatus_SSTHDvSimple(GObject): """Number of the terminal bus to which the switched shunt is attached.""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - ShuntID = ("ShuntID", str, FieldPriority.SECONDARY) + ShuntID = ("ShuntID", str, FieldPriority.PRIMARY) """2 character switched shunt identification field. Used to identify multiple switched shunts at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -160791,7 +160793,7 @@ class TimePointAreaLoadMW(GObject): """Date Hour""" TimeDomainDateTimeUTC = ("TimeDomainDateTimeUTC", str, FieldPriority.SECONDARY) """UTCISO8601""" - WhoAmI = ("WhoAmI", str, FieldPriority.SECONDARY) + WhoAmI = ("WhoAmI", str, FieldPriority.PRIMARY) """WhoAmI""" CalcField = ("CalcField", float, FieldPriority.OPTIONAL) """No Calculated Fields defined yet. To define a calculated field, browse to \"Case Information and Auxiliary/Calculated Fields\" """ @@ -160826,7 +160828,7 @@ class TimePointBranchStatus(GObject): """Date Hour""" TimeDomainDateTimeUTC = ("TimeDomainDateTimeUTC", str, FieldPriority.SECONDARY) """UTCISO8601""" - WhoAmI = ("WhoAmI", str, FieldPriority.SECONDARY) + WhoAmI = ("WhoAmI", str, FieldPriority.PRIMARY) """WhoAmI""" CalcField = ("CalcField", float, FieldPriority.OPTIONAL) """No Calculated Fields defined yet. To define a calculated field, browse to \"Case Information and Auxiliary/Calculated Fields\" """ @@ -160917,7 +160919,7 @@ class TimePointGenMW(GObject): """Date Hour""" TimeDomainDateTimeUTC = ("TimeDomainDateTimeUTC", str, FieldPriority.SECONDARY) """UTCISO8601""" - WhoAmI = ("WhoAmI", str, FieldPriority.SECONDARY) + WhoAmI = ("WhoAmI", str, FieldPriority.PRIMARY) """WhoAmI""" CalcField = ("CalcField", float, FieldPriority.OPTIONAL) """No Calculated Fields defined yet. To define a calculated field, browse to \"Case Information and Auxiliary/Calculated Fields\" """ @@ -160952,7 +160954,7 @@ class TimePointGenMWMax(GObject): """Date Hour""" TimeDomainDateTimeUTC = ("TimeDomainDateTimeUTC", str, FieldPriority.SECONDARY) """UTCISO8601""" - WhoAmI = ("WhoAmI", str, FieldPriority.SECONDARY) + WhoAmI = ("WhoAmI", str, FieldPriority.PRIMARY) """WhoAmI""" CalcField = ("CalcField", float, FieldPriority.OPTIONAL) """No Calculated Fields defined yet. To define a calculated field, browse to \"Case Information and Auxiliary/Calculated Fields\" """ @@ -160987,7 +160989,7 @@ class TimePointInjectionGroupMW(GObject): """Date Hour""" TimeDomainDateTimeUTC = ("TimeDomainDateTimeUTC", str, FieldPriority.SECONDARY) """UTCISO8601""" - WhoAmI = ("WhoAmI", str, FieldPriority.SECONDARY) + WhoAmI = ("WhoAmI", str, FieldPriority.PRIMARY) """WhoAmI""" CalcField = ("CalcField", float, FieldPriority.OPTIONAL) """No Calculated Fields defined yet. To define a calculated field, browse to \"Case Information and Auxiliary/Calculated Fields\" """ @@ -161022,7 +161024,7 @@ class TimePointLoadMWMvar(GObject): """Date Hour""" TimeDomainDateTimeUTC = ("TimeDomainDateTimeUTC", str, FieldPriority.SECONDARY) """UTCISO8601""" - WhoAmI = ("WhoAmI", str, FieldPriority.SECONDARY) + WhoAmI = ("WhoAmI", str, FieldPriority.PRIMARY) """WhoAmI""" CalcField = ("CalcField", float, FieldPriority.OPTIONAL) """No Calculated Fields defined yet. To define a calculated field, browse to \"Case Information and Auxiliary/Calculated Fields\" """ @@ -161059,7 +161061,7 @@ class TimePointWeather(GObject): """UTCISO8601""" TimeDomainDateHour = ("TimeDomainDateHour", str, FieldPriority.SECONDARY) """Date Hour""" - WhoAmI = ("WhoAmI", str, FieldPriority.SECONDARY) + WhoAmI = ("WhoAmI", str, FieldPriority.PRIMARY) """WhoAmI""" CalcField = ("CalcField", float, FieldPriority.OPTIONAL) """No Calculated Fields defined yet. To define a calculated field, browse to \"Case Information and Auxiliary/Calculated Fields\" """ @@ -161124,7 +161126,7 @@ class TimePointZoneLoadMW(GObject): """Date Hour""" TimeDomainDateTimeUTC = ("TimeDomainDateTimeUTC", str, FieldPriority.SECONDARY) """UTCISO8601""" - WhoAmI = ("WhoAmI", str, FieldPriority.SECONDARY) + WhoAmI = ("WhoAmI", str, FieldPriority.PRIMARY) """WhoAmI""" CalcField = ("CalcField", float, FieldPriority.OPTIONAL) """No Calculated Fields defined yet. To define a calculated field, browse to \"Case Information and Auxiliary/Calculated Fields\" """ @@ -161422,7 +161424,7 @@ class TransferLimiter(GObject): """ATCScenario The line/zone ATC load scenario number. Starts with zero (0) and counts up.""" DirName = ("DirName", str, FieldPriority.PRIMARY) """Direction:Name""" - ATCGenChanges = ("ATCGenChanges", int, FieldPriority.SECONDARY) + ATCGenChanges = ("ATCGenChanges", int, FieldPriority.PRIMARY) """ATCScenario The generator ATC scenario number. Starts with zero (0) and counts up.""" CTGLabel = ("CTGLabel", str, FieldPriority.SECONDARY | FieldPriority.REQUIRED) """Limiting CTG""" @@ -163651,7 +163653,7 @@ class TSContingencyElement(GObject): """The time (in seconds) at which the contingency element occurs during the transient stability run""" TSTimeInCycles = ("TSTimeInCycles", float, FieldPriority.SECONDARY) """The time (in cycles) at which the contingency element occurs during the transient stability run""" - WhoAmI = ("WhoAmI", str, FieldPriority.SECONDARY) + WhoAmI = ("WhoAmI", str, FieldPriority.PRIMARY) """Object on which the element acts""" AreaName = ("AreaName", str, FieldPriority.OPTIONAL) """List of the area names represented by all the transient contingency elements (without looking inside injection groups or interfaces)""" @@ -165316,7 +165318,7 @@ class TSStats_Bus(GObject): """Number""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV""" - TSCTGName = ("TSCTGName", str, FieldPriority.SECONDARY) + TSCTGName = ("TSCTGName", str, FieldPriority.PRIMARY) """Contingency Name:Name of the Transient Contingency""" ABCPhaseAngle = ("ABCPhaseAngle", float, FieldPriority.OPTIONAL) """Volt Phase Angle A""" @@ -166653,7 +166655,7 @@ class TSStats_Gen(GObject): """Contingency Name:Name of the Transient Contingency""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" ABCPhaseAngle = ("ABCPhaseAngle", float, FieldPriority.OPTIONAL) """Phase A""" @@ -169164,7 +169166,7 @@ class UnderExcitationLimiter_MNLEX1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -169355,7 +169357,7 @@ class UnderExcitationLimiter_MNLEX2(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -169548,7 +169550,7 @@ class UnderExcitationLimiter_MNLEX3(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -169741,7 +169743,7 @@ class UnderExcitationLimiter_UEL1(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -169950,7 +169952,7 @@ class UnderExcitationLimiter_UEL2(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -170211,7 +170213,7 @@ class UnderExcitationLimiter_UEL2C(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -170482,7 +170484,7 @@ class UnderExcitationLimiter_UEL2C_PTI(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -170763,7 +170765,7 @@ class UnderExcitationLimiter_UEL2_PTI(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -171065,7 +171067,7 @@ class UserDefinedExciter(GObject): """User defined model Name""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -171262,7 +171264,7 @@ class UserDefinedGovernor(GObject): """User defined model Name""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -171600,7 +171602,7 @@ class UserDefinedMachineModel(GObject): """User defined model Name""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -172072,7 +172074,7 @@ class UserDefinedStabilizer(GObject): """User defined model Name""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -173968,7 +173970,7 @@ class VoltageCompensator_CCOMP(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -174157,7 +174159,7 @@ class VoltageCompensator_CCOMP4(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -174354,7 +174356,7 @@ class VoltageCompensator_COMP(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -174531,7 +174533,7 @@ class VoltageCompensator_COMPCC(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -174716,7 +174718,7 @@ class VoltageCompensator_IEEEVC(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -174895,7 +174897,7 @@ class VoltageCompensator_REMCMP(GObject): """Number of the bus""" BusName_NomVolt = ("BusName_NomVolt", str, FieldPriority.SECONDARY) """Name_Nominal kV of the bus""" - GenID = ("GenID", str, FieldPriority.SECONDARY) + GenID = ("GenID", str, FieldPriority.PRIMARY) """2 character generator identification field. Used to identify multiple generators at a single bus""" AllLabels = ("AllLabels", str, FieldPriority.OPTIONAL) """This represents a comma-separated list of the label identifiers for this object. If labels are specified they can be used to input data into the model instead of using the key or secondary key fields""" @@ -178368,7 +178370,7 @@ class ZoneContingencyReserveBid(GObject): """Zone Number""" ZoneName = ("ZoneName", str, FieldPriority.SECONDARY) """Zone Name""" - GenericMW = ("GenericMW", float, FieldPriority.SECONDARY | FieldPriority.EDITABLE) + GenericMW = ("GenericMW", float, FieldPriority.PRIMARY | FieldPriority.EDITABLE) """MW""" GenericCostMWh = ("GenericCostMWh", float, FieldPriority.SECONDARY | FieldPriority.REQUIRED | FieldPriority.EDITABLE) """$/MWh""" @@ -178381,7 +178383,7 @@ class ZoneOperatingReserveBid(GObject): """Zone Number""" ZoneName = ("ZoneName", str, FieldPriority.SECONDARY) """Zone Name""" - GenericMW = ("GenericMW", float, FieldPriority.SECONDARY | FieldPriority.EDITABLE) + GenericMW = ("GenericMW", float, FieldPriority.PRIMARY | FieldPriority.EDITABLE) """MW""" GenericCostMWh = ("GenericCostMWh", float, FieldPriority.SECONDARY | FieldPriority.REQUIRED | FieldPriority.EDITABLE) """$/MWh""" @@ -178394,7 +178396,7 @@ class ZoneRegulatingReserveBid(GObject): """Zone Number""" ZoneName = ("ZoneName", str, FieldPriority.SECONDARY) """Zone Name""" - GenericMW = ("GenericMW", float, FieldPriority.SECONDARY | FieldPriority.EDITABLE) + GenericMW = ("GenericMW", float, FieldPriority.PRIMARY | FieldPriority.EDITABLE) """MW""" GenericCostMWh = ("GenericCostMWh", float, FieldPriority.SECONDARY | FieldPriority.REQUIRED | FieldPriority.EDITABLE) """$/MWh""" diff --git a/esapp/components/ts_fields.py b/esapp/components/ts_fields.py new file mode 100644 index 00000000..767491bb --- /dev/null +++ b/esapp/components/ts_fields.py @@ -0,0 +1,323 @@ +# +# -*- coding: utf-8 -*- +# This file is auto-generated by esapp/components/generate_components.py. +# Do not edit this file manually, as your changes will be overwritten. +# +# Transient Stability Field Constants for IDE Intellisense +# +# Usage: +# from esapp.components import TS, Gen +# pw.dyn.watch(Gen, [TS.Gen.P, TS.Gen.Speed]) +# + +from dataclasses import dataclass + + +@dataclass(frozen=True) +class TSField: + """ + Represents a Transient Stability result field. + + Attributes: + name: The PowerWorld field name string + description: Human-readable description of the field + + """ + name: str + description: str = "" + + def __str__(self) -> str: + return self.name + + def __repr__(self) -> str: + return f"TSField({self.name!r})" + + def __getitem__(self, index: int) -> "TSField": + """Allows accessing indexed fields like TS.Bus.Input[1].""" + return TSField(f"{self.name}:{index}", self.description) + + +class TS: + """ + Transient Stability Field Constants for Intellisense. + + Provides IDE autocomplete for all available TS result fields organized + by object type (Bus, Gen, Branch, Load, Shunt, Area, etc.). + + Example: + >>> from esapp.components import TS, Gen + >>> pw.dyn.watch(Gen, [TS.Gen.P, TS.Gen.Speed, TS.Gen.Delta]) + """ + + class Area: + """TS result fields for Area objects.""" + ACE = TSField("TSAreaACE", "DSC::TSTimePointResult_TSAreaACE") + AGCAble = TSField("TSAreaAGCAble", "") + AreaSchedMW = TSField("TSAreaAreaSchedMW", "") + AvgFreqHz = TSField("TSAreaAvgFreqHz", "Average Frequency (Hz)") + Bias = TSField("TSAreaBias", "") + Deadband = TSField("TSAreaDeadband", "") + GICQ = TSField("TSAreaGICQ", "Total GIC Mvar Losses") + GenAccP = TSField("TSAreaGenAccP", "Generator Accel MW Sum Area") + GenMWLoss = TSField("TSAreaGenMWLoss", "DSC::TSTimePointResult_TSAreaGenMWLoss") + GenP = TSField("TSAreaGenP", "Gen MW Sum Area") + GenPMech = TSField("TSAreaGenPMech", "Generator Mech Input Sum Area") + GenQ = TSField("TSAreaGenQ", "Gen Mvar Sum Area") + IntP = TSField("TSAreaIntP", "Net MW interchange leaving the area") + IntQ = TSField("TSAreaIntQ", "Net Mvar interchange leaving the area") + LoadNPT = TSField("TSAreaLoadNPT", "Load MW Nominal Tripped") + LoadP = TSField("TSAreaLoadP", "Load MW Sum Area") + LoadQ = TSField("TSAreaLoadQ", "Load Mvar Sum Area") + SchedMW = TSField("TSAreaSchedMW", "DSC::TSTimePointResult_TSAreaSchedMW") + WeightAvgSpeed = TSField("TSAreaWeightAvgSpeed", "Weighted Average Speed of online synchronous machines (weighted by generator MVA Base)") + + class Branch: + """TS result fields for Branch objects.""" + FromA = TSField("TSACLineFromA", "Current at From End in Amps") + FromAinPU = TSField("TSACLineFromAinPU", "Current at From End in pu") + FromAppImpR = TSField("TSACLineFromAppImpR", "Apparent Impedance Resistance at From End in pu") + FromAppImpROhms = TSField("TSACLineFromAppImpROhms", "Apparent Impedance Resistance at From End in Ohms") + FromAppImpX = TSField("TSACLineFromAppImpX", "Apparent Impedance Reactance at From End in pu") + FromAppImpXOhms = TSField("TSACLineFromAppImpXOhms", "Apparent Impedance Reactance at From End in Ohms") + FromAppImpZAng = TSField("TSACLineFromAppImpZAng", "Apparent Impedance Angle at From End") + FromAppImpZMag = TSField("TSACLineFromAppImpZMag", "Apparent Impedance Magnitude at From End in pu") + FromAppImpZMagOhms = TSField("TSACLineFromAppImpZMagOhms", "Apparent Impedance Magnitude at From End in Ohms") + FromGIC = TSField("TSACLineFromGIC", "Per phase GIC flowing into the line/transformer at the from end, amps") + FromP = TSField("TSACLineFromP", "MW at From End") + FromQ = TSField("TSACLineFromQ", "Mvar at From End") + FromS = TSField("TSACLineFromS", "MVA at From End") + MinProfileVpu = TSField("TSACLineMinProfileVpu", "Minimum Profile Vpu") + Percent = TSField("TSACLinePercent", "Flow Percentage of Contingency Limit (Result may be based on Amps or MVA depending on the Limit Monitoring Settings) ") + RelayInput = TSField("TSACLineRelayInput", "") + RelayOther = TSField("TSACLineRelayOther", "Other Fields of AC Line Relay/Other 1 (largest index is 10)") + RelayStates = TSField("TSACLineRelayStates", "States of AC Line Relay/State 1 (largest index is 3)") + Status = TSField("TSACLineStatus", "Status of line or transformer: 0 for open, 1 for closed") + ToA = TSField("TSACLineToA", "Current at To End in amps") + ToAinPU = TSField("TSACLineToAinPU", "Current at To End in pu") + ToAppImpR = TSField("TSACLineToAppImpR", "Apparent Impedance Resistance at To End in pu") + ToAppImpROhms = TSField("TSACLineToAppImpROhms", "Apparent Impedance Resistance at To End in Ohms") + ToAppImpX = TSField("TSACLineToAppImpX", "Apparent Impedance Reactance at To End in pu") + ToAppImpXOhms = TSField("TSACLineToAppImpXOhms", "Apparent Impedance Reactance at To End in Ohms") + ToAppImpZAng = TSField("TSACLineToAppImpZAng", "Apparent Impedance Angle at To End") + ToAppImpZMag = TSField("TSACLineToAppImpZMag", "Apparent Impedance Magnitude at To End in pu") + ToAppImpZMagOhms = TSField("TSACLineToAppImpZMagOhms", "Apparent Impedance Magnitude at To End Ohms") + ToGIC = TSField("TSACLineToGIC", "Per phase GIC flowing into the line/transformer at the to end, amps") + ToP = TSField("TSACLineToP", "MW at To End") + ToQ = TSField("TSACLineToQ", "Mvar at To End") + ToS = TSField("TSACLineToS", "MVA at To End") + + class Bus: + """TS result fields for Bus objects.""" + Deg = TSField("TSBusDeg", "Angle relative to angle reference (degrees)") + DegNoshift = TSField("TSBusDegNoshift", "Angle, No Shift (degrees)") + FreqMeasT = TSField("TSBusFreqMeasT", "Bus Frequency is calculated by taking the derivative of the bus angles in the system using this time delay") + GenP = TSField("TSBusGenP", "Total Generator MW") + GenQ = TSField("TSBusGenQ", "Total Generator Mvar") + GroupFreqHz = TSField("TSBusGroupFreqHz", "") + GroupLossP = TSField("TSBusGroupLossP", "") + GroupLossQ = TSField("TSBusGroupLossQ", "") + GroupSShuntP = TSField("TSBusGroupSShuntP", "") + GroupSShuntQ = TSField("TSBusGroupSShuntQ", "") + Input = TSField("TSBusInput", "Inputs of Bus/Input 1 (largest index is 10)") + LoadP = TSField("TSBusLoadP", "Total Load MW") + LoadQ = TSField("TSBusLoadQ", "Total Load Mvar") + MinMaxFreq = TSField("TSBusMinMaxFreq", "Minimum value for the signal over the time window") + MinMaxFreqTime = TSField("TSBusMinMaxFreqTime", "Time at which the minimum value over the time window is achieved") + MinMaxVoltPU = TSField("TSBusMinMaxVoltPU", "Minimum Per Unit Voltage during simulation") + MinMaxVoltPUTime = TSField("TSBusMinMaxVoltPUTime", "Time of Minimum Per Unit Voltage") + Other = TSField("TSBusOther", "Other Fields of Bus/Other 1 (largest index is 10)") + PairAngleDiff = TSField("TSBusPairAngleDiff", "DSC::TSTimePointResult_TSBusPairAngleDiff") + ROCOFHz = TSField("TSBusROCOFHz", "Rate of Change of Frequency (ROCOF) in Hz/s") + ROCOFHz_MISTAKE_FIXBUG_DONTUSE = TSField("TSBusROCOFHz_MISTAKE_FIXBUG_DONTUSE", "") + Rad = TSField("TSBusRad", "Angle relative to angle reference (radians)") + States = TSField("TSBusStates", "States of Bus/State 1 (largest index is 53)") + Status = TSField("TSBusStatus", "Status of bus: 0 for open, 1 for energized") + VPU = TSField("TSBusVPU", "Voltage Magnitude (pu)") + VinKV = TSField("TSBusVinKV", "Voltage Magnitude (kV)") + + class Gen: + """TS result fields for Gen objects.""" + AGCInput = TSField("TSGenAGCInput", "") + AGCOther = TSField("TSGenAGCOther", "") + AGCState = TSField("TSGenAGCState", "States of AGC Model/State 1 (largest index is 1)") + AGCStatus = TSField("TSGenAGCStatus", "") + AeroInput = TSField("TSGenAeroInput", "") + AeroOther = TSField("TSGenAeroOther", "") + AeroState = TSField("TSGenAeroState", "") + AppImpR = TSField("TSGenAppImpR", "DSC::TSTimePointResult_TSGenAppImpR") + AppImpX = TSField("TSGenAppImpX", "DSC::TSTimePointResult_TSGenAppImpX") + Delta = TSField("TSGenDelta", "Rotor Angle relative to angle reference (degrees)") + DeltaNoshift = TSField("TSGenDeltaNoshift", "Rotor Angle, No Shift (degrees)") + EField = TSField("TSGenEField", "") + ExciterInput = TSField("TSGenExciterInput", "Inputs of Exciter/Input 1 (largest index is 1)") + ExciterName = TSField("TSGenExciterName", "Shows the name of the active exciter type for transient stability") + ExciterOther = TSField("TSGenExciterOther", "Other Fields of Exciter/Other 1 (largest index is 8)") + ExciterState = TSField("TSGenExciterState", "States of Exciter/State 1 (largest index is 20)") + ExciterSubInterval2Used = TSField("TSGenExciterSubInterval2Used", "SubInterval Used, Exciter Model") + FieldV = TSField("TSGenFieldV", "Field Voltage Magnitude (pu)") + GEMVABase = TSField("TSGenGEMVABase", "") + GovernorInput = TSField("TSGenGovernorInput", "Inputs of Governor/Input 1 (largest index is 1)") + GovernorName = TSField("TSGenGovernorName", "Shows the name of the active governor type for transient stability") + GovernorOther = TSField("TSGenGovernorOther", "Other Fields of Governor/Other 1 (largest index is 16)") + GovernorState = TSField("TSGenGovernorState", "States of Governor/State 1 (largest index is 62)") + GovernorSubInterval2Used = TSField("TSGenGovernorSubInterval2Used", "SubInterval Used, Governor Model") + IPU = TSField("TSGenIPU", "Genrator current magnitude (pu)") + Id = TSField("TSGenId", "d-q axis/Direct Axis Current [pu]") + Ifd = TSField("TSGenIfd", "Field Current") + Iq = TSField("TSGenIq", "d-q axis/Quadrature Axis Current [pu]") + MWREf = TSField("TSGenMWREf", "MW reference value for the generator") + MachineInput = TSField("TSGenMachineInput", "Inputs of Machine/Input 1 (largest index is 1)") + MachineName = TSField("TSGenMachineName", "Shows the name of the active machine type for transient stability") + MachineOther = TSField("TSGenMachineOther", "Other Fields of Machine/Other 1 (largest index is 14)") + MachineState = TSField("TSGenMachineState", "States of Machine/State 1 (largest index is 15)") + MachineSubInterval2Used = TSField("TSGenMachineSubInterval2Used", "SubInterval Used, Machine Model") + MinMaxAngle = TSField("TSGenMinMaxAngle", "Maximum Angle Difference between internal machine angles during the simulation") + MinMaxAngleTime = TSField("TSGenMinMaxAngleTime", "Simulation Time at which the Maximum Angle Difference between internal machine angles occurred during the simulation") + MinMaxEfd = TSField("TSGenMinMaxEfd", "Minimum Field Voltage during simulation") + MinMaxEfdTime = TSField("TSGenMinMaxEfdTime", "Time of Minimum Field Voltage") + MinMaxFreq = TSField("TSGenMinMaxFreq", "Minimum Speed during simulation") + MinMaxFreqTime = TSField("TSGenMinMaxFreqTime", "Time of Minimum Speed") + MinMaxIfd = TSField("TSGenMinMaxIfd", "Minimum Field Current during simulation") + MinMaxIfdTime = TSField("TSGenMinMaxIfdTime", "Time of Minimum Field Current") + MinMaxPMech = TSField("TSGenMinMaxPMech", "Minimum Mechanical Power during simulation") + MinMaxPMechTime = TSField("TSGenMinMaxPMechTime", "Time of Minimum Mechanical Power") + MinMaxVs = TSField("TSGenMinMaxVs", "Minimum Stabilizer Vs during simulation") + MinMaxVsTime = TSField("TSGenMinMaxVsTime", "Time of Minimum Stabilizer Vs") + OELInput = TSField("TSGenOELInput", "") + OELOther = TSField("TSGenOELOther", "DSC::TSTimePointResult_TSGenOELOther/Other 1 (largest index is 16)") + OELState = TSField("TSGenOELState", "DSC::TSTimePointResult_TSGenOELState/State 1 (largest index is 24)") + OtherName = TSField("TSGenOtherName", "Shows the name of the first other model type for transient stability") + P = TSField("TSGenP", "MW injected by generator into its bus; this is after any transformer included as part of the generator model") + PAirGap = TSField("TSGenPAirGap", "Airgap Power MW") + PBus = TSField("TSGenPBus", "") + PMech = TSField("TSGenPMech", "Mech Input") + PauxCtrlInput = TSField("TSGenPauxCtrlInput", "DSC::TSTimePointResult_TSGenPauxCtrlInput/Input 1 (largest index is 2)") + PauxCtrlOther = TSField("TSGenPauxCtrlOther", "DSC::TSTimePointResult_TSGenPauxCtrlOther/Other 1 (largest index is 5)") + PauxCtrlState = TSField("TSGenPauxCtrlState", "DSC::TSTimePointResult_TSGenPauxCtrlState/State 1 (largest index is 10)") + PlantCtrlInput = TSField("TSGenPlantCtrlInput", "Inputs of Plant Controller/Input 1 (largest index is 4)") + PlantCtrlOther = TSField("TSGenPlantCtrlOther", "Other Fields of Plant Controller/Other 1 (largest index is 10)") + PlantCtrlState = TSField("TSGenPlantCtrlState", "States of Plant Controller/State 1 (largest index is 27)") + PlayIn = TSField("TSGenPlayIn", "") + PrefCtrlInput = TSField("TSGenPrefCtrlInput", "") + PrefCtrlOther = TSField("TSGenPrefCtrlOther", "Other Fields of Pref Controller such as Turbine Load Controller/Other 1 (largest index is 2)") + PrefCtrlState = TSField("TSGenPrefCtrlState", "States of Pref Controller such as Turbine Load Controller/State 1 (largest index is 4)") + Q = TSField("TSGenQ", "Mvar injected by generator into its bus; this is after any transformer included as part of the generator model") + QBus = TSField("TSGenQBus", "") + RelayInput = TSField("TSGenRelayInput", "") + RelayOther = TSField("TSGenRelayOther", "Other Fields of Gen Relay/Other 1 (largest index is 16)") + RelayState = TSField("TSGenRelayState", "States of Gen Relay/State 1 (largest index is 24)") + S = TSField("TSGenS", "Power/Terminal MVA") + SBus = TSField("TSGenSBus", "") + SCLInput = TSField("TSGenSCLInput", "") + SCLOther = TSField("TSGenSCLOther", "DSC::TSTimePointResult_TSGenSCLOther/Other 1 (largest index is 16)") + SCLState = TSField("TSGenSCLState", "DSC::TSTimePointResult_TSGenSCLState/State 1 (largest index is 24)") + SaveTwoBusEquiv = TSField("TSGenSaveTwoBusEquiv", "Save Two Bus Equivalent") + StabilizerInput = TSField("TSGenStabilizerInput", "") + StabilizerName = TSField("TSGenStabilizerName", "Shows the name of the active stabilizer type for transient stability") + StabilizerOther = TSField("TSGenStabilizerOther", "Other Fields of Stabilizer/Other 1 (largest index is 2)") + StabilizerState = TSField("TSGenStabilizerState", "States of Stabilizer/State 1 (largest index is 40)") + StabilizerVs = TSField("TSGenStabilizerVs", "Stabilizer Vs") + StabilzerSubInterval2Used = TSField("TSGenStabilzerSubInterval2Used", "SubInterval Used, Stabilizer Model") + Status = TSField("TSGenStatus", "Status of generator: 0 for open, 1 for closed") + TermVPU = TSField("TSGenTermVPU", "Terminal Voltage Magnitude (pu)") + UELInput = TSField("TSGenUELInput", "") + UELOther = TSField("TSGenUELOther", "DSC::TSTimePointResult_TSGenUELOther/Other 1 (largest index is 16)") + UELState = TSField("TSGenUELState", "DSC::TSTimePointResult_TSGenUELState/State 1 (largest index is 24)") + VOEL = TSField("TSGenVOEL", "Over-Excitation Limiter Signal") + VSCL = TSField("TSGenVSCL", "DSC::TSTimePointResult_TSGenVSCL") + VSCLOEL = TSField("TSGenVSCLOEL", "DSC::TSTimePointResult_TSGenVSCLOEL") + VSCLUEL = TSField("TSGenVSCLUEL", "DSC::TSTimePointResult_TSGenVSCLUEL") + VUEL = TSField("TSGenVUEL", "Under-Excitation Limiter Signal") + Vd = TSField("TSGenVd", "d-q axis/Direct Axis Voltage [pu]") + VoltPURef = TSField("TSGenVoltPURef", "Voltage setpoint for the generator (in per unit)") + VperHz = TSField("TSGenVperHz", "Generator V per Hertz in pu.") + Vq = TSField("TSGenVq", "d-q axis/Quadrature Axis Voltage [pu]") + W = TSField("TSGenW", "Speed") + + class InjectionGroup: + """TS result fields for InjectionGroup objects.""" + LoadNPT = TSField("TSInjectionGroupLoadNPT", "Load MW Nominal Tripped") + P = TSField("TSInjectionGroupP", "MW at Injection Group") + Pmech = TSField("TSInjectionGroupPmech", "Mech Input at Injection Group") + Q = TSField("TSInjectionGroupQ", "Mvar at Injection Group") + WARS = TSField("TSInjectionGroupWARS", "Weighted Average Rotor Speed. The formula is the sum of generator speed times Weight divided by sum of Weights. The intention is to set the Weights to be the H (Inertia) of the generators. The Weights are set in the Participation Factors of the injection group.") + + class Load: + """TS result fields for Load objects.""" + Breaker = TSField("TSLoadBreaker", "Model Parameters/LoadBreaker") + DistGenInput = TSField("TSLoadDistGenInput", "") + DistGenOther = TSField("TSLoadDistGenOther", "Other Fields of Load Distributed Generation/Other 1 (largest index is 10)") + DistGenP = TSField("TSLoadDistGenP", "Distributed Generation MW") + DistGenQ = TSField("TSLoadDistGenQ", "Distributed Generation Mvar") + DistGenStates = TSField("TSLoadDistGenStates", "States of Load Distributed Generation/State 1 (largest index is 10)") + IAMPS = TSField("TSLoadIAMPS", "Load Current (amps)") + IDeg = TSField("TSLoadIDeg", "Load Current Angle") + IPU = TSField("TSLoadIPU", "Load Current (pu)") + Input = TSField("TSLoadInput", "") + NPT = TSField("TSLoadNPT", "MW Nominal Tripped") + OnlyOrDistGenAndLoad = TSField("TSLoadOnlyOrDistGenAndLoad", "Set how the relay or event scaling will scale/affect the loads. The options are to affect Only Load MW and MVAR; or Dist Gen and Load MW and MVAR") + Other = TSField("TSLoadOther", "Other Fields of Load/Other 1 (largest index is 36)") + P = TSField("TSLoadP", "MW Load") + Q = TSField("TSLoadQ", "Mvar Load") + RelayInput = TSField("TSLoadRelayInput", "") + RelayOther = TSField("TSLoadRelayOther", "") + RelayStates = TSField("TSLoadRelayStates", "States of Load Relay/State 1 (largest index is 6)") + S = TSField("TSLoadS", "MVA Load") + Scalar = TSField("TSLoadScalar", "") + Scalar_NotUsed = TSField("TSLoadScalar_NotUsed", "") + States = TSField("TSLoadStates", "States of Load/State 1 (largest index is 20)") + Status = TSField("TSLoadStatus", "Status of load: 0 for open, 1 for closed") + VDeg = TSField("TSLoadVDeg", "Bus Voltage Angle (degrees)") + VPU = TSField("TSLoadVPU", "Bus Voltage Magnitude (pu)") + VinKV = TSField("TSLoadVinKV", "Bus Voltage Magnitude (kV)") + + class Shunt: + """TS result fields for Shunt objects.""" + BusVPU = TSField("TSShuntBusVPU", "Bus Voltage Magnitude (pu)") + BusVinKV = TSField("TSShuntBusVinKV", "Bus Voltage Magnitude (kV)") + IAMPS = TSField("TSShuntIAMPS", "Switched current magnitude (amp)") + IPU = TSField("TSShuntIPU", "Switched current magnitude (pu)") + Input = TSField("TSShuntInput", "Inputs of Switched Shunt/Input 1 (largest index is 1)") + Mvar = TSField("TSShuntMvar", "Actual Mvar") + MvarinPU = TSField("TSShuntMvarinPU", "Actual Mvar in pu") + NomMvar = TSField("TSShuntNomMvar", "Nominal Mvar") + NomMvarinPU = TSField("TSShuntNomMvarinPU", "Nominal Mvar in pu") + Other = TSField("TSShuntOther", "Other Fields of Switched Shunt/Other 1 (largest index is 1)") + States = TSField("TSShuntStates", "States of Switched Shunt/State 1 (largest index is 20)") + Status = TSField("TSShuntStatus", "Switched shunt status: 0 for open, 1 for closed") + + class Substation: + """TS result fields for Substation objects.""" + AvgFreqHz = TSField("TSSubAvgFreqHz", "Average Frequency (Hz)") + AvgPUVolt = TSField("TSSubAvgPUVolt", "Average Voltage (pu)") + GICEFieldDeg = TSField("TSSubGICEFieldDeg", "GIC Efield Directions (degrees)") + GICEFieldMag = TSField("TSSubGICEFieldMag", "GIC Efield Magnitude") + GICIAmp = TSField("TSSubGICIAmp", "Total GIC (amps)") + GICQ = TSField("TSSubGICQ", "Total GIC Mvar Losses") + GenAccP = TSField("TSSubGenAccP", "Gen Acceleration MW Sum Substation") + GenP = TSField("TSSubGenP", "Gen MW Sum Substation") + GenPMech = TSField("TSSubGenPMech", "Generator Mech Input Sum Substation") + GenQ = TSField("TSSubGenQ", "Gen Mvar Sum Substation") + IntP = TSField("TSSubIntP", "") + IntQ = TSField("TSSubIntQ", "") + Intervals = TSField("TSSubIntervals", "Specify the number of sub-interval integration steps to use. A blank value will cause Simulator to use a default for that model type. Normally a model will not use sub-interval integration. Values must be either blank, 1, 2, 4, 8, 16, 32, 64 or 128") + LoadP = TSField("TSSubLoadP", "Load MW Sum Substation") + LoadQ = TSField("TSSubLoadQ", "Load Mvar Sum Substation") + MaxPUVolt = TSField("TSSubMaxPUVolt", "Maximum Voltage (pu)") + MinPUOfHighestNomkV = TSField("TSSubMinPUOfHighestNomkV", "Lowest Voltage (pu) of Highest Nominal Voltage Buses") + MinPUVolt = TSField("TSSubMinPUVolt", "Minimum Voltage (pu)") + ROCOFHz = TSField("TSSubROCOFHz", "DSC::TSTimePointResult_TSSubROCOFHz") + + class System: + """TS result fields for System objects.""" + DSMetric = TSField("TSSystemDSMetric", "DSC::PWCaseInformation_TSSystemDSMetric") + GICQ = TSField("TSSystemGICQ", "Total GIC Mvar Losses") + GICXFIeffmax = TSField("TSSystemGICXFIeffmax", "Maximum Transformer Per phase effective GIC for the transfomer in amps") + GenAccP = TSField("TSSystemGenAccP", "Generator Accel MW Sum System") + GenP = TSField("TSSystemGenP", "Gen MW Sum System") + GenPMech = TSField("TSSystemGenPMech", "Generator Mech Input Sum System") + GenQ = TSField("TSSystemGenQ", "Gen Mvar Sum System") + LoadP = TSField("TSSystemLoadP", "Load MW Sum System") + LoadQ = TSField("TSSystemLoadQ", "Load Mvar Sum System") + UnservedLoadP = TSField("TSSystemUnservedLoadP", "Estimate of total system unserved load") + diff --git a/esapp/dev/generate_components.py b/esapp/dev/generate_components.py deleted file mode 100644 index 6b9ecd9d..00000000 --- a/esapp/dev/generate_components.py +++ /dev/null @@ -1,306 +0,0 @@ -""" -Parses the PowerWorld 'Case Objects Fields' Text File and generates a Python -module (components.py) containing the structured data. -""" -import os -from collections import OrderedDict -from dataclasses import dataclass, field -from enum import Flag, auto -from typing import Optional - - -class FieldRole(Flag): - """Maps to PWRaw Key/Required column symbols.""" - STANDARD = 0 - PRIMARY_KEY = auto() # * - ALTERNATE_KEY = auto() # *A* - COMPOSITE_KEY_1 = auto() # *1* - COMPOSITE_KEY_2 = auto() # *2* - COMPOSITE_KEY_3 = auto() # *3* - SECONDARY_ID = auto() # *2B* - CIRCUIT_ID = auto() # *4B* - BASE_VALUE = auto() # ** - STANDARD_FIELD = auto() # < - - -@dataclass -class FieldDefinition: - """Represents a single field/variable within a PowerWorld object type.""" - variable_name: str - python_name: str - concise_name: str - data_type: str - description: str - role: FieldRole - enterable: bool - available_list: str = "" - - @property - def is_primary(self) -> bool: - return bool(self.role & ( - FieldRole.PRIMARY_KEY | FieldRole.COMPOSITE_KEY_1 | - FieldRole.COMPOSITE_KEY_2 | FieldRole.COMPOSITE_KEY_3 - )) - - @property - def is_secondary(self) -> bool: - return bool(self.role & ( - FieldRole.ALTERNATE_KEY | FieldRole.SECONDARY_ID | - FieldRole.CIRCUIT_ID | FieldRole.BASE_VALUE - )) - - @property - def is_base_value(self) -> bool: - return bool(self.role & FieldRole.BASE_VALUE) - - -@dataclass -class ObjectTypeDefinition: - """Represents a PowerWorld object type (e.g., Gen, Bus, Load).""" - name: str - subdata_allowed: bool - fields: list = field(default_factory=list) - - -excludeObjects = [ - 'AlarmOptions', 'GenMWMaxMin_GenMWMaxMinXYCurve', - 'GenMWMax_SolarPVBasic1', 'GenMWMax_SolarPVBasic2', - 'GenMWMax_TemperatureBasic1', 'GenMWMax_WindBasic', - 'GenMWMax_WindClass1', 'GenMWMax_WindClass2', 'GenMWMax_WindClass3', - 'GenMWMax_WindClass4', 'GICGeographicRegionSet', 'GIC_Options', - 'LPOPFMarginalControls', 'MvarMarginalCostValues', 'MWMarginalCostValues', - 'NEMGroupBranch', 'NEMGroupGroup', 'NEMGroupNode', 'PieSizeColorOptions', - 'PWBranchDataObject', 'RT_Study_Options', 'SchedSubscription', - 'TSFreqSummaryObject', 'TSModalAnalysisObject', 'TSSchedule', - 'Exciter_Generic', 'Governor_Generic', - 'InjectionGroupModel_GenericInjectionGroup', 'LoadCharacteristic_Generic', - 'WeatherPathPoint', 'TSTimePointSolutionDetails' -] - -excludeFields = [ - 'BusMarginalControl', 'BusMCMVARValue', 'BusMCMWValue', 'LoadGrounded', - 'GEDateIn', 'GEDateOut' -] - -dtypemap = {"String": "str", "Real": "float", "Integer": "int"} - - -def fix_pw_string(name: str) -> str: - """Converts a Python-safe attribute name back to the PowerWorld string format.""" - new_name = "3" + name[5:] if name.startswith("Three") else name - new_name = new_name.replace('__', ':') - new_name = new_name.replace('___', ' ') - return new_name - - -def sanitize_for_python(name: str) -> str: - """Converts a PowerWorld field name to a Python-safe attribute name.""" - new_name = name.replace(":", "__") - new_name = new_name.replace(" ", "___") - if new_name and new_name[0] == '3': - new_name = 'Three' + new_name[1:] - return new_name - - -def strip_quotes(value: str) -> str: - """Strips surrounding single quotes from a value.""" - value = value.strip() - if value.startswith("'") and value.endswith("'"): - return value[1:-1] - return value - - -def sanitize_description(desc: str) -> str: - """ - Sanitizes a description string for use in a Python triple-quoted docstring. - - Handles: - - Backslashes (replaced with forward slashes) - - Embedded double quotes (escaped to prevent docstring termination) - - Triple quotes (escaped) - """ - desc = desc.replace("\\", "/") - desc = desc.replace('"""', r'\"\"\"') - desc = desc.replace('"', r'\"') - return desc - - -def parse_key_symbol(symbol: str) -> FieldRole: - """ - Parses Key/Required column symbols into FieldRole. - - Symbols can be combined (e.g., '*1*<' means COMPOSITE_KEY_1 + STANDARD_FIELD). - Order matters: check specific patterns before generic ones. - """ - symbol = symbol.strip() - role = FieldRole.STANDARD - - if '*1*' in symbol: - role |= FieldRole.COMPOSITE_KEY_1 - elif '*2B*' in symbol: - role |= FieldRole.SECONDARY_ID - elif '*4B*' in symbol: - role |= FieldRole.CIRCUIT_ID - elif '*2*' in symbol: - role |= FieldRole.COMPOSITE_KEY_2 - elif '*3*' in symbol: - role |= FieldRole.COMPOSITE_KEY_3 - elif '*A*' in symbol: - role |= FieldRole.ALTERNATE_KEY - elif '**' in symbol: - role |= FieldRole.BASE_VALUE - elif '*' in symbol and not any(x in symbol for x in ['*1*', '*2*', '*3*', '*A*', '**', '*2B*', '*4B*']): - role |= FieldRole.PRIMARY_KEY - - if '<' in symbol: - role |= FieldRole.STANDARD_FIELD - - return role - - -def parse_enterable(value: str) -> bool: - """ - Parses the Enterable column value. - Returns True if the field is user-editable. - """ - value = strip_quotes(value.strip().lower()) - return value in ('yes', 'edit mode only') - - -def get_sort_key(field_def: FieldDefinition) -> int: - """Returns sort priority based on FieldRole.""" - role = field_def.role - if role & FieldRole.COMPOSITE_KEY_1 or role & FieldRole.PRIMARY_KEY: - return 0 - elif role & FieldRole.COMPOSITE_KEY_2: - return 1 - elif role & FieldRole.COMPOSITE_KEY_3: - return 2 - elif role & FieldRole.ALTERNATE_KEY: - return 3 - elif role & FieldRole.SECONDARY_ID or role & FieldRole.CIRCUIT_ID: - return 4 - elif role & FieldRole.BASE_VALUE: - return 5 - return 10 - - -def get_column(parts: list, index: int, strip_q: bool = False) -> str: - """Safely extracts a column value from parts list.""" - value = parts[index].strip() if index < len(parts) else "" - return strip_quotes(value) if strip_q else value - - -def pw_to_dict(filepath: str) -> OrderedDict: - """Parses the PWRaw TSV file into structured ObjectTypeDefinition instances.""" - data = OrderedDict() - current_obj: Optional[ObjectTypeDefinition] = None - - with open(filepath, 'r', encoding='utf-8') as f: - next(f, None) - - for line in f: - line = line.rstrip('\n') - if not line.strip(): - continue - - parts = line.split('\t') - - if not line.startswith('\t'): - obj_name = parts[0].strip() - - if not obj_name or len(obj_name) <= 1 or obj_name in excludeObjects: - current_obj = None - continue - - subdata = get_column(parts, 1).lower() == 'yes' - current_obj = ObjectTypeDefinition(name=obj_name, subdata_allowed=subdata) - data[obj_name] = current_obj - - elif current_obj is not None: - var_name = get_column(parts, 3) - if not var_name or var_name in excludeFields or '/' in var_name: - continue - - key_str = get_column(parts, 2) - enterable = parse_enterable(get_column(parts, 8)) - - field_def = FieldDefinition( - variable_name=var_name, - python_name=sanitize_for_python(var_name), - concise_name=get_column(parts, 4), - data_type=get_column(parts, 5), - description=get_column(parts, 6, strip_q=True), - role=parse_key_symbol(key_str), - enterable=enterable, - available_list=get_column(parts, 7, strip_q=True) - ) - current_obj.fields.append(field_def) - - return data - - -def _build_field_priority_flags(field_def: FieldDefinition) -> str: - """Builds the FieldPriority flag string for a field definition.""" - flags = [] - - if field_def.is_primary: - flags.append('FieldPriority.PRIMARY') - elif field_def.is_secondary: - flags.append('FieldPriority.SECONDARY') - else: - flags.append('FieldPriority.OPTIONAL') - - if field_def.is_base_value: - flags.append('FieldPriority.REQUIRED') - - if field_def.enterable: - flags.append('FieldPriority.EDITABLE') - - return ' | '.join(flags) - - -def generate_components(data: OrderedDict, output_path: str) -> None: - """Generates components.py with classes for each PowerWorld object type.""" - preamble = """# -# -*- coding: utf-8 -*- -# This file is auto-generated by generate_components.py. -# Do not edit this file manually, as your changes will be overwritten. - -from .gobject import * -""" - - with open(output_path, 'w', encoding='utf-8') as f: - f.write(preamble) - - for obj_name, obj_def in data.items(): - cls_name = sanitize_for_python(obj_name.split(" ")[0]) - f.write(f'\n\nclass {cls_name}(GObject):') - - obj_def.fields.sort(key=get_sort_key) - - for field_def in obj_def.fields: - dtype = dtypemap.get(field_def.data_type, "str") - pw_name = fix_pw_string(field_def.python_name) - flags = _build_field_priority_flags(field_def) - safe_desc = sanitize_description(field_def.description) - - f.write(f'\n\t{field_def.python_name} = ("{pw_name}", {dtype}, {flags})') - f.write(f'\n\t"""{safe_desc}"""') - - f.write(f"\n\n\tObjectString = '{obj_name}'\n") - - -if __name__ == "__main__": - RAW_IN = 'PWRaw' - OUT_PY = 'components.py' - - script_dir = os.path.dirname(os.path.abspath(__file__)) - RAW_FILE_PATH = os.path.join(script_dir, RAW_IN) - OUTPUT_PY_PATH = os.path.join(script_dir, OUT_PY) - - parsed_data = pw_to_dict(RAW_FILE_PATH) - print(f"\nParsing complete.\n") - - generate_components(parsed_data, OUTPUT_PY_PATH) - print(f"Successfully Produced -> components.py!\n") \ No newline at end of file diff --git a/esapp/indexable.py b/esapp/indexable.py index bac79d95..96c8b02a 100644 --- a/esapp/indexable.py +++ b/esapp/indexable.py @@ -1,5 +1,5 @@ from .saw import SAW, PowerWorldPrerequisiteError -from .gobject import GObject +from .components import GObject from .utils import timing from typing import Type, Optional from pandas import DataFrame @@ -22,17 +22,6 @@ class Indexable: esa: SAW fname: str - def set_esa(self, esa: SAW): - """ - Set the SAW (SimAuto Wrapper) instance for this object. - - Parameters - ---------- - esa : SAW - An initialized SAW instance. - """ - self.esa: SAW = esa - @timing def open(self): """ @@ -41,16 +30,24 @@ def open(self): This method validates the case path, initializes the SimAuto COM object, and attempts to initialize transient stability to ensure initial values are available for dynamic models. + + Raises + ------ + FileNotFoundError + If the case file does not exist on disk. """ # Validate Path Name if not path.isabs(self.fname): self.fname = path.abspath(self.fname) + if not path.exists(self.fname): + raise FileNotFoundError( + f"Case file not found: '{self.fname}'\n" + f"Please verify the file path is correct and the file exists." + ) + # ESA Object & Transient Sim self.esa = SAW(self.fname, CreateIfNotFound=True, early_bind=True) - - # Attempt and Initialize TS so we get initial values - self.esa.TSInitialize() def __getitem__(self, index) -> Optional[DataFrame]: """Retrieve data from PowerWorld using indexer notation. @@ -89,13 +86,13 @@ def __getitem__(self, index) -> Optional[DataFrame]: # 3. Add any additional fields based on the request. if requested_fields is None: - # Case: wb.pw[Bus] -> only key fields are needed. + # Case: pw[Bus] -> only key fields are needed. pass elif requested_fields == slice(None): - # Case: wb.pw[Bus, :] -> add all defined fields. + # Case: pw[Bus, :] -> add all defined fields. fields_to_get.update(gtype.fields) else: - # Case: wb.pw[Bus, 'field'] or wb.pw[Bus, ['f1', 'f2']] + # Case: pw[Bus, 'field'] or pw[Bus, ['f1', 'f2']] # Normalize to an iterable to handle single or multiple fields. if isinstance(requested_fields, (str, GObject)): requested_fields = [requested_fields] @@ -119,6 +116,24 @@ def __setitem__(self, args, value) -> None: """ Set grid data in PowerWorld using indexer notation. + Two write modes are supported: + + **Case 1 — Bulk update** ``idx[GObject] = DataFrame``: + Sends every column in *value* to PowerWorld via + ``ChangeParametersMultipleElementRect``. If the objects do + not yet exist (PowerWorld returns *"not found"*), the method + falls back to ``ChangeParametersMultipleElement`` which can + create new objects **provided the SAW instance was opened + with** ``CreateIfNotFound=True`` **and PowerWorld is in EDIT + mode** (see ``esa.EnterMode('EDIT')``). If primary keys are + missing from the DataFrame, a ``ValueError`` is raised + immediately — secondary keys are *not* required. + + **Case 2 — Broadcast update** ``idx[GObject, field(s)] = value``: + Reads existing objects' primary keys, appends *value* as new + column(s), and writes the result back. This path only + *updates* existing objects; it never creates new ones. + Parameters ---------- args : Union[Type[GObject], Tuple[Type[GObject], Union[str, List[str]]]] @@ -134,12 +149,12 @@ def __setitem__(self, args, value) -> None: TypeError If the index or value types are mismatched or unsupported. """ - # Case 1: Bulk update from a DataFrame. e.g., wb.pw[Bus] = df + # Case 1: Bulk update from a DataFrame. e.g., pw[Bus] = df if isinstance(args, type) and issubclass(args, GObject): self._bulk_update_from_df(args, value) return - # Case 2: Broadcast update to specific fields. e.g., wb.pw[Bus, 'BusPUVolt'] = 1.05 + # Case 2: Broadcast update to specific fields. e.g., pw[Bus, 'BusPUVolt'] = 1.05 if isinstance(args, tuple) and len(args) == 2: gtype, fields = args @@ -158,24 +173,50 @@ def __setitem__(self, args, value) -> None: raise TypeError(f"Unsupported index for __setitem__: {args}") def _bulk_update_from_df(self, gtype: Type[GObject], df: DataFrame): - """Handles creating or overwriting objects from a complete DataFrame. - - This corresponds to the use case: `wb.pw[ObjectType] = dataframe`. + """Update (or create) objects from a DataFrame. + + Execution flow + -------------- + 1. Validate that every column is *settable* (key, secondary, or + editable). Reject read-only fields early. + 2. Call ``ChangeParametersMultipleElementRect`` — this is the fast + path that updates all rows in a single COM round-trip. + 3. **If** the call raises ``PowerWorldPrerequisiteError`` with + *"not found"*: + + a. Check whether the DataFrame contains all **primary keys** + (``gtype.keys``). If any are missing, raise ``ValueError`` + — we cannot identify/create objects without them. + b. Fall back to ``ChangeParametersMultipleElement`` which + iterates row-by-row. When the SAW property + ``CreateIfNotFound`` is ``True`` **and** PowerWorld is in + **EDIT mode**, this variant creates objects that do not yet + exist. *"not found"* messages from this call are silently + suppressed (they are expected for newly created rows). + + 4. Any *other* ``PowerWorldPrerequisiteError`` (not "not found") + is re-raised immediately. + + Prerequisites for object creation + ---------------------------------- + * ``SAW(path, CreateIfNotFound=True)`` + * ``esa.EnterMode('EDIT')`` before the call Parameters ---------- gtype : Type[GObject] The GObject subclass representing the type of objects to update. df : pandas.DataFrame - The DataFrame containing object data. Columns must match PowerWorld - field names, including primary keys. + The DataFrame containing object data. Must include all + primary key columns (``gtype.keys``). Raises ------ TypeError - If value is not a DataFrame. + If *df* is not a DataFrame. ValueError - If any column is not settable (keys or editable fields). + If any column is not settable, or if primary keys are missing + when object creation is required. """ if not isinstance(df, DataFrame): raise TypeError("A DataFrame is required for bulk updates.") @@ -190,20 +231,31 @@ def _bulk_update_from_df(self, gtype: Type[GObject], df: DataFrame): try: self.esa.ChangeParametersMultipleElementRect(gtype.TYPE, df.columns.tolist(), df) except PowerWorldPrerequisiteError as e: - # If objects not found, check if missing identifiers could be the cause if "not found" in str(e).lower(): - missing_identifiers = gtype.identifiers - set(df.columns) - if missing_identifiers: + missing_keys = set(gtype.keys) - set(df.columns) + if missing_keys: raise ValueError( - f"Missing required identifier field(s) for {gtype.TYPE}: {missing_identifiers}. " - f"All identifiers (primary and secondary keys) must be included to create new objects." + f"Missing required primary key field(s) for {gtype.TYPE}: {missing_keys}. " + f"All primary keys must be included to create new objects." ) from e - raise + # Primary keys present — fall back to + # ChangeParametersMultipleElement which creates objects + # that do not yet exist. The "not found" message from + # this call is expected and suppressed. + cols = df.columns.tolist() + values = df.values.tolist() + try: + self.esa.ChangeParametersMultipleElement(gtype.TYPE, cols, values) + except PowerWorldPrerequisiteError as create_err: + if 'not found' not in str(create_err).lower(): + raise + else: + raise def _broadcast_update_to_fields(self, gtype: Type[GObject], fields: list[str], value): """Modifies specific fields for existing objects by broadcasting a value. - This corresponds to the use case: `wb.pw[ObjectType, 'FieldName'] = value`. + This corresponds to the use case: `pw[ObjectType, 'FieldName'] = value`. Parameters ---------- @@ -242,8 +294,8 @@ def _broadcast_update_to_fields(self, gtype: Type[GObject], fields: list[str], v ) change_df = DataFrame(data_dict) - # For objects with keys, we first get the keys of all existing objects - # to ensure we only modify what's already there. + # For objects with keys, we first get the keys (primary keys) + # of all existing objects to ensure we only modify what's already there. else: keys = gtype.keys change_df = self[gtype, keys] diff --git a/esapp/saw/__init__.py b/esapp/saw/__init__.py index d1d2c270..f001bbc4 100644 --- a/esapp/saw/__init__.py +++ b/esapp/saw/__init__.py @@ -22,6 +22,15 @@ class built from numerous mixins. Each mixin corresponds to a specific SimAutoFeatureError, PowerWorldPrerequisiteError, PowerWorldAddonError, + GridObjDNE, + FieldDataException, + AuxParseException, + ContainerDeletedException, + PowerFlowException, + BifurcationException, + DivergenceException, + GeneratorLimitException, + GICException, ) from ._helpers import ( df_to_aux, @@ -30,6 +39,39 @@ class built from numerous mixins. Each mixin corresponds to a specific convert_df_to_variant, convert_nested_list_to_variant, create_object_string, + get_temp_filepath, + format_list, + format_optional, + format_optional_numeric, +) +from ._enums import ( + YesNo, + FilterKeyword, + SolverMethod, + LinearMethod, + FileFormat, + InterfaceLimitSetting, + ObjectType, + KeyFieldType, + StarBusHandling, + MultiSectionLineHandling, + IslandReference, + OnelineLinkMode, + ShuntModel, + BranchDeviceType, + TSGetResultsMode, + JacobianForm, + BranchDistanceMeasure, + BranchFilterMode, + ScalingBasis, + ObjectIDHandling, + RatingSetPrecedence, + RatingSet, + FieldListColumn, + SpecificFieldListColumn, + format_filter, + format_filter_selected_only, + format_filter_areazone, ) @@ -43,10 +85,51 @@ class built from numerous mixins. Each mixin corresponds to a specific "SimAutoFeatureError", "PowerWorldPrerequisiteError", "PowerWorldAddonError", + "GridObjDNE", + "FieldDataException", + "AuxParseException", + "ContainerDeletedException", + "PowerFlowException", + "BifurcationException", + "DivergenceException", + "GeneratorLimitException", + "GICException", "df_to_aux", "convert_to_windows_path", "convert_list_to_variant", "convert_df_to_variant", "convert_nested_list_to_variant", "create_object_string", + "get_temp_filepath", + "format_list", + "format_optional", + "format_optional_numeric", + # Enums and type-safe constants + "YesNo", + "FilterKeyword", + "SolverMethod", + "LinearMethod", + "FileFormat", + "InterfaceLimitSetting", + "ObjectType", + "KeyFieldType", + "StarBusHandling", + "MultiSectionLineHandling", + "IslandReference", + "OnelineLinkMode", + "ShuntModel", + "BranchDeviceType", + "TSGetResultsMode", + "JacobianForm", + "BranchDistanceMeasure", + "BranchFilterMode", + "ScalingBasis", + "ObjectIDHandling", + "RatingSetPrecedence", + "RatingSet", + "FieldListColumn", + "SpecificFieldListColumn", + "format_filter", + "format_filter_selected_only", + "format_filter_areazone", ] diff --git a/esapp/saw/_enums.py b/esapp/saw/_enums.py new file mode 100644 index 00000000..5be2a7f1 --- /dev/null +++ b/esapp/saw/_enums.py @@ -0,0 +1,399 @@ +"""Enum types and constants for SimAuto wrapper. + +This module defines standardized types for string literals used throughout +the SAW module, replacing hardcoded strings with type-safe enumerations. +""" + +from enum import Enum +from typing import Union + + +class YesNo(str, Enum): + """Boolean flag values for PowerWorld commands. + + PowerWorld uses "YES" and "NO" strings for boolean parameters in + script commands rather than true/false. + """ + YES = "YES" + NO = "NO" + + @classmethod + def from_bool(cls, value: bool) -> "YesNo": + """Convert a Python boolean to YesNo enum. + + Parameters + ---------- + value : bool + The boolean value to convert. + + Returns + ------- + YesNo + YesNo.YES if value is True, YesNo.NO otherwise. + """ + return cls.YES if value else cls.NO + + def __str__(self): + return self.value + + +class FilterKeyword(str, Enum): + """Special filter keywords for PowerWorld commands. + + These keywords are passed unquoted to PowerWorld, unlike custom + filter names which must be quoted. + """ + SELECTED = "SELECTED" + AREAZONE = "AREAZONE" + ALL = "ALL" + + +class SolverMethod(str, Enum): + """Power flow solution methods. + + These are the available solver algorithms for the SolvePowerFlow command. + """ + RECTNEWT = "RECTNEWT" # Rectangular Newton-Raphson (default) + POLARNEWT = "POLARNEWT" # Polar Newton-Raphson + GAUSSSEIDEL = "GAUSSSEIDEL" # Gauss-Seidel + FASTDEC = "FASTDEC" # Fast Decoupled + ROBUST = "ROBUST" # Robust solver + DC = "DC" # DC power flow + + +class LinearMethod(str, Enum): + """Linear calculation methods for sensitivity analysis. + + Used in PTDF, LODF, shift factor, and related calculations. + """ + DC = "DC" # DC linear method (most common default) + AC = "AC" # AC linear method + DCPS = "DCPS" # DC linear with post-solution adjustment + + +class FileFormat(str, Enum): + """File format types for import/export operations.""" + CSV = "CSV" # Comma-separated values + CSVCOLHEADER = "CSVCOLHEADER" # CSV with column headers + CSVNOHEADER = "CSVNOHEADER" # CSV without headers + AUX = "AUX" # PowerWorld auxiliary format + AUXCSV = "AUXCSV" # Hybrid auxiliary/CSV format + TAB = "TAB" # Tab-separated format + PTI = "PTI" # PTI/PSS-E format + TXT = "TXT" # Text format + PWB = "PWB" # PowerWorld case format + AXD = "AXD" # Oneline diagram format + GE = "GE" # GE EPC format + CF = "CF" # Custom format + UCTE = "UCTE" # UCTE format + AREVAHDB = "AREVAHDB" # AREVA HDB format + OPENNETEMS = "OPENNETEMS" # OPENNET EMS format + + +class InterfaceLimitSetting(str, Enum): + """Interface limit configuration values.""" + AUTO = "AUTO" # Automatic limit calculation + NONE = "NONE" # No limit applied + + +class ObjectType(str, Enum): + """PowerWorld object type identifiers. + + These are used for filtering and operations on specific element types. + """ + BUS = "BUS" + BRANCH = "BRANCH" + GEN = "GEN" + LOAD = "LOAD" + SHUNT = "SHUNT" + AREA = "AREA" + ZONE = "ZONE" + OWNER = "OWNER" + INTERFACE = "INTERFACE" + INJECTIONGROUP = "INJECTIONGROUP" + BUSSHUNT = "BUSSHUNT" + SUPERBUS = "SUPERBUS" + TRANSFORMER = "TRANSFORMER" + LINE = "LINE" + SUPERAREA = "SUPERAREA" + + +class KeyFieldType(str, Enum): + """Key field types for result output.""" + PRIMARY = "PRIMARY" + SECONDARY = "SECONDARY" + LABEL = "LABEL" + + +class StarBusHandling(str, Enum): + """Star bus handling options for case append operations.""" + NEAR = "NEAR" # Map to nearest bus (default) + MAX = "MAX" # Map to maximum impedance bus + + +class MultiSectionLineHandling(str, Enum): + """Multi-section line handling options for case append operations.""" + MAINTAIN = "MAINTAIN" # Maintain multisection line structure (default) + EQUIVALENCE = "EQUIVALENCE" # Convert to equivalent circuits + + +class IslandReference(str, Enum): + """Island reference options for sensitivity analysis.""" + EXISTING = "EXISTING" # Use existing island configuration + NO = "NO" # No area reference + + +class OnelineLinkMode(str, Enum): + """Oneline diagram linking modes.""" + LABELS = "LABELS" # Link objects by labels (default) + NUMBERS = "NUMBERS" # Link objects by numbers + + +class ShuntModel(str, Enum): + """Shunt model types for line tapping operations.""" + CAPACITANCE = "CAPACITANCE" + INDUCTANCE = "INDUCTANCE" + + +class BranchDeviceType(str, Enum): + """Branch device types for bus splitting operations.""" + LINE = "Line" + BREAKER = "Breaker" + + +class TSGetResultsMode(str, Enum): + """Mode for saving transient stability results.""" + SINGLE = "SINGLE" + SEPARATE = "SEPARATE" + JSIS = "JSIS" + + +class JacobianForm(str, Enum): + """Jacobian matrix coordinate forms.""" + RECTANGULAR = "R" # AC Jacobian in Rectangular coordinates + POLAR = "P" # AC Jacobian in Polar coordinates + DC = "DC" # B' matrix (DC approximation) + + +class BranchDistanceMeasure(str, Enum): + """Branch distance measurement types for topology analysis.""" + REACTANCE = "X" # Use reactance as distance measure + IMPEDANCE = "Z" # Use impedance magnitude as distance measure + + +class BranchFilterMode(str, Enum): + """Branch filter modes for topology traversal.""" + ALL = "ALL" # All branches + SELECTED = "SELECTED" # Only selected branches + CLOSED = "CLOSED" # Only closed branches + + +class ScalingBasis(str, Enum): + """Scaling basis for load/generation scaling operations.""" + MW = "MW" # Absolute MW/MVAR values + FACTOR = "FACTOR" # Multiplier factor + + +class ObjectIDHandling(str, Enum): + """Object ID handling modes for contingency export.""" + NO = "NO" # Standard object references + YES_MS_3W = "YES_MS_3W" # Include multi-section and 3-winding IDs + + +class RatingSetPrecedence(str, Enum): + """Rating set precedence for weather-based ratings.""" + NORMAL = "NORMAL" # Use normal rating set + CTG = "CTG" # Use contingency rating set + + +class RatingSet(str, Enum): + """Rating set identifiers for branch limits.""" + DEFAULT = "DEFAULT" # Use default rating + NO = "NO" # Don't update rating + A = "A" + B = "B" + C = "C" + D = "D" + E = "E" + F = "F" + G = "G" + H = "H" + I = "I" + J = "J" + K = "K" + L = "L" + M = "M" + N = "N" + O = "O" + + +class FieldListColumn(str, Enum): + """Column names for GetFieldList results. + + PowerWorld returns field metadata with these column headers. Different + Simulator versions may return different subsets of these columns. + """ + KEY_FIELD = "key_field" + INTERNAL_FIELD_NAME = "internal_field_name" + FIELD_DATA_TYPE = "field_data_type" + DESCRIPTION = "description" + DISPLAY_NAME = "display_name" + ENTERABLE = "enterable" + + @classmethod + def base_columns(cls) -> list: + """Returns the standard 5-column format (most common).""" + return [ + cls.KEY_FIELD.value, + cls.INTERNAL_FIELD_NAME.value, + cls.FIELD_DATA_TYPE.value, + cls.DESCRIPTION.value, + cls.DISPLAY_NAME.value, + ] + + @classmethod + def old_columns(cls) -> list: + """Returns the legacy 4-column format (older Simulator versions).""" + return [ + cls.KEY_FIELD.value, + cls.INTERNAL_FIELD_NAME.value, + cls.FIELD_DATA_TYPE.value, + cls.DESCRIPTION.value, + ] + + @classmethod + def new_columns(cls) -> list: + """Returns the extended 6-column format (newer Simulator versions).""" + return [ + cls.KEY_FIELD.value, + cls.INTERNAL_FIELD_NAME.value, + cls.FIELD_DATA_TYPE.value, + cls.DESCRIPTION.value, + cls.DISPLAY_NAME.value, + cls.ENTERABLE.value, + ] + + +class SpecificFieldListColumn(str, Enum): + """Column names for GetSpecificFieldList results. + + PowerWorld returns specific field metadata with these column headers. + """ + VARIABLENAME_LOCATION = "variablename:location" + FIELD = "field" + COLUMN_HEADER = "column header" + FIELD_DESCRIPTION = "field description" + ENTERABLE = "enterable" + + @classmethod + def base_columns(cls) -> list: + """Returns the standard 4-column format.""" + return [ + cls.VARIABLENAME_LOCATION.value, + cls.FIELD.value, + cls.COLUMN_HEADER.value, + cls.FIELD_DESCRIPTION.value, + ] + + @classmethod + def new_columns(cls) -> list: + """Returns the extended 5-column format (newer Simulator versions).""" + return [ + cls.VARIABLENAME_LOCATION.value, + cls.FIELD.value, + cls.COLUMN_HEADER.value, + cls.FIELD_DESCRIPTION.value, + cls.ENTERABLE.value, + ] + + +# Type aliases for flexibility - allows either enum or raw string +FilterType = Union[FilterKeyword, str] + + +def format_filter(filter_name: FilterType) -> str: + """Format a filter name for use in PowerWorld commands. + + Special filter keywords (SELECTED, AREAZONE, ALL) are passed unquoted, + while custom filter names are quoted. + + Parameters + ---------- + filter_name : FilterType + The filter name to format. Can be a FilterKeyword enum or a string. + + Returns + ------- + str + The formatted filter string for use in script commands. + """ + if not filter_name: + return "" + + # Handle enum values + if isinstance(filter_name, FilterKeyword): + return filter_name.value + + # Handle string values - check if it's a special keyword + if filter_name in (FilterKeyword.SELECTED.value, FilterKeyword.AREAZONE.value, FilterKeyword.ALL.value): + return filter_name + + # Custom filter name - needs quotes + return f'"{filter_name}"' + + +def format_filter_selected_only(filter_name: FilterType) -> str: + """Format a filter name, treating only SELECTED as special. + + Only SELECTED is passed unquoted; other values including AREAZONE and ALL + are quoted like custom filter names. + + Parameters + ---------- + filter_name : FilterType + The filter name to format. + + Returns + ------- + str + The formatted filter string. + """ + if not filter_name: + return "" + + if isinstance(filter_name, FilterKeyword) and filter_name == FilterKeyword.SELECTED: + return filter_name.value + + if filter_name == FilterKeyword.SELECTED.value: + return filter_name + + return f'"{filter_name}"' + + +def format_filter_areazone(filter_name: FilterType) -> str: + """Format a filter name, treating SELECTED and AREAZONE as special. + + SELECTED and AREAZONE are passed unquoted; ALL and custom names are quoted. + + Parameters + ---------- + filter_name : FilterType + The filter name to format. + + Returns + ------- + str + The formatted filter string. + """ + if not filter_name: + return "" + + if isinstance(filter_name, FilterKeyword): + if filter_name in (FilterKeyword.SELECTED, FilterKeyword.AREAZONE): + return filter_name.value + return f'"{filter_name.value}"' + + if filter_name in (FilterKeyword.SELECTED.value, FilterKeyword.AREAZONE.value): + return filter_name + + return f'"{filter_name}"' diff --git a/esapp/saw/_exceptions.py b/esapp/saw/_exceptions.py index 6c331184..f51d5457 100644 --- a/esapp/saw/_exceptions.py +++ b/esapp/saw/_exceptions.py @@ -98,7 +98,7 @@ class PowerWorldPrerequisiteError(PowerWorldError): Nuance: Many PowerWorld script commands (as defined in the Auxiliary File Format) require specific data structures to be populated before execution. For example, - `CTGSolve` requires defined contingencies, and `DetermineATC` requires defined + `CTGSolve` requires defined contingencies, and `ATCDetermine` requires defined transfer directions. This error indicates a setup issue rather than a fundamental system failure. """ @@ -145,4 +145,62 @@ class CommandNotRespectedError(PowerWorldError): change actually occurred. """ + pass + + +# ============================================================================= +# Application-level exceptions (consolidated from utils/exceptions.py) +# ============================================================================= + + +class GridObjDNE(Error): + """ + Raised when a grid object data query fails. + + This indicates the requested object does not exist in the case. + """ + pass + + +class FieldDataException(Error): + """Raised when there is an issue with field data retrieval or parsing.""" + pass + + +class AuxParseException(Error): + """Raised when parsing an auxiliary file fails.""" + pass + + +class ContainerDeletedException(Error): + """Raised when attempting to access a container that has been deleted.""" + pass + + +class PowerFlowException(Error): + """ + Raised when a power flow solution error occurs. + + This is the base class for power flow related errors. + """ + pass + + +class BifurcationException(PowerFlowException): + """Raised when voltage bifurcation is suspected during power flow.""" + pass + + +class DivergenceException(PowerFlowException): + """Raised when the power flow solution diverges.""" + pass + + +class GeneratorLimitException(PowerFlowException): + """Raised when a generator has exceeded a limit during power flow.""" + pass + + +class GICException(Error): + """Raised when a GIC (Geomagnetically Induced Current) analysis error occurs.""" pass \ No newline at end of file diff --git a/esapp/saw/_helpers.py b/esapp/saw/_helpers.py index db8218f8..db2fdcb8 100644 --- a/esapp/saw/_helpers.py +++ b/esapp/saw/_helpers.py @@ -1,14 +1,243 @@ """Helper functions for data conversion for SimAuto COM interface.""" import json -from pathlib import PureWindowsPath -from typing import List +import logging +import os +import re +import tempfile +import uuid +from pathlib import Path, PureWindowsPath +from typing import List, Optional, Tuple, Union, Sequence +import pandas as pd import pythoncom import win32com from win32com.client import VARIANT +# ============================================================================= +# PowerWorld Command String Formatting Helpers +# ============================================================================= + + +def load_ts_csv_results(base_path: Path, delete_files: bool = False) -> Tuple[pd.DataFrame, pd.DataFrame]: + """ + Reads and parses transient stability results from CSV files generated by PowerWorld. + + Args: + base_path: The base file path used in the TSGetResults command. + delete_files: Whether to delete the found files after reading. + + Returns: + Tuple[pd.DataFrame, pd.DataFrame]: (Metadata, Time-Series Data) + """ + logger = logging.getLogger(__name__) + + # PowerWorld appends suffixes, so we search for the base name pattern. + search_pattern = f"{base_path.stem}*.csv" + found_files = list(base_path.parent.glob(search_pattern)) + + meta = pd.DataFrame() + data_frames = [] + + try: + if not found_files: + return meta, pd.DataFrame() + + header_files = [f for f in found_files if "_header" in f.name.lower()] + data_files = [f for f in found_files if f not in header_files] + + # --- Process Header --- + if header_files: + # Use the first header file found + header_path = header_files[0] + try: + # Check if first line is just a title (e.g. "ObjectFields") + with header_path.open('r') as f: + first_line = f.readline() + + # PowerWorld sometimes puts "ObjectFields" on the first line alone + skip_rows = 1 if "ObjectFields" in first_line and "," not in first_line else 0 + + meta = pd.read_csv(header_path, sep=',', skiprows=skip_rows) + meta.columns = meta.columns.str.strip() + + # Standardize column names + rename_map = { + 'Column': 'ColHeader', + 'Object': 'ObjectType', + 'Variable': 'VariableName', + 'Key 1': 'PrimaryKey', + 'Key 2': 'SecondaryKey' + } + meta.rename(columns=rename_map, inplace=True) + + # Force ColHeader to be 0-based index strings to match data columns + meta['ColHeader'] = [str(i) for i in range(len(meta))] + + except Exception as e: + logger.warning(f"Failed to read header file {header_path}: {e}") + + # --- Process Data --- + for dpath in data_files: + try: + df = pd.read_csv(dpath, sep=',', header=None) + + if not df.empty: + # Rename time column (index 0) and data columns (1..N) + # Map 0 -> "time", 1 -> "0", 2 -> "1", ... + col_map = {0: "time"} + col_map.update({i: str(i-1) for i in range(1, len(df.columns))}) + df.rename(columns=col_map, inplace=True) + data_frames.append(df) + except Exception as e: + logger.warning(f"Failed to read data file {dpath}: {e}") + + data = pd.concat(data_frames, ignore_index=True) if data_frames else pd.DataFrame() + + # Ensure time is float and sorted + if 'time' in data.columns: + data['time'] = pd.to_numeric(data['time'], errors='coerce') + data.sort_values('time', inplace=True) + + return meta, data + + finally: + if delete_files: + for f in found_files: + try: + f.unlink(missing_ok=True) + except OSError as e: + logger.warning(f"Failed to unlink temp file {f}: {e}") + + +def get_temp_filepath(suffix: str = ".csv") -> str: + """Generates a unique temporary filepath.""" + temp_dir = tempfile.gettempdir() + unique_name = f"esa_{uuid.uuid4()}{suffix}" + return os.path.join(temp_dir, unique_name) + + +def format_list( + items: Optional[Sequence], + quote_items: bool = False, + stringify: bool = False, +) -> str: + """Format a Python sequence as a PowerWorld bracketed list. + + This is the standard way to pass array parameters to PowerWorld script commands. + + Parameters + ---------- + items : Optional[Sequence] + The items to format. If None or empty, returns "[]". + quote_items : bool, optional + If True, wraps each item in double quotes. Use for string fields like + names or labels. Defaults to False. + stringify : bool, optional + If True, converts each item to string using str(). Use for numeric + values or mixed types. Defaults to False. + + Returns + ------- + str + A bracketed list string like "[item1, item2, ...]" or "[]". + + Examples + -------- + >>> format_list(["BusNum", "BusName"]) + '[BusNum, BusName]' + + >>> format_list(["Gen1", "Gen2"], quote_items=True) + '["Gen1", "Gen2"]' + + >>> format_list([1.5, 2.0, 3.5], stringify=True) + '[1.5, 2.0, 3.5]' + + >>> format_list(None) + '[]' + """ + if not items: + return "[]" + + if quote_items: + formatted = [f'"{item}"' for item in items] + elif stringify: + formatted = [str(item) for item in items] + else: + formatted = list(items) + + return "[" + ", ".join(formatted) + "]" + + +def format_optional( + value: Optional[str], + quote: bool = True, + empty_quoted: bool = False, +) -> str: + """Format an optional string parameter for PowerWorld commands. + + Parameters + ---------- + value : Optional[str] + The value to format. If None or empty string, returns empty or quoted empty. + quote : bool, optional + If True, wraps non-empty values in double quotes. Defaults to True. + empty_quoted : bool, optional + If True, returns '""' for empty values instead of "". Defaults to False. + + Returns + ------- + str + The formatted parameter string. + + Examples + -------- + >>> format_optional("MyFilter") + '"MyFilter"' + + >>> format_optional("") + '' + + >>> format_optional("", empty_quoted=True) + '""' + + >>> format_optional("SomeValue", quote=False) + 'SomeValue' + """ + if not value: + return '""' if empty_quoted else "" + + return f'"{value}"' if quote else value + + +def format_optional_numeric(value: Optional[Union[int, float]]) -> str: + """Format an optional numeric parameter for PowerWorld commands. + + Parameters + ---------- + value : Optional[Union[int, float]] + The numeric value to format. If None, returns an empty string. + + Returns + ------- + str + The string representation of the value, or "" if None. + + Examples + -------- + >>> format_optional_numeric(3.14) + '3.14' + + >>> format_optional_numeric(None) + '' + + >>> format_optional_numeric(0) + '0' + """ + return str(value) if value is not None else "" + + def df_to_aux(fp, df, object_name: str): """Convert a dataframe to PW aux/axd data section. @@ -79,7 +308,7 @@ def create_object_string(object_type: str, *keys) -> str: """ Helper to format a PowerWorld object string identifier. - This function creates strings formatted like '[BUS 1]' or '[BRANCH 1 2 "1"]' + This function creates strings formatted like ``[BUS 1]`` or ``[BRANCH 1 2 1]`` which are used to identify objects in SimAuto script commands. Parameters @@ -87,23 +316,196 @@ def create_object_string(object_type: str, *keys) -> str: object_type : str The type of object (e.g. "Bus", "Gen", "Branch"). *keys : Any - The key values identifying the object. Strings will be automatically - enclosed in double quotes if they are not already quoted. + The key values identifying the object. Returns ------- str - Formatted string like '[ObjectType key1 key2 ...]'. + Formatted string like ``[ObjectType key1 key2 ...]``. """ parts = [object_type.upper()] for key in keys: - if isinstance(key, str): - # Check if already quoted with " or ' - if (len(key) >= 2) and ((key.startswith('"') and key.endswith('"')) or (key.startswith("'") and key.endswith("'"))): - parts.append(key) - else: - parts.append(f'"{key}"') - else: - parts.append(str(key)) + parts.append(str(key)) + + return f"[{' '.join(parts)}]" + + +def pack_args(*args) -> str: + """ + Formats arguments for a PowerWorld script command. - return f"[{' '.join(parts)}]" \ No newline at end of file + Filters out trailing None values. Converts remaining None values to empty strings. + Joins arguments with commas. + """ + args_list = list(args) + while args_list and args_list[-1] is None: + args_list.pop() + + return ", ".join("" if a is None else str(a) for a in args_list) + + +# ============================================================================= +# AUX Parsing / Building Helpers +# ============================================================================= + +_SPLITTER = re.compile(r'(?:[^\s"]|"(?:\\.|[^"])*")+') + + +def parse_aux_line(line: str) -> List[str]: + """Parse one AUX data line, detecting bracket or space-delimited format. + + Bracket format example: ``[1, 100.0], [2, 200.0]`` + Space-delimited example: ``101 "Gen 1" 50.0`` + + Only treats the line as bracket format when it consists entirely of + ``[...]`` groups (ignoring whitespace/commas between them). + + Parameters + ---------- + line : str + A single data line from inside a DATA or SUBDATA block. + + Returns + ------- + List[str] + Parsed field values. + """ + line = line.strip() + if not line: + return [] + # Bracket format: entire line is bracket groups separated by commas/spaces + stripped = re.sub(r'\[.*?\]', '', line).replace(',', '').strip() + if '[' in line and not stripped: + return [m.group(1).strip() for m in re.finditer(r'\[(.*?)\]', line)] + # Space-delimited (respecting quoted strings) + return [x.replace('"', '') for x in _SPLITTER.findall(line)] + + +def parse_aux_content(content: str, fieldlist: List[str], + subdatalist: Optional[List[str]] = None) -> List[dict]: + """Parse AUX file content into a list of record dicts. + + Supports both header formats produced by PowerWorld: + + * **Legacy**: ``DATA (ObjectType, [field1, field2]) { ... }`` + * **Concise**: ``ObjectType (field1, field2) { ... }`` + + Parameters + ---------- + content : str + Full text of the AUX file. + fieldlist : List[str] + Expected field names for the parent object. + subdatalist : List[str], optional + SubData section names to look for. Defaults to ``[]``. + + Returns + ------- + List[dict] + Each dict has keys from *fieldlist* (scalar strings) and from + *subdatalist* (lists of lists). + + Raises + ------ + ValueError + If a ```` tag is malformed (missing name). + """ + subdatalist = subdatalist or [] + + # Try Legacy format first, then Concise + match = re.search( + r'DATA\s*\(\s*\w+\s*,\s*\[.*?\]\s*\)\s*\{(.*)\}', + content, re.DOTALL | re.IGNORECASE, + ) + if not match: + match = re.search( + r'\w+\s*\(.*?\)\s*\{(.*)\}', + content, re.DOTALL, + ) + if not match: + return [] + + records: List[dict] = [] + curr: dict = {} + sub_key: Optional[str] = None + + for line in match.group(1).strip().split('\n'): + line = line.strip() + if not line or line.startswith('//'): + continue + + if line.upper().startswith('', line, re.IGNORECASE) + if not m: + raise ValueError(f"Malformed SUBDATA tag: {line!r}") + sub_key = m.group(1) + elif line.upper().startswith(''): + sub_key = None + elif sub_key: + curr.setdefault(sub_key, []).append(parse_aux_line(line)) + else: + if curr: + records.append(curr) + tokens = _SPLITTER.findall(line) + curr = { + k: v.replace('"', '') + for k, v in zip(fieldlist, tokens) + } + for s in subdatalist: + curr[s] = [] + + if curr: + records.append(curr) + return records + + +def _fmt_aux_value(val) -> str: + """Format a single value for AUX output (quote strings, stringify numbers).""" + if isinstance(val, str): + return f'"{val}"' + return str(val) + + +def build_aux_string(objecttype: str, fieldlist: List[str], + records: List[dict], + subdatatypes: Optional[Union[str, List[str]]] = None) -> str: + """Build an AUX DATA block string from records. + + Parameters + ---------- + objecttype : str + PowerWorld object type (e.g. ``"Gen"``, ``"Contingency"``). + fieldlist : List[str] + Field names for the parent object. + records : List[dict] + Each dict must have keys from *fieldlist*. If *subdatatypes* is + provided, the dict may also have a key for each subdata type + whose value is a list of lists. + subdatatypes : str or List[str] or None + SubData section names to write. A single string is normalised + to a one-element list. + + Returns + ------- + str + Complete AUX DATA block ready for ``exec_aux``. + """ + if subdatatypes is None: + subdatatypes = [] + elif isinstance(subdatatypes, str): + subdatatypes = [subdatatypes] + + header = f'DATA ({objecttype}, [{", ".join(fieldlist)}])\n{{\n' + body_lines: List[str] = [] + + for rec in records: + vals = [_fmt_aux_value(rec[f]) for f in fieldlist] + body_lines.append(" ".join(vals)) + for sdt in subdatatypes: + if sdt in rec and rec[sdt]: + body_lines.append(f" ") + for row in rec[sdt]: + body_lines.append(" " + " ".join(_fmt_aux_value(v) for v in row)) + body_lines.append(" ") + + return header + "\n".join(body_lines) + "\n}\n" \ No newline at end of file diff --git a/esapp/saw/atc.py b/esapp/saw/atc.py index ee8c6151..b571560d 100644 --- a/esapp/saw/atc.py +++ b/esapp/saw/atc.py @@ -2,11 +2,14 @@ import pandas as pd from typing import List +from ._enums import YesNo +from ._helpers import format_list, pack_args + class ATCMixin: """Mixin for ATC analysis functions.""" - def DetermineATC( + def ATCDetermine( self, seller: str, buyer: str, @@ -38,13 +41,11 @@ def DetermineATC( PowerWorldError If the SimAuto call fails (e.g., invalid seller/buyer, calculation error). """ - dist = "YES" if distributed else "NO" - mult = "YES" if multiple_scenarios else "NO" - return self.RunScriptCommand( - f"ATCDetermine({seller}, {buyer}, {dist}, {mult});" - ) + dist = YesNo.from_bool(distributed) + mult = YesNo.from_bool(multiple_scenarios) + return self._run_script("ATCDetermine", seller, buyer, dist, mult) - def DetermineATCMultipleDirections( + def ATCDetermineMultipleDirections( self, distributed: bool = False, multiple_scenarios: bool = False ): """Calculates ATC for all directions defined within the PowerWorld case. @@ -69,11 +70,9 @@ def DetermineATCMultipleDirections( PowerWorldError If the SimAuto call fails (e.g., no directions defined, calculation error). """ - dist = "YES" if distributed else "NO" - mult = "YES" if multiple_scenarios else "NO" - return self.RunScriptCommand( - f"ATCDetermineMultipleDirections({dist}, {mult});" - ) + dist = YesNo.from_bool(distributed) + mult = YesNo.from_bool(multiple_scenarios) + return self._run_script("ATCDetermineMultipleDirections", dist, mult) def GetATCResults(self, fields: list = None) -> pd.DataFrame: """Retrieves Transfer Limiter results from the case after an ATC calculation. @@ -126,11 +125,11 @@ def ATCCreateContingentInterfaces(self, filter_name: str = ""): """ filt = f'"{filter_name}"' if filter_name else "" - return self.RunScriptCommand(f"ATCCreateContingentInterfaces({filt});") + return self._run_script("ATCCreateContingentInterfaces", filt) def ATCDeleteAllResults(self): """Deletes all ATC results including TransferLimiter, ATCExtraMonitor, and ATCFlowValue object types.""" - return self.RunScriptCommand("ATCDeleteAllResults;") + return self._run_script("ATCDeleteAllResults") def ATCDeleteScenarioChangeIndexRange(self, scenario_change_type: str, index_range: List[str]): """Deletes entries within an ATC scenario change type by index. @@ -147,8 +146,8 @@ def ATCDeleteScenarioChangeIndexRange(self, scenario_change_type: str, index_ran The indices start at 0. """ - ir = "[" + ", ".join(index_range) + "]" - return self.RunScriptCommand(f"ATCDeleteScenarioChangeIndexRange({scenario_change_type}, {ir});") + ir = format_list(index_range) + return self._run_script("ATCDeleteScenarioChangeIndexRange", scenario_change_type, ir) def ATCDetermineATCFor(self, rl: int, g: int, i: int, apply_transfer: bool = False): """Determines the ATC for a specific Scenario RL, G, I. @@ -166,16 +165,16 @@ def ATCDetermineATCFor(self, rl: int, g: int, i: int, apply_transfer: bool = Fal Defaults to False. """ - at = "YES" if apply_transfer else "NO" - return self.RunScriptCommand(f"ATCDetermineATCFor({rl}, {g}, {i}, {at});") + at = YesNo.from_bool(apply_transfer) + return self._run_script("ATCDetermineATCFor", rl, g, i, at) def ATCDetermineMultipleDirectionsATCFor(self, rl: int, g: int, i: int): """Determines the ATC for Scenario RL, G, I for all defined directions.""" - return self.RunScriptCommand(f"ATCDetermineMultipleDirectionsATCFor({rl}, {g}, {i});") + return self._run_script("ATCDetermineMultipleDirectionsATCFor", rl, g, i) def ATCIncreaseTransferBy(self, amount: float): """Increases the transfer between the seller and buyer by a specified amount.""" - return self.RunScriptCommand(f"ATCIncreaseTransferBy({amount});") + return self._run_script("ATCIncreaseTransferBy", amount) def ATCRestoreInitialState(self): """Restores the initial state for the ATC tool. @@ -192,7 +191,7 @@ def ATCRestoreInitialState(self): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand("ATCRestoreInitialState;") + return self._run_script("ATCRestoreInitialState") def ATCSetAsReference(self): """Sets the present system state as the reference state for ATC analysis. @@ -208,7 +207,7 @@ def ATCSetAsReference(self): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand("ATCSetAsReference;") + return self._run_script("ATCSetAsReference") def ATCTakeMeToScenario(self, rl: int, g: int, i: int): """Sets the present case according to the scenarios along the RL, G, and I axes. @@ -234,7 +233,7 @@ def ATCTakeMeToScenario(self, rl: int, g: int, i: int): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f"ATCTakeMeToScenario({rl}, {g}, {i});") + return self._run_script("ATCTakeMeToScenario", rl, g, i) def ATCDataWriteOptionsAndResults(self, filename: str, append: bool = True, key_field: str = "PRIMARY"): """Writes out all information related to ATC analysis to an auxiliary file. @@ -265,8 +264,8 @@ def ATCDataWriteOptionsAndResults(self, filename: str, append: bool = True, key_ PowerWorldError If the SimAuto call fails. """ - app = "YES" if append else "NO" - return self.RunScriptCommand(f'ATCDataWriteOptionsAndResults("{filename}", {app}, {key_field});') + app = YesNo.from_bool(append) + return self._run_script("ATCDataWriteOptionsAndResults", f'"{filename}"', app, key_field) def ATCWriteAllOptions(self, filename: str, append: bool = True, key_field: str = "PRIMARY"): """Writes out all information related to ATC analysis (deprecated name). @@ -314,8 +313,8 @@ def ATCWriteResultsAndOptions(self, filename: str, append: bool = True): PowerWorldError If the SimAuto call fails. """ - app = "YES" if append else "NO" - return self.RunScriptCommand(f'ATCWriteResultsAndOptions("{filename}", {app});') + app = YesNo.from_bool(append) + return self._run_script("ATCWriteResultsAndOptions", f'"{filename}"', app) def ATCWriteScenarioLog(self, filename: str, append: bool = False, filter_name: str = ""): """Writes out detailed log information for ATC Multiple Scenarios to a text file. @@ -342,9 +341,9 @@ def ATCWriteScenarioLog(self, filename: str, append: bool = False, filter_name: PowerWorldError If the SimAuto call fails. """ - app = "YES" if append else "NO" + app = YesNo.from_bool(append) filt = f'"{filter_name}"' if filter_name else "" - return self.RunScriptCommand(f'ATCWriteScenarioLog("{filename}", {app}, {filt});') + return self._run_script("ATCWriteScenarioLog", f'"{filename}"', app, filt) def ATCWriteScenarioMinMax( self, @@ -353,8 +352,8 @@ def ATCWriteScenarioMinMax( append: bool = False, fieldlist: List[str] = None, operation: str = "MIN", - operation_field: str = "MaxFlow", - group_scenario: bool = True, + operation_field: str = "TransferLimit", + group_scenario: str = "NONE", ): """Writes out TransferLimiter results from multiple scenario ATC calculations. @@ -376,9 +375,11 @@ def ATCWriteScenarioMinMax( Operation to perform on each grouping: "MIN", "MAX", or "MINMAX". Defaults to "MIN". operation_field : str, optional - Field to use for the min/max operation. Defaults to "MaxFlow". - group_scenario : bool, optional - If True, groups by scenario. Defaults to True. + Field to use for the min/max operation. Must be "TransferLimit" + or "ATCExtraMonitor". Defaults to "TransferLimit". + group_scenario : str, optional + How to group scenarios. Use "NONE" to not group, or a scenario + type name. Defaults to "NONE". Returns ------- @@ -389,16 +390,10 @@ def ATCWriteScenarioMinMax( PowerWorldError If the SimAuto call fails. """ - app = "YES" if append else "NO" - gs = "YES" if group_scenario else "NO" - fields = "" - if fieldlist: - fields = "[" + ", ".join(fieldlist) + "]" - else: - fields = "[]" - return self.RunScriptCommand( - f'ATCWriteScenarioMinMax("{filename}", {filetype}, {app}, {fields}, {operation}, {operation_field}, {gs});' - ) + app = YesNo.from_bool(append) + fields = format_list(fieldlist) + args = pack_args(f'"{filename}"', filetype, app, fields, operation, operation_field, group_scenario) + return self.RunScriptCommand(f"ATCWriteScenarioMinMax({args});") def ATCWriteToExcel(self, worksheet_name: str, fieldlist: List[str] = None): """Sends ATC analysis results to an Excel spreadsheet for Multiple Scenarios ATC analysis. @@ -419,9 +414,7 @@ def ATCWriteToExcel(self, worksheet_name: str, fieldlist: List[str] = None): PowerWorldError If the SimAuto call fails. """ - fields = "" - if fieldlist: - fields = ", [" + ", ".join(fieldlist) + "]" + fields = ", " + format_list(fieldlist) if fieldlist else "" return self.RunScriptCommand(f'ATCWriteToExcel("{worksheet_name}"{fields});') def ATCWriteToText(self, filename: str, filetype: str = "TAB", fieldlist: List[str] = None): @@ -445,7 +438,5 @@ def ATCWriteToText(self, filename: str, filetype: str = "TAB", fieldlist: List[s PowerWorldError If the SimAuto call fails. """ - fields = "" - if fieldlist: - fields = ", [" + ", ".join(fieldlist) + "]" + fields = ", " + format_list(fieldlist) if fieldlist else "" return self.RunScriptCommand(f'ATCWriteToText("{filename}", {filetype}{fields});') diff --git a/esapp/saw/base.py b/esapp/saw/base.py index 2e210427..822c3590 100644 --- a/esapp/saw/base.py +++ b/esapp/saw/base.py @@ -3,88 +3,28 @@ import logging import os import re -import tempfile -from pathlib import Path -from typing import List, Tuple, Union +from typing import Union -import numpy as np -import pandas as pd import pythoncom import win32com from ._exceptions import ( COMError, - CommandNotRespectedError, - Error, PowerWorldError, RPC_S_UNKNOWN_IF, RPC_S_CALL_FAILED, ) from ._helpers import ( - convert_df_to_variant, convert_list_to_variant, - convert_nested_list_to_variant, - convert_to_windows_path, + get_temp_filepath, ) # Set up locale locale.setlocale(locale.LC_ALL, "") -logging.basicConfig(format="%(asctime)s [%(levelname)s] [%(name)s]: %(message)s", datefmt="%H:%M:%S", level=logging.INFO) - # noinspection PyPep8Naming class SAWBase(object): """Base class for the SimAuto Wrapper, containing core COM functionality.""" - POWER_FLOW_FIELDS = { - "bus": ["BusNum", "BusName", "BusPUVolt", "BusAngle", "BusNetMW", "BusNetMVR"], - "gen": ["BusNum", "GenID", "GenMW", "GenMVR"], - "load": ["BusNum", "LoadID", "LoadMW", "LoadMVR"], - "shunt": ["BusNum", "ShuntID", "ShuntMW", "ShuntMVR"], - "branch": [ - "BusNum", - "BusNum:1", - "LineCircuit", - "LineMW", - "LineMW:1", - "LineMVR", - "LineMVR:1", - ], - } - - FIELD_LIST_COLUMNS = [ - "key_field", - "internal_field_name", - "field_data_type", - "description", - "display_name", - ] - - FIELD_LIST_COLUMNS_OLD = FIELD_LIST_COLUMNS[0:-1] - - FIELD_LIST_COLUMNS_NEW = [ - "key_field", - "internal_field_name", - "field_data_type", - "description", - "display_name", - "enterable", - ] - - SPECIFIC_FIELD_LIST_COLUMNS = [ - "variablename:location", - "field", - "column header", - "field description", - ] - - SPECIFIC_FIELD_LIST_COLUMNS_NEW = [ - "variablename:location", - "field", - "column header", - "field description", - "enterable", - ] - SIMAUTO_PROPERTIES = { "CreateIfNotFound": bool, "CurrentDir": str, @@ -151,9 +91,9 @@ def __init__( self.pw_order = pw_order # Initialize temporary file for UI updates - self.ntf = tempfile.NamedTemporaryFile(mode="w", suffix=".axd", delete=False) - self.empty_aux = Path(self.ntf.name).as_posix() - self.ntf.close() + self.empty_aux = get_temp_filepath(".axd") + with open(self.empty_aux, "w") as f: + pass self.OpenCase(FileName=FileName) @@ -165,67 +105,8 @@ def __init__( 'CaseInfo_Options_Value (Option,Value)\n{"UseDefinedNamesInVariables" "YES"}' ) - self.lodf = None self._object_fields = {} - def change_and_confirm_params_multiple_element(self, ObjectType: str, command_df: pd.DataFrame) -> None: - """Modifies parameters for multiple elements and verifies the change was successfully applied in PowerWorld. - - This method first attempts to change parameters using `ChangeParametersMultipleElement`, - then immediately retrieves the same parameters from PowerWorld to confirm the changes. - - Parameters - ---------- - ObjectType : str - The PowerWorld object type (e.g., 'Bus', 'Gen'). - command_df : pandas.DataFrame - A DataFrame where columns are field names and rows are object data. - It must include the primary key fields for the specified `ObjectType`. - - Raises - ------ - CommandNotRespectedError - If the values in PowerWorld after the call do not match the `command_df`, - indicating that the change was not fully accepted by PowerWorld. - PowerWorldError - If the underlying SimAuto call fails. - """ - cleaned_df = self._change_parameters_multiple_element_df( - ObjectType=ObjectType, command_df=command_df - ) - df = self.GetParametersMultipleElement(ObjectType=ObjectType, ParamList=cleaned_df.columns.tolist()) - - # Get key field names from GetFieldList - field_list = self.GetFieldList(ObjectType=ObjectType, copy=False) - key_field_mask = field_list["key_field"].str.match(r"\*[0-9]+[A-Z]*\*").to_numpy() - key_field_names = field_list.loc[key_field_mask, "internal_field_name"].tolist() - - # Verify changes by merging on key fields and comparing values - merged = pd.merge( - left=cleaned_df, - right=df, - how="inner", - on=key_field_names, - suffixes=("_in", "_out"), - copy=False, - ) - - cols_in = merged.columns[merged.columns.str.endswith("_in")] - cols_out = merged.columns[merged.columns.str.endswith("_out")] - - # Simple string comparison (PowerWorld returns strings anyway) - eq = np.array_equal( - merged[cols_in].astype(str).to_numpy(), - merged[cols_out].astype(str).to_numpy() - ) - - if not eq: - m = ( - "After calling ChangeParametersMultipleElement, not all parameters were actually changed " - "within PowerWorld. Try again with a different parameter (e.g. use GenVoltSet " - "instead of GenRegPUVolt)." - ) - raise CommandNotRespectedError(m) def exit(self): """Closes the PowerWorld case, deletes temporary files, and releases the COM object. @@ -233,33 +114,14 @@ def exit(self): This method should be called when the SimAuto session is no longer needed to ensure proper cleanup and resource release. """ - os.unlink(self.ntf.name) + if os.path.exists(self.empty_aux): + os.unlink(self.empty_aux) self.CloseCase() del self._pwcom self._pwcom = None pythoncom.CoUninitialize() return None - def get_version_and_builddate(self) -> tuple: - """Retrieves the PowerWorld Simulator version string and executable build date. - - This method queries the 'PowerWorldSession' object for its version and build date. - - Returns - ------- - tuple - A tuple containing: - - str: The version string of PowerWorld Simulator (e.g., "22.0.0.0"). - - datetime.datetime: The build date of the PowerWorld Simulator executable. - - """ - return self._call_simauto( - "GetParametersSingleElement", - "PowerWorldSession", - convert_list_to_variant(["Version", "ExeBuildDate"]), - convert_list_to_variant(["", ""]), - ) - def set_simauto_property(self, property_name: str, property_value: Union[str, bool]): """Sets a property on the underlying SimAuto COM object. @@ -314,151 +176,16 @@ def _set_simauto_property(self, property_name, property_value): """Internal helper to directly set a SimAuto COM property.""" setattr(self._pwcom, property_name, property_value) - def ChangeParametersSingleElement(self, ObjectType: str, ParamList: list, Values: list) -> None: - """Modifies parameters for a single object in PowerWorld. - - This method is used to update specific fields for a single PowerWorld object, - identified by its primary key values (which must be included in `Values`). - - Parameters - ---------- - ObjectType : str - The PowerWorld object type (e.g., 'Bus', 'Gen'). - ParamList : List[str] - A list of internal field names to modify. This list must include the - primary key fields for the `ObjectType` to identify the target object. - Values : List[Any] - A list of values corresponding to the parameters in `ParamList`. The order - and length must match `ParamList`. - - Returns - ------- - None - - Raises - ------ - PowerWorldError - If the SimAuto call fails (e.g., invalid object type, field name, or value). - """ - return self._call_simauto( - "ChangeParametersSingleElement", - ObjectType, - convert_list_to_variant(ParamList), - convert_list_to_variant(Values), - ) - - def ChangeParametersMultipleElement(self, ObjectType: str, ParamList: list, ValueList: list) -> None: - """Modifies parameters for multiple objects using a nested list of values. - - This method is suitable for updating a moderate number of objects where - the data is structured as a list of lists. For very large datasets, - `ChangeParametersMultipleElementRect` is generally more efficient. - - Parameters - ---------- - ObjectType : str - The PowerWorld object type. - ParamList : List[str] - A list of internal field names to modify. This list must include the - primary key fields for the `ObjectType` to identify the target objects. - ValueList : List[List[Any]] - A list of lists, where each inner list contains values for one object. - The order of values in each inner list must match `ParamList`. - - Returns - ------- - None - - Raises - ------ - PowerWorldError - If the SimAuto call fails. - """ - return self._call_simauto( - "ChangeParametersMultipleElement", - ObjectType, - convert_list_to_variant(ParamList), - convert_nested_list_to_variant(ValueList), - ) - - def ChangeParametersMultipleElementRect(self, ObjectType: str, ParamList: list, df: pd.DataFrame) -> None: - """ - Modifies parameters for multiple objects using a pandas DataFrame (rectangular data structure). - - This is generally the most efficient way to update a large number of objects at once. - The DataFrame must include the primary key fields for the object type to identify - which objects to update. - - Parameters - ---------- - ObjectType : str - The PowerWorld object type. - ParamList : List[str] - A list of internal field names being updated. These must correspond to the - column names in the `df`. - df : pandas.DataFrame - A DataFrame containing the data to update. The column names of `df` must - match the `ParamList`, and it must contain primary key columns. - - Returns - ------- - None - - Raises - ------ - PowerWorldError - If the SimAuto call fails. - """ - return self._call_simauto( - "ChangeParametersMultipleElementRect", - ObjectType, - convert_list_to_variant(ParamList), - convert_df_to_variant(df), - ) - - def ChangeParametersMultipleElementFlatInput( - self, ObjectType: str, ParamList: list, NoOfObjects: int, ValueList: list - ) -> None: - """Modifies parameters for multiple objects using a flat, 1-D list of values. + def ProcessAuxFile(self, FileName): + """Executes a PowerWorld auxiliary (.aux) file. - This method is an alternative to `ChangeParametersMultipleElement` for cases - where the data is already flattened. + Auxiliary files contain script commands or data definitions that PowerWorld + can process to modify the case or perform actions. Parameters ---------- - ObjectType : str - The PowerWorld object type. - ParamList : List[str] - A list of internal field names to modify. - NoOfObjects : int - The number of objects being updated. - ValueList : List[Any] - A flat list of values. Its length must be `NoOfObjects * len(ParamList)`. - The values are ordered by object, then by parameter within each object. - - Returns - ------- - None - - Raises - ------ - Error - If `ValueList` is not a 1-D array (i.e., it's a list of lists). - PowerWorldError - If the SimAuto call fails. - """ - if isinstance(ValueList[0], list): - raise Error("The value list has to be a 1-D array") - return self._call_simauto( - "ChangeParametersMultipleElementFlatInput", - ObjectType, - convert_list_to_variant(ParamList), - NoOfObjects, - convert_list_to_variant(ValueList), - ) - - def CloseCase(self): - """Closes the currently open PowerWorld case without exiting the Simulator application. + FileName : str + Path to the auxiliary (.aux) file. Returns ------- @@ -467,432 +194,25 @@ def CloseCase(self): Raises ------ PowerWorldError - If the SimAuto call fails. - """ - return self._call_simauto("CloseCase") - - def GetCaseHeader(self, filename: str = None) -> Tuple[str]: - """Retrieves the header information from a PowerWorld case file. - - Parameters - ---------- - filename : str, optional - Path to the .pwb or .pwx file. If None, the header of the currently - open case is retrieved. - - Returns - ------- - tuple - A tuple of strings, where each string is a line from the case header. - - Raises - ------ - PowerWorldError - If the SimAuto call fails (e.g., file not found). - """ - if filename is None: - filename = self.pwb_file_path - return self._call_simauto("GetCaseHeader", filename) - - def GetFieldList(self, ObjectType: str, copy=False) -> pd.DataFrame: - """Retrieves the complete list of available fields for a given PowerWorld object type. - - This method queries PowerWorld for all fields associated with an object type - and caches the result for performance. - - Parameters - ---------- - ObjectType : str - The PowerWorld object type (e.g., 'Bus', 'Gen'). - copy : bool, optional - If True, returns a deep copy of the cached field list DataFrame. - Defaults to False. - - Returns - ------- - pandas.DataFrame - A DataFrame containing columns like 'key_field', 'internal_field_name', - 'field_data_type', 'description', 'display_name', and 'enterable'. - - Raises - ------ - PowerWorldError - If the SimAuto call fails (e.g., invalid object type). - """ - object_type = ObjectType.lower() - try: - output = self._object_fields[object_type] - except KeyError: - result = self._call_simauto("GetFieldList", ObjectType) - result_arr = np.array(result) - - try: - output = pd.DataFrame(result_arr, columns=self.FIELD_LIST_COLUMNS) - except ValueError as e: - exp_base = r"\([0-9]+,\s" - exp_end = r"{}\)" - nf_old = len(self.FIELD_LIST_COLUMNS_OLD) - nf_default = len(self.FIELD_LIST_COLUMNS) - nf_new = len(self.FIELD_LIST_COLUMNS_NEW) - r1 = re.search(exp_base + exp_end.format(nf_old), e.args[0]) - r2 = re.search(exp_base + exp_end.format(nf_default), e.args[0]) - r3 = re.search(exp_base + exp_end.format(nf_new), e.args[0]) - - if (r1 is None) or (r2 is None): - if r3 is None: - raise e - else: - output = pd.DataFrame(result_arr, columns=self.FIELD_LIST_COLUMNS_NEW) - else: - output = pd.DataFrame(result_arr, columns=self.FIELD_LIST_COLUMNS_OLD) - - output.sort_values(by=["internal_field_name"], inplace=True) - self._object_fields[object_type] = output - - return output.copy(deep=True) if copy else output - - def GetParametersSingleElement(self, ObjectType: str, ParamList: list, Values: list) -> pd.Series: - """Retrieves parameters for a single object identified by its primary keys. - - Parameters - ---------- - ObjectType : str - The PowerWorld object type (e.g., 'Bus', 'Gen'). - ParamList : List[str] - A list of internal field names to retrieve. This list must include the - primary key fields for the `ObjectType` to identify the target object. - Values : List[Any] - A list containing the primary key values for the object, followed by - empty strings or placeholders for other parameters in `ParamList` if they - are not part of the key. The length must match `ParamList`. - - Returns - ------- - pandas.Series - A pandas Series containing the requested data, indexed by `ParamList`. - - Raises - ------ - AssertionError - If the length of `ParamList` and `Values` do not match. - PowerWorldError - If the SimAuto call fails. - """ - assert len(ParamList) == len(Values), "The given ParamList and Values must have the same length." - - output = self._call_simauto( - "GetParametersSingleElement", - ObjectType, - convert_list_to_variant(ParamList), - convert_list_to_variant(Values), - ) - - return pd.Series(output, index=ParamList) - - def GetParametersMultipleElement( - self, ObjectType: str, ParamList: list, FilterName: str = "" - ) -> Union[pd.DataFrame, None]: - """Retrieves parameters for multiple objects of a specific type, optionally filtered. - - This method is commonly used to fetch data for all objects of a given type - or a subset defined by a PowerWorld filter. - - Parameters - ---------- - ObjectType : str - The PowerWorld object type (e.g., 'Bus', 'Gen'). - ParamList : List[str] - A list of internal field names to retrieve. - FilterName : str, optional - Optional name of a PowerWorld filter to restrict the result set. - Defaults to an empty string, meaning no filter is applied. - - Returns - ------- - Union[pandas.DataFrame, None] - A pandas DataFrame where columns correspond to `ParamList`. - Returns None if no objects are found matching the criteria. - - Raises - ------ - PowerWorldError - If the SimAuto call fails (e.g., invalid object type or field names). - """ - output = self._call_simauto( - "GetParametersMultipleElement", - ObjectType, - convert_list_to_variant(ParamList), - FilterName, - ) - if output is None: - return output - - return pd.DataFrame(np.array(output).transpose(), columns=ParamList) - - def GetParamsRectTyped( - self, ObjectType: str, ParamList: list, FilterName: str = "" - ) -> Union[pd.DataFrame, None]: - """Retrieves data in a rectangular format with PowerWorld's native variant typing preserved. - - This method is similar to `GetParametersMultipleElement` but attempts to preserve - the original data types as returned by SimAuto, which can sometimes be more efficient - or necessary for specific use cases. - - Parameters - ---------- - ObjectType : str - The PowerWorld object type. - ParamList : List[str] - A list of internal field names to retrieve. - FilterName : str, optional - Optional name of a PowerWorld filter to apply. Defaults to an empty string. - - Returns - ------- - Union[pandas.DataFrame, None] - A pandas DataFrame containing the requested data. Returns None if no objects found. - - Raises - ------ - PowerWorldError - If the SimAuto call fails. - """ - output = self._call_simauto( - "GetParamsRectTyped", - ObjectType, - convert_list_to_variant(ParamList), - FilterName, - pythoncom.VT_VARIANT, - ) - if output is None: - return output - - return pd.DataFrame(output, columns=ParamList) - - def GetParametersMultipleElementFlatOutput( - self, ObjectType: str, ParamList: list, FilterName: str = "" - ) -> Union[None, Tuple[str]]: - """Retrieves data for multiple elements in a flat, 1-D output format. - - The data is returned as a single tuple of strings, where values for each - object are concatenated. This format can be less convenient for direct - DataFrame conversion but might be useful for specific parsing needs. - - Parameters - ---------- - ObjectType : str - The PowerWorld object type. - ParamList : List[str] - A list of internal field names to retrieve. - FilterName : str, optional - Optional name of a PowerWorld filter to apply. Defaults to an empty string. - - Returns - ------- - Union[None, Tuple[str]] - A tuple of strings containing the data. Returns None if no data is found. - - Raises - ------ - PowerWorldError - If the SimAuto call fails. - """ - result = self._call_simauto( - "GetParametersMultipleElementFlatOutput", - ObjectType, - convert_list_to_variant(ParamList), - FilterName, - ) - - if len(result) == 0: - return None - else: - return result - - def GetSpecificFieldList(self, ObjectType: str, FieldList: List[str]) -> pd.DataFrame: - """Retrieves detailed metadata for a specific subset of fields for a given object type. - - This method provides more detailed information about specific fields, - including their display names and whether they are enterable. - - Parameters - ---------- - ObjectType : str - The PowerWorld object type. - FieldList : List[str] - A list of internal field names to query metadata for. - - Returns - ------- - pandas.DataFrame - A DataFrame with columns like 'variablename:location', 'field', - 'column header', 'field description', and 'enterable'. - - Raises - ------ - PowerWorldError - If the SimAuto call fails. - """ - try: - df = ( - pd.DataFrame( - self._call_simauto("GetSpecificFieldList", ObjectType, convert_list_to_variant(FieldList)), - columns=self.SPECIFIC_FIELD_LIST_COLUMNS, - ) - .sort_values(by=self.SPECIFIC_FIELD_LIST_COLUMNS[0]) - .reset_index(drop=True) - ) - except ValueError: - df = ( - pd.DataFrame( - self._call_simauto("GetSpecificFieldList", ObjectType, convert_list_to_variant(FieldList)), - columns=self.SPECIFIC_FIELD_LIST_COLUMNS_NEW, - ) - .sort_values(by=self.SPECIFIC_FIELD_LIST_COLUMNS_NEW[0]) - .reset_index(drop=True) - ) - return df - - def GetSpecificFieldMaxNum(self, ObjectType: str, Field: str) -> int: - """Retrieves the maximum index for a field that supports multiple entries (e.g., CustomFloat). - - Some PowerWorld fields, like 'CustomFloat', can have multiple instances - (e.g., 'CustomFloat:1', 'CustomFloat:2'). This method returns the highest - available index for such a field. - - Parameters - ---------- - ObjectType : str - The PowerWorld object type. - Field : str - The base field name (e.g., 'CustomFloat'). - - Returns - ------- - int - The maximum integer index available for the specified field. - - Raises - ------ - PowerWorldError - If the SimAuto call fails. - """ - return self._call_simauto("GetSpecificFieldMaxNum", ObjectType, Field) - - def ListOfDevices(self, ObjType: str, FilterName="") -> Union[None, pd.DataFrame]: - """Retrieves a list of all objects of a specific type and their primary keys. - - This method is useful for getting an inventory of all objects of a certain type - in the case, or a filtered subset. - - Parameters - ---------- - ObjType : str - The PowerWorld object type (e.g., 'Bus', 'Gen'). - FilterName : str, optional - Optional name of a PowerWorld filter to apply. Defaults to an empty string. - - Returns - ------- - Union[None, pandas.DataFrame] - A pandas DataFrame containing the primary key fields for the objects. - Returns None if no objects are found. - - Raises - ------ - PowerWorldError - If the SimAuto call fails. - """ - # Get key field metadata to know column names - field_list = self.GetFieldList(ObjectType=ObjType, copy=False) - key_field_mask = field_list["key_field"].str.match(r"\*[0-9]+[A-Z]*\*").to_numpy() - key_field_df = field_list.loc[key_field_mask].copy() - key_field_df["key_field"] = key_field_df["key_field"].str.replace(r"\*", "", regex=True) - key_field_df["key_field"] = key_field_df["key_field"].str.replace("[A-Z]*", "", regex=True) - key_field_series = key_field_df["key_field"] - if self.decimal_delimiter != ".": - try: - key_field_series = key_field_series.str.replace(self.decimal_delimiter, ".") - except AttributeError: - pass - key_field_df["key_field_index"] = pd.to_numeric(key_field_series, errors='coerce').fillna(key_field_df["key_field"]) - 1 - key_field_df.sort_values(by="key_field_index", inplace=True) - column_names = key_field_df["internal_field_name"].to_numpy() - - output = self._call_simauto("ListOfDevices", ObjType, FilterName) - - all_none = all(i is None for i in output) - - if all_none: - return None - - df = pd.DataFrame(output).transpose() - df.columns = column_names - - return df - - def ListOfDevicesAsVariantStrings(self, ObjType: str, FilterName="") -> tuple: - """Retrieves a list of devices where primary keys are returned as variant strings. - - This method returns the primary keys as a tuple of strings, which might be - useful for direct use in other SimAuto commands that expect string identifiers. - - Parameters - ---------- - ObjType : str - The PowerWorld object type. - FilterName : str, optional - Optional name of a PowerWorld filter to apply. Defaults to an empty string. - - Returns - ------- - tuple - A tuple of strings, where each string represents the primary key(s) of an object. - - Raises - ------ - PowerWorldError - If the SimAuto call fails. - """ - return self._call_simauto("ListOfDevicesAsVariantStrings", ObjType, FilterName) - - def ListOfDevicesFlatOutput(self, ObjType: str, FilterName="") -> tuple: - """Retrieves a list of devices in a flat, 1-D output format. - - Similar to `ListOfDevicesAsVariantStrings`, but the output format might differ - slightly depending on the SimAuto version. - - Parameters - ---------- - ObjType : str - The PowerWorld object type. - FilterName : str, optional - Optional name of a PowerWorld filter to apply. Defaults to an empty string. - - Returns - ------- - tuple - A tuple of strings. + If the SimAuto call fails (e.g., file not found, syntax error in aux file). - Raises - ------ - PowerWorldError - If the SimAuto call fails. """ - return self._call_simauto("ListOfDevicesFlatOutput", ObjType, FilterName) + return self._com_call("ProcessAuxFile", FileName) - def LoadState(self) -> None: - """Loads the last saved state of the PowerWorld case.""" - return self._call_simauto("LoadState") + def _run_script(self, command: str, *args) -> None: + """Execute a PowerWorld script command with optional arguments. - def OpenCase(self, FileName: Union[str, None] = None) -> None: - """Opens a PowerWorld case file. + This is the standard way for mixin methods to invoke PowerWorld script + commands. It builds the command string and routes it through + ``RunScriptCommand``. Parameters ---------- - FileName : Union[str, None], optional - Path to the .pwb or .pwx file. If None, it attempts to reopen the - last file path stored in `self.pwb_file_path`. + command : str + The script command name (e.g., ``"SolvePowerFlow"``, ``"GICCalculate"``). + *args + Arguments to pass to the command. ``None`` values are converted to + empty strings. Trailing ``None`` values are stripped. Returns ------- @@ -900,67 +220,22 @@ def OpenCase(self, FileName: Union[str, None] = None) -> None: Raises ------ - TypeError - If `FileName` is None and no previous `pwb_file_path` is set. PowerWorldError - If the SimAuto call fails (e.g., file not found). + If the script command fails. """ - if FileName is None: - if self.pwb_file_path is None: - raise TypeError("When OpenCase is called for the first time, a FileName is required.") - else: - self.pwb_file_path = FileName - return self._call_simauto("OpenCase", self.pwb_file_path) + # Strip trailing Nones + arg_list = list(args) + while arg_list and arg_list[-1] is None: + arg_list.pop() - def OpenCaseType(self, FileName: str, FileType: str, Options: Union[list, str, None] = None) -> None: - """Opens a case file of a specific type (e.g., PTI, GE) with options. - - Parameters - ---------- - FileName : str - Path to the file. - Different sets of optional parameters apply for the PTI and GE file formats. - The LoadTransactions and Star bus parameters are available for writing to RAW files. - MSLine, VarLimDead, and PostCTGAGC are for writing EPC files. - See `OpenCase` in the Auxiliary File Format PDF for more details on options. - FileType : str - The file format (e.g., 'PTI', 'GE', 'EPC'). - Valid options include: PWB, PTI (latest version), PTI23-PTI35, GE (latest version), - GE14-GE23, CF, AUX, UCTE, AREVAHDB, OPENNETEMS. - Options : Union[list, str, None], optional - A list or string of format-specific options. Defaults to None. - """ - self.pwb_file_path = FileName - if isinstance(Options, list): - options = convert_list_to_variant(Options) - elif isinstance(Options, str): - options = Options + if arg_list: + arg_str = ", ".join("" if a is None else str(a) for a in arg_list) + stmt = f"{command}({arg_str});" else: - options = "" - return self._call_simauto("OpenCaseType", self.pwb_file_path, FileType, options) + stmt = f"{command};" - def ProcessAuxFile(self, FileName): - """Executes a PowerWorld auxiliary (.aux) file. - - Auxiliary files contain script commands or data definitions that PowerWorld - can process to modify the case or perform actions. - - Parameters - ---------- - FileName : str - Path to the auxiliary (.aux) file. - - Returns - ------- - None - - Raises - ------ - PowerWorldError - If the SimAuto call fails (e.g., file not found, syntax error in aux file). - - """ - return self._call_simauto("ProcessAuxFile", FileName) + self.log.debug("RunScript: %s", stmt) + return self.RunScriptCommand(stmt) def RunScriptCommand(self, Statements): """Executes one or more PowerWorld script statements. @@ -970,17 +245,17 @@ def RunScriptCommand(self, Statements): Statements : str A string containing one or more PowerWorld script commands, separated by semicolons. See the "SCRIPT Section" in the Auxiliary File Format PDF for command syntax. - + Returns ------- None - + Raises ------ PowerWorldError If any of the script commands fail. """ - return self._call_simauto("RunScriptCommand", Statements) + return self._com_call("RunScriptCommand", Statements) def RunScriptCommand2(self, Statements: str, StatusMessage: str): """Executes script statements and provides a status message for the PowerWorld UI. @@ -1007,74 +282,7 @@ def RunScriptCommand2(self, Statements: str, StatusMessage: str): PowerWorldError If any of the script commands fail. """ - return self._pwcom.RunScriptCommand2(Statements, StatusMessage) - - def SaveCase(self, FileName=None, FileType="PWB", Overwrite=True): - """Saves the currently open PowerWorld case to a file. - - Parameters - ---------- - FileName : str, optional - Path to save the file. If None, the case is saved to its current path, - potentially overwriting the original file. - FileType : str, optional - The file format to save as (e.g., "PWB", "PTI", "GE"). Defaults to "PWB". - Overwrite : bool, optional - If True, overwrites an existing file at `FileName` without prompting. - Defaults to True. - - Returns - ------- - None - - Raises - ------ - TypeError - If `FileName` is None and no case has been opened previously. - PowerWorldError - If the SimAuto call fails (e.g., invalid path, permission issues). - """ - if FileName is not None: - f = convert_to_windows_path(FileName) - elif self.pwb_file_path is None: - raise TypeError("SaveCase was called without a FileName, but OpenCase has not yet been called.") - else: - f = convert_to_windows_path(self.pwb_file_path) - - return self._call_simauto("SaveCase", f, FileType, Overwrite) - - def SaveState(self) -> None: - """Saves the current state of the PowerWorld case. - - This creates an unnamed snapshot of the case that can be restored later - using `LoadState`. - """ - return self._call_simauto("SaveState") - - def SendToExcel(self, ObjectType: str, FilterName: str, FieldList) -> None: - """Exports data for the specified objects directly to Microsoft Excel. - - This method requires Microsoft Excel to be installed on the system. - - Parameters - ---------- - ObjectType : str - The PowerWorld object type (e.g., 'Bus', 'Gen'). - FilterName : str - Optional PowerWorld filter name to apply. - FieldList : List[str] - A list of internal field names to export. - - Returns - ------- - None - - Raises - ------ - PowerWorldError - If the SimAuto call fails (e.g., Excel not installed, invalid parameters). - """ - return self._call_simauto("SendToExcel", ObjectType, FilterName, FieldList) + return self._com_call("RunScriptCommand2", Statements, StatusMessage) @property @@ -1120,7 +328,7 @@ def ProgramInformation(self) -> Union[tuple, bool]: ) return False - def _call_simauto(self, func: str, *args): + def _com_call(self, func: str, *args): """Internal helper to execute SimAuto COM methods and handle error codes. This method wraps all direct COM calls to PowerWorld Simulator, providing @@ -1149,6 +357,7 @@ def _call_simauto(self, func: str, *args): PowerWorldError If SimAuto returns an error message (e.g., invalid parameters, operation failed). """ + self.log.debug("COM call: %s(%s)", func, ", ".join(repr(a) for a in args)) try: f = getattr(self._pwcom, func) except AttributeError: @@ -1172,6 +381,8 @@ def _call_simauto(self, func: str, *args): try: if output is None or output[0] == "": pass + elif not isinstance(output[0], str): + pass elif "No data" not in output[0]: raise PowerWorldError.from_message(output[0]) except TypeError as e: @@ -1189,72 +400,7 @@ def _call_simauto(self, func: str, *args): return output[1] if len(output) == 2 else output[1:] - def _change_parameters_multiple_element_df(self, ObjectType: str, command_df: pd.DataFrame) -> pd.DataFrame: - """Internal helper to prepare and execute `ChangeParametersMultipleElement` using a DataFrame. - - This method cleans the input DataFrame and then calls the SimAuto method - to apply the changes. - - Parameters - ---------- - ObjectType : str - The PowerWorld object type. - command_df : pandas.DataFrame - The DataFrame containing the data to update. - - Returns - ------- - pandas.DataFrame - The cleaned DataFrame that was sent to PowerWorld. - """ - cleaned_df = command_df.copy() - - self.ChangeParametersMultipleElement( - ObjectType=ObjectType, - ParamList=cleaned_df.columns.tolist(), - ValueList=cleaned_df.to_numpy().tolist(), - ) - return cleaned_df - - def _to_numeric( - self, data: Union[pd.DataFrame, pd.Series], errors="ignore" - ) -> Union[pd.DataFrame, pd.Series]: - """Internal helper to convert DataFrame or Series columns to numeric types. - - Handles locale-specific decimal delimiters before conversion. - - Parameters - ---------- - data : Union[pandas.DataFrame, pandas.Series] - The data to convert. - errors : str, optional - How to handle errors during conversion ('ignore', 'raise', 'coerce'). - Defaults to 'ignore'. - - Returns - ------- - Union[pandas.DataFrame, pandas.Series] - The data with numeric columns converted. - """ - if isinstance(data, pd.DataFrame): - df_flag = True - elif isinstance(data, pd.Series): - df_flag = False - else: - raise TypeError("data must be either a DataFrame or Series.") - - if self.decimal_delimiter != ".": - if df_flag: - data = data.apply(self._replace_decimal_delimiter) - else: - data = self._replace_decimal_delimiter(data) - - if df_flag: - return data.apply(lambda x: pd.to_numeric(x, errors='coerce')).fillna(data) - else: - return pd.to_numeric(data, errors='coerce').fillna(data) - - def _replace_decimal_delimiter(self, data: pd.Series): + def _replace_decimal_delimiter(self, data): """Internal helper to replace locale-specific decimal delimiters with '.' in a Series. Parameters @@ -1288,15 +434,27 @@ def exec_aux(self, aux: str, use_double_quotes: bool = False): """ if use_double_quotes: aux = aux.replace("'", '"') - file = tempfile.NamedTemporaryFile(mode="wt", suffix=".aux", delete=False) - file.write(aux) - file.close() - self.ProcessAuxFile(file.name) - os.unlink(file.name) + fpath = get_temp_filepath(".aux") + try: + with open(fpath, "w") as f: + f.write(aux) + self.ProcessAuxFile(fpath) + finally: + os.unlink(fpath) def update_ui(self) -> None: """Triggers a refresh of the PowerWorld Simulator user interface. This can be useful after making programmatic changes that might not immediately reflect in the GUI. """ - return self.ProcessAuxFile(self.empty_aux) \ No newline at end of file + return self.ProcessAuxFile(self.empty_aux) + + def set_logging_level(self, level: Union[int, str]) -> None: + """Sets the logging level for the SAW instance logger. + + Parameters + ---------- + level : int or str + The logging level (e.g., logging.DEBUG, "DEBUG"). + """ + self.log.setLevel(level) diff --git a/esapp/saw/case_actions.py b/esapp/saw/case_actions.py index 1a380b2b..930e5181 100644 --- a/esapp/saw/case_actions.py +++ b/esapp/saw/case_actions.py @@ -1,47 +1,117 @@ """Case Actions specific functions.""" -from typing import List +import os +from typing import List, Union + +from ._enums import YesNo +from ._exceptions import PowerWorldError +from ._helpers import convert_list_to_variant, convert_to_windows_path, format_list class CaseActionsMixin: """Mixin for Case Actions functions.""" - def AppendCase( - self, - filename: str, - filetype: str, - star_bus: str = "NEAR", - estimate_voltages: bool = True, - ms_line: str = "MAINTAIN", - var_lim_dead: float = 2.0, - post_ctg_agc: bool = False, - ): - """Merges another case file into the currently open PowerWorld case. + def get_version_and_builddate(self) -> tuple: + """Retrieves the PowerWorld Simulator version string and executable build date. + + This method queries the 'PowerWorldSession' object for its version and build date. + + Returns + ------- + tuple + A tuple containing: + - str: The version string of PowerWorld Simulator (e.g., "22.0.0.0"). + - datetime.datetime: The build date of the PowerWorld Simulator executable. - This action is used to combine the network and data from an external - case file with the currently loaded case. + """ + return self._com_call( + "GetParametersSingleElement", + "PowerWorldSession", + convert_list_to_variant(["Version", "ExeBuildDate"]), + convert_list_to_variant(["", ""]), + ) + + def OpenCase(self, FileName: Union[str, None] = None) -> None: + """Opens a PowerWorld case file. Parameters ---------- - filename : str - The file name of the case to be appended. - filetype : str - The format of the file to append (e.g., "PWB", "GE", "PTI", "CF", "AUX", - "UCTE", "AREVAHDB", "OPENNETEMS"). - star_bus : str, optional - For PTI RAW format, specifies how to handle star buses ("NEAR", "MAX", or a numeric value). - Defaults to "NEAR". - estimate_voltages : bool, optional - For GE EPC or PTI RAW format, if True, estimates voltages and angles for new buses - introduced by the append. Angle smoothing is done across new lines. - Defaults to True. - ms_line : str, optional - For GE EPC format, specifies how to handle multisection lines ("MAINTAIN" or "EQUIVALENCE"). - Defaults to "MAINTAIN". - var_lim_dead : float, optional - For GE EPC format, sets the var limit deadband. Defaults to 2.0. - post_ctg_agc : bool, optional - For GE EPC format, if True, populates the generator field 'Post-CTG Prevent Response' - based on the EPC file's generator base load flag. Defaults to False. + FileName : Union[str, None], optional + Path to the .pwb or .pwx file. If None, it attempts to reopen the + last file path stored in `self.pwb_file_path`. + + Returns + ------- + None + + Raises + ------ + TypeError + If `FileName` is None and no previous `pwb_file_path` is set. + PowerWorldError + If the SimAuto call fails (e.g., file not found). + """ + if FileName is None: + if self.pwb_file_path is None: + raise TypeError("When OpenCase is called for the first time, a FileName is required.") + else: + self.pwb_file_path = FileName + try: + return self._com_call("OpenCase", self.pwb_file_path) + except PowerWorldError as e: + hints = [f"Failed to open case: '{self.pwb_file_path}'"] + if not os.path.exists(self.pwb_file_path): + hints.append(f"File does not exist at the specified path.") + else: + hints.append("The file exists but PowerWorld could not open it.") + hints.append("Possible causes:") + hints.append(" - PowerWorld Simulator is not licensed or the license has expired") + hints.append(" - The file is corrupted or in an unsupported format") + hints.append(" - The file is locked by another process") + hints.append(f"Original error: {e.raw_message}") + raise PowerWorldError("\n".join(hints)) from e + + def OpenCaseType(self, FileName: str, FileType: str, Options: Union[list, str, None] = None) -> None: + """Opens a case file of a specific type (e.g., PTI, GE) with options. + + Parameters + ---------- + FileName : str + Path to the file. + Different sets of optional parameters apply for the PTI and GE file formats. + The LoadTransactions and Star bus parameters are available for writing to RAW files. + MSLine, VarLimDead, and PostCTGAGC are for writing EPC files. + See `OpenCase` in the Auxiliary File Format PDF for more details on options. + FileType : str + The file format (e.g., 'PTI', 'GE', 'EPC'). + Valid options include: PWB, PTI (latest version), PTI23-PTI35, GE (latest version), + GE14-GE23, CF, AUX, UCTE, AREVAHDB, OPENNETEMS. + Options : Union[list, str, None], optional + A list or string of format-specific options. Defaults to None. + """ + self.pwb_file_path = FileName + if isinstance(Options, list): + options = convert_list_to_variant(Options) + elif isinstance(Options, str): + options = Options + else: + options = "" + try: + return self._com_call("OpenCaseType", self.pwb_file_path, FileType, options) + except PowerWorldError as e: + hints = [f"Failed to open case: '{self.pwb_file_path}' (format: {FileType})"] + if not os.path.exists(self.pwb_file_path): + hints.append(f"File does not exist at the specified path.") + else: + hints.append("The file exists but PowerWorld could not open it.") + hints.append("Possible causes:") + hints.append(" - PowerWorld Simulator is not licensed or the license has expired") + hints.append(f" - The file format '{FileType}' does not match the actual file contents") + hints.append(" - The file is corrupted or locked by another process") + hints.append(f"Original error: {e.raw_message}") + raise PowerWorldError("\n".join(hints)) from e + + def CloseCase(self): + """Closes the currently open PowerWorld case without exiting the Simulator application. Returns ------- @@ -50,19 +120,43 @@ def AppendCase( Raises ------ PowerWorldError - If the SimAuto call fails (e.g., file not found, invalid parameters). + If the SimAuto call fails. """ - est = "YES" if estimate_voltages else "NO" - pc_agc = "YES" if post_ctg_agc else "NO" + return self._com_call("CloseCase") + + def SaveCase(self, FileName=None, FileType="PWB", Overwrite=True): + """Saves the currently open PowerWorld case to a file. + + Parameters + ---------- + FileName : str, optional + Path to save the file. If None, the case is saved to its current path, + potentially overwriting the original file. + FileType : str, optional + The file format to save as (e.g., "PWB", "PTI", "GE"). Defaults to "PWB". + Overwrite : bool, optional + If True, overwrites an existing file at `FileName` without prompting. + Defaults to True. + + Returns + ------- + None - if "PTI" in filetype.upper(): - args = f'"{filename}", {filetype}, [{star_bus}, {est}]' - elif "GE" in filetype.upper(): - args = f'"{filename}", {filetype}, [{ms_line}, {var_lim_dead}, {pc_agc}, {est}]' + Raises + ------ + TypeError + If `FileName` is None and no case has been opened previously. + PowerWorldError + If the SimAuto call fails (e.g., invalid path, permission issues). + """ + if FileName is not None: + f = convert_to_windows_path(FileName) + elif self.pwb_file_path is None: + raise TypeError("SaveCase was called without a FileName, but OpenCase has not yet been called.") else: - args = f'"{filename}", {filetype}' + f = convert_to_windows_path(self.pwb_file_path) - return self.RunScriptCommand(f"AppendCase({args});") + return self._com_call("SaveCase", f, FileType, Overwrite) def CaseDescriptionClear(self): """Clears the case description. @@ -78,7 +172,7 @@ def CaseDescriptionClear(self): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand("CaseDescriptionClear;") + return self._run_script("CaseDescriptionClear") def CaseDescriptionSet(self, text: str, append: bool = False): """Sets or appends text to the case description. @@ -100,8 +194,8 @@ def CaseDescriptionSet(self, text: str, append: bool = False): PowerWorldError If the SimAuto call fails. """ - app = "YES" if append else "NO" - return self.RunScriptCommand(f'CaseDescriptionSet("{text}", {app});') + app = YesNo.from_bool(append) + return self._run_script("CaseDescriptionSet", f'"{text}"', app) def DeleteExternalSystem(self): """Deletes the part of the power system where the 'Equiv' field on buses is set to true. @@ -117,7 +211,7 @@ def DeleteExternalSystem(self): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand("DeleteExternalSystem;") + return self._run_script("DeleteExternalSystem") def Equivalence(self): """Equivalences the power system based on Equiv_Options. @@ -134,7 +228,7 @@ def Equivalence(self): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand("Equivalence;") + return self._run_script("Equivalence") def LoadEMS(self, filename: str, filetype: str = "AREVAHDB"): """Opens an EMS (Energy Management System) file. @@ -155,7 +249,7 @@ def LoadEMS(self, filename: str, filetype: str = "AREVAHDB"): PowerWorldError If the SimAuto call fails (e.g., file not found, invalid format). """ - return self.RunScriptCommand(f'LoadEMS("{filename}", {filetype});') + return self._run_script("LoadEMS", f'"{filename}"', filetype) def NewCase(self): """Clears the existing case and opens a new, empty one. @@ -169,7 +263,7 @@ def NewCase(self): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand("NewCase;") + return self._run_script("NewCase") def Renumber3WXFormerStarBuses(self, filename: str, delimiter: str = "BOTH"): """Renumbers 3-winding transformer star buses based on user-specified values in a file. @@ -192,7 +286,7 @@ def Renumber3WXFormerStarBuses(self, filename: str, delimiter: str = "BOTH"): PowerWorldError If the SimAuto call fails (e.g., file not found, format error). """ - return self.RunScriptCommand(f'Renumber3WXFormerStarBuses("{filename}", {delimiter});') + return self._run_script("Renumber3WXFormerStarBuses", f'"{filename}"', delimiter) def RenumberAreas(self, custom_integer_index: int = 0): """Renumbers Areas using the value in the specified Custom Integer field. @@ -212,7 +306,7 @@ def RenumberAreas(self, custom_integer_index: int = 0): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f"RenumberAreas({custom_integer_index});") + return self._run_script("RenumberAreas", custom_integer_index) def RenumberBuses(self, custom_integer_index: int = 1): """Renumbers Buses using the value in the specified Custom Integer field. @@ -232,7 +326,7 @@ def RenumberBuses(self, custom_integer_index: int = 1): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f"RenumberBuses({custom_integer_index});") + return self._run_script("RenumberBuses", custom_integer_index) def RenumberMSLineDummyBuses(self, filename: str, delimiter: str = "BOTH"): """Renumbers dummy buses of multisection lines based on a provided file. @@ -253,7 +347,7 @@ def RenumberMSLineDummyBuses(self, filename: str, delimiter: str = "BOTH"): PowerWorldError If the SimAuto call fails (e.g., file not found, format error). """ - return self.RunScriptCommand(f'RenumberMSLineDummyBuses("{filename}", {delimiter});') + return self._run_script("RenumberMSLineDummyBuses", f'"{filename}"', delimiter) def RenumberSubs(self, custom_integer_index: int = 2): """Renumbers Substations using the value in the specified Custom Integer field. @@ -273,7 +367,7 @@ def RenumberSubs(self, custom_integer_index: int = 2): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f"RenumberSubs({custom_integer_index});") + return self._run_script("RenumberSubs", custom_integer_index) def RenumberZones(self, custom_integer_index: int = 3): """Renumbers Zones using the value in the specified Custom Integer field. @@ -293,7 +387,7 @@ def RenumberZones(self, custom_integer_index: int = 3): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f"RenumberZones({custom_integer_index});") + return self._run_script("RenumberZones", custom_integer_index) def RenumberCase(self): """Renumbers objects in the case according to the swap list in memory. @@ -309,7 +403,7 @@ def RenumberCase(self): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand("RenumberCase;") + return self._run_script("RenumberCase") def SaveExternalSystem(self, filename: str, filetype: str = "PWB", with_ties: bool = False): """Saves only buses where 'Equiv' is set to 'External' to a new case file. @@ -335,8 +429,8 @@ def SaveExternalSystem(self, filename: str, filetype: str = "PWB", with_ties: bo PowerWorldError If the SimAuto call fails. """ - wt = "YES" if with_ties else "NO" - return self.RunScriptCommand(f'SaveExternalSystem("{filename}", {filetype}, {wt});') + wt = YesNo.from_bool(with_ties) + return self._run_script("SaveExternalSystem", f'"{filename}"', filetype, wt) def SaveMergedFixedNumBusCase(self, filename: str, filetype: str = "PWB"): """Saves the Merged FixedNumBus case. @@ -359,7 +453,7 @@ def SaveMergedFixedNumBusCase(self, filename: str, filetype: str = "PWB"): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f'SaveMergedFixedNumBusCase("{filename}", {filetype});') + return self._run_script("SaveMergedFixedNumBusCase", f'"{filename}"', filetype) def Scale( self, @@ -397,5 +491,5 @@ def Scale( PowerWorldError If the SimAuto call fails. """ - params = "[" + ", ".join([str(p) for p in parameters]) + "]" - return self.RunScriptCommand(f"Scale({scale_type}, {based_on}, {params}, {scale_marker});") \ No newline at end of file + params = format_list(parameters, stringify=True) + return self._run_script("Scale", scale_type, based_on, params, scale_marker) diff --git a/esapp/saw/contingency.py b/esapp/saw/contingency.py index bc730905..78d33a54 100644 --- a/esapp/saw/contingency.py +++ b/esapp/saw/contingency.py @@ -1,15 +1,17 @@ """Contingency analysis specific functions.""" -from typing import List +from typing import List, Union + +from ._enums import YesNo, LinearMethod +from ._helpers import format_list class ContingencyMixin: """Mixin for contingency analysis functions.""" - def RunContingency(self, ctg_name: str): + def CTGSolve(self, ctg_name: str): """Runs a single defined contingency. - This method is a wrapper for the `CTGSolve` script command, which - executes the actions defined in a specific contingency and solves + Executes the actions defined in a specific contingency and solves the power flow. Parameters @@ -26,15 +28,23 @@ def RunContingency(self, ctg_name: str): PowerWorldError If the SimAuto call fails (e.g., contingency not found, power flow divergence). """ - return self.RunScriptCommand(f'CTGSolve("{ctg_name}");') + return self._run_script("CTGSolve", f'"{ctg_name}"') - def SolveContingencies(self): - """Solves all defined contingencies in the PowerWorld case. + def CTGSolveAll(self, distributed: bool = False, clear_results: bool = True): + """Solves all contingencies that are not marked to be skipped. - This method is a wrapper for the `CTGSolveAll` script command, which - iterates through all active contingencies, applies their actions, and + Iterates through all active contingencies, applies their actions, and solves the power flow for each. + Parameters + ---------- + distributed : bool, optional + If True, uses distributed computing for contingency analysis. + Defaults to False. + clear_results : bool, optional + If True, clears all existing contingency results before solving. + Defaults to True. + Returns ------- None @@ -44,11 +54,15 @@ def SolveContingencies(self): PowerWorldError If the SimAuto call fails or any contingency solution diverges. """ - return self.RunScriptCommand("CTGSolveAll(NO, YES);") + dist = YesNo.from_bool(distributed) + clear = YesNo.from_bool(clear_results) + return self._run_script("CTGSolveAll", dist, clear) def CTGAutoInsert(self): - """Auto-inserts contingencies based on the `Ctg_AutoInsert_Options` configured in PowerWorld. + """Auto-inserts contingencies based on the Ctg_AutoInsert_Options configured in PowerWorld. + Prior to calling this action, all options for this action must be specified + in the Ctg_AutoInsert_Options object using the SetData method or DATA sections. This typically generates N-1 contingencies for lines, transformers, and generators. Returns @@ -60,7 +74,7 @@ def CTGAutoInsert(self): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand("CTGAutoInsert;") + return self._run_script("CTGAutoInsert") def CTGWriteResultsAndOptions( self, @@ -109,18 +123,15 @@ def CTGWriteResultsAndOptions( PowerWorldError If the SimAuto call fails. """ - opts_str = "" - if options: - opts_str = "[" + ", ".join(options) + "]" + opts_str = format_list(options) if options else "" - uds = "YES" if use_data_section else "NO" - uc = "YES" if use_concise else "NO" - usdm = "YES" if use_selected_data_maintainer else "NO" - sd = "YES" if save_dependencies else "NO" - uazf = "YES" if use_area_zone_filters else "NO" + uds = YesNo.from_bool(use_data_section) + uc = YesNo.from_bool(use_concise) + usdm = YesNo.from_bool(use_selected_data_maintainer) + sd = YesNo.from_bool(save_dependencies) + uazf = YesNo.from_bool(use_area_zone_filters) - cmd = f'CTGWriteResultsAndOptions("{filename}", {opts_str}, {key_field}, {uds}, {uc}, {use_object_ids}, {usdm}, {sd}, {uazf});' - return self.RunScriptCommand(cmd) + return self._run_script("CTGWriteResultsAndOptions", f'"{filename}"', opts_str, key_field, uds, uc, use_object_ids, usdm, sd, uazf) def CTGApply(self, contingency_name: str): """Applies the actions defined in a contingency without solving the power flow. @@ -142,12 +153,15 @@ def CTGApply(self, contingency_name: str): PowerWorldError If the SimAuto call fails (e.g., contingency not found). """ - return self.RunScriptCommand(f'CTGApply("{contingency_name}");') + return self._run_script("CTGApply", f'"{contingency_name}"') - def CTGCalculateOTDF(self, seller: str, buyer: str, linear_method: str = "DC"): - """Computes OTDFs using the specified linear method. + def CTGCalculateOTDF(self, seller: str, buyer: str, linear_method: Union[LinearMethod, str] = LinearMethod.DC): + """Computes OTDFs (Outage Transfer Distribution Factors) for contingency violations. - OTDFs quantify the impact of an outage on power transfers between a seller and buyer. + This action first performs the same action as CalculatePTDF for the specified + seller and buyer. It then goes through all the violations found by the + contingency analysis tool and determines the OTDF values for the various + contingency/violation pairs. Parameters ---------- @@ -155,8 +169,8 @@ def CTGCalculateOTDF(self, seller: str, buyer: str, linear_method: str = "DC"): The seller (source) object string (e.g., '[AREA "Top"]', '[BUS 7]'). buyer : str The buyer (sink) object string (e.g., '[AREA "Bottom"]', '[BUS 8]'). - linear_method : str, optional - The linear method to use for calculation ("AC", "DC", "DCPS"). Defaults to "DC". + linear_method : Union[LinearMethod, str], optional + The linear method to use for calculation. Defaults to LinearMethod.DC. Returns ------- @@ -167,7 +181,8 @@ def CTGCalculateOTDF(self, seller: str, buyer: str, linear_method: str = "DC"): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f'CTGCalculateOTDF({seller}, {buyer}, {linear_method});') + method = linear_method.value if isinstance(linear_method, LinearMethod) else str(linear_method) + return self._run_script("CTGCalculateOTDF", seller, buyer, method) def CTGClearAllResults(self): """Deletes all contingency violations and any contingency comparison results from memory. @@ -181,7 +196,7 @@ def CTGClearAllResults(self): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand("CTGClearAllResults;") + return self._run_script("CTGClearAllResults") def CTGSetAsReference(self): """Sets the present system state as the reference for contingency analysis. @@ -192,7 +207,7 @@ def CTGSetAsReference(self): ------- None """ - return self.RunScriptCommand("CTGSetAsReference;") + return self._run_script("CTGSetAsReference") def CTGProduceReport(self, filename: str): """Produces a text-based contingency analysis report. @@ -211,7 +226,7 @@ def CTGProduceReport(self, filename: str): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f'CTGProduceReport("{filename}");') + return self._run_script("CTGProduceReport", f'"{filename}"') def CTGWriteFilePTI(self, filename: str, bus_format: str = "Name12", truncate_labels: bool = True, filter_name: str = "", append: bool = False): """Writes contingencies to a file in the PTI CON format. @@ -238,9 +253,9 @@ def CTGWriteFilePTI(self, filename: str, bus_format: str = "Name12", truncate_la PowerWorldError If the SimAuto call fails. """ - trunc = "YES" if truncate_labels else "NO" - app = "YES" if append else "NO" - return self.RunScriptCommand(f'CTGWriteFilePTI("{filename}", {bus_format}, {trunc}, "{filter_name}", {app});') + trunc = YesNo.from_bool(truncate_labels) + app = YesNo.from_bool(append) + return self._run_script("CTGWriteFilePTI", f'"{filename}"', bus_format, trunc, f'"{filter_name}"', app) def CTGCloneMany(self, filter_name: str = "", prefix: str = "", suffix: str = "", set_selected: bool = False): """Creates copies of multiple contingencies based on a filter. @@ -265,8 +280,8 @@ def CTGCloneMany(self, filter_name: str = "", prefix: str = "", suffix: str = "" PowerWorldError If the SimAuto call fails. """ - sel = "YES" if set_selected else "NO" - return self.RunScriptCommand(f'CTGCloneMany("{filter_name}", "{prefix}", "{suffix}", {sel});') + sel = YesNo.from_bool(set_selected) + return self._run_script("CTGCloneMany", f'"{filter_name}"', f'"{prefix}"', f'"{suffix}"', sel) def CTGCloneOne( self, ctg_name: str, new_ctg_name: str = "", prefix: str = "", suffix: str = "", set_selected: bool = False @@ -296,8 +311,8 @@ def CTGCloneOne( PowerWorldError If the SimAuto call fails. """ - sel = "YES" if set_selected else "NO" - return self.RunScriptCommand(f'CTGCloneOne("{ctg_name}", "{new_ctg_name}", "{prefix}", "{suffix}", {sel});') + sel = YesNo.from_bool(set_selected) + return self._run_script("CTGCloneOne", f'"{ctg_name}"', f'"{new_ctg_name}"', f'"{prefix}"', f'"{suffix}"', sel) def CTGComboDeleteAllResults(self): """Deletes all results associated with contingency combination analysis. @@ -311,7 +326,7 @@ def CTGComboDeleteAllResults(self): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand("CTGComboDeleteAllResults;") + return self._run_script("CTGComboDeleteAllResults") def CTGComboSolveAll(self, do_distributed: bool = False, clear_all_results: bool = True): """Runs contingency combination analysis for all primary and regular/secondary contingencies. @@ -334,9 +349,9 @@ def CTGComboSolveAll(self, do_distributed: bool = False, clear_all_results: bool PowerWorldError If the SimAuto call fails (e.g., no primary contingencies defined). """ - dist = "YES" if do_distributed else "NO" - clear = "YES" if clear_all_results else "NO" - return self.RunScriptCommand(f"CTGComboSolveAll({dist}, {clear});") + dist = YesNo.from_bool(do_distributed) + clear = YesNo.from_bool(clear_all_results) + return self._run_script("CTGComboSolveAll", dist, clear) def CTGCompareTwoListsofContingencyResults(self, controlling: str, comparison: str): """Compares two different contingency result lists. @@ -357,7 +372,7 @@ def CTGCompareTwoListsofContingencyResults(self, controlling: str, comparison: s PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f'CTGCompareTwoListsofContingencyResults({controlling}, {comparison});') + return self._run_script("CTGCompareTwoListsofContingencyResults", f'"{controlling}"', f'"{comparison}"') def CTGConvertAllToDeviceCTG(self, keep_original_if_empty: bool = False): """Converts breaker/disconnect contingencies to device outages. @@ -377,8 +392,8 @@ def CTGConvertAllToDeviceCTG(self, keep_original_if_empty: bool = False): PowerWorldError If the SimAuto call fails. """ - keep = "YES" if keep_original_if_empty else "NO" - return self.RunScriptCommand(f"CTGConvertAllToDeviceCTG({keep});") + keep = YesNo.from_bool(keep_original_if_empty) + return self._run_script("CTGConvertAllToDeviceCTG", keep) def CTGConvertToPrimaryCTG( self, filter_name: str = "", keep_original: bool = True, prefix: str = "", suffix: str = "-Primary" @@ -408,8 +423,8 @@ def CTGConvertToPrimaryCTG( PowerWorldError If the SimAuto call fails. """ - keep = "YES" if keep_original else "NO" - return self.RunScriptCommand(f'CTGConvertToPrimaryCTG("{filter_name}", {keep}, "{prefix}", "{suffix}");') + keep = YesNo.from_bool(keep_original) + return self._run_script("CTGConvertToPrimaryCTG", f'"{filter_name}"', keep, f'"{prefix}"', f'"{suffix}"') def CTGCreateContingentInterfaces(self, filter_name: str, max_option: str = ""): """Creates an interface based on contingency violations. @@ -435,7 +450,7 @@ def CTGCreateContingentInterfaces(self, filter_name: str, max_option: str = ""): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f'CTGCreateContingentInterfaces("{filter_name}", {max_option});') + return self._run_script("CTGCreateContingentInterfaces", f'"{filter_name}"', max_option) def CTGCreateExpandedBreakerCTGs(self): """Converts 'Open/Close with Breakers' actions in contingencies into explicit OPEN/CLOSE actions on individual breakers. @@ -451,7 +466,7 @@ def CTGCreateExpandedBreakerCTGs(self): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand("CTGCreateExpandedBreakerCTGs;") + return self._run_script("CTGCreateExpandedBreakerCTGs") def CTGCreateStuckBreakerCTGs( self, @@ -500,12 +515,9 @@ def CTGCreateStuckBreakerCTGs( PowerWorldError If the SimAuto call fails. """ - dup = "YES" if allow_duplicates else "NO" - inc = "YES" if include_ctg_label else "NO" - return self.RunScriptCommand( - f'CTGCreateStuckBreakerCTGs("{filter_name}", {dup}, "{prefix_name}", {inc}, "{branch_field_name}", ' - f'"{suffix_name}", "{prefix_comment}", "{branch_field_comment}", "{suffix_comment}");' - ) + dup = YesNo.from_bool(allow_duplicates) + inc = YesNo.from_bool(include_ctg_label) + return self._run_script("CTGCreateStuckBreakerCTGs", f'"{filter_name}"', dup, f'"{prefix_name}"', inc, f'"{branch_field_name}"', f'"{suffix_name}"', f'"{prefix_comment}"', f'"{branch_field_comment}"', f'"{suffix_comment}"') def CTGDeleteWithIdenticalActions(self): """Deletes contingencies that have identical actions. @@ -521,7 +533,7 @@ def CTGDeleteWithIdenticalActions(self): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand("CTGDeleteWithIdenticalActions;") + return self._run_script("CTGDeleteWithIdenticalActions") def CTGJoinActiveCTGs( self, insert_solve_pf: bool, delete_existing: bool, join_with_self: bool, filename: str = "" @@ -550,10 +562,10 @@ def CTGJoinActiveCTGs( PowerWorldError If the SimAuto call fails. """ - ispf = "YES" if insert_solve_pf else "NO" - de = "YES" if delete_existing else "NO" - jws = "YES" if join_with_self else "NO" - return self.RunScriptCommand(f'CTGJoinActiveCTGs({ispf}, {de}, {jws}, "{filename}");') + ispf = YesNo.from_bool(insert_solve_pf) + de = YesNo.from_bool(delete_existing) + jws = YesNo.from_bool(join_with_self) + return self._run_script("CTGJoinActiveCTGs", ispf, de, jws, f'"{filename}"') def CTGPrimaryAutoInsert(self): """Auto-inserts Primary Contingencies. @@ -570,7 +582,7 @@ def CTGPrimaryAutoInsert(self): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand("CTGPrimaryAutoInsert;") + return self._run_script("CTGPrimaryAutoInsert") def CTGProcessRemedialActionsAndDependencies(self, do_delete: bool, filter_name: str = ""): """Processes Remedial Actions and their dependencies. @@ -593,8 +605,8 @@ def CTGProcessRemedialActionsAndDependencies(self, do_delete: bool, filter_name: PowerWorldError If the SimAuto call fails. """ - delete = "YES" if do_delete else "NO" - return self.RunScriptCommand(f'CTGProcessRemedialActionsAndDependencies({delete}, "{filter_name}");') + delete = YesNo.from_bool(do_delete) + return self._run_script("CTGProcessRemedialActionsAndDependencies", delete, f'"{filter_name}"') def CTGReadFilePSLF(self, filename: str): """Loads a file in the PSLF OTG format and creates contingencies from it. @@ -613,7 +625,7 @@ def CTGReadFilePSLF(self, filename: str): PowerWorldError If the SimAuto call fails (e.g., file not found, invalid format). """ - return self.RunScriptCommand(f'CTGReadFilePSLF("{filename}");') + return self._run_script("CTGReadFilePSLF", f'"{filename}"') def CTGReadFilePTI(self, filename: str): """Loads a file in the PTI CON format and creates contingencies from it. @@ -632,7 +644,7 @@ def CTGReadFilePTI(self, filename: str): PowerWorldError If the SimAuto call fails (e.g., file not found, invalid format). """ - return self.RunScriptCommand(f'CTGReadFilePTI("{filename}");') + return self._run_script("CTGReadFilePTI", f'"{filename}"') def CTGRelinkUnlinkedElements(self): """Attempts to relink unlinked elements in the contingency records. @@ -649,7 +661,7 @@ def CTGRelinkUnlinkedElements(self): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand("CTGRelinkUnlinkedElements;") + return self._run_script("CTGRelinkUnlinkedElements") def CTGSaveViolationMatrices( self, @@ -704,41 +716,33 @@ def CTGSaveViolationMatrices( """ if field_list is None: field_list = [] - perc = "YES" if use_percentage else "NO" - objs = "[" + ", ".join(object_types_to_report) + "]" - sc = "YES" if save_contingency else "NO" - so = "YES" if save_objects else "NO" - fields = "[" + ", ".join(field_list) + "]" - unsolv = "YES" if include_unsolvable_ctgs else "NO" - - return self.RunScriptCommand( - f'CTGSaveViolationMatrices("{filename}", {filetype}, {perc}, {objs}, {sc}, {so}, ' - f'{field_list_object_type}, {fields}, {unsolv});' - ) - - def CTGSkipWithIdenticalActions(self): - """Sets the 'Skip' field to YES for contingencies that have identical actions. + perc = YesNo.from_bool(use_percentage) + objs = format_list(object_types_to_report) + sc = YesNo.from_bool(save_contingency) + so = YesNo.from_bool(save_objects) + fields = format_list(field_list) + unsolv = YesNo.from_bool(include_unsolvable_ctgs) - This helps in avoiding redundant calculations during contingency analysis. - - Returns - ------- - None - - Raises - ------ - PowerWorldError - If the SimAuto call fails. - """ - return self.RunScriptCommand("CTGSkipWithIdenticalActions;") + return self._run_script("CTGSaveViolationMatrices", f'"{filename}"', filetype, perc, objs, sc, so, field_list_object_type, fields, unsolv) def CTGSort(self, sort_field_list: List[str] = None): """Sorts the contingencies stored in Simulator's internal data structure. + This is different than sorting contingencies in case information displays + in the GUI or sorting data when it is written to an auxiliary file. + Contingencies are processed in the order in which they are stored in + the internal data structure, and they are not sorted by default; + contingencies are added in the order in which they are created. + This could be significant for other actions like CTGJoinActiveCTGs + if the goal is to join contingencies alphabetically. + Parameters ---------- sort_field_list : List[str], optional - A list of fields to sort the contingencies by. Defaults to None (no specific sort). + A list of fields to sort by. If None, sorts alphabetically by + contingency name. Format: ``["fieldname1:+:0", "fieldname2:-:1"]`` + where + is ascending, - is descending, 0 is case insensitive, + 1 is case sensitive. Returns ------- @@ -751,8 +755,8 @@ def CTGSort(self, sort_field_list: List[str] = None): """ if sort_field_list is None: sort_field_list = [] - sort = "[" + ", ".join(sort_field_list) + "]" - return self.RunScriptCommand(f"CTGSort({sort});") + sort = format_list(sort_field_list) + return self._run_script("CTGSort", sort) def CTGVerifyIteratedLinearActions(self, filename: str): """Creates a text file that contains validation information for iterated linear actions. @@ -762,7 +766,7 @@ def CTGVerifyIteratedLinearActions(self, filename: str): filename : str The path to the output text file. """ - return self.RunScriptCommand(f'CTGVerifyIteratedLinearActions("{filename}");') + return self._run_script("CTGVerifyIteratedLinearActions", f'"{filename}"') def CTGWriteAllOptions( self, @@ -822,8 +826,8 @@ def CTGWriteAuxUsingOptions(self, filename: str, append: bool = True): PowerWorldError If the SimAuto call fails. """ - app = "YES" if append else "NO" - return self.RunScriptCommand(f'CTGWriteAuxUsingOptions("{filename}", {app});') + app = YesNo.from_bool(append) + return self._run_script("CTGWriteAuxUsingOptions", f'"{filename}"', app) def CTGRestoreReference(self): """Resets the system state to the reference state for contingency analysis. @@ -848,4 +852,4 @@ def CTGRestoreReference(self): CTGSetAsReference : Sets the current state as the reference. CTGApply : Applies contingency actions without solving. """ - return self.RunScriptCommand("CTGRestoreReference;") \ No newline at end of file + return self._run_script("CTGRestoreReference") diff --git a/esapp/saw/data.py b/esapp/saw/data.py new file mode 100644 index 00000000..4dab9ad5 --- /dev/null +++ b/esapp/saw/data.py @@ -0,0 +1,606 @@ +"""Data retrieval and modification functions (SimAuto data access layer).""" +import re +from typing import List, Tuple, Union + +import numpy as np +import pandas as pd +import pythoncom + +from ._enums import FieldListColumn, SpecificFieldListColumn +from ._exceptions import Error +from ._helpers import ( + convert_df_to_variant, + convert_list_to_variant, + convert_nested_list_to_variant, +) + + +class DataMixin: + """Mixin for data retrieval, modification, enumeration, and export.""" + + def ChangeParametersSingleElement(self, ObjectType: str, ParamList: list, Values: list) -> None: + """Modifies parameters for a single object in PowerWorld. + + This method is used to update specific fields for a single PowerWorld object, + identified by its primary key values (which must be included in `Values`). + + Parameters + ---------- + ObjectType : str + The PowerWorld object type (e.g., 'Bus', 'Gen'). + ParamList : List[str] + A list of internal field names to modify. This list must include the + primary key fields for the `ObjectType` to identify the target object. + Values : List[Any] + A list of values corresponding to the parameters in `ParamList`. The order + and length must match `ParamList`. + + Returns + ------- + None + + Raises + ------ + PowerWorldError + If the SimAuto call fails (e.g., invalid object type, field name, or value). + """ + return self._com_call( + "ChangeParametersSingleElement", + ObjectType, + convert_list_to_variant(ParamList), + convert_list_to_variant(Values), + ) + + def ChangeParametersMultipleElement(self, ObjectType: str, ParamList: list, ValueList: list) -> None: + """Modifies parameters for multiple objects using a nested list of values. + + This method is suitable for updating a moderate number of objects where + the data is structured as a list of lists. For very large datasets, + `ChangeParametersMultipleElementRect` is generally more efficient. + + Parameters + ---------- + ObjectType : str + The PowerWorld object type. + ParamList : List[str] + A list of internal field names to modify. This list must include the + primary key fields for the `ObjectType` to identify the target objects. + ValueList : List[List[Any]] + A list of lists, where each inner list contains values for one object. + The order of values in each inner list must match `ParamList`. + + Returns + ------- + None + + Raises + ------ + PowerWorldError + If the SimAuto call fails. + """ + return self._com_call( + "ChangeParametersMultipleElement", + ObjectType, + convert_list_to_variant(ParamList), + convert_nested_list_to_variant(ValueList), + ) + + def ChangeParametersMultipleElementRect(self, ObjectType: str, ParamList: list, df: pd.DataFrame) -> None: + """ + Modifies parameters for multiple objects using a pandas DataFrame (rectangular data structure). + + This is generally the most efficient way to update a large number of objects at once. + The DataFrame must include the primary key fields for the object type to identify + which objects to update. + + Parameters + ---------- + ObjectType : str + The PowerWorld object type. + ParamList : List[str] + A list of internal field names being updated. These must correspond to the + column names in the `df`. + df : pandas.DataFrame + A DataFrame containing the data to update. The column names of `df` must + match the `ParamList`, and it must contain primary key columns. + + Returns + ------- + None + + Raises + ------ + PowerWorldError + If the SimAuto call fails. + """ + return self._com_call( + "ChangeParametersMultipleElementRect", + ObjectType, + convert_list_to_variant(ParamList), + convert_df_to_variant(df), + ) + + def ChangeParametersMultipleElementFlatInput( + self, ObjectType: str, ParamList: list, NoOfObjects: int, ValueList: list + ) -> None: + """Modifies parameters for multiple objects using a flat, 1-D list of values. + + This method is an alternative to `ChangeParametersMultipleElement` for cases + where the data is already flattened. + + Parameters + ---------- + ObjectType : str + The PowerWorld object type. + ParamList : List[str] + A list of internal field names to modify. + NoOfObjects : int + The number of objects being updated. + ValueList : List[Any] + A flat list of values. Its length must be `NoOfObjects * len(ParamList)`. + The values are ordered by object, then by parameter within each object. + + Returns + ------- + None + + Raises + ------ + Error + If `ValueList` is not a 1-D array (i.e., it's a list of lists). + PowerWorldError + If the SimAuto call fails. + """ + if isinstance(ValueList[0], list): + raise Error("The value list has to be a 1-D array") + return self._com_call( + "ChangeParametersMultipleElementFlatInput", + ObjectType, + convert_list_to_variant(ParamList), + NoOfObjects, + convert_list_to_variant(ValueList), + ) + + def GetCaseHeader(self, filename: str = None) -> Tuple[str]: + """Retrieves the header information from a PowerWorld case file. + + Parameters + ---------- + filename : str, optional + Path to the .pwb or .pwx file. If None, the header of the currently + open case is retrieved. + + Returns + ------- + tuple + A tuple of strings, where each string is a line from the case header. + + Raises + ------ + PowerWorldError + If the SimAuto call fails (e.g., file not found). + """ + if filename is None: + filename = self.pwb_file_path + return self._com_call("GetCaseHeader", filename) + + def GetFieldList(self, ObjectType: str, copy=False) -> pd.DataFrame: + """Retrieves the complete list of available fields for a given PowerWorld object type. + + This method queries PowerWorld for all fields associated with an object type + and caches the result for performance. + + Parameters + ---------- + ObjectType : str + The PowerWorld object type (e.g., 'Bus', 'Gen'). + copy : bool, optional + If True, returns a deep copy of the cached field list DataFrame. + Defaults to False. + + Returns + ------- + pandas.DataFrame + A DataFrame containing columns like 'key_field', 'internal_field_name', + 'field_data_type', 'description', 'display_name', and 'enterable'. + + Raises + ------ + PowerWorldError + If the SimAuto call fails (e.g., invalid object type). + """ + object_type = ObjectType.lower() + try: + output = self._object_fields[object_type] + except KeyError: + result = self._com_call("GetFieldList", ObjectType) + result_arr = np.array(result) + + # Try standard 5-column format first, fall back to old/new formats + base_cols = FieldListColumn.base_columns() + old_cols = FieldListColumn.old_columns() + new_cols = FieldListColumn.new_columns() + + try: + output = pd.DataFrame(result_arr, columns=base_cols) + except ValueError as e: + exp_base = r"\([0-9]+,\s" + exp_end = r"{}\)" + r1 = re.search(exp_base + exp_end.format(len(old_cols)), e.args[0]) + r2 = re.search(exp_base + exp_end.format(len(base_cols)), e.args[0]) + r3 = re.search(exp_base + exp_end.format(len(new_cols)), e.args[0]) + + if (r1 is None) or (r2 is None): + if r3 is None: + raise e + else: + output = pd.DataFrame(result_arr, columns=new_cols) + else: + output = pd.DataFrame(result_arr, columns=old_cols) + + output.sort_values(by=[FieldListColumn.INTERNAL_FIELD_NAME.value], inplace=True) + self._object_fields[object_type] = output + + return output.copy(deep=True) if copy else output + + def GetParametersSingleElement(self, ObjectType: str, ParamList: list, Values: list) -> pd.Series: + """Retrieves parameters for a single object identified by its primary keys. + + Parameters + ---------- + ObjectType : str + The PowerWorld object type (e.g., 'Bus', 'Gen'). + ParamList : List[str] + A list of internal field names to retrieve. This list must include the + primary key fields for the `ObjectType` to identify the target object. + Values : List[Any] + A list containing the primary key values for the object, followed by + empty strings or placeholders for other parameters in `ParamList` if they + are not part of the key. The length must match `ParamList`. + + Returns + ------- + pandas.Series + A pandas Series containing the requested data, indexed by `ParamList`. + + Raises + ------ + AssertionError + If the length of `ParamList` and `Values` do not match. + PowerWorldError + If the SimAuto call fails. + """ + assert len(ParamList) == len(Values), "The given ParamList and Values must have the same length." + + output = self._com_call( + "GetParametersSingleElement", + ObjectType, + convert_list_to_variant(ParamList), + convert_list_to_variant(Values), + ) + + return pd.Series(output, index=ParamList) + + def GetParametersMultipleElement( + self, ObjectType: str, ParamList: list, FilterName: str = "" + ) -> Union[pd.DataFrame, None]: + """Retrieves parameters for multiple objects of a specific type, optionally filtered. + + This method is commonly used to fetch data for all objects of a given type + or a subset defined by a PowerWorld filter. + + Parameters + ---------- + ObjectType : str + The PowerWorld object type (e.g., 'Bus', 'Gen'). + ParamList : List[str] + A list of internal field names to retrieve. + FilterName : str, optional + Optional name of a PowerWorld filter to restrict the result set. + Defaults to an empty string, meaning no filter is applied. + + Returns + ------- + Union[pandas.DataFrame, None] + A pandas DataFrame where columns correspond to `ParamList`. + Returns None if no objects are found matching the criteria. + + Raises + ------ + PowerWorldError + If the SimAuto call fails (e.g., invalid object type or field names). + """ + output = self._com_call( + "GetParametersMultipleElement", + ObjectType, + convert_list_to_variant(ParamList), + FilterName, + ) + if output is None: + return output + + return pd.DataFrame(np.array(output).transpose(), columns=ParamList) + + def GetParamsRectTyped( + self, ObjectType: str, ParamList: list, FilterName: str = "" + ) -> Union[pd.DataFrame, None]: + """Retrieves data in a rectangular format with PowerWorld's native variant typing preserved. + + This method is similar to `GetParametersMultipleElement` but attempts to preserve + the original data types as returned by SimAuto, which can sometimes be more efficient + or necessary for specific use cases. + + Parameters + ---------- + ObjectType : str + The PowerWorld object type. + ParamList : List[str] + A list of internal field names to retrieve. + FilterName : str, optional + Optional name of a PowerWorld filter to apply. Defaults to an empty string. + + Returns + ------- + Union[pandas.DataFrame, None] + A pandas DataFrame containing the requested data. Returns None if no objects found. + + Raises + ------ + PowerWorldError + If the SimAuto call fails. + """ + output = self._com_call( + "GetParamsRectTyped", + ObjectType, + convert_list_to_variant(ParamList), + FilterName, + pythoncom.VT_VARIANT, + ) + if output is None: + return output + + return pd.DataFrame(output, columns=ParamList) + + def GetParametersMultipleElementFlatOutput( + self, ObjectType: str, ParamList: list, FilterName: str = "" + ) -> Union[None, Tuple[str]]: + """Retrieves data for multiple elements in a flat, 1-D output format. + + The data is returned as a single tuple of strings, where values for each + object are concatenated. This format can be less convenient for direct + DataFrame conversion but might be useful for specific parsing needs. + + Parameters + ---------- + ObjectType : str + The PowerWorld object type. + ParamList : List[str] + A list of internal field names to retrieve. + FilterName : str, optional + Optional name of a PowerWorld filter to apply. Defaults to an empty string. + + Returns + ------- + Union[None, Tuple[str]] + A tuple of strings containing the data. Returns None if no data is found. + + Raises + ------ + PowerWorldError + If the SimAuto call fails. + """ + result = self._com_call( + "GetParametersMultipleElementFlatOutput", + ObjectType, + convert_list_to_variant(ParamList), + FilterName, + ) + + if len(result) == 0: + return None + else: + return result + + def GetSpecificFieldList(self, ObjectType: str, FieldList: List[str]) -> pd.DataFrame: + """Retrieves detailed metadata for a specific subset of fields for a given object type. + + This method provides more detailed information about specific fields, + including their display names and whether they are enterable. + + Parameters + ---------- + ObjectType : str + The PowerWorld object type. + FieldList : List[str] + A list of internal field names to query metadata for. + + Returns + ------- + pandas.DataFrame + A DataFrame with columns like 'variablename:location', 'field', + 'column header', 'field description', and 'enterable'. + + Raises + ------ + PowerWorldError + If the SimAuto call fails. + """ + base_cols = SpecificFieldListColumn.base_columns() + new_cols = SpecificFieldListColumn.new_columns() + sort_col = SpecificFieldListColumn.VARIABLENAME_LOCATION.value + + try: + df = ( + pd.DataFrame( + self._com_call("GetSpecificFieldList", ObjectType, convert_list_to_variant(FieldList)), + columns=base_cols, + ) + .sort_values(by=sort_col) + .reset_index(drop=True) + ) + except ValueError: + df = ( + pd.DataFrame( + self._com_call("GetSpecificFieldList", ObjectType, convert_list_to_variant(FieldList)), + columns=new_cols, + ) + .sort_values(by=sort_col) + .reset_index(drop=True) + ) + return df + + def GetSpecificFieldMaxNum(self, ObjectType: str, Field: str) -> int: + """Retrieves the maximum index for a field that supports multiple entries (e.g., CustomFloat). + + Some PowerWorld fields, like 'CustomFloat', can have multiple instances + (e.g., 'CustomFloat:1', 'CustomFloat:2'). This method returns the highest + available index for such a field. + + Parameters + ---------- + ObjectType : str + The PowerWorld object type. + Field : str + The base field name (e.g., 'CustomFloat'). + + Returns + ------- + int + The maximum integer index available for the specified field. + + Raises + ------ + PowerWorldError + If the SimAuto call fails. + """ + return self._com_call("GetSpecificFieldMaxNum", ObjectType, Field) + + def ListOfDevices(self, ObjType: str, FilterName="") -> Union[None, pd.DataFrame]: + """Retrieves a list of all objects of a specific type and their primary keys. + + This method is useful for getting an inventory of all objects of a certain type + in the case, or a filtered subset. + + Parameters + ---------- + ObjType : str + The PowerWorld object type (e.g., 'Bus', 'Gen'). + FilterName : str, optional + Optional name of a PowerWorld filter to apply. Defaults to an empty string. + + Returns + ------- + Union[None, pandas.DataFrame] + A pandas DataFrame containing the primary key fields for the objects. + Returns None if no objects are found. + + Raises + ------ + PowerWorldError + If the SimAuto call fails. + """ + # Get key field metadata to know column names + key_col = FieldListColumn.KEY_FIELD.value + name_col = FieldListColumn.INTERNAL_FIELD_NAME.value + + field_list = self.GetFieldList(ObjectType=ObjType, copy=False) + key_field_mask = field_list[key_col].str.match(r"\*[0-9]+[A-Z]*\*").to_numpy() + key_field_df = field_list.loc[key_field_mask].copy() + key_field_df[key_col] = key_field_df[key_col].str.replace(r"\*", "", regex=True) + key_field_df[key_col] = key_field_df[key_col].str.replace("[A-Z]*", "", regex=True) + key_field_series = key_field_df[key_col] + if self.decimal_delimiter != ".": + try: + key_field_series = key_field_series.str.replace(self.decimal_delimiter, ".") + except AttributeError: + pass + key_field_df["key_field_index"] = pd.to_numeric(key_field_series, errors='coerce').fillna(key_field_df[key_col]) - 1 + key_field_df.sort_values(by="key_field_index", inplace=True) + column_names = key_field_df[name_col].to_numpy() + + output = self._com_call("ListOfDevices", ObjType, FilterName) + + all_none = all(i is None for i in output) + + if all_none: + return None + + df = pd.DataFrame(output).transpose() + df.columns = column_names + + return df + + def ListOfDevicesAsVariantStrings(self, ObjType: str, FilterName="") -> tuple: + """Retrieves a list of devices where primary keys are returned as variant strings. + + This method returns the primary keys as a tuple of strings, which might be + useful for direct use in other SimAuto commands that expect string identifiers. + + Parameters + ---------- + ObjType : str + The PowerWorld object type. + FilterName : str, optional + Optional name of a PowerWorld filter to apply. Defaults to an empty string. + + Returns + ------- + tuple + A tuple of strings, where each string represents the primary key(s) of an object. + + Raises + ------ + PowerWorldError + If the SimAuto call fails. + """ + return self._com_call("ListOfDevicesAsVariantStrings", ObjType, FilterName) + + def ListOfDevicesFlatOutput(self, ObjType: str, FilterName="") -> tuple: + """Retrieves a list of devices in a flat, 1-D output format. + + Similar to `ListOfDevicesAsVariantStrings`, but the output format might differ + slightly depending on the SimAuto version. + + Parameters + ---------- + ObjType : str + The PowerWorld object type. + FilterName : str, optional + Optional name of a PowerWorld filter to apply. Defaults to an empty string. + + Returns + ------- + tuple + A tuple of strings. + + Raises + ------ + PowerWorldError + If the SimAuto call fails. + """ + return self._com_call("ListOfDevicesFlatOutput", ObjType, FilterName) + + def SendToExcel(self, ObjectType: str, FilterName: str, FieldList) -> None: + """Exports data for the specified objects directly to Microsoft Excel. + + This method requires Microsoft Excel to be installed on the system. + + Parameters + ---------- + ObjectType : str + The PowerWorld object type (e.g., 'Bus', 'Gen'). + FilterName : str + Optional PowerWorld filter name to apply. + FieldList : List[str] + A list of internal field names to export. + + Returns + ------- + None + + Raises + ------ + PowerWorldError + If the SimAuto call fails (e.g., Excel not installed, invalid parameters). + """ + return self._com_call("SendToExcel", ObjectType, FilterName, FieldList) diff --git a/esapp/saw/fault.py b/esapp/saw/fault.py index 41efca9d..915ab5db 100644 --- a/esapp/saw/fault.py +++ b/esapp/saw/fault.py @@ -1,6 +1,9 @@ """Fault analysis specific functions.""" +from esapp.saw._enums import YesNo + + class FaultMixin: """Mixin for fault analysis functions.""" @@ -41,26 +44,47 @@ def RunFault( PowerWorldError If the SimAuto call fails (e.g., invalid element, fault type, or location). """ + # If location is None, it is omitted from the arguments if location is not None: - return self.RunScriptCommand( - f"Fault({element}, {location}, {fault_type}, {r}, {x});" - ) + return self._run_script("Fault", element, location, fault_type, r, x) else: - return self.RunScriptCommand(f"Fault({element}, {fault_type}, {r}, {x});") + return self._run_script("Fault", element, fault_type, r, x) def FaultClear(self): - """Clears a single fault that has been calculated.""" - return self.RunScriptCommand("FaultClear;") + """Clears a single fault that has been calculated with the Fault command.""" + return self._run_script("FaultClear") def FaultAutoInsert(self): - """Inserts multiple fault definitions based on auto-insert options.""" - return self.RunScriptCommand("FaultAutoInsert;") + """Inserts multiple fault definitions using the Ctg_AutoInsert_Options object. + + Multiple fault definitions are inserted using the options in the + Ctg_AutoInsert_Options object that are relevant for fault analysis. + Faults can only be inserted for transmission lines or buses. + """ + return self._run_script("FaultAutoInsert") def FaultMultiple(self, use_dummy_bus: bool = False): - """Runs fault analysis on a list of defined faults.""" - dummy = "YES" if use_dummy_bus else "NO" - return self.RunScriptCommand(f"FaultMultiple({dummy});") + """Runs fault analysis on a list of defined faults. + + Parameters + ---------- + use_dummy_bus : bool, optional + If True, dummy buses are created and inserted at the specified + percent location for branch faults, and faults are calculated at + the dummy buses. If False, the fault is calculated at the branch + terminal bus closest to the specified location. Defaults to False. + """ + dummy = YesNo.from_bool(use_dummy_bus) + return self._run_script("FaultMultiple", dummy) def LoadPTISEQData(self, filename: str, version: int = 33): - """Loads sequence data in the PTI format.""" - return self.RunScriptCommand(f'LoadPTISEQData("{filename}", {version});') + """Loads sequence data in the PTI format. + + Parameters + ---------- + filename : str + Name of the file containing sequence data (typically ``.seq`` extension). + version : int, optional + Integer representing the PTI version of the SEQ file. Defaults to 33. + """ + return self._run_script("LoadPTISEQData", f'"{filename}"', version) diff --git a/esapp/saw/general.py b/esapp/saw/general.py index cb4d3b11..1a1b8ac9 100644 --- a/esapp/saw/general.py +++ b/esapp/saw/general.py @@ -1,8 +1,12 @@ """General script commands and data interaction functions.""" -from typing import List -import tempfile, os, re, uuid +from typing import List, Union +import os, re import pandas as pd +from ._enums import YesNo, format_filter, format_filter_areazone +from ._helpers import (format_list, get_temp_filepath, + parse_aux_content, build_aux_string) + class GeneralMixin: """Mixin for General Program Actions and Data Interaction.""" @@ -26,7 +30,7 @@ def CopyFile(self, old_filename: str, new_filename: str): PowerWorldError If the SimAuto call fails (e.g., file not found, permission issues). """ - return self.RunScriptCommand(f'CopyFile("{old_filename}", "{new_filename}");') + return self._run_script("CopyFile", f'"{old_filename}"', f'"{new_filename}"') def DeleteFile(self, filename: str): """Deletes a specified file. @@ -45,7 +49,7 @@ def DeleteFile(self, filename: str): PowerWorldError If the SimAuto call fails (e.g., file not found, permission issues). """ - return self.RunScriptCommand(f'DeleteFile("{filename}");') + return self._run_script("DeleteFile", f'"{filename}"') def RenameFile(self, old_filename: str, new_filename: str): """Renames a file from `old_filename` to `new_filename`. @@ -66,7 +70,7 @@ def RenameFile(self, old_filename: str, new_filename: str): PowerWorldError If the SimAuto call fails (e.g., file not found, new name already exists). """ - return self.RunScriptCommand(f'RenameFile("{old_filename}", "{new_filename}");') + return self._run_script("RenameFile", f'"{old_filename}"', f'"{new_filename}"') def WriteTextToFile(self, filename: str, text: str): """Writes a given text string to a file. @@ -88,7 +92,7 @@ def WriteTextToFile(self, filename: str, text: str): If the SimAuto call fails (e.g., permission issues). """ escaped_text = text.replace('"', '""') - return self.RunScriptCommand(f'WriteTextToFile("{filename}", "{escaped_text}");') + return self._run_script("WriteTextToFile", f'"{filename}"', f'"{escaped_text}"') def LogAdd(self, text: str) -> None: """Adds a message to the PowerWorld Simulator Message Log. @@ -107,7 +111,7 @@ def LogAdd(self, text: str) -> None: PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f'LogAdd("{text}");') + return self._run_script("LogAdd", f'"{text}"') def LogClear(self) -> None: """Clears all messages from the PowerWorld Simulator Message Log. @@ -121,7 +125,7 @@ def LogClear(self) -> None: PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand("LogClear;") + return self._run_script("LogClear") def LogShow(self, show: bool = True): """Shows or hides the PowerWorld Simulator Message Log window. @@ -140,8 +144,8 @@ def LogShow(self, show: bool = True): PowerWorldError If the SimAuto call fails. """ - yn = "YES" if show else "NO" - return self.RunScriptCommand(f"LogShow({yn});") + yn = YesNo.from_bool(show) + return self._run_script("LogShow", yn) def LogSave(self, filename: str, append: bool = False): """Saves the contents of the PowerWorld Simulator Message Log to a file. @@ -163,8 +167,8 @@ def LogSave(self, filename: str, append: bool = False): PowerWorldError If the SimAuto call fails (e.g., permission issues). """ - app = "YES" if append else "NO" - return self.RunScriptCommand(f'LogSave("{filename}", {app});') + app = YesNo.from_bool(append) + return self._run_script("LogSave", f'"{filename}"', app) def SetCurrentDirectory(self, directory: str, create_if_not_found: bool = False): """Sets the current working directory for PowerWorld Simulator. @@ -187,8 +191,8 @@ def SetCurrentDirectory(self, directory: str, create_if_not_found: bool = False) PowerWorldError If the SimAuto call fails (e.g., invalid path, permission issues). """ - c = "YES" if create_if_not_found else "NO" - return self.RunScriptCommand(f'SetCurrentDirectory("{directory}", {c});') + c = YesNo.from_bool(create_if_not_found) + return self._run_script("SetCurrentDirectory", f'"{directory}"', c) def EnterMode(self, mode: str) -> None: """Enters PowerWorld Simulator into a specific operating mode. @@ -211,7 +215,7 @@ def EnterMode(self, mode: str) -> None: """ if mode.upper() not in ["RUN", "EDIT"]: raise ValueError("Mode must be either 'RUN' or 'EDIT'.") - return self.RunScriptCommand(f"EnterMode({mode.upper()});") + return self._run_script("EnterMode", mode.upper()) def StoreState(self, statename: str) -> None: """Stores the current state of the PowerWorld case under a given name. @@ -232,15 +236,17 @@ def StoreState(self, statename: str) -> None: PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f'StoreState("{statename}");') + return self._run_script("StoreState", f'"{statename}"') - def RestoreState(self, statename: str) -> None: - """Restores a previously saved user state by its name. + def RestoreState(self, statename: str, state_type: str = "USER") -> None: + """Restores a previously saved state by its name. Parameters ---------- statename : str The name of the state to restore. + state_type : str, optional + The type of state to restore. Defaults to "USER". Returns ------- @@ -251,15 +257,17 @@ def RestoreState(self, statename: str) -> None: PowerWorldError If the SimAuto call fails (e.g., state not found). """ - return self.RunScriptCommand(f'RestoreState(USER, "{statename}");') + return self._run_script("RestoreState", state_type, f'"{statename}"') - def DeleteState(self, statename: str) -> None: - """Deletes a previously saved user state by its name. + def DeleteState(self, statename: str, state_type: str = "USER") -> None: + """Deletes a previously saved state by its name. Parameters ---------- statename : str The name of the state to delete. + state_type : str, optional + The type of state to delete. Defaults to "USER". Returns ------- @@ -270,7 +278,7 @@ def DeleteState(self, statename: str) -> None: PowerWorldError If the SimAuto call fails (e.g., state not found). """ - return self.RunScriptCommand(f'DeleteState(USER, "{statename}");') + return self._run_script("DeleteState", state_type, f'"{statename}"') def LoadAux(self, filename: str, create_if_not_found: bool = False): """Loads an auxiliary (.aux) file into PowerWorld Simulator. @@ -292,8 +300,8 @@ def LoadAux(self, filename: str, create_if_not_found: bool = False): PowerWorldError If the SimAuto call fails (e.g., file not found, syntax error in aux file). """ - c = "YES" if create_if_not_found else "NO" - return self.RunScriptCommand(f'LoadAux("{filename}", {c});') + c = YesNo.from_bool(create_if_not_found) + return self._run_script("LoadAux", f'"{filename}"', c) def ImportData(self, filename: str, filetype: str, header_line: int = 1, create_if_not_found: bool = False): """Imports data from a file in various formats into PowerWorld Simulator. @@ -318,8 +326,8 @@ def ImportData(self, filename: str, filetype: str, header_line: int = 1, create_ PowerWorldError If the SimAuto call fails. """ - c = "YES" if create_if_not_found else "NO" - return self.RunScriptCommand(f'ImportData("{filename}", {filetype}, {header_line}, {c});') + c = YesNo.from_bool(create_if_not_found) + return self._run_script("ImportData", f'"{filename}"', filetype, header_line, c) def LoadCSV(self, filename: str, create_if_not_found: bool = False): """Loads a CSV file, typically one formatted similarly to output from `SendToExcel`. @@ -340,8 +348,8 @@ def LoadCSV(self, filename: str, create_if_not_found: bool = False): PowerWorldError If the SimAuto call fails. """ - c = "YES" if create_if_not_found else "NO" - return self.RunScriptCommand(f'LoadCSV("{filename}", {c});') + c = YesNo.from_bool(create_if_not_found) + return self._run_script("LoadCSV", f'"{filename}"', c) def LoadScript(self, filename: str, script_name: str = ""): """Loads and runs a script from an auxiliary file. @@ -363,7 +371,7 @@ def LoadScript(self, filename: str, script_name: str = ""): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f'LoadScript("{filename}", "{script_name}");') + return self._run_script("LoadScript", f'"{filename}"', f'"{script_name}"') def SaveData( self, @@ -411,25 +419,16 @@ def SaveData( PowerWorldError If the SimAuto call fails. """ - fields = "[" + ", ".join(fieldlist) + "]" - subs = "[" + ", ".join(subdatalist) if subdatalist else "[]" - if subdatalist: - subs += "]" - - sorts = "[" + ", ".join(sortfieldlist) if sortfieldlist else "[]" - if sortfieldlist: - sorts += "]" + fields = format_list(fieldlist) + subs = format_list(subdatalist) + sorts = format_list(sortfieldlist) - filt = f'"{filter_name}"' if filter_name and filter_name not in ["SELECTED", "AREAZONE"] else filter_name + filt = format_filter_areazone(filter_name) - trans = "YES" if transpose else "NO" - app = "YES" if append else "NO" + trans = YesNo.from_bool(transpose) + app = YesNo.from_bool(append) - cmd = ( - f'SaveData("{filename}", {filetype}, {objecttype}, {fields}, {subs}, ' - f'{filt}, {sorts}, {trans}, {app});' - ) - return self.RunScriptCommand(cmd) + return self._run_script("SaveData", f'"{filename}"', filetype, objecttype, fields, subs, filt, sorts, trans, app) def SaveDataWithExtra(self, filename: str, filetype: str, objecttype: str, fieldlist: List[str], subdatalist: List[str] = None, filter_name: str = "", sortfieldlist: List[str] = None, header_list: List[str] = None, header_value_list: List[str] = None, transpose: bool = False, append: bool = True): """Saves data with extra user-specified header fields and values. @@ -471,22 +470,17 @@ def SaveDataWithExtra(self, filename: str, filetype: str, objecttype: str, field PowerWorldError If the SimAuto call fails. """ - fields = "[" + ", ".join(fieldlist) + "]" - subs = "[" + ", ".join(subdatalist) if subdatalist else "[]" - if subdatalist: subs += "]" - sorts = "[" + ", ".join(sortfieldlist) if sortfieldlist else "[]" - if sortfieldlist: sorts += "]" - headers = "[" + ", ".join([f'"{h}"' for h in header_list]) if header_list else "[]" - if header_list: headers += "]" - values = "[" + ", ".join([f'"{v}"' for v in header_value_list]) if header_value_list else "[]" - if header_value_list: values += "]" - - filt = f'"{filter_name}"' if filter_name and filter_name not in ["SELECTED", "AREAZONE"] else filter_name - trans = "YES" if transpose else "NO" - app = "YES" if append else "NO" - - cmd = f'SaveDataWithExtra("{filename}", {filetype}, {objecttype}, {fields}, {subs}, {filt}, {sorts}, {headers}, {values}, {trans}, {app});' - return self.RunScriptCommand(cmd) + fields = format_list(fieldlist) + subs = format_list(subdatalist) + sorts = format_list(sortfieldlist) + headers = format_list(header_list, quote_items=True) + values = format_list(header_value_list, quote_items=True) + + filt = format_filter_areazone(filter_name) + trans = YesNo.from_bool(transpose) + app = YesNo.from_bool(append) + + return self._run_script("SaveDataWithExtra", f'"{filename}"', filetype, objecttype, fields, subs, filt, sorts, headers, values, trans, app) def SetData(self, objecttype: str, fieldlist: List[str], valuelist: List[str], filter_name: str = ""): """Sets data for specified objects and fields. @@ -513,10 +507,10 @@ def SetData(self, objecttype: str, fieldlist: List[str], valuelist: List[str], f PowerWorldError If the SimAuto call fails. """ - fields = "[" + ", ".join(fieldlist) + "]" - values = "[" + ", ".join([str(v) for v in valuelist]) + "]" - filt = f'"{filter_name}"' if filter_name and filter_name not in ["SELECTED", "AREAZONE", "ALL"] else filter_name - return self.RunScriptCommand(f"SetData({objecttype}, {fields}, {values}, {filt});") + fields = format_list(fieldlist) + values = format_list(valuelist, stringify=True) + filt = format_filter(filter_name) + return self._run_script("SetData", objecttype, fields, values, filt) def CreateData(self, objecttype: str, fieldlist: List[str], valuelist: List[str]): """Creates a new object of a specified type with initial field values. @@ -540,9 +534,9 @@ def CreateData(self, objecttype: str, fieldlist: List[str], valuelist: List[str] PowerWorldError If the SimAuto call fails (e.g., object already exists, invalid parameters). """ - fields = "[" + ", ".join(fieldlist) + "]" - values = "[" + ", ".join([str(v) for v in valuelist]) + "]" - return self.RunScriptCommand(f"CreateData({objecttype}, {fields}, {values});") + fields = format_list(fieldlist) + values = format_list(valuelist, stringify=True) + return self._run_script("CreateData", objecttype, fields, values) def GetSubData(self, objecttype: str, fieldlist: List[str], subdatalist: List[str] = None, filter_name: str = "") -> pd.DataFrame: """Retrieves object data including nested SubData sections as a DataFrame. @@ -575,49 +569,70 @@ def GetSubData(self, objecttype: str, fieldlist: List[str], subdatalist: List[st ... print(f"Gen {row['BusNum']}: {len(row['BidCurve'])} bid points") """ subdatalist = subdatalist or [] - tmp = tempfile.NamedTemporaryFile(suffix=".aux", delete=False) - tmp.close() - - def parse_line(line: str) -> List[str]: - """Parse a line detecting bracket [x,y] or space-delimited format.""" - line = line.strip() - if '[' in line: # Bracket format: [x, y], [a, b] or [x, y] [a, b] - return [m.group(1).strip() for m in re.finditer(r'\[(.*?)\]', line)] - else: # Space-delimited: val1 val2 "val 3" - return [x.replace('"', '') for x in re.findall(r'(?:[^\s"]|"(?:\\.|[^"])*")+', line)] + tmp_path = get_temp_filepath(".aux") try: - self.SaveData(tmp.name, "AUX", objecttype, fieldlist, subdatalist, filter_name, append=False) + self.SaveData(tmp_path, "AUX", objecttype, fieldlist, subdatalist, filter_name, append=False) - if not os.path.exists(tmp.name): return pd.DataFrame(columns=fieldlist + subdatalist) - with open(tmp.name, 'r') as f: content = f.read() + if not os.path.exists(tmp_path): + return pd.DataFrame(columns=fieldlist + subdatalist) + with open(tmp_path, 'r') as f: + content = f.read() - match = re.search(r'DATA\s*\(\w+,\s*\[(.*?)\]\)\s*\{(.*)\}', content, re.DOTALL | re.IGNORECASE) - if not match: return pd.DataFrame(columns=fieldlist + subdatalist) + records = parse_aux_content(content, fieldlist, subdatalist) + if not records: + return pd.DataFrame(columns=fieldlist + subdatalist) + return pd.DataFrame(records) - records, curr, sub_key = [], {}, None - splitter = re.compile(r'(?:[^\s"]|"(?:\\.|[^"])*")+') + finally: + if os.path.exists(tmp_path): + os.remove(tmp_path) - for line in match.group(2).strip().split('\n'): - line = line.strip() - if not line or line.startswith('//'): continue + def SetSubData(self, objecttype: str, fieldlist: List[str], + records: List[dict], + subdatatype: Union[str, List[str], None] = None) -> None: + """Write object data with optional SubData sections to PowerWorld via AUX. - if line.upper().startswith('', line, re.IGNORECASE).group(1) - elif line.upper().startswith(''): - sub_key = None - elif sub_key: - curr.setdefault(sub_key, []).append(parse_line(line)) - else: - if curr: records.append(curr) - curr = {k: v.replace('"', '') for k, v in zip(fieldlist, splitter.findall(line))} - for s in subdatalist: curr[s] = [] + This is the write counterpart to ``GetSubData``. It constructs an AUX + DATA block and processes it, creating or updating objects including + their nested SubData sections. - if curr: records.append(curr) - return pd.DataFrame(records) + Parameters + ---------- + objecttype : str + The PowerWorld object type (e.g., "TSContingency", "Gen", "Contingency"). + fieldlist : List[str] + Field names for the parent object's scalar columns. + records : List[dict] + Each dict must have keys matching ``fieldlist`` for scalar values. + If ``subdatatype`` is specified, the dict may also contain a key + matching each subdata type whose value is a list of lists (each + inner list is one row of subdata values). + subdatatype : str, List[str], or None + Name(s) of the SubData section(s) (e.g., "CTGElement", + "BidCurve", or ["BidCurve", "ReactiveCapability"]). + If None, no subdata is written. - finally: - if os.path.exists(tmp.name): os.remove(tmp.name) + Examples + -------- + >>> saw.SetSubData( + ... "TSContingency", + ... ["TSCTGName", "StartTime", "EndTime", "CTGSkip"], + ... [{ + ... "TSCTGName": "Fault1", + ... "StartTime": 0.0, + ... "EndTime": 10.0, + ... "CTGSkip": "NO", + ... "TSContingencyElement": [ + ... ["FAULT BUS 1", 1.0], + ... ["CLEAR FAULT 1", 1.083], + ... ] + ... }], + ... subdatatype="TSContingencyElement" + ... ) + """ + aux = build_aux_string(objecttype, fieldlist, records, subdatatype) + self.exec_aux(aux) def SaveObjectFields(self, filename: str, objecttype: str, fieldlist: List[str]): """Saves a list of fields available for the specified objecttype to a file. @@ -640,8 +655,8 @@ def SaveObjectFields(self, filename: str, objecttype: str, fieldlist: List[str]) PowerWorldError If the SimAuto call fails. """ - fields = "[" + ", ".join(fieldlist) + "]" - return self.RunScriptCommand(f'SaveObjectFields("{filename}", {objecttype}, {fields});') + fields = format_list(fieldlist) + return self._run_script("SaveObjectFields", f'"{filename}"', objecttype, fields) def Delete(self, objecttype: str, filter_name: str = ""): """Deletes objects of a specified type, optionally filtered. @@ -662,8 +677,8 @@ def Delete(self, objecttype: str, filter_name: str = ""): PowerWorldError If the SimAuto call fails. """ - filt = f'"{filter_name}"' if filter_name and filter_name not in ["SELECTED", "AREAZONE"] else filter_name - return self.RunScriptCommand(f"Delete({objecttype}, {filt});") + filt = format_filter_areazone(filter_name) + return self._run_script("Delete", objecttype, filt) def SelectAll(self, objecttype: str, filter_name: str = ""): """Sets the 'Selected' field to YES for objects of a specified type, optionally filtered. @@ -684,8 +699,8 @@ def SelectAll(self, objecttype: str, filter_name: str = ""): PowerWorldError If the SimAuto call fails. """ - filt = f'"{filter_name}"' if filter_name and filter_name not in ["SELECTED", "AREAZONE"] else filter_name - return self.RunScriptCommand(f"SelectAll({objecttype}, {filt});") + filt = format_filter_areazone(filter_name) + return self._run_script("SelectAll", objecttype, filt) def UnSelectAll(self, objecttype: str, filter_name: str = ""): """Sets the 'Selected' field to NO for objects of a specified type, optionally filtered. @@ -706,10 +721,10 @@ def UnSelectAll(self, objecttype: str, filter_name: str = ""): PowerWorldError If the SimAuto call fails. """ - filt = f'"{filter_name}"' if filter_name and filter_name not in ["SELECTED", "AREAZONE"] else filter_name - return self.RunScriptCommand(f"UnSelectAll({objecttype}, {filt});") + filt = format_filter_areazone(filter_name) + return self._run_script("UnSelectAll", objecttype, filt) - def SendToExcelAdvanced(self, objecttype: str, fieldlist: List[str], filter_name: str = "", use_column_headers: bool = True, workbook: str = "", worksheet: str = "", sortfieldlist: List[str] = None, header_list: List[str] = None, header_value_list: List[str] = None, clear_existing: bool = True, row_shift: int = 0, col_shift: int = 0): + def SendtoExcel(self, objecttype: str, fieldlist: List[str], filter_name: str = "", use_column_headers: bool = True, workbook: str = "", worksheet: str = "", sortfieldlist: List[str] = None, header_list: List[str] = None, header_value_list: List[str] = None, clear_existing: bool = True, row_shift: int = 0, col_shift: int = 0): """Sends data for specified objects and fields directly to Microsoft Excel with advanced options. This is an extended version of SendToExcel that provides additional control over @@ -754,24 +769,20 @@ def SendToExcelAdvanced(self, objecttype: str, fieldlist: List[str], filter_name ------ PowerWorldError If the SimAuto call fails (e.g., Excel not installed, invalid parameters). - + See Also -------- SendToExcel : Basic version with fewer parameters for simple exports. """ - fields = "[" + ", ".join(fieldlist) + "]" - filt = f'"{filter_name}"' if filter_name and filter_name not in ["SELECTED", "AREAZONE"] else filter_name - uch = "YES" if use_column_headers else "NO" - sorts = "[" + ", ".join(sortfieldlist) if sortfieldlist else "[]" - if sortfieldlist: sorts += "]" - headers = "[" + ", ".join([f'"{h}"' for h in header_list]) if header_list else "[]" - if header_list: headers += "]" - values = "[" + ", ".join([f'"{v}"' for v in header_value_list]) if header_value_list else "[]" - if header_value_list: values += "]" - ce = "YES" if clear_existing else "NO" - - cmd = f'SendtoExcel({objecttype}, {fields}, {filt}, {uch}, "{workbook}", "{worksheet}", {sorts}, {headers}, {values}, {ce}, {row_shift}, {col_shift});' - return self.RunScriptCommand(cmd) + fields = format_list(fieldlist) + filt = format_filter_areazone(filter_name) + uch = YesNo.from_bool(use_column_headers) + sorts = format_list(sortfieldlist) + headers = format_list(header_list, quote_items=True) + values = format_list(header_value_list, quote_items=True) + ce = YesNo.from_bool(clear_existing) + + return self._run_script("SendtoExcel", objecttype, fields, filt, uch, f'"{workbook}"', f'"{worksheet}"', sorts, headers, values, ce, row_shift, col_shift) def LogAddDateTime( self, @@ -804,16 +815,11 @@ def LogAddDateTime( ------ PowerWorldError If the SimAuto call fails. - - Examples - -------- - >>> saw.LogAddDateTime("DateTime", True, True, True) - # Adds a log entry labeled "DateTime" with current date, time, and milliseconds. """ - id = "YES" if include_date else "NO" - it = "YES" if include_time else "NO" - im = "YES" if include_milliseconds else "NO" - return self.RunScriptCommand(f'LogAddDateTime("{label}", {id}, {it}, {im});') + id = YesNo.from_bool(include_date) + it = YesNo.from_bool(include_time) + im = YesNo.from_bool(include_milliseconds) + return self._run_script("LogAddDateTime", f'"{label}"', id, it, im) def LoadAuxDirectory( self, @@ -845,17 +851,12 @@ def LoadAuxDirectory( ------ PowerWorldError If the SimAuto call fails (e.g., directory not found). - - Examples - -------- - >>> saw.LoadAuxDirectory("C:/SimCases/AuxFiles", "*.aux", True) - # Loads all .aux files from the directory in alphabetical order. """ - c = "YES" if create_if_not_found else "NO" + c = YesNo.from_bool(create_if_not_found) if filter_string: - return self.RunScriptCommand(f'LoadAuxDirectory("{file_directory}", "{filter_string}", {c});') + return self._run_script("LoadAuxDirectory", f'"{file_directory}"', f'"{filter_string}"', c) else: - return self.RunScriptCommand(f'LoadAuxDirectory("{file_directory}", , {c});') + return self._run_script("LoadAuxDirectory", f'"{file_directory}"', "", c) def LoadData(self, filename: str, data_name: str, create_if_not_found: bool = False): """Loads a named DATA section from another auxiliary file. @@ -881,8 +882,8 @@ def LoadData(self, filename: str, data_name: str, create_if_not_found: bool = Fa PowerWorldError If the SimAuto call fails (e.g., file or data section not found). """ - c = "YES" if create_if_not_found else "NO" - return self.RunScriptCommand(f'LoadData("{filename}", {data_name}, {c});') + c = YesNo.from_bool(create_if_not_found) + return self._run_script("LoadData", f'"{filename}"', data_name, c) def StopAuxFile(self): """Treats the remainder of the file after this command as a comment. @@ -903,4 +904,4 @@ def StopAuxFile(self): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand("StopAuxFile;") \ No newline at end of file + return self._run_script("StopAuxFile") diff --git a/esapp/saw/gic.py b/esapp/saw/gic.py index afaf4e20..e8b672d6 100644 --- a/esapp/saw/gic.py +++ b/esapp/saw/gic.py @@ -1,11 +1,13 @@ """Geomagnetically Induced Current (GIC) specific functions.""" from typing import List +from ._enums import YesNo + class GICMixin: """Mixin for GIC analysis functions.""" - def CalculateGIC(self, max_field: float, direction: float, solve_pf: bool = True): + def GICCalculate(self, max_field: float, direction: float, solve_pf: bool = True): """Calculates the 'Single Snapshot' GIC solution for a uniform electric field. This method computes Geomagnetically Induced Currents (GIC) based on a @@ -30,19 +32,19 @@ def CalculateGIC(self, max_field: float, direction: float, solve_pf: bool = True PowerWorldError If the SimAuto call fails (e.g., GIC not enabled, invalid parameters). """ - spf = "YES" if solve_pf else "NO" - return self.RunScriptCommand(f"GICCalculate({max_field}, {direction}, {spf});") + spf = YesNo.from_bool(solve_pf) + return self._run_script("GICCalculate", max_field, direction, spf) - def ClearGIC(self): + def GICClear(self): """Clears GIC (Geomagnetically Induced Current) values from the case. - This is a wrapper for the `GICClear` script command. + This is a wrapper for the ``GICClear`` script command. Returns ------- None """ - return self.RunScriptCommand("GICClear;") + return self._run_script("GICClear") def GICLoad3DEfield(self, file_type: str, filename: str, setup_on_load: bool = True): """Loads GIC data, including time-varying electric fields, from a specified file. @@ -66,8 +68,8 @@ def GICLoad3DEfield(self, file_type: str, filename: str, setup_on_load: bool = T PowerWorldError If the SimAuto call fails (e.g., file not found, invalid format). """ - sol = "YES" if setup_on_load else "NO" - return self.RunScriptCommand(f'GICLoad3DEfield({file_type}, "{filename}", {sol});') + sol = YesNo.from_bool(setup_on_load) + return self._run_script("GICLoad3DEfield", file_type, f'"{filename}"', sol) def GICReadFilePSLF(self, filename: str): """Reads GIC supplemental data from a GMD text file format. @@ -86,7 +88,7 @@ def GICReadFilePSLF(self, filename: str): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f'GICReadFilePSLF("{filename}");') + return self._run_script("GICReadFilePSLF", f'"{filename}"') def GICReadFilePTI(self, filename: str): """Reads GIC supplemental data from a GIC text file format. @@ -105,7 +107,7 @@ def GICReadFilePTI(self, filename: str): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f'GICReadFilePTI("{filename}");') + return self._run_script("GICReadFilePTI", f'"{filename}"') def GICSaveGMatrix(self, gmatrix_filename: str, gmatrix_id_filename: str): """Saves the GMatrix used with the GIC calculations in a file formatted for use with Matlab. @@ -129,7 +131,7 @@ def GICSaveGMatrix(self, gmatrix_filename: str, gmatrix_id_filename: str): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f'GICSaveGMatrix("{gmatrix_filename}", "{gmatrix_id_filename}");') + return self._run_script("GICSaveGMatrix", f'"{gmatrix_filename}"', f'"{gmatrix_id_filename}"') def GICSetupTimeVaryingSeries(self, start: float = 0.0, end: float = 0.0, delta: float = 0.0): """Creates a set of Branch series DC input voltages for time-varying GIC analysis. @@ -155,7 +157,7 @@ def GICSetupTimeVaryingSeries(self, start: float = 0.0, end: float = 0.0, delta: PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f"GICSetupTimeVaryingSeries({start}, {end}, {delta});") + return self._run_script("GICSetupTimeVaryingSeries", start, end, delta) def GICShiftOrStretchInputPoints( self, @@ -193,10 +195,8 @@ def GICShiftOrStretchInputPoints( PowerWorldError If the SimAuto call fails. """ - update = "YES" if update_time_varying_series else "NO" - return self.RunScriptCommand( - f"GICShiftOrStretchInputPoints({lat_shift}, {lon_shift}, {mag_scalar}, {stretch_scalar}, {update});" - ) + update = YesNo.from_bool(update_time_varying_series) + return self._run_script("GICShiftOrStretchInputPoints", lat_shift, lon_shift, mag_scalar, stretch_scalar, update) def GICTimeVaryingCalculate(self, the_time: float, solve_pf: bool = True): """Calculates GIC values using the 'Time-Varying Series Voltage Inputs' calculation mode. @@ -221,8 +221,8 @@ def GICTimeVaryingCalculate(self, the_time: float, solve_pf: bool = True): PowerWorldError If the SimAuto call fails. """ - spf = "YES" if solve_pf else "NO" - return self.RunScriptCommand(f"GICTimeVaryingCalculate({the_time}, {spf});") + spf = YesNo.from_bool(solve_pf) + return self._run_script("GICTimeVaryingCalculate", the_time, spf) def GICTimeVaryingAddTime(self, new_time: float): """Adds a new time point to the time-varying voltage input series. @@ -241,7 +241,7 @@ def GICTimeVaryingAddTime(self, new_time: float): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f"GICTimeVaryingAddTime({new_time});") + return self._run_script("GICTimeVaryingAddTime", new_time) def GICTimeVaryingDeleteAllTimes(self): """Deletes all input time-varying voltage input values. @@ -255,7 +255,7 @@ def GICTimeVaryingDeleteAllTimes(self): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand("GICTimeVaryingDeleteAllTimes;") + return self._run_script("GICTimeVaryingDeleteAllTimes") def GICTimeVaryingEFieldCalculate(self, the_time: float, solve_pf: bool = True): """Calculates GIC Values using the 'Time-Varying Electric Field Inputs' calculation mode. @@ -277,8 +277,8 @@ def GICTimeVaryingEFieldCalculate(self, the_time: float, solve_pf: bool = True): PowerWorldError If the SimAuto call fails. """ - spf = "YES" if solve_pf else "NO" - return self.RunScriptCommand(f"GICTimeVaryingEFieldCalculate({the_time}, {spf});") + spf = YesNo.from_bool(solve_pf) + return self._run_script("GICTimeVaryingEFieldCalculate", the_time, spf) def GICTimeVaryingElectricFieldsDeleteAllTimes(self): """Clears all time-varying electric field input values. @@ -292,7 +292,7 @@ def GICTimeVaryingElectricFieldsDeleteAllTimes(self): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand("GICTimeVaryingElectricFieldsDeleteAllTimes;") + return self._run_script("GICTimeVaryingElectricFieldsDeleteAllTimes") def GICWriteFilePSLF(self, filename: str, use_filters: bool = False): """Writes GIC supplemental data to a GMD text file format (PSLF). @@ -313,8 +313,8 @@ def GICWriteFilePSLF(self, filename: str, use_filters: bool = False): PowerWorldError If the SimAuto call fails. """ - uf = "YES" if use_filters else "NO" - return self.RunScriptCommand(f'GICWriteFilePSLF("{filename}", {uf});') + uf = YesNo.from_bool(use_filters) + return self._run_script("GICWriteFilePSLF", f'"{filename}"', uf) def GICWriteFilePTI(self, filename: str, use_filters: bool = False, version: int = 4): """Writes GIC supplemental data to a GIC text file format (PTI). @@ -337,8 +337,8 @@ def GICWriteFilePTI(self, filename: str, use_filters: bool = False, version: int PowerWorldError If the SimAuto call fails. """ - uf = "YES" if use_filters else "NO" - return self.RunScriptCommand(f'GICWriteFilePTI("{filename}", {uf}, {version});') + uf = YesNo.from_bool(use_filters) + return self._run_script("GICWriteFilePTI", f'"{filename}"', uf, version) def GICWriteOptions(self, filename: str, key_field: str = "PRIMARY"): """Writes the current GIC solution options to an auxiliary file. @@ -360,21 +360,4 @@ def GICWriteOptions(self, filename: str, key_field: str = "PRIMARY"): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f'GICWriteOptions("{filename}", {key_field});') - - def GICWriteOptions(self, filename: str, key_field: str = "PRIMARY"): - """Writes the current GIC solution options to an auxiliary file. - - Parameters - ---------- - filename : str - The name (path) of the auxiliary file to write the options to. - key_field : str, optional - The identifier to use for the data in the auxiliary file - ("PRIMARY", "SECONDARY", or "LABEL"). Defaults to "PRIMARY". - - Returns - ------- - None - """ - return self.RunScriptCommand(f'GICWriteOptions("{filename}", {key_field});') + return self._run_script("GICWriteOptions", f'"{filename}"', key_field) diff --git a/esapp/saw/matrices.py b/esapp/saw/matrices.py index d80590f9..d833e107 100644 --- a/esapp/saw/matrices.py +++ b/esapp/saw/matrices.py @@ -1,15 +1,17 @@ import os import re -import tempfile from pathlib import Path from typing import Union import numpy as np from scipy.sparse import csr_matrix +from ._enums import YesNo +from ._helpers import get_temp_filepath + class MatrixMixin: - + def get_ybus(self, full: bool = False, file: Union[str, None] = None) -> Union[np.ndarray, csr_matrix]: """Obtain the YBus matrix from PowerWorld. @@ -39,40 +41,43 @@ def get_ybus(self, full: bool = False, file: Union[str, None] = None) -> Union[n """ if file: _tempfile_path = file + _cleanup = False else: - _tempfile = tempfile.NamedTemporaryFile(mode="w", suffix=".mat", delete=False) - _tempfile_path = Path(_tempfile.name).as_posix() - _tempfile.close() - cmd = f'SaveYbusInMatlabFormat("{_tempfile_path}", NO)' - self.RunScriptCommand(cmd) - with open(_tempfile_path, "r") as f: - f.readline() - mat_str = f.read() - mat_str = re.sub(r"\s", "", mat_str) - lines = re.split(";", mat_str) - ie = r"[0-9]+" - fe = r"-*[0-9]+\.[0-9]+" - dr = re.compile(r"(?:Ybus)=(?:sparse\()({ie})".format(ie=ie)) - exp = re.compile(r"(?:Ybus\()({ie}),({ie})(?:\)=)({fe})(?:\+j\*)(?:\()({fe})".format(ie=ie, fe=fe)) - dim = dr.match(lines[0])[1] - n = int(dim) - row, col, data = [], [], [] - for line in lines[1:]: - match = exp.match(line) - if match is None: - continue - idx1, idx2, real, imag = match.groups() - admittance = float(real) + 1j * float(imag) - row.append(int(idx1)) - col.append(int(idx2)) - data.append(admittance) + _tempfile_path = get_temp_filepath(".mat") + self._run_script("SaveYbusInMatlabFormat", f'"{_tempfile_path}"', "NO") + _cleanup = True + try: + with open(_tempfile_path, "r") as f: + f.readline() + mat_str = f.read() + mat_str = re.sub(r"\s", "", mat_str) + lines = re.split(";", mat_str) + ie = r"[0-9]+" + fe = r"-*[0-9]+\.[0-9]+" + dr = re.compile(r"(?:Ybus)=(?:sparse\()({ie})".format(ie=ie)) + exp = re.compile(r"(?:Ybus\()({ie}),({ie})(?:\)=)({fe})(?:\+j\*)(?:\()({fe})".format(ie=ie, fe=fe)) + dim = dr.match(lines[0])[1] + n = int(dim) + row, col, data = [], [], [] + for line in lines[1:]: + match = exp.match(line) + if match is None: + continue + idx1, idx2, real, imag = match.groups() + admittance = float(real) + 1j * float(imag) + row.append(int(idx1)) + col.append(int(idx2)) + data.append(admittance) - sparse_matrix = csr_matrix( - (data, (np.asarray(row) - 1, np.asarray(col) - 1)), - shape=(n, n), - dtype=complex, - ) - return sparse_matrix.toarray() if full else sparse_matrix + sparse_matrix = csr_matrix( + (data, (np.asarray(row) - 1, np.asarray(col) - 1)), + shape=(n, n), + dtype=complex, + ) + return sparse_matrix.toarray() if full else sparse_matrix + finally: + if _cleanup: + os.unlink(_tempfile_path) def get_gmatrix(self, full: bool = False) -> Union[np.ndarray, csr_matrix]: """Get the GIC conductance matrix (G). @@ -101,9 +106,9 @@ def get_gmatrix(self, full: bool = False) -> Union[np.ndarray, csr_matrix]: """ g_matrix_path, id_file_path = self._make_temp_matrix_files() try: - cmd = f'GICSaveGMatrix("{g_matrix_path}","{id_file_path}");' - self.RunScriptCommand(cmd) - self.RunScriptCommand(cmd) + # Double call is intentional — PW sometimes requires it for GMatrix. + self._run_script("GICSaveGMatrix", f'"{g_matrix_path}"', f'"{id_file_path}"') + self._run_script("GICSaveGMatrix", f'"{g_matrix_path}"', f'"{id_file_path}"') with open(g_matrix_path, "r") as f: mat_str = f.read() sparse_matrix = self._parse_real_matrix(mat_str, "GMatrix") @@ -112,7 +117,65 @@ def get_gmatrix(self, full: bool = False) -> Union[np.ndarray, csr_matrix]: os.unlink(g_matrix_path) os.unlink(id_file_path) - def get_jacobian(self, full: bool = False) -> Union[np.ndarray, csr_matrix]: + def get_gmatrix_with_ids(self, full: bool = False): + """Get the GIC conductance matrix (G) along with the node ID mapping. + + This method returns both the G-matrix and a list of node identifiers + that describe what each row/column represents (substations and buses). + + Parameters + ---------- + full : bool, optional + If True, returns a dense NumPy array. If False (default), returns a + SciPy CSR sparse matrix. + + Returns + ------- + tuple + A tuple of (G_matrix, node_ids) where: + - G_matrix: The G-matrix as either dense array or sparse CSR matrix + - node_ids: List of strings describing each node (e.g., "Sub 1", "Bus 101") + """ + g_matrix_path, id_file_path = self._make_temp_matrix_files() + try: + # Double call is intentional — PW sometimes requires it for GMatrix. + self._run_script("GICSaveGMatrix", f'"{g_matrix_path}"', f'"{id_file_path}"') + self._run_script("GICSaveGMatrix", f'"{g_matrix_path}"', f'"{id_file_path}"') + + with open(g_matrix_path, "r") as f: + mat_str = f.read() + sparse_matrix = self._parse_real_matrix(mat_str, "GMatrix") + + with open(id_file_path, "r") as f: + id_content = f.read() + + # Parse the ID file - format: "ObjectType, Number, Row/Col, Name" + # First line is header, skip it + node_ids = [] + lines = id_content.strip().split('\n') + for line in lines[1:]: # Skip header line + line = line.strip() + if not line: + continue + # Split by comma + parts = [p.strip() for p in line.split(',')] + # Format: ObjectType, Number, Row/Col, Name - Name is 4th field (index 3) + if len(parts) >= 4: + node_ids.append(parts[3]) # Name is 4th field + elif len(parts) >= 3: + node_ids.append(parts[2]) # Fallback to 3rd field + elif len(parts) >= 2: + node_ids.append(parts[1]) # Fallback to 2nd field + else: + node_ids.append(line) + + matrix = sparse_matrix.toarray() if full else sparse_matrix + return matrix, node_ids + finally: + os.unlink(g_matrix_path) + os.unlink(id_file_path) + + def get_jacobian(self, full: bool = False, form: str = 'R') -> Union[np.ndarray, csr_matrix]: """Get the power flow Jacobian matrix. This method calls the `SaveJacobian` script command to write the Jacobian @@ -125,6 +188,9 @@ def get_jacobian(self, full: bool = False) -> Union[np.ndarray, csr_matrix]: full : bool, optional If True, returns a dense NumPy array. If False (default), returns a SciPy CSR sparse matrix. + form : str, optional + Jacobian coordinate form: 'R' for rectangular, 'P' for polar, + 'DC' for B' matrix. Defaults to 'R'. Returns ------- @@ -140,8 +206,7 @@ def get_jacobian(self, full: bool = False) -> Union[np.ndarray, csr_matrix]: """ jac_file_path, id_file_path = self._make_temp_matrix_files() try: - cmd = f'SaveJacobian("{jac_file_path}","{id_file_path}",M,R);' - self.RunScriptCommand(cmd) + self._run_script("SaveJacobian", f'"{jac_file_path}"', f'"{id_file_path}"', "M", form) with open(jac_file_path, "r") as f: mat_str = f.read() sparse_matrix = self._parse_real_matrix(mat_str, "Jac") @@ -150,6 +215,55 @@ def get_jacobian(self, full: bool = False) -> Union[np.ndarray, csr_matrix]: os.unlink(jac_file_path) os.unlink(id_file_path) + def get_jacobian_with_ids(self, full: bool = False, form: str = 'R'): + """Get the power flow Jacobian matrix along with row/column ID mapping. + + Returns both the Jacobian matrix and a list of identifiers describing + what each row/column represents (equation type and bus number, + e.g. ``'dP 101'``, ``'dQ 102'``). + + Parameters + ---------- + full : bool, optional + If True, returns a dense NumPy array. If False (default), returns a + SciPy CSR sparse matrix. + form : str, optional + Jacobian coordinate form: 'R' for rectangular, 'P' for polar, + 'DC' for B' matrix. Defaults to 'R'. + + Returns + ------- + tuple + A tuple of (jacobian_matrix, row_ids) where: + - jacobian_matrix: The Jacobian as either dense array or sparse CSR matrix + - row_ids: List of strings describing each row/column + """ + jac_file_path, id_file_path = self._make_temp_matrix_files() + try: + self._run_script("SaveJacobian", f'"{jac_file_path}"', f'"{id_file_path}"', "M", form) + + with open(jac_file_path, "r") as f: + mat_str = f.read() + sparse_matrix = self._parse_real_matrix(mat_str, "Jac") + + with open(id_file_path, "r") as f: + id_content = f.read() + + # Jacobian ID file: one label per line, no header. + # Each line is an equation label like "dP 101" or "'dP 101'". + row_ids = [] + for line in id_content.strip().split('\n'): + line = line.strip() + if not line: + continue + row_ids.append(line) + + matrix = sparse_matrix.toarray() if full else sparse_matrix + return matrix, row_ids + finally: + os.unlink(jac_file_path) + os.unlink(id_file_path) + def _make_temp_matrix_files(self): """Internal helper to create temporary files for matrix export. @@ -161,12 +275,8 @@ def _make_temp_matrix_files(self): Tuple[str, str] A tuple containing the paths to the temporary matrix file and ID file. """ - mat_file = tempfile.NamedTemporaryFile(mode="w", suffix=".m", delete=False) - mat_file_path = Path(mat_file.name).as_posix() - mat_file.close() - id_file = tempfile.NamedTemporaryFile(mode="w", delete=False) - id_file_path = Path(id_file.name).as_posix() - id_file.close() + mat_file_path = get_temp_filepath(".m") + id_file_path = get_temp_filepath(".txt") return mat_file_path, id_file_path def _parse_real_matrix(self, mat_str, matrix_name="Jac"): @@ -221,9 +331,9 @@ def SaveJacobian(self, jac_filename: str, jid_filename: str, file_type: str = "M jac_form : str, optional "R" for AC Jacobian in Rectangular coordinates, "P" for Polar, "DC" for B' matrix. Defaults to "R". """ - return self.RunScriptCommand(f'SaveJacobian("{jac_filename}", "{jid_filename}", {file_type}, {jac_form});') + return self._run_script("SaveJacobian", f'"{jac_filename}"', f'"{jid_filename}"', file_type, jac_form) def SaveYbusInMatlabFormat(self, filename: str, include_voltages: bool = False): """Saves the YBus to a file formatted for use with Matlab.""" - iv = "YES" if include_voltages else "NO" - return self.RunScriptCommand(f'SaveYbusInMatlabFormat("{filename}", {iv});') \ No newline at end of file + iv = YesNo.from_bool(include_voltages) + return self._run_script("SaveYbusInMatlabFormat", f'"{filename}"', iv) diff --git a/esapp/saw/modify.py b/esapp/saw/modify.py index 2efacbe8..0fc2164a 100644 --- a/esapp/saw/modify.py +++ b/esapp/saw/modify.py @@ -1,6 +1,13 @@ """Modify Case Objects specific functions.""" from typing import List +from ._enums import ( + YesNo, + format_filter, + format_filter_selected_only, + format_filter_areazone, +) + class ModifyMixin: """Mixin for modifying case objects.""" @@ -20,7 +27,7 @@ def AutoInsertTieLineTransactions(self): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand("AutoInsertTieLineTransactions;") + return self._run_script("AutoInsertTieLineTransactions") def BranchMVALimitReorder(self, filter_name: str = "", limits: List[str] = None): """Modifies MVA limits for branches, allowing reordering or setting specific limits. @@ -47,10 +54,10 @@ def BranchMVALimitReorder(self, filter_name: str = "", limits: List[str] = None) # Pad limits to 15 entries (A through O) while len(limits) < 15: limits.append("") - + filt = f'"{filter_name}"' if filter_name else "" lim_str = ", ".join(limits) - return self.RunScriptCommand(f"BranchMVALimitReorder({filt}, {lim_str});") + return self._run_script("BranchMVALimitReorder", filt, lim_str) def CalculateRXBGFromLengthConfigCondType(self, filter_name: str = ""): """Recalculates R, X, G, B parameters for transmission lines using the TransLineCalc tool. @@ -71,8 +78,8 @@ def CalculateRXBGFromLengthConfigCondType(self, filter_name: str = ""): PowerWorldError If the SimAuto call fails (e.g., TransLineCalc not registered). """ - filt = f'"{filter_name}"' if filter_name and filter_name != "SELECTED" else filter_name - return self.RunScriptCommand(f"CalculateRXBGFromLengthConfigCondType({filt});") + filt = format_filter_selected_only(filter_name) + return self._run_script("CalculateRXBGFromLengthConfigCondType", filt) def ChangeSystemMVABase(self, new_base: float): """Changes the system MVA base. @@ -93,7 +100,7 @@ def ChangeSystemMVABase(self, new_base: float): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f"ChangeSystemMVABase({new_base});") + return self._run_script("ChangeSystemMVABase", new_base) def ClearSmallIslands(self): """Identifies the largest island in the system and de-energizes all other smaller islands. @@ -109,7 +116,7 @@ def ClearSmallIslands(self): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand("ClearSmallIslands;") + return self._run_script("ClearSmallIslands") def CreateLineDeriveExisting( self, from_bus: int, to_bus: int, circuit: str, new_length: float, branch_id: str, existing_length: float = None, zero_g: bool = False @@ -148,10 +155,8 @@ def CreateLineDeriveExisting( If the SimAuto call fails. """ el = str(existing_length) if existing_length is not None else "" - zg = "YES" if zero_g else "NO" - return self.RunScriptCommand( - f'CreateLineDeriveExisting({from_bus}, {to_bus}, "{circuit}", {new_length}, {branch_id}, {el}, {zg});' - ) + zg = YesNo.from_bool(zero_g) + return self._run_script("CreateLineDeriveExisting", from_bus, to_bus, f'"{circuit}"', new_length, branch_id, el, zg) def DirectionsAutoInsert(self, source: str, sink: str, delete_existing: bool = True, use_area_zone_filters: bool = False): """Auto-inserts directions to the case for transfer analysis. @@ -159,9 +164,9 @@ def DirectionsAutoInsert(self, source: str, sink: str, delete_existing: bool = T Parameters ---------- source : str - The source object string (e.g., '[AREA "Top"]', '[BUS 1]'). + The source object type (e.g., 'AREA', 'BUS', 'ZONE'). sink : str - The sink object string (e.g., '[AREA "Bottom"]', '[BUS 2]'). + The sink object type (e.g., 'AREA', 'BUS', 'ZONE'). delete_existing : bool, optional If True, deletes existing directions before inserting new ones. Defaults to True. use_area_zone_filters : bool, optional @@ -176,9 +181,9 @@ def DirectionsAutoInsert(self, source: str, sink: str, delete_existing: bool = T PowerWorldError If the SimAuto call fails. """ - de = "YES" if delete_existing else "NO" - uaz = "YES" if use_area_zone_filters else "NO" - return self.RunScriptCommand(f"DirectionsAutoInsert({source}, {sink}, {de}, {uaz});") + de = YesNo.from_bool(delete_existing) + uaz = YesNo.from_bool(use_area_zone_filters) + return self._run_script("DirectionsAutoInsert", source, sink, de, uaz) def DirectionsAutoInsertReference(self, source_type: str, reference_object: str, delete_existing: bool = True, source_filter: str = "", opposite_direction: bool = False): """Auto-inserts directions from multiple source objects to the same ReferenceObject. @@ -206,10 +211,10 @@ def DirectionsAutoInsertReference(self, source_type: str, reference_object: str, PowerWorldError If the SimAuto call fails. """ - de = "YES" if delete_existing else "NO" + de = YesNo.from_bool(delete_existing) filt = f'"{source_filter}"' if source_filter else '""' - od = "YES" if opposite_direction else "NO" - return self.RunScriptCommand(f'DirectionsAutoInsertReference({source_type}, "{reference_object}", {de}, {filt}, {od});') + od = YesNo.from_bool(opposite_direction) + return self._run_script("DirectionsAutoInsertReference", source_type, f'"{reference_object}"', de, filt, od) def InitializeGenMvarLimits(self): """Initializes all generators to be marked as at Mvar limits or not. @@ -226,7 +231,7 @@ def InitializeGenMvarLimits(self): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand("InitializeGenMvarLimits;") + return self._run_script("InitializeGenMvarLimits") def InjectionGroupsAutoInsert(self): """Inserts injection groups according to the IG_AutoInsert_Options. @@ -242,7 +247,7 @@ def InjectionGroupsAutoInsert(self): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand("InjectionGroupsAutoInsert;") + return self._run_script("InjectionGroupsAutoInsert") def InjectionGroupCreate(self, name: str, object_type: str, initial_value: float, filter_name: str, append: bool = True): """Creates or modifies an injection group. @@ -270,9 +275,9 @@ def InjectionGroupCreate(self, name: str, object_type: str, initial_value: float PowerWorldError If the SimAuto call fails. """ - app = "YES" if append else "NO" - filt = f'"{filter_name}"' - return self.RunScriptCommand(f'InjectionGroupCreate("{name}", {object_type}, {initial_value}, {filt}, {app});') + app = YesNo.from_bool(append) + filt = format_filter(filter_name) + return self._run_script("InjectionGroupCreate", f'"{name}"', object_type, initial_value, filt, app) def InjectionGroupRemoveDuplicates(self, preference_filter: str = ""): """Removes duplicate injection groups. @@ -293,7 +298,7 @@ def InjectionGroupRemoveDuplicates(self, preference_filter: str = ""): If the SimAuto call fails. """ filt = f'"{preference_filter}"' if preference_filter else "" - return self.RunScriptCommand(f'InjectionGroupRemoveDuplicates({filt});') + return self._run_script("InjectionGroupRemoveDuplicates", filt) def InterfacesAutoInsert(self, type_: str, delete_existing: bool = True, use_filters: bool = False, prefix: str = "", limits: str = "AUTO"): """Auto-inserts interfaces based on specified criteria. @@ -323,9 +328,9 @@ def InterfacesAutoInsert(self, type_: str, delete_existing: bool = True, use_fil PowerWorldError If the SimAuto call fails. """ - de = "YES" if delete_existing else "NO" - uf = "YES" if use_filters else "NO" - return self.RunScriptCommand(f'InterfacesAutoInsert({type_}, {de}, {uf}, "{prefix}", {limits});') + de = YesNo.from_bool(delete_existing) + uf = YesNo.from_bool(use_filters) + return self._run_script("InterfacesAutoInsert", type_, de, uf, f'"{prefix}"', limits) def InterfaceAddElementsFromContingency(self, interface_name: str, contingency_name: str): """Adds elements from a contingency to an existing interface. @@ -349,7 +354,7 @@ def InterfaceAddElementsFromContingency(self, interface_name: str, contingency_n PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f'InterfaceAddElementsFromContingency("{interface_name}", "{contingency_name}");') + return self._run_script("InterfaceAddElementsFromContingency", f'"{interface_name}"', f'"{contingency_name}"') def InterfaceFlatten(self, interface_name: str): """Flattens an interface. @@ -371,7 +376,7 @@ def InterfaceFlatten(self, interface_name: str): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f'InterfaceFlatten("{interface_name}");') + return self._run_script("InterfaceFlatten", f'"{interface_name}"') def InterfaceFlattenFilter(self, filter_name: str): """Flattens interfaces that meet a specified filter. @@ -391,7 +396,7 @@ def InterfaceFlattenFilter(self, filter_name: str): If the SimAuto call fails. """ filt = f'"{filter_name}"' if filter_name else "" - return self.RunScriptCommand(f'InterfaceFlattenFilter({filt});') + return self._run_script("InterfaceFlattenFilter", filt) def InterfaceModifyIsolatedElements(self, filter_name: str = ""): """Modifies isolated elements within interfaces. @@ -414,7 +419,7 @@ def InterfaceModifyIsolatedElements(self, filter_name: str = ""): If the SimAuto call fails. """ filt = f'"{filter_name}"' if filter_name else "" - return self.RunScriptCommand(f'InterfaceModifyIsolatedElements({filt});') + return self._run_script("InterfaceModifyIsolatedElements", filt) def InterfaceRemoveDuplicates(self, preference_filter: str = ""): """Removes duplicate interfaces. @@ -435,7 +440,7 @@ def InterfaceRemoveDuplicates(self, preference_filter: str = ""): If the SimAuto call fails. """ filt = f'"{preference_filter}"' if preference_filter else "" - return self.RunScriptCommand(f'InterfaceRemoveDuplicates({filt});') + return self._run_script("InterfaceRemoveDuplicates", filt) def InterfaceCreate(self, name: str, delete_existing: bool, object_type: str, filter_name: str): """Creates or modifies an interface with elements of a single object type. @@ -460,8 +465,8 @@ def InterfaceCreate(self, name: str, delete_existing: bool, object_type: str, fi PowerWorldError If the SimAuto call fails. """ - de = "YES" if delete_existing else "NO" - return self.RunScriptCommand(f'InterfaceCreate("{name}", {de}, {object_type}, "{filter_name}");') + de = YesNo.from_bool(delete_existing) + return self._run_script("InterfaceCreate", f'"{name}"', de, object_type, f'"{filter_name}"') def MergeBuses(self, element: str, filter_name: str = ""): """Merges buses based on specified criteria. @@ -482,8 +487,8 @@ def MergeBuses(self, element: str, filter_name: str = ""): PowerWorldError If the SimAuto call fails. """ - filt = f'"{filter_name}"' if filter_name and filter_name not in ["SELECTED", "AREAZONE"] else filter_name - return self.RunScriptCommand(f"MergeBuses({element}, {filt});") + filt = format_filter_areazone(filter_name) + return self._run_script("MergeBuses", element, filt) def MergeLineTerminals(self, filter_name: str = "SELECTED"): """Merges line terminals. @@ -504,8 +509,8 @@ def MergeLineTerminals(self, filter_name: str = "SELECTED"): PowerWorldError If the SimAuto call fails. """ - filt = f'"{filter_name}"' if filter_name and filter_name != "SELECTED" else filter_name - return self.RunScriptCommand(f"MergeLineTerminals({filt});") + filt = format_filter_selected_only(filter_name) + return self._run_script("MergeLineTerminals", filt) def MergeMSLineSections(self, filter_name: str = "SELECTED"): """Eliminates multi-section line records by merging them into single lines. @@ -524,8 +529,8 @@ def MergeMSLineSections(self, filter_name: str = "SELECTED"): PowerWorldError If the SimAuto call fails. """ - filt = f'"{filter_name}"' if filter_name and filter_name != "SELECTED" else filter_name - return self.RunScriptCommand(f"MergeMSLineSections({filt});") + filt = format_filter_selected_only(filter_name) + return self._run_script("MergeMSLineSections", filt) def Move(self, element_a: str, destination: str, how_much: float = 100.0, abort_on_error: bool = True): """Moves a generator, load, transmission line, or switched shunt. @@ -553,8 +558,8 @@ def Move(self, element_a: str, destination: str, how_much: float = 100.0, abort_ PowerWorldError If the SimAuto call fails. """ - abort = "YES" if abort_on_error else "NO" - return self.RunScriptCommand(f"Move({element_a}, {destination}, {how_much}, {abort});") + abort = YesNo.from_bool(abort_on_error) + return self._run_script("Move", element_a, destination, how_much, abort) def ReassignIDs(self, object_type: str, field: str, filter_name: str = "", use_right: bool = False): """Sets IDs of specified objects to the first/last two characters of a specified field. @@ -582,9 +587,9 @@ def ReassignIDs(self, object_type: str, field: str, filter_name: str = "", use_r PowerWorldError If the SimAuto call fails. """ - ur = "YES" if use_right else "NO" - filt = f'"{filter_name}"' if filter_name and filter_name not in ["SELECTED", "AREAZONE", "ALL"] else filter_name - return self.RunScriptCommand(f"ReassignIDs({object_type}, {field}, {filt}, {ur});") + ur = YesNo.from_bool(use_right) + filt = format_filter(filter_name) + return self._run_script("ReassignIDs", object_type, field, filt, ur) def Remove3WXformerContainer(self, filter_name: str = ""): """Deletes three-winding transformer container objects, leaving their internal two-winding transformers. @@ -603,8 +608,8 @@ def Remove3WXformerContainer(self, filter_name: str = ""): PowerWorldError If the SimAuto call fails. """ - filt = f'"{filter_name}"' if filter_name and filter_name not in ["SELECTED", "AREAZONE", "ALL"] else filter_name - return self.RunScriptCommand(f"Remove3WXformerContainer({filt});") + filt = format_filter(filter_name) + return self._run_script("Remove3WXformerContainer", filt) def RenameInjectionGroup(self, old_name: str, new_name: str): """Renames an injection group. @@ -625,7 +630,7 @@ def RenameInjectionGroup(self, old_name: str, new_name: str): PowerWorldError If the SimAuto call fails (e.g., group not found, new name already exists). """ - return self.RunScriptCommand(f'RenameInjectionGroup("{old_name}", "{new_name}");') + return self._run_script("RenameInjectionGroup", f'"{old_name}"', f'"{new_name}"') def RotateBusAnglesInIsland(self, bus_key: str, value: float): """Rotates bus angles in an island by a specified value. @@ -649,7 +654,7 @@ def RotateBusAnglesInIsland(self, bus_key: str, value: float): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f"RotateBusAnglesInIsland({bus_key}, {value});") + return self._run_script("RotateBusAnglesInIsland", bus_key, value) def SetGenPMaxFromReactiveCapabilityCurve(self, filter_name: str = ""): """Changes generator maximum MW output (PMax) based on its reactive capability curve. @@ -668,8 +673,8 @@ def SetGenPMaxFromReactiveCapabilityCurve(self, filter_name: str = ""): PowerWorldError If the SimAuto call fails. """ - filt = f'"{filter_name}"' if filter_name and filter_name not in ["SELECTED", "AREAZONE"] else filter_name - return self.RunScriptCommand(f"SetGenPMaxFromReactiveCapabilityCurve({filt});") + filt = format_filter_areazone(filter_name) + return self._run_script("SetGenPMaxFromReactiveCapabilityCurve", filt) def SetParticipationFactors(self, method: str, constant_value: float, object_str: str): """Modifies generator participation factors. @@ -695,7 +700,7 @@ def SetParticipationFactors(self, method: str, constant_value: float, object_str PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f"SetParticipationFactors({method}, {constant_value}, {object_str});") + return self._run_script("SetParticipationFactors", method, constant_value, object_str) def SetScheduledVoltageForABus(self, bus_id: str, voltage: float): """Sets the stored scheduled voltage for a specific bus. @@ -716,7 +721,7 @@ def SetScheduledVoltageForABus(self, bus_id: str, voltage: float): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f"SetScheduledVoltageForABus({bus_id}, {voltage});") + return self._run_script("SetScheduledVoltageForABus", bus_id, voltage) def SetInterfaceLimitToMonitoredElementLimitSum(self, filter_name: str = "ALL"): """Sets interface limits to the sum of its monitored element limits. @@ -738,8 +743,8 @@ def SetInterfaceLimitToMonitoredElementLimitSum(self, filter_name: str = "ALL"): PowerWorldError If the SimAuto call fails. """ - filt = f'"{filter_name}"' if filter_name and filter_name not in ["SELECTED", "AREAZONE", "ALL"] else filter_name - return self.RunScriptCommand(f"SetInterfaceLimitToMonitoredElementLimitSum({filt});") + filt = format_filter(filter_name) + return self._run_script("SetInterfaceLimitToMonitoredElementLimitSum", filt) def SplitBus( self, @@ -776,11 +781,10 @@ def SplitBus( PowerWorldError If the SimAuto call fails. """ - tie = "YES" if insert_tie else "NO" - open_line = "YES" if line_open else "NO" - return self.RunScriptCommand( - f'SplitBus({element}, {new_bus_number}, {tie}, {open_line}, "{branch_device_type}");' - ) + tie = YesNo.from_bool(insert_tie) + open_line = YesNo.from_bool(line_open) + new_bus_number = int(new_bus_number.iloc[0]) if hasattr(new_bus_number, 'iloc') else int(new_bus_number) + return self._run_script("SplitBus", element, new_bus_number, tie, open_line, f'"{branch_device_type}"') def SuperAreaAddAreas(self, name: str, filter_name: str): """Adds areas to a Super Area. @@ -803,8 +807,8 @@ def SuperAreaAddAreas(self, name: str, filter_name: str): PowerWorldError If the SimAuto call fails. """ - filt = f'"{filter_name}"' if filter_name and filter_name not in ["SELECTED", "AREAZONE", "ALL"] else filter_name - return self.RunScriptCommand(f'SuperAreaAddAreas("{name}", {filt});') + filt = format_filter(filter_name) + return self._run_script("SuperAreaAddAreas", f'"{name}"', filt) def SuperAreaRemoveAreas(self, name: str, filter_name: str): """Removes areas from a Super Area. @@ -825,8 +829,8 @@ def SuperAreaRemoveAreas(self, name: str, filter_name: str): PowerWorldError If the SimAuto call fails. """ - filt = f'"{filter_name}"' if filter_name and filter_name not in ["SELECTED", "AREAZONE", "ALL"] else filter_name - return self.RunScriptCommand(f'SuperAreaRemoveAreas("{name}", {filt});') + filt = format_filter(filter_name) + return self._run_script("SuperAreaRemoveAreas", f'"{name}"', filt) def TapTransmissionLine( self, @@ -845,7 +849,7 @@ def TapTransmissionLine( Parameters ---------- element : str - The transmission line identifier string (e.g., '[BRANCH 1 2 1]'). + The transmission line identifier string (e.g., ``[BRANCH 1 2 1]``). pos_along_line : float The position along the line (0-100%) where the tap is made. new_bus_number : int @@ -870,8 +874,7 @@ def TapTransmissionLine( PowerWorldError If the SimAuto call fails. """ - ms = "YES" if treat_as_ms_line else "NO" - uo = "YES" if update_onelines else "NO" - return self.RunScriptCommand( - f'TapTransmissionLine({element}, {pos_along_line}, {new_bus_number}, {shunt_model}, {ms}, {uo}, "{new_bus_name}");' - ) \ No newline at end of file + ms = YesNo.from_bool(treat_as_ms_line) + uo = YesNo.from_bool(update_onelines) + new_bus_number = int(new_bus_number.iloc[0]) if hasattr(new_bus_number, 'iloc') else int(new_bus_number) + return self._run_script("TapTransmissionLine", element, pos_along_line, new_bus_number, shunt_model, ms, uo, new_bus_name) diff --git a/esapp/saw/oneline.py b/esapp/saw/oneline.py deleted file mode 100644 index 135430db..00000000 --- a/esapp/saw/oneline.py +++ /dev/null @@ -1,302 +0,0 @@ -"""Oneline diagram specific functions.""" - - -class OnelineMixin: - """Mixin for oneline diagram functions.""" - - def OpenOneLine( - self, - filename: str, - view: str = "", - full_screen: str = "NO", - show_full: str = "NO", - link_method: str = "LABELS", - left: float = 0.0, - top: float = 0.0, - width: float = 0.0, - height: float = 0.0, - ) -> None: - """ - Open a oneline diagram. - Note: view needs to be quoted if not empty. - - Parameters - ---------- - filename : str - The path to the oneline diagram file (.axd). - view : str, optional - The name of a specific view within the oneline diagram to open. Defaults to "". - full_screen : str, optional - "YES" or "NO" to open in full screen. Defaults to "NO". - show_full : str, optional - "YES" or "NO" to show the full diagram. Defaults to "NO". - link_method : str, optional - Method for linking objects ("LABELS", "NUMBERS"). Defaults to "LABELS". - left : float, optional - Left coordinate for window placement. Defaults to 0.0. - top : float, optional - Top coordinate for window placement. Defaults to 0.0. - width : float, optional - Width of the window. Defaults to 0.0. - height : float, optional - Height of the window. Defaults to 0.0. - - Returns - ------- - None - - Raises - ------ - PowerWorldError - If the SimAuto call fails (e.g., file not found). - """ - view_str = f'"{view}"' if view else '""' - script = ( - f'OpenOneline("{filename}", {view_str}, {full_screen}, {show_full}, ' - f"{link_method}, {left}, {top}, {width}, {height})" - ) - return self.RunScriptCommand(script) - - def CloseOneline(self, OnelineName: str = "") -> None: - """Closes an open oneline diagram. - - Parameters - ---------- - OnelineName : str, optional - The name of the oneline diagram to close. If empty, closes the active oneline. - Defaults to "". - - Returns - ------- - None - - Raises - ------ - PowerWorldError - If the SimAuto call fails. - """ - script = f'CloseOneline("{OnelineName}")' - return self.RunScriptCommand(script) - - def SaveOneline(self, filename: str, oneline_name: str, save_file_type: str = "PWB"): - """Saves an open oneline diagram to a file. - - Parameters - ---------- - filename : str - The path to the file where the oneline diagram will be saved. - oneline_name : str - The name of the oneline diagram to save. - save_file_type : str, optional - The file type to save as (e.g., "PWB", "AXD"). Defaults to "PWB". - - Returns - ------- - None - - Raises - ------ - PowerWorldError - If the SimAuto call fails. - """ - return self.RunScriptCommand(f'SaveOneline("{filename}", "{oneline_name}", {save_file_type});') - - def ExportOneline(self, filename: str, oneline_name: str, image_type: str, view: str = "", full_screen: str = "NO", show_full: str = "NO"): - """Exports an image of the open oneline diagram. - - Parameters - ---------- - filename : str - The path to the output image file. - oneline_name : str - The name of the oneline diagram to export. - image_type : str - The image file type (e.g., "JPG", "PNG", "BMP"). - view : str, optional - The name of a specific view within the oneline diagram to export. Defaults to "". - full_screen : str, optional - "YES" or "NO" to export in full screen. Defaults to "NO". - show_full : str, optional - "YES" or "NO" to show the full diagram in the export. Defaults to "NO". - - Returns - ------- - None - - Raises - ------ - PowerWorldError - If the SimAuto call fails. - """ - return self.RunScriptCommand(f'ExportOneline("{filename}", "{oneline_name}", {image_type}, "{view}", {full_screen}, {show_full});') - - def ExportBusView(self, filename: str, bus_key: str, image_type: str, width: int, height: int, export_options: list = None): - """Exports an image of a bus view oneline diagram. - - Parameters - ---------- - filename : str - The path to the output image file. - bus_key : str - The key of the bus for which to export the view (e.g., '[BUS 1]'). - image_type : str - The image file type (e.g., "JPG", "PNG", "BMP"). - width : int - The width of the exported image in pixels. - height : int - The height of the exported image in pixels. - export_options : List[Any], optional - A list of additional export options. Defaults to None. - - Returns - ------- - None - - Raises - ------ - PowerWorldError - If the SimAuto call fails. - """ - opts = "" - if export_options: - opts = ", [" + ", ".join([str(o) for o in export_options]) + "]" - return self.RunScriptCommand(f'ExportBusView("{filename}", "{bus_key}", {image_type}, {width}, {height}{opts});') - - def ExportOnelineAsShapeFile(self, filename: str, oneline_name: str, description_name: str, use_lon_lat: bool = True, point_location: str = "center"): - """Saves an open oneline diagram to a shapefile. - - Parameters - ---------- - filename : str - The path to the output shapefile. - oneline_name : str - The name of the oneline diagram to export. - description_name : str - A description name for the shapefile. - use_lon_lat : bool, optional - If True, uses longitude and latitude for point locations. Defaults to True. - point_location : str, optional - Specifies the point location ("center", "bus", "gen", etc.). Defaults to "center". - - Returns - ------- - None - - Raises - ------ - PowerWorldError - If the SimAuto call fails. - """ - ull = "YES" if use_lon_lat else "NO" - return self.RunScriptCommand(f'ExportOnelineAsShapeFile("{filename}", "{oneline_name}", "{description_name}", {ull}, {point_location});') - - def PanAndZoomToObject(self, object_id: str, display_object_type: str = "", do_zoom: bool = True): - """Pans to and optionally zooms in on a display object on the active oneline diagram. - - Parameters - ---------- - object_id : str - The ID of the object to pan/zoom to (e.g., '[BUS 1]', '[GEN 2]'). - display_object_type : str, optional - The type of display object (e.g., "Bus", "Gen"). Defaults to "". - do_zoom : bool, optional - If True, also zooms in on the object. Defaults to True. - - Returns - ------- - None - - Raises - ------ - PowerWorldError - If the SimAuto call fails. - """ - dz = "YES" if do_zoom else "NO" - return self.RunScriptCommand(f'PanAndZoomToObject("{object_id}", "{display_object_type}", {dz});') - - def OpenBusView(self, bus_key: str, force_new_window: bool = False): - """Opens the Bus View to a particular bus. - - Parameters - ---------- - bus_key : str - The key of the bus for which to open the view (e.g., '[BUS 1]'). - force_new_window : bool, optional - If True, forces the view to open in a new window. Defaults to False. - - Returns - ------- - None - - Raises - ------ - PowerWorldError - If the SimAuto call fails. - """ - fnw = "YES" if force_new_window else "NO" - return self.RunScriptCommand(f'OpenBusView("{bus_key}", {fnw});') - - def OpenSubView(self, substation_key: str, force_new_window: bool = False): - """Opens the Substation View to a particular substation. - - Parameters - ---------- - substation_key : str - The key of the substation for which to open the view (e.g., '[SUB 1]'). - force_new_window : bool, optional - If True, forces the view to open in a new window. Defaults to False. - - Returns - ------- - None - - Raises - ------ - PowerWorldError - If the SimAuto call fails. - """ - fnw = "YES" if force_new_window else "NO" - return self.RunScriptCommand(f'OpenSubView("{substation_key}", {fnw});') - - def LoadAXD(self, filename: str, oneline_name: str, create_if_not_found: bool = False): - """Applies a display auxiliary file (.axd) to an open oneline diagram. - - This can be used to load graphical elements or display settings. - - Parameters - ---------- - filename : str - The path to the display auxiliary file. - oneline_name : str - The name of the target oneline diagram. - create_if_not_found : bool, optional - If True, creates the oneline diagram if it does not exist. Defaults to False. - - Returns - ------- - None - - Raises - ------ - PowerWorldError - If the SimAuto call fails. - """ - c = "YES" if create_if_not_found else "NO" - return self.RunScriptCommand(f'LoadAXD("{filename}", "{oneline_name}", {c});') - - def RelinkAllOpenOnelines(self): - """Attempts to relink all objects on all open oneline diagrams. - - This is useful if objects have been renumbered or modified in the case - and their graphical representations need to be updated. - - Returns - ------- - None - - Raises - ------ - PowerWorldError - If the SimAuto call fails. - """ - return self.RunScriptCommand("RelinkAllOpenOnelines;") \ No newline at end of file diff --git a/esapp/saw/opf.py b/esapp/saw/opf.py index 18d52d32..b2883a54 100644 --- a/esapp/saw/opf.py +++ b/esapp/saw/opf.py @@ -1,6 +1,9 @@ """Optimal Power Flow (OPF) specific functions.""" +from esapp.saw._enums import YesNo + + class OPFMixin: """Mixin for OPF analysis functions.""" @@ -30,9 +33,9 @@ def SolvePrimalLP(self, on_success_aux: str = "", on_fail_aux: str = "", create_ PowerWorldError If the SimAuto call fails or the OPF does not converge. """ - c1 = "YES" if create_if_not_found1 else "NO" - c2 = "YES" if create_if_not_found2 else "NO" - return self.RunScriptCommand(f'SolvePrimalLP("{on_success_aux}", "{on_fail_aux}", {c1}, {c2});') + c1 = YesNo.from_bool(create_if_not_found1) + c2 = YesNo.from_bool(create_if_not_found2) + return self._run_script("SolvePrimalLP", f'"{on_success_aux}"', f'"{on_fail_aux}"', c1, c2) def InitializePrimalLP(self, on_success_aux: str = "", on_fail_aux: str = "", create_if_not_found1: bool = False, create_if_not_found2: bool = False): """Clears all structures and results of previous primal LP OPF solutions. @@ -55,9 +58,9 @@ def InitializePrimalLP(self, on_success_aux: str = "", on_fail_aux: str = "", cr PowerWorldError If the SimAuto call fails. """ - c1 = "YES" if create_if_not_found1 else "NO" - c2 = "YES" if create_if_not_found2 else "NO" - return self.RunScriptCommand(f'InitializePrimalLP("{on_success_aux}", "{on_fail_aux}", {c1}, {c2});') + c1 = YesNo.from_bool(create_if_not_found1) + c2 = YesNo.from_bool(create_if_not_found2) + return self._run_script("InitializePrimalLP", f'"{on_success_aux}"', f'"{on_fail_aux}"', c1, c2) def SolveSinglePrimalLPOuterLoop(self, on_success_aux: str = "", on_fail_aux: str = "", create_if_not_found1: bool = False, create_if_not_found2: bool = False): """Performs a single optimization iteration of LP OPF. @@ -80,9 +83,9 @@ def SolveSinglePrimalLPOuterLoop(self, on_success_aux: str = "", on_fail_aux: st PowerWorldError If the SimAuto call fails. """ - c1 = "YES" if create_if_not_found1 else "NO" - c2 = "YES" if create_if_not_found2 else "NO" - return self.RunScriptCommand(f'SolveSinglePrimalLPOuterLoop("{on_success_aux}", "{on_fail_aux}", {c1}, {c2});') + c1 = YesNo.from_bool(create_if_not_found1) + c2 = YesNo.from_bool(create_if_not_found2) + return self._run_script("SolveSinglePrimalLPOuterLoop", f'"{on_success_aux}"', f'"{on_fail_aux}"', c1, c2) def SolveFullSCOPF(self, bc_method: str = "OPF", on_success_aux: str = "", on_fail_aux: str = "", create_if_not_found1: bool = False, create_if_not_found2: bool = False): """Performs a full Security Constrained Optimal Power Flow (SCOPF). @@ -108,9 +111,9 @@ def SolveFullSCOPF(self, bc_method: str = "OPF", on_success_aux: str = "", on_fa PowerWorldError If the SimAuto call fails or the SCOPF does not converge. """ - c1 = "YES" if create_if_not_found1 else "NO" - c2 = "YES" if create_if_not_found2 else "NO" - return self.RunScriptCommand(f'SolveFullSCOPF({bc_method}, "{on_success_aux}", "{on_fail_aux}", {c1}, {c2});') + c1 = YesNo.from_bool(create_if_not_found1) + c2 = YesNo.from_bool(create_if_not_found2) + return self._run_script("SolveFullSCOPF", bc_method, f'"{on_success_aux}"', f'"{on_fail_aux}"', c1, c2) def OPFWriteResultsAndOptions(self, filename: str): """Writes out all information related to OPF analysis to an auxiliary file. @@ -129,4 +132,4 @@ def OPFWriteResultsAndOptions(self, filename: str): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f'OPFWriteResultsAndOptions("{filename}");') + return self._run_script("OPFWriteResultsAndOptions", f'"{filename}"') diff --git a/esapp/saw/powerflow.py b/esapp/saw/powerflow.py index 90a785d8..427ede95 100644 --- a/esapp/saw/powerflow.py +++ b/esapp/saw/powerflow.py @@ -2,70 +2,71 @@ import pandas as pd from ._exceptions import PowerWorldError +from ._enums import YesNo, SolverMethod, format_filter class PowerflowMixin: - def SolvePowerFlow(self, SolMethod: str = "RECTNEWT") -> None: - """Solves the power flow using the specified solution method. + def SolvePowerFlow(self, SolMethod: Union[SolverMethod, str] = SolverMethod.RECTNEWT) -> None: + """Performs a single power flow solution. + + If the DC method is selected, the case is switched to DC power flow mode. + If one of the other AC methods is selected, the case is switched to AC power + flow mode. It may be difficult to solve a case with an AC power flow method + once the case has been switched to DC power flow mode. Parameters ---------- - SolMethod : str, optional - The solution method to use. Valid options include "RECTNEWT" (Rectangular Newton-Raphson), - "POLARNEWT" (Polar Newton-Raphson), "GAUSSSEIDEL" (Gauss-Seidel), "FASTDEC" (Fast Decoupled), - "ROBUST", and "DC". Defaults to "RECTNEWT". - + SolMethod : Union[SolverMethod, str], optional + The solution method to use for the power flow calculation: + + - ``RECTNEWT``: Rectangular Newton-Raphson (default) + - ``POLARNEWT``: Polar Newton-Raphson + - ``GAUSSSEIDEL``: Gauss-Seidel + - ``FASTDEC``: Fast Decoupled + - ``ROBUST``: Attempts the robust solution process + - ``DC``: DC power flow (switches case to DC mode) + Returns ------- None - + Raises ------ PowerWorldError If the SimAuto call fails or the power flow does not converge. """ - script_command = f"SolvePowerFlow({SolMethod.upper()})" - return self.RunScriptCommand(script_command) + method = SolMethod.value if isinstance(SolMethod, SolverMethod) else SolMethod.upper() + return self._run_script("SolvePowerFlow", method) def ClearPowerFlowSolutionAidValues(self): - """Clear power flow solution aid values. - - This is a wrapper for the ``ClearPowerFlowSolutionAidValues`` - script command. It is useful for clearing values set by - features like "Find" that can interfere with subsequent - analyses. + """Clears internal power flow solution aid values. + + PowerWorld Simulator maintains several internal flags that track which + branches are closed or opened, as well as information to help estimate + the generation change needed after making changes to load or generation. + This information relates to angle smoothing and generator MW estimation + features of the power flow solution. + + Typically, this information aids in getting successful power flow solutions. + However, in some circumstances you may be using an AUX file to edit + information you know is good and would not want PowerWorld to modify + the initial bus voltage and angle nor the generator MW outputs before + a solution is attempted. Call this command to clear all internally stored + information so PowerWorld does not perform these pre-processing steps. """ - self.RunScriptCommand("ClearPowerFlowSolutionAidValues;") + self._run_script("ClearPowerFlowSolutionAidValues") def ResetToFlatStart(self): """Resets all bus voltages to 1.0 per unit and angles to 0. This is a wrapper for the ``ResetToFlatStart`` script command. """ - self.RunScriptCommand("ResetToFlatStart();") - - def SolvePowerFlowWithRetry(self, SolMethod: str = "RECTNEWT") -> None: - """Run the SolvePowerFlow command, with a retry mechanism. - - If the first attempt to solve the power flow fails, this method - will reset the case to a flat start and try one additional time. - - Parameters - ---------- - SolMethod : str, optional - The solution method to use (e.g., "RECTNEWT"). Defaults to "RECTNEWT". - """ - try: - self.SolvePowerFlow(SolMethod) - except PowerWorldError: - self.log.warning("Power flow failed, resetting to flat start and retrying.") - self.ResetToFlatStart() - self.SolvePowerFlow(SolMethod) + self._run_script("ResetToFlatStart") def SetMVATolerance(self, tol: float = 0.1) -> None: """Sets the MVA Tolerance for Newton-Raphson convergence. - + Parameters ---------- tol : float, optional @@ -75,30 +76,30 @@ def SetMVATolerance(self, tol: float = 0.1) -> None: def SetDoOneIteration(self, enable: bool = True) -> None: """Sets the 'Do One Iteration' power flow option. - + Parameters ---------- enable : bool, optional If True, power flow will only perform one iteration. Defaults to True. """ - value = "YES" if enable else "NO" + value = YesNo.from_bool(enable) self.ChangeParametersSingleElement("Sim_Solution_Options", ["DoOneIteration"], [value]) def SetInnerLoopCheckMVars(self, enable: bool = True) -> None: """Sets the 'Check Mvar Limits Immediately' power flow option. - + Parameters ---------- enable : bool, optional If True, the inner loop of the power flow will check Mvar limits before proceeding to the outer loop. Defaults to True. """ - value = "YES" if enable else "NO" + value = YesNo.from_bool(enable) self.ChangeParametersSingleElement("Sim_Solution_Options", ["ChkVars"], [value]) def GetMinPUVoltage(self) -> float: """Gets the minimum per-unit voltage magnitude in the case. - + Returns ------- float @@ -108,105 +109,284 @@ def GetMinPUVoltage(self) -> float: return float(s.iloc[0]) def UpdateIslandsAndBusStatus(self): - """Updates islands and bus status without requiring a power flow solution.""" - return self.RunScriptCommand("UpdateIslandsAndBusStatus;") + """Updates islands and bus status without requiring a power flow solution. + + Changes to branch and generator status impact islands and whether or not + buses are connected. Islands and bus status are always updated at the + beginning of a power flow solution if necessary, but this command makes + it convenient to update this information without requiring a power flow + solution. + """ + return self._run_script("UpdateIslandsAndBusStatus") def ZeroOutMismatches(self, object_type: str = "BUSSHUNT"): - """Forces mismatches to zero by changing bus shunts or loads.""" - return self.RunScriptCommand(f"ZeroOutMismatches({object_type});") + """Forces mismatches to zero by changing bus shunts or loads. + + Bus shunts or loads are changed at each bus that has a mismatch greater + than the MVA convergence tolerance so that the mismatch at that bus is + forced to zero. + + Parameters + ---------- + object_type : str, optional + How to adjust the mismatch: + + - ``BUSSHUNT``: Adjust Bus Shunt fields at each bus (default) + - ``LOAD``: Add a new load at each bus with mismatch (ID starting with Q1) + """ + return self._run_script("ZeroOutMismatches", object_type) def ConditionVoltagePockets(self, voltage_threshold: float, angle_threshold: float, filter_name: str = "ALL"): - """Finds pockets of buses that may have bad initial voltage estimates.""" - filt = f'"{filter_name}"' if filter_name and filter_name not in ["SELECTED", "AREAZONE", "ALL"] else filter_name - return self.RunScriptCommand( - f"ConditionVoltagePockets({voltage_threshold}, {angle_threshold}, {filt});" - ) + """Finds pockets of buses with bad initial voltage estimates and conditions them. + + Identifies pockets of buses bounded by branches that meet the condition that + the absolute value of the voltage difference across the branch is greater than + ``voltage_threshold`` or the absolute value of the angle difference is greater + than ``angle_threshold``. The tool then estimates better voltages for buses + in each pocket using known good values outside the pocket. + + Parameters + ---------- + voltage_threshold : float + Per-unit voltage difference (absolute value) threshold for identifying + branches that bound voltage pockets. + angle_threshold : float + Angle difference in degrees (absolute value) threshold for identifying + branches that bound voltage pockets. + filter_name : str, optional + Filter specifying which branches to check. Defaults to "ALL". + """ + filt = format_filter(filter_name) + return self._run_script("ConditionVoltagePockets", voltage_threshold, angle_threshold, filt) def EstimateVoltages(self, filter_name: str): - """Estimates voltages and angles at buses meeting the filter.""" - filt = f'"{filter_name}"' if filter_name and filter_name not in ["SELECTED", "AREAZONE", "ALL"] else filter_name - return self.RunScriptCommand(f'EstimateVoltages({filt});') + """Estimates voltages and angles at buses meeting the filter. + + Parameters + ---------- + filter_name : str + Filter specifying which buses should have their voltages estimated. + """ + filt = format_filter(filter_name) + return self._run_script("EstimateVoltages", filt) def GenForceLDC_RCC(self, filter_name: str = ""): - """Forces generators onto line drop / reactive current compensation.""" - return self.RunScriptCommand(f'GenForceLDC_RCC("{filter_name}");') + """Forces generators onto line drop / reactive current compensation. + + Parameters + ---------- + filter_name : str, optional + Filter specifying which generators to force. Defaults to all generators. + """ + return self._run_script("GenForceLDC_RCC", f'"{filter_name}"') def SaveGenLimitStatusAction(self, filename: str): - """Saves Mvar information about generators in a text file.""" - return self.RunScriptCommand(f'SaveGenLimitStatusAction("{filename}");') + """Saves Mvar information about generators to a text file. + + Parameters + ---------- + filename : str + Path to the output text file. + """ + return self._run_script("SaveGenLimitStatusAction", f'"{filename}"') def DiffCaseClearBase(self): - """Clears the base case for the difference flows abilities.""" - return self.RunScriptCommand("DiffCaseClearBase;") + """Clears the base case for the difference case comparison abilities of Simulator.""" + return self._run_script("DiffCaseClearBase") def DiffCaseSetAsBase(self): - """Sets the present case as the base case for difference flows.""" - return self.RunScriptCommand("DiffCaseSetAsBase;") + """Sets the present case as the base case for difference case comparison.""" + return self._run_script("DiffCaseSetAsBase") def DiffCaseKeyType(self, key_type: str): - """Changes the key type used when comparing fields.""" - return self.RunScriptCommand(f"DiffCaseKeyType({key_type});") + """Changes the key type used when comparing fields in difference case mode. + + Parameters + ---------- + key_type : str + Key type to use: ``PRIMARY``, ``SECONDARY``, or ``LABEL``. + """ + return self._run_script("DiffCaseKeyType", key_type) def DiffCaseShowPresentAndBase(self, show: bool): """Toggles 'Show Present|Base in Difference and Change Mode'.""" - yn = "YES" if show else "NO" - return self.RunScriptCommand(f"DiffCaseShowPresentAndBase({yn});") + yn = YesNo.from_bool(show) + return self._run_script("DiffCaseShowPresentAndBase", yn) def DiffCaseMode(self, mode: str): - """Changes the mode for difference flows (PRESENT, BASE, DIFFERENCE, CHANGE).""" - return self.RunScriptCommand(f"DiffCaseMode({mode});") + """Changes the mode for difference case comparison. + + Parameters + ---------- + mode : str + Display mode: ``PRESENT``, ``BASE``, ``DIFFERENCE``, or ``CHANGE``. + """ + return self._run_script("DiffCaseMode", mode) def DiffCaseRefresh(self): - """Refreshes the linking between the base case and the present case.""" - return self.RunScriptCommand("DiffCaseRefresh;") + """Refreshes the linking between the base case and the present case. + + Call this before saving data that identifies objects as being added or + removed, especially if any topological differences have been made that + affect the comparison. + """ + return self._run_script("DiffCaseRefresh") def DiffCaseWriteCompleteModel(self, filename: str, append: bool = False, save_added: bool = True, save_removed: bool = True, save_both: bool = True, key_fields: str = "PRIMARY", export_format: str = "", use_area_zone: bool = False, use_data_maintainer: bool = False, assume_base_meet: bool = True, include_clear_pf_aids: bool = True, delete_branches_flip: bool = False): - """Creates an auxiliary file with difference case information.""" - app = "YES" if append else "NO" - sa = "YES" if save_added else "NO" - sr = "YES" if save_removed else "NO" - sb = "YES" if save_both else "NO" - uaz = "YES" if use_area_zone else "NO" - udm = "YES" if use_data_maintainer else "NO" - abm = "YES" if assume_base_meet else "NO" - icp = "YES" if include_clear_pf_aids else "NO" - dbf = "YES" if delete_branches_flip else "NO" - - cmd = f'DiffCaseWriteCompleteModel("{filename}", {app}, {sa}, {sr}, {sb}, {key_fields}, "{export_format}", {uaz}, {udm}, {abm}, {icp}, {dbf});' - return self.RunScriptCommand(cmd) - - def DiffCaseWriteBothEPC(self, filename: str, ge_file_type: str = "GE", use_area_zone: bool = False, base_area_zone_meet: bool = True, append: bool = False, export_format: str = "", use_data_maintainer: bool = False): - """Saves elements in both base and present cases in GE EPC format.""" - uaz = "YES" if use_area_zone else "NO" - baz = "YES" if base_area_zone_meet else "NO" - app = "YES" if append else "NO" - udm = "YES" if use_data_maintainer else "NO" - return self.RunScriptCommand(f'DiffCaseWriteBothEPC("{filename}", {ge_file_type}, {uaz}, {baz}, {app}, "{export_format}", {udm});') - - def DiffCaseWriteNewEPC(self, filename: str, ge_file_type: str = "GE", use_area_zone: bool = False, base_area_zone_meet: bool = True, append: bool = False, use_data_maintainer: bool = False): - """Saves new elements in GE EPC format.""" - uaz = "YES" if use_area_zone else "NO" - baz = "YES" if base_area_zone_meet else "NO" - app = "YES" if append else "NO" - udm = "YES" if use_data_maintainer else "NO" - return self.RunScriptCommand(f'DiffCaseWriteNewEPC("{filename}", {ge_file_type}, {uaz}, {baz}, {app}, {udm});') - - def DiffCaseWriteRemovedEPC(self, filename: str, ge_file_type: str = "GE", use_area_zone: bool = False, base_area_zone_meet: bool = True, append: bool = False, use_data_maintainer: bool = False): - """Saves removed elements in GE EPC format.""" - uaz = "YES" if use_area_zone else "NO" - baz = "YES" if base_area_zone_meet else "NO" - app = "YES" if append else "NO" - udm = "YES" if use_data_maintainer else "NO" - return self.RunScriptCommand(f'DiffCaseWriteRemovedEPC("{filename}", {ge_file_type}, {uaz}, {baz}, {app}, {udm});') + """Creates an auxiliary file with difference case comparison information. + + Creates an auxiliary file containing information about objects that have been + added or removed when comparing the present case to the base case. Fields + that have changed for objects that exist in both cases can also be written. + This auxiliary file can then be used to apply these same changes to other cases. + + Parameters + ---------- + filename : str + Name of the auxiliary file to create. + append : bool, optional + If True, append to existing file. Defaults to False. + save_added : bool, optional + If True, save added objects to the file. Defaults to True. + save_removed : bool, optional + If True, save removed objects to the file. Defaults to True. + save_both : bool, optional + If True, save changed fields for objects in both cases. Defaults to True. + key_fields : str, optional + Key field identifiers to use: ``PRIMARY`` or ``SECONDARY``. Defaults to "PRIMARY". + export_format : str, optional + Name of Auxiliary File Export Format Description to use. Defaults to "". + use_area_zone : bool, optional + If True, use Area/Zone/Owner filter for including objects. Defaults to False. + use_data_maintainer : bool, optional + If True, use Data Maintainer filter. Defaults to False. + assume_base_meet : bool, optional + If True, assume base case areas/zones/owners meet filters. Defaults to True. + include_clear_pf_aids : bool, optional + If True, include ClearPowerFlowSolutionAidValues command. Defaults to True. + delete_branches_flip : bool, optional + If True, treat branches with flipped bus order as removed and added. Defaults to False. + """ + app = YesNo.from_bool(append) + sa = YesNo.from_bool(save_added) + sr = YesNo.from_bool(save_removed) + sb = YesNo.from_bool(save_both) + uaz = YesNo.from_bool(use_area_zone) + udm = YesNo.from_bool(use_data_maintainer) + abm = YesNo.from_bool(assume_base_meet) + icp = YesNo.from_bool(include_clear_pf_aids) + dbf = YesNo.from_bool(delete_branches_flip) + + return self._run_script("DiffCaseWriteCompleteModel", f'"{filename}"', app, sa, sr, sb, key_fields, f'"{export_format}"', uaz, udm, abm, icp, dbf) + + def DiffCaseWriteBothEPC(self, filename: str, ge_file_type: str = "GE19", use_area_zone: bool = False, base_area_zone_meet: bool = True, append: bool = False, export_format: str = "", use_data_maintainer: bool = False): + """Saves elements that exist in both base and present cases in GE EPC format. + + Parameters + ---------- + filename : str + Name of the EPC file to create. + ge_file_type : str, optional + GE EPC file version (e.g., "GE18", "GE19", "PTI33"). Defaults to "GE19". + use_area_zone : bool, optional + If True, use Area/Zone/Owner filter. Defaults to False. + base_area_zone_meet : bool, optional + If True, assume base case meets filters. Defaults to True. + append : bool, optional + If True, append to existing file. Defaults to False. + export_format : str, optional + Export format name. Defaults to "". + use_data_maintainer : bool, optional + If True, use Data Maintainer filter. Defaults to False. + """ + uaz = YesNo.from_bool(use_area_zone) + baz = YesNo.from_bool(base_area_zone_meet) + app = YesNo.from_bool(append) + udm = YesNo.from_bool(use_data_maintainer) + return self._run_script("DiffCaseWriteBothEPC", f'"{filename}"', ge_file_type, uaz, baz, app, f'"{export_format}"', udm) + + def DiffCaseWriteNewEPC(self, filename: str, ge_file_type: str = "GE19", use_area_zone: bool = False, base_area_zone_meet: bool = True, append: bool = False, use_data_maintainer: bool = False): + """Saves elements that are new (added) in GE EPC format. + + Parameters + ---------- + filename : str + Name of the EPC file to create. + ge_file_type : str, optional + GE EPC file version (e.g., "GE18", "GE19", "PTI33"). Defaults to "GE19". + use_area_zone : bool, optional + If True, use Area/Zone/Owner filter. Defaults to False. + base_area_zone_meet : bool, optional + If True, assume base case meets filters. Defaults to True. + append : bool, optional + If True, append to existing file. Defaults to False. + use_data_maintainer : bool, optional + If True, use Data Maintainer filter. Defaults to False. + """ + uaz = YesNo.from_bool(use_area_zone) + baz = YesNo.from_bool(base_area_zone_meet) + app = YesNo.from_bool(append) + udm = YesNo.from_bool(use_data_maintainer) + return self._run_script("DiffCaseWriteNewEPC", f'"{filename}"', ge_file_type, uaz, baz, app, udm) + + def DiffCaseWriteRemovedEPC(self, filename: str, ge_file_type: str = "GE19", use_area_zone: bool = False, base_area_zone_meet: bool = True, append: bool = False, use_data_maintainer: bool = False): + """Saves elements that were removed in GE EPC format. + + Parameters + ---------- + filename : str + Name of the EPC file to create. + ge_file_type : str, optional + GE EPC file version (e.g., "GE18", "GE19", "PTI33"). Defaults to "GE19". + use_area_zone : bool, optional + If True, use Area/Zone/Owner filter. Defaults to False. + base_area_zone_meet : bool, optional + If True, assume base case meets filters. Defaults to True. + append : bool, optional + If True, append to existing file. Defaults to False. + use_data_maintainer : bool, optional + If True, use Data Maintainer filter. Defaults to False. + """ + uaz = YesNo.from_bool(use_area_zone) + baz = YesNo.from_bool(base_area_zone_meet) + app = YesNo.from_bool(append) + udm = YesNo.from_bool(use_data_maintainer) + return self._run_script("DiffCaseWriteRemovedEPC", f'"{filename}"', ge_file_type, uaz, baz, app, udm) def DoCTGAction(self, action: str): - """Applies a contingency action.""" - return self.RunScriptCommand(f'DoCTGAction({action});') + """Applies a contingency action without the full contingency analysis framework. + + Parameters + ---------- + action : str + The contingency action string to execute. + """ + return self._run_script("DoCTGAction", action) def InterfacesCalculatePostCTGMWFlows(self): - """Updates Interface MW Flow fields on Contingent Interfaces.""" - return self.RunScriptCommand("InterfacesCalculatePostCTGMWFlows;") + """Updates Interface MW Flow fields on Contingent Interfaces. + + Calculates the post-contingency MW flows for interfaces that have + contingent elements defined. + """ + return self._run_script("InterfacesCalculatePostCTGMWFlows") def VoltageConditioning(self): - """Perform voltage conditioning based on the Voltage Conditioning tool options.""" - return self.RunScriptCommand("VoltageConditioning;") \ No newline at end of file + """Performs voltage conditioning based on the Voltage Conditioning tool options. + + Uses the configured Voltage Conditioning options to improve initial voltage + estimates throughout the network, which can help power flow convergence. + """ + return self._run_script("VoltageConditioning") + + def SaveState(self) -> None: + """Saves the current state of the PowerWorld case. + + This creates an unnamed snapshot of the case that can be restored later + using `LoadState`. + """ + return self._com_call("SaveState") + + def LoadState(self) -> None: + """Loads the last saved state of the PowerWorld case.""" + return self._com_call("LoadState") diff --git a/esapp/saw/pv.py b/esapp/saw/pv.py index fb650084..fffb93f8 100644 --- a/esapp/saw/pv.py +++ b/esapp/saw/pv.py @@ -1,164 +1,243 @@ """PV (Power-Voltage) Analysis specific functions.""" +from esapp.saw._enums import YesNo + + class PVMixin: """Mixin for PV analysis functions.""" def PVClear(self): """ - Clear all results of the PV study. + Clear all results of the PV (Power-Voltage) study. + + This removes all computed results from a previous PV analysis, + allowing a fresh study to be performed. + + This is a wrapper for the ``PVClear`` script command. Returns ------- str The response from the PowerWorld script command. """ - return self.RunScriptCommand("PVClear;") + return self._run_script("PVClear") - def RunPV(self, source: str, sink: str): + def PVRun(self, source: str, sink: str): """ - Starts a PV analysis. - + Start a PV (Power-Voltage) analysis. + + PV analysis incrementally transfers power from a source to a sink + to determine the system's voltage stability limits. The analysis + increases the transfer until voltage collapse occurs or limits are + reached. + + This is a wrapper for the ``PVRun`` script command. + Parameters ---------- source : str - The source of power (e.g. '[INJECTIONGROUP "Source"]'). + The source of power for the PV study. Must be an injection group + specified as '[INJECTIONGROUP "name"]' or '[INJECTIONGROUP "label"]'. sink : str - The sink of power (e.g. '[INJECTIONGROUP "Sink"]'). + The sink of power for the PV study. Must be an injection group + specified as '[INJECTIONGROUP "name"]' or '[INJECTIONGROUP "label"]'. Returns ------- str The response from the PowerWorld script command. """ - return self.RunScriptCommand(f"PVRun({source}, {sink});") + return self._run_script("PVRun", source, sink) def PVDataWriteOptionsAndResults(self, filename: str, append: bool = True, key_field: str = "PRIMARY"): """ - Writes out all information related to PV analysis. + Write all PV analysis information to an auxiliary file. + + Saves the same information as ``PVWriteResultsAndOptions`` but uses + the concise format for DATA section headers and variable names. Data + is written using DATA sections instead of SUBDATA sections. + + This is a wrapper for the ``PVDataWriteOptionsAndResults`` script command. Parameters ---------- filename : str - The file to write to. + Name of the auxiliary file to save. append : bool, optional - If True, appends to the file. Defaults to True. + If True, appends results to existing file. If False, overwrites + the file. Defaults to True. key_field : str, optional - The key field to use. Defaults to "PRIMARY". + Identifier to use for data. Valid values are "PRIMARY" (bus numbers + and primary key fields), "SECONDARY" (bus name and nominal kV), + or "LABEL" (device labels). Defaults to "PRIMARY". Returns ------- str The response from the PowerWorld script command. """ - app = "YES" if append else "NO" - return self.RunScriptCommand(f'PVDataWriteOptionsAndResults("{filename}", {app}, {key_field});') + app = YesNo.from_bool(append) + return self._run_script("PVDataWriteOptionsAndResults", f'"{filename}"', app, key_field) def PVDestroy(self): """ - Destroy the PV study. + Destroy the PV study and release resources. + + This removes all results and prevents any restoration of the + initial state that is stored with the PV study. Use this when + you are finished with a PV analysis and want to free memory. + + This is a wrapper for the ``PVDestroy`` script command. Returns ------- str The response from the PowerWorld script command. """ - return self.RunScriptCommand("PVDestroy;") + return self._run_script("PVDestroy") def PVQVTrackSingleBusPerSuperBus(self): """ Reduce monitored buses to one per super bus. + If the topology processing add-on is installed, this examines each + monitored value for each bus, determines if that bus is part of a + super bus, and selects monitored buses so that only the pnode is + monitored. This reduces computational overhead for PV/QV studies. + + This is a wrapper for the ``PVQVTrackSingleBusPerSuperBus`` script command. + Returns ------- str The response from the PowerWorld script command. """ - return self.RunScriptCommand("PVQVTrackSingleBusPerSuperBus;") + return self._run_script("PVQVTrackSingleBusPerSuperBus") def PVSetSourceAndSink(self, source: str, sink: str): """ - Specify the source and sink elements. + Specify the source and sink elements for the PV study. + + Sets up the injection groups that define where power will be + incrementally injected (source) and withdrawn (sink) during + the PV analysis. + + This is a wrapper for the ``PVSetSourceAndSink`` script command. Parameters ---------- source : str - The source element. + The source of power for the PV study. Must be an injection group + specified as '[INJECTIONGROUP "name"]' or '[INJECTIONGROUP "label"]'. sink : str - The sink element. + The sink of power for the PV study. Must be an injection group + specified as '[INJECTIONGROUP "name"]' or '[INJECTIONGROUP "label"]'. Returns ------- str The response from the PowerWorld script command. """ - return self.RunScriptCommand(f"PVSetSourceAndSink({source}, {sink});") + return self._run_script("PVSetSourceAndSink", source, sink) def PVStartOver(self): """ - Start over the PV study. + Start over the PV study from the initial state. + + This clears the activity log, clears results, restores the initial + state, sets the current state as the new initial state, and + initializes the step size. Use this to reset a PV study without + destroying it completely. + + This is a wrapper for the ``PVStartOver`` script command. Returns ------- str The response from the PowerWorld script command. """ - return self.RunScriptCommand("PVStartOver;") + return self._run_script("PVStartOver") def PVWriteInadequateVoltages(self, filename: str, append: bool = True, inadequate_type: str = "LOW"): """ - Save PV Inadequate Voltages. + Save PV inadequate voltages to a CSV file. + + Exports buses with voltage violations identified during the PV study + to a CSV file. This helps identify which buses are most vulnerable + to voltage collapse. + + This is a wrapper for the ``PVWriteInadequateVoltages`` script command. Parameters ---------- filename : str - The file to write to. + Name of the CSV file to save. append : bool, optional - If True, appends to the file. Defaults to True. + If True, appends data to existing file. If False, overwrites + the file. Defaults to True. inadequate_type : str, optional - Type of inadequacy ("LOW", "HIGH", "BOTH"). Defaults to "LOW". + Type of inadequate voltages to save. Valid values are "LOW" + (undervoltage), "HIGH" (overvoltage), or "BOTH". Defaults to "LOW". Returns ------- str The response from the PowerWorld script command. """ - app = "YES" if append else "NO" - return self.RunScriptCommand(f'PVWriteInadequateVoltages("{filename}", {app}, {inadequate_type});') + app = YesNo.from_bool(append) + return self._run_script("PVWriteInadequateVoltages", f'"{filename}"', app, inadequate_type) def PVWriteResultsAndOptions(self, filename: str, append: bool = True): """ - Writes out all information related to PV analysis. + Write all PV analysis information to an auxiliary file. + + Exports complete PV analysis data including Contingency Definitions, + Remedial Action Definitions, Solution Options, PV Options, PV results, + ATC Extra Monitors, and any Model Criteria used by the Contingency + and Remedial Action Definitions. + + Dependencies for the PV setup are also included, such as Injection + Groups used as seller/buyer and Interfaces used for interface ramping. + + This is a wrapper for the ``PVWriteResultsAndOptions`` script command. Parameters ---------- filename : str - The file to write to. + Name of the auxiliary file to save. append : bool, optional - If True, appends to the file. Defaults to True. + If True, appends data to existing file. If False, overwrites + the file. Defaults to True. Returns ------- str The response from the PowerWorld script command. """ - app = "YES" if append else "NO" - return self.RunScriptCommand(f'PVWriteResultsAndOptions("{filename}", {app});') + app = YesNo.from_bool(append) + return self._run_script("PVWriteResultsAndOptions", f'"{filename}"', app) def RefineModel(self, object_type: str, filter_name: str, action: str, tolerance: float): """ Refine the system model to fix modeling idiosyncrasies. + This command helps prepare a model for voltage stability analysis + by addressing common modeling issues that may cause numerical + problems or unrealistic results. + + This is a wrapper for the ``RefineModel`` script command. + Parameters ---------- object_type : str - The type of object to refine. + The type of object to refine (e.g., "BUS", "GEN", "LOAD"). filter_name : str - Filter to apply. + Filter name to apply. Empty string means all objects of the type. action : str - Action to perform. + Action to perform on the filtered objects. tolerance : float - Tolerance value. + Tolerance value for the refinement action. Returns ------- @@ -166,4 +245,4 @@ def RefineModel(self, object_type: str, filter_name: str, action: str, tolerance The response from the PowerWorld script command. """ filt = f'"{filter_name}"' if filter_name else "" - return self.RunScriptCommand(f'RefineModel({object_type}, {filt}, {action}, {tolerance});') + return self._run_script("RefineModel", object_type, filt, action, tolerance) diff --git a/esapp/saw/qv.py b/esapp/saw/qv.py index 114e3dac..8843a0a0 100644 --- a/esapp/saw/qv.py +++ b/esapp/saw/qv.py @@ -1,86 +1,118 @@ """QV (Reactive Power-Voltage) Analysis specific functions.""" import os -import tempfile from pathlib import Path import pandas as pd +from esapp.saw._enums import YesNo +from ._helpers import get_temp_filepath + class QVMixin: """Mixin for QV analysis functions.""" def QVDataWriteOptionsAndResults(self, filename: str, append: bool = True, key_field: str = "PRIMARY"): - """Writes out all information related to QV analysis, including options and results. + """ + Write all QV analysis information to an auxiliary file. + + Saves the same information as ``QVWriteResultsAndOptions`` but uses + the concise format for DATA section headers and variable names. Data + is written using DATA sections instead of SUBDATA sections. + + This is a wrapper for the ``QVDataWriteOptionsAndResults`` script command. Parameters ---------- filename : str - The path to the auxiliary file where the QV information will be written. + Name of the auxiliary file to save. append : bool, optional - If True, appends to the file if it exists. If False, overwrites. + If True, appends results to existing file. If False, overwrites. Defaults to True. key_field : str, optional - Identifier to use for the data ("PRIMARY", "SECONDARY", "LABEL"). - Defaults to "PRIMARY". + Identifier to use for data. "PRIMARY" uses bus numbers and primary + key fields. "SECONDARY" uses bus name and nominal kV. "LABEL" uses + device labels. Defaults to "PRIMARY". Returns ------- - None + str + The response from the PowerWorld script command. Raises ------ PowerWorldError If the SimAuto call fails. """ - app = "YES" if append else "NO" - return self.RunScriptCommand(f'QVDataWriteOptionsAndResults("{filename}", {app}, {key_field});') + app = YesNo.from_bool(append) + return self._run_script("QVDataWriteOptionsAndResults", f'"{filename}"', app, key_field) def QVDeleteAllResults(self): - """Deletes all QV results from memory. + """ + Delete all QV results from memory. + + Removes all QV analysis results including QVCurve and + PWQVResultListContainer object types. Use this to free memory + after QV analysis is complete. + + This is a wrapper for the ``QVDeleteAllResults`` script command. Returns ------- - None + str + The response from the PowerWorld script command. Raises ------ PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand("QVDeleteAllResults;") + return self._run_script("QVDeleteAllResults") - def RunQV(self, filename: str = None) -> pd.DataFrame: - """Starts a QV (Reactive Power-Voltage) analysis. + def QVRun(self, filename: str = None, make_base_solvable: bool = True, write_case_after_solve: bool = False) -> pd.DataFrame: + """ + Run a QV (Reactive Power-Voltage) analysis. - This method simulates the system's voltage stability by varying reactive power - and observing voltage response. + Performs a QV study for buses whose QVSELECTED field is set to YES. + QV analysis varies reactive power injection at monitored buses to + determine voltage stability margins. The analysis produces QV curves + showing the relationship between reactive power and voltage. + + This is a wrapper for the ``QVRun`` script command. Parameters ---------- filename : str, optional - Optional path to a CSV file to save results to. If None, a temporary file - is used, and the results are returned as a pandas DataFrame. Defaults to None. + Path to a CSV file to save results. If None, a temporary file is + used and results are returned as a DataFrame. Defaults to None. + make_base_solvable : bool, optional + If True, attempts to fix the base case if it is not solvable + before running the QV analysis. Defaults to True. + write_case_after_solve : bool, optional + If True, writes the case file after each QV solve point. + Defaults to False. Returns ------- pandas.DataFrame or None - If `filename` is None, returns a DataFrame containing the QV analysis results. + If `filename` is None, returns a DataFrame containing the QV + analysis results (voltage vs. reactive power for each bus). Otherwise, returns None. Raises ------ PowerWorldError - If the SimAuto call fails or the QV analysis does not complete successfully. + If the SimAuto call fails or the QV analysis does not complete. """ + mbs = YesNo.from_bool(make_base_solvable) + wcas = YesNo.from_bool(write_case_after_solve) if filename: - self.RunScriptCommand(f'QVRun("{filename}", YES, NO);') + self._run_script("QVRun", f'"{filename}"', mbs, wcas) return None else: - with tempfile.NamedTemporaryFile(suffix=".csv", delete=False) as tmp: - temp_path = Path(tmp.name).as_posix() + temp_path = get_temp_filepath(".csv") try: - self.RunScriptCommand(f'QVRun("{temp_path}", YES, NO);') + self._run_script("QVRun", f'"{temp_path}"', mbs, wcas) if os.path.exists(temp_path) and os.path.getsize(temp_path) > 0: return pd.read_csv(temp_path) else: @@ -90,66 +122,99 @@ def RunQV(self, filename: str = None) -> pd.DataFrame: os.unlink(temp_path) def QVSelectSingleBusPerSuperBus(self): - """Modifies monitored buses for QV analysis to one per pnode (super bus). + """ + Reduce monitored QV buses to one per pnode (super bus). - This simplifies the QV analysis by focusing on representative buses. + When using QV analysis on a full topology model, this modifies the + monitored buses so that only one bus is monitored for each pnode. + This simplifies analysis and reduces computational load by focusing + on representative buses. + + This is a wrapper for the ``QVSelectSingleBusPerSuperBus`` script command. Returns ------- - None + str + The response from the PowerWorld script command. Raises ------ PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand("QVSelectSingleBusPerSuperBus;") + return self._run_script("QVSelectSingleBusPerSuperBus") def QVWriteCurves(self, filename: str, include_quantities: bool = True, filter_name: str = "", append: bool = False): - """Saves QV curve points to a file. + """ + Save QV curve points to a CSV file. + + Exports the QV curve data (voltage vs. reactive power points) for + each monitored bus to a comma-separated file. + + This is a wrapper for the ``QVWriteCurves`` script command. Parameters ---------- filename : str - The path to the output file. + Name of the CSV file to save. include_quantities : bool, optional - If True, includes quantities (e.g., MW, Mvar) in the output. Defaults to True. + If True, includes any Quantities to Track along with the QV + curve points. Defaults to True. filter_name : str, optional - A PowerWorld filter name to apply to buses. Defaults to an empty string (all). + Filter applied to QVCurve objects. Empty string selects all + curve results. Note: AREAZONE filtering is ignored for QVCurve. + Defaults to "" (all curves). append : bool, optional - If True, appends to the file if it exists. Defaults to False. + If True, appends data to existing file. If False, overwrites. + Defaults to False. Returns ------- - None + str + The response from the PowerWorld script command. Raises ------ PowerWorldError If the SimAuto call fails. """ - iq = "YES" if include_quantities else "NO" - app = "YES" if append else "NO" - return self.RunScriptCommand(f'QVWriteCurves("{filename}", {iq}, "{filter_name}", {app});') + iq = YesNo.from_bool(include_quantities) + app = YesNo.from_bool(append) + return self._run_script("QVWriteCurves", f'"{filename}"', iq, f'"{filter_name}"', app) def QVWriteResultsAndOptions(self, filename: str, append: bool = True): - """Writes out all information related to QV analysis to an auxiliary file. + """ + Write all QV analysis information to an auxiliary file. + + Exports complete QV analysis data including Contingency Definitions, + Remedial Action Definitions, Solution Options, QV Options, QV results, + and any Model Criteria used by Contingency and Remedial Action + Definitions. + + Dependencies are saved along with definitions, including: Model + Conditions, Model Filters, Model Planes, Model Expressions, Model + Result Overrides, Interfaces, Injection Groups, Calculated Fields, + and Expressions. + + This is a wrapper for the ``QVWriteResultsAndOptions`` script command. Parameters ---------- filename : str - The path to the auxiliary file. + Name of the auxiliary file to save. append : bool, optional - If True, appends to the file if it exists. Defaults to True. + If True, appends data to existing file. If False, overwrites. + Defaults to True. Returns ------- - None + str + The response from the PowerWorld script command. Raises ------ PowerWorldError If the SimAuto call fails. """ - app = "YES" if append else "NO" - return self.RunScriptCommand(f'QVWriteResultsAndOptions("{filename}", {app});') + app = YesNo.from_bool(append) + return self._run_script("QVWriteResultsAndOptions", f'"{filename}"', app) diff --git a/esapp/saw/regions.py b/esapp/saw/regions.py index 73e20fa5..265f5b81 100644 --- a/esapp/saw/regions.py +++ b/esapp/saw/regions.py @@ -1,6 +1,9 @@ """Regions specific functions.""" from typing import List +from ._enums import YesNo +from ._helpers import format_list + class RegionsMixin: """Mixin for Regions functions.""" @@ -37,12 +40,10 @@ def RegionLoadShapefile( str The response from the PowerWorld script command. """ - attrs = "[" + ", ".join(attribute_names) + "]" - add = "YES" if add_to_open_onelines else "NO" - delete = "YES" if delete_existing else "NO" - return self.RunScriptCommand( - f'RegionLoadShapefile("{filename}", "{class_name}", {attrs}, {add}, "{display_style_name}", {delete});' - ) + attrs = format_list(attribute_names) + add = YesNo.from_bool(add_to_open_onelines) + delete = YesNo.from_bool(delete_existing) + return self._run_script("RegionLoadShapefile", f'"{filename}"', f'"{class_name}"', attrs, add, f'"{display_style_name}"', delete) def RegionRename(self, old_name: str, new_name: str, update_onelines: bool = True): """ @@ -62,8 +63,8 @@ def RegionRename(self, old_name: str, new_name: str, update_onelines: bool = Tru str The response from the PowerWorld script command. """ - uo = "YES" if update_onelines else "NO" - return self.RunScriptCommand(f'RegionRename("{old_name}", "{new_name}", {uo});') + uo = YesNo.from_bool(update_onelines) + return self._run_script("RegionRename", f'"{old_name}"', f'"{new_name}"', uo) def RegionRenameClass(self, old_class: str, new_class: str, update_onelines: bool = True, filter_name: str = ""): """ @@ -85,9 +86,9 @@ def RegionRenameClass(self, old_class: str, new_class: str, update_onelines: boo str The response from the PowerWorld script command. """ - uo = "YES" if update_onelines else "NO" + uo = YesNo.from_bool(update_onelines) filt = f'"{filter_name}"' if filter_name else "" - return self.RunScriptCommand(f'RegionRenameClass("{old_class}", "{new_class}", {uo}, {filt});') + return self._run_script("RegionRenameClass", f'"{old_class}"', f'"{new_class}"', uo, filt) def RegionRenameProper1(self, old_prop: str, new_prop: str, update_onelines: bool = True, filter_name: str = ""): """ @@ -109,9 +110,9 @@ def RegionRenameProper1(self, old_prop: str, new_prop: str, update_onelines: boo str The response from the PowerWorld script command. """ - uo = "YES" if update_onelines else "NO" + uo = YesNo.from_bool(update_onelines) filt = f'"{filter_name}"' if filter_name else "" - return self.RunScriptCommand(f'RegionRenameProper1("{old_prop}", "{new_prop}", {uo}, {filt});') + return self._run_script("RegionRenameProper1", f'"{old_prop}"', f'"{new_prop}"', uo, filt) def RegionRenameProper2(self, old_prop: str, new_prop: str, update_onelines: bool = True, filter_name: str = ""): """ @@ -133,9 +134,9 @@ def RegionRenameProper2(self, old_prop: str, new_prop: str, update_onelines: boo str The response from the PowerWorld script command. """ - uo = "YES" if update_onelines else "NO" + uo = YesNo.from_bool(update_onelines) filt = f'"{filter_name}"' if filter_name else "" - return self.RunScriptCommand(f'RegionRenameProper2("{old_prop}", "{new_prop}", {uo}, {filt});') + return self._run_script("RegionRenameProper2", f'"{old_prop}"', f'"{new_prop}"', uo, filt) def RegionRenameProper3(self, old_prop: str, new_prop: str, update_onelines: bool = True, filter_name: str = ""): """ @@ -157,9 +158,9 @@ def RegionRenameProper3(self, old_prop: str, new_prop: str, update_onelines: boo str The response from the PowerWorld script command. """ - uo = "YES" if update_onelines else "NO" + uo = YesNo.from_bool(update_onelines) filt = f'"{filter_name}"' if filter_name else "" - return self.RunScriptCommand(f'RegionRenameProper3("{old_prop}", "{new_prop}", {uo}, {filt});') + return self._run_script("RegionRenameProper3", f'"{old_prop}"', f'"{new_prop}"', uo, filt) def RegionRenameProper12Flip(self, update_onelines: bool = True, filter_name: str = ""): """ @@ -177,9 +178,9 @@ def RegionRenameProper12Flip(self, update_onelines: bool = True, filter_name: st str The response from the PowerWorld script command. """ - uo = "YES" if update_onelines else "NO" + uo = YesNo.from_bool(update_onelines) filt = f'"{filter_name}"' if filter_name else "" - return self.RunScriptCommand(f"RegionRenameProper12Flip({uo}, {filt});") + return self._run_script("RegionRenameProper12Flip", uo, filt) def RegionUpdateBuses(self): """ @@ -190,4 +191,4 @@ def RegionUpdateBuses(self): str The response from the PowerWorld script command. """ - return self.RunScriptCommand("RegionUpdateBuses;") \ No newline at end of file + return self._run_script("RegionUpdateBuses") diff --git a/esapp/saw/saw.py b/esapp/saw/saw.py index d6cc3749..35576ce5 100644 --- a/esapp/saw/saw.py +++ b/esapp/saw/saw.py @@ -6,12 +6,12 @@ from .atc import ATCMixin from .case_actions import CaseActionsMixin from .contingency import ContingencyMixin +from .data import DataMixin from .general import GeneralMixin from .fault import FaultMixin from .gic import GICMixin from .matrices import MatrixMixin from .modify import ModifyMixin -from .oneline import OnelineMixin from .opf import OPFMixin from .powerflow import PowerflowMixin from .pv import PVMixin @@ -28,11 +28,11 @@ class SAW( SAWBase, CaseActionsMixin, + DataMixin, ContingencyMixin, GeneralMixin, MatrixMixin, ModifyMixin, - OnelineMixin, PowerflowMixin, RegionsMixin, SensitivityMixin, diff --git a/esapp/saw/scheduled.py b/esapp/saw/scheduled.py index 54e9f937..c05e7ad7 100644 --- a/esapp/saw/scheduled.py +++ b/esapp/saw/scheduled.py @@ -1,6 +1,9 @@ """Scheduled Actions specific functions.""" +from esapp.saw._enums import YesNo + + class ScheduledActionsMixin: """Mixin for Scheduled Actions functions.""" @@ -32,9 +35,9 @@ def ApplyScheduledActionsAt(self, start_time: str, end_time: str = "", filter_na PowerWorldError If the SimAuto call fails. """ - rev = "YES" if revert else "NO" + rev = YesNo.from_bool(revert) filt = f'"{filter_name}"' if filter_name else "" - return self.RunScriptCommand(f'ApplyScheduledActionsAt("{start_time}", "{end_time}", {filt}, {rev});') + return self._run_script("ApplyScheduledActionsAt", f'"{start_time}"', f'"{end_time}"', filt, rev) def IdentifyBreakersForScheduledActions(self, identify_from_normal: bool = True): """Identifies breakers for scheduled actions. @@ -56,8 +59,8 @@ def IdentifyBreakersForScheduledActions(self, identify_from_normal: bool = True) PowerWorldError If the SimAuto call fails. """ - ifn = "YES" if identify_from_normal else "NO" - return self.RunScriptCommand(f"IdentifyBreakersForScheduledActions({ifn});") + ifn = YesNo.from_bool(identify_from_normal) + return self._run_script("IdentifyBreakersForScheduledActions", ifn) def RevertScheduledActionsAt(self, start_time: str, end_time: str = "", filter_name: str = ""): """Reverts scheduled actions that were active during the specified time window. @@ -85,7 +88,7 @@ def RevertScheduledActionsAt(self, start_time: str, end_time: str = "", filter_n If the SimAuto call fails. """ filt = f'"{filter_name}"' if filter_name else "" - return self.RunScriptCommand(f'RevertScheduledActionsAt("{start_time}", "{end_time}", {filt});') + return self._run_script("RevertScheduledActionsAt", f'"{start_time}"', f'"{end_time}"', filt) def ScheduledActionsSetReference(self): """Sets the current system state as the reference for scheduled actions. @@ -103,7 +106,7 @@ def ScheduledActionsSetReference(self): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand("ScheduledActionsSetReference;") + return self._run_script("ScheduledActionsSetReference") def SetScheduleView( self, view_time: str, apply_actions: bool = None, use_normal_status: bool = None, apply_window: bool = None @@ -134,10 +137,10 @@ def SetScheduleView( PowerWorldError If the SimAuto call fails. """ - aa = "YES" if apply_actions else "NO" if apply_actions is not None else "" - uns = "YES" if use_normal_status else "NO" if use_normal_status is not None else "" - aw = "YES" if apply_window else "NO" if apply_window is not None else "" - return self.RunScriptCommand(f'SetScheduleView("{view_time}", {aa}, {uns}, {aw});') + aa = YesNo.from_bool(apply_actions) if apply_actions is not None else None + uns = YesNo.from_bool(use_normal_status) if use_normal_status is not None else None + aw = YesNo.from_bool(apply_window) if apply_window is not None else None + return self._run_script("SetScheduleView", f'"{view_time}"', aa, uns, aw) def SetScheduleWindow( self, start_time: str, end_time: str, resolution: float = None, resolution_units: str = None @@ -168,6 +171,4 @@ def SetScheduleWindow( PowerWorldError If the SimAuto call fails. """ - res = str(resolution) if resolution is not None else "" - units = resolution_units if resolution_units else "" - return self.RunScriptCommand(f'SetScheduleWindow("{start_time}", "{end_time}", {res}, {units});') \ No newline at end of file + return self._run_script("SetScheduleWindow", f'"{start_time}"', f'"{end_time}"', resolution, resolution_units) diff --git a/esapp/saw/sensitivity.py b/esapp/saw/sensitivity.py index f9d3cdfa..cc4c32fe 100644 --- a/esapp/saw/sensitivity.py +++ b/esapp/saw/sensitivity.py @@ -1,5 +1,8 @@ """Sensitivity analysis specific functions.""" +from typing import Union + from ._helpers import create_object_string +from ._enums import YesNo, LinearMethod, IslandReference class SensitivityMixin: @@ -28,9 +31,9 @@ def CalculateFlowSense(self, flow_element: str, flow_type: str): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f'CalculateFlowSense({flow_element}, {flow_type});') + return self._run_script("CalculateFlowSense", flow_element, flow_type) - def CalculatePTDF(self, seller: str, buyer: str, method: str = "DC"): + def CalculatePTDF(self, seller: str, buyer: str, method: Union[LinearMethod, str] = LinearMethod.DC): """Calculates the PTDF (Power Transfer Distribution Factor) values between a seller and a buyer. PTDFs indicate how much power flow on a specific branch changes for a @@ -42,8 +45,9 @@ def CalculatePTDF(self, seller: str, buyer: str, method: str = "DC"): The seller (source) object string (e.g., '[AREA "Top"]', '[BUS 7]'). buyer : str The buyer (sink) object string (e.g., '[AREA "Bottom"]', '[BUS 8]'). - method : str, optional - The linear method to use for calculation ("AC", "DC", "DCPS"). Defaults to "DC". + method : Union[LinearMethod, str], optional + The linear method to use for calculation (LinearMethod.AC, LinearMethod.DC, LinearMethod.DCPS). + Defaults to LinearMethod.DC. Returns ------- @@ -55,9 +59,10 @@ def CalculatePTDF(self, seller: str, buyer: str, method: str = "DC"): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f'CalculatePTDF({seller}, {buyer}, {method});') + m = method.value if isinstance(method, LinearMethod) else method + return self._run_script("CalculatePTDF", seller, buyer, m) - def CalculateLODF(self, branch: str, method: str = "DC", post_closure_lcdf: str = ""): + def CalculateLODF(self, branch: str, method: Union[LinearMethod, str] = LinearMethod.DC, post_closure_lcdf: Union[YesNo, str] = ""): """Calculates LODF (Line Outage Distribution Factors) for a specified branch outage. LODFs quantify how much power flow on other branches changes when a @@ -67,10 +72,11 @@ def CalculateLODF(self, branch: str, method: str = "DC", post_closure_lcdf: str ---------- branch : str The branch element string to outage/close (e.g., '[BRANCH 1 2 1]'). - method : str, optional - The linear method to use for calculation ("DC", "DCPS"). Defaults to "DC". - post_closure_lcdf : str, optional - Optional parameter ("YES" or "NO") to include LCDF (Line Closure Distribution Factor) + method : Union[LinearMethod, str], optional + The linear method to use for calculation (LinearMethod.DC, LinearMethod.DCPS). + Defaults to LinearMethod.DC. + post_closure_lcdf : Union[YesNo, str], optional + Optional parameter (YesNo.YES or YesNo.NO) to include LCDF (Line Closure Distribution Factor) calculation relative to post-closure flow. Defaults to "". Returns @@ -83,10 +89,11 @@ def CalculateLODF(self, branch: str, method: str = "DC", post_closure_lcdf: str PowerWorldError If the SimAuto call fails. """ - args = f'{branch}, {method}' + m = method.value if isinstance(method, LinearMethod) else method if post_closure_lcdf: - args += f', {post_closure_lcdf}' - return self.RunScriptCommand(f'CalculateLODF({args});') + lcdf = post_closure_lcdf.value if isinstance(post_closure_lcdf, YesNo) else post_closure_lcdf + return self._run_script("CalculateLODF", branch, m, lcdf) + return self._run_script("CalculateLODF", branch, m) def CalculateLODFAdvanced(self, include_phase_shifters: bool, file_type: str, max_columns: int, min_lodf: float, number_format: str, decimal_points: int, only_increasing: bool, filename: str, include_islanding: bool = True): """Performs an advanced LODF calculation with various output and filtering options. @@ -127,11 +134,10 @@ def CalculateLODFAdvanced(self, include_phase_shifters: bool, file_type: str, ma ----- This method corresponds to the `CalculateLODFAdvanced` script command in PowerWorld. """ - ips = "YES" if include_phase_shifters else "NO" - inc = "YES" if only_increasing else "NO" - isl = "YES" if include_islanding else "NO" - cmd = f'CalculateLODFAdvanced({ips}, {file_type}, {max_columns}, {min_lodf}, {number_format}, {decimal_points}, {inc}, "{filename}", {isl});' - return self.RunScriptCommand(cmd) + ips = YesNo.from_bool(include_phase_shifters) + inc = YesNo.from_bool(only_increasing) + isl = YesNo.from_bool(include_islanding) + return self._run_script("CalculateLODFAdvanced", ips, file_type, max_columns, min_lodf, number_format, decimal_points, inc, f'"{filename}"', isl) def CalculateLODFScreening(self, filter_process: str, filter_monitor: str, include_phase_shifters: bool, include_open_lines: bool, use_lodf_threshold: bool, lodf_threshold: float, use_overload_threshold: bool, overload_low: float, overload_high: float, do_save_file: bool, file_location: str, custom_high_lodf: int = 0, custom_high_lodf_line: int = 0, custom_high_overload: int = 0, custom_high_overload_line: int = 0, do_use_ctg_name: bool = False, custom_orig_ctg_name: int = 0): """Performs LODF Screening calculation to identify critical outages and overloads. @@ -180,16 +186,15 @@ def CalculateLODFScreening(self, filter_process: str, filter_monitor: str, inclu ------- None """ - ips = "YES" if include_phase_shifters else "NO" - iol = "YES" if include_open_lines else "NO" - ult = "YES" if use_lodf_threshold else "NO" - uot = "YES" if use_overload_threshold else "NO" - dsf = "YES" if do_save_file else "NO" - duc = "YES" if do_use_ctg_name else "NO" - cmd = f'CalculateLODFScreening({filter_process}, {filter_monitor}, {ips}, {iol}, {ult}, {lodf_threshold}, {uot}, {overload_low}, {overload_high}, {dsf}, "{file_location}", {custom_high_lodf}, {custom_high_lodf_line}, {custom_high_overload}, {custom_high_overload_line}, {duc}, {custom_orig_ctg_name});' - return self.RunScriptCommand(cmd) - - def CalculateShiftFactors(self, flow_element: str, direction: str, transactor: str, method: str = "DC"): + ips = YesNo.from_bool(include_phase_shifters) + iol = YesNo.from_bool(include_open_lines) + ult = YesNo.from_bool(use_lodf_threshold) + uot = YesNo.from_bool(use_overload_threshold) + dsf = YesNo.from_bool(do_save_file) + duc = YesNo.from_bool(do_use_ctg_name) + return self._run_script("CalculateLODFScreening", filter_process, filter_monitor, ips, iol, ult, lodf_threshold, uot, overload_low, overload_high, dsf, f'"{file_location}"', custom_high_lodf, custom_high_lodf_line, custom_high_overload, custom_high_overload_line, duc, custom_orig_ctg_name) + + def CalculateShiftFactors(self, flow_element: str, direction: str, transactor: str, method: Union[LinearMethod, str] = LinearMethod.DC): """Calculates Shift Factor Sensitivity values (formerly known as TLRs). Shift Factors quantify how much power flow on a specific element changes @@ -203,8 +208,9 @@ def CalculateShiftFactors(self, flow_element: str, direction: str, transactor: s The direction of transfer ("BUYER" or "SELLER"). transactor : str The transactor object string (e.g., '[AREA "Top"]', '[BUS 7]'). - method : str, optional - The linear method to use for calculation ("AC", "DC", "DCPS"). Defaults to "DC". + method : Union[LinearMethod, str], optional + The linear method to use for calculation (LinearMethod.AC, LinearMethod.DC, LinearMethod.DCPS). + Defaults to LinearMethod.DC. Returns ------- @@ -215,11 +221,10 @@ def CalculateShiftFactors(self, flow_element: str, direction: str, transactor: s PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand( - f'CalculateShiftFactors({flow_element}, {direction}, {transactor}, {method});' - ) + m = method.value if isinstance(method, LinearMethod) else method + return self._run_script("CalculateShiftFactors", flow_element, direction, transactor, m) - def CalculateShiftFactorsMultipleElement(self, type_element: str, which_element: str, direction: str, transactor: str, method: str = "DC"): + def CalculateShiftFactorsMultipleElement(self, type_element: str, which_element: str, direction: str, transactor: str, method: Union[LinearMethod, str] = LinearMethod.DC): """Calculates Shift Factor Sensitivity values for multiple elements. This method extends `CalculateShiftFactors` to apply the calculation @@ -235,8 +240,9 @@ def CalculateShiftFactorsMultipleElement(self, type_element: str, which_element: The direction of transfer ("BUYER" or "SELLER"). transactor : str The transactor object string (e.g., '[AREA "Top"]', '[BUS 7]'). - method : str, optional - The linear method to use for calculation ("AC", "DC", "DCPS"). Defaults to "DC". + method : Union[LinearMethod, str], optional + The linear method to use for calculation (LinearMethod.AC, LinearMethod.DC, LinearMethod.DCPS). + Defaults to LinearMethod.DC. Returns ------- @@ -247,7 +253,8 @@ def CalculateShiftFactorsMultipleElement(self, type_element: str, which_element: PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f'CalculateShiftFactorsMultipleElement({type_element}, {which_element}, {direction}, {transactor}, {method});') + m = method.value if isinstance(method, LinearMethod) else method + return self._run_script("CalculateShiftFactorsMultipleElement", type_element, which_element, direction, transactor, m) def CalculateLODFMatrix( self, @@ -255,7 +262,7 @@ def CalculateLODFMatrix( filter_process: str, filter_monitor: str, monitor_only_closed: bool = True, - linear_method: str = "DC", + linear_method: Union[LinearMethod, str] = LinearMethod.DC, filter_monitor_interface: str = "", post_closure_lcdf: bool = True, ): @@ -274,8 +281,8 @@ def CalculateLODFMatrix( A PowerWorld filter name for branches to monitor. monitor_only_closed : bool, optional If True, only monitors initially closed branches. Defaults to True. - linear_method : str, optional - The linear method to use ("DC" or "DCPS"). Defaults to "DC". + linear_method : Union[LinearMethod, str], optional + The linear method to use (LinearMethod.DC or LinearMethod.DCPS). Defaults to LinearMethod.DC. filter_monitor_interface : str, optional A PowerWorld filter name for interfaces to monitor. Defaults to "". post_closure_lcdf : bool, optional @@ -291,10 +298,10 @@ def CalculateLODFMatrix( PowerWorldError If the SimAuto call fails. """ - mon_closed = "YES" if monitor_only_closed else "NO" - post_lcdf = "YES" if post_closure_lcdf else "NO" - cmd = f"CalculateLODFMatrix({which_ones}, {filter_process}, {filter_monitor}, {mon_closed}, {linear_method}, {filter_monitor_interface}, {post_lcdf});" - return self.RunScriptCommand(cmd) + mon_closed = YesNo.from_bool(monitor_only_closed) + post_lcdf = YesNo.from_bool(post_closure_lcdf) + m = linear_method.value if isinstance(linear_method, LinearMethod) else linear_method + return self._run_script("CalculateLODFMatrix", which_ones, filter_process, filter_monitor, mon_closed, m, filter_monitor_interface, post_lcdf) def CalculateVoltToTransferSense( self, seller: str, buyer: str, transfer_type: str = "P", turn_off_avr: bool = False @@ -325,10 +332,10 @@ def CalculateVoltToTransferSense( PowerWorldError If the SimAuto call fails. """ - avr = "YES" if turn_off_avr else "NO" - return self.RunScriptCommand(f"CalculateVoltToTransferSense({seller}, {buyer}, {transfer_type}, {avr});") + avr = YesNo.from_bool(turn_off_avr) + return self._run_script("CalculateVoltToTransferSense", seller, buyer, transfer_type, avr) - def CalculateLossSense(self, function_type: str, area_ref: str = "NO", island_ref: str = "EXISTING"): + def CalculateLossSense(self, function_type: str, area_ref: str = "NO", island_ref: Union[IslandReference, str] = IslandReference.EXISTING): """Calculates loss sensitivity at each bus. Loss sensitivity indicates how much system losses change for a unit @@ -352,9 +359,9 @@ def CalculateLossSense(self, function_type: str, area_ref: str = "NO", island_re PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f'CalculateLossSense({function_type}, {area_ref}, {island_ref});') + return self._run_script("CalculateLossSense", function_type, area_ref, island_ref) - def LineLoadingReplicatorCalculate(self, flow_element: str, injection_group: str, agc_only: bool, desired_flow: float, implement: bool, linear_method: str = "DC", use_load_min_max: bool = True, max_mult: float = 1.0, min_mult: float = 1.0): + def LineLoadingReplicatorCalculate(self, flow_element: str, injection_group: str, agc_only: bool, desired_flow: float, implement: bool, linear_method: Union[LinearMethod, str] = LinearMethod.DC, use_load_min_max: bool = True, max_mult: float = 1.0, min_mult: float = 1.0): """Calculates injection changes required to alter a line flow to a desired value. This tool helps in determining how to adjust generation or load to achieve @@ -372,8 +379,8 @@ def LineLoadingReplicatorCalculate(self, flow_element: str, injection_group: str The desired flow value on the `flow_element`. implement : bool If True, immediately implements the calculated injection changes. - linear_method : str, optional - The linear method to use ("DC", "AC"). Defaults to "DC". + linear_method : Union[LinearMethod, str], optional + The linear method to use (LinearMethod.DC, LinearMethod.AC). Defaults to LinearMethod.DC. use_load_min_max : bool, optional If True, respects load min/max limits during adjustments. Defaults to True. max_mult : float, optional @@ -390,11 +397,11 @@ def LineLoadingReplicatorCalculate(self, flow_element: str, injection_group: str PowerWorldError If the SimAuto call fails. """ - agc = "YES" if agc_only else "NO" - imp = "YES" if implement else "NO" - ulmm = "YES" if use_load_min_max else "NO" - cmd = f'LineLoadingReplicatorCalculate({flow_element}, {injection_group}, {agc}, {desired_flow}, {imp}, {linear_method}, {ulmm}, {max_mult}, {min_mult});' - return self.RunScriptCommand(cmd) + agc = YesNo.from_bool(agc_only) + imp = YesNo.from_bool(implement) + ulmm = YesNo.from_bool(use_load_min_max) + m = linear_method.value if isinstance(linear_method, LinearMethod) else linear_method + return self._run_script("LineLoadingReplicatorCalculate", flow_element, injection_group, agc, desired_flow, imp, m, ulmm, max_mult, min_mult) def LineLoadingReplicatorImplement(self): """Applies the changes calculated by the Line Loading Replicator. @@ -411,7 +418,7 @@ def LineLoadingReplicatorImplement(self): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand("LineLoadingReplicatorImplement;") + return self._run_script("LineLoadingReplicatorImplement") def CalculateTapSense(self, filter_name: str = ""): """Forces voltage to tap sensitivity calculation. @@ -432,7 +439,7 @@ def CalculateTapSense(self, filter_name: str = ""): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f'CalculateTapSense("{filter_name}");') + return self._run_script("CalculateTapSense", f'"{filter_name}"') def CalculateVoltSelfSense(self, filter_name: str = ""): """Calculates the sensitivity of a bus's voltage to injections at the same bus. @@ -451,7 +458,7 @@ def CalculateVoltSelfSense(self, filter_name: str = ""): PowerWorldError If the SimAuto call fails. """ - return self.RunScriptCommand(f'CalculateVoltSelfSense("{filter_name}");') + return self._run_script("CalculateVoltSelfSense", f'"{filter_name}"') def CalculateVoltSense(self, bus_num: int): """Calculates the sensitivity of a bus's voltage to injections at all buses. @@ -471,7 +478,7 @@ def CalculateVoltSense(self, bus_num: int): If the SimAuto call fails. """ bus_str = create_object_string("Bus", bus_num) - return self.RunScriptCommand(f'CalculateVoltSense({bus_str});') + return self._run_script("CalculateVoltSense", bus_str) def SetSensitivitiesAtOutOfServiceToClosest(self, filter_name: str = "", branch_dist_meas: str = ""): """Populates sensitivity values at out-of-service buses by interpolating from the closest in-service buses. @@ -493,9 +500,9 @@ def SetSensitivitiesAtOutOfServiceToClosest(self, filter_name: str = "", branch_ If the SimAuto call fails. """ filt = f'"{filter_name}"' if filter_name else "" - return self.RunScriptCommand(f'SetSensitivitiesAtOutOfServiceToClosest({filt}, {branch_dist_meas});') + return self._run_script("SetSensitivitiesAtOutOfServiceToClosest", filt, branch_dist_meas) - def CalculatePTDFMultipleDirections(self, store_branches: bool = True, store_interfaces: bool = True, method: str = "DC"): + def CalculatePTDFMultipleDirections(self, store_branches: bool = True, store_interfaces: bool = True, method: Union[LinearMethod, str] = LinearMethod.DC): """Calculates PTDF values between all directions specified in the case. Parameters @@ -504,8 +511,9 @@ def CalculatePTDFMultipleDirections(self, store_branches: bool = True, store_int If True, stores PTDFs for branches. Defaults to True. store_interfaces : bool, optional If True, stores PTDFs for interfaces. Defaults to True. - method : str, optional - The linear method to use for calculation ("DC", "AC", "DCPS"). Defaults to "DC". + method : Union[LinearMethod, str], optional + The linear method to use for calculation (LinearMethod.DC, LinearMethod.AC, LinearMethod.DCPS). + Defaults to LinearMethod.DC. Returns ------- @@ -516,6 +524,7 @@ def CalculatePTDFMultipleDirections(self, store_branches: bool = True, store_int PowerWorldError If the SimAuto call fails. """ - sb = "YES" if store_branches else "NO" - si = "YES" if store_interfaces else "NO" - return self.RunScriptCommand(f'CalculatePTDFMultipleDirections({sb}, {si}, {method});') \ No newline at end of file + sb = YesNo.from_bool(store_branches) + si = YesNo.from_bool(store_interfaces) + m = method.value if isinstance(method, LinearMethod) else method + return self._run_script("CalculatePTDFMultipleDirections", sb, si, m) diff --git a/esapp/saw/timestep.py b/esapp/saw/timestep.py index 0a53075b..2c463c27 100644 --- a/esapp/saw/timestep.py +++ b/esapp/saw/timestep.py @@ -1,5 +1,7 @@ """Time Step Simulation specific functions.""" -from typing import List +from typing import List, Union +from ._helpers import format_list +from ._enums import FilterKeyword, format_filter class TimeStepMixin: @@ -21,10 +23,7 @@ def TimeStepDoRun(self, start_time: str = "", end_time: str = ""): str The result of the script command. """ - args = "" - if start_time and end_time: - args = f"{start_time}, {end_time}" - return self.RunScriptCommand(f"TimeStepDoRun({args});") + return self._run_script("TimeStepDoRun", start_time or None, end_time or None) def TimeStepDoSinglePoint(self, time_point: str): """ @@ -40,7 +39,7 @@ def TimeStepDoSinglePoint(self, time_point: str): str The result of the script command. """ - return self.RunScriptCommand(f"TimeStepDoSinglePoint({time_point});") + return self._run_script("TimeStepDoSinglePoint", time_point) def TimeStepClearResults(self, start_time: str = "", end_time: str = ""): """ @@ -58,10 +57,7 @@ def TimeStepClearResults(self, start_time: str = "", end_time: str = ""): str The result of the script command. """ - args = "" - if start_time and end_time: - args = f"{start_time}, {end_time}" - return self.RunScriptCommand(f"TimeStepClearResults({args});") + return self._run_script("TimeStepClearResults", start_time or None, end_time or None) def TimeStepDeleteAll(self): """ @@ -72,7 +68,7 @@ def TimeStepDeleteAll(self): str The result of the script command. """ - return self.RunScriptCommand("TimeStepDeleteAll;") + return self._run_script("TimeStepDeleteAll") def TimeStepResetRun(self): """ @@ -83,7 +79,7 @@ def TimeStepResetRun(self): str The result of the script command. """ - return self.RunScriptCommand("TimeStepResetRun;") + return self._run_script("TimeStepResetRun") def TimeStepAppendPWW(self, filename: str, solution_type: str = "Single Solution"): """ @@ -101,7 +97,7 @@ def TimeStepAppendPWW(self, filename: str, solution_type: str = "Single Solution str The result of the script command. """ - return self.RunScriptCommand(f'TimeStepAppendPWW("{filename}", "{solution_type}");') + return self._run_script("TimeStepAppendPWW", f'"{filename}"', f'"{solution_type}"') def TimeStepAppendPWWRange(self, filename: str, start_time: str, end_time: str, solution_type: str = "Single Solution"): """ @@ -123,7 +119,7 @@ def TimeStepAppendPWWRange(self, filename: str, start_time: str, end_time: str, str The result of the script command. """ - return self.RunScriptCommand(f'TimeStepAppendPWWRange("{filename}", {start_time}, {end_time}, "{solution_type}");') + return self._run_script("TimeStepAppendPWWRange", f'"{filename}"', start_time, end_time, f'"{solution_type}"') def TimeStepAppendPWWRangeLatLon(self, filename: str, start_time: str, end_time: str, min_lat: float, max_lat: float, min_lon: float, max_lon: float, solution_type: str = "Single Solution"): """ @@ -134,7 +130,7 @@ def TimeStepAppendPWWRangeLatLon(self, filename: str, start_time: str, end_time: str The result of the script command. """ - return self.RunScriptCommand(f'TimeStepAppendPWWRangeLatLon("{filename}", {start_time}, {end_time}, {min_lat}, {max_lat}, {min_lon}, {max_lon}, "{solution_type}");') + return self._run_script("TimeStepAppendPWWRangeLatLon", f'"{filename}"', start_time, end_time, min_lat, max_lat, min_lon, max_lon, f'"{solution_type}"') def TimeStepLoadB3D(self, filename: str, solution_type: str = "GIC Only (No Power Flow)"): """ @@ -145,7 +141,7 @@ def TimeStepLoadB3D(self, filename: str, solution_type: str = "GIC Only (No Powe str The result of the script command. """ - return self.RunScriptCommand(f'TimeStepLoadB3D("{filename}", "{solution_type}");') + return self._run_script("TimeStepLoadB3D", f'"{filename}"', f'"{solution_type}"') def TimeStepLoadPWW(self, filename: str, solution_type: str = "Single Solution"): """ @@ -163,7 +159,7 @@ def TimeStepLoadPWW(self, filename: str, solution_type: str = "Single Solution") str The result of the script command. """ - return self.RunScriptCommand(f'TimeStepLoadPWW("{filename}", "{solution_type}");') + return self._run_script("TimeStepLoadPWW", f'"{filename}"', f'"{solution_type}"') def TimeStepLoadPWWRange( self, filename: str, start_time: str, end_time: str, solution_type: str = "Single Solution" @@ -176,9 +172,7 @@ def TimeStepLoadPWWRange( str The result of the script command. """ - return self.RunScriptCommand( - f'TimeStepLoadPWWRange("{filename}", {start_time}, {end_time}, "{solution_type}");' - ) + return self._run_script("TimeStepLoadPWWRange", f'"{filename}"', start_time, end_time, f'"{solution_type}"') def TimeStepLoadPWWRangeLatLon(self, filename: str, start_time: str, end_time: str, min_lat: float, max_lat: float, min_lon: float, max_lon: float, solution_type: str = "Single Solution"): """ @@ -189,7 +183,7 @@ def TimeStepLoadPWWRangeLatLon(self, filename: str, start_time: str, end_time: s str The result of the script command. """ - return self.RunScriptCommand(f'TimeStepLoadPWWRangeLatLon("{filename}", {start_time}, {end_time}, {min_lat}, {max_lat}, {min_lon}, {max_lon}, "{solution_type}");') + return self._run_script("TimeStepLoadPWWRangeLatLon", f'"{filename}"', start_time, end_time, min_lat, max_lat, min_lon, max_lon, f'"{solution_type}"') def TimeStepSavePWW(self, filename: str): """ @@ -200,7 +194,7 @@ def TimeStepSavePWW(self, filename: str): str The result of the script command. """ - return self.RunScriptCommand(f'TimeStepSavePWW("{filename}");') + return self._run_script("TimeStepSavePWW", f'"{filename}"') def TimeStepSaveResultsByTypeCSV( self, object_type: str, filename: str, start_time: str = "", end_time: str = "" @@ -224,10 +218,7 @@ def TimeStepSaveResultsByTypeCSV( str The result of the script command. """ - args = f'{object_type}, "{filename}"' - if start_time and end_time: - args += f", {start_time}, {end_time}" - return self.RunScriptCommand(f"TimeStepSaveResultsByTypeCSV({args});") + return self._run_script("TimeStepSaveResultsByTypeCSV", object_type, f'"{filename}"', start_time or None, end_time or None) def TimeStepSavePWWRange(self, filename: str, start_time: str, end_time: str): """ @@ -238,7 +229,7 @@ def TimeStepSavePWWRange(self, filename: str, start_time: str, end_time: str): str The result of the script command. """ - return self.RunScriptCommand(f'TimeStepSavePWWRange("{filename}", {start_time}, {end_time});') + return self._run_script("TimeStepSavePWWRange", f'"{filename}"', start_time, end_time) def TIMESTEPSaveSelectedModifyStart(self): """ @@ -249,7 +240,7 @@ def TIMESTEPSaveSelectedModifyStart(self): str The result of the script command. """ - return self.RunScriptCommand("TIMESTEPSaveSelectedModifyStart;") + return self._run_script("TIMESTEPSaveSelectedModifyStart") def TIMESTEPSaveSelectedModifyFinish(self): """ @@ -260,7 +251,7 @@ def TIMESTEPSaveSelectedModifyFinish(self): str The result of the script command. """ - return self.RunScriptCommand("TIMESTEPSaveSelectedModifyFinish;") + return self._run_script("TIMESTEPSaveSelectedModifyFinish") def TIMESTEPSaveInputCSV(self, filename: str, field_list: List[str], start_time: str = "", end_time: str = ""): """ @@ -271,11 +262,10 @@ def TIMESTEPSaveInputCSV(self, filename: str, field_list: List[str], start_time: str The result of the script command. """ - fields = "[" + ", ".join(field_list) + "]" - args = f'"{filename}", {fields}, {start_time}, {end_time}' - return self.RunScriptCommand(f"TIMESTEPSaveInputCSV({args});") + fields = format_list(field_list) + return self._run_script("TIMESTEPSaveInputCSV", f'"{filename}"', fields, start_time, end_time) - def TimeStepSaveFieldsSet(self, object_type: str, field_list: List[str], filter_name: str = "ALL"): + def TimeStepSaveFieldsSet(self, object_type: str, field_list: List[str], filter_name: Union[FilterKeyword, str] = FilterKeyword.ALL): """ Sets fields to save during simulation. @@ -285,17 +275,17 @@ def TimeStepSaveFieldsSet(self, object_type: str, field_list: List[str], filter_ Object type. field_list : List[str] List of fields. - filter_name : str, optional - Filter to apply. Defaults to "ALL". + filter_name : Union[FilterKeyword, str], optional + Filter to apply. Defaults to FilterKeyword.ALL. Returns ------- str The result of the script command. """ - fields = "[" + ", ".join(field_list) + "]" - filt = f'"{filter_name}"' if filter_name != "ALL" and filter_name != "SELECTED" else filter_name - return self.RunScriptCommand(f"TimeStepSaveFieldsSet({object_type}, {fields}, {filt});") + fields = format_list(field_list) + filt = format_filter(filter_name) + return self._run_script("TimeStepSaveFieldsSet", object_type, fields, filt) def TimeStepSaveFieldsClear(self, object_types: List[str] = None): """ @@ -311,10 +301,8 @@ def TimeStepSaveFieldsClear(self, object_types: List[str] = None): str The result of the script command. """ - objs = "" - if object_types: - objs = "[" + ", ".join(object_types) + "]" - return self.RunScriptCommand(f"TimeStepSaveFieldsClear({objs});") + objs = format_list(object_types) if object_types else "" + return self._run_script("TimeStepSaveFieldsClear", objs) def TimeStepLoadTSB(self, filename: str): """ @@ -325,7 +313,7 @@ def TimeStepLoadTSB(self, filename: str): str The result of the script command. """ - return self.RunScriptCommand(f'TimeStepLoadTSB("{filename}");') + return self._run_script("TimeStepLoadTSB", f'"{filename}"') def TimeStepSaveTSB(self, filename: str): """ @@ -336,4 +324,4 @@ def TimeStepSaveTSB(self, filename: str): str The result of the script command. """ - return self.RunScriptCommand(f'TimeStepSaveTSB("{filename}");') \ No newline at end of file + return self._run_script("TimeStepSaveTSB", f'"{filename}"') diff --git a/esapp/saw/topology.py b/esapp/saw/topology.py index db3fcce7..82256811 100644 --- a/esapp/saw/topology.py +++ b/esapp/saw/topology.py @@ -1,8 +1,10 @@ import os -import tempfile from pathlib import Path import pandas as pd +from ._enums import YesNo, format_filter +from ._helpers import format_list, get_temp_filepath + class TopologyMixin: @@ -14,52 +16,81 @@ def DeterminePathDistance( BusField="CustomFloat:1", ) -> pd.DataFrame: """ - Calculate a distance measure at each bus in the entire model. + Calculate a distance measure at each bus from a starting location. + + Computes how far each bus is from the specified starting group using + the chosen distance measure (impedance, length, or nodes). Results + are stored in a bus field. Buses in the start group have distance 0, + unreachable buses have distance -1. + + This is a wrapper for the ``DeterminePathDistance`` script command. Parameters ---------- start : str - The starting element identifier (e.g. '[BUS 1]'). + The starting location. Can be a Bus, Area, Zone, SuperArea, + Substation, or Injection Group. Examples: '[BUS 1]', + '[Area "East"]', '[InjectionGroup "Source"]'. BranchDistMeas : str, optional - The branch field to use as the distance measure. Defaults to "X". + Distance measure to use. Options: "X" (series reactance), + "Z" (impedance magnitude sqrt(R^2+X^2)), "Length", "Nodes" + (count branches), "FixedNumBus", "SuperBus", or any branch + field variable name. Defaults to "X". BranchFilter : str, optional - Filter to apply to branches. Defaults to "ALL". + Filter for branches that can be traversed. Options: "ALL", + "SELECTED", "CLOSED", or a filter name. Defaults to "ALL". BusField : str, optional - The bus field to store the distance in temporarily. Defaults to "CustomFloat:1". + Bus field to store the distance results. Defaults to "CustomFloat:1". Returns ------- pd.DataFrame DataFrame containing BusNum and the calculated distance. """ - self.RunScriptCommand(f"DeterminePathDistance({start}, {BranchDistMeas}, {BranchFilter}, {BusField});") + self._run_script("DeterminePathDistance", start, BranchDistMeas, BranchFilter, BusField) def DetermineBranchesThatCreateIslands( - self, Filter: str = "ALL", StoreBuses: str = "YES", SetSelectedOnLines: str = "NO" + self, Filter: str = "ALL", StoreBuses: bool = True, SetSelectedOnLines: bool = False ) -> pd.DataFrame: """ - Determine the branches whose outage results in island formation. + Determine which branches, if opened, would create electrical islands. + + Evaluates each branch to check if its removal causes part of the + system to become electrically isolated. Useful for identifying + critical transmission lines. + + This is a wrapper for the ``DetermineBranchesThatCreateIslands`` script command. Parameters ---------- Filter : str, optional - Filter to apply to branches. Defaults to "ALL". - StoreBuses : str, optional - Whether to store bus information. Defaults to "YES". - SetSelectedOnLines : str, optional - Whether to set the Selected field on lines. Defaults to "NO". + Which branches to check. Options: "ALL", "SELECTED", "AREAZONE", + or a filter name. Defaults to "ALL". + StoreBuses : bool, optional + If True, stores the buses in each island to the output. + Defaults to True. + SetSelectedOnLines : bool, optional + If True, sets the Selected field to YES for branches that + create islands. Note: this overwrites existing Selected values. + Defaults to False. Returns ------- pd.DataFrame - DataFrame containing the results. + DataFrame with branch/bus pairs showing which buses would be + islanded by each critical branch. + + Raises + ------ + PowerWorldError + If the command fails to execute. """ - with tempfile.NamedTemporaryFile(suffix=".csv", delete=False) as tmp: - filename = Path(tmp.name).as_posix() - + filename = get_temp_filepath(".csv") + + sb = YesNo.from_bool(StoreBuses) + ssl = YesNo.from_bool(SetSelectedOnLines) try: - statement = f'DetermineBranchesThatCreateIslands({Filter},{StoreBuses},"{filename}",{SetSelectedOnLines},CSV);' - self.RunScriptCommand(statement) + self._run_script("DetermineBranchesThatCreateIslands", Filter, sb, f'"{filename}"', ssl, "CSV") return pd.read_csv(filename, header=0) finally: if os.path.exists(filename): @@ -69,30 +100,43 @@ def DetermineShortestPath( self, start: str, end: str, BranchDistanceMeasure: str = "X", BranchFilter: str = "ALL" ) -> pd.DataFrame: """ - Calculate the shortest path between a starting group and an ending group. + Calculate the shortest path between two network locations. + + Computes the lowest-impedance (or other measure) path between a + starting location and an ending location. Returns the buses along + the path with cumulative distance from the end to the start. + + This is a wrapper for the ``DetermineShortestPath`` script command. Parameters ---------- start : str - The starting element identifier. + The starting location. Same format as DeterminePathDistance: + '[BUS 1]', '[Area "East"]', etc. end : str - The ending element identifier. + The ending location. Same format as start. BranchDistanceMeasure : str, optional - The branch field to use as distance. Defaults to "X". + Distance measure to use. Options: "X", "Z", "Length", "Nodes", + or any branch field variable name. Defaults to "X". BranchFilter : str, optional - Filter to apply to branches. Defaults to "ALL". + Filter for branches that can be traversed. Options: "ALL", + "SELECTED", "CLOSED", or a filter name. Defaults to "ALL". Returns ------- pd.DataFrame - DataFrame describing the shortest path. + DataFrame with columns [BusNum, distance_measure, BusName] + listing the path from end to start with cumulative distances. + + Raises + ------ + PowerWorldError + If the command fails or no path exists. """ - with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as tmp: - filename = Path(tmp.name).as_posix() - + filename = get_temp_filepath(".txt") + try: - statement = f'DetermineShortestPath({start}, {end}, {BranchDistanceMeasure}, {BranchFilter}, "{filename}");' - self.RunScriptCommand(statement) + self._run_script("DetermineShortestPath", start, end, BranchDistanceMeasure, BranchFilter, f'"{filename}"') df = pd.read_csv( filename, header=None, sep=r'\s+', names=["BusNum", BranchDistanceMeasure, "BusName"] ) @@ -103,25 +147,33 @@ def DetermineShortestPath( os.unlink(filename) def DoFacilityAnalysis(self, filename: str, set_selected: bool = False): - """Determine the branches that would isolate the Facility from the External region. - - This command assumes the user has set options in the Select Bus Dialog in the Simulator Tool dialog - (or via other automation means) before calling this. - + """ + Find the minimum cut to isolate a Facility from an External region. + + Identifies the minimum number of branches that need to be opened to + isolate the Facility (power system device) from the External region. + The Facility and External regions must be defined beforehand using + the Select Bus Dialog or other automation means. + + This is a wrapper for the ``DoFacilityAnalysis`` script command. + Parameters ---------- filename : str - The auxiliary file to which the results will be written. + Auxiliary file path to write the results. Output includes + buses forming each isolating path and the branches in the + minimum cut. set_selected : bool, optional - If True, sets the Selected field to YES for branches in the minimum cut. Defaults to False. - + If True, sets the Selected field to YES for branches in the + minimum cut. Defaults to False. + Returns ------- str The response from the PowerWorld script command. """ - yn = "YES" if set_selected else "NO" - return self.RunScriptCommand(f'DoFacilityAnalysis("{filename}", {yn});') + yn = YesNo.from_bool(set_selected) + return self._run_script("DoFacilityAnalysis", f'"{filename}"', yn) def FindRadialBusPaths( self, @@ -130,53 +182,68 @@ def FindRadialBusPaths( bus_or_superbus: str = "BUS", ): """ - Calculate series paths of buses or superbuses that are radial. - - Populates fields: Radial Path End Number, Radial Path Index, Radial Path Length. + Identify radial (dead-end) bus paths in the network. + + Scans the network for series of buses that end in a dead-end (radial + path) and populates the following fields for involved buses and + branches: Radial Path End Number, Radial Path Index, Radial Path Length. + + This is a wrapper for the ``FindRadialBusPaths`` script command. Parameters ---------- ignore_status : bool, optional - If True, ignores element status. Defaults to False. + If True, ignores element status when traversing branches. + Defaults to False. treat_parallel_as_not_radial : bool, optional - If True, treats parallel lines as not radial. Defaults to False. + If True, treats parallel branches as not radial when traversing. + Defaults to False. bus_or_superbus : str, optional - "BUS" or "SUPERBUS". Defaults to "BUS". + Grouping level for traversal. "BUS" or "SUPERBUS". When using + "SUPERBUS", branches within the same superbus have blank results. + Defaults to "BUS". Returns ------- str The response from the PowerWorld script command. """ - ign = "YES" if ignore_status else "NO" - treat = "YES" if treat_parallel_as_not_radial else "NO" - return self.RunScriptCommand(f"FindRadialBusPaths({ign}, {treat}, {bus_or_superbus});") + ign = YesNo.from_bool(ignore_status) + treat = YesNo.from_bool(treat_parallel_as_not_radial) + return self._run_script("FindRadialBusPaths", ign, treat, bus_or_superbus) def SetBusFieldFromClosest(self, variable_name: str, bus_filter_set_to: str, bus_filter_from_these: str, branch_filter_traverse: str, branch_dist_meas: str): """ - Set buses field values equal to the closest bus's value. + Copy a bus field value from the electrically closest bus. + + For buses matching bus_filter_set_to, sets their field value equal + to the value from the closest bus that matches bus_filter_from_these, + where "closest" is determined by traversing branches according to + the specified distance measure. + + This is a wrapper for the ``SetBusFieldFromClosest`` script command. Parameters ---------- variable_name : str - The variable to set. + The bus field to set (and copy from the closest bus). bus_filter_set_to : str - Filter for buses to set. + Filter specifying which buses should have their field overwritten. bus_filter_from_these : str - Filter for source buses. + Filter specifying which buses can be used as sources. branch_filter_traverse : str - Filter for branches to traverse. + Filter for branches that can be traversed. Options: "ALL", + "SELECTED", "CLOSED", or a filter name. branch_dist_meas : str - Distance measure. + Distance measure: "X", "Z", "Length", "Nodes", "FixedNumBus", + "SuperBus", or a branch field variable name. Returns ------- str The response from the PowerWorld script command. """ - return self.RunScriptCommand( - f'SetBusFieldFromClosest("{variable_name}", "{bus_filter_set_to}", "{bus_filter_from_these}", {branch_filter_traverse}, {branch_dist_meas});' - ) + return self._run_script("SetBusFieldFromClosest", f'"{variable_name}"', f'"{bus_filter_set_to}"', f'"{bus_filter_from_these}"', branch_filter_traverse, branch_dist_meas) def SetSelectedFromNetworkCut( self, @@ -233,121 +300,156 @@ def SetSelectedFromNetworkCut( str The response from the PowerWorld script command. """ - sh = "YES" if set_how else "NO" - en = "YES" if energized else "NO" - init = "YES" if initialize_selected else "NO" - uaz = "YES" if use_area_zone else "NO" - ukv = "YES" if use_kv else "NO" - - objs = "" - if objects_to_select: - objs = "[" + ", ".join(objects_to_select) + "]" - - bf = f'"{branch_filter}"' if branch_filter and branch_filter not in ["SELECTED", "AREAZONE", "ALL"] else branch_filter - inf = f'"{interface_filter}"' if interface_filter and interface_filter not in ["SELECTED", "AREAZONE", "ALL"] else interface_filter - dcf = f'"{dc_line_filter}"' if dc_line_filter and dc_line_filter not in ["SELECTED", "AREAZONE", "ALL"] else dc_line_filter - - cmd = ( - f"SetSelectedFromNetworkCut({sh}, {bus_on_cut_side}, {bf}, {inf}, " - f"{dcf}, {en}, {num_tiers}, {init}, {objs}, {uaz}, {ukv}, " - f"{min_kv}, {max_kv}, {lower_min_kv}, {lower_max_kv});" - ) - return self.RunScriptCommand(cmd) + sh = YesNo.from_bool(set_how) + en = YesNo.from_bool(energized) + init = YesNo.from_bool(initialize_selected) + uaz = YesNo.from_bool(use_area_zone) + ukv = YesNo.from_bool(use_kv) + + objs = format_list(objects_to_select) if objects_to_select else "" + + bf = format_filter(branch_filter) + inf = format_filter(interface_filter) + dcf = format_filter(dc_line_filter) + + return self._run_script("SetSelectedFromNetworkCut", sh, bus_on_cut_side, bf, inf, dcf, en, num_tiers, init, objs, uaz, ukv, min_kv, max_kv, lower_min_kv, lower_max_kv) def CreateNewAreasFromIslands(self): """ - Create permanent areas that match the area Simulator creates temporarily while solving. + Create permanent areas matching the temporary islands from power flow. + + Creates permanent area definitions that match the areas Simulator + creates temporarily while solving the power flow. New areas are + created if an area is on AGC, spans multiple viable islands, and + only one of those islands has more than one area in it. + + This is a wrapper for the ``CreateNewAreasFromIslands`` script command. Returns ------- str The response from the PowerWorld script command. """ - return self.RunScriptCommand("CreateNewAreasFromIslands;") + return self._run_script("CreateNewAreasFromIslands") def ExpandAllBusTopology(self): """ - Expand the topology around all buses. + Expand the topology model around all buses. + + Expands the topology representation for all buses in the model, + showing breaker-level detail where available. + + This is a wrapper for the ``ExpandAllBusTopology`` script command. Returns ------- str The response from the PowerWorld script command. + + See Also + -------- + ExpandBusTopology : Expand topology for a specific bus. """ - return self.RunScriptCommand("ExpandAllBusTopology;") + return self._run_script("ExpandAllBusTopology") def ExpandBusTopology(self, bus_identifier: str, topology_type: str): """ - Expand the topology around the specified bus. + Expand the topology model around a specific bus. + + Expands the topology representation for a specific bus to show + breaker-level detail according to the specified topology type. + + This is a wrapper for the ``ExpandBusTopology`` script command. Parameters ---------- bus_identifier : str - The bus identifier. + The bus to expand, e.g., "BUS 1" or a bus number. topology_type : str - The type of topology expansion. + The type of topology expansion (e.g., "BREAKERANDAHALF"). Returns ------- str The response from the PowerWorld script command. + + See Also + -------- + ExpandAllBusTopology : Expand topology for all buses. """ - return self.RunScriptCommand(f'ExpandBusTopology({bus_identifier}, {topology_type});') + return self._run_script("ExpandBusTopology", bus_identifier, topology_type) def SaveConsolidatedCase(self, filename: str, filetype: str = "PWB", bus_format: str = "Number", truncate_ctg_labels: bool = False, add_comments: bool = False): """ - Saves the full topology model into a consolidated case. + Save the full topology model as a consolidated case file. + + Exports the complete topology model (including breaker-level detail) + into a single consolidated case file. + + This is a wrapper for the ``SaveConsolidatedCase`` script command. Parameters ---------- filename : str - The file path to save. + The file path to save the consolidated case. filetype : str, optional - The file type ("PWB", "AUX"). Defaults to "PWB". + Output file format: "PWB" or "AUX". Defaults to "PWB". bus_format : str, optional - Bus format ("Number", "Name"). Defaults to "Number". + How to identify buses: "Number" or "Name". Defaults to "Number". truncate_ctg_labels : bool, optional If True, truncates contingency labels. Defaults to False. add_comments : bool, optional - If True, adds comments. Defaults to False. + If True, adds comments for object labels. Defaults to False. Returns ------- str The response from the PowerWorld script command. """ - tcl = "YES" if truncate_ctg_labels else "NO" - ac = "YES" if add_comments else "NO" - return self.RunScriptCommand(f'SaveConsolidatedCase("{filename}", {filetype}, [{bus_format}, {tcl}, {ac}]);') + tcl = YesNo.from_bool(truncate_ctg_labels) + ac = YesNo.from_bool(add_comments) + return self._run_script("SaveConsolidatedCase", f'"{filename}"', filetype, f'[{bus_format}, {tcl}, {ac}]') def CloseWithBreakers(self, object_type: str, filter_val: str, only_specified: bool = False, switching_types: list = None, close_normally_closed: bool = False): """ - Energize objects by closing breakers. + Energize objects by closing associated breakers. + + Closes the breakers (or other switching devices) required to energize + the specified objects. This is used when working with breaker-level + topology models. + + This is a wrapper for the ``CloseWithBreakers`` script command. Parameters ---------- object_type : str - The type of object to energize. + The type of object to energize (e.g., "GEN", "BRANCH", "LOAD"). filter_val : str - Filter or identifier for the object. + Filter name or object identifier (e.g., "[1 1]" for Gen at bus 1). only_specified : bool, optional - If True, only closes specified breakers. Defaults to False. + If True, only closes breakers directly associated with the + specified object, not all breakers needed for energization. + Defaults to False. switching_types : list, optional - List of switching device types to use. Defaults to None (Breakers). + List of switching device types to close, e.g., + ["Breaker", "Load Break Disconnect"]. Defaults to ["Breaker"]. close_normally_closed : bool, optional - If True, closes normally closed breakers. Defaults to False. + If True, also closes normally-closed disconnects. + Defaults to False. Returns ------- str The response from the PowerWorld script command. + + See Also + -------- + OpenWithBreakers : Disconnect objects by opening breakers. """ - only = "YES" if only_specified else "NO" - cnc = "YES" if close_normally_closed else "NO" - sw_types = '["Breaker"]' - if switching_types: - sw_types = "[" + ", ".join([f'"{t}"' for t in switching_types]) + "]" - + only = YesNo.from_bool(only_specified) + cnc = YesNo.from_bool(close_normally_closed) + sw_types = format_list(switching_types, quote_items=True) if switching_types else '["Breaker"]' + # This command has a unique syntax where the object type is the first argument # and the second argument is an identifier with keys *only*, not the full object string. # This block handles cases where a full object string (e.g., from create_object_string) @@ -359,32 +461,42 @@ def CloseWithBreakers(self, object_type: str, filter_val: str, only_specified: b keys_part = filter_val.strip()[len(prefix_to_check):-1].strip() processed_val = f"[{keys_part}]" - return self.RunScriptCommand(f'CloseWithBreakers({object_type}, {processed_val}, {only}, {sw_types}, {cnc});') + return self._run_script("CloseWithBreakers", object_type, processed_val, only, sw_types, cnc) def OpenWithBreakers(self, object_type: str, filter_val: str, switching_types: list = None, open_normally_open: bool = False): """ - Disconnect objects by opening breakers. + Disconnect objects by opening associated breakers. + + Opens the breakers (or other switching devices) to disconnect the + specified objects from the network. This is used when working with + breaker-level topology models. + + This is a wrapper for the ``OpenWithBreakers`` script command. Parameters ---------- object_type : str - The type of object to disconnect. + The type of object to disconnect (e.g., "GEN", "BRANCH", "LOAD"). filter_val : str - Filter or identifier for the object. + Filter name or object identifier (e.g., "[1 2 1]" for Branch). switching_types : list, optional - List of switching device types to use. Defaults to None (Breakers). + List of switching device types to open, e.g., ["Breaker"]. + Defaults to ["Breaker"]. open_normally_open : bool, optional - If True, opens normally open breakers. Defaults to False. + If True, also opens normally-open disconnects. + Defaults to False. Returns ------- str The response from the PowerWorld script command. + + See Also + -------- + CloseWithBreakers : Energize objects by closing breakers. """ - ono = "YES" if open_normally_open else "NO" - sw_types = '["Breaker"]' - if switching_types: - sw_types = "[" + ", ".join([f'"{t}"' for t in switching_types]) + "]" + ono = YesNo.from_bool(open_normally_open) + sw_types = format_list(switching_types, quote_items=True) if switching_types else '["Breaker"]' # This command has a unique syntax where the object type is the first argument # and the second argument is an identifier with keys *only*, not the full object string. @@ -396,4 +508,4 @@ def OpenWithBreakers(self, object_type: str, filter_val: str, switching_types: l keys_part = filter_val.strip()[len(prefix_to_check):-1].strip() processed_val = f"[{keys_part}]" - return self.RunScriptCommand(f'OpenWithBreakers({object_type}, {processed_val}, {sw_types}, {ono});') \ No newline at end of file + return self._run_script("OpenWithBreakers", object_type, processed_val, sw_types, ono) diff --git a/esapp/saw/transient.py b/esapp/saw/transient.py index 58ff254c..1ca9fdef 100644 --- a/esapp/saw/transient.py +++ b/esapp/saw/transient.py @@ -1,112 +1,29 @@ -from typing import List, Tuple, Union +from pathlib import Path +from typing import List, Tuple, Union, Optional import numpy as np import pandas as pd - +from ._enums import YesNo, TSGetResultsMode +from ._exceptions import PowerWorldError +from ._helpers import format_list, get_temp_filepath, load_ts_csv_results, pack_args class TransientMixin: - def TSGetContingencyResults( - self, - CtgName: str, - ObjFieldList: List[str], - StartTime: Union[None, int, float] = None, - StopTime: Union[None, int, float] = None, - ) -> Union[Tuple[None, None], Tuple[pd.DataFrame, pd.DataFrame]]: - """ - WARNING: This function should only be used after the simulation - is run (for example, use this after running script commands - TSSolveAll or TSSolve). - - The TSGetContingencyResults function is used to read - transient stability results into an external program (Python) - using SimAuto. - - `PowerWorld documentation: - `__ - - Parameters - ---------- - CtgName : str - The contingency to obtain results from. Only one - contingency be obtained at a time. - ObjFieldList : List[str] - A list of strings which may contain plots, - subplots, or individual object/field pairs specifying the - result variables to obtain. - StartTime : Union[None, int, float], optional - The time in seconds in the simulation to begin - retrieving results. If not specified (None), the start time - of the simulation is used. Defaults to None. - StopTime : Union[None, int, float], optional - The time in seconds in the simulation to stop - retrieving results. If not specified, the end time of the - simulation is used. Defaults to None. - - Returns - ------- - Tuple[pd.DataFrame, pd.DataFrame] or Tuple[None, None] - A tuple containing two DataFrames, "meta" and "data." - Alternatively, if the given CtgName does not exist, a tuple - of (None, None) will be returned. - """ - out = self._call_simauto( - "TSGetContingencyResults", - CtgName, - ObjFieldList, - str(StartTime), - str(StopTime), - ) - # We get (None, (None,)) if the contingency does not exist. - if out == (None, (None,)): - return None, None - - assert len(out) == 2, "Unexpected return format from PowerWorld." - - # Extract the meta data. - meta = pd.DataFrame( - out[0], - columns=[ - "ObjectType", - "PrimaryKey", - "SecondaryKey", - "Label", - "VariableName", - "ColHeader", - ], - ) - - # Remove extraneous white space in the strings. - meta = meta.apply(lambda x: x.str.strip(), axis=0) - - # Extract the data. - data = pd.DataFrame(out[1]) - - # Align column names with meta frame and set time column - data.rename(columns=lambda x: x - 1, inplace=True) - data.rename(columns={-1: "time"}, inplace=True) - - # Attempt to convert all columns to numeric. - data = self._to_numeric(data, errors="ignore") - meta = self._to_numeric(meta, errors="ignore") - - return meta, data def TSTransferStateToPowerFlow(self, calculate_mismatch: bool = False): - """Transfers the current transient stability state to the power flow. + """Transfers the transient stability state to the power flow. After running a transient stability simulation, this allows the state of the system at the final time step to be loaded into the power flow solver for steady-state analysis. - This is a wrapper for the ``TSTransferStateToPowerFlow`` script command. - Parameters ---------- calculate_mismatch : bool, optional - Set to True to calculate power mismatch when transferring. Defaults to False. + If True, calculates power mismatch when transferring transient state + to the power flow case. Defaults to False (no mismatch calculation). """ - cm = "YES" if calculate_mismatch else "NO" - self.RunScriptCommand(f"TSTransferStateToPowerFlow({cm});") + cm = YesNo.from_bool(calculate_mismatch) + self._run_script("TSTransferStateToPowerFlow", cm) def TSInitialize(self): """Initializes the transient stability simulation parameters. @@ -117,8 +34,8 @@ def TSInitialize(self): This is a wrapper for the ``TSInitialize`` script command. """ try: - self.RunScriptCommand("TSInitialize()") - except Exception: + self._run_script("TSInitialize") + except PowerWorldError: self.log.warning("Failed to Initialize TS Values") def TSResultStorageSetAll(self, object="ALL", value=True): @@ -135,33 +52,59 @@ def TSResultStorageSetAll(self, object="ALL", value=True): If True, results for this object type will be stored. If False, they will not. Defaults to True. """ - yn = "YES" if value else "NO" - self.RunScriptCommand(f"TSResultStorageSetAll({object}, {yn})") + yn = YesNo.from_bool(value) + self._run_script("TSResultStorageSetAll", object, yn) - def TSSolve(self, ctgname: str): + def TSSolve( + self, + ctgname: str, + start_time: float = None, + stop_time: float = None, + step_size: float = None, + step_in_cycles: bool = False, + ): """Solves a single transient stability contingency. - + This is a wrapper for the ``TSSolve`` script command. - + Parameters ---------- ctgname : str The name of the contingency to solve. + start_time : float, optional + Start time in seconds. Overrides the contingency's property. + stop_time : float, optional + Stop time in seconds. Overrides the contingency's property. + step_size : float, optional + Step size (in seconds unless step_in_cycles is True). + Overrides the contingency's property. + step_in_cycles : bool, optional + If True, step_size is interpreted as cycles rather than seconds. + Defaults to False. """ - self.RunScriptCommand(f'TSSolve("{ctgname}")') + if start_time is not None or stop_time is not None or step_size is not None: + parts = [] + parts.append(str(start_time) if start_time is not None else "") + parts.append(str(stop_time) if stop_time is not None else "") + parts.append(str(step_size) if step_size is not None else "") + sic = YesNo.from_bool(step_in_cycles) + parts.append(str(sic)) + self.RunScriptCommand(f'TSSolve("{ctgname}", [{", ".join(parts)}])') + else: + self._run_script("TSSolve", f'"{ctgname}"') def TSSolveAll(self): - """Solves all defined transient stability contingencies. - - This is a wrapper for the ``TSSolveAll`` script command. + """Solves all defined transient contingencies that are not set to skip. + + Distributed computing is not enabled by default. """ - self.RunScriptCommand("TSSolveAll()") + self._run_script("TSSolveAll") def TSStoreResponse(self, object_type: str = "ALL", value: bool = True): """Convenience wrapper to toggle transient stability result storage. This is a high-level wrapper around ``TSResultStorageSetAll``. - + Parameters ---------- object_type : str, optional @@ -191,19 +134,25 @@ def TSClearResultsFromRAM( if ctg_name.upper() not in ["ALL", "SELECTED"] and not ctg_name.startswith('"'): ctg_name = f'"{ctg_name}"' - c_sum = "YES" if clear_summary else "NO" - c_evt = "YES" if clear_events else "NO" - c_stat = "YES" if clear_statistics else "NO" - c_time = "YES" if clear_time_values else "NO" - c_sol = "YES" if clear_solution_details else "NO" - self.RunScriptCommand(f"TSClearResultsFromRAM({ctg_name},{c_sum},{c_evt},{c_stat},{c_time},{c_sol});") + c_sum = YesNo.from_bool(clear_summary) + c_evt = YesNo.from_bool(clear_events) + c_stat = YesNo.from_bool(clear_statistics) + c_time = YesNo.from_bool(clear_time_values) + c_sol = YesNo.from_bool(clear_solution_details) + try: + self._run_script("TSClearResultsFromRAM", ctg_name, c_sum, c_evt, c_stat, c_time, c_sol) + except Exception as e: + if "access violation" in str(e).lower(): + self.log.warning("TSClearResultsFromRAM: PW access violation (no results in RAM to clear)") + else: + raise def TSClearPlayInSignals(self) -> None: """Deletes all defined PlayIn signals. This is a wrapper for the ``DELETE(PLAYINSIGNAL)`` script command. """ - self.RunScriptCommand("DELETE(PLAYINSIGNAL);") + self._run_script("DELETE", "PLAYINSIGNAL") def TSSetPlayInSignals(self, name: str, times: np.ndarray, signals: np.ndarray) -> None: """Sets PlayIn signals using an AUX file command. @@ -248,16 +197,25 @@ def TSClearResultsFromRAMAndDisableStorage(self) -> None: self.TSClearResultsFromRAM() def TSAutoCorrect(self): - """Runs auto correction of parameters for transient stability.""" - return self.RunScriptCommand("TSAutoCorrect;") + """Runs auto correction of parameters for transient stability. + + Attempts to automatically fix common model parameter issues. + """ + return self._run_script("TSAutoCorrect") def TSClearAllModels(self): - """Clears all transient stability models.""" - return self.RunScriptCommand("TSClearAllModels;") + """Clears all transient stability models from the case.""" + return self._run_script("TSClearAllModels") def TSValidate(self): - """Validate transient stability models and input values.""" - return self.RunScriptCommand("TSValidate;") + """Validates transient stability models and input values. + + Useful for examining model errors and warnings when preparing a case + for analysis. Validation is done automatically when running transient + analysis, so this command does not need to be run manually prior to + analysis. + """ + return self._run_script("TSValidate") def TSWriteOptions( self, @@ -273,41 +231,59 @@ def TSWriteOptions( ): """Save transient stability option settings to an auxiliary file.""" opts = [ - "YES" if save_dynamic_model else "NO", - "YES" if save_stability_options else "NO", - "YES" if save_stability_events else "NO", - "YES" if save_results_events else "NO", - "YES" if save_plot_definitions else "NO", - "YES" if save_transient_limit_monitors else "NO", - "YES" if save_result_analyzer_time_window else "NO", + YesNo.from_bool(save_dynamic_model), + YesNo.from_bool(save_stability_options), + YesNo.from_bool(save_stability_events), + YesNo.from_bool(save_results_events), + YesNo.from_bool(save_plot_definitions), + YesNo.from_bool(save_transient_limit_monitors), + YesNo.from_bool(save_result_analyzer_time_window), ] - opt_str = "[" + ", ".join(opts) + "]" - return self.RunScriptCommand(f'TSWriteOptions("{filename}", {opt_str}, {key_field});') + opt_str = format_list(opts) + return self._run_script("TSWriteOptions", f'"{filename}"', opt_str, key_field) def TSLoadPTI(self, filename: str): - """Loads transient stability data in the PTI format.""" - return self.RunScriptCommand(f'TSLoadPTI("{filename}");') + """Loads transient stability data in the PTI DYR format. + + Parameters + ---------- + filename : str + Path to the PTI DYR file to load. + """ + return self._run_script("TSLoadPTI", f'"{filename}"') def TSLoadGE(self, filename: str): - """Loads transient stability data stored in the GE DYD format.""" - return self.RunScriptCommand(f'TSLoadGE("{filename}");') + """Loads transient stability data stored in the GE DYD format. + + Parameters + ---------- + filename : str + Path to the GE DYD file to load. + """ + return self._run_script("TSLoadGE", f'"{filename}"') def TSLoadBPA(self, filename: str): - """Loads transient stability data stored in the BPA format.""" - return self.RunScriptCommand(f'TSLoadBPA("{filename}");') + """Loads transient stability data stored in the BPA format. + + Parameters + ---------- + filename : str + Path to the BPA file to load. + """ + return self._run_script("TSLoadBPA", f'"{filename}"') def TSAutoInsertDistRelay( self, reach: float, add_from: bool, add_to: bool, transfer_trip: bool, shape: int, filter_name: str ): """Inserts DistRelay models on the lines meeting the specified filter.""" - af = "YES" if add_from else "NO" - at = "YES" if add_to else "NO" - tt = "YES" if transfer_trip else "NO" - self.RunScriptCommand(f'TSAutoInsertDistRelay({reach}, {af}, {at}, {tt}, {shape}, "{filter_name}");') + af = YesNo.from_bool(add_from) + at = YesNo.from_bool(add_to) + tt = YesNo.from_bool(transfer_trip) + self._run_script("TSAutoInsertDistRelay", reach, af, at, tt, shape, f'"{filter_name}"') def TSAutoInsertZPOTT(self, reach: float, filter_name: str): """Inserts ZPOTT models on the lines meeting the specified filter.""" - self.RunScriptCommand(f'TSAutoInsertZPOTT({reach}, "{filter_name}");') + self._run_script("TSAutoInsertZPOTT", reach, f'"{filter_name}"') def TSAutoSavePlots( self, @@ -321,66 +297,82 @@ def TSAutoSavePlots( include_category: bool = False, ): """Create and save images of the plots.""" - plots = "[" + ", ".join([f'"{p}"' for p in plot_names]) + "]" - ctgs = "[" + ", ".join([f'"{c}"' for c in ctg_names]) + "]" - icn = "YES" if include_case_name else "NO" - icat = "YES" if include_category else "NO" - self.RunScriptCommand( - f"TSAutoSavePlots({plots}, {ctgs}, {image_type}, {width}, {height}, {font_scalar}, {icn}, {icat});" - ) + plots = format_list(plot_names, quote_items=True) + ctgs = format_list(ctg_names, quote_items=True) + icn = YesNo.from_bool(include_case_name) + icat = YesNo.from_bool(include_category) + self._run_script("TSAutoSavePlots", plots, ctgs, image_type, width, height, font_scalar, icn, icat) def TSCalculateCriticalClearTime(self, element_or_filter: str): """Calculate critical clearing time for faults.""" - self.RunScriptCommand(f"TSCalculateCriticalClearTime({element_or_filter});") + self._run_script("TSCalculateCriticalClearTime", element_or_filter) def TSCalculateSMIBEigenValues(self): """Calculate single machine infinite bus eigenvalues.""" - self.RunScriptCommand("TSCalculateSMIBEigenValues;") + self._run_script("TSCalculateSMIBEigenValues") def TSClearModelsforObjects(self, object_type: str, filter_name: str = ""): """Deletes all transient stability models associated with the objects that meet the filter.""" - self.RunScriptCommand(f'TSClearModelsforObjects({object_type}, "{filter_name}");') + self._run_script("TSClearModelsforObjects", object_type, f'"{filter_name}"') def TSDisableMachineModelNonZeroDerivative(self, threshold: float = 0.001): """Disable machine models with non-zero state derivatives.""" - self.RunScriptCommand(f"TSDisableMachineModelNonZeroDerivative({threshold});") + self._run_script("TSDisableMachineModelNonZeroDerivative", threshold) def TSGetVCurveData(self, filename: str, filter_name: str): """Generates V-curve data for synchronous generators.""" - self.RunScriptCommand(f'TSGetVCurveData("{filename}", "{filter_name}");') - - def TSWriteResultsToCSV( - self, - filename: str, - mode: str, - contingencies: List[str], - plots_fields: List[str], - start_time: float = None, - end_time: float = None, - ): - """Save out results for specific variables to CSV.""" - ctgs = "[" + ", ".join([f'"{c}"' for c in contingencies]) + "]" - pfs = "[" + ", ".join([f'"{p}"' for p in plots_fields]) + "]" - time_args = "" - if start_time is not None and end_time is not None: - time_args = f", {start_time}, {end_time}" - self.RunScriptCommand(f'TSGetResults("{filename}", {mode}, {ctgs}, {pfs}{time_args});') + self._run_script("TSGetVCurveData", f'"{filename}"', f'"{filter_name}"') + + def TSGetResults( + self, + mode: Union[TSGetResultsMode, str], + contingencies: List[str], + plots_fields: List[str], + filename: Optional[str] = None, + start_time: float = None, + end_time: float = None, + ) -> Tuple[Optional[pd.DataFrame], Optional[pd.DataFrame]]: + """Retrieves transient stability results. + + If `filename` is None, creates a temporary file, reads the results + into DataFrames, deletes the temporary files, and returns (meta, + data). + """ + # 1. Determine File Path + is_temp_mode = filename is None + file_path = Path(get_temp_filepath(".csv")) if is_temp_mode else Path(filename) + + # PowerWorld requires forward slashes + pw_path_str = str(file_path).replace("\\", "/") + + # 2. Format Script Arguments + ctgs_str = format_list(contingencies, quote_items=True) + pfs_str = format_list(plots_fields, quote_items=True) + + # 3. Execute PowerWorld Command + self._run_script("TSGetResults", f'"{pw_path_str}"', mode, ctgs_str, pfs_str, start_time, end_time) + + if not is_temp_mode: + return None, None + + # 4. Retrieval and Cleanup + return load_ts_csv_results(file_path, delete_files=True) def TSJoinActiveCTGs( self, time_delay: float, delete_existing: bool, join_with_self: bool, filename: str = "", first_ctg: str = "Both" ): """Joins two lists of TSContingency objects.""" - de = "YES" if delete_existing else "NO" - jws = "YES" if join_with_self else "NO" - self.RunScriptCommand(f'TSJoinActiveCTGs({time_delay}, {de}, {jws}, "{filename}", {first_ctg});') + de = YesNo.from_bool(delete_existing) + jws = YesNo.from_bool(join_with_self) + self._run_script("TSJoinActiveCTGs", time_delay, de, jws, f'"{filename}"', first_ctg) def TSLoadRDB(self, filename: str, model_type: str, filter_name: str = ""): """Loads a SEL RDB file.""" - self.RunScriptCommand(f'TSLoadRDB("{filename}", {model_type}, "{filter_name}");') + self._run_script("TSLoadRDB", f'"{filename}"', model_type, f'"{filter_name}"') def TSLoadRelayCSV(self, filename: str, model_type: str, filter_name: str = ""): """Loads relay data from CSV.""" - self.RunScriptCommand(f'TSLoadRelayCSV("{filename}", {model_type}, "{filter_name}");') + self._run_script("TSLoadRelayCSV", f'"{filename}"', model_type, f'"{filter_name}"') def TSPlotSeriesAdd( self, @@ -393,80 +385,106 @@ def TSPlotSeriesAdd( attributes: str = "", ): """Adds one or multiple plot series to a new or existing plot definition.""" - self.RunScriptCommand( - f'TSPlotSeriesAdd("{plot_name}", {sub_plot_num}, {axis_group_num}, {object_type}, {field_name}, "{filter_name}", "{attributes}");' - ) + self._run_script("TSPlotSeriesAdd", f'"{plot_name}"', sub_plot_num, axis_group_num, object_type, field_name, f'"{filter_name}"', f'"{attributes}"') def TSRunResultAnalyzer(self, ctg_name: str = ""): """Run the Transient Result Analyzer.""" - self.RunScriptCommand(f'TSRunResultAnalyzer("{ctg_name}");') + self._run_script("TSRunResultAnalyzer", f'"{ctg_name}"') def TSRunUntilSpecifiedTime( self, ctg_name: str, stop_time: float = None, - step_size: float = None, - steps_in_cycles: bool = False, + step_size: float = 0.25, + steps_in_cycles: bool = True, reset_start_time: bool = False, steps_to_do: int = 0, ): """Allows manual control of the transient stability run.""" - opts = [] - if stop_time is not None: - opts.append(str(stop_time)) - if step_size is not None: - opts.append(str(step_size)) - if steps_in_cycles: - opts.append("YES") - else: - opts.append("NO") - if reset_start_time: - opts.append("YES") - else: - opts.append("NO") + # Construct the options list for the second argument + opt_list = [ + stop_time, + step_size, + YesNo.from_bool(steps_in_cycles), + YesNo.from_bool(reset_start_time) + ] if steps_to_do > 0: - opts.append(str(steps_to_do)) + opt_list.append(steps_to_do) - opt_str = "[" + ", ".join(opts) + "]" - self.RunScriptCommand(f'TSRunUntilSpecifiedTime("{ctg_name}", {opt_str});') + # Use pack_args to build the inner bracket content + opt_content = pack_args(*opt_list) + opt_str = f"[{opt_content}]" + + self._run_script("TSRunUntilSpecifiedTime", f'"{ctg_name}"', opt_str) def TSSaveBPA(self, filename: str, diff_case_modified_only: bool = False): - """Save transient stability data stored in the BPA IPF format.""" - dc = "YES" if diff_case_modified_only else "NO" - self.RunScriptCommand(f'TSSaveBPA("{filename}", {dc});') + """Saves transient stability data in the BPA IPF format. + + Parameters + ---------- + filename : str + Path for the output file. + diff_case_modified_only : bool, optional + If True, only saves models modified from base case. Defaults to False. + """ + dc = YesNo.from_bool(diff_case_modified_only) + self._run_script("TSSaveBPA", f'"{filename}"', dc) def TSSaveGE(self, filename: str, diff_case_modified_only: bool = False): - """Save transient stability data stored in the GE DYD format.""" - dc = "YES" if diff_case_modified_only else "NO" - self.RunScriptCommand(f'TSSaveGE("{filename}", {dc});') + """Saves transient stability data in the GE DYD format. + + Parameters + ---------- + filename : str + Path for the output file. + diff_case_modified_only : bool, optional + If True, only saves models modified from base case. Defaults to False. + """ + dc = YesNo.from_bool(diff_case_modified_only) + self._run_script("TSSaveGE", f'"{filename}"', dc) def TSSavePTI(self, filename: str, diff_case_modified_only: bool = False): - """Save transient stability data stored in the PTI DYR format.""" - dc = "YES" if diff_case_modified_only else "NO" - self.RunScriptCommand(f'TSSavePTI("{filename}", {dc});') + """Saves transient stability data in the PTI DYR format. + + Parameters + ---------- + filename : str + Path for the output file. + diff_case_modified_only : bool, optional + If True, only saves models modified from base case. Defaults to False. + """ + dc = YesNo.from_bool(diff_case_modified_only) + self._run_script("TSSavePTI", f'"{filename}"', dc) def TSSaveTwoBusEquivalent(self, filename: str, bus_identifier: str): """Save the two bus equivalent model of a specified bus to a PWB file.""" - self.RunScriptCommand(f'TSSaveTwoBusEquivalent("{filename}", {bus_identifier});') + self._run_script("TSSaveTwoBusEquivalent", f'"{filename}"', bus_identifier) def TSWriteModels(self, filename: str, diff_case_modified_only: bool = False): - """Save transient stability dynamic model records only the auxiliary file format.""" - dc = "YES" if diff_case_modified_only else "NO" - self.RunScriptCommand(f'TSWriteModels("{filename}", {dc});') + """Saves transient stability dynamic model records to an auxiliary file. + + Parameters + ---------- + filename : str + Name and path for the output file. Typically with ``.aux`` extension. + diff_case_modified_only : bool, optional + If True, only saves models that are new or have had a parameter modified + compared to the difference case tool base case. Defaults to False. + """ + dc = YesNo.from_bool(diff_case_modified_only) + self._run_script("TSWriteModels", f'"{filename}"', dc) def TSSetSelectedForTransientReferences( self, set_what: str, set_how: str, object_types: List[str], model_types: List[str] ): """Set the Custom Integer field or Selected field for objects referenced in a transient stability model.""" - objs = "[" + ", ".join(object_types) + "]" - models = "[" + ", ".join(model_types) + "]" - self.RunScriptCommand(f"TSSetSelectedForTransientReferences({set_what}, {set_how}, {objs}, {models});") + objs = format_list(object_types) + models = format_list(model_types) + self._run_script("TSSetSelectedForTransientReferences", set_what, set_how, objs, models) def TSSaveDynamicModels( self, filename: str, file_type: str, object_type: str, filter_name: str = "", append: bool = False ): """Save dynamics models for specified object types to file.""" - app = "YES" if append else "NO" - self.RunScriptCommand( - f'TSSaveDynamicModels("{filename}", {file_type}, {object_type}, "{filter_name}", {app});' - ) \ No newline at end of file + app = YesNo.from_bool(append) + self._run_script("TSSaveDynamicModels", f'"{filename}"', file_type, object_type, f'"{filter_name}"', app) diff --git a/esapp/saw/weather.py b/esapp/saw/weather.py index aa32d4c2..1ed2ea30 100644 --- a/esapp/saw/weather.py +++ b/esapp/saw/weather.py @@ -1,196 +1,309 @@ """Weather related functions.""" from typing import List +from ._enums import YesNo +from ._helpers import format_list + + class WeatherMixin: """Mixin for Weather functions.""" def WeatherLimitsGenUpdate(self, update_max: bool = True, update_min: bool = True): """ - Updates generator MW limits based on weather data. + Update generator MW limits based on weather data. + + Updates generator MW limits using weather limit curves and weather + station temperature data. This allows for temperature-dependent + generator capacity modeling. + + This is a wrapper for the ``WeatherLimitsGenUpdate`` script command. Parameters ---------- update_max : bool, optional - If True, updates the maximum MW limit. Defaults to True. + If True, updates the Max MW limit based on the calculated + weather-dependent MWMax limit. Defaults to True. update_min : bool, optional - If True, updates the minimum MW limit. Defaults to True. + If True, updates the Min MW limit based on the calculated + weather-dependent MWMin limit. Defaults to True. Returns ------- str The response from the PowerWorld script command. """ - umax = "YES" if update_max else "NO" - umin = "YES" if update_min else "NO" - return self.RunScriptCommand(f"WeatherLimitsGenUpdate({umax}, {umin});") + umax = YesNo.from_bool(update_max) + umin = YesNo.from_bool(update_min) + return self._run_script("WeatherLimitsGenUpdate", umax, umin) def TemperatureLimitsBranchUpdate( self, rating_set_precedence: str = "NORMAL", normal_rating_set: str = "DEFAULT", ctg_rating_set: str = "DEFAULT" ): """ - Updates branch limits based on temperature. + Update branch limits based on temperature limit curves. + + Updates branch thermal limits using temperature limit curves and + weather station temperature data. This allows for dynamic line + rating based on ambient conditions. + + This is a wrapper for the ``TemperatureLimitsBranchUpdate`` script command. Parameters ---------- rating_set_precedence : str, optional - Determines which rating set takes precedence. Defaults to "NORMAL". + Determines which rating set takes precedence when the same rating + set is specified for both normal and CTG curves. Valid values are + "NORMAL", "CTG", or blank (same as "NORMAL"). Defaults to "NORMAL". normal_rating_set : str, optional - The rating set to use for normal operation. Defaults to "DEFAULT". + Which limit to update with the normal temperature-dependent limit. + Valid values are "DEFAULT" (uses Limit Monitoring Settings), + "NO" (don't update), or "A" through "O". Defaults to "DEFAULT". ctg_rating_set : str, optional - The rating set to use for contingency operation. Defaults to "DEFAULT". + Which limit to update with the contingency temperature-dependent + limit. Valid values are "DEFAULT", "NO", or "A" through "O". + Defaults to "DEFAULT". Returns ------- str The response from the PowerWorld script command. """ - return self.RunScriptCommand( - f"TemperatureLimitsBranchUpdate({rating_set_precedence}, {normal_rating_set}, {ctg_rating_set});" - ) + return self._run_script("TemperatureLimitsBranchUpdate", rating_set_precedence, normal_rating_set, ctg_rating_set) def WeatherPFWModelsSetInputs(self): """ - Sets inputs for PFWModels. + Set inputs for all case PFWModels without applying them. + + Sets the inputs for all Power Flow Weather (PFW) models in the case, + but does not apply them to the power flow case. Usually these inputs + require the availability of weather measurements. + + This is a wrapper for the ``WeatherPFWModelsSetInputs`` script command. Returns ------- str The response from the PowerWorld script command. + + See Also + -------- + WeatherPFWModelsSetInputsAndApply : Sets inputs and applies to case. """ - return self.RunScriptCommand("WeatherPFWModelsSetInputs;") + return self._run_script("WeatherPFWModelsSetInputs") def WeatherPFWModelsSetInputsAndApply(self, solve_pf: bool = True): """ - Sets inputs for PFWModels and applies them to the case. + Set inputs for PFWModels and apply them to the case. + + Sets the inputs for all Power Flow Weather (PFW) models and applies + them to the power flow case. Usually these inputs require the + availability of weather measurements, which can be loaded using + ``WeatherPWWLoadForDateTimeUTC``. + + When PFWModels are applied, some case values may be changed (e.g., + generator MaxMW fields). Use ``WeatherPFWModelsRestoreDesignValues`` + to restore these values to the design values. + + This is a wrapper for the ``WeatherPFWModelsSetInputsAndApply`` script command. Parameters ---------- solve_pf : bool, optional - If True, solves the power flow after applying inputs. Defaults to True. + If True, solves the power flow using the default method after + applying inputs. If False, you can call another solution command + (e.g., SolvePowerFlow or SolvePrimalLP). Defaults to True. Returns ------- str The response from the PowerWorld script command. + + See Also + -------- + WeatherPFWModelsRestoreDesignValues : Restores values changed by this method. + WeatherPWWLoadForDateTimeUTC : Loads weather data for a specific time. """ - spf = "YES" if solve_pf else "NO" - return self.RunScriptCommand(f"WeatherPFWModelsSetInputsAndApply({spf});") + spf = YesNo.from_bool(solve_pf) + return self._run_script("WeatherPFWModelsSetInputsAndApply", spf) def WeatherPWWFileAllMeasValid(self, filename: str, field_list: List[str], start_time: str = "", end_time: str = ""): """ - Checks if PWW file has valid measurements. + Check if a PWW file has valid measurements for specified fields. + + Returns true if the specified PWW file: 1) has all the specified + fields, and 2) all the measurements for those fields are valid. + This command only works with version 2 or greater PWW files. + + This is a wrapper for the ``WeatherPWWFileAllMeasValid`` script command. Parameters ---------- filename : str - The path to the PWW file. + The path to the PWW file to check. field_list : List[str] - List of fields to check. + List of fields to check. At least one field must be provided. + Valid fields include: TEMP, DEWPOINT, WINDSPEED, WINDSPEED100, + GLOBALHORZIRRAD, DIRECTHORZIRRAD, WINDGUST, SMOKEVERTINT, + PRECIPRATE, PRECIPPERCFROZEN. start_time : str, optional - Start time for the validity check. Defaults to "". + Start datetime in ISO8601 format. If provided, only returns + true if the PWW file's starting datetime is at or before this. + Defaults to "" (no start time check). end_time : str, optional - End time for the validity check. Defaults to "". + End datetime in ISO8601 format. If provided, only returns true + if the PWW file's ending datetime is at or after this. + Defaults to "" (no end time check). Returns ------- str The response from the PowerWorld script command. """ - fields = "[" + ", ".join(field_list) + "]" - return self.RunScriptCommand(f'WeatherPWWFileAllMeasValid("{filename}", {fields}, {start_time}, {end_time});') + fields = format_list(field_list) + return self._run_script("WeatherPWWFileAllMeasValid", f'"{filename}"', fields, start_time or None, end_time or None) def WeatherPFWModelsRestoreDesignValues(self): """ - Restores case values changed by WeatherPFWModels. + Restore case values changed by PFWModels to their design values. + + Restores the case values (such as generator MaxMW fields) that were + changed by ``WeatherPFWModelsSetInputsAndApply`` back to the design + values specified with each PFWModel. + + This is a wrapper for the ``WeatherPFWModelsRestoreDesignValues`` script command. Returns ------- str The response from the PowerWorld script command. + + See Also + -------- + WeatherPFWModelsSetInputsAndApply : The method whose changes this restores. """ - return self.RunScriptCommand("WeatherPFWModelsRestoreDesignValues;") + return self._run_script("WeatherPFWModelsRestoreDesignValues") def WeatherPWWLoadForDateTimeUTC(self, iso_datetime: str): """ - Loads weather for a specific date and time. + Load weather data for a specific date and time. + + Loads weather data by searching the directory (and optionally + subdirectories) set with ``WeatherPWWSetDirectory``. + + This is a wrapper for the ``WeatherPWWLoadForDateTimeUTC`` script command. Parameters ---------- iso_datetime : str - The date and time in ISO format (UTC). + The desired date and time in ISO8601 format. This should be + either a UTC value (e.g., "2024-03-06T18:00Z") or local time + with time zone offset (e.g., "2024-03-06T12:00-06"). Returns ------- str The response from the PowerWorld script command. + + See Also + -------- + WeatherPWWSetDirectory : Sets the directory to search for PWW files. """ - return self.RunScriptCommand(f'WeatherPWWLoadForDateTimeUTC("{iso_datetime}");') + return self._run_script("WeatherPWWLoadForDateTimeUTC", f'"{iso_datetime}"') def WeatherPWWSetDirectory(self, directory: str, include_subdirs: bool = True): """ - Sets the directory to search for PWW files. + Set the directory to search for PWW weather files. + + Specifies the directory (and optionally its subdirectories) to search + when loading weather information from PWW files. + + This is a wrapper for the ``WeatherPWWSetDirectory`` script command. Parameters ---------- directory : str - The directory path. + Directory path that contains the PWW files. include_subdirs : bool, optional - If True, includes subdirectories in the search. Defaults to True. + If True, includes subdirectories in the search path. + Defaults to True. Returns ------- str The response from the PowerWorld script command. + + See Also + -------- + WeatherPWWLoadForDateTimeUTC : Loads weather data using this directory. """ - sub = "YES" if include_subdirs else "NO" - return self.RunScriptCommand(f'WeatherPWWSetDirectory("{directory}", {sub});') + sub = YesNo.from_bool(include_subdirs) + return self._run_script("WeatherPWWSetDirectory", f'"{directory}"', sub) def WeatherPWWFileCombine2(self, source1: str, source2: str, dest: str): """ - Combines two PWW files. + Combine two PWW weather files into one. + + Merges two PWW files, provided they have the same weather stations + and non-overlapping datetime ranges. The source2 file should be + the second file chronologically. + + This is a wrapper for the ``WeatherPWWFileCombine2`` script command. Parameters ---------- source1 : str - Path to the first source file. + Path to the first source file (first chronologically). Must exist. + Should have ".pww" extension or no extension. source2 : str - Path to the second source file. + Path to the second source file (second chronologically). Must exist. + Should have ".pww" extension or no extension. dest : str - Path to the destination file. + Path to the destination file. Does not need to exist and can be + the same as either source file. Returns ------- str The response from the PowerWorld script command. """ - return self.RunScriptCommand(f'WeatherPWWFileCombine2("{source1}", "{source2}", "{dest}");') + return self._run_script("WeatherPWWFileCombine2", f'"{source1}"', f'"{source2}"', f'"{dest}"') def WeatherPWWFileGeoReduce( self, source: str, dest: str, min_lat: float, max_lat: float, min_lon: float, max_lon: float ): """ - Reduces the geographic scope of a PWW file. + Reduce the geographic scope of a PWW file. + + Extracts weather data only for the geographic region bounded by the + specified latitude and longitude coordinates. Rectangles spanning + the international date line are not allowed. + + This is a wrapper for the ``WeatherPWWFileGeoReduce`` script command. Parameters ---------- source : str - Path to the source PWW file. + Path to the source PWW file. Must exist. Should have ".pww" + extension or no extension. dest : str - Path to the destination PWW file. + Path to the destination PWW file. Does not need to exist and + can be the same as the source file. min_lat : float - Minimum latitude. + Minimum latitude for the bounding rectangle. Must be >= -90 + and less than max_lat. max_lat : float - Maximum latitude. + Maximum latitude for the bounding rectangle. Must be <= 90 + and greater than min_lat. min_lon : float - Minimum longitude. + Minimum longitude for the bounding rectangle. Must be >= -180 + and less than max_lon. max_lon : float - Maximum longitude. + Maximum longitude for the bounding rectangle. Must be <= 180 + and greater than min_lon. Returns ------- str The response from the PowerWorld script command. """ - return self.RunScriptCommand( - f'WeatherPWWFileGeoReduce("{source}", "{dest}", {min_lat}, {max_lat}, {min_lon}, {max_lon});' - ) \ No newline at end of file + return self._run_script("WeatherPWWFileGeoReduce", f'"{source}"', f'"{dest}"', min_lat, max_lat, min_lon, max_lon) diff --git a/esapp/utils/__init__.py b/esapp/utils/__init__.py index fd9234e7..99b82c95 100644 --- a/esapp/utils/__init__.py +++ b/esapp/utils/__init__.py @@ -1,8 +1,36 @@ -from .exceptions import * -from .mathtools import * -from .misc import * -from .mesh import * -from .decorators import * -from .map import * -from .plotwavelet import * -from .b3d import * \ No newline at end of file +""" +ESAplus utilities module. + +Provides tools for: +- Binary data formats (B3D electric field data) +- Analysis modules (GIC, network topology, dynamics, contingency) +- Function decorators for debugging and profiling +""" + +from .misc import timing + +from .b3d import B3D + +from .gic import GIC +from .contingency import ContingencyBuilder, SimAction +from .network import Network, BranchType +from .dynamics import TSWatch, process_ts_results, get_ts_results + +__all__ = [ + # misc + 'timing', + # b3d + 'B3D', + # gic + 'GIC', + # contingency + 'ContingencyBuilder', + 'SimAction', + # network + 'Network', + 'BranchType', + # dynamics + 'TSWatch', + 'process_ts_results', + 'get_ts_results', +] diff --git a/esapp/utils/b3d.py b/esapp/utils/b3d.py index a4493e25..4f66416a 100644 --- a/esapp/utils/b3d.py +++ b/esapp/utils/b3d.py @@ -1,45 +1,65 @@ -from numpy import array, zeros, frombuffer, stack, meshgrid, linspace, ndarray -from numpy import single, uint32, double, uint32, uint32 +""" +Binary 3D (B3D) file format handler for electric field data. + +The B3D format stores time-varying electric field data (Ex, Ey) at +geographic locations. It is used by PowerWorld for GIC electric field +input. This module supports version 4 with variable location points +and variable time points. +""" + +from __future__ import annotations + +import numpy as np +from numpy import array, zeros, frombuffer, stack, meshgrid, linspace +from numpy import single, uint32, double + +__all__ = ['B3D'] + +_B3D_CODE = 34280 +_B3D_VERSION = 4 + class B3D: """ - Class for handling B3D (Binary 3D) file format for electric field data. - """ + Handler for the B3D (Binary 3D) electric field file format. - def __init__(self, fname=None): - """ - Initialize the B3D object. + Supports reading, writing, and constructing B3D files containing + time-varying electric field vectors at geographic locations. - Parameters - ---------- - fname : str, optional - Path to a B3D file to load. Defaults to None. - """ - - # This function creates a default, tiny B3D object that can be set with data + Parameters + ---------- + fname : str, optional + Path to a B3D file to load on initialization. + + Attributes + ---------- + comment : str + Metadata comment string. + time_0 : int + Reference time origin. + time_units : int + Time unit code (0 = milliseconds). + lat, lon : np.ndarray + 1D arrays of geographic coordinates (float64). + grid_dim : list of int + Grid dimensions [nx, ny]. + time : np.ndarray + 1D array of time points (uint32). + ex, ey : np.ndarray + 2D arrays of electric field components, shape (nt, n), dtype float32. + """ - # Comment should be a single string which will be stored in the metadata of the B3D file + def __init__(self, fname: str | None = None) -> None: self.comment = "Default 2x2 grid with 3 time points" - self.time_0 = 0 + self.time_0 = 0 self.time_units = 0 - # lat and lon should be a 1-dimensional np arrays of doubles - # They must be the same length (n) - # Only variable location point formats are supported here self.lat = array([30.5, 30.5, 31.0, 31.0]) self.lon = array([-84.5, -85.0, -84.5, -85.0]) - - # Optional parameter to describe how the lat and lon points are organized into a grid - # If invalid, it will be updated to n-by-1 self.grid_dim = [2, 2] - - # Time array should be a 1-dimensioal np array of integers. By default they are milliseconds - # Only variable location point formats are supported here - self.time = array([0, 1000, 2000], dtype=uint32) - - # Data: Each of these should be 2-dimensional np arrays of singles - # First dimension is the time point, with length nt - # Second dimension is the location point, with length n + + self.time = array([0, 1000, 2000], dtype=uint32) + self.ex = zeros([3, 4], dtype=single) self.ey = zeros([3, 4], dtype=single) @@ -47,188 +67,219 @@ def __init__(self, fname=None): self.load_b3d_file(fname) @classmethod - def from_mesh(cls, long, lat, ex: ndarray, ey: ndarray, times=None, comment="GWB Electric Field Data"): + def from_mesh( + cls, + long: np.ndarray, + lat: np.ndarray, + ex: np.ndarray, + ey: np.ndarray, + times: np.ndarray | None = None, + comment: str = "GWB Electric Field Data", + ) -> B3D: """ - Convert mesh-grid style efield data to B3D - Only Supporting Static Fields at the moment. + Construct a B3D from mesh-grid style electric field data. + + Currently supports static (single time step) fields only. Parameters ---------- long : np.ndarray - Array of longitudes, shape (n, ). + Array of longitudes, shape (n,). lat : np.ndarray - Array of latitudes, shape (m, ). + Array of latitudes, shape (m,). ex : np.ndarray - Mesh array of X-Component Electric Field, shape (n, m). + X-component electric field, shape (n, m). ey : np.ndarray - Mesh array of Y-Component Electric Field, shape (n, m). + Y-component electric field, shape (n, m). times : np.ndarray, optional - Time points. Defaults to None. - comment : str, optional - Comment string for metadata. Defaults to "GWB Electric Field Data". + Time points. Currently unused. + comment : str, default "GWB Electric Field Data" + Metadata comment string. Returns ------- B3D Initialized B3D object. """ - b3d = cls() b3d.comment = comment - # n x m Geographic - n = len(long) + n = len(long) m = len(lat) - nt = n*m + nt = n * m X, Y = meshgrid(long, lat) b3d.lon = X.reshape(nt, order='F') b3d.lat = Y.reshape(nt, order='F') b3d.grid_dim = [n, m] - # Time Periods - periods = 1 - b3d.time = linspace(0,10, periods, dtype=uint32) + b3d.time = linspace(0, 10, 1, dtype=uint32) - # Prepare Efield - eshape = (1,nt) - eorder = 'F' - b3d.ex = ex.reshape(eshape, order=eorder).astype(single) - b3d.ey = ey.reshape(eshape, order=eorder).astype(single) + eshape = (1, nt) + b3d.ex = ex.reshape(eshape, order='F').astype(single) + b3d.ey = ey.reshape(eshape, order='F').astype(single) return b3d - def write_b3d_file(self, fname): + def write_b3d_file(self, fname: str) -> None: """ - Write the B3D object to a file. + Write the B3D data to a binary file. Parameters ---------- fname : str - The path to write the file to. + Output file path. + + Raises + ------ + ValueError + If data arrays have inconsistent shapes or incorrect dtypes. """ with open(fname, "wb") as f: n = self.lat.shape[0] nt = self.time.shape[0] + if self.lon.shape[0] != n: - raise Exception("Lat and lon must be same length!") + raise ValueError("lat and lon must have the same length") if self.lat.dtype != double: - raise Exception("Latitude must by np array of doubles") + raise ValueError("lat must be a float64 (double) array") if self.lon.dtype != double: - raise Exception("Latitude must by np array of doubles") + raise ValueError("lon must be a float64 (double) array") if self.time.dtype != uint32: - raise Exception("Time must by np array of uint32") + raise ValueError("time must be a uint32 array") if self.ex.dtype != single: - raise Exception("Ex must by np array of singles") + raise ValueError("ex must be a float32 (single) array") if self.ey.dtype != single: - raise Exception("Ey must by np array of singles") + raise ValueError("ey must be a float32 (single) array") if self.ex.shape[1] != n: - raise Exception("Ex dimension 2 must be length of latitude") + raise ValueError(f"ex columns ({self.ex.shape[1]}) must match location count ({n})") if self.ey.shape[1] != n: - raise Exception("Ey dimension 2 must be length of latitude") + raise ValueError(f"ey columns ({self.ey.shape[1]}) must match location count ({n})") if self.ex.shape[0] != nt: - raise Exception("Ex dimension 1 must be length of time") + raise ValueError(f"ex rows ({self.ex.shape[0]}) must match time count ({nt})") if self.ey.shape[0] != nt: - raise Exception("Ey dimension 1 must be length of time") - f.write((34280).to_bytes(4, byteorder="little")) # Code - f.write((4).to_bytes(4, byteorder="little")) # Version 4 - f.write((2).to_bytes(4, byteorder="little")) # Two metastrings + raise ValueError(f"ey rows ({self.ey.shape[0]}) must match time count ({nt})") + + def _write_int(val: int) -> None: + f.write(val.to_bytes(4, byteorder="little")) + + _write_int(_B3D_CODE) + _write_int(_B3D_VERSION) + _write_int(2) # Two meta strings meta = self.comment + "\0" + str(self.grid_dim) + "\0" f.write(meta.encode('ascii')) - f.write((2).to_bytes(4, byteorder="little")) # 2 float channels - f.write((0).to_bytes(4, byteorder="little")) # 0 byte channels - f.write((1).to_bytes(4, byteorder="little")) # Variable locations - f.write((n).to_bytes(4, byteorder="little")) # Number of lat/lons + _write_int(2) # 2 float channels (ex, ey) + _write_int(0) # 0 byte channels + _write_int(1) # Variable location format + _write_int(n) + loc0 = zeros(n, dtype=double) - loc_data = stack([self.lon, self.lat, loc0]).transpose().reshape(1,n*3).tobytes() + loc_data = stack([self.lon, self.lat, loc0]).transpose().reshape(1, n * 3).tobytes() f.write(loc_data) - f.write((self.time_0).to_bytes(4, byteorder="little")) # Time 0 - f.write((self.time_units).to_bytes(4, byteorder="little")) # Time units code - f.write((0).to_bytes(4, byteorder="little")) # Time offset not supported - f.write((0).to_bytes(4, byteorder="little")) # Time step - f.write((nt).to_bytes(4, byteorder="little")) # Number of time points + + _write_int(self.time_0) + _write_int(self.time_units) + _write_int(0) # Time offset (not supported) + _write_int(0) # Time step (variable) + _write_int(nt) f.write(self.time.tobytes()) - exd = self.ex.reshape(n*nt) - eyd = self.ey.reshape(n*nt) - f.write(stack([exd, eyd]).transpose().reshape(n*nt*2).tobytes()) - def load_b3d_file(self, fname): + exd = self.ex.reshape(n * nt) + eyd = self.ey.reshape(n * nt) + f.write(stack([exd, eyd]).transpose().reshape(n * nt * 2).tobytes()) + + def load_b3d_file(self, fname: str) -> None: """ - Load a B3D file into the object. + Load a B3D binary file into this object. Parameters ---------- fname : str - The path to the B3D file. + Path to the B3D file. + + Raises + ------ + IOError + If the file is not a valid B3D file or uses an unsupported format. """ with open(fname, "rb") as f: b = f.read() code = int.from_bytes(b[0:4], "little") - if code != 34280: - raise Exception("Invalid B3D file") + if code != _B3D_CODE: + raise IOError(f"Invalid B3D file (code {code}, expected {_B3D_CODE})") + version = int.from_bytes(b[4:8], "little") - if version == 4: - nmeta = int.from_bytes(b[8:12], "little") - self.grid_dim = [0, 0] - x1 = x2 = 12 - meta_strings = [] - for _ in range(nmeta): - while b[x2] != 0: - x2 += 1 - meta_strings.append(b[x1:x2].decode("ascii")) + if version != _B3D_VERSION: + raise IOError(f"Unsupported B3D version {version} (expected {_B3D_VERSION})") + + nmeta = int.from_bytes(b[8:12], "little") + self.grid_dim = [0, 0] + x1 = x2 = 12 + meta_strings = [] + for _ in range(nmeta): + while b[x2] != 0: x2 += 1 - x1 = x2 - if nmeta <= 0: - self.comment = "No comment" - else: - self.comment = meta_strings[0] - if nmeta >= 2: - try: - dim_text = meta_strings[1].strip("[]") - if "," in dim_text: - self.grid_dim = [int(x) for x in dim_text.split(',')] - else: - self.grid_dim = [int(x) for x in dim_text.split()] - assert(len(self.grid_dim) == 2) - except: - self.grid_dim = [0,0] - float_channels = int.from_bytes(b[x2:x2+4], "little") - byte_channels = int.from_bytes(b[x2+4:x2+8], "little") - loc_format = int.from_bytes(b[x2+8:x2+12], "little") - if float_channels < 2: - raise Exception("Only B3D files with at least 2 float channels" - + " are supported") - if loc_format != 1: - raise Exception("Only location format 1 is supported") - n = int.from_bytes(b[x2+12:x2+16], "little") - if self.grid_dim[0]*self.grid_dim[1] != n: - self.grid_dim = [n, 1] - x3 = x2 + 16 + 3*8*n - loc_data = frombuffer(b[x2+16:x3],dtype=double).reshape([n, 3]).copy() - self.lon = loc_data[:,0] - self.lat = loc_data[:,1] - self.time_0 = int.from_bytes(b[x3:x3+4], "little") - self.time_units = int.from_bytes(b[x3+4:x3+8], "little") - self.time_offset = int.from_bytes(b[x3+8:x3+12], "little") - time_step = int.from_bytes(b[x3+12:x3+16], "little") - nt = int.from_bytes(b[x3+16:x3+20], "little") - if time_step != 0: - raise Exception("Only B3D files with variable time points are supported") - x4 = x3 + 20 + 4*nt - self.time = frombuffer(b[x3+20:x4], dtype=uint32).copy() - npts = n*nt - if float_channels == 2 and byte_channels == 0: - x5 = x4 + 4*2*n*nt - raw_exy = frombuffer(b[x4:x5], dtype=single) - else: - bxy = bytearray(npts*8) - for i in range(npts): - x5 = x4 + i*(float_channels*4+byte_channels) - bxy[i*8:(i+1)*8] = b[x5:x5+8] - raw_exy = frombuffer(bxy, dtype=single) - edata = raw_exy.reshape([nt, n, 2]).copy() - self.ex = edata[:,:,0] - self.ey = edata[:,:,1] - + meta_strings.append(b[x1:x2].decode("ascii")) + x2 += 1 + x1 = x2 + + if nmeta <= 0: + self.comment = "No comment" else: - raise Exception(f"Version {version} not supported") \ No newline at end of file + self.comment = meta_strings[0] + if nmeta >= 2: + try: + dim_text = meta_strings[1].strip("[]") + if "," in dim_text: + self.grid_dim = [int(x) for x in dim_text.split(',')] + else: + self.grid_dim = [int(x) for x in dim_text.split()] + if len(self.grid_dim) != 2: + raise ValueError("grid_dim must have exactly 2 elements") + except (ValueError, IndexError): + self.grid_dim = [0, 0] + + float_channels = int.from_bytes(b[x2:x2+4], "little") + byte_channels = int.from_bytes(b[x2+4:x2+8], "little") + loc_format = int.from_bytes(b[x2+8:x2+12], "little") + + if float_channels < 2: + raise IOError("Only B3D files with at least 2 float channels are supported") + if loc_format != 1: + raise IOError(f"Only location format 1 is supported (got {loc_format})") + + n = int.from_bytes(b[x2+12:x2+16], "little") + if self.grid_dim[0] * self.grid_dim[1] != n: + self.grid_dim = [n, 1] + + x3 = x2 + 16 + 3 * 8 * n + loc_data = frombuffer(b[x2+16:x3], dtype=double).reshape([n, 3]).copy() + self.lon = loc_data[:, 0] + self.lat = loc_data[:, 1] + + self.time_0 = int.from_bytes(b[x3:x3+4], "little") + self.time_units = int.from_bytes(b[x3+4:x3+8], "little") + self.time_offset = int.from_bytes(b[x3+8:x3+12], "little") + time_step = int.from_bytes(b[x3+12:x3+16], "little") + nt = int.from_bytes(b[x3+16:x3+20], "little") + + if time_step != 0: + raise IOError("Only B3D files with variable time points are supported") + + x4 = x3 + 20 + 4 * nt + self.time = frombuffer(b[x3+20:x4], dtype=uint32).copy() + npts = n * nt + + if float_channels == 2 and byte_channels == 0: + x5 = x4 + 4 * 2 * n * nt + raw_exy = frombuffer(b[x4:x5], dtype=single) + else: + bxy = bytearray(npts * 8) + for i in range(npts): + x5 = x4 + i * (float_channels * 4 + byte_channels) + bxy[i * 8:(i + 1) * 8] = b[x5:x5 + 8] + raw_exy = frombuffer(bxy, dtype=single) + + edata = raw_exy.reshape([nt, n, 2]).copy() + self.ex = edata[:, :, 0] + self.ey = edata[:, :, 1] diff --git a/esapp/utils/contingency.py b/esapp/utils/contingency.py new file mode 100644 index 00000000..d25afec9 --- /dev/null +++ b/esapp/utils/contingency.py @@ -0,0 +1,156 @@ +""" +Contingency Builder Utilities +============================= + +Provides fluent builder tools for constructing transient stability +contingency event sequences. + +Classes +------- +ContingencyBuilder + Fluent builder for TS contingencies with method chaining. +SimAction + Enumeration of standard simulation action strings. +""" + +from enum import Enum +from typing import List, Tuple, Union, Any + +from pandas import DataFrame + +__all__ = ['ContingencyBuilder', 'SimAction'] + + +class SimAction(str, Enum): + """Enumeration of standard simulation actions to prevent magic string errors.""" + FAULT_3PB = "FAULT 3PB SOLID" + CLEAR_FAULT = "CLEARFAULT" + OPEN = "OPEN" + CLOSE = "CLOSE" + +class ContingencyBuilder: + """ + Fluent builder for Transient Stability (TS) contingencies. + + Constructs a timeline of events to be simulated using method chaining. + + Parameters + ---------- + name : str + Unique name for the contingency. + runtime : float, optional + Simulation duration in seconds (default: 10.0). + + Attributes + ---------- + name : str + The contingency name. + runtime : float + Simulation end time in seconds. + + Example + ------- + >>> builder = ContingencyBuilder("GenTrip", runtime=5.0) + >>> builder.at(1.0).fault_bus("101").at(1.1).clear_fault("101") + """ + + def __init__(self, name: str, runtime: float = 10.0): + self.name = name + self.runtime = runtime + self._current_time: float = 0.0 + self._events: List[Tuple[float, str, str, str]] = [] + + def at(self, t: float) -> 'ContingencyBuilder': + """ + Set the current time cursor for subsequent events. + + Parameters + ---------- + t : float + Time in seconds (must be non-negative). + + Returns + ------- + ContingencyBuilder + Self for method chaining. + + Raises + ------ + ValueError + If time is negative. + """ + if t < 0: + raise ValueError(f"Time cannot be negative: {t}") + self._current_time = t + return self + + def add_event(self, obj_type: str, who: str, action: Union[str, SimAction]) -> 'ContingencyBuilder': + """ + Add a generic event at the current time cursor. + + Parameters + ---------- + obj_type : str + PowerWorld object type (e.g., "Bus", "Gen", "Branch"). + who : str + Object identifier string. + action : Union[str, SimAction] + Action to perform (e.g., SimAction.OPEN or "OPEN"). + + Returns + ------- + ContingencyBuilder + Self for method chaining. + """ + act_str = action.value if isinstance(action, SimAction) else str(action) + self._events.append((self._current_time, obj_type, who, act_str)) + return self + + def fault_bus(self, bus: Any) -> 'ContingencyBuilder': + """Apply a 3-phase solid fault to a bus at the current time.""" + return self.add_event("Bus", str(bus), SimAction.FAULT_3PB) + + def clear_fault(self, bus: Any) -> 'ContingencyBuilder': + """Clear the fault at a bus at the current time.""" + return self.add_event("Bus", str(bus), SimAction.CLEAR_FAULT) + + def trip_gen(self, bus: Any, gid: str = "1") -> 'ContingencyBuilder': + """Trip (open) a generator at the current time.""" + return self.add_event("Gen", f"{bus} '{gid}'", SimAction.OPEN) + + def trip_branch(self, f_bus: Any, t_bus: Any, ckt: str = "1") -> 'ContingencyBuilder': + """Trip (open) a branch at the current time.""" + return self.add_event("Branch", f"{f_bus} {t_bus} '{ckt}'", SimAction.OPEN) + + def to_dataframes(self) -> Tuple[DataFrame, DataFrame]: + """ + Generates DataFrames matching the ESA GObject schemas. + + Returns: + Tuple[DataFrame, DataFrame]: (Contingency Definition, Element Definitions) + """ + # 1. Contingency Header + ctg_df = DataFrame({ + 'TSCTGName': [self.name], + 'StartTime': [0.0], + 'EndTime': [self.runtime], + 'CTGSkip': ['NO'] + }) + + # 2. Elements + if not self._events: + return ctg_df, DataFrame() + + # Vectorized list creation is generally fast enough here + ele_rows = [ + { + 'TSCTGName': self.name, + 'TSEventString': f"{action} {obj_type} {who}", + 'TSTimeInSeconds': t, + 'WhoAmI': f"{obj_type} {who}", + 'TSTimeInCycles': t * 60.0, + } + for t, obj_type, who, action in self._events + ] + + return ctg_df, DataFrame(ele_rows) diff --git a/esapp/utils/decorators.py b/esapp/utils/decorators.py deleted file mode 100644 index 179ef962..00000000 --- a/esapp/utils/decorators.py +++ /dev/null @@ -1,13 +0,0 @@ -from functools import wraps -from time import time - -def timing(f): - @wraps(f) - def wrap(*args, **kw): - ts = time() - result = f(*args, **kw) - te = time() - print('%r took: %2.4f sec' % \ - (f.__name__, te-ts)) - return result - return wrap \ No newline at end of file diff --git a/esapp/utils/dynamics.py b/esapp/utils/dynamics.py new file mode 100644 index 00000000..28f606e1 --- /dev/null +++ b/esapp/utils/dynamics.py @@ -0,0 +1,152 @@ +""" +Transient stability simulation utilities. + +Provides field-watching, result retrieval, and result processing +for transient stability simulations in PowerWorld Simulator. +""" + +import logging +import numpy as np +from typing import List, Tuple, Dict, Any, Type, Optional + +from pandas import DataFrame + +from ..components import GObject + +logger = logging.getLogger(__name__) + +__all__ = ['TSWatch', 'process_ts_results', 'get_ts_results'] + + +class TSWatch: + """ + Manages TS result field registration and environment preparation. + + Example + ------- + >>> tsw = TSWatch() + >>> tsw.watch(Gen, [TS.Gen.P, TS.Gen.W]) + >>> fields = tsw.prepare(pw) + """ + + def __init__(self): + self._watch_fields: Dict[Type[GObject], List[str]] = {} + + def watch(self, gtype: Type[GObject], fields: List[Any]) -> 'TSWatch': + """ + Register fields to record during simulation for a specific object type. + + Parameters + ---------- + gtype : Type[GObject] + The GObject type to watch (e.g., Gen, Bus, Branch). + fields : list + List of TS field constants or field name strings. + + Returns + ------- + TSWatch + Self for method chaining. + """ + field_names = [str(f) for f in fields] + self._watch_fields[gtype] = field_names + return self + + def prepare(self, pw) -> List[str]: + """ + Configure the ESA environment for simulation and build retrieval fields. + + Parameters + ---------- + pw : PowerWorld + An initialized PowerWorld instance. + + Returns + ------- + List[str] + List of retrieval field strings for TSGetResults. + """ + fields = [] + for gtype, flds in self._watch_fields.items(): + pw.esa.TSResultStorageSetAll(object=gtype.TYPE, value=True) + + objs = pw[gtype, ['ObjectID']] + + if objs is not None and not objs.empty: + valid_ids = objs['ObjectID'].dropna().unique() + for oid in valid_ids: + fields.extend(f"{oid} | {f}" for f in flds) + + return fields + + @property + def fields(self) -> Dict[Type[GObject], List[str]]: + """Currently registered watch fields.""" + return self._watch_fields + + +def get_ts_results(esa, ctg: str, fields: List[str]) -> Tuple[Optional[DataFrame], Optional[DataFrame]]: + """ + Retrieve results for a single contingency using TSGetResults. + + Parameters + ---------- + esa : SAW + The SAW (SimAuto Wrapper) instance. + ctg : str + Contingency name. + fields : List[str] + List of fields/plots to retrieve. + + Returns + ------- + Tuple[Optional[DataFrame], Optional[DataFrame]] + Tuple of (Metadata DataFrame, Data DataFrame), or (None, None). + """ + result = esa.TSGetResults("SEPARATE", [ctg], fields) + if result is None: + return None, None + return result + + +def process_ts_results(meta: DataFrame, df: DataFrame, ctg_name: str) -> Tuple[DataFrame, DataFrame]: + """ + Clean and format raw transient stability simulation results. + + Parameters + ---------- + meta : DataFrame + Metadata DataFrame from TSGetResults. + df : DataFrame + Time-series data DataFrame from TSGetResults. + ctg_name : str + Name of the contingency (added as a column to metadata). + + Returns + ------- + Tuple[DataFrame, DataFrame] + (Processed metadata, Processed time-series data). + """ + if df is None or df.empty: + return DataFrame(), DataFrame() + + if "time" in df.columns: + df = df.set_index("time") + + valid_headers = set(meta['ColHeader']) if 'ColHeader' in meta.columns else set() + existing_cols = [c for c in df.columns if c in valid_headers] + + if not existing_cols: + return DataFrame(), DataFrame() + + df_processed = df[existing_cols].astype(np.float32) + + meta = meta.rename(columns={ + 'ObjectType': 'Object', + 'PrimaryKey': 'ID-A', + 'SecondaryKey': 'ID-B', + 'VariableName': 'Metric' + }) + meta["Contingency"] = ctg_name + + return meta, df_processed diff --git a/esapp/utils/exceptions.py b/esapp/utils/exceptions.py deleted file mode 100644 index f918766f..00000000 --- a/esapp/utils/exceptions.py +++ /dev/null @@ -1,42 +0,0 @@ - - -class ESAPlusError(Exception): - '''Base exception class for ESA++ library errors''' - pass - - -class GridObjDNE(ESAPlusError): - '''Describes a data query failure''' - pass - -class FieldDataException(ESAPlusError): - pass - -class AuxParseException(ESAPlusError): - pass - -class ContainerDeletedException(ESAPlusError): - pass - -'''Observable Exceptions''' - -class PowerFlowException(ESAPlusError): - '''Raised When Power Flow Error Occurs''' - pass - -class BifurcationException(PowerFlowException): - '''Raised when bifurcation is suscpected''' - pass - -class DivergenceException(PowerFlowException): # TODO in use? - pass - -class GeneratorLimitException(PowerFlowException): - '''Raised when a generator has exceed a limit''' - pass - -''' GIC Exceptions ''' - -class GICException(ESAPlusError): - pass - diff --git a/esapp/utils/gic.py b/esapp/utils/gic.py new file mode 100644 index 00000000..08a0d171 --- /dev/null +++ b/esapp/utils/gic.py @@ -0,0 +1,466 @@ +""" +GIC (Geomagnetically Induced Currents) Analysis Module +====================================================== + +This module provides tools for analyzing geomagnetically induced currents +in power systems, including matrix generation, sensitivity analysis, and +integration with PowerWorld's GIC calculation engine. + +The primary entry point is the :class:`GIC` class, accessed via ``pw.gic`` +from a :class:`~esapp.PowerWorld` instance. + +See Also +-------- +esapp.saw.gic : Low-level GIC SAW functions. +esapp.saw.matrices : Matrix retrieval functions including get_gmatrix(). +""" + +from typing import Union, Optional + +import numpy as np +from pandas import DataFrame, read_csv +from scipy.sparse import csr_matrix, eye as speye, hstack, vstack, diags +from scipy.sparse.linalg import inv as sinv + +from .._descriptors import GICOption +from ..components import GIC_Options_Value, GICInputVoltObject +from ..components import Branch, Substation, Bus, Gen, GICXFormer + +__all__ = ['GIC'] + + +class GIC: + """ + GIC analysis application for PowerWorld integration. + + Provides methods for GIC calculations, sensitivity analysis, and + model generation using PowerWorld case data. All data access is + delegated to the parent PowerWorld instance. + + This class is accessed via ``PowerWorld.gic``. + + GIC Options + ----------- + GIC analysis requires certain options to be enabled for full functionality. + The most important is ``pf_include = True`` which must be set before + retrieving GIC data like transformer coil resistances (GICCoilR fields). + Methods like ``model()`` and ``gmatrix()`` automatically + enable this option. Use ``configure()`` to set multiple options at once. + + Example + ------- + >>> pw = PowerWorld("case.pwb") + >>> pw.gic.configure() # Enable GIC with default options + >>> pw.gic.storm(100, 90) # 100 V/km, 90 degrees + >>> pw.gic.model() + >>> G = pw.gic.gmatrix() + + See Also + -------- + configure : Set GIC options with sensible defaults. + settings : View or modify all GIC settings. + """ + + # --- GIC Options (descriptors) --- + + #: Include GIC effects in power flow calculations. + pf_include = GICOption('IncludeInPowerFlow') + #: Include GIC effects in transient stability simulations. + ts_include = GICOption('IncludeTimeDomain') + #: Calculation mode: ``'SnapShot'``, ``'TimeVarying'``, ``'NonUniformTimeVarying'``, or ``'SpatiallyUniformTimeVarying'``. + calc_mode = GICOption('CalcMode', is_bool=False) + + #: Electric field storm direction in degrees (float). + efield_angle = GICOption('EfieldAngle', is_bool=False) + #: Electric field magnitude in V/distance (float). + efield_mag = GICOption('EfieldMag', is_bool=False) + #: Automatically calculate maximum E-field direction. + calc_max_direction = GICOption('CalcMaxDirection') + + #: Auto-update line DC voltages during GIC solution. + update_line_volts = GICOption('UpdateLineVoltages') + #: Skip DC voltage calculation on equivalent lines. + skip_equiv_lines = GICOption('CalcInducedDCVoltEquiv') + #: Skip DC voltage calculation on low per-unit-distance R lines. + skip_low_r_lines = GICOption('CalcInducedDCVoltLowR') + #: Minimum nominal kV to include GIC effects (float). + min_kv = GICOption('IgnoreInducedDCVoltBelowkV', is_bool=False) + #: Maximum line segment length in km for non-uniform fields (float). + segment_length_km = GICOption('SegmentLengthKM', is_bool=False) + #: Substation auto-insert option for buses without substations (str). + bus_no_sub = GICOption('BusNoSub', is_bool=False) + + #: Include hotspot in the electric field calculation. + hotspot_include = GICOption('HotSpotInclude') + + def __init__(self, pw=None): + self._pw = pw + + # --- GIC Options Configuration --- + + def configure( + self, + pf_include: bool = True, + ts_include: bool = False, + calc_mode: str = 'SnapShot' + ) -> None: + """ + Configure GIC options with sensible defaults. + + This is the recommended way to initialize GIC analysis. It ensures + all necessary options are set for typical GIC workflows. + + Parameters + ---------- + pf_include : bool, default True + Include GIC effects in power flow calculations. Required for + accessing GIC-related data like transformer coil resistances. + ts_include : bool, default False + Include GIC effects in transient stability simulations. + calc_mode : str, default 'SnapShot' + GIC calculation mode. Options: + - 'SnapShot': Single time point calculation + - 'TimeVarying': Time series from uniform field + - 'NonUniformTimeVarying': Time series with spatial variation + - 'SpatiallyUniformTimeVarying': Spatially uniform time series + + Example + ------- + >>> pw.gic.configure() # Use defaults (pf_include=True) + >>> pw.gic.configure(ts_include=True) # Enable for transient stability + >>> pw.gic.configure(calc_mode='TimeVarying') # For time series analysis + """ + self.pf_include = pf_include + self.ts_include = ts_include + self.calc_mode = calc_mode + + # --- G-Matrix Retrieval --- + + def gmatrix(self, sparse: bool = True) -> Union[csr_matrix, np.ndarray]: + """ + Retrieve the G-matrix directly from PowerWorld. + + This is the recommended approach when working with PowerWorld cases, + as it uses the simulator's internal GIC calculation engine and + ensures consistency with PowerWorld's results. + + This method automatically enables GIC in power flow (pf_include=True) + before retrieving the matrix, ensuring GIC data is available. + + Parameters + ---------- + sparse : bool, default True + If True, returns scipy sparse CSR matrix. + If False, returns dense numpy array. + + Returns + ------- + scipy.sparse.csr_matrix or np.ndarray + The GIC conductance matrix (G-matrix) from PowerWorld. + + See Also + -------- + model : Generate full GIC model with H-matrix and per-unit model. + configure : Set GIC options manually. + """ + # Ensure GIC is included in power flow before retrieving matrix + self.pf_include = True + return self._pw.esa.get_gmatrix(full=not sparse) + + def storm(self, maxfield: float, direction: float, solvepf: bool = True) -> None: + """ + Configure synthetic storm with uniform electric field. + + Parameters + ---------- + maxfield : float + Maximum electric field magnitude (V/km). + direction : float + Storm direction in degrees (0-360, 0=North). + solvepf : bool, default True + Whether to include GIC results in power flow solution. + """ + self._pw.esa.GICCalculate(maxfield, direction, solvepf) + + def cleargic(self) -> None: + """Clear all GIC calculation results from the case.""" + self._pw.esa.RunScriptCommand("GICClear;") + + def loadb3d(self, ftype: str, fname: str, setuponload: bool = True) -> None: + """ + Load B3D file containing electric field data. + + Parameters + ---------- + ftype : str + File type identifier. + fname : str + Path to the B3D file. + setuponload : bool, default True + Whether to set up time-varying series on load. + """ + self._pw.esa.GICLoad3DEfield(ftype, fname, setuponload) + + def settings(self, value: Optional[DataFrame] = None) -> Optional[DataFrame]: + """ + View or modify GIC calculation settings. + + Parameters + ---------- + value : DataFrame, optional + If provided, updates settings. If None, returns current settings. + + Returns + ------- + DataFrame or None + Current settings if value is None. + """ + return self._pw.esa.GetParametersMultipleElement( + GIC_Options_Value.TYPE, + GIC_Options_Value.fields + )[['VariableName', 'ValueField']] + + def timevary_csv(self, fpath: str) -> None: + """ + Upload time-varying series voltage inputs from CSV file. + + Parameters + ---------- + fpath : str + Path to CSV file with format:: + + Time In Seconds, 1, 2, 3 + Branch '1' '2' '1', 0.1, 0.11, 0.14 + Branch '1' '2' '2', 0.1, 0.11, 0.14 + """ + csv = read_csv(fpath, header=None) + obj = GICInputVoltObject.TYPE + fields = ['WhoAmI'] + [f'GICObjectInputDCVolt:{i+1}' for i in range(csv.columns.size - 1)] + + for row in csv.to_records(False): + values = list(row) + # Quote the WhoAmI identifier (contains spaces) for PowerWorld + values[0] = f'"{values[0]}"' + self._pw.esa.SetData(obj, fields, values) + + # --- Model --- + + def model(self) -> 'GIC': + """ + Generate GIC model from current PowerWorld case data. + + Extracts substation, bus, line, transformer, and generator data + from PowerWorld and computes all GIC matrices (incidence, G-matrix, + H-matrix, per-unit linear model). Results are stored as properties + on this instance. + + Transformer data is sourced from the ``GICXFormer`` object type, + which provides the authoritative per-winding configuration, substation + assignments, and auto-transformer status used by PowerWorld's GIC + calculation engine. + + This method automatically enables GIC in power flow (pf_include=True) + before retrieving data. + + Returns + ------- + GIC + Self, with computed model matrices accessible via properties + (``G``, ``H``, ``A``, ``zeta``, ``Px``, ``eff``). + + See Also + -------- + gmatrix_from_powerworld : Get just the G-matrix from PowerWorld. + configure : Set GIC options manually. + """ + self.pf_include = True + MOHM = 1e6 + + # ---- Data from PowerWorld ---- + subs = self._pw[Substation, ["SubNum", "GICUsedSubGroundOhms", "Longitude", "Latitude"]] + buses = self._pw[Bus, ["BusNum", "BusNomVolt", "SubNum"]] + lines = self._pw[Branch, ["BusNum", "BusNum:1", "GICConductance", "BranchDeviceType"]] + lines = lines.loc[lines['BranchDeviceType'] != 'Transformer',["BusNum", "BusNum:1", "GICConductance"]] + xf = self._pw[GICXFormer, [ + "BusNum3W", "BusNum3W:1", "SubNum", "SubNum:1", + "GICXFCoilR1", "GICXFCoilR1:1", "GICXFConfigUsed", + "GICBlockDevice", "GICAutoXFUsed", "GICXF3Type", + "GICXFMVABase", "GICModelKUsed", + ]] + xf = xf[xf['GICXF3Type'].astype(str).str.upper() != 'YES'].copy() + gens = (self._pw[Gen, ["BusNum", "GICConductance", "GICGenIncludeImplicitGSU"]] + .query("GICConductance != 0 and GICGenIncludeImplicitGSU != 'NO'") + .merge(buses[['BusNum', 'SubNum']], on='BusNum', how='inner')) + + # ---- Transformer high/low winding assignment ---- + cfg = xf['GICXFConfigUsed'].astype(str).str.lower().str.split('-') + kv = buses.set_index('BusNum')['BusNomVolt'] + fromV, toV = xf['BusNum3W'].map(kv).to_numpy(), xf['BusNum3W:1'].map(kv).to_numpy() + + def _hilo(a, b): + """Sort paired from/to values into (high-side, low-side) by voltage.""" + return np.where(fromV >= toV, a, b), np.where(fromV >= toV, b, a) + + high_bus, low_bus = _hilo(xf['BusNum3W'], xf['BusNum3W:1']) + high_sub, low_sub = _hilo(xf['SubNum'], xf['SubNum:1']) + high_cfg, low_cfg = _hilo(cfg.str[0], cfg.str[-1]) + g_from, g_to = 1.0 / xf['GICXFCoilR1'].replace(0, MOHM), 1.0 / xf['GICXFCoilR1:1'].replace(0, MOHM) + high_g, low_g = _hilo(g_from, g_to) + highV, lowV = np.maximum(fromV, toV), np.maximum(np.minimum(fromV, toV), 1.0) + + HWYE, LWYE = high_cfg == 'gwye', low_cfg == 'gwye' + BD = xf['GICBlockDevice'].astype(str).str.upper() == 'YES' + AUTO = xf['GICAutoXFUsed'].astype(str).str.upper() == 'YES' + K = xf['GICModelKUsed'] + MVA = xf['GICXFMVABase'] + + # ---- Index maps & helpers ---- + ns, nb, nx, nl, ng = len(subs), len(buses), len(xf), len(lines), len(gens) + ncol = ns + nb + sub_map = {v: i for i, v in enumerate(subs['SubNum'])} + bus_map = {v: i + ns for i, v in enumerate(buses['BusNum'])} + + def _perm(ids, lookup=bus_map): + cols = np.array([lookup[v] for v in ids]) + return csr_matrix((np.ones(len(cols)), (np.arange(len(cols)), cols)), + shape=(len(cols), ncol)) + + def _mask(mat, m): + return diags(np.asarray(m, dtype=float)) @ mat + + def _g(vals, blocked=None): + g = np.asarray(vals, dtype=float) + if blocked is not None: + g = np.where(blocked, 0.0, g) + return np.where(g == 0, 1 / MOHM, g) + + # ---- Incidence matrix ---- + SH, SL = _perm(high_sub, sub_map), _perm(low_sub, sub_map) + BH, BL = _perm(high_bus), _perm(low_bus) + + A = vstack([ + _mask(-SH + BH, HWYE & ~AUTO) + _mask(BH - BL, ~HWYE | AUTO), # high + _mask(-SL + BL, LWYE & ~AUTO) + _mask(SL - BL, AUTO), # low + _perm(lines['BusNum']) - _perm(lines['BusNum:1']), # lines + _perm(gens['SubNum'], sub_map) - _perm(gens['BusNum']), # GSUs + ]) + + # ---- Conductances ---- + Gd = diags(np.concatenate([ + 3 * _g(high_g, BD & HWYE & ~AUTO), + 3 * _g(low_g, BD & (LWYE | AUTO)), + 3 * _g(lines['GICConductance']), + _g(gens['GICConductance']), + ])) + Gs = diags(np.concatenate([ + 1 / subs['GICUsedSubGroundOhms'].replace(0, MOHM), + np.full(nb, 1 / MOHM), + ])) + + # ---- Core computations ---- + Eff = hstack([speye(nx), diags(highV / lowV), csr_matrix((nx, nl + ng))]) + Px = _perm(xf['BusNum3W'])[:, ns:].T + G = A.T @ Gd @ A + Gs + Gi = sinv(G.tocsc()) + H = Eff @ (Gd - Gd @ A @ Gi @ A.T @ Gd) / 3 + K = diags(K * highV / (1e3 * MVA * np.sqrt(2 / 3))) + zeta = K @ H + + self._A, self._G, self._H = A, G, H + self._eff, self._zeta, self._Px = Eff, zeta, Px + return self + + # --- Model Properties --- + + @property + def A(self): + """ + General incidence matrix of the GIC network. + + The first N columns are substation neutral buses, and the remaining + M columns are bus nodes. The first 2X rows are high and low windings, + and the remaining rows are non-winding branches. + + Returns + ------- + scipy.sparse matrix + Shape (branches, N+M). + """ + return self._A + + @property + def G(self): + """ + Conductance Laplacian of the GIC network. + + The first N nodes are substation neutral buses, and the remaining + M nodes are bus nodes. Computed as: G = A.T @ Gd @ A + Gs + + Returns + ------- + scipy.sparse matrix + Shape (N+M, N+M). + """ + return self._G + + @property + def H(self): + """ + Linear GIC function matrix (H-matrix). + + Maps induced line voltages to signed effective transformer GICs. + Values are in actual current (Amps), not per-unit. + + Returns + ------- + scipy.sparse matrix + Shape (nxfmr, nbranches). + """ + return self._H + + @property + def zeta(self): + """ + Per-unit linear GIC model. + + Returns the constant-current load (prior to absolute value) in + per-unit for each transformer. This is the fastest option for + modeling GICs in power flow studies. + + Returns + ------- + scipy.sparse matrix + Per-unit GIC model matrix. + """ + return self._zeta + + @property + def Px(self): + """ + Bus assignment permutation matrix. + + Maps each transformer to the bus used to model losses + (default: from-bus). + + Returns + ------- + scipy.sparse matrix + Shape (nbus, nxfmr). + """ + return self._Px + + @property + def eff(self): + """ + Effective GIC operator matrix. + + Calculates effective transformer GICs when applied to the vector + of branch GICs. Includes non-winding branches; trim dimensions + for faster computation when only line voltages are used. + + Returns + ------- + scipy.sparse matrix + Shape (nxfmr, nbranches). + """ + return self._eff diff --git a/esapp/utils/map.py b/esapp/utils/map.py deleted file mode 100644 index af445072..00000000 --- a/esapp/utils/map.py +++ /dev/null @@ -1,211 +0,0 @@ -from functools import partial -from os.path import dirname, abspath, sep -import geopandas as gpd -import numpy as np - -from matplotlib.axes import Axes -from matplotlib.cm import ScalarMappable -from matplotlib.colors import Normalize, rgb_to_hsv, hsv_to_rgb -import matplotlib.pyplot as plt -from matplotlib.patches import Rectangle - - -def formatPlot(ax: Axes, - title='Chart Tile', - xlabel='X Axis Label', - ylabel="Y Axis Label", - xlim=None, - ylim=None, - grid=True, - plotarea='linen', - spineColor='black', - xticksep = None, - yticksep = None - ): - '''Generic Axes Formatter''' - - ax.set_facecolor(plotarea) - ax.grid(grid) - - # Grid plotted below all data - if grid: - ax.set_axisbelow(True) - - ax.tick_params(color=spineColor, labelcolor=spineColor) - for spine in ax.spines.values(): - spine.set_edgecolor(spineColor) - - # Viewport - if xlim: - ax.set_xlim(xlim) - if xticksep: - ax.set_xticks(np.arange(*xlim,xticksep)) - if ylim: - ax.set_ylim(ylim) - if yticksep: - pass - - # Text - ax.set_title(title) - ax.set_ylabel(ylabel) - ax.set_xlabel(xlabel) - - -def darker_hsv_colormap(scale_factor=0.5): - """Creates a modified version of the HSV colormap that is darker. - - Parameters - ---------- - scale_factor : float, optional - Factor to scale the value (brightness), by default 0.5. - Should be between 0 and 1. 1 means no change, 0 means - complete darkness. - - Returns - ------- - darker_hsv_cmap - A modified colormap that is a darker version of the original - HSV colormap. - """ - # Create the HSV colormap in RGB - hsv_cmap = plt.cm.hsv(np.linspace(0, 1, 256))[:, :3] - hsv_colors = rgb_to_hsv(hsv_cmap) - - # Scale the Value component to make it darker - hsv_colors[:, 2] *= scale_factor - hsv_colors[:, 2] = np.clip(hsv_colors[:, 2], 0, 1) - - darker_rgb_colors = hsv_to_rgb(hsv_colors) - darker_hsv_cmap = plt.cm.colors.ListedColormap(darker_rgb_colors) - return darker_hsv_cmap - - -def border(ax, shape='Texas'): - '''Plot Shape data (Country, State, Etc.) on a Matplotlib Axis''' - - # Load - _DIRNAME = dirname(abspath(__file__)) - shapepath = _DIRNAME + sep + 'shapes' + sep + shape + sep + 'Shape.shp' - shapeobj = gpd.read_file(shapepath) -# - # Plot - shapeobj.plot(ax=ax, edgecolor='black', facecolor='none') - - -def plot_lines(ax, lines, ms=50, lw=1): - '''Draw Transmission Line Geographically - -lines: GWB DataFrame of Line Data - -coordsX -> nx2 array of x-coords for TO and FROM repsectively - -coordsY -> nx2 array of y-coords for TO and FROM repsectively - ''' - - cX = lines[['Longitude', 'Longitude:1']].to_numpy() - cY = lines[['Latitude', 'Latitude:1']].to_numpy() - - for i in range(cX.shape[0]): - ax.plot(cX[i], cY[i], zorder=4, c='k', linewidth=lw) - ax.scatter(cX[i], cY[i], c='k', zorder=2, s=ms) - - -def plot_mesh(ax, gt, include_lines=True, color='grey', tcolor='red', talpha=0.3): - '''Plot a GIC Tool Tesselation Grid. Hx and Hy should be calculated with gt.tesselations before calling. - Tile Colors should be a 2D array.''' - - - if include_lines: - plot_lines(ax, gt.lines, ms=2) - - X, Y, W = gt.tile_info - - # Plot Horizontal and Vertical Grid Lines - for x in X: ax.plot([x, x], [Y.min(), Y.max()], c=color, zorder=1) - for y in Y: ax.plot([X.min(), X.max()], [y, y], c=color, zorder=1) - - # Plot Intersections - #inter = np.unique(allpnts[:,~np.isnan(allpnts[0])],axis=1) - #ax.scatter(inter[0], inter[1]) - - # Plot Used Tiles - tile_ids = gt.tile_ids - refpnt = np.array([[X.min(), Y.min()]]).T - tiles_unique = np.unique(tile_ids[:,~np.isnan(tile_ids[0])],axis=1) - tile_pos = tiles_unique*W + refpnt - - for tile in tile_pos.T: - ax.add_patch(Rectangle((tile[0],tile[1]), W, W, facecolor=tcolor, alpha=talpha)) - - plt.axis('scaled') - formatPlot(ax, xlabel='Longitude ($^\circ$E)', ylabel='Latitude ($^\circ$N)', title='Geographic Line Plot', plotarea='white', grid=False) - -def plot_tiles(ax, gt, colors=None): - - X, Y, W = gt.tile_info - - for i in np.arange(len(X)-1): - for j in np.arange(len(Y)-1): - ax.add_patch(Rectangle((X[i]*W + 0, Y[j]*W + 0), W, W, facecolor=colors[j,i] if colors is not None else 'red', alpha=0.3)) - - plt.axis('scaled') - formatPlot(ax, xlabel='Longitude ($^\circ$E)', ylabel='Latitude ($^\circ$N)', title='Tile Plot', plotarea='white', grid=False) - - -def plot_compass(ax: Axes, cmap=None, center=(-81.75, 33.2), radius=0.4, card_fs=16, band_width=0.1, band_thick=2, comp_thick=100, dir_perc=0.6): - '''Plot a compass element on the passed Axes. - Inteded for use as a color legend for vector field plots. - :param ax: Matplotlib Axes object to draw compass onto. - :type Axes: - :param cmap: Matplotlib Colormap of wheel. Ideally Cyclical. - ''' - - # Custom Ideal Cmap - if cmap is None: - cmap = darker_hsv_colormap(0.8) - - # Smoothness - n_points = 400 - - theta = np.linspace(-np.pi,np.pi, n_points) - shift = np.pi/2 - xr = radius*np.cos(-theta+shift) - yr = radius*np.sin(-theta+shift) - norm = Normalize(vmin=-np.pi, vmax=np.pi) - - # Fill White circle - circle = plt.Circle(center, radius, color='w') - ax.add_patch(circle) - - # Colors in Band - ax.scatter(center[0] + xr, center[1] + yr, c=cmap(norm(theta)), s=comp_thick) - - # Black Band - ax.scatter(center[0] + (1+band_width)*xr , center[1] + (1+band_width)*yr, c='k', s=band_thick) - ax.scatter(center[0] + (1-band_width)*xr , center[1] + (1-band_width)*yr, c='k', s=band_thick) - - # Cardinal Directions - dir_rad = radius*dir_perc - text = partial(ax.text, horizontalalignment='center', verticalalignment='center', fontsize=card_fs, fontfamily='monospace') - text(center[0] , center[1] + dir_rad , 'N') - text(center[0] , center[1] - dir_rad , 'S') - text(center[0] + dir_rad , center[1] , 'E') - text(center[0] - dir_rad , center[1] , 'W') - -def plot_vecfield(ax: Axes, X, Y, U, V, cmap=None, pivot='mid', scale=70, width=0.001, title=''): - '''Plot a vectorfield. A scalar mappable is returned for use in a colorbar or other mpl object.''' - - # Custom Ideal Cmap - if cmap is None: - cmap = darker_hsv_colormap(0.8) - - # Coloring via Angle - norm = Normalize(vmin=-np.pi, vmax=np.pi) - colors = np.arctan2(U, V) - colors[np.isnan(colors)] = 0 - - # Plot Arrows - ax.quiver(X, Y, U, V, colors, norm=norm,pivot=pivot, scale=scale, width=width, cmap=cmap)#, headwidth=2, headlength=3, headaxislength=3) - - # Format - formatPlot(ax, xlabel='Longitude ($^\circ$E)', ylabel='Latitude ($^\circ$N)', title=title, plotarea='white', grid=False) - plt.axis('scaled') - - return ScalarMappable(norm, cmap) \ No newline at end of file diff --git a/esapp/utils/mathtools.py b/esapp/utils/mathtools.py deleted file mode 100644 index 67222c3e..00000000 --- a/esapp/utils/mathtools.py +++ /dev/null @@ -1,451 +0,0 @@ -from abc import ABC - -import scipy.sparse as sp -from scipy.sparse.linalg import eigsh -from scipy.linalg import schur - -import numpy as np -from numpy import block, diag, real, imag - -# Constants -MU0 = 1.256637e-6 - - -def takagi(M): - """ - Performs the Takagi factorization of a complex symmetric matrix. - - Parameters - ---------- - M : np.ndarray - Complex symmetric matrix. - - Returns - ------- - tuple - (U, Sigma) where M = U * diag(Sigma) * U^T. - """ - n = M.shape[0] - D, P = schur(block([[-real(M),imag(M)],[imag(M),real(M)]])) - pos = diag(D) > 0 - Sigma = diag(D[pos,pos]) - # Note: The arithmetic below is technically not necessary - U = P[n:,pos] + 1j*P[:n,pos] - return U, Sigma.diagonal() - - - -def eigmax(L): - """ - Finds the largest eigenvalue of a matrix (intended for sparse Laplacians). - - Parameters - ---------- - L : Union[np.ndarray, sp.spmatrix] - The input matrix. - - Returns - ------- - float - The largest eigenvalue. - """ - return eigsh(L, k=1, which='LA', return_eigenvectors=False)[0] - - -def sorteig(Lam, U): - """ - Sorts eigenvalue decomposition by eigenvalue magnitude (least to greatest). - - Parameters - ---------- - Lam : np.ndarray - Eigenvalues. - U : np.ndarray - Eigenvectors. - - Returns - ------- - tuple - (Sorted Lam, Sorted U). - """ - idx = np.argsort(np.abs(Lam)) - return Lam[idx], U[:,idx] - -# TODO rename to 'pathlap' so periodicity is an option -def periodiclap(N, periodic=True): - """ - Creates a branchless periodic discrete graph Laplacian. - - Parameters - ---------- - N : int - Number of nodes. - periodic : bool, optional - Whether the graph is periodic. Defaults to True. - - Returns - ------- - np.ndarray - The Laplacian matrix. - """ - - O = np.ones(N) - - L = sp.diags( - [2*O, -O[:1], -O[:1]], - offsets=[0, 1, -1], - shape=(N,N) - ).toarray() - - if periodic: - L[0, -1] = -1 - L[-1, 0] = -1 - else: - L[0, 0] = 1 - L[-1, -1] = 1 - - return L - -def periodicincidence(N, periodic=True): - """ - Creates a branchless periodic discrete graph incidence matrix. - - Parameters - ---------- - N : int - Number of nodes. - periodic : bool, optional - Whether the graph is periodic. Defaults to True. - - Returns - ------- - np.ndarray - The incidence matrix. - """ - - O = np.ones(N) - - L = sp.diags( - [O, -O[:1]], - offsets=[0, 1], - shape=(N,N) - ).toarray() - - if periodic: - L[-1, 0] = -1 - - return L - -# Matrix Helper Functions -def normlap(L, retD=False): - """ - Returns the normalized Laplacian of a square matrix. - - Parameters - ---------- - L : Union[np.ndarray, sp.spmatrix] - Input square Laplacian matrix. - retD : bool, optional - Whether to return the diagonal scaling matrices. Defaults to False. - - Returns - ------- - Union[np.ndarray, tuple] - Normalized Laplacian, or (NormL, D, Di) if retD is True. - """ - - # Get Diagonal and Invert for convenience - Yd = np.sqrt(L.diagonal()) - Di = sp.diags(1/Yd) - - # Return Normalized Laplacian with or without scaled diag - if retD: - D = sp.diags(Yd) - return Di@L@Di, D, Di - else: - return Di@L@Di - - -def hermitify(A): - """ - Converts a complex symmetric matrix to a Hermitian matrix. - - Parameters - ---------- - A : Union[np.ndarray, sp.spmatrix] - Input complex symmetric matrix. - - Returns - ------- - np.ndarray - The Hermitian version of the matrix. - """ - - if isinstance(A, np.ndarray): - return (np.triu(A).conjugate() + np.tril(A))/2 - else: - return (np.triu(A.A).conjugate() + np.tril(A.A))/2 - - -class Operator(ABC): - """Abstract Mathematical Operator Object.""" - - def __init__(self) -> None: - pass - - -class DifferentialOperator(Operator): - """ - Finite difference operator generator for 2D grids. - Only Supports 2D Fortran Style Ordering. - """ - - def __init__(self, shape, order='F') -> None: - """ - Initialize the DifferentialOperator. - - Parameters - ---------- - shape : tuple - (nx, ny) dimensions of the grid. - order : str, optional - Memory ordering. Defaults to 'F'. - """ - self.shape = shape - self.nx, self.ny = shape - self.nElement = self.nx*self.ny - - self.D = [-1, 1] - - def newop(self): - """Create empty operator matrices.""" - return np.zeros((self.nElement, self.nElement)), np.zeros((self.nElement, self.nElement)) - - def aslil(self, Dx, Dy): - """Convert to LIL sparse format.""" - return sp.lil_matrix(Dx), sp.lil_matrix(Dy) - - def flatidx(self, x, y): - """ - Convert 2D coordinates to flat index. - - Parameters - ---------- - x : int - X coordinate. - y : int - Y coordinate. - """ - return y*self.nx + x - - def flattoloc(self, idx): - return idx%self.nx, idx//self.nx - - def up(self, idx): - return idx + self.nx - - def down(self, idx): - return idx - self.nx - - def right(self, idx): - return idx + 1 - - def left(self, idx): - return idx - 1 - - def elementiter(self): - """Iterate through each tensor element to get index and position.""" - - for yi in np.arange(self.ny): - for xi in np.arange(self.nx): - yield xi, yi, self.flatidx(xi, yi) - - def central_diffs(self) -> None: - """ - Produces central difference gradient operators for a vector field. - - Returns - ------- - tuple - (Dx, Dy) sparse matrices. - """ - - Dx, Dy = self.newop() - - for xi, yi, idx in self.elementiter(): - - if xi==0 or xi==self.nx-1: continue - if yi==0 or yi==self.ny-1: continue - - # Selectors - dx = [ self.left(idx) , self.right(idx) ] - dy = [ self.down(idx) , self.up(idx) ] - - Dx[idx , dx] += self.D - Dy[idx , dy] += self.D - - return self.aslil(Dx/2, Dy/2) - - - def forward_diffs(self) -> None: - """ - Produces forward difference gradient operators for a vector field. - - Returns - ------- - tuple - (Dx, Dy) sparse matrices. - """ - - Dx, Dy = self.newop() - - for xi, yi, idx in self.elementiter(): - - # Selectors - dx = [idx , self.right(idx)] - dy = [idx , self.up(idx)] - - # Add Y Differential to Tile - if xi < self.nx-1: - Dx[idx , dx] += self.D - - # Add to Adjacent Tiles - if yi < self.ny-1: - Dy[idx , dy] += self.D - - return self.aslil(Dx, Dy) - - def backward_diffs(self) -> None: - """ - Produces backward difference gradient operators for a vector field. - - Returns - ------- - tuple - (Dx, Dy) sparse matrices. - """ - - Dx, Dy = self.newop() - - for xi, yi, idx in self.elementiter(): - - # Selectors - dx = [idx, self.left(idx)] - dy = [idx, self.down(idx)] - - if xi != 0: - Dx[idx , dx] += self.D - - if yi != 0: - Dy[idx , dy] += self.D - - return self.aslil(Dx, Dy) - - def partial(self): - """ - Return centered partial operators for a 2D vector field tensor. - - Returns - ------- - tuple - (Dx, Dy) sparse matrices. - """ - - Dxf, Dyf = self.forward_diffs() - Dxb, Dyb = self.backward_diffs() - - return Dxb - Dxf, Dyb - Dyf - - def divergence(self): - """ - Central Difference Based Finite Divergence. - - Returns - ------- - sp.spmatrix - Divergence operator. - """ - - Dx, Dy = self.partial() - return sp.hstack([Dx, Dy]) - - def curl(self): - """ - Central Difference Based Finite Curl. - - Returns - ------- - sp.spmatrix - Curl operator. - """ - - Dx, Dy = self.partial() - return sp.hstack([Dy, -Dx]) - - def laplacian(self): - """ - Central Difference Based Discrete Laplacian. - - Returns - ------- - sp.spmatrix - Laplacian operator. - """ - - Dxf, Dyf = self.forward_diffs() - return Dxf.T@Dxf + Dyf.T@Dyf - - def J(self): - """Complex Unit Equivilent and/or hodge star.""" - - n = self.nElement - I = sp.eye(n) - return sp.bmat([ - [None, -I ], - [I , None] - ]) - - def ext_der(self): - """Calculate exterior derivative of linear function/operator.""" - # Used outside class up top - pass - - - - -class MeshSelector: - """Helper for selecting regions of a 2D mesh.""" - - def __init__(self, dop: DifferentialOperator) -> None: - """ - Initialize the MeshSelector. - - Parameters - ---------- - dop : DifferentialOperator - The operator defining the mesh dimensions. - """ - - self.SELECTOR = np.full(dop.nElement, False) - - nsel = lambda n: (self.SELECTOR.copy() for i in range(n)) - - # Sides Including Corners - self.LEFT, self.RIGHT, self.UP, self.DOWN = nsel(4) - - # Primary Indexing - for xi, yi, idx in dop.elementiter(): - self.LEFT[idx] = (xi==0) - self.RIGHT[idx] = (xi==dop.nx-1) - self.UP[idx] = (yi==dop.ny-1) - self.DOWN[idx] = (yi==0) - - # CENTRAL2[idx] = ~((xi==1) or (yi==1) or (xi==dop.nx-2) or (yi==dop.ny-2)) - - # Secondary Indexing - self.ALLCRNR = (self.LEFT|self.RIGHT)&(self.UP|self.DOWN) - self.BOUND = self.LEFT|self.RIGHT|self.UP|self.DOWN - self.CENTRAL = ~self.BOUND - - - # TODO Generic versions of above diff --git a/esapp/utils/mesh.py b/esapp/utils/mesh.py deleted file mode 100644 index 4c4d8569..00000000 --- a/esapp/utils/mesh.py +++ /dev/null @@ -1,193 +0,0 @@ -""" - -Handles .ply mesh file reading and writing. - -And conversions to useful formats. - -""" - -from dataclasses import dataclass -import numpy as np -import struct -from scipy.sparse import csc_matrix - -def extract_unique_edges(faces): - """ - Extracts a sorted list of unique edges from a list of faces. - - Parameters - ---------- - faces : list of lists - The mesh faces. - - Returns - ------- - np.ndarray - An (M, 2) array of unique edges where col 0 < col 1. - """ - unique_edges = set() - - for face in faces: - n = len(face) - for i in range(n): - u = face[i] - v = face[(i + 1) % n] # Connect to next vertex - # Sort pair to ensure (u, v) is same as (v, u) - edge = (u, v) if u < v else (v, u) - unique_edges.add(edge) - - # Return as a sorted numpy array for consistent indexing - return np.array(sorted(list(unique_edges)), dtype=int) - - -@dataclass -class Mesh: - vertices: list[tuple[float, float, float]] - faces: list[list[int]] - - @classmethod - def from_ply(cls, filepath: str) -> "Mesh": - """ - Reads a .ply file and constructs a Mesh object. - - Parameters - ---------- - filepath : str - Path to the .ply file. - - Returns - ------- - Mesh - The constructed Mesh object. - """ - with open(filepath, 'rb') as f: - # Parse Header - header_ended = False - fmt = "ascii" - vertex_count = 0 - face_count = 0 - vertex_props = [] - current_element = None - - while not header_ended: - line = f.readline().strip() - if not line: - break - line_str = line.decode('ascii', errors='ignore') - - if line_str == "end_header": - header_ended = True - break - - parts = line_str.split() - if not parts: - continue - - if parts[0] == "format": - fmt = parts[1] - elif parts[0] == "element": - current_element = parts[1] - if current_element == "vertex": - vertex_count = int(parts[2]) - elif current_element == "face": - face_count = int(parts[2]) - elif parts[0] == "property": - if current_element == "vertex": - # parts[1] is type, parts[2] is name - vertex_props.append((parts[2], parts[1])) - - # Parse Body - vertices = [] - faces = [] - - if fmt == "ascii": - lines = f.readlines() - for i in range(vertex_count): - parts = lines[i].strip().split() - # Assume first 3 are x, y, z - v = (float(parts[0]), float(parts[1]), float(parts[2])) - vertices.append(v) - - for i in range(face_count): - parts = lines[vertex_count + i].strip().split() - vertex_indices = [int(x) for x in parts[1:]] - faces.append(vertex_indices) - - elif fmt == "binary_little_endian": - np_type_map = { - 'char': 'i1', 'uchar': 'u1', 'short': 'i2', 'ushort': 'u2', - 'int': 'i4', 'uint': 'u4', 'float': 'f4', 'double': 'f8' - } - dtype_fields = [(name, np_type_map.get(type_str, 'f4')) for name, type_str in vertex_props] - vertex_dtype = np.dtype(dtype_fields) - - vertex_data = f.read(vertex_count * vertex_dtype.itemsize) - v_arr = np.frombuffer(vertex_data, dtype=vertex_dtype) - - # Extract x, y, z - if 'x' in v_arr.dtype.names and 'y' in v_arr.dtype.names and 'z' in v_arr.dtype.names: - vertices = list(zip(v_arr['x'], v_arr['y'], v_arr['z'])) - else: - names = v_arr.dtype.names - vertices = list(zip(v_arr[names[0]], v_arr[names[1]], v_arr[names[2]])) - - for _ in range(face_count): - n = struct.unpack(' csc_matrix: - """ - Constructs the sparse oriented incidence matrix B for the mesh. - - Returns - ------- - scipy.sparse.csc_matrix - Matrix B of size (\|V\| x \|E\|). - """ - # Topological data - vertices = self.vertices - faces = self.faces - - # Extract unique edges - edges = extract_unique_edges(faces) - num_verts = len(vertices) - num_edges = len(edges) - - # COO format data - x = edges.ravel() - y = np.repeat(np.arange(num_edges), 2) - e = np.tile([1.0, -1.0], num_edges) - - # Construct Incidene matrix - Bshp = (num_verts, num_edges) - B = csc_matrix((e, (x, y)), shape=Bshp) - - return B - - def get_xyz(self) -> np.ndarray: - """ - Returns the vertex coordinates as a numpy array. - - Returns - ------- - np.ndarray - An (N, 3) array of vertex coordinates. - """ - return np.array(self.vertices) - - def to_laplacian(self) -> csc_matrix: - """ - Constructs the graph Laplacian matrix L for the mesh. - - Returns - ------- - scipy.sparse.csc_matrix - The graph Laplacian matrix L. - """ - B = self.get_incidence_matrix() - L = B @ B.T - return L diff --git a/esapp/utils/misc.py b/esapp/utils/misc.py index 651ebd94..36816069 100644 --- a/esapp/utils/misc.py +++ b/esapp/utils/misc.py @@ -1,135 +1,55 @@ -from numpy import sum -from pandas import DataFrame +""" +Power system utilities and general-purpose helpers. +This module provides: +- Function decorators for debugging and profiling +""" -class InjectionVector: - """Represents a normalized injection vector for power system sensitivity studies.""" +from __future__ import annotations - def __init__(self, loaddf: DataFrame, losscomp=0.05) -> None: - """Initializes the InjectionVector. +from functools import wraps +from time import time +from typing import Callable, TypeVar - Parameters - ---------- - loaddf : pandas.DataFrame - A DataFrame containing at least a 'BusNum' column for all buses in the system. - losscomp : float, optional - Loss compensation factor. For an increased injection, generation will be - increased to compensate for losses. Defaults to 0.05. - """ - self.loaddf = loaddf.copy() +__all__ = [ + 'timing', +] - self.loaddf['Alpha'] = 0 - self.loaddf = self.loaddf.set_index('BusNum') +# ============================================================================= +# Decorators +# ============================================================================= - self.losscomp = losscomp - - @property - def vec(self): - """Returns the current injection vector as a NumPy array. +F = TypeVar('F', bound=Callable) - Returns - ------- - numpy.ndarray - The injection vector. - """ - return self.loaddf['Alpha'].to_numpy() - - def supply(self, *busids): - """Sets the specified buses as supply points (positive injection). - The 'Alpha' value for these buses will - """ - self.loaddf.loc[busids, 'Alpha'] = 1 - self.norm() - - def demand(self, *busids): - """Sets the specified buses as demand points (negative injection). - - :param busids: Variable number of bus IDs. - """ - self.loaddf.loc[busids, 'Alpha'] = -1 - self.norm() - - def norm(self): - """Normalizes the vector so that total supply equals total demand plus losses.""" - # Normalize Positive - isPos = self.vec>0 - posSum = sum(self.vec[isPos]) - negSum = -sum(self.vec[~isPos]) - - self.loaddf.loc[isPos,'Alpha'] /= posSum/(1+self.losscomp) if posSum>0 else 1 - self.loaddf.loc[~isPos,'Alpha'] /= negSum if negSum>0 else 1 - - -def ybus_with_loads(Y, buses, loads, gens=None): +def timing(func: F) -> F: """ - Modifies a Y-Bus matrix to include constant impedance load and generation models. - - This function converts P/Q injections into equivalent shunt admittances based on - the current bus voltages and adds them to the diagonal of the Y-Bus matrix. - - :param Y: The original sparse Y-Bus matrix (scipy.sparse). - :param buses: List of Bus component objects. - :param loads: List of Load component objects. - :param gens: Optional list of Gen component objects. Generators without dynamic - models (e.g., GENROU) are treated as negative constant impedance loads. - :return: The modified sparse Y-Bus matrix. - :rtype: scipy.sparse.base.spmatrix + Decorator that prints the execution time of a function. + + Parameters + ---------- + func : callable + The function to wrap. + + Returns + ------- + callable + Wrapped function that prints timing information. + + Examples + -------- + >>> @timing + ... def slow_function(): + ... time.sleep(1) + ... + >>> slow_function() + 'slow_function' took: 1.0012 sec """ - - # Copy so don't modify - Y = Y.copy() - - # Map the bus number to its Y-Bus Index - # TODO Do a sort by Bus Num to gaurentee order - busPosY = {b.BusNum: i for i, b in enumerate(buses)} - - # For Per-Unit Conversion - basemva = 100 - - for bus in buses: - - # Location in YBus - busidx = busPosY[bus.BusNum] - - # Net Load at Bus - pumw = bus.BusLoadMW/basemva if bus.BusLoadMW > 0 else 0 - pumvar = bus.BusLoadMVR/basemva if bus.BusLoadMVR > 0 or bus.BusLoadMVR < 0 else 0 - puS = pumw + 1j*pumvar - - # V at Bus - vmag = bus.BusPUVolt - - # Const Impedenace Load/Gen - constAdmit = puS.conjugate()/vmag**2 - - # Add to Ybus - Y[busidx][busidx] += constAdmit # TODO determine if to use + or -! - - - # Add Generators without models as negative load (if closed) - if gens is not None: - for gen in gens: - - if gen.TSGenMachineName == 'GENROU' and gen.GenStatus=='Closed': - continue - else: - basemva = 100 - # Net Load at Bus - pumw = gen.GenMW/basemva - pumvar = gen.GenMVR/basemva - puS = pumw + 1j*pumvar - - # V at Bus - vmag =gen.BusPUVolt - - # Const Impedenace Load/Gen - constAdmit = puS.conjugate()/vmag**2 - - # Location in YBus - busidx = busPosY[gen.BusNum] - - # Negative Admittance - Y[busidx][busidx] -= constAdmit - - return Y + @wraps(func) + def wrapper(*args, **kwargs): + start = time() + result = func(*args, **kwargs) + elapsed = time() - start + print(f'{func.__name__!r} took: {elapsed:.4f} sec') + return result + return wrapper diff --git a/esapp/utils/network.py b/esapp/utils/network.py new file mode 100644 index 00000000..9b41f52f --- /dev/null +++ b/esapp/utils/network.py @@ -0,0 +1,337 @@ +""" +Network Matrix Utilities +======================== + +Provides network topology analysis including incidence matrices, +graph Laplacians with various weighting schemes, and branch parameter +calculations for power system analysis. + +Classes +------- +Network + Network matrix construction and branch weight calculations. +BranchType + Enumeration of supported branch weight types for Laplacian construction. + +Example +------- +Basic network matrix operations:: + + >>> from esapp import PowerWorld + >>> pw = PowerWorld("case.pwb") + >>> A = pw.network.incidence() # Incidence matrix + >>> L = pw.network.laplacian(BranchType.LENGTH) # Length-weighted Laplacian + +See Also +-------- +esapp.utils.gic : GIC analysis with network topology. +esapp.saw.matrices : Matrix retrieval from PowerWorld. +""" + +from __future__ import annotations + +from enum import Enum + +import numpy as np +from pandas import DataFrame, Series, concat +from scipy.sparse import diags, coo_matrix, csc_matrix + +from ..components import Branch, Bus, DCTransmissionLine, Substation + +__all__ = ['Network', 'BranchType'] + + +class BranchType(Enum): + """ + Branch weighting schemes for Laplacian construction. + + Attributes + ---------- + LENGTH : int + Weight by inverse squared physical length (km^-2). + RES_DIST : int + Weight by inverse impedance magnitude (resistance distance). + DELAY : int + Weight by inverse squared propagation delay (s^-2). + """ + LENGTH = 1 + RES_DIST = 2 + DELAY = 3 + + +class Network: + """ + Network matrix construction and analysis. + + Builds sparse network matrices (incidence, Laplacian) and computes + branch electrical parameters. AC branches and HVDC transmission lines + are always included when present in the case. + + This class is accessed via ``PowerWorld.network`` and delegates all + data access to its parent PowerWorld instance. + + Notes + ----- + Matrix dimensions follow PowerWorld bus ordering. Use busmap() + to translate between bus numbers and matrix indices. + """ + + def __init__(self, pw=None): + self._pw = pw + self._A = None + + def _dc_lines(self) -> DataFrame | None: + """Return DC transmission line data, or None if unavailable.""" + try: + df = self._pw[DCTransmissionLine] + return df if df is not None and len(df) > 0 else None + except Exception: + return None + + def busmap(self) -> Series: + """ + Create mapping from bus numbers to matrix indices. + + Returns + ------- + pd.Series + Series indexed by BusNum with positional values. + """ + buses = self._pw[Bus] + return Series(buses.index, buses["BusNum"]) + + def incidence(self, remake: bool = True) -> csc_matrix: + """ + Construct the sparse arc-incidence matrix. + + Each row represents a branch with +1 at the to-bus and -1 at the + from-bus. HVDC lines are appended after AC branches when present. + + Parameters + ---------- + remake : bool, default True + If True, recomputes even if cached. + + Returns + ------- + scipy.sparse.csc_matrix + Sparse incidence matrix (branches x buses). + """ + if self._A is not None and not remake: + return self._A + + fields = ["BusNum", "BusNum:1"] + branches = self._pw[Branch][fields] + + dc = self._dc_lines() + if dc is not None: + branches = concat([branches, dc[fields]], ignore_index=True) + + bmap = self.busmap() + fr = branches["BusNum"].map(bmap).to_numpy() + to = branches["BusNum:1"].map(bmap).to_numpy() + + nb, nbus = len(branches), len(bmap) + idx = np.arange(nb) + self._A = coo_matrix( + (np.concatenate([-np.ones(nb), np.ones(nb)]), + (np.concatenate([idx, idx]), np.concatenate([fr, to]))), + shape=(nb, nbus), + ).tocsc() + + return self._A + + def laplacian( + self, + weights: BranchType | np.ndarray, + longer_xfmr_lens: bool = True, + len_thresh: float = 0.01, + ) -> csc_matrix: + """ + Construct weighted graph Laplacian: L = A.T @ W @ A. + + Parameters + ---------- + weights : BranchType or np.ndarray + Weighting scheme or custom weight vector. + longer_xfmr_lens : bool, default True + Use impedance-based pseudo-lengths for transformers. + len_thresh : float, default 0.01 + Threshold (km) below which branches are treated as transformers. + + Returns + ------- + scipy.sparse.csc_matrix + Sparse weighted Laplacian matrix (buses x buses). + """ + if isinstance(weights, BranchType): + if weights is BranchType.LENGTH: + W = 1 / self.lengths(longer_xfmr_lens, len_thresh) ** 2 + elif weights is BranchType.RES_DIST: + W = 1 / self.zmag() + else: + W = 1 / self.delay() ** 2 + else: + W = weights + + A = self.incidence() + return (A.T @ diags(W) @ A).tocsc() + + def lengths( + self, + longer_xfmr_lens: bool = False, + length_thresh_km: float = 0.01, + ) -> Series: + """ + Get branch lengths in kilometers. + + Parameters + ---------- + longer_xfmr_lens : bool, default False + Calculate pseudo-lengths for transformers based on + their impedance relative to average line impedance per km. + length_thresh_km : float, default 0.01 + Branches shorter than this are treated as transformers. + + Returns + ------- + pd.Series + Branch lengths in kilometers. + """ + fields = ["LineLengthByParameters", "LineLengthByParameters:2", + "LineR:2", "LineX:2"] + data = self._pw[Branch, fields][fields] + + # Prefer user-specified length over calculated + user = data["LineLengthByParameters"] + data.loc[user > 0, "LineLengthByParameters:2"] = user[user > 0] + ell = data["LineLengthByParameters:2"] + + dc = self._dc_lines() + if dc is not None: + dc_ell = self._pw[DCTransmissionLine, "LineLengthByParameters"]["LineLengthByParameters"] + ell = concat([ell, dc_ell], ignore_index=True) + + if longer_xfmr_lens: + is_line = ell > length_thresh_km + z = np.abs(data["LineR:2"] + 1j * data["LineX:2"]) + z_per_km = (z[is_line] / ell[is_line]).mean() + ell.loc[~is_line] = (z[~is_line] / z_per_km).to_numpy() + else: + ell.loc[ell == 0] = 0.01 + + return ell + + def zmag(self) -> Series: + """ + Get branch impedance magnitudes |Z|. + + Returns + ------- + pd.Series + Impedance magnitude for each branch. + """ + return 1 / np.abs(self.ybranch()) + + def ybranch(self, asZ: bool = False) -> Series: + """ + Get branch admittance (or impedance) in complex form. + + Parameters + ---------- + asZ : bool, default False + If True, return impedance Z = R + jX. + + Returns + ------- + pd.Series + Complex admittance Y = 1/(R + jX) or impedance Z. + """ + branches = self._pw[Branch, ["LineR:2", "LineX:2"]] + Z = branches["LineR:2"] + 1j * branches["LineX:2"] + + dc = self._dc_lines() + if dc is not None: + Z = concat([Z, Series(np.full(len(dc), 0.001 + 0j))], ignore_index=True) + + return Z if asZ else 1 / Z + + def yshunt(self) -> Series: + """ + Get branch shunt admittance in complex form. + + Returns + ------- + pd.Series + Complex shunt admittance Y = G + jB. + """ + branches = self._pw[Branch, ["LineG", "LineC"]] + return branches["LineG"] + 1j * branches["LineC"] + + def gamma(self) -> Series: + """ + Compute propagation constants for each branch. + + Returns + ------- + pd.Series + Complex propagation constant gamma = sqrt(Z * Y). + """ + ell = self.lengths() + Z = self.ybranch(asZ=True).copy() + Y = self.yshunt().copy() + + Z[Z == 0] = 0.000446 + 0.002878j + Y[Y == 0] = 0.000463j + + return np.sqrt((Y / ell) * (Z / ell)) + + def delay(self, min_delay: float = 10e-4) -> np.ndarray: + r""" + Compute effective propagation delay for network branches. + + Parameters + ---------- + min_delay : float, default 10e-4 + Minimum delay value to prevent numerical overflow when + computing 1/delay^2 in the Laplacian. + + Returns + ------- + np.ndarray + Effective propagation parameter beta for each branch. + + Notes + ----- + - Branch inductance: omega * L_ij = Im(Z^br_ij) + - Effective capacitance: C_ij = (C_i + C_j) / 2 + - Propagation delay: omega * tau_ij = Im(sqrt(Z_ij * Y_ij)) = beta_ij + """ + Z = self.ybranch(asZ=True) + + Ybus = self._pw.esa.get_ybus() + AVG = np.abs(self.incidence()) / 2 + Y = AVG @ Ybus @ np.ones(Ybus.shape[0]) + + return np.maximum(np.imag(np.sqrt(Z * Y)), min_delay) + + def buscoords(self, astuple: bool = True): + """ + Retrieve bus latitude and longitude from substation data. + + Parameters + ---------- + astuple : bool, default True + If True, return (Longitude, Latitude) Series tuple. + If False, return merged DataFrame. + + Returns + ------- + tuple of pd.Series or pd.DataFrame + """ + A = self._pw[Bus, "SubNum"] + S = self._pw[Substation, ["SubNum", "Longitude", "Latitude"]] + LL = A.merge(S, on="SubNum") + if astuple: + return LL["Longitude"], LL["Latitude"] + return LL diff --git a/esapp/utils/plotwavelet.py b/esapp/utils/plotwavelet.py deleted file mode 100644 index 5de6e8ea..00000000 --- a/esapp/utils/plotwavelet.py +++ /dev/null @@ -1,181 +0,0 @@ - -import numpy as np - - -# MISC -from os.path import dirname, abspath, sep -from numpy import array, linspace, meshgrid, where, nan, pi -from scipy.interpolate import LinearNDInterpolator, NearestNDInterpolator, CloughTocher2DInterpolator -import geopandas as gpd -import shapely.vectorized - -# MPL -import matplotlib as mpl -import matplotlib.pyplot as plt -from matplotlib.pyplot import Axes -from matplotlib.colors import Normalize - -def get_shapeobj(shape='Texas'): - _DIRNAME = dirname(abspath(__file__)) - shapepath = _DIRNAME + sep + 'shapes' + sep + shape + sep + 'Shape.shp' - shapeobj = gpd.read_file(shapepath) - - return shapeobj - -def scatter_map(values, long, lat, shape='Texas', ax:Axes=None, title='Texas Contour', usecbar=True, interp=300, cmap='plasma', norm=None, highlight=None, hlMarker='go', radians=False, method='nearest', extrap=(0,0,0,0)): - """Plot Spatial data with a country or state border. - - Parameters - ---------- - values : array_like - The values to plot. - long : array_like - The longitude values. - lat : array_like - The latitude values. - shape : str, optional - The shape to use for the border, by default 'Texas'. - Can be 'Texas' or 'US'. - ax : Axes, optional - The matplotlib axes to plot on, by default None. - title : str, optional - The title of the plot, by default 'Texas Contour'. - usecbar : bool, optional - Whether to use a colorbar, by default True. - interp : int, optional - The interpolation resolution, by default 300. - cmap : str, optional - The colormap to use, by default 'plasma'. - Good cmaps include 'Rocket' and 'Twilight'. - norm : Normalize, optional - The normalization for the colormap, by default None. - highlight : int, optional - The index of a point to highlight, by default None. - hlMarker : str, optional - The marker for the highlighted point, by default 'go'. - radians : bool, optional - Whether the values are in radians, by default False. - method : str, optional - The interpolation method, by default 'nearest'. - Can be 'linear', 'nearest', or 'cl'. - extrap : tuple, optional - The percentage to extend the plot in each direction - (xleft, xright, ydown, yup), by default (0,0,0,0). - """ - - cmap = mpl.colormaps[cmap] - - #Base Figure - if ax is None: - fig, ax = plt.subplots() - - # Plot Text - ax.set_title(title) - ax.set_title(title) - ax.set_xlabel("Longitude") - ax.set_ylabel('Latitude') - - # Data used to Interpolate - x = array(long) - y = array(lat) - z = array(values) - - # Post-Interpolation Input Values to Plot - cartcoord = list(zip(x, y)) - - xmin, xmax = min(x), max(x) - xdist = xmax-xmin - xmin -= extrap[0]*xdist - xmax += extrap[1]*xdist - - ymin, ymax = min(y), max(y) - ydist = ymax-ymin - ymin -= extrap[2]*ydist - ymax += extrap[3]*ydist - - X = linspace(xmin, xmax, interp) - Y = linspace(ymin, ymax, interp) - X, Y = meshgrid(X, Y) - - # Interpolation Function - if method=='linear': - interp = LinearNDInterpolator(cartcoord, z) - elif method=='nearest': - interp = NearestNDInterpolator(cartcoord, z) - elif method=='cl': - interp = CloughTocher2DInterpolator(cartcoord, z) - Z0 = interp(X, Y) - - # Use Bound if Givven - if type(norm) is tuple: - norm = Normalize(vmin=norm[0], vmax=norm[1]) - elif radians: - norm = Normalize(vmin=-pi, vmax=pi) - - # Texas Border Over Data - And Mask - if shape is not None: - - # Load - _DIRNAME = dirname(abspath(__file__)) - shapepath = _DIRNAME + sep + 'shapes' + sep + shape + sep + 'Shape.shp' - shapeobj = gpd.read_file(shapepath) - - # Mask - mask = shapely.vectorized.contains(shapeobj.dissolve().geometry.item(), X, Y) - - # Plot Heatmap with Mask - im = ax.pcolormesh(X, Y, where(mask, Z0, nan), cmap=cmap, norm=norm) - - # Plot - shapeobj.plot(ax=ax, edgecolor='black', facecolor='none') - - else: - im = ax.pcolormesh(X, Y, Z0, cmap=cmap, norm=norm) - - if usecbar: - cb = plt.gcf().colorbar(im, ax=ax) - - # Color Bar - if radians: - cb.set_ticks(ticks=[-pi,-pi/2,0,pi/2,pi], labels=[r'$-\pi$',r'$-\pi/2$',r'$0$',r'$\pi/2$',r'$\pi$']) - - - # Highlight a Specific Point - if highlight is not None: - ax.plot(x[highlight], y[highlight],hlMarker) - - -def plotwave(W, ax, L1, L2, method='nearest', zero_scale=False, cmap='seismic', mx = None, mn = None): - - if zero_scale: - norm = (0, np.max(W)) - else: - norm = (-np.max(W), np.max(W)) - if mx is not None: - if mn is None: - norm = (-mx, mx) - else: - norm= (mn, mx) - - scatter_map(W, L1, L2,method=method,cmap=cmap, - ax=ax, title=f'', norm=norm, usecbar=False, - extrap=(0.2, 0.1, 0, 0.1) - ) - - ax.set_xticks([],[]) - ax.set_yticks([],[]) - ax.set_axis_off() - -def quickwave(W, ax, L1, L2, method='nearest', cmap='seismic', norm=None): - - if norm is None: - norm = (np.min(W), np.max(W)) - - scatter_map(W, L1, L2,method=method,cmap=cmap, - ax=ax, title=f'', norm=norm, usecbar=False, - extrap=(0.2, 0.1, 0, 0.1) - ) - - ax.set_xticks([],[]) - ax.set_yticks([],[]) - ax.set_axis_off() \ No newline at end of file diff --git a/esapp/workbench.py b/esapp/workbench.py index db5dabf7..fd78fda1 100644 --- a/esapp/workbench.py +++ b/esapp/workbench.py @@ -1,1398 +1,646 @@ -from .apps.gic import GIC -from .apps.network import Network -from .apps.modes import ForcedOscillation -from .indexable import Indexable -from .grid import Bus, Branch, Gen, Load, Shunt, Area, Zone, Substation, Sim_Solution_Options -from .saw import create_object_string +from typing import List, Optional, Tuple, Union +from contextlib import contextmanager +import logging import numpy as np -from numpy import any as np_any -from pandas import DataFrame +import pandas as pd +from pandas import DataFrame, concat + +from .utils.gic import GIC +from .utils.network import Network +from .utils.dynamics import get_ts_results, process_ts_results +from .indexable import Indexable +from .components import Bus, Branch, Gen, Load, Shunt, Area, Zone, Sim_Solution_Options +from .saw._helpers import create_object_string +from ._descriptors import SolverOption + import tempfile import os -from scipy.sparse import csr_matrix -class GridWorkBench(Indexable): +class PowerWorld(Indexable): """ Main entry point for interacting with the PowerWorld grid model. """ - def __init__(self, fname=None): + def __init__(self, fname: Optional[str] = None): """ - Initialize the GridWorkBench. + Initialize the PowerWorld interface. Parameters ---------- fname : str, optional Path to the PowerWorld case file (.pwb). - - Examples - -------- - >>> wb = GridWorkBench("case.pwb") """ - # Applications - self.network = Network() - self.gic = GIC() - self.modes = ForcedOscillation() - - #self.dyn = Dynamics(self.esa) - #self.statics = Statics(self.esa) - - # State chain for iterative solvers - self._state_chain_idx = -1 - self._state_chain_max = 2 - - # ZIP load dispatch dataframe (initialized on first use) - self._dispatch_pq = None + # Embedded application modules (back-reference to self) + self.network = Network(self) + self.gic = GIC(self) if fname: - # Required to set to use IndexTool self.fname = fname - # Sets the global esa object self.open() else: self.esa = None self.fname = None - # Propagate the esa instance to the applications. - self.set_esa(self.esa) - - def set_esa(self, esa): - """Sets the SAW instance for the workbench and its applications.""" - super().set_esa(esa) - self.network.set_esa(esa) - self.gic.set_esa(esa) - self.modes.set_esa(esa) - - def voltage(self, complex=True, pu=True): - """ - Retrieves bus voltages. - - Parameters - ---------- - complex : bool, optional - If True, returns complex numbers. Else tuple of (mag, angle_rad). Defaults to True. - pu : bool, optional - If True, returns per-unit voltages. Else kV. Defaults to True. + # --- Solver Options (descriptors) --- + + #: Solve only one Newton iteration per call. + do_one_iteration = SolverOption('DoOneIteration') + #: Disable optimal multiplier acceleration. + disable_opt_mult = SolverOption('DisableOptMult') + #: Start from flat voltage profile (1.0 pu, 0 deg). + flat_start = SolverOption('FlatStart') + #: Maximum Newton-Raphson iterations (int). + max_iterations = SolverOption('MaxItr', is_bool=False) + #: Maximum voltage-constrained loop iterations (int). + max_vcl_iterations = SolverOption('MaxItr:1', is_bool=False) + #: Power flow convergence tolerance (float). + convergence_tol = SolverOption('ConvergenceTol', is_bool=False) + #: Minimum voltage for constant-current loads (float, pu). + min_volt_i_load = SolverOption('MinVoltILoad', is_bool=False) + #: Minimum voltage for constant-impedance loads (float, pu). + min_volt_s_load = SolverOption('MinVoltSLoad', is_bool=False) + + #: Check switched shunt/contingency controls in inner loop. + inner_ss_check = SolverOption('SSContPFInnerLoop') + #: Disable generator MVR limit checking. + disable_gen_mvr_check = SolverOption('DisableGenMVRCheck') + #: Check generator VAR limits in inner loop. + inner_check_gen_vars = SolverOption('ChkVars') + #: Back off generator VAR limits in inner loop. + inner_backoff_gen_vars = SolverOption('ChkVars:1') + #: Check transformer tap adjustments. + check_taps = SolverOption('ChkTaps') + #: Check switched shunt adjustments. + check_shunts = SolverOption('ChkShunts') + #: Check phase shifter adjustments. + check_phase_shifters = SolverOption('ChkPhaseShifters') + #: Prevent control oscillations. + prevent_oscillations = SolverOption('PreventOscillations') + + #: Disable automatic angle rotation to slack bus. + disable_angle_rotation = SolverOption('DisableAngleRotation') + #: Allow multiple island solutions. + allow_mult_islands = SolverOption('AllowMultIslands') + #: Evaluate solution quality per island. + eval_solution_island = SolverOption('EvalSolutionIsland') + #: Enforce generator MW output limits. + enforce_gen_mw_limits = SolverOption('EnforceGenMWLimits') + + #: Enable DC power flow approximation mode. + dc_mode = SolverOption('DCPFMode') + + # --- Bus Voltage & Analysis --- + + def voltage( + self, + complex: bool = True, + pu: bool = True, + ) -> Union[pd.Series, Tuple[pd.Series, pd.Series]]: + """ + Retrieve bus voltages. + + Parameters + ---------- + complex : bool, default True + If True, return complex voltage. Else (magnitude, angle_rad). + pu : bool, default True + If True, per-unit. Else kV. Returns ------- - Union[pd.Series, Tuple[pd.Series, pd.Series]] - The voltage data. - - Examples - -------- - >>> v_complex = wb.voltage() + pd.Series or tuple of pd.Series + If ``complex=True``, a complex-valued Series V = |V| * exp(j*theta). + If ``complex=False``, a tuple ``(magnitude, angle_rad)``. """ fields = ["BusPUVolt", "BusAngle"] if pu else ["BusKVVolt", "BusAngle"] df = self[Bus, fields] - mag = df[fields[0]] ang = df['BusAngle'] * np.pi / 180.0 - if complex: return mag * np.exp(1j * ang) return mag, ang - # --- Simulation Control --- - - def pflow(self, getvolts=True, method="POLARNEWT"): + def set_voltages(self, V: np.ndarray) -> None: """ - Solve Power Flow in external system. - By default bus voltages will be returned. + Set bus voltages from a complex vector. Parameters ---------- - getvolts : bool, optional - Flag to indicate the voltages should be returned after power flow, - defaults to True. - - Returns - ------- - pd.Series or tuple or None - Returns the output of the voltage() method if requested. - - Examples - -------- - >>> wb.pflow() - """ - # Solve Power Flow through External Tool - self.esa.SolvePowerFlow(method) - - # Request Voltages if needed - if getvolts: - return self.voltage() - - - def flatstart(self): - """ - Resets the case to a flat start (1.0 pu voltage, 0.0 angle). - - Examples - -------- - >>> wb.flatstart() - """ - self.esa.ResetToFlatStart() - - def reset(self): - """ - Alias for flatstart(). Resets the case to a flat start (1.0 pu voltage, 0.0 angle). - - Examples - -------- - >>> wb.reset() - """ - self.flatstart() - - def save(self, filename=None): - """ - Saves the case to the specified filename, or overwrites current if None. - - Parameters - ---------- - filename : str, optional - The path to save the case to. - - Examples - -------- - >>> wb.save("case_modified.pwb") + V : np.ndarray + Complex voltage vector (per-unit). """ - self.esa.SaveCase(filename) + V_df = np.vstack([np.abs(V), np.angle(V, deg=True)]).T + self[Bus, ["BusPUVolt", "BusAngle"]] = V_df - def command(self, script: str): + def violations(self, v_min: float = 0.9, v_max: float = 1.1) -> DataFrame: """ - Executes a raw script command string. + Return bus voltage violations. Parameters ---------- - script : str - The PowerWorld script command. + v_min : float, default 0.9 + Low voltage threshold (pu). + v_max : float, default 1.1 + High voltage threshold (pu). Returns ------- - str - The result of the command. - - Examples - -------- - >>> wb.command("SolvePowerFlow;") + DataFrame + Columns 'Low' and 'High' with violating bus voltages. """ - return self.esa.RunScriptCommand(script) + v = self.voltage(complex=False, pu=True)[0] + low = v[v < v_min] + high = v[v > v_max] + return DataFrame({'Low': low, 'High': high}) - def log(self, message: str): + def mismatch(self, asComplex: bool = False): """ - Adds a message to the PowerWorld log. + Return bus power mismatches. Parameters ---------- - message : str - The message to log. + asComplex : bool, default False + If True, return P + jQ as complex Series. - Examples - -------- - >>> wb.log("Starting analysis...") + Returns + ------- + tuple of pd.Series or pd.Series + (P, Q) mismatches or complex S = P + jQ. """ - self.esa.LogAdd(message) + df = self[Bus, ["BusMismatchP", "BusMismatchQ"]] + P = df['BusMismatchP'] + Q = df['BusMismatchQ'] + if asComplex: + return P + 1j * Q + return P, Q - def print_log(self, clear: bool = False, new_only: bool = False): + def netinj(self, asComplex: bool = False): """ - Prints the PowerWorld Message Log to the console. - - This function saves the PowerWorld log to a temporary file, reads its - contents, and prints them to the console. Useful for debugging and - monitoring PowerWorld operations. + Sum of all generator, load, bus shunt, and switched shunt P and Q. Parameters ---------- - clear : bool, optional - If True, clears the PowerWorld log after printing. Defaults to False. - new_only : bool, optional - If True, only prints log entries added since the last call to print_log. - Defaults to False. + asComplex : bool, default False + If True, return P + jQ as complex array. Returns ------- - str - The log contents that were printed. - - Examples - -------- - >>> wb.pflow() - >>> wb.print_log() # See what PowerWorld reported - >>> wb.print_log(clear=True) # Print and clear the log - >>> wb.print_log(new_only=True) # Only show new entries + tuple of np.ndarray or np.ndarray + (P, Q) or complex S = P + jQ. """ - # Initialize tracking attribute if needed - if not hasattr(self, "_log_last_position"): - self._log_last_position = 0 - - # Create temp file, save log, read contents - tmp = tempfile.NamedTemporaryFile(mode="w", suffix=".txt", delete=False) - tmp_path = tmp.name - tmp.close() - - try: - self.esa.LogSave(tmp_path, append=False) - with open(tmp_path, "r") as f: - content = f.read() - finally: - os.unlink(tmp_path) - - # Handle new_only mode - if new_only: - output = content[self._log_last_position:] - else: - output = content - - # Update position tracker - self._log_last_position = len(content) - - # Print to console - if output.strip(): - print(output) - - # Clear log if requested - if clear: - self.esa.LogClear() - self._log_last_position = 0 - - return output - - def close(self): - """ - Closes the current case. - - Examples - -------- - >>> wb.close() - """ - self.esa.CloseCase() - - def edit_mode(self): - ''' - Description: - Enters PowerWorld into EDIT mode. - ''' - self.esa.EnterMode("EDIT") - - def run_mode(self): - ''' - Description: - Enters PowerWorld into RUN mode. - ''' - self.esa.EnterMode("RUN") - - # --- File Operations --- - - def load_aux(self, filename: str): - """ - Loads an auxiliary file. + df = self[Bus, ['BusNetMW', 'BusNetMVR']] + P = df['BusNetMW'].to_numpy() + Q = df['BusNetMVR'].to_numpy() + if asComplex: + return P + 1j * Q + return P, Q - Parameters - ---------- - filename : str - The path to the .aux file. + # --- Matrix Retrieval --- - Examples - -------- - >>> wb.load_aux("data.aux") - """ - self.esa.LoadAux(filename) - - def load_script(self, filename: str): + def ybus(self, dense: bool = False): """ - Loads and runs a script file. + Return the Y-Bus matrix. Parameters ---------- - filename : str - The path to the script file. - - Examples - -------- - >>> wb.load_script("run.pws") - """ - self.esa.LoadScript(filename) - - def generations(self): - """ - Returns a DataFrame of generator outputs (MW, Mvar) and status. + dense : bool, default False + If True, return dense array. Else sparse CSR. Returns ------- - pd.DataFrame - Generator data. - - Examples - -------- - >>> gens = wb.generations() + np.ndarray or scipy.sparse.csr_matrix + The system admittance matrix (n_bus x n_bus). """ - return self[Gen, ["GenMW", "GenMVR", "GenStatus"]] - - def loads(self): - """ - Returns a DataFrame of load demands (MW, Mvar) and status. - - Returns - ------- - pd.DataFrame - Load data. - - Examples - -------- - >>> loads = wb.loads() - """ - return self[Load, ["LoadMW", "LoadMVR", "LoadStatus"]] - - def shunts(self): - """ - Returns a DataFrame of switched shunt outputs (MW, Mvar) and status. - - Returns - ------- - pd.DataFrame - Shunt data. + return self.esa.get_ybus(dense) - Examples - -------- - >>> shunts = wb.shunts() + def jacobian(self, dense: bool = False, form: str = 'R', ids: bool = False): """ - return self[Shunt, ["ShuntMW", "ShuntMVR", "ShuntStatus"]] + Get the power flow Jacobian matrix. - def lines(self): - """ - Returns all transmission lines. + Parameters + ---------- + dense : bool, default False + If True, return dense array. Else sparse CSR. + form : str, default 'R' + Coordinate form: 'R' (rectangular), 'P' (polar), 'DC' (B'). + ids : bool, default False + If True, return ``(matrix, row_ids)`` with row/column labels. Returns ------- - pd.DataFrame - Line data. - - Examples - -------- - >>> lines = wb.lines() - """ - branches = self[Branch, :] - return branches[branches["BranchDeviceType"] == "Line"] - - def transformers(self): + np.ndarray or scipy.sparse.csr_matrix + The power flow Jacobian matrix (when ``ids=False``). + tuple + ``(matrix, row_ids)`` when ``ids=True``. """ - Returns all transformers. + if ids: + return self.esa.get_jacobian_with_ids(dense, form=form) + return self.esa.get_jacobian(dense, form=form) - Returns - ------- - pd.DataFrame - Transformer data. + # --- Network Delegation --- - Examples - -------- - >>> xformers = wb.transformers() + def busmap(self) -> pd.Series: """ - branches = self[Branch, :] - return branches[branches["BranchDeviceType"] == "Transformer"] + Create mapping from bus numbers to matrix indices. - def areas(self): - """ - Returns all areas. + Delegates to ``network.busmap()``. Returns ------- - pd.DataFrame - Area data. - - Examples - -------- - >>> areas = wb.areas() - """ - return self[Area, :] - - def zones(self): + pd.Series + Series indexed by BusNum with positional index values. """ - Returns all zones. - - Returns - ------- - pd.DataFrame - Zone data. + return self.network.busmap() - Examples - -------- - >>> zones = wb.zones() + def buscoords(self, astuple: bool = True): """ - return self[Zone, :] - - # --- Modification --- + Retrieve bus latitude and longitude from substation data. - def set_voltages(self, V): - """ - Sets bus voltages from a complex vector. + Delegates to ``network.buscoords()``. Parameters ---------- - V : np.ndarray - Complex voltage vector. - - Examples - -------- - >>> V_new = np.ones(len(wb.buses)) * 1.05 - >>> wb.set_voltages(V_new) - """ - V_df = np.vstack([np.abs(V), np.angle(V, deg=True)]).T - self[Bus, ["BusPUVolt", "BusAngle"]] = V_df - - def open_branch(self, bus1, bus2, ckt='1'): - """ - Opens a branch. + astuple : bool, default True + If True, return ``(Longitude, Latitude)`` as a tuple of Series. + If False, return a merged DataFrame. - Parameters - ---------- - bus1 : int - From bus number. - bus2 : int - To bus number. - ckt : str, optional - Circuit ID. Defaults to '1'. - - Examples - -------- - >>> wb.open_branch(1, 2, "1") + Returns + ------- + tuple of pd.Series or DataFrame + Bus geographic coordinates. """ - self.esa.ChangeParametersSingleElement("Branch", ["BusNum", "BusNum:1", "LineCircuit", "LineStatus"], [bus1, bus2, ckt, "Open"]) + return self.network.buscoords(astuple) - def close_branch(self, bus1, bus2, ckt='1'): + def pflow(self, getvolts: bool = True, method: str = "POLARNEWT") -> Optional[Union[pd.Series, Tuple[pd.Series, pd.Series]]]: """ - Closes a branch. + Solve Power Flow. Parameters ---------- - bus1 : int - From bus number. - bus2 : int - To bus number. - ckt : str, optional - Circuit ID. Defaults to '1'. - - Examples - -------- - >>> wb.close_branch(1, 2, "1") - """ - self.esa.ChangeParametersSingleElement("Branch", ["BusNum", "BusNum:1", "LineCircuit", "LineStatus"], [bus1, bus2, ckt, "Closed"]) + getvolts : bool, optional + Return voltages after solving. Defaults to True. + method : str, optional + Solution method. Defaults to "POLARNEWT". - def set_gen(self, bus, id, mw=None, mvar=None, status=None): + Returns + ------- + pd.Series, tuple of pd.Series, or None + Complex voltage Series if ``getvolts=True`` (default), or + None if ``getvolts=False``. """ - Sets generator parameters. + self.esa.SolvePowerFlow(method) + if getvolts: + return self.voltage() - Parameters - ---------- - bus : int - Bus number. - id : str - Generator ID. - mw : float, optional - MW output. - mvar : float, optional - Mvar output. - status : str, optional - Status ('Closed' or 'Open'). - - Examples - -------- - >>> wb.set_gen(bus=10, id="1", mw=150.0) + def ts_solve(self, ctgs: Union[str, List[str]], fields: List[str]) -> Tuple[DataFrame, DataFrame]: """ - param_map = {"GenMW": mw, "GenMVR": mvar, "GenStatus": status} - params = {k: v for k, v in param_map.items() if v is not None} - - if params: - fields = ["BusNum", "GenID"] + list(params.keys()) - values = [bus, id] + list(params.values()) - self.esa.ChangeParametersSingleElement("Gen", fields, values) - - def set_load(self, bus, id, mw=None, mvar=None, status=None): - """ - Sets load parameters. + Run transient stability simulation for the specified contingencies. - Parameters - ---------- - bus : int - Bus number. - id : str - Load ID. - mw : float, optional - MW demand. - mvar : float, optional - Mvar demand. - status : str, optional - Status ('Closed' or 'Open'). - - Examples - -------- - >>> wb.set_load(bus=5, id="1", mw=50.0) - """ - param_map = {"LoadMW": mw, "LoadMVR": mvar, "LoadStatus": status} - params = {k: v for k, v in param_map.items() if v is not None} - - if params: - fields = ["BusNum", "LoadID"] + list(params.keys()) - values = [bus, id] + list(params.values()) - self.esa.ChangeParametersSingleElement("Load", fields, values) - - def scale_load(self, factor): - """ - Scales system load by a factor. + Handles auto-correction, initialization, solving each contingency, + result retrieval, processing, and concatenation. Parameters ---------- - factor : float - Scaling factor. + ctgs : Union[str, List[str]] + A single contingency name or a list of names. + fields : List[str] + Retrieval field strings (e.g., from TSWatch.prepare). - Examples - -------- - >>> wb.scale_load(1.1) # Increase load by 10% + Returns + ------- + Tuple[DataFrame, DataFrame] + (Metadata, Time-Series Data). """ - self.esa.Scale("LOAD", "FACTOR", [factor], "SYSTEM") + logger = logging.getLogger(__name__) + ctgs_list = [ctgs] if isinstance(ctgs, str) else list(ctgs) - def scale_gen(self, factor): - """ - Scales system generation by a factor. + if not fields: + logger.warning("No fields provided. Simulation will run but no results will be retrieved.") - Parameters - ---------- - factor : float - Scaling factor. + self.esa.TSAutoCorrect() + self.esa.TSInitialize() - Examples - -------- - >>> wb.scale_gen(1.1) # Increase generation by 10% - """ - self.esa.Scale("GEN", "FACTOR", [factor], "SYSTEM") + all_meta_frames = [] + all_data_frames = {} - def create(self, obj_type, **kwargs): - """ - Creates an object with specified parameters. - Example: adapter.create('Load', BusNum=1, LoadID='1', LoadMW=10) + for ctg in ctgs_list: + logger.info(f"Solving contingency: {ctg}") + self.esa.TSSolve(ctg) + meta, df = get_ts_results(self.esa, ctg, fields) - Parameters - ---------- - obj_type : str - The PowerWorld object type. - **kwargs - Field names and values. - - Examples - -------- - >>> wb.create("Load", BusNum=1, LoadID="1", LoadMW=10) - """ - fields = list(kwargs.keys()) - values = list(kwargs.values()) - self.esa.CreateData(obj_type, fields, values) - - def delete(self, obj_type, filter_name=""): - """ - Deletes objects of a given type, optionally matching a filter. - - Parameters - ---------- - obj_type : str - The PowerWorld object type. - filter_name : str, optional - The filter to apply. - - Examples - -------- - >>> wb.delete("Gen", filter_name="AreaNum = 1") - """ - self.esa.Delete(obj_type, filter_name) + if meta is None or df is None or df.empty: + logger.warning(f"No results returned for contingency: {ctg}") + continue - def select(self, obj_type, filter_name=""): - """ - Sets the Selected field to YES for objects matching the filter. + meta, df = process_ts_results(meta, df, ctg) + if not df.empty: + all_data_frames[ctg] = df + all_meta_frames.append(meta) - Parameters - ---------- - obj_type : str - The PowerWorld object type. - filter_name : str, optional - The filter to apply. - - Examples - -------- - >>> wb.select("Bus", filter_name="BusPUVolt < 0.95") - """ - self.esa.SelectAll(obj_type, filter_name) + if not all_meta_frames: + return DataFrame(), DataFrame() - def unselect(self, obj_type, filter_name=""): - """ - Sets the Selected field to NO for objects matching the filter. + final_meta = concat(all_meta_frames, axis=0, ignore_index=True).set_index('ColHeader') + final_data = concat(all_data_frames.values(), axis=1, keys=all_data_frames.keys()).sort_index(axis=1) - Parameters - ---------- - obj_type : str - The PowerWorld object type. - filter_name : str, optional - The filter to apply. - - Examples - -------- - >>> wb.unselect("Bus") - """ - self.esa.UnSelectAll(obj_type, filter_name) + return final_meta, final_data - # --- Advanced Topology & Switching --- + def flatstart(self) -> None: + """Resets the case to a flat start (1.0 pu voltage, 0.0 angle).""" + self.esa.ResetToFlatStart() - def energize(self, obj_type, identifier, close_breakers=True): + def save(self, filename: Optional[str] = None) -> None: """ - Energizes a specific object by closing breakers. + Save the case to disk. Parameters ---------- - obj_type : str - Object type (e.g. 'Bus', 'Gen', 'Load'). - identifier : str - Identifier string (e.g. '[1]', '[1 "1"]'). - close_breakers : bool, optional - Whether to close breakers. Defaults to True. - - Examples - -------- - >>> wb.energize("Bus", "[1]") + filename : str, optional + Output file path. If None, overwrites the currently open case. """ - self.esa.CloseWithBreakers(obj_type, identifier) + self.esa.SaveCase(filename) - def deenergize(self, obj_type, identifier): + def log(self, message: str) -> None: """ - De-energizes a specific object by opening breakers. + Add a message to the PowerWorld message log. Parameters ---------- - obj_type : str - Object type (e.g. 'Bus', 'Gen', 'Load'). - identifier : str - Identifier string (e.g. '[1]', '[1 "1"]'). - - Examples - -------- - >>> wb.deenergize("Bus", "[1]") - """ - self.esa.OpenWithBreakers(obj_type, identifier) - - def radial_paths(self): - """ - Identifies radial paths in the network. - - Examples - -------- - >>> wb.radial_paths() + message : str + The message text to append. """ - self.esa.FindRadialBusPaths() + self.esa.LogAdd(message) - def path_distance(self, start_element_str): + def print_log(self, clear: bool = False, new_only: bool = False): """ - Calculates distance from a starting element to all buses. + Prints the PowerWorld Message Log to the console. Parameters ---------- - start_element_str : str - e.g. '[BUS 1]' or '[AREA "Top"]'. + clear : bool, optional + If True, clears the log after printing. Defaults to False. + new_only : bool, optional + If True, only prints new entries. Defaults to False. Returns ------- - pd.DataFrame - Distance data. - - Examples - -------- - >>> dists = wb.path_distance("[BUS 1]") - """ - return self.esa.DeterminePathDistance(start_element_str) - - def network_cut(self, bus_on_side, branch_filter="SELECTED"): - """ - Selects objects on one side of a network cut defined by selected branches. - - Parameters - ---------- - bus_on_side : str - Bus identifier string (e.g. '[BUS 1]') on the desired side. - branch_filter : str, optional - Filter for branches defining the cut. Defaults to "SELECTED". - - Examples - -------- - >>> wb.network_cut("[BUS 1]") - """ - self.esa.SetSelectedFromNetworkCut(True, bus_on_side, branch_filter=branch_filter, objects_to_select=["Bus", "Gen", "Load"]) - - # --- Difference Flows --- - - def set_as_base_case(self): - """ - Sets the currently open case as the base case for difference flows. - - Examples - -------- - >>> wb.set_as_base_case() - """ - self.esa.DiffCaseSetAsBase() - - def diff_mode(self, mode="DIFFERENCE"): - """ - Sets the difference mode (PRESENT, BASE, DIFFERENCE, CHANGE). - - Parameters - ---------- - mode : str, optional - The mode to set. Defaults to "DIFFERENCE". - - Examples - -------- - >>> wb.diff_mode("DIFFERENCE") - """ - self.esa.DiffCaseMode(mode) - - # --- Analysis --- - - def run_contingency(self, name): - """ - Runs a single contingency. - - Examples - -------- - >>> wb.run_contingency("Line 1-2 Out") - """ - self.esa.RunContingency(name) - - def solve_contingencies(self): - """ - Solves all defined contingencies. - - Examples - -------- - >>> wb.solve_contingencies() - """ - self.esa.SolveContingencies() - - def auto_insert_contingencies(self): - """ - Auto-inserts contingencies based on current options. - - Examples - -------- - >>> wb.auto_insert_contingencies() - """ - self.esa.CTGAutoInsert() - - def violations(self, v_min=0.9, v_max=1.1): - """ - Returns a DataFrame of bus voltage violations. - - Examples - -------- - >>> v_viols = wb.violations(v_min=0.95, v_max=1.05) - >>> print(v_viols.head()) - """ - v = self.voltage(complex=False, pu=True)[0] - low = v[v < v_min] - high = v[v > v_max] - return DataFrame({'Low': low, 'High': high}) - - def mismatch(self, asComplex=False): - """Returns bus mismatches.""" - """ - Returns bus mismatches. - - Examples - -------- - >>> mm = wb.mismatch() - """ - #return self.esa.GetBusMismatches() - df = self[Bus, ["BusMismatchP", "BusMismatchQ"]] - P = df['BusMismatchP'] - Q = df['BusMismatchQ'] - - if asComplex: - return P + 1j * Q - return P, Q - - def netinj(self, asComplex=False): + str + The log contents. """ - Sum of all generator, load, bus shunt, and switched shunt P and Q. - - + if not hasattr(self, "_log_last_position"): + self._log_last_position = 0 - Examples - -------- - >>> mm = wb.netinj() - """ - #return self.esa.GetBusMismatches() - df = self[Bus, ['BusNetMW', 'BusNetMVR']] - P = df['BusNetMW'].to_numpy() - Q = df['BusNetMVR'].to_numpy() + tmp = tempfile.NamedTemporaryFile(mode="w", suffix=".txt", delete=False) + tmp_path = tmp.name + tmp.close() - if asComplex: - return P + 1j * Q - return P, Q + try: + self.esa.LogSave(tmp_path, append=False) + with open(tmp_path, "r") as f: + content = f.read() + finally: + os.unlink(tmp_path) + if new_only: + output = content[self._log_last_position:] + else: + output = content - def islands(self): - """ - Returns information about islands. + self._log_last_position = len(content) - Examples - -------- - >>> islands = wb.islands() - """ - return self.esa.DetermineBranchesThatCreateIslands() + if output.strip(): + print(output) - def refresh_onelines(self): - """ - Relinks all open oneline diagrams. + if clear: + self.esa.LogClear() + self._log_last_position = 0 - Examples - -------- - >>> wb.refresh_onelines() - """ - self.esa.RelinkAllOpenOnelines() + return output - # --- Sensitivity & Faults --- + def close(self) -> None: + """Closes the current case.""" + self.esa.CloseCase() - def ptdf(self, seller, buyer, method='DC'): - """ - Calculates PTDF between seller and buyer. + def edit_mode(self) -> None: + """Enter PowerWorld into EDIT mode.""" + self.esa.EnterMode("EDIT") - Parameters - ---------- - seller : str - Seller identifier (e.g. '[AREA "Top"]' or '[BUS 1]'). - buyer : str - Buyer identifier (e.g. '[AREA "Bottom"]' or '[BUS 2]'). - method : str, optional - Calculation method ('DC', etc.). Defaults to 'DC'. + def run_mode(self) -> None: + """Enter PowerWorld into RUN mode.""" + self.esa.EnterMode("RUN") - Returns - ------- - pd.DataFrame - PTDF results. + # --- Data Retrieval --- - Examples - -------- - >>> ptdf = wb.ptdf("[AREA 1]", "[AREA 2]") - """ - return self.esa.CalculatePTDF(seller, buyer, method) - - def lodf(self, branch, method='DC'): + def gens(self) -> DataFrame: """ - Calculates LODF for a branch. - - Parameters - ---------- - branch : str - Branch identifier string like '[BRANCH 1 2 1]'. - method : str, optional - Calculation method. Defaults to 'DC'. + Retrieve generator outputs and status. Returns ------- - pd.DataFrame - LODF results. - - Examples - -------- - >>> lodf = wb.lodf("[BRANCH 1 2 1]") + DataFrame + Columns: ``GenMW``, ``GenMVR``, ``GenStatus``, plus key fields. """ - return self.esa.CalculateLODF(branch, method) + return self[Gen, ["GenMW", "GenMVR", "GenStatus"]] - def fault(self, bus_num, fault_type='SLG', r=0.0, x=0.0): + def loads(self) -> DataFrame: """ - Runs a fault at a specified bus number. - - Parameters - ---------- - bus_num : int - The bus number to fault. - fault_type : str, optional - Type of fault (e.g. 'SLG', '3PB'). Defaults to 'SLG'. - r : float, optional - Fault resistance. Defaults to 0.0. - x : float, optional - Fault reactance. Defaults to 0.0. + Retrieve load demands and status. Returns ------- - str - Result string from SimAuto. - - Examples - -------- - >>> wb.fault(bus_num=5, fault_type="SLG") - """ - return self.esa.RunFault(create_object_string("Bus", bus_num), fault_type, r, x) - - def clear_fault(self): + DataFrame + Columns: ``LoadMW``, ``LoadMVR``, ``LoadStatus``, plus key fields. """ - Clears the currently applied fault. - - Examples - -------- - >>> wb.clear_fault() - """ - self.esa.FaultClear() + return self[Load, ["LoadMW", "LoadMVR", "LoadStatus"]] - def shortest_path(self, start_bus, end_bus): + def shunts(self) -> DataFrame: """ - Determines the shortest path between two buses. - - Parameters - ---------- - start_bus : int - Starting bus number. - end_bus : int - Ending bus number. + Retrieve switched shunt outputs and status. Returns ------- - pd.DataFrame - DataFrame describing the path. - - Examples - -------- - >>> path = wb.shortest_path(1, 10) + DataFrame + Columns: ``ShuntMW``, ``ShuntMVR``, ``ShuntStatus``, plus key fields. """ - start_str = create_object_string("Bus", start_bus) - end_str = create_object_string("Bus", end_bus) - return self.esa.DetermineShortestPath(start_str, end_str) - - # --- Advanced Analysis --- - + return self[Shunt, ["ShuntMW", "ShuntMVR", "ShuntStatus"]] - def calculate_gic(self, max_field, direction): + def lines(self) -> DataFrame: """ - Calculates GIC with specified field (V/km) and direction (degrees). - - Parameters - ---------- - max_field : float - Maximum electric field in V/km. - direction : float - Direction of the field in degrees. + Retrieve all transmission lines (excluding transformers). Returns ------- - str - Result string. - - Examples - -------- - >>> wb.calculate_gic(max_field=1.0, direction=90.0) + DataFrame + All branch fields for branches with ``BranchDeviceType == "Line"``. """ - return self.esa.CalculateGIC(max_field, direction) - - def solve_opf(self): + branches = self[Branch, :] + return branches[branches["BranchDeviceType"] == "Line"] + + def transformers(self) -> DataFrame: """ - Solves Primal LP OPF. + Retrieve all transformers (excluding lines). Returns ------- - str - Result string. - - Examples - -------- - >>> wb.solve_opf() + DataFrame + All branch fields for branches with ``BranchDeviceType == "Transformer"``. """ - return self.esa.SolvePrimalLP() + branches = self[Branch, :] + return branches[branches["BranchDeviceType"] == "Transformer"] - def ybus(self, dense=False): + def areas(self) -> DataFrame: """ - Returns the Y-Bus Matrix. - - Parameters - ---------- - dense : bool, optional - Whether to return a dense array. Defaults to False (sparse). + Retrieve all area objects with all available fields. Returns ------- - Union[np.ndarray, csr_matrix] - The Y-Bus matrix. - - Examples - -------- - >>> Y = wb.ybus() + DataFrame + All defined fields for Area objects. """ - return self.esa.get_ybus(dense) + return self[Area, :] - def branch_admittance(self): + def zones(self) -> DataFrame: """ - Calculate the branch admittance matrices, Yf and Yt. - - These matrices describe the relationship between branch currents and bus voltages. - Yf relates the current flowing from the 'from' bus to the 'to' bus, - and Yt relates the current flowing from the 'to' bus to the 'from' bus. + Retrieve all zone objects with all available fields. Returns ------- - tuple[csr_matrix, csr_matrix] - A tuple containing two SciPy CSR sparse matrices: (Yf, Yt). - - Examples - -------- - >>> Yf, Yt = wb.branch_admittance() - """ - bus_df = self[Bus, ["BusNum"]] - branch_df = self[Branch, ["BusNum", "BusNum:1", "LineCircuit", - "LineR", "LineX", "LineC", "LineTap", "LinePhase"]] - - nb = len(bus_df) - nl = len(branch_df) - - Ys = 1 / (branch_df["LineR"].to_numpy() + 1j * branch_df["LineX"].to_numpy()) - Bc = branch_df["LineC"].to_numpy() - tap = branch_df["LineTap"].to_numpy() * np.exp(1j * np.pi / 180 * branch_df["LinePhase"].to_numpy()) - Ytt = Ys + 1j * Bc / 2 - Yff = Ytt / (tap * np.conj(tap)) - Yft = -Ys / np.conj(tap) - Ytf = -Ys / tap - - # Build bus number to index mapping - bus_to_idx = {bus: idx for idx, bus in enumerate(bus_df["BusNum"])} - f = np.array([bus_to_idx[b] for b in branch_df["BusNum"]]) - t = np.array([bus_to_idx[b] for b in branch_df["BusNum:1"]]) - - i = np.r_[range(nl), range(nl)] - Yf = csr_matrix((np.hstack([Yff.reshape(-1), Yft.reshape(-1)]), (i, np.hstack([f, t]))), (nl, nb)) - Yt = csr_matrix((np.hstack([Ytf.reshape(-1), Ytt.reshape(-1)]), (i, np.hstack([f, t]))), (nl, nb)) - return Yf, Yt - - def shunt_admittance(self): + DataFrame + All defined fields for Zone objects. """ - Calculate the shunt admittance vector, Ysh. + return self[Zone, :] - This vector represents the equivalent admittance to ground for each bus, - derived from fixed bus shunts. + # --- Convenience Features --- - Returns - ------- - np.ndarray - A complex-valued NumPy array representing the shunt admittance for each bus. + @contextmanager + def snapshot(self): + """Context manager that saves and restores case state. - Examples - -------- - >>> Ysh = wb.shunt_admittance() - """ - base_df = self[Sim_Solution_Options, ["SBase"]] - base = float(base_df["SBase"].iloc[0]) - bus_df = self[Bus, ["BusNum", "BusSS", "BusSSMW"]] - bus_df = bus_df.fillna(0) - return (bus_df["BusSSMW"].to_numpy() + 1j * bus_df["BusSS"].to_numpy()) / base + Usage:: - def incidence_matrix(self): + with pw.snapshot(): + pw[Gen, "GenMW"] = modified_gen + pw.pflow() + v = pw.voltage() + # state restored here """ - Calculate the bus-branch incidence matrix. + self.esa.SaveState() + try: + yield + finally: + self.esa.LoadState() - The incidence matrix (A) describes the topology of the network. - For a system with N buses and L branches, it is an L x N matrix - where A[i, j] = 1 if branch i starts at bus j, -1 if branch i - ends at bus j, and 0 otherwise. + def flows(self) -> DataFrame: + """Retrieve branch power flows and loading. Returns ------- - np.ndarray - A NumPy array representing the incidence matrix. - - Examples - -------- - >>> A = wb.incidence_matrix() - """ - branch_df = self[Branch, ["BusNum", "BusNum:1", "LineCircuit"]] - bus_df = self[Bus, ["BusNum"]] - - # Build bus number to index mapping - bus_to_idx = {bus: idx for idx, bus in enumerate(bus_df["BusNum"])} - - incidence = np.zeros([len(branch_df), len(bus_df)], dtype=int) - for i, row in branch_df.iterrows(): - incidence[i, bus_to_idx[row["BusNum"]]] = 1 - incidence[i, bus_to_idx[row["BusNum:1"]]] = -1 - return incidence - - def jacobian(self, dense=False): + DataFrame + Columns: ``LineMW``, ``LineMVR``, ``LineMVA``, ``LinePercent``, + plus branch key fields. """ - Get the power flow Jacobian matrix. + return self[Branch, ["LineMW", "LineMVR", "LineMVA", "LinePercent"]] - The Jacobian is crucial for Newton-Raphson power flow solutions - and sensitivity analysis. + def overloads(self, threshold: float = 100.0) -> DataFrame: + """Return branches exceeding a loading threshold. Parameters ---------- - dense : bool, optional - If True, returns a dense NumPy array. If False (default), returns a - SciPy CSR sparse matrix. + threshold : float, default 100.0 + Percent loading threshold. Returns ------- - Union[np.ndarray, csr_matrix] - The Jacobian matrix. - - Examples - -------- - >>> J = wb.jacobian() - """ - return self.esa.get_jacobian(dense) - - def gmatrix(self, dense=False): + DataFrame + Subset of ``flows()`` where ``LinePercent > threshold``. """ - Get the GIC conductance matrix (G). + df = self.flows() + return df[df["LinePercent"] > threshold] - The G-matrix relates GIC currents to earth potentials. + def ptdf(self, seller: int, buyer: int, method: str = "DC") -> DataFrame: + """Calculate Power Transfer Distribution Factors. Parameters ---------- - dense : bool, optional - If True, returns a dense NumPy array. If False (default), returns a - SciPy CSR sparse matrix. + seller : int + Seller bus number. + buyer : int + Buyer bus number. + method : str, default "DC" + Linear method: "DC", "DCPS", or "AC". Returns ------- - Union[np.ndarray, csr_matrix] - The G-matrix. - - Examples - -------- - >>> G = wb.gmatrix() - """ - return self.esa.get_gmatrix(dense) - - ''' LOCATION FUNCTIONS ''' - - def busmap(self): + DataFrame + Branch PTDF values (``LinePTDF`` column) plus key fields. """ - Returns a Pandas Series indexed by BusNum to the positional value of each bus - in matricies like the Y-Bus, Incidence Matrix, Etc. - - Returns - ------- - pd.Series - Series mapping BusNum to index. + seller_str = create_object_string("Bus", seller) + buyer_str = create_object_string("Bus", buyer) + self.esa.CalculatePTDF(seller_str, buyer_str, method) + return self[Branch, ["LinePTDF"]] - Examples - -------- - >>> mapping = wb.busmap() - """ - return self.network.busmap() - - - def buscoords(self, astuple=True): - """ - Retrive dataframe of bus latitude and longitude coordinates based on substation data. + def lodf(self, branch: tuple, method: str = "DC") -> DataFrame: + """Calculate Line Outage Distribution Factors. Parameters ---------- - astuple : bool, optional - Whether to return as a tuple of (Lon, Lat). Defaults to True. + branch : tuple + Branch key as ``(from_bus, to_bus, circuit)``. + method : str, default "DC" + Linear method: "DC" or "DCPS". Returns ------- - pd.DataFrame or tuple - Coordinates data. - - Examples - -------- - >>> lon, lat = wb.buscoords() - """ - A, S = self[Bus, "SubNum"], self[Substation, ["SubNum", "Longitude", "Latitude"]] - LL = A.merge(S, on="SubNum") - if astuple: - return LL["Longitude"], LL["Latitude"] - return LL - - def write_voltage(self,V): + DataFrame + Branch LODF values (``LineLODF`` column) plus key fields. """ - Given Complex 1-D vector write to PowerWorld. + branch_str = create_object_string("Branch", *branch) + self.esa.CalculateLODF(branch_str, method) + return self[Branch, ["LineLODF"]] - Parameters - ---------- - V : np.ndarray - Complex voltage vector. - - Examples - -------- - >>> V_new = np.ones(len(wb.buses)) * 1.05 - >>> wb.write_voltage(V_new) - """ - V_df = np.vstack([np.abs(V), np.angle(V,deg=True)]).T - - self[Bus, ["BusPUVolt", "BusAngle"]] = V_df - - # --- Generator Limit Checking --- - - def gens_above_pmax(self, p=None, is_closed=None, tol=0.001): - """ - Check if any closed generators are outside active power limits. - - Parameters - ---------- - p : pd.Series, optional - Generator MW output. If None, retrieves from case. - is_closed : pd.Series, optional - Boolean series of generator status. If None, retrieves from case. - tol : float, optional - Tolerance for limit checking. Defaults to 0.001. - - Returns - ------- - bool - True if any closed generators violate P limits. - - Examples - -------- - >>> if wb.gens_above_pmax(): - ... print("Generator P limit violation detected") - """ - return self._check_gen_limits('GenMW', 'GenMWMax', 'GenMWMin', p, is_closed, tol) - - def gens_above_qmax(self, q=None, is_closed=None, tol=0.001): - """ - Check if any closed generators are outside reactive power limits. - - Parameters - ---------- - q : pd.Series, optional - Generator Mvar output. If None, retrieves from case. - is_closed : pd.Series, optional - Boolean series of generator status. If None, retrieves from case. - tol : float, optional - Tolerance for limit checking. Defaults to 0.001. + # --- Quick Properties --- - Returns - ------- - bool - True if any closed generators violate Q limits. + @property + def n_bus(self) -> int: + """Number of buses in the case.""" + return len(self[Bus]) - Examples - -------- - >>> if wb.gens_above_qmax(): - ... print("Generator Q limit violation detected") - """ - return self._check_gen_limits('GenMVR', 'GenMVRMax', 'GenMVRMin', q, is_closed, tol) + @property + def n_branch(self) -> int: + """Number of branches in the case.""" + return len(self[Branch]) - # --- State Chain Management --- + @property + def n_gen(self) -> int: + """Number of generators in the case.""" + return len(self[Gen]) - def _check_gen_limits(self, value_col, max_col, min_col, value=None, is_closed=None, tol=0.001): - """ - Helper method to check if generators exceed limits. + @property + def sbase(self) -> float: + """System MVA base.""" + return float(self[Sim_Solution_Options, "SBase"]["SBase"].iloc[0]) - Parameters - ---------- - value_col : str - Column name for current value (e.g., 'GenMW' or 'GenMVR'). - max_col : str - Column name for maximum limit. - min_col : str - Column name for minimum limit. - value : pd.Series, optional - Current values. If None, retrieves from case. - is_closed : pd.Series, optional - Boolean series of generator status. If None, retrieves from case. - tol : float, optional - Tolerance for limit checking. Defaults to 0.001. + def summary(self) -> dict: + """Quick overview of the current case state. Returns ------- - bool - True if any closed generators violate limits. - """ - gens = self[Gen, [value_col, max_col, min_col, 'GenStatus']] - - value = gens[value_col] if value is None else value - is_closed = (gens['GenStatus'] == 'Closed') if is_closed is None else is_closed - - violation = is_closed & ((value > gens[max_col] + tol) | (value < gens[min_col] - tol)) - return np_any(violation) - - # --- GIC Functions --- - - def gic_storm(self, max_field: float, direction: float, solve_pf=True): - """ - Configure a synthetic GIC storm with uniform electric field. - - Parameters - ---------- - max_field : float - Maximum electric field magnitude in Volts/km. - direction : float - Storm direction in degrees (0-360). - solve_pf : bool, optional - Whether to include results in power flow. Defaults to True. - - Examples - -------- - >>> wb.gic_storm(max_field=1.0, direction=90.0) - """ - yn = "YES" if solve_pf else "NO" - self.esa.RunScriptCommand(f"GICCalculate({max_field}, {direction}, {yn})") - - def gic_clear(self): - """ - Clear manual GIC calculations from PowerWorld. - - Examples - -------- - >>> wb.gic_clear() - """ - self.esa.RunScriptCommand("GICClear;") - - def gic_load_b3d(self, file_type: str, filename: str, setup_on_load=True): - """ - Load a B3D file containing electric field data for GIC analysis. - - Parameters - ---------- - file_type : str - The type of B3D file. - filename : str - Path to the B3D file. - setup_on_load : bool, optional - Whether to configure GIC settings on load. Defaults to True. - - Examples - -------- - >>> wb.gic_load_b3d("STORM", "storm_data.b3d") - """ - yn = "YES" if setup_on_load else "NO" - self.esa.RunScriptCommand(f"GICLoad3DEfield({file_type}, {filename}, {yn})") - - - def _set_option(self, key: str, enable: bool): - """Internal helper to set a Sim_Solution_Options boolean flag.""" - self[Sim_Solution_Options, key] = 'YES' if enable else 'NO' - - def set_do_one_iteration(self, enable: bool = True): - """Enable/disable single iteration mode for power flow solutions.""" - self._set_option('DoOneIteration', enable) - - def set_max_iterations(self, val: int = 250): - """Set maximum number of iterations for power flow convergence.""" - self[Sim_Solution_Options, 'MaxItr'] = val - - def set_disable_angle_rotation(self, enable: bool = True): - """Enable/disable angle rotation during power flow.""" - self._set_option('DisableAngleRotation', enable) - - def set_disable_opt_mult(self, enable: bool = True): - """Enable/disable optimal multiplier during power flow.""" - self._set_option('DisableOptMult', enable) - - def enable_inner_ss_check(self, enable: bool = True): - """Enable/disable inner steady-state contingency power flow check.""" - self._set_option('SSContPFInnerLoop', enable) - - def disable_gen_mvr_check(self, enable: bool = True): - """Enable/disable generator MVAR limit checking.""" - self._set_option('DisableGenMVRCheck', enable) - - def enable_inner_check_gen_vars(self, enable: bool = True): - """Enable/disable inner loop generator VAR checking.""" - self._set_option('ChkVars', enable) - - def enable_inner_backoff_gen_vars(self, enable: bool = True): - """Enable/disable inner loop generator VAR backoff.""" - self._set_option('ChkVars:1', enable) + dict + Keys: ``n_bus``, ``n_branch``, ``n_gen``, ``n_load``, + ``total_gen_mw``, ``total_load_mw``, ``v_min``, ``v_max``, + ``sbase``. + """ + g = self.gens() + l = self.loads() + v_mag = self.voltage(complex=False, pu=True)[0] + return { + 'n_bus': self.n_bus, + 'n_branch': self.n_branch, + 'n_gen': len(g), + 'n_load': len(l), + 'total_gen_mw': g['GenMW'].sum(), + 'total_load_mw': l['LoadMW'].sum(), + 'v_min': v_mag.min(), + 'v_max': v_mag.max(), + 'sbase': self.sbase, + } diff --git a/examples/__init__.py b/examples/__init__.py new file mode 100644 index 00000000..157648d2 --- /dev/null +++ b/examples/__init__.py @@ -0,0 +1,32 @@ +""" +ESAplus Example Implementations +=============================== + +This directory contains example application classes, reusable utilities, +and Jupyter notebooks demonstrating advanced usage of the esapp package. + +Application Classes +------------------- +statics.py + Continuation power flow, state chain management, ZIP load interface, + and generator limit checking. +dynamics.py + Transient stability simulation with contingency definition, execution, + and result retrieval. + +Utilities +--------- +injection.py - Normalized injection vectors for sensitivity studies +map.py - Geographic visualization (borders, lines, vector fields) +mesh.py - Discrete geometry, Grid2D, PLY mesh I/O +plot_helpers.py - Shared plotting functions for all notebooks + +Notebooks +--------- +dynamics/ - Transient stability simulation examples +steady_state/ - Contingency analysis, SCOPF, ATC, and CPF examples +gic/ - GIC analysis and sensitivity examples +network/ - Network topology and matrix extraction examples +nonuniform/ - Non-uniform electric field GIC analysis +visualization/ - Discrete calculus, spectral analysis, geographic plotting +""" diff --git a/examples/data/case.txt b/examples/data/case.txt new file mode 100644 index 00000000..512a6a47 --- /dev/null +++ b/examples/data/case.txt @@ -0,0 +1 @@ +r"C:\Users\wyatt\OneDrive - Texas A&M University\Research\Cases\Hawaii 37\Hawaii40_20231026.pwb" \ No newline at end of file diff --git a/examples/data/case_B.txt b/examples/data/case_B.txt new file mode 100644 index 00000000..37df999b --- /dev/null +++ b/examples/data/case_B.txt @@ -0,0 +1 @@ +r"C:\Users\wyatt\OneDrive - Texas A&M University\Research\Cases\Texas\ACTIVSg2000.PWB" \ No newline at end of file diff --git a/examples/dynamics.py b/examples/dynamics.py new file mode 100644 index 00000000..55fe9326 --- /dev/null +++ b/examples/dynamics.py @@ -0,0 +1,155 @@ +""" +Transient Stability Simulation Example +======================================= + +High-level interface for running transient stability simulations in +PowerWorld Simulator. Enables contingency definition, simulation +execution, and result retrieval through a fluent API. + +Example +------- + >>> from esapp import PowerWorld + >>> from esapp.utils import ContingencyBuilder, SimAction, TSWatch + >>> from examples.dynamics import Dynamics + >>> pw = PowerWorld("case.pwb") + >>> dyn = Dynamics(pw) + >>> dyn.watch(Gen, [TS.Gen.P, TS.Gen.W, TS.Gen.Delta]) + >>> dyn.bus_fault("Fault1", "101", fault_time=1.0, duration=0.1) + >>> meta, results = dyn.solve("Fault1") +""" + +import logging +import os +import re +from typing import List, Tuple, Dict, Union, Optional, Type + +from pandas import DataFrame + +from esapp.components import GObject, TS, TSContingency, TSContingencyElement +from esapp.utils.contingency import ContingencyBuilder, SimAction +from esapp.utils.dynamics import TSWatch +from esapp.saw._helpers import get_temp_filepath + +logger = logging.getLogger(__name__) + +__all__ = ['Dynamics'] + + +class Dynamics: + """ + Transient stability simulation manager. + + Parameters + ---------- + pw : PowerWorld + An initialized PowerWorld instance. + + Attributes + ---------- + runtime : float + Default simulation duration in seconds (default: 5.0). + + Example + ------- + >>> dyn = Dynamics(pw) + >>> dyn.runtime = 10.0 + >>> dyn.watch(Gen, [TS.Gen.P, TS.Gen.W]) + >>> dyn.bus_fault("Fault1", "101", fault_time=1.0, duration=0.1) + >>> meta, data = dyn.solve("Fault1") + """ + + def __init__(self, pw) -> None: + self.pw = pw + self.runtime: float = 5.0 + self._pending_ctgs: Dict[str, ContingencyBuilder] = {} + self._tswatch = TSWatch() + + def watch(self, gtype: Type[GObject], fields: list) -> 'Dynamics': + """ + Register fields to record during simulation for a specific object type. + + Parameters + ---------- + gtype : Type[GObject] + The GObject type to watch (e.g., Gen, Bus, Branch). + fields : list + List of TS field constants or field name strings. + + Returns + ------- + Dynamics + Self for method chaining. + """ + self._tswatch.watch(gtype, fields) + return self + + def contingency(self, name: str) -> ContingencyBuilder: + """ + Start building a new contingency. + + Parameters + ---------- + name : str + Unique name for the contingency. + + Returns + ------- + ContingencyBuilder + A builder instance for defining contingency events. + """ + builder = ContingencyBuilder(name, self.runtime) + self._pending_ctgs[name] = builder + return builder + + def upload_contingency(self, name: str) -> None: + """ + Compile and upload a pending contingency to the simulation engine. + + Parameters + ---------- + name : str + Name of the contingency to upload (must exist in pending list). + + Raises + ------ + ValueError + If the contingency name is not found in the pending list. + """ + if name not in self._pending_ctgs: + raise ValueError(f"Contingency '{name}' not found in pending list.") + + builder = self._pending_ctgs.pop(name) + builder.runtime = self.runtime + + ctg_df, ele_df = builder.to_dataframes() + + self.pw[TSContingency] = ctg_df + + if not ele_df.empty: + self.pw[TSContingencyElement] = ele_df + + logger.info(f"Uploaded contingency: {name} with {len(ele_df)} events.") + + def solve(self, ctgs: Union[str, List[str]]) -> Tuple[DataFrame, DataFrame]: + """ + Run the simulation for the specified contingencies. + + Parameters + ---------- + ctgs : Union[str, List[str]] + A single contingency name or a list of names. + + Returns + ------- + Tuple[DataFrame, DataFrame] + (Metadata, Time-Series Data). + """ + ctgs_to_solve = [ctgs] if isinstance(ctgs, str) else list(ctgs) + + for ctg in ctgs_to_solve: + if ctg in self._pending_ctgs: + self.upload_contingency(ctg) + + retrieval_fields = self._tswatch.prepare(self.pw) + + return self.pw.ts_solve(ctgs_to_solve, retrieval_fields) diff --git a/examples/dynamics/01_transient_stability.ipynb b/examples/dynamics/01_transient_stability.ipynb new file mode 100644 index 00000000..3798ae6b --- /dev/null +++ b/examples/dynamics/01_transient_stability.ipynb @@ -0,0 +1,143 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "aa1b2c3d", + "metadata": {}, + "source": [ + "# Transient Stability Simulation\n\nDemonstrates the dynamics module's fluent API for configuring and running\ntransient stability simulations. The notebook covers simulation setup,\ncontingency definition with the fluent builder, dynamic model inventory,\nand result visualization." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bb2c3d4e", + "metadata": {}, + "outputs": [], + "source": "from esapp import PowerWorld, TS\nfrom esapp.components import Bus, Gen\n\nimport sys; sys.path.insert(0, '..')\nfrom plot_helpers import plot_dynamics" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cc3d4e5f", + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": "# This cell is hidden in the documentation.\nimport ast\n\nwith open('../data/case.txt', 'r') as f:\n case_path = ast.literal_eval(f.read().strip())\n\npw = PowerWorld(case_path)" + }, + { + "cell_type": "markdown", + "id": "dd4e5f6a", + "metadata": {}, + "source": "Import the case and instantiate the `PowerWorld`.\n\n```python\nfrom esapp import PowerWorld, TS\nfrom esapp.components import Bus, Gen\n\npw = PowerWorld(case_path)\n```\n\n## 1. Simulation Setup\n\nConfigure the simulation runtime and specify which fields to record.\nThe `TS` class provides IDE autocomplete for all transient stability result fields." + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ee5f6a7b", + "metadata": {}, + "outputs": [], + "source": "# Set simulation duration\npw.dyn.runtime = 10.0\n\n# Watch generator fields during simulation\npw.dyn.watch(Gen, [TS.Gen.P, TS.Gen.W, TS.Gen.Delta])\n\n# Watch bus voltage\npw.dyn.watch(Bus, [TS.Bus.VPU, TS.Bus.Deg]) # TODO remove TS.Bus.FreqMeasT (parsed wrong?)" + }, + { + "cell_type": "markdown", + "id": "ff6a7b8c", + "metadata": {}, + "source": [ + "## 2. Defining Contingencies\n", + "\n", + "The fluent API allows natural definition of timed events using method chaining." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ab7b8c9d", + "metadata": {}, + "outputs": [], + "source": "# Define a bus fault contingency\n(pw.dyn.contingency(\"Fault_Bus1\")\n .at(1.0).fault_bus(\"1\") # 3-phase fault at bus 1 at t=1.0s\n .at(1.153).clear_fault(\"1\")) # Clear after ~9 cycles\n\nprint(\"Contingency 'Fault_Bus1' defined:\")\nprint(\" t=1.000s: Apply 3-phase bus fault at Bus 1\")\nprint(\" t=1.153s: Clear fault at Bus 1\")" + }, + { + "cell_type": "markdown", + "id": "bc8c9d0e", + "metadata": {}, + "source": [ + "## 3. Dynamic Model Inventory\n", + "\n", + "List all dynamic models present in the case. This shows generators, exciters,\n", + "governors, and other dynamic models." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cd9d0e1f", + "metadata": {}, + "outputs": [], + "source": "models = pw.dyn.list_models()\nprint(\"Dynamic Models:\")\nprint(models.to_string())" + }, + { + "cell_type": "markdown", + "id": "de0e1f2a", + "metadata": {}, + "source": [ + "## 4. Running the Simulation\n", + "\n", + "The `solve()` method runs the transient stability simulation and returns\n", + "metadata and time-series results." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ef1f2a3b", + "metadata": {}, + "outputs": [], + "source": "meta, results = pw.dyn.solve(\"Fault_Bus1\")\n\nprint(f\"Metadata shape: {meta.shape}\")\nprint(f\"Results shape: {results.shape}\")\nprint(f\"\\nMetadata columns: {list(meta.columns)}\")\nprint(f\"Time range: {results.index.min():.3f} to {results.index.max():.3f} seconds\")" + }, + { + "cell_type": "markdown", + "id": "fa2a3b4c", + "metadata": {}, + "source": "## 5. Plotting Results\n\nThe `plot_dynamics()` helper creates grouped subplots by object type and field." + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ab3b4c5d", + "metadata": {}, + "outputs": [], + "source": "plot_dynamics(meta, results)" + }, + { + "cell_type": "markdown", + "id": "bc4c5d6e", + "metadata": {}, + "source": "## Summary\n\nThe dynamics module provides a fluent interface for defining contingencies\nand running transient stability simulations. Watched fields are recorded\nat each time step and can be plotted with `plot_dynamics()` from the\nplot helpers. Multiple contingency definitions can coexist for comparative\nstudies." + } + ], + "metadata": { + "kernelspec": { + "display_name": "esaplus", + "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.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file diff --git a/examples/dynamics/02_multi_contingency.ipynb b/examples/dynamics/02_multi_contingency.ipynb new file mode 100644 index 00000000..0fa0016b --- /dev/null +++ b/examples/dynamics/02_multi_contingency.ipynb @@ -0,0 +1,116 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "aaa1b2c3", + "metadata": {}, + "source": [ + "# Multi-Contingency Transient Stability\n\nDemonstrates batch transient stability simulation with multiple contingency\nscenarios and comparative visualization. Several fault types are defined,\nsolved in sequence, and their dynamic responses compared side-by-side." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": "import matplotlib.pyplot as plt\nfrom esapp import PowerWorld, TS\nfrom esapp.components import Bus, Gen\nfrom examples.map import format_plot" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ccc3d4e5", + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": "# This cell is hidden in the documentation.\nimport ast\n\nwith open('../data/case.txt', 'r') as f:\n case_path = ast.literal_eval(f.read().strip())\n\npw = PowerWorld(case_path)" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": [ + "# Plotting functions (hidden from documentation)\n", + "import sys; sys.path.insert(0, \"..\")\n", + "from plot_helpers import plot_comparative_dynamics" + ] + }, + { + "cell_type": "markdown", + "id": "ddd4e5f6", + "metadata": {}, + "source": [ + "## 1. Define Multiple Contingencies\n", + "\n", + "Create several contingency scenarios to compare their dynamic impact." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "eee5f6a7", + "metadata": {}, + "outputs": [], + "source": "pw.dyn.runtime = 10.0\npw.dyn.watch(Gen, [TS.Gen.P, TS.Gen.W, TS.Gen.Delta])\npw.dyn.watch(Bus, [TS.Bus.VPU])\n\n# Contingency 1: Bus fault\n(pw.dyn.contingency(\"Bus_Fault\")\n .at(1.0).fault_bus(\"1\")\n .at(1.153).clear_fault(\"1\"))\n\n# Contingency 2: Generator trip\n(pw.dyn.contingency(\"Gen_Trip\")\n .at(1.0).trip_gen(\"2\", \"1\"))\n\n# Contingency 3: Branch trip\nbranches = pw[Gen].head()\n(pw.dyn.contingency(\"Branch_Trip\")\n .at(1.0).trip_branch(\"1\", \"2\", \"1\"))" + }, + { + "cell_type": "markdown", + "id": "fff6a7b8", + "metadata": {}, + "source": [ + "## 2. Batch Simulation\n", + "\n", + "Solve all contingencies and collect results." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "aab7b8c9", + "metadata": {}, + "outputs": [], + "source": "ctg_names = [\"Bus_Fault\", \"Gen_Trip\", \"Branch_Trip\"]\nall_meta = {}\nall_results = {}\n\nfor name in ctg_names:\n meta, results = pw.dyn.solve(name)\n all_meta[name] = meta\n all_results[name] = results\n print(f\"Solved '{name}': {results.shape[0]} time steps, {results.shape[1]} channels\")" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plot_comparative_dynamics(ctg_names, all_results)" + ] + }, + { + "cell_type": "markdown", + "id": "eef1f2a3", + "metadata": {}, + "source": [ + "## Summary\n\nBatch simulation enables systematic screening of contingencies by solving\neach scenario in sequence and collecting results. The comparative plot\nreveals which fault types produce the most severe dynamic response,\nsupporting contingency ranking and worst-case identification." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "name": "python", + "version": "3.11.0" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file diff --git a/examples/example_get_subdata.py b/examples/example_get_subdata.py deleted file mode 100644 index c07580ce..00000000 --- a/examples/example_get_subdata.py +++ /dev/null @@ -1,107 +0,0 @@ -""" -Example: GetSubData - Retrieving nested SubData from PowerWorld objects. - -SubData sections store hierarchical data not available through CSV exports: -- BidCurve: Generator/Load cost curves (MW, $/MWh) -- ReactiveCapability: Generator Q limits by MW output (MW, MinMVAR, MaxMVAR) -- CTGElement: Contingency element definitions (actions) -- InterfaceElement: Interface branch membership -- SuperAreaArea: Areas within a super area -- ColorPoint: Contour color breakpoints -- Line: Polyline coordinates for background objects -""" - -from esapp.saw import SAW - -case_path = r"C:\Users\wyattluke.lowery\OneDrive - Texas A&M University\Research\Cases\Hawaii 37\Hawaii40_20231026.pwb" -saw = SAW(case_path) - -# ----------------------------------------------------------------------------- -# Example 1: Generator Cost Curves (BidCurve) and Reactive Capability -# ----------------------------------------------------------------------------- -print("=" * 60) -print("GENERATORS: BidCurve + ReactiveCapability") -print("=" * 60) - -df = saw.GetSubData("Gen", ["BusNum", "BusName", "GenID", "GenMW", "GenMWMax"], - ["BidCurve", "ReactiveCapability"]) - -for _, row in df.iterrows(): - print(f"\nGen @ Bus {row['BusNum']} ({row['BusName']}) ID={row['GenID']}") - print(f" Output: {row['GenMW']} MW (Max: {row['GenMWMax']})") - - if row["BidCurve"]: - print(f" BidCurve: {len(row['BidCurve'])} points") - for mw, price in row["BidCurve"]: - print(f" {mw:>8} MW @ ${price}/MWh") - - if row["ReactiveCapability"]: - print(f" ReactiveCapability: {len(row['ReactiveCapability'])} points") - for mw, qmin, qmax in row["ReactiveCapability"]: - print(f" {mw:>8} MW: Q=[{qmin}, {qmax}] MVAR") - -# ----------------------------------------------------------------------------- -# Example 2: Load Benefit Curves -# ----------------------------------------------------------------------------- -print("\n" + "=" * 60) -print("LOADS: BidCurve (Benefit Curves)") -print("=" * 60) - -df = saw.GetSubData("Load", ["BusNum", "LoadID", "LoadMW"], ["BidCurve"]) -for _, row in df.iterrows(): - if row["BidCurve"]: - print(f"Load @ Bus {row['BusNum']} ID={row['LoadID']}: {len(row['BidCurve'])} bid points") - -# ----------------------------------------------------------------------------- -# Example 3: Contingency Elements -# ----------------------------------------------------------------------------- -print("\n" + "=" * 60) -print("CONTINGENCIES: CTGElement (Actions)") -print("=" * 60) - -df = saw.GetSubData("Contingency", ["TSContingency", "CTGSkip"], ["CTGElement"]) -for _, row in df.iterrows(): - print(f"\nContingency: {row['TSContingency']} (Skip={row['CTGSkip']})") - if row["CTGElement"]: - for elem in row["CTGElement"][:5]: # Show first 5 elements - print(f" {' '.join(elem)}") - if len(row["CTGElement"]) > 5: - print(f" ... and {len(row['CTGElement']) - 5} more elements") - -# ----------------------------------------------------------------------------- -# Example 4: Interface Elements -# ----------------------------------------------------------------------------- -print("\n" + "=" * 60) -print("INTERFACES: InterfaceElement") -print("=" * 60) - -df = saw.GetSubData("Interface", ["InterfaceName", "InterfaceMW"], ["InterfaceElement"]) -for _, row in df.iterrows(): - if row["InterfaceElement"]: - print(f"Interface '{row['InterfaceName']}': {len(row['InterfaceElement'])} elements, MW={row['InterfaceMW']}") - -# ----------------------------------------------------------------------------- -# Example 5: Super Areas -# ----------------------------------------------------------------------------- -print("\n" + "=" * 60) -print("SUPER AREAS: SuperAreaArea") -print("=" * 60) - -df = saw.GetSubData("SuperArea", ["SuperAreaName", "SuperAreaNum"], ["SuperAreaArea"]) -for _, row in df.iterrows(): - if row["SuperAreaArea"]: - areas = [a[0] for a in row["SuperAreaArea"]] - print(f"SuperArea '{row['SuperAreaName']}': Areas {areas}") - -# ----------------------------------------------------------------------------- -# Example 6: Using Filters -# ----------------------------------------------------------------------------- -print("\n" + "=" * 60) -print("FILTERED: Generators in Area 1 only") -print("=" * 60) - -df = saw.GetSubData("Gen", ["BusNum", "GenID", "GenMW"], ["BidCurve"], filter_name="AreaNum=1") -print(f"Found {len(df)} generators in Area 1") - -saw.CloseCase() -print("\nDone.") diff --git a/examples/gic/01_gic_basics.ipynb b/examples/gic/01_gic_basics.ipynb new file mode 100644 index 00000000..e61a2b3e --- /dev/null +++ b/examples/gic/01_gic_basics.ipynb @@ -0,0 +1,201 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "fa1b2c3d", + "metadata": {}, + "source": [ + "# GIC Basics\n\nIntroduces the GIC module for computing geomagnetically induced currents\nin power systems. The notebook walks through configuring a uniform E-field\nstorm, retrieving transformer GIC currents, visualizing the distribution,\nand sweeping storm direction to identify the worst-case orientation." + ] + }, + { + "cell_type": "markdown", + "id": "fb2c3d4e", + "metadata": {}, + "source": "Import the case and instantiate the `PowerWorld`.\n\n```python\nfrom esapp import PowerWorld\nfrom esapp.components import *\n\npw = PowerWorld(case_path)\n```" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fc3d4e5f", + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": "# This cell is hidden in the documentation.\nfrom esapp import PowerWorld\nfrom esapp.components import *\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport ast\n\nwith open('../data/case.txt', 'r') as f:\n case_path = ast.literal_eval(f.read().strip())\n\npw = PowerWorld(case_path)" + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "670cab8a", + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": [ + "# Plotting functions (hidden from documentation)\n", + "import sys; sys.path.insert(0, \"..\")\n", + "from plot_helpers import plot_gic_distribution, plot_direction_sensitivity" + ] + }, + { + "cell_type": "markdown", + "id": "fd4e5f6a", + "metadata": {}, + "source": [ + "## Calculate GIC Response\n", + "\n", + "Compute geomagnetically induced currents for a uniform electric field. This calculates harmonic currents in transformers due to a 1.0 V/km electric field oriented at 90 degrees:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fe5f6a7b", + "metadata": {}, + "outputs": [], + "source": "pw.gic.storm(max_field=1.0, direction=90.0)" + }, + { + "cell_type": "markdown", + "id": "ff6a7b8c", + "metadata": {}, + "source": [ + "## Retrieve GIC Results\n", + "\n", + "Extract GIC neutral currents from the transformers to identify which components experience the largest impacts:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a07b8c9d", + "metadata": {}, + "outputs": [], + "source": "gics = pw[GICXFormer, ['BusNum3W', 'BusNum3W:1', 'GICXFNeutralAmps']]\ngics.head()" + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "a18c9d0e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Maximum |GIC|: 15.440 Amps\n" + ] + } + ], + "source": [ + "max_gic = gics['GICXFNeutralAmps'].abs().max()\n", + "print(f\"Maximum |GIC|: {max_gic:.3f} Amps\")" + ] + }, + { + "cell_type": "markdown", + "id": "a29d0e1f", + "metadata": {}, + "source": [ + "### GIC Distribution\n", + "\n", + "Visualize the distribution of GIC magnitudes across all transformers." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "3869bdf3", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABWwAAAHqCAYAAACQrwf+AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAZY1JREFUeJzt3QucVWW5MPAHQW4KKKggxU0RL6hAJiaZiBpKaCpWakCglEiKqXkB+QQ9akCRWEqQJdD5RCFPokYlBgrqRwoqJGR5CwS85g1UEgX293vXOXvOzDADAwzMhvn/f78ls9Zee+13r73Hefazn/W8NXK5XC4AAAAAAKhyu1X1AAAAAAAA+G8StgAAAAAABULCFgAAAACgQEjYAgAAAAAUCAlbAAAAAIACIWELAAAAAFAgJGwBAAAAAAqEhC0AAAAAQIGQsAUAAAAAKBAStgDVwE9+8pM44IADombNmtGxY8eqHg4AAAVk8uTJUaNGjVi2bNkOebzWrVtH//79d8hjVfUY0jlN5zad47z0uHvuuWfsKOnxr7/++h32eMC2k7AFtvmPf0WWOXPmbNczvWLFirjhhhuic+fOsffee8c+++wTJ5xwQsyaNavM/T/44IO48MILY99994099tgjunXrFs8++2yFAtnNLSn4KyQPP/xwXH311fHlL385Jk2aFD/60Y+iunjuuefi/PPPjzZt2kTdunWzwDglrNP5+Oc//1li300FztOnT48ePXpk76vatWtH8+bN41vf+lY88sgjO+iZAAAVsXTp0rjkkkuiXbt2Ub9+/Ww57LDD4uKLL87iguJSAivFbu+8885Gx0mxa69evaJZs2bZ3/799tsvTj/99Ljvvvs2O4YUC6bjnnzyyWXe/qtf/aoobnz66acL9oX9xS9+USLJWMhS3J8/p7vttls0bNgwDj744Ojbt2/8+c9/rrTH+eMf/1iwic9CHhuw5WptxX0Aivzf//t/S5yN//zP/8yCotLbDz300O161h544IEYPXp0nHnmmdGvX79Yt25dNpavfvWrMXHixCxpl7dhw4bo2bNn/PWvf42rrroqS8KlgDQFes8880wcdNBBZT7G8ccfv9Hz+u53v5sliVPyN29HflteESmpmALXO++8M/vAUV2kD0ODBg3KXt/evXvHIYcckr0vlixZkr03br311vj3v/+dVR2XJ5fL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76T7pD7B6YNSOmfp0sUkvQapsjdNmpeqM55++umsqrr4ZBIAwPaR/t6nZFOqZk1Vsulvf4p3UhIsxRbptlQ5+PnPf36Tx0mTvqaWCDfffHMsXLgwO15KmqVkXuqxmqpg07G2RLr/5q64SQmy/HwEn332Wda7P8XMaeylpWOl27785S/HoEGDioojUhy9aNGiqCwpphk/fnwWr6XEZaruTe3GUrIvVbwOGDAgi5VSAnDixIlZ5eby5cuL7p/WUyyX2nWlODgVDKRzmhLLKf4uLh0nTQab9kstxNJjpyRwei1SPJVixdL3KS31+c1/BkiFDSmJnWLv1OYgxcY33njjJu9fkVguPzly+qySPrOk5765uLs8qVI6vadSTJ5aZ6Tzkua2SMUn+SsLU7uPNJFySnqnYpcUP6cvDMrq6bslY0uvaertnJKz3//+97PPEanfc0pOp/cgUAByAJXo4osvTl+fl9j24Ycf5i6//PJc8+bNc7vvvnvuoIMOyv3kJz/JbdiwocR+6X7p/nfddVe2T506dXKdOnXKPfroo5t93BEjRmT3L28pfYz33nsvN2DAgFyTJk1y9evXz3Xt2jW3YMGCLX6+e+yxR65fv35F60uXLs0eLz2/0tLz/dGPfpRr1apV0XObMWNGdv+0rSLHSNvTc03eeeed7Hwdcsgh2TgaNWqUO+aYY3K//e1vS9wnHT/dXtpnn32Wu+GGG3Jt2rTJXpcWLVrkhg4dmvvkk09K7JfG1rNnz43un85pGs+9995bYvukSZOy7aXPZ/41+te//lVi++9+97vccccdl40xLen5pOf1wgsvFO2TXp/27dvnttTChQtz3/nOd3ItW7bM1a5dOzv+kUcemfvhD3+Ye/nllyt0npL/+q//ynXv3j3XuHHjXK1atXL7779/7pxzzsnNmTOnaJ+bbrop17lz59xee+2Vq1evXvY8br755tynn366xeMGALZO+vs+aNCgXNu2bXN169Yt+pt80UUX5RYtWlSh2CSZPXt27owzzsjtt99+2d/+fffdN3f66afnHnjggc2OobzYaXPx0sqVK3NnnXVWFkukuO6b3/xm7vXXXy8R/xUfX4olU3xz4IEH5n79619n8U16zmXF12WNsXgMmx9PikPz3nzzzex5NGjQILstxWN5zzzzTBZ3psdPcdYtt9xS5jHWr1+fxZspdkqvxQknnJBbsmTJRo+f/8yQYtH02qXj7rPPPrkuXbrkxowZs9l4Ko2teOy/5557Zp8n+vTpk3v44YfLvE/pMVQkllu3bl1u8ODB2fuhRo0aRZ97NhW/529L56d03PnKK69kMWb6PNK0adPsdU7nrLj0/jz77LOzffbee+/cwIEDs3NY+pjljS0p6z307LPP5k455ZTsXKVjd+vWLTdv3rwKxfX5zwEV+ZwGbJ0a6T9VnTQGSNK3xhdffPFG7RMAAIBNS1crpSuDypoTAoCdix62AAAAsBP597//XWI9JWn/+Mc/Zpf0A7Dz08MWAAAAdiIHHHBA1us1/fvqq69mvWZTf/40pwMAOz8JWwAAANiJnHrqqXHPPfdkE6GmiXqPPfbY+NGPfpRNvgbAzk8PWwAAAACAAqGHLQAAAABAgZCwBQAAAAAoENWmh+2GDRvi9ddfjwYNGkSNGjWqejgAAGyjXC4XH374YTRv3jx2223XqkMQuwIAVN+4tdokbFOytkWLFlU9DAAAKtmKFSvi85///C51XsWuAADVN26tNgnbVFmbPzENGzas6uEAALCNVq9enX0hn4/zdiViVwCA6hu3VpuEbb4NQkrWStgCAOw6dsV2V2JXAIDqG7fuWs2+AAAAAAB2YhK2AAAAAAAFQsIWAAAAAKBASNgCAAAAABQICVsAAAAAgAIhYQsAAAAAUCAkbAEAAAAACoSELQAAAABAgZCwBQAAAAAoEBK2AAAAAAAFQsIWAAAAAKBASNgCAAAAABQICVsAAKhk69evj+uuuy7atGkT9erViwMPPDBuvPHGyOVyzjUAAJtUa9M3AwAAW2r06NExfvz4+M1vfhPt27ePp59+Os4///xo1KhRXHrppU4oAADlkrAFAIBKNm/evDjjjDOiZ8+e2Xrr1q3jnnvuifnz5zvXAABskpYIAABQybp06RKzZ8+OF198MVv/61//Gk888UT06NHDuQYAYJOqXYXtWaNnRq269at6GAAAu4yZ1/13FSn/a8iQIbF69eo45JBDombNmllP25tvvjl69+5d5mlau3ZttuSl+wIAUD2psAUAgEr229/+NqZMmRJ33313PPvss1kv2zFjxmT/lmXkyJFZf9v80qJFiyp5TdZvyO3SjwcAsDOodhW2AACwvV111VVZle25556brR9xxBHx6quvZonZfv36bbT/0KFD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8Gx9W82ZMyf222+/OPjgg2PQoEHx7rvvVsp4AQAAAAB2yQrbJPWXHT9+fBx66KFxxBFHxJAhQ8rcL/W73W23/80ZP/7449GpU6dy2yGk3rht2rSJV155Ja699tro0aNH/OUvf8laMZS2du3abMlbvXp1pTw3AAAAAICdKmGbTJw4MerXrx9Lly6NlStXRuvWrTfaZ9q0aVlSNy9NTFaec889t+jnlAQ+8sgj48ADD8yqbk866aSN9h85cmTccMMNlfJcAAAAAAB22pYI8+bNi7Fjx8aMGTOic+fOMWDAgMjlchvtlxK0bdu2LVq2ZBKxAw44IPbZZ594+eWXy7x96NChsWrVqqJlxYoV2/ScAAAAAAB2ugrbNWvWRP/+/bMes926dctaGKSK2AkTJmTbKkuq2k09bPfff/8yb0/J3y1JAAMAAAAA7HIVtqmyNVXTjho1KltPrRDGjBkTV199dSxbtmyrjvnRRx/FVVddFU8++WR2jNmzZ8cZZ5yRVeWecsoplfwMAABg21x//fXZvA7Fl0MOOcRpBQBgxyZs586dG+PGjYtJkyZl/WvzBg4cmE0wVl5rhM1Jk4o999xz8fWvfz3atWuXHeeoo47KJilTRQsAQCFq3759vPHGG0XLE088UdVDAgCgurVE6Nq1a6xbt67M22bOnFn0c6q63ZLEbb169UrcHwAACl2tWrWiWbNmVT0MAAB2Mttl0jEAAKjuXnrppWjevHk2WW7v3r1j+fLlVT0kAACq46RjAABQ3R1zzDExefLkOPjgg7N2CDfccEN85StfiSVLlkSDBg022n/t2rXZkrd69eodPGIAAAqFhC0AAFSyHj16FP185JFHZgncVq1axW9/+9tsPobSRo4cmSV1AQBASwQAANjO9tprr2zy3JdffrnM24cOHRqrVq0qWlasWOE1AQCopiRsAQBgO/voo4/ilVdeif3337/M2+vUqRMNGzYssQAAUD1J2AIAQCW78sorY+7cubFs2bKYN29enHXWWVGzZs0477zznGsAADap2vWwnX7NKSoWAADYrlauXJklZ999993Yd99947jjjosnn3wy+xkAADal2iVsAQBge5s6daqTDADAVtESAQAAAACgQEjYAgAAAAAUCAlbAAAAAIACIWELAAAAAFAgqt2kY2eNnhm16tbfoY8587qeO/TxAAAAAICdkwpb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P4xTTz01GjRokLVl2H333cvdNz1eaplQfAEAAAAA2GUStmvWrIn+/fvHoEGDolu3bnHnnXdmE49NmDAhtrdUIdu9e/dscrMHH3ww6tatu90fEwAAAACgYFsipDYDqZp21KhR2XpqhTBmzJi48soro0ePHmW2RqiI9957L5YvXx6vv/56tv7CCy9k/zZr1ixb8snalDC+6667svX8JGL77rtv1KxZc6seFwAAAABgp6ywnTt3bowbNy4mTZqU9a/NGzhwYDbBWHmtESoiVcx26tQp602bnHvuudl6vnL32WefjaeeeioWL16ctVfYf//9i5YVK1Zs1WMCAAAAAOy0FbZdu3aNdevWlXnbzJkzi35OVbZbmrhNbRbSUp4TTjhhq5PBAAAAAAC77KRjAAAAAABsHxK2AAAAAAAFQsIWAAAAAKBASNgCAAAAABQICVsAAAAAgAIhYQsAAAAAUCAkbAEAAAAACoSELQAAAABAgZCwBQAAAAAoEBK2AAAAAAAFQsIWAAAAAKBASNgCAAAAABQICVsAAAAAgAIhYQsAAAAAUCAkbAEAAAAACoSELQAAAABAgZCwBQAAAAAoEBK2AAAAAAAFQsIWAAAAAKBASNgCAAAAABQICVsAANhOxo0bF61bt466devGMcccE/Pnz3euAQDYJAlbAADYDqZNmxZXXHFFjBgxIp599tno0KFDnHLKKfH222873wAAlEvCFgAAtoNbbrklvve978X5558fhx12WEyYMCHq168fEydOdL4BAChXragmcrlc9u/q1aureigAAFSCfFyXj/MKyaeffhrPPPNMDB06tGjbbrvtFieffHL85S9/2Wj/tWvXZkveqlWrqix23bd+xKeNau6QxxGbA7Az2lF/K5OGu2/I/l5Wh7/PO/K87ruDn+eWxq3VJmH77rvvZv+2aNGiqocCAEAl+vDDD6NRo0YFdU7feeedWL9+fTRt2rTE9rT+j3/8Y6P9R44cGTfccMNG23f12HXjZwwAlHbxDj4l1eXv8w0FHLdWm4Rt48aNs3+XL19ecAF9IUvfAKQPCitWrIiGDRtW9XB2Gs6b8+b9Vvj8njpv3ms7/+9oqlBIQW/z5s1jZ5cqcVO/27wNGzbEe++9F02aNIkaNWps98f3/0Tnynuq6vj9c568n/zuFTL/j6qc87SlcWu1SdimS9CSlKyVeNxy6Zw5b87bjuL95rztSN5vzpv32s79O1qoX8Tvs88+UbNmzXjrrbdKbE/rzZo122j/OnXqZEtxe+21V+xo/p/oXHlPVR2/f86T95PfvULm/1Hbfp62JG416RgAAFSy2rVrx1FHHRWzZ88uUTWb1o899ljnGwCAclWbClsAANiRUouDfv36xRe/+MXo3Llz3HrrrfHxxx/H+eef74UAAKBc1SZhmy4xGzFixEaXmuG8eb8VDr+nzpv3W+Hze+qcea9V3DnnnBP/+te/Yvjw4fHmm29Gx44d46GHHtpoIrJC4HfbufKe8vtX6Px/ynnynvK7V53+H1Ujl7reAgAAAABQ5fSwBQAAAAAoEBK2AAAAAAAFQsIWAAAAAKBASNgCAAAAABSIapOwHTduXLRu3Trq1q0bxxxzTMyfP7+qh1TQRo4cGUcffXQ0aNAg9ttvvzjzzDPjhRdeqOph7VRGjRoVNWrUiMsuu6yqh7JTeO2116JPnz7RpEmTqFevXhxxxBHx9NNPV/WwCtb69evjuuuuizZt2mTn68ADD4wbb7wxzCNZ0mOPPRann356NG/ePPt9vP/++0vcns5Xmr19//33z87jySefHC+99FJUd5s6b5999llcc8012e/oHnvske3zne98J15//fWo7jb3fivuoosuyva59dZbo7qryHn7+9//Hl//+tejUaNG2fsuxSjLly+vkvHuqsTKmyY23npi4vKJfzdPzFs+cW7FiGsrTixbWLFrtUjYTps2La644ooYMWJEPPvss9GhQ4c45ZRT4u23367qoRWsuXPnxsUXXxxPPvlk/PnPf84+oHfv3j0+/vjjqh7aTmHBggXxy1/+Mo488siqHspO4f33348vf/nLsfvuu8ef/vSneP755+OnP/1p7L333lU9tII1evToGD9+fNx+++3ZH4O0/uMf/zhuu+22qh5aQUn/z0r/z0+JiLKkc/bzn/88JkyYEE899VT2xzT9ffjkk0+iOtvUeVuzZk32tzR9YZD+ve+++7Iv9FJAUt1t7v2WN3369Ozvawry2Px5e+WVV+K4446LQw45JObMmRPPPfdc9v5LX8JTOcTKmyc23jpi4vKJfytGzFs+cW7FiGsrTixbYLFrrhro3Llz7uKLLy5aX79+fa558+a5kSNHVum4diZvv/12Lr1d5s6dW9VDKXgffvhh7qCDDsr9+c9/znXt2jX3gx/8oKqHVPCuueaa3HHHHVfVw9ip9OzZM3fBBReU2NarV69c7969q2xMhS79P2z69OlF6xs2bMg1a9Ys95Of/KRo2wcffJCrU6dO7p577qmiURb+eSvL/Pnzs/1effXVHTaunfW8rVy5Mve5z30ut2TJklyrVq1yY8eOrZLx7Uzn7Zxzzsn16dOnysZUHYiVt5zYePPExJsm/q0YMW/FiHO37jyVRVy76XMllt1xsesuX2H76aefxjPPPJNd5pq32267Zet/+ctfqnRsO5NVq1Zl/zZu3Liqh1LwUmVyz549S7zn2LQHH3wwvvjFL8Y3v/nNrAVHp06d4le/+pXTtgldunSJ2bNnx4svvpit//Wvf40nnngievTo4bxV0NKlS+PNN98s8buaLllJbXP8fdjyvxHpcqC99trL+28TNmzYEH379o2rrroq2rdv71xV8Jz94Q9/iHbt2mXV7+lvRPod3VS7CbaMWHnriI03T0y8aeLfihHzbh1x7tYT15ZPLLtjY9ddPmH7zjvvZH1vmjZtWmJ7Wk8f1KnYGy71YU2XrB9++OFO2SZMnTo1u0Q49Tmj4v75z39ml/cfdNBBMXPmzBg0aFBceuml8Zvf/MZpLMeQIUPi3HPPzS6zSK0kUpI7/Z727t3bOaug/N8Afx+2TWofkXrannfeedGwYUPvv81c1lmrVq3s/29UTGpf9dFHH2U9ME899dR4+OGH46yzzopevXpll6iz7cTKW05svHli4s0T/1aMmHfriHO3jrh208SyOzZ2rbVFe1Ntvx1fsmRJVr1H+VasWBE/+MEPsp6/+upt+QefVGH7ox/9KFtPycf0nkt9Rfv16+dtV4bf/va3MWXKlLj77ruzSr1FixZlCdvUE9M5Y0dJ/c2/9a1vZZO3pS9dKF+62udnP/tZ9qVeqkam4n8fkjPOOCMuv/zy7OeOHTvGvHnzsr8RXbt2dSrZ4cTGmyYmrhjxb8WIedlRxLWbJpbd8bHrLl9hu88++0TNmjXjrbfeKrE9rTdr1qzKxrWzuOSSS2LGjBnx6KOPxuc///mqHk7B/w8sfZvyhS98IaugSkv6BiVNaJR+TpXelG3//fePww47rMS2Qw891Azgm5Auqc5XHBxxxBHZZdbpD4Lq7orL/w3w92HbgtpXX301+6JKde2mPf7449nfiJYtWxb9jUjn7oc//GG0bt16K1+FXV+K49K58jdi+55jsXLFiY03T0xcMeLfihHzbh1x7pYR126eWHbHx667fMK2du3acdRRR2W9HotnvNP6scceW6VjK2SpWioFpGkm60ceeSTatGlT1UMqeCeddFIsXrw4q3TML6lqNF2inn5OH4YoW2q3kWaZLy71Zm3VqpVTVo41a9Zk/biLS++x/Dd6bF76/1oKZov/fVi9enU89dRT/j5UMKh96aWXYtasWdGkSRNvuc1IX6qkGWKL/41IFfHpg2hqBUP5cdzRRx/tb8R2JFauGLFxxYmJK0b8WzFi3q0jzq04cW3FiGV3fOxaLVoiXHHFFdklwil51rlz57j11lvj448/jvPPP7+qh1bQl3qlS60feOCBaNCgQVEPnDQhT7169ap6eAUpnafSPX732GOPLJGh9++mpcrQNKFAaomQkkDz58+PO+64I1so2+mnnx4333xzVq2XWiIsXLgwbrnllrjgggucsmJS/6CXX365xAQMKVGWJlBM5y61kbjpppuy/skpsL3uuuuyJNqZZ55Zrc/jps5bqgj6xje+kV3an67ASFcP5P9GpNtTkFJdbe79VjqxnfpPpy8NDj744KjONnfeUlL7nHPOieOPPz66desWDz30UPz+97+POXPmVOm4dyVi5c0TG1ecmLhixL8VI+Ytnzi3YsS1FSeWLbDYNVdN3HbbbbmWLVvmateunevcuXPuySefrOohFbT01ihrmTRpUlUPbafStWvX3A9+8IOqHsZO4fe//33u8MMPz9WpUyd3yCGH5O64446qHlJBW716dfbeSv9fq1u3bu6AAw7IDRs2LLd27dqqHlpBefTRR8v8f1m/fv2y2zds2JC77rrrck2bNs3eeyeddFLuhRdeyFV3mzpvS5cuLfdvRLpfdba591tprVq1yo0dOzZX3VXkvN155525tm3bZv+/69ChQ+7++++v0jHvisTKmyY23jZi4rKJfzdPzFs+cW7FiGsrTixbWLFrjfSfLUvxAgAAAACwPezyPWwBAAAAAHYWErYAAAAAAAVCwhYAAAAAoEBI2AIAAAAAFAgJWwAAAACAAiFhCwAAAABQICRsAQAAAAAKhIQtAAAAAECBkLAFqKA5c+ZE69atd+j5WrZsWdSoUWOz+3366afRtm3bmDdvXhS6d955J/bbb79YuXJlVQ8FAGCXJXatHGJXoCpI2AJso0cffTROO+202HfffaNu3bpx4IEHxjnnnBOPPfZYiYA5JV4/+OCDom25XC7uuOOOOOaYY2LPPfeMvfbaK774xS/GrbfeGmvWrNmiMUyYMCHatGkTXbp02ei2gQMHRs2aNePee++NQrDPPvvEd77znRgxYkRVDwUAoNoRu24ZsStQFSRsAbbBL37xizjppJOiSZMmMW3atHjhhRdi+vTpWeL08ssv3+R9+/btG5dddlmcccYZWeC8aNGiuO666+KBBx6Ihx9+uMJjSInf22+/PQYMGLDRbSnxO3Xq1Lj66qtj4sSJUSjOP//8mDJlSrz33ntVPRQAgGpD7Lp1xK7ADpcDoEIeffTRXKtWrYrWX3311dzuu++eu/zyy8vcf8OGDSXum/6X+/7772fr06ZNy9bvv//+Mu/3wQcfZD8vXbo0229TFixYkNttt91yq1ev3ui2yZMn5770pS9lx6tfv35u+fLlJW7v169f7owzzsjdfPPNuf322y/XqFGj3A033JD77LPPcldeeWVu7733zn3uc5/LTZw4seg++THdc889uWOPPTZXp06dXPv27XNz5swp2ue9997Lffvb387ts88+ubp16+batm1b4hhJmzZtcr/+9a83+dwAANg6YlexK7DzUmELsJV+97vfxWeffZZVr5ZlU71nU3XpwQcfnFXXlnW/Ro0aVXgcjz/+eLRr1y4aNGiw0W133nln9OnTJztejx49YvLkyRvt88gjj8Trr7+etXC45ZZbslYFqcXD3nvvHU899VRcdNFFWVuF0j1nr7rqqvjhD38YCxcujGOPPTZOP/30ePfdd7PbUqXw888/H3/605/i73//e4wfPz67nKy4zp07Z2MHAGD7E7uKXYGdh4QtwFZ68cUXo2HDhtGsWbMSgXDqR5tfFi9eXOZ9X3rppSxhWxleffXVaN68eZmP8eSTT2b9dJOUuJ00aVLWQqG4xo0bx89//vNsPBdccEH2b2qlcO2118ZBBx0UQ4cOjdq1a8cTTzxR4n6XXHJJnH322XHooYdmCdmUFE4J4mT58uXRqVOnrCdvmqjt5JNPzhK6xaUxp7EDALD9iV3FrsDOQ8IWYBuUrqI95ZRTsl60f/jDH+Ljjz+O9evXl3m/0knTbfHvf/87m+ystNSzNo0nX9n6ta99LVatWpVV1BbXvn372G23//1z0LRp0zjiiCOK1tOEZalH79tvv13ifqmqNq9WrVpZcjZV0yaDBg3Keud27Ngxq0CeN2/eRuOrV6/eFk+uBgDA1hO7/jexK1DoJGwBtlKqPk0J0DfffLNoW6qqbdu2bbRq1WqT900tDP7xj39UyrlPCdn333+/xLaUKP7Nb36TJY5TQJqW+vXrZ5N8lZ58bPfdd98okC9r24YNGyo8ptR+IVXPponXUruFNDHblVdeWWKfNJZ99913C54pAABbS+xaPrErUGgkbAG20je+8Y0ssTl69Ogtvu+3v/3t7LK0Bx54oMzq25QIrqjUeiAlf4tX7f7xj3+MDz/8MOsvmyp+88s999wT9913X3zwwQexrVK7hbx169bFM888k7VHyEvJ2H79+sVdd90Vt956a9xxxx0l7r9kyZJs7AAAbH9iV7ErsPOQsAXYSi1btoyf/vSn8bOf/SxLTD766KOxbNmyePbZZ7OesPl2AmX51re+lfWWPe+88+JHP/pRPP3001lF6owZM7J+r+lYFdWtW7f46KOP4m9/+1vRttRLtmfPntGhQ4c4/PDDi5b0uHvttVc26dm2GjduXEyfPj1LFl988cVZlW/qgZsMHz48S0a//PLL2bjS8yqezE2tEFKCt3v37ts8DgAANk/sKnYFdh4StgDbYPDgwfHwww/Hv/71r6xqIV1qlnrFLl26NB566KESvWBLtxi4++6745Zbbon7778/unbtGkceeWRcf/31ccYZZ2S9Zysq9Zc966yzipKwb731VtYKIU0IVlrqVZv2zU8Oti1GjRqVLSkpnCYke/DBB4v65aZJytJkZek5HX/88VniOvW0zUvJ3PSh4Stf+co2jwMAgIoRu4pdgZ1DjVxlznwDsAubM2dO9O/fP6ui3VHSY7Vp02azk5Q999xz8dWvfjVeeeWVrI/ujhhTareQJhXbGl/60pfi0ksvzVpDAABQ+cSu/03sCuyMVNgC7AJSJWvqpZsqewvdO++8E7169craQQAAUP2IXQE2rdZmbgdgJ5Gqf3cGqW3C1VdfXdXDAACgColdAconYQtQQa1bt47LLrtsh56vNEHYiBEjotDOg246AACFTez6v+dB7ArsbPSwBQAAAAAoEHrYAgAAAAAUCAlbAAAAAIACIWELAAAAAFAgJGwBAAAAAAqEhC0AAAAAQIGQsAUAAAAAKBAStgAAAAAABULCFgAAAAAgCsP/B8ruIi1lNBuIAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "gic_abs = gics['GICXFNeutralAmps'].abs().sort_values(ascending=False)\n", + "plot_gic_distribution(gic_abs)" + ] + }, + { + "cell_type": "markdown", + "id": "a41f2a3b", + "metadata": {}, + "source": [ + "## Storm Direction Sensitivity\n", + "\n", + "Sweep the E-field direction to find which orientation produces the worst-case GIC." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a52a3b4c", + "metadata": {}, + "outputs": [], + "source": "directions = np.arange(0, 361, 10)\nmax_gics = []\n\nfor d in directions:\n pw.gic.storm(max_field=1.0, direction=d)\n gic_vals = pw[GICXFormer, 'GICXFNeutralAmps']['GICXFNeutralAmps']\n max_gics.append(gic_vals.abs().max())\n\nmax_gics = np.array(max_gics)" + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "18590645", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Worst-case direction: 130 degrees\n", + "Worst-case max GIC: 19.50 Amps\n" + ] + } + ], + "source": [ + "plot_direction_sensitivity(directions, max_gics)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "esaplus", + "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.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file diff --git a/examples/gic/02_gic_model.ipynb b/examples/gic/02_gic_model.ipynb new file mode 100644 index 00000000..5edd2501 --- /dev/null +++ b/examples/gic/02_gic_model.ipynb @@ -0,0 +1,204 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a1b2c3d4e5f6", + "metadata": {}, + "source": "# GIC Linear Model\n\nExplores the internal structure of the GIC linear model built by\n`pw.gic.model()`. The notebook covers GIC configuration, construction\nof the G-matrix (conductance Laplacian) and H-matrix (linear mapping\nfrom induced voltages to transformer neutral currents), comparison\nwith PowerWorld's own G-matrix, and storm application with result\nvalidation." + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3b21282a", + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": "import numpy as np\nfrom esapp import PowerWorld\nfrom esapp.components import Bus, Branch, Substation, GICXFormer\nfrom examples.map import format_plot" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c3d4e5f6a7b8", + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": "# This cell is hidden in the documentation.\nimport ast\n\nwith open('../data/case.txt', 'r') as f:\n case_path = ast.literal_eval(f.read().strip())\n\npw = PowerWorld(case_path)" + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "01173666", + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": [ + "# Plotting functions (hidden from documentation)\n", + "import sys; sys.path.insert(0, \"..\")\n", + "from plot_helpers import (\n", + " plot_spy_matrices, plot_gmatrix_comparison,\n", + " plot_gic_bar_hist,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "d4e5f6a7b8c9", + "metadata": {}, + "source": [ + "## GIC Configuration\n", + "\n", + "Before building a GIC model, configure the GIC options. The `configure()` method\n", + "sets sensible defaults." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e5f6a7b8c9d0", + "metadata": {}, + "outputs": [], + "source": "pw.gic.configure(pf_include=True, ts_include=False, calc_mode='SnapShot')\n\npw.gic.settings()" + }, + { + "cell_type": "markdown", + "id": "f6a7b8c9d0e1", + "metadata": {}, + "source": [ + "## 2. Building the GIC Model\n", + "\n", + "The `model()` method extracts substation, bus, branch, transformer, and generator\n", + "data from the case and computes all GIC matrices." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a7b8c9d0e1f2", + "metadata": {}, + "outputs": [], + "source": "pw.gic.model()\n\nprint(f\"Incidence matrix (A): {pw.gic.A.shape} (branches x nodes)\")\nprint(f\"G-matrix: {pw.gic.G.shape} (nodes x nodes)\")\nprint(f\"H-matrix: {pw.gic.H.shape} (transformers x branches)\")\nprint(f\"Zeta (per-unit): {pw.gic.zeta.shape}\")\nprint(f\"Effective operator: {pw.gic.eff.shape}\")\nprint(f\"Bus permutation (Px): {pw.gic.Px.shape}\")" + }, + { + "cell_type": "markdown", + "id": "b8c9d0e1f2a3", + "metadata": {}, + "source": [ + "## 3. Matrix Sparsity Patterns\n", + "\n", + "Visualize the sparsity structure of the GIC matrices using spy plots." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "37fb8c5e", + "metadata": {}, + "outputs": [], + "source": "plot_spy_matrices(\n [pw.gic.A, pw.gic.G, pw.gic.H],\n [f'Incidence Matrix A\\n{pw.gic.A.shape}, nnz={pw.gic.A.nnz}',\n f'G-Matrix (Conductance Laplacian)\\n{pw.gic.G.shape}, nnz={pw.gic.G.nnz}',\n f'H-Matrix (GIC Function)\\n{pw.gic.H.shape}, nnz={pw.gic.H.nnz}'])" + }, + { + "cell_type": "markdown", + "id": "f2a3b4c5d6e7", + "metadata": {}, + "source": [ + "## 5. Storm Application and GIC Results\n", + "\n", + "Apply a uniform electric field storm and examine the resulting transformer GICs." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a3b4c5d6e7f8", + "metadata": {}, + "outputs": [], + "source": "# Apply 1 V/km eastward storm\npw.gic.storm(1.0, 90)\n\ngic_results = pw[GICXFormer, ['BusNum3W', 'BusNum3W:1', 'GICXFNeutralAmps']]\ngic_sorted = gic_results.reindex(\n gic_results['GICXFNeutralAmps'].abs().sort_values(ascending=False).index\n)\n\nprint(f\"Total transformers: {len(gic_results)}\")\nprint(f\"Max |GIC|: {gic_results['GICXFNeutralAmps'].abs().max():.3f} A\")\nprint(f\"\\nTop transformers:\")\nprint(gic_sorted.head(10).to_string(index=False))" + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "1b42e9af", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "gic_abs = gic_results['GICXFNeutralAmps'].abs()\n", + "plot_gic_bar_hist(gic_abs)" + ] + }, + { + "cell_type": "markdown", + "id": "c5d6e7f8a9b0", + "metadata": {}, + "source": [ + "## Per-Unit Zeta Model\n", + "\n", + "The zeta matrix converts the linear GIC model to per-unit form, suitable\n", + "for integration into power flow studies. Each row represents a transformer's\n", + "contribution to reactive power losses." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8028ece3", + "metadata": {}, + "outputs": [], + "source": "plot_spy_matrices(\n [pw.gic.zeta, pw.gic.Px],\n [f'Zeta Sparsity Pattern\\n{pw.gic.zeta.shape}',\n f'Bus Permutation Matrix Px\\n{pw.gic.Px.shape}'])" + }, + { + "cell_type": "markdown", + "id": "e7f8a9b0c1d2", + "metadata": {}, + "source": [ + "## Summary\n", + "\n", + "The GIC model expresses transformer neutral currents as a linear function\n", + "of induced line voltages through the H-matrix. The G-matrix is a\n", + "conductance Laplacian ($A^T G_d A + G_s$), and the per-unit zeta matrix\n", + "enables integration with power flow studies. The Px permutation matrix\n", + "maps transformers to their loss-modeling buses." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "esaplus", + "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.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file diff --git a/examples/gic/03_efield_geographic.ipynb b/examples/gic/03_efield_geographic.ipynb new file mode 100644 index 00000000..27e98993 --- /dev/null +++ b/examples/gic/03_efield_geographic.ipynb @@ -0,0 +1,369 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a1b2c3d4e5f6", + "metadata": {}, + "source": [ + "# Electric Field & GIC Geographic Analysis\n", + "\n", + "This notebook demonstrates the complete GIC workflow on a geographic coordinate\n", + "system: building a 2D electric field grid over the case's footprint, computing\n", + "spatially-varying E-fields, overlaying them on the transmission network,\n", + "running GIC calculations, and exporting the field to PowerWorld's B3D format." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "247ecbe5", + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": "import numpy as np\nimport matplotlib.pyplot as plt\nfrom matplotlib.colors import Normalize\n\nfrom esapp import PowerWorld\nfrom esapp.components import Branch, Bus, Substation, GICXFormer\nfrom esapp.utils import (\n Grid2D, B3D,\n format_plot, plot_vecfield, plot_lines,\n border, darker_hsv_colormap,\n)" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c3d4e5f6a7b8", + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": "# This cell is hidden in the documentation.\nimport ast\n\nwith open('../data/case_B.txt', 'r') as f:\n case_path = ast.literal_eval(f.read().strip())\n\npw = PowerWorld(case_path)\n\n# Configure geographic border shape ('US', 'Texas', etc.)\nSHAPE = 'Texas'" + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "6f7d9a1e", + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": [ + "# Plotting functions (hidden from documentation)\n", + "import sys; sys.path.insert(0, \"..\")\n", + "from plot_helpers import (\n", + " plot_geo_grid_buses, plot_efield_comparison, plot_efield_vectors,\n", + " plot_network_efield, plot_barh_top, plot_gic_geo_map,\n", + " plot_direction_sensitivity, plot_b3d_roundtrip,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "d4e5f6a7b8c9", + "metadata": {}, + "source": "Import the case and instantiate the `PowerWorld`.\n\n```python\nfrom esapp import PowerWorld\npw = PowerWorld(case_path)\n```\n\n## Extracting Geographic Extent\n\nWe extract bus coordinates from the case and determine the geographic bounding box\nthat will define our E-field computation grid." + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e5f6a7b8c9d0", + "metadata": {}, + "outputs": [], + "source": "# Get bus coordinates\nlon, lat = pw.buscoords()\n\n# Determine geographic bounding box with padding\npad = 0.5 \nlon_min, lon_max = lon.min() - pad, lon.max() + pad\nlat_min, lat_max = lat.min() - pad, lat.max() + pad" + }, + { + "cell_type": "markdown", + "id": "f6a7b8c9d0e1", + "metadata": {}, + "source": [ + "## 2. Building a Geographic E-Field Grid\n", + "\n", + "We construct a 2D grid in latitude/longitude space covering the case's geographic\n", + "footprint. Each grid point will hold Ex and Ey components of the electric field in V/km." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a7b8c9d0e1f2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Grid: 40 x 30 = 1200 points\n", + "Edges: 2330 (horizontal: 1170, vertical: 1160)\n", + "Resolution: 0.281 deg lon x 0.364 deg lat\n" + ] + } + ], + "source": [ + "# Grid resolution\n", + "nx, ny = 40, 30\n", + "\n", + "# Coordinate arrays\n", + "lons = np.linspace(lon_min, lon_max, nx)\n", + "lats = np.linspace(lat_min, lat_max, ny)\n", + "LON, LAT = np.meshgrid(lons, lats)\n", + "\n", + "# Grid2D for finite difference operators if needed\n", + "grid = Grid2D((nx, ny))" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "2ac51215", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, axes = plt.subplots(1, 2, figsize=(6.5, 2.8))\n", + "plot_geo_grid_buses(LON, LAT, lon, lat, SHAPE,\n", + " xlim=(lon_min, lon_max), ylim=(lat_min, lat_max),\n", + " ax=axes[0], fig=fig)\n", + "# Bus coordinate density\n", + "axes[1].hist2d(lon, lat, bins=20, cmap='Blues')\n", + "format_plot(axes[1], title='Bus Density',\n", + " xlabel=r'Lon ($^\\circ$E)', ylabel=r'Lat ($^\\circ$N)',\n", + " plotarea='white', grid=False, titlesize=11, labelsize=9, ticksize=8)\n", + "axes[1].set_aspect('equal')\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "c9d0e1f2a3b4", + "metadata": {}, + "source": [ + "## 3. Defining Electric Fields\n", + "\n", + "We define several E-field patterns on the geographic grid. A **uniform field**\n", + "with constant magnitude and direction serves as a baseline. A **spatially\n", + "varying field** whose magnitude increases with latitude models conductivity\n", + "variation. A **rotational field** whose direction varies with longitude\n", + "demonstrates non-uniform storm geometry." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "d0e1f2a3b4c5", + "metadata": {}, + "outputs": [], + "source": [ + "E_mag = 1.0 # V/km\n", + "E_dir = 90.0 # degrees from North (90 = East)\n", + "\n", + "Ex_uniform = E_mag * np.sin(np.radians(E_dir)) * np.ones_like(LON)\n", + "Ey_uniform = E_mag * np.cos(np.radians(E_dir)) * np.ones_like(LON)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "f2a3b4c5d6e7", + "metadata": {}, + "outputs": [], + "source": [ + "# Latitude-dependent magnitude: stronger in the north\n", + "E_magnitude = 0.5 + 1.5 * (LAT - lat_min) / (lat_max - lat_min) # 0.5 to 2.0 V/km\n", + "\n", + "Ex_varying = E_magnitude * np.sin(np.radians(E_dir))\n", + "Ey_varying = E_magnitude * np.cos(np.radians(E_dir))\n", + "\n", + "# Rotational field: direction varies with longitude\n", + "lon_center = (lon_min + lon_max) / 2\n", + "angle_field = np.pi / 2 + 0.5 * np.pi * (LON - lon_center) / (lon_max - lon_center)\n", + "\n", + "Ex_rotational = E_mag * np.cos(angle_field)\n", + "Ey_rotational = E_mag * np.sin(angle_field)" + ] + }, + { + "cell_type": "markdown", + "id": "a3b4c5d6e7f8", + "metadata": {}, + "source": [ + "## E-Field Visualization Gallery\n", + "\n", + "We demonstrate multiple visualization styles for the electric fields overlaid on geographic features." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "eb66f969", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fields = [\n", + " ('Uniform', Ex_uniform, Ey_uniform),\n", + " ('Latitude-Varying', Ex_varying, Ey_varying),\n", + " ('Rotational', Ex_rotational, Ey_rotational),\n", + "]\n", + "\n", + "plot_efield_comparison(LON, LAT, fields, SHAPE)" + ] + }, + { + "cell_type": "markdown", + "id": "d6e7f8a9b0c1", + "metadata": {}, + "source": [ + "### E-Field with Transmission Network Overlay\n", + "\n", + "Combine the E-field visualization with the actual transmission network from the PowerWorld case." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6c63c324", + "metadata": {}, + "outputs": [], + "source": "lines = pw[Branch, ['Longitude', 'Longitude:1', 'Latitude', 'Latitude:1']]\nmagnitude = np.sqrt(Ex_varying**2 + Ey_varying**2)\n\nfig, axes = plt.subplots(1, 2, figsize=(6.5, 2.8))\nplot_network_efield(LON, LAT, magnitude, lines, lon, lat,\n Ex_varying, Ey_varying, SHAPE, ax=axes[0], fig=fig)\nplot_efield_vectors(LON, LAT, Ex_varying, Ey_varying, SHAPE,\n ax=axes[1], fig=fig)\nplt.tight_layout()\nplt.show()" + }, + { + "cell_type": "markdown", + "id": "f8a9b0c1d2e3", + "metadata": {}, + "source": "## 5. Computing GIC from the E-Field\n\nWith the GIC model built from `pw.gic.model()`, we compute transformer\nGICs. The storm function applies a uniform E-field and PowerWorld\ncomputes the resulting neutral currents in each transformer." + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b0c1d2e3f4a5", + "metadata": {}, + "outputs": [], + "source": "pw.gic.configure()\npw.gic.model() # Cosntructs GIC Model\n\n# Uniform storm via PowerWorld (baseline)\npw.gic.storm(1.0, 90)\ngic_data = pw[GICXFormer, ['BusNum3W', 'BusNum3W:1', 'GICXFNeutralAmps']]\n\n# Top 10 transformers by GIC magnitude\ntop10 = gic_data.reindex(gic_data['GICXFNeutralAmps'].abs().sort_values(ascending=False).index).head(10)\nprint(top10.to_string(index=False))" + }, + { + "cell_type": "markdown", + "id": "d2e3f4a5b6c7", + "metadata": {}, + "source": [ + "## GIC Results on the Geographic Map\n", + "\n", + "Overlay GIC magnitudes on the transmission network map. Transformer locations are\n", + "plotted with marker size proportional to GIC magnitude." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d25b8b37", + "metadata": {}, + "outputs": [], + "source": "bus_coords = pw[Bus, ['BusNum', 'Longitude', 'Latitude']]\nxf_geo = gic_data.merge(bus_coords, left_on='BusNum3W', right_on='BusNum', how='inner')\ngic_mag = xf_geo['GICXFNeutralAmps'].abs()\n\nfig, axes = plt.subplots(1, 2, figsize=(6.5, 2.8))\nplot_gic_geo_map(lines, xf_geo, gic_mag, SHAPE,\n xlim=(lon_min, lon_max), ylim=(lat_min, lat_max),\n ax=axes[0], fig=fig)\n# Top transformer GICs\ntop = gic_mag.sort_values(ascending=False).head(15)\naxes[1].barh(range(len(top)), top.values, color='#4C72B0')\naxes[1].set_yticks(range(len(top)))\naxes[1].set_yticklabels([f'XF {i+1}' for i in range(len(top))], fontsize=7)\naxes[1].invert_yaxis()\nformat_plot(axes[1], title='Top 15 Transformer GICs',\n xlabel='|GIC| (A)', plotarea='white',\n titlesize=11, labelsize=9, ticksize=8)\nplt.tight_layout()\nplt.show()" + }, + { + "cell_type": "markdown", + "id": "f4a5b6c7d8e9", + "metadata": {}, + "source": [ + "## 7. Storm Direction Sensitivity\n", + "\n", + "Sweep the E-field direction from 0 to 360 degrees and track the maximum GIC\n", + "at each direction. This reveals which storm orientations produce the worst-case\n", + "GIC for this network." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a5b6c7d8e9f0", + "metadata": {}, + "outputs": [], + "source": "directions = np.arange(0, 361, 10)\nmax_gics = []\n\nfor d in directions:\n pw.gic.storm(1.0, d)\n gic_vals = pw[GICXFormer, 'GICXFNeutralAmps']['GICXFNeutralAmps']\n max_gics.append(gic_vals.abs().max())\n\nmax_gics = np.array(max_gics)" + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "5e7fcc21", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Worst-case direction: 10 degrees\n", + "Worst-case max GIC: 184.07 Amps\n" + ] + } + ], + "source": [ + "plot_direction_sensitivity(directions, max_gics,\n", + " title='Maximum Transformer GIC vs. Storm Direction')" + ] + }, + { + "cell_type": "markdown", + "id": "a1b2c3d4e5f7", + "metadata": {}, + "source": [ + "## Summary\n", + "\n", + "This notebook demonstrated the full GIC geographic analysis workflow, from\n", + "extracting the geographic extent to constructing E-field patterns, visualizing\n", + "them with network overlays, computing GIC from spatially-varying fields,\n", + "identifying worst-case storm directions, and exporting custom fields to B3D\n", + "format for PowerWorld import." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "esaplus", + "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.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file diff --git a/examples/gic/04_b3d_file_io.ipynb b/examples/gic/04_b3d_file_io.ipynb new file mode 100644 index 00000000..4047c6bb --- /dev/null +++ b/examples/gic/04_b3d_file_io.ipynb @@ -0,0 +1,184 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a1b2c3d4", + "metadata": {}, + "source": [ + "# B3D File I/O\n", + "\n", + "Demonstrates the `B3D` class for creating, writing, and reading PowerWorld's\n", + "B3D binary format. The notebook covers constructing B3D objects from scratch\n", + "and from mesh-grid data, round-trip file I/O verification, and E-field\n", + "visualization from loaded B3D files." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": "import numpy as np\nimport matplotlib.pyplot as plt\nfrom esapp.utils import B3D\nfrom examples.map import format_plot, border" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": [ + "# Plotting functions (hidden from documentation)\n", + "import sys; sys.path.insert(0, \"..\")\n", + "from plot_helpers import plot_b3d_components, plot_b3d_roundtrip" + ] + }, + { + "cell_type": "markdown", + "id": "c9d0e1f2", + "metadata": {}, + "source": [ + "## 1. Creating a B3D Object from Scratch\n", + "\n", + "The `B3D` class stores time-varying electric field data at geographic locations." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a3b4c5d6", + "metadata": {}, + "outputs": [], + "source": [ + "b3d = B3D()\n", + "\n", + "print(f\"Default B3D object:\")\n", + "print(f\" Comment: {b3d.comment}\")\n", + "print(f\" Grid dimensions: {b3d.grid_dim}\")\n", + "print(f\" Locations: {len(b3d.lat)}\")\n", + "print(f\" Time steps: {len(b3d.time)}\")\n", + "print(f\" Lat: {b3d.lat}\")\n", + "print(f\" Lon: {b3d.lon}\")\n", + "print(f\" Ex shape: {b3d.ex.shape}\")\n", + "print(f\" Ey shape: {b3d.ey.shape}\")" + ] + }, + { + "cell_type": "markdown", + "id": "e7f8a9b0", + "metadata": {}, + "source": [ + "## 2. Building B3D from Mesh-Grid Data\n", + "\n", + "Use `B3D.from_mesh()` to construct a B3D from regularly-spaced geographic arrays.\n", + "This is the most common workflow for custom E-field creation." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c1d2e3f4", + "metadata": {}, + "outputs": [], + "source": [ + "# Define geographic grid covering Texas\n", + "nx, ny = 25, 20\n", + "lons = np.linspace(-106, -93, nx)\n", + "lats = np.linspace(25.5, 36.5, ny)\n", + "LON, LAT = np.meshgrid(lons, lats)\n", + "\n", + "# Create a spatially-varying E-field: gaussian hot spot\n", + "lon_c, lat_c = -99.5, 31.0\n", + "sigma = 2.0\n", + "gaussian = np.exp(-((LON - lon_c)**2 + (LAT - lat_c)**2) / (2 * sigma**2))\n", + "\n", + "Ex = 2.0 * gaussian # V/km eastward\n", + "Ey = 0.5 * gaussian # V/km northward\n", + "\n", + "b3d = B3D.from_mesh(\n", + " long=lons, lat=lats, ex=Ex, ey=Ey,\n", + " comment=\"Gaussian hotspot E-field over Texas\"\n", + ")\n", + "\n", + "print(f\"B3D from mesh:\")\n", + "print(f\" Grid: {b3d.grid_dim}\")\n", + "print(f\" Points: {len(b3d.lat)}\")\n", + "print(f\" Ex range: [{b3d.ex.min():.3f}, {b3d.ex.max():.3f}] V/km\")\n", + "print(f\" Ey range: [{b3d.ey.min():.3f}, {b3d.ey.max():.3f}] V/km\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. Visualizing the E-Field" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plot_b3d_components(LON, LAT, Ex, Ey, 'Texas',\n", + " suptitle='Gaussian Hotspot E-Field')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4. Write and Read Round-Trip\n", + "\n", + "Write the B3D to disk and read it back to verify data integrity." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a7b8c9d0", + "metadata": {}, + "outputs": [], + "source": [ + "b3d.write_b3d_file(\"gaussian_efield.b3d\")\n", + "\n", + "# Read back\n", + "b3d_loaded = B3D(\"gaussian_efield.b3d\")\n", + "\n", + "plot_b3d_roundtrip(LON, LAT, b3d.ex, b3d_loaded.ex, 'Texas', ny, nx)" + ] + }, + { + "cell_type": "markdown", + "id": "c5d6e7f8", + "metadata": {}, + "source": [ + "## Summary\n", + "\n", + "The `B3D` class provides a clean interface for PowerWorld's binary E-field\n", + "format. Fields can be constructed from mesh-grid arrays with `B3D.from_mesh()`,\n", + "written to disk, and read back with full fidelity. The round-trip test\n", + "confirms that all field components and metadata survive serialization." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "esaplus", + "language": "python", + "name": "python3" + }, + "language_info": { + "name": "python", + "version": "3.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file diff --git a/examples/gic/05_gic_sensitivity.ipynb b/examples/gic/05_gic_sensitivity.ipynb new file mode 100644 index 00000000..f879bf0d --- /dev/null +++ b/examples/gic/05_gic_sensitivity.ipynb @@ -0,0 +1,262 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f1a2b3c4", + "metadata": {}, + "source": [ + "# GIC Sensitivity Analysis\n", + "\n", + "Demonstrates the E-field-to-GIC Jacobian ($dI/dE$) for identifying which\n", + "transformers and branches are most sensitive to E-field perturbations. The\n", + "notebook builds the GIC model, computes the Jacobian, ranks transformers\n", + "by overall sensitivity, identifies critical branches by column analysis,\n", + "and profiles directional vulnerability for selected transformers." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "32cc9e7a", + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": "import numpy as np\nimport matplotlib.pyplot as plt\nfrom esapp import PowerWorld\nfrom esapp.components import Bus, GICXFormer\nfrom examples.map import format_plot" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b9c0d1e2", + "metadata": { + "nbsphinx": "hidden", + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": "# This cell is hidden in the documentation.\nimport ast\n\nwith open('../data/case.txt', 'r') as f:\n case_path = ast.literal_eval(f.read().strip())\n\npw = PowerWorld(case_path)" + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "718ac5d2", + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": [ + "# Plotting functions (hidden from documentation)\n", + "import sys; sys.path.insert(0, \"..\")\n", + "from plot_helpers import (\n", + " plot_jacobian_sensitivity, plot_branch_impact,\n", + " plot_direction_profiles,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "f3a4b5c6", + "metadata": {}, + "source": [ + "## 1. Build the GIC Model\n", + "\n", + "The sensitivity analysis requires the H-matrix from `model()`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d7e8f9a0", + "metadata": {}, + "outputs": [], + "source": "pw.gic.configure()\npw.gic.model()\n\n# Apply a baseline storm to get signed currents\npw.gic.storm(1.0, 90)\ngic_baseline = pw[GICXFormer, 'GICXFNeutralAmps']['GICXFNeutralAmps'].to_numpy()" + }, + { + "cell_type": "markdown", + "id": "b1c2d3e4", + "metadata": {}, + "source": [ + "## 2. E-Field to GIC Jacobian (dI/dE)\n", + "\n", + "The `dIdE()` method computes the Jacobian of absolute transformer GICs with respect\n", + "to the electric field components. This identifies which E-field perturbations have\n", + "the greatest effect on each transformer." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f5a6b7c8", + "metadata": {}, + "outputs": [], + "source": "# Compute dI/dE Jacobian using H-matrix and baseline currents\nJ = pw.gic.dIdE(pw.gic.H, i=gic_baseline)\n\nprint(f\"dI/dE Jacobian shape: {J.shape}\")\nprint(f\" Rows: {J.shape[0]} (transformers)\")\nprint(f\" Cols: {J.shape[1]} (branch voltages)\")" + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "6801577a", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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UgQJgiAIgiBaFFIECYIgCIIgWhRSBAmCIAiCIFoUUgQJgiAIgiBaFFIECYIgCIIgWhRSBIm68IMf/AAOOeQQ4/Qnn3wynH322ZGvh9fCaxIEQaQF3PbxqaeegrSw3XbbwR//+Eff/XiPPPLIuvTZROPw7mRNNAX77rsvPProo2yfQux8cO9BVIy+9KUvQRbAbXIIgiCSZsSIEc77tWvXQqFQYP0m8slPfpLtR6viuOOOY1uUXXHFFZltpMWLFzvvf/nLXzJZREV19uzZkfps3O92s802g5UrV/pu40akA7IINjE/+tGP2Mblq1evhh//+Mdw1FFHuTanFuF7KhIEQbQS2EfyFyp+vN/El04JJIhmghTBFgAtglOnTmVPZi+++CI79uCDD7LP1157LbMW7rXXXuz40UcfDRtttBGMGjUKdtttN3jggQdcT4w777wzXHDBBWyj8Q022MDzNIybY+NG6Xj+pEmT2DmcwcFBOPXUU9l18Zq4qboOfNo+44wznKdLlOE3v/kN28gcz8fvReUVNzrH70aPHg1f+9rXoFQqufJ74oknYL/99oN1112XpbvuuuvYcVSSt9hiC/jf//1fJ+0XvvAF+OpXvxq5vgmCaA7+/Oc/wy677ML6lV133RXuu+8+dvzKK6+E3/72t/Czn/2MWRTRxYrceOONsP3228PIkSNZH/f9738fbBu3tw0G+6g999yT9Z3rrbce64c47733HnuQHz9+POufsW/s6+tz9eXYh02cOBHGjh0LZ511lnPusmXL4FOf+hSTAfu/vffeG9asWcO+23TTTeHOO++EJ598krl2n3nmGSYPvl5//XVXSM/pp58Oxx9/vKvMqDQfdNBBnj57jz32YH8nTJjA8sK6wnoUxwPkM5/5DMuDaDCx7p5MpIYpU6bYl19+OXs/ODho33nnnfaIESPsd999lx174IEH7FwuZ5900kl2T08PeyG4yfmqVavYptU//vGP7XXXXddevXo1+27+/Pl2oVCwL7nkEvY95oGfly5dyr6/++67Wfr777+fXROv9cQTT7DvzjvvPLtYLNo33XSTXSqV7F/96lesPDxvmWOPPdY+/fTT2XvcbBtv1SOPPJKlf+utt+wJEyaw8iAvvvii3dbWxq4/MDDANg3HDbzxmsjy5ctZufi1n3nmGXv8+PH2fffdx77/5z//aY8ePdp+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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "J_dense = J if isinstance(J, np.ndarray) else J.toarray()\n", + "plot_jacobian_sensitivity(J_dense)" + ] + }, + { + "cell_type": "markdown", + "id": "b3c4d5e6", + "metadata": {}, + "source": [ + "## 3. Most Sensitive Transformers\n", + "\n", + "Identify which transformers are most sensitive to E-field perturbations." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "f7a8b9c0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Rank XF Index Total Sensitivity \n", + "------------------------------------\n", + "1 8 14.8116 \n", + "2 7 14.8116 \n", + "3 9 14.8116 \n", + "4 1 12.5756 \n", + "5 0 12.5756 \n", + "6 2 12.5756 \n", + "7 6 12.5283 \n", + "8 5 12.5283 \n", + "9 11 11.5955 \n", + "10 10 11.5955 \n" + ] + } + ], + "source": [ + "# Rank transformers by total sensitivity\n", + "sensitivity = np.sum(np.abs(J_dense), axis=1)\n", + "ranked = np.argsort(sensitivity)[::-1]\n", + "\n", + "print(f\"{'Rank':<6} {'XF Index':<10} {'Total Sensitivity':<20}\")\n", + "print(\"-\" * 36)\n", + "for rank, idx in enumerate(ranked[:10]):\n", + " print(f\"{rank + 1:<6} {idx:<10} {sensitivity[idx]:<20.4f}\")" + ] + }, + { + "cell_type": "markdown", + "id": "d1e2f3a4", + "metadata": {}, + "source": [ + "## 4. Column-Wise Analysis: Critical Branches\n", + "\n", + "Which branches (line voltages) have the greatest aggregate impact on GIC?" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "da92e31d", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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yB01apSWB7MF8TeZMWNGvO/HgJlu8e3bEB0dbRszZoz+/fDe0qdPr6+DGc4HDhyIcwajo5UrV9rq1aun7wnlxEzunj17ap0RUdzfIU++4zt37rRVqlRJ25WSJUvaVq1aFW/VXr582da0aVNdkQHPyZIli6127dq2r7/+OsE/ScxZwEFBQdqmYX+//vprgu2ssVJA8+bNbcHBwba8efPaBg0aZJs9e7bT70dcv0dvvvmm7tdRRESEvn7WrFm1rcJqDl9++WWcdQuTJ0/W+x2dO3dOV5rAbGTUC+qndevWth9//FEfx28BVmowHsffBuXhrGDvBeEfRsJkNRjMjLEdOAp0J61BRJSc0MOOjEpC43KJrIpjAImIiIgCDANAIiIiogDDFDARERFRgGEPIBEREVGAYQBIREREFGAYABIREREFmBR3nigsfIlTzwQHB/OE90R+DqtU4SwDWAwWC2CTd9huEgUGmwdtZooLABH8hYSEmF0MIkpGOLsCzohD3mG7SRRY/nKjzUxxASB6/ow3h/MBuuvYsWMSFhYmVmX18gHLyHpMbjjpOw74jO89JW+7GUjtidXKY8UysTzWryNP2swUFwDifLaARsyThgyVYZWGLyWWD1hG1qPZ33tK3nYzkNoTq5XHimVieVJOHbnTZnJQDREREVGAYQBIREREFGAYABIREREFGAaARERERAGGASARERFRgGEASERERBRgUtwyMCnB8bGt7NdDh4abWhYiIkPkhI4SnCGtZXofjot1WK08ViwTy2NOHfkqjmAPIBEREVGAYQBIREREFGAYABIREREFGAaARERERAGGASARERFRgGEASERERBRgGAASERERBRgGgEREREQBhgEgERERUYBhAEhEREQUYBgAEpFfK1KkiJQsWVLKly8vjz/+uHTo0EFu3LiRbK/fpUsXmTJlilvb9u3bV8sbFBQk+/fvd3ps/fr1UrFiRX0fpUuXlgULFvioxEQUCBgAEpHfW7JkiQZUEREREhUVJfPnz3e53YMHD8RMrVu3lu3bt0vhwoWd7rfZbNKxY0ctN97H2rVrpWfPnhIdHW1aWYkoZTMtALxz54706dNHihcvLmXKlNHGjYjIl+7evSs3b96UHDly6G0EVHXq1JFWrVppO7R7926ZNGmSVKlSRXva8P+OHTvsz0fv3IgRI6R69epStGhRGTNm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XnFrZ3Pnzk1seYiIiIjICj2AWFPGuKRKlUq++OILXQMQq81fuHBBFi9erKc3IiIiIiI/6QGcPHmy/Xrr1q1l2bJl0rhxY/t969atY+8fERERkb9NAjF88803ejJyR88995y0b98+KctFRERJrOiAzy1zRhWrnG3GquWxYplYnpRXR0k6CaRIkSKxevvmz58vhQsXTspyEREREZFVegBxgvNmzZrJlClTNOg7efKknDlzRlat4tkHiIiIiPwyAKxZs6ZERkbK2rVr5ezZs3oO4BdeeEFy5MjhVQHmzZuns4xXrFghzZs392ofREREROTDABCyZ88uHTt2lMQ6ceKEzJ49W6pVq5bofRERERFREgaAp06dEk8DxIQGGuPMIt27d5dp06bJW2+95dH+iYiIiMjHAWCtWrXiPQ+wI2zXr18/6du3b7zbTZo0SZ566impVKlSvNvduXNHL4Zr1665U2QiIiIiSkwAiDF/SengwYMSHh4u27ZtS3DbcePGyciRI2Pdf+zYMQkODnb7NW/cuKHTs30xbTrmfhOaWu2qHElVPl9iGVNOPSZ2/1b5W0dHR5tdBCIiv+TVGMDE+uGHH3T8X/HixfU2zirSo0cPOXfunPTq1ctp2yFDhkj//v2degBDQkIkLCzMo/WskmptnuMu7ou5X1fbOPrPpxH262smNkvS8vkSy5hS6jEi0fu3yt+aPf5JK3JCRwnOkFasIJUbbWUgl8eKZbJ6eUKHhptYmpTHlAAQQZ5joFe7dm1NG7uaBYzTzeFCRERERCYtBE1EREREKZspPYAxbd261ewiEBEREQUM9gASERERBZhU3p69o169elK2bFm9/f3338tXX32V1GUjIiIiIisEgGPHjpXJkydLu3bt7AtE58uXTyZMmOCL8hERERGR2QHgZ599JuvXr9ezeGDRZ8ByEViXj4iIiIj8MADEArHo8QMjALx37x6XaiEiIiLy1wCwWrVq8sknnzjdN3fuXD2tGxERERH5YQCI8X84jy/O4Xv9+nWpUaOGfPjhhxwDSESWVKRIESlZsqSUL19eHn/8cenQoYNmMpJLly5dZMqUKW5ti3Ooo7zIruzfv99+/+3bt3Wh/BIlSki5cuWkfv36ljhVHxEFUACIU7D9/vvveoq29957T9588005cOCAFC1a1DclJCJKpCVLlmhAFRERIVFRUTJ/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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Top 5 most influential branches: [18 17 12 13 14]\n" + ] + } + ], + "source": [ + "col_sens = np.sum(np.abs(J_dense), axis=0)\n", + "plot_branch_impact(col_sens)" + ] + }, + { + "cell_type": "markdown", + "id": "f9a0b1c2", + "metadata": {}, + "source": [ + "## 5. Direction Sensitivity Profile\n", + "\n", + "Sweep storm direction and track individual transformer responses to identify\n", + "directional vulnerability." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d3e4f5a6", + "metadata": {}, + "outputs": [], + "source": "directions = np.arange(0, 360, 5)\nn_xf = min(5, len(gic_baseline))\ntop_xf_idx = np.argsort(np.abs(gic_baseline))[::-1][:n_xf]\n\ngic_profiles = np.zeros((len(directions), n_xf))\n\nfor i, d in enumerate(directions):\n pw.gic.storm(1.0, d)\n gic_vals = pw[GICXFormer, 'GICXFNeutralAmps']['GICXFNeutralAmps'].to_numpy()\n gic_profiles[i] = np.abs(gic_vals[top_xf_idx])\n\nplot_direction_profiles(directions, gic_profiles,\n labels=[f'XF {idx}' for idx in top_xf_idx])" + }, + { + "cell_type": "markdown", + "id": "f1b2c3d4", + "metadata": {}, + "source": [ + "## Summary\n", + "\n", + "The $dI/dE$ Jacobian maps small E-field perturbations to transformer GIC\n", + "changes. Row-wise analysis reveals which transformers are most sensitive\n", + "overall, while column-wise analysis identifies the branches that carry the\n", + "most GIC influence. Directional profiles show how individual transformer\n", + "sensitivity varies with storm orientation." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "esaplus", + "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.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file diff --git a/examples/gic/formulations/gic.rst b/examples/gic/formulations/gic.rst new file mode 100644 index 00000000..8e9c8fec --- /dev/null +++ b/examples/gic/formulations/gic.rst @@ -0,0 +1,276 @@ +GIC Analysis Formulation +======================== + +This section describes the mathematical model built by :meth:`~esapp.utils.gic.GIC.model`, +which constructs a sparse linear system relating geoelectric fields to transformer GICs. + +.. contents:: On this page + :local: + :depth: 2 + +Conductance Network +------------------- + +Overview +^^^^^^^^ + +The GIC model represents the power system as a DC resistive network. Unlike AC power flow, +which uses bus admittance, the GIC network is defined by branch conductances and substation +grounding resistances. The network nodes are substations (neutral points) and buses, ordered +as :math:`[n_s \text{ substations}, \; n_b \text{ buses}]`. Branches include transformer +windings, transmission lines, and implicit generator step-up (GSU) connections. + +Let :math:`n_x`, :math:`n_w`, and :math:`n_\ell` denote the number of transformers, windings, +and lines. Each two-winding transformer contributes two winding branches (high and low), so +:math:`n_w = 2 n_x`. Generators that model an implicit GSU contribute :math:`n_g` additional +branches. + +Branch and Grounding Conductances +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The branch conductance diagonal :math:`\tilde{G}` and the grounding conductance diagonal +:math:`\tilde{G}_s` collect all network conductances into two sparse matrices: + +.. math:: + + \tilde{G} := \text{diag}\!\left( + \begin{bmatrix} + \mathbf{g}_w^T & \mathbf{g}_\ell^T & \mathbf{g}_{gsu}^T + \end{bmatrix}\right), + \qquad + \tilde{G}_s := \text{diag}\!\left( + \begin{bmatrix} + \mathbf{g}_s^T & \mathbf{0}^T + \end{bmatrix}\right) + +where :math:`\mathbf{g}_w`, :math:`\mathbf{g}_\ell`, :math:`\mathbf{g}_{gsu}`, and +:math:`\mathbf{g}_s` are the vectors of winding, line, GSU, and substation grounding +conductances. Winding and line conductances are per-phase values scaled by 3 for the +three-phase equivalent; GSU conductances are already three-phase totals. Zero-valued +conductances are replaced by :math:`10^{-6}` S to avoid singularity. + +Incidence Matrix +^^^^^^^^^^^^^^^^ + +The incidence matrix :math:`A` encodes how each branch connects to the network nodes. Its rows +correspond to branches and its columns to nodes :math:`[s_1, \dots, s_{n_s}, b_1, \dots, b_{n_b}]`. +The matrix is formed by stacking four blocks: + +.. math:: + + A := + \begin{bmatrix} + A_{\text{high}} \\ + A_{\text{low}} \\ + A_\ell \\ + A_{gsu} + \end{bmatrix} + +Each winding row encodes a signed connection between two nodes. The specific pattern depends on +the transformer configuration (see :ref:`winding-config`). + +Line branches connect two buses: row :math:`j` of :math:`A_\ell` has :math:`+1` at the from-bus +and :math:`-1` at the to-bus. GSU branches connect a generator bus to its substation neutral. + +G-Matrix +^^^^^^^^ + +The conductance Laplacian (G-matrix) combines the branch conductances and grounding into a +single nodal conductance matrix: + +.. math:: + + G := A^T \tilde{G}\, A + \tilde{G}_s + +Entry :math:`G_{ij}` gives the mutual DC conductance between nodes :math:`i` and :math:`j`. +This matrix is analogous to the :math:`Y_{bus}` used in AC analysis. It is accessible via the +:attr:`~esapp.utils.gic.GIC.G` property. + + +Computing GICs +-------------- + +Given a vector of induced branch voltages :math:`\mathbf{v}_{emf}`, the GIC calculation +proceeds through Norton equivalent injection and nodal voltage solution. + +The Norton branch currents and their nodal aggregation are: + +.. math:: + + \mathbf{i}_{nort}^{\ell} = \tilde{G}\, \mathbf{v}_{emf}, + \qquad + \mathbf{i}_{nort}^{b} = A^T \mathbf{i}_{nort}^{\ell} + +The DC node voltages are obtained by solving the linear system, and the resulting branch +currents follow from Ohm's law: + +.. math:: + + \mathbf{v}_{dc}^{b} = -G^{-1} \mathbf{i}_{nort}^{b}, + \qquad + \mathbf{i}_{dc}^{\ell} = \tilde{G}\, A\, \mathbf{v}_{dc}^{b} + +The per-conductor GICs are the superposition of continuity and Norton currents, divided by +three for the single-phase equivalent: + +.. math:: + + \mathbf{i}_{gic} = \left( \mathbf{i}_{dc}^{\ell} + \mathbf{i}_{nort}^{\ell} \right) / 3 + + +Transformer Impact +------------------ + +Effective GICs +^^^^^^^^^^^^^^ + +A transformer's susceptibility to half-cycle saturation depends on the *effective* GIC flowing +through its core, not the individual winding currents. The effective GIC combines the high- and +low-winding currents, weighted by the turns ratio :math:`N_t`: + +.. math:: + + \mathbf{i}_{eff} = \left( P_H + N_t^{-1}\, P_L \right) \mathbf{i}_{gic} + +where :math:`P_H` and :math:`P_L` are selection matrices that extract the high and low winding +rows from the branch current vector. The combined extraction operator +:math:`(P_H + N_t^{-1} P_L)` is accessible via the :attr:`~esapp.utils.gic.GIC.eff` property. + +H-Matrix +^^^^^^^^ + +Substituting the full GIC derivation into the effective current expression yields a single +linear operator :math:`\mathcal{H}` that maps induced branch voltages directly to effective +transformer GICs: + +.. math:: + + \mathcal{H} := \left( P_H + N_t^{-1}\, P_L \right) + \left( \tilde{G} - \tilde{G}\, A\, G^{-1} A^T \tilde{G} \right) / 3 + +This is the **H-matrix**, accessible via the :attr:`~esapp.utils.gic.GIC.H` property. + +Per-Unit Loss Model (:math:`\zeta`) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To model GIC-driven reactive power losses in power flow studies, the effective GICs must be +expressed in per-unit. Each transformer has a loss coefficient :math:`k_i` +(``GICModelKUsed``) and an MVA base :math:`S_i` (``GICXFMVABase``). The per-unit base +current for transformer :math:`i` is: + +.. math:: + + I_{base,i} = \frac{1000 \, S_i \sqrt{2/3}}{V_{high,i}} + +where :math:`V_{high,i}` is the high-side rated voltage in kV. Folding the loss coefficient +and base conversion into a single diagonal scaling matrix: + +.. math:: + + K := \text{diag}\!\left( + \frac{k \cdot V_{high}}{1000 \, S_{base} \sqrt{2/3}} + \right) + +the per-unit GIC model reduces to: + +.. math:: + + \zeta := K\, \mathcal{H} + +This is the :math:`\zeta` operator accessible via the :attr:`~esapp.utils.gic.GIC.zeta` property. +It maps induced branch voltages to per-unit transformer losses in a single matrix multiply. +The bus-level reactive power injection is then: + +.. math:: + + \mathbf{q}_{loss} = \mathbf{v} \circ P_x \left| \zeta \, \mathbf{v}_{emf} \right| + +where :math:`\mathbf{v}` is the vector of AC bus voltage magnitudes (p.u.), :math:`P_x` assigns +each transformer to its modeled bus, and :math:`\circ` is the element-wise (Hadamard) product. + + +.. _winding-config: + +Implementation Notes +-------------------- + +Code Mapping +^^^^^^^^^^^^ + +.. list-table:: + :header-rows: 1 + :widths: 20 20 60 + + * - Symbol + - Code + - Description + * - :math:`A` + - :attr:`~esapp.utils.gic.GIC.A` + - Branch incidence matrix :math:`\in \mathbb{R}^{(n_w + n_\ell + n_g) \times (n_s + n_b)}` + * - :math:`G` + - :attr:`~esapp.utils.gic.GIC.G` + - Conductance Laplacian (G-matrix) + * - :math:`\tilde{G}` + - ``Gd`` (local) + - Diagonal branch conductance matrix + * - :math:`\tilde{G}_s` + - ``Gs`` (local) + - Diagonal grounding conductance + * - :math:`\mathcal{H}` + - :attr:`~esapp.utils.gic.GIC.H` + - Maps :math:`\mathbf{v}_{emf} \mapsto \mathbf{i}_{eff}` + * - :math:`P_H + N_t^{-1} P_L` + - :attr:`~esapp.utils.gic.GIC.eff` + - Effective GIC extraction operator + * - :math:`K` + - ``K`` (local) + - Per-unit scaling diagonal (absorbs :math:`k` and :math:`I_{base}^{-1}`) + * - :math:`\zeta` + - :attr:`~esapp.utils.gic.GIC.zeta` + - Per-unit model :math:`K\mathcal{H}` + * - :math:`P_x` + - :attr:`~esapp.utils.gic.GIC.Px` + - Transformer-to-bus permutation + +Winding Configuration Rules +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The structure of each winding's incidence row depends on the transformer type and winding +configuration. Let :math:`S_H, S_L` denote substation permutation rows and :math:`B_H, B_L` +denote bus permutation rows for the high and low sides. + +**Standard (non-auto) transformers:** + +- *Gwye high side:* :math:`A_{\text{high}} = -S_H + B_H` — connects bus to substation neutral. +- *Delta/other high side:* :math:`A_{\text{high}} = B_H - B_L` — connects high bus to low bus. +- *Gwye low side:* :math:`A_{\text{low}} = -S_L + B_L` — connects bus to substation neutral. +- *Delta/other low side:* :math:`A_{\text{low}} = 0` — no grounded path. + +**Autotransformers:** + +- *High (series) winding:* :math:`A_{\text{high}} = B_H - B_L` — always bus-to-bus. +- *Low (common) winding:* :math:`A_{\text{low}} = S_L - B_L` — connects substation neutral + to low bus (if Gwye). + +These rules are applied using boolean masks (``HWYE``, ``LWYE``, ``AUTO``, ``BD``) combined +with the ``_mask`` helper function. + +GIC Blocking Devices +^^^^^^^^^^^^^^^^^^^^^ + +A blocking device on a winding sets its conductance to :math:`10^{-6}` S, effectively +removing that GIC path from the network. + +Generator GSU Transformers +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Implicit GSU transformers appear as branches from the generator bus to the substation +neutral. Their ``GICConductance`` is the three-phase total in Siemens. Generators with +``GICGenIncludeImplicitGSU`` set to ``NO`` are excluded. + + +See Also +-------- + +- :class:`~esapp.utils.gic.GIC` -- GIC analysis and model interface +- :meth:`~esapp.utils.gic.GIC.model` -- Build the conductance network model diff --git a/examples/gic/formulations/index.rst b/examples/gic/formulations/index.rst new file mode 100644 index 00000000..d6ba1a0a --- /dev/null +++ b/examples/gic/formulations/index.rst @@ -0,0 +1,9 @@ +Formulations +============ + +Mathematical formulations and derivations for the analysis modules in ESA++. + +.. toctree:: + :maxdepth: 2 + + gic diff --git a/examples/injection.py b/examples/injection.py new file mode 100644 index 00000000..41c9e429 --- /dev/null +++ b/examples/injection.py @@ -0,0 +1,117 @@ +""" +Normalized injection vector for power system sensitivity studies. + +Represents a pattern of power injections across system buses, +normalized so that total supply equals total demand plus losses. +Useful for computing power transfer distribution factors (PTDFs) +and line outage distribution factors (LODFs). +""" + +from __future__ import annotations + +import numpy as np +from numpy.typing import NDArray +from pandas import DataFrame + + +class InjectionVector: + """ + Normalized injection vector for power system sensitivity studies. + + Represents a pattern of power injections across system buses, + normalized so that total supply equals total demand plus losses. + Useful for computing power transfer distribution factors (PTDFs) + and line outage distribution factors (LODFs). + + Parameters + ---------- + loaddf : pandas.DataFrame + DataFrame containing at least a 'BusNum' column for all buses. + losscomp : float, default 0.05 + Loss compensation factor. Supply is scaled up by (1 + losscomp) + to account for system losses. + + Attributes + ---------- + loaddf : pandas.DataFrame + Internal DataFrame with 'Alpha' column for injection values, + indexed by BusNum. + losscomp : float + Loss compensation factor. + + Examples + -------- + >>> inj = InjectionVector(bus_df, losscomp=0.05) + >>> inj.supply(101, 102) # Set buses 101, 102 as supply + >>> inj.demand(201) # Set bus 201 as demand + >>> alpha = inj.vec # Get normalized injection vector + """ + + def __init__(self, loaddf: DataFrame, losscomp: float = 0.05) -> None: + self.loaddf = loaddf.copy() + self.loaddf['Alpha'] = 0.0 + self.loaddf = self.loaddf.set_index('BusNum') + self.losscomp = losscomp + + @property + def vec(self) -> NDArray[np.float64]: + """ + Get the current injection vector as a numpy array. + + Returns + ------- + np.ndarray + Injection values for all buses in bus number order. + """ + return self.loaddf['Alpha'].to_numpy() + + def supply(self, *busids: int) -> None: + """ + Set specified buses as supply points (positive injection). + + The injection vector is automatically normalized after this call. + + Parameters + ---------- + *busids : int + Bus numbers to set as supply points. + """ + self.loaddf.loc[list(busids), 'Alpha'] = 1.0 + self.norm() + + def demand(self, *busids: int) -> None: + """ + Set specified buses as demand points (negative injection). + + The injection vector is automatically normalized after this call. + + Parameters + ---------- + *busids : int + Bus numbers to set as demand points. + """ + self.loaddf.loc[list(busids), 'Alpha'] = -1.0 + self.norm() + + def norm(self) -> None: + """ + Normalize the injection vector. + + Scales supply and demand so that: + - Total supply = (1 + losscomp) * total demand + - Supply buses sum to 1.0 + - Demand buses sum to -1.0 + + This ensures power balance accounting for system losses. + """ + alpha = self.vec + is_supply = alpha > 0 + is_demand = alpha < 0 + + supply_sum = np.sum(alpha[is_supply]) + demand_sum = -np.sum(alpha[is_demand]) + + if supply_sum > 0: + self.loaddf.loc[is_supply, 'Alpha'] /= supply_sum / (1 + self.losscomp) + if demand_sum > 0: + self.loaddf.loc[is_demand, 'Alpha'] /= demand_sum diff --git a/examples/map.py b/examples/map.py new file mode 100644 index 00000000..eb9a20be --- /dev/null +++ b/examples/map.py @@ -0,0 +1,326 @@ +""" +Geographic visualization utilities for power system analysis. + +Provides plotting functions for transmission lines, tesselation grids, +vector fields, and geographic boundaries using matplotlib and geopandas. +""" + +from __future__ import annotations + +from pathlib import Path + +import geopandas as gpd +import numpy as np +from numpy.typing import NDArray + +from matplotlib.axes import Axes +from matplotlib.cm import ScalarMappable +from matplotlib.collections import LineCollection, PatchCollection +from matplotlib.colors import Normalize, ListedColormap, rgb_to_hsv, hsv_to_rgb +import matplotlib.pyplot as plt +from matplotlib.patches import Rectangle +from pandas import DataFrame + +__all__ = [ + 'format_plot', + 'darker_hsv_colormap', + 'border', + 'plot_lines', + 'plot_mesh', + 'plot_tiles', + 'plot_vecfield', +] + +_SHAPES_DIR = Path(__file__).resolve().parent / 'shapes' + + +def format_plot( + ax: Axes, + title: str | None = None, + xlabel: str | None = None, + ylabel: str | None = None, + xlim: tuple[float, float] | None = None, + ylim: tuple[float, float] | None = None, + grid: bool = True, + plotarea: str = 'white', + spine_color: str = 'black', + xticksep: float | None = None, + yticksep: float | None = None, + titlesize: float = 12, + labelsize: float = 10, + ticksize: float = 9, + spine_width: float = 0.8, +) -> None: + """ + Apply journal-standard formatting to a matplotlib axes. + + Parameters + ---------- + ax : matplotlib.axes.Axes + The axes to format. + title : str, optional + Plot title. + xlabel, ylabel : str, optional + Axis labels. + xlim, ylim : tuple of float, optional + Axis limits as (min, max). + grid : bool, default True + Whether to show grid lines. + plotarea : str, default 'white' + Background face color. + spine_color : str, default 'black' + Color for axis spines and ticks. + xticksep, yticksep : float, optional + Tick separation for x and y axes. + titlesize : float, default 12 + Font size for the title. + labelsize : float, default 10 + Font size for axis labels. + ticksize : float, default 9 + Font size for tick labels. + spine_width : float, default 0.8 + Line width for axis spines. + """ + ax.set_facecolor(plotarea) + + if grid: + ax.grid(True, color='#cccccc', linewidth=0.5, linestyle='-') + ax.set_axisbelow(True) + else: + ax.grid(False) + + ax.tick_params( + axis='both', color=spine_color, labelcolor=spine_color, + labelsize=ticksize, + ) + for spine in ax.spines.values(): + spine.set_edgecolor(spine_color) + spine.set_linewidth(spine_width) + + if xlim: + ax.set_xlim(xlim) + if xticksep: + ax.set_xticks(np.arange(*xlim, xticksep)) + if ylim: + ax.set_ylim(ylim) + if yticksep: + ax.set_yticks(np.arange(*ylim, yticksep)) + + if title is not None: + ax.set_title(title, fontsize=titlesize) + if xlabel is not None: + ax.set_xlabel(xlabel, fontsize=labelsize) + if ylabel is not None: + ax.set_ylabel(ylabel, fontsize=labelsize) + + +def darker_hsv_colormap(scale_factor: float = 0.5) -> ListedColormap: + """ + Create a darker version of the HSV colormap. + + Parameters + ---------- + scale_factor : float, default 0.5 + Factor to scale the value (brightness). 1 means no change, + 0 means complete darkness. + + Returns + ------- + matplotlib.colors.ListedColormap + A darker version of the HSV colormap. + """ + hsv_cmap = plt.cm.hsv(np.linspace(0, 1, 256))[:, :3] + hsv_colors = rgb_to_hsv(hsv_cmap) + + hsv_colors[:, 2] *= scale_factor + hsv_colors[:, 2] = np.clip(hsv_colors[:, 2], 0, 1) + + darker_rgb = hsv_to_rgb(hsv_colors) + return ListedColormap(darker_rgb) + + +def border(ax: Axes, shape: str = 'Texas') -> None: + """ + Plot a geographic boundary on a matplotlib axes. + + Parameters + ---------- + ax : matplotlib.axes.Axes + The axes to plot on. + shape : str, default 'Texas' + Name of the shape directory under ``esapp/utils/shapes/``. + """ + shapepath = _SHAPES_DIR / shape / 'Shape.shp' + shapeobj = gpd.read_file(shapepath) + shapeobj.plot(ax=ax, edgecolor='black', facecolor='none') + + +def plot_lines( + ax: Axes, + lines: DataFrame, + ms: float = 50, + lw: float = 1, + color: str = 'k', +) -> None: + """ + Draw transmission lines geographically using a single LineCollection. + + Parameters + ---------- + ax : matplotlib.axes.Axes + The axes to plot on. + lines : pandas.DataFrame + DataFrame with 'Longitude', 'Longitude:1', 'Latitude', 'Latitude:1'. + ms : float, default 50 + Marker size for bus endpoints. + lw : float, default 1 + Line width for transmission lines. + color : str, default 'k' + Color for lines and endpoint markers. + """ + cX = lines[['Longitude', 'Longitude:1']].to_numpy() + cY = lines[['Latitude', 'Latitude:1']].to_numpy() + + segments = np.stack([ + np.column_stack([cX[:, 0], cY[:, 0]]), + np.column_stack([cX[:, 1], cY[:, 1]]), + ], axis=1) + + ax.add_collection( + LineCollection(segments, colors=color, linewidths=lw, zorder=4) + ) + ax.scatter(cX.ravel(), cY.ravel(), c=color, s=ms, zorder=2) + ax.autoscale_view() + + +def plot_mesh( + ax: Axes, + gt, + include_lines: bool = True, + color: str = 'grey', + tcolor: str = 'red', + talpha: float = 0.3, +) -> None: + """ + Plot a GIC tool tesselation grid. + + Parameters + ---------- + ax : matplotlib.axes.Axes + The axes to plot on. + gt : object + GIC tool object with ``tile_info``, ``tile_ids``, and ``lines``. + include_lines : bool, default True + Whether to overlay transmission lines. + color : str, default 'grey' + Grid line color. + tcolor : str, default 'red' + Tile face color. + talpha : float, default 0.3 + Tile transparency. + """ + if include_lines: + plot_lines(ax, gt.lines, ms=2) + + X, Y, W = gt.tile_info + + segs = [[(x, Y.min()), (x, Y.max())] for x in X] + segs += [[(X.min(), y), (X.max(), y)] for y in Y] + ax.add_collection( + LineCollection(segs, colors=color, linewidths=0.5, zorder=1) + ) + + tile_ids = gt.tile_ids + refpnt = np.array([[X.min(), Y.min()]]).T + tiles_unique = np.unique(tile_ids[:, ~np.isnan(tile_ids[0])], axis=1) + tile_pos = tiles_unique * W + refpnt + + patches = [Rectangle((t[0], t[1]), W, W) for t in tile_pos.T] + pc = PatchCollection(patches, facecolor=tcolor, alpha=talpha, + edgecolor='none') + ax.add_collection(pc) + ax.autoscale_view() + + +def plot_tiles( + ax: Axes, + gt, + colors: NDArray | None = None, + alpha: float = 0.3, +) -> None: + """ + Plot colored tiles on a tesselation grid. + + Parameters + ---------- + ax : matplotlib.axes.Axes + The axes to plot on. + gt : object + GIC tool object with ``tile_info``. + colors : np.ndarray, optional + 2D array of tile colors. If None, uses red. + alpha : float, default 0.3 + Tile transparency. + """ + X, Y, W = gt.tile_info + + patches = [] + facecolors = [] + for i in range(len(X) - 1): + for j in range(len(Y) - 1): + patches.append(Rectangle((X[i] * W, Y[j] * W), W, W)) + facecolors.append(colors[j, i] if colors is not None else 'red') + + pc = PatchCollection(patches, alpha=alpha, edgecolor='none') + pc.set_facecolor(facecolors) + ax.add_collection(pc) + ax.autoscale_view() + + +def plot_vecfield( + ax: Axes, + X: NDArray, + Y: NDArray, + U: NDArray, + V: NDArray, + cmap: ListedColormap | None = None, + pivot: str = 'mid', + scale: float = 70, + width: float = 0.001, +) -> ScalarMappable: + """ + Plot a vector field colored by angle. + + Parameters + ---------- + ax : matplotlib.axes.Axes + The axes to plot on. + X, Y : np.ndarray + Coordinates of vector origins. + U, V : np.ndarray + Vector components. + cmap : matplotlib colormap, optional + Colormap for angle encoding. Defaults to a darker HSV. + pivot : str, default 'mid' + Quiver pivot point. + scale : float, default 70 + Quiver arrow scaling. + width : float, default 0.001 + Quiver arrow width. + + Returns + ------- + matplotlib.cm.ScalarMappable + Mappable for creating colorbars. + """ + if cmap is None: + cmap = darker_hsv_colormap(0.8) + + norm = Normalize(vmin=-np.pi, vmax=np.pi) + colors = np.arctan2(U, V) + colors[np.isnan(colors)] = 0 + + ax.quiver(X, Y, U, V, colors, norm=norm, pivot=pivot, scale=scale, + width=width, cmap=cmap) + + return ScalarMappable(norm, cmap) diff --git a/examples/mesh.py b/examples/mesh.py new file mode 100644 index 00000000..f294cc1c --- /dev/null +++ b/examples/mesh.py @@ -0,0 +1,802 @@ +""" +Discrete geometry and linear algebra utilities. + +This module provides tools for: +- Linear algebra: matrix decomposition, eigenvalue analysis, spectral methods +- Unstructured meshes: PLY file I/O, graph operations +- Structured 2D grids: finite difference operators + +Both mesh types support computing incidence matrices, Laplacians, and +other discrete differential operators. +""" + +from __future__ import annotations + +from collections.abc import Iterator +from dataclasses import dataclass + +import numpy as np +from numpy import block, diag, real, imag +from numpy.typing import NDArray +import scipy.sparse as sp +from scipy.sparse import csc_matrix, csr_matrix +from scipy.sparse.linalg import eigsh +from scipy.linalg import schur + +__all__ = [ + # Physical constants + 'MU0', + # Graph Laplacians + 'pathlap', + 'pathincidence', + # Matrix transformations + 'normlap', + 'hermitify', + # Mesh utilities + 'Mesh', + 'extract_unique_edges', + 'Grid2D', +] + + +# ============================================================================= +# Unstructured Mesh Utilities +# ============================================================================= + +def extract_unique_edges(faces: list[list[int]]) -> NDArray[np.int_]: + """ + Extract unique edges from a list of mesh faces. + + Each face is a list of vertex indices forming a polygon. Edges are + extracted by connecting consecutive vertices (including last to first). + Duplicate edges are removed, and each edge is stored with the smaller + vertex index first. + + Parameters + ---------- + faces : list of list of int + Mesh faces, where each face is a list of vertex indices. + + Returns + ------- + np.ndarray + An (M, 2) array of unique edges, sorted lexicographically. + Column 0 contains the smaller vertex index for each edge. + + Examples + -------- + >>> faces = [[0, 1, 2], [1, 2, 3]] + >>> extract_unique_edges(faces) + array([[0, 1], + [0, 2], + [1, 2], + [1, 3], + [2, 3]]) + """ + unique_edges = set() + + for face in faces: + n = len(face) + for i in range(n): + u = face[i] + v = face[(i + 1) % n] + edge = (u, v) if u < v else (v, u) + unique_edges.add(edge) + + return np.array(sorted(unique_edges), dtype=np.int_) + + +@dataclass +class Mesh: + """ + A 3D mesh consisting of vertices and polygonal faces. + + This class represents an unstructured mesh and provides methods for + loading from PLY files and computing graph-theoretic properties like + incidence matrices and Laplacians. + + Attributes + ---------- + vertices : list of tuple + List of (x, y, z) vertex coordinates. + faces : list of list of int + List of faces, where each face is a list of vertex indices. + + Examples + -------- + >>> mesh = Mesh.from_ply("model.ply") + >>> L = mesh.to_laplacian() + >>> xyz = mesh.get_xyz() + """ + vertices: list[tuple[float, float, float]] + faces: list[list[int]] + + @classmethod + def from_ply(cls, filepath: str) -> Mesh: + """ + Load a mesh from a PLY file. + + Supports both ASCII and binary_little_endian PLY formats. + Extracts vertex positions (x, y, z) and face connectivity. + + Parameters + ---------- + filepath : str + Path to the PLY file. + + Returns + ------- + Mesh + The loaded mesh. + + Raises + ------ + ValueError + If the PLY format is not supported. + + Notes + ----- + Supported vertex property types: char, uchar, short, ushort, + int, uint, float, double. + """ + import struct + + with open(filepath, 'rb') as f: + # Parse header + header_ended = False + fmt = "ascii" + vertex_count = 0 + face_count = 0 + vertex_props = [] + current_element = None + + while not header_ended: + line = f.readline().strip() + if not line: + break + line_str = line.decode('ascii', errors='ignore') + + if line_str == "end_header": + header_ended = True + break + + parts = line_str.split() + if not parts: + continue + + if parts[0] == "format": + fmt = parts[1] + elif parts[0] == "element": + current_element = parts[1] + if current_element == "vertex": + vertex_count = int(parts[2]) + elif current_element == "face": + face_count = int(parts[2]) + elif parts[0] == "property": + if current_element == "vertex": + vertex_props.append((parts[2], parts[1])) + + # Parse body + vertices = [] + faces = [] + + if fmt == "ascii": + lines = f.readlines() + for i in range(vertex_count): + parts = lines[i].strip().split() + v = (float(parts[0]), float(parts[1]), float(parts[2])) + vertices.append(v) + + for i in range(face_count): + parts = lines[vertex_count + i].strip().split() + vertex_indices = [int(x) for x in parts[1:]] + faces.append(vertex_indices) + + elif fmt == "binary_little_endian": + np_type_map = { + 'char': 'i1', 'uchar': 'u1', 'short': 'i2', 'ushort': 'u2', + 'int': 'i4', 'uint': 'u4', 'float': 'f4', 'double': 'f8' + } + dtype_fields = [ + (name, np_type_map.get(type_str, 'f4')) + for name, type_str in vertex_props + ] + vertex_dtype = np.dtype(dtype_fields) + + vertex_data = f.read(vertex_count * vertex_dtype.itemsize) + v_arr = np.frombuffer(vertex_data, dtype=vertex_dtype) + + if all(n in v_arr.dtype.names for n in ('x', 'y', 'z')): + vertices = list(zip(v_arr['x'], v_arr['y'], v_arr['z'])) + else: + names = v_arr.dtype.names + vertices = list(zip( + v_arr[names[0]], v_arr[names[1]], v_arr[names[2]] + )) + + for _ in range(face_count): + n = struct.unpack(' csc_matrix: + """ + Construct the oriented incidence matrix for the mesh graph. + + The incidence matrix B has shape (|V|, |E|) where each column + represents an edge with +1 at the source vertex and -1 at the + target vertex. + + Returns + ------- + scipy.sparse.csc_matrix + The incidence matrix B. + + Notes + ----- + The edge orientation is determined by vertex index ordering + (smaller index is source, larger is target). + """ + edges = extract_unique_edges(self.faces) + num_verts = len(self.vertices) + num_edges = len(edges) + + row = edges.ravel() + col = np.repeat(np.arange(num_edges), 2) + data = np.tile([1.0, -1.0], num_edges) + + return csc_matrix((data, (row, col)), shape=(num_verts, num_edges)) + + def get_xyz(self) -> NDArray[np.float64]: + """ + Get vertex coordinates as a numpy array. + + Returns + ------- + np.ndarray + An (N, 3) array of vertex coordinates. + """ + return np.array(self.vertices, dtype=np.float64) + + def to_laplacian(self) -> csc_matrix: + """ + Compute the graph Laplacian matrix. + + The Laplacian is computed as L = B @ B.T where B is the + incidence matrix. This produces the combinatorial Laplacian + with diagonal entries equal to vertex degrees. + + Returns + ------- + scipy.sparse.csc_matrix + The graph Laplacian matrix L. + """ + B = self.get_incidence_matrix() + return B @ B.T + + +# ============================================================================= +# Structured Grid Utilities +# ============================================================================= + +class Grid2D: + """ + Graph-based discrete operator generator for regular 2D grids. + + Constructs an oriented incidence matrix for the 2D grid graph and + derives all discrete operators (gradient, divergence, curl, Laplacian) + from it. The Laplacian is computed as L = A^T diag(w) A where A is + the incidence matrix and w are edge weights. + + Also provides boolean masks for boundary and interior region selection, + useful for applying boundary conditions in finite difference schemes. + + Parameters + ---------- + shape : tuple of int + Grid dimensions (nx, ny). + + Attributes + ---------- + nx : int + Number of grid points in x direction. + ny : int + Number of grid points in y direction. + size : int + Total number of grid points (nx * ny). + n_edges_x : int + Number of horizontal edges: (nx - 1) * ny. + n_edges_y : int + Number of vertical edges: nx * (ny - 1). + n_edges : int + Total number of edges. + + Examples + -------- + >>> grid = Grid2D((10, 10)) + >>> A = grid.incidence() # Oriented incidence matrix + >>> L = grid.laplacian() # L = A^T A (unit weights) + >>> Dx, Dy = grid.gradient() # Extracted from A + >>> u[grid.boundary] = 0 # Apply Dirichlet BC + + Notes + ----- + Grid points are indexed in Fortran order (column-major), so point + (x, y) maps to flat index y * nx + x. This matches numpy's 'F' order. + + Edges are ordered with all horizontal edges first, then vertical edges. + Each edge is oriented from the lower-index node to the higher-index node + (left-to-right for horizontal, bottom-to-top for vertical). + """ + + def __init__(self, shape: tuple[int, int]) -> None: + self.nx, self.ny = shape + self.size = self.nx * self.ny + self.n_edges_x = (self.nx - 1) * self.ny + self.n_edges_y = self.nx * (self.ny - 1) + self.n_edges = self.n_edges_x + self.n_edges_y + + # Build and cache the incidence matrix and region masks + self._A = self._build_incidence() + self._build_masks() + + @property + def shape(self) -> tuple[int, int]: + """Grid dimensions (nx, ny).""" + return (self.nx, self.ny) + + # ----------------------------------------------------------------- + # Region masks (formerly GridSelector) + # ----------------------------------------------------------------- + + def _build_masks(self) -> None: + """Compute boolean masks for boundary and interior regions.""" + idx = np.arange(self.size) + x = idx % self.nx + y = idx // self.nx + + self._left = (x == 0) + self._right = (x == self.nx - 1) + self._bottom = (y == 0) + self._top = (y == self.ny - 1) + self._corners = (self._left | self._right) & (self._bottom | self._top) + self._boundary = self._left | self._right | self._bottom | self._top + self._interior = ~self._boundary + + @property + def left(self) -> NDArray[np.bool_]: + """Boolean mask for left boundary (x = 0).""" + return self._left + + @property + def right(self) -> NDArray[np.bool_]: + """Boolean mask for right boundary (x = nx-1).""" + return self._right + + @property + def bottom(self) -> NDArray[np.bool_]: + """Boolean mask for bottom boundary (y = 0).""" + return self._bottom + + @property + def top(self) -> NDArray[np.bool_]: + """Boolean mask for top boundary (y = ny-1).""" + return self._top + + @property + def corners(self) -> NDArray[np.bool_]: + """Boolean mask for corner points.""" + return self._corners + + @property + def boundary(self) -> NDArray[np.bool_]: + """Boolean mask for all boundary points.""" + return self._boundary + + @property + def interior(self) -> NDArray[np.bool_]: + """Boolean mask for interior (non-boundary) points.""" + return self._interior + + # ----------------------------------------------------------------- + # Indexing + # ----------------------------------------------------------------- + + def flat_index(self, x: int, y: int) -> int: + """ + Convert 2D coordinates to flat index. + + Parameters + ---------- + x : int + X coordinate (0 to nx-1). + y : int + Y coordinate (0 to ny-1). + + Returns + ------- + int + Flat index in column-major order. + """ + return y * self.nx + x + + def grid_coords(self, idx: int) -> tuple[int, int]: + """ + Convert flat index to 2D coordinates. + + Parameters + ---------- + idx : int + Flat index. + + Returns + ------- + tuple of int + (x, y) coordinates. + """ + return idx % self.nx, idx // self.nx + + def iter_points(self) -> Iterator[tuple[int, int, int]]: + """ + Iterate over all grid points. + + Yields + ------ + tuple of int + (x, y, flat_index) for each grid point in column-major order. + """ + for y in range(self.ny): + for x in range(self.nx): + yield x, y, self.flat_index(x, y) + + # ----------------------------------------------------------------- + # Incidence matrix (core data structure) + # ----------------------------------------------------------------- + + def _build_incidence(self) -> csr_matrix: + """ + Build the oriented incidence matrix of the 2D grid graph. + + The matrix A has shape (n_edges, n_nodes). Each row has exactly + two nonzeros: -1 at the source node and +1 at the target node. + Horizontal edges are listed first, then vertical edges. + + Returns + ------- + scipy.sparse.csr_matrix + Incidence matrix A of shape (n_edges, n_nodes). + """ + n = self.size + nx, ny = self.nx, self.ny + + # --- Horizontal edges: (x, y) → (x+1, y) --- + # For each row y, there are (nx-1) horizontal edges + ex = self.n_edges_x + if ex > 0: + # Source nodes for horizontal edges + all_nodes = np.arange(n).reshape(ny, nx) + src_x = all_nodes[:, :-1].ravel() # left endpoints + tgt_x = all_nodes[:, 1:].ravel() # right endpoints + edge_idx_x = np.arange(ex) + else: + src_x = np.array([], dtype=int) + tgt_x = np.array([], dtype=int) + edge_idx_x = np.array([], dtype=int) + + # --- Vertical edges: (x, y) → (x, y+1) --- + ey = self.n_edges_y + if ey > 0: + all_nodes = np.arange(n).reshape(ny, nx) + src_y = all_nodes[:-1, :].ravel() # bottom endpoints + tgt_y = all_nodes[1:, :].ravel() # top endpoints + edge_idx_y = np.arange(ex, ex + ey) + else: + src_y = np.array([], dtype=int) + tgt_y = np.array([], dtype=int) + edge_idx_y = np.array([], dtype=int) + + # Assemble COO data + rows = np.concatenate([edge_idx_x, edge_idx_x, edge_idx_y, edge_idx_y]) + cols = np.concatenate([src_x, tgt_x, src_y, tgt_y]) + data = np.concatenate([ + -np.ones(ex), np.ones(ex), + -np.ones(ey), np.ones(ey), + ]) + + return csr_matrix((data, (rows, cols)), shape=(self.n_edges, n)) + + def incidence(self) -> csr_matrix: + """ + Return the oriented incidence matrix of the 2D grid graph. + + The matrix A has shape (n_edges, n_nodes). Rows 0..n_edges_x-1 + correspond to horizontal edges, and rows n_edges_x..n_edges-1 + correspond to vertical edges. Each row has -1 at the source + node and +1 at the target node. + + Returns + ------- + scipy.sparse.csr_matrix + Incidence matrix A. + """ + return self._A + + # ----------------------------------------------------------------- + # Discrete operators derived from the incidence matrix + # ----------------------------------------------------------------- + + def gradient(self) -> tuple[csr_matrix, csr_matrix]: + """ + Build gradient operators for a scalar field. + + The gradient operators Dx, Dy are extracted directly from the + incidence matrix A: Dx consists of the horizontal-edge rows, + and Dy consists of the vertical-edge rows. + + Returns + ------- + Dx : scipy.sparse.csr_matrix + X-direction gradient, shape (n_edges_x, n_nodes). + Dy : scipy.sparse.csr_matrix + Y-direction gradient, shape (n_edges_y, n_nodes). + + Notes + ----- + For a scalar field u (length n_nodes), the gradient components + are Dx @ u and Dy @ u. + """ + Dx = self._A[:self.n_edges_x, :] + Dy = self._A[self.n_edges_x:, :] + return Dx, Dy + + def divergence(self) -> csr_matrix: + """ + Build divergence operator for a vector field. + + The divergence is the negative adjoint of the gradient: + div = -A^T, applied to an edge-based vector field. + + Returns + ------- + scipy.sparse.csr_matrix + Divergence operator of shape (n_nodes, n_edges). + + Notes + ----- + For an edge-based vector field f (length n_edges), + the divergence is -A^T @ f. + """ + return -self._A.T.tocsr() + + def curl(self) -> csr_matrix: + """ + Build 2D curl operator for a vector field. + + Returns + ------- + scipy.sparse.csr_matrix + Curl operator of shape (n_faces, n_edges), where n_faces + is the number of grid cells (nx-1) * (ny-1). + + Notes + ----- + The discrete curl maps an edge field to a face field. For each + rectangular cell, the curl sums the edge values around the cell + boundary (with orientation signs). + + For a grid cell with corners (x,y), (x+1,y), (x+1,y+1), (x,y+1): + curl = bottom + right - top - left + """ + nx, ny = self.nx, self.ny + n_faces = (nx - 1) * (ny - 1) + if n_faces == 0: + return csr_matrix((0, self.n_edges)) + + # Edge indices within the incidence matrix + # Horizontal edges: row y, column x → index y*(nx-1) + x + # Vertical edges: row y, column x → n_edges_x + y*nx + x + face_idx = np.arange(n_faces) + fx = face_idx % (nx - 1) + fy = face_idx // (nx - 1) + + bottom = fy * (nx - 1) + fx # horizontal, row y + top = (fy + 1) * (nx - 1) + fx # horizontal, row y+1 + left = self.n_edges_x + fy * nx + fx # vertical, col x + right = self.n_edges_x + fy * nx + (fx + 1) # vertical, col x+1 + + rows = np.tile(face_idx, 4) + cols = np.concatenate([bottom, right, top, left]) + data = np.concatenate([ + np.ones(n_faces), # bottom: +1 + np.ones(n_faces), # right: +1 + -np.ones(n_faces), # top: -1 + -np.ones(n_faces), # left: -1 + ]) + + return csr_matrix((data, (rows, cols)), shape=(n_faces, self.n_edges)) + + def laplacian(self, weights: NDArray[np.floating] | None = None) -> csr_matrix: + """ + Build the discrete Laplacian operator. + + Computed as L = A^T diag(w) A where A is the incidence matrix + and w are per-edge weights. + + Parameters + ---------- + weights : np.ndarray, optional + Per-edge weight vector of length n_edges. If None, unit + weights are used (standard combinatorial Laplacian). + + Returns + ------- + scipy.sparse.csr_matrix + Laplacian operator of shape (n_nodes, n_nodes). + + Notes + ----- + With unit weights, this produces the standard 5-point stencil + for interior nodes: L[i,i] = degree(i), L[i,j] = -1 for + adjacent nodes j. + """ + A = self._A + if weights is None: + return (A.T @ A).tocsr() + else: + W = sp.diags(weights) + return (A.T @ W @ A).tocsr() + + def hodge_star(self) -> csr_matrix: + """ + Build the 2D Hodge star operator on node-based vector fields. + + The Hodge star rotates vectors by 90 degrees, equivalent to + multiplication by the imaginary unit in the complex plane. + + Returns + ------- + scipy.sparse.csr_matrix + Hodge star operator of shape (2n, 2n). + + Notes + ----- + For a node-based vector field [u; v] of length 2n, + returns [-v; u]. + """ + n = self.size + I = sp.eye(n, format='csr') + Z = csr_matrix((n, n)) + return sp.bmat([[Z, -I], [I, Z]], format='csr') + + +# ============================================================================= +# Physical Constants +# ============================================================================= + +MU0: float = 1.256637e-6 +"""Permeability of free space (H/m).""" + +def pathlap(N: int, periodic: bool = False) -> NDArray: + """ + Create the graph Laplacian for a path or cycle graph. + + Parameters + ---------- + N : int + Number of nodes. + periodic : bool, default False + If True, creates a cycle graph (first and last nodes connected). + If False, creates a path graph. + + Returns + ------- + np.ndarray + The Laplacian matrix of shape (N, N). + + Notes + ----- + - For a path graph: L[i,i] = 2 for interior nodes, 1 for endpoints. + - For a cycle graph: L[i,i] = 2 for all nodes. + - Off-diagonal entries are -1 for adjacent nodes. + """ + O = np.ones(N) + L = sp.diags( + [2 * O, -O[:1], -O[:1]], + offsets=[0, 1, -1], + shape=(N, N) + ).toarray() + + if periodic: + L[0, -1] = -1 + L[-1, 0] = -1 + else: + L[0, 0] = 1 + L[-1, -1] = 1 + + return L + + +def pathincidence(N: int, periodic: bool = False) -> NDArray: + """ + Create the incidence matrix for a path or cycle graph. + + Parameters + ---------- + N : int + Number of nodes. + periodic : bool, default False + If True, creates a cycle graph incidence matrix. + If False, creates a path graph incidence matrix. + + Returns + ------- + np.ndarray + The incidence matrix. + + Notes + ----- + For a path graph: shape is (N, N-1) with N-1 edges. + For a cycle graph: shape is (N, N) with N edges. + Each column has +1 at source node and -1 at target node. + """ + O = np.ones(N) + B = sp.diags( + [O, -O[:1]], + offsets=[0, 1], + shape=(N, N) + ).toarray() + + if periodic: + B[-1, 0] = -1 + + return B + + +def normlap( + L: NDArray | sp.spmatrix, + return_scaling: bool = False +) -> NDArray | tuple[NDArray, sp.dia_matrix, sp.dia_matrix]: + """ + Compute the normalized Laplacian of a matrix. + + The normalized Laplacian is defined as: + L_norm = D^{-1/2} @ L @ D^{-1/2} + + where D is the diagonal matrix of L's diagonal entries. + + Parameters + ---------- + L : np.ndarray or scipy.sparse matrix + Input Laplacian matrix. + return_scaling : bool, default False + If True, also return the scaling matrices. + + Returns + ------- + L_norm : np.ndarray + The normalized Laplacian. + D : scipy.sparse.dia_matrix, optional + Diagonal scaling matrix (sqrt of original diagonal). + Only returned if return_scaling=True. + D_inv : scipy.sparse.dia_matrix, optional + Inverse diagonal scaling matrix. + Only returned if return_scaling=True. + + Notes + ----- + The normalized Laplacian has eigenvalues in [0, 2] for + undirected graphs and is useful for spectral clustering. + """ + Yd = np.sqrt(L.diagonal()) + Di = sp.diags(1 / Yd) + + if return_scaling: + D = sp.diags(Yd) + return Di @ L @ Di, D, Di + else: + return Di @ L @ Di + diff --git a/examples/network/01_matrix_extraction.ipynb b/examples/network/01_matrix_extraction.ipynb new file mode 100644 index 00000000..0fabb974 --- /dev/null +++ b/examples/network/01_matrix_extraction.ipynb @@ -0,0 +1,104 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a1b2c3d4", + "metadata": {}, + "source": [ + "# Matrix Extraction\n", + "\n", + "Extracting system matrices (Y-Bus, Incidence, Jacobian) for external mathematical analysis." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b2c3d4e5", + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": "# This cell is hidden in the documentation.\nfrom esapp import PowerWorld\nfrom esapp.components import *\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport ast\n\nwith open('../data/case.txt', 'r') as f:\n case_path = ast.literal_eval(f.read().strip())\n\npw = PowerWorld(case_path)" + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": [ + "# Plotting functions (hidden from documentation)\n", + "import sys; sys.path.insert(0, \"..\")\n", + "from plot_helpers import plot_ybus_analysis, plot_incidence_and_laplacian" + ] + }, + { + "cell_type": "markdown", + "id": "c3d4e5f6", + "metadata": {}, + "source": "Import the case and instantiate the `PowerWorld`.\n\n```python\nfrom esapp import PowerWorld\nfrom esapp.components import *\n\npw = PowerWorld(case_path)\n```" + }, + { + "cell_type": "markdown", + "id": "d4e5f6a7", + "metadata": {}, + "source": [ + "## Admittance Matrix (Y-Bus)\n", + "\n", + "Extract the sparse Y-Bus admittance matrix for the power system. This matrix is commonly used in power flow calculations and network analysis:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e5f6a7b8", + "metadata": {}, + "outputs": [], + "source": "Y = pw.ybus()\nprint(f\"Y-Bus shape: {Y.shape} (n_bus x n_bus)\")\nprint(f\"Non-zeros: {Y.nnz}\")\nprint(f\"Density: {Y.nnz / (Y.shape[0] * Y.shape[1]):.2%}\")" + }, + { + "cell_type": "markdown", + "id": "b8c9d0e1", + "metadata": {}, + "source": [ + "## Network Topology\n", + "\n", + "The `Network` app provides graph-based representations of the system topology. Extract the incidence matrix (branches x buses):" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c9d0e1f2", + "metadata": {}, + "outputs": [], + "source": "A = pw.network.incidence()\n\nplot_incidence_and_laplacian(A)" + } + ], + "metadata": { + "kernelspec": { + "display_name": "esaplus", + "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.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file diff --git a/examples/network/02_network_topology.ipynb b/examples/network/02_network_topology.ipynb new file mode 100644 index 00000000..925f2722 --- /dev/null +++ b/examples/network/02_network_topology.ipynb @@ -0,0 +1,187 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a1b2c3d4", + "metadata": {}, + "source": [ + "# Network Topology Analysis\n\nDemonstrates graph-theoretic analysis of power system networks using the\n`Network` application module. The notebook covers bus-to-index mapping,\nweighted Laplacian construction (by length, impedance, and propagation\ndelay), branch parameter distributions, spectral decomposition, and Fiedler\nvector visualization for identifying natural network partitions." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": "import numpy as np\nfrom scipy.sparse.linalg import eigsh\nfrom esapp import PowerWorld\nfrom esapp.components import Branch, Bus\nfrom esapp.utils import BranchType, sorteig\nfrom examples.map import format_plot" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c3d4e5f6", + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": "# This cell is hidden in the documentation.\nimport ast\n\nwith open('../data/case.txt', 'r') as f:\n case_path = ast.literal_eval(f.read().strip())\n\npw = PowerWorld(case_path)" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": [ + "# Plotting functions (hidden from documentation)\n", + "import sys; sys.path.insert(0, \"..\")\n", + "from plot_helpers import (\n", + " plot_incidence_and_degree, plot_spy_matrices,\n", + " plot_histograms, plot_eigenspectrum, plot_fiedler,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "d4e5f6a7", + "metadata": {}, + "source": [ + "## 1. Bus Mapping and Incidence Matrix\n\nThe `busmap()` provides the mapping from PowerWorld bus numbers to matrix indices.\nThe incidence matrix has one row per branch with +1/-1 entries." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e5f6a7b8", + "metadata": {}, + "outputs": [], + "source": "bmap = pw.network.busmap()\nprint(f\"Bus count: {len(bmap)}\")\nprint(f\"First 5 mappings:\")\nprint(bmap.head())\n\nA = pw.network.incidence()\nprint(f\"\\nIncidence matrix: {A.shape} (branches x buses)\")\nprint(f\"Non-zeros: {A.nnz}\")" + }, + { + "cell_type": "markdown", + "id": "a7b8c9d0", + "metadata": {}, + "source": [ + "## 2. Weighted Laplacians\n", + "\n", + "The graph Laplacian L = A.T @ W @ A captures network connectivity with different\n", + "weighting schemes: inverse squared length, inverse impedance, or inverse squared delay." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": "L_len = pw.network.laplacian(BranchType.LENGTH)\nL_res = pw.network.laplacian(BranchType.RES_DIST)\n\nprint(f'Length-weighted Laplacian: {L_len.shape}, nnz={L_len.nnz}')\nprint(f'Impedance-weighted Laplacian: {L_res.shape}, nnz={L_res.nnz}')\n\nplot_spy_matrices([L_len, L_res],\n ['Length-Weighted Laplacian', 'Impedance-Weighted Laplacian'])" + }, + { + "cell_type": "markdown", + "id": "c9d0e1f2", + "metadata": {}, + "source": [ + "## 3. Branch Parameters\n", + "\n", + "Examine the distributions of branch lengths, impedance magnitudes, and\n", + "propagation delays." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": "lengths = pw.network.lengths()\nzmag = pw.network.zmag()\n\nplot_histograms([lengths, zmag],\n ['Branch Length Distribution', 'Impedance Magnitude Distribution'],\n ['Length (km)', '|Z| (pu)'])\n\nprint(f'Length range: [{lengths.min():.3f}, {lengths.max():.3f}] km')\nprint(f'|Z| range: [{zmag.min():.6f}, {zmag.max():.6f}] pu')" + }, + { + "cell_type": "markdown", + "id": "e1f2a3b4", + "metadata": {}, + "source": [ + "## 4. Spectral Analysis\n", + "\n", + "The eigenvalues of the Laplacian encode the network's structural properties.\n", + "The algebraic connectivity (second-smallest eigenvalue) measures how well-connected\n", + "the network is." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "k = min(10, L_len.shape[0] - 1)\n", + "vals_len, vecs_len = eigsh(L_len.astype(float), k=k, which='SM')\n", + "vals_len, vecs_len = sorteig(vals_len, vecs_len)\n", + "\n", + "vals_res, vecs_res = eigsh(L_res.astype(float), k=k, which='SM')\n", + "vals_res, vecs_res = sorteig(vals_res, vecs_res)\n", + "\n", + "plot_eigenspectrum([vals_len, vals_res],\n", + " ['Length-Weighted Eigenvalues', 'Impedance-Weighted Eigenvalues'])\n", + "\n", + "print(f'Algebraic connectivity (length): {vals_len[1]:.6f}')\n", + "print(f'Algebraic connectivity (impedance): {vals_res[1]:.6f}')" + ] + }, + { + "cell_type": "markdown", + "id": "a3b4c5d6", + "metadata": {}, + "source": [ + "## 5. Fiedler Vector Visualization\n", + "\n", + "The Fiedler vector (eigenvector of the second-smallest eigenvalue) reveals the\n", + "natural partition of the network into two clusters." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "fiedler = vecs_len[:, 1]\n", + "plot_fiedler(fiedler)" + ] + }, + { + "cell_type": "markdown", + "id": "c5d6e7f8", + "metadata": {}, + "source": [ + "## Summary\n\nThe network module provides graph-theoretic tools for power system topology.\nWeighted Laplacians encode connectivity under different physical metrics,\nand their spectral decomposition reveals structural properties such as\nalgebraic connectivity and natural clustering via the Fiedler vector." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "esaplus", + "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.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file diff --git a/examples/network/03_network_expansion.ipynb b/examples/network/03_network_expansion.ipynb new file mode 100644 index 00000000..14e62326 --- /dev/null +++ b/examples/network/03_network_expansion.ipynb @@ -0,0 +1,155 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a1f2e3d4", + "metadata": {}, + "source": [ + "# Network Expansion and Topology Modification\n", + "\n", + "Demonstrates how to programmatically modify system topology by tapping existing lines and splitting buses. This is essential for planning studies where new substations or interconnections are evaluated." + ] + }, + { + "cell_type": "markdown", + "id": "b2a3f4e5", + "metadata": {}, + "source": "Import the case and instantiate the `PowerWorld`.\n\n```python\nfrom esapp import PowerWorld\nfrom esapp.components import *\nfrom esapp.saw._helpers import create_object_string\n\npw = PowerWorld(case_path)\n```" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c3b4a5f6", + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": "# This cell is hidden in the documentation.\nfrom esapp import PowerWorld\nfrom esapp.components import *\nfrom esapp.saw._helpers import create_object_string\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport ast\n\nwith open('../data/case.txt', 'r') as f:\n case_path = ast.literal_eval(f.read().strip())\n\npw = PowerWorld(case_path)" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": [ + "# Plotting functions (hidden from documentation)\n", + "import sys; sys.path.insert(0, \"..\")\n", + "from plot_helpers import plot_spy_matrices" + ] + }, + { + "cell_type": "markdown", + "id": "d4c5b6a7", + "metadata": {}, + "source": [ + "## Y-Bus Before Modification\n", + "\n", + "Capture the Y-Bus sparsity pattern before making network changes:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e5d6c7b8", + "metadata": {}, + "outputs": [], + "source": "Y_before = pw.ybus()\nprint(f\"Y-Bus before: {Y_before.shape}, nnz={Y_before.nnz}\")" + }, + { + "cell_type": "markdown", + "id": "f6e7d8c9", + "metadata": {}, + "source": [ + "## Tap Existing Transmission Lines\n", + "\n", + "Select a branch to tap and insert a new bus at the midpoint:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a7f8e9d0", + "metadata": {}, + "outputs": [], + "source": "branches = pw[Branch]\nb = branches.iloc[10]\ntobus = b['BusNum']\nfrombus = b['BusNum:1']\ncircuit = b['LineCircuit']\nbranch_str = create_object_string(\"Branch\", tobus, frombus, circuit)" + }, + { + "cell_type": "markdown", + "id": "b8a9f0e1", + "metadata": {}, + "source": [ + "Tap the transmission line at 50% of its length and create a new bus at the tap point:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c9b0a1f2", + "metadata": {}, + "outputs": [], + "source": "new_bus_num = int(pw[Bus, \"BusNum\"][\"BusNum\"].max()) + 100\n\npw.esa.TapTransmissionLine(\n branch_str,\n 50.0,\n new_bus_num,\n 'CAPACITANCE',\n False, False,\n 'Tapped_Substation'\n)" + }, + { + "cell_type": "markdown", + "id": "d0c1b2a3", + "metadata": {}, + "source": [ + "## Split a Bus\n", + "\n", + "Split an existing bus into two buses connected by a tie-line:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e1d2c3b4", + "metadata": {}, + "outputs": [], + "source": "target_bus = 1\nsplit_bus_num = int(pw[Bus, 'BusNum']['BusNum'].max()) + 1\n\npw.esa.SplitBus(\n create_object_string(\"Bus\", target_bus),\n split_bus_num,\n insert_tie=True,\n line_open=False,\n branch_device_type=\"Breaker\"\n)" + }, + { + "cell_type": "markdown", + "id": "f2e3d4c5", + "metadata": {}, + "source": [ + "## Validate Network Changes\n", + "\n", + "Compare the Y-Bus before and after the topology modifications:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": "V = pw.pflow()\nY_after = pw.ybus()\n\nprint(f'Y-Bus before: {Y_before.shape}, nnz={Y_before.nnz}')\nprint(f'Y-Bus after: {Y_after.shape}, nnz={Y_after.nnz}')\nprint(f'New buses added: {Y_after.shape[0] - Y_before.shape[0]}')\n\nplot_spy_matrices([Y_before, Y_after],\n [f'Y-Bus Before\\n{Y_before.shape}', f'Y-Bus After\\n{Y_after.shape}'])" + } + ], + "metadata": { + "kernelspec": { + "display_name": "esaplus", + "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.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file diff --git a/examples/nonuniform/01_nonuniform_gic.ipynb b/examples/nonuniform/01_nonuniform_gic.ipynb new file mode 100644 index 00000000..5ec9eef5 --- /dev/null +++ b/examples/nonuniform/01_nonuniform_gic.ipynb @@ -0,0 +1,572 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Non-Uniform Electric Field GIC Analysis\n", + "\n", + "This notebook demonstrates the complete workflow for computing\n", + "geomagnetically induced currents (GICs) under **spatially varying**\n", + "electric fields. Unlike a uniform storm analysis, non-uniform fields\n", + "capture realistic conductivity gradients, coastal effects, and\n", + "geologic heterogeneities.\n", + "\n", + "**Key steps:**\n", + "\n", + "1. Build the GIC model from a PowerWorld case\n", + "2. Construct a geographic E-field grid using `Grid2D`\n", + "3. Define a non-uniform E-field pattern (Gaussian hotspot)\n", + "4. Build the line integration operator $L$ and compute $|\\mathbf{I}| = |H \\, L \\, \\mathbf{E}|$\n", + "5. Visualize transformer GIC distribution\n", + "6. Map bus-level GIC magnitudes as a geographic heatmap\n", + "7. Export E-fields to B3D format for PowerWorld integration" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "from esapp import PowerWorld\n", + "from esapp.components import Branch, Bus, GICXFormer\n", + "from esapp.utils import B3D\n", + "\n", + "from examples.mesh import Grid2D\n", + "from examples.map import format_plot, border, plot_lines\n", + "from examples.nonuniform.nonuniform import build_L_matrix, stack_efield, compute_gic, bus_gic\n", + "from examples.nonuniform.plotting import plot_efield, plot_gic_heatmap" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "'open' took: 13.0517 sec\n" + ] + } + ], + "source": [ + "# This cell is hidden in the documentation.\n", + "import ast\n", + "\n", + "with open('../data/case_B.txt', 'r') as f:\n", + " case_path = ast.literal_eval(f.read().strip())\n", + "\n", + "pw = PowerWorld(case_path)\n", + "SHAPE = 'Texas'" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [], + "source": [ + "# Plotting style constants (hidden from documentation)\n", + "_C1 = '#4C72B0'\n", + "_C2 = '#DD8452'\n", + "_C3 = '#55A868'\n", + "_C4 = '#C44E52'\n", + "_C5 = '#8172B3'\n", + "_CG = '#8C8C8C'\n", + "_FS = dict(titlesize=11, labelsize=9, ticksize=8)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. Build the GIC Model\n", + "\n", + "The GIC model extracts substation, bus, branch, and transformer data\n", + "from the PowerWorld case and computes the **H-matrix** — the linear\n", + "mapping from induced branch voltages to transformer neutral currents." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "H-matrix: (861, 4137) (transformers x branches)\n", + "G-matrix: (3250, 3250) (nodes x nodes)\n", + "Incidence: (4137, 3250) (branches x nodes)\n" + ] + } + ], + "source": [ + "pw.gic.configure(pf_include=True, calc_mode='SnapShot')\n", + "pw.gic.model()\n", + "\n", + "print(f\"H-matrix: {pw.gic.H.shape} (transformers x branches)\")\n", + "print(f\"G-matrix: {pw.gic.G.shape} (nodes x nodes)\")\n", + "print(f\"Incidence: {pw.gic.A.shape} (branches x nodes)\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. Geographic Grid & Network Footprint\n", + "\n", + "We extract bus coordinates from the case and build a structured 2D grid\n", + "covering the network footprint. The `Grid2D` class from `examples.mesh`\n", + "provides the grid structure and discrete operators." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Grid: 50 x 35 = 1750 points\n", + "Edges: 3415 (H: 1715, V: 1700)\n" + ] + } + ], + "source": [ + "lon, lat = pw.buscoords()\n", + "\n", + "pad = 0.5\n", + "lon_min, lon_max = lon.min() - pad, lon.max() + pad\n", + "lat_min, lat_max = lat.min() - pad, lat.max() + pad\n", + "\n", + "nx, ny = 50, 35\n", + "lons = np.linspace(lon_min, lon_max, nx)\n", + "lats = np.linspace(lat_min, lat_max, ny)\n", + "LON, LAT = np.meshgrid(lons, lats)\n", + "\n", + "grid = Grid2D((nx, ny))\n", + "print(f\"Grid: {nx} x {ny} = {grid.size} points\")\n", + "print(f\"Edges: {grid.n_edges} (H: {grid.n_edges_x}, V: {grid.n_edges_y})\")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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b28AvvvuO3r27KmqetyrVy8WLVpULHYWF4WZv7OzM/Xq1cPKygqAr776isWLFxeLncVJYZ7BuXPnOHfuHBMnTiQtLY2YmBiqV6/O3bt3C3x/caVWgnTt2pXvv/+erKwsYmJi2LdvH927d8fS0pIXL14QEhJCSEgI/v7+tG3bttQ5tMKia/4Ad+7coX379nz33Xd89NFHJWxp8ZDf/PNrK8u8ePFCVdX42rVrHDp0iJEjRwLg7u7OsWPHEAQBQRA4cuQItWvXLklzi5z85t+zZ09OnTpFeno6AL/99hs+Pj4lZmtxkd8zyPnMCwkJYe/evdSqVeu1HBogRj8WNydOnBCqVKkimJubC2ZmZkKVKlWEw4cPC4IgCAqFQhg5cqTg5uYmuLu7C998843WMbZu3Vpmox/fdP5t2rQR5HK54OPjo/r5/fffS2oab8ybzr+g742yxtGjRwVPT0+hRo0aQuPGjYW//vpL1fbixQuhc+fOQq1atYRatWoJnTp1EqKiokrQ2qInv/kLgiAsW7ZMqFmzplC7dm2he/fu5TL68VXPIIdTp069UfSjqP0oIiIiIlJuELcfRURERETKDaJTExEREREpN4hOTURERESk3CA6NRERERGRcoPo1EREREREyg2iUxMRERERKTeITk1EREREpNwgOjURERERkXKD6NRERERERMoNolMTESlBvL29+fXXX4tsvEOHDuHq6lqoMfbu3Uu3bt2KxqCXtG3blhMnThTpmCIi2hCdmogI0LJlS61l5Yub27dv89lnnwHZNdMOHTr01m3IjVKpZNq0acycOVOj7fjx47Ru3VolPpubli1bYmhoiJmZmerHxsZG1T59+nQmTZpUrLaLiIDo1ERERHJx9OhRrK2tqVOnjta2bdu2kZCQgFKp1GhfunQpSUlJqp/o6GhV2/vvv09cXBx///13sdovIiI6NRGRfHj+/DndunXD1tYWZ2dnpk+fjkKhULW7urqybNkymjZtirm5OR988IFacdCIiAg++ugjLCwsaNiwIYsWLVLbHsxZnXXt2pWwsDC++uorzMzMGD58OAASiYTAwEDV9d988w0tW7ZUG79t27aq8YOCgtTsT0pKwtfXF2dnZ+zs7Ojbty/x8fE65/vzzz/TqlUrrW2+vr5MnTqV1q1bI5W+3keHRCKhVatW/Pzzz6/VT0TkdRGdmohIPvTs2ROZTEZwcDBnz57l0KFDLFu2TO2aXbt2sWfPHqKiojA1NVXbuuvZsycuLi48f/6cPXv28MMPP2i9z48//oizszN79uwhKSmJjRs3Fti+ypUr8+zZM3bv3s3333+v1j5w4EBiYmK4ceMGwcHBZGZm4uvrq3O8wMBAatSoobXNw8ODXbt2MWDAgALZlpdatWqpOWgRkeJAdGoiIjp4/PgxJ0+eZOXKlZiZmeHi4sL06dPVqvYCjBw5Ejc3N4yMjOjVqxdXrlwBIDw8nLNnz7JkyRKMjY2pVq2aagVWFOSMv3z5ckxMTKhRo4ba+FFRUfzvf/9j3bp1yOVyTE1NmTdvHvv27SMrK0vrmLGxsVhYWLyRPVOnTkUul6t+8hZ3tbCwIDY29o3GFhEpKPolbYCISGklIiICIyMj7O3tVa+5u7sTERGhdp2Dg4Pq/01NTUlMTATgyZMnGBkZqQVMODs7F5l9OePb2dmpXnNxcVH9f0hICEqlEjc3N7V+UqmUZ8+eUaVKFY0xraysSEhIeCN7Fi9ezNixY3W2JyQkYGVl9UZji4gUFNGpiYjooGrVqqSlpfH8+XOVYwsJCaFq1aoF6u/o6EhaWhrR0dEqxxYWFqbzem3nVKampqSkpKh+f/r0qcb4kZGRKseWe3wnJyekUilPnjzBxMSkQDbXq1ePf//9t0DXvi5BQUHUq1evWMYWEclB3H4UEXmJQqEgLS1N9WNjY8OHH37IxIkTSU5OJiwsjIULF9KvX78Cjefk5MS7777LtGnTSE1N5f79+3z33Xc6r7e3t+fhw4dqrzVo0ICdO3eiUCgIDAxk586dGuNPmTKF1NRU7t69y6ZNm1TtDg4OdOzYEV9fX1Uk4rNnzzh48KBOGz7//HNOnTpVoPm9LqdOnVKlL4iIFBeiUxMRecmkSZMwNjZW/VSvXp2AgABSU1NxcXHh3Xff5dNPP+Xrr78u8JgBAQE8evQIe3t7evToQe/evTE0NNR67bRp01i7di1yuVyVC/btt9/yzz//IJfLmTx5soZDDQgIIDw8HDs7O3r27MnAgQPV2rdt24ZcLqdx48ZYWFjQokUL1ZmfNtq3b090dDS3bt0q8BxzmDx5slqempmZGS9evADg7NmzqvuLiBQnEkEQhJI2QkSkorB48WJOnjzJ8ePHS9oUnezZs4dDhw6xb9++Ihvz448/ZuLEiRrBIyIiRY3o1EREipGrV69iYmJC9erVuXr1Kp9//jlz5sxh6NChJW2aiEi5RAwUEREpRqKiohg+fDjPnz/Hzs6OIUOGMGjQoJI2S0Sk3CKu1EREREREyg1ioIiIiIiISLlBdGoiIiIiIuUG0amJiIiIiJQbRKcmIiIiIlJuEJ2aiIiIiEi5QXRqIiIiIiLlBtGpiYiIiIiUG0SnJiIiIiJSbhCdmoiIiIhIuUF0aiIiIiIi5Yb/B80Ca5rctJubAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "lines = pw[Branch, ['Longitude', 'Longitude:1', 'Latitude', 'Latitude:1']]\n", + "\n", + "fig, ax = plt.subplots(figsize=(6.5, 4.5))\n", + "border(ax, SHAPE)\n", + "plot_lines(ax, lines, ms=6, lw=0.6)\n", + "ax.scatter(LON.ravel(), LAT.ravel(), s=0.8, c='#aaaaaa', alpha=0.3,\n", + " label=f'Grid ({nx}$\\\\times${ny})', zorder=1)\n", + "ax.scatter(lon, lat, s=18, c=_C4, zorder=6, edgecolors='white',\n", + " linewidth=0.4, label='Substations')\n", + "ax.set_xlim(lon_min - 0.1, lon_max + 0.1)\n", + "ax.set_ylim(lat_min - 0.1, lat_max + 0.1)\n", + "format_plot(ax, title='Transmission Network & Computation Grid',\n", + " xlabel=r'Longitude ($^\\circ$E)',\n", + " ylabel=r'Latitude ($^\\circ$N)',\n", + " plotarea='white', grid=False, **_FS)\n", + "ax.legend(fontsize=8, loc='lower right')\n", + "ax.set_aspect('equal')\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. Non-Uniform Electric Field Pattern\n", + "\n", + "We define a spatially varying E-field with a **Gaussian hotspot** to\n", + "model a localized conductivity anomaly (e.g., a geological boundary\n", + "or coastal effect)." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "# Normalize geographic coordinates to [0, 1]\n", + "Xn = (LON - lon_min) / (lon_max - lon_min)\n", + "Yn = (LAT - lat_min) / (lat_max - lat_min)\n", + "\n", + "# Gaussian hotspot E-field\n", + "cx, cy = 0.4, 0.5 # hotspot center (normalized)\n", + "sigma = 0.15\n", + "gauss = 2.5 * np.exp(-((Xn - cx)**2 + (Yn - cy)**2) / (2 * sigma**2))\n", + "Ex_field = (0.3 + gauss) * np.sin(np.radians(90))\n", + "Ey_field = (0.3 + gauss) * np.cos(np.radians(90))" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA30AAAMWCAYAAABFue8gAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOzdeZhcWX3f//etfa+urt73bq2jGc1II2k2zQbDEhgbgx2CbWzAJE5MkicmxAkY2z+IExs7TvzYxsELsQ14wYbgGQLDZphN+zLa15Z636q7a9+3e+/vj5Z61KOW1KckTavV3xdPP4Oq6lP3VNWtuud7l3M00zRNhBBCCCGEEELclSzL3QAhhBBCCCGEELePFH1CCCGEEEIIcReTok8IIYQQQggh7mJS9AkhhBBCCCHEXUyKPiGEEEIIIYS4i0nRJ4QQQgghhBB3MSn6hBBCCCGEEOIuJkWfEEIIIYQQQtzFpOgTQgghhBBCiLuYFH1CCLGI7373u7z73e+msbERu91Oc3Mzzz77LF/96lcxDGO5m7eop59+mh/7sR9705b32c9+Fp/Pp3zf9XzpS1/i7/7u7262aTfl+eef5wtf+MKSHvuRj3wETdMW/fv7v//762Y/+9nPLpq77777ANA0jf/5P/+nUttffvllNE3j8OHD133cH/zBH6BpmtJzCyGEWLlsy90AIYS403z605/mc5/7HO973/v44z/+Y1pbW5menub555/n537u56ivr+ed73zncjfzKl/4whewWq3L3Yyb8qUvfQmfz8fP/uzPLlsbnn/+eQ4fPsy//bf/dkmP7+vr42//9m+vun3dunU3zLrdbl588cUFt3k8HgD27dtHd3f3ktoghBBCXI8UfUIIcYUXXniBz33uc3zmM5/hs5/97IL73v/+9/PLv/zL2O325WncDWzatGm5m7Aqud1uHnnkkZqyFovlmtlan1MIIYR4Izm9UwghrvD7v//7tLa28uu//uuL3v/QQw+xdevW+X+/8MILvP3tb6epqYlAIMDDDz/M9773vQWZa53qWFdXt6Cw3LNnD08++STBYBC/38/mzZv58pe/vOT733h657lz5/jpn/5pOjs78Xg8bNq0if/1v/7XgtNTh4eH0TSNv/mbv+Hf//t/TygUorW1lV/5lV+hWq0u/Y1bgng8zkc/+lEaGhpwu9089thjvPrqqwva/8orr/DCCy/Mn+p4+f1Z6mv/yle+wpo1a3C73Tz99NOcP39+QRuKxSKf+MQnaGtrw+VysWXLFp577rn5+z/ykY/w5S9/mdOnT8+34SMf+cgtfR+WarHTO1944QUefvhh3G43jY2NfOxjHyOXy133edLpNB/60Ifw+/00NjbyX/7Lf7nln60QQog7mxzpE0KIS6rVKnv27OGf//N/js22tJ/HoaEhfvzHf5xf+ZVfwWKxzF8L+OKLL/L0008vednpdJpnn32Wxx9/nK9+9as4nU7OnDlDMplc0v2LmZiYYMOGDXzwgx/E7/dz7NgxPvOZz5DNZvnMZz6z4LG/9mu/xk/8xE/wta99jb179/LZz36WtWvX8ku/9Es3bPtiBcQbr3vUdZ13vetdDA4O8ru/+7s0NzfzR3/0R7z97W9n7969bNu2jS984Qv83M/9HB6PZ77Y6ejoWPJrP3LkCAMDA/zO7/wOAL/+67/OO9/5Ts6fP4/T6QTggx/8IN/73vf4rd/6LTZu3MhXvvIVfuqnfornn3+e97znPfzGb/wGs7OznDt3bv6UzcbGxpreg6WuQ2/MWq3WRa+3+7//9//ygQ98gF/4hV/gv/7X/8rU1BSf+tSnSCQS171+8KMf/Sjf//73+Z3f+R16e3v5whe+sOzXTQohhHiTmUIIIUzTNM1IJGIC5qc+9akFtxuGYVYqlfk/XdcXzeu6blYqFfMd73iH+TM/8zPzt3/mM58xvV7vVY8PBoPmZz7zGdM0TfPQoUMmYJ44cWLR577R/aZpmk899ZT57LPPLnrf5dfwW7/1W2Zra+v87UNDQyZgvv/977/quZ555plrLuvy6wKu+Xfla/7mN79pAub3vve9+dvK5bLZ1dVl/uRP/uR1X8NSX7vFYjH7+/vnb7tw4YJpsVjMP/3TPzVN0zSPHz9uAvP/vuzRRx81H3zwwfl/f/jDHzbvvffe6772Kx97rdc/NjZ23ey13r+//uu/Nk3TNAHz937v90zTnPv8uru7F6xXpmma3/3ud01N08xTp06ZpmmaL730kgmYhw4dMk3TNE+fPm1qmmb+xV/8xXymWq2avb29pnQBhBBi9ZDTO4UQ4g3eeJTlG9/4Bna7ff7vP/yH/zB/3/j4OB/+8Idpb2/HZrNht9v5wQ9+QH9/v9Iy16xZQyAQ4GMf+xhf+9rXmJ2dVbp/McVikc985jOsXbsWp9OJ3W7n137t15iamiKbzS547Dve8Y4F/960aRPj4+M3XIbb7ebQoUNX/f3iL/7igsft2rWLQCCwYAAcu93OT/7kT7J79+7rLmOpr/2+++5bMHjK2rVreeCBBzhw4MB8G2Du2swrfeADH+Do0aM3PE3yeu1b7D1obm4G5o5yVqvV+T/TNOezi71/7373u69aRn9/PyMjI/yLf/EvFjzXU089hcViueZonYcOHcI0Td73vvfN32a1Wnnve99b02sVQgixMknRJ4QQl4TDYZxO51XFzjPPPDPfIW9tbZ2/3TAM3vOe97B7925+8zd/k5deeolDhw7xrne9i2KxqLTsUCjEP/3TP+H3+/n5n/95WlpaePrppzl58uSS7l/MJz/5SX7v936PX/zFX+Q73/kOhw4dmr9W8Y3tq6urW/Bvh8OxpNdgsVjYvn37VX9tbW0LHpdIJGhqaroq39zcTDwev+4ylvrar/X8U1NT822w2+3U19df9RjTNK97quz1uFyuRd+DywP+PPPMMwt2Grzyyivz2cXevze2DyAajQLwvve9b8FzeTwedF1nbGxs0bZNTU1ht9sJhUJXvWYhhBCrh1zTJ4QQl9hsNnbu3MmPfvQjdF2fn/4gFAqxfft2YK4YuuzixYscPXqU559/np/4iZ+Yv71QKCx4XpfLRaVSWXBbpVK56mjbQw89xHe/+10KhQIvvfQSv/Irv8J73/teBgYGlnT/G33961/n3/ybf8MnP/nJ+dteeOEF1bfllqivr2dmZuaq26enpxctct5oKa/9Ws+/ZcuW+TZUKhUSicSCImh6ehpN064qfG+VP/uzPyOTycz/e8OGDcrPcfk9+uM//mMefvjhq+5/Y5F9WWtr6zVfsxBCiNVDjvQJIcQVPvGJTzA5Oclv//Zv3/Cxl4u7KwvBkZER9uzZs+BxHR0dlMvlBQXKiy++iK7riz6v2+3m3e9+Nx/72McYGhq66ojbje6/sn1Xtk3X9RtOGH67PP7446TTaX7wgx/M31atVnnuued4/PHH52+70RHG6732U6dOcfHixfl/X7x4kePHj88XSZeX8/Wvf33Bc379619n69ateL3eJbVB1YYNGxYcyfP7/crPsXHjRjo6OhgcHFzSkdXLduzYAbBghFJd13n++edrei1CCCFWJjnSJ4QQV3j2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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots(figsize=(12, 8))\n", + "\n", + "im = plot_efield(ax, lons, lats, Ex_field, Ey_field,\n", + " shape=SHAPE, lines=lines,\n", + " cmap='viridis', title='Gaussian Hotspot E-Field')\n", + "\n", + "fig.colorbar(im, ax=ax, label='|E| (V/km)', shrink=0.7, pad=0.02)\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4. Computing GICs from a Non-Uniform Field\n", + "\n", + "For a uniform storm, PowerWorld's `storm()` method suffices. For a\n", + "non-uniform field, we construct a **line integration operator** $L$\n", + "that maps a gridded electric field to branch induced voltages.\n", + "\n", + "### The line integral\n", + "\n", + "The EMF voltage induced on branch $k$ connecting buses $a$ and $b$ is\n", + "the line integral of the electric field along the conductor path:\n", + "\n", + "$$V_k = \\int_a^b \\mathbf{E} \\cdot d\\boldsymbol{\\ell}$$\n", + "\n", + "We approximate each transmission line as a **straight segment** from\n", + "$(\\lambda_a, \\phi_a)$ to $(\\lambda_b, \\phi_b)$ (longitude, latitude).\n", + "\n", + "### Cell-by-cell discretization\n", + "\n", + "The E-field is known at the nodes of a regular $(n_x \\times n_y)$ grid.\n", + "Rather than evaluate $\\mathbf{E}$ at a single point, we **trace** the\n", + "line through every grid cell it intersects and accumulate contributions\n", + "cell by cell.\n", + "\n", + "For each cell $c = (i, j)$ that branch $k$ passes through, we compute\n", + "the **directed segment** $(\\Delta x_{kc},\\, \\Delta y_{kc})$ —\n", + "the signed length of the line within that cell in km:\n", + "\n", + "$$\\Delta x_{kc} = \\delta\\!f_{x}\\;\\Delta\\lambda\\;(111\\;\\text{km/°})\\;\\cos\\bar\\phi_k,\n", + "\\qquad\n", + "\\Delta y_{kc} = \\delta\\!f_{y}\\;\\Delta\\phi\\;(111\\;\\text{km/°})$$\n", + "\n", + "where $\\delta\\!f_x$ and $\\delta\\!f_y$ are the directed lengths in\n", + "**grid-coordinate units** (fractional cells) obtained by intersecting\n", + "the segment with the cell boundaries.\n", + "\n", + "The E-field inside cell $(i, j)$ is approximated as the **average of\n", + "its four corner nodes**:\n", + "\n", + "$$\\bar{E}_x^{(c)} = \\tfrac{1}{4}\\bigl(\n", + "E_x^{(i,j)} + E_x^{(i{+}1,j)} + E_x^{(i,j{+}1)} + E_x^{(i{+}1,j{+}1)}\n", + "\\bigr)$$\n", + "\n", + "so the voltage contribution from cell $c$ is:\n", + "\n", + "$$\\delta V_{kc} = \\bar{E}_x^{(c)}\\,\\Delta x_{kc}\n", + " + \\bar{E}_y^{(c)}\\,\\Delta y_{kc}$$\n", + "\n", + "### The $L$ operator\n", + "\n", + "We stack the gridded field into a single master vector\n", + "$\\mathbf{E} \\in \\mathbb{R}^{2N}$ ($N = n_x n_y$):\n", + "\n", + "$$\\mathbf{E} = \\bigl[\\,E_x^{(1)},\\ldots,E_x^{(N)},\\;\n", + " E_y^{(1)},\\ldots,E_y^{(N)}\\,\\bigr]^T$$\n", + "\n", + "For each cell $(i,j)$ that branch $k$ traverses, we place weight\n", + "$\\tfrac{1}{4}\\,\\Delta x_{kc}$ at each of the four corner-node columns\n", + "in the $E_x$ block, and $\\tfrac{1}{4}\\,\\Delta y_{kc}$ in the $E_y$\n", + "block. When a branch passes through multiple cells, the COO $\\to$ CSR\n", + "conversion automatically sums contributions at shared corner nodes.\n", + "\n", + "The full branch voltage is:\n", + "\n", + "$$V_k = (L\\,\\mathbf{E})_k\n", + " = \\sum_{c \\in \\text{cells}(k)}\n", + " \\bigl[\\bar E_x^{(c)}\\,\\Delta x_{kc}\n", + " + \\bar E_y^{(c)}\\,\\Delta y_{kc}\\bigr]$$\n", + "\n", + "and the transformer GICs follow as:\n", + "\n", + "$$\\mathbf{I}_{\\text{GIC}} = \\lvert\\, H \\, L \\, \\mathbf{E} \\,\\rvert$$" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "H-matrix: (861, 4137) (transformers x branches)\n", + "L-matrix: (4137, 3500) (branches x 2·grid), nnz = 27796\n" + ] + } + ], + "source": [ + "# Build the line integration operator (computed once for a given grid)\n", + "H = pw.gic.H\n", + "n_branches_model = H.shape[1]\n", + "N_grid = len(lons) * len(lats)\n", + "\n", + "L = build_L_matrix(pw, lons, lats, n_branches_model)\n", + "print(f\"H-matrix: {H.shape} (transformers x branches)\")\n", + "print(f\"L-matrix: {L.shape} (branches x 2·grid), nnz = {L.nnz}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Transformer GICs computed: 861\n", + "Max |GIC| (transformer): 2265.40 A\n", + "Mean |GIC| (transformer): 60.68 A\n", + "\n", + "Buses with GIC: 357\n", + "Max |GIC| (bus): 2265.40 A\n" + ] + } + ], + "source": [ + "# Compute transformer GICs: |I| = |H @ L @ E|\n", + "gic_xf = compute_gic(H, L, Ex_field, Ey_field)\n", + "\n", + "# Aggregate to bus-level totals for geographic plotting\n", + "gic_bus = bus_gic(pw, gic_xf)\n", + "\n", + "print(f\"Transformer GICs computed: {len(gic_xf)}\")\n", + "print(f\"Max |GIC| (transformer): {gic_xf.max():.2f} A\")\n", + "print(f\"Mean |GIC| (transformer): {gic_xf.mean():.2f} A\")\n", + "print(f\"\\nBuses with GIC: {len(gic_bus)}\")\n", + "print(f\"Max |GIC| (bus): {gic_bus['GIC'].max():.2f} A\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 5. Transformer GIC Distribution\n", + "\n", + "The absolute GIC magnitudes $|\\mathbf{I}|$ are always non-negative.\n", + "We visualize the ranked magnitudes and their distribution." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABKUAAAHqCAYAAADVi/1VAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAACcpUlEQVR4nOzdf1yUVf7//8egNBCB5CZaigqpKAJOaWypK6Bk5JZk0Y9VQtpVocW2FjB/lb/T0thdN7ck3uFSbusPpL7csh+8W6Jww81KUtZiIwTDsmwJRhFHhfn+4cd5Nyk6Y8gw+rzfbtftxpxzXee8rjntet3OnPO6DFar1YqIiIiIiIiIiEgH8nB1ACIiIiIiIiIicunRpJSIiIiIiIiIiHQ4TUqJiIiIiIiIiEiH06SUiIiIiIiIiIh0OE1KiYiIiIiIiIhIh9OklIiIiIiIiIiIdDhNSomIiIiIiIiISIfTpJSIiIiIiIiIiHQ4TUqJiIiIiIiIiEiH06SUSCdiMBjOefz1r3+9YP2vWrWK6667Dn9/f3x8fAgPD2fNmjVYrVa786xWK08++SR9+/bF29ubm266ie3bt3fqe3PU3r17GTduHL6+vhgMBsrLy10dUruqqanBYDBQU1NzWl1ZWRkJCQlcffXVXHbZZfzsZz9j7NixZGdnc+zYMdt5ixYt4oorrjjt+oMHD5KRkcGgQYPw8vLCz8+PqKgoXnjhBVpaWmznGQwGSkpKLsTtiYiIdCh3+Xf1r3/9q90zl6+vL4MHD+bXv/41H3zwwWnnR0dHc9tttzn8PZSUlLB8+XKHzz/1veXn59vK+vfvz8yZMx1u43ziaeu7FhHX6erqAETk/5SVldl9vummm3jooYeYPHmyrezaa6+9YP03NDRw7733EhYWhpeXF//4xz/43e9+h9lsZt68ebbznnrqKRYuXMiTTz5JREQEf/nLXxg/fjzl5eUEBwefsW1X35ujHn/8caqrq8nPz6dbt24MGjTI1SF1iOeee46ZM2cyZswYnnrqKfr37099fT1vvvkmDz/8MAApKSltXl9VVUVMTAwtLS2kp6czfPhwLBYLxcXF/P73v+eqq64iPj6+o25HRETEpTrrv6tvvvkm3bp148iRI1RWVpKbm8uNN97IihUrmD17tu28Z599li5dujjcbklJCU8//bTd8+LZXH311ZSVlV2w56y24pk2bRq//OUvL0ifInJ+NCkl0onceOONp5X17dv3jOUXwhNPPGH3OTY2ln379vHXv/7V9o/60aNHWbFiBRkZGfz+978H4Be/+AWDBg3i6aef5tlnnz1j2+dzb83NzXh7e5/v7ZyXzz77jF/84hfccsstP7ktV8QPYLFY8PT0xMPDscWwn3zyCb/73e9ISkoiNzcXg8Fgq7vjjjvIyMjgyy+/PGsbU6ZM4cSJE3z44Yf07t3bVh4XF8fMmTNpbGw8v5sRERFxM53539Xhw4dz1VVXATB27FhSUlKYOnUqc+fOZdSoUYwePRqA0NDQ82rfEaeejzrq+faH+vTpQ58+fTq8XxFpm7bvibiR1tZWli1bRv/+/TEajQwePJjs7Gy7c04tS96xYweRkZF4eXkxZMgQXnvttfPq82c/+5ndEvP3338fs9nMPffcYyu77LLLuPPOO3n99dfP78Z+EPcHH3zATTfdhJeXF3/5y18AmDNnDuHh4VxxxRX07t2bX/3qV3z99dd2159aZp6fn09ISAhXXHEFY8eO5YsvvrA778knn2TAgAF4eXnRo0cPYmNj2bt3r20Z+UcffcRLL72EwWCgf//+tuuys7MJCQnBaDTSv39/li1bRmtrq63+1LL4srIybr75Znx8fJg1axYlJSUYDAbeeust7rnnHq644gr69u3Lyy+/DMCf//xn+vbtS/fu3Zk2bRoWi8Uu3rq6OhITE7nqqqvw9vZmzJgxfPTRR3bnnFruvnLlSvr164e3tzf19fUOf/d//vOf6dKlC1lZWXYPzqcMHDiQsWPHtnl9aWkpH3zwAfPmzbN7cD6lb9++hIeHOxyPiIiIO3Onf1c9PDxYvXo1RqPR7ofFH2/fq6ur45577qFnz554eXkRFBRk+3Fy0aJFLF68mKamJtv2wOjoaFvdmZ7vzrR975RVq1bRu3dvLr/8cuLj4+2e+U49V3344Yd219xxxx12fZ4rnh+qra0lISGBbt264ePjwy233MLu3bvtzjn1rPWXv/yFfv360a1bN+644w4OHjzo3BcuIqfRSikRNzJr1ixWr17NY489xsiRI3nttddITU3l+PHjdnvwjx8/zr333ktGRgZBQUE899xzTJo0iY8//tihh5gTJ07Q3NzMe++9x4svvsjChQttdZ999hkAgwcPtrtmyJAh7Nu37yetDjp27BiTJ0/m97//PcuXL+dnP/sZAN9++y3z5s3jmmuu4eDBg2RlZREVFcWePXvo2vX//m+svLycVatW8eSTT9qWuycmJtq2Dr744os8/vjjLFmyhJtuuonGxkZKS0sxm80MHjyYsrIykpKSGDhwII8//jhGoxGAZ555ht/97nc89NBD3Hbbbbz//vssWrSIhoYGnn76abt7mDx5MjNmzGDevHlcfvnlNDc3A/Dggw+SnJzM9OnTycnJ4f777+eTTz6hoqKCtWvXUl1dTXp6OsHBwbZVad9//z2jR4/miiuu4JlnnqFbt24888wzjB07ls8//5yAgABbv1u2bGHgwIGsXr2aLl264OPj4/D3XlJSwogRI+jevft5jBq8++67wMlfb0VERC517vbvavfu3Rk+fPhpqRZ+KCkpia+++oo///nP9OzZk3379tkmhqZNm0ZdXR0vv/wyxcXFAPj5+dmubev57kxeeeUV+vXrx3PPPcf333/P7NmzufPOO88a24+dK54fOnToENHR0Xh4eLB27Vq8vLx44oknGDNmDLt27SIwMNB2bmFhIZ9//jl/+ctf+O677/j973/PQw89xIYNGxyOTUROp0kpETfx3Xff8cwzzzBr1iwWLVoEwPjx4/nuu+9YsmQJDz74oG3v/7Fjx3jsscf49a9/DcAtt9zCwIEDWb58OX//+9/P2k9VVRUDBw60fX7sscdsv4TByYkSo9GIl5eX3XVXXnklVquV77///rwnpY4fP84TTzzBvffea1eem5tr+7ulpYWbbrqJPn36UFxczPjx4211DQ0N7Ny5kx49egBw+PBhHnjgAerq6ujTpw8ffPABERERzJ0713bND/Mx3HjjjVx++eX06NHDtqS8paWFJUuWcN999/HnP/8ZOPm9Hzt2jKysLObOnWv3cJWammqXk+FU4tG7776bBQsWABAZGUlBQQF///vf+eKLL/D09LSdu3nzZtuk1J/+9CcaGhr44IMPbBNQ48aNs22VXLlypd1398Ybbzg1GXXKV199RWRk5GnlJ06csP3t4eHR5nbA/fv3Ayd/uRUREbnUueO/q4GBgaetxP6hDz74gBUrVtg9oyUlJQH/tyXOw8PjjFvyzvR8d6bE8HBykuiNN96gW7dutrjGjRvHW2+95XBqhXPF80Pr1q2jtraWf//73wwZMgSAqKgo+vbty5/+9CeysrJs51qtVgoLC20/WtbU1LB8+XJaW1sdTpkgIqfT/3pE3MS//vUvjh8/zt13321Xfu+993Lw4EH+85//2JVPmjTJ9neXLl244447+Ne//nXOfgIDA9mxYwfvvPMOS5Ys4Q9/+IPdSqkL7UzJJ9944w1GjhxJt27d6Nq1qy0XwI/v2WQy2Sak4P/yIdTV1QFw/fXXs3PnTtLT09m2bRvHjx8/ZzyfffYZ33333Rm/92PHjp32xpq2kmfefPPNtr+7detGQEAAY8aMsU1IAQwaNMgux0RRURExMTF0796dEydOcOLECbp06UJUVBQ7duywaz86Ovq8JqRO+fH2gg8//BBPT0/bMXHiRKfbEBERuVS527+rVqv1rP1df/31PP300zz33HNUVVU53b6jycVjYmJsE1JwMu9V9+7dHXqGPR+lpaWEhYXZJqTg5Mqxm2++mW3bttmdGxUVZZuQgpPPmcePH+fbb7+9ILGJXCo0KSXiJr7//nsAevbsaVd+6vMPcwh5enpy5ZVXnnbej/MwnYnRaGTEiBFER0fz+OOPs3z5cp544gkOHDgAnFwRZbFYOHr06GnxGQyG0/p1xuWXX37aPv8dO3YwceJErrnmGl566SXKysrYvn07wGkx+Pv7232+7LLL7M5LTk7mj3/8I2+99Ra/+MUv6NGjBw8//LBti92ZOPO9n+m8s8V2prIf3tN3333Hq6++avcQ6+npyUsvvXRagtS2+nXENddcY5u4OyU0NJQdO3awY8cOrr/++rNefyrfxb59+847BhERkYuFO/67WldXR69evdqs37hxI+PGjWP+/PkMHDiQwYMHU1BQ4FDbZ3q+a8sPUxP8sMyRZ9jz8f3335/xGapnz56nPeOd6zlTRM6PJqVE3MSpvAQ//jXmm2++sauHk8ukT02m/PC8q6++2ul+hw8fTktLi22Z9alcUpWVlXbnffbZZ/Tt2/cnvW3uTL/QvfLKK3Tr1o1NmzYxceJEbrzxxrM+NJ2Nh4cHDz/8MP/+97+pq6vj8ccf59lnnz0tL9QPOfO9t3UP56t79+7ExcXZHmJ/eLzyyivt1m90dDQ7duyw+2/m8ssvZ8SIEYwYMQJfX99zXg/w1ltvnXcMIiIiFwt3+3f1v//9Lx9++CEjR45s85yrr76a3NxcvvvuOz744ANCQkK49957qa6uPmf7zjyjnGnV0bfffmt7hj2VPuKHL+EBTnvudVT37t3P2Oc333xz3jnBRMQ5mpQScRORkZF4enqyefNmu/JNmzYREBDAoEGD7Mp/OGnR0tLCq6++ys9//nOn+922bRsGg4GgoCAARo4ciZ+fn10cx48fp6CggAkTJjjd/rk0Nzfj6elp90Dzt7/97Se327t3bzIyMoiIiODTTz9t87yQkBB69Ohxxu/9sssuO2POiPYSGxvLnj17GDJkiO1B9tTRnm+z+93vfseJEyeYNWvWeV0/evRoIiMjWb58+Rl/yfzyyy9Pe4uNiIjIxcqd/l1tbW3lkUce4dixY6SlpZ3zfA8PD2644QaWLVvGiRMnbFv5LrvsstPeIHw+3nnnHRobG22fi4uLqa+vtz3Dnkrh8MNnt++++46PP/7Yrh1H4xk9ejS7d++2+7H1+++/5+2332b06NE/6V5ExDFKdC7iJq666ioeeughVq1ahZeXFzfeeCOvv/46L7/8Ms8884wtyTmc/Id42bJlHD16lKCgIJ599lm+/PJLXn311Tbbb2xsZMKECSQmJjJgwACOHz9OSUkJq1evJiUlxba02cvLi7lz57Jo0SJ69OhBeHg4zz77LP/973/JzMxs9/u++eab+dOf/sRDDz3EpEmTKCsr46WXXjqvtlJSUrjyyiu58cYbufLKK/nnP//JJ598wm9/+9s2r+nSpQuPP/44v/vd7wgICGDChAls376dp556ikceeeSsb5D5qdLT0/nb3/5GVFQUDz/8MH379uXgwYP861//4pprrrFLQP9TDBs2jD//+c/MnDmT6upqHnjgAfr378/hw4f58MMP2bVr1zmTi/7tb38jOjqaESNGkJ6ezvDhw7FYLLz77rv85S9/4cUXX2zXiTQREZHOqjP/u/rRRx/RrVs3mpubqaysJDc3l48++oiVK1dy0003nfGaxsZGbrnlFu6//35CQkI4duwYzzzzDP7+/ratiEOGDOHEiROsXr3a9gNmSEiI0/H5+vpy6623MmfOHBoaGpg9ezaRkZG276tPnz78/Oc/Z/HixbZco0899ZRdHipn4nnggQf44x//yC9/+UuWLVtme/te165deeSRR5yOX0Scp0kpETeyatUq/P39+Z//+R+WLVtG//79Wbt2LSkpKXbneXp68ve//520tDR2795NUFAQW7ZsISIios22vby8GDRoEH/4wx/Yv38/3t7eDBgwgLVr19rernLK7NmzsVqtPP300xw8eBCTycRbb71FcHBwu9/zhAkTeOqpp3jmmWdYt24do0aN4rXXXjttZZgjRo4cSU5ODjk5ORw5coTg4GD++Mc/8pvf/Oas1z300EN4enryhz/8gWeffZarr76aRYsW2d6Sd6H87Gc/Y/v27Tz22GPMnj2b//73vwQEBHDjjTfaJbJvDw8++CDDhg0jKyuLWbNm8d///hdfX19MJhPLly+3vcmxLQMGDODjjz/mqaee4rnnnuPLL7/EaDRy3XXX8ac//YnbbrutXeMVERHpzDrrv6txcXEA+Pj40Lt3b0aNGsVf/vIXbrjhhjav8fLyIjw8nGeeeYZ9+/bh7e3NiBEjKCoq4qqrrgLg9ttv57e//S0rVqzg22+/ZcyYMbY3EDtj0qRJ9OnTh9TUVL7//ntuvvlm1q5da3fO3/72N6ZPn05ycjK9evVi2bJlbNiwgYaGBts5jsbj6+tLSUkJ6enpzJgxg5aWFkaNGsV7771HYGCg0/GLiPMMVqvV6uogRKT9LFq0iKeffprDhw+7OhTphGpqaggKCmLv3r3079/fJTEYDAbeeecdW84MERERd6V/V0VEfhrllBIRERERERERkQ6nSSkREREREREREelwmpQSucgsWrRIW/dERERERESk01NOKRERERERERER6XBaKSUiIiIiIiIiIh1Ok1IiIiIiIiIiItLhuro6gI7S2trKV199ha+vLwaDwdXhiIiIiBuwWq0cOnSIa665Bg+PS++3PD0/iYiIyPlw9BnqkpmU+uqrrwgMDHR1GCIiIuKGvvzyS/r06ePqMDqcnp9ERETkpzjXM9QlMynl6+sLnPxC/Pz8XByNOOuLL77g2muvdXUYch40du5LY+e+NHbtx2w2ExgYaHuOuNR01POT/pt1Dxon96Bxcg8aJ/egcTp/jj5DXTKTUqeWnPv5+WlSyg35+vpq3NyUxs59aezcl8au/V2qW9c66vlJ/826B42Te9A4uQeNk3vQOP1053qGuvSSI4iIiIiIiIiIiMtpUkpERERERERERDqcJqVERERERERERKTDaVJKREREREREREQ6nCalRERERERERESkw2lSSkREREREREREOpwmpUREREREREREpMNpUkpERERERERERDqcJqVERERERERERKTDaVJKREREREREREQ6nCalRERERERERESkw2lSSkREREREREREOpwmpUREREREREREpMNpUkpERERERERERDqcJqVERERERERERKTDaVJKREREREREREQ6XFdXB9DR9q5KxNfL09VhiJM8gGpXByHnRWPnvjR27utSGrvg+VtcHYK0g65dL7lHUhEREaGdVko1NDTQr18/ysrKbGVr1qwhJiYGq9VKSUkJ3t7emEwm21FYWHhaO6+88goRERGYTCZCQ0OZP38+Vqv1nHUiIiIi4r76BAb+pOtbW/VMKCIi4o7a5Wcpf39/srOzSU5Opry8nLq6OpYuXcr27dsxGAwAhISEUF5eftZ2YmNjiY+Px8PDg2PHjjF69GhGjBjBpEmTzlonIiIiIu6ra5cuPP23j6j75pDT1/bp6UvmlOEXICoRERG50NptrXRcXBxRUVFkZmayc+dOlixZQlBQkFNt+Pr62v4+evQoFovFNql1tjoRERERcW913xzii/2Nrg5DREREOlC7JjrPyspi06ZNeHl5kZKSYldXWVlpt32vpaXljG28//77hIeHExAQwNixY4mPj3eo7scsFgtms9nuEBERERERERGRzqFds0qWlpZiNBqprq7GbDbj5+dnq3Nk+x7AyJEj2b17NwcPHuSuu+6itLSUMWPGnLPux1asWMHixYvb5b5ERESkc6qqqrqg7R865Px2MhERERFxTLtNStXX15OamkpBQQF5eXlkZGSQk5Nz3u316NGDCRMmsHnz5tMmns5Wd8rcuXNJT0+3fTabzQT+xCSaIiIi0rkMGDDggravldYiIiIiF067bd9LS0sjMTGRyMhIVq5cSXFxMUVFRU618dlnn9Ha2gqc/GVy69atREREnLPuTIxGI35+fnaHiIiIiIiIiIh0Du2yUio/P5+Kigry8vIA8PHxITc3l6SkJHbt2uVwOxs3bmTjxo14enrS0tJCQkIC06ZNO2ediIiIiIiIiIi4l3aZlEpISCAhIcGuLCoqitraWgCio6Mdyie1cOFCFi5c6HSdiIiIiIiIiIi4l3ZNdO4Ogmat11Y+N1RVVXXB84bIhaGxc18aO/elsRMRERERd9BuOaVEREREREREREQcpUkpERERERERERHpcJfc9r29qxLx9fJ0dRjiJA+g2tVByHn5qWMXPH9Le4UiIiIiIiIinYjDK6UaGhro168fZWVltrI1a9YQExOD1WqlpKQEb29vTCaT7SgsLDytnVdeeYWIiAhMJhOhoaHMnz8fq9UKQFNTEw888ADh4eEMHjyYOXPm2OpqamqIjo6mW7dumEymn3jbIiIiIiIiIiLiSg6vlPL39yc7O5vk5GTKy8upq6tj6dKlbN++HYPBAEBISMg537IXGxtLfHw8Hh4eHDt2jNGjRzNixAgmTZrE8uXLaWlpYdeuXZw4cYKJEyeSn5/P3XffjZ+fH8uWLaOxsZH58+f/pJsWERERERERERHXciqnVFxcHFFRUWRmZjJ16lSWLFlCUFCQUx36+vri4XGy26NHj2KxWGyTWp988glxcXEYDAY8PT25+eabeemllwDo3r07o0ePxsfHx6n+RERERERERESk83E60XlWVhabNm3Cy8uLlJQUu7rKykq77XstLS1nbOP9998nPDycgIAAxo4dS3x8PADDhw9n8+bNWCwWDh8+zKuvvkpNTY3zdwVYLBbMZrPdISIiIiIiIiIinYPTic5LS0sxGo1UV1djNpvx8/Oz1TmyfQ9g5MiR7N69m4MHD3LXXXdRWlrKmDFjmDNnDnPmzOHnP/853bp1IzIykuLiYmdDBGDFihUsXrz4vK4Vkc6jqqrK1SFcspqamvT9uymNXfs5dOiQq0MQERERuWg5NSlVX19PamoqBQUF5OXlkZGRQU5Oznl33qNHDyZMmMDmzZsZM2YM3t7erF692lb/5JNPMnTo0PNqe+7cuaSnp9s+m81mAgMDzztWEXGNAQMGuDqES1ZVVZW+fzelsWs/WmktIiIicuE4NSmVlpZGYmIikZGRDB06lIiICIqKihg/frzDbXz22WcMGjQIDw8PDh06xNatW0lKSgJOPvh17dqVyy+/nL179/Lcc8/x//1//59zd/T/GI1GjEbjeV0rIiIiIiIiIiIXlsOTUvn5+VRUVJCXlweAj48Pubm5JCUlsWvXLoc73LhxIxs3bsTT05OWlhYSEhKYNm0aANXV1dxzzz107dqVrl278sc//hGTyQTAkSNHGDRoEBaLhcbGRvr06cP999/PihUrnLhdERERERERERHpDByelEpISCAhIcGuLCoqitraWgCio6Mdyie1cOFCFi5ceMY6k8nEf/7znzPWXX755dTV1TkaroiIiIiIiIiIdGJOJzp3d0Gz1tsl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DhzAw8OD5ORkFixYwLJlywDo378/n3zyCYcPHyYxMZGCggLuu+++M/axYsUKFi9e7OztyUWuqqrK1SFccpqamvS9uymNnfvS2LWfQ4cOuToEERERkYuWU5NS9fX1pKamUlBQQF5eHhkZGeTk5Jx35z169GDChAls3ryZMWPG8PzzzzN58mS8vLwAmDJlCsuXLz/tuiuuuIL77ruPv/3tb21OSs2dO5f09HTbZ7PZTGBg4HnHKheHAQMGuDqES05VVZW+dzelsXNfGrv2o5XWIiIiIheOU9v30tLSSExMJDIykpUrV1JcXExRUZFTHX722We0trYCJ3993Lp1KxEREQAEBwdTVFSE1WrFarWydetWwsLCgJMP2MePHwdO5pQ69Ra/thiNRvz8/OwOERERERERERHpHByelMrPz6eiooJFixYB4OPjQ25uLtOnT6exsdHhDjdu3EhYWBjDhg3jpptuYty4cUybNg2ARYsWcfjwYcLCwggLC+Obb77hiSeeAKC4uJjrrruOYcOGcd1119GzZ08ef/xxJ25VREREREREREQ6C4e37yUkJJCQkGBXFhUVRW1tLQDR0dEO5ZNauHAhCxcuPGNd9+7dyc/PP2PdjBkzmDFjhqPhioiIiIiIiIhIJ+Z0onN3FzRrvbbyuSHlRxERERERERG5uDiVU0pERERERERERKQ9aFJKREREREREREQ63CW3fW/vqkR8vTxdHYY4yQNg/hZXhyEiIiIiIiIi7cThlVINDQ3069ePsrIyW9maNWuIiYnBarVSUlKCt7c3JpPJdhQWFrbZXnNzM6GhoZhMJltZa2sr6enphIaGEhERQUxMDFVVVQAcPnyYW265hauuugp/f3/n71RERERERERERDoNh1dK+fv7k52dTXJyMuXl5dTV1bF06VK2b9+OwWAAICQkxKE38AHMnj2bUaNGsWPHDltZYWEh//znP/nkk0/w9PRk2bJlzJs3j02bNuHp6cns2bPp3r070dHRTt2kiIiIiIiIiIh0Lk7llIqLiyMqKorMzEymTp3KkiVLCAoKcrrTt99+m/379zNlyhS7coPBgMVi4ejRo1itVsxmM3369AHAaDQyduxYrZISEREREREREbkIOJ1TKisri+DgYMLDw0lJSbGrq6ystNuO99FHH9GlSxe7cxoaGnj00Ud588032bNnj13d7bffzjvvvEOvXr3w9fWld+/evPvuu86GCIDFYsFisdg+m83m82pHRERERERERETan9OTUqWlpRiNRqqrqzGbzfj5+dnqHNm+N3PmTObNm0dAQMBpk1IffvghFRUV7N+/Hz8/P+bMmUNqairr1693NkxWrFjB4sWLnb5OOq9T+cXEvTQ1NWns3JTGzn1p7NrPoUOHXB2CiIiIyEXLqUmp+vp6UlNTKSgoIC8vj4yMDHJycpzqcNu2bWzbto3MzEyOHj1KfX09ISEhVFZW8uKLL9pt0Zs6dSrjx493qv1T5s6dS3p6uu2z2WwmMDDwvNqSzmHAgAGuDkHOQ1VVlcbOTWns3JfGrv1opbWIiIjIheNUTqm0tDQSExOJjIxk5cqVFBcXU1RU5FSHNTU1tmPDhg2EhoZSWVkJQHBwMMXFxRw7dgyA1157jbCwMKfaP8VoNOLn52d3iIiIiIiIiIhI5+DwSqn8/HwqKirIy8sDwMfHh9zcXJKSkti1a1e7BJOWlsann37KsGHD8PT0pFevXqxdu9ZWHxERwcGDB20J0GNiYnjppZfapW8REREREREREek4Dk9KJSQkkJCQYFcWFRVFbW0tANHR0efMJ/VjP77GaDSedTtge01+iYiIiIiIiIiIazmd6NzdBc1ar618bkgJe0VEREREREQuLk7llBIREREREREREWkPl9xKqb2rEvH18nR1GOKA4PlbXB2CiIiIiIiIiFwgDq+UamhooF+/fpSVldnK1qxZQ0xMDFarlZKSEry9vTGZTLajsLCwzfaam5sJDQ3FZDLZylpbW8nMzCQsLIzBgwfzm9/8xvYmvpqaGrp06WLX/hdffHEetywiIiIiIiIiIq7m8Eopf39/srOzSU5Opry8nLq6OpYuXcr27dsxGAwAhISEOJzsfPbs2YwaNYodO3bYyl544QU+/vhjPv74Yzw9PZkxYwarV69m1qxZAPj6+jqdTF1ERERERERERDofp3JKxcXFERUVRWZmJlOnTmXJkiUEBQU53enbb7/N/v37mTJlil35J598QmxsLJdddhkGg4Fbb72Vl156yen2RURERERERESkc3M60XlWVhabNm3Cy8uLlJQUu7rKykq77XUtLS2nXd/Q0MCjjz7Kc889d1rd8OHDKSwsxGw2c/z4cTZt2kRNTY2tvqmpiRtuuIHrr7+eJUuWnLH9UywWC2az2e4QEREREREREZHOwelE56WlpRiNRqqrqzGbzfj5+dnqHNm+N3PmTObNm0dAQAB79uyxq0tOTqa2tpaoqCi8vb2JjY2lqKgIgKuvvpr9+/cTEBBAfX099957L1lZWTz66KNn7GfFihUsXrzY2duTTqSqqsr2d1NTk91ncR8aO/elsXNfGrv2c+jQIVeHICIiInLRcmpSqr6+ntTUVAoKCsjLyyMjI4OcnBynOty2bRvbtm0jMzOTo0ePUl9fT0hICJWVlRgMBhYtWsSiRYsA2LBhA0OHDgXAaDQSEBAAQPfu3fn1r3/Nyy+/3Oak1Ny5c0lPT7d9NpvNBAYGOhWruNaAAQNsf1dVVdl9FvehsXNfGjv3pbFrP1ppLSIiInLhODUplZaWRmJiIpGRkQwdOpSIiAiKiooYP368w238cDteSUkJjzzyiG111dGjR2lububKK6/ku+++48knn2Tp0qUAfPvtt1x55ZV4enpisVgoKCjguuuua7Mfo9GI0Wh05vZERERERERERKSDODwplZ+fT0VFBXl5eQD4+PiQm5tLUlISu3btapdgGhsbiY6OxsPDg9bWVh5++GFuv/124OQKqwULFtClSxdOnDjB2LFjmT9/frv0KyIiIiIiIiIiHcvhSamEhAQSEhLsyqKioqitrQUgOjr6nPmkfuzH1/Ts2ZNPP/30jOfeeeed3HnnnU61LyIiIiIiIiIinZPTic7dXdCs9XbJ2UVEREREREREpON5uDoAERERERERERG59GhSSkREREREREREOtwlt31v76pEfL08XR2GnEHw/C2uDkFEREREREREOojDK6UaGhro168fZWVltrI1a9YQExOD1WqlpKQEb29vTCaT7SgsLDytnQ0bNmAymQgLCyMsLIysrCxbXWtrK5mZmYSFhTF48GB+85vfcOzYMQB2797NmDFjGDx4MGFhYfz617+mubn5p9y7iIiIiIiIiIi4iMOTUv7+/mRnZ5OcnExzczOff/45S5cuJTc3F4PBAEBISAjl5eW2Y+LEiae1ExgYyJtvvklFRQX//Oc/ee655ygpKQHghRde4OOPP+bjjz/m008/xcPDg9WrVwPg5eXFmjVr+Oyzz/jkk09oamriqaeeaoevQERERMS9rFu3DoPBwKuvvgrAt99+S1xcHAMHDiQsLIz33nvPdu7Z6kRERERcyamcUnFxcURFRZGZmcnUqVNZsmQJQUFBTnU4atQoevXqBUC3bt0YPHgwNTU1AHzyySfExsZy2WWXYTAYuPXWW3nppZcAGDhwIBEREQB06dKFG264wXadiIiIyKWipqaGnJwcbrzxRlvZnDlzuPHGG/n8889Zt24dkydP5vjx4+esExEREXElpxOdZ2VlsWnTJry8vEhJSbGrq6ystNu+19LScta29uzZQ1lZGbGxsQAMHz6cwsJCzGYzx48fZ9OmTWeceGpqauJ//ud/iI+Pb7Nti8WC2Wy2O0RERETcWWtrK9OmTeOZZ57BaDTayjdt2kRqaioAN9xwA9dccw3vvvvuOetEREREXMnpROelpaUYjUaqq6sxm834+fnZ6k5t33NEXV0d8fHxrF27lj59+gCQnJxMbW0tUVFReHt7ExsbS1FRkd11x44d495772X8+PFMmjSpzfZXrFjB4sWLnb09caGqqqo265qams5aL52Xxs59aezcl8au/Rw6dMjVIdj5wx/+wKhRoxg+fLit7L///S/Hjx+3rUQH6N+/P/v27Ttr3ZlYLBYsFovts37UExERkQvJqUmp+vp6UlNTKSgoIC8vj4yMDHJycpzu9KuvviI2NpbHHnuMu+++21ZuMBhYtGgRixYtAk4mRR86dKit/vjx49x7771cffXVtlxTbZk7dy7p6em2z2azmcDAQKdjlY4zYMCANuuqqqrOWi+dl8bOfWns3JfGrv10pkmZiooKtmzZckFzQrX1o94XX3yBr6/vBenTaDS2yzPal19+aTehJu1PE97uQePkHjRO7kHjdP4c/WHPqUmptLQ0EhMTiYyMZOjQoURERFBUVMT48eMdbuPrr79m3LhxzJ49m6lTp9rVHT16lObmZq688kq+++47nnzySZYuXQrAiRMnuO++++jevTvPP/+8Lbl6W4xGo92ydhERERF3VlpaSk1NDQMHDgTgwIEDzJgxg8WLF9O1a1cOHDhgWxFVU1ND3759+dnPftZm3Zm09aPetddea7c6vjPSj48Xnia83YPGyT1onNyDxun8OfrDnsM5pfLz86moqLCtYvLx8SE3N5fp06fT2NjocGALFixg3759rF692pZ7at26dQA0NjYycuRIhg4dyi9+8QtSU1O5/fbbAdi4cSMFBQV8+OGHXHfddZhMJtLS0hzuV0RERMSdPfjgg3z99dfU1NRQU1PDjTfeyPPPP8+DDz7I3Xffzdq1awHYsWMH+/fvJyoqCuCsdT9mNBrx8/OzO0REREQuFIdXSiUkJJCQkGBXFhUVRW1tLQDR0dEO5ZPKyclpc8tfz549+fTTT89YN2XKFKZMmeJouCIiIiKXjKeeeor777+fgQMHctlll7F+/Xo8PT3PWSciIiLiSk4nOnd3QbPW61c/ERERcXslJSW2v3v27Hnay2EcqRMRERFxJYe374mIiIiIiIiIiLSXS26l1N5Vifh6acl6ZxQ8f4urQxARERERERGRDuLwSqmGhgb69etHWVmZrWzNmjXExMRgtVopKSnB29vblrzcZDJRWFjYZnvNzc2EhoZiMplsZcXFxURGRhIaGsrQoUN59NFHaW1tBU6+KaZLly527X/xxRfnccsiIiIiIiIiIuJqDq+U8vf3Jzs7m+TkZMrLy6mrq2Pp0qVs374dg8EAQEhIiEPJzgFmz57NqFGj2LFjh63syiuvZMOGDQQHB3P06FFiY2N58cUXSU5OBsDX19fh9kVEREREREREpPNyavteXFwcUVFRZGZmsnPnTpYsWUJQUJDTnb799tvs37+fhx56yG5S6rrrrrP97eXlhclkoqamxun2RURERERERESkc3M6p1RWVhbBwcGEh4eTkpJiV1dZWWm3He+jjz6iS5cuduc0NDTw6KOP8uabb7Jnz542+zlw4AD5+fm89tprtrKmpiZuuOEGWlpauOOOO5g/f/5p7Z9isViwWCy2z2az2ZnbFBERERERERGRC8jpSanS0lKMRiPV1dWYzWb8/PxsdY5s35s5cybz5s0jICCgzUkps9nM7bffzqOPPsqIESMAuPrqq9m/fz8BAQHU19dz7733kpWVxaOPPnrGNlasWMHixYudvT1xoaqqqjbrmpqazlovnZfGzn1p7NyXxq79HDp0yNUhiIiIiFy0nJqUqq+vJzU1lYKCAvLy8sjIyCAnJ8epDrdt28a2bdvIzMzk6NGj1NfXExISQmVlJXDy4S8uLo74+HjS09Nt1xmNRgICAgDo3r07v/71r3n55ZfbnJSaO3eu3fVms5nAwECnYpWONWDAgDbrqqqqzlovnZfGzn1p7NyXxq79aKW1iIiIyIXj1KRUWloaiYmJREZGMnToUCIiIigqKmL8+PEOt/HDHFElJSU88sgjttVV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tba2kp6eTmhoKBEREcTExFBVVXUetywiIiLSserr650qFxEREbkUODwp5e/vT3Z2NsnJyTQ3N/P555+zdOlScnNzMRgMAISEhFBeXm47Jk6ceFo7gYGBvPnmm1RUVPDPf/6T5557jpKSEgD8/PxYtmwZL7/88mnXFRYW8s9//pNPPvmEXbt2MW7cOObNm3eety0iIiLSMW688Ub+9re/nbHu73//Oz//+c87OCIRERGRzsGp7XtxcXFERUWRmZnJzp07WbJkCUFBQU51OGrUKNvf3bp1Y/DgwdTU1ADQvXt3Ro8ebZuk+iGDwYDFYuHo0aN07doVs9lMnz59nOpbREREpKPNmzePCRMmcPjwYe677z569+7N/v372bBhA08++SRvvPGGq0MUERERcQmnc0plZWURHBxMeHg4KSkpdnWVlZV22+4++ugjunTp0mZbe/bsoaysjLVr156z39tvv5133nmHXr164evrS+/evXn33XfbPN9isWCxWGyfzWbzOfsQERERaW+jR4/m5Zdf5uGHH+axxx6zlffv35+XX36ZkSNHujA6EREREddxelKqtLQUo9FIdXU1ZrMZPz8/W92p7XuOqKurIz4+nrVr1zq04unDDz+koqKC/fv34+fnx5w5c0hNTWX9+vVnPH/FihUsXrzYoVjkwmqP3F9NTU3KIeamNHbuS2PnvjR27efQoUPt0s5tt93Gbbfdxueff87Bgwe56qqr2kx+LiIiInKpcGpSqr6+ntTUVAoKCsjLyyMjI4OcnBynO/3qq6+IjY3lscce4+6773bomhdffJGxY8fi7+8PwNSpUxk/fnyb58+dO5f09HTbZ7PZTGBgoNOxyk83YMCAn9xGVVVVu7QjHU9j5740du5LY9d+2nul9cCBAxk4cGC7tikiIiLirhxOdA6QlpZGYmIikZGRrFy5kuLiYoqKipzq8Ouvv2bcuHHMnj2bqVOnOnxdcHAwxcXFHDt2DIDXXnuNsLCwNs83Go34+fnZHSIiIiIiIiIi0jk4PCmVn59PRUUFixYtAsDHx4fc3FymT59OY2Ojwx0uWLCAffv2sXr1akwmEyaTiXXr1gFw5MgR+vTpw913382ePXvo06cPc+fOBU5OiAUFBTFs2DAiIiL4xz/+wXPPPefErYqIiIiIiIiISGfh8Pa9hIQEEhIS7MqioqKora0FIDo62qF8Ujk5OW1u+bv88supq6s7Y53RaDyvrYIiIiIiIiIiItL5OJ3o3N0FzVqvrXwiIiIiIiIiIi7mVE4pEREREXGt8ePHExERgclk4he/+AU7d+4E4PPPP2fkyJEMGjSIG264gX//+9+2a85WJyIiIuIql9xKqb2rEvH18nR1GBed4PlbXB2CiIjIJWHTpk22txG/8sorJCcn88knn5CSksKMGTNITk4mPz+f5ORkduzYAXDWOhERERFXcXilVENDA/369aOsrMxWtmbNGmJiYrBarZSUlODt7W1LXm4ymSgsLDytnVdeecX2615oaCjz58/HarXandPc3ExoaCgmk+m0661WK2PHjrU9jImIiIhcSn74DNTY2IjBYODbb7/lww8/JDExEYC77rqLL7/8kqqqqrPWiYiIiLiSwyul/P39yc7OJjk5mfLycurq6li6dCnbt2/HYDAAEBIScs5k57GxscTHx+Ph4cGxY8cYPXo0I0aMYNKkSbZzZs+ezahRo874C94f//hHrr32Wj7++GNHQxcRERG5qCQlJfHOO+8A8Prrr/Pll19y9dVX07XryUc7g8FA37592bdvH926dWuzbsCAAXbtWiwWLBaL7bPZbO6gOxIREZFLkVPb9+Li4oiKiiIzM5OdO3eyZMkSgoKCnOrQ19fX9vfRo0exWCy2SS2At99+m/379/PQQw+dNin173//m1dffZV169axefNmp/oVERERuVi8+OKLAOTl5TF79myWLl3aLu2uWLGCxYsXn1b+xRdf2D3DtSej0UhgYOBPbufLL7+0m1CT9tfU1KQVdm5A4+QeNE7uQeN0/g4dOuTQeU7nlMrKyiI4OJjw8HBSUlLs6iorK+223H300Ud06dLltDbef/99UlJS+Pzzz3nwwQeJj48HTm4RfPTRR3nzzTfZs2eP3TXHjx9n+vTpvPDCC2ds88f0S5+IiIhc7KZOnUpqaip9+vTh66+/5sSJE3Tt2hWr1cq+ffvo27cvfn5+bdb92Ny5c0lPT7d9NpvNBAYGcu2113b6txe3x8SWnF1VVdVpq+uk89E4uQeNk3vQOJ0/R+dgnJ6UKi0txWg0Ul1djdlstntAcWT7HsDIkSPZvXs3Bw8e5K677qK0tJQxY8Ywc+ZM5s2bR0BAwGmTUosXL+bOO+9kyJAh1NTUnLOPtn7pkwvjQs8ea4bafWns3JfGzn1p7NqPo7/ydZSGhgaOHDnCNddcA8Crr77Kz372MwICArj++utZv349ycnJbNmyhT59+tgepM9W90NGoxGj0dih9yQiIiKXLqcmperr60lNTaWgoIC8vDwyMjLIyck578579OjBhAkT2Lx5M2PGjGHbtm1s27aNzMxMjh49Sn19PSEhIVRWVvLuu++yb98+1qxZw4kTJzCbzfTv358dO3bQo0eP09pu65c+uTAu9OyxZqjdl8bOfWns3JfGrv10tpXWjY2N3H333TQ3N+Ph4UGPHj147bXXMBgMttyfy5cvx8/Pj3Xr1tmuO1udiIiIiKs4NSmVlpZGYmIikZGRDB06lIiICIqKihg/frzDbXz22WcMGjQIDw8PDh06xNatW0lKSgKwWwFVUlLCI488Ylt5VVpaaqurqanBZDKddcWUfukTERGRi02/fv344IMPzlgXEhJi95ZkR+tEREREXMXhSan8/HwqKirIy8sDwMfHh9zcXJKSkti1a5fDHW7cuJGNGzfi6elJS0sLCQkJTJs2zfnIRURERERERETEbTk8KZWQkEBCQoJdWVRUFLW1tQBER0c7lE9q4cKFLFy48Jznna29/v3709DQcM42RERERERERESkc3I60bm7C5q1vtO/PUZERERERERE5GLn4eoARERERERERETk0qNJKRERERERERER6XCX3Pa9vasS8fXydHUYF53g+VtcHYKIiIiIiIiIuBGHV0o1NDTQr18/u9cJr1mzhpiYGKxWKyUlJXh7e2MymWxHYWHhae288sorREREYDKZCA0NZf78+VitVgCam5tJSkoiLCyMsLAwJk6cyMGDBwHO2H5zc/NPvX8REREREREREXEBh1dK+fv7k52dTXJyMuXl5dTV1bF06VK2b9+OwWAAICQk5Jxv4IuNjSU+Ph4PDw+OHTvG6NGjGTFiBJMmTSI7O5sjR46we/duDAYD06dPZ9WqVaxcudLh9kVEREREREREpPNzavteXFwcUVFRZGZmsnPnTpYsWUJQUJBTHfr6+tr+Pnr0KBaLxTapZTAYOHLkCMePH8fDw4PDhw8THh7uVPsiIiIiIiIiItL5OZ3oPCsri02bNuHl5UVKSopdXWVlpd32upaWljO28f777xMeHk5AQABjx44lPj4egJSUFHx9fQkICKBnz540NjYyc+ZM23Vf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BHPkyBEGDRqExWKhsbGRPn36cP/997NixYqz1omIiIiIiIiIiHtxeFIqISGBhIQEu7KoqChqa2sBiI6OdnrF04+vufzyy6mrqzvjuWerExERERERERER9+J0onN3FzRrvV1ydhERERERERER6Xgerg5AREREREREREQuPZqUEhERERERERGRDnfJbd/buyoRXy9PV4fhdoLnb3F1CCIiIiIiIiJyEWmXlVINDQ3069ePsrIyW9maNWuIiYnBarVSUlKCt7c3JpPJdhQWFp6xrXfffZcbbriBoUOHEhoaamuzubmZpKQkwsLCCAsLY+LEiRw8eLA9whcRERERERERkQ7WLiul/P39yc7OJjk5mfLycurq6li6dCnbt2/HYDAAEBIScs6383311VdMnTqVN954gyFDhmCxWGhubgYgOzubI0eOsHv3bgwGA9OnT2fVqlWsXLmyPW5BREREREREREQ6ULtt34uLiyMqKorMzEx27tzJkiVLCAoKcqqNZ599lsmTJzNkyBAAjEYjRqMRAIPBwJEjRzh+/DgeHh4cPnyY8PDw9gpfREREREREREQ6ULsmOs/KymLTpk14eXmRkpJiV1dZWWm3fa+lpeW06/fs2UNzczOxsbGYTCYeeughmpqaAEhJScHX15eAgAB69uxJY2MjM2fObDMWi8WC2Wy2O0REREREREREpHNo10TnpaWlGI1GqqurMZvN+Pn52eoc2b534sQJ3nvvPd5++22uuOIKHnjgARYuXMjTTz9NUVERra2tHDhwAA8PD5KTk1mwYAHLli07Y1srVqxg8eLF7Xl7l7SqqiqX9t/U1OTyGOT8aOzcl8bOfWns2s+hQ4dcHYKIiIjIRavdJqXq6+tJTU2loKCAvLw8MjIyyMnJcaqNvn37YjKZuPLKKwH41a9+xYoVKwB4/vnnmTx5Ml5eXgBMmTKF5cuXt9nW3LlzSU9Pt302m80EBgY6e1vy/wwYMMCl/VdVVbk8Bjk/Gjv3pbFzXxq79qOV1iIiIiIXTrtt30tLSyMxMZHIyEhWrlxJcXExRUVFTrUxefJk3nnnHSwWCwBvvPEGw4YNAyA4OJiioiKsVitWq5WtW7cSFhbWZltGoxE/Pz+7Q0REREREREREOod2WSmVn59PRUUFeXl5APj4+JCbm0tSUhK7du1yuJ2RI0cyceJErrvuOrp06cLQ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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "ranked = np.argsort(gic_xf)[::-1]\n", + "top_n = min(30, len(ranked))\n", + "\n", + "fig, axes = plt.subplots(1, 2, figsize=(12, 5))\n", + "\n", + "# Left: top transformers by |GIC| magnitude\n", + "axes[0].barh(range(top_n), gic_xf[ranked[:top_n]], color='#DD8452')\n", + "axes[0].set_yticks(range(top_n))\n", + "axes[0].set_yticklabels([f'XF {i}' for i in ranked[:top_n]], fontsize=7)\n", + "axes[0].invert_yaxis()\n", + "format_plot(axes[0], title=f'Top {top_n} Transformer |GIC|',\n", + " xlabel='|GIC| (A)', plotarea='white', **_FS)\n", + "\n", + "# Right: histogram of |GIC|\n", + "axes[1].hist(gic_xf, bins=30, color='#4C72B0', edgecolor='white')\n", + "format_plot(axes[1], title='|GIC| Distribution',\n", + " xlabel='|GIC| (A)', ylabel='Count', plotarea='white', **_FS)\n", + "\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 6. Geographic GIC Heatmap\n", + "\n", + "Transformer GICs are aggregated to bus-level totals using ``bus_gic()``\n", + "and interpolated onto the computation grid to produce a continuous\n", + "heatmap of GIC magnitude across the network footprint." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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yWacOBFNenomAC1bPm2pckVExIromXwRERGRQqBhwz7s3HnotvsTErbi6anncEUeVXomX3JoJl9ERESkENix4yt+/nkR3bu/YLa9VClvvv76AwV8EREBNJMvIiIiUigZjUays29SrFhRS5ciIlZAM/mSQzP5IiIiIoWQnZ2dAr6IiOSikC8iIiIiIiJiIxTyRURERERERGyEQr6IiIiIiIiIjVDIFxEREREREbERCvkiIiIiIiIiNkIhX0RERERERMRGKOSLiIiIiIiI2AiFfBEREREREREboZAvIiIiIiIiYiMU8kVERERERERshEK+iIiIiIiIiI1QyBcRERERERGxEQr5IiIiIiIiIjZCIV9ERERERETERijki4iIiIiIiNgIhXwRERERERERG6GQLyIiIiIiImIjFPJFREREREREbIRCvoiIiIiIiIiNUMgXERERERERsREK+SIiIiIiIiI2QiFfRERERERExEYo5IuIiIiIiIjYCIV8ERERERERERuhkC8iIiIiIiJiIxTyRURERERERGyEQr6IiIiIiIiIjVDIFxEREREREbERRS1dwINiNBoBSEm5buFKREREREREHqyc3JOTg+TRZbMh/9q1awD4+7excCUiIiIiIiIPx7Vr13B3d7d0GWJBdkYb/arHYDBw8eJFXF1dsbOzs3Q5hVpKSgr+/v7ExMTg5uZm6XKkkNN4koKisSQFSeNJCpLGkxSk/I4no9HItWvXKF26NPb2eir7UWazM/n29vaUKVPG0mXYFDc3N/1DJQVG40kKisaSFCSNJylIGk9SkPIznjSDL6CF90RERERERERshkK+iIiIiIiIiI1QyJe7cnR05IMPPsDR0dHSpYgN0HiSgqKxJAVJ40kKksaTFCSNJ/m7bHbhPREREREREZFHjWbyRURERERERGyEQr6IiIiIiIiIjVDIFxEREREREbERCvli5vvvv6du3bo4Ojry5ptvmu0zGAwMGTKEChUqULFiRaZNm5br+CtXruDr60vHjh0fTsFite51LH3++ecEBQVRs2ZNnnjiCRYuXPiQKxdrdK/jKT+/t0QuX75Mp06deOKJJ6hWrRpTpkwx7UtPT+fVV18lKCiIoKAg2rdvz9WrVy1XrFi9O40ngO3bt1OvXj1q1KhB9erV2bNnj2UKlULhbuMJbv2eql69OsHBwQ+9PrFORS1dgFiXSpUqMW/ePJYtW0ZqaqrZvoULFxIVFcVvv/1GcnIytWvXpkmTJtSoUcPUpn///rRt25b4+PiHXbpYmXsdSzVq1GDXrl24u7sTExND7dq1adCgARUqVLDQlYg1uNfxlJ/fWyJDhw6levXqrFixguvXrxMSEkJISAj16tVj1qxZpKWlceTIEezs7Ojbty+ffPIJEydOtHTZYqXuNJ4uXrxIz549Wb9+PdWqVSMzM5P09HRLlyxW7E7jKcfw4cMJCQlh3759FqxUrIlm8sVM5cqVqVWrFkWL5v7+Jzw8nL59+1KkSBG8vLzo0qULS5YsMe2fO3cu5cqVo2HDhg+zZLFS9zqWmjVrhru7OwD+/v74+fkRExPzUGsX63Ov4+luv7dEAH755Rdat24NQIkSJWjUqBELFiwAwM7OjrS0NLKyssjOziY1NZUyZcpYslyxcncaT19++SWhoaFUq1YNuPVqNA8PD0uVKoXAncYTQEREBBcuXKBbt26WKlGskEK+5Nu5c+cIDAw0fS5btiznzp0D4MyZM8ycOZNx48ZZqjwpRO40lv4sIiKCxMREs2+rRf7qTuMpv2NNHm1169Zl8eLFGAwGrl69ysaNG4mOjgZu3aHm6uqKj48Pvr6+JCcnM3jwYMsWLFbtTuMpKiqK9PR0mjdvTnBwMEOGDOH69euWLVis2p3GU1JSEsOGDWPGjBmWLVKsjkL+I6ZBgwZ4e3vn+XOvs6VGo5HevXszbdo0ihcvXsAVi7V6EGPpz44cOUKvXr0IDw+nRIkSBVCxWLMHPZ7k0Xa38fXpp5+SmppK7dq1CQ0NpXHjxqa7RjZt2oTBYCA2NpZLly7h4eHB+++/b+ErEku6n/GUnZ3NDz/8wLJly9i3bx+JiYl88MEHFr4isaT7GU+DBw9m1KhR+Pj4WPgqxNromfxHzP0s7hIQEMDZs2dp0KABANHR0QQEBJCSksLhw4fp0qULAKmpqaSlpdGsWTO2bNlSIHWL9XkQYylHVFQUbdu2Zd68eTz77LP3XatYvwc1nu421uTRkJ/xNX/+fNOfBwwYYFq3Yfbs2YSGhuLk5ARAt27dGD9+/AOpUwqH+xlPAQEBBAcH4+npCcArr7zChAkTHkidUjjcz3jauXMnO3fu5J133iEjI4OEhASqVKnCiRMnHlS5UkhoJl/yrXPnzsyZM4ebN2+SkJBAeHg4Xbp0wd3dnfj4eKKjo4mOjmbSpEm0bNlSAV9u63ZjCeDXX3+ldevWzJ49mxYtWli4UikM7jSe7rRPJEd8fDxZWVkA/Pzzz6xatYqBAwcCUL58eTZt2oTRaMRoNPL9998TFBRkyXLFyt1pPIWGhhIZGUlmZiYA69evp1atWharVazfncZTzv+9o6OjWbp0KdWrV1fAF0Az+fIXW7ZsoWfPnqSkpGA0Glm+fDlffvkl7du3p0ePHuzbt49KlSphZ2fH0KFDqVmzpqVLFit1r2PpjTfeIDk5meHDhzN8+HAAPv74Y1q1amXJyxELu9fxpN9bkh8//fQTb7zxBkWLFsXV1ZX//e9/lCpVCoAPP/yQfv36mYJ91apVmTVrliXLFSt3p/H0zDPP0L59e2rXrk2RIkWoUaMGM2fOtHDFYs3uNJ5EbsfOaDQaLV2EiIiIiIiIiNw/3a4vIiIiIiIiYiMU8kVERERERERshEK+iIiIiIiIiI1QyBcRERERERGxEQr5IiIiIiIiIjZCIV9ERERERETERijki4iIiIiIiNgIhXwRERERERERG6GQLyIiIiIiImIjFPJFRETyUKNGDdauXVtg/a1atYqyZcveVx9Lly7l5ZdfLpiC/l/Lli2JiIgo0D5FRETEchTyRUTEqjVu3JgpU6Y89PMeO3aMtm3bAlC2bFlWrVr10Gv4M4PBwKhRo3jvvfdy7du8eTPNmjVj4MCBufY1btwYR0dHXFxcTD/e3t6m/WFhYbz77rsPtHYRERF5eBTyRURECoF169bh5eVFzZo189w3f/58UlJSMBgMufZ//PHHpKammn7i4uJM+xo1akRSUhK7du16oPWLiIjIw6GQLyIihdLly5d5+eWXeeyxxwgICCAsLIzs7GzT/rJlyzJx4kSefvppXF1dee6554iJiTHtP3/+PC1atMDNzY26desyfvx4s9vpc2bvO3fuzLlz53jllVdwcXFhwIABANjZ2XHo0CFT+ylTptC4cWOz/lu2bGnqPyoqyqz+1NRUBg8eTEBAAD4+Prz66qskJyff9nrXrFlD06ZN89w3ePBgRo4cSbNmzbC3/3v/tNvZ2dG0aVPWrFnzt44TERER66SQLyIihVJoaCjFihXjzJkz7Nixg1WrVjFx4kSzNgsXLmTJkiVcvXqVEiVKmN3qHhoaSmBgIJcvX2bJkiXMnTs3z/MsW7aMgIAAlixZQmpqKjNnzsx3faVKlSI2NpZFixYxZ84cs/29e/cmISGBw4cPc+bMGbKyshg8ePBt+zt06BBVq1bNc1+FChVYuHAhvXr1yldtf1W9enWzLyxERESk8FLIFxGRQufChQts3bqVyZMn4+LiQmBgIGFhYcyfP9+s3cCBAylXrhxOTk5069aNAwcOABATE8OOHTv46KOPKF68OJUrVzbN0BeEnP4/+eQTnJ2dqVq1qln/V69e5dtvv2X69Ol4eHhQokQJ/vOf/xAeHs7Nmzfz7DMxMRE3N7d7qmfkyJF4eHiYflq0aGG2383NjcTExHvqW0RERKxLUUsXICIi8nedP38eJycnfH19TdvKly/P+fPnzdr5+fmZ/lyiRAmuXbsGwMWLF3FycjJbgC4gIKDA6svp38fHx7QtMDDQ9Ofo6GgMBgPlypUzO87e3p7Y2Fgef/zxXH16enqSkpJyT/VMmDCBN99887b7U1JS8PT0vKe+RURExLoo5IuISKFTpkwZMjIyuHz5sinoR0dHU6ZMmXwdX7p0aTIyMoiLizMF/XPnzt22fV7PuZcoUYK0tDTT50uXLuXq/8qVK6ag/+f+/f39sbe35+LFizg7O+er5uDgYI4fP56vtn9XVFQUwcHBD6RvERERebh0u76IiFi97OxsMjIyTD/e3t40adKEd955h+vXr3Pu3DnGjRtHz54989Wfv78/ISEhjBo1ivT0dH7//Xdmz5592/a+vr6cOnXKbFudOnVYsGAB2dnZHDp0iAULFuTqf8SIEaSnp3PixAlmzZpl2u/n50fHjh0ZPHiwaaX72NhYVq5cedsa2rVrR2RkZL6u7++KjIw0vS5QRERECjeFfBERsXrvvvsuxYsXN/1UqVKFxYsXk56eTmBgICEhIbRp04Zhw4blu8/Fixdz+vRpfH196dq1K927d8fR0THPtqNGjWLatGl4eHiY3kX/xRdfsGfPHjw8PBg+fHiuLxgWL15MTEwMPj4+hIaG0rt3b7P98+fPx8PDg3r16uHm5kbDhg1NawbkpXXr1sTFxXH06NF8X2OO4cOH4+LiYvYTHx8PwI4dO0znFxERkcLPzmg0Gi1dhIiIiKVNmDCBrVu3snnzZkuXcltLlixh1apVhIeHF1ifrVq14p133sm1GJ+IiIgUTgr5IiLySDp48CDOzs5UqVKFgwcP0q5dOz788EP69etn6dJERERE7pkW3hMRkUfS1atXGTBgAJcvX8bHx4e+ffvy2muvWbosERERkfuimXwRERERERERG6GF90RERERERERshEK+iIiIiIiIiI1QyBcRERERERGxEQr5IiIiIiIiIjZCIV9ERERERETERijki4iIiIiIiNgIhXwRERERERERG6GQLyIiIiIiImIjFPJFREREREREbIRCvoiIiIiIiIiN+D/i0ZPa6kSHBwAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots(figsize=(14, 9))\n", + "\n", + "im = plot_gic_heatmap(ax, lons, lats, gic_bus,\n", + " shape=SHAPE, lines=lines,\n", + " cmap='YlOrRd',\n", + " title='Bus-Level |GIC| Heatmap (Gaussian Hotspot)')\n", + "\n", + "fig.colorbar(im, ax=ax, label='|GIC| (A)', shrink=0.7, pad=0.02)\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 7. Export to B3D Format\n", + "\n", + "The non-uniform E-field can be exported to PowerWorld's B3D format\n", + "for time-varying GIC simulation. `B3D.from_mesh()` converts a gridded\n", + "field to the binary format." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "B3D grid: [50, 35]\n", + "Locations: 1750\n", + "Time steps: 1\n" + ] + } + ], + "source": [ + "b3d = B3D.from_mesh(\n", + " lons, lats,\n", + " Ex_field.astype(np.float32),\n", + " Ey_field.astype(np.float32),\n", + " comment='Gaussian hotspot E-field'\n", + ")\n", + "\n", + "print(f\"B3D grid: {b3d.grid_dim}\")\n", + "print(f\"Locations: {len(b3d.lat)}\")\n", + "print(f\"Time steps: {len(b3d.time)}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Summary\n", + "\n", + "This notebook demonstrated the full non-uniform GIC analysis workflow:\n", + "\n", + "- **GIC model** construction via `pw.gic.model()` produces the H-matrix\n", + " that linearly maps branch voltages to transformer neutral currents\n", + "- The **line integration operator** $L$ traces each transmission line\n", + " through the E-field grid cell by cell, accumulating directed segment\n", + " lengths to discretize the line integral $V_k = \\int \\mathbf{E} \\cdot d\\boldsymbol{\\ell}$\n", + "- Stacking the gridded field as $\\mathbf{E} = [E_x, E_y]^T$ enables\n", + " the clean matrix formulation $|\\mathbf{I}| = |H \\, L \\, \\mathbf{E}|$\n", + "- ``bus_gic()`` aggregates transformer-level GICs to bus-level totals\n", + " for geographic plotting at known bus coordinates\n", + "- ``plot_gic_heatmap()`` interpolates sparse bus GICs onto the\n", + " computation grid for a continuous geographic heatmap\n", + "- Export to **B3D format** enables PowerWorld integration for\n", + " time-varying non-uniform GIC simulations" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "esapp", + "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.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/nonuniform/__init__.py b/examples/nonuniform/__init__.py new file mode 100644 index 00000000..384f1496 --- /dev/null +++ b/examples/nonuniform/__init__.py @@ -0,0 +1,6 @@ +""" +Non-uniform electric field GIC analysis examples. + +Uses the esapp GIC model with geographic plotting and mesh tools +to compute and visualize GICs under spatially varying E-fields. +""" diff --git a/examples/nonuniform/nonuniform.py b/examples/nonuniform/nonuniform.py new file mode 100644 index 00000000..5fe24c51 --- /dev/null +++ b/examples/nonuniform/nonuniform.py @@ -0,0 +1,304 @@ +""" +Non-uniform GIC model formulation helpers. + +Provides the line integration operator **L** and E-field vector +assembly for the non-uniform GIC computation: + + I_gic = abs(H @ L @ E) + +where: +- **H** is the transformer-to-branch transfer matrix from ``pw.gic.model()`` +- **L** maps a gridded E-field vector to branch induced voltages +- **E** = [Ex.ravel(), Ey.ravel()] is the stacked master E-field vector + +The operator L discretizes the line integral of E along each branch by +tracing every transmission line through the 2-D grid and accumulating +the directed segment length (dx, dy) within each cell. The E-field +inside a cell is taken as the average of its four corner nodes. + +Example +------- +>>> from examples.nonuniform.nonuniform import build_L_matrix, stack_efield +>>> +>>> L = build_L_matrix(pw, lons, lats, H.shape[1]) +>>> E = stack_efield(Ex, Ey) +>>> gic = np.abs(H @ L @ E) +""" + +import numpy as np +from scipy.sparse import coo_matrix + +from esapp.components import Branch, Bus, GICXFormer + +__all__ = ['build_L_matrix', 'stack_efield', 'compute_gic', 'bus_gic'] + + +def stack_efield(Ex, Ey): + """Stack 2-D Ex and Ey grids into a single master E-field vector. + + Parameters + ---------- + Ex : np.ndarray + East-component of the electric field on a (ny, nx) grid. + Ey : np.ndarray + North-component of the electric field on a (ny, nx) grid. + + Returns + ------- + np.ndarray + 1-D vector of length 2*N where N = nx*ny, ordered as + [Ex.ravel(), Ey.ravel()]. + """ + return np.concatenate([Ex.ravel(), Ey.ravel()]) + + +def _trace_line_through_grid(x0, y0, x1, y1, xs, ys): + """Trace a straight line segment through a regular grid. + + Finds every cell the segment passes through and returns the + directed (dx, dy) length within each cell in **grid-coordinate + units** (i.e. fractional cell widths). + + Parameters + ---------- + x0, y0 : float + Start point in continuous grid coordinates + (x = (lon - lon0) / dlon, y = (lat - lat0) / dlat). + x1, y1 : float + End point in continuous grid coordinates. + xs : int + Number of grid nodes in the x-direction (nx). + ys : int + Number of grid nodes in the y-direction (ny). + + Yields + ------ + (ix, iy, frac_dx, frac_dy) : tuple + Cell indices (ix, iy) and the directed length of the line + segment within that cell, in fractional grid units. + """ + # Clamp endpoints into valid grid range [0, size-1] + x0c = np.clip(x0, 0, xs - 1) + y0c = np.clip(y0, 0, ys - 1) + x1c = np.clip(x1, 0, xs - 1) + y1c = np.clip(y1, 0, ys - 1) + + dx_total = x1c - x0c + dy_total = y1c - y0c + + if abs(dx_total) < 1e-12 and abs(dy_total) < 1e-12: + # Zero-length segment (co-located buses) + return + + # Collect all t-values where the line crosses vertical or horizontal + # grid lines. t parameterizes the clamped segment: r(t) = r0 + t*(r1-r0). + crossings = [0.0, 1.0] + + if abs(dx_total) > 1e-12: + # Vertical grid lines at x = 1, 2, ..., xs-2 + ix_lo = int(np.floor(min(x0c, x1c))) + ix_hi = int(np.ceil(max(x0c, x1c))) + for ix in range(max(ix_lo, 1), min(ix_hi, xs - 1) + 1): + t = (ix - x0c) / dx_total + if 0 < t < 1: + crossings.append(t) + + if abs(dy_total) > 1e-12: + # Horizontal grid lines at y = 1, 2, ..., ys-2 + iy_lo = int(np.floor(min(y0c, y1c))) + iy_hi = int(np.ceil(max(y0c, y1c))) + for iy in range(max(iy_lo, 1), min(iy_hi, ys - 1) + 1): + t = (iy - y0c) / dy_total + if 0 < t < 1: + crossings.append(t) + + crossings.sort() + + # Walk through consecutive pairs of crossings + for i in range(len(crossings) - 1): + t_a = crossings[i] + t_b = crossings[i + 1] + if t_b - t_a < 1e-14: + continue + + # Midpoint of this sub-segment -> determines which cell we're in + t_mid = 0.5 * (t_a + t_b) + mx = x0c + t_mid * dx_total + my = y0c + t_mid * dy_total + + ix = int(np.clip(np.floor(mx), 0, xs - 2)) + iy = int(np.clip(np.floor(my), 0, ys - 2)) + + # Directed length of this sub-segment in grid units + frac_dx = (t_b - t_a) * dx_total + frac_dy = (t_b - t_a) * dy_total + + yield ix, iy, frac_dx, frac_dy + + +def build_L_matrix(pw, lons, lats, n_branches_model): + """Build the line integration operator L. + + L is a sparse matrix of shape ``(n_branches_model, 2*N)`` where + ``N = len(lons) * len(lats)``. Given the master E-field vector + ``E = stack_efield(Ex, Ey)``, the product ``L @ E`` yields the + induced voltage on each branch. + + **Discretization.** Each transmission line is traced through the + 2-D grid cell by cell. For every cell the line passes through, the + directed segment length ``(dx_km, dy_km)`` within that cell is + computed. The E-field inside the cell is approximated as the + average of its four corner nodes. The voltage contribution from + cell ``(ix, iy)`` for branch ``k`` is therefore: + + dV = E_x_avg * dx_km + E_y_avg * dy_km + + which translates to weight ``(1/4) * dx_km`` at each of the four + corner nodes in the ``E_x`` block of L, and ``(1/4) * dy_km`` in + the ``E_y`` block. + + Parameters + ---------- + pw : PowerWorld + Live workbench instance (used to read branch coordinates). + lons : np.ndarray + 1-D array of grid longitudes (length nx). + lats : np.ndarray + 1-D array of grid latitudes (length ny). + n_branches_model : int + Total number of branch columns in the H-matrix + (``H.shape[1]``). Rows beyond the number of geographic + branches are left as zeros (transformer windings, GSUs). + + Returns + ------- + scipy.sparse.csr_matrix + Sparse matrix of shape ``(n_branches_model, 2*N)``. + """ + nx = len(lons) + ny = len(lats) + N = nx * ny + + dlon = lons[1] - lons[0] + dlat = lats[1] - lats[0] + + # Branch endpoint coordinates + br = pw[Branch, ['BusNum', 'BusNum:1', 'BranchDeviceType', + 'Longitude', 'Longitude:1', 'Latitude', 'Latitude:1']] + + lon_a = br['Longitude'].to_numpy() + lon_b = br['Longitude:1'].to_numpy() + lat_a = br['Latitude'].to_numpy() + lat_b = br['Latitude:1'].to_numpy() + + n_br = min(len(br), n_branches_model) + + rows, cols, data = [], [], [] + + for k in range(n_br): + # Continuous grid coordinates for endpoints + gx0 = (lon_a[k] - lons[0]) / dlon + gy0 = (lat_a[k] - lats[0]) / dlat + gx1 = (lon_b[k] - lons[0]) / dlon + gy1 = (lat_b[k] - lats[0]) / dlat + + # Midpoint latitude for the cos correction + mid_lat = 0.5 * (lat_a[k] + lat_b[k]) + cos_lat = np.cos(np.radians(mid_lat)) + + # Conversion: 1 grid-unit in x = dlon degrees = dlon * 111 * cos(lat) km + # 1 grid-unit in y = dlat degrees = dlat * 111 km + km_per_gx = dlon * 111.0 * cos_lat + km_per_gy = dlat * 111.0 + + for ix, iy, fdx, fdy in _trace_line_through_grid(gx0, gy0, gx1, gy1, nx, ny): + dx_km = fdx * km_per_gx + dy_km = fdy * km_per_gy + + # Four corner nodes of cell (ix, iy), each gets weight 1/4 + corners = [ + iy * nx + ix, + iy * nx + (ix + 1), + (iy + 1) * nx + ix, + (iy + 1) * nx + (ix + 1), + ] + w = 0.25 + for idx in corners: + # Ex block: columns [0, N) + rows.append(k) + cols.append(idx) + data.append(w * dx_km) + # Ey block: columns [N, 2N) + rows.append(k) + cols.append(N + idx) + data.append(w * dy_km) + + L = coo_matrix((data, (rows, cols)), shape=(n_branches_model, 2 * N)) + # COO allows duplicate entries; converting to CSR sums them automatically + return L.tocsr() + + +def bus_gic(pw, gic): + """Aggregate absolute transformer GICs to bus-level totals. + + Each transformer in the H-matrix corresponds to a row in the + GICXFormer table. This function sums |GIC| contributions at each + bus (using ``BusNum3W`` as the transformer's primary bus) and + returns a DataFrame with bus coordinates for geographic plotting. + + Parameters + ---------- + pw : PowerWorld + Live workbench instance. + gic : np.ndarray + Absolute transformer GIC magnitudes (length n_transformers). + + Returns + ------- + pandas.DataFrame + Columns: ``BusNum``, ``Longitude``, ``Latitude``, ``GIC``. + One row per bus that hosts at least one transformer, with + ``GIC`` being the sum of |GIC| over all transformers at that bus. + """ + import pandas as pd + + gic = np.asarray(gic).ravel() + + xf = pw[GICXFormer, ['BusNum3W', 'BusNum3W:1']] + xf = xf.iloc[:len(gic)].copy() + xf['GIC'] = gic + + # Aggregate by primary bus (BusNum3W) + bus_total = xf.groupby('BusNum3W')['GIC'].sum().reset_index() + bus_total.columns = ['BusNum', 'GIC'] + + # Join with bus coordinates + coords = pw[Bus, ['BusNum', 'Longitude', 'Latitude']] + result = bus_total.merge(coords, on='BusNum', how='inner') + return result + + +def compute_gic(H, L, Ex, Ey): + """Compute absolute transformer GICs from a gridded E-field. + + Evaluates ``|H @ L @ E|`` where E is the stacked field vector. + + Parameters + ---------- + H : sparse matrix or np.ndarray + Transfer matrix (n_transformers x n_branches). + L : sparse matrix + Line integration operator (n_branches x 2N). + Ex, Ey : np.ndarray + Electric field components on the (ny, nx) node grid. + + Returns + ------- + np.ndarray + Absolute transformer GIC magnitudes (n_transformers,). + """ + E = stack_efield(Ex, Ey) + gic = H @ L @ E + if hasattr(gic, 'A'): + gic = np.asarray(gic).ravel() + return np.abs(gic) diff --git a/examples/nonuniform/plotting.py b/examples/nonuniform/plotting.py new file mode 100644 index 00000000..d56005bc --- /dev/null +++ b/examples/nonuniform/plotting.py @@ -0,0 +1,247 @@ +""" +Plotting helpers for non-uniform GIC analysis. + +Provides standardized functions for visualizing gridded electric fields +and transformer GIC results on geographic maps. +""" + +import numpy as np +import matplotlib.pyplot as plt +from matplotlib.colors import Normalize +from scipy.interpolate import NearestNDInterpolator +from scipy.ndimage import gaussian_filter + +from examples.map import format_plot, border, plot_lines + +__all__ = [ + 'plot_efield', + 'plot_gic_map', + 'plot_gic_heatmap', +] + + +def plot_efield(ax, lons, lats, Ex, Ey, shape=None, lines=None, + cmap='viridis', vmax=None, title=None, **fmt_kw): + """Plot a gridded electric field with one arrow per cell. + + Renders the field magnitude as a filled heatmap and overlays a + quiver arrow at every cell center. Arrow length is proportional + to field magnitude so both direction and strength are visible. + + Parameters + ---------- + ax : matplotlib.axes.Axes + Target axes. + lons, lats : np.ndarray + 1-D grid node coordinates (length nx, ny). + Ex, Ey : np.ndarray + Electric field components on the (ny, nx) node grid. + shape : str or None + Border shape name passed to ``border()``. + lines : DataFrame or None + Branch coordinate DataFrame for ``plot_lines()``. + cmap : str + Colormap for the magnitude heatmap and arrows. + vmax : float or None + Upper limit for the color scale. If None, uses data max. + title : str or None + Axes title. + **fmt_kw + Extra keyword arguments forwarded to ``format_plot()``. + + Returns + ------- + im : QuadMesh + The pcolormesh artist (for external colorbar creation). + """ + LON, LAT = np.meshgrid(lons, lats) + mag = np.sqrt(Ex**2 + Ey**2) + if vmax is None: + vmax = float(np.nanmax(mag)) + + # Magnitude heatmap at nodes + im = ax.pcolormesh(LON, LAT, mag, cmap=cmap, shading='auto', + vmin=0, vmax=vmax) + + # Cell-center coordinates and cell-average field + lon_c = 0.5 * (lons[:-1] + lons[1:]) + lat_c = 0.5 * (lats[:-1] + lats[1:]) + LONc, LATc = np.meshgrid(lon_c, lat_c) + + Ex_c = 0.25 * (Ex[:-1, :-1] + Ex[:-1, 1:] + Ex[1:, :-1] + Ex[1:, 1:]) + Ey_c = 0.25 * (Ey[:-1, :-1] + Ey[:-1, 1:] + Ey[1:, :-1] + Ey[1:, 1:]) + mag_c = np.sqrt(Ex_c**2 + Ey_c**2) + + # Quiver: arrows proportional to magnitude, colored by magnitude + ax.quiver(LONc, LATc, Ex_c, Ey_c, mag_c, + cmap=cmap, clim=(0, vmax), + scale_units='xy', angles='xy', + scale=vmax / (0.8 * (lons[1] - lons[0])), + width=0.003, headwidth=3, headlength=3.5, + linewidth=0.3, edgecolors='k', zorder=5) + + if shape is not None: + border(ax, shape) + if lines is not None: + plot_lines(ax, lines, ms=1.5, lw=0.3) + + ax.set_xlim(lons[0], lons[-1]) + ax.set_ylim(lats[0], lats[-1]) + ax.set_aspect('equal') + + defaults = dict(plotarea='white', grid=False, + titlesize=11, labelsize=9, ticksize=8) + defaults.update(fmt_kw) + if title is not None: + defaults['title'] = title + format_plot(ax, xlabel=r'Longitude ($^\circ$E)', + ylabel=r'Latitude ($^\circ$N)', **defaults) + return im + + +def plot_gic_map(ax, lons, lats, Ex, Ey, xf_lons, xf_lats, gic, + shape=None, lines=None, cmap_field='viridis', + cmap_gic='YlOrRd', vmax_field=None, title=None, + **fmt_kw): + """Plot transformer |GIC| bubbles over an E-field background. + + GIC magnitudes are shown via both bubble size and colour on a + sequential (all-positive) colour scale. + + Parameters + ---------- + ax : matplotlib.axes.Axes + Target axes. + lons, lats : np.ndarray + 1-D grid node coordinates. + Ex, Ey : np.ndarray + Electric field on the (ny, nx) node grid. + xf_lons, xf_lats : array-like + Transformer geographic coordinates. + gic : np.ndarray + Absolute transformer GIC magnitudes (non-negative). + shape : str or None + Border shape name. + lines : DataFrame or None + Branch coordinate DataFrame. + cmap_field : str + Colormap for the E-field magnitude background. + cmap_gic : str + Sequential colormap for GIC bubbles. + vmax_field : float or None + Upper colour limit for E-field magnitude. + title : str or None + Axes title. + **fmt_kw + Extra keyword arguments forwarded to ``format_plot()``. + + Returns + ------- + (im, sc) : tuple + The pcolormesh and scatter artists (for external colorbars). + """ + LON, LAT = np.meshgrid(lons, lats) + mag = np.sqrt(Ex**2 + Ey**2) + if vmax_field is None: + vmax_field = float(np.nanmax(mag)) + + # E-field magnitude background (faded) + im = ax.pcolormesh(LON, LAT, mag, cmap=cmap_field, shading='auto', + vmin=0, vmax=vmax_field, alpha=0.4) + + if shape is not None: + border(ax, shape) + if lines is not None: + plot_lines(ax, lines, ms=2, lw=0.3) + + # GIC bubbles: size AND colour encode |GIC| + gic = np.asarray(gic).ravel() + gic_max = max(float(gic.max()), 1e-6) + sizes = 10 + 250 * (gic / gic_max) + sc = ax.scatter(xf_lons, xf_lats, + s=sizes, c=gic, cmap=cmap_gic, + vmin=0, vmax=gic_max, + zorder=8, edgecolors='black', linewidth=0.4) + + ax.set_xlim(lons[0], lons[-1]) + ax.set_ylim(lats[0], lats[-1]) + ax.set_aspect('equal') + + defaults = dict(plotarea='white', grid=False, + titlesize=11, labelsize=9, ticksize=8) + defaults.update(fmt_kw) + if title is not None: + defaults['title'] = title + format_plot(ax, xlabel=r'Longitude ($^\circ$E)', + ylabel=r'Latitude ($^\circ$N)', **defaults) + return im, sc + + +def plot_gic_heatmap(ax, lons, lats, bus_df, shape=None, lines=None, + cmap='YlOrRd', title=None, **fmt_kw): + """Plot bus-level |GIC| as a heatmap interpolated onto the grid. + + Interpolates sparse bus GIC values onto the regular (lons, lats) + grid using radial basis function interpolation, producing a + continuous heatmap of GIC magnitude across the geographic domain. + + Parameters + ---------- + ax : matplotlib.axes.Axes + Target axes. + lons, lats : np.ndarray + 1-D grid node coordinates (length nx, ny). + bus_df : pandas.DataFrame + Output of ``bus_gic()`` with columns + ``Longitude``, ``Latitude``, ``GIC``. + shape : str or None + Border shape name passed to ``border()``. + lines : DataFrame or None + Branch coordinate DataFrame for ``plot_lines()``. + cmap : str + Colormap for the GIC heatmap. + title : str or None + Axes title. + **fmt_kw + Extra keyword arguments forwarded to ``format_plot()``. + + Returns + ------- + im : QuadMesh + The pcolormesh artist (for external colorbar creation). + """ + LON, LAT = np.meshgrid(lons, lats) + + points = np.column_stack([bus_df['Longitude'].to_numpy(), + bus_df['Latitude'].to_numpy()]) + values = bus_df['GIC'].to_numpy() + gic_max = max(float(values.max()), 1e-6) + + interp = NearestNDInterpolator(points, values) + gic_grid = interp(LON, LAT) + gic_grid = gaussian_filter(gic_grid, sigma=2) + + im = ax.pcolormesh(LON, LAT, gic_grid, cmap=cmap, shading='auto', + vmin=0, vmax=gic_max) + + if shape is not None: + border(ax, shape) + if lines is not None: + plot_lines(ax, lines, ms=2, lw=0.3) + + # Overlay bus locations as small markers + ax.scatter(bus_df['Longitude'], bus_df['Latitude'], + s=8, c='black', zorder=6, alpha=0.4) + + ax.set_xlim(lons[0], lons[-1]) + ax.set_ylim(lats[0], lats[-1]) + ax.set_aspect('equal') + + defaults = dict(plotarea='white', grid=False, + titlesize=11, labelsize=9, ticksize=8) + defaults.update(fmt_kw) + if title is not None: + defaults['title'] = title + format_plot(ax, xlabel=r'Longitude ($^\circ$E)', + ylabel=r'Latitude ($^\circ$N)', **defaults) + return im diff --git a/examples/nonuniform/sens.py b/examples/nonuniform/sens.py new file mode 100644 index 00000000..5e8eeae4 --- /dev/null +++ b/examples/nonuniform/sens.py @@ -0,0 +1,143 @@ +""" +GIC sensitivity analysis for non-uniform electric fields. + +Provides standalone functions for computing: +- Interface flow sensitivity to transformer GIC currents (dBound/dI) +- E-field to GIC Jacobian (dI/dE) + +These functions operate on matrices produced by ``PowerWorld.gic.model()`` +and require a live ``PowerWorld`` instance for bus category data. + +Example +------- +>>> from esapp import PowerWorld +>>> from examples.nonuniform.sens import jac_decomp +>>> from examples.nonuniform.sens import dBounddI, dIdE +>>> +>>> pw = PowerWorld("case.pwb") +>>> pw.gic.model() +>>> H = pw.gic.H +>>> J = pw.jacobian(dense=True) +>>> V = pw.voltage(complex=False)[0].to_numpy() +>>> eta = ... # injection vector +>>> PX = pw.gic.Px +>>> sens = dBounddI(pw, eta, PX, J, V) +""" + +import numpy as np +from scipy.sparse import hstack +from scipy.sparse.linalg import inv as sinv + +from esapp.components import Bus + +__all__ = ['jac_decomp', 'dBounddI', 'dIdE', 'signdiag'] + + +def jac_decomp(jac): + """ + Decompose a power flow Jacobian into sub-matrices. + + Parameters + ---------- + jac : np.ndarray + Full Jacobian matrix of shape (2n, 2n). + + Yields + ------ + np.ndarray + Sub-matrices in order: dP/dTheta, dP/dV, dQ/dTheta, dQ/dV. + """ + dim = jac.shape[0] + nbus = int(dim / 2) + + yield jac[:nbus, :nbus] # dP/dTheta + yield jac[:nbus, nbus:] # dP/dV + yield jac[nbus:, :nbus] # dQ/dTheta + yield jac[nbus:, nbus:] # dQ/dV + + +def signdiag(x): + """ + Create diagonal matrix of signs. + + Parameters + ---------- + x : np.ndarray + Input vector. + + Returns + ------- + np.ndarray + Diagonal matrix with sign(x) on diagonal. + """ + return np.diagflat(np.sign(x)) + + +def dBounddI(pw, eta, PX, J, V): + """ + Compute interface sensitivity with respect to transformer GIC currents. + + Parameters + ---------- + pw : PowerWorld + Live PowerWorld instance (used to retrieve bus categories). + eta : np.ndarray + Injection vector (n x 1). + PX : np.ndarray or sparse matrix + Transformer to loaded-bus mapping (n x m). + J : np.ndarray + Full AC power flow Jacobian at boundary. + V : np.ndarray + Bus voltage magnitudes (n x 1). + + Returns + ------- + np.ndarray + Sensitivity vector (1 x n). + """ + buscat = pw[Bus, ['BusCat']]['BusCat'] + slk = buscat == 'Slack' + pv = buscat == 'PV' + pq = ~(slk | pv) + + dPdT, dPdV, dQdT, dQdV = jac_decomp(J) + + A = hstack([dPdT[:, ~slk], dPdV[:, pq]]) + B = hstack([dQdT[pq][:, ~slk], dQdV[pq][:, pq]]) + + Vdiag = np.diagflat(V[pq]) + + return (1 / (eta.T @ eta)) @ eta.T @ A @ B.T @ sinv((B @ B.T).tocsc()) @ Vdiag @ PX[pq] + + +def dIdE(H, E=None, i=None): + """ + Compute Jacobian between mesh E-field and absolute transformer GICs. + + Parameters + ---------- + H : np.ndarray or sparse matrix + H-matrix (e.g., from ``pw.gic.H`` after calling ``model()``). + E : np.ndarray, optional + Electric field vector. If provided and i is None, computes i = H @ E. + i : np.ndarray, optional + Signed neutral transformer currents. Required if E is not provided. + + Returns + ------- + np.ndarray + Jacobian matrix (rows: transformers, cols: E-field components). + + Raises + ------ + ValueError + If neither E nor i is provided. + """ + if E is not None: + if i is None: + i = H @ E + elif i is None: + raise ValueError("Either E or i must be provided") + + F = signdiag(i) + return F @ H diff --git a/examples/plot_helpers.py b/examples/plot_helpers.py new file mode 100644 index 00000000..932b6904 --- /dev/null +++ b/examples/plot_helpers.py @@ -0,0 +1,1704 @@ +""" +Shared plotting helpers for ESAplus example notebooks. + +These functions encapsulate common visualization patterns so that +notebook cells remain focused on core esapp operations. Import from +a hidden cell near the top of each notebook:: + + import sys; sys.path.insert(0, '..') + from plot_helpers import plot_barh_top, plot_direction_sensitivity, ... + +Figure sizes are optimized for PDF documentation rendering via nbsphinx +with a LaTeX text width of 6.5 inches. All figures fit within page width +without scaling, so font sizes render at their true point size. +""" + +import numpy as np +import matplotlib.pyplot as plt +from matplotlib.collections import LineCollection +from matplotlib.colors import Normalize +from matplotlib.cm import ScalarMappable + +# Import plotting utilities from examples.map +try: + from examples.map import format_plot, border, plot_lines, plot_vecfield, darker_hsv_colormap +except ImportError: + pass + +# --------------------------------------------------------------------------- +# Standard figure dimensions (inches) for 6.5" LaTeX text width +# --------------------------------------------------------------------------- +_W1 = 4.5 # single panel width +_H1 = 3.2 # single panel height +_W2 = 6.5 # two-panel row width +_H2 = 2.8 # two-panel row height +_W3 = 6.5 # three-panel row width +_H3 = 2.5 # three-panel row height +_WFULL = 6.5 # full page width + +# Font sizes for multi-panel (3+) plots to avoid title crowding +_FS3 = dict(titlesize=10, labelsize=9, ticksize=8) +_FS2 = dict(titlesize=11, labelsize=9, ticksize=8) + +# --------------------------------------------------------------------------- +# Professional color palette +# --------------------------------------------------------------------------- +_C1 = '#4C72B0' # primary blue +_C2 = '#DD8452' # secondary orange +_C3 = '#55A868' # tertiary green +_C4 = '#C44E52' # accent red +_C5 = '#8172B3' # purple +_C6 = '#CCB974' # yellow +_C7 = '#64B5CD' # cyan +_CG = '#8C8C8C' # gray +_LIMIT = '#C44E52' # limit/warning lines + + +# --------------------------------------------------------------------------- +# Generic chart helpers +# --------------------------------------------------------------------------- + +def plot_barh_top(values, labels=None, n=20, title='', xlabel='', ylabel='', + color=None, figsize=(_WFULL, 3.5), ax=None): + """Horizontal bar chart of the top-*n* items sorted descending.""" + if color is None: + color = _C1 + top = values[:n] if len(values) <= n else values.sort_values(ascending=False).head(n) + if labels is None: + labels = [f'{i+1}' for i in range(len(top))] + show = ax is None + if ax is None: + fig, ax = plt.subplots(figsize=figsize) + ax.barh(range(len(top)), top.values if hasattr(top, 'values') else top, + color=color) + ax.set_yticks(range(len(top))) + ax.set_yticklabels(labels[:len(top)]) + ax.invert_yaxis() + format_plot(ax, title=title, xlabel=xlabel, ylabel=ylabel, plotarea='white') + if show: + plt.tight_layout() + plt.show() + return ax + + +def plot_dual_bar(values_a, values_b, label_a='A', label_b='B', + xlabel='Index', ylabel='Value', title='', + figsize=(_W2, _H2), ax=None): + """Grouped bar chart comparing two datasets side-by-side.""" + show = ax is None + if ax is None: + fig, ax = plt.subplots(figsize=figsize) + x = range(len(values_a)) + width = 0.35 + ax.bar([i - width / 2 for i in x], values_a, width, + label=label_a, color=_C1, alpha=0.85) + ax.bar([i + width / 2 for i in x], values_b, width, + label=label_b, color=_C2, alpha=0.85) + format_plot(ax, title=title, xlabel=xlabel, ylabel=ylabel, plotarea='white') + ax.legend(fontsize=8) + if show: + plt.tight_layout() + plt.show() + return ax + + +def plot_hist(values, bins=20, title='', xlabel='', ylabel='Count', + color=None, ax=None): + """Simple histogram with white edge on bars.""" + if color is None: + color = _C1 + show = ax is None + if ax is None: + fig, ax = plt.subplots(figsize=(_W1, _H1)) + ax.hist(values, bins=bins, color=color, edgecolor='white') + format_plot(ax, title=title, xlabel=xlabel, ylabel=ylabel, plotarea='white') + if show: + plt.tight_layout() + plt.show() + return ax + + +# --------------------------------------------------------------------------- +# PTDF / LODF / sensitivity +# --------------------------------------------------------------------------- + +def plot_ptdf(ptdf_df, n=20, figsize=(_W2, _H2)): + """PTDF bar chart (top-N by magnitude) + histogram (2-panel).""" + vals = ptdf_df['LinePTDF'] + fig, axes = plt.subplots(1, 2, figsize=figsize) + + top = vals.abs().sort_values(ascending=False).head(n) + colors = [_C4 if vals.loc[i] < 0 else _C1 for i in top.index] + labels = [f"{int(ptdf_df.loc[i, 'BusNum'])}-{int(ptdf_df.loc[i, 'BusNum:1'])}" + for i in top.index] + axes[0].barh(range(len(top)), vals.loc[top.index].values, color=colors) + axes[0].set_yticks(range(len(top))) + axes[0].set_yticklabels(labels, fontsize=7) + axes[0].invert_yaxis() + axes[0].axvline(x=0, color=_CG, linewidth=0.5) + format_plot(axes[0], title=f'Top {n} PTDFs', + xlabel='PTDF', plotarea='white', **_FS2) + + axes[1].hist(vals.values, bins=30, color=_C1, edgecolor='white') + axes[1].axvline(x=0, color=_CG, linewidth=0.5) + format_plot(axes[1], title='PTDF Distribution', + xlabel='PTDF', ylabel='Count', + plotarea='white', **_FS2) + + plt.tight_layout() + plt.show() + + +def plot_lodf(lodf_df, n=20, figsize=(_W2, _H2)): + """LODF bar chart (top-N by magnitude) + histogram (2-panel).""" + vals = lodf_df['LineLODF'] + fig, axes = plt.subplots(1, 2, figsize=figsize) + + top = vals.abs().sort_values(ascending=False).head(n) + colors = [_C4 if vals.loc[i] < 0 else _C1 for i in top.index] + labels = [f"{int(lodf_df.loc[i, 'BusNum'])}-{int(lodf_df.loc[i, 'BusNum:1'])}" + for i in top.index] + axes[0].barh(range(len(top)), vals.loc[top.index].values, color=colors) + axes[0].set_yticks(range(len(top))) + axes[0].set_yticklabels(labels, fontsize=7) + axes[0].invert_yaxis() + axes[0].axvline(x=0, color=_CG, linewidth=0.5) + format_plot(axes[0], title=f'Top {n} LODFs', + xlabel='LODF', plotarea='white', **_FS2) + + axes[1].hist(vals.dropna().values, bins=30, color=_C1, edgecolor='white') + axes[1].axvline(x=0, color=_CG, linewidth=0.5) + format_plot(axes[1], title='LODF Distribution', + xlabel='LODF', ylabel='Count', + plotarea='white', **_FS2) + + plt.tight_layout() + plt.show() + + +def plot_sensitivity_map(lines, values, shape=None, title='Sensitivity Map', + clabel='Factor', cmap='RdBu_r', symmetric=True, + figsize=(_W2, 2.8), ax=None, fig=None): + """Geographic network map with lines colored by sensitivity values. + + Parameters + ---------- + lines : DataFrame + Branch data with 'Longitude', 'Longitude:1', 'Latitude', 'Latitude:1'. + values : array-like + One value per branch (PTDF, LODF, etc.). Length must match ``lines``. + shape : str, optional + Shape name for geographic border overlay (e.g. 'Texas', 'US'). + title : str + Plot title. + clabel : str + Colorbar label. + cmap : str + Matplotlib colormap name. + symmetric : bool + If True, center the colormap at zero. + """ + show = ax is None + if ax is None: + fig, ax = plt.subplots(figsize=figsize) + + vals = np.asarray(values, dtype=float) + valid = np.isfinite(vals) + vmax = np.abs(vals[valid]).max() if valid.any() else 1.0 + norm = Normalize(vmin=-vmax if symmetric else vals[valid].min(), + vmax=vmax) + + cX = lines[['Longitude', 'Longitude:1']].to_numpy() + cY = lines[['Latitude', 'Latitude:1']].to_numpy() + segments = np.stack([ + np.column_stack([cX[:, 0], cY[:, 0]]), + np.column_stack([cX[:, 1], cY[:, 1]]), + ], axis=1) + + cm = plt.get_cmap(cmap) + colors = cm(norm(vals)) + widths = 0.5 + 3.0 * np.abs(vals) / vmax if vmax > 0 else np.ones(len(vals)) + widths[~valid] = 0.3 + + # Sort by magnitude so largest values draw on top + order = np.argsort(np.abs(vals)) + lc = LineCollection(segments[order], colors=colors[order], + linewidths=widths[order], zorder=4) + ax.add_collection(lc) + + # Bus endpoints in neutral gray + ax.scatter(cX.ravel(), cY.ravel(), c=_CG, s=8, zorder=3, + edgecolors='white', linewidth=0.2) + + if shape is not None: + border(ax, shape) + + ax.autoscale_view() + sm = ScalarMappable(cmap=cm, norm=norm) + sm.set_array([]) + if fig is not None: + fig.colorbar(sm, ax=ax, label=clabel, shrink=0.8) + + format_plot(ax, title=title, + xlabel=r'Lon ($^\circ$E)', ylabel=r'Lat ($^\circ$N)', + plotarea='white', grid=False, **_FS2) + ax.set_aspect('equal') + if show: + plt.tight_layout() + plt.show() + return ax + + +def plot_sensitivity_dual(lines, vals_a, vals_b, shape=None, + titles=('PTDF', 'LODF'), + clabels=('PTDF', 'LODF'), + cmaps=('RdBu_r', 'RdBu_r'), + symmetric=(True, True), + figsize=(_W2, 2.8)): + """Side-by-side geographic sensitivity maps (2-panel).""" + fig, axes = plt.subplots(1, 2, figsize=figsize) + plot_sensitivity_map(lines, vals_a, shape=shape, title=titles[0], + clabel=clabels[0], cmap=cmaps[0], + symmetric=symmetric[0], ax=axes[0], fig=fig) + plot_sensitivity_map(lines, vals_b, shape=shape, title=titles[1], + clabel=clabels[1], cmap=cmaps[1], + symmetric=symmetric[1], ax=axes[1], fig=fig) + plt.tight_layout() + plt.show() + + +def plot_sensitivity_triple(lines, vals_list, shape=None, + titles=('A', 'B', 'C'), + clabels=('', '', ''), + cmaps=('RdBu_r', 'RdBu_r', 'RdBu_r'), + symmetric=(True, True, True), + figsize=(_WFULL, 2.5)): + """Three-panel geographic sensitivity maps.""" + fig, axes = plt.subplots(1, 3, figsize=figsize) + for ax, vals, t, cl, cm, sym in zip(axes, vals_list, titles, + clabels, cmaps, symmetric): + plot_sensitivity_map(lines, vals, shape=shape, title=t, + clabel=cl, cmap=cm, symmetric=sym, + ax=ax, fig=fig) + plt.tight_layout() + plt.show() + + +def plot_flow_map(lines, loading, shape=None, + title='Branch Loading', clabel='Loading (%)', + threshold=100.0, highlight_idx=None, + figsize=(_W2, 2.8), ax=None, fig=None): + """Geographic map with lines colored by loading percentage. + + Parameters + ---------- + lines : DataFrame + Branch data with geographic endpoints. + loading : array-like + Branch loading (%) values. + threshold : float + Overload threshold shown as a colorbar marker. + highlight_idx : int or array-like, optional + Index(es) into ``lines`` to draw with a thick dashed overlay. + """ + show = ax is None + if ax is None: + fig, ax = plt.subplots(figsize=figsize) + + vals = np.asarray(loading, dtype=float) + valid = np.isfinite(vals) + vmax = max(vals[valid].max(), threshold) if valid.any() else threshold + norm = Normalize(vmin=0, vmax=vmax) + + cX = lines[['Longitude', 'Longitude:1']].to_numpy() + cY = lines[['Latitude', 'Latitude:1']].to_numpy() + segments = np.stack([ + np.column_stack([cX[:, 0], cY[:, 0]]), + np.column_stack([cX[:, 1], cY[:, 1]]), + ], axis=1) + + cm = plt.get_cmap('YlOrRd') + colors = cm(norm(vals)) + widths = 0.8 + 2.5 * vals / vmax + widths[~valid] = 0.3 + + # Sort by loading so heavily loaded lines draw on top + order = np.argsort(vals) + lc = LineCollection(segments[order], colors=colors[order], + linewidths=widths[order], zorder=4) + ax.add_collection(lc) + + # Highlight specific branches + if highlight_idx is not None: + hi = np.atleast_1d(highlight_idx) + hi_segs = segments[hi] + lc_hi = LineCollection(hi_segs, colors='black', linewidths=3.5, + linestyles='dashed', zorder=5, + label='Outaged') + ax.add_collection(lc_hi) + ax.legend(fontsize=7, loc='lower right') + + ax.scatter(cX.ravel(), cY.ravel(), c=_CG, s=6, zorder=3, + edgecolors='white', linewidth=0.2) + + if shape is not None: + border(ax, shape) + + ax.autoscale_view() + sm = ScalarMappable(cmap=cm, norm=norm) + sm.set_array([]) + if fig is not None: + fig.colorbar(sm, ax=ax, label=clabel, shrink=0.8) + + format_plot(ax, title=title, + xlabel=r'Lon ($^\circ$E)', ylabel=r'Lat ($^\circ$N)', + plotarea='white', grid=False, **_FS2) + ax.set_aspect('equal') + if show: + plt.tight_layout() + plt.show() + return ax + + +def plot_bus_markers(ax, lon, lat, indices, marker='*', color=_C4, + size=120, label=None): + """Add star markers at specific bus locations on an existing axes.""" + ax.scatter(lon[indices], lat[indices], marker=marker, c=color, + s=size, zorder=10, edgecolors='black', linewidth=0.5, + label=label) + if label: + ax.legend(fontsize=7, loc='lower right') + + +def plot_solver_comparison(results, figsize=(_W2, _H2)): + """Compare solver results: mismatch vs iteration (2-panel).""" + fig, axes = plt.subplots(1, 2, figsize=figsize) + pal = [_C1, _C2, _C3, _C4, _C5] + + for i, (label, data) in enumerate(results.items()): + c = pal[i % len(pal)] + if 'mismatches' in data and data['mismatches']: + axes[0].semilogy(data['mismatches'], 'o-', color=c, + markersize=3, label=label) + axes[1].bar(i, data.get('iterations', 0), color=c, label=label) + + format_plot(axes[0], title='Convergence History', + xlabel='Iteration', ylabel='Max Mismatch', + plotarea='white', **_FS2) + axes[0].legend(fontsize=7) + + axes[1].set_xticks(range(len(results))) + axes[1].set_xticklabels(list(results.keys()), fontsize=7, rotation=30) + format_plot(axes[1], title='Iterations to Converge', + ylabel='Iterations', plotarea='white', **_FS2) + + plt.tight_layout() + plt.show() + + +def plot_snapshot_comparison(base, modified, field='BusPUVolt', + figsize=(_W2, _H2)): + """Before/after voltage scatter + difference histogram (2-panel).""" + fig, axes = plt.subplots(1, 2, figsize=figsize) + + axes[0].scatter(range(len(base)), base, s=12, c=_C1, + edgecolors='white', linewidth=0.3, label='Base', alpha=0.7) + axes[0].scatter(range(len(modified)), modified, s=12, c=_C2, + edgecolors='white', linewidth=0.3, label='Modified', alpha=0.7) + axes[0].axhline(y=0.95, color=_LIMIT, linestyle='--', alpha=0.5) + axes[0].axhline(y=1.05, color=_LIMIT, linestyle='--', alpha=0.5) + format_plot(axes[0], title='Voltage Comparison', + xlabel='Bus Index', ylabel='Voltage (pu)', + plotarea='white', **_FS2) + axes[0].legend(fontsize=7) + + diff = modified - base + axes[1].hist(diff, bins=25, color=_C1, edgecolor='white') + axes[1].axvline(x=0, color=_CG, linewidth=0.5) + format_plot(axes[1], title=f'Voltage Change (max={np.abs(diff).max():.4f})', + xlabel='\u0394V (pu)', ylabel='Count', + plotarea='white', **_FS2) + + plt.tight_layout() + plt.show() + + +def plot_state_chain(states, labels=None, figsize=(_W1, _H1)): + """Line plot of state-chain voltage trajectories.""" + fig, ax = plt.subplots(figsize=figsize) + pal = [_C1, _C2, _C3, _C4, _C5] + for i, v in enumerate(states): + lbl = labels[i] if labels else f'State {i}' + ax.plot(range(len(v)), v, 'o-', color=pal[i % len(pal)], + markersize=3, label=lbl) + ax.axhline(y=0.95, color=_LIMIT, linestyle='--', alpha=0.5) + ax.axhline(y=1.05, color=_LIMIT, linestyle='--', alpha=0.5) + format_plot(ax, title='State Chain Voltages', + xlabel='Bus Index', ylabel='Voltage (pu)', + plotarea='white', **_FS2) + ax.legend(fontsize=7) + plt.tight_layout() + plt.show() + + +# --------------------------------------------------------------------------- +# Power system specific +# --------------------------------------------------------------------------- + +def plot_voltage_profile(vmag, vang=None, figsize=(_W2, _H2)): + """Scatter of bus voltage magnitudes + angle stem plot (always 2-panel).""" + fig, axes = plt.subplots(1, 2, figsize=figsize) + + axes[0].scatter(range(len(vmag)), vmag, c=_C1, s=18, edgecolors='white', + linewidth=0.4) + axes[0].axhline(y=0.95, color=_LIMIT, linestyle='--', alpha=0.7, label='0.95 pu') + axes[0].axhline(y=1.05, color=_LIMIT, linestyle='--', alpha=0.7, label='1.05 pu') + axes[0].axhline(y=1.0, color=_CG, linestyle='-', alpha=0.3) + format_plot(axes[0], title='Voltage Magnitude', + xlabel='Bus Index', ylabel='Voltage (pu)', + plotarea='white', **_FS2) + axes[0].legend(fontsize=7) + + if vang is not None: + axes[1].stem(range(len(vang)), vang, linefmt=_C1, markerfmt='o', basefmt=' ') + format_plot(axes[1], title='Voltage Angles', + xlabel='Bus Index', ylabel='Angle (deg)', + plotarea='white', **_FS2) + else: + axes[1].hist(vmag, bins=20, color=_C1, edgecolor='white') + format_plot(axes[1], title='Voltage Distribution', + xlabel='Voltage (pu)', ylabel='Count', + plotarea='white', **_FS2) + + plt.tight_layout() + plt.show() + + +def plot_branch_loading(branches_loaded, figsize=(_W2, _H2)): + """Branch loading bar chart + loading histogram (2-panel).""" + fig, axes = plt.subplots(1, 2, figsize=figsize) + + labels = [f"{int(r['BusNum'])}-{int(r['BusNum:1'])}" for _, r in branches_loaded.iterrows()] + axes[0].barh(range(len(branches_loaded)), branches_loaded['LinePercent'].values, + color=_C1) + axes[0].set_yticks(range(len(branches_loaded))) + axes[0].set_yticklabels(labels, fontsize=7) + axes[0].invert_yaxis() + axes[0].axvline(x=100, color=_LIMIT, linestyle='--', alpha=0.7, label='100%') + format_plot(axes[0], title='Most Loaded Branches', + xlabel='Loading (%)', plotarea='white', **_FS2) + axes[0].legend(fontsize=7) + + axes[1].hist(branches_loaded['LinePercent'].values, bins=15, + color=_C1, edgecolor='white') + axes[1].axvline(x=100, color=_LIMIT, linestyle='--', alpha=0.7) + format_plot(axes[1], title='Loading Distribution', + xlabel='Loading (%)', ylabel='Count', + plotarea='white', **_FS2) + + plt.tight_layout() + plt.show() + + +def plot_gen_dispatch_and_voltage(online_gens, bus_data, figsize=(_W2, _H2)): + """Generator MW bar chart + bus voltage scatter (2-panel).""" + fig, axes = plt.subplots(1, 2, figsize=figsize) + + gen_mw = online_gens.sort_values('GenMW', ascending=True) + axes[0].barh(range(len(gen_mw)), gen_mw['GenMW'].values, color=_C1) + axes[0].set_yticks(range(len(gen_mw))) + axes[0].set_yticklabels([f"Bus {b}" for b in gen_mw['BusNum']], fontsize=7) + format_plot(axes[0], title='Generator Dispatch', + xlabel='MW Output', plotarea='white', **_FS2) + + axes[1].scatter(bus_data['BusNum'], bus_data['BusPUVolt'], + c=_C1, s=25, edgecolors='white', linewidth=0.4) + axes[1].axhline(y=0.95, color=_LIMIT, linestyle='--', alpha=0.5, label='0.95 pu') + axes[1].axhline(y=1.05, color=_LIMIT, linestyle='--', alpha=0.5, label='1.05 pu') + format_plot(axes[1], title='Bus Voltage Profile', + xlabel='Bus Number', ylabel='Voltage (pu)', + plotarea='white', **_FS2) + axes[1].legend(fontsize=7) + + plt.tight_layout() + plt.show() + + +def plot_gen_load_balance(total_gen, total_load, ax=None, figsize=(4.5, 3)): + """Bar chart comparing total generation vs. total load.""" + show = ax is None + if ax is None: + fig, ax = plt.subplots(figsize=figsize) + bars = ax.bar(['Generation', 'Load'], [total_gen, total_load], + color=[_C1, _C2]) + format_plot(ax, title='Generation vs Load Balance', + ylabel='MW', plotarea='white', **_FS2) + for bar, val in zip(bars, [total_gen, total_load]): + ax.text(bar.get_x() + bar.get_width() / 2, bar.get_height() + 1, + f'{val:.1f}', ha='center', va='bottom', fontsize=8) + if show: + plt.tight_layout() + plt.show() + return ax + + +def plot_contingency_results(violations, figsize=(_W2, _H2)): + """Bar chart of violations per contingency + histogram (2-panel).""" + if len(violations) == 0 or 'Contingency' not in violations.columns: + return + ctg_counts = violations['Contingency'].value_counts().head(15) + + fig, axes = plt.subplots(1, 2, figsize=figsize) + + axes[0].barh(range(len(ctg_counts)), ctg_counts.values, color=_C1) + axes[0].set_yticks(range(len(ctg_counts))) + axes[0].set_yticklabels(ctg_counts.index, fontsize=7) + axes[0].invert_yaxis() + format_plot(axes[0], title='Top Contingencies', + xlabel='Number of Violations', plotarea='white', **_FS2) + + axes[1].hist(violations.groupby('Contingency').size(), bins=20, + color=_C1, edgecolor='white') + format_plot(axes[1], title='Violation Distribution', + xlabel='Violations per Contingency', ylabel='Count', + plotarea='white', **_FS2) + + plt.tight_layout() + plt.show() + + +def plot_pv_curve(mw_points, v_points, ax=None, figsize=(_W1, _H1)): + """PV curve with nose point marker.""" + if not mw_points: + return + show = ax is None + if ax is None: + fig, ax = plt.subplots(figsize=figsize) + ax.plot(mw_points, v_points, 'o-', color=_C1, markersize=3) + + nose_idx = np.argmax(mw_points) + ax.plot(mw_points[nose_idx], v_points[nose_idx], '*', color=_C4, + markersize=12, label=f'Nose: {mw_points[nose_idx]:.0f} MW') + + ax.axhline(y=0.95, color=_LIMIT, linestyle='--', alpha=0.5, label='0.95 pu') + format_plot(ax, title='PV Curve', + xlabel='Transfer (MW)', ylabel='Voltage (pu)', + plotarea='white', **_FS2) + ax.legend(fontsize=7) + if show: + plt.tight_layout() + plt.show() + return ax + + +# --------------------------------------------------------------------------- +# Sparse matrix / spectral +# --------------------------------------------------------------------------- + +def plot_spy_matrices(matrices, titles, figsize=None, markersize=3, colors=None): + """Side-by-side spy() plots for one or more sparse matrices.""" + n = max(len(matrices), 2) + if figsize is None: + figsize = (min(_WFULL, 3.2 * n), _H2) + if colors is None: + colors = [_C1, _C2, _C3, _C5, _C6, _C7][:len(matrices)] + fig, axes = plt.subplots(1, n, figsize=figsize) + if n == 1: + axes = [axes] + fs = _FS3 if n >= 3 else _FS2 + for ax, M, t, c in zip(axes, matrices, titles, colors): + ax.spy(M, markersize=markersize, color=c) + format_plot(ax, title=t, plotarea='white', grid=False, **fs) + for j in range(len(matrices), n): + axes[j].set_visible(False) + plt.tight_layout() + plt.show() + + +def plot_ybus_analysis(Y, figsize=(_W2, _H2)): + """Y-Bus sparsity pattern + eigenvalue spectrum (2-panel).""" + fig, axes = plt.subplots(1, 2, figsize=figsize) + + axes[0].spy(Y, markersize=3, color=_C1) + format_plot(axes[0], title=f'Y-Bus Sparsity\n{Y.shape}, nnz={Y.nnz}', + plotarea='white', grid=False, **_FS2) + + eig_Y = np.linalg.eigvals(Y.toarray()) + axes[1].scatter(eig_Y.real, eig_Y.imag, s=15, c=_C1, edgecolors='white', + linewidth=0.4) + axes[1].axhline(y=0, color=_CG, linewidth=0.5) + axes[1].axvline(x=0, color=_CG, linewidth=0.5) + format_plot(axes[1], title='Eigenvalue Spectrum', + xlabel='Real', ylabel='Imaginary', + plotarea='white', **_FS2) + + plt.tight_layout() + plt.show() + + +def plot_incidence_and_degree(A, figsize=(_W2, _H2)): + """Incidence matrix spy + bus degree bar chart (2-panel).""" + fig, axes = plt.subplots(1, 2, figsize=figsize) + + axes[0].spy(A, markersize=2, color=_C1) + format_plot(axes[0], title=f'Incidence Matrix\n{A.shape}', + xlabel='Bus index', ylabel='Branch index', + plotarea='white', grid=False, **_FS2) + + degrees = np.abs(A).T @ np.ones(A.shape[0]) + axes[1].bar(range(len(degrees)), degrees, color=_C1) + format_plot(axes[1], title='Bus Degree Distribution', + xlabel='Bus index', ylabel='Degree', + plotarea='white', **_FS2) + + plt.tight_layout() + plt.show() + + +def plot_incidence_and_laplacian(A, figsize=(_W2, _H2)): + """Incidence matrix spy + |A^T A| image (2-panel).""" + fig, axes = plt.subplots(1, 2, figsize=figsize) + + axes[0].spy(A, markersize=2, color=_C1) + format_plot(axes[0], title=f'Incidence Matrix\n{A.shape}', + xlabel='Bus index', ylabel='Branch index', + plotarea='white', grid=False, **_FS2) + + L_unw = (A.T @ A).toarray() + axes[1].imshow(np.abs(L_unw), cmap='Blues', aspect='auto') + format_plot(axes[1], title='|A\u1d40A| (Unweighted Laplacian)', + xlabel='Bus index', ylabel='Bus index', + plotarea='white', grid=False, **_FS2) + + plt.axis('equal') + plt.tight_layout() + plt.show() + + +def plot_eigenspectrum(eigenvalue_sets, titles, figsize=None): + """Stem plots of eigenvalue arrays (always >= 2 panels).""" + n = max(len(eigenvalue_sets), 2) + if figsize is None: + figsize = (min(_WFULL, 3.2 * n), _H2) + fig, axes = plt.subplots(1, n, figsize=figsize) + if n == 1: + axes = [axes] + fs = _FS3 if n >= 3 else _FS2 + for ax, vals, t in zip(axes, eigenvalue_sets, titles): + ax.stem(vals, basefmt=' ') + format_plot(ax, title=t, xlabel='Index', ylabel='Eigenvalue', + plotarea='white', **fs) + for j in range(len(eigenvalue_sets), n): + axes[j].set_visible(False) + plt.tight_layout() + plt.show() + + +def plot_fiedler(fiedler, figsize=(_W2, _H2)): + """Fiedler vector bar chart colored by sign + partition histogram (2-panel).""" + fig, axes = plt.subplots(1, 2, figsize=figsize) + + colors = [_C1 if v >= 0 else _C2 for v in fiedler] + axes[0].bar(range(len(fiedler)), fiedler, color=colors) + axes[0].axhline(y=0, color='black', linewidth=0.5) + format_plot(axes[0], title='Fiedler Vector (Network Partition)', + xlabel='Bus index', ylabel='Fiedler component', + plotarea='white', **_FS2) + + axes[1].hist(fiedler, bins=15, color=_C1, edgecolor='white') + axes[1].axvline(x=0, color='black', linewidth=0.5) + n_pos = sum(1 for v in fiedler if v >= 0) + n_neg = len(fiedler) - n_pos + axes[1].set_title(f'Partition: {n_pos} vs {n_neg} buses', fontsize=11) + format_plot(axes[1], xlabel='Component value', ylabel='Count', + plotarea='white', **_FS2) + + plt.tight_layout() + plt.show() + + +def plot_histograms(datasets, titles, xlabels, colors=None, bins=25, figsize=None): + """Side-by-side histograms (always >= 2 panels).""" + n = max(len(datasets), 2) + if figsize is None: + figsize = (min(_WFULL, 3.2 * n), _H2) + if colors is None: + colors = [_C1, _C2, _C3, _C6][:len(datasets)] + fig, axes = plt.subplots(1, n, figsize=figsize) + if n == 1: + axes = [axes] + fs = _FS3 if n >= 3 else _FS2 + for ax, data, t, xl, c in zip(axes, datasets, titles, xlabels, colors): + ax.hist(data, bins=bins, color=c, edgecolor='white') + format_plot(ax, title=t, xlabel=xl, ylabel='Count', + plotarea='white', **fs) + for j in range(len(datasets), n): + axes[j].set_visible(False) + plt.tight_layout() + plt.show() + + +# --------------------------------------------------------------------------- +# Direction sensitivity (GIC) +# --------------------------------------------------------------------------- + +def plot_direction_sensitivity(directions, max_gics, title='Max GIC vs Direction', + figsize=(_W2, 2.8)): + """Line plot + polar plot of GIC vs. storm direction (2-panel).""" + fig = plt.figure(figsize=figsize) + + ax1 = fig.add_subplot(121) + ax1.plot(directions, max_gics, 'o-', color=_C1, markersize=3) + format_plot(ax1, title=title, + xlabel='Direction (deg from N)', + ylabel='Max |GIC| (A)', plotarea='white', **_FS2) + + ax2 = fig.add_subplot(122, projection='polar') + theta = np.radians(directions) + ax2.plot(theta, max_gics, 'o-', color=_C2, markersize=3) + ax2.set_title('Polar Response', pad=15, fontsize=10) + + plt.tight_layout() + plt.show() + + worst = directions[np.argmax(max_gics)] + print(f"Worst-case direction: {worst} degrees") + print(f"Worst-case max GIC: {max_gics.max():.2f} Amps") + + +def plot_direction_profiles(directions, gic_profiles, labels, figsize=(_W2, 2.8)): + """Multi-transformer direction sensitivity: line + polar (2-panel).""" + fig, axes = plt.subplots(1, 2, figsize=figsize) + + pal = [_C1, _C2, _C3, _C4, _C5] + for j, lbl in enumerate(labels): + axes[0].plot(directions, gic_profiles[:, j], label=lbl, + color=pal[j % len(pal)]) + format_plot(axes[0], title='Transformer GIC vs Direction', + xlabel='Direction (deg from N)', ylabel='|GIC| (A)', + plotarea='white', **_FS2) + axes[0].legend(fontsize=7) + + ax_polar = fig.add_axes(axes[1].get_position(), projection='polar') + axes[1].set_visible(False) + theta = np.radians(directions) + for j, lbl in enumerate(labels): + ax_polar.plot(theta, gic_profiles[:, j], label=lbl, + color=pal[j % len(pal)]) + ax_polar.set_title('Polar Response', pad=15, fontsize=10) + ax_polar.legend(loc='upper right', bbox_to_anchor=(1.3, 1.0), fontsize=7) + + plt.tight_layout() + plt.show() + + +# --------------------------------------------------------------------------- +# GIC matrix / sensitivity +# --------------------------------------------------------------------------- + +def plot_gic_distribution(gic_abs, n=15, figsize=(_W2, _H2)): + """Histogram + top-N bar chart for GIC magnitudes (2-panel).""" + fig, axes = plt.subplots(1, 2, figsize=figsize) + + axes[0].hist(gic_abs, bins=20, color=_C1, edgecolor='white') + format_plot(axes[0], title='GIC Distribution', + xlabel='|GIC| (A)', ylabel='Count', + plotarea='white', **_FS2) + + top = gic_abs.sort_values(ascending=False).head(n) + axes[1].barh(range(len(top)), top.values, color=_C1) + axes[1].set_yticks(range(len(top))) + axes[1].set_yticklabels([f'XF {i + 1}' for i in range(len(top))], fontsize=7) + axes[1].invert_yaxis() + format_plot(axes[1], title=f'Top {n} Transformer GICs', + xlabel='|GIC| (A)', ylabel='Transformer', + plotarea='white', **_FS2) + + plt.tight_layout() + plt.show() + + +# Keep backward compatibility alias +plot_gic_bar_hist = plot_gic_distribution + + +def plot_gmatrix_comparison(G_model, G_pw, figsize=(_W3, _H3)): + """Compare model G-matrix vs PowerWorld G-matrix with difference (3-panel).""" + fig, axes = plt.subplots(1, 3, figsize=figsize) + + im0 = axes[0].imshow(np.abs(G_model), cmap='Blues', aspect='auto') + fig.colorbar(im0, ax=axes[0], shrink=0.7) + format_plot(axes[0], title='|G| Model', plotarea='white', + grid=False, **_FS3) + + im1 = axes[1].imshow(np.abs(G_pw), cmap='Blues', aspect='auto') + fig.colorbar(im1, ax=axes[1], shrink=0.7) + format_plot(axes[1], title='|G| PowerWorld', plotarea='white', + grid=False, **_FS3) + + if G_model.shape == G_pw.shape: + diff = np.abs(G_model - G_pw) + im2 = axes[2].imshow(diff, cmap='Reds', aspect='auto') + fig.colorbar(im2, ax=axes[2], shrink=0.7) + format_plot(axes[2], title=f'|Diff| max={diff.max():.2e}', + plotarea='white', grid=False, **_FS3) + else: + axes[2].text(0.5, 0.5, 'Shape mismatch', + ha='center', va='center', transform=axes[2].transAxes, + fontsize=9) + format_plot(axes[2], title='Difference', plotarea='white', + grid=False, **_FS3) + + plt.tight_layout() + plt.show() + + +def plot_jacobian_sensitivity(J_dense, figsize=(_W2, _H2)): + """dI/dE Jacobian heatmap + row-wise sensitivity bar chart (2-panel).""" + fig, axes = plt.subplots(1, 2, figsize=figsize) + + im0 = axes[0].imshow(np.abs(J_dense), cmap='Blues', aspect='auto') + fig.colorbar(im0, ax=axes[0], shrink=0.7) + format_plot(axes[0], title='|dI/dE| Jacobian', + xlabel='Branch index', ylabel='Transformer index', + plotarea='white', grid=False, **_FS2) + + row_sens = np.sum(np.abs(J_dense), axis=1) + axes[1].barh(range(len(row_sens)), row_sens, color=_C1) + axes[1].invert_yaxis() + format_plot(axes[1], title='Transformer E-Field Sensitivity', + xlabel='Total sensitivity', ylabel='Transformer index', + plotarea='white', **_FS2) + + plt.tight_layout() + plt.show() + + +def plot_branch_impact(col_sens, top_n=5, figsize=(_W2, _H2)): + """Branch impact bar chart + top-N detail (2-panel).""" + fig, axes = plt.subplots(1, 2, figsize=figsize) + + top_branches = np.argsort(col_sens)[::-1][:top_n] + colors = [_C2 if i in top_branches else _C1 for i in range(len(col_sens))] + axes[0].bar(range(len(col_sens)), col_sens, color=colors, width=1.0) + format_plot(axes[0], title='Branch Impact on GIC', + xlabel='Branch index', ylabel='Aggregate |dI/dE|', + plotarea='white', **_FS2) + + axes[1].barh(range(top_n), col_sens[top_branches], color=_C2) + axes[1].set_yticks(range(top_n)) + axes[1].set_yticklabels([f'Branch {b}' for b in top_branches], fontsize=7) + axes[1].invert_yaxis() + format_plot(axes[1], title=f'Top {top_n} Branches', + xlabel='|dI/dE|', plotarea='white', **_FS2) + + plt.tight_layout() + plt.show() + + print(f"\nTop {top_n} most influential branches: {top_branches}") + + +# --------------------------------------------------------------------------- +# Geographic / E-field +# --------------------------------------------------------------------------- + +def plot_geo_grid_buses(LON, LAT, lon, lat, shape, xlim, ylim, + figsize=(_W2, 2.8), ax=None, fig=None): + """Grid points + bus locations on a geographic border.""" + show = ax is None + if ax is None: + fig, ax = plt.subplots(figsize=figsize) + ax.scatter(LON.ravel(), LAT.ravel(), s=1, c=_C7, alpha=0.5, + label='Grid points') + ax.scatter(lon, lat, s=12, c=_C4, zorder=5, label='Bus locations') + border(ax, shape) + ax.set_xlim(xlim[0] - 0.1, xlim[1] + 0.1) + ax.set_ylim(ylim[0] - 0.1, ylim[1] + 0.1) + format_plot(ax, title='Grid & Bus Locations', + xlabel=r'Lon ($^\circ$E)', ylabel=r'Lat ($^\circ$N)', + plotarea='white', grid=False, **_FS2) + ax.legend(fontsize=7, loc='lower right') + ax.set_aspect('equal') + if show: + plt.tight_layout() + plt.show() + return ax + + +def plot_efield_comparison(LON, LAT, fields, shape, figsize=None): + """Side-by-side magnitude heatmaps for E-field patterns (>= 2-panel). + + Parameters + ---------- + fields : list of (name, Ex, Ey) tuples + """ + n = max(len(fields), 2) + if figsize is None: + figsize = (_WFULL, _H3) + fig, axes = plt.subplots(1, n, figsize=figsize) + if n == 1: + axes = [axes] + fs = _FS3 if n >= 3 else _FS2 + for ax, (name, Ex, Ey) in zip(axes, fields): + magnitude = np.sqrt(Ex ** 2 + Ey ** 2) + im = ax.pcolormesh(LON, LAT, magnitude, cmap='hot_r', shading='auto') + border(ax, shape) + ax.set_xlim(LON.min(), LON.max()) + ax.set_ylim(LAT.min(), LAT.max()) + fig.colorbar(im, ax=ax, label='|E| (V/km)', shrink=0.7) + format_plot(ax, title=f'{name} |E|', + xlabel=r'Lon ($^\circ$E)', + ylabel=r'Lat ($^\circ$N)', + plotarea='white', grid=False, **fs) + ax.set_aspect('equal') + for j in range(len(fields), n): + axes[j].set_visible(False) + plt.tight_layout() + plt.show() + + +def plot_efield_vectors(LON, LAT, Ex, Ey, shape, step=3, + figsize=(_W2, 2.8), ax=None, fig=None): + """Heatmap of E-field magnitude + vector field overlay.""" + show = ax is None + if ax is None: + fig, ax = plt.subplots(figsize=figsize) + magnitude = np.sqrt(Ex ** 2 + Ey ** 2) + im = ax.pcolormesh(LON, LAT, magnitude, cmap='YlOrRd', shading='auto', alpha=0.6) + border(ax, shape) + ax.set_xlim(LON.min(), LON.max()) + ax.set_ylim(LAT.min(), LAT.max()) + + sm = plot_vecfield(ax, LON[::step, ::step], LAT[::step, ::step], + Ex[::step, ::step], Ey[::step, ::step], + scale=40, width=0.003) + if fig is not None: + fig.colorbar(im, ax=ax, label='|E| (V/km)', shrink=0.7) + format_plot(ax, title='E-Field Vectors', + xlabel=r'Lon ($^\circ$E)', + ylabel=r'Lat ($^\circ$N)', grid=False, **_FS2) + ax.set_aspect('equal') + if show: + plt.tight_layout() + plt.show() + return ax + + +def plot_network_efield(LON, LAT, magnitude, lines, lon, lat, Ex, Ey, + shape, step=4, figsize=(_W2, 2.8), ax=None, fig=None): + """Full network overlay: heatmap + lines + buses + E-field vectors.""" + show = ax is None + if ax is None: + fig, ax = plt.subplots(figsize=figsize) + + im = ax.pcolormesh(LON, LAT, magnitude, cmap='YlOrRd', shading='auto', alpha=0.4) + border(ax, shape) + plot_lines(ax, lines, ms=4, lw=0.6) + ax.scatter(lon, lat, s=12, c='navy', zorder=6, label='Buses', + edgecolors='white', linewidth=0.4) + ax.quiver(LON[::step, ::step], LAT[::step, ::step], + Ex[::step, ::step], Ey[::step, ::step], + color='darkred', alpha=0.7, scale=30, width=0.002, zorder=7) + ax.set_xlim(LON.min(), LON.max()) + ax.set_ylim(LAT.min(), LAT.max()) + + if fig is not None: + fig.colorbar(im, ax=ax, label='|E| (V/km)', shrink=0.7) + format_plot(ax, title='Network + E-Field', + xlabel=r'Lon ($^\circ$E)', + ylabel=r'Lat ($^\circ$N)', + plotarea='white', grid=False, **_FS2) + ax.legend(loc='lower right', fontsize=7) + ax.set_aspect('equal') + if show: + plt.tight_layout() + plt.show() + return ax + + +def plot_gic_geo_map(lines, xf_geo, gic_mag, shape, xlim, ylim, + figsize=(_W2, 2.8), ax=None, fig=None): + """GIC magnitudes on a geographic map with transmission network.""" + show = ax is None + if ax is None: + fig, ax = plt.subplots(figsize=figsize) + border(ax, shape) + plot_lines(ax, lines, ms=3, lw=0.4) + + sizes = 10 + 120 * gic_mag / gic_mag.max() + sc = ax.scatter(xf_geo['Longitude'], xf_geo['Latitude'], + s=sizes, c=gic_mag, cmap='Reds', zorder=8, + edgecolors='black', linewidth=0.4) + if fig is not None: + fig.colorbar(sc, ax=ax, label='|GIC| (A)', shrink=0.7) + + ax.set_xlim(*xlim) + ax.set_ylim(*ylim) + format_plot(ax, title='Transformer GIC Map', + xlabel=r'Lon ($^\circ$E)', + ylabel=r'Lat ($^\circ$N)', + plotarea='white', grid=False, **_FS2) + ax.set_aspect('equal') + if show: + plt.tight_layout() + plt.show() + return ax + + +def plot_b3d_roundtrip(LON, LAT, ex_orig, ex_loaded, shape, ny, nx, + figsize=(_W2, _H2)): + """Side-by-side original vs loaded Ex from B3D (2-panel).""" + fig, axes = plt.subplots(1, 2, figsize=figsize) + + ex_2d_orig = ex_orig[0].reshape(ny, nx, order='F') + ex_2d_load = ex_loaded[0].reshape(ny, nx, order='F') + + for ax, data, title in zip(axes, + [ex_2d_orig, ex_2d_load], + ['Original Ex', 'B3D Round-Trip Ex']): + im = ax.pcolormesh(LON, LAT, data, cmap='RdBu_r', shading='auto') + border(ax, shape) + ax.set_xlim(LON.min(), LON.max()) + ax.set_ylim(LAT.min(), LAT.max()) + fig.colorbar(im, ax=ax, label='Ex (V/km)') + format_plot(ax, title=title, + xlabel=r'Lon ($^\circ$E)', + ylabel=r'Lat ($^\circ$N)', + plotarea='white', grid=False, **_FS2) + ax.set_aspect('equal') + + plt.tight_layout() + plt.show() + + +def plot_b3d_components(LON, LAT, Ex, Ey, shape, suptitle='', + figsize=(_W3, _H3)): + """Three-panel plot: |E|, Ex, Ey on a geographic background.""" + magnitude = np.sqrt(Ex ** 2 + Ey ** 2) + fig, axes = plt.subplots(1, 3, figsize=figsize) + + for ax, data, cmap, label, title in zip( + axes, + [magnitude, Ex, Ey], + ['hot_r', 'RdBu_r', 'RdBu_r'], + ['|E| (V/km)', 'Ex (V/km)', 'Ey (V/km)'], + ['|E| Magnitude', 'Ex (Eastward)', 'Ey (Northward)'], + ): + im = ax.pcolormesh(LON, LAT, data, cmap=cmap, shading='auto') + border(ax, shape) + fig.colorbar(im, ax=ax, label=label, shrink=0.7) + format_plot(ax, title=title, + xlabel=r'Lon ($^\circ$E)', + ylabel=r'Lat ($^\circ$N)', + plotarea='white', grid=False, **_FS3) + ax.set_aspect('equal') + + if suptitle: + plt.suptitle(suptitle, fontsize=12) + plt.tight_layout() + plt.show() + + +# --------------------------------------------------------------------------- +# Dynamics +# --------------------------------------------------------------------------- + +def plot_dynamics(meta, df, xlim=None, figsize_width=10, **kwargs): + """Plot transient stability results grouped by Object and Metric. + + Parameters + ---------- + meta : DataFrame + Metadata DataFrame returned by ``Dynamics.solve()``. + df : DataFrame + Time-series DataFrame returned by ``Dynamics.solve()``. + xlim : tuple, optional + (min, max) for x-axis limits. + figsize_width : float, default 10 + Figure width in inches. + kwargs : dict + Additional arguments passed to ``plt.subplots()``. + """ + if meta.empty or df.empty: + return + + grouped = meta.groupby(['Object', 'Metric']) + n_groups = len(grouped) + if n_groups == 0: + return + + if xlim is None: + xlim = (df.index.min(), df.index.max()) + + fig_height = max(n_groups * 3.0, 5) + fig, axes = plt.subplots(n_groups, 1, sharex=True, + figsize=(figsize_width, fig_height), + squeeze=False, **kwargs) + axes_flat = axes.flatten() + + for ax, ((obj, metric), grp) in zip(axes_flat, grouped): + ctg_list = df.columns.get_level_values(0).unique() + for ctg in ctg_list: + ctg_data = df[ctg] + matching_cols = grp.index.intersection(ctg_data.columns) + for col in matching_cols: + id_a = grp.at[col, 'ID-A'] + id_b = grp.at[col, 'ID-B'] if 'ID-B' in grp.columns else None + id_a_str = str(id_a) if id_a is not None and str(id_a).lower() != 'nan' else "" + id_b_str = str(id_b) if id_b is not None and str(id_b).lower() != 'nan' else "" + label_parts = [p for p in [id_a_str, id_b_str] if p] + lbl = " ".join(label_parts) + plot_label = f"{ctg} | {lbl}" if lbl else ctg + ax.plot(ctg_data.index, ctg_data[col], label=plot_label, linewidth=1.5) + + ax.set_ylabel(f"{obj}\n{metric}", fontsize=10, fontweight='bold') + ax.grid(True, which='major', linestyle='-', linewidth=0.75, alpha=0.7) + ax.grid(True, which='minor', linestyle=':', linewidth=0.5, alpha=0.5) + ax.minorticks_on() + if xlim: + ax.set_xlim(xlim) + + axes_flat[-1].set_xlabel("Time (s)", fontsize=10, fontweight='bold') + plt.tight_layout(pad=2.0) + plt.show() + + +def plot_comparative_dynamics(ctg_names, all_results, figsize=None): + """Stacked subplots of generator power for each contingency (multi-row).""" + n = len(ctg_names) + ncols = min(n, 2) + nrows = (n + ncols - 1) // ncols + if figsize is None: + figsize = (_WFULL, 2.6 * nrows) + fig, axes = plt.subplots(nrows, ncols, figsize=figsize, sharex=True) + axes_flat = np.array(axes).ravel() if n > 1 else [axes] + fs = _FS3 if ncols >= 3 else _FS2 + for ax, name in zip(axes_flat, ctg_names): + results = all_results[name] + p_cols = [c for c in results.columns if 'P' in str(c) or 'MW' in str(c)] + if p_cols: + results[p_cols].plot(ax=ax, legend=True) + ax.legend(fontsize=6) + format_plot(ax, title=f'{name}', + xlabel='Time (s)', ylabel='P (MW)', + plotarea='white', **fs) + for j in range(n, len(axes_flat)): + axes_flat[j].set_visible(False) + plt.tight_layout() + plt.show() + + +# --------------------------------------------------------------------------- +# Discrete calculus / Grid2D utilities +# --------------------------------------------------------------------------- + +def plot_grid_regions(X, Y, grid, figsize=(_W3, _H3)): + """Three-panel view of grid: all points, boundary/interior, edges. + + Parameters + ---------- + grid : Grid2D + Grid2D instance (provides .boundary, .interior, .left, etc.). + """ + fig, axes = plt.subplots(1, 3, figsize=figsize) + xf = X.ravel(order='C') + yf = Y.ravel(order='C') + + axes[0].scatter(xf, yf, s=5, c=_C1) + axes[0].set_aspect('equal') + format_plot(axes[0], title='All Grid Points', xlabel='x', ylabel='y', + grid=False, plotarea='white', **_FS3) + + axes[1].scatter(xf[grid.interior], yf[grid.interior], + s=5, c=_C1, label='Interior') + axes[1].scatter(xf[grid.boundary], yf[grid.boundary], + s=8, c=_C2, label='Boundary') + axes[1].set_aspect('equal') + format_plot(axes[1], title='Boundary vs Interior', xlabel='x', ylabel='y', + grid=False, plotarea='white', **_FS3) + axes[1].legend(markerscale=2, fontsize=7) + + axes[2].scatter(xf[grid.left], yf[grid.left], + s=8, c=_C4, label='Left') + axes[2].scatter(xf[grid.right], yf[grid.right], + s=8, c=_C1, label='Right') + axes[2].scatter(xf[grid.top], yf[grid.top], + s=8, c=_C3, label='Top') + axes[2].scatter(xf[grid.bottom], yf[grid.bottom], + s=8, c=_C2, label='Bottom') + axes[2].set_aspect('equal') + format_plot(axes[2], title='Edge Selectors', xlabel='x', ylabel='y', + grid=False, plotarea='white', **_FS3) + axes[2].legend(markerscale=2, fontsize=7) + + plt.tight_layout() + plt.show() + + +def plot_incidence_directed(grid, figsize=(_W2, 3.8)): + """Oriented incidence matrix as directed edges + matrix heatmap (2-panel). + + Parameters + ---------- + grid : Grid2D + A small Grid2D instance (recommended nx, ny <= 6 for readability). + """ + from matplotlib.lines import Line2D + + A = grid.incidence().toarray() + nx, ny = grid.nx, grid.ny + + fig, axes = plt.subplots(1, 2, figsize=figsize, + gridspec_kw={'width_ratios': [1.3, 1]}) + + ax = axes[0] + for xi in range(nx): + for yi in range(ny): + idx = grid.flat_index(xi, yi) + ax.plot(xi, yi, 'o', color=_C1, markersize=14, + markeredgecolor='#2c3e50', markeredgewidth=1.0, zorder=5) + ax.text(xi, yi, str(idx), ha='center', va='center', + fontsize=7, fontweight='bold', color='white', zorder=6) + + shrink = 0.22 + for e in range(grid.n_edges): + src = np.where(A[e] == -1)[0][0] + tgt = np.where(A[e] == +1)[0][0] + sx, sy = grid.grid_coords(src) + tx, ty = grid.grid_coords(tgt) + dx_a, dy_a = tx - sx, ty - sy + length = np.hypot(dx_a, dy_a) + sx_s = sx + shrink * dx_a / length + sy_s = sy + shrink * dy_a / length + dx_s = dx_a * (1 - 2 * shrink) + dy_s = dy_a * (1 - 2 * shrink) + color = _C4 if e < grid.n_edges_x else _C3 + ax.annotate('', xy=(sx_s + dx_s, sy_s + dy_s), xytext=(sx_s, sy_s), + arrowprops=dict(arrowstyle='->', color=color, lw=1.8, + mutation_scale=14)) + mx, my = (sx + tx) / 2, (sy + ty) / 2 + perp_x, perp_y = -dy_a / length, dx_a / length + ax.text(mx + 0.15 * perp_x, my + 0.15 * perp_y, f'e{e}', + ha='center', va='center', fontsize=5.5, color=color, + fontstyle='italic', alpha=0.85) + + ax.legend([Line2D([0], [0], color=_C4, lw=2), + Line2D([0], [0], color=_C3, lw=2)], + [f'Horizontal (0..{grid.n_edges_x - 1})', + f'Vertical ({grid.n_edges_x}..{grid.n_edges - 1})'], + loc='upper left', fontsize=7, framealpha=0.9) + + ax.set_xlim(-0.6, nx - 0.4) + ax.set_ylim(-0.6, ny - 0.4) + ax.set_aspect('equal') + format_plot(ax, title=f'Oriented Edges ({nx}\u00d7{ny})', + xlabel='x', ylabel='y', plotarea='#f8f9fa', grid=False, **_FS2) + ax.grid(True, alpha=0.15, linestyle='--') + + ax2 = axes[1] + ax2.imshow(A, cmap='RdBu_r', vmin=-1.5, vmax=1.5, aspect='auto', + interpolation='nearest') + + for e in range(A.shape[0]): + for n in range(A.shape[1]): + if A[e, n] != 0: + label = '\u22121' if A[e, n] < 0 else '+1' + ax2.text(n, e, label, ha='center', va='center', + fontsize=5, fontweight='bold', + color='white' if abs(A[e, n]) > 0.5 else 'black') + + if grid.n_edges_x > 0 and grid.n_edges_y > 0: + ax2.axhline(y=grid.n_edges_x - 0.5, color='#2c3e50', linewidth=1.2) + + if grid.n_edges_x > 0: + ax2.text(-1.2, (grid.n_edges_x - 1) / 2, 'H', ha='center', va='center', + fontsize=8, fontweight='bold', color=_C4) + if grid.n_edges_y > 0: + ax2.text(-1.2, grid.n_edges_x + (grid.n_edges_y - 1) / 2, 'V', + ha='center', va='center', fontsize=8, fontweight='bold', color=_C3) + + format_plot(ax2, title=f'Incidence A ({grid.n_edges}\u00d7{grid.size})', + xlabel='Node', ylabel='Edge', + plotarea='white', grid=False, **_FS2) + plt.tight_layout() + plt.show() + + +def plot_scalar_field(X, Y, f, title='', clabel='f(x,y)', cmap='RdBu_r', + figsize=(_W1, _H1), ax=None, fig=None): + """Pcolormesh of a scalar field with colorbar.""" + show = ax is None + if ax is None: + fig, ax = plt.subplots(figsize=figsize) + im = ax.pcolormesh(X, Y, f, cmap=cmap, shading='auto') + if fig is not None: + fig.colorbar(im, ax=ax, label=clabel) + ax.set_aspect('equal') + format_plot(ax, title=title, xlabel='x', ylabel='y', grid=False, + plotarea='white', **_FS2) + if show: + plt.tight_layout() + plt.show() + return ax + + +def plot_field_panels(X, Y, fields, titles, cmap='RdBu_r', figsize=None, + suptitle=None, equal_aspect=True): + """Row of pcolormesh panels (always >= 2 panels). + + Parameters + ---------- + fields : list of 2-D arrays + titles : list of str + """ + n = max(len(fields), 2) + if figsize is None: + figsize = (min(_WFULL, 3.2 * n + 0.5), 3) + fig, axes = plt.subplots(1, n, figsize=figsize) + if n == 1: + axes = [axes] + fs = _FS3 if n >= 3 else _FS2 + for ax, data, t in zip(axes, fields, titles): + im = ax.pcolormesh(X, Y, data, cmap=cmap, shading='auto') + fig.colorbar(im, ax=ax) + if equal_aspect: + ax.set_aspect('equal') + format_plot(ax, title=t, xlabel='x', ylabel='y', grid=False, + plotarea='white', **fs) + for j in range(len(fields), n): + axes[j].set_visible(False) + if suptitle: + plt.suptitle(suptitle, fontsize=12) + plt.tight_layout() + plt.show() + + +def plot_gradient_vecfield(X, Y, f, grad_x, grad_y, step=3, + figsize=(_W1, _H1), ax=None, fig=None): + """Scalar field background + gradient vector field overlay.""" + show = ax is None + if ax is None: + fig, ax = plt.subplots(figsize=figsize) + Xs = X[::step, ::step] + Ys = Y[::step, ::step] + Us = grad_x[::step, ::step] + Vs = grad_y[::step, ::step] + + ax.pcolormesh(X, Y, f, cmap='Greys', shading='auto', alpha=0.3) + sm = plot_vecfield(ax, Xs, Ys, Us, Vs, scale=150, width=0.003) + if fig is not None: + fig.colorbar(sm, ax=ax, label='Angle (rad)') + ax.set_aspect('equal') + format_plot(ax, title='Gradient Vector Field', xlabel='x', ylabel='y', + grid=False, plotarea='white', **_FS2) + if show: + plt.tight_layout() + plt.show() + return ax + + +def plot_div_curl(X, Y, u_field, v_field, div_uv, curl_uv, step=3, + figsize=(_W3, _H3)): + """Vector field + divergence + curl pcolormesh (3-panel).""" + fig, axes = plt.subplots(1, 3, figsize=figsize) + + axes[0].quiver(X[::step, ::step], Y[::step, ::step], + u_field[::step, ::step], v_field[::step, ::step], + color=_C1) + axes[0].set_aspect('equal') + format_plot(axes[0], title='Vector Field (u, v)', xlabel='x', ylabel='y', + grid=False, plotarea='white', **_FS3) + + im1 = axes[1].pcolormesh(X, Y, div_uv, cmap='RdBu_r', shading='auto') + fig.colorbar(im1, ax=axes[1]) + axes[1].set_aspect('equal') + format_plot(axes[1], title='Divergence', xlabel='x', + ylabel='y', grid=False, plotarea='white', **_FS3) + + im2 = axes[2].pcolormesh(X, Y, curl_uv, cmap='RdBu_r', shading='auto') + fig.colorbar(im2, ax=axes[2]) + axes[2].set_aspect('equal') + format_plot(axes[2], title='Curl', xlabel='x', + ylabel='y', grid=False, plotarea='white', **_FS3) + + plt.tight_layout() + plt.show() + + +def plot_hodge_rotation(X, Y, f, grad_x, grad_y, rot_x, rot_y, step=3, + figsize=(_W2, _H2)): + """Gradient vs Hodge-rotated gradient quiver plots (2-panel).""" + fig, axes = plt.subplots(1, 2, figsize=figsize) + + axes[0].pcolormesh(X, Y, f, cmap='Greys', shading='auto', alpha=0.3) + axes[0].quiver(X[::step, ::step], Y[::step, ::step], + grad_x[::step, ::step], grad_y[::step, ::step], + color=_C1) + axes[0].set_aspect('equal') + format_plot(axes[0], title='Gradient Field', xlabel='x', ylabel='y', + grid=False, plotarea='white', **_FS2) + + axes[1].pcolormesh(X, Y, f, cmap='Greys', shading='auto', alpha=0.3) + axes[1].quiver(X[::step, ::step], Y[::step, ::step], + rot_x[::step, ::step], rot_y[::step, ::step], + color=_C2) + axes[1].set_aspect('equal') + format_plot(axes[1], title='Hodge Star (90\u00b0 Rotation)', xlabel='x', + ylabel='y', grid=False, plotarea='white', **_FS2) + + plt.tight_layout() + plt.show() + + +def plot_eigenmodes(X, Y, vals, vecs, ny, nx, k=9, figsize=(_WFULL, 5.5)): + """3x3 grid of Laplacian eigenmodes.""" + fig, axes = plt.subplots(3, 3, figsize=figsize) + for i, ax in enumerate(axes.ravel()): + if i >= len(vals): + ax.set_visible(False) + continue + mode = vecs[:, i].reshape(ny, nx) + ax.pcolormesh(X, Y, mode, cmap='RdBu_r', shading='auto') + ax.set_aspect('equal') + ax.set_xticks([]) + ax.set_yticks([]) + format_plot(ax, title=f'Mode {i}, \u03bb={vals[i]:.3f}', + grid=False, plotarea='white', **_FS3) + plt.suptitle('Laplacian Eigenmodes', fontsize=12, fontweight='bold') + plt.tight_layout() + plt.show() + + +# --------------------------------------------------------------------------- +# Spectral analysis utilities +# --------------------------------------------------------------------------- + +def plot_vecfield_gallery(X, Y, fields, step=3, figsize=(_WFULL, 5.5)): + """2x2 vector field gallery using plot_vecfield. + + Parameters + ---------- + fields : dict of {name: (U, V)} tuples + """ + fig, axes = plt.subplots(2, 2, figsize=figsize) + for ax, (name, (U, V)) in zip(axes.ravel(), fields.items()): + sm = plot_vecfield(ax, X[::step, ::step], Y[::step, ::step], + U[::step, ::step], V[::step, ::step], + scale=30, width=0.004) + format_plot(ax, title=name, xlabel='x', ylabel='y', grid=False, + **_FS3) + plt.tight_layout() + plt.show() + + +def plot_graph_operators(matrices, titles, cmaps=None, vranges=None, + suptitle='', figsize=None): + """Grid of imshow plots for graph matrices.""" + n = len(matrices) + ncols = min(n, 4) + nrows = (n + ncols - 1) // ncols + if figsize is None: + figsize = (min(_WFULL, 3.2 * ncols), 3 * nrows) + if cmaps is None: + cmaps = ['RdBu_r'] * n + fig, axes = plt.subplots(nrows, ncols, figsize=figsize) + axes_flat = np.array(axes).ravel() if n > 1 else [axes] + fs = _FS3 if ncols >= 3 else {} + for i, (ax, M, t, cm) in enumerate(zip(axes_flat, matrices, titles, cmaps)): + kwargs = {'cmap': cm, 'aspect': 'auto'} + if vranges and i < len(vranges) and vranges[i]: + kwargs['vmin'], kwargs['vmax'] = vranges[i] + ax.imshow(M, **kwargs) + format_plot(ax, title=t, xlabel='Column', ylabel='Row', + plotarea='white', grid=False, **fs) + # Hide extra axes + for j in range(n, len(axes_flat)): + axes_flat[j].set_visible(False) + if suptitle: + plt.suptitle(suptitle, fontsize=12) + plt.tight_layout() + plt.show() + + +def plot_normlap_spectrum(L_norm, evals, figsize=(_W2, _H2)): + """Normalized Laplacian image + eigenvalue stem plot (2-panel).""" + fig, axes = plt.subplots(1, 2, figsize=figsize) + + axes[0].imshow(L_norm, cmap='RdBu_r') + format_plot(axes[0], title='Normalized Cycle Laplacian', + plotarea='white', grid=False, **_FS2) + + axes[1].stem(evals, basefmt=' ') + axes[1].axhline(y=2, color=_LIMIT, linestyle='--', alpha=0.5, label='eig=2') + format_plot(axes[1], title='Eigenvalue Spectrum', + xlabel='Index', ylabel='Eigenvalue', + plotarea='white', **_FS2) + axes[1].legend(fontsize=7) + + plt.tight_layout() + plt.show() + + +def plot_hermitify(M, H, figsize=(_W2, _H2)): + """Side-by-side |M| vs |H| images (2-panel).""" + fig, axes = plt.subplots(1, 2, figsize=figsize) + axes[0].imshow(np.abs(M), cmap='viridis') + format_plot(axes[0], title='|M| (complex symmetric)', + plotarea='white', grid=False, **_FS2) + axes[1].imshow(np.abs(H), cmap='viridis') + format_plot(axes[1], title='|H| (Hermitian)', + plotarea='white', grid=False, **_FS2) + plt.tight_layout() + plt.show() + + +def plot_colormap_scales(scales, figsize=(_WFULL, 1.8)): + """Show darker_hsv_colormap at different scales.""" + fig, axes = plt.subplots(1, len(scales), figsize=figsize) + if len(scales) == 1: + axes = [axes] + gradient = np.linspace(-np.pi, np.pi, 256).reshape(1, -1) + fs = _FS3 if len(scales) >= 3 else {} + for ax, scale in zip(axes, scales): + cmap = darker_hsv_colormap(scale) + ax.imshow(gradient, aspect='auto', cmap=cmap) + format_plot(ax, title=f'darker_hsv_colormap(scale={scale})', + plotarea='white', grid=False, **fs) + ax.set_yticks([]) + plt.tight_layout() + plt.show() + + +def plot_colormap_2d(LON, LAT, theta, scales, figsize=(_WFULL, 4)): + """1D gradient + 2D angle field at multiple colormap scales.""" + gradient = np.linspace(-np.pi, np.pi, 256).reshape(1, -1) + + fig, axes = plt.subplots(2, len(scales), figsize=figsize) + fs = _FS3 if len(scales) >= 3 else {} + for ax, scale in zip(axes[0], scales): + cmap = darker_hsv_colormap(scale) + ax.imshow(gradient, aspect='auto', cmap=cmap) + format_plot(ax, title=f'scale={scale}', plotarea='white', + grid=False, **fs) + ax.set_yticks([]) + for ax, scale in zip(axes[1], scales): + cmap = darker_hsv_colormap(scale) + ax.pcolormesh(LON, LAT, theta, cmap=cmap, shading='auto') + format_plot(ax, title=f'Angle field (scale={scale})', + plotarea='white', grid=False, **fs) + ax.set_aspect('equal') + plt.suptitle('darker_hsv_colormap at Different Scales', fontsize=12) + plt.tight_layout() + plt.show() + + +def plot_borders(shapes, figsize=(_W2, _H2)): + """Side-by-side geographic borders.""" + fig, axes = plt.subplots(1, len(shapes), figsize=figsize) + if len(shapes) == 1: + axes = [axes] + fs = _FS3 if len(shapes) >= 3 else {} + for ax, shape in zip(axes, shapes): + border(ax, shape) + format_plot(ax, title=f'{shape} Border', + xlabel=r'Longitude ($^\circ$E)', + ylabel=r'Latitude ($^\circ$N)', + plotarea='white', grid=False, **fs) + ax.set_aspect('equal') + plt.tight_layout() + plt.show() + + +def plot_network_map(lines, lon, lat, shape, pad=0.5, + figsize=(_W2, 2.8), ax=None, fig=None): + """Transmission network on geographic background.""" + show = ax is None + if ax is None: + fig, ax = plt.subplots(figsize=figsize) + border(ax, shape) + plot_lines(ax, lines, ms=8, lw=0.8) + ax.set_xlim(lon.min() - pad, lon.max() + pad) + ax.set_ylim(lat.min() - pad, lat.max() + pad) + format_plot(ax, title='Transmission Network', + xlabel=r'Lon ($^\circ$E)', + ylabel=r'Lat ($^\circ$N)', + plotarea='white', grid=False, **_FS2) + ax.set_aspect('equal') + if show: + plt.tight_layout() + plt.show() + return ax + + +def plot_bus_voltages_map(lines, lon, lat, vmag, shape, pad=0.5, + figsize=(_W2, 2.8), ax=None, fig=None): + """Bus voltages colored on geographic map with network overlay.""" + show = ax is None + if ax is None: + fig, ax = plt.subplots(figsize=figsize) + border(ax, shape) + plot_lines(ax, lines, ms=3, lw=0.6) + + sc = ax.scatter(lon, lat, s=30, c=vmag, cmap='RdYlGn', vmin=0.95, vmax=1.05, + zorder=6, edgecolors='black', linewidth=0.4) + if fig is not None: + fig.colorbar(sc, ax=ax, label='V (pu)', shrink=0.7) + + ax.set_xlim(lon.min() - pad, lon.max() + pad) + ax.set_ylim(lat.min() - pad, lat.max() + pad) + format_plot(ax, title='Bus Voltages', + xlabel=r'Lon ($^\circ$E)', + ylabel=r'Lat ($^\circ$N)', + plotarea='white', grid=False, **_FS2) + ax.set_aspect('equal') + if show: + plt.tight_layout() + plt.show() + return ax + + +def plot_vecfield_map(LON, LAT, Ex, Ey, lines, shape, + figsize=(_W2, 2.8), ax=None, fig=None): + """Vector field over network with geographic border.""" + show = ax is None + if ax is None: + fig, ax = plt.subplots(figsize=figsize) + border(ax, shape) + plot_lines(ax, lines, ms=3, lw=0.4) + + sm = plot_vecfield(ax, LON, LAT, Ex, Ey, scale=30, width=0.003) + if fig is not None: + fig.colorbar(sm, ax=ax, label='Angle (rad)', shrink=0.7) + + ax.set_xlim(LON.min(), LON.max()) + ax.set_ylim(LAT.min(), LAT.max()) + format_plot(ax, title='Vector Field over Network', + xlabel=r'Lon ($^\circ$E)', + ylabel=r'Lat ($^\circ$N)', + grid=False, **_FS2) + ax.set_aspect('equal') + if show: + plt.tight_layout() + plt.show() + return ax + + +def plot_format_showcase(x_data, figsize=(_W3, _H3)): + """Showcase of format_plot styling options (3-panel).""" + fig, axes = plt.subplots(1, 3, figsize=figsize) + + axes[0].plot(x_data, np.sin(x_data), 'o-', markersize=3, color=_C1) + format_plot(axes[0], title='Default Style', xlabel='x', ylabel='sin(x)', + **_FS3) + + axes[1].plot(x_data, np.cos(x_data), 'o-', markersize=3, color=_C2) + format_plot(axes[1], title='Colored Background', xlabel='x', ylabel='cos(x)', + plotarea='#f0f0f0', **_FS3) + + axes[2].plot(x_data, np.sin(x_data) * np.exp(-x_data / 5), 'o-', + markersize=3, color=_C3) + format_plot(axes[2], title='Custom Ticks', xlabel='x', ylabel='y', + xlim=(0, 10), ylim=(-1, 1), xticksep=2.5, yticksep=0.5, **_FS3) + + plt.tight_layout() + plt.show() diff --git a/esapp/utils/shapes/Texas/Shape.cpg b/examples/shapes/Texas/Shape.cpg similarity index 100% rename from esapp/utils/shapes/Texas/Shape.cpg rename to examples/shapes/Texas/Shape.cpg diff --git a/esapp/utils/shapes/Texas/Shape.dbf b/examples/shapes/Texas/Shape.dbf similarity index 100% rename from esapp/utils/shapes/Texas/Shape.dbf rename to examples/shapes/Texas/Shape.dbf diff --git a/esapp/utils/shapes/Texas/Shape.prj b/examples/shapes/Texas/Shape.prj similarity index 100% rename from esapp/utils/shapes/Texas/Shape.prj rename to examples/shapes/Texas/Shape.prj diff --git a/esapp/utils/shapes/Texas/Shape.shp b/examples/shapes/Texas/Shape.shp similarity index 100% rename from esapp/utils/shapes/Texas/Shape.shp rename to examples/shapes/Texas/Shape.shp diff --git a/esapp/utils/shapes/Texas/Shape.shx b/examples/shapes/Texas/Shape.shx similarity index 100% rename from esapp/utils/shapes/Texas/Shape.shx rename to examples/shapes/Texas/Shape.shx diff --git a/esapp/utils/shapes/US/Shape.cpg b/examples/shapes/US/Shape.cpg similarity index 100% rename from esapp/utils/shapes/US/Shape.cpg rename to examples/shapes/US/Shape.cpg diff --git a/esapp/utils/shapes/US/Shape.dbf b/examples/shapes/US/Shape.dbf similarity index 100% rename from esapp/utils/shapes/US/Shape.dbf rename to examples/shapes/US/Shape.dbf diff --git a/esapp/utils/shapes/US/Shape.prj b/examples/shapes/US/Shape.prj similarity index 100% rename from esapp/utils/shapes/US/Shape.prj rename to examples/shapes/US/Shape.prj diff --git a/esapp/utils/shapes/US/Shape.shp b/examples/shapes/US/Shape.shp similarity index 100% rename from esapp/utils/shapes/US/Shape.shp rename to examples/shapes/US/Shape.shp diff --git a/esapp/utils/shapes/US/Shape.shp.ea.iso.xml b/examples/shapes/US/Shape.shp.ea.iso.xml similarity index 100% rename from esapp/utils/shapes/US/Shape.shp.ea.iso.xml rename to examples/shapes/US/Shape.shp.ea.iso.xml diff --git a/esapp/utils/shapes/US/Shape.shx b/examples/shapes/US/Shape.shx similarity index 100% rename from esapp/utils/shapes/US/Shape.shx rename to examples/shapes/US/Shape.shx diff --git a/esapp/utils/shapes/US/Shape.xml b/examples/shapes/US/Shape.xml similarity index 100% rename from esapp/utils/shapes/US/Shape.xml rename to examples/shapes/US/Shape.xml diff --git a/examples/statics.py b/examples/statics.py new file mode 100644 index 00000000..73ca50b4 --- /dev/null +++ b/examples/statics.py @@ -0,0 +1,405 @@ +""" +Static Analysis Example +======================= + +Advanced static analysis tools built on top of the esapp PowerWorld. +Provides continuation power flow, state chain management, ZIP load +injection, generator limit checking, and random load variation. + +Example +------- + >>> from esapp import PowerWorld + >>> from examples.statics import Statics + >>> pw = PowerWorld("case.pwb") + >>> s = Statics(pw) + >>> interface = np.array([1, -1, 0, ...]) + >>> for mw in s.continuation_pf(interface, maxiter=100): + ... print(f"Converged at {mw:.2f} MW") +""" + +import warnings +from typing import Optional, Iterator + +import numpy as np +from numpy import exp, any +from pandas import DataFrame + +from esapp.components import Gen, Load, Bus + +warnings.simplefilter(action="ignore", category=FutureWarning) + +__all__ = ['Statics'] + + +class Statics: + """ + Advanced static analysis application using a PowerWorld instance. + + Parameters + ---------- + pw : PowerWorld + An initialized PowerWorld instance. + """ + + def __init__(self, pw) -> None: + self.pw = pw + self._gen_limits_cached = False + self._dispatch_initialized = False + + # ------------------------------------------------------------------ + # Lazy initialization helpers + # ------------------------------------------------------------------ + + def _ensure_gen_limits(self) -> None: + """Cache generator limits from PowerWorld on first access.""" + if self._gen_limits_cached: + return + gens = self.pw[Gen, ['GenMVRMin', 'GenMVRMax', 'GenMWMax', 'GenMWMin']] + self.genqmax = gens['GenMVRMax'] + self.genqmin = gens['GenMVRMin'] + self.genpmax = gens['GenMWMax'] + self.genpmin = gens['GenMWMin'] + self._gen_limits_cached = True + + _ZIP_FIELDS = ['LoadSMW', 'LoadSMVR', 'LoadIMW', 'LoadIMVR', + 'LoadZMW', 'LoadZMVR'] + + def _ensure_dispatch(self) -> None: + """Create dispatch loads (LoadID='99') at every bus if not yet done.""" + if self._dispatch_initialized: + return + + buses = self.pw[Bus, ['BusNum', 'BusName_NomVolt']] + + dispatch = DataFrame({ + 'BusNum': buses['BusNum'].values, + 'BusName_NomVolt': buses['BusName_NomVolt'].values, + 'LoadID': '99', + 'LoadStatus': 'Closed', + **{zf: 0.0 for zf in self._ZIP_FIELDS}, + }) + + self.pw.esa.EnterMode('EDIT') + try: + self.pw[Load] = dispatch + finally: + self.pw.esa.EnterMode('RUN') + + self.DispatchPQ = dispatch[['BusNum', 'LoadID'] + self._ZIP_FIELDS].copy() + self._dispatch_initialized = True + + # ------------------------------------------------------------------ + # Generator limit checking + # ------------------------------------------------------------------ + + def gens_above_pmax( + self, + p: Optional[np.ndarray] = None, + is_closed: Optional[np.ndarray] = None, + tol: float = 0.001, + ) -> bool: + """Check if any closed generators exceed P limits.""" + self._ensure_gen_limits() + if p is None: + p = self.pw[Gen, 'GenMW']['GenMW'] + is_high = p > self.genpmax + tol + is_low = p < self.genpmin - tol + if is_closed is None: + is_closed = self.pw[Gen, 'GenStatus']['GenStatus'] == 'Closed' + violation = is_closed & (is_high | is_low) + return any(violation) + + def gens_above_qmax( + self, + q: Optional[np.ndarray] = None, + is_closed: Optional[np.ndarray] = None, + tol: float = 0.001, + ) -> bool: + """Check if any closed generators exceed Q limits.""" + self._ensure_gen_limits() + if q is None: + q = self.pw[Gen, 'GenMVR']['GenMVR'] + is_high = q > self.genqmax + tol + is_low = q < self.genqmin - tol + if is_closed is None: + is_closed = self.pw[Gen, 'GenStatus']['GenStatus'] == 'Closed' + violation = is_closed & (is_high | is_low) + return any(violation) + + # ------------------------------------------------------------------ + # Continuation power flow (predictor-corrector) + # ------------------------------------------------------------------ + + @staticmethod + def _build_cpf_dFdlam( + interface: np.ndarray, + bus_to_idx: dict, + jac_ids: list, + sbase: float, + n_jac: int = 0, + ) -> np.ndarray: + """Map a bus-indexed interface vector into Jacobian row ordering.""" + dF = np.zeros(n_jac if n_jac > 0 else len(jac_ids)) + for row, raw_label in enumerate(jac_ids): + parts = raw_label.strip().strip("'\"").split() + if len(parts) < 2: + continue + if not parts[0].lower().startswith('dp'): + continue + try: + bus = int(parts[1]) + except ValueError: + continue + idx = bus_to_idx.get(bus) + if idx is not None: + dF[row] = -interface[idx] / sbase + return dF + + def _cpf_halve_step(self, step: float, min_step: float) -> float: + """Return ``step / 2``, or ``-1`` if below *min_step*.""" + step *= 0.5 + return step if step >= min_step else -1.0 + + def continuation_pf( + self, + interface: np.ndarray, + initialmw: float = 0, + step_size: float = 0.05, + min_step: float = 0.001, + max_step: float = 0.1, + maxiter: int = 200, + verbose: bool = False, + restore_when_done: bool = False, + qlim_tol: Optional[float] = 0, + plim_tol: Optional[float] = None, + sbase: float = 100.0, + ) -> Iterator[float]: + """Predictor-corrector continuation power flow. + + Yields + ------ + float + Interface transfer level (MW) after each converged solution. + """ + self._ensure_gen_limits() + self._ensure_dispatch() + + log = (lambda msg, **kw: print(msg, **kw)) if verbose else (lambda *a, **k: None) + + if restore_when_done: + self.pw.esa.StoreState('CPF_BACKUP') + + lam_current = initialmw + self.setload(SP=-lam_current * interface) + self.pw.pflow(getvolts=False) + self.pw.esa.StoreState('CPF_PREV') + yield lam_current + + J0, jac_ids = self.pw.jacobian(dense=True, form='P', ids=True) + n_jac = J0.shape[0] + + bus_nums = self.pw[Bus, 'BusNum']['BusNum'].to_numpy() + bus_to_idx = {int(b): i for i, b in enumerate(bus_nums)} + + dF_dlam = self._build_cpf_dFdlam(interface, bus_to_idx, jac_ids, sbase, n_jac) + + step = step_size + cont_param = n_jac + tangent_prev = np.zeros(n_jac + 1) + tangent_prev[-1] = 1.0 + crossed_nose = False + + for it in range(maxiter): + J, _ = self.pw.jacobian(dense=True, form='P', ids=True) + + J_aug = np.zeros((n_jac + 1, n_jac + 1)) + J_aug[:n_jac, :n_jac] = J + J_aug[:n_jac, n_jac] = dF_dlam + J_aug[n_jac, cont_param] = 1.0 + + rhs = np.zeros(n_jac + 1) + rhs[n_jac] = 1.0 + + try: + tangent = np.linalg.solve(J_aug, rhs) + except np.linalg.LinAlgError: + log(f' [{it}] Singular augmented Jacobian') + step = self._cpf_halve_step(step, min_step) + if step < 0: + break + continue + + tnorm = np.linalg.norm(tangent) + if tnorm < 1e-15: + break + tangent /= tnorm + if np.dot(tangent, tangent_prev) < 0: + tangent = -tangent + + lam_pred = lam_current + step * tangent[-1] + log(f' [{it}] Predict: lam={lam_pred:.2f} MW ' + f'(step={step:.4f}, dlam={step * tangent[-1]:.2f})', + end='') + + self.setload(SP=-lam_pred * interface) + try: + self.pw.pflow(getvolts=False) + except Exception: + log(' FAIL', end='') + step = self._cpf_halve_step(step, min_step) + if step < 0: + log(f'\n Step below minimum ({min_step})') + break + self.pw.esa.RestoreState('CPF_PREV') + log(f' -> retry (step={step:.4f})') + continue + + reject = False + if qlim_tol is not None: + gen_df = self.pw[Gen, ['GenMVR', 'GenStatus']] + closed = gen_df['GenStatus'] == 'Closed' + if self.gens_above_qmax(gen_df['GenMVR'], closed, tol=qlim_tol): + log(' Q-LIM', end='') + reject = True + + if not reject and plim_tol is not None: + if self.gens_above_pmax(tol=plim_tol): + log(' P-LIM', end='') + reject = True + + if reject: + step = self._cpf_halve_step(step, min_step) + if step < 0: + break + self.pw.esa.RestoreState('CPF_PREV') + continue + + if tangent_prev[-1] > 0 and tangent[-1] < 0: + crossed_nose = True + log(' NOSE', end='') + + if abs(tangent[-1]) < 0.1: + n_half = n_jac // 2 + v_sens = np.abs(tangent[n_half:n_jac]) + if len(v_sens) > 0: + best = int(np.argmax(v_sens)) + n_half + if cont_param != best: + cont_param = best + log(f' SWITCH(V[{best - n_half}])', end='') + else: + cont_param = n_jac + + cos_angle = np.clip(np.dot(tangent, tangent_prev), -1.0, 1.0) + angle = np.arccos(cos_angle) + if angle < 0.05: + step = min(step * 1.5, max_step) + elif angle > 0.3: + step = max(step * 0.5, min_step) + + self.pw.esa.StoreState('CPF_PREV') + tangent_prev = tangent.copy() + lam_current = lam_pred + + log(f' OK (lam={lam_current:.2f})') + yield lam_current + + if crossed_nose and lam_current < initialmw: + log(f' Lambda returned below initial ({initialmw})') + break + + self.clearloads() + if restore_when_done: + self.pw.esa.RestoreState('CPF_BACKUP') + + # ------------------------------------------------------------------ + # State chain management + # ------------------------------------------------------------------ + + def chain(self, maxstates: int = 2) -> None: + """Initialize state chain for iterative algorithms.""" + self.maxstates = maxstates + self.stateidx = -1 + + def pushstate(self, verbose: bool = False) -> None: + """Push current state onto the state chain.""" + self.stateidx += 1 + self.pw.esa.StoreState(f'GWBState{self.stateidx}') + if verbose: + print(f'Pushed States -> {self.stateidx}') + if self.stateidx >= self.maxstates: + self.pw.esa.DeleteState(f'GWBState{self.stateidx - self.maxstates}') + + def istore(self, n: int = 0, verbose: bool = False) -> None: + """Update the nth state in the chain with current state.""" + if n > self.maxstates or n > self.stateidx: + raise Exception("State index out of range") + if verbose: + print(f'Store -> {self.stateidx - n}') + self.pw.esa.StoreState(f'GWBState{self.stateidx - n}') + + def irestore(self, n: int = 1, verbose: bool = False) -> None: + """Restore the nth previous state from the chain.""" + if n > self.maxstates or n > self.stateidx: + if verbose: + print('Restoration Failure') + raise Exception("State index out of range") + if verbose: + print(f'Restore -> {self.stateidx - n}') + self.pw.esa.RestoreState(f'GWBState{self.stateidx - n}') + + # ------------------------------------------------------------------ + # ZIP load interface + # ------------------------------------------------------------------ + + def setload( + self, + SP: Optional[np.ndarray] = None, + SQ: Optional[np.ndarray] = None, + IP: Optional[np.ndarray] = None, + IQ: Optional[np.ndarray] = None, + ZP: Optional[np.ndarray] = None, + ZQ: Optional[np.ndarray] = None, + ) -> None: + """Set ZIP load components on the dispatch loads (LoadID='99').""" + self._ensure_dispatch() + + _col_map = { + 'LoadSMW': SP, 'LoadSMVR': SQ, + 'LoadIMW': IP, 'LoadIMVR': IQ, + 'LoadZMW': ZP, 'LoadZMVR': ZQ, + } + + changed_cols = [] + for col, arr in _col_map.items(): + if arr is not None: + self.DispatchPQ[col] = arr + changed_cols.append(col) + + if not changed_cols: + return + + write_cols = ['BusNum', 'LoadID'] + changed_cols + self.pw[Load] = self.DispatchPQ[write_cols] + + def clearloads(self) -> None: + """Zero all six ZIP components on the dispatch loads.""" + self._ensure_dispatch() + self.DispatchPQ[self._ZIP_FIELDS] = 0.0 + self.pw[Load] = self.DispatchPQ + + # ------------------------------------------------------------------ + # Random load variation + # ------------------------------------------------------------------ + + load_nom = None + load_df = None + + def randomize_load(self, scale: float = 1.0, sigma: float = 0.1) -> None: + """Apply random variation to system loads.""" + if self.load_nom is None or self.load_df is None: + self.load_df = self.pw[Load, 'LoadMW'] + self.load_nom = self.load_df['LoadMW'] + random_factors = exp(sigma * np.random.random(len(self.load_nom))) + self.pw[Load, 'LoadMW'] = scale * self.load_nom * random_factors + + randload = randomize_load diff --git a/examples/steady_state/01_contingency_analysis.ipynb b/examples/steady_state/01_contingency_analysis.ipynb new file mode 100644 index 00000000..21b8f809 --- /dev/null +++ b/examples/steady_state/01_contingency_analysis.ipynb @@ -0,0 +1,113 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a1b2c3d4", + "metadata": {}, + "source": [ + "# Contingency Analysis\n", + "\n", + "Automating N-1 contingency analysis and retrieving results." + ] + }, + { + "cell_type": "markdown", + "id": "b2c3d4e5", + "metadata": {}, + "source": "Import the case and instantiate the `PowerWorld`.\n\n```python\nfrom esapp import PowerWorld\nfrom esapp.components import *\n\npw = PowerWorld(case_path)\n```" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c3d4e5f6", + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": "# This cell is hidden in the documentation.\nfrom esapp import PowerWorld\nfrom esapp.components import *\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport ast\n\nwith open('../data/case.txt', 'r') as f:\n case_path = ast.literal_eval(f.read().strip())\n\npw = PowerWorld(case_path)" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": [ + "# Plotting functions (hidden from documentation)\n", + "import sys; sys.path.insert(0, \"..\")\n", + "from plot_helpers import plot_contingency_results" + ] + }, + { + "cell_type": "markdown", + "id": "d4e5f6a7", + "metadata": {}, + "source": [ + "## Automated N-1 Contingency Analysis\n", + "\n", + "ESAplus provides built-in support for N-1 contingency analysis through the SAW interface. First, create and solve contingencies for all branches:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e5f6a7b8", + "metadata": {}, + "outputs": [], + "source": "pw.pflow() # Solve base case first\npw.auto_insert_contingencies() # Create N-1 contingencies\npw.solve_contingencies() # Solve all contingency scenarios" + }, + { + "cell_type": "markdown", + "id": "f6a7b8c9", + "metadata": {}, + "source": [ + "## Retrieve Violations\n", + "\n", + "After solving contingencies, retrieve all violations found during the analysis:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a7b8c9d0", + "metadata": {}, + "outputs": [], + "source": "violations = pw[ViolationCTG, :]\nprint(f\"Total violations: {len(violations)}\")\nviolations.head()" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plot_contingency_results(violations)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "esaplus", + "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.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file diff --git a/examples/steady_state/02_scopf_analysis.ipynb b/examples/steady_state/02_scopf_analysis.ipynb new file mode 100644 index 00000000..ae00c2f0 --- /dev/null +++ b/examples/steady_state/02_scopf_analysis.ipynb @@ -0,0 +1,117 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "aa1b2c3d", + "metadata": {}, + "source": [ + "# Security Constrained OPF (SCOPF)\n", + "\n", + "Finds least-cost dispatch satisfying base-case and N-1 constraints." + ] + }, + { + "cell_type": "markdown", + "id": "ab2c3d4e", + "metadata": {}, + "source": "Import the case and instantiate the `PowerWorld`.\n\n```python\nfrom esapp import PowerWorld\nfrom esapp.components import *\n\npw = PowerWorld(case_path)\n```" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ac3d4e5f", + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": "# This cell is hidden in the documentation.\nfrom esapp import PowerWorld\nfrom esapp.components import *\nimport matplotlib.pyplot as plt\nimport ast\n\nwith open('../data/case.txt', 'r') as f:\n case_path = ast.literal_eval(f.read().strip())\n\npw = PowerWorld(case_path)" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": [ + "# Plotting functions (hidden from documentation)\n", + "import sys; sys.path.insert(0, \"..\")\n", + "from plot_helpers import plot_dual_bar" + ] + }, + { + "cell_type": "markdown", + "id": "ad4e5f6a", + "metadata": {}, + "source": [ + "## Setup SCOPF Optimization\n", + "\n", + "Initialize the solver and prepare contingency constraints for the security-constrained problem:" + ] + }, + { + "cell_type": "markdown", + "id": "ae5f6a7b", + "metadata": {}, + "source": [ + "The Primal LP solver is PowerWorld's optimization engine. Auto-insert N-1 contingencies to make the optimization security-constrained:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "af6a7b8c", + "metadata": {}, + "outputs": [], + "source": "# Capture pre-OPF dispatch\npre_opf = pw[Gen, ['BusNum', 'GenMW', 'GenStatus']]\npre_opf_online = pre_opf[pre_opf['GenStatus'] == 'Closed'].copy()\n\npw.esa.InitializePrimalLP()\npw.auto_insert_contingencies()" + }, + { + "cell_type": "markdown", + "id": "b07b8c9d", + "metadata": {}, + "source": [ + "## Solve SCOPF" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b18c9d0e", + "metadata": {}, + "outputs": [], + "source": "pw.esa.SolveFullSCOPF()\n\nproduction_cost = pw[Area, \"GenProdCost\"]\nprint(\"Production Cost by Area:\")\nprint(production_cost.to_string(index=False))" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": "post_opf = pw[Gen, ['BusNum', 'GenMW', 'GenStatus']]\npost_opf_online = post_opf[post_opf['GenStatus'] == 'Closed'].copy()\n\nfig, axes = plt.subplots(1, 2, figsize=(6.5, 2.8))\nplot_dual_bar(pre_opf_online['GenMW'].values, post_opf_online['GenMW'].values,\n label_a='Pre-OPF', label_b='Post-OPF',\n xlabel='Generator Index', ylabel='MW Output',\n title='Dispatch Comparison', ax=axes[0])\n# Redispatch delta\ndelta = post_opf_online['GenMW'].values - pre_opf_online['GenMW'].values\ncolors = ['#55A868' if d >= 0 else '#C44E52' for d in delta]\naxes[1].bar(range(len(delta)), delta, color=colors)\nfrom examples.map import format_plot\nformat_plot(axes[1], title='Redispatch Delta',\n xlabel='Generator Index', ylabel='\\u0394 MW',\n plotarea='white', titlesize=11, labelsize=9, ticksize=8)\nplt.tight_layout()\nplt.show()" + } + ], + "metadata": { + "kernelspec": { + "display_name": "esaplus", + "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.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file diff --git a/examples/steady_state/03_atc_analysis.ipynb b/examples/steady_state/03_atc_analysis.ipynb new file mode 100644 index 00000000..0e1d5211 --- /dev/null +++ b/examples/steady_state/03_atc_analysis.ipynb @@ -0,0 +1,61 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "ca1b2c3d", + "metadata": {}, + "source": [ + "# Available Transfer Capability (ATC) Studies\n", + "\n", + "Determining the maximum power that can be transferred between two areas without violating system limits, considering N-1 contingencies." + ] + }, + { + "cell_type": "markdown", + "id": "cb2c3d4e", + "metadata": {}, + "source": "Import the case and instantiate the `PowerWorld`.\n\n```python\nfrom esapp import PowerWorld\nfrom esapp.components import *\nfrom esapp.saw._helpers import create_object_string\n\npw = PowerWorld(case_path)\n```" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cc3d4e5f", + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": "# This cell is hidden in the documentation.\nfrom esapp import PowerWorld\nfrom esapp.components import *\nfrom esapp.saw._helpers import create_object_string\nimport ast\n\nwith open('../data/case.txt', 'r') as f:\n case_path = ast.literal_eval(f.read().strip())\n\npw = PowerWorld(case_path)" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cd4e5f6a", + "metadata": {}, + "outputs": [], + "source": "areas = pw[Area, ['AreaNum', 'AreaName']]\nif len(areas) >= 2:\n seller = create_object_string(\"Area\", areas.iloc[0]['AreaNum'])\n buyer = create_object_string(\"Area\", areas.iloc[1]['AreaNum'])\n \n pw.esa.SetData(\"ATC_Options\", [\"Method\"], [\"IteratedLinearThenFull\"])\n pw.esa.DetermineATC(seller, buyer, do_distributed=False, do_multiple_scenarios=False)" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ce5f6a7b", + "metadata": {}, + "outputs": [], + "source": "results = pw.esa.GetATCResults([\"MaxFlow\", \"LimitingContingency\", \"LimitingElement\"])\n\nif results is not None and not results.empty:\n atc_results = results.iloc[0]\n print(f\"ATC Results:\")\n print(f\" Maximum Transfer: {atc_results['MaxFlow']:.1f} MW\")\n print(f\" Limiting Contingency: {atc_results['LimitingContingency']}\")\n print(f\" Limiting Element: {atc_results['LimitingElement']}\")" + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "name": "python", + "version": "3.11.0" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file diff --git a/examples/steady_state/04_continuation_power_flow.ipynb b/examples/steady_state/04_continuation_power_flow.ipynb new file mode 100644 index 00000000..76c93190 --- /dev/null +++ b/examples/steady_state/04_continuation_power_flow.ipynb @@ -0,0 +1,578 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "da1b2c3d", + "metadata": {}, + "source": [ + "# Continuation Power Flow\n", + "\n", + "Demonstrates continuation power flow (CPF) analysis for voltage stability\n", + "assessment. The notebook sets up interface transfers, runs the CPF solver\n", + "to trace the PV curve, and visualizes the nose point that marks the voltage\n", + "stability limit." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "from esapp import PowerWorld\n", + "from esapp.components import *\n", + "from examples.statics import Statics" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "dc3d4e5f", + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "'open' took: 9.6130 sec\n" + ] + } + ], + "source": [ + "# This cell is hidden in the documentation.\n", + "import ast\n", + "\n", + "with open('../data/case.txt', 'r') as f:\n", + " case_path = ast.literal_eval(f.read().strip())\n", + "\n", + "pw = PowerWorld(case_path)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": [ + "# Plotting functions (hidden from documentation)\n", + "import sys; sys.path.insert(0, \"..\")\n", + "from plot_helpers import plot_pv_curve" + ] + }, + { + "cell_type": "markdown", + "id": "dd4e5f6a", + "metadata": {}, + "source": [ + "## 1. Define Interface Transfer\n", + "\n", + "The continuation power flow traces the PV curve by increasing a transfer\n", + "pattern (the `interface` vector) and solving power flow at each step. It uses\n", + "a predictor-corrector method with tangent vectors from the augmented Jacobian\n", + "for accurate nose-point tracking." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "de5f6a7b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Base case min voltage: 0.9749 pu\n", + "Critical bus index: 10\n", + "Critical bus voltage: 0.9749 pu\n" + ] + } + ], + "source": [ + "s = Statics(pw)\n", + "\n", + "# Solve base case\n", + "V_base = pw.pflow()\n", + "print(f\"Base case min voltage: {np.abs(V_base).min():.4f} pu\")\n", + "\n", + "# Critical bus: lowest voltage magnitude\n", + "critical_bus_idx = np.argmin(np.abs(V_base))\n", + "print(f\"Critical bus index: {critical_bus_idx}\")\n", + "print(f\"Critical bus voltage: {np.abs(V_base[critical_bus_idx]):.4f} pu\")\n", + "\n", + "# Build interface vector: uniform load increase at all buses\n", + "n_buses = \n", + "interface = np.zeros(pw.n_bus)\n", + "interface /= np.sum(interface) # normalize to 1 MW total\n", + "interface" + ] + }, + { + "cell_type": "markdown", + "id": "df6a7b8c", + "metadata": {}, + "source": [ + "## 2. PV Curve\n", + "\n", + "The PV curve shows how voltage at a critical bus varies with increasing\n", + "power transfer. The nose point indicates the maximum transfer before\n", + "voltage collapse." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "e07b8c9d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " [0] Predict: lam=0.05 MW (step=0.0500, dlam=0.05) OK (lam=0.05)\n", + " [1] Predict: lam=0.12 MW (step=0.0750, dlam=0.08) OK (lam=0.12)\n", + " [2] Predict: lam=0.24 MW (step=0.1125, dlam=0.11) OK (lam=0.24)\n", + " [3] Predict: lam=0.41 MW (step=0.1688, dlam=0.17) OK (lam=0.41)\n", + " [4] Predict: lam=0.66 MW (step=0.2531, dlam=0.25) OK (lam=0.66)\n", + " [5] Predict: lam=1.04 MW (step=0.3797, dlam=0.38) OK (lam=1.04)\n", + " [6] Predict: lam=1.61 MW (step=0.5695, dlam=0.57) OK (lam=1.61)\n", + " [7] Predict: lam=2.46 MW (step=0.8543, dlam=0.85) OK (lam=2.46)\n", + " [8] Predict: lam=3.74 MW (step=1.2814, dlam=1.28) OK (lam=3.74)\n", + " [9] Predict: lam=5.67 MW (step=1.9222, dlam=1.92) OK (lam=5.67)\n", + " [10] Predict: lam=8.55 MW (step=2.8833, dlam=2.88) OK (lam=8.55)\n", + " [11] Predict: lam=12.87 MW (step=4.3249, dlam=4.32) OK (lam=12.87)\n", + " [12] Predict: lam=17.87 MW (step=5.0000, dlam=5.00) OK (lam=17.87)\n", + " [13] Predict: lam=22.87 MW (step=5.0000, dlam=5.00) OK (lam=22.87)\n", + " [14] Predict: lam=27.87 MW (step=5.0000, dlam=5.00) OK (lam=27.87)\n", + " [15] Predict: lam=32.87 MW (step=5.0000, dlam=5.00) OK (lam=32.87)\n", + " [16] Predict: lam=37.87 MW (step=5.0000, dlam=5.00) OK (lam=37.87)\n", + " [17] Predict: lam=42.87 MW (step=5.0000, dlam=5.00) OK (lam=42.87)\n", + " [18] Predict: lam=47.87 MW (step=5.0000, dlam=5.00) OK (lam=47.87)\n", + " [19] Predict: lam=52.87 MW (step=5.0000, dlam=5.00) OK (lam=52.87)\n", + " [20] Predict: lam=57.87 MW (step=5.0000, dlam=5.00) OK (lam=57.87)\n", + " [21] Predict: lam=62.87 MW (step=5.0000, dlam=5.00) OK (lam=62.87)\n", + " [22] Predict: lam=67.87 MW (step=5.0000, dlam=5.00) OK (lam=67.87)\n", + " [23] Predict: lam=72.87 MW (step=5.0000, dlam=5.00) OK (lam=72.87)\n", + " [24] Predict: lam=77.87 MW (step=5.0000, dlam=5.00) OK (lam=77.87)\n", + " [25] Predict: lam=82.87 MW (step=5.0000, dlam=5.00) OK (lam=82.87)\n", + " [26] Predict: lam=87.87 MW (step=5.0000, dlam=5.00) OK (lam=87.87)\n", + " [27] Predict: lam=92.87 MW (step=5.0000, dlam=5.00) OK (lam=92.87)\n", + " [28] Predict: lam=97.87 MW (step=5.0000, dlam=5.00) OK (lam=97.87)\n", + " [29] Predict: lam=102.87 MW (step=5.0000, dlam=5.00) OK (lam=102.87)\n", + " [30] Predict: lam=107.87 MW (step=5.0000, dlam=5.00) OK (lam=107.87)\n", + " [31] Predict: lam=112.87 MW (step=5.0000, dlam=5.00) OK (lam=112.87)\n", + " [32] Predict: lam=117.87 MW (step=5.0000, dlam=5.00) OK (lam=117.87)\n", + " [33] Predict: lam=122.87 MW (step=5.0000, dlam=5.00) OK (lam=122.87)\n", + " [34] Predict: lam=127.87 MW (step=5.0000, dlam=5.00) OK (lam=127.87)\n", + " [35] Predict: lam=132.87 MW (step=5.0000, dlam=5.00) OK (lam=132.87)\n", + " [36] Predict: lam=137.87 MW (step=5.0000, dlam=5.00) OK (lam=137.87)\n", + " [37] Predict: lam=142.87 MW (step=5.0000, dlam=5.00) OK (lam=142.87)\n", + " [38] Predict: lam=147.87 MW (step=5.0000, dlam=5.00) OK (lam=147.87)\n", + " [39] Predict: lam=152.87 MW (step=5.0000, dlam=5.00) OK (lam=152.87)\n", + " [40] Predict: lam=157.87 MW (step=5.0000, dlam=5.00) OK (lam=157.87)\n", + " [41] Predict: lam=162.87 MW (step=5.0000, dlam=5.00) OK (lam=162.87)\n", + " [42] Predict: lam=167.87 MW (step=5.0000, dlam=5.00) OK (lam=167.87)\n", + " [43] Predict: lam=172.87 MW (step=5.0000, dlam=5.00) OK (lam=172.87)\n", + " [44] Predict: lam=177.87 MW (step=5.0000, dlam=5.00) OK (lam=177.87)\n", + " [45] Predict: lam=182.87 MW (step=5.0000, dlam=5.00) OK (lam=182.87)\n", + " [46] Predict: lam=187.87 MW (step=5.0000, dlam=5.00) OK (lam=187.87)\n", + " [47] Predict: lam=192.87 MW (step=5.0000, dlam=5.00) OK (lam=192.87)\n", + " [48] Predict: lam=197.87 MW (step=5.0000, dlam=5.00) OK (lam=197.87)\n", + " [49] Predict: lam=202.87 MW (step=5.0000, dlam=5.00) OK (lam=202.87)\n", + " [50] Predict: lam=207.87 MW (step=5.0000, dlam=5.00) OK (lam=207.87)\n", + " [51] Predict: lam=212.87 MW (step=5.0000, dlam=5.00) OK (lam=212.87)\n", + " [52] Predict: lam=217.87 MW (step=5.0000, dlam=5.00) OK (lam=217.87)\n", + " [53] Predict: lam=222.87 MW (step=5.0000, dlam=5.00) OK (lam=222.87)\n", + " [54] Predict: lam=227.87 MW (step=5.0000, dlam=5.00) OK (lam=227.87)\n", + " [55] Predict: lam=232.87 MW (step=5.0000, dlam=5.00) OK (lam=232.87)\n", + " [56] Predict: lam=237.87 MW (step=5.0000, dlam=5.00) OK (lam=237.87)\n", + " [57] Predict: lam=242.87 MW (step=5.0000, dlam=5.00) OK (lam=242.87)\n", + " [58] Predict: lam=247.87 MW (step=5.0000, dlam=5.00) OK (lam=247.87)\n", + " [59] Predict: lam=252.87 MW (step=5.0000, dlam=5.00) OK (lam=252.87)\n", + " [60] Predict: lam=257.87 MW (step=5.0000, dlam=5.00) OK (lam=257.87)\n", + " [61] Predict: lam=262.87 MW (step=5.0000, dlam=5.00) OK (lam=262.87)\n", + " [62] Predict: lam=267.87 MW (step=5.0000, dlam=5.00) OK (lam=267.87)\n", + " [63] Predict: lam=272.87 MW (step=5.0000, dlam=5.00) OK (lam=272.87)\n", + " [64] Predict: lam=277.87 MW (step=5.0000, dlam=5.00) OK (lam=277.87)\n", + " [65] Predict: lam=282.87 MW (step=5.0000, dlam=5.00) OK (lam=282.87)\n", + " [66] Predict: lam=287.87 MW (step=5.0000, dlam=5.00) OK (lam=287.87)\n", + " [67] Predict: lam=292.87 MW (step=5.0000, dlam=5.00) OK (lam=292.87)\n", + " [68] Predict: lam=297.87 MW (step=5.0000, dlam=5.00) OK (lam=297.87)\n", + " [69] Predict: lam=302.87 MW (step=5.0000, dlam=5.00) OK (lam=302.87)\n", + " [70] Predict: lam=307.87 MW (step=5.0000, dlam=5.00) OK (lam=307.87)\n", + " [71] Predict: lam=312.87 MW (step=5.0000, dlam=5.00) OK (lam=312.87)\n", + " [72] Predict: lam=317.87 MW (step=5.0000, dlam=5.00) OK (lam=317.87)\n", + " [73] Predict: lam=322.87 MW (step=5.0000, dlam=5.00) OK (lam=322.87)\n", + " [74] Predict: lam=327.87 MW (step=5.0000, dlam=5.00) OK (lam=327.87)\n", + " [75] Predict: lam=332.87 MW (step=5.0000, dlam=5.00) OK (lam=332.87)\n", + " [76] Predict: lam=337.87 MW (step=5.0000, dlam=5.00) OK (lam=337.87)\n", + " [77] Predict: lam=342.87 MW (step=5.0000, dlam=5.00) OK (lam=342.87)\n", + " [78] Predict: lam=347.87 MW (step=5.0000, dlam=5.00) OK (lam=347.87)\n", + " [79] Predict: lam=352.87 MW (step=5.0000, dlam=5.00) OK (lam=352.87)\n", + " [80] Predict: lam=357.87 MW (step=5.0000, dlam=5.00) OK (lam=357.87)\n", + " [81] Predict: lam=362.87 MW (step=5.0000, dlam=5.00) OK (lam=362.87)\n", + " [82] Predict: lam=367.87 MW (step=5.0000, dlam=5.00) OK (lam=367.87)\n", + " [83] Predict: lam=372.87 MW (step=5.0000, dlam=5.00) OK (lam=372.87)\n", + " [84] Predict: lam=377.87 MW (step=5.0000, dlam=5.00) OK (lam=377.87)\n", + " [85] Predict: lam=382.87 MW (step=5.0000, dlam=5.00) OK (lam=382.87)\n", + " [86] Predict: lam=387.87 MW (step=5.0000, dlam=5.00) OK (lam=387.87)\n", + " [87] Predict: lam=392.87 MW (step=5.0000, dlam=5.00) OK (lam=392.87)\n", + " [88] Predict: lam=397.87 MW (step=5.0000, dlam=5.00) OK (lam=397.87)\n", + " [89] Predict: lam=402.87 MW (step=5.0000, dlam=5.00) OK (lam=402.87)\n", + " [90] Predict: lam=407.87 MW (step=5.0000, dlam=5.00) OK (lam=407.87)\n", + " [91] Predict: lam=412.87 MW (step=5.0000, dlam=5.00) OK (lam=412.87)\n", + " [92] Predict: lam=417.87 MW (step=5.0000, dlam=5.00) OK (lam=417.87)\n", + " [93] Predict: lam=422.87 MW (step=5.0000, dlam=5.00) OK (lam=422.87)\n", + " [94] Predict: lam=427.87 MW (step=5.0000, dlam=5.00) OK (lam=427.87)\n", + " [95] Predict: lam=432.87 MW (step=5.0000, dlam=5.00) OK (lam=432.87)\n", + " [96] Predict: lam=437.87 MW (step=5.0000, dlam=5.00) OK (lam=437.87)\n", + " [97] Predict: lam=442.87 MW (step=5.0000, dlam=5.00) OK (lam=442.87)\n", + " [98] Predict: lam=447.87 MW (step=5.0000, dlam=5.00) OK (lam=447.87)\n", + " [99] Predict: lam=452.87 MW (step=5.0000, dlam=5.00) OK (lam=452.87)\n", + " [100] Predict: lam=457.87 MW (step=5.0000, dlam=5.00) OK (lam=457.87)\n", + " [101] Predict: lam=462.87 MW (step=5.0000, dlam=5.00) OK (lam=462.87)\n", + " [102] Predict: lam=467.87 MW (step=5.0000, dlam=5.00) OK (lam=467.87)\n", + " [103] Predict: lam=472.87 MW (step=5.0000, dlam=5.00) OK (lam=472.87)\n", + " [104] Predict: lam=477.87 MW (step=5.0000, dlam=5.00) OK (lam=477.87)\n", + " [105] Predict: lam=482.87 MW (step=5.0000, dlam=5.00) OK (lam=482.87)\n", + " [106] Predict: lam=487.87 MW (step=5.0000, dlam=5.00) OK (lam=487.87)\n", + " [107] Predict: lam=492.87 MW (step=5.0000, dlam=5.00) OK (lam=492.87)\n", + " [108] Predict: lam=497.87 MW (step=5.0000, dlam=5.00) OK (lam=497.87)\n", + " [109] Predict: lam=502.87 MW (step=5.0000, dlam=5.00) OK (lam=502.87)\n", + " [110] Predict: lam=507.87 MW (step=5.0000, dlam=5.00) OK (lam=507.87)\n", + " [111] Predict: lam=512.87 MW (step=5.0000, dlam=5.00) OK (lam=512.87)\n", + " [112] Predict: lam=517.87 MW (step=5.0000, dlam=5.00) OK (lam=517.87)\n", + " [113] Predict: lam=522.87 MW (step=5.0000, dlam=5.00) OK (lam=522.87)\n", + " [114] Predict: lam=527.87 MW (step=5.0000, dlam=5.00) OK (lam=527.87)\n", + " [115] Predict: lam=532.87 MW (step=5.0000, dlam=5.00) OK (lam=532.87)\n", + " [116] Predict: lam=537.87 MW (step=5.0000, dlam=5.00) OK (lam=537.87)\n", + " [117] Predict: lam=542.87 MW (step=5.0000, dlam=5.00) OK (lam=542.87)\n", + " [118] Predict: lam=547.87 MW (step=5.0000, dlam=5.00) OK (lam=547.87)\n", + " [119] Predict: lam=552.87 MW (step=5.0000, dlam=5.00) OK (lam=552.87)\n", + " [120] Predict: lam=557.87 MW (step=5.0000, dlam=5.00) OK (lam=557.87)\n", + " [121] Predict: lam=562.87 MW (step=5.0000, dlam=5.00) OK (lam=562.87)\n", + " [122] Predict: lam=567.87 MW (step=5.0000, dlam=5.00) OK (lam=567.87)\n", + " [123] Predict: lam=572.87 MW (step=5.0000, dlam=5.00) OK (lam=572.87)\n", + " [124] Predict: lam=577.87 MW (step=5.0000, dlam=5.00) OK (lam=577.87)\n", + " [125] Predict: lam=582.87 MW (step=5.0000, dlam=5.00) OK (lam=582.87)\n", + " [126] Predict: lam=587.87 MW (step=5.0000, dlam=5.00) OK (lam=587.87)\n", + " [127] Predict: lam=592.87 MW (step=5.0000, dlam=5.00) OK (lam=592.87)\n", + " [128] Predict: lam=597.87 MW (step=5.0000, dlam=5.00) OK (lam=597.87)\n", + " [129] Predict: lam=602.87 MW (step=5.0000, dlam=5.00) OK (lam=602.87)\n", + " [130] Predict: lam=607.87 MW (step=5.0000, dlam=5.00) OK (lam=607.87)\n", + " [131] Predict: lam=612.87 MW (step=5.0000, dlam=5.00) OK (lam=612.87)\n", + " [132] Predict: lam=617.87 MW (step=5.0000, dlam=5.00) OK (lam=617.87)\n", + " [133] Predict: lam=622.87 MW (step=5.0000, dlam=5.00) OK (lam=622.87)\n", + " [134] Predict: lam=627.87 MW (step=5.0000, dlam=5.00) OK (lam=627.87)\n", + " [135] Predict: lam=632.87 MW (step=5.0000, dlam=5.00) OK (lam=632.87)\n", + " [136] Predict: lam=637.87 MW (step=5.0000, dlam=5.00) OK (lam=637.87)\n", + " [137] Predict: lam=642.87 MW (step=5.0000, dlam=5.00) OK (lam=642.87)\n", + " [138] Predict: lam=647.87 MW (step=5.0000, dlam=5.00) OK (lam=647.87)\n", + " [139] Predict: lam=652.87 MW (step=5.0000, dlam=5.00) OK (lam=652.87)\n", + " [140] Predict: lam=657.87 MW (step=5.0000, dlam=5.00) OK (lam=657.87)\n", + " [141] Predict: lam=662.87 MW (step=5.0000, dlam=5.00) OK (lam=662.87)\n", + " [142] Predict: lam=667.87 MW (step=5.0000, dlam=5.00) OK (lam=667.87)\n", + " [143] Predict: lam=672.87 MW (step=5.0000, dlam=5.00) OK (lam=672.87)\n", + " [144] Predict: lam=677.87 MW (step=5.0000, dlam=5.00) OK (lam=677.87)\n", + " [145] Predict: lam=682.87 MW (step=5.0000, dlam=5.00) OK (lam=682.87)\n", + " [146] Predict: lam=687.87 MW (step=5.0000, dlam=5.00) OK (lam=687.87)\n", + " [147] Predict: lam=692.87 MW (step=5.0000, dlam=5.00) OK (lam=692.87)\n", + " [148] Predict: lam=697.87 MW (step=5.0000, dlam=5.00) OK (lam=697.87)\n", + " [149] Predict: lam=702.87 MW (step=5.0000, dlam=5.00) OK (lam=702.87)\n", + " [150] Predict: lam=707.87 MW (step=5.0000, dlam=5.00) OK (lam=707.87)\n", + " [151] Predict: lam=712.87 MW (step=5.0000, dlam=5.00) OK (lam=712.87)\n", + " [152] Predict: lam=717.87 MW (step=5.0000, dlam=5.00) OK (lam=717.87)\n", + " [153] Predict: lam=722.87 MW (step=5.0000, dlam=5.00) OK (lam=722.87)\n", + " [154] Predict: lam=727.87 MW (step=5.0000, dlam=5.00) OK (lam=727.87)\n", + " [155] Predict: lam=732.87 MW (step=5.0000, dlam=5.00) OK (lam=732.87)\n", + " [156] Predict: lam=737.87 MW (step=5.0000, dlam=5.00) OK (lam=737.87)\n", + " [157] Predict: lam=742.87 MW (step=5.0000, dlam=5.00) OK (lam=742.87)\n", + " [158] Predict: lam=747.87 MW (step=5.0000, dlam=5.00) OK (lam=747.87)\n", + " [159] Predict: lam=752.87 MW (step=5.0000, dlam=5.00) OK (lam=752.87)\n", + " [160] Predict: lam=757.87 MW (step=5.0000, dlam=5.00) OK (lam=757.87)\n", + " [161] Predict: lam=762.87 MW (step=5.0000, dlam=5.00) OK (lam=762.87)\n", + " [162] Predict: lam=767.87 MW (step=5.0000, dlam=5.00) OK (lam=767.87)\n", + " [163] Predict: lam=772.87 MW (step=5.0000, dlam=5.00) OK (lam=772.87)\n", + " [164] Predict: lam=777.87 MW (step=5.0000, dlam=5.00) OK (lam=777.87)\n", + " [165] Predict: lam=782.87 MW (step=5.0000, dlam=5.00) OK (lam=782.87)\n", + " [166] Predict: lam=787.87 MW (step=5.0000, dlam=5.00) OK (lam=787.87)\n", + " [167] Predict: lam=792.87 MW (step=5.0000, dlam=5.00) OK (lam=792.87)\n", + " [168] Predict: lam=797.87 MW (step=5.0000, dlam=5.00) OK (lam=797.87)\n", + " [169] Predict: lam=802.87 MW (step=5.0000, dlam=5.00) OK (lam=802.87)\n", + " [170] Predict: lam=807.87 MW (step=5.0000, dlam=5.00) OK (lam=807.87)\n", + " [171] Predict: lam=812.87 MW (step=5.0000, dlam=5.00) OK (lam=812.87)\n", + " [172] Predict: lam=817.87 MW (step=5.0000, dlam=5.00) OK (lam=817.87)\n", + " [173] Predict: lam=822.87 MW (step=5.0000, dlam=5.00) OK (lam=822.87)\n", + " [174] Predict: lam=827.87 MW (step=5.0000, dlam=5.00) OK (lam=827.87)\n", + " [175] Predict: lam=832.87 MW (step=5.0000, dlam=5.00) OK (lam=832.87)\n", + " [176] Predict: lam=837.87 MW (step=5.0000, dlam=5.00) OK (lam=837.87)\n", + " [177] Predict: lam=842.87 MW (step=5.0000, dlam=5.00) OK (lam=842.87)\n", + " [178] Predict: lam=847.87 MW (step=5.0000, dlam=5.00) OK (lam=847.87)\n", + " [179] Predict: lam=852.87 MW (step=5.0000, dlam=5.00) OK (lam=852.87)\n", + " [180] Predict: lam=857.87 MW (step=5.0000, dlam=5.00) OK (lam=857.87)\n", + " [181] Predict: lam=862.87 MW (step=5.0000, dlam=5.00) OK (lam=862.87)\n", + " [182] Predict: lam=867.87 MW (step=5.0000, dlam=5.00) OK (lam=867.87)\n", + " [183] Predict: lam=872.87 MW (step=5.0000, dlam=5.00) OK (lam=872.87)\n", + " [184] Predict: lam=877.87 MW (step=5.0000, dlam=5.00) OK (lam=877.87)\n", + " [185] Predict: lam=882.87 MW (step=5.0000, dlam=5.00) OK (lam=882.87)\n", + " [186] Predict: lam=887.87 MW (step=5.0000, dlam=5.00) OK (lam=887.87)\n", + " [187] Predict: lam=892.87 MW (step=5.0000, dlam=5.00) OK (lam=892.87)\n", + " [188] Predict: lam=897.87 MW (step=5.0000, dlam=5.00) OK (lam=897.87)\n", + " [189] Predict: lam=902.87 MW (step=5.0000, dlam=5.00) OK (lam=902.87)\n", + " [190] Predict: lam=907.87 MW (step=5.0000, dlam=5.00) OK (lam=907.87)\n", + " [191] Predict: lam=912.87 MW (step=5.0000, dlam=5.00) OK (lam=912.87)\n", + " [192] Predict: lam=917.87 MW (step=5.0000, dlam=5.00) OK (lam=917.87)\n", + " [193] Predict: lam=922.87 MW (step=5.0000, dlam=5.00) OK (lam=922.87)\n", + " [194] Predict: lam=927.87 MW (step=5.0000, dlam=5.00) OK (lam=927.87)\n", + " [195] Predict: lam=932.87 MW (step=5.0000, dlam=5.00) OK (lam=932.87)\n", + " [196] Predict: lam=937.87 MW (step=5.0000, dlam=5.00) OK (lam=937.87)\n", + " [197] Predict: lam=942.87 MW (step=5.0000, dlam=5.00) OK (lam=942.87)\n", + " [198] Predict: lam=947.87 MW (step=5.0000, dlam=5.00) OK (lam=947.87)\n", + " [199] Predict: lam=952.87 MW (step=5.0000, dlam=5.00) OK (lam=952.87)\n", + " [200] Predict: lam=957.87 MW (step=5.0000, dlam=5.00) OK (lam=957.87)\n", + " [201] Predict: lam=962.87 MW (step=5.0000, dlam=5.00) OK (lam=962.87)\n", + " [202] Predict: lam=967.87 MW (step=5.0000, dlam=5.00) OK (lam=967.87)\n", + " [203] Predict: lam=972.87 MW (step=5.0000, dlam=5.00) OK (lam=972.87)\n", + " [204] Predict: lam=977.87 MW (step=5.0000, dlam=5.00) OK (lam=977.87)\n", + " [205] Predict: lam=982.87 MW (step=5.0000, dlam=5.00) OK (lam=982.87)\n", + " [206] Predict: lam=987.87 MW (step=5.0000, dlam=5.00) OK (lam=987.87)\n", + " [207] Predict: lam=992.87 MW (step=5.0000, dlam=5.00) OK (lam=992.87)\n", + " [208] Predict: lam=997.87 MW (step=5.0000, dlam=5.00) OK (lam=997.87)\n", + " [209] Predict: lam=1002.87 MW (step=5.0000, dlam=5.00) OK (lam=1002.87)\n", + " [210] Predict: lam=1007.87 MW (step=5.0000, dlam=5.00) OK (lam=1007.87)\n", + " [211] Predict: lam=1012.87 MW (step=5.0000, dlam=5.00) OK (lam=1012.87)\n", + " [212] Predict: lam=1017.87 MW (step=5.0000, dlam=5.00) OK (lam=1017.87)\n", + " [213] Predict: lam=1022.87 MW (step=5.0000, dlam=5.00) OK (lam=1022.87)\n", + " [214] Predict: lam=1027.87 MW (step=5.0000, dlam=5.00) OK (lam=1027.87)\n", + " [215] Predict: lam=1032.87 MW (step=5.0000, dlam=5.00) OK (lam=1032.87)\n", + " [216] Predict: lam=1037.87 MW (step=5.0000, dlam=5.00) OK (lam=1037.87)\n", + " [217] Predict: lam=1042.87 MW (step=5.0000, dlam=5.00) OK (lam=1042.87)\n", + " [218] Predict: lam=1047.87 MW (step=5.0000, dlam=5.00) OK (lam=1047.87)\n", + " [219] Predict: lam=1052.87 MW (step=5.0000, dlam=5.00) OK (lam=1052.87)\n", + " [220] Predict: lam=1057.87 MW (step=5.0000, dlam=5.00) OK (lam=1057.87)\n", + " [221] Predict: lam=1062.87 MW (step=5.0000, dlam=5.00) OK (lam=1062.87)\n", + " [222] Predict: lam=1067.87 MW (step=5.0000, dlam=5.00) OK (lam=1067.87)\n", + " [223] Predict: lam=1072.87 MW (step=5.0000, dlam=5.00) OK (lam=1072.87)\n", + " [224] Predict: lam=1077.87 MW (step=5.0000, dlam=5.00) OK (lam=1077.87)\n", + " [225] Predict: lam=1082.87 MW (step=5.0000, dlam=5.00) OK (lam=1082.87)\n", + " [226] Predict: lam=1087.87 MW (step=5.0000, dlam=5.00) OK (lam=1087.87)\n", + " [227] Predict: lam=1092.87 MW (step=5.0000, dlam=5.00) OK (lam=1092.87)\n", + " [228] Predict: lam=1097.87 MW (step=5.0000, dlam=5.00) OK (lam=1097.87)\n", + " [229] Predict: lam=1102.87 MW (step=5.0000, dlam=5.00) OK (lam=1102.87)\n", + " [230] Predict: lam=1107.87 MW (step=5.0000, dlam=5.00) OK (lam=1107.87)\n", + " [231] Predict: lam=1112.87 MW (step=5.0000, dlam=5.00) OK (lam=1112.87)\n", + " [232] Predict: lam=1117.87 MW (step=5.0000, dlam=5.00) OK (lam=1117.87)\n", + " [233] Predict: lam=1122.87 MW (step=5.0000, dlam=5.00) OK (lam=1122.87)\n", + " [234] Predict: lam=1127.87 MW (step=5.0000, dlam=5.00) OK (lam=1127.87)\n", + " [235] Predict: lam=1132.87 MW (step=5.0000, dlam=5.00) OK (lam=1132.87)\n", + " [236] Predict: lam=1137.87 MW (step=5.0000, dlam=5.00) OK (lam=1137.87)\n", + " [237] Predict: lam=1142.87 MW (step=5.0000, dlam=5.00) OK (lam=1142.87)\n", + " [238] Predict: lam=1147.87 MW (step=5.0000, dlam=5.00) OK (lam=1147.87)\n", + " [239] Predict: lam=1152.87 MW (step=5.0000, dlam=5.00) OK (lam=1152.87)\n", + " [240] Predict: lam=1157.87 MW (step=5.0000, dlam=5.00) OK (lam=1157.87)\n", + " [241] Predict: lam=1162.87 MW (step=5.0000, dlam=5.00) OK (lam=1162.87)\n", + " [242] Predict: lam=1167.87 MW (step=5.0000, dlam=5.00) OK (lam=1167.87)\n", + " [243] Predict: lam=1172.87 MW (step=5.0000, dlam=5.00) OK (lam=1172.87)\n", + " [244] Predict: lam=1177.87 MW (step=5.0000, dlam=5.00) OK (lam=1177.87)\n", + " [245] Predict: lam=1182.87 MW (step=5.0000, dlam=5.00) OK (lam=1182.87)\n", + " [246] Predict: lam=1187.87 MW (step=5.0000, dlam=5.00) OK (lam=1187.87)\n", + " [247] Predict: lam=1192.87 MW (step=5.0000, dlam=5.00) OK (lam=1192.87)\n", + " [248] Predict: lam=1197.87 MW (step=5.0000, dlam=5.00) OK (lam=1197.87)\n", + " [249] Predict: lam=1202.87 MW (step=5.0000, dlam=5.00) OK (lam=1202.87)\n", + " [250] Predict: lam=1207.87 MW (step=5.0000, dlam=5.00) OK (lam=1207.87)\n", + " [251] Predict: lam=1212.87 MW (step=5.0000, dlam=5.00) OK (lam=1212.87)\n", + " [252] Predict: lam=1217.87 MW (step=5.0000, dlam=5.00) OK (lam=1217.87)\n", + " [253] Predict: lam=1222.87 MW (step=5.0000, dlam=5.00) OK (lam=1222.87)\n", + " [254] Predict: lam=1227.87 MW (step=5.0000, dlam=5.00) OK (lam=1227.87)\n", + " [255] Predict: lam=1232.87 MW (step=5.0000, dlam=5.00) OK (lam=1232.87)\n", + " [256] Predict: lam=1237.87 MW (step=5.0000, dlam=5.00) OK (lam=1237.87)\n", + " [257] Predict: lam=1242.87 MW (step=5.0000, dlam=5.00) OK (lam=1242.87)\n", + " [258] Predict: lam=1247.87 MW (step=5.0000, dlam=5.00) OK (lam=1247.87)\n", + " [259] Predict: lam=1252.87 MW (step=5.0000, dlam=5.00) OK (lam=1252.87)\n", + " [260] Predict: lam=1257.87 MW (step=5.0000, dlam=5.00) OK (lam=1257.87)\n", + " [261] Predict: lam=1262.87 MW (step=5.0000, dlam=5.00) OK (lam=1262.87)\n", + " [262] Predict: lam=1267.87 MW (step=5.0000, dlam=5.00) OK (lam=1267.87)\n", + " [263] Predict: lam=1272.87 MW (step=5.0000, dlam=5.00) OK (lam=1272.87)\n", + " [264] Predict: lam=1277.87 MW (step=5.0000, dlam=5.00) OK (lam=1277.87)\n", + " [265] Predict: lam=1282.87 MW (step=5.0000, dlam=5.00) OK (lam=1282.87)\n", + " [266] Predict: lam=1287.87 MW (step=5.0000, dlam=5.00) OK (lam=1287.87)\n", + " [267] Predict: lam=1292.87 MW (step=5.0000, dlam=5.00) OK (lam=1292.87)\n", + " [268] Predict: lam=1297.87 MW (step=5.0000, dlam=5.00) OK (lam=1297.87)\n", + " [269] Predict: lam=1302.87 MW (step=5.0000, dlam=5.00) OK (lam=1302.87)\n", + " [270] Predict: lam=1307.87 MW (step=5.0000, dlam=5.00) OK (lam=1307.87)\n", + " [271] Predict: lam=1312.87 MW (step=5.0000, dlam=5.00) OK (lam=1312.87)\n", + " [272] Predict: lam=1317.87 MW (step=5.0000, dlam=5.00) OK (lam=1317.87)\n", + " [273] Predict: lam=1322.87 MW (step=5.0000, dlam=5.00) OK (lam=1322.87)\n", + " [274] Predict: lam=1327.87 MW (step=5.0000, dlam=5.00) OK (lam=1327.87)\n", + " [275] Predict: lam=1332.87 MW (step=5.0000, dlam=5.00) OK (lam=1332.87)\n", + " [276] Predict: lam=1337.87 MW (step=5.0000, dlam=5.00) OK (lam=1337.87)\n", + " [277] Predict: lam=1342.87 MW (step=5.0000, dlam=5.00) OK (lam=1342.87)\n", + " [278] Predict: lam=1347.87 MW (step=5.0000, dlam=5.00) OK (lam=1347.87)\n", + " [279] Predict: lam=1352.87 MW (step=5.0000, dlam=5.00) OK (lam=1352.87)\n", + " [280] Predict: lam=1357.87 MW (step=5.0000, dlam=5.00) OK (lam=1357.87)\n", + " [281] Predict: lam=1362.87 MW (step=5.0000, dlam=5.00) OK (lam=1362.87)\n", + " [282] Predict: lam=1367.87 MW (step=5.0000, dlam=5.00) OK (lam=1367.87)\n", + " [283] Predict: lam=1372.87 MW (step=5.0000, dlam=5.00) OK (lam=1372.87)\n", + " [284] Predict: lam=1377.87 MW (step=5.0000, dlam=5.00) OK (lam=1377.87)\n", + " [285] Predict: lam=1382.87 MW (step=5.0000, dlam=5.00) OK (lam=1382.87)\n", + " [286] Predict: lam=1387.87 MW (step=5.0000, dlam=5.00) OK (lam=1387.87)\n", + " [287] Predict: lam=1392.87 MW (step=5.0000, dlam=5.00) OK (lam=1392.87)\n", + " [288] Predict: lam=1397.87 MW (step=5.0000, dlam=5.00) OK (lam=1397.87)\n", + " [289] Predict: lam=1402.87 MW (step=5.0000, dlam=5.00) OK (lam=1402.87)\n", + " [290] Predict: lam=1407.87 MW (step=5.0000, dlam=5.00) OK (lam=1407.87)\n", + " [291] Predict: lam=1412.87 MW (step=5.0000, dlam=5.00) OK (lam=1412.87)\n", + " [292] Predict: lam=1417.87 MW (step=5.0000, dlam=5.00) OK (lam=1417.87)\n", + " [293] Predict: lam=1422.87 MW (step=5.0000, dlam=5.00) OK (lam=1422.87)\n", + " [294] Predict: lam=1427.87 MW (step=5.0000, dlam=5.00) OK (lam=1427.87)\n", + " [295] Predict: lam=1432.87 MW (step=5.0000, dlam=5.00) OK (lam=1432.87)\n", + " [296] Predict: lam=1437.87 MW (step=5.0000, dlam=5.00) OK (lam=1437.87)\n", + " [297] Predict: lam=1442.87 MW (step=5.0000, dlam=5.00) OK (lam=1442.87)\n", + " [298] Predict: lam=1447.87 MW (step=5.0000, dlam=5.00) OK (lam=1447.87)\n", + " [299] Predict: lam=1452.87 MW (step=5.0000, dlam=5.00) OK (lam=1452.87)\n", + " [300] Predict: lam=1457.87 MW (step=5.0000, dlam=5.00) OK (lam=1457.87)\n", + " [301] Predict: lam=1462.87 MW (step=5.0000, dlam=5.00) OK (lam=1462.87)\n", + " [302] Predict: lam=1467.87 MW (step=5.0000, dlam=5.00) OK (lam=1467.87)\n", + " [303] Predict: lam=1472.87 MW (step=5.0000, dlam=5.00) OK (lam=1472.87)\n", + " [304] Predict: lam=1477.87 MW (step=5.0000, dlam=5.00) OK (lam=1477.87)\n", + " [305] Predict: lam=1482.87 MW (step=5.0000, dlam=5.00) OK (lam=1482.87)\n", + " [306] Predict: lam=1487.87 MW (step=5.0000, dlam=5.00) OK (lam=1487.87)\n", + " [307] Predict: lam=1492.87 MW (step=5.0000, dlam=5.00) OK (lam=1492.87)\n", + " [308] Predict: lam=1497.87 MW (step=5.0000, dlam=5.00) OK (lam=1497.87)\n", + " [309] Predict: lam=1502.87 MW (step=5.0000, dlam=5.00) OK (lam=1502.87)\n", + " [310] Predict: lam=1507.87 MW (step=5.0000, dlam=5.00) OK (lam=1507.87)\n", + " [311] Predict: lam=1512.87 MW (step=5.0000, dlam=5.00) OK (lam=1512.87)\n", + " [312] Predict: lam=1517.87 MW (step=5.0000, dlam=5.00) OK (lam=1517.87)\n", + " [313] Predict: lam=1522.87 MW (step=5.0000, dlam=5.00) OK (lam=1522.87)\n", + " [314] Predict: lam=1527.87 MW (step=5.0000, dlam=5.00) OK (lam=1527.87)\n", + " [315] Predict: lam=1532.87 MW (step=5.0000, dlam=5.00) OK (lam=1532.87)\n", + " [316] Predict: lam=1537.87 MW (step=5.0000, dlam=5.00) OK (lam=1537.87)\n", + " [317] Predict: lam=1542.87 MW (step=5.0000, dlam=5.00) OK (lam=1542.87)\n", + " [318] Predict: lam=1547.87 MW (step=5.0000, dlam=5.00) OK (lam=1547.87)\n", + " [319] Predict: lam=1552.87 MW (step=5.0000, dlam=5.00) OK (lam=1552.87)\n", + " [320] Predict: lam=1557.87 MW (step=5.0000, dlam=5.00) OK (lam=1557.87)\n", + " [321] Predict: lam=1562.87 MW (step=5.0000, dlam=5.00) OK (lam=1562.87)\n", + " [322] Predict: lam=1567.87 MW (step=5.0000, dlam=5.00) OK (lam=1567.87)\n", + " [323] Predict: lam=1572.87 MW (step=5.0000, dlam=5.00) OK (lam=1572.87)\n", + " [324] Predict: lam=1577.87 MW (step=5.0000, dlam=5.00) OK (lam=1577.87)\n", + " [325] Predict: lam=1582.87 MW (step=5.0000, dlam=5.00) OK (lam=1582.87)\n", + " [326] Predict: lam=1587.87 MW (step=5.0000, dlam=5.00) OK (lam=1587.87)\n", + " [327] Predict: lam=1592.87 MW (step=5.0000, dlam=5.00) OK (lam=1592.87)\n", + " [328] Predict: lam=1597.87 MW (step=5.0000, dlam=5.00) OK (lam=1597.87)\n", + " [329] Predict: lam=1602.87 MW (step=5.0000, dlam=5.00) OK (lam=1602.87)\n", + " [330] Predict: lam=1607.87 MW (step=5.0000, dlam=5.00) OK (lam=1607.87)\n", + " [331] Predict: lam=1612.87 MW (step=5.0000, dlam=5.00) OK (lam=1612.87)\n", + " [332] Predict: lam=1617.87 MW (step=5.0000, dlam=5.00) OK (lam=1617.87)\n", + " [333] Predict: lam=1622.87 MW (step=5.0000, dlam=5.00) OK (lam=1622.87)\n", + " [334] Predict: lam=1627.87 MW (step=5.0000, dlam=5.00) OK (lam=1627.87)\n", + " [335] Predict: lam=1632.87 MW (step=5.0000, dlam=5.00) OK (lam=1632.87)\n", + " [336] Predict: lam=1637.87 MW (step=5.0000, dlam=5.00) OK (lam=1637.87)\n", + " [337] Predict: lam=1642.87 MW (step=5.0000, dlam=5.00) OK (lam=1642.87)\n", + " [338] Predict: lam=1647.87 MW (step=5.0000, dlam=5.00) OK (lam=1647.87)\n", + " [339] Predict: lam=1652.87 MW (step=5.0000, dlam=5.00) OK (lam=1652.87)\n", + " [340] Predict: lam=1657.87 MW (step=5.0000, dlam=5.00) OK (lam=1657.87)\n", + " [341] Predict: lam=1662.87 MW (step=5.0000, dlam=5.00) OK (lam=1662.87)\n", + " [342] Predict: lam=1667.87 MW (step=5.0000, dlam=5.00) OK (lam=1667.87)\n", + " [343] Predict: lam=1672.87 MW (step=5.0000, dlam=5.00) OK (lam=1672.87)\n", + " [344] Predict: lam=1677.87 MW (step=5.0000, dlam=5.00) OK (lam=1677.87)\n", + " [345] Predict: lam=1682.87 MW (step=5.0000, dlam=5.00) OK (lam=1682.87)\n", + " [346] Predict: lam=1687.87 MW (step=5.0000, dlam=5.00) Q-LIM [347] Predict: lam=1685.37 MW (step=2.5000, dlam=2.50) Q-LIM [348] Predict: lam=1684.12 MW (step=1.2500, dlam=1.25) OK (lam=1684.12)\n", + " [349] Predict: lam=1686.00 MW (step=1.8750, dlam=1.88) Q-LIM [350] Predict: lam=1685.06 MW (step=0.9375, dlam=0.94) Q-LIM [351] Predict: lam=1684.59 MW (step=0.4688, dlam=0.47) Q-LIM [352] Predict: lam=1684.36 MW (step=0.2344, dlam=0.23) Q-LIM [353] Predict: lam=1684.24 MW (step=0.1172, dlam=0.12) OK (lam=1684.24)\n", + " [354] Predict: lam=1684.42 MW (step=0.1758, dlam=0.18) Q-LIM [355] Predict: lam=1684.33 MW (step=0.0879, dlam=0.09) Q-LIM [356] Predict: lam=1684.29 MW (step=0.0439, dlam=0.04) OK (lam=1684.29)\n", + " [357] Predict: lam=1684.35 MW (step=0.0659, dlam=0.07) Q-LIM [358] Predict: lam=1684.32 MW (step=0.0330, dlam=0.03) Q-LIM [359] Predict: lam=1684.30 MW (step=0.0165, dlam=0.02) Q-LIM [360] Predict: lam=1684.29 MW (step=0.0082, dlam=0.01) Q-LIM [361] Predict: lam=1684.29 MW (step=0.0041, dlam=0.00) Q-LIM [362] Predict: lam=1684.29 MW (step=0.0021, dlam=0.00) Q-LIM [363] Predict: lam=1684.29 MW (step=0.0010, dlam=0.00) OK (lam=1684.29)\n", + " [364] Predict: lam=1684.29 MW (step=0.0015, dlam=0.00) Q-LIM\n", + "Collected 351 points\n", + "Transfer range: 0.0 to 1684.3 MW\n" + ] + } + ], + "source": [ + "# Collect PV curve data points\n", + "mw_points = []\n", + "v_points = []\n", + "\n", + "for mw in s.continuation_pf(\n", + " interface=-interface,\n", + " initialmw=0,\n", + " step_size=0.05,\n", + " min_step=0.001,\n", + " max_step=5,\n", + " maxiter=1000,\n", + " verbose=True,\n", + " restore_when_done=True,\n", + "):\n", + " V = pw.voltage()\n", + " v_critical = np.abs(V[critical_bus_idx])\n", + " mw_points.append(mw)\n", + " v_points.append(v_critical)\n", + "\n", + "print(f\"\\nCollected {len(mw_points)} points\")\n", + "if mw_points:\n", + " print(f\"Transfer range: {min(mw_points):.1f} to {max(mw_points):.1f} MW\")" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "plot_pv_curve(mw_points, v_points)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "esapp", + "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.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/steady_state/05_ptdf_lodf_analysis.ipynb b/examples/steady_state/05_ptdf_lodf_analysis.ipynb new file mode 100644 index 00000000..bad68093 --- /dev/null +++ b/examples/steady_state/05_ptdf_lodf_analysis.ipynb @@ -0,0 +1,537 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a1", + "metadata": {}, + "source": [ + "# PTDF & LODF Geographic Sensitivity Analysis\n", + "\n", + "Power Transfer Distribution Factors (PTDFs) and Line Outage Distribution\n", + "Factors (LODFs) reveal how power flows shift through the network in\n", + "response to transfers and contingencies. This notebook visualizes both\n", + "factors *entirely on geographic network maps*, making it easy to see\n", + "which corridors carry the transfer, where flow reroutes after an outage,\n", + "and how loading patterns change across the system." + ] + }, + { + "cell_type": "markdown", + "id": "a2", + "metadata": {}, + "source": [ + "```python\n", + "import numpy as np\n", + "from esapp import PowerWorld\n", + "from esapp.components import *\n", + "\n", + "pw = PowerWorld(case_path)\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "a3", + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "'open' took: 8.2118 sec\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "from esapp import PowerWorld\n", + "from esapp.components import *\n", + "import ast\n", + "\n", + "with open('../data/case_B.txt', 'r') as f:\n", + " case_path = ast.literal_eval(f.read().strip())\n", + "\n", + "pw = PowerWorld(case_path)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "a3b", + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [], + "source": [ + "import sys; sys.path.insert(0, '..')\n", + "from plot_helpers import (\n", + " plot_sensitivity_map, plot_sensitivity_dual, plot_sensitivity_triple,\n", + " plot_flow_map, plot_bus_markers,\n", + ")\n", + "\n", + "SHAPE = 'Texas'" + ] + }, + { + "cell_type": "markdown", + "id": "a4", + "metadata": {}, + "source": [ + "## 1. Base Case Loading Map\n", + "\n", + "Start by solving the base case and plotting every branch colored by\n", + "its loading percentage. Hot colors indicate heavily loaded lines." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "a5", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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euml/PSnP+WPf/wj6enph3Svm6xcuZJ7772Xu+++m2g0ys9+9jMuv/xyPv300+ZtzjvvPN555x1+85vfcMIJJzSXSu2tpKSEH//4x8yZMwePx8Ovf/1rZs+ezebNm4/ojcrNN9/MQw89xC233MJJJ53E66+/zrXXXks4HOaGG24AYNeuXfTr14/LLrsMt9vNypUruf3226mrq+P2229vPtbZZ5/Nzp07+cc//kFKSgp33303RUVFLe5HW377299y9tlnM3fuXD755BPuuOMOCgoKuPbaawH48ssvueCCCzjzzDN54IEH2L59OxdddBHBYPAbX7sQ4uiSzH8caSHEceP222/XwH7LRRddpCORSJv7RSIRvXPnTg3ot956S2ut9fLlyzWgV61a1eo+sVhMd+/eXV9yySUt1i9YsEArpfSaNWvaPF///v31CSeccNjXF41GdTgc1tOnT29x3kGDBumf/exnbe532223aY/Ho0tLS5vXBQIB3a1bN33zzTcf8Jzdu3ff734mJCTouXPnttiu6d7/73//O+DxWrvXWms9adIknZiYqMvKyprXPf744xrQRUVFWmutFy1apAH97LPPtnn8K6+8cr/7/+6772pAf/jhhwdsG6DvvffeVj8rLy/XNptNz5kzp8X6Sy65RGdmZrb69ysWi+lwOKzvuusunZub27x+wYIFGtBLlixpXldTU6Pdbrfu3r37ftdfXl6utdZ669atGtAXXHBBi/NMmjRJT5kypfn7Cy64QBcUFOhoNNq87umnn9aAvv322w94D4QQx5bX69WA/i+99Uv0bdflv/TWgPZ6vfG+DXElD0FCHGcSEhJYvnw5y5cv56OPPuKhhx5i4cKFXHXVVS22W7BgASeddBIejwer1UrXrl0BKCwsBKB3794kJydz3XXXMXfuXMrLy1vsX1hYyPbt27nwwguJRCLNy6RJkzAMg88///yA7VRKHdL17Ny5kyuvvJIuXbpgtVqx2WwsWrSouZ0AI0eO5IknnuC+++5jzZo1+x1j0aJFnHLKKaSlpTW302KxMGnSJJYvX37QNlx44YXN9/Stt97iwgsv5IorrmDx4sX7bbvv2wA4+L1uMnz48BY17gMHDmy+BwBLlizB5XLtV9K0r7y8PAYNGtTmcb6JpUuXEg6HueCCC1qsv+iiiygvL2++lkAgwO23305BQQEOhwObzcZvf/tbiouLqauraz6Wx+Ph1FNPbT6Ox+Nh6tSph9SW6dOnt/h+4MCBLa5t+fLlnHHGGRjGnv/izj777MO7YCGEOE5J8C/EccYwDEaPHs3o0aMZP348P/7xj7ntttt4/PHHmwPj5cuXc9ZZZ5GXl8fTTz/Np59+ymeffQaYwRtAamoqixcvxu12c8UVV5CTk8PkyZNZvXo1QHMd9uzZs7HZbM2Ly+UiGo1SVFTUZhu7dOnCjh07DnotsViMs846i48++ojf//73vPvuuyxfvpzTTjutuZ0ADz/8MFdccQV/+ctfGDJkCN26deMf//hH8+cVFRXMnz+/RTttNhtPP/30AdvZJDMzs/meTp8+nccff5x+/frx61//usV2LpeLpKSkFusO5V432XdUm6b+EE3bVVZWkpube9AHp4Md55uorq4GzM7Pe2v6vqqqCoBf/epX3HvvvVx11VW8+eabLF++nFtuuaXF+YuLi1vtyLvvsdvS2vXtfW2tHd/tduN0Og/p+EKIY8+I0yKk5l+ITmHAgAEArF27lsGDB/Pyyy/j8XiYO3duc3Z0+/bt++03duxYFixY0Nx34Be/+AXnnHMOmzdvJi0tDYC//e1vjBs3br998/Ly2mzP5MmTWbJkCWvXrm2Rod7Xpk2b+PLLL5k/f36LzK3f72+xncfj4cEHH+TBBx9k9erVPPTQQ1x//fUMHjyYk08+mbS0NGbOnMkf/vCH/c7hcDjaPH9blFL079+fV199db/1+zrUe30o0tPTKS4uRmt9yG9Ojpamn3dZWRldunRpXl9aWtri8xdeeIFrrrmGX/3qV83bvPHGGy2OlZubu9+bpL2PdaRaO35tbe0RPfwIIcTxQh6ChOgEmjL+GRkZgBk822y2FgHkM8880+b+CQkJzJo1i+uuu46tW7cSCATo378/Xbt2ZcuWLc1Z8b2XAwX/P/zhD0lOTuanP/3pfqMQgTlSTUNDQ3OQv/eIQNu3b+fjjz9u89hDhgzhgQceAGD9+vUATJ06lXXr1jFgwID92nkonY73pbVm3bp1zffzQA73Xh/I1KlTaWhoYO7cud9o/yMxduxYbDYbL7zwQov1c+fOJSsri759+wLm9e7984pGo/t1/h47dixer7d5PgoAr9fL22+/fVTaOmbMGF5//fUWIwzNnz//qBxbCHF0SOY/fiTzL8RxJhaLNZeVhEIhVqxYwZ133snAgQOZOHEiANOmTePBBx/kxhtvZPbs2Xz66ac8/fTTLY7zxhtv8O9//5vZs2fTrVs3SkpKePjhhxk/fnxz+cT999/PpZdeSn19PaeffjqJiYls376dN954gz/+8Y/NAeG+cnJyeOqpp7jwwgsZP348P/rRj+jVq1dzec4zzzxDZWVl8wPGnDlziEajzSPG7J15Bhg/fjyzZ89m8ODBWCwWnnrqKex2OyeffDJgjgb0zDPPMGnSJH7yk5/QrVs3ysvLWbp0KXl5efz0pz894D0tLS1tvqfV1dU8++yzrFmzhrvuuuugP49DudeHaurUqcyaNYvvf//7bN68mXHjxlFVVcW8efN4/vnnv9Ex97V69WrmzZvXYl1SUhIzZ87kxhtv5N57720ePvPNN9/k2Wef5eGHH8ZisQDm9T722GMMHDiQjIwM/u///m+/UXZmzpzJyJEjueyyy/jzn/9MSkoKf/rTn0hOTj4q1/DrX/+aMWPGcN5553H11Vezfft27rvvPpxOZ4t+AEII0RlJ8C/Eccbv93PiiScCYLVayc/P5/LLL+f2229vHuZx1qxZ/PnPf+bhhx/m8ccfZ/z48bz++ustgvWCggIMw+C3v/0tZWVlpKenM336dP70pz81b3PBBReQkpLCXXfdxX//+18AevTowcyZMw9av3322WezfPly7r77bubMmUNFRQWpqalMmDCBxYsXN8/u+9JLL/GjH/2ICy64gPz8fG655RbeeeedFh2Kx48fz1NPPcXWrVsxDIMhQ4bw2muvNZc7paen89lnn3HLLbfwq1/9isrKSrKysjjhhBOYPXv2Qe/pvHnzmgNit9tNQUEB//73v/ne97530H0P5V4fjhdffJHf/e53PProo9xxxx1kZ2fv1wH2SDz11FM89dRTLdb17t2bTZs2ce+995KSksK//vWv5vH+H3nkEa655prmbR9++GGuvfZabrzxRlwuF9/97neZPXt2iw7nSileeeUVrr32Wq655hpSU1O58cYbKS0tPSoZ+hEjRjB37tzmIU4HDx7Mk08+yeTJkzvMrNFCdHYy1Gf8KK21jncjhBBCiGNpyZIlTJ06lffee49JkybFuzlCdFo+n8/sB0VvXFja9dwNRLmQzXi93qP2pvHbSDL/QgghjjvXX389U6ZMIT09nbVr1/KH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l+3btzN69GgAtm3bRm5ubuO2c845pzF4Peecc/j6669PuJawY1F/Ho+HFStWcOGFFwLg9Xrx+XxMmTKFOXPmHJVydxTH6vcPjFbE008/nWeffZZx48YdcVk7qmP5//DB6vdE1JK6fO655xo///znP28cA/Gvf/2LmTNn4nA4ALj44ov505/+dEzK2ZEdSR3m5uYyZMgQkpKSAPjJT37C/ffff0zK2VEdSf19+eWXfPnll9x22234/X6qqqro06cP69evP1bFFeKIScv/ceb888/n6aefJhKJUFVVxauvvtoYsM6cObOxJSwcDvPZZ58xePDgdi5xx3Kg+nO5XFRWVrJt2za2bdvGww8/zLRp0064wP9IHez3b+3atUyfPp1//etfFBYWtnNJO66D1eHBtnVWlZWVhEIhAL7//nveeecdrrvuOgB69uzJZ599htYarTUffvghAwYMaM/idkgHq8OZM2cyb948AoEAAB9//LH83fiBg9Xfnr8Z27Zt45VXXqGgoEAC/5ZSpvZZhLT8d0Rz5szh8ssvx+PxoLXmjTfe4Mknn+TMM8/k0ksvZcmSJfTu3RulFLfeeisDBw4E4KKLLuK7776jf//+mM1mxo8fz80339zOd9P2Drf+hOFw6++mm27C7XZz5513cueddwLw4IMPcuqpp7bn7bSLw61D+f3c1+LFi7npppuwWCzEx8fz2muv0aVLFwB+97vfcc011zQG/H379uWf//xnexa3QzpYHY4ZM4YzzzyToUOHYjab6d+/P0899VQ7l7hjOVj9CXE8Ulpr3d6FEEIIIYQQJz6Px4PL5cK940USEto2I6HH48OVdQlut5uEhIQ2vXZHIi3/QgghhBCijamGpa2vKaTzkxBCCCGEEJ2EtPwLIYQQQoi21R6pNyXVJyAt/0IIIYQQQnQa0vIvhBBCCCHamIm2b4OWNm+QWhBCCCGEEKLTkOBfCCGEEEKITkK6/QghhBBCiLYlA37bjbT8CyHEMfbKK69wwQUXHNVzTps2jdmzZx/VcwohhDjxSfAvhOiUJk6cyKOPPnrMrxONRvn1r3/Nvffeu8+2WbNmMWXKFK677rr9ls9utxMXF9e4pKamNm6/5557uP32249p2YUQ4tgxtdMipBaEEOIY+uijj0hOTmbgwIH73fbcc8/h8XiIRqP7bH/wwQfxer2NS0VFReO2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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pw.pflow()\n", + "\n", + "geo_fields = ['BusNum', 'BusNum:1', 'LineCircuit',\n", + " 'Longitude', 'Longitude:1', 'Latitude', 'Latitude:1']\n", + "lines_geo = pw[Branch, geo_fields]\n", + "flows = pw.flows()\n", + "\n", + "plot_flow_map(\n", + " lines_geo, flows['LinePercent'].values,\n", + " shape=SHAPE,\n", + " title='Base Case Branch Loading',\n", + " figsize=(8,8)\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "a6", + "metadata": {}, + "source": [ + "## 2. PTDF Transfer Corridor\n", + "\n", + "PTDFs show what fraction of a seller-to-buyer transfer flows through\n", + "each line. Blue lines carry flow in the transfer direction; red lines\n", + "carry counter-flow. Thicker lines have larger absolute PTDFs.\n", + "\n", + "The seller and buyer buses are marked with stars on the map." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "a7", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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c801rF69ms997nO9voaioiIqKiq46aabmDx5MmVlZQDs3LmTXbt28de//pW9e/dmPOeRRx4hPz+ftrY2Lr74YmbOnJkxGz6QotEor7/+OolEgjvuuIOioiIefvjhHkHVF7/4RWbNmsWYMWPw+Xz853/+J9deey0rV67k0KFD/PGPfwTg73//O5dddhkLFy7k0ksv5dixYzQ0NLBv3z6+9rWvMXfu3IxajtT6QMuXL+ell17iqquuyjhudXV1ur5EiKHigQceYO7cuQQCAUpKSrj22mt59913M7aJRqPcddddFBYW4vf7ueGGGwiFQlk641On2B/QZL3W1lZyc3NpaWkhJycn26cjRK9ef/11LrnkEnbt2sXUqVOzfTqDLmEYqJ355wAtHRECHvcZTQ/qnrKTOn5vqTqDqbKykpdeegnTslgwfz5jx40jNyfnrEiZ2LlzJ60tLeTm5tLW0YHP68Xn9dDc0srGjRu5+OKLmT59ep/PTxgGCkqPVCjbtjFjESwjge7x8ebGt/jyl7/M/v37aWho4KabbuKKK67g8ccfZ9WqVVx44YU88cQT6UF4d7Ztc/ToUfLz8/H5fADccsst7Nu3j82bNyfPJZHImKFzOBzk5+dTU1PDD3/4Q+677z6OHTtGXl4ev/zlL/nTn/7Epz/9aV5//XUeffRRXn75ZRYvXoxt28ycOROAW2+9lREjRnDkyBHq6ur4z//8TyC5oKau63zve99L33F/7rnnegQxp8MwDN544w3KysqIRqOce+65vW5XUlLCT3/6U55++mkOHDjApk2bAPh//+//8eabb/Lv//7v7Ny5k2PHjuH3+7nyyiu5+OKLqa6u7ve5PPjgg9x99909Hv+v//ovfvvb37Jx40YsyyI3N5eysjLuu+8+brrpptN74aKHoTYeSp1PzZ9+SI53YFLz+n3scJTSj9zT72tx5ZVXcssttzB37lwMw+Ab3/gGO3bsYNeuXenfIf/0T//EypUr+d3vfkdubi6f//znUVWVN95440y/nAGR/So0IYax4V4jYFkWepfXbtmckWJh27YxLQvLNLEhoxXmUJFKuamtrU12P8vJwehcP0DX9SF1rt01NDTw1ltvoaoqlmVx6aWXEiwpAUXloosuIhqNnvD5mqpiGCaQGQgoioLu9mIZCYxIO3Nnz2L9+vWYpsnvfvc7vv/97/OXv/yFc889lyeeeIIbbrjhhMdRFCVjBse2bf7+979zxRVXEAqFCAQC3HfffQDMnj2bH/3oR7zyyissWbKEo0ePsnr1aiKRCNu2bePiiy/mc5/7HIZhsHr1ahRF4Ze//CWLFy9OH+t//ud/ePXVV/H5fLS2tlJcXIyu66xatYpwOMzChQsZMWIEK1euBGDmzJm43W62bNmC1+tlypQpp/pWsHXrVq644grq6ur63Oaaa67hgQce4MCBA3z961/n1ltvBZJpP7Nnz+b666/nX/75n4Fkqtf555/Ps88+S3t7O/X19elmHJZlEY/H2bNnD1VVVUSjUQoLC2lra+OCCy7ANE0CgQC5ubnpY3dtu3vnnXdy55138uSTT7Jhwwa2bNnCyy+/zF133cWTTz7JN7/5zRMGkOIsp6pZWFn41H6PPv/88xnf/+53v6OkpITNmzezcOFCWlpa+PWvf83//u//pv/t//a3v2Xq1Kls2LDhrFgQVwIBIbIolRo0HGsEuhbQvvf96acGVVZWpgcYFRUVJyz2HarGjx/P+PHj0987nU4sy0oGBJ1FykOxvWpqSry9vR2/38+o8nKqqqvZt28fzc3NJ233qSgKlt13WoiqO5IrEkfCtDa0sLfyMIsXL+b2228nHA6n78ydKkVR+PznP89PfvITSktL04//4Ac/4J577gFIn/unP/1pNm3axLe//W0uuugiFEVh1KhRHDx4EICVK1eyfPnyjP2fe+65JBIJdF1H13UcDgearrNr504qKyspLi7miiuuoKioiPz8fH71q1+lj6frOtu3bz+lYODll19m6dKlQHKwf+TIEb70pS+xf/9+XC4XN9xwAy0tLel/I9OmTeOq5cvZ+NZb5AQCVIwfT31dHaVlZel/K5ZlUXP8OCPKymhsakoXbkMyoHa73Zx33nm9pvV2V11dzcqVK9Ofk1R9zfXXX8/1118PwMMPP8zdd9/NY489xmOPPSYdhsQZ0X2tqf42nGlpaQGSTRMgWeeTSCTS/+4ApkyZwujRo1m/fr0EAkKIExvOxcJm52rCXSmcfhDw0ksvJbv5WBb5BQX4vN5kS8shPvg/GVVV0wFBqoDZoWdnXYG+TJ8+Hdu2aWxspLi4GE1TicVi1NbWEo/HaWtrO+HzFUUhGo2xe9cuiouL03ft092XbBvbsmmJxIlF40ydMI6q47XU1NRQUlLSo9bkVPz7v/87d999N5s3byYSiTB+/HjmzZvXYzuXy4WiKNx9993ous6uXbs4ePAgn/nMZ7j22mt7BAEppaWlNDc3s2bNGhwOBwsWLMDn93PxJZfg9/mwbBuHw8F1113HggULUBSFSCTC4sWLeeihh5g1axbvvPMOU6dO5c4778worLUsi9ra2nQQ03Ug8/TTT2ecR2VlJRvWryc3Lw+fz0dzUxNenw9VVZk/f376+o0eMybjeeXl5WialiyG7jajcqpCoRDt7e1cvWIF1UePEgqFeuzvzjvv5M033+R//ud/cDgc7Nu3jzFjxtDe3k5ubq4UFn+AKKqKMsgznanjdV9r6tvf/jbf+c53Tvhcy7L40pe+xEUXXcSMGTMAqKmpwel0kpeXl7FtMBikpqZmwM77TJJAQIgsSs0I6Prw+6domWZGStSpFgqncv0t28bj8XDZZZeRm5OT7PgTj4PXi21ZmJ37VeicfchyLcDpUlUVV2dhbjyRQO2cIRgqryX1h9FIJGhqakJRFPLy8giHwxl3kXtTXV1NdfVRNF2joaGRQE5O56A22W5VURVUVeHI4UNs2LCBhZdcwqiyEuIJA9NMziTYtk3q3nHqvVZUJd2yNXWdFEXpsSp0NBqlpKSEkpISJk6c2Os5fvrTn+YXv/gFDz74IN/97neZOHEiBQUFlJWVsWLFih6vp+v+3W43559/PoWFhXg8HtavX097ezuBQIBr/uEfaGpupr2jA03XaW1pYeLEidx222088sgj3H///cyfP5/Kykp+9atf8Y//+I8AVFVVMXr0aAAuueQSPve5z6W7Kj344IPpa5Kqh/H7/cydN48jhw6xbt06Os49lwULFvT5fnQ9/9LSUhLxOM732aI7GAzi9/t5adUqPvqRj/R6t9/pdPKHP/yB8ePH893vfpdJkyYxc+ZMdu3axYc//GF27drFokWL+PGPfzxkPvvi7FNVVZVRI9Cf2YC77rqLHTt28Prrr5/JUxt0w2/0IcQQkgoEhtsaGKlBW9c/5MnC3RNs32XgnxpAqKqKqihEo1FWr16dTjm4/PLLKS4uTj8vdVeZLs9NSd9J7vxfpdugMaX74ChbtM7ahlR+tqpp6bak2ZZMxzIoKi7GBopLSnA5nSe9XqFQiPXr1zFq1GhaW1swTYPZs2f32C4vLw9N03jhxRcZO3Ysy5Yuxo51oHv8aPp7QWXGTIJtY3QWhts2xGJRmpqbURSV4zU1oChUVVWzZ89udF3Htu1e1ymYMmUKs2bN4tFHH2XZsmWUlJRg23Z6Vi913Lq6WhobGmhva0vXErS1t7N161YURWHFihWsWLEi/VkqKy1l8+bNrFmzBk3TGDVqFJMmT+ahhx7iO9/5Dq+88grHjx+nuLiY2tpaHnvsMW655Rb+67/+C0imMeXm5hKPx8nNzeW73/0ud955J7HO3y1aZz1Me3s7G9av5/y5c9l/4ECfwVl1dTVVR47g9njYvXs3qqom1/pRkp2ddu3aRUNDA4WFhaecv59quxsKhYjGYhTk55OIx9F7mbX7zne+w1VXXcW8efN45513ANIdi95++20mTJjQZwcnIU4mJyfnlAqnP//5z/PMM8+wdu3ajN9npaWlxONxmpubM2YFQqFQRrrhUCaBgBBZNFyLhS3L6lH8miwUfq9ewLKs9MAfuvTm72UxrnHjxvWxWNWJB8epAWMqQLBTgUbyh+ntwpEINcePs2//fjZt2tTr2gGDKbXSr6qqmJ0BgaZpJ2x3OhiS72vyHIqKisjLz8fZj892MBjE6/Vy+PAh/H4/JSUlvW7XtaA6GAziy8nDiMcwIm1YDje6y50RzPWWdLBzx3bWrl2Lx+PB7fag6zrhcAdXXbmMF19aRU1NDV6vt8f7GwgEWLlyJVdeeSUXXXQRkEwv+Md//EdMw8A0DbBtOto7eGPdOspKS1m08BJsFCoPHGD27Nm89tprhEKhHm1nU3fKU8W4pmHgdDppa2vjnHPOoampifb2dmbOnMm1115LcXExW7duZc6cOdx66628unYt4ysquPjii8nPz08Xl3f9LKTqZlAUrrnmmvRCnt3V19eTk5ubHvAoQDwWwyaZBvHWW2/R0NCA3+/Htu30TFBXJwqay8vL049ZlkWic82O3up3LrjgAg4dOsTjjz+ertlIueuuu3jwwQdZs2YNb775JpMmTRqWndfOakoW+vorp3Y827a5++67eeqpp1izZk16vZCUOXPm4HA4ePnll9PNCt59912OHDnS54zbUCOBgBBZNBwDgcrKShwOB7ZtM3r06PSgv6GxEVXTiEU6CPj96Z77ej9TeboX2vZHf/LKbdvm0O7deP1+cnNzOXbsWK+5zdmgKAq6pqGpajJlKB5H03W0boPAwWIaCXSHM31u/S307Hqn+GQzLt3fZ4fLjeVwkIh0EO+I4/D4M1Y77i4VdLS3t6MoCm6Xi2PHjlFXV8eVy65g89tb2b17d6/BXiQS4ec//zk+n4+W5mZmz5qF0+nAti10R3J1YEfnKsEHKisJ1dayYsVVXHD++VgkV0Tu7U58X6/f5/NxsLKSyZMnc/DgwXQAkSpM/Pd//3caGhqYO3cub7z+Om+88QaLFi1izpw5fV4727aJJxI9Fu9LzdKNGjWKvXv3UjZiBIGcHBwuFxbJYm6v3881H7oWM5H8nDl0nUg0mqzs6Uy/i0SjhGpqOHzkCFVVVWiaRjAY7HWWTVVVdIcD0zBIxOMcPXaMmpqajGB+zJgx/Ou//iv/+q//CsATTzyRbi367rvvZrSKvfjiiyktLeVXv/pVRqciIU7XXXfdxf/+7//y97//nUAgkM77z83NxePxkJuby+23385XvvIVCgoKyMnJ4e6772bBggVnRaEwSCAgRFbF4/H0gHc4SBX1/sOHPkQ0EqG1rQ2n00l7Wxvtra1UHz3G3j27Moqxsk1RFEaNHs2uXbvYvXs3fr//pDnvg03prBfQNA2jMyDo7a7wmWR3dmdKzfSc6mrRXe8UnypV1XCmFiALt6I6PehOF0c7C1K7Dq57G3RrmkZNTQ173n2Xc2eew4svreoR7FVWVrJ9+3ZGlJWSmxOgrDSItzNg7f46uu+/uroaIxplyeLLiEQibNmyhZKSkoz99/b6U9+7XC6Ki4sBePbZZ2lqaqKgoIBp06bR1tbG888/T2NjY8ZnMxWEvZceRzpdyrJsItFYZ6/e9yorFMDj9TJx0mSCpaX4fD7y8vLS71+0o4NYPEFbawtr1qzh4osvTt+FT6XeNTc1kZ+fT3t7OwnDIJFIYBpG+ue9SXX48no8rFu3Dr/fz9KlS3sN7G+88UaOHz/OJz/5SY4ePcrOnTvTP0vlbj/xxBOsWrWKJUuWYNs2NTU1fa4tIbIoGyv9nuLxfv7znwOwaNGijMd/+9vfphci/OlPf4qqqtxwww3EYjGWLVvGI488MhBnOygkEBAii1JT4sNFqmvI21u2JPOhIxEmT57M0aNHqW9oJL+wqF8r0Q4mwzAIBAKMGzsWr8eT9RqBE0l1FLI1DcMwMEyTpqYmjlZXn/HzNgwDrVvRu6IoyVqQM3bUzGPpLg+qnpwdCMcibN60if0HDmS0qoSeg+5Jkybh9XpZuXIlx4/XsGL5lcQNk/Xr1zOqvJxgsIScgJ+S4iLy8gv465NPceGFF1IS7D0HuPv+U/8dCoVoa2slLzeHygMHMn6W0ltazYEDBzh08CCbNm1i2rTpHDlSRVt7OyXBIDk5OSy9/HJisTgerweXy0W4c90GBYVIJEx7ezsejydZY9FZM9DW3kZVVRX5eXkZqTqmaVJUWEBRYUHGjM6+ffs6V5G2OLB/P8uWLaO8vDy9NgedMwr5+fl0dHQwduzYdN2CbdvJz4CqZswepBcNsW1aW1vZs2cPAO3t7dTW1vY5w1daWsoLL7wAwFNPPcV9993H7bffnrFoWdd2jgC/+MUv0oXWQvRXf2Y13W43P/vZz/jZz342CGc08CQQECKLuq9i+kGXyoVO3VmfOHFiMv1H1zlwYD/Lp00nLy+PwsLCbJ8qAKZpYlkWDofjfd2xHmypGYL6+noUkoO4M1nbkEzvMjMWhwNQFSU5UzCIM16qpuP05VB/5BCXXbyAhoZ6mppbTprO1fVOfjxh4HQ6KA2WEKqpwbItDMPkne07uOyyy057Vii1Gu/rr7/GxAkT8LpdGIlEcm2BXbuIRqNs2rSJaDSK3+/nqqtWEI3FcDhdLLn8ClRNxTRMykaM6FwwLFkrkpeb26PI3bZt6urr2fvuu7z55psZwVB1dTVr165lxowZtLa20tLSkhGs2e4uq712Dto9Hg9ulwvbSgZ87W1tmYX2nds6HA6i0ShRy8Lj9fY7Rae9o4OysjKCwSAdHR39vr7XXXcd1113HQA333wzM2bM6HUxtdra2pPuy7btdDcnceZls32oeI8EAkJk0XCbEehe7JnKA071oY9HoyxavITx48Zm90RJrnNgmOZZtQ5BKsXCMk0A2tvaePGll2hvbwc4Y7UNlmn2WqisdHY3GuzEN0VRUJ1uahqauOryJezZt79fA8tUsLd3716O14TSqSYXXnghCxYsYOnSpegOB8uXL0+37jwVwWCQUE0Nfn+AquqjzDw3Rk4utDQ3YZoGYysqmDh5Mh0dHbS1tmGYJjk5OWx9+21ef20tbrebiRMnYts2582aRW0oRNWRw+nZg1SBvWlZYNs4HY70ALi9vT39/odCIY4fP059fT0Al156KZs2beLiiy5izauv9ggYTdPE6/PxzP/9Hz6vh7lz5hCOxfpMaSwuLqagoOCUfrdVVFRQWVnJsiuuIByJMKbbegb9UVJSQm1tLYlEgt///vcUFBRw5513Ul9fz3e+8x0CgQAHDx7k/vvvx+v18ve//53HH3+cd999lx07dhAIBGhubsblcvGjH/2IxYsXc8cdd/DFL36Rm2+++ZTPR4izgQQCQmRRPB4fVoEA9F3UO2PGDOKGSSxhZOGsMlmWhdE5WzOUg4B0m8zOmQsUJbmCcud5O7rMNp3OXez+tkw1DQNHLy1wVUVJr+w82AqLilAUhZrjx5l93rl4PB5syzrpHUHTMCgqLGT16tVA5nUbP348pmn2K12g+7WzbZsRI0bg8/kYUV6Ox+3G7fFgWBYWCmPGjqO+vp43N2zg+PHj6Tv4JcXFzJ8/P72v5uZmcvPyiEQiaJrGwYMHsYFATg4ejwe1s1uSrSh0dHSk7453fR1duxT5/X4ikQiGYdDc3JwRMEAy5cuyLAry85kzZw6NjY2YNowfO7bP+o9TKRTvqqKiArtz4bz+1pb0xuFwcPvttwOwfPlyfve73/GTn/yEL3/5y0BynQWXy0UsFst4XnNzMwCxWCwjzWjdunUUFxefdIVsIc5GEggIkUXDLTXoZByaSkc02cJTzdIAPNUbfqgGAak2p2bn3V9VUVA1rdfVhk+lG0931dXVrFy5Mj1Y7CutKBmA9N6qVVEUItEo27dvH7Aahf4EJ6lrFAwGKS0tTQZLiTiJcCu624eq9x58m6aJaZrkFxT0OnMFyWLormsH9HWOK1euZMGFFxKORGhpbcXtdqMqCj6/H5/Xi6Jp6RWRkylcCk8//XfOO+88xowZw5gxY3qtaSgtK8O2bd7Zto2dO3dSNmIE2995BwWYPXs2iS5rS4wcObLX97/75wJg27Zt5OblUVBQQDAYTP47MAwUSLf27FrAb5kGiWgYh9uDonRbIVxR+iwMPhmls5NQIh5Prz7c/T04FW63m89+9rPccMMNGW1puwcBTqeTeDzOvffeSyAQ4Gtf+xpXX301b731FqFQiP/3//7fB24hqaw7C4qFhwMJBITIouGWGnQyiqLg1DUShonLMfi/nmzbTs/SDKUgIL2ugmkmg6RUa9V+rCx8urUNbe3tLLviCv765JM97hJ3ZRoJ9M6B9d69e6mrq0svtlVXV8eEiRNZu3YtXq/3fdcoVFdX88477xAOh09Y82BZFmqXVCVFUdCcLhRNx4i0o+oONJcn49pZppmc2egMAPuauUoVQJ9IKBQiHA4TiURwOBwcra5m2rRpyb75hoFt2+iKkk47Gz9+PKGaEHPnzj3hQl2HDx/G7Xanc+g3bdrEO9u24ff7KR85Mr04V9dORn29/90fX7FiBR0dHfzDNddQUFhIPJFIFhb3seq5qunoTkhEI70GA9FolO07dpxWAKiqKvX19bS3t5+0i1B/FRcX09raymuvvUY8HmfRokW43W7cXeshuvjqV7+aXmBu2bJlQ+r3gRADSQIBIbJIAoGenLpGNJ4Y9EAg1V+9+0AqW7rn+6uqmuzdPgjnZhgmZWUjaGlM5pD3lVaUClB0h8revXupra2lqLAQn9dLR0cHebm5vL15MxdddFF6Ma33EwiEQiE0TeOCCy7gL3/5S6/7q6ysxOPxEIvFGDt2bMbPVE3D4cvBjEVIdLSie/wcO36clpYWRpWXE8jJ6deALxwOs2fPHgoLCnp9Pam1CuKxGI0NDUydNo1INJrsm69ptHV0sPvtt9N3ui3LoqSkhBEjem9xmWqBaZoma197jcaGBpYuXZq+qz9u7FgCgUCvK/T2Vyp9qa2tjYbGRgzDoPQkqWR9BQPV1dVEwmEOHz5MXV0dLpeL/Pz85GtJvqAe/211mUGwbRtfIIDX50u2Fz5JF6H+CgQCXHXVVf3aNhUAKYpCXl4eTU1N7+vYoheqmoUZgez/bh9q5IoIkUXxeFxSg7rRNRXTsjMGBmdaKh0otTjXYKqurmbz5s1UV1enaxPisRiJeBwAh9OJ0+UalAAleR0MTMskJ+AjNy+PRYsW9Xnn3TQNNC05YMoJBGior2fls8+yY+dOnv6//+P5F15g565dRCKRAVl/IRgMEu3MZx87dmyP/VVWVrJ27Vqam5t54YUXONDZorMrRVHQ3V50t5dIaxP79+4hHovx5FNPcfTo0ZOeQ3V1NVu2bOHw4cOsXLky3Qmoq/Lyci699FI0XackGGTb1q3UhkIoikJzSwtNzc2sW7eOl156iQMHDmBbNqqqpPef/jyYZnLl3Xic1pYWXnrpJSZOmMCMGTNoa2vj2LFjVIwbR25uLg6nk6NHj6afezpCoRAJw2Db1q38/W9/69d+ksGAm0Q0kl5LIhQKsfa11/B4PCQSCZqamt5b7bnbIn5255fSWd+i6zoup5PGhgYef/xx4vH4kFi7Q2YExAeVzAgIkUUyI9BTshe+RiJh4nKe+V9RqVzobCzsVl1dzWuvvcao8nKMRILWlpbkaq79SPkZaKkgAAWcDgeWZeH3+/tcpda2bUzDQHc4ScTjxGIxakIhIHk3tWsxamFh4YC0Li0vL08ukgYsXbKE3Ly8jJ+HQiFmzpyJx+3GMs0T3kVWdQf7DlUxbvQodF2n4wTpT13V1dVRPnIkr7/++glTphKJBBUVFfzxf/4HSOaqjxkzhiOHD6fbU6budI8sH4WiKOnagvLycgry82lubiYvPz+9YjHAyy+/zOLFi8nPy8Pj9VJ99CilhoHucNDY0EAkEuFodTVut5v8/Pz3+vZ3SZOqrKxMHnfkSMrKypJpZ7aN1+fjrY0b2b17N7FY7KTXo2u9xoiyMhKxCA5Xcq0NVVVpbGykrKyMouJijM6ZLaXzHBRVRes8r94+6+PGjeuzTkMIMXAkEBAii2RGoHdOXSMSTwxKIGCYJgr0mQt9pti2DYrCpEmT2Lt3LxvfeotLL720z4H3mT6XeCKRHHB2XgfbsnrkfXd14MABvB43breH/Px8xowdy2WXXZauESgvL0//98SJEwfsXMvKykjE4yiKkqwF6DJLMnbsWI5UVbF69WquXL78pMFUUXFx8s565X5uuvYabK3voLy6upq6ujrGjh3Lq2vW0NzcfMI71WPGjmX9unVAZmpVfn4+7R0dPR5XFIVQKEQsFqNi3Die+tvfkp+HzjU1urbeDYfD+AMB1r7wArFYjHPPPRen08m6detQFQV35+Jh+Xl5WJ0LfdmdK/uGw2FM0yRYWsrRo0dRFIVgaSmqZdHa0sL+/fuJxWInvQufClpMy2LkiBG4L7qIQCBAPBqmuLiY6667jpaWluS5dFvnoL/6qtPIhtPpgiROTNE0lEG++TLYxzsbSCAgRBYNx/ah/aFrKpZlY3VJmTgTjM5WkI5BDgJM08QwDBwOB5s2bUrfOc9G+oNt28TiybQoXde6PG6har1flx2738Xt8dDWEea5519g3rx5zJgxg0mTJjFp0qT0dl3/e6CkBpOarmMYRjqQtiyLgsJCwuEwU6ZOTS60lZfH1q1bKSoq6vXO9siRI2lrbU0OjlWdwoAPIxruUUhcXV3NCy+8wMUXXcSra9Ywbfp0Ro0e3Wch7PHjx/H5/YwZM4acnJyMO9qpPv4XXnghwWCQsWPHYhjJu+XBYJCSkhKam5vx+Xw9Pg+pgfGx48fZtWsXtbW1+P1+8vLykq1DVTW5ZkRnd6LuKz0DbN6yhY0bNzJ//nx0hyOZgmfb6UXzTtZlKlUXoigKl112GQ0NDXSEwzQ0NFBQUICta5jxGLk5OeR1m7E5W72fVqZCDHUSCAiRRZIa1LtUelDcMHA7B/76VFdX097eTllZGTn9LBAdCKlaBBQFp9NJsKTkpAOv/vbyPx1WqkuSrvdIi0oOfnrOCLTHDOK+QkxFITcvB83porGxcUDPqz9SMwGpQWnCMHA6HOnBcmrwPn7CBDZu3AjQ4/qlFspKzcLYtp1RSKx2XpPa2lrOPfdcNm/ZwvHjxxk1enSfMzfV1dUYpsnON9/kwIEDPVKi2traqK6uTgcHhmGmg93y8nIuu+wywuEwo0aP7nMgXlhYyOhRo/C43RkzLv1pFRsMBnG73Wx4803+4R/+gby8vGS6lfLeOXR9bmqtilS7WgCtc/vVq1eng9gpkyd3vicqilNJpwl1X7dhz5491NXVUVxczJQpU3o9x6HG4XAQ76zZEQNIVQe/eFeKhXuQQECILJJAoG8uh0Y4lhjwQCA1QLxk4UKeeOIJli1bdkZW2+0q1QHINE0c/WzvmDrX/vTyPx2WZRFPJHD2UYTc213QpnCcI01hVAW2v/4Kc+YvYMlVHyLS0jAg53QqbNtG13VaW1qIxGIoipLR5SYUCnHkyBFqa2uZv2ABqqr2eE2WaWYsupYqJLaMBEakDc3pRtGdjB8/nldffTW90NeJZm5aWlrw+nyEQqEeNQQHDx4kEY/T0dGRLBK2bUaNHp0RhBUWFlJUVNRrvUp1dTUoCrqm9Zh9gf61iq2oqOCKK67A5/cTj8UI+P0kDAPTsqirraWmpobS0lJKS0sxLQu7c00PtbO/f+r6jRgxos/AQ9U0dJe7RzCwZ88e1q1bh6Zp7N69G9u2mTp16gnPdyjoOvMkxAeNBAJCZJEsKNY3TT0z6UGhUIi2tjY0TaO1tfV9t7Q8mVTveFVVT3mRslAohG3brLjqKg5XVVFfXz8g52qaFgkjgdPh7PXa2raN0u37UHuMmtYoHodGRWEO+jlTqauqxD1hCt68Ipo6ouT7eu/JnjJQsxupa3js2DHa2tqoratjz+7dGYFS19VzN731Fh/60IeSvfE7O0MdO3YMXdNIGEaPc1F1B8fqmvA4VPz+AD5/gNmzZzNy5MgTnnt1dTXFxcXU1NQQ7qVTUjQWQ1dVysvLmTx5Mg6nE9M0URUFuzOHvqWlhVAoRE5OTsZxqquree6555g1ezabT7CGwslYlsWIESMyAlKnw5E+Z5/fT2trK06nk8KiohMu7HeiwENV3wsGdNd7aUsLL70Un89Ha0sLXq83+fq7zEiIYUQWFBsSJBAQIosSiQQ+ny/bpzEkpRYXG+j0oGAwiMfjYd++fZx73nlnLC/ftm0M08SyLBy6flqtP4PBIMGSEhoaGlAUhbHjKojF4snBrHZ6gyfDNDEME9cJgpLjx4+jYGNaNiNHjqSqOUJjOE6OW2dMvg9NzVxltiUcoy2aIGGEKQq4e32tAzm7oShKMjgJhVizZk368a5BXfd899QKw4Zp0trWxtGjR9MFwN3PpbKykpdeeom5c+firG9g7OhRjCg9cfBSXV3Nmxs3Ul5eTnFREbPOO4/S0tKM55QGg9SGQjyzciWTJ0/m4osvBpILlMUTCSKRCM3NzaxduxZFUTLOKxQK0drais/nO2G3ohMxTRPDNHsNSI8ePcqaNWtQVRXLsli0aBHFxcUn3WdlZWWfq/8mgwEPRiyCojsZV1HB/z39NJMmTyZUU8OMGTOS6XKdaTeqpqF1WQhuqEh93oT4IJJAQIgsisfjH5iCujPBeQbSg1IDxNraWiZMnEjA7x+wfadYlkWi8+6z830u8uTQdaLRCJruIC83Jz2YjXV2ztE1rd93VBOGgWVauJx9n1N1dTVb334br9dL5aHDLFj2DyQUnSKfk5G5nl6fl+t1oWsqTR0xQq0RgjmeHsFAKBRi0qRJeNxu3li37v3NxHQOzLre9e8tZaf7Hetk7YnO4UOHiCcSHD58GMuyepxLKBQiEAhQXFTEE3/9K4sWLmT6ZCcdkSgHj1RT0nmcrrMbdXV1jBs7ljfffJNFixahKEqP4KKoqAhFVdOFwoFAgHg8QVNDA1WdPfu3b99OR2dXoa7nlXqtCn0v8HYihmFgWVafn8eTXcveVFZWsnPnThSgubkZp9NJWVlZumUpALaNrWrYiRh5OTnMmzeP5uZmFl56KYUFBcltOlfwTf27oXP1bFXTOHToUJ+BxmCRIEB8kEkgIEQWSY3AiaXSg0zLGtCFvlIDRMMwME1zwFqHptYkwLZPOQ2oL0VFRcl8+M7PSWow69D15AJkpplMPVJUdF3rtU3je+cFzhMEAZAcfDY0NjB1+gwCY6eSQGNErptin+uEz/O5HDg0hbrWKMebwxTneHB26UIUDAbJy8vD6/UyZuxYzM6+8l31N3UodYe2P11uelNQUMD69evTayV0H/QGg0Fs2+bgoUNceuml5OblUdvcRuhoFUWFBax99VUqxo/njTfeYNasWRw/doyJEyfy8iuvEA6H0XQ9Y5+VlZW8++67xONxXn31VZYuXZosFDZN2jvaOXbsGIcPH0ZV1XRRavfzSr1W3eFgxdVXUz5yZL9ea+q9V0gWvfb1Hp7qtbRtG4/bzcgRIygpKWHv3r1EwuF0cXFq1WCzs5gbzYERj1IxbiyKomLZNrFotNfzSdXURKNR8vPyOHjwIC+99BJLly4dMu1ExfunqBrKIKfqDPbxzgYSCAiRRfF4HJfLle3TGLIURcHp0IgbJh7nwHd70DSNeDz+vtIRUoPX8lGjyMvNRe+lA8/71sepqaqKs7MI1rJsDMPEsi00NZk6dOzYMUKhEBUV4/H7/eiOk7/OYDDIrn0HqLdcOF0ugh6FPEeysFY9yXVy6jrBPC+1LWFqWyMU+Fx4XckApqWlhV073mHOrPNobQ8zelxFMjghOfALd3QQCoV44/XXcbndJ0wdOnDgAA5dJxyJMH369FOeWejPoHdcRQUH9u9n5MiRuFwubNtmxKgxuN0url1xJaaikpeXl3yvbZuXX3mFc845h4kTJ5ITCBAOh9P7CoVCxOJx9u/fn15EbPz48ViWRX1dHavXrOGqq67imWee4bLLLkvPdnQ/r/Lycmrr6qivqyMei530DnlqfYjUir39uS79uZamaWIaBgnD4K1Nm1AUhSWLF+PxeqmpqSEUCjFixAgKCgtxOp3p2SHbciRrBhxOFFVNFqv3USNl2zb79u3D4/Fw6ODBjOsmhBg40kdJiCySdQROzqnrxBM97x4PBEVRkv3oe7k73R/V1dWsWrUKh8PB0epq6urrBzwIsLFR+ooEOimKgqapOJ2OZO6/qtDS2kYsFsft9rBp0yZCoZp+BTuBwiDnXHw5TqeTPCVGWWEeusOJbVvEY1ES8RiWZfaZLqGrKqW5XpyaSmN7lNaWZhLNdVQUuPnQwgvIdShMK8vFGWnE6mhGsUz0zhSQw4cPM2/+/HQOfG927tzJxrc24TLDWC217Nu94+QXsRfl5eXMmTOn14FvKBRCVRSmTplCJBJBQSFh2uw/XMXOfQc51NBGh6kzPkdltF9lZK6LWVMn4HVq7N6zm4bGRl566SUOHDgAJIMrh64zfsIE5syZQ15eHjt37qSurh4Ar9dLc1MTo8rLcblc6fOqrq5m8+bNyW5BJGcWtm7dypEjRzL239s1Wr9+PU1NTZ3rQ7z/e36VlZW8+eabNDQ0JOtenE5Gjx7N0qVLOeecc1BUFbfbTX1dXbo9b31dXUaKmKKqOFwejHi0c8E6Jd2StDvTNBkxciRrXn2V5paWrK2zAQy5moUPDEV9r4XoYH2dYJHE4UpmBITIIkkNOjlNVbAZ+PSg9/afTMewT2NWoK2tjUsuvpj1GzYQCoVYtGhRv1M2+s2mzxmB3qTqBioP7GfdunXouk44HKagIP+kd3vr2mMcbYng6uwM5OpM7VFVFVV1ouk2tmVhduabJ4uWdRRVZefOnTQ0NBAsLmT86HLyjQ7sRBQ7AXHNRUvU4qVXX6e+oZGyYDGLFlxAsTOCFWnB1l2MLs5j5/Y23G43FRUVfQ76GhoaMCwbAsX421sYlevAqD+C6stHcfvf16AtWX9hUT5mHIrDzaGjx8gvLKTD1tAcOmMrxtNYX49DAWLthF257Nq6hUkVYyh0K/icBtdddC7huMmcyWMwO5rZt3snx+samDZtOvFEgnEV43G6XLjcbnRVIc/j5OMfuRnbhvEVFex6910OHjyI2+3mxRdfJBwOU15ejtvtxul0MmH8eEKhEPv27XtvZqEzBcc0bWrr6nD7cxkzIoilKHSEI+jdPtup/+x6pTKuW7dr2NHejsPhIDcnh7Vr1zJz5sz0nfmuq/9u3ryZgwcPUlhUxDPPPMPChQsZ2e3fQyoYSMQiaA4XCcPA1WVWwLZtjEQCRVHIz89n0aJF1NbWZrVGQIqFxQeZBAJCZJG0Dz25dPeghInHNfCBgKIo6J2zAv1dYdi2bUzDYERZGX998kmamprO2B3L2toQtbV1uNzuU+q5HgwGcTqd/Sr+tG2bYy1R6jpi+J06Ywu96L0EXYqioGgaqqYl05FMk0QiTltbG7YRY/r4sfg1g0RbI7ongO7PJ2yqNEcT6Pl5zDl/Lo2NjRQWFjJifHIxKTMRxwi3ElCi3LT0YqKGycTy+bhzCno918LCQo5UHyWme3nl7XdZuCCPijIXVvNxUDRUXx4Ha+qpqa3PWGyr++s1LZuEaWGYFoZlkTAtTCvZM193ezAtC5/biZKIUlZWjG1ZtJgxjjQ3UFpYQXX1USrGj2fDO3swnH5KS0uh1cDr0jm0bz+lRfmMLPChqwpFxVMJGzb5hV6qqo7Qcfw45SNHkpuXx9s7d1NYUIDX48KwbI4fO0ZxURG6rnP+3LmYhkFTczMNDQ24XC42bd7CvPnzuWjhIsaOq6CpPYIN6KqCqioomooRjZJIaDitdtoSNnlFpe+N+hWF1DcWNsnxbXJ14fT7nAo+04uJ2Rw9epTDhw/T0dFBY2MjFRUVPYKuYDDIpk2bOHz48Ak/c12DAdRkrUtqnYdEPI7WJb2ua6CRLbKysPggk0BAiCyS1KD+cek67dEYHteZuVaqqmL0c1YgNVhRVZWc3FyuuOKKM7by765du2hubGTfgQNEo1Fs22batGn9em5/iz8ty+ZwU5iWaIJ8j4NR+d4T9o5PSaVVabrOu5u3oDuctGg+Opwu4tEIBXoAFyoet4bu0Khvi5I/cixTpkxD198LMjSHEzWnsPOagi8RxYq0YzZUY+oOVJcf1e0DPVl8PX36dOzO81tw4UVMnDIZADunCDvcSrS5lnKPRUSJsuPtTaAojBozNjngNy0SVvKuv6KAQ1Vpa2ulpakRr9vF+HHjOHToIJqmsXPnTqqqqli6dCmKonDw8GGqqqqoqBiH0+miuroaj9fLjTfeyKFDh2hrayMvL48DVdXo/gJcJaOx8/Npbm/DhYlL12msr+XF558jPz+fCRMmADZvvvkmEyeMZ8G8eTS0tFFcXIxl26iaztFjx/F4vRSXjaSgtAxN01i4eAlGPE7FuLHk5+WgaSqqomCYJpFYAjMeZ82qFxk7ZgznTJtKjlNBNyKovlxAwe5cITh1h1vVVBRV5ciRI9TU1DB61Kj3zkFVO3P54yQSBiNGlhMIBCgfNYpILHOlXQUoKi7hxptupq29DZ/HS15+HoZponR+XlL/thRFyQgGmpvbOXCgkgnjx5PbudLxUJIKVMTAkmLhoUECASGySFKD+kfTkn+Ez1R6UHpWwDBO+H6k2hs6dB21845lfwssT0d9fT3FRYW0vt1KPB6nvr7+lJ5/snNLmBYHGzoIJ0xKA26CgRN3BupLbm4ur7/+Ou1rX6U4WMq8Cy/CzgnQEonT0GGjqwpuh0YkYXK8NUxHQw21x49RWFjI9OnTk52QnM7k3WCXH92TQyIWRTXj2PEwRkMTaDqq24/i8jFtyhQON3bQ2tbGzp07mT59OqYFMc1Nu7MIh2IwrsLD5LHlGIpKvK0Jy+lH13U8TgVdU8G2OXbsOKpt49ZAw6KlqRG/z0tLSyt79+7FNM10+k0oFGL37t2ce845PPm3vzFnzhxM0yQ3J4ctW7bg8/n40LXXUlJSQl5uLrm5uTQ1N/N///d/LF60kBHFhdi5ucyZM4cZM87B7XLS2NCA3+/nvJnn0NbejsPjZfyUaXi8XlxOJ7PnnE9LczN+n5fCgJ9jx46mAzuXx8WmtzYSDAYZUT6KcCRC9ZHDFOTnc9FFF9HY2EhuQSE7duxg0mgbvxFHDxSi6g5SQ6FUy86G+noUkt2UDh8+TMIwGDt2bPr9HVFWRiQcpra2lpyAn6KC/Iz3PxVU2LaNIy+X3NyczkkGG8u2sDv/O91NqItwRxSPUycvN5e/P/00559/fsYaFUKIM0sCASGySAKB/ksVDZ+J9CDonBUwzV7TAFLtDK0+FmM6U4qLi/G4XcTjcfx+f78WeOqvaMKksqGDhGkxOs9Lge/0U9SmT5+ObdvptJ/JFWPTPzMsi1jCJGaYaKqCYdl48op4e+UzuD0ebNtmxowZ7wUDiURyQOlyE4+rOL05YFvYsTBWtAOr4xgJ08J2FFFSNgqv101Nczs2CpoClqqyc99hGhvrOXfaFIIBF55YM1akkVBLGDy5lIwox7Is3B4P0WiUykOH2bVzJxdccAEjR47kldWrMU0zI70lGAyy+LJFvLJmDRdfcgmRcJjm5mby8/KYPXs2x44do76ujrKyMpwuF22trbS0tLD8yiuTaS6ajhaPk5Ofj6ZpvLtnD80tLSy65GICXg8uj4djdU0888zTnDNjBgsXLiTX6yZYlEyRqq6uZsObbxLwJwOaeDyOPycHX04e7R0d7N29C03XqTdNxowdS7C0lI5wmKbmZv68bRv/cOXlFFoWmj8PzeUFUkXmGsdravB5vbz00kvEYjEuvPDCjEAATpyi0/VO/4l0bQ87YsQIjEQC00jQHguzevVq2trbaWxsPI1PoDgrqWoWVhaWmZ3uJBAQIovi8bjUCPST06HRHjlz6UGpItvuswK2bZPoLF50DGIQADBlyhSaGuqZO3cuxcXFp1QjcCJtsQSHGsLY2FQU+QgMwDXt6y6urqroLhVf5zFef2Md544fSY7fS2NLW8bAT1EUHA4HhmFgGAaaptHU2MjBQ4cIBoOUlZVhGwlaW9tRsYlEO9j/7i5yAn7mzT2/873x0daYh2olSBgmroIy6uvq8TosivNUdBIkGqpw5ZdwpL6O1ra25OrJR45QXFxMRUUFS5cuzShQ3bNnD5Zpkp+fnwwMbJvKgweZMH48hmGgOxwUFBSiaTqqptPa0orT5aQkGMRIJNB0nVBDM4U+F+NGj8ZWVSzTZFz5CEaUBemIm4RjBkerjqBrGoWFhaxfvz5d5xEKhQiWljJy5Eiqq6pwOBy0tncwZuw41r2+lpEjR7Jr167OO/DJQDYajRKLRmluaqK9vZ3K6uMEL5iL0daAnYih+fLSXXvGjhnDk089RSwWO+Val/6u/ZBaWTovL4+A309rays5gQBNzU14XQ7aOmtZCgsL+33swSTFwuKDSgIBIbIokUgM2GJWH3SplCDTtNKpQgOt+6xAKhXojKwN0A+2ZRHIyWXhwoUDts/GcJyqpjAOTaWi0I/bMbivKz8vF802Cfh9xE27x8CvazDQ3t5OXV0dXo+HeCxGc1MTmjdATHHy5ppVVB8+iN/v5+KLL84I0CZNmsSkSZPS3+/bv48NGzbgdDopCHhZcuH5FGEw2q9QFbEpKA1SUlKCaZq88cYblJSUUFhYyPHjx4lEIuzevYsLzj+fZ1auZMGCBbz99tsES0pobGzk4MGDTJk6jbq6OjRNpaW5iQ0bNhCLxVixYgVerxdVVZOLedkmHtskZttMqhiDoqpYqhPdmUx5mzJlCpMmTWL/gQO0trURiUQIBAJ4vF5279pFR0cHDQ2NnD9vAY2NDTz1xJ9xu91MnTIF0zTTheGFhYVEIhEMw2DbO+/g9/spKSlBdThx5JVgtDURrjvK0cY2SstGkJOb/Iydanee6upqXn31VUrLyjAtC6/Ph9/vTxYZd9vW5XYz94ILCHd08Mrq1cydO5c5c+YwoaKCmprjzJ07N50qNtRIofAZkmrpOdjHFBlkBCJEFpmmmZUB5tnKqevEDAOvdmZmUVKzAqFQiIb6esrKysjPz0fJ0h8Py7ZQ1YEZhNi2TagtRk1bFK9DY1yhD8cZCqhOZPr06URCh5kxfTqm6uhz4KfrOnV1dVi2zdrXXqO9vZ2rPnQ9ftVNaa6P6VMmUVZS1K/BY0lJCX6/n/b2dtpjTtoUL8HgOEJ73qEk4MQXb+Ly+bOIKE7WrVtHLBZj3759jBw5kslTpjBu7BgSCYM555+PaZrMu+ACOsJhIpEIe/bsYfyECYQ7Ojh69CgzzzmHqqqq5B1k2+ZIVRWlJSVs2bqVC+fPA9PCiUXU6UmmxiQSPPPMM0QiEebPn080GiUvL49IJEJzczMOp5MtW7YkX//VV3PRwkUY8Rh5AT8XXHBBeuDu9/t73Jlvamxk9uzZGd2TFFUj1BYldKSSaRPGsfa1V5l+3uzT6s7T3t7OBfPm8fbbb3O0uhqP2830GTN6bUsai0Z5a+PGHl2sLCPByPLRlI8ee0rHFkIMDAkEhMiyoXa3qb9T/f197p49e6irq6OgoIDGxkaKi4uZMmXKKe1379691NXVUVpWhj+vgE1vbjhjdw/37NmD3x8gGo3y1yefZMGCBWe0eLGysjJ9zbrfibUtC3UAZows26aqKUxTJEGu28GYfO+ABRinQ3c4mTC+At2bc8LtPJ7kYmhLliyhurYeX34RJQEPLod2Su/JxIkTsW2burq6jEGx4Qzwl1dWE8zzM2faBEoLcrnlyoXsP1rLOTNnMmHCBMxEgmONjWzfsYPZs2cTTyQI5Oayd98+Jk6cyJIlS7CB5cuX09HRQTgcxrZt/H4/hmmyft06br7pRs6dNhnNMgibNrrDSbS1Dc3tpaW1jZkzZ3L48GECgUCyDSlw+MgRdF3H6/EwafJkxo4bj8/no/rIIYqLinoM3LsXhh89ehRN0xgzZkyPf8ehUIiDx+uwVZ0LZk6lI9be7xaZqc/ruIoKSsvK+OsTT9Dc3Izf7yc/P7/PjlO9dbGyOxcTy1agLYSQQECIrBtKgUAqj1fTHfj9fi655JIe+cJ9ne7x48dZteplwh1teL0+Lr/8cjo6Onj99deZOXMmGze+RXt7G06nE9u2+53vvnfvXlavXo3b5UJXbPw+P8ePH2P37t3pQtOB1NjYSF5+AXX19bS2tg5Y8WLqDrHd5b/r6uupb2hg/fr1+Hw+li5dmjG4sy0b5X2uhGlYFocawrTHDYp9LkbkurP+mUsYBq21tRh66wmDzdTPwoZNxZTpFPvduE4zlSmVLpRarTcYDKYDhI6ODqIuP1Vhi1wHTCsvIhY3cKgGbZZCNBajsLAQh64Tj8VQFYX5CxYQjUbZ9NZbqKqK1+OhpaUFn9fL3LlzKSgoIB6LceXlS9BtA18gl4Rts3fvu5SOKMftcmIlYiiaji+Qw+jRoykpKUm39pw/b14yRcqyQNUIt7VhxKMk4nGaGhvxer3kBALQ2Zaza8Hu0aNH2bJlC16vlwMHDrBixYqM6xwMBtmxYwcOr5//W/0G1y9fitFajx4oOGF7xcrKSlatWsXs2bM5dCgZkCxbtqzfNw66ByumkUDTpVnCcKVoGsogz4gP9vHOBhIICCHSQqEQsViM6669kba2VmzNSVsk1S/c7vL/e1JdPi5atIR8NQqKgtsFOU4vl196EbnBcsrHjMWKR8n1+1BVjVi4HUVJ9ilXtWQ/6d56dYdCIc47Zzq5OTkcqDxIPLGb+XPP57U31p2RDiOjRo3mYGUl58yYga7rPXLYu7ZKTP9vtwF+co2mbldKUZIpE6mBG9Da2sbEiRN54/XXaW9vT7eqTB+L97eQUcxIdgaKGRYjcz0U+12nva+BUl1dTaKlnnjCYM2bW3oMUrsLFJZgR+IU+10otvW+erqnAt1UesqKFSsAqDpyhIrx43njjTdYcfXVHG2oZ2RhDnoiiuIuZszYAEXFxSi2jc/nY+WzzzLrvPPIyc1l/IQJ6ZmAnJwcnnvuOaZPn05OwE++34Npe4ij0VTfiGWZna1OLSxFo6O1GSMWp6C4mMLCAjo6ZxPcLhdVVVWUjixHVVWee/ppGurrOeecc9i5cyculyvZVagzmLbt5IrPqfacLqeTiRMnsm7dOtrb2wmFQhnXuLy8nCVLluByuyksKMBXPBIz3EKiOYQeKORQ1dGMWapUm1GHrnPJwoVEo1FeffVVLrzwQhYsWHDa7XMtI4HD7T2t5w4mKRQWH2QSCAgh0oLBIC6Xi53vbGVsxXhIRMj396+LR3VzA6+8kDnIam/v4NVX13L++XOoDYUoKshHHTECr9eL0+XEtsEyTSzTyBw4KyqqqtLU3MzIsiCWYfD3lc/h9/uZ6A/w7Asvcs1VVxGJx/s+odNUWlZGONxBNBqlID8fXdNobmrC6+0yYOkcyCuKkvHfqqqiAEePHTvpXVLbtikJBqmrq8WyrB7dWg4dOojL6SQSjfW7eLOrjrjBwYYOLNtmXIGPXM/QuPMaCoVQY20UFRb2OkjtqiUSpzUST6cD9bbybF+6p6lZloVpmixYsID6+nq2bt1KKBTCMAzmzL0Ap0MnLy+PDevXc96sWVQeb6CstBQjEqHNNCnND7BuwwbKR45k0aWXojscxGMx3tywAZ/Px+w5c8jLz+eWW24BI4ZtWbRHE7h9PqLhMK+9tparrroKDZu2cBjd7aO6upoZM2ZgmiaGlQwMwx3tjBk7ltHjxhOPx/j7k3+lra0t3T7Wsiw0TSMvL6/PaxCLx1m7du0JV5UuLy9PLmhYWJisjfHlYekuYk211B09TF1TG16PJ/nZ9/lQVTVZr/Hqq0ycOJGrVqzA7Tr9wNK2LFDOnrSgbM+ifSCpWhbah8qMQHcSCAiRZUPpblPXPN683By8Xl+/c4f7WsnWtm3q6+sZNXoMTU1NtIajlJWPxjKNzgDASs4M6A5UTU/eWbfMZH68oqDYNu2RKOeff34yB1lV0XWdjkiUcWNGYVkm6gD9crc6c5aLCgvZum0blZWVRKNR5s2bx4IFC/q1j9Rd53A4jNfr7fWOt23bxBMJvF4Pfr+fCy+8MKNGoLKykuNHq8nJzeOd7duxbfuUCjmbI3EON4XRFIUJRX68zqHzqz4YDFK1rwF/Z4eZvlpVdg8CgIy1BhobGzly5EivwVbqPbAsi+kzZhDIycHjduN2u3nhhRcYPXo0H7r2WmzLwu8PsHPXTirGjmXOnDmsXLmSqVOncuDAAfw+L9FYguDocbTFDKbPmEGkowO3x8PGN99k3vz5XH311Wi6jmWZmLEIDhU6YnFMJXnO7W1tOBxOpk2bhq6qmLZNbk4OURPKRoygtaUFbJuW1lZ8OXmMDgaxLIvGuhDHjx/jkksuobq6Gsuy2LhxI5dffjkFBQUnTanqz6rSiqqmAwsAxekm1BFnxuQJjGxuZdUbbxKORNKf/TFjxqRbqwa6BCanM0NzNqUFDaXf0UIMtKHz10GIYWgo/oFJ5fHatk1LOEZHLIHf3b8uPb2tZNtXLYCmOtEcyf3aloVlGpiJGLZloigqqqYTjkZ58ZU16Tubl19+ecbdcduySMQi6C7PaaeLpPdl28TjCVAgHIlw8OBBOjo6TrmveigU4qILF+Dz+di1a3evd7wN00RVVGxsgiUllHUWiAJYpkGu38sx22bfvn3MmHEOfn8g3Vf/REGZbdvUdcQ41hLFrSfbgzr100+jOd2i8RMpLy/Ho1roisWHPvShdHFsV70FASmKolBbW0tNTQ0dHR1s2rSpR7AVCoUoLS2lvLycqqoqDuzfz+zZswkGg1x11VWEQiEs08QfCLBjxw4qKw9QkJfHxIkTWXjppSQMg5KSEoLBUlra2iAWxvb4aWhuY+e2LSy74gomTZxIa0sLXp+PN9a+ysUL5tHU3sHRmhAbNrzJ0iVL8Pp8eLxeIuEOJk2ahENVeHn1Gi655BIURUNRVHJycti1ezf5BYXJNUUsi//5799x7rnnUlxcjG3bzDrvPP7+9NO0t7fT0dHBzJkz+3WdT/a+qZ3rGWialg5O3R4fuw4dxq/DNYsvJmxnDta7FimnnqOpKkeOHOmz6L03Z0taUIrMCIgPKgkEhMiyofoHRlEUcrwumjuiROIGnjN4V1lR1XRgkM53Ng3KSoq59cM30tbWjqLpBEvLejxPd7kxYhEcLs9ppxmYpplc0RYFt9PJ2LFjeywq1V8jRoygsb6ep//vGWbPmsWkCRMwjASapqMoCqZlYZoWTodOIpFA7Vy8zLYsjHgMgPZwlJ279yT76NfXc8UVV1BYWEAsnkBRQNeS9RRdPzu2bXO0JUJ9Rxy/S2dcgQ9NVU7Ylagv1dXVPP/887S1tfU5q/F+5BcUYoZbcPsLevysJRKnJRyj6XgVSl5Or8cNhUK8+uqrzDznHC688EJqa2szc+BHjcLn9/Pcs8/i9Xo5//zz3/tZeTnhcJhwJEJ+QQHbtm0FoK29ndbWVkaPGsWql19m5MiROBw6r65ZA8DChQvJLyzm8itXEI92sOfddykpLuKcqZO59JKLCMcMGppbKSwoZMKECex5910WLVpER0eYpqZG3C4HitfHrNmzMU2To6HjlI4YgaVoTJoyDSyTxqZm4tEICy+5hPyCAgKBAJqq0tzcTPw0Fvs6GVVRMDpXzTZME4euU1paSiKRIBGPk1A1gl4HZrQd1eXr8btKURScDgd1dXW0tbezbt06/H5/j6L37mzLTKbUnSVpQeIMkdSgIUECASGybKgGApAcKOR6XTR3xNBUBad+5n+JKoqS7OygaWi40N1evIFcLNMkEYskU4lUDbVzFVdV1dBdbhKnEQzYto2RSADJvvW2/d77cTp91QEKC/IBm4svvphgMIg/JwfTMIjHomiajmGauFyuZMqVqmLbNmYijmWa6E4nqqYzplsgMm7cuM5zTKYvGaZJwjCSaVKaxq7de4g4/Dh8ORR4HZTnusG2OFZ9jOojh7EVlYbGRvyBHHJycrCx6fy/XrncHi5ZeCnhcAc5ubkoqkY8YaCpSkYActqzBqoKtk00GuWd7dsJBoOMHDmSlnCM1miCRGsDHW0tbHpzPcuWLeux72AwiN/v553t24nGYlx66aXYlsW+/fuJxWKMLC/H7/OxcOHCHueW6kJ1y0c+wgvPPw+A3+/H7XZz7PhxJk2cyIULFnQWdCssXbKE7Tt2EItGicZD2EVBFAvmnHsO+bk5HKw6imnD/v37ueCCCwgEArg83mTaUSAHVdPwej143C5QVPJy87CAkmApiqLR3tLMiy++wI033kB+QQHtzY1UVFSwa9culBEjKBsxAsuyOG/WrB7pY6ca4PXGsiwMwOlwpN/X8vJyEvE4TpcLy0h0rkYcR/Pn9ehipSgKLS0tFBcXA/Ra9N7d2ZQWlDIUZ2+FGAgSCAiRZUP9D4ymquR4XbSGY+R6XeiDvAhVMjBIDvrB1TljkCwwTkTDgJ0OClqbG9m5Zy+5ubl9rjGwa9cu6uvrGTt2LKXBILquo2oasVgch+P9DU5SNQZlZSMoKxuRflx3OFA1jXgshoKNaRo0NDYRDYcpyMvB6wvgcDszgsK+AhFVVXF2BhCWZdNYV0tRYQE1hgufFSHXSmBEk0FGPB4jHA4z/ZxzefXVV9E1naJzZwJKug1sb4FoY30da1a/kk7Juuaaa1AUMEwLK2FgYxONRDlQWcmePXvAtk9t1kBRMY0Eu/fvxuVyEY/FqG1uI26rRJpqee6Z/2PkyJFcumgRLS0tPfbbPQfe7/fT0tLCsWPHKCsr48m//pWFCxcyZ86cHoeuq6sjHo8Ti8XIzc2ltLSU4qIi8vLzAYgnEjidTt5++23mnj+HaCzG9OnT0TpnYdxOnZimgdtLm2Wxc+8BjHiMhRdfhMfrZe1rr7Fn926WLVtGPBajqbGRksJ8TBRMw8QwE3jcbjxOJwkbDh2sJB6PEw5HUXWdg4cOseXtt1mwYAFul4va2locus6oUaPS16GyspI33niDWCzGzp07M2pIUmtudF0voTeWZaWDSYeuZ3wOUv9t2zaq7sCRW4LZ3oTRXIseKETpMoi3TJOiwkLqOzt49WfWwjISODy+E24zlAzlmzVnM0VVB31WSGahepJAQAhxUg5Nxe920hKOkedzo2VxMaqMwMDZ2TrRNKgN1aCpCtMnT6I9Gqeuro7c/5+9/w6S67zuvPHPjR1nuqcn9OSAwSADBEAiBwIkmCmSkiU5abVbDuvdsl+Xw3plV/3KLnurvKVaOcl+y0G765XstfRKtERSIikSFAkxIQciDMIAM5hBT+jJnbtv/P1xuxszmIAZBAKk+1McDqb79n2ee7vv7XOec873BALFxgcCjhE4NjZGVWUl/ZEIyWSSVatWFZ2x222yNd9Kp2lZSLKCLEsMR6PoWo6B/ghv/cRJIVlM9MG2LexcGjuTxC/k0GUPkeOHuXSxk4ceeojdu3cDYCHSey1CdbgORZEJBMoXVEtxo6FdX18/7Xnbtrnc1UVscpI9u3byo9den1f950YEQUTA5r333ydUUUG4uY1VgWpqAx5G0y48Hg99fX2k02mef+EFdMMgOjQ0LfpQ+LHy9SW6prGsYykv/uv30XWdkZERli1bNmPsmpoaVFVFkiSuXr3Kzp07efe999j00EPU1NTQPzCAx+NhdV7Nx+PxYJgmvrIyMjkdTTdQJYFsTsMSJXY8vBdbEDE0jZwJhmVTHgjS2tpGJHLNUdZR3JiWjWkZpGIT2LqXkbExGlvaaO9YRiAYxO3zMTw0yLKOpfT2XaOnp4e6+noUWSGeSJJMJSkrK8flduEvK2PdAw8QqgiSTCQp8/vRcjlisRjX+voYika5cOECtm1POweFKEJrWxuhUAhVURgdHWUyFsPjdk97/8QphcSCKCKVhbCyKfTYCJI/iOTyOipOhuE4UaI4o+h9NizLBEG87f4YJUqUuDOUHIESJUosCJciYdky8XSOoM9136ySCYJAV7dT2OtyuTj90fvsevhhZEVFzPcoKEiTDg0N0T8wwJkzZ8hkMmzatAkAwzCRbjPtqVDbICozDRzTsrBMC1V10i+6e3r48MMPi8/fLJWiOIahY2WTWNkUgiSjyR6Sgp9opI+LF87h9/un9T1YsmQJ+/btI5PJsHfvI9TUVC/4eOYrNhUEgVBFBYcOHmTtqhWLz10XRSftrLycmqZWVqxdj6SlcCvlM5yQQHk5o2NjZLJZjuabdz333GeoDFU6ilGC8x7HEgkAfOUB/GXl1DQ0EctomJbtRF80DY/Hi6uyjn2f+3kyNjzy2OO8vf9NduzYQSwW48TJk2zYsIEyvx/V5cI0dBKpNBYCugXpVJLYxDj14bCjhNXYSHR4kJymEa6tR5REtu18GMEycCUGWFIugWBhpYYdZStBxKVaDF67TG11NWJyFLcnQFl5OTbw+muvsXbtGtav38i1SATTNDnf2UkikSAej2MaBhs3bmQgkeDQwYPs3rWTg4cOs2fPHqpraujt62N8YoKmpiaqqqsJBINomoYoigwODvL+++/zwPr19HR3k85fLx98+CGNDQ2cPXt2WlRHlCTMfCFx4T2XPH4EWcFIjGPrOSzZg6I6kSyv17sgZS3rE5gWVOIuIdyDGgGhVCNwIyVHoESJe8z9nho0FY+qYFo28YxGuUe9b5yBkZERGhobuXTxIv0D/fzoh6/wxOOP43a5EAwTVVUQRRGPx0NscpJMJlPUZbdtG9MycckLU0aaje7ubgRsXC439Q0N056zbRtd13Gp189XIZ1lPp33qa+3tQxWJolt5BBcXuRADVlLIJXT8aoCsiSwadMmKisrZ6REtbe3Y9s2uTvcc6GxsZGnn34ar0tdfDFxfjV46+49lFWGEbUUTfXXC8EbGhqoq2/AtGwyukk8nUXxlvHEZ17AtCGNjJXWMW1nhdm0NQg45/DhZz6X34vNeMrR87dFyZGexSlPUG0L27LwVlTzhZ/7BQRTd9SLBAFFkhBlmUgkQjAQAFHG5VIYjw4Rm5xg6bIObNOifckSdF0nm81iWRa9PVfoaF+CSxbRBJFhXQFTx63KpNNpBAEE2yZUESSr62i5HNdyMoZmELJMTMNA13VOnDgJCFy6dImHH36Y3t7e4uekpqYGuO7gYds88fjjNOTPfSAQKMqq+v1+HnnkEWryEp+GabJl61YunD/P5cuX2b59O6qqkkmnEUVxRk8HQRAcrf8bEBUXSrAGPT4GuoagVGLbC78POGlB/oV/VkqUKHFXKTkCJUrcQ4R8l9lPEj6XQjyjLUpW9G5TU1PD4UOH2L17N263m8rKSlrb2ooGUDanIYkiy5cvL/Y1qK6uZuXKlZimNUOBZzF0d3dz6NAhtm/dwo9efZVHH310uryipqPIyrT9Fwy5QjEwwMGDB6elVdimmV/9T4IgIHrKkMqrEESRnG6QyOaYHB3G8nlYuXLlnDKtUPicibfVlXc2Ghsb0TIpQtU1i3pdZ2cnVZUhXBUVDPb3UxEKEZlIY9o2pmVj3egce8rRDINMJo2Wy1IZCiFLEi5RQBIERx3pymUuXbxIY0MDyUSc1pZmmpcs4dSpUxw+fBhN07Asi61bt7J6eQcXe7qxBImGtmW4JAmfW8U0DQwLrnb3OIpUHj/x0WHSiTger5flK1Zw8uRJ3C4XA4OD9Pb28sgjj9AXGWDH5gcRsBlPZXG73PgDFQiWwfhknKwp0NXVxcDAAD/7xS/StHI9IyMjDI0nCLor8PvLiE1OAE6OfSgUKkrl+v3+WQuy29vbsUwT0zSLj3V0dDgSsjfUCEiShG1ZHD92jAceeIChoSHC4TCqqjI+NsbY2NgMh1QQBDKZDOc6O6murp42tmUDngCSmUOfHEbyVyxopdUyHWngT9o9r0SJTzMlR6BEiXvMJykiAHlZUY/KZCpHRtPxqPc+zF8wgARBoK6urmgAFQprZUlC1w2yOY2lHR2sXLmyaIwYpoEi39qt0DJNPG4Xa9esJp3JUFVZOS3NxzBMRFFEmqXAulAM3N3dzf79+693ZH7iMWoryrC1LILLg1RWiaBcT8XSDINYOsfFc2eoDgV54833eOihh1i1atW8c5Ulsej03GvGx8eRgjXouQy6aZLLZqisCIBtI2Ah4hj4iiyhKDKSKNLf309iMkpdOExj7UzZ0cpAGeMjUfp6ruD3+1m5YjmSJFFeXo6UT3Px+/20t7WQ1XQuXrxEfX09RiqGWBYkntXREpPolk24rh5JlhEtnWQ8BjgG+okTJ7jW18eOHdvp7etj2crVlNfUsypYTSpnUOUrw22lyWbS+IIBkpqFv6wMBIHlK1YQjUbJZLN4vF6am5sxyzLENBu3qqLnZLZu3UogECAYDBKNRolEIvOnaIkitj490rNs2bJZayOWLFmCbdvIsswzzz5LYz5y5fV6GRwcZP369dPGiUQiXLp4kZHRUY4cOVKM+liWhWkY+ZQgF4KsYiTGERQ3tlIxr5FvGTpiKS2oRAFBKEYHP9YxS0yj5AiUKFFi0UztMSAKAi7l3t9Kli1b5uRqz5JmI4oiLpeKZVlomk7WyKEoMl1dXQQrQoyPjc6pMnQjtm07K7GGgSAKaLrBhwcPkU6neebpp/H6HDUU07SwLKcuYD6i0SjPPvUULtFCsQ1kWUCQVaSyED1Xe4lGu4qRAsOwiKU1sukklRUB+vv7GRkZYXR09KbzFkUR3dBQ7oPbfmtrKyPJJDnDQEhP0rKkEZdooRs60eFh3G7PrEpBt9JNd+oqeV1tLRWBckZjSZ79zGd47733eOn7L7J9x04al64gYQqUeT1cudzFqhXLURWF9iVLMCyLo0eOcObMGSRZJlgVZte+p7Ask3R8knfeepNEIkEgEOBnv/hFBGxOfXQaW5Robmri6tWrdHV18fgTTyAKAiPRKBUVFWA7q+hv/eQtHli7jppwGI/Hywfvv08kcs1xDOdJu3KMbmHB3b8LaWKarhdf4/f5WLVq1YzXR6NRRkZHCVVWFmViGxoaMHS9WBcAIKpupEANZmIMIz6KXBZCmCXv27ludBS1lBZUosT9xL3/RihR4t8wn+QQuSQ6PQZi6ZwjQfgxy4rOhiAI2DgKQbMhiiJutwvDNEmn0lRWVXH0yFEikWvYts2aNWvm3LdtO7KfpmEgihKKy1mlb2lpKab5KIpCTXW1k+9tmtPqAmbdp66xqrUBt2iTs+BizyDty1aiyG7GRsc4cuQIg4ODtLe3U1ZWBi4fsiiAnuPI4cPFlI6ChvvNzk0mk6Hr0iUqKiruaIOwxdDT04MiyzRUVzBpiFTVhvD5/cVCbrfLzaVLlwEWPcebOQtVoSAmEi6Xixe/9z3i8Th+v59cNotg5AgGQ+RyWfRcjqs9PSxZ0kY8nuDDgwdJZzKsWf8gy9esRbPgzMmjrF6xnHBlBU899RTxeBxZltE0DduyOH32LKIo0rF0KWvXrWPVypWMjIxw9Px5BgYH2bx5M2KoHlQf/f0D1NbUcO7cObZs3cqS9iUIgsC1a303VWOajMWIDkfx+fwL6icgCAKSKGKaJnI+EjbbZzQcDnPx0iXK/P5i2pCu60g3SI1CXpLRV4Ggp9Eno8hllYiKa9o2tmWV0oJKTEcQ70FE4N5/T91vlByBEiXuMZ+01KCpyJJImUctKglJ9zjtRCwUOErz5yvLksSpUydZsXw59XW1XLhwnvG8DvqN2LaNaeh5BRUZ1eWeYcxM1fy3LCvfk2CmweTsz5H+tDJJbNPA6/UyEk8zmUzTumwloaoqbNtmeHiY5cuW8dCmTQwMDGDJblRRoMLvocLfzObNm6fVOtyMSCTCRx99hNfn48MPP7zj3YIXiiiK2ILABwfeYeX2vVwdHuaBQBCPx8vQ4BD9/RHWrFmL2+NFNwxkSUIQhFtuXnbp0iUOHz7M008/5XRfHhhg6dKlPPLIIwwPDxOqqsbt8yNi89HRD+lYu5721Q+gJydQVZWxiUkaWttZ0rGcdDJBLj6B7HGzYe0aqmtqOH78OCdOnHCiNm1tyKJAZGiEz77wArlcjsnJCaprwpw6eZLLly+TzWbZsmULS9ra+KhvGF+1D3/e2N65cyeBQIA333yTPXv3ksmk5y0k7+7u5lpfL16Plw8/PHjTjr4FJElC03XEWYqBCzQ2NrJ71y4UVSUUCmHoOol4nMqqqhnbRqNRpyeBIFBfXYkRH0PylCF6/MVr4JOcFlRyXkp8mik5AiVK3EMWGtK/n1FlCa9LKfYYEO/h8QgF7fMFbFtZWUkqlSIcDhMMBqfJboKzgmkYOnZe/191KQt6r0zTQpIlLNPEEsViTr5t6liZ69KfoscPqgdd06hrrKReENA0zek3IIp4vV72f/ABD+/eTduyVViWScB7vQnTzWoCbiQajdLb28umhx6coRDzcWFZFlVVVbz00ksMDQ3Rsno9leF6LNsik0kzNDRIJpPh/PlOlixpIxAoJ6dppJIp3n77bUZGRm6aLnMjIyMjKIqCR5H45+98l9Wr17B06VLa2pZQU99IOp1m/+uvURmqoKOjg6BHIZHTkP0VJDWbyoYWgrkM1QEflwb7GBsbo66ujqq8w9bY0IBlmgSDQcrL/ExMTHDo8BEMw2DXrl289957rFi5kg0bH6Sqqor6ujp6enr4p3/+Z3Z95vMYwO6HH6ZjSVtxzo8//jixWJznX/gsgfKyOc+l1+PG7/OTy2XZs3sn42NjC3IEBEFAliQmJiaITU5iWtaszccaGxuJxeN8eO4cS9vbeePNN2ec+0gkwpEjRwiHw0UJ0oa6Woz4GJaRQ/aHQBBKaUElStynlByBEiXuMZ90RwDAo8qYlsXIRIxIz5VFr9reKURBwJhnlXMqq1evZnRkhGw2y5NPPklDQwMXLlwgmUzS2tLsFJnKCqKy8HSGG+sCtFwOGRM7m5om/SkojtqSme/sCk6XYEmS0DUNZJmW5maeeOJxyvxlZCyBH33/e2zbtm3e9KX5CIfDhMM16LqxeN3/Oeju7ibg9xEbjC4oLUXTNFRVZdu2bUiyjOQtJ20JyLI8Z46/LEn0jl5l3QPrOf3RKUZGRhblxNTU1KDnsqTSWR588CHKy8vJ6QaZnCPtWRMKsm3bVoaHh6mursbv92OOjRHpv0ZrWxsVbglcXuLjY3RduUImEUcSRRobGtA0jcrKSmxgcHCQunANqUyWVatWFes6ZFkmk8mgaTlqqqv58RtvsG7dOvx+P26Xm6QNzc3N0+bspDiBrhsYhokypQbHtm0MXcO2bDTd4NiJEySTSZa2t/PInt1YppHvwj0/V65cQVFVRsfG+Oijj2Y0HyuQy+XI5gucfT7fjHMfjUbp6emhtbWVLZs3Mz4+TmNjI3LQ6UasT0aRfMEZaUG3GuEp8enBFkTsjzlV5+Me75NAyREoUeIe80lODZrK5OgwIxNxxmJxjh07dk9STxbrVFmWhWEYlJeXc+nSJWzbRhIFfvL226xb9wArV650dPwL75FtY0/9jZ3/zwbbdhqTSSJGLgNaBkHLYAJZS8SWfXgUD5Zpgpkpji+IIrqmISCAAKIA6XSKxMQYdT4V08pw/MQ54vH4nOlLC6GxsRGXupt4PE5zS8ttvzcFtaN9j+zlp++9j23bc65GX7p0CYDaujq8skx9fQOyImNacHUiRUYz8bnkWXP8BUHA5/Nx7NhxNm3ezLs//eminJilS9uprarg3MXLrFm9BluSyekGZd7rqWyF1C7DMLCBiYkJyn1uDn/wLhndZOPW7RiCyrYNa6lID3Kkb5J0Ok0gGESWZWpra6msCDIyOlo0bguO0bJlyzh06BBut5tjR4+wfetWJmMxnnnmGXIeH8lEjrnuALIskdN0RoeGGOzvp7m5mbIyP7KiICoSzc3N02Ro/eVB9FwWUTKRlPnrU0ZGRhgcHGT1mjXs3bsXWZZnlZdVVZVUKsUbb7zBrl27aG5qmhbJLPTEeOedd2hqbOSJJ55A1zT6BwYYHBykrbGOkDWO4Ckrvi4SifDqq69eV8q6R2lqi+HTcp8uUeJGSo5AiRIl7gjRaJSr1yK0tLVz5uSJe5J6Ak6h8HwpV+fOnWNsbIyqqioEAXxeL4lEnLraOizbYmQ4yoMbN1JeXo6WzVzfq+D8Fm74PTg0SDwWp76+Hr9bRcgkHelP1c1I2uDs+Yu0LVnCtWsXaG1tvd4nwLbRcllcbs+0+UUiEWQjQ6XPzVg8yeVIlPVrVhDp75+RvrRYCilQ4k1qKBZCNBolmUySSKV44oknGBoamnW7S5cuceLECR57/HFikzFSyRS1teF8egqokkhS0/G55v46amxs5OGHdyOIIs8//7zT/GuBGLkcHl8ZGx58iHROQ7ZtfG511noWSZLQcjlaliylp3+I9o3bQJSwRQEjMclHZ06yoy3E1qYyMtkJTN3HxYsXyWYytLU20z8wyJGjR3G7XNPy9VetXs2xY8f46KPTDAwM8vRTTxIIBLgwOAnIDA0O0drUMGM+giAwNjqCaVlUVAQ5e/YsSzs6ZvQTmOqAKW4Ppq5h5DL0D0YZzPcMuDFiU1NTQ2dnJ6Io8pOf/IQnn3yy6AhJkoSU762haRoPPfQQmqYRCoUoLy9H1zRESUKSpGIkZ3h4mLraWvxlZYyPjeHzepmYmOD06dN86YufQ8mlMC0DyR9kbGyMrdu2IQD79++/Z/eKEveYUrHwfUHpjJQoUeKOEA6HaWtfSl9P9x1LPbkVCnUCs3Hu3DlOnDhBTXUVwfIyPG4PP37jTQ4dPgKCwMjICD/80av85O13GJ+YRHV78j9uVJcb1eVCUV0oqoqsqFzq6uKt/fuRTA0xPYEeH0WQVfqTOkc7L2Mg0tDUxIEDB0glk/i8XqcOwDQZHBigv7+f7u7u4vwsy6JcNAh6Xbx3/AzffulVJFkmkcrw1OP7FixxOhe27UQg7gSFleB3330PLIv29qWY5szzPjY2xsN79pBOZ3jttVfp7r4yzUnzuWSSOeOmK66NjY3U1dYRrAgtaHX23LlzHDt6lEQiQcawyekG5V43qiQwNjrKBx98QFdXV3H7nGEylsrRn9Tpm0zjKgtQ4fPQGHBT71cIumV8lWGu6D5ytoQ3OQSjPYyNjdHS1IisuGhqbGTH9u0kk0mGh4cB0HUdVVWpDYfZtGkTmzZtoqq6homJSWzbOV/vvPMOkUhk1uMYGhri5Zde4tVXX+P4CcfBng9BEJBVF8OjY7gUiav5yM2VK1embdfR0cHDDz9Mmd/Pvn37aGlpQVVVVEWBvMTo8PAwvVevcuHiRS5cuFB0FIS86lAumyWXy+H3+airq0NRFEeqdXSUDz/8kFAohM/rIZ7K0D+ZYWxslMzoIG2tzVw4fx6Xqt7Te0WJEiVKEYESJUrcIRoaGlD9QTA0Nj+08Z6t8ImCMKuhWIgSPPzww4iSzA9/9EP8Ph8PPfQQzc3NJBNxqquq2L59O5IkoSjzK5zYukZAhZ9/5lEsUeZcVw8Zw6ax0eLQoUM89NBDXL7syGDG43EsyyKVTlNTU8PI6Cgej5v+/n4udXVh2zZtjfUYiTEURebF139CdGQUv99PS0sLDQ0NaMmYI8F4G4b8nSxOn9odWZIlfF6PYyjaYlGW0rZtli9fjiCKvPLyy4CzEj0VvyozkdbIGRZuZf5IhSgKiILgFITPE9U4d+4c77//Pk899SQ5ZHKJOBXBALquO+o2ksShQ4eoqgljqV5cZQFyhoUkCPhdMqKepetCJ1ZNDTUdHfT395NOpRgZHubs8DChp5/ClxqiPDXGhioJ3bb4p3/6J9auW+d0IF6+nHA4XOxs7VLVGcXd1yIRKK8GRSWdycy5Kl7oAFxIo1mI0WwaBl6PByFfdD4wNDSt0V2BZcuWYRjGtCZLguDUbEi2TX9/P+Xl5WzbsoWx8XEs08S27XyTPOf8T05O0t3dzbvvvovP52Pfvn243W5sIJvJsGrFcjTDZGBwkOqaGkYjgyxpCPPIrh1Yosyzzz5LQ8PMaEiJfwMIwsff4OtTUJN3pyk5AiVKlLgjaIaFS5XZuGHDPZ2HKIrouj7tMdu20XWdYDDIsWPHiMXibH7oIfxlZYiSSDw2SV/fNVavXk24to533v4JK1asmGE42bbFYG83HtHG63YRDIY4ePocV3v7eP6557Bsm57ubnbs2MHp06e5dOkSW7duZfv27dPSM65cuUJ9QyN1dXWEQiGqy9zo8VHSukWgtok9jzw6s2jW5cHIpVE8t6a8Ytv2nP0VbpVCWkohzUlRXRiGiabrKLKMYZq4PV4y6TRLly6lpqZmhjqNR5EQBYGkZtzUEQBQFJl4IsHlrq45C03HxsZYurQDf3kF2UwaAbuY6nLqo9MMjI6z46nnqaiqwTJN3LJEtd+NV5Ho6uoim82SyWR4++23sW2bRCLBgQMHeO6557jyyitEh0cQRZll1UE8ySju2FUaKsuprKwkmUyya9cuRkZGiCcSpJLJoqHb3d1dfF/bWls4FxlFCvjw+XxzGvhzFVFP5cKFC4yMjNCxdCnBQDkIAllN45VXfnhTB0KSJOd6ucGxEgQBv9/PhfPn8Xi9XLlyhUceeaTo5BW4ePEizc3NrFm9mjNnzzI8PMy2bdsQBIFcNktjXRhLkjEsm9dfe41cLsdjj+xhRUs9OdOiOzpKLpdbULH5vaRUI1Di00rJEShR4hPI/ai4kTMMVPne31IKTcUKmKaJYRgoikJ9fT1Llizhww8/5O0DB+jo6KCnp4edu3bj9fvp7u5GVVUe3rMXl6oW91GQ/tRTcTwS2KqPM5FBAmXlhGvrkGSF8YkJGhsbWblyJRcvXWLlypWMjo5SV1c3w8gJh2sZHo5y9MghfvGFZ3AJNleHxpA9jmJNfV0dDQ0N9Pf3c/z4ccLhMA0NDZhadsGqMDfS19eHlO+EfKeNLkEQkBUV09BRVRe6YZDLaZimQTyeIJvNsmPHjjlf63fJpHI6VT7XrNtMpb+/n8GhIXq6e+YsSq+srKS+oZFXXnmJbCbDzl278QQriWc1KlqWUd5oMHStl0jXedatWkFtneOcWJZFRchJPdI1jW3btjExMUFDQwN+v5+xsTEaGxsJh8N4PW5e+vEbfO7xPSjjvTy7vg2xNoRYsZqrV6/iLytjYnycN998s1iMe/78eZa0t3O1p4cHHlhHMBgkYcPDDz9MY+Pcq+LzNUq7cOECpqHzwNo1jI6NOQpCHR3UebzTConnes8L18ts0aKOjg4UWca2bVpaWmaVGG1ra6Ozs5P29nZ6+/oIh8OOYzI8zJo1q7Fsm+hQlLfffttJI/L78QcqGIhlcNsaDUEvP/7pe/MWm99rPg3KbiVKzMW9/9YuUaLEoigobuSyWVxu911X3FiI02HbNpph4nepsz7/cZPNZOg8d47Wlhb8fj/qlA6/a9asIRgMEo1GKS8vZ3BwkAPvvM2aNWvZtHkzkfEkk/FxqgNljET6qPC7sY0c8azOaCxBdX0Tk+MTVIcqGYpG2bJlS3HcK1euUBMO09TYiGlZPPvMM1y4eJFMJkM8Hi+meYyMjFAdCvBLX3geBIGro3Hc5SFisUmnSDlfR5BIJDh69CiCIPDMM89QXxvGyKZRvGULNk5s26avr5fhoSGy2SydFy4uuPHUYpAkCdPQnbQdUSRn5kgmU4yNj/HB+++zd+/eWeUpwUkPGsjqGKaFfJMO1dFolLNnzrJq9apZO++eOdfJ0Hic6npY+cBGykLViC4Pw4ksPpdMXcDLYF8PLiPDA6tWFI1b3TAwDAPLsnjpBz8gmUzS1trKI48+SllZGc888wypVIqlS5cSqqjANAw2btxITIfy8HKMSCe+6GWsbJKB/iiirDIyPEwymWRkZARRFFm1Zg2JeILNW7eRTqedlXhZIZFI3tI5N02TUGUVpmUxNhHj9NlzVIZCLM0f042FxHMhFvpvzJJu1dzSgmkYKOrMa9u2bSpCIVpaWrBMk6eefJLo8DDpdJqcpmGZBm//9F1qwrUznJKzZ89iuFwohs7PPPkIExljVtWiEp9iRNH5+bjHLDGNkiNQosQnjGg0imWZfPa5Z0ilM4znVynvBtciETq7evCVlfPBoSNs3wpNs4ylmxayKCKK937lLBKJEB0epioU4tChQ6xdt27G+Zm6wqqJKh/0jHNYU3n9wDUMy2azMMjzsReRXC5yLheCJOEBmgC6oKBZUw1kXjpYjEDUAfYZ8BeMdEFgg23DmFNgKYw6ObEhQBgBw7axEajUNFwuN55sDtc1Nygqhq4Ttiyeq8xhWhbej15Du+zHtixMSUIQnY67ReWN4r+dMZw5CdiCQEDTsSdjBIJB/AET6cox9NwQiJLzxSiIzr8FAUQRQcg/XnxMzj/ufHEL+b8RRJDk4utFID4+ii1IpDIZXnnlh+i6hmEYjIyMzOkIeFVn1fnk2fO4JehYsQLdtDFMC92y0U0L3bTRLYuMt5KUp5JRsRyxcSVDUoi3L4+gmzap+CQVgRBSbRU9cRNvdQN6NkVLVQV+l4KU/3yWL1vG8vxcLMtCy6eSuVSVcE0Ne/fuZWRkhJqaGgKBAIZhUFNTgyzLxGIxhqNRcrrOypUrudzVRSAQ4J8OnOKxdW20Aw9UKrx89Dxbd+1heDhKTU0NHo+XkdFRAmU+vv+vL7Jv3z7K/T60lMaFixcRLX3BPSIsy0LXDQRBQNd1zp09y/nznWzfsYO2tiVYls35852MjY1RWVl50yJzSRQxTHNWR+DGCNtUjHzn5/b2diKRCIauc/jwYXbt3k0qmURVZBobm6gJh2lpacE0TccBLyujNhzmpZdfJhaLsWxJK4/t3IKRnATVW1QkulOF7bdLKSJQ4tNMyREoUeITRjgcZt2a1Zw7f4GcpvPonocxtNxNdcNvhVgqw5IVqxgZHGDzw4+iGTqJrCP1OLWDcE43cS0gv3supkp6LrZj7o1Eo1F++tOf4nK5yGaz1NwQychoBh9eneCjgRj9k1lypgVIgFnc5opZDpaFmclAJoMgy4huN6I62zmennsvABT7DnC9y/EsSkaF52QJMLKUyYCewdYzFNZfPUp+r3oKezI1ZVTmNNBuxAWEAUbGWOEG0gMYlwYW+OrFUUjucdnwH+rJnwsRRo6QeenI9Q2L59Ep7m4C/k/5o0zaLohOV7iZQfVyTsWAqqWcGtNhbAKAcskkWCEhmzkwBXKCjM/SOHvi6Iz6hEuXLqGoKjU1NaiKMq04fNmyZdOcFkVRsPIRmmw2y/DwMIcOH2bfvn0MDg0RCAZRXW5+ePQiLzy8mVa/zs9sWkp/OsYzzz5LbThMJpvD7/PS29vLzp07uXz5Mp7qBixPkI6Vqwn4XTddEbfzvSpMy0JVZARBoCJUQXNzEx6PmzK/n1BFkInJSUZHRzl+/Dg+nw/btud1MoQ5CuynDDzjoYGBAWRZRtM0Ghsbi52rd+3eTXRoiNbWFjLpDD6fj0wmw+jICKIg0NLczODQED6fjx07djA6Okp1dTWuUC1GYhxyCfAG8oXn9nWn4B4b46UagTtPqaHY/UHJEShR4h6z2C+4hoYGgn4vXT1Xqa6uwReowNRy6JkUsstzRzTiAUzLpqwyTOep43R+dILKqioeeeJpYmmNiXQOv0uhzK1w6cJ5KmobiI9EWbFi+Yz92LbTbMu2LbCsGb8TiTgeyaLSp9LXfRmwWbXq1mUyw+EwPp+vWCRZWV3N4d5xjl+b5Op4hrRuzvt6VbQJChq2vwIh6RiYtmFgJpNogOYNIlbVE6xrQrBtotEhDEOnKhTkancPAA0N9UgCCNjo2RyGaeBWZBTBMd8tREcByGl6gGUaZDMZREFAUeSihKOh65imgVRQabFtTMPAtk0EnM9O4bdjrF1vfJb/x5SHrj//cZhU1+38OUabMkchPyfJNrjuSiwcUQDBtvApIj0H32TLhgeYmEjjrltKxlVBZY2Ny60STyRQFCWfUlNJPB7nu//f/8eOHTvmjFYUx5Akzp8/jyxLnDl9pigR2rFsGWfPOg3f/H4/ur8asSmM3H+BFuIYYgVXe3spLw+QSaV4YP16wEmlGp5Mggd6+iL4WuvQDRPbNlBkCVEU6e/vL6bl1dXVoRsGsiTjUhUEQXBW8UWJFStWsGLFiuJcz509g6Ko7Nq1i3ffffemjegEQSCRSHCut5dgMDijnsC2bUzLyl/HNrF8c7vjx4+TzWZ55plnCIfDHDt2jJ6eHsrKyli6pI1EMlWsP+i6fBld15mcmCCdTrNjxw5cqoqmafT19REMBqmpqcFKx9Anh7kaHacsGHKOW9fhBqfg466TKjkCJT6tlByBEiXuMYv9grEtE5fbzYYNG4uPyS43lmViZDPOl6Xqvu0VtFhGQ5Fl1qzooKai3PnCra3Gtm3Smkkiq9E/oWGqPnLpDKODEYZ8LqpCIcfIty3svPGAIDhhfkGc9luQZK5GBhkdHWFJSxNLWxppqA6gJ8YQFTei6kYQF+fY1NfXs3LHYxy5FqdHl/ja0Ulgcs7tJVEg7HexutbPdtcolS44nwhxNraV5jIVZbAL4dpFPIKJBHjSk9A3SW5iCKVjA1LbA/hDNXzvpZfYseNxvF4vlttNQtNJxGKMRIdY2dGIy+sia9h4KmudSEC+OLPr8mWOHT3K1q2PoJsW8ViMbdu2zTnfgwcPcuTIET7/2ef56bvv09bePu/2s2GZhlNr4PHPSL+wLMdBwzKv/9gWmIbz27KwLWOaM4dlgG0zPDjIuXNn0HM5PG4XK5cvpzJUUXxdcV+WjY0FhoGlZbANDd2ysXqv4FX9tLW20FRfhyIJKKKInP+tSAKKJKKIAqZp4HOrqJKEJAqcO3eOMq+b7x0a4oMPkuzcuZPYaB9WZROTeLhw4hjNTY2sX7+egwcPcujQoeIxz5e2NJWamhr2799fdDJbW9sIVYSorQ2zefNmqquriwa52Loeq78TeewqNe4KuvvjfPDBh+zatQvDMGhpbSOeTKMDTUvaWbbUMWZt20Y3DJKpNOfPn89HEHYRi8WpqAhOu651w8A1i8xtZWUlAwMDjnKS3z9vIzqnhqSP0dFRXG43uVyOiclJvF4vkG/Ql/9cFJzOwYEBDhw4QC6XAyga5Fu3biWTyVBWVkY2neJi12WGhkfYsWMHVVVVKIrC8ePH8fv9JJJJ3nzzTSorK6moqCCXzWIaBmlTJJnK0VIdJJ7VSMbjeH0+bJyaCNMw0HSdixcvcurUqY+lM/FNIyYlSnyCKTkCJUp8wjB1DUmZWbgnihKKx4dlaOiZJJLqRpLn18KfC80wSWR1wuUe3MHGaXUBgiDgc8n4XDJHjh0nXN+IXzQoX7YUzTAQZAVRkor55E4X3rmdEpfXR3fvCdral3Lw6EnWr19PwO+lvqYSPRNHEGXHIVDcCJI86776JtJ80DPOxeEkY2ktv9gsMlvyjCBApVdlRY2f7W0hmiscg8eeGMAezyJULyMWOUd90MtYIsXbZwfZueNJyjPjVKeHUYavgmViJcbJnfgJHsCuauK5DasRgwECVdWIosjEhU7qvBKtHU3Iqsp4xkRyefCLYv78OMfhdrvJ5NNN2pa043G7531vwuEwbrebH732Y559+imMWzBQRElGdnnQM8kZzoBYLOBb/NdDfcMyMhWNxaLQ2jmUamzbxs4mMRPjyIqLnFrGQCTCGjuaz2lfedOxNE1Alpy6lO7ubt5//31+9mc+x6ZNm4p58V1dXZw6e4zWdZsJtK7E73WOr6amBr/fXzTob+xtMBdTeyc0NTURCoVQFJmVK2fOV1A9iC3rGT7zIVVMEIgnsPQco6Oj1NbV8/prr7Jjx04ytoDqvS4JKwgCqqJw9sxZbGDN2rUcPPgh69atIxR6sLidZTnRntlSiVavXk2gvBxFdbFz585pNQJ2flXfsizH6bMdadX+/n6Gh4dJpdNs3rRpmnOp5XIoUxTBgsEgLpcLr9dLOBymvr6e6PAwDQ0NTg8CUSSdSbOrsZmRaJRAIFDsN7B06VI6OjooLy/H5/MxOjpKNptl48aNKKrK5TNnOHDgAIEyP0/v2YGWsCgrL78eWbJtevv6GBsbAyCZTH4snYnvdWrSp5JSZ+H7gpIjUKLEJwjbtrEtc85VckEQkBQXoqRgaFksQ0dW3YsqurNtm/FUDq8qz6vrblsWK9qaOHjkGGc7z1MbDrP34d2Yhg6miaQoiHnt9vlYtWoVlmWRzWb5zLPP8K1//r9s2LCB5iVLneM1NCwti5l00htExcWEIfJBX5LOoSTRZA7Tmt8YDrhlllb52NISYkWNb4bxZOs57IkB8FWAu4y1S5u52hfhnQ+P4Pf7CQQrWLHVMYysXBr9yhnipz9ATY07q6Sj1xBHr8Hpd8g2tKOEG2hzuxEMgd7hNB9evMZQdJhNmzaxe/fuaWMXjMvR0REC5WW4vbXMx1Rj1ATqaqpvqVGYKCtIgJ5JoXh9juN2B7iZUo1t6JiJUWxdQywLoQkqqiyxYvlyViyfmVo2F1NXaaPRKJIkkchkOXbsWNGI7ejowLZtxmLD+CtqEDxO59vC44WC4NlkMefC5XLh9/spKw+g5lN05qLnai9DKRHJ66euwuYXd63hmuFC1/W84R3FU7+UlGbMeA9raqo5evTIrH0AIpEIhmnicXvwuGd3YlRVxcJ2fueN/oLhLwgCoiiiKM78NV1ncHBwxlgFpyGTzdLb10ewooLy8nKqa2r44he/SCKZxOVyMTY6yunTpykvK+Oll17i8ccf54MPPmDLtu00NDYyMjTIG2+8Uez43djYyKpVq2btj1DoWB1LJHnt3YN84dmnMGIjyOUhRNlZAPF6vUxMOGl7pc7EJUrcHiVHoESJTxCWoSPK8xsf4CjUKG4vpqGjZ1OOc7CA1wGkNAPNsKivmHtl2rYs9EwKX3mQxuYWPD4/VVVV1Dc1O/M0TScykU4iiBKirMw7vizLmIaBZej8/C/8IuNjo85xCAKC4iJrS3wQyfFRf4yBeBbNnN/w9yoSrSEPDzUF2dgURL5JAaY92uv8UVGPHh/FWx5E9ifZtGnTtHQPANHlxbVqC+dHc/R3fsTupgCuaDeKbYCeQ7/aiX61E9EfJB5q5r3uEUaS2XlTNArGs65pmLqOfJM6j6nGtmUa6NkMituzaGdAkp1aBD2dQvH67+qqp23bWOkYVnISwe1DrqrBsGwwrZse72xMdQTC4TCqy8Xg4BCrV6+ZZhguW7YM27bpnUgzktTom8jQXOGZURC8ECKRCG+88Qb7HnucN378Otu3b5+2Ej2tYVhbG7phEAgEyXorONs7waoKhQ4ly6joIlRZSTgcJqdIJHLGjM7KczUSi0QivPbaa+x7/AleeeVlnnrqqRmr4ZcuXQLbpiJUiSSKjI2NEaqoKBr+U7Ftm9bWVp599lky2SwVwSD+sjJymgZAbHISXdM4ffo0mUyGzZs3s2zZMlyqSiAQACCXzZJJp7lw4QIPbdpEMBhkx44djI+PU1VVSWNzC/UNDUSuXZtmuM/WH+HG4w7UNmJmUxixESRfEMntW1CTtRKfAEoRgfuCkiNQosQnCFPXUNzeBW8vyQqiJGNqWfSs5hQTz5Nzb1k2kymNgFed03guOAGS6kJS1FmlCUVJQpQ82Kob2zKxdA09l0WQJERFRbwhxceyLDo7OwlXbufS5W6WdCzjYM8YxyMx+iYWUOArQYNf4YH6Mra3VeH1zJ9eM430pPMTrMdIJ5A8ZUhu36zpHsVzoOdYFg6wzL+GmoAPe9kyMmOjCBPDGENXwbKwkpP4k5M8Jwsk6kPo9U20LZ/f8JRkGS2d5tLp01SEQgsycERJRpJtjFwW2bX42hAnzcxGz6QYHp+8K8aVrecw4qNgW0jBMKLLg5mX7fS6XbfkgAiC4BSw4jS1qojF6Lp0iS1btxAoL5+xbUuFl3gyzXASMqkEK5qmryJPNeLnar4VjUaZnJxkcGCAVavX4HJ7yOY0BEFgYmKcrq4uysrLEQSB8YkJysvKePPNN9mxcxdHz3UReuRhasxxwlaC57etJW3bePLGf0Y3Z0TgZjOUo9EoHo+Hvt5e4vH4rGkxIyMjrFi+HFGSSWcyRIeHaW1tJZFIEKqspLy8fFrOuygIhMNhx/EWxWJRsGlZWLaNrCisWrWKo0ePzlpPMdUwX9rRQSqZLHYLbqyvJ6frPPXMs/Rf66PM77/pZ+vG45bcPgRZwYiPY+s5JH/FvE3WSpQosXBKjkCJEp8QLMu8/kW9CARBQHZ5sMxCMbGMpM5ufMUyGoII5e7ZawscJyBffzBLncJsYwuSjCg5OvG2aWDqOmbWkeSUZJXunh6Cfi91qx/iexeTXBpR0Qf7mU/bRhYFwmUu1tSWs2NJiAqPjK3nsLQsVnYSXRMRCsXG0tyRCNsysUd6QXFjCBKyL4iozu5E2HoWkhPYqXHIpaiRIVNWxpjlIiu5adq6FQArm0a/8hFa10mssQEEbMrTY3D5Q+J9J1CXrENZthGpqmHGvAYGBhz9dVXh1VdfXXARpKQo2LaFqeWQXYtwgoqvdzExMUlsbIQDBw7csQJM27awkhNY6QSitxzRH0QQRGzbJqtpuF23LnnrCCU5xqxpmpSVlbF582Y0XWd4eJhIJFJ0aGzbZnBwkMELnZS1LCfh8dM9OEpzTQUCznk/cuQIw8PDuFyuORuuFdJWPvjg/eI5qqoMYVkWpm7Q2NDIiZMnOHTwINu2bWPbtm3s3LkTQRR46qmnaWxsoP9aH9q1TppDkB08T8ZaBXhI6yYVCzjucDhMPJ4gHo/NmRYTDAbZ/9ZbPPX0M07evqKQzKfxdF+5QmNTE9lMZlr0wrIsTMvCNh1FKlEUkUQRVZY58NOfMjw8zPbt26lvaJhV5rRgmA8ODhKLx2d8jkRBoLG5BZdya2aHKKsowRqM5ATG5DByeQhBurUaqBIlSlyn5AiUKPEJwdI1xAUY33MhSk4xsak7xcSO1KhzC+ju7mZsYpLqlg7C5bOnmCzWCbgRQRCcQmLZydPuGYlz4FKEy+NZ4nqaouEvzlIIXSjwDfvZ2VZJQ9Azc/+qB1H15OsKdCw96zQosi1E1Y2ouBEUdVouvD3ej21qmL4wclnljPPrGP/j2Mlx0NLOgy4fQmUT+EL4FBcey1EyKc7V7cW1ehuu1dswx4fQLp1Av/IRdjYFWhbtwhG0C0cQgzWoHRtQlq5H9JYBha65Z3jqqSeprq5eVBGkpKgYWg5D15Bv4f3pvRbB71apDFUwNj5x2wWYVi6NmRgDQUQO1SEojixod3c3oizjUlV8tfPXQ8yHkxp0XdpSzavnjIyMkMvm6O7uQdN1/GXluN2u/PtuMXT+JHWrHmLMdhPM6JS5ZEzLYtPmzUiSzPf/9UWGh4dndQRmS0mxbRvTNJEVmfc/eH9Gnn17ezuWZWEYTlRraHiEAwfP8ciGZaytD5LO9BN1L6XnWj+TkdxNm381Njbi8foYHOhn44YNs75HY2NjRKNRDMPg//zj/2bTpk0cPXoUl8tFS0sLjU1NyIpSrB8YHx8nEAgg54vYC9e/oeuUBwKsWbOGkZERPB4PoYoKdMNpZqbIM4v3Jycni2pCUwt5nW1FMrkclg1udfFGvCCKyGUhrGwSfXIE2R9EdC08Qno7lIqF7wKl1KD7gnvuCDz++OMMDQ0hiiJlZWV8/etfZ+XKlfzcz/0cnZ2deDweampq+Nu//VuWLl16r6dbosQ9wc5rzStzrFYvFEEQkFUXtqxg5DKYgkZkMMo7733Amo2biPZfw4y5ZhhB150AD9IscoULYTSZ472ecTqH4gwnNMxpajc3fMnaNn5VYFm4nIfqy3GlRxgdHaXGL83qBNx4jIKiOka9txzbNJxi42wSO6kjKC5E1UVvTzctcgZT9aKE6ouri7aWgdTEDca/v2j8Fwza6+OJWJY1a8GuFKrFs/Vp3Jsex4h0oV06gXHtItgW1uQw2aNvkD22H7mxA7VjA+HqKo7lcnx48BCPPrKXi5e66O7unjNV5cbjllVX/n0VFq0YFQ6HuXS+kyWtLeQ0/ZYLMG3LxEyMY2dTiP4KRG958bx0d3fz3vvv88QTjzMUiSBYFjXhGsdIF+ZXl7oRZ1tH/Uac8tqhwUH6+weoqqqit7cXt8vFhg0bME2Dqz09JJNJYok46x5+mp6JDCtq/Pi8Xq729JBIpVi1atW8xz41JcW2LHRdR5JlwuFwsYg7HA6jqirHjx8nHA7T0NBAJpvlzJnTlJeX4/f7efvkJYZjDexZ2YRtGhiWzfsH379p869IJILqdhMMBud01CorKwkGg5imSbCigsrKSvx+P6IkUZOfW1dXF12XLhGLxdi+ffsMCVrTNLFtG1mWZ9RTuFS1mNoliiKyJNHf308sFqO+vp7vf//7wMxCXlkS8bldpLI5bMvC4158zwhBEJA8ZQiyipEYR9Q1JF/grhvqJfnQEp9W7rkj8N3vfpdgMAjAD37wA/7Df/gPHD58mP/4H/8jTz31FIIg8Dd/8zf8yq/8CgcOHLincy1R4l5hmcaMvPrbQRBFZLeXeDrLhOCjedsTmGgMXjyNVVUxzREoOgEuz6KMy6RmcLBnfGEFvraNZBs0lKl0lMP2JTWE86vFfX3X0GSFM2dOF9NKFlPkKUgykseP5PFjWxamlmF4LIa3PISWHuDld0+wcYNFR12lk/ajZZwXuv0Ilc3gr0CQ5zZYCgos8yn3CJKM0rISpWUlViaJfuU0WtcJrPEhsC2Maxcxrl2k3OXhc0vaGXL56e3tI5lIcPLkyTlTVWabi+zyoGfTjIyM0j8wsOB8/8bGRgRBwKtKLOlYvuhogCMJmsJMjCEoKnJlA8INn5doNMr42BhaJsPZzk48Xi9VVZXYlu70JEBAEAUEQUQQJafXxE0cBMMwUNXrEZBCY6uuLmdlvrq6unh8U1fzK6rLuTCc4NJIiuVVAUKVldhAx4aNVAQD8x5rJBIhEY/T0NjoGNj5NJlCEXckEuHw4cNUVlWRTKZAEMhkMpzr7CSTTrN3714SiQThcJifXosyqGRYEXDzM08/RiydxbLMWWt5IpEIb7/zDps2b+bdAwfmTN9avXp1sfHWw7t309rWRmNTE6lUClEQiMdiXDh/flZFInBqdkzDQJm1k7aDJIqIioJpWSSSSa729hIOh3nppZfYtWtX8fhunJ8oOs5AOqeRymTxuNR5uynPhai4nFShxDhGbITuwVGiI6NF6dgS9z+2INyDzsKlyM6N3HNHoOAEAMRiMQRBwO128/TTTxcf37p1K1/72tfuwewWhmEYjIyMTFsxKMiuTdVsLlBYPZxtm8JPYV83yi8WvhRv/Jn63Fzb3vjYjdvN9ZrC4zce240UDKKPm4UYx4tZzZn6Xs02zp1YGSrsI5PJ3HTb7u5ufG6VnG7S3NJy22MDXLzSw0BGwHT5AAHJNvAoIms378CIj/Lee+9RWVmJrmssbWnC7S+/qROgGRZH+yY40T9J30SGjD77eSzgkkUaA24aVI1qc4LG2pqirOPkxARHjhyhoqKC4eFhenp6eGLfo0zG4iQScTo7OxkdHaW6unreot6p2LZNxrAYy0BO9qNkJjhzpZ9HVjdR5c5iT/SDuwyhqtlZ+ZcXnl4jSpLjrM2S1jRjW48f15rtqKu3YY0NonWddFKHcmnsXAa17yzNwLgpUb1sI+dT8TlTVWZDEARGxyexTYNTJ09imOaC8/0bGhrQ0gmClb4FjVXANnXM+JhTyFkWQnDPrkAUDofxer1c7e2lqqoaxeVGVq87WcX7oWU6Reamjm05HZGFQhM6USz+O5VKkcvlSCWTRQnQ+RRlCqv53d3dnD11nMYlyxjI2FwZz7CytY329nY0Tce0LKRZ7mW2bTMUjRLp78fn9fLiiy/y+OOPz1rQ275kCdciEXRdp7qmmv5IhJHhYQASiQQPPvgghmVzIGpg2iIfXe5DDtqs6mjDiI2ApCK6PEiKCyHvaBqmybbt2/ngvffm1c+3bZv2pUvRdAO/3we2TXlZ2bQi6qnRi6kRJzvf0Xo+J6CAIAjIkkRXVxfD0ShnTp8mnU4Xj28uRFHE61LJ5DTSOQ3vLToDgighl1cx1HuF+oCH1984gcfjuWlUZdHjlBqKlfgUc88dAYAvf/nLvPPOOwC89tprM57/q7/6K55//vl595HL5Yp5iQDxePzOTnIOent7efLJJ7lw4cLHMl6JTx8u19yrzd3d3Rw9coQdWzfTdaUHQRRpbGiYlkYRiUQWpfTS3d1Nz4VzyB1b0FJx6v0KfkknnUjiLfOQKa9Cj/Rx8dwZHtq4gQPvfcADGzbO2LdlWZwdSnC4d4LusTSJnDHHiA6yKFBb5mJNXTk72kJUeGc3mru6ujh16hRLly7l7bffZufOnaRSKb7/8g9pX9LGwzu3oaVTTAykOH2yD9u2WbVq1bxjZ3ST8WQWI5emwkzgzk0i2waN7XUMTiYZ0lXqlq5alPE/FVGU0HUdFpGNIwgCUlU9nqp63JufwLh20UkdinSBbRGSTLhylF8ICBjDZ9CvBpCbliFIN79tDw4N8dFHp9j00Eb2/+SdReX7i7KCZehI6s3TNhxJ0DhWagLB5UWuapy3E3ShB8L4+Djr1q0jWBGa9nxxAeLGPg9OMQB2vlu1aeqkkkm0XI7xyTgnjh+bFimaT1Gmu7ubQ4cOsXnTJo68f4DlDzxECj9doymW1/iRZYmJyUkuXbx4vZA2Xwdg2zamYXDl8mWGhoYAZj234XCYgf5+4rEYyVSKtWvX0t3dDUxPl+mMJtBsEQGbdj+4yytwV9Zj6TmsXAorNYklStiSiiXK+LxefvCDH5BIJGZdyS84C4XFDCkvLiDLMz8zs/V7sG0bXdeRZ8n9n49wTQ3Hjh4lnU4vWNdfFEV8HjfpbI5UNofP7bq1hSTbwuPxIqkqkiiSTCYZHx9f/H7mQRAE3nnnHb761a/yla985Y7u+980pRqB+4L7whH41re+BcA3v/lNvvKVr0xzBv70T/+Uy5cv85Of/GTeffz3//7f+eM//uO7Os/Z+O53v1t0Al599dViekDhJipOCW1PXXUXbwh5i6JY/Jm6/dToATDt940/Uyl8Ecy2zVz/LrxutshGgbmiBPF4HJ9vcauIs7HYlZf5tr3xvbjZuHP9fWPKx9T93nhuFjL3qfuSZZk9e/bMuW18cpLd27dw5MSporFpGEZxnGw2y8T4OKdOncIwjAWt/EajUTyCyVr3JO8cO0SmrYP1+fzgDz74gKalK9iwtJGyZbWASd3GDiw7jjF4iasJm4NRk66YyUTOnqVv73VEAaq8CiuqvexoraA+6F1Qp+GRkRFCoRA2UFVVRSqV4qnHHkEwNCrL/WBkmUwkWN7ewqbVHaRzOmZyAtHjn6EiktMNYvE4UnqCSj2OauvYgOAuYzCepW8sQXlFLatX3F4qgSAIIAjYtsWtNOYSJBmldTVK62qsdAL9ykckzx5CTk8iYqOO9pH+yb8guL0o7etROzYgVdbNub9wOIyuGxiGwdL29kXl+4uyQio2waUzZ+d1Lm09hxkfxbZMpEDNgos2CwaolsvOqj4zG4XzKyCCBBJw7thxDh8+zJL2dnbtfhhg3v0Voq4+r5ft27Zz/sJ5uru7qa2tpXnVegZiWbpHUwiJYUzDZHRsDJ/PRywWw+fzFQtpwSmChbmbWTU2NuJ2uQgGg3h9ju69x+OZ5rBndZOPhmIArK0N8FDj9WifpLqRVDeGoWNkkghGFkkQCbhkfuHzn2NsMobidlNf31A8LiOv9iNJErKiOOk9glWUWIX5JVIjkQiWaeL1eqnKp1MtlPmiMDeTZfW6XWRzGqlsjoFrfUSj0QWl99i27dT+5DKoXj8v/+hVpzh8nn4dt8qv/Mqv8C//8i/8/u//Pk8++SQPPPDAHd1/iRL3EsG+z+JdHo+HSCRCZWUlX/va1/jOd77DW2+9NS2FaDZmiwg0NTURi8Uov0FT+k6STqeLBvB9dipLfMKxTIN0PMarb+wn0t+P3+/nsccem/Zlevz4cfr6+qiurubw4cPs2bNn3pA8OF/M+/fv5xcf34ZpWlya0AkGgyxpayObSTM+NoZLFjh0+CjReIbJskZS3homshY36eNFUBVoD4hsrRbpmO+yEyTHKRBEyKd6FP6dTKXRDJOuy1fw+/20NdYjKQouXzmC6uHilR7ee+89Ht33GB+8d4B9O7dRU+bF1jMIogyqSv/wOG5VJiDqqJaGDWjIDCdzvHvyAg9u3nLTKMJiMQ3HyZAXWaQ7F7ZtY44OkD1/BLP3HGjZac+LoTrUZRtR2tchumc64ZFIhImJcVqaGikPhmY8PxeRSATJ0vnXl3+EoqoznEtHEnQSKx1zJEF9FYuWtAWn6ZxpGigLiDzMRldXF2+//XYxz/2pp5+hsrqqKHl5+fJlRkZGqKuro6mpCSuf7hPp72dwaIie7m4SiQSPPfYYbW1tXB1PM5rSsJLjaOODyLLM2bNnWbN69YxC2oVE4UaGh0kk4qgu96zbHOwb5/xwErcs8vm19ajSFDUr2yan69i2jSvfBMzWc5i5FLahI8gqtiBhI4AoIcqy0zNkyvtgGCa2baGbFl63q3jdZzIZKisrefjhh2loaADbZnJykp6eHgCOnzhxR6RjwbnXnOvsJBSqRFFkWlpaCE2NAuUlYAXbJhaL4XKpfP+lV8hm0uzYsWPO9B7bMomPDaPrOu7yStweNxfOn2d8fPyu1QjkcjnWr1+PZVkcPXr0rtoVd5p4PE4gELjr9tBi5zPa9RHlZWUf79iJBFUdD9w35+J+4J5GBCYnJ0mn09TX1wPw0ksvUVlZSSgU4s///M/59re/vSAnAJz0ivlSLO4W/f39H/uYJT79WKaBkU3jDQR5aNMmmltaZl1RC4fD9Pb2YlnWgkPyS5YsYc/mzZz8T7/Psl/7EiO2iKqsJJtJkzMtjo2anByIExeWY5TbgACZ2fP9/apEa8jLpuYKHmgon9aEzHGMbbAssK3ib9s2pz1mWSa2aYCpg5bBa+uI2QRLQh7K/D4GrlzE7XFTH67GNnSWSQZND7Uhxy7zs2vrkGI9MGlN0x2qcgdwo5IxZdKSn8FYhvcOHiKVdmoyRkdHF/uW3BRRktG1HNwhR0AQBOTqBjwVn8Ha/AT2wBX0rpMY/V1g21jjg2QPvUr2yI+Rm5ejdmxEbuwopuYU0mP0bAbLNBEX2L03Go0y2H+NR/fs5u2fvjct9cXSMpjxURAEpFA9Yl5BabHpaeAUrFv67GpLC6FQTzIyMkJNTQ3NTY351BiLiXicnKZTFQqh5XIMDgzQ1NyMIAi0trbi95ehKioVFcHiNdUa8qKbFjFCVPl9/Phfv43X651zxb+xsZFIJFJUBiqeI8tmdHSUsbFxurouMjg4NMOwjmV1Low4UYUN9YGiE2DbNrphYpgGqqIUOy4Xzm9tbS011VVYuTSCnkaQFETRhaVrGHruegdvUaJ/oJ94PE5dfQOKJOL3+/nCF7/IQCRCLpfDyqc6CcDI6Chnzp4tptTcjnSsbdtOKpVhUlZWTlVliJamJq5c7kJPJ7H93vx9wHbuAeAUjJoaY2MJHn78Kd744Q9mTe8pRAGyqTgnT59l+eq1XDpzmqrKyjtaEzAbLpeL7373u6xbt45QKMSv//qv85WvfKVov5S4BfKRvo99zBLTuKeOQCwW4wtf+AKZTAZRFKmuruZHP/oR/f39/O7v/i5Llixh7969gHMRHj58+F5Od1b+63/9r4CTmlSixJ3AMnSMXAbF40MQpVlzeQs0NjYiyzI5TXO6eC7gy9tIJhn5L3+AGYtx/r//NfKv/jpvlMl862ovueKSf+HWMP2m6ZZFGoNuNjQE2dIaxC3LjtqLaYCexTZ1bEN3/jZ1MPXrRr5pgDHLY6Y+bQwB8OR/SKRp8wNksUevXZ+HKIEkY4tukFUnb15WQJK51j+EYcPxjy4RGYyyadMmqquriwbyVCWZO4kgCGSzWc6e66SmpuaOdT0VJQnDEFDb1qAuWYuViqNfPuU0LIuNgGViXO3EuNqJ4PGjtD+A2rERKeQYsJKiYuoaojS/7GqBguqObdn8zPOfcVafLRMzOY6dSSH6g4je63KNkUiEd3/6U2ycCNXTTz+9oGMXBAFJkjENA/kWJWlvlLV0tO0lLl+86Bhopk7nhYv4y8qnFdr7y8rYuHHDjFTH9io/pyNjJHGxdc8+wgHfnNKtkUiEV199FUVRaW1rxef34/E4PTiSyQSHDh9ifGwMmGlYH41MYtsQcMsoiREOXjlLU1MzoapKZEnG43JNO7+vvfYaTzz5JEI+Yub3+wE/GDksLQOWCYoby7Ixc1kMLYdHkVArK1FVhVQ6jWXb/OuLLxKPx4vRxULtgN/vR9O04r8XsqBg2zZ9vVeJTcaorqqkqqoSy3QcfSG/COCVoaGmCkvPEa6pRlFVJEUtFnxPrXW63Bvh/fffp7FtCY888TR6MjZ9PNPEyCQQRJHLfYM0Nrdy4O23WbV2HV5/2YLTzG6HtWvX8k//9E98+ctf5utf/zpf//rX+fM//3N++7d/+66OW6LE3eSeOgItLS0cOXJk1uc+KWk2Lfkvly1bttzjmZT4NHDdCfAvON2iuroay7ZRZikInI0Pf+ZnsWL5L1kblH/4f5n4lT8iVz1zZUsRIeyBtQHYHjIpl3LYRhxy/dBpYJi6Y4QsFkkGSQHVA1IZSAqWICIqLgRZQZBkhscmmIwnKasIUVtXh6XroKhI3vJiU7KcpuG+IRKYSohc7emmvqGRyUSKyspKVq5ciW3bi1YaWgyRSISrPT1Eh6McPXr0jqVXODVFEpZlIkkyoq8c1wO7UdftwhyJoHedQOs+A1oWO5NEO/sB2tkPkKoaUDo2oLSvcxpvWdaCPlNT870tUaLKq2CMRsgaJl0DowRDFm2t5ZimiWlZuF0uli9fzmQsRktrK1o+pWUhq/ySLKPlskiLLE69GUvb2/npu+/S29vL1s2bWLVyxYyoyGzjXbnchaTpJKVy1Io6skZi1v3bto1hmOzavZt0Ks3g4ADX+vpYu3YtgiCgqipaPlW1YFgXcuVdoTB9CedabXMbdF26SEtrGyOjI2i6xpK2tmljRaNREokEx44eRdd11q9ffz2lQfWA6nEccC2DnY0hSCrZnIbLpXL42EkU1UVFMMj69Q/wyCOPzKoUdGOOf0NDA7ZlOepNeRUn8oXaTsG2jWEYiJZBKFiGokhkMlk8Xi+i5HKkTwUBlyAwNB5jfHScpe3tVITmTlFbvXo1tm0zPj6OIktUtizh3LlzjI2N0d7SRHVFANnjwxZlmpubefmVVxgbGyOeSPDkk0+R0TRkUUJV7uxn6Ua+9KUv8ZnPfKaYqfA7v/M7/OzP/mwpMnArlIqF7wvui2LhTzK/9Vu/xTe/+U2ef/55fvKTn7Bp06Z7PaUSn1BMXcPUcotyAhbLuc5Osju2o7zyo+Jaf7RtFYm8EyBiUyUbLPdk2FmWIqxOUQJKki8OFoqr7yj5At2CYS/L0/+WHKPeeS7/uDj9i9q2bTRdR5HlaSt6tWGY2ndWtG0sPYeRSSDKKpLLWyyon/q6Qn5wuCpEqKq6+Pedrgm4kWg0ypmzZ9mzZy+9fb0MDw/fsaiAJMsYuoY0RTFIEATkmibkmibcW55G7+3Mpw5dAWzM0X7M0X6yh19HblqOtWQdrtaV86r6FGhsbKShrhYzMYadS5K2JSYzmvNa22Z8YoJgIICiKGRzOY4dP04ymeTKlSu88NnPTms0NZ9RVuzBYFkIC0xduhmmaVJeXs6aNWsIh8NU1dRQHqzA0HKYhkBkYBCvz89AMjFjtX9kZISKQICuIwdYvv1RkkoZac1gKNKXX9VvoiZcg22Dx+vhzTffKCr4bNhwPcJwo2GtaRp9vT3Uhus5k3Y+q2GfSoWYYUQQ8Pn9HDr4IStXrpzhCITDYfx+P1evXsXv9+P3+5FuPFeShK24MHQNK5fBJZiIloVo5mht6SCnaZw7d47Vq1c7x2zbWIZRVGHCtgiHgtRUlGNbFlrSkfIuyLUiiAiSjChf//vEoUNcvtzF3j17iCUzKKqJrzwwQ/K6WByuaTd1EAvpPbZtExkZJ6XpNNdWEZ+cIJZKs2zZcqx8k7Tt27cX08JaWpqLaVXpbA5VkbnW1zdvkfLtEAgEsG2bQCBAPB7nr/7qr/jqV796R8coUeLj4r4rFr5TfJzFMR988AE7d+4E4A//8A/5tV/7tdLqwKeMW8mBXgzXnQDfop2AaDRKJpNBluVpcyvOubae8lAlOd1AM5xVvjf/4du0ff+bjDYu5aNf+l06/LC1RmRphXrdcM8b9EXDXs4/Joh3bMWtIFcoSdJM42ae11haBjOXJZXVmEikQWDGl72eTSOr7rvmVN1IIVUknU7zwAPrefChh/B5PcXGTreLls062u43OR4rOYl2+RR610ms+Ni05wRPGcrS9ajLNiAFa2Z9vW3bWJkEVnIcQfUglVVy6MhRFMFmdHyCc+cvzOhEe+P1MVXJRhSEeeUoLcvC0DVU1+11zS7MXdM01Dk08AciESzTwAR+/OM3ZjRq6+rqYmhwkLGxMRI5gxXbHkXAZrL7LK3NTcTjcSpDFcVI8ELvC+fPnaOhvpZvv/k+SvsGAJ5bWUs8GmH//v2IosjjTz6FbRq0trbOeP184zjn2sTQdSRJRpJlLNNgYmQYTA2vSyapWWSzOUIVQRRFnWnkT+nNsNDru7u7m49OnSRcXc2ZzvM89dRT1NXXX5cunaKEB46DNjY6ypXu7lmN88JnplBjMD42jsdI0Ds0ylvvfsjnPvtZGhsbbxo9sm2b4dExMpkMP3z5JVRVXXBDvsUyNDREXZ2j3hWPxyn7mAtfF8p9Wyx85ey9KRZuX3PfnIv7gZIjcId4/fXX+dVf/dVi8XBnZ+ddST8o8fFTMPCeePxxp1tmba2Tc36HjGFTz2FqGorXt2jpyUgkwsGDB1m+fDldly+zZfPmYhHjq6++ytYdOwnVNeESbVySyPjoCAcPHqR12+NEP3yfJWuX3DMpvEgkAjj1P7eSs3+1p4fY2Ajl5WW8+c67M77sTd3JeZaUW+sNcCtMNdgaGhowTBPTNJElGUm6PQfKzK/gygs8Htu2MYf70C6dQO85C3pu2vNSdSPKso2obWsRXE79gG1ojiSoaSCVVRbViLq7u+m6dAGv20PnxUsz1Kvmm8NCHAItm0FxuW5JerVAd3c3siQhybKjhjMLBw8e5MiRwzy652GGolF8ZYEZikBXe3oQBAFN16lubOHScBLJNgmLGV778eusXbtuxmvmwzRNtHSK1/a/xXjNSiS3j7Bq8cy6VgCuXLnC8PAwDY2NVFVXT6sPmO9Yo9EoDfX11NaGneiQct35MXJZxiYmeHP/Wzz92KNE+iP0RgapCIXYtWvXgud+M6719TrqTzYzmpJZliNdWogCjAwPo+VyvPTyy9TX17Nr165iWiM4tUGCKCLmo0SdnZ3UqTojSQ3B60SfFFVd0ELMla5LyJLEtYEhDh8+NMNxvZP80i/9Ev/4j/8IOMpCU7tc3y/cr47ASHfnPXEEqpesum/Oxf3ALaUGHTx4kFdeeYVTp04xMTFBRUUF69ev59lnn2XHjh13eo6fCJ566ikikQgXL15kxYoVfO5zn+Mf//Ef+Zd/+Rf27dvHvn378HoXprNd4v4iGo2STCZ558ABHtm7F13XneZRtg35L60b+0IsFFPLYRoainf2TqwLmVtfXx/ZbJalHR14PB40TUPPZXh42ybqK30YyQEik1nWPbCeMp+HqmAZw7pCaOt6Vixtu/kgd4FIJMKVK1eQZJlzZ8/eUj794NAQV7uvsGblcpLJ5Izuu6IkY2g5pDsj4rMgbmxkpcgysiRhGCY5TUOWZYYGB28puiRKEolYgnPnjy8o3UEQBORwC3K4BXvrM2hXz6FdPI4VvQqAORLBHImQPfQa6YoG0koFDevWopRXIgVrp0UelixZgiSKuBWJhuaWBadaOAXBTrTHtCw0XS92o52aziXJSr5oePFGlG3bXLt2jWuRCA0NDRzYv5+9e/fOugIcDodxuz3sf/sAzz75OOXBihnbtLS2ouWyuNyOc+S30qQkHyO2h2eefBJRlhdcA9Hf30+wzEcmqxFavoFYRkLE5uEV19/3qWIAhmGSzWm4XXN39S3IgG7ftg1ZlojF4wSDFehT+otgGgiSzJrVqzENnbff/YD29nZC8+To3woNDY1Ypo6sTo/mTH3fC71ostksCAJPPf00E+PjxONxamtrkee4b65evZrJq+dxqxaT2Sw//NGP2LNnz7zXjG3bmFqOimCQF3/wEo/u20cgEFhUH43F8r//9/9mYGCAN954g1/4hV/gxRdfvGtjlShxN1jU8svbb7/Nxo0b+dKXvsTIyAiPPfYYv/Irv8Jjjz3GyMgIX/7yl9m4cSNvv/323Zrvfc/y5cv5wQ9+QG9vL9u2bePv/u7veP7552lubuYv//IvMc1bKKwscU8p5OiOj4+z/6238Hq9CICiqiiKgoCzWqtrGlouh6HrRWm++TC0LKahOzUBt7hSXJjb8PAwXRcvIpgaZJOEKysIVNZwtrufXE6nMeTn4vlzpGKT+AIhPC6F2nuUvmZZFoqiYBgGhw8dIplMEo1GF72fcDhMc1MjQ8MjsyqdCKLo5EDf46CnIAgoioxLVYlNxshpGpcuXeLVV18tRkUWQk9PDxcuXmRwYID9+/dz5cqVhc9BUXF1bMDzxJcx9v0HxmpXYnnyq2GmgT06BG+8yJW/+R9cOnp01vSj5paWaXKbi0USRVyqmneMDDRNK6aRiJJU7Nx7MyzLzjtWOplsjkwuB4JIOp2mf2CARx9/AsXlxphlf4XOxlu3bkVyeQgFAxja9EiJIAgIXBesWNXWiNvMYAgycaWcylAII5e96VwjkQh6NkP/wCD/+sNXuZZ1Ut/W1Abwq7OvwcmyhCxJ5DR9zv1Ho1Gy2SzBUCUHDx1mcHAISZJQZBlVUfK1NhJaLodtaJw8fQafz0d7e/td0deft6sg0xtovrV/P6/+6EecPn0aVVVn1BPMeK2iYuQyvPXWWzdVM4pEIowMDRJPJKioqubRRx/FNEyeeebZO14jcCO/9Eu/BHBHmmr+myLfO+Zj/SkVC89gURGBr371q/zlX/4lu3fvnnOb9957jz/90z/lkUceue3JfVJ54YUXOHPmDG+++SbPP/880WiUv/3bv+W3f/u3EUWR3/zN37zXUyyxCG4s/KuoqMA0TXRNQ1YUJFmmkN1eCIlbloVlOIW2wg1do7u7uxEsg4pgkEDl7aUYNTQ08NnnPoNgGfi9HhSPF0l1o4oS48kIVeFalGAAt5VGiKd58aVX2LFzJ8G6JvSbdQe7wzhKKwZW/hxdvnwZWLhc4Y0sWbKEUJmX3sgg7ctWzPplL0oytmkiLFBR6W4iCAJDQ4O4FIWqqioGBgYWpdcejUY5ceIEv/CzX6Cn5yoT4+OwyLznoegwgqBwcBJWrNhHe9BNtvMwsfffQwXcmSS88k1GxgaofO7nEd3Xo5iCIKBpOucunqS6uvqWa2VEUURV1WLKkG0YReN1cGCA3r6+YsTDtm3M/PU0Nc1EEkUkSSwqxBi6Rl9vL8lkkgudnTz19NMYpuMsSJLo7D+/8jx1Bd62bYxsGlMDaUpjs2QqxfDVXvx+P42NjaxprSs2HBtImTQF3OjZNBOxOJH+gVmjO8lEHEkQyOU0wmu3MG478rvr6uZPR1AUGUvT0XQDlzoznOVENdzE43FSeSnRqdEV09ARJZmG+noqfG6QFVavW39XapsWQ8EJm021aC7KgpW4MNmzZ8+8EbT+/n4mRkfoi0SI9A/wzDPP0N7eXlQWu9VeFQvlscceo6GhgW9961v82Z/9GVVVVXdtrBIl7jSlGoGPkV/4hV/g29/+Nv/zf/5PfvmXf/leT6fEbWJbFrquI+ZD4LN90RTC4gXnIJNOMzQwgCjCgfc+4JFHHrmlIjbbsrC0LKaeRRAlJNXtSHDaYJgmumlhmBaSKDDQH+HIoUOMDDur7lu3bmXV+ofIGiZ1gbufrlbMEzcM5LwykCAIt12Abds2WjKG6g/M+SVvmaYTdbkDhai3Q+Gzkk6n+OGPXmV4eBi/37+olKhCSkiZ38/uXTspLyvD6/UWddkXwvHjxxno76ehuZlLFy7Q0dGB1+2m5+Xv0D58Bdm+3jhOCoao/sIv41vjdKqORCKMjwxz6fJlxsYn7pg8asEhSKVSpJIJPjp9hoaGRppbWvC43YiimC88FeZNvyvk2k81MguOhG6YWLaFLEko+bSkQp59OBymqS6MKMlIqqvYJKyhvp5znZ08+uijNDY2Ytk2l0eSxLIGDeUu7NQEqXiM6Ogoo6PjbNr0ULE+Z3xsjNbmRv71pVeYzOgENj0BgsDWxgDlRuKmn3vHgNWRRJFodGjG9leuXEHTdCpCFdTe4ERrmTSK242ZyyKIonNvuEtYpoll6Mh36fqycmmssWtIdcvmKTY3iY+P88ZbbxHpHwCY1mFd0/W843hnVKnm4r/8l//Cn/3Zn/EzP/Mz91160P1mDxVrBK5eorz8Y64RiCeobl1235yL+4F7v0z2b4h//ud/xjRN/uRP/oRf/MVfxO2+t8ZJidtDEEUUVcUwDHRdd9KEbviyKhguhRW748ePc+nSJbbt2MnK1WsYGR1dsCNg2za2qWNpWSzDQFRciJ4yDAtyhoWeyyGJArIk4lZkZLdjcEexyaRTgLP6XlNTgyyJ6Dn9JiPePpZloRtGcRV46vm5MZ9+0dhWXu1kntQCUSxqod/NFcG5sG0b03BSxWRFJVgRYu/evbfkAE1dUZVkBbfXiyBK6LkMoighqepNi20LzcIudXUVIzGNjY3Yws8z2ttDzbkPEa85KUfm5DhD3/gf+Ddup/Jz/55oNMqpUyfZt2c3oigh2GZx9fl2zq0oiqiiyEddXaTTaQRB4NTJE2TSqUUVeM7WeK9QjyDnc9UN0ySr6WSyGXp6e7l86RIA+/bto7m+FjQn8nL58mUEUWTzli2oLje6YSCJEu1Vfi5EE/THc0jJNO+8/jrh2lqWLFmCy+NlfGKSzs5Olra18sb+t9ixYwen4wJxBAIumTqXyaWrET748EN8Pt+czpQgCLhUhclYnI8+Os2FC+enOY5TV7unUlzXs8EyNBRfYJHvxv2FIOdrRkwd5Ov1IwUnrqW5iapQBWlNZzIWB2ZGGGVJQteNu+4I/Nmf/RkAn//85+/qOCVK3GkW7Qj09fXddJvm5uZbmsynHVEU+cM//EM2btzI7/3e7/HXf/3X93pKJW4TJ/9bwTJNNE1zUhDm+cIJh8OcPn2aH778Ehs2PsjqjRsxTBN5ntfYloWlZzG1HAgCtqSiyyqGaSNYJorspEj43LMbxR0dHdi2XdTc7ujoIKMbmJZ91wxkR9PbANtGURTEuzCGZRqI0vy3sIJMom1bCMLdNQSmYts2lmnkoyAKiuu6k3g7DtBUY1fXNGxAcXuxTAM9m3GiU8rcDsGNaW6FeaxatQpWrcJ+8mmSx95n9Affwko5zbSSJz4kffEMVQ8/i6EbvPjSDwkGg3zmmaexTQM9n2MvSs5nf2AoekuOTmVlJSdOnCCZTN5yuth8OF2HZRRZpuvSJVasXEVFIIDH48Hn92OJMpahsbR9CROTk4yOjHDixAn2PPwwAgLxeBzdMKiSYciS0PyVbNm1B68scPToUZqbmpiYmECSZQ4dPcrg4BA1S1YSJwjApqYKuq904vP78Hg8xdqYuc6RIAhc7emmubWFCxfOz9i+sMgwtY+Gc01ImFoWSXXf8Wt7tije7aYUzBsZzDcmsw2t6BQUImMrly8jGY+TzTld1Wf7XAPXz83H0HkY4Atf+MJdH6NEiTvJoh2B1tZWBEGYUchUuOEIgoBhGLO9tASOEsJf/MVf8Ou//ut87nOfY+/evfd6SiXuAKIkoYqikypkWXNqXd+YJxso85PVdXTDxK0qdHZ2MjY25nTDXd6BmctimTqWqKChgiAiCxKqLOKVpQUb2MuWLWPZsmXFv5X8F6Jh2SjSnTMWbNsudpyVF9Eb4JbGMg2nx8FNECXZiaCod9cRKKxSNjU2UlNd5XwmXHfeGCsgKwq6lkMwBSRZcY6z6BDIeYdg5tjzOSKCIFC2aReeFesY+/43SZ74EAArlcB67ds81racyYcepqZ9GTW1dcXX2baFZZrEY5NItslIdIhjx44tKn3oVnLIbwXDNGlqaebHr73G4MAAfr+fxx57jHBNDbatIJDmoQ0PMBFPEggE8Pl8pNIpeq724HG7cXs81JdX0Je08VfXM3LxJA/v3lU8zg8//LDozAzLQTCgrsxFU8CNVFtLTtNIp9MLcnbC4TCJ5PVo3o3bS5KEad7oCMiYWuaORwMKksSFY3vmmWeor6+7+QsXsE+P18vAwCCqqjrdh22wnf8hiApGNoMlOI6Az+/nkUcexeOSeesn77B8hVMfNN/nWpYd5S5VvTuOQDweL/77bkcePlWUOgvfFyzaEZiYmJjxmGmafPOb3+RP//RPWbp06R2Z2KeZ//yf/zN//Md/zDe+8Y2SI/ApohAdKBQSK3M0NboxhcGjqhimyXgsTjQ6TLDMS1NNiEwigSWpiIofWZYokyRE8c4YlZLoKKPopoUi3ZkbYyENSBJF1FnSpO40lmGgqJ6bbidKMrqeuatz6e7u5uCHH7J2zRrGx8fRDYO2GzrE3mkEQUBRXei5LIIoOOlB0xyC9LwOwXzIZQHC//438T+4g5Hv/S/MyXEA7J6LBPuv4n/257Dr64u1CYIgIskiV6728e677/Jzn/8s585fWFQxNMye3nOnKESpDNOiorycLZs3z3A6BEFA8fjwCQJlZWVIilNAfPbMGQ4cOACALMts2ryZsZRG26r1hEKVhCvK0eLj1IYCfP6F5xgcHiHtruBszFkw29xUQX9/P7puoCrKTYtfC1RVVyPJ8pzbS6JIztCQbcf4tC0Ly9YQlYU7oHOtyBfrm2wb27KRFYV9jz3G0OAQhw4dJBqN3rYjEI1GqautpaGhkfHJCRKJBKHKSgSnqYCj3qS4ABNFde4pA8kkb7/9EyRJYteOHVRVV900simKYlFe9W7cl/7hH/4BgOeff/6O77tEibvNoi2AQCAw7eenP/0pu3fv5hvf+AZ///d/z8GDB+/GPD9VCILAH/3RH/Gd73yHCxcu3OvplLiDCPmmSbKioGnaguRiC3nMI9Eh1qxdS01NDYdPneWjC5coKy/D53HhUuQ75gRcH1PEMK2bb3wTbNtG03UM00RVlHm7yN4pCkbKQopkC3Ox7ds/1rnmgmXwyMO70E2T/W+9xdDQ0F0Z60YEQUBxuZw0ofzxCYITIVDcXgRBRM+mMbTcLcmo+tY8SPMffI3yHY8VH7O1HGPf/yb9f/VHaEPT5U/D4TBer5fhkVGWtLXekfSeQvHuYqRWb8S2bbKajmXbePIa/e3t7Wzbtm1G5EEQBGS3F9MwMPNN2MLhMO3t7bS2ttLS0kKgvJyljbUIgsDFq9cYGIuhlAURFReBQDntLU10Owv5tAddGLER3vjxj7Fxmk8uNG3KMC1qqqt58MEH56wlEAXRuR4sCwQR29CnKSDNR2FF/vDhwxw/fpyR0VFymk42lyOnaeiGU18jigKmYfDW/v2UlZfT1Nx8R97bcDhMR8dSjhw9QveVK7hcrmIksdCZWFBUJzUofx0XIkerV69GcbkIVoTQclkMfW7J1cI91rhL8t0FJcWCHG6JBVKICHzcPyWmccuqQe+//z5f+cpX6O3t5Y/+6I/45V/+5Y8l/26h3G9V8jcyNjbmNEyZnOQb3/gG/+7f/bt7PaUSdxjbtjF0pyBXnmOFvJBKY5kmQ0NDCLLCd7/zbfx+Pzt37rw7ut95hmJpFEmk0r/4ovXCKmJLSwtl5eV5+ceP7/q3DB1Ty6F4/Qva3tC1ooF8Jygcf0N9HaFAOZPxBPvfeps169Zx6OCHC+68e6ewLBND0xgeHZuZw23bWIaBaWjFCEFPT09xu4XOM3PlPCPf+Qf04cHrD0oSFY99lorHXihKtEYiEdKpJNWVlVRULb5j9FQikQivv/46jz76KINDQyxpW1LspLtQLNsmm9OQJQlVWXgQ3LZt9Gya0bFxenr7sG2bzs5OADasX09Hexv9mgufkaClsX7anD4ajHG8P4YkwGeXV2Cm4rgUhXgiQffVPqpqwnSsWDFvcbdlWeR0HY9rfqO+kIon2hZWvnh7oSo+nZ3nwLKxBIGxsTHqamtZunTpnOpMkUiEiYkJmppbCAbKsSwTU791VS7btknEY3RdvjKnc2Rl4lixYeTaubMNnKJ8A9M0HElnSZ4R6SgUV7vmiNTeLs3NzVy7do1vfetb7N27F7/fTzAYvOPj3Ar3mz1UVA3q6743qkHNS+6bc3E/sOhv7rNnz/KZz3yG5557jueee47Lly/zq7/6q/eVE/BJoLKykq6uLh599FH+23/7b6W6ik8hTuqGiihJ6PnmSd3d3Rw8eJDu7m5HbSiv+qGoKvWNjUiSyKZNm+66EwCgSCKGtfh1gEgkwocffkh5IMBHp08zMjz8sV//Vr5z6kIp1AncCSKRCG+88QamliWTSjI2GaOmto6t27ZSW1f7sTsBAKIoMRmLk4zHOXDgwLRmZYIgICmFCIFAMjbBQP8ABw8eXFRjMk/7Shr/61cJPvaCU8QJYJpM/PhFrv2P3yd7tQtwahA6li3H53XfdjO3aDRKPB4nNjnpSMFaTofmnKZhGPM3IItEIpw5e5Z4IomqyItyAorjj4yhyCJNTY2Ul5ezZ+9etmzdysjoKOfz0VxJdaGnYpi6cy1ndJPTg07O+OpwGS7VBS4f//rqG7z+kwNouk5tdSV6YhI9MYGRSWJqWWxr+mr12PgE13r7bhoJEUURy7QwDR3bNBYUDbAtCy2Xpb6ujuMnT/LGj3/MhfPn8Xq98zb5amxsZO3atXg9nny08/YMatuy8Hi8c0Y8IK8cZJkzzs+0bQQBWVFQXW6nVmVygvffe2/atVBQb7tbq/bHjh1DVVW+/OUv09TUREVFBV/72tfueUPDEiVuxqK/vdevX8/hw4f5zd/8TTweD//wD//A17/+9Wk/JRZGWVkZf/AHf0B3dzdf/epX7/V0StwlJElCURTisRi9V68yOTGBIAiMjIygqGoxlaaQBrB79+677gQAt5waNDExwQPr1/PGj3/MqZMnb6kr8O1iL0AxaCriHewyPDoyws5tWxgbH+f7L/+QgUEnDai9vZ2ysvKP1Qlw1IlMdC2HJIkM5d+L2bo1C4KAICukcjrBUIg9ex8hlUoxPDy84PFERaXy2Z+j8b/8Ka6m68epD0Xo/8s/ZPT738TKZfNqTdK8xttCKHTOfve992hpakIUwO1yocgyNjZaPo1F0/VpnYnPnTvH6NgY4bo6Xn/1RwwNDt5kpOsUInlaLoth6PzglVfRcxofffQRV3t6uHjhAlu2biVc14CATXR0gt6BKKaWRU8neOfcVXTLRhVheciDLMtUBIPs3buXdQ+sZ+mKVZRXhVHLQ8i+cgRJwTYNjFQcLT6OkU4wFh1kfGyE119/7aYdqAVBIJ1Oo+WyJDPZOY34SCTCiRMnGB8bRddyyLJSlLPds2fPogq7FUVGN0y4zevJNM2bF9dKedlQ4+Zyx4W6mb5IP2vXPQBMvxZkWSaRTN12qtls1NTUMDExwf/9v/+3+Njv/d7vlRb55sEWBGxB/Jh/Pn4Z6TvF7t27mZycLP79yiuvkMncfv3bopdIdu7ciSAI/PSnP531eUEQSp1zF8HOnTv5/Oc/z9/93d+xbNkynn32WTyemxdAlvhkIYgiV7q7aW9v59y5c7z00kts3bqVurrrxXamaeK6hVXLW0URRXTTWlQBnW3btLS08PLLL5PL5e6KzONC5mDdRHJ1NsS8YbqYSMLMsS2WtrVw4N33uNh1ecbxC/n53fVCacvCNAwsy3QabkkymWyOi3ld/NneF8M0MQwDLZfjg/ffY9mKFTz+5FN43QvLJ5+Kq6GFht/+b8R++jrjr30XW9fAton99HVSZ45R/bO/gmvpqmKqyq0yVe5UcbmorAjmc9ad/HHkQsM6G9My0Q2DZDKFKEm0NbfwyssvsXzZsgUVLdv5pneWZSLJMqrLjZG/Pt7cv5/PfvYFIv0DlJX5eefHP2Lfrm0kyHL5Wh/Hey+zc+dOfB43Qa9KNG6hJEbp7Y6zZs2a4rHcOAenGaAEOO+BbVvYhoFhTFBd7uPLX/wsw6NjWLkMlqEjzNKzIRKJMDTYz8ql7SSSKRTXJO5iOpEAAmTSGWITEwTKyzh+4gQrV64qzuVW5Gyd1XUB07K4HQFRyzKRlfnT9QRRBFF26gQW2Byttq6OkydOANOvhYH+fmLxOKdOncIwjDvWFK+A1+vl53/+5/nFX/xFAPbu3VvKlihxx3j//ffRpvQO+dKXvsSpU6due/Fp0XfognJCiTvH1772NV544QW++MUvsmXLFl588cV73g6+xJ3FNE2Wtrfz6muvMTg4OMNQsyxr3q6pdwNZErBxcqilBYxbKAr2+f233BTrjmBbCOLiz5Uo52VEb9EwtW0LPZPG6y9j/cYHqWtonHH8gigs+HwuhKl5zvX19VimgWk6xr8oydNqT+bqEeC8bwYC4FJVmpubizKdlZUhgsHgLTkvgiQRfORZfOseYuQ73yDTdQ4AY3yEwb/97/g37aL8ic8hVd2ehOpUQ9XQdUxDR1auN5cSBAFJEpDy6lcnjh9n+arViILA88+/kE+/s6fpyE/tKtza0oJh6GCDpEw/p4UeHOlEjEhXJ+2NtXgVDw81PUQ8m+by6TNcvngV27YZGxsjVx5gTAphIxDHxej4TJW9ec+p4BTHqr4Ar7/+GsPRIVqamnh41w7MXBrbNJ0merKCKCkIskx/fz+tDbWc+Og0R46fZM+ePWzcuHHafjvPX+DwoUOk0mls2yYUqrzt61aRZeLxBKn4JFndWLQxYi/inifITsHwgvZr2/j9flauXEkoFJp2LUSjUaJDQ1RVVXL58pVFq1otBEEQ+I3f+A3+5m/+hnfeeYcvfelLfPvb376jY3xqKMmH3hZ3Ku2s1Fn4PqCxsZFjx45x+PBhnn32WVpbW6mvr+d//a//xWOPPXbzHZS4bykUsVm2TXkgwJYtW2bVSTdMa9Er3LeLnDecdNNmIQqiRl4aVBLF2+8KfBsspJHYbAiihGXlbmnMghMgqy5EWZnz+EVBwLbsW0i6nEkkEuHtt9+mob6eUDBAPDZJWXk5qjy3NOuN8zIty+l6LcvTUjCmynRqukEmpxXVdBaLUlVL3a///0gceoexl/8ZK5MGIHn0PVLnTpLY+DDyyg2szq+M3w6SLKNrOSzTnLVxX3d3N1XVNZiGwTf+9/9i5apVbNu2HZfLRTanIQDZbIYLFy6Qy2WpDdcwMTFORahy2sqtbdvYWho7m2RJQAKfn1RGITIURfEFCNU2EssmuRQZKRqetXX1BKtq6PzJO9hN65B85aSlxRfRWpaF2+1m965dRWclVFN3fV6WiW3oWHqOXHycjqZaFJeLE6dOU1ZWRjg8s5i6qqrKacyVn+udiOL19PQwMjxCuKaa/fv3s2/fvkVJv46NjTI5GcPt8dz8XiKrsEBHQNcNFFme9RoNh8PEJifRk/pdjWb+9V//Nc8++yxPPvkkJ0+evCtjlChxp7hl1aD7nfutSn6hJBIJvvOd7/Dd736XAwcO0N7eTmVlJdXV1fzWb/0We/bsuddTLLFAbNt2GowJwpwNxgqkszncqvKxh5H7xpOEvC787vnD84ZpYlkW6k3C+B8HRjaFIMlFjffFoGczyKprQbKjBW50Auadm2Fi2XfmPF26eJF0OkV3Tw99fdfYtWsXDz744ALnbDtzsSxU9eY9HTTdwDDNW3YGChixCUZf/EdSp48UHzPdPt5rfZAtu3YX02RuB9u20XLZWZu1nTp1irLyALGCJn0oxJo1azBNE8MwESWRyLUIkihy9WoPnZ2drN+wgW3btmGbOnY2hZ1NYudSYFugeBDdPobjaV5+9cfFZlqf+cxnqKoMEY/F6e7poTwYJNzQjN+tcvHCebrjOqNqJQBPLauhrnzhDkFO05AkaUELA0cOHaSjsYZYziZj2sQnxtmyZcus287bwfcWOHjwIIcOHeKpZ56h89w56mpr2bZt24JeG4lEyGXSvPf+B+Q07aYpOlZyAisdQ65pBaCzs5PR0VGqq6tZuXLl9e0sC103cLnUOfbk1PiMT4zj9fru6mJGKpWiKd9t+u/+7u/4tV/7tbs21s243+yhwnyG+/s+9vnE43FqGprvm3OxGERR5Jvf/CaBgNMs8Od//uf5y7/8yxkO7XPPPbeo/ZYcgfsUTdP4+7//e65evcrY2BinT5/mo48+4ktf+hJ/+Id/eNea7pS4M9j5lVjphpXYWbe1bdK5HD73rUnw3Q4Dk2k8qkSFd26jutAo7ONoErYQtFQMxeNHEBcfQTF1HRt7WmrJfCzGCQBnBd4wDFzqwvY/F4auk0om+d6//iuxWKzYyXUhhotlWWi6gSSJyJK04PdMMwwM4/adAYDkR0cY+Je/Q8qmcW14CLt1OeP1a1na0ohXXfic5sI0DUzDQFFdxX2ZpkkikeTll19idHS02DG4EHkrOEepdJrDhw5y7txZ2hrr2b3lQQIeGfSc08TK7Xd+XL5p9SSzGdJWvnlg2rTJpVP0X+sjHA7T0NDAjy8NM5jI4VclXlhdh7qAsJtt22RyOTwu103PkW0apMeHOHLyDCfOdLJtx06WtLcTrqr8WK7T7u5u9u/fT07TePYzz6EqMo0NDQt67fHjx7na082StiX4y/xUVFQQKA84KX+i6KRITUkbsrIpjLFrHLoyTGVlJRcvXiQajSKKIrt27WLVqlUA5HIaijK/lLGh6wiigHQbtSsLJZPJUFZWhmmavPDCC/zgBz+462POxv1mD5UcgVtjIQuFgiAsqH/RVBZ9JfzGb/wG8XicRx99lH//7//9Yl9eYoGoqsr/8//8P8W/TdPkT/7kT/jqV79KOp3me9/73j2cXYn5MPNFmYqysBV+w7SQb8GovRMokjCvclAhqqHeJe3txWLnu5zeap6nKEvouSwswBFYrBMATmqQdQuSrNfHLPSesCkPBnnyyScXvIrr9KSwMEzHaVtsdEmVZQS4rTShAv4HNqObItZb36bajqON9ODu2MZALIMogM8l43cpeFUJ8RbGkSTZkcw0DWRZyRdCmwQC5ezcuXPW9DtBEJBFKJMtdq5dyt41LYjYIMsILj9ioBZUz4LTrsApZM3aApahYWg5Dhw4UHTadrXW8oNzgyQ1kyPXJtjZWnnT49INJ61lIU6AnhjDXRakur6JTW4fgTI/FcEA47EEvT1XqKmuvqsr3oXGXsPDwwi2RUVlFbphosg3v5eFw2GOHTvG1d6+4vmqVBQs28K2bCxLv94AUBAZHxmhSoQlbS2UBysJBivw+X2cP3+B0dFRAEzTgrxE6PzY3JHcvQXgKcqsQjab/VjGLPHp5W5J3y7aEbhw4QL/5//8H/7gD/6g5Ah8jEiSxB//8R/T09PDO++8w5//+Z/zn/7Tf8Lr9d7rqZXIM7U52GIMZ9M0kRfw5Xk3kCWRjDb76kGhOFi5TyIBAHY+N/xW5yMIItg3V/a5FSfA2b9ANpvl1MkTi2rW5Yxpo2s5RFEqRiwWWotReK8EQbithklKvilYOqfhvU1nYPXGh7gWvQRDF1Ayk7TVBBBEiWTOIJkzGCw4BaqM3y3jVeVFOQWyoqDlstg2mJaNK58CNbX+wbZt0HPY2SRWLglaBgQRt8sHrhCm5MYSJcf4lsRpRcQ3e+8syyKZ1bAtm1Qizqs/+hFwXa6ysbGRLc0VvH91nEujKZqDHpqDc9+vI5EIbq+XbDo973tuWyZ6YgzJ5UNy+6elW0UiEfoi/WQzGY4eOXLHVXFu5MZznc7lEOCm97O5CtslRJjyUtu2wbYxUzFyqs3Js5cI19Zy8uRJNE3jM889TygUorunB6/XRyIeo6Oj46bz/rjuZoN52do1a9bwwx/+8GMa9RNEqVj4vmDRjsDv//7v8xd/8Rf88R//8d2YT4mb8Ad/8Ae8//77/O7v/i7f+973+J3f+R2+8IUv3Otp/Ztnaj2AsghDzLZtTMvCJd6b3HtZFDGs2fW5dcNAkqT7Sv5uYnyURCKB7IrdsoEjShKWaczaZbi7u5ux0VFWdCzBVxZElBd3i+zu7kaUZE6ePIkkSQsuoLRtGz2Xc1LJFjmmaZrFleSbarIvAMcZEEjnU1RuZcW+QHjpSrJDFxBMAz0xSSyrMzg4SDgcpq2ufopTkEXIOwVlLhmv6+ZOgSAICJLspGJNSaWxLRM7l8/1z6bAMkBWnXSfsmoEl7e4rcT11LdYPMWxY8e4du0afr9/xntXSA2qra2lpiZMVtOxgHKvi+Tk9ZXoqUWoHZU++iYz9E1m+ODqODWrXbiVme9RJBLh4MGDtLS1cfL48TkNeNsy0eNjSC4vkmdmV+2xsTHqGxrZ/+PXpjkkHweCIOB1uUjnciBw0xqHhTi5giBgmzo1XpGTXX1c6upiYHCQHTt2MD4+TiadYgKbiooQw9Eo77//HoZhTKsbuJGPMxn6nXfeAWB4eJjR0VFqa2s/vsFLfGp5++23+f73v8/Vq1cRBIG2tjY+//nPs3v37lva36IdgX379rFv375bGqzE7bNy5Uq6u7v5m7/5G77+9a/zcz/3c3g8Hp599tl7PbV/syymHuBG/v/svXd4XOd5p32fOh0dGHSQIAl2ihRFiVWiRKpb7o7rWraT9caJ1k6869j54thpTjbZjXdjx05sR/baceK1LEeyLaoXihRFikXsnQRAYFAGgzK9nPr9MUUACZAACBKghPu65mKZmXPeOXPmnPd5n+f5/aycJvp0rbgrkohp2dlxDBuDYWTlJq+3ktHlCAQCDPR2MxSJcLa1nfvvv39SkxxRljF17ZJAoLW1lR2vvsrmTRt4ZcdrLF22fMK9OMFgkCKfj6333IvD6UASJTK6XlBbGu17ti0LTcugKOqoSjhjYds2umFg2/ZVZQFGQ5ElBIFCvfpkgwGxuKLw93h3O0l3Ba+++ioej6cw2S1xqxim9VZQEH0rKPA6ZDyjBAX5en/bzp3D6QSYWnbyryUBAcHhRvSVZwMAeexSMFEUcagqJ44fZ9mKFdy++U4SsRi+oqKs0pCQXeVvbWvD5XSh6QZDkQiK002x24koCmOucAuCwIamMvriPaQMi9c7BrmzueKS7yoYDNLT08OKm1bi91ePOoG3LQsjNoCoOhGdI4OA1tZW+vr6mNeyiF07dxCNRqfF40MQBFwOB6lMVp1rKq4f1lA3oqLi8TeyZo2P8vLyEYaLJ0+cYGhoiI7OTjbfeRdaJnNlOdzrdLn90Ic+xLlz5/j6179OQ0MDX//61/nqV796fXZ+A5A3+bre+7yR+d3f/V2+//3vU1paSktLC7Zt8/rrr/Od73yH3/u93+Pb3/72hLd5Yx+RdzCPPPIIJ0+e5J577uHhhx/m6NGj0z2kdySWaaLpOrKiTGo11jDNgozndCBL2Tvinjf2cuLECSDb8GpaFvIEV6avNcFgkL1vHsTn9fCe++9BtAws05iwlrIgiNjWpS7DwWCQrXffQ3ugm7Pnzk/IcTeP3+8nlUrxxuu7eHbbNsxclsgwTZKZDIlUmlRGQ9MNenp6OHbsGPFYDEV1TCgIsCyLjKYjCuI1a+KWJQmHopBKZybd9yANCwRiXe2cOXWKlatuvsT5WJZEStwq9aVu5lZ4qPQ6MC2b3mia1lCcnkiKWFrnxImT7Nixg2BvEDsTR070w2AnwlAAKz4IigOxvB6ppgWpohHRW3bZIGA4xcXFvLZjB8eOHkGUZVLJBA5VQZFlgr29hEIhTpw4zquvvootyhS5HYjiW8e9vr6e1atXXzKBdykS65vKAGgfStE6mLxk336/H4fDwbPPPM2SZcuob2gY8Xw+CBAUB5LLN+L7zjftqi43x44eYWHLggk7BU8lYi4YyOg6xgSbFi/GTkYgHUMsrWPpsuWXuK4bhkFFZSV79+7l7JkzvPzSixQV+choGsG+vjEchG2uVySgKApf+9rX+PGPf4xhGPzpUSOV/AABAABJREFUn/4psVjsuux7lqnlO9/5DnPmzMHpdHLbbbexd+/eK79pinniiSf40Y9+xA9/+EP6+/sLyl2hUIgf/OAHfP/73+fXv/71hLc7GwjcwEiSxL/927/R2NjIli1baGtrm+4hvWPIrkgaGIaBqqqTLp8xp9A/IBAIjHHjG5vTJ09iGgZt7RfYuXMnp06dyn6mGdQXkMfv92PZsP213fz62RdQVAdGOomeiGJk0tjjbKQSBAFBlC55/Zw5c3A4HRw4cGDSq6nNzc3ZCeEtq7n77rtpampEkWWcqorH6cTtdKDKMuFwmIGhMHUNjQxGYwyGw+iGgTlKgDKcfBZA0w1URUaWr16B53LIkoRDVUhlMpNqVBMcLgSnB4ASyaKzs4PKykoWtLSMeXxlUaTYlQ0Kmis8VPocWLad7Skoraa8ph4tFUMId4OhIXpKESvnYpbUIRZXITp9E5KHzdPc3MyWLVvwuN1IAlRU+dENk+7ubgzDoD8UIpVOc9c992FmUkgT2MecUjeVSnZSvKutn4RmjHg+n1HYuHEjbqeDoqJidCP7GtvOBQGyguQqypbL2DaWYWBoGbwuJ/fdvYWaEi9nTh4nHA6PGpBcT4YHA525sqfW1tYJbcO2TKxwD4K7BGFYBiR/nevv78e2LCoqKti0aRO33normzZtoq6ujoH+ftrb2rGBV1/dMaFr4rXgk5/8ZEE+9KMf/ei0jmWWifPzn/+cL37xi3z961/nzTff5KabbuLee++d1GLR1fCjH/2IL37xi3zqU58acd0XRZHPfOYz/MEf/AGPPvrohLc7Kx/6NqC/v5+1a9cyNDTEq6++OiVa3bOMTUHZRRCQx6HwMRZdXV3IDgd6On3VN+1AIMALL7yAYZqUlpSwadMmKioqsio72UGP/DPH4OAgAjZDXRd4bucePvLRj1JVWTmj+gKGM5qEo22ZmLqGpWcQRAlRyTb4Xu57MQ0D2zKR1axsqmVZpDMaob4g3d3dE270vWTbto18GS+BAwcOsHv3bu6//wF27HiV29auY978eViWhWVlyxokUUTMlRS1t7fR3z/A/Pnz8fq841KWmUoM0ySj6YT6gvRM8Pgknn4UM3gBqXYeQ0u3EAqFmDtvPkVez4TOs52v7aJnMIJz7nJsUcab6GPLrTcVnrdME0PXUcYhvTkebNtmcChMd28vzz/zNDevXs3CpcsRLJMaf9WEtnX27FlC/QOcFsqxZQclksn7Vs4Zc5y2bZPWNELBIG5BR5RkiiqqsW0rG8AKAqIoIYgSnZ2dPPf889RUVXDrqptI2SJz507u3J1q2trbESSJwwcPkkomWbduHQ0XZTtGRRCwwz2QGEKobinIuHZ3d/Piiy9SX1dHeXk5FWMoIx04cIDt27dTUlLC7bffgSiJNM+diyAI2V6cSahqXS1tbW00NzfzW7/1W6xatYr6+no+9rGPXZdxzLT5UH48wd7eaZEP9VdXT+hY3HbbbaxZs4Z//Md/BLL3i4aGBv7rf/2vfOUrX7mWwx1BfX09//Ef/8Gtt9466vNvvPEGH/jAByYc+E7oDPzIRz5SKB8YixMnTsxGvNeZiooKXn75ZWKxGL/3e7/HP/7jP2IYxpXfOMuEsS0LXdMQJemq1HQCgQCHjxzh5PETbNu27apXrILBIM3Nzbzn3e9m48aNqA4HhmFkV3Fz9bJSbsyqouBQVRyqSiadRrBN5tWU8fEPvIdUMjljgwAYvfxCECVkhwvFU4ykOrEMDS0ewUgnsczRfwf5huE8mm4giiJNTU2sW7du0kFAdjzCW9KHY+D3+1EUhVdeeZnNm++kuMiHQ1FwORx4XE6cuSyTZVm5enQX1TU1HDiwn86OjuuerZEliYH+EJKscPz4cV544QXOnz8/rveKxZUAWJF+6uvrWbVqFT6Ph4ymT6isq6K8jKGeTvpOHUIQBBJeP+cHEm/tR5IQJZG+YPCSFejxZsuGv043TGygq7MDQRAp99eQjMcnHATYlkV5kQdTS3NThQuAsClxKhS/7Pu6u7pwuT2IkkxHbz9d3d1IigPF6UZ1upFVB5IsM2fuXLZu3UpldS2S6qS+qvyKn3cy2cOJYlsmomXgEizqaqppmjMHcmVyV3yk4tjxASxfJYadFS7QjexvdMWKFeiGwUsvvzyivGw4fr8fr9dLOBzmlVdepri4mIymY9k2iWSCo0ePXPcswZw5c/B6vTz22GP88R//Mf/pP/0n3njjjes6hlneIhqNjnhkMqO7zmuaxoEDB0b0xoqiyNatW9m9e/f1Gi6QXfS93KJhfX09AwMDE97uhIqA3/ve9/LQQw9RXl7OXXfdxaJFiygqKiIajXLq1ClefvllBgYG+Ou//usJD2SWq6OxsZGvfe1r/PCHP+QLX/gCTz75JD/5yU+ora2d7qG9bbDy6ixTsJoUDAbp6+3l9g3rePPA/qtW98jrcu/fv7+gy11cVJTNCOQelmFgDp94CQKVFRUcO34Cs6qUClXHVK6/qdlUIQgCgqwgykr28+oaRjoJto2kOhAVNSsfmn+tIGBbFqZtY1kWzsu4kU5sHOIVJ7jDm0tdLiclpWUjGhxFMbviCxJvHjjJ66+/jt9fzfKbVuD2+jAME0m6vk3mXYEA6XSKe+66gwNvHso2p46jmVoszurn24kItq4hKGrW7MyS0HQDhzo+xazFixdj2zb9/f04SBDEw/FgDMOyaanwIAgCHZ0BJFGgoqKcZDJJd1cXTqeTvmBwhMb/aL+1QCDAtm3bqKzyU+mvJhKNkEmnudDezrqNm9A1DafPM6FjZpkGRipOMqNz4tRpzBMnmXf7g3SlYF8gTF2Rk6Jhrt7Z0i8T3dBx+Uro7O5h+4vPYds2a9asoWnO3FH3k5fxtG2baH+QSKiXV1/dgc/n4/7776e2ro5cSpCenl5e3bGDYG/viKbtqSB7ndExdQ2wUR1OfvPMswVTPH9V1RVdt23bxhoMgupCKqoccY6bpsnevXsLDs9jlZdd3LxdUV6OZVnEYnEi0Rg7d76GoijXtY9CEAT++Z//me985zuFCeTwfod3IrYgYF/nRY38/i7OTH3961/nz/7szy55fX9/P6ZpXnKu+f1+Tp06dc3GORqapqFc5vcjyzKapk14uxMKBD7ykY/w4Q9/mKeffppf//rX/NM//RNDQ0OUlpaycuVKvva1r/HAAw/M6BXFtzNf/epX+epXv8rjjz/OJz7xCerr61m7di1/+qd/yv333z/dwxuTiWh3TweT9Qe4HH6/n/2aRndPL2tvveWq1T3GUi0Zi7zc6eDgIJlMmoQl0N/eSXNDLbZlTarGeiYhCAKS6kBSHVimiaVn0OJRRElGUh0IkowoyQQ6OykqLWNgYIDmuXOmbgDjWOkeLp9oGGah7v/i8yu/uhkM9pJ4Pc69992HaVloho4syTmFn2t7M7Vti0Ut8+no6OSlV3Zwz52bcLo9V1Zn4a2MAIAVHUAqrwGyWvMZTac3GKQrELjieRsIBEilUoU+jO5omgOBMKdDcQzLYkmVj2AwSHFxMXMaG+ju6eHEyZPMmTsXjy/bYHs5Sc1gMEg8HmfrPffy/LPPsmrVSlavXs173vcBjJwfwXgmjfnytYa6Goo9bhS3l/rGEu68805CoRAVqkbEdBHXTJ49EcAf76SmuprGOXOwLBtZEjERsSyT/Xt2Yds2Xq+X8vIrG5IJgsC5ji7MTJrf+vgnsS0LRVWJJtOF9lhBcXDb+o20njvH0cMHr2oRIv9Za2uqqSwrwzJ1RElBdrgQJYkat48777xzVIO3sbATg6ClEP3zLzm3JnKdu1ieVBRFzp87S3d3N5qmkclkrqu8KsDHP/5xPv7xj/P+97+fJ554Aq/3UgnYWa4PnZ2dI0qDHA7HNI5m/Pzpn/7pmP5RyeSlQgTjYcKyIIIg8OCDD/Lggw9OaoezXHs++MEPsmXLFn7961/z93//9zzwwAN8/vOf56//+q/xeCa2onWtyStelJWVEQgEEASBOXPGrp293gzvB5iIP8CVGH5DWzhvLm5f8ZRsc7w3tbxRjyCKnD59mpraOvadPE/L3EasaB9isX/GfAdXS7ZkxI3kcGGbOqaWwbYSDEViuF0OBvr7eeGF59mwYcOU9NcIgsBEG69kWcLWs5KYijLysjzcwdXv9zOnqQkA25bRDZNUOpMt+5KvjeeDaRiYeoai4lK8RVEWLVlCBhl/cTFGPIzsLkK4TMO7VPKWcpAVCRUCAUEQ6A/1EY3HURwOBgaHcLrd+Lw+BCGXtUEAAUJ9IV55ZTt9fcERq/pyYyn7Ooc4P5DEMG2qqvy0tp6n48IFFi5cSF1tDdWVlex+Yw8APp9vzGtgPuA6evQIt65dS1lJMRndQFId9LSdo7KyctT3DSefVZjbWE9dZRkDpk2trwSAlpYWWlpaACiOpXn6dB8p3aQqOYCuV9DZ0cG85maSmoFl2dRVVbB+/XoGBwcvkcy8HH6/n23btrFz9xuFY+UvLyk8Hxsa4MDeN1i6/Cbazp+d9CJEIBDg2OFDLFwwn3QixpAkUVF16XVjuOnYlbBNHTvci+CrQFBdo75mIte5i6mqqmLfvn2F4Op6y6sCPPnkkzzxxBMA7/hF09xt6LrvE6CoqGhcPQIVFRVIknRJGVreU+R6cvvtt3P69OkrvmaizCx9wFmmjNLSUh5++GE2bNjAN7/5TX7wgx8QiUT40Y9+NKMmeMFg9sa+ZcsWzpw+jUNV0S9KbeXLOMj9Wfh37rlrRdbpVZuUP8B4yN/QLMvESKdQXJ7r8t3kgxtZUaivr+f+++/H4XRx733346isxOzvxFZdCO6rD05mEtnSIRVRVrFti6ELAaqrq3j++edIJBIMDg5O3b64snvxxciyhJaTXLxYSWq0yZQgCKhKNiNgmlk5UUEQcsZiVz/BsG0bQ8uAbaM43Ze49gJYegY9EUFyepDU0VfUBE8JSDKYBmakn+GJ7WAwyI4dO3A4HKiqiiyto2RRcdb9may/BTmlpHW3reE320YaZVV5HaxtKuONjiEuhFPUFZVRV5dh584dBLq6+OAHP0gskaB5bjOrVq4k2NfHuXPnUFWVZDrDQH+IqspKFi9ePCI4r6urIx6PE47FsVIxjp84TiKeuGIpSTAYZMWSRXjcbh7/1VOsW78+W5ZzEdU+J3MHTrK4dRdiIsKuY0cov/VOahua0A2LYk+24XkygemVVs3r6+vZsH4dqts36dIYyzSy5m8+Ly9u30E0FmPz5s1U+q9uYmSHe0GUEIom1ocxXiaaOb0WDA8+Pve5z/FP//RP130Ms4wfVVVZvXo1L730Eu9973uBbLPwSy+9xCOPPHJdx7J9+/Zrst13djj6DmD+/Pl897vf5c/+7M/48Y9/zOuvvz7dQxpB/qLY3dNDcXEx6UwG1eEoPBRVRZLlrOkW2cY70zTRdR1d09AymexD09A1DUPXsyuYpol1BSnGy2GZJpqmTdofYCKIooQkK5ha+pruJ49lmgg5RRrI3hy9Xi91dXUIigOxuBIrEsLWR2+eejsgCCJOj5eu3lChiW88pRcT2f7E/Q0EVEXBMExMc/xSnYIgIMsSLqcDRZbRDYNUOpMz3Jrs+W+gp5PZpnina8yARlQcKN5iLC2FkYyNuj9BFBF9WR19K9I/4jm/34/b7SaVSmGaJsXFxciShCxLKLKMqsioioIogKrIWJZ1yUpuuVtlfVMZqiTQFU3TbXtYtHgJDz30EJFIhMFwhEBokINnL5BUi/E0LaXb9jGgVjDPoeG1koQGB0mk0pSWV7Bw8RJkWcbjdpMc6OXChQ623HP/CO+D1tbWSxqSbdtmwZwGinw+XtrxGoqqXnbFuabYjZDMasrfIkSor64ioxsUe67OzRnG9jQY/ryqqtSNEqRcDtu2MdIpjHSKjGFx7ORporHYlKyu2+k4djKMWFqLIF67a+6Vjs21Zt26dfzLv/wLAP/8z/886d/oLNePL37xi/zgBz/gxz/+MSdPnuRzn/sciUSCT3/609d1HM3NzZNqBr4SsxmBdwhf/OIX+fKXv8wPf/hDNmzYMN3DKZCvGXW5XIiieMlkbPjq/1jkL6T5plhsG9uysPL/HrnBEVkF4aL/CwQCaJpGeXk5RUVF1y17IipqVuXG0BHl8TVPTgbbtjFyvQ4j9i8KWJaNJAkIriIELYU51INU0XjD9wuMRW1NDedbW1m1ahUNDQ1T27gnCJPKeQuCgENVyGgagjDxpnRJEpEkFcvK+Q1MsI/Atm1MPZOtLXe4xvXdC6KE7CnGzCRzpUK+gtxjHrGkEivcd0kgMN4V2vr6euKRITZv3jzq60pcChvmlLPjXB9JQUUuaaQ9bmEKHnTVA1UVqEASEN1gWQbOcBdVxiBWeIiEtxjR7UEUs+pa+/ftY9euXdnPJwjMXbi0MNnNlzPW19WhpdO4HA4qqyowM2lcbg/l/hru3rqVsvIyampqCtegi4//orWb6I90YR3djcM2cZ7aQ/H8hVcdBIwXSRSyxoHjWOgoNAFr6axykcNLtcc3Zavrtm1hDXWB04fgmn55y2vJvn37OHfuXOHfp06dYvHixdM4ounDsnNZv+u8z4ny4Q9/mFAoxNe+9jV6e3tZuXIlzz777HUvLWtvb8e8SpO+0ZgNBN4hyLLMvffey89+9jMeeughHnzwwct2n19PmpubyWgaqqKg6zqWaU7IZXW8ZUIXBwwXP9LpNIl4nFAoxIsvvsgDDzxwXRUlZIcLPZ1AkaSCus1UY+j6qN4HgiBi2RYSWSUasagKc6DzbdcvkMeyLARBYPHixei6TmVFxZXfNAGyEqKTu8HlMwOaruOYZF+KKGYDCtuWMQyTVCaDJIoouezaaFimiaGlkWQFaYJa/IIgIDs9WJKCnogiOd1I6lsKVGJRNsC3IgPYtjXi/B5Pzbdt26gOB6tXrx7zNT6HjHuonSFnJZVlxaRtEQyDdDyCraWpKPZSU1GGUxawTIEzoQxHI7C82MbddRhnZRWCMzsJ9fl8eL1e4vE4Ho8H27Z417seoq6ult27d2OaBretXomBiKkbmOkkgqwgSBLlZaWUl5WATdboLqfWczGZTAaW3Eb61GGcehL7zEHMjrVIcxaN+7hfDaIoYlo28hiX2nwjcE11NZWlxdk+KZd3RHB4NfX6w7GjITB1xMrRVZHeTuQ14BVF4X/+z//JokXX5/ue5ep45JFHrnsp0PVi0oHA7/3e7/Hd7373kv9/5JFHCqYLs8wsfvjDH7Jx40be9773AbBt2zYeeOCBaR7VWwiCgKIoaJqGKk69NOKVAoajx46NqMG73ooSgigiqU6MTBrZMXY5xmTJl0qNVuokisKIchRBFJFKqt+2/QKmYSDJ2cufJElZN+UpLAHLS5NOFlEUUWSFjKbjUCfvV5H9TWUdiE0r20eAAGouIOjq6iIYDDK3qRGvxzPuLMCY41ZUFKkkWyZk6HT2hugNBmnExgdg6tiJKIK3ZELbvTh4OHPmDKFQiKqqKhYsWJB7TbbBttqy0dKDzCktodjrRrecDA6G8Xo9FBe5UXPqIKG+EvoNg7DToCTdj35iB8ryLQgOF0uXLs0aiuUadQ1dJxQKEQ4P4ff7qautpaOzi96+EHduWg+y47IlVCM+i2ViaBky6TRvnjrHok3vg5f/DYDoC49R/qmvIChTI2V7OYYGB0il00jYl6j5BAIBnnnmGRY0z6W2spzBaAx/dc01GYetZ7CjIYRiP4J87T/3TOFv/uZv+PznP/+2W2SZCDajhcjXfp83Ms899xzFxZe/H7/73e+e0DYn7Syc9w+4mLKysiltupssM81Jb6ZgmiaPPvpowe78jTfeGNOl7nqS0TQcuXIVy7KyDqFTqNIzHvKKH3mN6uupMT2cbG22jDSFk4F847M8hgfC+fPnUR1O0qlkYWJ14sQJhEyCef5ilMomBOXGkFe7EvljoQ6Ti9MymSk93yzLwjR0lDEaaMeLYZiYljWqrOhkMS0LXTdIp9O8eeAAcxpq6Q320Thn7pTqyff3dmHpGs+8tB2PnuBeJQSA+57/hFy3YELbs0wDy8w6QZ85c4bt27ejqCr19fWsWHFT7sZoAwKpTIbWc2dxOZ0sXrQo2/AM9PUPYJoGhmmNmPjato159g2sUAeCpwR52eYRE9Ljx4/T1z+IZVucO32KDRs2UFFWimVoFHm9uIvLsMmaXkmShCyNXoZlWxaGlsa2LGTVSUd3D6Lq4qVnt7EsfJ4mI5I9PrduwXv7xG7kl8O2bbBMbNPAtgxs0yQeDZNJpUigIqlOvD4v6rDrTSqdYmign2CgkzcPH2HTpk2XzcZczdisUBtY5qhyoW9Hvv3tb/P5z38egN/85je8613vuub7nGnzofx4Aj3T4yxcXzMxZ+GZwnhKRQVBmHD50IQzAr/+9a+B7ITyN7/5zYj09/nz5ykpKZnoJme5jkiSxGc/+1nKysr40Ic+xG233cY999zDM888M+1SZnmVFVEUEXOrtNezfGkmKEoA2RKhVBxRkqesPt8yzexxHWV7+YnVhnVrcbuc9PcFsx4DoT4isSiimaHeAnft/MJ4jh8/zsDAwIRkDWcKw7MBeSRZZnBggPYLF6bku79w4QJul5NEMnVV3hiXkxWdLJIoIjlUTp08QSqVZMeu1xkYGMThck/ZOS8IAufaO2lvPc89997Lgb1vwFA2EDDD/RMOBGzrLQWmUChETU0NN61cxfFjR+kKBKiqrEDIuda6BAerb7658F7F6SLQ2QGWSSaVYt+bB7Ftu6B+JAgC0vw12ZXpcJD+PU8TKpnHoiVLMQ2D2mo/jQ11vHnoCPF4nMHBQVrmNoJtobiLCr8JURQxDJNMzvTnQnt7trSmpoa6Gj+2aWaN7SQZ07LxlVYQGwqxaGEL5SW3ILz8b9ipBMl9r+BYtBqlanyNvNm+KCs30TfBNAp/t00DLBMEEUGSEEQZJJnQYISDh48QGgqTyWisW7eOdevWFbYZGexn+8svX9G462qxkxHIJBCrmt8RQQDApz/9af7X//pfdHR0cOTIkesSCMzy9qG3t5eqqqlV1ZrwneULX/gCAOl0uhDVQvYi6Pf7+da3vjV1o5vlmvHBD36Qs2fPsmDBAp5//nkkSeKll17irrvumpbxXHwTkCQpqwBkmtdctWc4U1XzejUU+gUySRTn1UuKjtUgnCcUChGLxXj2+RdwqCr33nM35aUlNM+dgw34vF5ULYo+2A2eUoJ9Ifbt3cvA4CBerxfbtqdEf/96YOdchJWLAoGenh50XefVV1+9arfVfDPp3Vu3cL61HUVVqautnbTkbVZW1MAwTOSxCronQUVFBW+88cY1m+z5/X6OHDlCd0+QRctXYu89i5BOYEX7r/zmi7BtK+e0nNWCP3bsGKIosXjJ4qwfRu6Y6oYxqnNtZ6CL119/neY5Taxbsxq3U8UyjOzkWBAQRImzdiklqS4qXKBmeknHG5EUhWgshoXIkcOH8fl8LJ7fjG2ZI4IAeKsMS7IkwuEwsVgcCRsZi75QP7V19blgxSKSzOBzqZT7GpnT2AhA2n4/0af/FWyLgad+QteKrfira6ivr8e2LTDNwop+fnWf3N/BBklGEOXsZ5IURNUFucn/xQsKksvLUCxBOp0Z9bu/HositmVih3sQPGUIjpnlb3Mt+cd//Ec6OjoA+OxnPzvNo5leLDv7uN77nGUkEw4E2traAPit3/otHnvssSkf0CzXj/nz52NZFt/97nd55JFH2LJly7RJmV2suy4IArKioGsaoiC8bZVrxkKUZERRwtQ15KstLxmjQThPVVUVVZWVzGlqYH5zM7KiMBCJ8vLLrxQmiVs3305TkYWtpfC43Tz04P28vP1VOjoDM6IUcLxYlpWVor3oWASDQSLhMBUVFYRCoavqD8k71EqKg1Q6RSaTk/LEHiEkJAggMFzFaqRK1vA/VUUmo+n094fo6uqaksnZtZ7s5Y3QorEYpaUlSCWVWL0JzHBowtuybRvE7PFYsGABtm0TCoUQEKipq8UwTc6eOUNpeQUDob5LslR5s7DW9gv09Q/wwP33ZdWRMlZ2lV5WiCfT2OULKde7caWHSLUfRmm5hdqaGsKRKGtvvZX5cxtBEMloBqFIz6jHTBQFTp8+xcDAAE0Ndfz8l0+wfv166uobMK1sEOB1KqgXBXWOxatRT+xDaz+FONiLN3AKSotIhgLIAiCKuYm+DKKEqLoQcpN/JthTdbFJ3WhZq2u9KGKHewEbofj6m3pNJ48//jgAzz77LBVTLFIwyyyTYdKzq9kg4O2BIAj8/u//fqFkRBAEfud3fodEInHdx3FxEFIIBnT9Ham1LKlOLCOrojRZLMvChlGzKnlJwDn1tbz7wfupqKwintaorK5lwYIWNm3axJo1a7j99tuZt3AxYnEVQjLMwEA/x0+c5PYNG6Zcf/9aM1pZEGQnirZtU1RUdNWr4/lJp6ZpBHt7EQUBVVVwqCpOR/bhUBVURUGWJcTcBNeysiVAmqaT0XTSGY10RiOjaeiGQTwWw0bgzYMH2bZtG4FAYNJjzHOtNdXnzZvHqpUrcbndiMVZZ14r0o9uGBP7TV/ULNzS0sKGDRuYO3cODlVlcGAQWXVw6NBBXnvtNY4dOzbi7fmJ7/r167n77rtpaGwiODDEqXOtxKIRtESUhfObOXGulX/d10rasHDFeqGvDcs0Kfa6WbG4BYfqIJNO09HZednvwO/309XVhdebdS/1+/1Ylk0kmcHtUHCMUuYlCAK+rR/CymU+itsOYQkyQ4KXtKcSobgaubgS2VeG7ClGcnoQFUchqzFR5s2bx7p1666qdG2y2JkkdmIQoaTmEqnZtzvxeByAVCo1zSOZfsZS8LvWjxuVj3/843zve99jw4YNrFmzhq985StTch5d1S9w9+7dbN++nf7+/hEH95vf/OZVD2yW68v27dv54z/+Y3bt2sWjjz7Ko48+SnFxMf/+7//OPffcQzwev7b9H4Iwaje/KIpIslxoHn4nkS8RMjKTcx3OOwgP77MIBAL0h0I01Nfi87gRRBlJdVLs8lBcXjni/UuWLBnxb9FdhK0lmSul0YxKvF4PW+66i/kLJlbvPV3kJUNHO4719fWoikI8kUDNNaFOlvyk0+lyc/fddzNnzpxLXjMZydv+gX46OjpIxOOYpnndVa2uBkWS0XOmYqTiWVMqxUFHext9fX1UVlZeVkbxcvduQRBobT3PwkWLOHfWLtTxX8xwV+S8MMBNN91EX/8gvqIiKstLufeuzQxFIgwmo9TG2rE7j5PSTJTyGpzeYo4dOcqOHTuA7Pk01neQPwcs2+bBBx+guqaWcCKNU5FxqWPfdqWSCqzlGxAP70A0DYZ+9UPKP/wItsfFYCKFJAg4FRmnItN6/twlykk3ArZtZz0DHB4Ed8l0D+e6s2DBAk6fPs3hw4cLTrWzzDIeWlpa+LM/+zO2bt2Ky+XiH/7hH+jr6+OHP/zhVW130hmB73znO2zZsoW9e/fyne98h7a2Nr73ve/R29t7VQOaZXrYtGkTr732GpqmsXLlSgAikUjBb6C0tJTPf/7zpNPXxv02Xxo0GvnV7GthpDHTESUJcRKuwydOnODUyZP09/dDrokyNDBAMpNBkUWOHTtGaDCC4nRNyLNBLKoCQWBRfQWqw0VjXe1EP9K0MVY2IE9FRQWNDQ1TMrmeN28e5RXlNOTqvydLPnARRRGvx0NbayumaV7TBs5rgSJL2J7Swr/VVJS+YC+yw8GZM2d59dVXOXny5KjvDQQCxONxurq6Rn3etm0WLlzIYH8/CxctwufzXTFLFQwGSaVSVPv9PP/CC3R3dyOrTnxlFdQ3NFLbvIB07WJswBU8zf6dr9De0VlwQh7N4fhi5s2bR/O8eZSXlhFJZnAoMm7HlcUPau56L1ZJNiivMeNUxIMUuxxUel34JBtiIVKBU1QRIxEZZPfruzhz5swVtztTsOP9oGcQS+veMQ3CeQ4fPsxTTz0FwIc+9KFpHs30k+8RuN6PG5V//dd/5bvf/S7PPfccTz75JL/5zW/4t3/7N6yrkKqGqwgE/s//+T8888wzPPHEE7hcLp544gl+8Ytf4HC8PSQG36koisLBgwcJBoOcO3eO97znPYXnvv3tb+NyuUZo7U8VwhWcWGVFwTSMqz7hb0QkRcWyLAKdHezevZvW1tYRz9t5J2XTxDIMOtrbCA/2U1pWhmZaDAyFMUyTwYEBXnzuOZ59/kX2v3mI3mBwwmPJ+wvYqTiimc46glozP0DLp4Qvq4w1Snna1SBO8fbyNf2bN2+eNmnbySIIAlLJWxknMxKi48IFME3u2rIFp8uVDVovIq9nH+rvH7UUx7ZtNF3H63EjSiKWaXL33fdcUcnK7/fjcrnY+dpr3HvPPYUJvSAISIqK6vbRNpTmAsUI2KwusYgHA5P6DpKGjSwKuC+TCRhOV08PoXlrChnS+AuPYbQdwm7dh9zxJq6BVlzJASRTY25TI++++w7K3ApmOplVDZrB2IaGHelDKKp828gRj5dYLFZYZPvqV796ScZ1llmuxIULF0Z4P23duhVBEOju7r6q7U46EAgGg9xxxx3ZjYgitm1z//33F+RFZ7mxqaqqYt68eTz55JMYhsGBAwcKF7E777wTQRDGXKGbDKP1CFz8vKIoGO/AfgFBEOgJhhAtE9E2SSdiRAZCaMkYWjKGnoqjZ1KYegbL1Mlk0tTXN7Bv/36efOI/OHHsKE5VxeN2F7IrV7OiLCgOxOIq7Gg/IjZG5tpkiaaSK2UDIHcOTuE+BaY2EIBrX9N/LVGKSrHF7HfQ13qayspKLMviuWef4Y47NlNf33DJe4LBINFolL6+PtavvY2+vr7Cc7Zto+s6siRhWRZz5syluXku/pqaKx73/IR+yZIllJSU4K+qIhAIcODAgUKw4Ssq5pVj7ezqCKNKIi3CAHYqPu7vwLZtoikNSRJxiPa4Vr/zJUsJQYS52YmilUrw6PPH+fdTGmfxY9ctpV2qotUuY9/RUzz21AukDBvb1NGjA+ixAcx0AtsyL/lM040V7smqGxVVXvnFbzM+85nPAFnX6q9//evTPJpZbkQMw8DpdI74PyXXR3k1TLpHoLq6mu7ubmpra5kzZw7bt2+nsrJy2rXoZ5l6JEni5ptvZv/+/XzrW9/im9/8JoFAdnUsHA5f0eVuvFxpyiQM6xeQlcm7rd6I9PT2UllZSduFDlKpNMuWZbhlzZpRj4HbW0RbaytnTp/G6/VSWZm96U6lSky+X4DEIJa7tKDGMxMZSzJ0jBdP2X4FQcCy33kZrLE4c+YMlQ4vjlSYcOd5XPNuwe12s3TpUrRMmvrGpkskUvON13v3H2DJ4kVs2rCe1vPn6entZf6CBZSXlWVLp4Ssao4ASKKAaVnIVyh5G66KMzg4yJnTpzl46FDBTLCgrBMMEnNp+JJ9OffhuxBU52W3bds2sbSGAHidKolYlGPHT1BVVXXZ311eccoua6CrcQXVwQBCIsovwpWkhnT++VgAj6OH5XXFzC1zUFkxlw0rS2iY01zYr21oWFqa9FAfg8FuDh4+hqnr055FslNRSEURK+eMaPx+p7B3797Cn/J4rkXvEN5Zy3pXh23bfOpTnxpReZNOp/nd3/1dPJ63JHj/4z/+Y0LbnfTZ+LnPfY433niD973vfXzxi1/knnvuAeBP/uRPJrvJWWY4kiTxh3/4h/zhH/4h73nPe/j1r39NSUkJv/M7v8PWrVt58MEH8Xq9k9r2eCf1Um71zzTNd9TFtKmpiZMnT9LV3ZNV6qmoGPWYWZZFZUUFkUiENWvWUFlZyeLFiwvPT6UkoFhUhTnQiZiJY4gyqntmaoGPJRl6MVMdWAoCzMYB2VXuYDBIIpHAiKWZI0O5IhA1TaqqqqipqQGyN7l0RsO27YJ52sXBa2hgCFUSkSWRQCBAJBxm7pw5iMOuBYqclVqVhn3nra2thW3kVXLy5WKWZaHrOpU5k554PF5oAs43GNu2jXl6D9ZAJ8bJnVn3YWn0en/btomndSzLptjtoKuri75gkDNnzrBv377LTsjzgc+el56lrnkB0op7CPf1kTrz1udLZEz2tA6yJ1chqBxMsHh/jJsaSripvoTldcV4PcUcPnWOjs5u7r7/IQ7ue2Nam8tty8Ia6kZwFyM4fdMyhukm72K7cOHCaR7JLDcqDz/88CX/94lPfOKqtyvYU5S77uzsZHBwkPe9732X1DBPBzPNUvvtyG/91m/xi1/8ovDvlpYWjhw5Muk+kYym4RiHMpBt2+iahqwoM3YVeirJ10EHOjsvq/tt2zaapqGq6nXLlth6BrO/E8vpQy6emRlBLZNBGecx0TIZ1Cnqc7IsC003cDpuPLWr/OT9ajNHgUCAZ599FlmWWbVqFfF9z7NcimELItZ7/4DioqIR54xt22Q0HVEUUEbxvti1axdvvnmAj370Y/z0pz9lzZo13LL6ZlSHs/DaQCCAIGZlWWuqqwsGb/F4nLq6Ou7YvJnysjJscj0Bokhvby9PPfVUwTdjtMm6bZkYx3dgR0MIJdXIizeO6m+SSGtopkWJ25HzO+invb2dN97Yg67rbN68mdWrV4/r2EciEZ7ZeZB9yTIC2uWzEHlEAeZVeplXKpMMnMSvZHjgvrsp8nrxl5dMSybVCvdgxwcRa1rGDKDerpw7d47PfvazvPLKK3zpS1/i7/7u7677GGbafCg/nvOdPfiu83hi0SjzGmpmzLGYCUzZkmpDQwNVVVVcuHBhqjY5ywznscce4/Dhw+zcuZNHH32UQ4cO8cwzz1yVJNpwU7GxEAQBRVWv+6R3usivaA+XP7yYQr30ZYzDrgWFfoFIEFN1IXpm1oX1cpKh15or9b3MVPINunPnzmX//v1XVVLS3x/ijk2bMAyDc+fPs3TBUmjdg2BbKFqKjO7COew3LAgCDlVB03U0XUe9qASwqqoKVXWQTKVZsnQp9XV1I7I9+Rr7VTffTGPTHMLhMG6PhzvuuANZURgaHGRocJBqv3/Eduvq6q5YNieIEvLiDRhHX8EO92Ke24e04NYR20lmdDTDpMjtQDcMLMvGskwOHTqIruvj6s0ZnrXLugrbrOsPUhdt58yAwbG0l0N6BW0peVQFFMuGs31xzvYBZLMtO7e1s6KhlMXVUW5tLqep/Oody8eLraWxY/0IJbXvuCAgmUwWpF03b97Mn//5n0/ziGaZ5VLeObUVs1wTbrrpJm666SZ++7d/G7fbzbe+9S3WrVs3qX6RidyWBCG7Yqhr2rhXe29UDNNEVS5/AzVNM7u6OQEp0KlCdBdhZZLYsX52Hz5GRWXljNE1H0+T8MWMJxgd97ZuwArYfJ36okWLcLlcky4psS2LeXPn8vyLL9LR0cmDD9yPVzCgdQ8AUmIIuaySZCaDS3UUjNWyTsoKumGQ0XQc6lvBQN5V2NB1Vq++hSKvG2mYIVUwGETXdfx+P0NDg9imidPp5NVXX8Xr87FixQqcTueo3+94yuYEWUVecjv60ZewQhdAdSHPWQFAStNJ6wZeh1wIyhVZpKam5qp6c5YtWwYsY8/ru6gO72FjRRgIEHVX8S/tAmL1QrozKse7o2jG6LVovTGd3hN9PH+iD14+T5lHZU6RwOZqg4V15bl9TD0FzwDVheAtuyb7mMl89KMfBWDjxo288sor0zyaWWYZndlAYJYpweVycf/99/PMM89QXV1NZWVlVpt7IpOw3ArqeCdhoiQh2jamYSBfYaJ8ozKeFW0rJx06nYZrbaEo9R6BhTWlvHmuDZfDQW1tbS66y40/93e4fD3+VJWljEsy9CIKMrZTEAjcqMFpXis/Ho8jCMKohmhXwrIsdC2Dx1fEbbetZc6cubg9XopLfGTyL4oNFMp/UpkMA6E+urq6CqVvqqKg6wbpjIbT8Vaw39LSgmVZJJJJwuEwfaH+glyo3+9HURT2793LokWLqamvo6ykJNv029eHv6oKTdPYtWvXpI24BIcLZcnt6Edfxuo6RWAwTL9cRk1DIz6XioCA46LFianozamqruGFox4GMjFuK7EpSvbx2QqJ9lI/vpom5n94Jad7YxzuDHO4M8yRQIRYxhh1W4MJDcMQ6UhJeNr72NzzJh+7fQVex9ROCezEEGhJRP/8G/b3MFlCoVBBRfGRRx6Z5tHMTKbD6fdGzNJeayb8q//Wt7415nOGMfpFZ5Z3Br/61a946aWXuP/++wmFQvzJn/wJf/u3fzvu909GvlGSJHRdxzLNCRlj3SgYhnHZYCpfEjTdJVJ9oRChPpNb5lbjL/aQyaSz/gJ2bk3ctgE7J8oz2rcsIAiQTKUID/QTDQ8RHhpEliT81dWT+myTyQbkHa6n8khOZYbhepBv0FUdDrxeL0VFRQWlrvFgmSa6rqGqDgRRHDEJtm2bjLsIklH6Wk8Tl8tzQaKEr8jH+dY2zpw7jy2INDQ0Zr8PQSSaTOfKhLJnT3tbO5VVfs6cPcexY8ewbZtly5YVxj40NITP58W2bE6ePEUo1EdVVRXhcBhBFDl58mThfS0tLRM+RoK7CHnxRrSjr1CZ6qWoroJoXzuDCNQ1NIIpZaVSRQkkaUyVnBMnTtDf339JU/9oZFWM7mYoHCHuAvfxl/CKJovDJ/nFufbsMViyhGV1xXx8bROWbdMWSnA4kA0MDgcihGKFMAy/T2HAEokh85u2DM917Gf93HLuW+xnSbXvqs9Z2zSwI70I3nIE1XVV27rRsG2bqlzzOWTFHmaZZaYy4UDgiSeeuOzzt99++6QHM8uNjaIo3HfffViWxapVq/i7v/s7vvKVr1BaWnrlN5ObfE0wWs/7C2iahjoOZZgbibx52uVWtI1p6AsYjaqqKgRJ5tU3D7Jp1RJ6MwKyOr6m27dWaGwunDnLm2++idPhoKysHNs00NMpwEYQRARx2EMY+/uekGToMKa6rl+Y0pDi+lFfX09G0wolaYZhXDEohWzwZRrGiObd4XR1daGW1qKW+pGrWnBVveUdoAPr732o8O9AODHyzam3FprU0irCaZ2aBUu50NXD4OBg4blIJMLrr7+O1+tl7dq1+IqLOHfuLP7qavx+P5Zts/Xue3jzwH5CodCEAgHTMtEyGpphotsO7PpVCMkwJWYCr5L9vHbv2UveZwsC5AOD3CMaT2CFehnoHeDsmTPYtn1Fk6k5c+fijaWJDvXTWbqEedFznCtuIdrbcYkhmygIzKvyMq/Ky/tvrqezs5Pz3f2E8XKwM0JrTx84SsiHvZpps/1cP9vP9VNf4uKeRVXc1VJJsXNy2VY73AOCgFB84zhgTxX79+8Hsp4BZ86cobq6eppHNDOxco/rvc9ZRjLhQGC2zm2WKyEIAp/+9Kf5gz/4A+68804OHTo07vdNZhKWDwbebv0CxhUkUk3DgGnqC7iYefPmMxgewl3mJ2VJ1PsUbMsaVVXlYt76vgTKysrJaDoDg0NEYnGWLFuG6nJnz4vc5N62sg7Kdk6b860AQcoGTYIwbsnQS8YCU+4lcKNlBPLkxy6KInLOv+NywYBhZDNzisMx6ucNBALs3r2bu9euwaNHCWdkytL9DCZSnGy9wOBQmOa5czANg/r6BhqbGvOFZAiAaVtomoZTVTl16hRHjx5lzaY7WXvnPdhaih07d1JVWYkoCGy58058xcUcPHiQ1bes4Y477uDgoUMk4nH27duHpmmsXbeeec3Nl/XAMAwDTdPQTBPdAtMWkAUbVRTwOmTaRR9JxcGPf/ULSop8bFy3jpYF88AywDTByj+MrOtv/mEaiKZOc00F5S034RRtjGQcMxVDVF0I0qXH2LZthhIZnIqEf04jhxJJnilaiCE78RRFC34hoxEIBNj3xh5uu2UVbxw4xH9eu5Zw2El7cJBzmodDAxYDybcCrUA4xQ/3XOAneztYN6eMexf7WV5bhDjO89hOx7GTYcTyRgRx+q9P15vnn38eyLoJu93uaR7NLLNcnimTD51pzDS5rHcamqYVZERN0xxXnXbeH0CZZL2/YRg5DfIbv18gLxk6lpyqZVkYuj5jAh9NNxCErIa7bVmYA50IsgOxxD/h8U2kRyBbY2phW8MetoVt2YiyhChKhSBhPOMwTRPbtqfMoyKj6ciSOCOCtYmiGwbisEAz36Qr5oz98ti2jWlkHb9lZezz8cCBA7S1tvLALQsZGBzkse0HaJnbxB23rgTToD04QMqWWLxwIb7i4lHLaSzLIq1pOBSVkydPUFFeRiytI3qKKZYsHIpMKp2mo7OTrkCAivJyblq5El03eOyxn7NhwwZUVSUUChXc0zU9/znFbLOxYeD2+rAlGTs/8ZdEFEVCVdTCtSytm1wYSmBE+hnoCVBeXl7oVRgPHZ0BYvE4Z1vbWXHLWtT0ENUlXmwtDZKMqDoRVBeCkvUiyFgCLo+HmrJiBEHgcHeEI70xFDPDCo/GkiVjlxYdOHAAlyzw5pFjBPtCl0iYmpbNgY5Bnjvexf7uxKhqRDVFDu5e5GdrSyWl7rH7kU4cP0aD08ASJYrmLJsR16frzXCfm5/+9Kd8/OMfn9bxzLT5UH48py90T4t86MKm2hlzLGYCs83Cs1wTVFXlXe96F0899RTJZHJ8RmOT6BEYjpxTETJN84aceA3HMM0xnVHzE7KZ5K5smiaOnF6+IIpIJdWYA53YKReCe2LO0xNprMw2UufKLXLkgyQpF5RYhoFlaZCr/hfzgUGhxOitY9jd1YVpmli2PapXw0SJRiMMDg7icbun1dV1MlzcsyMIAnLezt4w6OntJRgM0jx3Dj6f77JBAGQbedvOn0O1dSRvKWvWrKG8vJxAVMNMJ2iuq84qBMkCeiaD6ry0rry9vZ2BgUHmL1jAosWLEWybWGsrgyf3IZeXki6twef1sXjRYirKKygtK6O/fwCP18PmzZsJBoOUl5ezYcOG7HliGOiGjm5Y6DaIbh/EY3QHOqmqrMTv94+5iDGQzKBIIi3z5yIsmNi5YhgmFZWVJOIxynxubD2NUFSF4HMjCTa2lsHWUpixgWzPRWQIq8jPc795kru3bqW2ro5zA0kAVjb5WVR1+eur3+/HKdr0hfpHlTCVRIFb55Rz65xyQpEYLx4L8GJbjL6kWXhNTzTDT/Z28G/7Orm1qZRF7jRlZoTKimwAZFkWHa1n8ZFGEWV+ufMAK5PihIKjtwuSJLF8+XKOHj3KokWLpns4s8xyWWYDgVmuGbfddhtPPfUUgUBgXBdDgavv6JdzJUKiIIyrLGUmkq9vH6s5Mz/JnSnmXVbuOxteNiAoDsSiKqxIH4LiRFCmxqRrPORVpERRBEkC3jqO+eyBZVlYhp4t1yBbXhSORDh/7hzllZWcOXMGWVGyykf2WzKg+Wbnt07Tt/5uZ1+YfyWappHOaOx9Yy/JZOKq9PinAyFXYnXx/ymKQiQS4fixo9TV1nHw0CFaWhZe8bPV19ezee1qBDOK6C7m9ttvGvG8bdvY6QRmYgjBjhKOSJwP9OL3+6mtraW7u4cLHR0M9Ic4duwo73nv+/B5vVRWVlChmMQ1g/DQEKFQiAULWnIqWjYI0Hmhg+b58/H5fAyGwwQHhkBSEAQbRQBVlujv6sThdPHLxx/Htm02b95ccD2+mIxhEs8YVPtG74W4HKZpkdF1XE4HixcvZvHixdi2TTCaIhRL4y9yIjpc4HAh2jbHjx6m9cxpuvp3k0wkCAaD4CsnqZtIAjSXXbn0pLbaTzwyxB133HHFTFtlsY+PrF/EB1dFOdQW5IULafZ1JzFyaQLTttndPsgbWHyuIYFPLCbV14EkitQUu7FsN6/tP0xvaICBgYEJHZu3E7/zO7/DF77wBT73uc+xd+/e6R7OLLOMycyYSczytiRvpf7JT35yXK+fitXt4auWN2rVm2maSGPUt5tmduI6kzIepjF6BkZ0FyG4vJhDPdjW9WnRupJkqCCIiJKMrKgoDieqy4PidCOrDkKhfgQBEokkNbW1GIaRDRhsqyB0JAggCiKSJCJLIrIkoygyqiLjUFScDhWXQ8XlcHD+7Fke+38/o68vq8sfDAavyzGYKsbq2REEgba2Nm5etYqu7m4OHjw07s9W5lKwBImuvgECgcAl2xVdXuTyeqI6OKwMi2tLkS2dSCSCpmkk4gnu2nwntm1z5vQpDNPEsGw8TgVfSTkej4eamloymTSiKHDk8GHisRiGaSJJ2dIap9NFdLCfcq+TqmIfpUU+3C4n/upadr22C9u2r2j8NZDIoIgCRRNspM2XNrkc6sjAWRCo9DkxLIuhpDbi/0vKKugZCJNMJArjOtufbaRuKnWjyuMouzQNPL4iVq9ePa5gVBAEFHcxtyyex5c31vL9e6t4eGUltUVvuRvf6k2yscxEFASCg1EEXzlxycu5YJi2rh68Xi8VFRUTOTxvGzKZDF/4whcAaGxsnObRzFwse3oes4xkNiMwyzXj/e9/P5BVCrme5GuY8zX0NxK2bWNa1qgGYrZlYRrGjPtMhmmO2csgFlVhDnRiRfom1S8wUUzTnLBkaFa+UsDpdnPqzFni8Ther5dqv/+KRm6Xw+/34/V6C9u7kqPsTGOsDJ1tWcxvnsvre/ZQV1dH+4UL4/pstm1jxIeI6TZvvvkmlmWNmiURBIH2nhA7d+xgectcblm2ECHej1OS6OoKMBReyJ2b7yCZSnPu7BkcqoNiH1iiRGVlJQODgwwOJHC5nLhcLlKpFEuWLkEABkNBXnrpJTZu3Fio4TZNE90wKPJ5uf32TVfsT8kYJrFJZAMs2yaVyTY7jxaoSqJIpc9JMJJCkUR8uSAjL4maH1dpVTVdx3oBWFDhueJ+W1tbKXapxDMGTRP0hBBECamognKXj/d6Bnj3XJWTSQe/eu0I9xonMbpsth3q4t777sNCIpVMUOX3s2LFCnw+3xVVkN6OaJqG0/lWwPTDH/5wGkczyyxXZjYjMMs1QxRFKioq6O7uZsmSJSMk/q41kiSBIGSVdW4gxlK7yfsFzKS+AHhroph3hb2YfL+AnYljp6LXfCzWOBvTRyOr076V9evXc/fdd191j0B+Ard58+YbriwIRs/QWZaFljMKW7p0GSWlpbz3Pe8Z32fTU0hYHDx1ni133UlJcfGYmQS/34/L7ebQqfM8/sIuDEml0iXx0Qe3Uuxx4nK7KS7y4fF6eWPvHhLJJEf37SYWjVJRXoHb7aasrIwlS5awaNEiDF1Hy/1+Nm7ciMvlYvfu3XR3d6MbZsEArL6+ntLSUjo7O2ltbR11bAMJDXmC2YBAIEBoYIBYNIIkjX1+OmSJcq+DwUSGtP5WfX59fX1hNf/8QBIbKHbKVHouvyjQ2trKzp07ME2D555/nvPnz497zMMRFQdSaQ2yt5Ql7gxfmhNjkRQGUeL9H/gANTW1hEJ9bNu2jZ6eHg4dOvSObcT86U9/Wvi7ZVnv2OMwHvIZ3Ov9mGUks4HALNcMQRB44403ADh58iTPPffcuN43VT9UWZazjZ/XqSxlKhirSdgwjKyT8gzpC8hjjKMx+61+gRC2nrnsa6+GyUqGDmfevHmsW7duShqFYeQE7kbHMk10LYOqOhBzRmF1dXWUlpaO6zdrJ6PYQEcozLann2HlTTcxp6lx1PcOD6Luve8+ymqbkCvqiaYy+AQdIT6ApWUoKy1l8ZKlZCQXty1vIZPKTpJLiotIJJL0BYNZ6VHTZMerr6KqKi6XixdeeIFUOk0sFqenuwub7Ip9W1s727dv5/XXX+eFF164ZOKsGSaxjE65Z3SJ1NEIBAJ0BQK8uf8Av3ryyUtKoi7G41AociqEYmkMc+S1y7Jtzg1ky4IWVHiuOIZkMsntm+8k0Bvi3q134XO7MHQNK6eOlR/fgQMHrjiubOmWD7m8rvB/siThcjhQcopL8XicgYEBmpqabrhSuKniL//yLwF44IEHZtSizSyzjMVsadAs15Tm5mZeeukltmzZwsc+9jFWrFhxWRWJvFLJVFw+BUFAUVV0TaMvFBq3JOV0YVpWtsn5opvHVEtaTiWGYeJQr7wyKrqLsLUk5lAPUkXjNWnknollU28Hss3rJqauX2IUJggCoiRhjaMky05FEZxe7rn3PoLBIB6fj+LiYnQtg6JeOrG+WD1KECVSKPSbCrFonLk1biwtRnV5GWc6OrllbiVlTgFREEim03h9Poa0DKfPnMHr89KyYAGyKOB1O7n/nq2kdBPTsnG43KQz2bp8p9vN2nXrqa/xk0qlMEwT0zA439pKKBSiomk+stM9oWzA4MAA1ZVlvLZrFwDBYPCK16ASt4pmWtnm4WJXoZ+gJ5omoZmIAjSXXVoWlJfera6poay8HH9NDU8/9RT9/Vm1oHvvvYdyQcjKvVom6XSG82fP0N5+gWOiyJYtW0aMbTQpX0GUSGY0HAAC2JFeYikvhmHg8/k4fOgQD7373ciSxIEDB2b0NfdakG+Qfvrpp6d5JLPMMj5m3sxilrcdd911F48//jgf/OAHWbZsGXv37mXNmjWjvrZg6DRFKymCIDAUDhMOh9m+fTter3fGlmnk1W6GY9s2hmGgzhC/gOHYdlZLZ7xZimvZL2BZVk5KdGYdoxudWDRKOBymvKyUktKyUY+vJElZpS5pbK8G2zIhHUcoraW+pHrE7880DbRMGiWXabgc0WiUgYEB0uk0slenptRBlQvKFjeDKONKDRJLxgua6bphUl1ZjtPpxLLhQkcHvqJitm/fXujduPvuu3FXZ3scervj7NzxKvF4nJb589mwYQOpZIIafxWCJGHKDox4BLHCN+5j2FBXy76c0+x4e0UEQaDS66QnkmQwnqHcmw2UhjcJOy5qEg4EAjz99NM0z5tHeWUVkaEhqqur2bhxI319ffj9fubMmQuAJGevM6fOniORSDCvuZmyslJcqoKWyu5D0zRsQ+fM6dPs37+/cN20bRsp9z0PROJo4SRNVQ5KPC6aGhspLStDEkUs22bHjh243e4Ze829FuzevZtly5YB2e9xVq9+bGadhWcGM6vOYJa3LR/4wAf42c9+BsCtt95KOp0e9XWTdRe+HIFAgEQySVFR0YxVb8mXLw1XErFtO+uWPMP6AvJky5jGfwm5lv0CpmFMuEl4lsvT2trKyVOnMDSNXzz+yzFr5gVBQJLly/fj5L5vwXXphEiSZBTVga5lMM3L9/T4fD6OHj2K1+vFFkSCsQzdMQNN05G0OABuCQTLpMjrxeVy0jcYJmPa9A8Ocb61jXg8PmYvyPA+kaXLl1NWUcHho8d47vkXkL0lZNIp+rs7rnToCti2jcftZMmy5RPuFRFFgaoiF0ndIJrWSWomgUj2ujlak3AwGGTR4iXIsswTv3y8INJwuXK3srJyOru6eWP/fna+vpuUpqO6PKguD6fPtfLkb55i/dpbC9dN27bJaFpBdjeVySArMqbs5OSZsyyc30ytv5JEPE5HRwd+v3/GXnOvFUuXLuXRRx8t/Pvd7373NI5mllmuzOydc5brxkMPPVT4++LFizl58uQIdQW4NoGA3+9H13VisdiMVW8xhjlR5jFnaF9AHsM0cUxQVeda+AtcSTJ0lskRDAY5dfIkRbfdRiwWo6+vj3nz5o36WlEU0XPO3qMFrXYqCpIC6qUmYfn3qw4nupbBtix6g32jlvLFYjEqKyupqKwkFovRUF+PlslwobeX5lIVpyRCKoKZSSE6vRT7vBQVF/H6rtepq6tDEITCNsf6LPPmzRvxXFVVFdU1NWSQ6Tx3hIVN41/ZNnUNUVYnZJI3HEUSqfQ66YulOd/Tj42MQzCpGqVJuLq6Gs0w+Y/HfzHu69zFikTDx+j3+1FVlWBfiIfe9SBD4ShD4TAlxcWgqhi5fTr9Vew6cIjzbe0EQ/3cvXULDXXVNDXUcc7nIxaLzchr7rXkM5/5DM899xyPPfYYr7766nQPZ8Zik/dmub77nGUks3fOWa4bHo+HZDLJJz7xCdrb2/na17526Yuu0l14NGpqavAVFXHHHXfMyBT1aBNZK+duO5P8AoaTHfP4y4KGM9X+ApORDJ3lyvj9fqyclG15efllJ3N5/w5D1y95zrZt7GQUwVV02cxWtqfHQSQSIRIe4rXXXmPbtm0jmlj9fj/BYJBfPv44u19/nWg0yokTJ6itKsMlWujuCjKOYlRZRMlEsuVIhs6mjRuoqa6moaGBSCQyoeOwYMECHCUV2KZBS1M9CxYsGNf7bNvGMjQk5er6VlyqjBbqxIqEAIh3nOH48eOXvK6yqgqPyzXhzMNYDe35IKGouASnqlJRUcHT27Zx4sQJopEwAJIsc+jkGc6fb+Oee+5h8eLFpDMar762m2BfP6XFPj74vvdQO4Yx29uZX/ziF0A2Az7LLDMZwX6bailFo9FCnehsfd7MwrIs/H4/oihekjK2LAvDNK9Kv/1iMpqGOkPLawB0Xc96H+Qm/baddaWdiX0BefKrv5P9nmzLwhzoRJAdV9UvUCifmsHH6kbm/PnzZDKZKwYCecJDQwS6uigpKSlMLG0thdV1ErFqLoKn9IrbOHDgAG1tbSxevITnn3+O22+/ndWrVxeeH97A6nK7kUQJd7o/20/jqyaZTOB0OMDQUM0MWAaW4sJWnGx75jkGw2E2bNhQqOO+EumMxoVImkqvgzL3+DJYgUCAVCJOZUU5JeWV43rPWJiDPYSf+RGSZXJi2fvxVFRjZxLMqavGq8rIkoht26TSGVzO8asZjZcdO3Zwy6qV9PQPousasiRTdOx53PE+MmUNDM1bz4E3D+J0uUin06y86SZUh4NINIrT4UBVFOpr/QgIdPUG6eruoaqqatwB1Y1K/nvIZDKo0yxiMNPmQ/nxHG3rwue7vuOJxaIsn1s3Y47FTGA2IzDLdUcURX7/93+fvr4+jhw5MuI5QRCmNFc405tIbdvGGpYNyPsFKLI8Y8cMY8ucjpep6heYCsnQtxvjlYMcD/PmzWPx4sWUlJRcsWQvEAjw1LZtxKLRESv5djL3/TrH12Dr9/sZGBigrb2NLVu3XhKA5FewtUwGURRJDoUQjTSmw8eBfXvp6Q1i2TYD8RRJ2UNbKIKWjGGEg9y1/ha23nUng4ODo66qX8zx48fpGYoi2DYlrvFN5gKBANu2bUMS4ennnr+q78HoOkfy2R+hmhqCZWIc34lDT+Lx+uiNpjnXH6dtIE5fLI1uT91voLW1ld27d3P8+HHm5XoLnvyPX7Jr506wbZyubEmnJCu0d3Ry++2buOP221m2fDkvvfwy58+f56UXX2T37t24vV5sSSUST2CbBhWlxRw9cpgzZ85M2XhnImvXrgXgJz/5yTSPZOZi5e5/1/sxy0hmA4FZpoWbbroJyCosXMxU/kyvdsJ6rTFzOvz5iaxpmog5ScaZylTV5E+Fv8Bsk3CWvJnaQH8/iXgcTdd5/vmrm4TmEQQBURSv6McRDAYJBoOUlpaOaBC1UxFweBGk8X1P+ZKUmupqamtrqfL7OXXqFDt37uTUqVMYhkE6naa8vJxUPIaXFAlDIJ7S2PfmQXbv3o1pmvSHQuzYuZO+oSgZtQhd8eB1KDQUqZR6VIJdnXS0nsPMpEZ9dLadp6+nmzQKPYGOcQUO+ePg83oYGgrT09M76UZZ7eybpF7+NzA0kGT6562HxiWYqSjNlT4afTJ+r4KeThJOavTEMpwLxemOpIimdUxrclfS1tZWDN1g0cKFNDY04HQ6sGybNWvWcNttt5HJpDH1bFO3ICvZcqtoDE3LUFtTgyRJ1NbWsn79eu64446CQ3doYBBvcSlOt5eN69dRVVaCoWtvW4Onv//7vwfg937v96Z5JLPMcnlm76CzTAvbtm0DoLy8fMT/T+XK7kxvIrVtGzNXgw3Z1W3LNGe8Fr5pWlMWXF2Nv8BMz/ZMJa2trYVymObm5py2vzXCGEoQRUL9/bzwwgtUVFRwx+bNJBKJKdm/JMsYun7ZnhW/34/X6wXeksnMyoYmEEonViOeb661bZu+vhC9wSCCbeOvqiKZSODxejl//jxatJ/K+goCCQtTT7FmzRoqKytJplKUl5VRWlJCKpViaGgI1eFg0DRxSzbVNbV4PF4s0yAWCeP1eS8Zg2XouJ0Kom1SWtOIaRp0R1KUulVcyuWPQ1mRl52v756UOIFt22iHX0E7sgMAwenGdefHmFdZz/D2ZpdLIhHqQ9USWEKK4ydPs3DZCtKil2g626vhViSMdIJwqJfK8jJ0TRtxHo2GoqocPnyE1tbzLFu2jJIiH5V+PydPnmTjxo1Eo1Hqc8s1iVSK6ppauru6+Nn/+zn/+Xd+m/vuu5eOjk4qK7MlUQcPHqSpqYmKigrCQ0M899xzFBUVsXXLFly6hqllQJJBELPiCLnAE6b2fnC9yd/b9FH6ZmbJYnP9m3ffnmHn1TEzZ0izvO3JOw7v2LHjmu1jpmcDLMtCypW1FEqCboBa9/G4CU8EsagKBAErEpzQ6uA7JRvQ1tbGgQMHiMViZNJpwuEwuq5n9dxlGUVVUR0OFEXB6/Wiqird3d1sf+UVqqqq0HKvvRrEXBP/5baTX8kvLy9/q1k1FQPsUWVDx4MgCFy40M7CRYtomjOHJ558ksNHjiBJErFolAXVZSQsidLySvpC/bS0tFBWWkpbWzuJZIp9+/czODSEZds8//zzZNJpnnr+ZXbu2Y+guth78DA/f+LX9A5EkF2+EY+4ZnLo+GmOvfYSVaqBaOn0JzTOhuKcCcXoj2cwRsmS1NZUU15RztJlyycsTmCbBuldT7wVBPjKcN//O0iVl25DEATOnW/l+RdepPXcOSpLi/HKUOtTqS9yUOaSMQyDjKDirp5DxFJpDw5xtq2Do0ePsWfPnksyRoZh4HQ46evLZjF8Ph9z5jThcrnZuHEjr732GslUirykQ6h/gJ/9+79RXVPDmjW3YtrgUFRaWhbgcDrRcpPgZ555hmgkQnlFBatWrWLdunXU1tVxIdDNsZOnSUSjCKYOtoVlWeiGgabrZDQNXdcxcg7x+fMvX7o0lqTtdGNZFu973/uA2YzALDOfGXEXveeee+jt7UUURXw+H9/61rdYtWoVZ8+e5eGHH6a/v5/i4mL+7//9v5d1pZ3lxkHTsk6eg4ODoz4/lgzheMmvmF5s0DVTsG270BSdDwLkGd4XAPmeBmuE38HVku8XMAc6s+6z7uJxjWMmZ3smQ75fxLas7J+5SY/T6eSWW27h8OHDvLJ9e2EiNRoXy0GWlpZimiaapiHLMqdOnWJgYICKigqWLFkyofHJkoRhmiiXCb7qc3KeqiPbVHsl2dDLYds2pmkyf8ECDh48iCCI6LpeWGlurilHlXRSoptMOkNZWRl79uyhpaWFEydO0NQ0h0WLF+Nxu1mwYAGqqtLX18eGDRsYHBzkN09tY+vWu3nllZdHdftdunQptm0zODiIauksqvQiONwMJXWGUhrd0TQ90TRFToVSt4LPIXPixAkqS4uJJpIjGpxH42LXXltLk9r+c8zeNgDEygbcd34Uwekecxt+v58jR45w+PAhvF4vVVWVOB3VAHicNr3t5zlx8gQ1DU346xqpndNMbfMCsC1S8Sin2jqxEEgnE8TjCebMnUNFRTlbt24lHo+zZ88e5s1p5Oz5cxQXFaFpGrfccgv29tMApNIZRNFHe1srS5ctI5lM4ikqorOzE1EQ6OjoIJ1K0dvbi6ZpRCIRSkpK6OvrQ9M0XnvtNeLxOPu9Xu7eupWGuhpsy0JSHZw6c5aBgQGqq6tpnjcPwzCwbJtMJoMgCPT09HDkyBG2bt06phTsdHHo0CFOnjwJwFe/+tVpHs3MxbKzj+u9z1lGMiMCgccee4ySkhIAnnjiCT71qU9x+PBh/st/+S989rOf5VOf+hSPP/44n/rUp9i3b9/0DnaWKSHfKPYXf/EXlzw3FVPMmd5Eatk2Yq6sxTCMrCnTDM5e5An29ZHJZJBEcUplWCfqL2BOcVbiepGf3OdXN4dP+AWyQZEoCMi5c1cQBFKpFJZpcv78+XGVmlysWS/lvCj6QiF0w+DQoUM4HA5s257Qwoooihiahn0ZB+GLP6udjFxRNvRiAoEA/f39zJk7F4/HQ2lJCXW1tRSXllJbU82iRYuwLZMy1SItuDBNeH3PGyyYP5/z58/j9/u58847CYVCVPurKSsvA0b6AwQCAU6ePMmJE8dZu24d/qqqUceSVxayLAs9GSPU3Ul7R4DKqirmNc1lKKkRTulE0jpYJoMJHVEIs2PnLtIZbUxlonxDsWmaeDwetm64jZITL2OF+wCQm5bg3PA+BFm5JGAYTt4ALe8cPLzcRxAEyspKiYTDdAUCzJvXy7z58+kJhkjqJnVNzdQtWEJSEDBdKkWeEl7Z8RrLFi9kYUtLoX/L4/EwNDiEJIrZYCoYpDr3dS5YuIjFq7Zy8tQp0pkMLnfW6Gznzp0sXrQIp9PJksWLqa2rIx6PE4lEKC4qYk5TE16vl3c9+CAuVzZIVBQF0xYAESOVpL7GX3CrDofD+Hw+RFEkFAqh6zoer5e2trbL+ltMFwsXLiz8/Qc/+MHoUtmzzDJDmBGBQD4IAIhEIgiCQF9fH/v37+f5558Hss60jzzyCOfOnWP+/PnTNNJZpgqHw0Emk2Hu3LmXPJcvlbmaSfxUS5BONYZhoCrKDdMXANnJS08wSCKeoCvQyR133DGlwUC2XyB1xX6BfGPsdB+zy03QbNvOltJMYMI/Fs3NzYSHhli/fv1la7svhyAInD51it5gkHc/9BBd3d3EYrEJb0OUpGxJ23iCMD0Npo7gHn9ZUCAQYP/+/TQ2NfHySy9x6623Ul9fz6JFi0ilM1TnJux2fDArX+srRxsMMzQ4SCQaZfXq1YVj1NLSksu2GeiGMSKTMTxzMn/efHyj9AgMRxRFgv2DlJYUcb61jWQqha+oiLLiEopVgZhmEsuAv74JQRRoWb6KoXB4zO0Fg0FUReG2DRsQk2F8B36Dlcn2cwgtt2LfdBcZ0yYRHeRCRwf9fX20tbWydu26S841h8OBqqqjSlRenCHyeDzomsb+/fs5f/wwxaWlrFi1Bg2Rytp6lq69o9ALUVHbQO1AP5KsMG/+PATg/vsfQDd0qGpC8BQhV9RlDcOq/GRSSdwuJ1omw8c+9nF6e7rZvn07dbW1CEB9QwMOh4NAIEBHZycdHR1EIpGC0eNdd93FggULsCyLPbsP0jS3mePHj3OhvZ01a9Zw++23A6AqCrqucyznMD3TzMpM0+SLX/wiAB/96Ed55JFHpnlEs8xyeWZEIADwyU9+kldeeQWAp59+ms7OTmpqagpuq4Ig0NjYSEdHx6iBQCaTIZN5S3kkGp28JOEs1x5ZlslkMvzkJz/h4YcfHvnkVboLz/Qm0vz4AAxdR5nBHgfDCQaD7N+7l7lzm1m2YgVOl5t0RkOSRCRRnJIyHbG4ErO/EysSRCypHvW4zIRsT35FN5FI4K+uZuvWrZSVlWUn/rnXCIJQyPrIkpQNACYxZtu2cbvdY5YDjZeKigpOnjzJztde487Nm7M13JkMkiyPejxHC3RkSUK7QtNwYdyp8cuG5vdVWVXF3OZmdrz6Kpqm0dTUVNi3lCtNkgWwYv3YzmIEWaaxqamwKr5o0SKKi98qLRMEAUWR0XQdwzCR5bfGnc+cmLmadMcVAsvOrm46Ozq4/8EHSSYTWFY2qycrCi6ng6GTJ9m77wALlq2gpnkhAhCKJinzupDEkcfW7/ezauVNdB/ezc1GN4KQPWsca+5HWZQ1oLJtm/M9PXQFArhcThqr63CpCloqgSCICKLEwOAgL734Iv0DA3i93lF7EoZniDKaxs0330xVVVXhu02lUrz88sv4iorYdOcWLFkhY5iYziIW3HI7/YkMc4tkwrYDQVEwTRPbNJC0BLooEejowOPz0djYmF3YsCxi0Qi1dfU89NBDRMJhMpkMR48epbS0lL6+Pjo7O6mqqmLDhg2Ew+ERvgKiKFJcUoKuaXjcHrxeb6Hx1rZt/NXVdHd1XVVgfK0Ih8N84AMfYPv27fzhH/4h3/zmN6d7SDMb+/o7C892C1/KjAkE8lq7P/7xj/nyl7/MX/7lX07o/X/zN3/Dn//5n1+Loc1yDfjEJz7B9773Pb7xjW9cEggIV+kuPNObhPPjM3QdSZYnpJQzneRN4I4fP8aFC+08+OCDlJaWYJoWGV3HtuycMdrkAwNBuHK/gGkY054NCAaDxONxHnr3uwmHwyQSCSrKyxFzWaipVr+aiu0tWbIE27YZGBjAME2qiouRZTlb9qJp2V6NXBlRIBDgueeeI5FI4HA4ChPM/DiuNKa8mzAOzxVlQwOBANu3b+eWW27h/LlzRCIRNE27ZLVXlkQ03UBMDYIgYqseZDWrZ58v+xnNjE8QBFRFIaPpDAz0EwgERgQ3kihiAGaueX8sqqqqePnll9mzb39hBbuuprrw/PCeAnOwm/LaRgZSOkMpnTK3QpnXVeitqauro3iwnWYzFwRIMs5NH0BpXFzYniAIFBcXMzQ0RGdnnO7uHmrrGylzusG2sSwTLZPm1ltWk8ho7NyxY9Reh9G4uHzMtm1CoRCybVFW4kGwbRAluvv6celJXKl+nIBp+8h4yslkUqhAT18fi29aTyqTQRIEBElC13X6Bwbo6elh4aLFHD9xgqbGRiKRCK+++iq//ZnP8C+PPsrKlSvHLE1bunQpoVA/C1oW0NjYUHidYZpIosjcuXNHzSZPJ4ZhcP/993PkyBG+8pWv8I1vfGO6hzTLLONiRjoLu1wu2tvbWbBgAYODg8iyjG3b1NTU8Nprr407I5C3k591j5t5nD9/vvA9XnwKmjlJRHkSijC2baPp+hVX96aL/PhkSZoR5S0T5UrlMJZtY5oWppX9DkVhcoGBlYxiRfqQKhpG9AtYljUjAoF8RqChoYGi4mLmDFu5nmpM08S+Bo3vhq5jk63NzjdfmznH6EB3d2HfZ86codrvLzS/mqaJZdtjNg1rmpZ1u+04ilBajVgytnSoZVn0BoMMDQ6yZ88ewuEwmzZtQpKkS84x27ZJJeOoQ51YnjIEpw/F5Rl1m3qu9G54sBIIBNA0nd27dxOPx0asnluWhaYbONTLZ+fOnDlDKBQatzOuZpgMxFJENBNJgDK3Sm97KyU9xyjqyTaTCg43rrs+ilTZMOo2LvebK5yHjU1UVlZQU1192fMwo2mXvTZmAymd/v4QiizjcDo519pGd+tpttyyDIcWRbAttJ4LkIpjLNyAUDUn+17LwhYEIuEwgUCAOU1NyIqC0+XCMIyCBO7tGzfyxJNPctttt7FgwYIxj2kmJyiRH+9Y3+tM4eDBg9x888384he/4IMf/OB0D2cEM9VZeP+5TrzX2Vk4Hotyy/zZueFwpj0jEA6HSSaT1NbWAvDkk09SXl5OVVUVN998Mz/96U/51Kc+xS9/+Uvq6+vH7A9wOBw4HOOzf59l+rlcc1dfXx+6YSAKwoQnVzM+G2AYSJI0Iyazk+HilcThCIKAJAi5VVV5RGCQyUlYvhUYSIji2DfzsfoFZopk6Iga8/nz8fnG55o7GWzbviZZo7w3QP6YCoKAqKpYlkVFRQWDAwMMRSL4q6qYv2BBYcX8Sk3DyUSCga525nhsBNdbGZ3hE9ra2loMI2dKBQX1GK/XS21t7ajnmCAIyKkhbEnBlp0oDueI50+cOEF/fz+VlZUsaGnBMAyUYcFTMBhk9+7dbNq4kZdfeWXE6rmY69kwrct7ZLS0tNDS0jLuY6zKEjWlXsoNk/5YilBCwyVYhSBAd3gpeeAziL6yMbdxud/c8PNwbvM8ii5zHo5nzU8QBHp7exAEkV89+Tgf/cR/or6ulkwqyZBSirekHjMcxF1hojlKkIorspO6oiJMy8K0sopi9XV1OJ1OYrFYrpx3AeVl5aRSKURR5O6776akpIRINEpJaSnJXHmSbduF4ysIAlZO4sW27UKfx0wMAgBeeOEFnE4n99xzz3QPZZZZJsS031EjkQgf+tCHCheIyspKnnrqKQRB4Hvf+x6f+tSn+Ou//muKior40Y9+NN3DnWUK8Xg8JBIJfvd3f5d//ud/BrKThVdeeYXFS5ZwYP/+Celw3wiSoaZlIVjWDdMXcDWMHRiYZDQNm8sHBhf3CwAzSjI0P0GzcvKv12ql8lp9ZiFX365rWqERGLIrry6XC1mWUVWVuro6nKqKoesYgoAiy6M2Ddu2TW9vL0ODg5gDvSTlMiJ9A9Q3uAsr10XFxRTlViaLi4sRRZGampoRDa1j/d5tPY2QipFUijBTGVRvcaHZfnBoCLfHg97Tw7Fjx7Btm/kLFhTq0f1+P36/H0VRGBoaYtGihZc0mSqKTCajFbw9phJVlqgt9dK2ew/NZU6EpiWEuy5woWolGy4TBIyH4eZrqUwGURQmfb5YlkVZeTnbX3mFxqZGLMvm8KFDrFy1CllRGYpESRhOvOVL8CqAKFFcrGKZJn19QaqrawjGYsiSxODQEPF4HNM0SSbiiJJEY2MTNhCNxZAkiVAoxOuvv8573/MeXorHCYVCbwUCCNi2RWtrK7quU1JScsXG4MtlT64l8Xicf/mXf+Hee++dXWWe5YZj2u+oTU1N7N27l6NHj3L48GFefPFFVq5cCWQluHbv3s2ZM2fYv38/y5cvn97BzjKlHDt2DIDvfe97nDhxAsiu2vX39yNJEqlUimAwOO7tzYQm0sthmiYC2YbL6ZrM2rbN//gf/wNBEFi6dCn/7b/9N77//e8XVmevJUIuKFBzzZUuhwMlV/aX0TSS6TRpTUPP6YXn+wXsTIKu86c4ffo0PT0913ycE0XMfS7DNK/J9qeqR2A0BEFAUdXsMc81euZXxevr61m+fDllZWWoDke2VM+yyGgapmkyFA6zc+dO2lpb0TUNXdOwTJPDR45QX15Ee28/wb6sHGa+p2LB/PkMDQ3R1tY24jdQX1/P6tWrLzt5CwfOE4rEEBweRNVBPJEko2kYpkUymURVHYQjEerq6ykrLyeZTGLZNkeOHCk4mT/44IOUlpWyYd36S/aVl/Dt7x/gwIEDl5htTQWlRV5K7CSRohrSt76XluUrr9rsLY8gCDhUlbQ2uoGcbdskE4lRP9uJEyfYt28fyVSKaDRKd3c3LQsXEw0P0dTUhGYYxBMJFG8JlqHx/G+eoCvQhSSAaYGNSFlZGZIk0tDQQJXfT1FREcePH6e7uxvdMBgaHMDn82Lb8PS2bZw9exZZlgvyyVkfhLdkXAVByHoN7NqF0+Viz+7ddHZ2Fs7Tix/d3d28+OKLbN++nW3btl2T72802traeN/73kdnZyd/+7d/e132+XbBtqfnMctIpj0QmOWdy5w5cwpa1UuXLiUcDuP3+3G73bS1tnLH5s0TkoabyWVBeQMxQRCmtbTlL/7iL/jjP/5jAIaGhvjmN7/Jf/kv/4UVK1bwwAMP8A//8A/XbSzZiddFgYGUCwwy2cAgYwsMaCIVTgGXIvHc888XAsiZhJRbIbdGcZq9aq7xnSvfTKtrGtoYmY38JNnhdOJ0OIhEIqiqit/vJxAI0NrWhupwYAOiqVHkcdEbThZ+v36/H6/Xy6uvvsrAwADzczKR48XOJPEpcCLQT2ugm0cffZSDbx7A5XTidDpQVAfHjx+jva2No0eOMDQ4SFtrK/v37SMWixGPxwulQDfdtBKnyznq/oPBXlKpFLt27bomk8nFjTU4FJl+TaC0rIKy0lK0XGA1FUiiiCJLBUff4fT19dHa2kprWzunT58h1N+Prhs5Kdk4ixYvzjaS6zorVqygosqPaRr4a2oIR2JYsgtLz1BVWsSG9etpbm4m2D+AYGQNviTFQVv7BWzLRBYFqqqq+NjHPsZD7343ZaWlNNTXY5kmNjb/6ZMPU1xcQk9PDxs2bEBVVZYsWTLiOJxvPY9t29y5eTMd7e34fL5CsGmZJuZFD8uyuHXNGgRBKHzf1xLbtvn2t7/NihUrOHPmDD/72c9G+AfMMsuNwmwgMMu0snbt2sLfN2zYUKh5bWpqoqmxkeqasRsNhzOTJUNbW1s5e+4chqaNqFm+3ti2zQ9+8ANuueWWrJZ3RwePPvooAKdOneKZZ57hD/7gD/jXf/3XUd8/NDTEY489RiQSGfH/hmHQ0dFBIpEY1zgCgcCIxv48YwUG4bRB2JSJWgqpdHpMN+rpRMiVzOi5Zttrsf1riSCKIIpZtZhxYNs2B998k47OTvbu21eYdNXX13PPpnXYts2S1bcVVt3zv+vNmzezfNkyfF4vumGg66OvXl+8LzMSJK5DdeN8Thw7NkJS0rJtSstKqautLejNL168mMrKSrq6utB1/RIFIkmWMUfJggWDQQ4fPkRLy8JrMpm0YyGQVVbcuoHi4iLC0SjHjx8nEo2iadqUnDvZLBt0dXeze/duWltbsyWJokhNbV2hJHNocBBRFOgLBjl77iyH3nwTyzAoLS1l+bJlyKJAdU0tgihR5q/Fo4ADE0kQaGtvxzAMXtv1OggChpYmGglT39CIjUA0FiedTpNMxGk7f45MTpVKdToRBRHVodLQ1IRt2wW51/Pnz3PixAna2ttpa29ncGAASZJ4Zft2urq7OXvuHOTK2WRFQbnoARBPJCgvL78u/gJf//rX+fznP8/DDz/MkSNHeO9733tN9/d2JO8sfL0fs4xkNhCYZdrpzimUnDhxgn/6p38qlAmUlpYWVnquxEzMBti2zYULFzh16hQlxcU8+9xztLa2Xpd9JxIJgsEgg4ODhcnFzp076erq4qtf/Sp1dXXIssxnPvOZguTiU089xfLly/nkJz9JS0sLn/zkJ/m7v/s77r33Xurr6ykrK+PDH/4wlZWVLF68mA9/+MN86EMfQlEUmnJOoc888wxaTu1jNP78z/+cefPm8elPfxqAo0ePsn///lFfmw8MDF1n20s7EVQnq9bdXpgAzjREMauONFWruzC+Bs+pwMxlq+ScWdNY+82q6+hEIxHOnDlDY2PjiEk5QJEqIDi91DU0AtnA78CBAwCF8p98FkIQRTRdv+xv3E7HQUviq23GX11NfV0tGzduLEhK6rqOKissWbKkEATAyODj4l4jUZSwcspWw/H7/fT19bGgpWXKJ5O2oUEqCr4KBEEg2NtLdGiI1157jV889hiDQ0NTlh3o7u5C0w1S6QyCINIf6mdocJATx49x8sRxenq6cbvdSJKE0+kkEY+zd98+nn/hBWKRML092XIeG7C1NB7RxCUJ+NwOvE6VLXdsQlVk7ti0CUsQcKoyxUVFnDp5AkEU8RYVoygKbq+Xuc3NuBwqkqJgGiaGZTI0NIRpGqxevRqv18tQJMKCBQsoKytD0zRcDgfzc4ISob4+amtrufvuuy/rGVBfX09TUxO3b9o0od6yyaDrOn/7t3/LH/3RH/GP//iPI7wrZpnlRmNGyodOBTNNLmuWy/PGG28UsgPpdLqgAJWX27xcI+ZMkAzNyy9allVwkwXoC4U4fvw4HR0dRKNR1q9ff9XGUGORTqf567/+a97//vezadMm4vE4AF6vl/vuu4/HH38cyErtjuZCClnpx7//+7/nT//0Ty+ZkKxZs4bTp08XzPqWLl1KMplEEIQRAU5xcTFz5sxh7dq1JJNJbr75Znp6ejh48CAvvPACkC2l+aM/+iP+5m/+BoCf/exnHDhwgD/5kz8Z4TSe59ixYyQyOuWN86kpcuFxTLvOwajkz0UlZ9I1FdszdP2aKkxd/BszclmNi7NXRq4EI/+6Y8eOUVRcTCqZJB6P4/f7qautwbpwBKGkGrG0hkAgwNNPP52d+KsqW7dsobaubsRvOb///v5+zp87Vwg088+ZfeeJJjIEdQW3201Tw1sTPMuySGs6Loc64ayJoWvZPpSLSvUCgUD2/yWR6urqMd49ceyhbuzBANQvw0IkGo2wfcdO2tovALB582Zuvvlm9Fym4moUcvK9dWtuvZUXX3iBVatWEQwGWbBgAcFgkOrqalasWFF4/bFjxxgcHKR57hz8lZV0Broor65FtAwee+wxTMvi/gcexO3xEI+EcagqXq8HLDMrFWtnA3fdBkmUsAQBEDBNA0USsWyIRGMIWJQUFZPRNRLxOP/xxJOsvOkmli9fzvMvvMDKlSspKS4mlU6zb98+HnjwXfz0X3/Chg0bAFi2bNnlj3G+cf8a3wtM0yyUsf77v/87GzduvKb7u1pm2nwoP549p6dHPnTtwln50OHMBgKzzBg+9KEP8fjjj/OVr3ylMEGE7EXXtKwxb4x5qdHxuJ1OBYUJf+7PfA23kJMgFHINy/kJ8gsvvFCQRrzSqtZECIfD/O///b/5wAc+wG9+8xu++c1vXlI2c/fdd2PbNq+//jrJZJJ3v/vd/OpXvxr35zx58iThcJi1a9cWJrbhcJjXXnuNBx54AFEUsW2bXbt2sWPHDkpLS3n55Zd58sknL2lAXrNmTcEX5PTp0wiCwLp163j99dcLr9m2bRsPPPDAmGPqi6VJZAway9yXNX+aTqZS79zKZcSulRLWaIFLPvgQxewk2bbtbHDApZPTYDBIoKuLA/v3Y9s2779/K2VmBLF2EYLDzYEDB94yzhME6urqKCstvWQcsVgsKw+pqrS3t+NyOlmyZAlWIow52MUvXtnH+jvvZvvLL3LL6tWFCWE6o6HI0qR++7ZtoWc0VKfzkuey36GJQ730uE9Gmca2bezOI9iCjFkxF1lR6e7tZdu2bYVrw/BVbNM0MQwDWVEmdZ7nrzt3bdnCKy+/zO23384bb7zB6tWr2bVr14h9HT9+nNdee43ly5dTU1ODIAh4PG4UlwcJG0kUGRgYwOP1oqgqmqZj6Dput4t0Oo1hGASDvSxsnkNWDBYEbGwbTBsQJWwETMskkUhSUlyEbWUXGSKRKLF4HEmWqaqszGZK+vqQcu7CLkWm9UIHzz33XKHs60pomQzqdZASP336NA8++CA9PT10dHTM2EwlzLz50GwgMLOYDQRmmTGcO3euYChz8Wmp63q2dOGi1bvxZAwmS36Vf/hKfx5RFLMT/9xN+nL7Pn/+PH19ffj9/ikLAgA+8pGP8POf/7zw7w0bNiDLMsFgkC996Us8/PDDhQlSvo6/vLz8uqSx86VJoVCIN998k5tvvpnbbrsNgJ6eHs6cOcOKFSvweDx88Ytf5J/+6Z+wLIsf//jHfPKTnxxzu5Zt0zmYQJUlqoucM7InBCgEQZMxxRtOvo79WjSYBwIBNF2nyOejoqJixHO2bRONRunp7aW6uhqvx1Mwdiwotdh2oV/kQns7xSUlVKsGHnSEhmWIosiZM2ewLYuntm3D5/Nxyy23UFVVdYlR2JmzZzFNkxPHj3PnnXfidLlQZAmz9xwJA3CXEk1leOI//qMwITQtC03TcTknP+kb7O/nfFsbJSUllxiEhcMRTp8+RWVlJc3Nzdi2TTAY5PiJk5w6dRJZksZVgmJZFmZ8ECnUCuWNCMX+wnl7JYM+XddBEDh/7hyhUGhEtuRKnD9/HlEUURSF+vp6AoEATqeToaEhotFoNoNTV8fhw4eRiqtwuNw4lEvPs6z/h4AAWJZZkCfNrvlnH6IAggAyFk5ZxAY03UCVJbCz105RAJvsQgmCiGYYyJKEQDZgsCyL3t5eFEXhjTfeYPOdd+JWZf7lRz/G6/WOKAe7HLqmIV8nx/b/9b/+F3/0R39EQ0MDJ0+exO12X/N9ToaZNh+aDQRmFrOBwCwzivwNsr29naampsL/j1VycSWX0/EyVmmPkFvhH77SPxMIh8OUlpayadMm/vt//++Fv9+oaJpGeXk5RUVFvPjii5ed7KR0g65wiiqfkyLnzPWM0HSdgf5+enp6Jq1rnl+ZFye44j3aBHN4YDs0NEQgEMC0LPbv23fJhDYQCLBr1y7uu+8+LnR00NDQgNvtzk76cgGwIAh0dXUxMJCV29R1nU/fuxbR5cMsrScajTIQCtHR2YmqqoTDYc6fPz9i9TvvwRDq62Pbtm2kUinmzZvHunXr8Io6VjJKylGGrqUIx5Ls2bOHNWvWsHTpUlKZDOokV8wh6xLc3t5OZUUFHZ2drFq1itq6OrChL9TH4OAglmWjOlT8/mqcDgehUFZ5p7i4hJdfepHNmzcXHJeH09raSiQcZk5jA16vBynSA4khhDmrEMSJfZftF7KlQ7typmubNm1iyZIl43qvZVkYuXIugIHBQXbu2MGFCxdYsWIFq2+5hXAsQRgX7SeP0HPuJBs3beTo0WPcfd/9HDp0kNrqGmRFwev1EY1FKa+oJJVKozqdGLqevT5KctZwTgCvImLZFpFIhJKiYmTRRrBMbMASlWzOQMjL4oo5nwyBPW/spbe3l6amJpYuW0ZkaIgir4dAT29B7ng8GIaBwLUJnvP9VIqiFO5De/bsYf369XzjG98oKLLNNGbafCg/ntdPd0xLILB+YeOMORYzgZmZW5/lHcuXv/xlALZs2TLi/wsShxc1Mk6mSdjOmVoZhoGmaWiZDHquSS9/A1FUFdXhQFFV5JyB0kwJAoCC2s8XvvAF3v3ud9/QQQCAqqrs3LmT7u5uvve979Ha2jqmt4FLkSlxqfTH0+jmNZDrnAIEQWCgv594PH5VuuaxeJxjx49P6L15865YPE4sFiMSjZLRNHRdxzSzDbKh/n727t3Lq9u3j6qOEwwGqW9ooK29nYqyMroCARyqipr/PeQCgfr6enw+H7ffcQdb7tiIZJsMJHXSqRSWaeIrKuLo0aNouVXaB9/1LtxuN4ODg9l+k0gESZKorq7mgx/4AB/9yEdYu3YtPq8XIxkjIPvpzEgENYV0JsPdd9/N0qVLc79V4ZIgoLW1taCUkw/s8791XdfRNI1M7uErKmJhSwuqQ8VXVEQ6k8ldW2yikSjnzp3j+PFjbH/5ZU6dOI7L6UAUBE6fOoXH6ymYlF1Ma2srsfAQ/qoKXnl1B51d3ZAMg6d0wkEAQHdXAJ9D4b47b6espIj+/v5xv1cQhELwB9AXDLJs+XI2bdpEMpnk3NmzmA4f2BalDpGNGzcQjURYtnQJWCarV62iqb6WYo8LpyLSUF2FWxbwKAIeVcTrUihyyMhWBrcsoFg64aFBBMugosiDgk4qmcSUFGzFycDgIGldR9MNbBu6e3qyamO2nQ0Cm5tZtmwZlmlSXFxMNBZj165dE2qaF0VxymR8k8kkv/rVr3jkkUfYtGkTFRUVOJ1OVFUt9Fl84xvfwLZt/r//7/+7Ln4ss8wy1cwGArPMKL70pS8B2bT2E088MeK5i1VNriQZOnwioOs6WiZTmPTbufcqivLWpF9RkIZNcmYq27Zt46/+6q8oKSnh5ptvnu7hTBk33XQTt956K//wD//AvHnzWLBgAQMDA6O+ttyjIosifbH0dVPWmQh5F+W+UAhgUlKUgUCA/lCIF198cUKBRN68q8bvZ9++fZw7e7YwiVcUBVmW8Xm9hQniaOo4fr+fY0eP8tKLL7Lr9ddpbGgY9TifOXOGttZW/FVVVPmc2MChU+f4xS9+QSKRIBKJsGzZMiorK1m9ejXdXV1svvNOysrKcDidRMJh4rEYpmni8fkoLS8nmUrR036OXqUSTUvTduIItupCKKqkvKIip1xkoF5UxtLW1kYykaCsvBwz5zacD3zyPgiKouBQVRyqikC2mf/ZZ5/j7JkzCGR7ILKOygrB3l66u7oQBKFwfPJKRLZpcd8DD1xazmNZFHnc9ASDHDh4mOU33ZQNAiwToahyvF99AdPQWbl0Md29QZ7Y9gx3bVxP3TgllSF7zQyHwxw6fJju7m7q6uvxeDy88sorBAIBSqtqiGUMqnwuGhvqOX36NG2trXR0dBQagVvb2kimUvT39xdWxB1OJ4JlkUkmMQFBUpAxcSkCFcUeJEHAkhQs2YnTVwyCiGWaBINBDMPg8OHDGKZJbV0doiTR19fHyZMnkVWVVCqVNYoDFKeLO+64Y0QwM57PfDXXBNu2efXVV3n44Yfx+/28973v5bnnnqOxsZHPf/7z/N//+3/59re/zec+9zk2bdo0Yl979uyZ9H7fiVwP87DRHrOMZGZKb8zyjqW8vJzvf//7fPazn+X9738/GzZsYPv27YVaa0kUsUSR7u5uTMtC1zTmzZt3xdIeSRQRrkKFY6Zg2zYf+9jHiEajnD59mrlz5073kKYMQRD4+te/zv/7f/+PZcuW8eUvf5nq6mpuuukmfvWrX1FXVzfitf4iJ51DSSJpnRLX9ClGXczwvpXjOfOzyUhRBoNBpFwz9nBDrCuRN+96+ZVXuPeee0ZtnMxPaMeqT7/4eY/Xi67rKIpCV1cXfX19NDY2UlJSgqqqCKKIbKQZSqRpXrCQU2fO4XA6KSktxV9djSgIDA0OMq+5GY/LhShJ9A8MMDAwQDKdpmXBAmwELly4QDAYpGbu/Gx/RGyQcqeIkI5hO320hSKoWhy3203NMEUfy7Lweb2E+vsJnD1LW1vbZRW6DF2nvLycaDTK2rVrqaqqGtEj0NzczNatW0ft7amvr8e2bVK5DEL+mmKZJoaWJq3pXOjoJB6PE4lE+K3bV2JbBji8jPfqY9s2ppbB1DOoLi+S6qBl4SIiKY2G6nJsyxxXduHMmTMEAgGWr1iBoesYhoHX6+Xjn/gEsqwwaCpIpkWxCnpJCUuWLCEWi9HY1EQkEqFUkmhsaGBoaAhREN7qiYJsj0Ymg+py48JAQMCwBTJ2tqdLlm1UVSWZSBANhykqKaG6uhpFklhzyy1omsbBN99k+fLluCoq+fjHPobD5SIWjSIqCmePH6eyooK9e/dy5113oeXK5OQrZGfzz03Ukbu7u5uf/OQn/PCHP+Ts2bPMmzePL33pS3zkIx+hpaXlsu9Np9P8xV/8xbjLl2aZZSYx2yMwy4zk8ccf5z//5/9cUKz5+c9/TmNjVpf81KlTCKKIz+tlcGCAurqsSc5oqj1vJ2zb5q/+6q/42te+xhe/+EX+/u//frqHdM34/d//fb773e8W/v3LX/6S97///Ze8biiZYTCh0VDqzjYmTjOmaWKYZqGXZTIKM3kCgQCDg4MF9+2JaKPn99vQ0EBpaemUGNkZhkE0EuFXv/4169ato+PCBRoaGxkaGsKyTNbWeTnU1k1P0mbxkiVUVfmJRSM4ndmJvyRJhMMR3B43lm1jmRaiJBX6e7IZPpAlmUQ8iiwrKIpMoLOTc+fOMX/VWgzZSZmQYfuLz3HzzTezbNkyTMPANE26e3o4cOAA1dXVHDt2bEyFLkPXsck2cl/NNUI3DMLhCB0X2mlqqKfI50VxuBBEsSAQUFtVQQNDWMXVmEXV4xI1sG0LPZXEti0khwtZHvndWXoGM51E9hYjCGMn9W3bpqOzk1AoxO7XX0fTtGxwEwqhyDLuknKcVY34PQoVXgcXLlygtbWV+oYG3tizh9WrV5PRNBa2LCSRiOHx+hAEgVQigUOREEURQ5AxM0mS6QyablJWXo6uZUglEpSUltLT08PZs2dZumwZJSUlKJKEruv8+je/4V0PZuVILdvGtiy6urt56je/4c677mLR4iW0njuLKIp4vV4aGxsLCz15h3ZZksaU6M33LlxJTcowDLZt28aPfvQjnnrqKRRF4QMf+AC//du/zebNm98295CZNh/Kj2fXqenpEdiwaLZHYDizGYFZZiQf/OAHee9738t3v/td/uZv/oZFixbxt3/7t/zX//pfC0o0/qoqwpEIS5cuveFr5MdDV1cXX/va1wC49957p3k015aLlY3GqosucakkMgbBWJr6Eve03bht28YwTWzLGjHZq6+vn7SxUX19PS6nkzvuuAOv1zuh7Qzfr65pWKY54Ybji5FlmVQ6TW1tLZIkEYvHSaVSqKpKb0cbRvMq5q+8jfmyE0HM6snohokDGBwcpKqyEq/HldWb///Zu+/wuKo7gfvf26Zp1MuoWbYly022ccEU2xgbTDWEQCiBkLYBNuUNm+xuKqls+rIpb/JCEkgvLAmBBHBoCxgbMAZssI27LcvyqIx6GWlmbjvvH6MZJEu2Jbmb83kePWBr5s6ZcTu/e34lEae3p5dAwE9HNEpXVxczZ8xA03Wefvop9u3bRzAY5OKLL0bVNBacfTYZfg9Ry6S4bRvXnFXB1s4OIpEIebm5GB4PkyZNwnEcgpmZlJSUHDoIEAL9GHQZizQ3I1AQtkVLS4S4aVFengFAVVVV8qSysxHR0YmWXYSq6elaiUNtUF3Hxo71I1QVw5cx4q+ZangRrovd14uekTXi+3BcN1lorihseOMNTNMkGAzS09ODbZrU1MyiIWrj2iZmby9v7W2hcvJkzjrrLPbs2cMFF1yQ7pTU0dVFRiCAKhxc08Kvg4uCpRpEe7rJCASIxbrJy8/HdR0cV9Ay8Oc1KyuLadOmUZCfnzzNdV0ira0sWrw4fVrQ0dlJfn4+Tz/1FHl5+UycNBmfx8OsWbPSp2tAOr1L07R0QCBsO/lzB6VzpusEDvE579q1i9/85jf87ne/o6mpifnz5/OTn/yEW2+9VQ4HO4HcgRTKE/2a0lAyEJBOWbquc+edd/KRj3yEj3/849x5550UFhYyd+5cfD4fDY2NBINBCgvHnnt7Ovr0pz8NwJ///GcuvfTSk7ya4+szn/kMb775JtOmTeMnP/kJO3fuHPFxyRQhP/UdfXT2m+RlHP/+4QdLbVY0VT0mG8zBcnJzyc7JOao2pLphYJkmxjGofRFCMH3aNFRVpbe3F1VVmVJZyeyKIizVQPP46WhrxRGCUChEfl5yOnhRYQGaAtH+Pjw+P6qi4A8kTwpc12X27Nns3rUL07KYOnUqBQUF5OfnEwgEUGP9ZAczcAER7cfxZpHR3868bIPXN79JfumEdEpGVVUVCdOkaIS/E45lEACpGQphMgMZvPjSyyxbtmxYW1TR2wq+TBTDh0KyKN6y7WFzUYQQuJaJbSVA0zC8/sMOpNO8foTr4MSiaP4giqIQDodpaWlh0uTJBDMy8Hg8TJgwgeXLl9Pa2kpRUVGyBazr8ta2nZTPmIvW38kLr6zhvPPO47XXXqOmpmZIOpWiKLS1tlFQFCKgOnT1RsnOK8B2BR2RZnJyctixfTsZGRk0NzVRUVFBzO5n6rTpKEKgqQrZ2dnYtk1HVxeZmZnJ1CrXpTcaxUwkCIVCdHZ2MnfuXKbNmElWZiaqqqRfX1EUXNcd8nmoqopnIG3OcZxk2tBAe+lUOqh7UOFuW1sbDz74IH/84x957bXXyMnJ4eabb+aOO+5g7ty5R/37QZJOVzI1SDottLa2cvnll7Nx40amTp3KL3/5SwByc3OZNWvWMZnieip75JFHeN/73odhGDQ2Ng7r+36m+uY3v8k3vvENbr31VqqqqqipqeH6668ftpHrjpm0RhOU5wTwGScuRch13WQ+9FG0sTzS9Z2BQVtHdZ2BqcDjuU5tbW16Gm15+QS6e7rxeX24wiXaG8WOdpCX4WNHYwdTpk1HUxUS8Th9/f3k5uSkO26JgfaSff0xXn7llfQ8AV3XWbVqFd3d3SxcuJDCwkKmVlcne+gj6OuPUVdXRygUoqurC9NMMDEAWfE2ErbL3oSPsxYvT6/XtKxhaSO2bSMGBrMdq0At1Z1ppIFgACLWi2jcjlI4eVihcKqTkWEY7N9fh9/Q8fn9+AMZeLy+UfXAF0Jg9/eiaBrNbZ28+uqrzJ03j107dzJnzpyR5xKYJvXhMFE9E103KNAt+vqirHnxRTo6Ooa0QxVCEDcton39uJaJJmx8WTlYtovfo9Pb00N/fz+u62IMFKJ7vV6am5spLS3FdgVvvP4a++vquOY978Hv93MgHGbz5s1MnjyZoqIicrKz8Xg89PT0kFdQSEdnJ3t27aSwsJDp06cnPyvXxXWcw6a3DW4MAcnOb73d3Wzbvh2v18u3v/1tnnjiCYQQrFy5kptuuolrr70W3wjD5M5Ep9p+KLWe1Vv3n5TUoGU1E0+Zz+JUIE8EpNNCYWEhGzZs4G9/+xv/+Z//ybJlyzAGOgjV1NTw4IMPMnv27JO9zOMmNTistbX1XXV0fdlll/HnP/+Zt956i+eee46mpibuvfdePvGJTwx5XJbPSKcITcgNoJ6AFCF74M6ux+M5bilJR9sBJUXVNJyBjdJop/AKIWhoaCAWi1M9dSqqqhHtixLtjdLd1UVhYSGZAT9eNUBU9VM5JY/O7m78gSB+rx+nt5fOzk4yg0Ec1yUei6U78uTk5NAz0Nb0lVdeobu7m8zMTConT6agIB/LMtGNZKtSnz+QntpaXl7Otm3bePjFtRT6FK6YXcHMoIXbVo9akKwhSqWFpAKBIwUB463jOFLBtehtA0WFYN6w52oDgUp3Vxc5GQF27dlLYSiE0t3L5FEOHVQUBT2Qid3XjUeFyZWVPP3UU8Tj8RHXk5rwjDeIqnrJ0iyCGQHq6vbR0dExpKDdsh1iCZPurk7CB+qZM6sG4bqYlkMs2suWvXsoKipKd2IydJ3MzEwikQiu69IXjdLW3k5pWTmZWVn886mnmD9vHhMrKrBsm30DtQixeBzXddm8ZQvnnr8IxXXo6elh27ZtCCGYMWMGqqJgDzSAONSfs4PThiItLaiqyqZNm1BVlVtvvZULL7yQW2655V1zgixJoyUDAem08r73vY/3ve99QPJu6a9//Wtuv/125syZwx/+8AduvfXWk7zCY08IwV/+8hc0TXvX3cE477zzhqQFffCDH+TOO+/kkUce4bzzzuOss87i6quvxuv1UpTpo76zj46+BAXB43enTwiBNTC06HhMtB7sWF5b13Us0zxse1zHcXGcZICDgIyMIM3NzcnWp0IggJqZM2lva6O+vp4poRwc3Utvnwm2ghHIRNF1+myBkZmPrrgIVUGI5KmJz+fDo2t4vV4MXScrK4uioiIWzJ9PSUkxuq5jGJ7D1jPMnDkTIQTt7e00eLOYpPTgNuxAxPtQy6alN45w+CBACEFTUxObN29OdiFznDEVZMOha0CE60C0HYJ5I3b3SaUCYSdo7+klEAzy+BOrOOecc0YdCKS4ho/MgE3TgXri8fiIHapSd8obm5roMnV0NU5L2wHU4mKmTZtGfl4efr+f0rIy+uMJHFfQ3Bjmheef59YPfjA5SVrRcBJxsrMyQVE4cOAA06ZPpyEcJpiZSUYwSFFREQrJU5mgaZKVmUlJSTEzZs4k0d8PikKoqAjXccgIBEiYJrphcO6ixTTU1zNpYgUTJ05kx44d6bogRVHSKWSHC2Jd12XVqlX8/ve/557/+R9279pFf38/AHPmzBmx2YB0cskagVODDASk05aqqtx2223U1tby3e9+l+eff/6MDAR++tOfAslOOmdKF4vx+vnPf04gEODZZ5/ljTfeoKuri7lz57Jx40Z0TaUw6CPSGyfg0Ql4jv1fb67rYtk2+sDdxxNlrK0QR5Kaw9He3s62bdsoKChg+vTp2I6D67i4QgxMDk4O71NVlaamRjZs2EA0GiU/P58rrrwyXXha6prgmHQrGeDzEfB68GmgaArChQQuaAYJRyBUDc3rQdGSQcjEigo6uzrBdTln4dk4jkt3T++opzAPbtMorARO3SZE+wHcRB9KxRz6+2Psb2khLzeX3Ly8ZC656yJcgStS7YWTBc2Gx8OKSy7lbw//ddQtWo+orxOEi5I5PIVPCIEd70/+mho+du3ayPbt28fcYjaVlmYYHhQ9l4uXLmJyZSXZuXnp97Br1y66u7upnjKFrOxs+lwNj89P867NbNnwGsuWLWN+WRmBQACBQrQ/jsfQ8Xt1mpuaiEajbNm8ma1bt3L1Ne+lvb2NvJwc5syZw7Zt2+js6KBsoKg9Fouxe/dutm7dyo033EBPVxcZfj95eXk4gKEbWIk4Ho+Hqqoq+vv7eeyxx5g95yyqqiqZPHkSHR0d6Lo+rPZL07TkicYIf+Zc1+XBBx/k7rvvJhQK8b3vfY+uzk727t0LjK91ryS9m8hAQDrt3XXXXaxbt47f/OY3XHzxxXzgAx842Us6pl5++WUAvvzlL5/klZx8GRkZ/OIXv0j/+L777uOTn/wk99xzD5/73OfI9Bn0mTYtvXEqcjPSRYdHI5U6Ul5eTk5ubro16ImiDBRFHosgcPv27bS1tVE1eTLBzCz6+vrxeAx0PZmqcvD7OriffkF+PpZtE4/HycAiZmRiCZ2ABh7VxTKt5KA+nw+fx8B1HHwejQMNTfT29TNhUhVRW+APBJmQkUFvNMqf/vwgF198McJ1eeWVV/B4PGO6M68YXrSqs3HDWxGdTZjbXyaaUU5GMJOe3iiqbiSLjhUFVVXQFANFYaAI1aF27178fj/V1VOP2YZR9LaB7gVf5pCfdx0HK94Hioaie8jyZzBt2jRyc3OHzSsYSer34sSJE8nMyhqSlubNzKV6ko6RkUwd3LVrF6tXr+aySy+luaUFW4Cl++lpb2HLhtfSG2QhwHJcXNcl4PWkC9MLCwsJBoMEg0Fs2+aF55/j4hWX0NzYwOtvvMG1115Le1sb5WVlJEwTr8dDV1dXMjWor4+GxkYCGRnkFxSgOg5mPI5q6HgUhddff53CggIuXrECj9dHSyTCg88/z0c+/GEMj4cLli7FcRzWrFlDQUFB8hSI4QHxhg0buP3229m8eTO/+e1vuWj5ckpLS1EUhWAwOOIcCEmShjqzKyyld4WMjAyeeeYZZsyYwW233cYjjzxyspd0TO3fvx+A9evXn+SVnHo+/vGPc+WVV/LjH/+YpqYmAAqDyQm3rX2Jo75+qiC0PxajqbmZ1oHc4xPpWNUJALS3t7N582a8hkZjuB4zFkVNNsE8ZKBRVVXFeeedR3l5Oa7rUrdvHyLRh6Po7D7QhO4kMPv7MHSdv//jH8m1DtxxN00TFUj09bJuzQuIWDcaDt1xm9q6Ovbs3cuKFSvo6uoCkoOoxjOFWVFV1AmzUEuq0V2L3M49bFj9DI888jd2bN+G15OcSZDMzX9nxkgqzz8rM5MLli49JqcBwkpArAclsyD9OuFwmNrdu0j09YBmYPj86U18VVUV559//qiCgKeffhp/IMD27dtpbWkZ2jJTN9B9Gdh9PQjhEo/Hue666+jr7+eVl19mX1MbAoXy3AyWLVvGypUrKQwVE43FMXSdaHcX3d3dNDQ0ADBjxgwuuOACOjo6WLx4MSXFxQPpidlUVVbS2tJCaVkZzc3N9Pf3s3fvXqqrq1m+fDldXV0sWbyY6urqZB2Bx8OWLZs5sK+Wnu4udu3cSU9vL/kFhSTiMV5++WXmz5tHrL+fTW+9RSAQwHVdXn/9ddauXcvWrVvRNC2d4gTw1FNPsXjxYkKhEOGGBm6++WbKysrSn8loP1fp5HGFwDnBXzI1aDgZCEhnBMMw+PnPf048Hud973sfgUCAJ5544mQv66glEol0APBuTwsaiaIofO973yORSHDLLbfQ29uLpioUZfrojVv0JYa2EAyHw2zYsIFwODyq60ciEaLRKOWlpezeuXPMG9RjQR3ouHMsFBQUJFtYmiZrX1lHpK0DTTcQrosVj2HG+rHNBK7jIIRg69atbNmyhe6eHlxXYNsOJaWl4M3gQGcfa557ht07d/Liiy+SME2uueYaurq6aGttpauzk7b2DqLRKNXV1Vy5ciVZ2dm0tLbhmHFeffVV8vPzqaysJD8/n3giQVlZWfpO9Vh/rRRFQS2aTFugBFVVuGx6iIVVJUe8y19eXs6cOXPw+/3HJuDqHZh5MZAWFA6HiXZ1kpebw+qX1tHa1j6uYDISidDT0wNCUBwKoakqjm0PWfOO3XupCzcS6+qgavJk1q1bx5NPPgmKijengCyfzqTyUubOm0dOfgG27RD0+2iNNPPCCy/w9pYtxBOJ9Gc+c+ZMli5dyqxZs1i6dCmZGQHyCwq44IILqK6uJtLcTEYwyMsvv8zzzz/Prl27mDp1KjNravB4PMle/gPy8/PJzc7iqaee5pJLL2XK1KmsfuF5fF4vy5cvT74PRWHmjBkYusHkykpWXHwxCskAVlPVZO0K0Nvbywc+8AG+/OUv88ijj1JUWIh+AlP1JOlMIgMB6YyxdOlS6urquPbaa4nFYlx99dV87WtfIx6Pn+yljcsf//hHqqqqAPjoRz/K1VdffZJXdGqaPXs2d999N6tXryY/P5877riDhrpasnwGLb3x9OYhHA6zb18d+fkFdHf30NbWjm3b2I6DM5AaIYQYsrEKhUIEg0Eee/xxFi1eTEFBAXv27Dmh709R1WN2F2vmzJksWbIEf8DPBRdcwMyZM1E1Dd3jxeMPYPiSk3Ed26Kns51QYQGVkyZixuN0tLfh9XoIHzhASyRCUWEh5WVlTJ48mbMXLKCnuxsFyCsowO/zYVomDQ0NdPf24rgupSUl4Lpk5eSz/e0tLF68mBkzZtDQ0IDjOLR3dBAqLubKK6/E4/Xy1ltv8dJLL7Fq1apRBwMAJVNn0xqswEJl0eQCJnoSCHHkQErXNGzbOeLjDic5O6BtYHaAF+E6ZHh1eqNRtu3aw7bt28cdTIZCIQKBAE8++STPv/BCMlWG5CmKmUjQ0tJCX18fRSVl9ET7iEW7mTZtGueddx7nXnQZKCqhoJe4adEXS+AxdDL8XlRVoaWlhXMWLkQ3DMxEAt0wRgyKNE0DRUkP+WpoaOCB++9n965dRKNRWltb049VNQ17UC//GdOn4/F6mTJlCl6vj3h/jP6+PiKRCNXV1UyaNAlFUQlmZRPICNAQDvPWW2+x/KKLqK6uBlLpXC4vvvgiX/3qV/H6fHzi4x8faDUrnW5c8U7B8In7Otnv+tQj5whIZ6Suri7e+9738uKLL7Jo0SJ+/vOfn3btRS+//HKefvppvv71r/P//D//z7tmdsB47dmzh2984xs88sgj+P1+vv/9H7Di2pvw6hrFWT42btzIq6++yoSKCkqKS5hcWUlGRnISrKKAgkKyL87Qk5d4PE48Hid84AA9vT1MnjQJRVGYNGnSCXlfQgi6u7rYvmPHMct3NvujGP6Mw54yrVmzhj17dlNYUEBRQT6VkyeTnZ2FoqjE4gn6YzEygkHa25OtJy3Lore3l1AoRHdPD/F4nFgsRlEohMfjxTQT+AMZdFsKiY5msjKD5OXns7+ujo0bNybv6KsqM2fOxDAM6vbto7SsjHA4TDAYZOLEiWNK3UkVEdPfhRLMQ514Fop++F70qVz38Z6+iVgPonEHSlElri8Lx4zT0RPlH489zvLly1mzZg2XX375uFOQDtXqVAjBhg0bmFBejs/no6mpidygj/zCIlzdz86WXrJ8Onk+DU1V8Hk96Ra7qd9fa9auZffu3cyePZvzzz8fr8+HZ4Te/aZlY9s2Pq+HvXv38vzzz6dnKVw0aNPuui5mIoHP7wfANuMoqk5Layv9CZOnVj3BBRdcwKTJk3Hd5IyDt7dsoaOzA8dxOPfccxFCEIvFmDp1KrZto6pqug6hubk5PQissbGRkpKScX2m7wan2n4otZ5nNu8jIzPzyE84hvp6e7l0zuRT5rM4FchiYemMlJOTw+rVq3n44Yf51Kc+xZw5c5g9ezbz5s1j5syZTJkyhaVLl5Kfn39KDiOLx+M8/fTTfOADH+Ab3/jGyV7OaWHKlCn88Y9/ZMuWLdx6663cfvtt3PziGu7+4c/oTdiEQiF0XWf3rl00NTZSUlJMfl7uwDAiMXAikLyWqiY3pZqq4vUY7Nq5g/6+PgxN45///CfXXnttui/78U7ZqqurQ1EUuru76e3pwePxJO+uK8qQ1x78/0fqjZ+sO3BRlEOnU+Tn57N9+3Z27d5DY1MzwexcCopLEcJFxBM0NjSQk5NFwO9HU1ws12HXzh2sW7eOq66+mpzcXBRFIRaL4fF6UDWVtza/TcmkKlY//xwXXnghxQN5511dXenNpM/nw+PxULtvHwWFhRSHQvzfc8/x9ttvH1URsbNnPdrkeSjejJEfPxCIHKlN5eGkZgc4mg/XMjH8QYozsli5ciXxeJxrrrnmqPrYH6pdaaoT08uvvMK+fftYtmwZEyZMwDUT1Lb1IRQPHmHh8/gw9OR727p1K+3t7VROnkxxcTHz58+nrKwsffJgWRaWomAcNNXa0DUs28Y0LaqrqxFCpCcXp4IASHZ1S5gm++rq0HWdieWl6LqHrJxc1J4err3ufWQEAsRiMaLRKH6fjz1799DT00MwGMRxHCZOnIhj24TDYRobG6meOhWv18uf/vQnVFVl9erVNDc3yyBAko6CDASkM9r111/PVVddxeOPP86f//xnHn/8cX7/+98PecxZZ53FwoULWbRoEddeey05OTknZ7GDPP300wBMnTr1JK/k9DN79mzeeustvvOd7/CVr3yFCy5awcVXXE2WxzviAKjkBhAguUEaHBiYjoUQUFlVhbAtnvm/5/B4PPT19UFREdZAH/RjHUwOnpTqDwR4bf16LNPE4/USi8WSQUvygcNSOOLxOB0dHWzdupU33nhjxM2zoqrJc/nDLLumpgYhBB0dHeTn56dbdtbV1ePYNn3xBD0NzRQVFZGrGvT193Peuefi83pwHBs73o/h8RDMCBBuaCQvv4AJkyeTSCRYsmRJenLswZ2JUiceK1euZP/+/eiaRjAYTBcRj+VueqqIWPiCuE27cXavR514Fmpm/oiP17XkJnc8gUBydkAHri8TNB3D4x1SlJya7HusOkAN5jgOOTk5TJ06lby8PHw+Hz6/n47OOI6iobk2nQ0NuP05FBeXsK+ujvXr1+PxeCgqLGTnrl3U1NQM+2xNy6KttTU92bmysjLZFUrXBmZOOEydOnXEv6d27dpFOBymvKyMt7dsITc7C7+ioZCcCJ/qVLVt3VbWrVtHdXU1l11+OfFYLDmkzDB46623yMrKQgEqKiqIx+O8vWVLej6AqqrcdNNNx/SzlE4cx01+nejXlIaSgYB0xvP5fNxwww3ccMMNQLIA9y9/+QubN2+mra2Nl156iQceeIAHHniAv/3tb6dEkfGqVasAyBvogS4LhcdGURQ+//nP09PTw3/d9UXKJ1fR0d7GOTOrWbBgwRGfq2kKmvbOLllTMuno7GTRosVk52QTCGTgugJFVbFMk9a2Nvbt20dhYWF6gzseQoiBvv4Oqqqi6zr9fX00DfR0DwaD1NTUoI+QspGy5e23WbduHZdceikbN2wYefM8cCJwJLNmzRryY9d1yc7Kor6+ntdeew2ACy+8kLVr11JWXs6M6dPpivbx3P/9H/PmzsVMxJk9exZlRQVomopwdZSuWjbuqkcIl1mzkul6VVVV6XqYlNSae3p6sCxr3P3gFUVBKZoM3gzc+i24tRuhbFp6EvFgqqqSbHo09j9zbk8rinBRs4pQvcMH2imKkqz3OIoTh5EIIbBtG4/Hw4wZM3AdB8dxcGybxkgrPf4i2ur3EK3fyfx58wiFQvg8BhctXYKqqpimicdr4NgWqqqlT5o0TSMSDhPw+3nttdfw+XysWLGCqqoqDF3HdhKYloXvEAPq+vr6mDd3Lk2RCOcsPBvV8KAAfp93yONDoRAZGRns2rWLpqYmrrrqKjKCQba9/TavrFtHZmZmOq2lt7eXs846C2DYrAFJksZHBgLSu47X6+WDH/zgkJ/buXMn06dPZ9WqVZx77rm88MILBAKBk7TCdzZgn/70p5kyZQqXX375SVvL6cowDL7//e9z11138ctf/Zorb/wgP/n+t/np/3wf4zAb6YMJIRCuk5yaOiivOjWkqrs3iuHxUlBQyI6dOxFCMGPGjDFdP3X3X5C8K60PylM/1B3zQwmFQhiGwVNPPcUVV1xB9gh5sIqijrpDTm1tbbp3fTAjAyEEb23aRDAYpKqqitKyMjIzM6mrq+Mf//gHF154IStWrCAWixEIBnntjY3U1tYyc8YMZleW4vdorJg9CdOJ4rYfQMkqQjG8I752eXk5Pd3dnH/++aMaNHY4anYRypRzcPa9OWQSsaIMPRZJFQ0bxpH/edy2bRttbW1Mq6ok3+1C0b0oGTmHfHxquvOxCgR27dqF1+PB5/ORm5cHQqAOtOtUFAWV1K+xSn8sDqqG7vHR0xdj7dq1RKNRQkVFXLBkMcJxsC0z2aFKVVFVjVi0FysRRwhBNBqlpaWFqqqqdBqVAiN+Vnv27KGgoABl4LMMBAIIRcXv9Q4LGg7+/V1cXEx7WxvRaBQgXXeSqhUpKSnB6/UeddAtnXxysvCpQRYLS9KAr371q3zrW98C4Nvf/jZf+tKXTuideNd16e/v54033mD58uVAskvHa6+9xvz580/YOs5UD/39cWrmn8vLTz/Gv95+26ifZ5kJVE0/5OZt7dq1vPZackDTrFmzmFJdTX5eHpqmHfb3z8F3/zVdTxdwHq3BNQJFRUXJzkCD1u/aFq5jo3v9h71ObW0tzz77LLNmzSIQCNDV2UlVdTW6ruM4DtrAsLMnnngifWKxcuVKAP75z3+y/KKLeOH551m0aBEZfh/Rnh7+74XVLJ4/k7mTStHtZIoHgRyU7FDyvwd9BmYigcc7cqAwHkcqIh5t0fC2bdvYtm0b82bNpLe7izkFOkpeGUpu2WFf3zRN9GMwlC41MOzyyy4jHA4TKi4edqriuIJX6joQ/T3kK/1DJjKnagRSA7tSUnMgXNeho70NY+BUKmGaZGZmkZuXh6JpCJEsHFYUqNu3j5aWFiZOnEhRUQhXuLREWnjyyX9SVFjIRZdcSnZm5pBTtoMJIdInGa+9/jrbtm1L/5668MIL6ezslMPBxulU2w+l1rPqzdqTUiy8cl7lKfNZnArkiYAkDfiv//ovvvnNb3LllVdy11138eMf/5ibbrqJW265BZ/Px9SpU9NdZo61xsZGFi9eTF1dXfrnLrroIn75y18O+8ddGp/rVl7OI8+sZuKMOaNO/Ui1FD3cHdzUBNZoNMrbb79NQUEB+Xl5mJaFqijouk5DQ0N6Y15SUnLIu//HyuCiUiEElm1jC5GeGssoTwQikQimaVJRUUFrWxvRvj6eevJJent7WbZsWTrN6uDaizfffJPFixaxadMment7SSQSTKuaTL0QLDj7bDLy8zEmzsSJ9UJPK2p/J6K/C3QPZIUgqxBF9xyzQWqDHamIWFEUVEXFdQWaNvKvi+u6FBWFKCkpZf/+OvpaGxD5FSjBI3f20nUdx7ZRPZ6jeh+tra309vby14cfBuC8884b9ndFarB2Xn4+NSWTh3xvcFAwmJIcu4ymqnR295Kbk8O+Aw2UlZWSm5+PcB3chJUsNncFfbEYuTnZlJWV4wpBZ2cHfX19PP/888RiMc5btAjTTKBp2Yd8L67rYlsWu/fs4aabbmLbtm089NBDzJs3j9LS0mMy6E069aSGfJ3o15SGkoGAJA2iqioPP/wwd999N5s2beJnP/sZP/vZz4BkHrOu65immcyJLjv8nb+x+Otf/0pdXR033HADfX193HfffVRUDM9hlsZP0zTu/tJ/8ufHnuLxZ57nPZddfMTn2JaJbhx+wzZ9+nSEELS1tVFYWMi0adOSrzeQ8tPd00N3Tw99/f1Ytk1XVxd5eXkn7LRJGej8Yts27e3t1NXVUVwcojA354jPDYVCZGdn0xKJULd/P+ecey4er5f9A8WjKYMDD9d1qaqq4tlnn2V/XV06t184DpVVU6ia8k5nGT2QhesLYpslqLFu1L4ORMcB6AgjgrmQVQTa4U8txvWZHKGIWNc12tra2bFj+5BCadd1MU0LIQTxeIzGpmZq9+7l8ppS+oVO5iFSnAZTVRV7ILXsaH4PFBUVpQPQYDBIUVHR8PepKKjK8M3PSF2lUicBQggEguamZnq6u3Btm23btlFYWIimG8A7pyeWbZHo7iEjI8hjj/2D5uZmFi5cyNKlS5OtP+NxsrKzCR4izVIIgWPbxGIx7vrKV/jpT3/KokWLeP31149YyyNJ0rEhAwFJOkgwGOQHP/gBkDz+/8c//kFBQQF/+ctfePXVV5OTZsvLeemll1i8ePFRv15DQwOf+cxnmDJlCv/7v/97SrYzPROoqso/H3+Mn93/c/7lk//Gb37/R1ZefumIGyhIdmJJ5UIfyUg1AamCy7179rDxzTfxeb288frrXHjhheTnj9y15nhRFIVIJMKBAwdo7+jgjTfe4Nb338CR7klXVlaiqiqqqiZTQki2aT3vvPMIBoPDHp9K7cjMzOTcc89l0qRJyVOQUBFi4PM8mKqqGF4/ru7B8ueguxZKtD05oTfagaZ7ETnFkFmIoh27f7IOV0S8fft2DMPD1q1bk2lbmsakSZMRQqDrGpqmUV5eji+QgU8kyAoYKEUTR/3a2kBqla6P//0crnXnkNdSFNxBU5TC4TA7d+4gVFSEZSbo7e7C4/Ump2cMFAorikJPbw91+/ezZPFiLrvkEvpjsWHBi67p+DIy6Y/HaG5uJhgMpn9vV1dX0xeP41VH/jOUOgV47fXXueaaa1AUhV/96ld85CMfkX8HStIJJAMBSTqMmTNnpvNnb7/9dgAeffRRrrvuOpYsWcLLL7/MokWLxnXtvr4+HnjgAT7zmc8A8Lvf/U7+A3icTZw4ka9/8XOs3biFkspp1NTM4vnnnxs2bE4IgWOZGCN0fxmrUCiE6zi0tLSMu/PNsRCJRHjllVe45j3vYeeOHUOmvh5ORUUFjuMMKbBOpRs5jkNjQwNNTU1MqaoiJycnXaiautMciUTICvgIZucc8jUURUnWSGgatqUhsorR88pp37+LDKsfX9t+aK9HBAtQsovAGzxmJyojFRF3tLdRu6+OSy69DISgKBSivaOdkuLi9J9RIQSBQIBZk0og2gEZuaN/zYFuU+IIdSRHcqjWnUNfS8EZiANc18Xv9eI6Li+uWUs8Hh+S4jWYrhu0t3fwf889z7x588jPy8VMxNF0HU3T0wGD3+cF4bJw4cL06YkQgrhpogPaQYX5qS5HiXicL3zxi9x7773cdNNN/PSnP5VdgN5lXDjhk35l99DhZCAgSWN07bXXsn79es4991wWL17Mf/3Xf/GVr3xlXNd59tlnAfif//mfcQcU0tgEg0EuWXwu+zuifO6r3+Sb3/wmDw/kWae4joN6lJu0lPLy8hHnF5xooVCIYDBIU1MTVVVVaJo+6vSUgx+hKAoew+DAgQM4jkMoFKKlpQXLsggVF6MAkZYWnnvuOaK9vZQV5dPTHz/ie1cUBcPjwXVdujo76BEeXnp7FyLey7L5NeRE2xC9reANJGsJMgtQ1KPvwKP4M9Gqz8Wp24RoP8CcHC97LJPNmzexcMHZ1O+vo6Ojg7LS0vRzXNdFw00GAcH8Ma0jddLU2NhIfX39cS2C1RQFxxXYlonrOCQsi9p9+4jH44cNTIecOBQWkjcwfNGxLcxEHF032LFzZ3JQn+HhggsuSP9esmwHBQUVN9mSdEDqFGDL229z9tlnA/CHP/yBW2+99bi8d0mSjkwGApI0Dueccw6PPvoo1157LV/96lfZuHEjv/jFLwgGg/zqV7/ioosuGtKJ42D/+7//mw4CnIGuMdKJo2sqRZl+rn3/B1j7wv8N+V7yjqWF5xicBqQcaiLsiZQKSDo7Opg9ezZer+eI04UBOExxXTgc5pVXXklOo/X7qampoSgUSud+nzVnDrG+KLv21JKRlT3qz0BVVbZu287kyZMoCRXx8rpaCsr6uGDxIuhtRXRHEK37oK0ekVWAkhVC8R5du9/BRcQZnU3ctLCSt3s1dEPnwIEDTJo0acjjHddFi/eAcFEyj1wkfLAD4TC2ZfHKK68QDAbTPfoHO9KE6NFQFTCFCygYXh+lpaWjDkxTJw5CiOS8AY8H3fCg6YLGhgYyMzIwdI2t27ZRUlLM5EmTcFwXy7Hxqird0T7qtu0gFAol60SEoKm5OT0E7E9/+hO33HLLuN6XdPpzXIFzgo8ETvTrnQ7k7kOSxum9730vdXV1lJWV8eijj1JUVERVVRWf/vSnqampOexgsueeew6AZ599VgYBJ0mmzyC8bw//8dW7MS0r/fOObaHr+hk5xK28vJzZc+YkZ2QoymE3+SkCko8dQeqUIRKJ0NrWhuHxoOt6cuCZovD21q1Mm1pNuKlpzClRU6dN4623NhEqKqSoqIjCwmSNgJJTglJxFkrpDMjIge4WxIHNuOG3Eb2tyT7445QqIlZLqvHgcFamReu+nZx77rlMHygCT3EcF7WvAwwv+IbXSxxJa2srKAorr7qKC5ctIxAIYFpWssOT49Dc3Mzq1atZvXo1q1atIhwOj+n6QiRPARQErgDdMIZMOl6wYMGogwtloPuVPfDnRFEU9tbW8o/HH6evr5/ZM6aRm53N2rVr6ezuxufx0N8f5cmnnmbnjh1YpklnRwd/+MMfmD17No7jsHbtWhkESNIpQO5AJOkoTJw4kbq6Ov785z8zadIkWlpa0t+7+uqr+fjHP87evXt5++236e9P9kx3XZe1a9dSVFTE0qVLT9bSJSBDTea+v7VjLzAw3MtxUI9hUeqpSB1oh3o0m2Z4ZxjUokWLuOSSS4akt5SXl3PR8uV4vR4uvHDZmO5o27ZNXm4ulZWVdPdGueLSS4YUZCuKghLIRi2uRpk0DyVvAtgmIrIXUbcRt20/woyN6z0pioJaNBl10lw0VWVmhkW204tlWel2pkIIsOIQ70XJLBxz0CiEYNrUqWzevJlVTzzBi6tXE4/H0TUtPUsikUiwcOFCDMMgGo0SiURGfX3XdTETcUBB1zTcgWnJR0PTNMTAtQHy8/PxeDw8+L//S8w0MXSNmTNr2L9vH7t27CARTzB12jQqKip4YtUqXlm3jttuu43rr7+et956iyVLlhzVeiRJOjbkQDFJOoYcxyEej/Pd736Xb3/728O+X1JSgmEY1NfX873vfY8vfOELJ2GV0mAXXXo5v/zTXzGsPnTXRtd1QsXFJ3tZx5UQAjPej6bp6J7Dt7xsaWmhp7sbn98/5vQU24zjugJVN0bdIcd1XSzbxjPoDrYV70fzeIfkm8PQ1JmysjLo70J0t0B/Z/IB/uxkcXFG7rAJwqMhYr04+95MbvpzyxDFUzA8XhzXxW07gNYbQZl4Foo++oFnQgisgaFi++rqDjkxOhwOk0gk+Pvf/54e1Hakzz+ZkmXhOi66x4OqqmyP9NLWZ7JoUh6aenSnXEIIor297N69m6JQiK6uLjo6OsjKCFBeXEjUcuhs72BSRQVCUVj78ivs2bOHYDBIT08PU6ZM4dprrz2qNUhjd6rth1Lrefj13QSCJ3agWH+0l+sXVp8yn8Wp4My+7SVJJ5imaWRkZPCtb32LYDDIunXrmDhxIsFgEL/fz89+9jMmTJjAxz/+cT7+8Y+f7OVKwAvPPk1rQz05BSFETwdr164d1abrdKYoCv19MXp7u+ntjx9yuFSy1eROenp6aGlpGfPn4loWui9ATzTK9m3bjlgUm+pGNDgIANA8Xhwzgep7pw6goaGBNzZsoC8aZcuWLaxYsYLy8nKUjFyElUD0tEBPC6J5N2gGIqsIJasIZRS9/lMGFxHT2QCJPpyJc3DRUPs7wZ817iBA1TSqqqoOOTCwrKyM3p4eli1bNqoaAdd1sEwTTdMxvN7055c6YXCEQBtW9j2yYQGWEAPDwjrp7uqivr6e1994g2vfcxXTJpbS3x/j5dfeYPuu5KbfBdaufYkZM2awcOFCtmzZwo033sjEiaNvsSpJ0okhAwFJOk6++MUvDvu5r371qydhJdKhWAM5z+E928nIzsWXVZBOwzgTA4HksCjYu2cPthknLzubZ19djRCCWbNmDXt8JBKhtbWVktJSamtrx/S5uI4DikLd/v10d3eDorBu3TqEECNufoUQmJaFMUJ9hqpq2CjJlpuKgnBdNF3H7/ORl5dHTnY2Xp+PhGmiAIqqoeaUouSUQH8XidYDeDsbcDsbUDJyUbKKIJAzuo5Jg4qI6WzC3fM6fcFishyThm6FCaVHvET6/VmmmW6TOprH+/3+Iw7WGnwKYHi8w2qOtIEfuq6AUTQ2CofDrFmzhhkzZmAmEvT29OD3+1EUhfb2dl5+6SWKC/O55tLlqK6N5g+SFcylYnIVwexc8vPzeemll3Ach7q6OhYvXsyHP/zhEedOSO9ujiDd2vZEvqY0lAwEJEl61zIMgwULFrBzxw4cobDgwktYtOxiQqGxd4E5EYbdqYUheeupjT6D/38w4aI4FiW5QRzHT2dPHysvvRjHFbi2lSzGHbQ5DoVCvPHGG1RWVjJ79uwxFfy6tolmGEQiEfJyc6ndt49Zs2YRzMzEtm20gfasqQCjsqqK/Lw8VFVNvxfXdXFdN/keFRVhW+heH+pA4WpdXV16su7KlSvxDAyzSj3HEYKY8NBkBVAsFa/ZQzndqH2doHshuwgyi1B047DvZfAkYqdpNxlddSR0P0+//BbnOdqIQdSQj31QEKCNIghIPUc5QiOBQ50CDDb4RGA0WlpaOPecc1i9ejVd3d3pOQNCCApyMrnmsotojLSw5rUNLFp8AaqeHEuX+gy6urpYvHgxHR0d5OXl8bOf/Yyf//zno3ptSZJOPBkISJL0rvbXv/6VpUuXcscdd1BSMYnyymqKcjNO9rKGCYfDrFq1ioULF9Ifi9HT24vf53tnGiykhzyl/j9F2CaOGUPYNqrhpamjG0XV+eeTT+Pz+Vhx0UU4lomIx1B1A9XwoA5Mz021mjzn3HPJHOVdXSGSgYURCFJSUkKsv5+6fftoa23l0ksvJT8/H9Oy6OvrY/uOHUSjUfLy8xGuS25eHvBOr33dMNKbWdskGcwo2mHnMwzebG/ZvJnVq1cTCASYMGECvpL55HlB62uH9gPQHqYXD/VdcQK5RVQeIlUnNYl4Z12YSdke4pklJMzNdHR0HPGzGGsQAMlC7pE6ioXDYVoiESZNmkgwIzjiKcBg2sBn546ybeLkyZN5+eWX6eruJhgMUhwK4cT7cBIxsjMzael0MdFZtPiCYadDe/fu5bLLLqO9vZ3f/va3LF26VAYB0iG5AylnJ/o1paFkICBJ0rva5MmTOXDgQHJI1re+xdt1TUR6YpTlBE6p1q6RSIRoNEogEODxxx475ETYFOHYOGYc14yjaDqax4cSSN41rpoylUhLC3PnziU/P5/KKVOSzxnYwNuJGAiBahiUlZZSXl6eTt1JbdAPR7gOiqqhKCrl5eVEIhEWLVpEKBRi8uTJAOiaxpbNm/H7fFRXV9PV2Ylj24RCoUOm7GiGByvejzpwcjGa+QypFqfRaJSGhgbmzp2LkVuGyCnGiUexOxoJxLuZmaPQGT1A655+CibPQDlE5yhf0QR6MoJYjsv1t3yQrtbmQ752bW0tgUAAx3HSJzijUVtbi8/nw0wkmDR5cvqEpLWtjf3795Ofl8vmzZuZUj31iO9fVVMnAkd+XcdxCGZkMHfuXCaUlzOxNETAayCEwMjMRVE1SgOZlJYlX1MIwV//+lf+53/+h507d9Lf309OTg5vvPHGIWsfJEk6tchAQJIkieTdzKqqKm68+jL++s/n6Oo3yQseu6FiRyu1oXVcl6ysrBHTdIRwcc0ErhlDCIHm8aU3cIPZtk2oqIiSg7ojKYqCZnjQDA/CdXFsEyvWBwM/b+g6lm3T3tZG08BsgJE2oq5log6k27iOQ2lp6Ygb4by8PDZs2MCbb76ZnPh8ySWHzdtXFAVVN5KzHgzPqD63Q50cKIqCGsjijU1bycnKxO/2U+QP4KMPUbcREcxHyQ6hHDQjoLiklN7eXur27GLGrDnkF5eRsGy8xjv/nAohaGpsxHUc3nzzTerr60ccGDaS2tpann32WS6+eAWKotDVlezYpCoKfX19NDY2sXHjRkzTJHMUQ9q0gY9z85Yt5Gd4D1kYnvz1ttE1leK8LIoyfWheP6rXP2LHpRdffJHPf/7zvPbaa1xyySV86UtfIj8/n6uuuoriM7zrliSdSWQgIEmSRLIn/ic/+Unuvfde/vDAz/ng7Z8g4DXwGaNP5zieUhtagKuuuoqSkhJgoDbAtnDNGK5tohpeNH8QRTNG3FSnjsaPdFdfUVV0jw88PlzHwbVNHDNOImEiHId169ZhGMawTkLJUwUbw+sfyO1XDrm5T80hOFQLzZFouoEV70foI7+/kRzu5KC8vJyO9nb++dxaJldWcskF5xOwe1GibckBZd4MlKwQZOajqBqu65CTncWSJUtwXUF/PE5vzKQ50kJDfR0TJ1ZQkJ9PLBbjlXXrOOfcc9m2bRstLS2jCgQikQh9fX0IIXjiicc599xzOf/88wHwGAYdHe2YpkkwGDxszYawLUS0A2vvboKBYrY3NFLb3Q6Qnnqe+vx27NhBfm4OBg4Bvw/NG8DwZ474+W7ZsoUvf/nLPPHEEyxcuJDnnnuOiy666IjvS5IOJicLnxpkICBJkjTg//v//j8KCwv5r69+iQ/fdgctPTHKc0+dFKHy8nJs20ZRFITr4JpxHDOGomioXh9GIPOI/fId20YbZU//FFXTUDU/wuOjdv82hOvwoZtvJJYwQdMxTRNVVZPrchyUgULg5uZmOjs78Xq9h9zkH66F5khSpxaOZR5xBsJohIqKsG07nboUzA9hWfmI7DKMeFeyBWlrLbTvRwQLwJuN4ctNfi6qgs/jwYr34M/IYEJ1DR0dbfSbreiGl4Rpsr+ujrPPPnvUhdahUIiioiJ6e3vx+/1Dnneo0w3hOoi+LkRPO25vO6K3HdHXAwiKAc1OEJg3F4+h4ff56eyLgWBgQJiDPysHxYrx2uatTJhcNWR4W0ptbS3f/OY3+cMf/kBlZSUPPvggN9544ynzZ0OSpPGRgYAkSdIgFRUVuK7L9772Jb7wXz+goy9BQab/ZC8LGLj775jJAMB1UT0+jIycQ+azj/R8Vwj0MU7CTVEUhWBWNqtWrSIeizFj+lTOP+cchBVHaDpC03EtEzSNzq4u4rEYzzzzTLIgeZSpMaOhajrd3e3s2LWR7JycETeuo+E4DoqiMHny5HTtAoDHY+A4KqaSj55ZhGb2IbojiJ4W/EQQvZmIzAIcTxAhXBLxflrbOzF8fhoO1FNZPRVfdi5XXPd+rEQcv89L0O/FtB0MTT3sSUZlZSWG4cG0zGHTmiE5X6A0LwvR0469+w3cnjZEtBPEQVOiNQMlM4+EJ4Mtb+9h20tvEQwGWbJkyZD0oLVr17Jx40Zs2wbAn5k95DJNTU384Ac/4Gc/+xkFBQX89Kc/5fbbb8fjGV1qliQdiiwWPjXIQECSJGmQ973vffzkJz/h/l/8nLu+cTddcR8ZPhu/cXL+ukxu/m1cM45rJZKtLnUfhs8/6tQYSHabsSyLjIwMioqKxr2eg+9KZ+YVDOSXWziJOAgXzTDYtXMnHsPA4/EQjUZHlRozpBVq8n8Qyf8AAiFAIGhrbaOnp5uigjy6OjtpPLA/eedcGdhkKyqKqgCHTktK9t+3MQ6xodU0DVVVMS0bRw+wt9MhN6uUbCWG1+xFad2HpuqQVUhPZw+27eBD0NPRihUtoriiFFcITNtHwnboT9h09SeSt+GFSzDgw6OpGLqGrg5dpxCC/v5+VEVBJPpxe5J3+VP/xbGGLlZRUTLzUbMKUDLzULIKwBfEsm0ydJ0JbiYZxR3k5+cPqxEoLCzE5/Ol27AWFhYC0NnZybe+9S3uvfdePB4P3/jGN/jsZz9LIBBAkqQzhwwEJEmSBsnOzubOO+/ktttuw4334c/JINITZ0JuAO0EpkEI101u/s0YKEry7r8vDxQl3b1ntMLhME8//TRLly7l73//O1deeeVRDUw7OOc+WU+Q7Ejk2hYIl5nVlfRG+5h/9tkIIZgwoSKZSjRoQz980ME7eeupNqgooKCgDPxAVRRaW1tpaYlQkJvDgYZGMoJBigoLEcIZmKHgpmcppK+pKMm0KUVBGZhVAMnuSmLw9wZ9roqi4PUY1NbWUlZajKGpdHZDd7/JjEmViO4IdDUxxQtRXcPxa1x00UVs27aNbdu2UVNTg9+j4vfotLW1sXfrVnbs3EVp+QTmnb0Qrz+A1W8CYOgqHk0j0tSA29lEoGUvuQaYrW8N/4wC2ShZ+aiZ+ShZ+SgZOcMKwk3LSgczh5tzMH36dIQQtLW1UVhYSEVFBT/4wQ/4/ve/TyKR4Itf/CL/9m//Rk5OzpF+W0iSdBqSgYAkSdJBUnnPmcEgOZk+6jv7aI8mKMo6vilCycJfEycRQzg2qseLlpGNOsrUn0Nd00wkuHDpUl5Zt47e3t7jNjnZtS00jxdV03lz/etoqoI/I4ht20SamyguKkpv6FP77bEENClej0FhQQFvvfkmpmUxdfoMdN/Id6qTG36BcAWI5KAx4bq4jo2qqjhWAuEODhzEO6cKA//1GSr90SjBnFyefPIpzjv//OSE4ozcZFpUTwvBnlaIR3AT7RRrcXqb9tKkmRSXlIGq0tlQR7ZX5dILF2PZNiLWS15eNigKjgDLcbEcl4yAj2xTwQgkfw8m0PAXlg3c8c9HCeYdcQCabdsoJFu0jsaMGTPo7e3lvvvu44c//CHt7e187GMf4+tf/3q6KF2SjjU5WfjUIAMBSZKkg1x++eWoqsoFF1zA97//fc5fupzuhE1GwiLDe/hN2HiM2PPfGHlSLIDCwOTZI2yiHcfBsW2ysrJ45NFH6e3tPWK3mXG/B+Gm5wcA5Ofn89JLL6VTTpYsWYKmHZsTlenTp9PZ2Ulvby+FhYWHrRFIfkYKigaQXJtj22iqhm4M/7VMnRQMDhq6unvo7e2lTFG45OLleL1eHMtMzjMwfCj5FYi8cra//gp+t5eJoRwU10XXLERbHQBVQSDoBaLJf3ntOOxvQSgqmqIm1+MKvLaJrsELTQnKZswF49AtPw8WDofpjUYpKSkhOytrVM/Zt28f9913Hw888ADRaJQPf/jDfOlLXxpVBydJkk5/stxfkiTpICUlJTz44INEo1GuueYavvX1r5Dh0WjpjeM47pEvMApCuDiJGFZvB1ZfN4qiYGTmYgRzUD2+I/bTF4cpenNdFzORwHVdDI+HgsJCrrzySpYtWzas3eex4loW6qCWnjU1NSxevJiFCxcOK1A9WkIIMjMzWbp06ZgLhYUQ2I5zyM5J6enMqoaq6cmZCopGW2c3e2v38dSzz9Hd2weAbcYxY33YZvJUQWTk8symWn797AYO6EXsIw9l0jyUijko5TW0Gfnsjap06jkoBRNR8spRsoogkI0wfKBquKrGW202Wxo7ae+JjikIWLt2LYZh8LeHH6ahoeGQj7Usi8cff5yrrrqKqqoq7r//fj760Y+yd+9e7r//fhkESCdEqlj4RH8dD3V1dXzsYx9j8uTJ+P1+qqqq+PrXv45pmkMet3nzZi644AJ8Ph8TJkzgBz/4wXFZz1jIEwFJkqQR3Hjjjbz3ve8lMzOTX/3qV3z6zjvRsotojcYpzh5fweTIPf8zUQYm5Y6Woqq4Qgy7kyOEwLYsBKAbxpDWjqOZwns0HNtC9w5NnTpcbvpRvZbjoI0y7WWwcDhMIh4nOyeHgoKCUT+vpqaGzKxsenq6WbJkCdOmTweSk46TxdwOrm1TXTmJUEE+La1t2KbJ5MpKHKGwc9de2tvbk8W6Z52N6yZPalzHAgGqrqNqBjt37OCVVzayfNkygsEg+fn5o1pfavLwnDlzeP655w6Z/vXGG2/wpz/9iYceeoimpibmzZvHL37xCz7wgQ/IImBJOgo7duzAdV1+8YtfMGXKFN5++21uv/12+vr6uOeeewDo6enh0ksvZcWKFfz85z9ny5Yt/Mu//As5OTnccccdJ23tMhCQJEk6BI/Hw69+9Stuu+02qqdM4dEn/smsc5bQG7fI9I0+RUg4Do4Zw7Xig3r+Z40rPx5AVRQcx4GBzXCqA47ruui6jjqOTfLRSOXYn4jXTaXrKGOchRAOh3nyySe5aPlyHn30Ua644ooxBUZFRUWUlZYMC0AURUHRddSB9eR5/eTk5eE6NjgW0Wgc4bo0hA+Q4fPS3d5KIBBA1Q0MbwBlULBWU1ODEAKvz8eyZcuYNm3aYdckhMC2bYTr4vF4hqRipdK/TNPk0Ucf5d5772XNmjUAfOITn+D2229n3rx5o37/knSsua7APcEDvo7X611++eVcfvnl6R9XVlayc+dO7rvvvnQg8Kc//QnTNPn1r3+Nx+OhpqaGt956ix/+8IcnNRCQqUGSJEmHceutt/LMM88AUL93N5lendZoHPsIKUJCCBwzjhXtxIp2AmBk5GBk5qJ5xtb682CKotDb28u6detobGzENM1kapHHc8KDAADHNlFHyLc/Hpqbm2lpbT1s6stIIpEI1dXVbHn7bXp6eohEImN6vivEkE37oaiqim548PgCGL4ABw6Eyc7KZE5NDXX797Nl2w4Mfwaa4RnxerNmzaK0tJSqw6TnCCGwLAtrYJCb4fEQCoVYuXJlOv3L6/Vy9913U1FRwfvf/36EEDz44IP09fVx7733yiBAko6z7u5u8vLy0j9et24dS5cuHTKD47LLLmPnzp10dnaejCUC8kRAkiTpiPr6kjnhXq+XwkwfsY4+WnpjlGQHhvV/T/b8j+FaCVTdg+bNQBmUO38s7Nu3D1XTyMvNpW7fPmKx2DEb1jUermVh+DOO++uEw2E2b9pEqLiYTZs2cemll476rv6ECRNobmpiw4YN4yqYFkIw1l9BRVFQdZ1oLM7ql15G13Wmzzxyzr+qqlgDA74OXkPqBEAbOIUY/PuqvLwcy7L47ne/y69+9StUVeXDH/4wn/rUp45bmpYknY56enqG/Njr9eL1Hv2k8pQ9e/bw05/+NH0aAMmbGIMHFwLpv4eam5vJzc09Zq8/FvJEQJIk6QguvfRSrrrqKj7+8Y8zf948nvnHX+m3XHbtq2fNmjXs2L4NJ96P3duBE+tF0XSMzHz0jGxUw3NMgwBI3t2ONDXR3d3Nq+vX09LSckyvPxau6yR7/Z+AGQuRSITtO3awd+9ellxwAZZlHbZo+p01uuRkZ5OXnz+ugmkhRPI9juPXcebMmYSKipg9e/aoi6ZTcw9c102/vm1ZmINOADRNG7KeTZs28aEPfYjq6moeeughvvzlL1NfX899990ngwDplOSKd1qInqivVGbQhAkTyM7OTn9997vfHXGNX/ziF99pIHCIrx07dgx5TkNDA5dffjk33HADt99++/H+GI+aPBGQJEk6Ak3TePDBB1m5ciVr1qzh3z71STZfcjlaMIdQbgehnAzaWlsoLC0/qp7/oxUKhXj22WcpLy/n6quuwjhBaTkjcS0TTR95Ou+xFgqFCAaDHDhwgM7OTq697rr04CxNVUfcqKfSaDwez7gLpl0hUJXxBTpCCIIDHY7GQtM0Ojs6iPb1kZebSyAjA48+vKi8ubmZr3/96/zyl79kwoQJ3HPPPdx+++1kZBz/ExpJOl0dOHCArEEtdg91GvAf//EffOQjHznstQZ32WpsbGT58uUsWrSIX/7yl0MeV1xcPCwlMfXj4uLisSz/mJKBgCRJ0iikeuGvWbOGj370ozTV7SEY8FEU9PG7hx5l3vz5hCZMOiFrqaysZMWKFbS0tODz+SgKhXBdd0iXoBNBCIFrWxiB4Al5vfLyclauXEkkEiEUCg1MExY4joNpWegDk3RTm2UhBJZpYhhHl5rlugJ1nM8fy69LOBwmEolQHArh8/vRdZ0333yTSCQy7BTDtm1+/OMf881vfhNd1/nBD37AZz/7WfQxFlFL0slyPNt5Hu41AbKysoYEAodSWFhIYWHhqK7d0NDA8uXLWbBgAb/5zW+G/bk///zzueuuu7AsK33z5tlnn2XatGknLS0IZGqQJEnSqN199928//3v58EHHyQ/L48NG94kFo9z6dLzR93q8Vipqqri/PPPZ0JFBR6PB9uycEbIKz+ekgPEVJRx3i0fj/LychYsWJDeFCuKgq7reAwjOT/BsnBdl9raWsIHDtDW3n7UAZIrXFR1nIGAGF0QEQ6HWbVqFaZp4vf7UVWV+vp69u7dSzQaHXIncdOmTSxdupQvfOEL/Mu//Au1tbV87nOfk0GAJJ0kDQ0NLFu2jIqKCu655x5aW1tpbm6mubk5/ZhbbrkFj8fDxz72MbZu3cpDDz3ET37yE/793//9JK5cnghIkiSNmqZp9PX1kZuby8yZMxFCEOnsZHbVBDKyckY17fd4SHUMsm0b1zTRj/IO+Gglh4idmLSgI1EUBcMwEELQ0dGBbds0NzWx5e23WbFixVEVUwtXoOrj68Y02t8TkUiEaDRK+MABduzYwaxZs9i4cSNAurhZCMG3v/1tvvGNb1BWVsYLL7ww5pQjSZKOvWeffZY9e/awZ8+eYemHqTqm7OxsnnnmGT71qU+xYMECCgoK+NrXvnZSW4eCDAQkSZLGpLGxEb/fTzweTxdhCtfF7m7BjalogSMfNx8PqY2w4zjJdBjPsS9SHiydFuT1HbfXGA9FUdi1axe9vb3E43Gi0SgtLS1HFQi4QozrRCDVaWg0vw6p+of6AwcIBoOUlJQMSYMqLy/nd7/7HV/96ldZuXIljz766EmtDZGko+UIgXOCU4OO1+t95CMfOWItAcCcOXNYu3btcVnDeMnUIEmSpDH4yU9+wr59+7jzzjvTP6eoKnpWIU68DycWPYmrS55a6IaBZZq4jnPcXkc4NspBnWtOFaFQiHA4TPWUKeNqFXqw0XQmGslY6gNS9Q+DuxoNToMyTZMvfOELzJkzh/vvv18GAZIkHRPyRECSJGkMFi9ezJe//GW+/vWvc/PNN3PRRRcBoGgaRnYBVlcrqCqaN3DS1phqMWlZFqoQNDc3D7mzfCw4toVmDE0LShW7HsvXGY/KykqEEPj9fi677DImTZo07msdTetQ13WHTSI+nEN1NdqyZQv/8z//QyQS4emnn6akpGTMa5GkU82ZNFn4dCZPBCRJksboc5/7HMuWLeOGG25I93oHUDQDPbsAJ9qFa8ZP4grfSRXq7uqiu6uLl156iVWrVhEOh4/62kIIhG2jDGqVGg6HefLJJ4nHYuzatYtIJILruuO+m360qqqqkgFJWdlRXWe8rUPD4TBd3d00NjaO73VdlyeffJIrr7ySOXPm8Pjjj3Pvvfdy1llnjet6kiRJI5GBgCRJ0hh5vV4qKyvTA2UGU3UPemYedm8HrpU4SStMUhSFuv372VdXx7z584d1nxkv17ZQDuppH4lE6I/FKC4tpauri/7+fhzbxjJNzEQi+WWaWJaFbds4jjNioBAOh9mwYcMxCVhUVaU/Fjuq642ndWg4HGbnzp3U7t075uArHo/z85//nOnTp3PllVcSiUT43e9+R3NzM5/4xCfGunxJkqTDkoGAJEnSOFRXV9Pe3s6Pf/zjYd9TPT70YC52TzuubZ34xQ0SCoWYWVPD9m3bjkm+PCQDgYPTgkKhED6vl/a2NmzbxjAMDI8Hj9eb/jIMIz0RN9X/f3Cg0N3VRSQSoba29picXjQ0NLB71y62bt067uuNtXWo47r4/H5QFF555ZVRB19CCB566CGmTZvGJz/5Sc466yxeeukl3njjDT70oQ/JmgDpjONw4icLH7+qqdOXDAQkSZLG4fOf/zyf/exn+fd//3fKysr40Y9+NOT7qtePlpGN3dOGcE5sf//BikIhghkZnH322cOGUo2HEGJgfsDQ3PdUsWsgEOCSSy4Z8XUURUFV1WRBs65jGMaQQGFvbS2bNm2ipKSEOXPmHPXpRSQSYeObbzKrpmbcpyHJE4Ej/1Ppui6maeI4Dol4nD27d+O67qiCr9RcgPe///3MnTuX7du389e//pXFixefksXYkiSdOWSxsCRJ0jjdc889VFdX8+tf/5p77rmHO++8c0hxqObLANfF6mnDyC4ctnk+3pyBrkFFRUUUFRUdk2u6toWqjzynIFXsmjDNcc1UKCoqwrIs1q9fz4IFC5g+Y8ZRzWYIDUxcbm1tZdH55x9xQz5SsbM4QutQIURyfoMQGLqOqqqUlZUNa/05kng8zt13381///d/M3XqVJ5++mkuvfTScb1XSTrdnMzJwtI7ZCAgSZI0Tqqq8olPfAKfz8e//Mu/MGXKFH74wx+yaNGi9KZTC2QihIPd3YaeXYhylFNuR8sVAttx8BzjlBLHMtG9/sM+RtM0HMcZ86Tb1KlCagOdmZmJaVl4xjkgbfD1qiorycw69IyHxsZGamtrSSQSvP3221x88cWUl5cfMhBJpTal3qeuqkMed6gOQCkbN27k1ltvZc+ePXzta1/jC1/4Ah7PqTGcTZKkdw8ZCEiSJB2lD3/4wxQWFvKd73yH6667DsMw+OAHP8h1113HypUr0QLZOG4ndm87elbBcU/3EEJgWRbGQQW9R31d1wUhUI/QElNTVUzLQhvH3fyDN9AKHHUwkNrQW6ZJOBymsbGRUCjE5MmTcV0X23FQNY2W1lY0VWX+ggV4PB4s+52Urtra2nSAMnHSJGzbRlVVPGMc3Oa6Lj/84Q/58pe/zKxZs3jzzTepqakZ8/uSpNPdmTRQ7HQmawQkSZKOkqqqXHXVVaxZs4bXXnuNz3/+87z44otcddVVvPLKKyiKghbMBUXB7m0/7i01bdtGU9VRD7MarVRa0JEoioI6UBB8tDRNw9B1TMs67PVqa2tZt24dtbW1h1xTU3MzjuOwe/duOru66O7uRgiBxzCwLYv2tjZqa2t55eWXsSwLMdBzvL2jg63btrFlyxbiiQSdnZ14DGPMgVZLSwtXXHEFn//857nzzjt59dVXZRAgSdJJpYiT1eT5OOvp6SE7O5vu7m6yDnMcLEmSdDzYts2cOXOwbZt169aRn5+fzCfvbkXRdLRg7nE5GUilqxjjvIN+OGZfL4Y/Y1TpTak77ccqNcl1XSzLorm5ecgdfYADBw7w6quv0tDQQCAQYMWKFVRVVQ27xrp165KBhWGwZcsWqqurOf/889PfP7hGwBrI/d+yaROO65KdlcX69euZOnXqkOeNxvr167n++usxTZM//OEPshZAOmFOtf1Qaj0/eHYT/ozME/rasb5ePn/JWafMZ3EqOKknAvF4nPe+971MnTqVs846i0suuYQ9e/YA8Nprr3Heeecxb948ZsyYwQ9+8IOTuVRJkqQx0XWdX/ziF+zevZuvfvWrdHR0oCgKelYBwrZw+nuO+WumClePRxAgXCc5YXeUpwyqqiY7DB2je02qqtLc3IwQgrzcXFzHoauzE9uyQAiqKiv5wC230N/fT0tLy4jXqKioIBAI8PzzzxOLxYYVD5eXl7NgwYJ0alJymJhCfkEBRUVFPPfcc8Tj8TG3YP3d737H0qVLKS8vZ8OGDTIIkCSSHbmcE/wlJwsPd9JrBO644w6uuOIKFEXhZz/7GbfddhurV6/mjjvu4O677+Y973kPHR0dTJ8+nauuuoqZM2ee7CVLkiSNypIlS/i3f/s37r//fnbu3Mlzzz2Hoqro2QVYXa04iooWODZ3xMLhMIbHg+s4lJSUHJNrDuZYFpo+tmJWfZxFwyMRQuD1evm///u/dBvQRYsWcf7552M7Dm9s2ADA+2+6iVh8+FRn13UpLCggkUiki7krKysP+5quK9B0ldLSUiLNzcyfP39Uzxu85q985St85zvf4aMf/Sj33XcfXq93jO9ckiTp+DmpgYDP5+PKK69M//i8887jnnvuAZL5nF1dXQD09fXh8XjIy8s7GcuUJEkaF0VR+PGPf0xpaSnf+MY3kgW8hoGiahjZBVjdraCqyTajRyEcDtPY1ER7Wxv19fXHZF7AYEIIXNvE8AfH9Dz1KIqGD359y7JwHIe+vj6AIf35KysrWbFiBS0tLfj8/mH/VqSLpw2DysrKUW3kt23bRm5BAYoQFBQUUFFRQUVFxajX7Loun/jEJ/jlL3/J1772Nb7xjW/ImQCSNEjqLv2Jfk1pqFOqWPgnP/kJ11xzDQC/+c1v+OpXv0pFRQVTp07lO9/5DsXFxYd8biKRoKenZ8iXJEnSqeDSSy8lFovx29/+Nv1ziqajZxXg9HXjJmLjvrbrunh9PhobG9m2bdu4B2cdjnAdFEUdc+vTVNGw67rjfu1Ul5+u7m7KyspYsWIFixYt4pJLLhmyoa+qquL8888nNzcXADORSK59IAjQB3r8j8a2bdtYu3YtCgoNDQ3s2rlzTGs2TZP3v//9PPDAA/zmN7/hm9/8pgwCJEk6JZ0ygcB3vvMd9uzZw3e/+10Avve97/Hd736X+vp6tm7dyl133cW2bdsO+fzvfve7ZGdnp78mTJhwopYuSZJ0WHPnzuWWW27hjjvuYP78+Vx77bW0tLSg6gZ6Vj52tBPXSoz5urbjYNk2lmkSaW4GGNUk27FyLQvVGF+Pe03X04PNxiocDrNz1y527tzJo488QjgcTm/4D3dX3/B4EELQ0tLCnt27aWtrGzLo7Uja2tro7+8D12HNiy/S1tY26ufats3NN9/MP/7xD/72t7/xkY98ZNTPlSRJOtFOiUDgnnvu4ZFHHuHJJ58kEAjQ1tbGo48+yi233AIkj33PO+88Xn755UNe40tf+hLd3d3prwMHDpyo5UuSJB3RAw88wP33348Qgr///e/s3bsXANXwomfmYfe049rmqK4lhMA0TYTr4jEMSktLWblyJcuWLTs+aUHO6NqGjkRVFMTAdcYqEokQKipi06ZNYzrpUFWVfXV1KCRTUB9//HG2b98+4mO3bt3KmjVrhtxoKiwsJDs7B0OFkpISCgsLR/W6ruvy0Y9+lMcee4yHH36Y9773vaN6niS9G53oQuGTkYp0OjjpgcAPf/hDHnzwQZ599llycnIAyM3NJSMjg+effx5I3p1Zv349s2bNOuR1vF4vWVlZQ74kSZJOFX6/n9tuu41PfepTAOzfvz/9PdXjQwvmYHe3IRzrsNdxXRfTNNNtMFMpJwd3vDlWhOOgqNpRpbbomoY9jlOBUCiEx+PBdd0xn3S0trby5wcfxDAMlixZMuJd/a1bt9La1kZ7Wxtr165l69atAMyYMYPFixfhCsGyC5cyY8aMUb3mF7/4Rf70pz/xhz/8gauvvnrUa5UkSTpZTmqxcDgc5j/+4z+orKxk+fLlQHJDv379ev7yl7/wuc99Dtu2sSyLz3zmM2Pu2yxJknSqufnmm7nnnnu4+eabaW9vTwcGmjcArovV3YaRXYRyUCqLEALbcXBdd8zTbI+GY5vjTgtKUVUVe2Ag2FjWXV5eTnd3N8uWLUv39h+twsJCfD4ff/rzn7nu2mspnz0b13WH1AnE43HmzJnD9q1bqZoyhb6+PtauXUthYSHTpk7FNhP0xWKsWbOG/Pz8YcO/Bs8dWLVqFf/93//Nj370I97//vePep2S9G7luCe+eNcZf7nSGUsOFJMkSTrBurq6qKysZO7cuemTzxS7rxthxtCzi9LFuUKIZPcdVUXTju7u/FgIIbD6ejEyMo/6NS3bpqO9nXA4PKZNfcI08XrGF4hs376dtrY2CgsLqaqsxHEcPF4vqqriui59/f2sfuEFdu3axYQJE1i6dCnGQJDl8RioQmC7gqamJurr68nMzKSoqIjKykrC4TCrVq0iGo0SDAZpa2ujqamJn/70p7IwWDqlnGr7odR6vv74RnwZY+tEdrTifVG+efX8U+azOBWc9DkCkiRJ7zbBYJC+vj4yMjIwTRPPoI2uFsjCES49zfVs2XuA8gkTKCkpwTCMUXe9OVZcx0bR9SNubA+eyDuSlkiE3miU1atXEwwGj3ktw0gGp/SEw2EsyyJUVERDQwMer5eMYJDKykqys7MJBoMI1+Xxxx5DVVUuueRSAl4PL6xdy6SJE5k/bx7NkQjOwCAzr8fDkiVLeOqpp4hGo1RXV/Of//mfMgiQpFGS7UNPDSe9RkCSJOndRtd1fvazn/HEE0/wwAMPDPmeoijsqm+iKRKhoriA7p4eamtrT3gQAOBa5hGHiIXDYVavXo1wXTo6Ouju6sJMJIZ9eQyDzo4OgOPS4vRIa1y1ahVNzc30RqOUlJSQmZXFo488ghCC/Px8otEomVlZnL9oMXPnzcOxTfpj/USam9m7dy+//d3veOqpp3jsscfYvmMHpmWlf02CwSBNTU1yWJgkSacdGQhIkiSdBLfffjs5OTm89NJLWNbQAuG2tjaeXP0KamY+XT1RWltbT/j6hBDJ+QFHaLsZiUSwTJOcnBxeeeUVamtrMTwePF7vkK+EabJ582bg+LQ4PdIao9EoHe3tqJrGvro6mhoayMrKQghBbk4OEydOwnZcXMfGTCSwbYfCwkIWL17MhAkTyMzMHLZ2r8fDggULaG1tPaGBjSRJ0rEiU4MkSZJOkszMTB588EE6Ozu54447uPbaa4FkoWsgEOD/nn6KK6+5jq6WpmP6uqNJ5XHtZMvQI6W6hEIhTMviwIEDVE+ZQmFR0YjPKS8vZ+XKlUd83cGOVQlbKBQiGAyyc+dOpkyZQjAzE9dx6OrqorOzk6qqSuKxOLqu0drayuuvv85ll14CipLuVpefn09LS0s6CIg0N7Pl7beJx+PceOONTJ069ZisVZLeLWRq0KlBBgKSJEknyVtvvcWHPvQhVq1axVNPPcWmTZuYM2cOM2bMQAhBW1sbZryfwtLyMXfcOZSDi1wPlavvWiaa13/E6w3e4FdPmULmYQrwysvLx1wXcCwy7gevsauri1dffZXrb7iB91xzTbIFqwDLcfAqCgUFBaxYsYKc7GwUBuYouC4TJ05kQkVFsn1rIoFj27S3tyOEoL29/RisUpIk6cSTqUGSJEknSV5eHr/61a/47//+bwBuueUWfvzjHwMwc+ZMli5dSlmoECEEscTh5wuMViQSYfGSJay86ips2x4xpUW4LkK46a5FR5KaYRDMzMQyzWN2Jx+AY1R8O3jOgt/v56H//V9aW1vx6Dq2Y6f/MQwVF5ORkUFmVhb98TjNkQidXV0DqVIumqKwY8cOnn/hBYQQJzzNSZLOFO5JGCbmyhOBYeSJgCRJ0kkUCoX4z//8TyoqKvj+97/PZz/7WaZPn87ll18OJIuHM/1euvsTeAwdXTu6+zcTJ03i7S1b2L9/P1euXIlvhALXZFrQ2GcVqKqKoqq4joOmH/0/L0KIY3IiMNjg04Henh5s18WMx2ht76DQdYn29dHY2EhbawuqotLd28uUqioYKCrevXs3F154IY899lg6CKisrDzGq5QkSToxZCAgSZJ0Crjxxhu59tprufLKK7nuuut49dVXqaioICcnB0PX8BkavbEEORm+cacIua5LZmYmU6ZMITMzE49hkJefj+046IOKgh3bxPAFxvUauq5jmSbqMZh3EIlEsAa68xzLVqOpFKXdu3fjOg4NDQ20tXeQn5+P1+OhqKiIooJ8dI+HxsYmHv3737nwwgvJy8vjiiuuIBQKsXjxYgKB8X1GkiRJpwoZCEiSJJ0iDMPgscceY8aMGZx11ln4/X5uuOEGfvjDHyZTZAwfMdMm4DXGfG0hBJZl4fF4huTqCyGwbRvTdTF0HYQLAhT18N2CDkVRFHTDoLu7m7179455InBKOBxm/fr1lJWXs2XzZq644opjGgzs2LEDIUQyGCooAFWjJRLBYxh4vV46OztpaGykKFScvvP/u9/9jtraWp5++mkZBEjSUXLESSgWPjNn6B4VWSMgSZJ0CvH7/Tz66KPMnTuXWCzG73//ewoKCijIz+euz/8n/QkLx3HHfF3LstBHGA6mKEp6WJlpWTiWiWaMb5IvJAOLSCRCJBJh3759rFq1inA4PObrRCIR6urq6Onu5oKlS1FVFcd1x11/4LpuMuBJJIjHYpSVlqJrGt1dXbS3tRPt7WXTpk1seftt2tvbKSwspLKyioL8fIqKiujt7eVLX/oSN954I5deeum41iBJknSqkYGAJEnSKWbevHm8+eabbN26leXLl5OVlYWu6/zi5/fx97/9lX3hxjFtiG3HQVEUtMPMBNA1DUPXcSwTNI1t27axZs0atm/fPuyxqU46juNg2TamZZEwTRKmiWlZ2LZNbW0tzc3N4x4elmr5uWXLFl5cvRoA13EwLQvLsnDdwwdDB2/8U51+FFXF4/XS0NjI8y+8gGmZbNiwgfz8fBKJBOFwmLc2baKrq4tgMIOenh6mTJmS7jh0zz33jPm9SJI03IkuFD4Z7UpPBzI1SJIk6RQ1c+ZMnn/+eQCamppYuHAhH7/9Y+yorafuQAMH6mrJz8+npqZmxOfX1tbS2dlJZVUVOdnZR35BIVBUjc6ubiKRCPvr6+nv7ycrO5vCwsIhwYeqKCiKgqqqqAOnDMqg/9bX15NIJMbdVefguQOlpaUDSxTJdCbHQdg2qqpSu3cvkUiEigkTKC0txRUi+V4UBVXT8AyceAw2ffp0NE3D4/Fw4YUXMn36dPx+Py0tLRQUFJCfn88/Hn8i/bnH43E+/elPM2HChDG/F0mSpFOVDAQkSZJOAyUlJYTDYUzTZF/dfjLyCvB4vaxbtw4hRHrwVUptbS0bNmxg/oIFPPnPf3LuuedSVVV12Ndw7WRa0LY3NhJPJKieMoWu7mRQUFpSAjCqAuDxDA871HUOfq4yEIB4VBUhBHV1dbhCMG3qVGzHob2jg1AoNGzjP5LKyZMRQqAbyZqLyspKKiZMoKe3l57eXpqamggGg+Tl5bFy5Upqa2vH9T4kSRpODhQ7NchAQJIk6TTi8XiINDdRf+AAc+efTVZWNvX768jJyaY4FMIdyKMPZgSYUF5GY0MD8xcsIBgMYtk2mqqmN9ODCSFwbQsj4KOwsJDta9akh45VTp485g5A4xkeNlaKonDgwAFs2+btLVuor69n4cKFlAwELUfiuu+0ORVCpLsdZWQEiPb2snDhQvLz8zn77LP54he/SGFh4fF8O5IkSSecDAQkSZJOM3l5ebS1taGpCvkFhXh0FTORQFFVDE0HRSHa18SmzVvSm/lLL72UgoICHMdJps4Amqome/8rCrV79uD3GnTWHaCmpiY92biwsJAZM2ac5Hd8aIWFhXi9XjZt2kQwGBzTZl24Loqi4roulmVhGEYy/UkIKiZOZOKkSdx+++0Eg0HuvPPO4/guJEmSTg4ZCEiSJJ1mWlpaKC8vR1cEUdPkQGOEiRPK0LR3/kqvrKxkxYoVtLS0EAqFmDx5MkC6YDhV8GtZFvFYP7nZWeytq2Nf3f4RU41OVdOmTaOtrY0FCxaMKWhJ1Ts4joPrOHg8yQFq8UQCVUkGR/v37+e3v/0t3/nOd8jNzT2eb0OS3nVsV6Cd4FQdW6YGDSMDAUmSpNNMaWkpL7zwAvPmzWPGjBnMPmsuWcHhfe2rqqpGrAtwXRfhODi2Ca4LrkNPXx/dPVEqJk6koLCIeMJEVZPFwKl0olNRZ2cnHR0dVFZWjikVKZlClTwVMAaCANd1UYRIpwv993//N9nZ2Xzyk588XsuXJEk6qWQgIEmSdJqZPn06ra2t9Pb2Jgt5S0vpiyXQAj40beQi2cGbf+G6oCiomoHuNdhTV093dzfNzU307e0jMxgkVFSI6wpc4WJaFiLVhUdVURUVVR1eZ3CihcNh2tvbee6558jIyGDlypWjCgaEENimiaqqGJ53ZiZYtg0IVE2jvb2dX//613zxi18kIyPjOL4LSXp3ksXCpwYZCEiSJJ2GXn31Vb72ta/R2dmJx+NBxBP0xuI01u+nra2V/Px8ZsyYccjN/+CuOjU1NdTX15ORkYGu6+l2pJqmoA0aNyOEwHFdHNfBspP/oKqp4GAgMDiRwUEkEiEej1NUWEikpYVIJHLEQCCVDqWoCpphDPl5eKcr0a9+9Stc1+UTn/jEcX0PkiRJJ5McKCZJknQaSiQSuK6Lruuoqorf5wXHIa+wiJ7uLrKDARJ9vdhWAkXVMfwZeANBDK93xNaaPp+PjIwMsg8zb0BRFPSBvvw+rwevx0DXNQQCy3aSQ8USJpZl4zjOuKcAj1YoFKKhoYHq6upRzStwbBvbspKB08AJR4pt26gINE1HCMEvf/lLbrjhBtkpSJKkM5o8EZAkSTrNOI7D/fffzwUXXIA+kM+uqiqbN73J1GnTWbLofDZt3kLdgQaWLFlyxOuFw2HWr19PTk4Oe/bsGXWKjTJoqFhKqgjZdQWWbQECRVHRBuoNjuWpQXl5OYsWLcLn81F2mHalQghsywJIpwIpvLOO1GmA67rohod169axd+9eHnjggWOyTkmShnNPQmqQK1ODhpEnApIkSaeZv//979TX1/PhD394yM/n5+ezdctmotEo0b7+UXe6iUQi7N+/n9LS0uScgkhk3GtTFAVN0zAMfeDUwIOha4CCbTskTIt4wsS0rOR04KM8NSgvLycnO/uQswNS8wGUgXoARVGSbUMHBS+24wyZr/DQQw9RWlrK0qVLj2ptkiRJpzp5IiBJknQaeemll7j++usB6OnpGfK9mpoa/H4//bEESxadR2bO6AKBUChERkYGL7zwAldcfjker/eYrfedUwOAwa1LkycHpm0hGFSIrKqoYzw1UDUNx7bTrVFTBs8HGHxq4boO6kBRtRAi+TUoLeiRRx7hfe9736imE0uSND6OEDjHOX1wpNeUhpJ/y0mSJJ1GampqWLx4MQCf/exnaWtrG/L9SZMmUVlVRWZOLnYiPqo77uXl5axcuZJzzz0XfyBAYWHhcc3vT54aqBiGjtfrwef1YhgGiqLgOINODUwL23bS05IPRVXV9IY+ZXA9wMEbetd1UdVk0GDbNrqu4zgOqqaxadMmwuEw73nPe47Pm5ckSTqFyEBAkiTpNJKbm8tLL73ERz7yESzLoqioiB/96EdDHiOEQFU1NMOLlYiNOhhYsGABxcXFqKqKY9vH6y2MSD1sIbJ9xEJkVVWp27ePNWvW0NzUhDtoPsDBUoXCQghcIVAGfqwoCs888wyBQIALLrjgRL11SXpXSrUPPdFf0lAyNUiSJOk09PnPfx7LsmhsbORb3/oWn/3sZ4Hk3fbUP3WariNcB8dMoHt9o762pmnYloXjOMPSbU6UwxUiO66LZTuASM802F9/gEQi2Up027ZtFIVCI05HFsJNBwe246BrGq7rpKcyr127lsWLF+M9hulRkiRJpyp5IiBJknQamjFjBn/84x+ZO3cuXV1d1NfXv/PNQXfLNSPZKtMZ6JozGoqioBsGjm0n5w+cIlKFyO+cGnjQ9WSgkpGRwYQJE3CFYPeePXR0dIx4Dddx06lEyRQhNZ0WJITglVdeSadeSZIknelkICBJknQa+7d/+zdc1+X5558HGJYKoygKuteHY5u4jjPq66aCAWtgqvCpKN3+03EIZgR49plnyAwGufDCC5kxYwbOCLUFqfoAe+C0QwxKC6qtraWjo4Nzzz33ZLwdSXpXkalBpwYZCEiSJJ3GsrKyyMrKYt++femfi8fjbNiwgXA4DCQ3zIbXj23Gx3SHX1VVNF1P9+A/lezatYv169fT39cHQCAjg6nTptEciVBUWEh+fj6u4yTblNp2OiBITVh2B1qGuo6dTgvas2cPANOnTz85b0qSJOkEkzUCkiRJp7Gnn36anp4eJk2aBCSHg8VjMVavXk0wGEwPB1NUFd3jxUrEMXz+Ubfn1DQN13VpbW2lvr6eUCg0qmFjx9OuXbuo3buXc889l9dee43yCROYOnVquibAcRxs28YwjPSPTctCAfr7+2jct4/MYJAJEybgOA4eb/JxDQ0NAJSWlp6U9yVJ7yYn4w69PBEYTp4ISJIkncaKiooAyM7OBpLDwRoaGyksLCQajQ4ZDqZqevIO/yjbiqZEIhE6Ozp4++23WbVqVfqk4WTxeDycc845PPy3v/HmW2/R2to65PuapqGqKrZtJ1OcdB2PYdDY2Ihl24RCIZ566il27do5ZNJxU1MTBQUFeAamD0uSJJ3pZCAgSZJ0Gtu/fz8A/f39QHI42IEDB1gwfz7BYJBQKDTk8ZrhAUXBsUef7tPZ2Ul/fz+TJk4cFlycSK7rkojHycvN5W+PPEJPTw/BYDAdDA2m6zoIkW6DqigKfdFe6g+EMU2T884/H1VRaGhoTD+nra2NgoKCE/Z+JEmSTjaZGiRJknQa+81vfoPf7+ecc84BkvMAli1bhqooXHPNNRQXFw97ju7xYsVjuIqKqo/8z4AQAuG62LbNhPJynn7mGcLh8IjBxYngui6maaKqKlnZ2Vx44YW0trZSVFREdXX1iM/RDQPLNGGg21BBQQEJy+aRv/2ND9xyC67j8LdHH+X8/n5mzZpFV1cXubmjm8YsSdLRcUSyFfCJfk1pKBkISJIkncZ0Xee8885j6tSp6Z8rLy9HCJHcBI9AURQMnx8r3o+uqiP36rdtFFXF8HjI8XpZvHgxkUjkpNQIOI6DZZrouo4+kPc/derUIe95JIqiYHg8WKbJ3r17yc/LRSgqH/rgBwdONprp6elJtxq1BiYRS5IkvVvIQECSJOk0NnHiRH77298ybdo0Xn755XRqSyr33R3okX+wVFtROxHD8AWA5IY79fiDp/KWl5eflCJhe6Drj+HxjGu4maIo1O7bh8/rxevxorsuLS0ttLS00NDYQDAYJD8/H0h2SXJPobkJknQmc09CsbAri4WHkTUCkiRJp7FvfetbfOADH2DPnj1ce+21HDhwIP093TCwB3LkR6KqGpruwYz1YyYSKIDh8aDr+qi7Ch1PpmliOw4er/eoJhwnEgkKCwuxHZvf/+EPNDQ2Mn3aNEKhYpYsWUJNTQ2QLEI2D3GKIkmSdCaSJwKSJEmnsbKyMv74xz+Sn5/P//v//r/89a9/5d///d+B4acC4XA4nd5TWlqanBwsRPrEQDtEvcCJ5rpuOq3J4/EMSV0aC8dxsC2L6ilTsG2bX/36NwSDQYqLi8kIBrnggguGPD47O5uurq6jXb4kSaPguAJVtg896U6Nv/UlSZKko5IagmVZFlu3bk3f5U4VzLY0NbFq1SoCgQAZgQA93d1kZWejqipCCOxEHMe20HTjZL6NZFFwIoGm6+k5AKO1a9cuWltbKSsro6S4GAEgBKqqUn/gAAsXLiQ/P5/KyZNQRgguCgsLaWlpOTZvRJIk6TQgU4MkSZLOAB/5yEd43/vex1133cWsWbO4++67gYFTAVWlt7eXaDTKvLlzWf3ii+ytrU3faU/VCziWies4J3ztu3bt4uWXX+bAgQOYiQS6YYwrCHjhhRcoLysjMxikpbWVVHKT4fEwa9Ysli5dSk1NDY7joKrDU43Ky8vp7Oykb2BasSRJ0plOBgKSJElnAL/fz8MPP0xXVxczZ87ktddeS39P13XKSksJBoNoA/n/B7cAVRQFw+vHNuOIE1gwm9rAO45DMCODxqam5AyAMWptbSUajZKZlcUbGzYQzMhACDGsyNh1XVRFHbEGIjWded++feN+P5IkjY7tgu2KE/x1st/1qUcGApIkSWeQYDCIz+dj1apVLF++nF27dqEoCv5AgPdecw0F+fmsXLlyxA5AiqomZwyMcfLw0WhtbeXsBQuYWFHB7//wB5qamsZ1naKiIoLBIA8++CBLlizB6/WO2GnIsW1UfeTC41R61datW8e1BkmSpNONrBGQJEk6w/ztb3/jgQce4MEHH+SWW27hjTfeQNd1cnNzEULg9fkO+VxV09F0F9tMoHu8x7170PRp07Btmz8/+CCBQGDEKcGjUV1djRCCosJCEAJF04YFM8kZCU56FsHBCgoKmDBhAhs3buSmm24a1zokSRodWSx8apCBgCRJ0hlm0qRJfOtb32LmzJl84AMfYO/evVRVVaGoKmIUNQCa4cEdKB7WjeM3YMtMJAgGg+yvr+ecc8457JTg0ZhYUZFOB1IUhcRA56FUqpEQ4pBpQSlnn332kLQqSZKkM5lMDZIkSTpDXX311UyaNInbb78dSG6IhRCjSvvRPV5c28Z1Dj2H4GiYiUR60z516lQWL158VEFAIh4fUhOgqipejwfLtrEHgp/DpQWlLFmyhFdffVXOE5Ak6V1BBgKSJElnqMzMTD71qU/x6quvAqTvhI9meq6iKBg+H7aZOObFw4ODgPHOCBjs4CAgJR0MWBaWbeO6I3cLGuyCCy4gHo/z+uuvH/W6JEk6NGdgsvCJ/pKGkoGAJEnSGay8vJxYLMaPf/xjhBAoipIeJHYkiqKie3xYidgxKx4+UUFASioYsC0LUI5Y8zB//nxycnJ49tlnj3ptkiRJpzoZCEiSJJ3Brr32Wv71X/+Vz372s7z22msoioKqqrS0tLBhwwbC4fBhn69qGprhwT7KTkKu65KIxwHw+nwnJAhIUVUVTVVxhcA5wumGpmlcdtllPP7440e9PkmSDk2eCJwaZCAgSZJ0BvN6vfzHf/wHAL29vQBEWlroi0ZZvXo1q1atOmIwoOkGiqriWOPLm3ddF8s0URQFj9c7rmscLB6LjSoIAAbqIlwMw8A0zSOmRl199dVs3LiRhoaGY7JWSZKkU5UMBCRJks5wEydOJBAIsHHjRgCam5tpbGoiGAwSjUaJRCJHvIZmeBCui2NbY3rtYx0EOI5DPBYDGFUQACCEi6qq6LqOYRgkjhAMXHHFFWiaJk8FJOk4ck/CaYArTwSGkYGAJEnSGc7j8XD55Zdz77334jgOoVCIrKwsXNclGAwOmzI8EkVR0L0+HMvEHUULUjg+QYA10M1ntEEAgGM7qFqyhaiuaUcMBvLy8rjooot46KGHjnrNkiRJpzI5R0CSJOld4Ac/+AE1NTXU1dUxY+ZMMoNBbNumqKhoxCnDI1EUBcPrx0rEMHx+FGXke0m1tbVEIhFmzZqF1+vF4zn6WQSDgwCf3z/q5400REzXNBCChGniPUTR8s0338zHPvYx6uvrqaioOOr1S5IknYrkiYAkSdK7QFVVFevXrycnN5etW7fi9/uZP3/+qIOAFEVV0T1erPjIxcO1tbU8++yzTJ48mdraWg4cOHDUa08FAYqijCkIgHfSgg7uFqTrOoaukzBN9uzZw8svv8zu3bvT37/++uvx+/388Y9/POr1S5I0nCwWPjXIQECSJOldYOvWrbz66qt0dXWxe/duOjs7qa2tHde1VE1H1XVsMzHse5FIhGg0SjQapTcapa2t7ajWPTgI8Pp8Y3/+oLSgg6mqSl9fH5mZmbz66qs8//zz7Nq1C0jOYLjuuuu466676OnpOar3IEmSdKqSgYAkSdK7QHt7O9FoFNuymFpdTTQa5dlnn2Xv3r3jup6mG4AY1kkoFAoRDAb5xz/+QUdHB9OmT8ce5dyCgx1tEJBKCzo49cd2HOKJBAnTxLYsnnzySQCi0Sitra3px33oQx8CkMPFJOk4EEIg3BP8dYzmoZxJZI2AJEnSu0B+fj7BYJBdu3fT0dHBvPnzWXjOOXR2do7reoqiJIeNxWMoqpq+615ZWcmKFStoaWkhFAqRnZWF47qYloWmaWgjpOmM5HBBQDgcJhKJEAqFDpvatGfPHjyGTrSvnxkzZmDbNo7rJteuaaiqSm9vL4lE8mQjGAxSVFSUfv6KFSuYMGECjz76KBdffPF4PiZJkqRTmgwEJEmS3gVqamoQQhCLxWhvb+fF1aupqKhgxSWXYNk2uqaNaoM+WLJ4ODl52PCqKAN33quqqqiqqko/Th8IABzHwbSs5I81jV27dtHa2kpRURHV1dXpxzuOQ6y/H9u2aW1rG/K9cDjMqlWriEajBINBVq5cOWIwsHXrVvr7ooDCxEmT6Ovvx+v1DisOrq6uRggx4joUReH666/nz3/+Mz/5yU9G3aVIkiTpdCEDAUmSpHeJWbNmAcn2mLW1tbS0tJCTnY3rupimiabro75jn5IsHh4IBnyBQz5XURR0XUcTAtu26e7uZtOmTdTX1xMMBhFCMHXq1HQQ0NfXxx//9Kch34NkDYLP52PRokWsXr2aSCQyLBBwXRefz8eE8nJa2tp45plnqKioYOnSpSOuberUqenrH+ymm27iRz/6EWvXrmXZsmWj/lwkSTo89yT09ZdzBIaTNQKSJEnvMtnZ2dx444089thjKIqCpmnJFp9CYFoWzijnBKSomoZmeLATI3cSGkxRFAzDYM+ePdTMmsVHPvpR3nf99RSXlBCLxTBNE1VV0QyDm97//mF5+6FQiMWLFrFjxw6uuOKK9AwEMRBgmIkEtm0DYNo2jmXR19dHfn7+GD+lpIULF1JWVsYjjzwyrudLkiSdymQgIEmS9C4TDofp6upi69atPP3001xzzTU89thjRCIRmhobkzn9R5i+ezBNN1BUdVjx8KHk5ubi8/n4/e9+x98efphIczMKoCoKDY2N/O3hh3Edh5kzZw7J2y8pKSE3L4/KykqCwSAFhYWYicSQQWMej4eqqiqEEGTn5HDFFVdQU1Mzps8oRVVV3vOe9/DEE0/IQkNJOoaEECflSxpKBgKSJEnvMnPnzuXee+9l69atXH755axZs4b3vve9VFRUMHnyZLweD9///vexLAvTsnBdd1RBgWZ4EK6DY1tHfGxlZSUBv59zzjmHiy66iAnl5enC4OrqapYvX040GmXRokXpvP1wOExnZyeJRIKz5swhNzcXFXBJBgC6rg9JTcrJziYnN5fiUGhMQc3BVq5cyb59+9i5c+e4ryFJknQqkjUCkiRJ70Kf+MQnmDlzJvF4nPPPP5/77ruPWCzGN7/5TQC+9rWv8cMf/pAbb7yR9998Mw8//DDTpk7lzjvvPOQ1FUVB9/qx4v3JTkLqoYtrbcchFApRWFg4YnegqVOn4rouiYGTicbGRsLhMJMnTaKrsxNN0ygqKkJRFBzHobOzk507dxIKhaisrARA0zRi8Tjbt22jesoUmpqbaW9vp6CggJkzZ476s1q+fDkej4ennnqK6dOnj/p5kiRJpzpFnKHnJD09PWRnZ9Pd3U1WVtbJXo4kSdJpYfv27bz88ss8+OCDvP766yxatIiOjg4WL1nCVVddhW1ZhEIh5s6de8hruK6LnYjR2tFFc3Nzus3njh07aG1tpbS0lAkVFWiqetg5AUIIEokEZiJBLBajs6uLnu5u+mMxMjMzmT9/PkIIIpEI3d3d9Pf18fobb7BixQoqKysJh8Pk5OTQ3d2NaVkE/H7+NFCAvGTJkjGlC61YsQKPx8M///nP8XysknTSnGr7odR6Fn3rCXRfxgl9bTvexytfueqU+SxOBTI1SJIkSUqbMWMGt912G88++yzt7e089dRTvPbaa9z8/vfzvuuu46WXXmLfvn20DCrgPZiqqnR29+JaJpGWFlatWsXWrVtZt24doVAITdOo27eP/r4+TNNMBwG1tbWsW7eOuro6bMvCNE36+/pIWBZrX3qJ1tZWiktKmDF9OtOnTcMyTVzHoauri/Xr1yOACRMm4PP5sEyTrq4uFFVl7dq1tLe3EwgEuPzyy4knErS3t4/pc1mxYgVr1qzBNEdXAyFJknQ6kKlBkiRJ0jCqqg7pt3/OOeewc+dOiouLKSsr42tf+xoXX3wxPr+f5qYmQqEQ/f396X78PT095GZlMm/ObPw+H+3t7eTl51NUVISmaeiahjWwwZ80aRKdnZ3k5+WRm5NDLBajORKhrKyMjbt2MW3qVHJycmhsaMAwDMrLy/H6fHS0t7Nj504KCwupnDyZ3JwcJkyYQEtLC0KI9PobGxvp6enB7/ORk53Ne97zHhzbpra2Nj2YLJVOdCgrVqzgS1/6Eq+//jqLFy8+rp+9JL0byPahpwYZCEiSJEmjEgqF2Lx5M/Pnz+df//Vfuf/++znvvPPwejy0trSwd+9e6g8cICMjg8WLF+PLCGImYpQWh8jOy2dfbS0CUIC2tjbe2rSJhQsXEggEKC0tJRaL4fP5iEQiGLqOZZrMmD4d13WZNWsWvT09FBYWEggE6OrqIhaLUVZaim3blJeX0xyJ0NfXx+49e2hra6OwsJBJkyezYMECCgoKUBSF9vZ2SktL0XSdHTt2sHPnTrZv344QYsgQNBg6wfiss87C7/ezfv16GQhIknTGkIGAJEmSNGqzZ8+mra2N73//+3g8Hp5++mm8Xi9nnXUWZWVlLL3wQgJ+PwJobm7mxRdf5Ppr30t/IsHMmTPxGAbxeJz9+/czY8YMGhsbKSos5KG//AWAq6+6imhvL16vl1BxMR6vl7q6OnJzc+nv7ycnNxchBNu3b+fNN99Mzw9YuHAhGRkZPP/CCyw6/3xqZs6kuLiYaDTKhg0bWLhwYXqgmGWa7Nq9G4TggiVL6O/vJ5iRgZlIAMmi5+6eHt5++20OHDiA67qsXLmSuXPnsmHDhpP10UvSGUW4ya8T/ZrSUDIQkCRJksYkOzub73znO6xZs4ZYLEY0GqW9vZ2WlhZeWbeOvLw8zjvvPOLxOBcuXUrCsvFoGoauI4TAdV1KSkqItLSQnZ1NX18fAMFgkFg8TkVFBXl5eQghUBSFSZMmEY/FmDRpEpDcqOfl5eH1eolGowSDQfLz88nOzsbn89HY2MjUqVNpjkR44oknCAaDFBYWptevGwblZWW88cYbeL1eIi0tBDMzCRUXp1ulOo7D7NmzMU2T3bt3E4lEqKmpkYGAJElnFBkISJIkSeOydOlSKisr0+kz/f39NDc3k5eXx5o1a9Kb9Llz52KZJvPmz0Og4AsEyPz/27v34KjqM/7jn92QC2STDYSQCyFclltIgEQEBCoKqFRUxp+daglabwUdb2WQS5EB7c8qFa+11Kodrf2JYryPo0UjIApKJVWQSyKIEAnQBMhtsyEJ2Zzz+wOyNYCpJuScTfb9mjkzbM7mfJ99Zo377PP9fo9hqF///tq2bZvSBg7UmDFjFBkZqWPHjikxKUl+v1/+hgZ9u3evjhw5oqFDh8pRU6NvvvlGiYmJysjIkGmaKi8vV3x8vDIyMmQYhnJmzJBpmvLV1KixsVGjR49WQkKC0tPTA3E7HA7FxMZq+hVXaNfu3Ro/bpxcMTFq8PtlGIacDocMw9C7774beA2JiYlKT0/XSy+9dOI5TvbaANDxUQgAAFotNTVVqampgceDBw+WJHXt2lUlJSXq1auX6uvr9enWrfp882bFx8fr5z//uWJiY1VXX6+BHo/CnE6lJCfLGRamQ4cOaefOnSorK1PftDRFRkaqtrZWhYWFGjlihD777DO5XC5ddNFFyszMlHRit6Fdu3apT2qqorp2VXh4uGLdbqWkpPxg3E6nU66YGJ2TnS1Dkt/vV5cuXRQRHi6Hw6Hk5GRddtllgSInNTVVHo9HtbW1Onz4sJKSkto1r0BnZ8edfjvpjvltQiEAADjrPB7PaYtvy8vL1aNHDyUnJ+vqq6/WihUrVFJSov4DBigpJUWGYSgpMVGmaSohIUGRUVE6evSoUvv0UXh4uBoaGgLTgQ4fPiyPx6O9e/dq27ZtGj9+vN586y2NGzfutHF3794d2M1o4MCBgak/hmnKYZoKP/nh39/QoLCw/94E7dQip+nfBw8epBAA0ClQCAAA2l3Tt/dN+/e/+uqrmjdvntxut8rLynTo0CFVV1crIzNTVZWV2rdvn8LDw7V37175fD7FxMRo+PDh8gwcqP3ffSe32y1JKi0t1b59++QZOFDh4eGBAqHJ7t27tX79erlcLrlcLlVUVio2Jibw4d8wDPkbGhQeEaGwLl3U0NAQOHeq3r17Szqxm9CoUaPaO2VAp8b2ocGBQgAAYJn4+Hjt2bNHAwcO1OHDh7Vx40alp6droMejOLdbTkkREREaOWKEorp105gxY+StqpIpyd/QoH79+6tXQoJ2796tmJgY9e/XT42Njar2ejV58mSFh4fLW1Wl+vp6RUZGKjY2VhdMnKjE5GStXr1aPp+v2fafTqdTYWFh8vv9Cg8PD+xCVFpa2mxakCT16tVLkSd3MQKAzsD21U51dXW68sorNXjwYI0cOVIXX3yx9uzZI+nEXK777rtPgwcP1vDhwzVp0iSbowUAtJXH41FlZaVSUlLUrVs37dy5U2vXrVPNsWPaWVCg2tpafbt3r0pLSvT444/r2337VFpaqli3W7U1NUpJTtaY0aPVNSpKm/PzlZycLLfbrdLSUjmcTn2Ql6f/9+KLWvXKK6qoqND6jz/Wxx9/rEsvvVR90tJOi8cZFnZiN6PGRnXp0kW+6moV7Nyp9evX67333tOBAwdOPM/pVH19vebMmaOjR49anTYAOOuCoiMwe/ZsXXrppXI4HFqxYoV+85vfaP369XryySe1bds27dixQxERESopKbE7VADAWeB2u5Wdna2oqCgdOXJEtbW1OvfccwPnPR6Pvv32W0nS73//e0nSmjVrFB4ersTERDX4/aqpqdGcOXPUu3dvDRgwQB6PRzkzZsgzYID2798vn8+nwsJCjRkzRseOHVNFebmSkpNVUlqqb/fsUa9evTRo0CA5HA6Fh4fr+PHjinA6tXffPiUkJCgsLEw+n0+lpaXN1gpIUrdu3axLFtAJmYYp0+KpOlaP1xHYXghERUVp2rRpgcfnnXeeHnnkEUnSww8/rHXr1ikiIkKSWJwFAJ1Menq60tPTZZqmysrKVFdXp9LSUmVnZ+vxxx/Xc889p8mTJ2vJkiXq2bOnCgsLA7v2xPfooW3bt+vQoUP6+9//rgceeEBOpzNwzwCXy6WCggL94he/UE5Ojl566aUTU4piY5WYlKSCggIdP35c5eXlSkhI0KBBg+RvaFBiYqJqfD6ZphnYOrTJ/Pnz9dZbb1EIAOgUHGaQ7aV03XXXqUePHrr//vsVHx+vBx98UK+//rokae7cubrmmmvO+Hv19fWqP3lXSEnyer3q06ePqqqqFBsba0nsAADrGYahxpM7AVVVVqqoqEgVFRWqrq7WzJkz1dDQIEnasWOHKisr9a9//UtDhgzR+JNrBXZs367CwkJNnDhRAz0eOU92Avbs2dNsjYAkPfroo1q6dKmqq6u5lwA6BK/XK7fbHTSfh5riGbXoLYVFRVs6dmNdjb5Y9n/aNRf19fUaO3asvvrqK23ZskVZWVmBc9u2bdPtt9+u/Px8JSQk6M4779SCBQvaJY4fy/aOwPc9+OCD2rNnj9auXau6ujr5/X7V1tbq888/V1FRkcaPH6+hQ4dq5MiRp/3usmXLAu1jAEDocDqdcjqdCu/SRREJCeoRHy/DMORwOFRbWyuPx6PvvvtOmZmZ+vzzz+VyubRr1y65XC5lZGaq/4ABys/P19GjRzV06FA1HD+uxpNTjyorK/XFF19o7dq12rlzp9atWydJKi4uVt++fW1+5QCCzYIFC5SSkqKvvvqq2c+9Xq8uueQSXXTRRXr66ae1fft23XTTTYqLi9Ps2bNtijaICoFHHnlEb775ptasWaNu3bqpW7ducrlcuvbaayVJ/fr104QJE5Sfn3/GQmDRokWaO3du4HFTRwAAEDqaigLpv52CXbt3a8Mnn+iPf/yjJkyYoC+//FIVFRXKPuccVVdX69XcXLlcLiUnJ8vn86m2rk5hDofy8/Plcrk0duxY/fnPf242jsvlsuxJAzIAABFFSURBVOPlAZ1G0308rB6zPa1evVp5eXl64403tHr16mbnXnrpJR0/flzPP/+8IiIilJGRoa1bt+qxxx6ztRAIir7mY489plWrVunDDz9UXFxc4OczZszQ+++/L+nEjWg2b96sESNGnPEaTdvEff8AAISupi5BZESEJk+erHPOOUclpaUyTFMjs7JkGIZc0dGaNXu2Zl57rRKTkpT/73/L5/Np9QcfSJJ8Pp+8Xq8Mw1BFRYUKCgr09ddfKz4+3uZXB6C1vF5vs+P7U8tbq7S0VLNmzdKLL754xjVEmzZt0sSJEwPrXiVp6tSp2rVrlyoqKto8fmvZXggcOHBAd999tyorKzVp0iRlZWVp7Nixkk5M93n//feVmZmpiRMnauHChRozZozNEQMAOhqn06nly5dr544d+nd+vvZ8843+tWmTvv76a23+/HO5oqP17DPPaMrkyfJWVanG55N04pv/+Ph4ORwOxcXFKT09XUOGDLH51QBoiz59+sjtdgeOZcuWtel6pmnqhhtu0K233tps97PvKykpabbxgKTAYzt3xbR9alBqaqp+aL1yfHy83nnnHYsjAgB0VvHx8SosLAzcbbh3794aO3aslixZorVr10qSsrOztX37dpWXlys+Pl4ZGRk2Rw10PqZpw/ahJz9vFhcXN5s5EhkZecbn/+53v9NDDz3U4jULCwuVl5en6upqLVq06OwFaxHbCwEAAKySkZEh0zQDH/IzMzMlSffff3/gOTfffHPg5wA6nx87hfzuu+/WDTfc0OJzBgwYoHXr1mnTpk2nFRTnnnuuZs6cqX/84x9KSkpSaWlps/NNj+3cHp9CAAAQUr7/Id/n8+mpp54KbOF32WWX6S9/+YtdoQEhoyPcUCwhISFwX5KWPPnkk/rDH/4QeHzo0CFNnTpVubm5genu48aN0+LFi9XQ0KDw8HBJ0ocffqghQ4aoe/fuPymus8n2NQIAANglOjpa8+fPPzFNwTT17rvv/uA0AQA4k7S0NGVmZgaOwYMHSzpxh/Sm+5Dk5OQoIiJCN998s3bu3Knc3Fz96U9/arbjpR3oCAAAAADtyO12Ky8vT7fffrtGjRqlnj17aunSpbZuHSpRCAAAAMBihiE5LJ4aZBjWjNOvX78zboQzYsQIbdiwwZogfiSmBgEAAAAhiI4AAAAALNW0LsfqMdEcHQEAAAAgBNERAAAAgKVM48Rh9Zhojo4AAAAAEIIoBAAAAIAQxNQgAAAAWMowTBu2D2Wx8KnoCAAAAAAhiI4AAAAALGUapkyLv6G3eryOgI4AAAAAEIIoBAAAAIAQxNQgAAAAWIqpQcGBjgAAAAAQgugIAAAAwFKGacphWrx9qMXjdQR0BAAAAIAQREcAAAAAlmKNQHCgIwAAAACEoE7bETBPzgPzer02RwIAAGCPps9BJvPjcQadthCorq6WJPXp08fmSAAAAOxVXV0tt9ttdxgBpmnD1CCKodN02kIgJSVFxcXFiomJkcPhsDucNvN6verTp4+Ki4sVGxtrdzgdDvlrG/LXduSwbchf25C/tuuoOTRNU9XV1UpJSbE7FAShTlsIOJ1Opaam2h3GWRcbG9uh/gAFG/LXNuSv7chh25C/tiF/bdcRcxhMnYAmpmHKYLGw7VgsDAAAAIQgCgEAAAAgBHXaqUGdTWRkpO69915FRkbaHUqHRP7ahvy1HTlsG/LXNuSv7cjh2WWapuWLd1ksfDqHSVYAAABgAa/XK7fbrf43vyhnRDdLxzaOH9O+565TVVVVh1vn0V7oCAAAAMBS3Fk4OLBGAAAAAAhBFAJB6L333tOoUaMUGRmpOXPmNDtnGIbuvPNOeTweDRw4UCtWrGh2/o033tDw4cOVmZmpzMxMFRUVWRd4kGhL/iTp8OHDSkxM1JVXXmlNwEGmtfl78sknlZmZqeHDh2vEiBFauXKlxZEHj9bm8Me8P0NNaWmprrrqKo0YMULp6el64oknAudqa2v161//OvD3bvr06Tpy5Ih9wQaplnIoSR9//LFGjx6tjIwMDRs2TJs2bbIn0CD1v/InnXgvDhs2TFlZWZbH11EZJ7cPtfpAc0wNCkKDBg3S888/r9dee00+n6/ZuZUrV6qgoEC7d+9WVVWVsrOzNWnSJGVkZGjLli1avHix1q1bp5SUFFVXVyssLMymV2Gf1uavyS233KLLL79cZWVlVoceFFqbv4yMDH366adyu90qLi5Wdna2xo0bJ4/HY9MrsU9rc/hj3p+hZu7cuRo2bJjefPNN1dTUaMKECZowYYJGjx6tZ555RseOHdP27dvlcDg0a9YsPfzww1q+fLndYQeVlnJ46NAhXX/99Vq9erXS09NVX1+v2tpau0MOKi3lr8nChQs1YcIE5efn2xgp8NPREQhCgwcP1siRI9Wly+l1Wm5urmbNmqWwsDD16NFD11xzjVatWiVJevTRRzV37tzA3QNjYmLUrZu1C3GCQWvzJ0nPPfec+vfvr/PPP9/KkINKa/M3ZcqUwE1r+vTpo6SkJBUXF1sae7BobQ7/1/szFH311VeaNm2aJCk6OloTJ07Uiy++KElyOBw6duyYGhoa5Pf75fP5OuWNJNuqpRw+9dRTysnJUXp6uqQTO+PExcXZFWpQail/krRmzRodPHhQM2fOtCtEoNUoBDqY/fv3q2/fvoHH/fr10/79+yVJBQUF2r9/vy644AJlZ2dryZIlamxstCvUoNRS/vbt26enn35aDzzwgF3hBb2W8vd9a9asUUVFRbNvzHBCSzn8sfkNJaNGjdLLL78swzB05MgRffDBB4Epj7fccotiYmLUq1cvJSYmqqqqSnfccYe9AQehlnJYUFCg2tpaXXTRRcrKytKdd96pmpoaewMOMi3lr7KyUgsWLNBf//pXe4PsgEyj0ZYDzVEI2GDcuHHq2bPnGY+2fIPq9/u1ZcsWvf/++9q4caM+++yzTvnHqT3yZ5qmbrrpJq1YsUJdu3Y9yxEHl/Z6/zXZvn27brzxRuXm5io6OvosRBx82juHoeR/5fLRRx+Vz+dTdna2cnJydOGFFwY6LXl5eTIMQyUlJfrPf/6juLg4LV261OZXZL225NDv9+uTTz7Ra6+9pvz8fFVUVOjee++1+RVZqy35u+OOO3TPPfeoV69eNr8KoHVYI2CDtizESktL03fffadx48ZJkoqKipSWlhY4d9VVVwU+yF511VXatGlTp/uGrD3y5/V6tW3bNl1zzTWSJJ/Pp2PHjmnKlClau3btWYk7WLTX+0868e3i5Zdfrueff14/+9nP2hxrsGrP/4Zbym9n9GNy+cILLwT+feuttwbWTDz77LPKyclRVFSUJGnmzJl68MEH2yXOYNaWHKalpSkrK0vdu3eXJM2YMUPLli1rlziDVVvyt3HjRm3cuFHz5s1TXV2dysvLNWTIEO3atau9wu007PiGno7A6egIdDC//OUv9be//U2NjY0qLy9Xbm5u4MNrTk5O4Bsyv9+vvLw8jRw50uaIg8sP5c/tdqusrExFRUUqKirSI488oksuuaTTFQFt1dL7r7CwUNOmTdOzzz6riy++2OZIg1dLOWzpXKgqKytTQ0ODJGnLli16++23ddttt0mSBgwYoLy8vMAdSt977z1lZmbaGW5QaimHOTk5+uijj1RfXy9JWr16Nf/fOEVL+Wv6f0ZRUZFeeeUVDRs2jCIAHQodgSC0du1aXX/99fJ6vTJNU6+//rqeeuopTZ8+Xdddd53y8/M1aNAgORwOzZ07V8OHD5ck/epXv9KXX36pjIwMhYWF6fzzz9dvf/tbm1+N9VqbP5zQ2vzdddddqqqq0sKFC7Vw4UJJ0kMPPaSpU6fa+XJs0doc8v483ebNm3XXXXepS5cuiomJ0auvvqrk5GRJ0n333afZs2cHPvwPHTpUzzzzjJ3hBqWWcjh+/HhNnz5d2dnZCgsLU0ZGhp5++mmbIw4uLeUP6OgcpmmyqSoAAADandfrldvtVu8Zz8gZYe2aPON4rQ6uukVVVVWKjY21dOxgxdQgAAAAIAQxNQgAAACWMhsbZVq8xbnV43UEdAQAAACAEERHAAAAAJYyTRu2DzXpCJyKjgAAAAAQgigEAAAAgBDE1CAAAABYijsLBwc6AgAAAEAIoiMAAAAAS9ERCA50BACgnb3yyiu6+uqrz+o1L7nkEq1Zs+asXhMAEFooBACEpAsvvFBPPPFEu49jGIbuueceLVmy5LRzH374oaZMmaLbbrvtjPFFRkbK5XIFjp49ewbOL168WPPnz2/X2AEAnRuFAAC0o3/+85/q0aOHhg8ffsZzL7zwgrxerwzDOO38Qw89JJ/PFziOHj0aODdx4kRVVlbq008/bdf4AaA9NE0NsvpAcxQCAPA9paWluvrqq5WQkKC0tDQtXrxYfr8/cL5fv35avny5zjvvPMXExOiCCy5QcXHxD17vnXfe0eTJk8947o477tCiRYs0ZcoUOZ0/7c+xw+HQ5MmT9c477/yk3wMAoAmFAAB8T05OjsLDw7Vv3z5t2LBBb7/9tpYvX97sOStXrtSqVat05MgRRUdHn3HaT5OtW7dq6NChZzzn8Xi0cuVK3Xjjja2KddiwYdq6dWurfhcA7GQahg0dgdM7r6GOQgAATjp48KDWrVunxx57TC6XS3379tXixYv1wgsvNHvebbfdpv79+ysqKkozZ87UF1988YPXrKioUGxsbKviWbRokeLi4gLHxRdf3Ox8bGysKioqWnVtAADYPhQATjpw4ICioqKUmJgY+NmAAQN04MCBZs9LSkoK/Ds6OlrV1dU/eM3u3bvL6/W2Kp5ly5Zpzpw5P3je6/Wqe/furbo2AAAUAgBwUmpqqurq6lRaWhooBoqKipSamtrqa2ZlZenrr78+WyE2U1BQoKysrHa5NgC0J8NolCxevGuwWPg0TA0CELL8fr/q6uoCR8+ePTVp0iTNmzdPNTU12r9/vx544AFdf/31rR7jiiuu0EcffXQWo/6vjz76SJdffnm7XBsA0PlRCAAIWfPnz1fXrl0Dx5AhQ/Tyyy+rtrZWffv21YQJE3TZZZdpwYIFrR5j2rRpOnr0qHbs2PGTf3fhwoXN7iPgcrlUVlYmSdqwYYNiY2N1/vnntzo2ALAL24cGB4dpmqbdQQBAZ7Zq1Sq9/fbbys3NPWvXnDp1qubNm3faAmIACGZer1dut1s9Lv2/coZHWTq20VCn8tVLVVVV1epNHDobCgEAAABYoqkQ6D71XlsKgYoPfk8h8D1MDQIAAABCEIUAAAAAEILYPhQAAADWamyU6bR48W4ji4VPRUcAAAAACEF0BAAAAGAp07T+hmKmSUfgVHQEAAAAgBBEIQAAAACEIKYGAQAAwFKmYVg/NcgwLB2vI6AjAAAAAIQgOgIAAACwlGnYsFjY4vE6AjoCAAAAQAiiIwAAAABLnVgjYO2cfdYInI6OAAAAABCCKAQAAACAEMTUIAAAAFiKxcLBgY4AAAAAEILoCAAAAMBSdASCAx0BAAAAIARRCAAAAAAhiKlBAAAAsJRhNMrB1CDb0REAAAAAQhAdAQAAAFjKbDQkh8UdgUbuLHwqOgIAAABACKIjAAAAAEuZpg3bh5qsETgVHQEAAAAgBFEIAAAAACGIqUEAAACwlGk0Wr9YmO1DT0NHAAAAAAhBdAQAAABgKToCwYGOAAAAABCCKAQAAACAEMTUIAAAAFiKqUHBgUIAAAAA1mpskGnDmGiOQgAAAACWiIiIUFJSkkoKXrVl/KSkJEVERNgydjBymKZpeUEGAACA0FRXV6fjx4/bMnZERISioqJsGTsYUQgAAAAAIYhdgwAAAIAQRCEAAAAAhCAKAQAAACAEUQgAAAAAIYhCAAAAAAhBFAIAAABACKIQAAAAAELQ/wdK0wS5sq3vwAAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "buses = pw[Bus, ['BusNum', 'BusPUVolt']]\n", + "lon, lat = pw.buscoords()\n", + "\n", + "seller_bus = int(buses['BusNum'].iloc[0])\n", + "buyer_bus = int(buses['BusNum'].iloc[-1])\n", + "\n", + "ptdf_df = pw.ptdf(seller_bus, buyer_bus, method='DC')\n", + "\n", + "ax = plot_sensitivity_map(\n", + " lines_geo, ptdf_df['LinePTDF'].values,\n", + " shape=SHAPE,\n", + " title=f'PTDF: Bus {seller_bus} \\u2192 Bus {buyer_bus}',\n", + " clabel='PTDF',\n", + " figsize=(8,8)\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "a9", + "metadata": {}, + "source": [ + "## 3. LODF Redistribution Pattern\n", + "\n", + "When a branch trips, its flow redistributes across the remaining\n", + "network. LODFs quantify each line's share. The outaged branch is\n", + "shown as a dashed black line on the base-case loading map, then\n", + "the LODF pattern shows where the power reroutes." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "a10", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAv8AAAKJCAYAAAAsgEb+AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOzdd3xV9f348de5OzfjZicEQoCEsPeSIaAQEEQRt+KqVatWW/q1jg5HrdZq3W1/1ap1tIIDBRUFQcQFyBJkE1YgjOzkZt19P78/TnIhZDCE3Gjez8fjPMI994zPPRm8z/u8P5+PppRSCCGEEEIIIX7yDOFugBBCCCGEEKJ1SPAvhBBCCCFEOyHBvxBCCCGEEO2EBP9CCCGEEEK0ExL8CyGEEEII0U5I8C+EEEIIIUQ7IcG/EEIIIYQQ7YQE/0IIIYQQQrQTEvwLIYQQQgjRTkjwL4QQQgghRDshwb8QQgghhBDH+Oqrr7jgggtIS0tD0zTmz5/f4H2lFA888AAdOnQgIiKCiRMnsnPnzgbblJWVMXPmTGJiYoiNjeXnP/851dXVrfgpGpPgXwghhBBCiGPU1NQwYMAA/vnPfzb5/hNPPMHzzz/PCy+8wKpVq4iMjGTy5Mm43e7QNjNnzmTLli0sWbKEBQsW8NVXX3HLLbe01kdokqaUUmFtgRBCCCGEEG2YpmnMmzePiy66CNCz/mlpadx111389re/BcDpdJKSksJrr73GlVdeybZt2+jduzdr1qxh6NChACxatIipU6dy4MAB0tLSwvJZTGE5qxBCCCGEaJfcbjderzcs51ZKoWlag3VWqxWr1XpSx9m7dy8FBQVMnDgxtM7hcDBixAhWrlzJlVdeycqVK4mNjQ0F/gATJ07EYDCwatUqZsyY8cM+zCmS4F8IIYQQQrQKt9tNUkQU1QTCcv6oqKhGNfcPPvggDz300Ekdp6CgAICUlJQG61NSUkLvFRQUkJyc3OB9k8lEfHx8aJtwkOBfCCGEEEK0Cq/XSzUBfkNXrK3c9dRDkGeq95Kfn09MTExo/clm/X/sJPgXQgghhBCtKgIDNoytes76W42YmJgGwf+pSE1NBaCwsJAOHTqE1hcWFjJw4MDQNkVFRQ328/v9lJWVhfYPBxntRwghhBBCiJPQtWtXUlNTWbp0aWhdZWUlq1atYuTIkQCMHDmSiooK1q1bF9rm888/JxgMMmLEiFZvcz3J/AshhBBCiFZloPUz0Cd7vurqanbt2hV6vXfvXjZs2EB8fDydO3dm1qxZPPLII3Tv3p2uXbty//33k5aWFhoRqFevXpx33nncfPPNvPDCC/h8Pu644w6uvPLKsI30AxL8CyGEEEII0cjatWs555xzQq//7//+D4Drr7+e1157jXvuuYeamhpuueUWKioqGDNmDIsWLcJms4X2efPNN7njjjuYMGECBoOBSy65hOeff77VP8vRZJx/IYQQQgjRKiorK3E4HPyRzFav+XcT4BF243Q6f3DN/4+ZZP6FEEIIIUSr+jGU/fxUyXUQQgghhBCinZDMvxBCCCGEaFWS+Q8fuQ5CCCGEEEK0ExL8CyGEEEII0U5I2Y8QQgghhGhVUvYTPnIdhBBCCCGEaCck8y+EEEIIIVqVVre09jmFZP6FEEIIIYRoNyTzL4QQQgghWpXU/IePXAchhBBCCCHaCQn+hRBCCCGEaCek7EcIIYQQQrQqKfsJH7kOQgghhBBCtBOS+RdCCCGEEK1KMv/hI9dBCCGEEEKIdkKCfyGEEEIIIdoJKfsRQgghhBCtSqP1M9Ayw69OMv9CCCGEEEK0E5L5F0IIIYQQrUo6/IaPXAchhBBCCCHaCcn8CyGEEEKIViWZ//CR6yCEEEIIIUQ7IcG/EEIIIYQQ7YSU/QghhBBCiFYlZT/hI9dBCCGEEEKIdkIy/0IIIYQQolVJ5j985DoIIYQQQgjRTkjwL4QQQgghRDshZT9CCCGEEKJVSdlP+Mh1EEIIIYQQop2QzL8QQgghhGhVkvkPH7kOQgghhBBCtBOS+RdCCCGEEK1KMv/hI9dBCCGEEEKIdkKCfyGEEEIIIdoJKfsRQgghhBCtSqtbWvucQjL/QgghhBBCtBuS+RdCCCGEEK1Ko/Uz0JL510nmXwghhBBCiHZCgn8hhBBCCCHaCSn7EUIIIYQQrUrG+Q8fuQ5CCCGEEEK0E5L5F0IIIYQQrUoy/+Ej10EIIYQQQoh2QjL/QgghhBCiVUnmP3zkOgjRjDfffJNRo0YRHR1NVFQUI0eO5L///e8pH++hhx5ixYoVp7GFp9fAgQO54YYbWtzmhhtuQNO00BIZGcmAAQN45ZVXWqeRJ+m1115D0zRKSkpOy/Fef/11zjrrLOLj47HZbPTo0YM///nPeDyeRtu+8sorZGdnY7PZGDBgAAsWLGjwfl5eXoNrWb+cddZZjY4VDAZ55pln6NmzJ1arldTUVGbOnHnc9q5Zs4acnBxSU1OxWq107tyZn//85xw6dKjRtitWrGDkyJFERESQkZHB448/jlKqwTZdunRpss1ut/uUztmUoqIioqOj2bx5c2jd22+/zSWXXEKnTp3QNI0nn3yyyX03b97MtGnTSEpKIjY2lrFjx7Js2bJmz3XgwAGioqJO6Gfk6O/XokWLGr3/0ksvhd6v17lz50bfJ6UUiYmJWK3WRj83v/71r4mJiSEQCFBVVUV8fDzLly9vsV1CCHGyJPgXogl33nkn1157Lb179+bdd9/lvffeo2/fvlx//fXceeedp3TMP/3pT206+D9R3bp1Y+XKlaxcuZL58+czevRobrrpJt56661wN+2MKysr47zzzuM///kPCxcu5Gc/+xl/+ctfGv1MvPXWW9x8881cccUVLFy4kJEjRzJjxgy+/fbbRsf8y1/+ErqeK1eubPJG6he/+AWPP/44d955J4sXL+bZZ58lLi7uuO0tLy+nZ8+ePPfcc3z66ac89NBDLF26lPPOO69B4Llr1y4mT55Mhw4dWLBgAbNmzeKBBx7gqaeeanTMSy+9tEF7V65cidVqPelzNufRRx9l/Pjx9O3bN7Ru7ty57Nmzh2nTpjW7X0lJCRMmTKC0tJRXXnmFt956i6ioKKZMmcKmTZua3Oeuu+4iKirquG06WlRUVJM/63PmzGl0rNGjRzf6nd+xYwdlZWUYDAbWrl3b4L3ly5dz1llnYTQaiY6O5s477+T3v//9SbVPCCGOSwkhGvjggw8UoB588MFG7z3wwAMKUB9++OFJHxdQf/vb305DC8+MAQMGqOuvv77Fba6//nrVp0+fRusHDhyoLrvsshb3ra2t/SHNOyWvvvqqAlRxcfEZO8fvf/97FRERofx+f2hddna2uuqqqxpsN3LkSDVlypTQ67179ypAvfvuuy0e/7PPPlMmk0lt3LjxtLR38eLFClDLly8PrbvllltURkaG8ng8oXW/+93vVGxsrHK73aF1GRkZ6pe//OVpOWdTqqqqVGRkpHr//fcbrA8EAqF/N/d7NGfOHAWovXv3htbV1tYqm82mHn744UbbL126VMXHx6snn3zyhH5G6r9fM2fOVDExMcrlcoXeO3TokDIYDOqaa65RR/+3+o9//EMB6uDBg6F1L7/8surVq5caP368evzxx0Prq6urlclkUn/6059C6/Ly8hSgNmzY0GLbhPgxcTqdClBvkKnmkt2qyxtkKkA5nc5wX4awksy/EMeoz6r+9re/bfTe3XffTVxcHM8++2xo3fjx4xtlJDds2ICmaXzxxRcAoVKAu+++O1QaUP/eU089xbBhw3A4HCQnJzNt2jRyc3MbnfvFF18kIyMDu91OTk4O69evR9M0XnvttQbbvfbaa/Tv3x+bzUbHjh35wx/+QCAQaLDNihUrGDJkCDabjb59+7Jw4cKTvEoNRUdH4/P5Qq+/+OILNE3j448/5tJLLyUmJobLLrsMgDfeeIMxY8YQHx9PXFwc48ePZ/Xq1Q2O99BDDxEVFcWmTZsYM2YMdrudvn378umnnzY69xtvvMGgQYOw2WwkJiYydepU9u3b12Cb/Px8pkyZQmRkJN27d+eNN974QZ/3aAkJCfh8PoLBIAB79uwhNzeXyy+/vMF2V155JUuXLj2h7PfRXnrpJcaPH0+/fv1OW3sBvF5vaN3ChQu56KKLsFgsDdpbUVHBypUrz8g5mzJ37lwApkyZ0mC9wXD8/6rqf/4cDkdonc1mw2KxNCpf8vl83HHHHfzpT38Kte1ETZkyBU3T+OSTT0Lr3nrrLbKyshgyZEiDbceMGQPQoHRn+fLljBo1ipEjRzZYv2rVKvx+P6NHjw6ty8jIYPjw4Y1+x4UQ4oeQ4F+Io/j9flasWME555zTZDlAVFQU55xzDitWrMDv95/wcesDqDvvvDNUKjF48GBArzu+4447+OCDD3j55ZcJBoOMGjWKsrKy0P4ffvght956K5MmTWLevHlMnDixUXAJ8PTTT3PTTTcxefJkPvroI+69916ef/55/vCHP4S2KSgoYPLkyVitVt555x3uvvtubrvtNg4ePHhS18nv91NRUcF//vMfli9fzqWXXtpou1tuuYXMzEzmzZsXupnKy8vjuuuu491332X27Nl07tyZsWPHNrrh8fl8zJw5kxtuuIF58+aRnJzMJZdcQmlpaWibv/3tb1x//fUMGTKE999/n1deeYXu3btTXFzc4FgzZ85k0qRJzJ8/n0GDBnHDDTewbdu20Pv1fQPqb8hO5PPX1tby9ddf8+yzz3L77bdjNpsB2L59OwA9e/ZssE+vXr3wer3s3bu3wfrbbrsNo9FIcnIyN998c4PvO8C3335Lz549mTVrFrGxsURERHDeeec1eYPYnEAggNfrZfv27dxzzz0MHjw4FJjW1NSQn5/fqL09e/ZE07TQ56n35ptvYrVaiYqKYurUqc2W1LR0zuZ89tlnDB48GJvNdsKfrd60adNISUnhrrvu4vDhw5SUlPC73/0OTdO45pprGmz73HPPYTQaue222076PFarlYsvvpg5c+aE1s2ZM4errrqq0bb9+vUjJiamyeB/1KhRDUqCli9fjslkatTnY9SoUSxZsuSk2ylEW2cI0yJktB8hGigpKcHj8dC5c+dmt+ncuTNut5vS0lJSUlJO6Lj1/6F37ty50X/uzzzzTOjfgUCAnJwckpOTmTt3LrfccgsAjzzyCOeeey4vvfQSAJMnT8bn83H//feH9q2qquLBBx/knnvu4S9/+QsAOTk5WCwW/u///o+7776bhIQEnn32WTRNY+HChaEsaXp6OhMmTDihz7Jly5ZQoFvvrrvuarID6oUXXsjjjz/eYN0DDzwQ+ncwGCQnJ4fVq1fz2muvhdoNepb4r3/9K1OnTgWgR48edO3alYULF3LNNdfgdDp56KGHuOWWW3jxxRdD+02fPr1RO+644w5uv/12QA+mPv74Y9577z3++Mc/Anpm2Wg0Nuis2Ry/39/g819//fUNvofl5eUAxMbGNtivvka/Pri3Wq3cdtttTJ48mdjYWFatWsWjjz7K2rVrWb16degcBQUFvPbaa/Tu3Zs333wTr9fLH/7wByZPnsy2bdtOKFAeN25cKAAdOnQon3zyCSaT/ue/oqKiyfZaLBbsdnuDm5ELL7yQESNG0LlzZ/bs2cOjjz7KmDFjWL9+Pd26dTvhczanvrPwqYiLi+Prr79m2rRppKWlAfoTh4ULFzZo26FDh3j44YeZP38+RqPxlM511VVXMX36dKqrqyksLGTNmjX873//a/A0APSfq5EjR4aC/JKSEnJzcxk1ahRJSUmh19nZ2axYsYKBAwcSGRnZ4BgDBgzgueeeo6qqiujo6FNqrxBCHE1ugoQIs2+//ZacnBwSEhIwmUzY7Xaqq6tDmd1AIMD69eu58MILG+x3bJC7YsUKqqurueyyy0KZeb/fz8SJE3G5XKHRU1atWsU555zToDzi3HPPJT4+/oTam5mZyZo1a1izZg1ffvkljzzyCH//+995+OGHG217/vnnN1q3bds2ZsyYQUpKCkajEbPZzI4dOxplsg0GAxMnTgy97tKlCxERERw4cADQn6bU1tby85///LhtnjRpUujfkZGRZGRkhI4DcN111+H3+xk3btxxj2UymVizZg1ff/01zzzzDAsWLOBnP/vZcfc7VocOHfh//+//MX36dMaNG8c999zD7Nmz2bBhA/PmzQttFwwG8fv9fPjhh5x//vnMmDGDefPmsX//fmbPnt1gm/rl2DKXV155hW+//Zb//e9/eDweJk6cSGVl5Um3+fnnn2fmzJmcffbZXH/99Xz55ZcATY6+cyrnPHz4MElJSSfdLtBHCZoxYwaZmZl88sknfPrpp4wfP54LL7ywwVOe3/72t+Tk5HDuueee0nlA/32Jjo5m/vz5zJkzh8GDB5Odnd3ktvU3R7W1taxYsYKEhAR69OhBQkIC2dnZLF++nGAwyMqVKxuU/NRLTExEKUVhYeEpt1cIIY4mmX8hjlI/BN/+/fub3Wb//v3YbLaTrhVu7liTJk1i6NChvPjii6SlpWGxWDj//PNDwycWFxfj9/sbBUXJyckNXtcPVVhfTnSs/Px8QA+wsrKyGr1/7PGaY7PZGDp0aOj12LFjKSws5NFHH+WOO+5ocBNx7JORqqoqJk2aRFJSEk8//TQZGRnYbDZuuummBsNFAkRERDSoQQc9G12/XX35T32WtyVNZbWPPd/JqP/8Y8aMoWvXrlx00UXceeedDB06NJThdzqdpKamhvapfyLQ0k3W1KlTiYyMZN26daGyrri4ONLT0xtcyx49etCpUye2bNkCwI033sjrr78eev/VV19tMGxrjx49ABgxYgQTJ04kIyODf//73/z2t78NXRun09mgLV6vl9ra2hbb26FDB8aMGcO6desavdfSOZvjdrsbjBx0Mp544gnKy8tZt25d6BgTJkygT58+/PnPf2b27NmsXLmSuXPnsmrVqtATj9raWgAqKyux2+3Y7fbjnstoNHL55ZczZ84c8vLyuPHGG5vddvTo0fj9flavXh0azaf+CdOoUaNYvnw5Q4cOxel0NlkWVf9ZXC7XSV0PIdo6Gec/fCT4F+IoJpOJUaNG8cUXX1BTU9PoEXxNTQ1ffPEFo0aNCpUw2Gy2Rh0Z6wO941m0aBHV1dW8//77oSDM7/c3KLVISkrCZDI1qmMvKipq8Lo+SHv//fdJT09vdK6uXbsCesB27L5NHe9k1Nez79y5kxEjRoTWH1tGs3LlSg4cOMCCBQsYMGBAaL3T6aRTp04ndc76m69Dhw6d9L6nU30nz127djF06NBQ7fz27dtDAXD9a4vF0qg85nj69OnTbMa8/gbmoYce4o477gitr/9eNyUlJYVOnTqxa9cuQH8Skp6e3qi2f8eOHSilGvUFOBXHnrM58fHxoaD8ZG3dujU0D0I9o9FI//792b17N6B/Jp/P1+QNcmZmJldcccUJD1l71VVXcfbZZwNwxRVXNLvdiBEjMJvNLF++nOXLl4fK2ABGjhzJM8880+Bm8lj11+N0JBuEEALkJkiIRmbNmkVZWVmTY5w/9dRTlJWVMWvWrNC6Tp06hQKleosXL260r9lsbpRtdrlcaJrWoIb8nXfeadCZ2Gg0MmjQID744IMG+86fP7/B65EjR2K32zlw4ABDhw5ttNQHD8OHD2fZsmUNMr2ff/55o46mJ6O+pCgxMbHF7eqzl0dn9FesWEFeXt5Jn7P+87766qsnve/p9M033wCEgvpu3bqRnZ3Nu+++22C7t99+mwkTJjR6mnG0BQsWUFNTw7Bhw0Lrpk2bxpYtWygoKAit2759OwcOHAjdeHTp0qXJ73VT8vPz2bdvX4ObkClTpvDBBx80GLHp7bffJjY2llGjRjV7rEOHDvHNN980aO+JnrMpPXr0aNQh+kRlZGSwbdu2Br9jgUCA77//ni5dugBw3nnnsWzZsgbLvffeC+i/T0f3RzmekSNHcvXVVzNr1qwWbz7tdjuDBg1i2bJlrFu3rsH1HDVqFDt27OCjjz6iW7duDZ4U1cvLy8PhcDT5nhA/ZtLhN3wk8y/EMS688ELuuOMOHnroIfLz80NDVL733nu89NJL3HHHHVxwwQWh7S+99FJeeeUV7rzzTi666CJWrFgRGrLwaL169eKDDz7g7LPPJjIykh49eoTqjn/2s5/xi1/8gi1btvDUU081KlP54x//yPTp07n55pu57LLLWL9+fajMo34YxNjYWB5++GHuueceDhw4wPjx4zEajezZs4cPPviA9957D7vdzqxZs/jnP//JlClTuO+++ygvL+fBBx884cyiy+UKTVblcrn4+uuveemll8jJySEzM7PFfc866yyioqL45S9/yX333cfBgwd58MEH6dix4wmd+2gOh4MHH3yQe++9l2AwyPTp0wkGgyxbtoyrrrqqQWnS8bzxxhvceOONLF26tMW6/7FjxzJjxgx69eqFwWBg1apVPPnkk5x33nkMHz48tN1DDz3EzJkzyczM5JxzzuHtt99m1apVfPXVV6Ft7rrrLgwGA2eddRaxsbGsXr2axx57jKFDh3LRRReFtrv55pv5+9//zrRp07j//vvxer3cf//9ZGZmcuWVV7b4uW699VYSExMZOnQoDoeDHTt28NRTT5GSktKgr8Tdd9/Nm2++yVVXXcXtt9/Opk2b+Nvf/sajjz4aulmZM2cOCxYsYOrUqaSlpbFnzx4ee+wxjEYjd91110mfsymjR4/mnXfeabR+69atbN26NfR606ZNzJ07l8jIyNCwoDfddBMvv/wy06dP54477sBoNPLvf/+bnTt3hjrKp6amNgqi6288R48efdyb16NpmnbCM36PHj2aZ599FqPR2ODnpHfv3sTExLBw4UKuvfbaJvddu3Yto0aNOqHhToUQ4oSEdZYBIdqw//3vf2rkyJEqMjJSRUZGqrPOOku98cYbTW77xBNPqPT0dBUZGakuu+wy9dlnnylALVu2LLTN119/rQYPHqwiIiIavPfGG2+obt26KZvNps466yy1evXqJidT+te//qXS09OVzWZT48aNC02cNH/+/AbbzZkzRw0bNkxFRESomJgYNWjQIHX//fcrn88X2uarr75SAwcOVBaLRfXq1UstWLDghCf5AkKLxWJR3bt3V7///e9VZWVlaLtly5YpQK1Zs6bRMRYuXKj69OmjbDab6t+/v/rkk0/UuHHj1Pnnnx/a5sEHH1SRkZGN9nU4HI0mX/vPf/6j+vXrpywWi0pISFDTpk1T+/btU0o1P8nXsZ+1frujv19N+c1vfqN69eql7Ha7cjgcauDAgerpp59uMBFWvZdfflllZWUpi8Wi+vXrpz766KNG7w8ePFjFxMQok8mkMjIy1KxZs5qcfGbPnj3qggsuUJGRkSo6OlpdeumlKj8/v8W2KqXUK6+8okaMGKFiY2NVRESE6tGjh/rVr36lCgoKGm27fPlyNWLECGW1WlWnTp3UY489poLBYOj9lStXqvHjx6vExERlMplUYmKiuvzyy9X27dtP+ZzHWrdunQJUbm5ug/UPPvhgg5+7+iUjI6PBdkuXLlXjxo1T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XgNACIHX6yUUChEOh3G73WRnZ3dkcTulg9Xhs88+y8yZM+nTpw+g57JPSEjoqKJ2SgerP4A5c+awY8cOLr300o4qoqK0iQr+jzOlpaXk5eU1fe/atSulpaUArF+/ntLSUiZMmMCQIUO4//77iUQiHVXUTulg9bdt2zaef/55HnzwwY4qXqd3sPrb25w5c6irq2vRMqboDlaHra3fE8mwYcN44403iEajVFVV8eWXXzZ1Z7z++uuJi4sjLS2N9PR0nE4nN998c8cWuBM6WB2uX78en8/H1KlTGTx4MLfccgsej6djC9zJHKz+6uvrueuuu3juuec6tpCK0gYq+O8Ao0ePJiUlZb/LkbSUhsNhfvzxR7744gu+/fZbFi9e/LP8B+lY1J+UkmuuuYann36amJiYo1zizuVY/f7tsWbNGq6++mreeust7Hb7UShx53Os6/BEcqi6/Nvf/obb7WbIkCHMnDmTiRMnNr1R+eqrr4hGo1RUVLBr1y4SEhL4wx/+0MF31P6OpA7D4TDffPMNb7/9NsuWLaOuro4HHnigg++ofR1J/d18883ce++9pKWldfBdHIf2DPht70VRff47wpEMpsrNzWX79u2MHj0agJKSEnJzc5u2nXvuuU3B67nnnst33333s2sJOxb153K5WL16NRdddBEAbrcbr9fLlClTmDt37lEpd2dxrH7/QG9FPP3003n55ZcZN27cEZe1szqW/w8frH5/jlpTl6+88krT51/96ldNYyD++c9/MnPmTKxWKwCXXnopf/nLX45JOTuzI6nD3NxcBg8eTGJiIgCXXHIJDz300DEpZ2d1JPX37bff8u2333LnnXfi9/upra2lV69ebNq06VgVV1GOmGr5P85ccMEFvPjii0QiEWpra3nrrbeaAtaZM2c2tYSFw2G++uorBg0a1MEl7lwOVH8Oh4OamhpKSkooKSnhscceY9q0aT+7wP9IHez3b8OGDUyfPp1//vOfFBYWdnBJO6+D1eHBtp2oampqCIVCAPz444988MEH3HjjjQB0796dr776CiklUko+/fRT+vfv35HF7ZQOVoczZ85k/vz5BAIBAD7//HP1d+MnDlZ/e/5mlJSU8L///Y++ffuqwL+1hNYxi6Ja/jujuXPncuWVV+JyuZBS8s477/Dss89y5plncvnll7Ns2TJ69uyJEII77riDAQMG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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "most_loaded_idx = flows['LinePercent'].idxmax()\n", + "branch_key = (\n", + " int(flows.loc[most_loaded_idx, 'BusNum']),\n", + " int(flows.loc[most_loaded_idx, 'BusNum:1']),\n", + " str(flows.loc[most_loaded_idx, 'LineCircuit']),\n", + ")\n", + "\n", + "# Show base loading with the outaged branch highlighted\n", + "plot_flow_map(\n", + " lines_geo, flows['LinePercent'].values,\n", + " shape=SHAPE,\n", + " title=f'Outaged Branch: {branch_key[0]}-{branch_key[1]} '\n", + " f'({flows.loc[most_loaded_idx, \"LineMW\"]:.0f} MW)',\n", + " highlight_idx=most_loaded_idx,\n", + " figsize=(8,8)\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "a11", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAY8AAAEOCAYAAABxdpuaAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAACPVklEQVR4nOyddXhTVxvAfzepu9JSoaVAKVqguBZ3lzHYkMH4BmMbQ8aQwQSZMGBssDHDna24uw4v7tYWKtTdkvv9URqaJm2T0tJS7u957gM559xz36TJfe85rwmiKIpISEhISEjogaykBZCQkJCQeP2QlIeEhISEhN5IykNCQkJCQm8k5SEhISEhoTeS8pCQkJCQ0BtJeUhISEhI6I2kPCQkJCQk9EZSHhISEhISeiMpDwkJCQkJvZGUx3O+/PJLLCwsChy3Zs0amjZtiqWlJRYWFjRp0oRVq1ZpnU8QBARBQCaTYW1tTa1atRg7diw3b97UGO/v768an/MYO3as3u/l1q1bDBo0CGdnZ4yNjfHy8mLChAlER0frPRfAli1bWLJkSaHOLU189tlnlC9fHplMxrhx47SOOXfuHO3bt1d9dhUqVGDEiBE8ffpUY+ypU6do0qQJpqameHh48N1335E7YYOnp6fWv2tqaqrGfDt37qRp06aYm5tja2tL69atCQkJyfc9xcXF0bdvXzw9PTE1NcXR0ZHOnTtz7tw5jbFPnz6lb9++WFpaYmdnx8iRI4mPj1cbM2zYMK3y7tmzp1DXlCi7GJS0AK8TH330EYsXL+a9995jxowZCILA5s2bGTp0KGfPnuXnn39WG29qasqhQ4cASEhI4OrVq/z+++/88ccf/PXXX7zzzjtq45s1a8a8efPU2pydnfWS8dixY3Tp0oXKlSszb9483N3duXz5MrNmzWL79u0cO3ZM7zm3bNnC+fPnGTNmjF7nlSYOHDjADz/8wIIFC2jUqBEuLi5ax8XExODj48PIkSNxcnLiwYMHfP3115w7d45z585hbGwMwL179+jYsSPt27dn1qxZXLlyhc8//xy5XM7EiRPV5uzXrx8TJkxQa8ueJ5vVq1czYsQIJkyYwOzZs0lISOD48eNalUxO0tLSMDEx4YsvvqBixYrExcWxcOFC2rRpw4ULF/D29gYgIyODjh07ArB27VqSk5OZOHEigwYNYseOHWpzenl5sWbNGrW2atWq6X1NiTKOKCGKoijOnDlTNDc3z7N/69atIiDOnDlTo2/GjBkiIG7btq3A+VJSUsQ2bdqIRkZG4v3791XtrVq1Ert27fpS7yE5OVl0cXERq1evLiYmJqr13bx5UzQ2Nhb79Omj97xDhw4Va9So8VKylTQ///yzCIgKhULvc/ft2ycC4smTJ1Vto0aNEj08PMS0tDRV25QpU0QbGxsxNTVV1ebh4SF++OGH+c4fFRUlWllZiUuWLNFbNm0kJCSIRkZG4uzZs1Vta9euFQVBEG/duqVq27t3rwiIZ86cUbUV9m+t7ZoSZRtp20pHFi5ciK2trcZTJcCkSZOwtbVl4cKFBc5jYmLCzz//THp6On/++WeRyrhp0yaePn3KtGnTMDc3V+vz8fHh3XffJSAggMePHwOwfPlyBEEgMjJSbWydOnUYNmwYkLWNsWLFCq5fv67awsjuO336ND169MDFxQVzc3Pq1KmjdQvv+vXrtGzZEhMTE6pUqcKaNWvo1asX/v7+auNu3rxJz549sba2xtzcnK5du3L//v0C33d0dDTvvfceDg4OmJqa0rRpU44dO6bq9/f356OPPgJALpcjCAJHjhwpcN5s7O3tAUhPT1e17d69m169emFkZKRqGzhwILGxsZw+fVrnuQE2btyIQqFgxIgRep2XF+bm5piYmGjIW7t2bapWrapqa9++PXZ2duzatatYrilRtpGUhw5kZmZy6tQpWrdurdUuYmFhQevWrTl16hSZmZkFzle9enVcXV01bjKiKJKZmal2ZOPp6alxs83N0aNHAejevbvW/h49eiCKIidOnChQxmy++OILunTpgpeXF6dPn+b06dN88cUXADx+/JhmzZrx559/sn37dvr27cuIESNYsWKF6vyUlBQ6dOhAVFQUq1evZu7cuXz77bdcuHBB7ToPHjygadOmREdHs3z5ctauXcuzZ89o27YtaWlpecqnUCjo3Lkz27dv57vvvmPTpk1YWFjQvn171TWWLFmisnFkv4d69erl+74VCgXp6encunWLzz77jHr16tG8eXMAkpKSCA4OxsfHR+0cHx8fBEHg1q1bau1r1qzB2NgYCwsLunTpwtWrV9X6//vvP3x8fFixYgUeHh4YGBhQp04ddu/ena+MOVEqlWRmZhIaGsqECROQyWQMGTJE1X/r1i0NeQVBwMfH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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "lodf_df = pw.lodf(branch_key, method='DC')\n", + "\n", + "plot_sensitivity_map(\n", + " lines_geo, lodf_df['LineLODF'].values,\n", + " shape=SHAPE,\n", + " title=f'LODF: Outage of {branch_key[0]}-{branch_key[1]}',\n", + " clabel='LODF',\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "a12", + "metadata": {}, + "source": [ + "## 4. PTDF vs LODF Side-by-Side\n", + "\n", + "Placing the transfer corridor (PTDF) next to the outage redistribution\n", + "(LODF) reveals whether the same lines are critical for both scenarios." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "a13", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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jOCLL75otL96DRFFkaCgIPr168fs2bPJyMho0L4pbZs9e3ab7yUzM5Nrr72W6OhoNBoNKSkpPPDAA1RVVbW5L4CFCxfy9ttvn9C5p4Lrr7+ebt264e/vT0hICGPHjuXPP/9s0K412nL8b1D99u677zborzV61hgvvfQSaWlpBAcH4+/vT79+/XjzzTc5PqOcJEm88MILJCYmotPpGDFiBJs2bfJps2rVqkbHe/XVV5/QNY+lo7Vu27ZtpKWleUvO3X///aSlpfH4448DUFxc7DUIAbp06cLixYtZunQpAwYM4OWXX+bDDz9k6tSpbbpuZyIvB58AOp2OFStWAFBQUMDTTz/NpEmT2L59O2+//TZGo9Hb9p///Cd+fn7MmzfPuy8iIsL79+WXX84DDzzgLZS9cuVKHnnkEd5++21WrFhBfHy8z7Wfe+65BmV2evXq1eqx79u3j8WLFzNs2DA8Hk+TRba//fZbbr/9dh555BEmTpzI/PnzufTSS1m7di3Dhw/3trvqqqvYt28f7777LlqtlkceeYRp06axbds2lMq6r9f69etZu3Ytw4YNw2q1tnqsLVFRUcGkSZNISUnho48+Qq1W8/rrrzNt2jS2bt3qLSvU2usXFxczYsQIevTowfvvv09gYCD79u3Dbrf7tGvNPXcmnb1EItN53H333bz11lvccsstPP744wiCwA8//MCNN97Ili1beOONN3zaH6tltbW17Nmzh/fff58PPviAjz76iOuvv96n/ahRo3y0DOr8otrCmjVrmD59OqmpqcybN4+EhAR27drFM888wy+//MKaNWva3OfChQvZtm0b//znP9t03qnC4XBw//33061bN2w2Gx999BHTp09n5cqVjBkzxtuutdpy7OdWT0pKis/r1upZY9TU1HDVVVfRt29ftFoty5cv51//+hdGo5H/+7//87abO3cuc+bM4YUXXqB///689dZbTJkyhZ07dzYYzyeffOJTyi08PPyErnksHa1148ePb9bo/PTTTxs9Z8eOHW26zmmFJNMm5syZI/n7+/vsy83NlQRBkO66664G7ceNGyfNmDGj0b6SkpIaPWf79u2Sn5+fNHnyZO++7OxsCZC+//77do3f7XZ7/77xxhulPn36NNque/fu0jXXXOOzb8SIEdK0adO8rzds2CAB0pIlS7z7MjMzJUEQpPnz5zd6zebej7byzTffSICUnZ3t3WexWCStVis99dRTbb7+9ddfL40cOVJyuVxNXrO199wZGAwGCZAe1nSRntR2bXJ7WNNFAiSDwdCp45VpG41pz7H8/PPPEiDNmTOnwbHHH39cAqRFixa12J/VapUmTpwoqdVq6ciRI979HfG/a7FYpNjYWKl3796SyWTyOZaRkSFpNBrpsssua3O/zWnZ6YjL5ZISEhKk22+/3buvtdrS0vegntboWVu49tprpW7dunlfW61WKTAwUHr44Ye9++x2u5SUlCTdeeed3n0rV66UAGnr1q3tvmY9stZ1HPJycAeQmJhIREQE2dnZHdJfWload911F8uWLePAgQMd0mc9otjyR56VlcXBgwe58sorffZfffXVLF++3Psk+fvvvxMcHMz555/vbdOjRw8GDhzo4yzbmmueCE6nE4CgoCDvPq1Wi1qt9nmaa831jUYj3333Hf/85z9RKBRNtmvtPXcm8nLwuclrr71GSEgI//73vxsce/DBBwkJCeG1115rsR+tVssbb7yBw+Hgww8/7NAxfv/99xQVFfHII4/g7+/vc6xnz5787W9/46effiI3Nxeom3kRBIGKigqftgMHDvS61dx000189tln7Nu3r4HLzcaNG7nooouIjY3F39+fgQMHNro0vm/fPsaOHYtWq6Vbt2589dVXXHLJJYwfP96nXUZGBhdffDFBQUH4+/szY8YMjhw50ub3QaFQEBwc7JPsuCO1pbV61hbCwsJ8xrthwwaMRqPP74Rareayyy7rMC08/prHI2td+5GNwA7AaDRSWVlJbGxsh/U5ZcoUgAb+FR6PB5fL5d3ql3Pr/S4am65uK5mZmQA+U/dQt+zscDi8xm5mZiY9evRokI29V69e3j46Ao/Hw3PPPUdNTY3P/gsvvJCoqCgeeOABiouLqaio4OGHH0YQhAbLWC2xfft2HA4HKpWKcePGoVKpiI6O5qGHHvIam3Dq7rk91DlEC81snT1CmY7G5XKxYcMGJkyY0KjfoF6vZ8KECWzYsAGXy9Vif7179yYuLo6NGzf67JckyUd/ju0rOTm5gdF0PKtXrwZg5syZjR6/6KKLkCSJdevWtTjGeh577DGmT59OSkoKGzduZOPGjTz22GMA5ObmMmrUKD788EN++eUXZs2axa233spnn33mPd9qtTJlyhQqKyv58ssv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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_sensitivity_dual(\n", + " lines_geo,\n", + " ptdf_df['LinePTDF'].values,\n", + " lodf_df['LineLODF'].values,\n", + " shape=SHAPE,\n", + " titles=(\n", + " f'PTDF: {seller_bus}\\u2192{buyer_bus}',\n", + " f'LODF: Outage {branch_key[0]}-{branch_key[1]}',\n", + " ),\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "a14", + "metadata": {}, + "source": [ + "## 5. Estimated Post-Outage Loading\n", + "\n", + "Using the LODF we can estimate post-contingency flows without\n", + "re-solving power flow:\n", + "\n", + "$$f_k^{\\text{post}} = f_k^{\\text{pre}} + \\text{LODF}_k \\times f_{\\text{outaged}}$$\n", + "\n", + "The three-panel view below compares pre-outage loading, the estimated\n", + "flow change, and the resulting post-outage loading." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "a15", + "metadata": {}, + "outputs": [ + { + "ename": "KeyError", + "evalue": "'LineLimitMVA'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mKeyError\u001b[0m Traceback (most recent call last)", + "File \u001b[1;32mc:\\Users\\wyatt\\.conda\\envs\\esapp\\Lib\\site-packages\\pandas\\core\\indexes\\base.py:3641\u001b[0m, in \u001b[0;36mIndex.get_loc\u001b[1;34m(self, key)\u001b[0m\n\u001b[0;32m 3640\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m-> 3641\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_engine\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_loc\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcasted_key\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 3642\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m err:\n", + "File \u001b[1;32mpandas/_libs/index.pyx:168\u001b[0m, in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[1;34m()\u001b[0m\n", + "File \u001b[1;32mpandas/_libs/index.pyx:197\u001b[0m, in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[1;34m()\u001b[0m\n", + "File \u001b[1;32mpandas/_libs/hashtable_class_helper.pxi:7668\u001b[0m, in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[1;34m()\u001b[0m\n", + "File \u001b[1;32mpandas/_libs/hashtable_class_helper.pxi:7676\u001b[0m, in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[1;34m()\u001b[0m\n", + "\u001b[1;31mKeyError\u001b[0m: 'LineLimitMVA'", + "\nThe above exception was the direct cause of the following exception:\n", + "\u001b[1;31mKeyError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[8], line 6\u001b[0m\n\u001b[0;32m 3\u001b[0m post_mw \u001b[38;5;241m=\u001b[39m flows[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mLineMW\u001b[39m\u001b[38;5;124m'\u001b[39m]\u001b[38;5;241m.\u001b[39mvalues \u001b[38;5;241m+\u001b[39m delta_mw\n\u001b[0;32m 5\u001b[0m \u001b[38;5;66;03m# Estimate post-outage loading (approximate using same MVA limit)\u001b[39;00m\n\u001b[1;32m----> 6\u001b[0m limits \u001b[38;5;241m=\u001b[39m \u001b[43mflows\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mLineLimitMVA\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m]\u001b[49m\u001b[38;5;241m.\u001b[39mvalues\n\u001b[0;32m 7\u001b[0m safe_limits \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39mwhere(limits \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m0\u001b[39m, limits, \u001b[38;5;241m1.0\u001b[39m)\n\u001b[0;32m 8\u001b[0m post_loading \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39mabs(post_mw) \u001b[38;5;241m/\u001b[39m safe_limits \u001b[38;5;241m*\u001b[39m \u001b[38;5;241m100\u001b[39m\n", + "File \u001b[1;32mc:\\Users\\wyatt\\.conda\\envs\\esapp\\Lib\\site-packages\\pandas\\core\\frame.py:4378\u001b[0m, in \u001b[0;36mDataFrame.__getitem__\u001b[1;34m(self, key)\u001b[0m\n\u001b[0;32m 4376\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcolumns\u001b[38;5;241m.\u001b[39mnlevels \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m1\u001b[39m:\n\u001b[0;32m 4377\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_getitem_multilevel(key)\n\u001b[1;32m-> 4378\u001b[0m indexer \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcolumns\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_loc\u001b[49m\u001b[43m(\u001b[49m\u001b[43mkey\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 4379\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m is_integer(indexer):\n\u001b[0;32m 4380\u001b[0m indexer \u001b[38;5;241m=\u001b[39m [indexer]\n", + "File \u001b[1;32mc:\\Users\\wyatt\\.conda\\envs\\esapp\\Lib\\site-packages\\pandas\\core\\indexes\\base.py:3648\u001b[0m, in \u001b[0;36mIndex.get_loc\u001b[1;34m(self, key)\u001b[0m\n\u001b[0;32m 3643\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(casted_key, \u001b[38;5;28mslice\u001b[39m) \u001b[38;5;129;01mor\u001b[39;00m (\n\u001b[0;32m 3644\u001b[0m \u001b[38;5;28misinstance\u001b[39m(casted_key, abc\u001b[38;5;241m.\u001b[39mIterable)\n\u001b[0;32m 3645\u001b[0m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28many\u001b[39m(\u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mslice\u001b[39m) \u001b[38;5;28;01mfor\u001b[39;00m x \u001b[38;5;129;01min\u001b[39;00m casted_key)\n\u001b[0;32m 3646\u001b[0m ):\n\u001b[0;32m 3647\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m InvalidIndexError(key) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01merr\u001b[39;00m\n\u001b[1;32m-> 3648\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m(key) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01merr\u001b[39;00m\n\u001b[0;32m 3649\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m:\n\u001b[0;32m 3650\u001b[0m \u001b[38;5;66;03m# If we have a listlike key, _check_indexing_error will raise\u001b[39;00m\n\u001b[0;32m 3651\u001b[0m \u001b[38;5;66;03m# InvalidIndexError. Otherwise we fall through and re-raise\u001b[39;00m\n\u001b[0;32m 3652\u001b[0m \u001b[38;5;66;03m# the TypeError.\u001b[39;00m\n\u001b[0;32m 3653\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_check_indexing_error(key)\n", + "\u001b[1;31mKeyError\u001b[0m: 'LineLimitMVA'" + ] + } + ], + "source": [ + "outaged_flow = flows.loc[most_loaded_idx, 'LineMW']\n", + "delta_mw = lodf_df['LineLODF'].values * outaged_flow\n", + "post_mw = flows['LineMW'].values + delta_mw\n", + "\n", + "# Estimate post-outage loading (approximate using same MVA limit)\n", + "limits = flows['LineLimitMVA'].values\n", + "safe_limits = np.where(limits > 0, limits, 1.0)\n", + "post_loading = np.abs(post_mw) / safe_limits * 100\n", + "\n", + "plot_sensitivity_triple(\n", + " lines_geo,\n", + " [flows['LinePercent'].values, delta_mw, post_loading],\n", + " shape=SHAPE,\n", + " titles=('Pre-Outage Loading', '\\u0394 MW (LODF)', 'Est. Post-Outage Loading'),\n", + " clabels=('Loading (%)', '\\u0394 MW', 'Loading (%)'),\n", + " cmaps=('YlOrRd', 'RdBu_r', 'YlOrRd'),\n", + " symmetric=(False, True, False),\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "a16", + "metadata": {}, + "source": [ + "## 6. Multiple Transfer Scenarios\n", + "\n", + "Compare PTDF corridors for different seller-buyer pairs to identify\n", + "which transfers compete for the same network paths." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "a17", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAocAAADECAYAAADtR4sJAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAACZ9klEQVR4nOydd3gd1Z2w35nbu3RVrrpkuUi23HvBNu4YYzA4QPiSUJIQCJBsNiRhs0mAJAtsdkNC2BBIISQkofdiMNgGF3CVbVxly5Ylq7fbe5n5/rjogrBkS7aMkT3v88zz2GdG0zSvzpnfnPM7gizLMgoKCgoKCgoKCgqAeK5PQEFBQUFBQUFB4YuD0jhUUFBQUFBQUFBIoTQOFRQUFBQUFBQUUiiNQwUFBQUFBQUFhRRK41BBQUFBQUFBQSGF0jhUUFBQUFBQUFBIoTQOFRQUFBQUFBQUUiiNQwUFBQUFBQUFhRTqc30CCucP4XCYaDTa63qtVoter/8cz0hBYXByKpdA8UlBoa8oPvUfpXGoMCCEw2EyDGaCJHrdJicnh2PHjikCKiichL64BIpPCgp9QfHp9FAahwoDQjQaJUiCm4QCtD30Vogi8URLA9FoVJFPQeEknMolUHxSUOgrik+nh9I4VBhQ9IKITjhRQFEGlFm8FRT6TG8ugeKTgkJ/UXzqH0rjUGFA0YoCWkE4oVyWBZDOwQkpKAxSenMJFJ8UFPqL4lP/UBqHCgOKShBQ9SCgip6lVFBQ6JneXALFJwWF/qL41D+UxqHCgKISkssJ5Z//qSgoDGp6cwkUnxQU+oviU/9QGocKA4paEND08HaWUN7MFBT6RW8ugeKTgkJ/UXzqH0rjUGFAUT4rKygMDMpnMAWFgUPxqX8ojUOFAUUr0mOnX0kZCaag0C96cwkUnxQU+oviU/9QGocKA4rS51BBYWBQ+kgpKAwcik/9Q2kcKgwoml7SBSRkJWyvoNAfenMJFJ8UFPqL4lP/UBqHCgOK0udQQWFgUPpIKSgMHIpP/UNpHCoMKMl+HSeWJ5Q+HQoK/aI3l0DxSUGhvyg+9Q+lcagwoCiRQwWFgUGJdCgoDByKT/1DaRwqDCgaQUArnihaXFLkU1DoD725BIpPCgr9RfGpfyiNQ4UBpdfRyop7Cgr94qSjKxWfFBT6heJT/1AahwoDSq+flXsJ5ysoKPTMST+DKT4pKPQLxaf+IZ7rE1A4v9CKQq+LgoJC3zmZS/316d5770UQhG5LeXl5an04HOb2228nIyMDs9nMypUraW1tHehLUlA4ZwykTxcCSuNQYUARBaHXRUFBoe+czKXT8amiooLm5ubUsmnTptS6f//3f+f111/n+eefZ/369TQ1NXHVVVcN5OUoKJxTBtqn8x3ls7LCgKLSiqjEE985VMr8RAoK/aI3l+D0fFKr1eTk5JxQ7vF4ePzxx3nqqaeYP38+AE888QQjR45ky5YtTJ8+vd/HUlD4ojHQPp3vKJFDhYFFJSL0sKBSHjUFhX7Ri0uf9snr9XZbIpFIr7urrq4mLy+P0tJSvvKVr3D8+HEAKisricViLFy4MLVteXk5RUVFbN68+exeo4LC50UffFL4BOWOKAwoKo2YfEP77KJRHjUFhf7Qq0uf8qmwsBCbzZZaHnjggR73NW3aNP72t7/x9ttv8+ijj3Ls2DFmz56Nz+ejpaUFrVZLWlpat59xOBy0tLSc7ctUUPhc6ItPCp+gfFZWGFAEUUToIXQvyErYXkGhP/TmEnziU319PVarNVWu0+l63H7p0qWpf48dO5Zp06ZRXFzMc889h8FgGMCzVlD4YtIXnxQ+QWkuKwwovb6Zac/sUfvv//5vBEHge9/7XqpMGWGpcD5zMpe6fLJard2W3hqHnyUtLY0RI0Zw5MgRcnJyiEajuN3ubtu0trb22EdRQWEw0hefFD5BuSMKA4qgEnrp13H6o8G2b9/OH//4R8aOHdutXBlhqXA+07tLZ+YTgN/v5+jRo+Tm5jJp0iQ0Gg1r165NrT906BDHjx9nxowZZ3oZCgpfCM6WT+dr4EJpHCoMKCp1sv/GCYv69B41v9/PV77yFf785z+Tnp6eKu8aYfmb3/yG+fPnM2nSJJ544gk+/PBDtmzZMlCXo6BwzujVpdPw6Qc/+AHr16+ntraWDz/8kCuvvBKVSsV1112HzWbjG9/4Bt///vd57733qKys5KabbmLGjBnKSGWF84aB9KmL8zlwoTQOFQYUUSX2upwOt99+O8uWLes2khKUEZYK5z8nc6m/PjU0NHDddddRVlbGNddcQ0ZGBlu2bCErKwuA3/72t1x22WWsXLmSOXPmkJOTw0svvXQ2LktB4ZwwkD7B+R+4UAakKAwoydD9iSF6QU6Web3ebuU6na7XflLPPPMMO3fuZPv27SesU0ZYKpzv9OYSfOJTX3nmmWdOul6v1/PII4/wyCOP9Gu/CgqDhYH0CboHLv7rv/4rVX6qwMVgicYrjUOFAUWlVaFSq04sF5OjwQoLC7uV33PPPdx7770nbF9fX8+//du/8e6776LX68/KuSoofJHpzSX4xCcFBYW+0Ref+hq8uBACF0rjUGFg6e3t7OM3s76m3qisrKStrY2JEyemyhKJBBs2bOD3v/89q1evTo2w/LSEyghLhfOGk0Q6OI1Ih4LCBU0ffOpL8OJCCVwojUOFAUWlVqHS9BA5JPlm1pVy41QsWLCAvXv3diu76aabKC8v56677qKwsDA1wnLlypWAMsJS4fyiN5fgE58UFBT6Rl986kvw4kIJXCiNQ4UBRVQJiD28nYlS/yIdFouF0aNHdyszmUxkZGSkyrtGWNrtdqxWK9/5zneUEZYK5w29uQT990lB4UKnLz71JXhxoQQuztvRykeOHOHWW29l/PjxqNXqExoaXTz++OOMGDECvV7PuHHjeOONN07YxuPx8I1vfAO73Y7FYuFLX/oSzc3N3bbZsWMHN910EyNHjkQURS677LIBu5Z9+/Zx2WWXkZWVRVpaGnPmzOG999477eM3NjZyww03kJWVhcFgYOTIkfzrX//q9zX3hKhV9boMNMoIy8+Pz9unP/7xjyxevJicnBysVivTp0/n1VdfHZBrGUifSkpKEAThhCUcDnfbbvPmzcyePRuDwYDD4eA73/kOwWDwpOd5MpfOhk8Knx/nS/1UW1vb4/N/shf0hoYGzGYzgiDQ0dHRbd1Xv/pVhg8fjslkIj09nTlz5vDOO+/0uJ8tW7awcOFCLBZL6m/E7t27ez3uQPnUFbj49PLpwMX5khrqvG0c7t+/nzfffJNhw4YxatSoHrd55plnuPnmm7n22mt56623mDFjBldeeeUJw82vvfZa3nnnHR577DH+9a9/cejQIZYuXUo8Hk9t88EHH7Bx40YmTpxIUVHRgF1HR0cHCxYsoLOzk8cff5xnnnkGs9nM0qVLu7299PX4zc3NzJgxg6amJv70pz/xxhtv8O1vf5tIJNLva+4JUfXJG1r35czuA8D777/PQw89lPp/1whLp9NJIBDgpZdeGlRh+8HE5+3TfffdR3FxMY8++igvvvgiY8eOZcWKFfz9738/o+sYaJ8AvvSlL7F58+Zuy6c/R9XV1bFgwQJMJhMvvvgi9913H0899RTXX3/9Sffbu0sD45PCueN8qZ+6uP/++7s9/48//niv2955552YzeYe10WjUb7//e/z6quv8o9//IOMjAwuvfRSNm7c2G27devWcfHFFzNixAheeuklnnnmGS655JKTvnB9nj6dF4EL+TwlkUik/n3DDTfIFRUVJ2wzYsQI+brrrutWNmPGDHnp0qWp/3/44YcyIK9evTpVVlVVJQuCID/77LM9Hm/u3LnysmXLBuQ6nn76aRmQjx07lioLBoOyXq+Xf/GLX/T7+F/96lflmTNnyvF4vNdj9vWaP43H45EBeeu1S+T9X7vshGXrtUtkQPZ4PH29dIUvEJ+3T+3t7Sfsf9GiRfLo0aPP6DoG2qfi4mL59ttvP+kxb7nlFjkvL08Oh8OpshdeeEEG5J07d56w/alcUnwa/Jwv9dOxY8dkQH7++ef7tP3atWtlu90u//rXv5aBHj3/NPF4XC4sLJRvvvnmVFksFpNLSkrkH/3oR306puLT6XHeRg7FXibY7qKmpobDhw9zzTXXdCv/8pe/zNq1a1ORtLfeeou0tDQWLVqU2qasrIzx48ezatWqPh/vdInFYgDYbLZUmV6vR6vVIn9qsvC+HN/r9fLcc89x2223oVL1/qrU12vuia5cUj0tCoOXz9unzMzME44xYcIEmpqazuQyBtSnvrJr1y7mzJnTLZq4ZMkSAF5//fVef+5kLik+DW7Ol/qpP8RiMe644w5+/vOfk5GR0aefUalUpKWlEY1GU2Vr1qyhtraW7373u/06vuJT/zj3T8w5oqqqCkgmp/w0I0eOJBqNcuzYsdR2ZWVlCIJwwnZd+xgIJEni/vvvx+12dyu/7LLLcDgc3HnnnTQ3N9PR0cGPf/xjBEHgq1/9ar+OsXPnTqLRKBqNhrlz56LRaMjJyeGuu+5KVZpwZtcsatS9LgrnL5+HT5s2bWLkyJF9Op/Pw6cu/vWvf6HT6TCbzVx66aUndFYPh8MnjHrUaDQIgsDBgwd73e/JXFJ8Or8ZLPVTF9/+9rdRqVRkZ2dz880343Q6T9jmd7/7HSqVim9/+9snPZYsy8TjcTo7O/n1r39NdXU1t9xyS2r9li1byMjIYMeOHZSVlaFWqxkxYgRPPvnkSfer+NQ/Ltg74nK5AE5IVNk1DU7Xw+1yuU7Ypmu7ngQ4XTweD08//TQvvvgi7777Lna7PXWcjRs3ctlll5GXlwdARkYGb731FqWlpf06RlcCzm9+85vcfPPN3HvvvWzbto27774bURR54IEHgDO75t6mIjrd6fMUBgdn26ennnqKDz/8kJdffrlP5/N5+ARw+eWXM23aNIqKiqipqeG+++7joosuYteuXan9DR8+nO3btyPLcqoS37ZtG7Isn/SaTzatl+LT+c1gqZ90Oh3f/va3WbJkCWlpaWzdupX77ruPHTt2sG3bNjQaDQBNTU384he/4JVXXjnpVytIDsK5+eabATCbzTz77LPdRvm2tLQQCAS46aab+MUvfsGoUaN46qmnuOGGG3A4HKmo/GdRfOofF2zj8FzQ3NyMx+Ppdf2jjz7KNddcw7x581izZg1ZWVm0tbVx5ZVXMnToUB566CFUKhV/+tOfuPzyy9mwYUOfIymQfPsDWLhwIQ8++CAA8+bNw+fz8etf/5q7774bg8FwZhepEhF6Ek2RT+E02bNnD7feeis33XQTK1asSJWfa58AHn744dS/Z8+ezeLFiykvL+fXv/41f/jDHwC47bbbWLBgAT/+8Y+58847aWpq4vbbb0elUp0Q8elGby59vE5BYSA5HZ9yc3NTzznA3Llzqaio4LLLLuPll19OfRb/wQ9+wKJFi5g/f/4pz2PFihWMHz+ejo4Onn/+ea655hpefvllli5dCiTrsXA4zK9+9SvuuOMOAObPn09VVRX33Xdfr41Dxaf+ccE2DrvewDweT7cRrl1vbJ+ONNTX15/w8y6XK7VNX/nxj3/cp9GWzc3NPPbYY/zsZz/jf/7nf3C5XFRWVqY+TS1YsICKigp++ctf8tRTT/X5+F3X/FlBFyxYwH333ceRI0cYM2bMGV2zqO45RC9KStLe85mz5VNdXR1Lly5l6tSp/PGPf+y27lz71BO5ublcdNFFVFZWpsrmz5/Pr371K+69915+9atfIYoit956K1qtltzc3F731ZtLoPh0vjNY6qeeuPTSSzGZTFRWVnLNNdewefNmXnjhBbZu3Zr6LN01qtjr9WI0GjEajamfz8zMTPU5vuSSS3A6nfzwhz9MNQ5PVo/9/ve/7/W8FZ/6xwXbXO7qy/HZfhlVVVVotdrUJ6Hy8nIOHTrUrbN613af7Q9yKv72t78hy3Kvy8GDB8nNzWXp0qX88Ic/BODAgQOUl5d367OkUqkYO3YsR48e7dfxe0uZ0EVXbrYzuWZBJSKoVD0sF+yjdkFwNnzq6OhgyZIlZGdn89JLL6U+UXVxrn3qDz/60Y9ob29nz549tLS08Lvf/Y4jR46cNO9Z7y4pPp3vDJb6qS8cOnSIWCzGxIkTSU9PJz09ndtvvx2AoUOH8vWvf/2kPz9p0iSOHDmS+n9FRUWv2342v+inUXzqHxfsHSktLWXEiBE8//zz3cqfffZZFixYgFarBWDp0qW4XC7Wrl2b2ubw4cPs2rWLSy+9dMDOp7Ozk4svvpgpU6bwyiuvpOZsLC4u5uDBg90e+kQiwUcffURJSUm/jlFcXMyYMWNYs2ZNt/J3330Xg8GQajyeyTWrNOpeF4Xzl4H2ye/3s3TpUqLRKKtWrerTlIuf5vPwqSeamprYtGkTU6ZMOWGdyWRizJgxZGVl8eSTTyLL8gmjUT/NyVxSfDq/GSz1U0+88cYbBAKBlAOXXHIJ7733XrflrrvuAuCVV17h7rvvPumxN23a1K0/8JIlS9BoND3WY5MmTep1P4pP/eO8vSPBYDA1lL+urg6v18sLL7wAJPtFZGVlce+99/KVr3yFoUOHMm/ePJ599lm2bt3Khg0bUvuZMWMGS5Ys4etf/zoPPvgger2en/zkJ4wdO5arrroqtV17ezvr169P/dvv96eOd+mll3YLm/dERkYGf/jDH1i+fHm3CMk3v/lN/vKXv3DFFVdwxx13pPpIVVdX8+c//7nfx7/vvvu44oor+N73vseyZcvYvn07v/71r/nRj36EyWTq1zX3hNBLvw7lzWxw83n7dNVVV7F7927++te/UldXR11dXWpdX2YZ+Dx8evrpp3njjTe49NJLycvLo6amhgceeACVSsWdd96Z2texY8f4+9//zrRp04BkAt+HHnqIJ554IvWJrCd6c6lrncLg5Xypn+68805EUWT69OmkpaWxbds2HnjgASZPnpzqH5yTk3PC5AS1tbUAzJo1K/UJ+c033+TJJ5/ksssuo7CwEKfTyVNPPcXq1at5+umnUz/rcDj47ne/y09/+lMEQWDkyJE8/fTTbNmyhbfffrvXa1B86iefQy7Fc0JXcs6elvfeey+13V/+8hd52LBhslarlceMGSO//vrrJ+zL7XbLX//61+W0tDTZbDbLV111ldzY2Nhtm/fee6/X43064e7psHbtWnnu3Lmy3W6X09LS5FmzZslvvfXWaR//mWeekSsqKmStVisXFxfL999/vyxJUr+v+dN0JRo9+B83yg33fuuE5eB/3KgkGR3EfN4+9XasgfiTNVA+bd68Wb744ovlzMxMWa1Wy5mZmfI111wjV1VVddtXfX29PHfuXNlms8kGg0GePn16j/eli1O5pPg0+Dlf6qe//OUv8sSJE2Wr1Sqr1Wq5uLhY/t73vnfK5/KJJ544IQn2wYMH5SuuuELOy8uTtVqtnJeXJ19yySXy+++/f8LPx2Ix+Z577pHz8/NlrVYrjxs3Tn711Vd7PJbi0+khyPJnOisoKJwGXq8Xm81G1U++jkWvPWG9Lxyl/L6/4vF4+v2JUEHhQuJULoHik4JCX1F8Oj3O28/KCucGlVaNSnviY6X6OI2OgoJC3+jNJVB8UlDoL4pP/UNpHCoMKIIoIPQwVZMgKtMTKSj0h95c6lqnoKDQdxSf+ofSOFQYUEStGrGHtzNRSpyDs1FQGLz05hIoPiko9BfFp/6hNA4VBhRBEHuOHArKaDAFhf7Qm0td6xQUFPqO4lP/UBqHCgOKoFIh9jB3pnCK+TQVFBS605tLXesUFBT6juJT/1CaywoDSlfovqdFQUGh75zMpf769MADDzBlyhQsFgvZ2dmsWLGCQ4cOddvm4osvRhCEbsutt946kJekoHDOGEifLgSUxqHCgCKIYq+LgoJC3zmZS/31af369dx+++1s2bKFd999l1gsxuLFiwkEAt22u/nmm2lubk4t//M//zOQl6SgcM4YSJ8uBM7L5rIkSTQ1NWGxWBAEZRTSQCLLMj6fj7y8PMQehBI1qp4HpMTjn8fpKZwFFJ/OHifzqTeXoP8+fXbmiL/97W9kZ2dTWVnJnDlzUuVGo/GE2SwUBhbFp7PD6dZNoNRPPXFeNg6bmpooLCw816dxXlNfX09BQcEJ5b29hfX3zeyBBx7gpZdeoqqqCoPBwMyZM/nVr35FWVlZaptwOMydd97JM888QyQSYcmSJfzhD3/A4XD0/4IUekXx6ezTk08ni2icaaTD4/EAYLfbu5X/61//4p///Cc5OTksX76cn/3sZ6ecWk2hfyg+nV36Wzd1rVPoznnZOLRYLEDyIVGynQ8sXq+XwsLC1D3+LIJai6A+MQu9oO5fktGuz2BTpkwhHo/zn//5nyxevJgDBw6k5oD+93//d958802ef/55bDYbd9xxB1dddRUffPBB/y9MoVcUn84eJ/OpN5eS66TUz38anU6HTqc76TElSeJ73/ses2bNYvTo0any//f//h/FxcXk5eWxZ88e7rrrLg4dOsRLL73U38tSOAmKT2eH062bkuv6Xj9dKIGL87Jx2BWqt1qtZ1W+Bx98kHfeeafXTwM9lcuy3GP5vHnz+NGPfjTg53i26PVziCgml57K+8GpPoN5PB4ef/xxnnrqKebPnw/AE088wciRI9myZQvTp0/v1/EUeufz8CkUCnHTTTfhcrn67FPXzJ+fLRcEgZ/85CfMmjXrrJzr2aDHa+7Npa51cEIE6p577uHee+896bFuv/129u3bx6ZNm7qVf+tb30r9e8yYMeTm5rJgwQKOHj3K0KFDT30RCn3i8/Bp8+bN/PKXv0Q6ycwfPfnU03NotVr561//mnop/6LT77qpa10fuVACF+dl4/Dz4q9//SsHDhxg5cqVvW7z6amre3toX3zxRWpqagZV47A3BI0WQdND5FBzZtMTffYzWGVlJbFYjIULF6a2KS8vp6ioiM2bNyuNw0HG8ePHefbZZ8nPzz/p766vPk2ZMmVQNQ57ojeXkuuSPn02+nSqqOEdd9zBG2+8wYYNG3r89PZppk2bBsCRI0eUxuEgY82aNbz11lt9rpugZ58qKyupra3lZz/7Wbco82CkLz71hQslcKE0Ds8AlUrFd77zHR5++OEz2s+dd97JW2+9NUBndY4RRRB7yBn18ZvZQH0Ga2lpQavVkpaW1m1bh8NBS0vL6Z+/wjnl6aefZvbs2We0j/OmP1dvLnWto+/RJ1mW+c53vsPLL7/M+++/z5AhQ075M7t37wYgNze3z6es8MVAEAQcDgcvvPDCGe1ny5YtzJgxY4DO6hzTB59Op346XwMXSi/MM0AQhBPevvpCQ0MDlZWVNDQ0nIWzOrcIKg2CuodFpQGSFbfNZkstDzzwwCn32fUZ7Jlnnjnbp68wyLggXfqUT33l9ttv55///CdPPfUUFouFlpYWWlpaCIVCABw9epRf/vKXqUjRa6+9xvXXX8+cOXMYO3bs2bg8hS8gF7pP/a2fzufAhRI5PANOt2G4ceNGSktLqampSb11nDeIql4ih8mygfoMlpOTQzQaxe12d5OwtbVVScUxiOmPUw0NDbzzzjtEo1EmT55MTU0NmZmZZ/HsPmd6c6lrXT949NFHgWSi60/zxBNPcOONN6LValmzZg0PPfQQgUCAwsJCVq5cyU9/+tPTOXOFQUhDQwPr1q1j1KhRJ9RN50XKnT741N/6qbf+u+cDSuPwDOmLNA0NDbS1tRGNRiktLWX27NnEYxHWrn2Pg4kE119//XnzWflUqWwG6jPYpEmT0Gg0rF27NtWv5tChQxw/fvz8+QxyAdIXn/bv309nZyc5OTnMmTMHs9lMU2MDlTt2YDSZePXVV3n11Vc/h7M9uwxk6o1TNboLCwtZv359v/ap8MWlt8Eln6WrbgqFQhQWFLBk8WLisSiVO3dy8ODBVL/d0wmEfNHoi0/9GSR0vgcuznnjcPHixbS0tCCKIhaLhYcffpgJEyZQUlKCTqfDYDAA8OMf/5hrr732HJ9t//mkInNgNmQQ9rrIykgnHBX58sor2Lxtx/kVPVRroKd0Aer+JRm9/fbbeeqpp3j11VdTn8EAbDYbBoMBm83GN77xDb7//e9jt9uxWq185zvfYcaMGYOmT8fZYLD61JfK5/Dhw0QiEXw+HyXFRagEMBv0aDQahBwHN33t//HSa2/i9/s/hzP+HOjNJei3Twqnx2D1qS901U0Zdjs2sxEhHsZi1iGpNcybOYUOp5vGdte5Ps2BY4B8ulACF+e8cfjcc8+lWtcvv/wyN954Ix999BEAzz77LOPHjz93J3cKTvV2tn//flxOJ+PHjSMuSQjxCL5Egvo2F++9/z5mo5Hlly4hFo9jNBo+xzM/ewgqVY+TmPd3YvNTfQYD+O1vf4soiqxcubJbLqkLmcHsE/QeOTx8+DBerxdHdjYlJSWEQiG0KgFfKIy33cnGjRupKC/nmquuoMPp/nxP+izRm0td6xTOPoPdp97Yv38/mzdv5ksrVyKo1MjRIJFIlE5/hLdWryYUCnHNiuVMGpXJlEkTz/XpDggD5dOFErg4rcbh5s2bee2119i9ezcul4v09HTGjx/PZZdd1u/0EZ8Ou3o8nvOjb8PHdHZ2cvDgQYaUlqK3pFFfX8/WLVuYNWsWF110EZ2dnTS1OzHpNLz87NNIiTii6py3188MtSa59FTeD/oSSdLr9TzyyCM88sgj/dr3Fw3Fp1P/vtvb24nH4+zZu5fpM2Yii2oOHanGZDIxevRoZFmms7OTdpcXo07LtStXIMsSgjCIx9z15lLXOoUTGEiXYHD7dLJz7ezsxOPxUFtXR0FJKcGIxJrV7zJ16lRmzZpFZ2cnrkCYhCCw+rUXCcXkPn+q/sIyQD5dKIGLfrVE1q1bxw9+8AM8Hg/z5s1j0aJFWK1WvF4vBw4c4Prrr8dms/HrX/86ld+nL1x//fW89957AKxatapbuSzLTJ06lf/+7/8mKyurx5+PRCJEIpHU/z87HP1scjJZMjIygOQb5v+74evkOBzMnDkTm80GJLOom81mHn74YS6eM5vs7GxUGi0qnWHQSiiIKoQeOv32VHaho/jUd7Kzs/F4PFRVVfH++vVMnTad7Oxs6uvraWhowGazEQ6H0Wi1XHn11bz4/LNEA340eiOienC+cPXmUtc6hU84Wy7B4PXpZC9cGRkZmM1m1q5dyyXLLeRkZTBjxgza29vJzc3FZDJhtVppaGjgkf/7P/74f78l7nejNlkH7bM3UD5dKIGLfv3V/NWvfsVDDz3UbaL2z7Jx40buv//+fgn45JNPAvD3v/+du+66i1WrVrFhwwaKioqIxWL89Kc/5YYbbugm5qd54IEH+PnPf96fSxkQTvWQVFRUIMsyHo8XgWQof9jQofi8XgwGA5s3b0aj0TB9+nR+8KO7+Gj3LhLRCFLCh8ZgGpQSdqUL6KlcoTuKTyfS20vR8OHDOXz4MDNmzEBQqYlGI/i9XoaWluJyudBotbz//vuYzWa+dPXVPPHkP7nz379HLBxEpdGg0uoH3QtXby51rVP4hLPlEgxen072vHfVTU6nk7S0dNatW8fIshGUDhlCp9OJLMu8+eabTJs2jX8+9RR333MPRXkOYj4XKoMZlVb/OV7JwKD41D8E+Qs2DMlgMNDQ0JCKugE0NzczYsQIfD5fjz/T05tZYWEhHo/nrE6fN3r0aBYuXMhDDz100u2qqg5hsqVRe+QwTU1NGI1GZkyfzvMvvEAwGKS8vJxrr70Wv99PIh4nHg1DIo5ab0TVS0b3c4XX68Vms51wb7vKOze8gNV84jRLXn+AjDlfOuu/E4XuDBafDhw4QEVFBZs2bTrl57/a4w34/T5cnR00NTWRk5NDWVkZ//rXv4DkaMFNmzbxhz/8gVg0gpyII8gyGoPxC/fC1ZNPp3IJFJ/OFYPFp5///Of86U9/orGx8ZTbNne6OXa4ikQ8RktLC2PGjAHgzTffZOrUqcyZM4cdO3YwccIEouEgQjyCqNagMpi/UN02TrduAsWnnjin31vcbjfBYJC8vDwAXnnlFTIyMtDr9d2GgT/99NNMmDCh1/30JYv52aAvfTAaGhrYd2A/w0aUc+zYMdLT03FkZ7N9+3bS09MRRZF4PE4gEOB73/set956K/F4nNzsLDSRKAaTEbXeNGiiHoJGg6DpIXLYQ5nCwDLYfYJTp7JpaGigpbWV9vY2nO1tZGVlUZCfz+rVq8nPz8fj8dDR0cFjjz3GpZdeis1mIz8/D6vJhCEawWC2Iqo1g8Kn3lzqWqdwdhnMPvU15tPQ0ICgM7Fv7x50Oh2lpaWEw2G2bdtGaWlpqgvUsmXLeO+994hGImRlZWLURjHGY6iNSZ8GA4pP/aPfjcPjx4+fcpuioqI+7cvj8XD11VcTCoUQRZGsrCzeeOMNWltbWblyJYlEAlmWKS0tTYX2v2icqpJpbW1FpVKTmZHBmDFjsFitVB8+zIGDB5k+fToXXXQRJpOJ//3f/+U//uM/WLx4MfX19SDLXLJkCaFoFKM+yPGmVmxp6aecD/Wcc4ok2ArdUXzqTl98stls2NNtBPNyMVssfPDBB3R0dKR88vl8rFixgssvv5w333yTNWvWkpWZyaRJE7HG4ogqFTXHG5INyy+yTwOYBPtCYCBdgsHvU19egFpbWykYWsaUKVMQVSpUKhXr1q4lFosxYcIERo8ezVtvvcW3vvUtjh07Rn19PYFAgIvnzqEwPw9z3EkoluBYQzMOh0Px6Tyi343DkpKSHqeN63oQBUEgHu9bzqDi4mK2bdvW47pdu3b199S+kDgcDhBVuFwutm/fTnZ2NkePHsVsNpOVlUVraysOh4Mf/OAHTJ8+HVmWmTv3YjQaDdt2bGfWjJlUVddQUpBHc1trasqrwsJCSkpKzvXlnUDXdEQ9lSuciOJTkr5GOhwOByqdgXXvribg95OdnU17e/sJPr344os8+eSTZGc7GFJaSiQSZevWbcybdzFtjY0UOLJoam2jvr4en8/H4sWLz+r1nQ69udS1TqE7A+kSDG6f+oojJwdkiXXr1mGxWMjOziYWi2E2m7HZbOzatYvRo0ezY8cODh48yKhRFWRlZ9NQX4/eYMClEjGqRXLSzTQ1NlJXV4fRaDxpJPVcofjUP/rdOHS5TkyKmUgk+Pvf/87999/PsGHDBuTEBgN9mVu5oKAAk8WK0+Vizpw5OJ1OhgwZgsFg4MMPP0Sj0VB16BBz58whv6AAi8XKxg0baG5uYsKEiag0WjKystCaLRTp9AjI7Nq7nyNHjuByufjnP//JLbfcgtVqxefzUV1dnWyQkvy95OXlEY1GaW1tJS0tjaamJvLz82loaCAajTJq1KiBbWQKvbydCcqbWU8oPvWP/Px8XL4gFRUV6HW6bj7t3LmTRCLB3r17mTZtGpMmTSYvP5/XXn0FrVbLhIkTicUSFJUMIRaLM3RIMf5AiAOHDvPBBx8QiUTYu3cvN910Ex0dHRw/fhyz2QxAPB6noKCAgoICampqUhHMxsZGhg4dysGDB1Gr1VRUVAxc9KQ3l7rWKXRDcekT+tptIjs7G08gwsUXX4zJZOrm0549ewgGg+zcuZOLLrqIYcOH09jQyKo332Ds2HFkZjloaWkmJ7cYKRpmdFoabS4vR+vq2bBhA9FolHA4zPz583E6nVRVVWGz2RAEAUmSyMvLo6CggKNHj9La2orZbMbpdKZGSaelpVFaWqr4dI7od+Owqw9CF6+99hr/+Z//iSRJ/PGPf+Sqq64asJP7ohOPxxFPMY1VTU0NNnsGAb8fEZl9+/ZRVl5OXl4ekyZPpqmpCXt6Olqtllg8zq6dO3E4ssnMzECWJZ577lmuuPwKopEowVAYtSgwaexoNnywme01NXzlK1+hs7MTn8+HVqslPz+fjo4ORFEkFovh9/tJT09PfQIpLCykpaWFnJwcVq9eTUNDA2PHjh245JyCAD11Uh4EfbzOBYpPSRKJBMApfTpWW4slLQONWsP69esxmUyUlZWRX1BA6dChBPx+7BkZmC0WZFlmzZp3mTJlCh0dHXR2dIAs43S5yM/LZV9VNRXlIxg+pIh16zcSjkS5+OKL2bt3LxaLBYvFgt/vTzpqt+P3+3G73bS0tJCdnY3JZMJoNBIMBmloaMDv91NXV8e0adMYN27cmd+U3lzqWqfQDcWlT4jH46dsINbU1GCyWAnHEuj1ej744APsGRkMHz6cdLudjIwMcnNzSbfbMZvN+H1+JCnBlClTUKlU/PMfT3L55VfgdbsxmIwcaWyiNC+boN/Gex9sRa1WM3HiRA4ePIhWq8XhcNDc3IxeryccDqd8amtrw5GTg8FgwO12o9VqaW5uprq6mqqqKi666CJGjRp15jdF8alfnPaAlE2bNnHXXXdRV1fHPffcwze+8Y1T/mE/34hGo2i1vY8mrqmpQZJl4vEEep0OlUrkmmuuSY5qk2W0Gg379u7FbDZjMBhoa2ujqLgIi9nM1q1biUQiTJ48mdq6WkYMH0Y8Hqelo4MhQ4Ywe9YMZEHEEwjT2tJMwO/HmptDWloaBfn5hMJhAsEgkiSTk+NAkiREUYVKFDGbzXS0t3PrLbfw7po1hMNhtm7dyvTp07n77rvJycnhpptuQq/vf7oCWVQjiyc+Vj2VKXzChe5TLBYDOKlP+/fvR/Nxx3GtVsPKlSuREglCoRByIkEiHmfnzp2YzWYmT55MOBxm7ty5tLS04Ha7EQQBo9GI0+mkqCCPRCKO2+cnLotcfdUK/MEwbp8fl8uFx+WidOhQ9CUljKqowOfz4XG5MVssTMwvQJISqNVqTCYzPp+XFStWoNfpePyvf8XlcvHkk09y4403cvfddzN9+nQuueSSft+T3lzqWqfQMxe6S5Csm042CKampoZAIIDJakOWZfQGA1dccQWxaIRQKEQiFktFzy0WC6NGjcJoMlFcMoRDVVU0NTUxY8YMmpoak4N0jEba2ztIs2diz8jkpuu+hNMfJhiOUnvsKIUFhdjS0iguLMAfCBAIhggEAuQ4HBTk5xOLxzEYDBgNBjxuN9d++cu0t7by2uuv09bWxo4dO9i6dSsWi4XbbrutX31Hu1B86h/9Nmbfvn0sX76cyy+/nMsvv5wjR45w8803X3Dywakbh62trTQ3NeFydnK8voFXXn6ZPXv2UFlZSUdnJyaTiZKSEkaNGsUHH3yASqUiHouh02qTb2/p6cTjcex2OyqVCsvHSV3b2tp46bU3CYVCWHUq8nIcDB8+HKvVhtPpQm8wYEtLI9vhoKAgn0QiQe2xWpAlQMKo11FSUkIwFOLiefNobW1l9+7d/P3vf+cXv/gFt912G1dfffXp3RRB7H1ROAHFpyTRaBQ4eeOws7OT3bt3EwoFWffeexw4cIB//POf7Nq9m1g8jsViSflUWVmJKIoE/X7y8/LQ63Tk5uYSDoUYNnQowVCY3Lw8qqqqcLpcvPbGW+g0agwaFaMrKhheVkY4EiEej2MyGMjIyGTI0KHY7XbcbhdulztZqWrUpNtsaDQaErLMddddh9vtpry8HFmW+fnPf87SpUtZvXp1/2/KyVxSfDoBxaVPiMVip6ybXC4XR6oPE4vFeeXllzlw4AAbNm6i+mgNolqDRqNh4sSJZGdns3PnTlSCgBSPMmb0KOx2O4FAkMysLNLS0xE//lTscTl59/2NHKo5TrpRi0ZIMGniBLKys+l0OkGlxpaWRmZWFsOGDcNgMHD06FFkWSYai2E0mcnJzSUei5HtcLBs2bKUT3/4wx/41a9+RXFx8endFMWnftHv5vL48eOx2+1897vfxWAw8Kc//emEbb773e8OyMl90YnFYqlIRk84HA6CwSAf7d7FuImTOVp9CLvdTmtrK4IgsGrVKsaPH48kSSy77DLUoojL7aahsZFYLMaw4cOx2OzUtbvwx0U2v/8uY8aMIRwO86UvfYlwOEwoFiXNbMQfChMMRcjOySESjQICAb8Pg8FAKBikZEgJokpFU3MzudlZxOMx1Go1brebiooKXC4X8Xg8FfI/7T+oKlVy6al8kDJnzhxee+21VOqK1157jUWLFmEwnPl82IpPSboihyfzKSMjg4MHD3K0upphI8rIyMhg7ty5xBMJ9uzZw/Hjxxk9ejQ2m43FS5agVqlwOZ34/H6ysrOx2tIw2uwEIzGa2tvYtX0rU6dORa/Xc+myZcQTCQxGIzoVyJJANBpFr9cTicVIxOIkpASiIKASBLJykm47/X5yszLwhyKo1WqcLhfDhg0jkUiwaNEi3n33XSA5G1K/6c2lrnWDlLPlk+LSJ/S1bvrggw9YXFSKIyeXjIwMDh06xMRJk1m75l2GDh1KJBKhqLiYcWPHIqpEGpta0Om0OHJyyM4tZH+rFxV6Du3bj8PhIBwOc8mSJSAIBBISWfZ0YtEoEVkkw24nEY+DKOL3JeumWDyONS0No8FAp9OJWq3GarOhkWWCwSAAQ4cOxev1kpeXR1NT0+nflPPQp7NZN/W7cXjRRRchCALr16/vcb0gCBeUgJ99O2toaEiNmAyFQiQSCSpGjSLdbmfs2GQ/pEQigclspry8nKzs7GSeQ7+fjo52RgwfQSAURqvV0uHx4wvJaExWNCqZS+bPRSck8AQjtDY34GxuRDClEc3Jw2y2kqkLIYRcRPU2REEAUaS1vYPsLDvxWAyPx4PFZCYuyRh0OmQg3WZj44YNTJgwAVEUCYVCzJw5k/T09NO6J7IgIvfwFtZT2WBh06ZNqcgWwFe/+lV2795NaWnpGe9b8SlJb43DLp+sVit+vz+ZIFsQSMvIor25Mdl4i0YpLCpKRg6HDKG9rY2A349KFMh25BAIBDCazBysrSfblIUsxSnOzaZk+aVokNhcuRt1IsqxujrKx04gJoNeb6A4K42A34XWYscTDGA0mqirr6dsWGnyM7UMep2OmAQWo4FYIkFGejqvvvYas2bN4tFHH0Wv11NQUHDSiro3enOpa91g5Wz5pLj0CdFotMdn7tM+JRIJZs2ahZyIMWnKVMIBHzNmzCA9PY2CggJsNhsqtYZ4LEZDYyMjy8tS/dd11nT2dISQ1Xo84RijSgvRE0eUVFQfOUyhUaI1BMaC4QgaI2o5Tm7LTvy2fKL2omRXEFkmGg6Tk5tLe0cHarUalUoEWUal0aAH2traUKlUpKen09jYyEMPPcRPfvKT07on56NPZ7Nu6nfj8P333z/jg54vfFbAhoYG3nzzTUKhMBarhazMTI4cOcKiRYuoPlRFIBBgz56PmDVrFmqVitIhQ4jH4wQDAbZs2YJWq0UtqjCazYRkNVp7Dkhxju/ZhqF8JFJ6FkLMTZpRixoL+RYNKjlBVBUnkogiCCIalQq1IBEV1ehNVgxmG4ZEEEGOo0uz4fL4iPh8xBJGLAYd+/bto62tDafTmboWQRBOP0mwqE4uPZWfJwzkpEKKT0l6+qz8iU8hjCYTVouFoqIi9u7dy8Kly9i7bx8F+fnk5eWRlpZGpt2O0+kEkn80RwwfjqhS09bWTnpBKdlFw5BDXpqq95MzbjSSWo8mEWDWxLHEBRV5aQZkIUxMZSCOBIKI2aAHEtjSM5BkmdKhw9AkgthNesKygMvlRgZ0Gi0GnZrV77yD3+9P+dT1Cey0fOrNpa515wkD5ZPi0if0FrhY9dZbhEMhjEYTVouZgsJC9h88yPjJ09i2bVuye5LNRmFBITqtBpfHw8aNG/H7/cnInyThjEiEkUFQEWw+hkEr0TmkAmvCR7ocRp07FGOkjlG6KIlADX5tGjG1EVmlQRcPkqjZQdaQCWjUIjLpSAjY7XaikQg+rwdZkjAYjERjMdavX8/48eO71bMDXjd1rTsPGMi66fy4I+eI5CCPT944Wltb8fv9XHH1l9Hp9MR9ncyYOgmzyYQ/GEQlqrGajAAIoojRaMTv91OQn8eXv3wdXrcTrU7Pruo6ckrLCLidZGgSFBcW0NrUwBAhjmDU06ayIUoJ1ry/nWnjR1Ng1yPJCeJqIyqVmoigQhZENGqB9uZmAho1UiRITrqEWorh9AXY/OGHLF04j8rKSsxmM3a7HaPReOY3pbf+G4P0zUzh86FrtPKn//C3trYiy3Dd124kGo0ih33YMzMZN3oUXp+fJQsWcOjIERKJBEajibbWFiwWCwa9ni9/+Tri0TA7du3GlFOCrDWiCnupOfgReXl5HDh8lLHDiwjEZCRzBt6ONg4d2MfkMSPJtKiIyQZkrRFBjhMWtAiAkIgTDgbYvGsXs6dNQitLqEWR/fv3E/T7mTBuDB0dHQPn08n6Qik+KZyEz9ZNkPSpvGIMQ4eXEfJ7sahlLGlpjBlVhsvjZ9GC+TQ0NZOIx7HbM/B43GRlZnL1l75EPJ5ArRbZULkfQ/FIZFkmkyB5GUZcLhextlrMDjv7olmgUrPNrSVHJTHEpsEghQnrsnCZcwlW7UWd5cAkx/H44siyzJ49HzF95iwkQUSt0bJ+w0aKiktIxGPodLqzXzd1rVPohtI4PEM+XZk5HA7MZjP7du9izPiJHDh4mMOHD7F8+WUY9TrkRIhR5WX4AkGMBiNVVQfxeb0MKSkhzWZDioQwaAXGjyihMxzGIodQqwzYcnKw2ax43U7iFgcyAglZYvrCS5ER8GkEZEQSsowQjyJHQwS0aVj0GixmM4FQEKPNji8eJ02vwmbJ4ki1BkmG8RMmpOQbiFC0LKp6Ga08OPt0dLF69epUqgxJkli7di379u3rts3ll19+Lk7tvODTiYq7cDgcCAI0NtQTCgVpqKulqKiIjvY2Jk6YgN6gZezYsXg8HsLhMOFIhEQijigIxOMxQqEgYydNwx9NIMYCqMQEhYVFZGdlodfpCEeiSOYsEpKMKT2T8bPmIahEgmoBSRYISDLmaIiEHEXWmVALAmqNhtJhw4irdRANk2XWIAwfSntbG7IgMmXKlG4+nUkfqd5c6lo3mFF8+vxxOBy8v349RSWlfLR7F/FohNIhQ/D7vFSMGonBYiLNnkE0GqOzs4PNmzczd85szCYzYtSPEIqwcFQeO4IS6aooVo2AM5hgxIjhtLd3cDyiJS6IGEUBQ0EJUQQOSQmCcRlNSMCECXv5WPRqAVEAjUokQbJPYSwcQhZVmNPS0Ov15Ofl0dnZwaxZs8563dS1brBytlxSGodnQFdF9ul+hsuWLaOhoQERieGjRhONRgiHI7S0JEcEL16yBIvZTKPbz9Ahybcji16DHPZjSjcTFvU0N7ZQU11NWloaDkc2e3bvYvq0qXi1RqIIaGUZt7ODcCjM0CElBBMykixhi3ai0pmpTZgJ+uM4vC4sJgM7d2xn7sXzcHkCaLOzUMeCXDJ7OnVt7Wg0mlOObOvnTek5Z9QgzyN1ww03dPv/Lbfc0u3/giCkol8KZ8ZnfWpsbPw4khDHZDJhMBRz9FgtXp+PjIwMysrKCIdC5OXmIssyalFAjYxJK+JTqdix4W3Khg9Hr9cTCgVJxCIcOVLNxJmzSQhqhESMA/v2UZCfS3Z2DsGEjCAlMElBJI2ehoCIOuDBKIUxGfQ0NjTgyM7GG4piMxnJtqrIsAxh60f7yMzMQqVSDUhl1qtLXesGMYpPnw+fdqmgoICpU6bgbG1ixuyL2bF5Izq9Ho1WS1X1UTKzsvD7fFhyi0mLh1k8eQyGhB+5rRWDVk1crccv69j9xr+YN28+AY2GSCiIQaPmQE09Yomddl+ENLWEHA1RXpyL/+MJaVQiJAxWYrKG7EgTx1pimDIchEMhIuEwcbMZnVpNPBpjzrx5hIMhOjs7yc7OPvt1U9e6QcrZcqnfjcM77rgDr9fLggULTjipC5FRo0bx9ttvI0sSkiwzb9489h84iNWehc1uZ8SIEbS1thGzZNGWMYq/H4rii3WiEeHn3pfQqlRIOh2CWo0kCGiAMqBMBfiOI/tkSlUCVDaQBoSr1TxmWoAsiIzJTCMtKqMSBQwxH1ZfPZJaD7ohyDLUHKth/NixXLJkCfVNzeQ4HIBAXG1EL8QYkmPng52NtLZGiEQiAGecjf58zHMoSdJZ27fiU3f8fj/bdlTi9/tAkpg3bx7BYBC/10NxSQlHDx8ikYiTm5tHS0cHWem57G0PM8J7GKPzKGh0oNYkB2QJAnbgijwBMVyDFJCQZBCP17M4S4VUvZ46fT4fJTKRrYUMsabhi8sIgD3SgSXqImrMANJJyDKNzU2MGzOG8uHDkQGz2YxKoyEuy2jkCJMqyti5/zBGk4mGhoZuLp1OX6DzNS/b2fJJcak7N9xwA6tWrUIUBRKJpEsbN21i+sxZRCNhRpSV09rciDucoEOTxTvVEbxxPVJ9K98MbWRIpJmuJkXXWHs9cJMN2PkiXU+0fBCWAHR8yH8KCzga1lKYpqMwH7qaXCZRwqZRYZNliEAwHEYfj5GZmUl7Wysmk+njbBk6BEFEZTaTnZPL8dpjhEIh4OzVTV3rBiNns27q9x2pqqrib3/7Gz/+8Y8VAYG0tDQuXbwQrVZLY1MzLo+XBctX0uaPsOOIkxqngDOUheQB9NkQSyoVk2Q6E1rs8SBSJAKiiEqnQ9TpEFLD6uWP5ZLh48pFQyw1siosgS+SwCwF2Ve1l/QxIzD4mzHhJqhOo2L0WFRaHaFIBI1KRSweT/Z/9PtRGfR4vEEumjiGUELgr/96BovFwqWXXpo84ul2bBVE6CkNjtKno0cUn7oTikSZvXApAPXHjuDz+RgzZgxCLISo05E1pAxvXKQxIWAZlYlTFkAGja8V4tHkIghIai2CJumSGiAhJZO6CiTzfcbjqAAhGiKqSUYmvDEZsyDjbTyKW4ThGRaMwU50WjOi3kBhxWicbi9qlZpIJILFYkGSJGRZJiSrkeQYM8aP4kh9M6tWrWLmzJnY7XbgNH3qzaWudQrdUFzqztixY9Fp1OQ6snG73UQiES6+ZDmBmERla4iazhhNfjuxVPvik2dqh7qIIZHmk+6/p1ibUYgDWuREglAsQaFZTeORA1iHFCFE1QhGPRICuZl2NCYjHo+LtPR0wuEwFouFSDSKWq3G7/VSUFBAcXExr7/6Cnv27GHmzJl9mrK29xNWfOoP/W4c/sd//Ae//e1v+fnPf342zuessH//fubPn8+0adOQZTn1cHWNyv10PyeXy5X6g94TV111FRaLBZ/Pxx//+EcOVVWRlz2LVa+vYviBw6xadCPe+loSp3h+LSoJr8WB3VebbPhJEolQiHgoRFxnIqyzEFBpkiPEEnF0yGg0KkSVhrEmDVqNmnQNqJAJqUwUlQ4narQTSghUu2VsugAavQZnu4fMbAf2zEzisRiBQIBAMIjH5ycjM4MtOysZXpDN0vmzeWvdRpqamhAEgS1btpzezT6PB6SsW7eOl156idraWgRBYMiQIXzpS19izpw5p73PwejTQw89xMMPP8zo0aNTPn3ao65/x+NxAoHACdOadfFpl77zne/wj3/+k0BURupop/rAHiZPmU486KWlvo5IJIYoxVBLMeyJKNlSDHUiSkPWaExCHFlnAikE0XDSp1gEORbBjwbRnsdHx1vJy08mhE8zm7AZtEiyjEVjo0IUMBkNxANeEup00vNLiTqbiFtz6PRpaQ9EyDWokCJQV3uMiZMm4/N5kSWJaDRKMBhEq9MTTwise/c9llx8EXuNeo4ePZq61srKSpYtW9a/G32ed6AfaJ8Go0uSJDFnzhxkWcZut/daNwmCgNvtxmq19pqD9tM+LVy4MNmNaf7FbNleSc6HW9g+60qOHW0hcorKSSvIWIw6VLos5EQi6ZMsIwOhBIhaPe0dnWTYk5M0IIPBoEeQJfIw0KnWUJCmp9wUJcumJ2NkGZFQMDlIMxEnIaqRVGoCoTACAjmOHPw+L5FoFEmSaGttJTsri4MfJ6ifc/E8XnjuWWpqaliwYAHBYJDGxkby8/P7d7PPY5/ORt0kyAM59vkLgtfrxWaz4fF4sFqtjB49mv379wOwfPlyRFFMSfjpxqLL5UpNDN4TV199NYlEArfbTWlpKTkOB0MK8zladxyzxUrw6WepPdLCpmu+85k3FBmDKFGkjTLaJjPVoabdEyCusxCVJOz+DoS6fehD7m7Hi8oCscyhmLJykEvK2Xu0jrIRZRw5epSc3Bxs6RnE4nGOB0AUBLI0MdpCCfa6kh8DLs1Xka4TkAQVbn+ESCSM2WRCp9OiEkUQBLxxAbMUJoLA62++zciRI+ns7GTZsmVMnTqVrVu3nvTefra8/XgNVqulh9+Jj6yi0hN+brBw66238qc//Yn09HRGjBiBLMtUV1fjdru57bbb+L//+79zfYpnjc/+zrv8yM/PZ9KkSam3+U87BeB0OnvNl3n11VcTDocxp6UTj4QpLytDa89FYzBibdiFvmEf6MyYo56TnlssbwQ6tUhHFHwqMxkFJURa6tC7GjDHvKnohiyIHAtAXlEp6oJSApKGmvpGMu12Ol0ucnPzsNls+CJxPAk1RAKkaaEhLNAcgkwdTMlSIyATF9X4fEFUKhGVKKLTaZODYBDpcHvIMuuobe5k/7695ObmUltbyw033MA///lPvvKVr5z03n66rDeXktsoPg1WPv079/v9qUbO3LlzU/VPl09dLkWjUaLRKCaTqcd9Xn311UQiESLhMFqdjkmTJmEx6hEFkYQgEqo6ROujj7P2y98nZO0e/FAj49DEGGUKc5FDQACckeRSOmwYrrpDpMV9WAmnfHLHRBpkM47RU0GSaGuqx2Y2cfz4cfLycklLS0cQBEKhIDaLhVA4jEarRRN0YpAjeEy5qHRGEjKoEhE8Hg96nQ69Xo9apQJBQJbBGwhiNBh4f91aorEYubm5zJ07F4BQKNRtitfTrZuS2wxen86WS4PzQ3s/efvtt5kyZQotLS3k5+fz6KOPntZ+KisrkSWJIaWluJxODFo1e/cfID8vl6I8B74772T/Lx7mouf+j63XfYdsTZwx6QJDRRfxUJAhQ4bQ6PLx1q6jdLrczJw5k81bNzN+/ARM45bSdHAP42wiqqbDqOMRRBlCH7xHKBohUjKSjLmXgSBgTU9HqzcSj8fwe73k6o20JHR0xjVUe5P54vINAtt27GLm9CmYNCKBYAC1RktDcwvFRYW4A0HUGg26YAeeOOhsWSxevASnszP1Zrpt2za8Xm+/ZJEFoZck2KfX4feRRx7hf//3f2lpaWHcuHH83//9H1OnTj2tfZ0uL7/8Mk888QR//etfueGGG1KNI0mS+Nvf/sa3v/1tFi1adMGMrvzHP/7B1772NRobG3niiSdYtGhRv/dRWVnJhg0bWHzVl/FHEmyv7USq7eCaztWo5OTLjRwLImu0IAgkBDWoNai0OoKxBILOiMZgQmXP5x/rtiKJKmbOnMm7Gz5k9uzZVLYHERNGphakIzVXY5TjONQCiW3vEKnKpHPoVHILSjEa9IRiMXR6PbFEHCnoxWKw4Neb8URDtIQkQCZXL7Bh+0fMmjoRKRYnFovh8YaIxWLYMzKRZBlBgHxtnMP1nRQUFuNxu7HZrKk5br/+9a+f0Dg8Gb251LXudFB8+mKRl5fHypUrefHFFzl27Bj79u3DYum5AXMyKisrObB/P19auZJgKETI78Pv9+H1+RhXMQrNRVM56Fcz78nfsParP8RkNTHcIjE1AxLuVvLy8pAw0x6BN95Zi9lsZtKkSWz8cDPTp03ng61bUMswe1QJsZZjpGklDFY9kuc4dd44sgQ6vYHC4hJARgJ8Xu/Hky0I2CwWOjrayBXDdMZUeJ0uENzYsnMJ+gNIkkxd3XHyCwpIJBKIoohKpUKWoaW5iXnz5rFh40bsdjsTJkxg165d/OhHP+Lhhx/u8z0aaJ/Od5cGdyy1jxQUFHD06FF++MMf8thjj/GPf/zjtEbvOBwOKnfu5PChQwiCQCCanDcyO9tBRzDK9u3bGXrHrbhnjOO7E2ysLLcRaa0lZs4mYssjYkhDZc1kypQpzJo1i2g0yqL588jMSOfw4cNYC0uptw9DvfzbJKYux+2JQTQ5UERXexDtC4/R0drCoYMH8Xs91NfWYjSbUclxcrRxgtEE4QSIApRbZMqHD0UlCLg8PvzBMDqjGZs9E78/QEtLC/FYDI3eiM1sJBQO4fX5qKysxOfz8fe//x2AX/7yl/27SaKq96WfPPvss3z/+9/nnnvuYefOnYwbN44lS5bQ1tbW732dCU888QTf//73ufHGG7tFlUVR5Otf/zrf+973ePzxxz/XczqXfPWrX6Wuro7Jkydzww03UF1d3e99OBwOjEYjf352Fbc9uZP9DV5WH48QkpPPiaw3E8vIJ5o3jJf8mcSnrcBTPpetqiJah8ziPY+e4LAZRE3pXDRrRrI/EjLz51xEZ1srXp8PW3YeLmshqqkrCJTNJtaZfG7U3g4cu9/Gv3sTnU4XciLB4UNVNNY3oDOZMItxTEIMV1xAkmVydMm+VHqdBmTYe6CKhAyiRos9M4v29nZqa2vRapMVYX5uDsdqa0m32/nggw8IBAL84he/IBqNnhCJPyknc0nx6bzhhRde4J133qG5uZlvfvOb+Hy+fu/D4XAQDIV46eWXEQCPP0hhcQmjR43EHQjT6ApQNn0cDVdfy0TVcf5tTgn5oo9dVUeQMos57k/gFk3k5eczdcoUZs6cibOjnamTJnLwwH6Ki4vJyMnDo8uAkbNptAzBl1BjTvgZYYxQkmWlpuYosWiUeCxGzdGjHw/SBEkQiEdC5GhiIIgIWiN2q5lINIosSezftw+NWk263Y5Go+HYsWN0dHSg1WgwmUzk5OZysKoKs8mEz+fjscceA+h/RGwAfboQXLogGocARqOR++67j3nz5nH99ddTUlLCnj17ety2pqaGzZs3U1NT0628oKCAZcuWYTSZ0Gi1uNwu9h0+wo7dH1F37BilxUUU200sueoKOjs7ef2116itrSUQCHDk8GGCoTAHDlaRZrPSUF9PaXEBjc0tNDQn51oOh0JkZdhp63QRzxmKsPSrRIpGpI4vlJYR7mihYtwEsjIyKSstwi5GyRSC5CQ6KdSG0SIhyDIqlUh2ug0tcSIJOHbsGNWHD7Fj21bC8QT79u1DFJKfK6R4lIQs0NLUiOnjZKPDhw8H4Ne//nX/RkQN4MTmv/nNb7j55pu56aabGDVqFI899hhGo5G//vWv/d7XmbBz506uvPLKXtdfddVVVFZWfo5ndO4pKirib3/7G5FIhBEjRrB8+fJe5w+uqanhX29tYt2OgzgDESRZJi8/H7djCu92ZhCOSXx4uINEPMHzjGSPrYKdGRORHaWYjSauWHwxe/Yf5LnXV2O2pZFIJCgtLaWmpgZ3IISaBG5nJwU5DjpcHvbs24/RaMSg0yAKMp1eH1FzFolFN9BizAaSn74t6enUNzZjtaVRUVbG8OJ8bEIUU9xPtuwmXZ0cbBKJRTEaDIwfORwpEUdvTI5G3r9vH/UNDYTCEepqa4nHYkRicULBINa0dGKRMH6/H0jO+wswffr0vt/kk7mk+HResWjRIv7nf/6H5557jszMzJM2fHqqn7rqpvLy8mQ6J7UKTyDIC6+8zqHDh2lpbsJu0jH9osksXbqU5559ll07d1JcXMwHH3yAIzuLqsPVhKMxnJ0dpFlMFBYUEIklaO/ooOboUTIz7LS2tSKLarwJNbG0Aj5qjyEhoI+40NhzqK5vJC3dzogRZWTm5qMx2wgkVERkgbiowS8aCUSiaFQCRY4MpFiEtLQ0qg4d4sCBAwT8fupqa/EHAvgDAWRZpr6ujlgshtliQZZlVJ+aB/nPf/5z32/yAPp0IbjUrzvy5S9/mQMHDpx0mwMHDnDddded1smcbTQaDWvWrOGFF14gEAhw8cUX89JLL3XbpqamhnfffZcPP/yQd999t1un8oaGBnw+H8VFybkhHdnZIMnU1iaT8xoMeohH0aoEdu3aBSTTXeh0OlxuN2qVCkdGOuFQmIkTJ1Jb18D+AwcoKS5m1uw5DC8rJxiNE4sn2LvnI7yxOOZrb0FY/jVks4lMwUOBvwGVNYs6b5hjrhB+nw8/OvzGbESDGVkQSCBQ2RJAjAWJyQIdne0Ew2FEUeR4fT1HqquZO3cuTqcLA1EQVajUKnJycjCbzQBkZGRw8cUXA7B48eI+3+OudAE9LZDs//HppSuFzmeJRqNUVlaycOHCVJkoiixcuJDNmzf3+XwGgo6OjpOmUSgoKKCzs7Pf+x3sPlVUVFBdXc1//Md/8MYbb7Bw4UIOHz7cbZsun/683c1db9az5NfrmfVfa5h7/1pe+KgjtV1cFsgS4gzPMLCnvo0RQ4oRavcTi8Zob22hcu8BzGYzeXl5xONxGhoayMrMJBKXyc/OYujQoew/VE1nexsLl1zC9FmzURtMqPQmjtc3sGf3bpweH5lXfIP20QsQ09Nx+OsYUVxAwphGY0gi6HXjD4bwiwaCugyQEyBAZ1xDm9uHKEvEZYHm1lZcbjdpaWls2rgRq9XCiPJy/F4XBlFCZzQiSRJ2uz31ibCsrCx1rX39Y30ylxSfujPYXQL43ve+x759+5g2bRrf/e53+cEPfpBK49JFb/VTQ0MDHR0djBo1CqfLhcVqJR6NUVJSQmtrK6NGjUKUEmTb03jnnXcIBoOpusnv99PR6aSkIJdgMMikiRPxB4I4PV4SiTgXzZnLxfMXEI0nyMnL561VbyII4HR2UlQ+ho86EjTGjFgtFoaNmUhHWCYi6mhp7yQWDmGSw1gSAVwRGVml4XhjE8EExFU6PM5OampqUv2T3169mnnz5yMnEslMAEB2djYmkwmr1YpGo8FisbBp0yYAvvWtb/U5eDFQPp3vLnXRrz6HK1asYPny5WRkZDB//nzKy8uxWq14vV6qqqpYt24dnZ2d3H///ad1Mp8HoiiycuVKpkyZwrJly1i5ciW33347v//974FPpsC79tprCQWDmE0mYtEoXp+P+vp6LBYLL738MuXl5RQX5uPIyiB91ix8Ph/paWmkq8KoEmFGlZdhsiQfZpvNhqhS8fwrr3PF8svQqkWCsSixRIKcnBwEOcGhgwcoLhlCU2MjZeVlmEwmWpqbiYcCpI2diBTrQGg5iibQiUGOUhVRIQhqOtUGJrmPEpdycHd6mWDPoqmujjGH19Kst+Itm05WdjYFRUNwuTpZvGAeKlGk9lgNRXYTomxg95F6mlraKCoqIr+ggHfeeQebzcaqVaswGo2sXbu2z/c32a/jxP4bXWWFhYXdyu+55x7uvffeE7bv6OggkUjgcDi6lTscDqqqqvp8PgNBb5PYd6FWq7tNft5Xzgef7HY7DzzwABMnTuSb3/wmZWVlrFmzhgULFgDQeaSKYZ4mInJx6mfikkxckhGR+DjBDEO0Xr679GJC7nby83KQD3yI2NFIrKOJzHGzWbhgPmqNNvWHcMeOHdTX13P55ZcTFTXU1BxGbzSh02poaziO2mBErzfQ2NjAiLIy/D4fXrcTMRYir2Is8WgbxAMYQp34jOm4EhpCqnRsqgTF4VY6EgLmRIAigxFL/R6yKrezQVtETtkYJk2ajD8QIB4Ns/zSSwgGg7Q2NzN0ZDHukMSb767GaDRSWFTEtGnTWLNmDTabjWuvvZZnn32WFStWUF9ff8p725tLXetA8amL88ElSL5wrV+/nltuuYUHH3yQP/3pT9TV1aUGdrW2tjJt6lTSP07/otfrcXZ2UnvsGHl5eaxdu5b8/Hy2b9vGVSuW09piYNKkSXi9XjLSbeijPsqHllBeXp6qm8xmM2+vWcflyy9DkiTS0iy8+MqrzJo1C41aRfWhKnJyc+ns7MRoNLJw0WKcnZ1EIxFi4SAV5cOprTuO3RRBBBJaAY0ok5uVgTrqR5OIUN/mxJZbhMvtYvKYCpwuFzU1x7DZbCxetIgjR4/icDhIt9upPnIEn9fL8JEjqa05SkNDAzqdDo/Hg9lsxufzMWvWrNQ9O3ToECNHjjzlvR0on853l1I/25+Nv/zlL3PttdeyatUqXnvtNR599FFcLhfp6emMHz+eu+++m0svvbTXofZfJIqKiti9ezdjx47lkUce4ZFHHuHpp59m6tSpmM1mEokEoXAYlVpNVnY2bW1tHD16lNbWViAZEVz19jtcdfkymts7OXr0KBPGj6fZGaDAqmF8aR7Pv7ORio/TfSxbtozW1lbqGhrJyspCrVYjiiKtra1EojHS0tMRRYGKigoOH6rC5XYzsrycyl07saWlM9ZgQwuIYT9H9lYyqnwscZUG3O3o3Q3I3mZKSyYS1WrJqlqN4Hdz2K3mOV+AcYVORmQGGFeYBtrkoBQpGqEoPYvth+qIa8xoNBra2trw+XyYzWYcDke3kWB9JSHJJKQTB8B3ldXX13cb4NLVWf+Lzs9+9rNe5/cMBoOntc/zyaerr76asrIyxo0bx8KFCxkxYgRvvfUWmWowetuIa068htGaNvbGHFw92oql/RhHD+yhfNxE9Ic3YmhIRoFEswW9ycAQVYLD3hD79u1j9OjRKZ9a2toRC4tJs5gJROO0trYwZsxYfP4ANpsVWZKoPlRFYVEx8ViMl199g5EjRzLOagdngGN7d5I9NYNiSwaJhIQt0Io20obDECNoycUW8iEf+RBBltgTNbO+RqbC30ZFjhmH2YrH7eJ4YxO5aUYMWhWVte3o9Xp0Oh1Gg4E1a9akfIrHk9NFZGZm9ume9uZS1zpQfOrifHJJEAT+9Kc/MXz4cH70ox9ht9v57ne/y4MPPojD4cDr8yEDW7ZuZe7cubjdbhobG9n90UdEIhHKysqIJxLs3bufoUOHsn3nLhwOB9FwmLxMG6OKc9iw6yBpGVnd6qbmlmRdNFytpaysDK1WS0enk5zcPEBmzOgxHK4+zJHqaubMmUtrSzMbNm5k+vTpVJSPwOvz8fyzz3LZsmWkGfWEwmESCMh6G1lFFpBlMtIsRCNhjPYshtkyUKlUxKJRhpaWEo5EkBIJAn4/BUVFVB8+TDwaTUVPc3Nz2bJlywkpoT7boOuN89Wns1E3wWmMVhYEgWXLlvU/Z9cXEJVKxUcffUR2djYul4vrrruOhQsX8thjj6HX6zEaDKTb7YiiiMViIRAIAMmGod1uZ/bs2by/8QNmTp9GwUUz6fT66ejs5P31e/nasvksuWgqhxrbAYhEIjgcDkLBIMFgEFEQ8Pv9+Hw+dAYDVVVVJBIJWlta2bs32RfSoNfT0NhERmYWLaEEpSQTj1pECbtejUqn43hnnFhWKZr2GuKHtxIbPovE5MWo33+OPYYh1Pig5oAHm14kfU8rwy0JFo90MDXPSigeJ3d4BVqtjoaGBkwmE4FAgGXLllFQUMA3v/lNAL7xjW/0+Z7KHy89lQNYrdY+jX7OzMxEpVKlGuNdtLa2kpOT0+fzGQjmzJnDoUOHTrnN6XA++TR27Fi2bNnC9OnTOXz4MEOHDuWFR37LOBL8JL6BDscIgmXTaHV6qTrWwDB1J2W2GNdNWwIUUtXiZt3hZuZ0tGPR64mgJW510N7ppSTPQJ5J4J0t2xBFMdmtw+FAEjUcqz5EQaaNDo8vmW8QkeN1tcTjMXbt3Inb7SYajbJnzx5sNhu2tDTaOl0UACOL86n1+xmS5SAYDhMz2okJETQhF8eP1VEweQGhwgr0DVVs89vo9AfYUh9gYo4XkzrBrGIb+bm5VOSY6YzIlJQOw2CyYLVaCQaDzJo1i4KCAgoKCnjxxRcBePrpp/t0P3tzCRSfeuJ8cgnghz/8Ic3Nzfz2t7/l4Ycf5uGHH+bgwYPk5uTgdru5/PLLSUtLo7GxEbfHQyQSSdVNy5Ytw+l0IgoCF02fQiQu0dzSyjOvbGT+tAlcNKGCzfuPsnPnTqZOnYrD4UhG5qw2qvbvQ5Zl3G43JrOZjo52PG4PkXCYDzZtQpZlqqoOpnyyWCw0trRRlJfDxfPmIUkSgkqN29lCVnY20Vgct8eLEPGTm53JMaePwmI7Oq2Ay+kkIUk0NzfT2trKsGHDKB06lKxsBwGfF61Wi9FoPKFu6hoEp1KpUl2hTsVA+XQhuARfgFQ2ixcvpqWlJdUAe/jhh5kwYQLV1dXccMMNdHR0YLPZ+Nvf/kZFRcWAH1+tVuN0Ouno6CAnJ4c1a9bw6KOPct/996NRq4nHYjS3t9Pa2sq8efPw+XypeSo3b96MLd1OU2s7mRkZrHn3XdLS0kjIAmu2fcTi6eMxjByOJKppbW3D1dFOyZAhuFwuVGoNmZmZlJeXE41EqampoampiaysLCDZAM3JyWHc+PGEgkEM8TCJYCOSJZPMIWV40aGPxikoLKK1s51MWz6akAtzoBHSddRMv5Tq7Z+Ek/NsOlpjUBmAEe4oUzN1HAuqiBKmtHRoj/0WukY59SddwKkih31Fq9UyadIk1q5dy4oVK4BPJhW/4447+rWvM+X999//XI93Jpxrn7oSzf/jH//g+uuv586f3s3G265mktyMqLXgG5uLPm7FNUJNLJZPXl5e6tl7/YgXj6xmtXUqNwRept6QQeXxEAF/Fbdc7sChg69cModgNIFsNOL1tJGWnUss3Yw9PY2gJHK4+giyDI2NjTgcDtxud8olWZaZNn06dbW1ZJWMINEQI27NIj1vGIGEjNFoJB6N0inkYZcSjCixovbUohpWTnVUoNPzyRyvokZLQ1zk+ZoYPxmnwe0L0BnXoop4mDRp0gn3pathCFBeXt6ne9mXSEdfUXw6Pc61T7/5zW948MEHWb58OW+++SaLFi3i2LFjZGZmIssyTqezx7oJko2VQDiCQTDw3vvr0Wg0yDK8+f6HfOvaFUypGM7QkiJkBPxeN/m5ucTiCQqLChEFFcFQCF8ggM/jobGxgezsZKSxy6fCwkKys7LweL2YzWYEUaSwqBhRJZJISOTm5ePxehEEgayMNDSSkWAcbDYbe/fsYezYsdTV1zN27FjS0tJQqVR4PB6yc3Jwu5zEolFKS0t7rJu67vVvf/vbPt/LgfLpQnHpnDcOn3vuOdLS0oBkzp4bb7yRjz76iFtuuYVvfetb3HjjjbzwwgvceOONbN++/aydR2ZmJvF4HEEQePDBB7nnnnvQajS0d3QQjUb58MMP0Wq1qTcXSPYxEEQROZFg3/79TJw4EUmSMJlMJCQJdxR0kotdNS3s2bcPR3Y2BUVFAMSiESw2G+MnTqT+eD2JRCI1VZjD4UjO26pS0dDQQJ7DQVCWcIyfjaTWotFrSMQ8GIQoEZUdS3oGLoOVmCQht9eRk21HLC6kpPEIUZ+KNk+YiCQDAjpBYjE17DlsxK+19Ro2b2hoSP27t5B1T0hycumpvL98//vf54YbbmDy5MlMnTqVhx56iEAgwE033dT/nZ0BpaWlbN++nYyMjM/1uKfDF8Wnr33ta2RmZnLNiitSZWLYj0qK442LbPrgQ7QaNXl5eQA0ecN45GTfmTH+w7hUZuSi0UwpVRMOh3GaC8jw1uHzNlLljNPS3MjY0aMxhUOYtSKBQBBLmp2y8lHUHDmM3+9HlmWmTp1KRkYGgUAAu92Oy+WiqLCQ2tpjVJRWEEaPXfKRkAXUiEhqA3rRRJtQCrEwcsCJJT2LeHkW80K1VAfUtHsjdEYBEcYZg+SGAzy/u54hw8t69enBBx8E6NeAiN5c6lrXXxSf+s8XwSdBEHjjjTcoLCykoaGBV199lSuuuIKWlhY8bjfV1dV4PJ5udRNAcXExHe3tVB85Qn5+fioC5/Z4CIgGDDEfH+3ejdZoof74ca666ipCwQBGnQ5Ro8VoNqPT6zl8qCrl07Rp07BYLKhUKvYfOIB67Fgy7HZef/NNLr9sOUI8jEalRxLVCIKI2WolFo0gRoPsqT5GbkEhBr2erKwsOp1OOjs6iEUitLS2Ulr6cd7RSIz9+/ai0+lOmKO8i1gsBsBtt93W5/s4kD5dCC6d88Zhl3gAHo8HQRBoa2tjx44dvPPOOwCsXLmSO+64gyNHjjBs2LCzej7PPvss1157LU/+4x98+9ZbkwJ6PGRlZdHY2Ehra2vqYS0sKiIYCHC8ro6RI0dSWloKJBtWao2WY8frGJljozTLwq5EgoKCQmKxOHFJ5t1311BSUoLFYmHfvn1IkoTZbMbr9eJ2u2lvb6eoqIji4mL8wQAZVjPagExVqxNTpoFco4yYiKKP+ahv7kTrGEI8HgG1ni2VHzE+2siX7EXsK5vEhEw1DQ2NNAUFEnX70TfXMOKiq3GLJuobGtm3bx8ej4fc3NzUNfSnQfhZBmrKnWuvvZb29nbuvvtuWlpaGD9+PG+//fYJHYHPNrW1taeVF/Nc8EXyaenSpYybMpVwPI5erUYK+Ai1HidPF8OkU+Hy+lM+ba1J5gdTSXHKw3XEJl3ClLJkJ/OGxiYEnYmjngSjMkykuVrZ2dbJDEcRnT4X7637EL/fz4wZM9i3bx8+nw+LxUJTUxPxeJympiaam5uZNm0aGrWa2ro6irLthKNeWvxx0mwCWTogRrLPUxziajMRn5cMq52j+/cyMtJIYvh0FqU5yBTDhCMxDh1vpcx9CDoErlixAqfbQ3NLK7t378ZqtaZcAlJdUp5++mmeeuqpPt/DgZy+SvGp/3yRfNqyZQsFBQX86le/4vLLL6e1tZXKHTsYP2ECGzdu7FY3ybKM2ZLs5+dyu3E4HKnnsbWtjVAkSqfLx4JpE3jylbex2TNApU7WTWvW9uiT3++noaGBaDRKdnY2NqsVo8lEOBKhYtQodu7ayYjhw4nLYDIakABXaxOZ6emIooq4JNPZ0UE8Hmdo6RAElZqZs2bR0dGB5eOR0wIyGrWKsrIy2tracLvd1NXVdaubPk1/+5AqdVPfOeeNQ4Drr7+e9957D4BVq1ZRX19Pbm4uanXy9ARBoKioiOPHj/coXyQS6Tbk3Ov1nva5XHPNNVx77bUMGzaMQ4cOYbVaSbfb2bNnT6pjOSRTCqSnpxOLxRgzdmzq5xsaGpLh/8VLaGpspCA3h9xMgesuX4rKkkF7RwcVFRXMmTOHDRs2YDAYmDJlCpmZmSQkCbVKRWNDAxMmTECtVrN161YmTJyIv6MFix5CsoYcmw0x3EZCbSCGmqK8HNqiUeIqHQZbNhNCa9CFvRQHOrDklxBSF5M/ZBglAScOnwuEDNAaSTfbsKenJSdeP36co0ePEo1GKS8vT3We7y8D9Vm5izvuuONzD9UPdr5IPt199910vP44BTYznS4vj7/8AfesHE+otom0Ti/+hld49T//l6M33Q6OHMqDx8idvxJVdjLC3tDQwK69+xlWPopjbW6KsksZUwyZxcOIxCLEolEWLlyI1+tl27ZtlI8cSYbdTmZWFqFgEI1aRW1dHbNnz+HQoSp2796NyWxmRLaZkKwimohhtdkg7CaqtSDH42iEGPGEDNZM/J5GRvmrUckJxrZtoTV3BbLKhtEAc6NtWBIysjEdtU5PbraW7GwHgVCI1pYWqqqqUp+QR40axZ49e/j617/e53s3kJ+Vu1B86j9fFJ+6ptn72te+RltbW3Jq2DFjqKurO6FuUqlU2NPTycjMJPPjrkrwccqbzs7kAJSmJrIWzua6y5fgjKtxdXYwdOjQlE8fffQRo8eMIT09HbvdTjwaJSMjg3A4TF5eHlu3bqWzo4P6+npmzprF/v37EUQRtU5PQlAjx6JkpKcTT8RR64yMrqhg/4EDlJYUo/p47nWNVkteQQGSJKESBUBGpVZjMpsZZrEQlyRaW1q61U2fvbd9HTg50D6d7y6dduPwtttu4w9/+MMJ5XfccUcqLUxfefLJJwH4+9//zl133dXvWTkeeOCBAZ1s/b/+67+Ix+Oo1Wr8fj+OnBxmz56d6s9RU1NDfX09RoOB115/nfnz57N+/Xruu+8+7r33Xvx+P1u3bKaouARZpSGgUmM3+thZU8OePXuSiXUjEfx+P7Nnz05Nlr13zx6mTJ1KIBjE4/UyceJELlmyBJVGg9BWQyAeo3T4CBKeNtDKhLVWorE4Lqeb/fv3MWbKdAQ5gbqkAqo205k1ghZPgEx9J1qDCcxW1EUjiFuywZoJCCRkCUmKp/KxrV+/HrPZzLe+9S0A3nrrrX7dO+njpafywczq1aux2Wwn3eZMpvs6X32aOnUquz94k/d8Mj/dHKAlXMmRZ1bxFecxABo/3k4z7xjxbAcjLNASU/HYz37Gf/3Xf/Hkk0/idDoxmkyUlo3Eb8lA6z+OLRHmrR1VONtamDVrFpIkEY5EGDJkCBvWr6eiogK/z0fs45ec5uYmxo4Zg6BSgSyjDrbii0o4srMRQ14krZ6IrCIuJfD4wuzds50J06ZjNBgR0rKJ+VxsCVko9rkwGA0Iaj2qdAeCSkK25YCoJhaPIYoioiDg7Owk8fHXgEgkwhtvvAH0r49Uby5xkvLBwtn0aSBdgi+WT08++SSRSISWlhZkWWbYsGHo9XpmzJiRqps2bNjAiiuu4PU33mDatGk0NDTw4IMP8vrrr/Ovf/0Ln8/PsGHDmDZ9OrIhHTHswqgWeGX1GkKhEKNHj6ayspLMzEwMBgObP/yQcePHk52ZyZYtWygpKcH+ccog9cczm0SjUSpGjsTpdGJNS0eOx4jF4zQ0NtHZ0UEwFGL4iBGMqagAWeLwkaN0dHQweswYdHo9ep3u4xk+knM7i6JIJBpFpVJhNBrJz89P1U1dqdWuvPLKfmXUOF99OlsuCXLXzN79pCuH1Gex2+04nc7T2SUABoOB2tpahg8fjtPpRK1WI8syubm5bNq0qc9vZoWFhac9ifaaNWuwWq1kZmYSjkSoPnyYCRMmkJubiyxJeDwejh8/zu6PPsLtdlNRUcHSpUuB5HRzWVlZ+P1+zGYz7e3tzJs3D0mlxZ5fzLrXnmfcmDGUlpby5ptvgiAwf/58dlZWMmTIEBwOB2+//TaLFy8mIUmkWa3odFoMnTVEtFYkSxYRn5OgJHLs2DFGDBuOWq1GUKtxOV1YYy4ytRLVbQGshUN5d+06Llt+Of6ECgkRUZBRiwJ2dYy4oEYlimzZso2KilEc/bjRq9frUx1tP/t4nGpy84O1TVh6uOc+r5eRJXmDcmLzvny6EAThjML756tPsixz4/cf4PmNNcQTEuZEjG85jzA24um2XXz+NExfWoYjx8HsT42u+6xPbreHJUsWETVnEw6F2LHmdSZPmkRpaSmrVq2iuKQEg8GAs7OTyZMm0el04nK5yMjMxGQ0kp6ejlaQ0AbaCJgcCCSn9grG4OCBfUyZPIlYQkKW4eCB/UwrtIIo4lPZONbQxP6qw1y1ciWdwTgqrQYVMgYVmFQSCVGFIAu8uWoVC+bPZ8/evRiNxtSsKCtWrODll1/udt09+XQql0Dx6WScLZfg3Pu0fft2NmzYwMqVK/F4PLhcLvx+PxMnTiQzIwOPx0NHRweHq6s5cuQIEyZMSOUchRN9GjlyJJ0dHUyYdTHvr36T0pJi5syZQ0NDA6tWrWLuxRezdcsWrFYrM2fOpLGxkXg8jslkwmwyYc/IQAYkSUZARlSriMfi1B8/jvXjkcyyJBEOh6k+fJjJE8bjCwbRaLS8u2YNDoeDSZMnoxJViKpPnguB5N+OrkTUsViMyspKrFYrl156KQBVVVXdksufbt0Eg9ens+lSvyOHr732GgCJRILXX3+9W+Ph6NGj3fponAq3200wGEx1Sn/llVfIyMggOzubiRMn8s9//pMbb7yRF198kYKCgl77c+h0ugHNR1ReXk5NTQ1r167l4osvJicnh4Dfj0qlQlCr8fn97Kis7NYAHD9+PH/+85+ZMGFCali+yWSio6MDk8nE9h07mJKVy9wly/G1JhPgXnTRRZhMJtRqNQ0NDRQWFhIJh5k8eTI6nY731q3jotmz0akgrjMT1achIOISLeT5j2LP1hPRqPEHgnh9Puzp6aQhExF0FJQPJR6PceWlS/DHJTxxFSa1hFUrIgBxUY0gQ1SSGT9hPJIs09LSgtvtZvTo0WRlZTFixIiT36gekGX5hAZlV/lgpqWlhezs7AHf7/nuU6fbz+qdTcQTEkMdJm7b8wEZsROn2Ysfb6bD2ZmcGJxk9P4rX/kKJSUlNDQ00Nrailqtpq6uDhBoOHyA0nFTmDH/EiS/k1AoxEWzZ5ORkYHL6WT7tm1MnDiRUCiE1WrFaDBw8OBBpkydhk4lEdVakVU6ZClBQFKTG6xBO7QASYb29nYEQWBIbhY6IYRHbcVksVI+wkhuXi7eSIIwajJEUIsiGlEmgRoQiMRiLPh45oRdu3ZhNptTAwgWLVrUr3vXm0td6wYzZ8OngXQJvpg+5ebmYjabU4mx7enpxGMx2trayM3Nxef3s2HjxlTd1NiYjM2vWrWK6dOnk56eTkNDA83NzYiiiEaj4eDBg+zduYMZFy8k7ndRWVmJXq9n+owZZGRkYDSZOHr0KNOmTcPr9VJUVER9fX1ywIk5it6gR6USkqM6ZAmtWiTH4SAhSQSDQQJ+P/FEgvz8fOKJBIIgotPpuGTJEnyBAKIgIklSt8Zh1+9ObzCAIKRS6+Tl5TF16lS2bduGVqvt8R71xvnq09mqm/rdOPy3f/s3AMLhMN/97ndT5aIo4nA4+pX2xOPxcPXVVxMKhRBFkaysLN544w0EQeCPf/wjN954I/fffz9Wq5Unnniiv6d62hQUFOD1ejl48CCvvfYaZrOZyZMn8+6777JkyRJKS0tZuHAhbW1tHDlyhOuvv55IJJJ6WLvymnURCoUQBAE56MHgKMDr7CAajaHX6zl06BChUIh58+axf/9+hpSU0NHZye7du7l82aUgighSjLDWRgAdxkScSFs9ETmAVYih6agmYS2m3uPBrJLQ6GQko42Wjk46XW7KS4sJSWoEwKYVUIsCoiCAkMwKr0Im8bE0sizj9/sRRfG0JxBPAIkePBsc3c8/f853nzLTLfzrV9/m6dfXMzFfwHR8F7QnG4ea7Eyyxo+GfAeJolzy585JDez6yU9+ktrHp30aN24c77//PqV5WcjhAHq7gwQJEARsVitvvP46GRkZzJs3j+PHj5OdnZ2MsHS0M/+iGSRQIcsxwioriUQCAwk666rJsEhkSp0EAyKZ9gwOHT5ElsOCJIPKaGXPwcMMKSkhIy2N4yERnSijEWQ0ogpRFEnmAhAQBQhFoql+WY2NjYwZM+a0Kp/eXOpap9CdgXQJvpg+dc2h7HQ62bx5c6oRmPlxNPDTdZPL5WLZsmX89Kc/TX3Z6trHZ0cAu91udBoN3phEVkYGLpcLo8nEB5s2UVRYSElxMaFgEIvFQnt7O+XDh2E0mxBFNQgCgpT8aOv1+Wlta8eo1+PIycHr9aJRq2ltbaVs+LCP5zEW2FFZSXlZGZl2OxICspQgkUgkI2GynKwvAWQZjVrN7qoqbDYbKpWKrVu3nta9U3zqH/1uHB47luwrdM011/Dcc8+d0cGLi4vZtm1bj+vKyso+93kKP82oUaMQBIH29na0Wi2TJ08GICsri//93//lhhtu4Pnnn+fHP/4x48ePP+lbjMFgYNy4cWzYsIGm9k6GjhyNRoqQZjGSbs+g+vAhBEFgxsyZhMJhhg0dSqfTSSgUpMPtpSAvB0QJqxzE5KxBa9ZR59QS12mxRwNYOw6hjsukq41ICPhkHc0t9YRCIVpddgI6NRoRDKIKWUogf5xmIBKNEI9EENVqXnn5ZYYMGdKtY/PpIMkyUg8VYU9lCheGTwumV7BgegUHDx7keFRGrdex4rZb8HccZEGulod/cgcjRoxITQPVVcn3Rtec36vfXUP60NFo03OwaBIYjXouuWQph6sPYzQasdlsydxrhYXEIiGO1dVhS8/EbDGhJ44QcqMJuRjiSOe4J0S+EMUUbCcR8uP1uEgrMBFRGWhzeojH4xw5epSh5RXEEgksKgmDqEYmQUISEEU1HrcbWUo2VLdu2YJGozkjn3pzqWudQncG0iX44vrU1bjTaDS0tycnWZgwYQIAN9xwA48//jihUIiZM2cCyRk0TsbYsWPp7Ozkgw8/ZOzUixDjYYqKi1Gr1cRiMWqPHWP0mDF43G6yMjPR6nQkomHq6xuxZ2Sg1WjQa7XIspQcZKLREI5G2bt3L8OHD8Pv96NWqzEZDASjMRrq64nFYuzatYs5c+YQjSdQiwIIHy9AQpKIhMMIgsDq1asRRRGj0XhGSaYVn/rHafc5/CLTW9+DM8Hj8XD99denPl18mj179jBmzJhT7iPZj+MtZi1ZjpyI01pzkCNHaxg6dCiiSsXRI0cYN24cu3fvZs6cORTkZNHW6cZqsyEABiGOt6WOTB2IyHiCEWRRjTnmR1CJCDojHTE1DWEV9o8/r+3Zt59hs5ehiQUptqiwmozIokA8AU1NjQiCwKpVqwCYMWMGNpvtpMlcT9WvY+fRBiyWHvoc+rxMHFow6Pp0QHJ04IgRI3j77beJRqMsWLCAe+65B4PBcK5P7XPhbPi0bt067rrrLnbs2NGtfPLkyWzcuLFPHc0bGho41tSGJb8UVcTPvi0byMnNTUY9jEa0Wi16vZ59+/axYvkyBClBSBIw6PXo1CJy0EPC58SmTX5W8sdFYuEgdh1Iah2iIFDlljCkZRKJRkkkEsTVBmJGO7iaGJKbiVanQRTVBANBwpEIHq+Xd955h+HDh5OXl4fdbu8xBUcXJ+tz2JtLoPg0mBlonyRJ4v777+fuu+8+IUL9+9//nttvv71P+2loaKClw0l6di6JgJv31q0jNzc3+SmYZPJqk8nE3r17uWblldQer6egqJhoJIJJp+HY8Xry8/KRpeRAFKMpORgrLzcHnd6A3+dl04ebk5+nfT4+2LSJxYuXYDKbOFZTw4jhw5ODLyGZ/zAe59VXXwVg+PDhDB069KzUTTB4fTqbLp1RKpvNmzfz/vvv09HR0e2h/M1vfnPGJ/ZFw2az8eqrr+J2u5k/fz67du3CYDCwe/fuPvfNKygo4NJLl1JXX0f20HLiagN+v59gMEh1dTUzZsygrb2dq664HI0oI0gJ0sxGZFnG5XahzcqEjGKcSOhifnSyB72QQNKYkMMhJARCGhPFDgc+r4eiNCPDp42izXOUTkshKuIIiQiuDjeVew5wpKaGKVOmAGCxWEhLS2PUqFFndqNk6PF1YxC/gowYMYJ7772XhQsXYjAY+N3vfkdbWxt//etfB/Q4F5JP8+fPZ/v27XzwwQcsXryYYDDIvHnzWLduXZ/3UVBQkOw/VXuE3JJhRGQxOR9sRwfFxcVUV1czbuwYrr1yOVo5hqTVopYE2p2dZKdZkLVmAiYN6DTE3a2kayVEtZ6EJCHGo8T0FozpVrQ6LQatGjHiR53w0BaGqF6PCgkhGqG+tYGt2yspHTqU7du3Y7FYTlmR9YneXPp43WDl8/DpQnJJFEV++tOf8tOf/pS77747NZr6d7/7XZ8bhpD06fjx4/i9HvQ6PX6/H4BjNTVMmDCB2tpaFi9aRGlJEWoBigrykaUE7a2tWIoLycnJJSFJaHQGjCYzjqzkNHO+QACDwUBCkph90UX4AwEcWVksX74cSZKIxxPY7XYQBLxuN4erq/noo4+YOHEigOLTSTibLp124/CRRx7hhz/8IUuWLOGtt95i6dKlvPPOO1xxxRWn/uFBTFpaGjt37jztny8oKCAWi1Fz+CBDR42FWIT8XAcF+XnYrWbGlQ0hFovj9oXw+kOoVCJZGXbyHVmEonFkQcTtD2AzWfFEwagWsOpiiIIHUQCHBgi2YZAiaBoPApAnahCyiwGBhjYn763fkOqrYrFYmDNnDrm5uT1mou8vCTnZh7Gn8sHKP/7xD/7whz9wyy23AMnR7MuWLeMvf/lLv5Ow9saF6tOsWbNSCaJPh4KCAva98w7Z+UWMn72QQGM1M2fORI6GKcqwMLSoAG/AR1DUUHV0P0UFBeRk2tGpwBUVCIajhKIxrOYMnIk4JjVoYwGEWBCNFCNbHUFORMDvROtpBkDSZ+LLGEo4EuWtd9fgcrlTLs2ePbvblIBnQm8uda0brJxtny5UlwB+8Ytf8Itf/OK0f76oqIh316xh4fKrmDV3HolIiNLSUlQCjC4bjtGop7W9k4BOz/G6OgrzCygtKQZk4pKM1+vBbDaj1Wrw+Hykp6ej1+kQBUhPT09GIUUBtVpFJBTEarUSiERQq9W0t7ezbt26z71u6lo3GDmbLp124/Chhx7irbfeYu7cuaSnp/Pyyy+zatUqnn/++TM6oQuBIUOGEAgEiAT9FJePRhtoY0hOPv5wlK279zN8RBlNrR0Eg0E6OjooKSmmfOgQmlva2bN3L6MqKjBqddQ3t2G1mGlXq0mz5SN520nTiajiEQS1Br/KiGy04U6o2L/9Q/QGI3l5ecyaNQun00laWhp2u31AxOtiIKfP+6JQV1eXSp8AsHDhQgRBoKmpacDuneLT6VFQUMAlixfT6myHjHxMaZkUmmRUGhNtbh/HXUHUWh379+xHp9ezY+duJo8fi9VsZMOH2xhZPhKP14MuP5/NH37I3Llz6HDFKMwrJtRRT5paQpASxHUmOmU92nQHm/dUkVmoQZIkpk6dlnJJpVKl+n4NBAM9fd4XhbPtk+LS6VNQUMCsmTPxd7ZRMGQ4zdV7caRbkQWBD7ZsY9LkKUQTMh3H62lubkGj0WI26vEGgmzZuo3Ro0cjJRJEo1FaW1sZPmwYBw4eZMqUqURCQUxmE6IgEI/GcHq8BCJRDuzfj8FgwGQynZO6qWvdYORsunTaTcvW1lbmzp2b3IkoIssyS5cu7bFPnsKJOJ1ONqx+A33IidftpvJANTX1Tez+aA8ul4tQKITb7cbtdpOTlcXRY7Ws37CB4uJiBGDr9m1kZWURCIaSI7A0OjbsqWbTwXreO9xKs2yi3jKEV3cfI2Swk5dfgMFgQKPRMHr0aObMmcPYsWMHVD5Ihu17WwYr8Xj8hD5wGo0mNb/nQKD4dPoUFBQQcHdy7KOtlJpltn20n53V9TQ7fWz44EMkScLt8eD5eDFoVWzaso2iwkJkWWL/vn0crKpi+syZuL0+BJWamErLaxt2UBdS8493txA05/CRV0VTXIcuLQuNJtk4VKvVKZfO+LPXZziZS4pPvaO4dGaMGDGC9pYmaqv2kJedyTMvvkLVkWPUHKtl3969yJKEy+XC7XZjs9lIxOOsWbuOIUOGIAgC27ZtIxaNMnToUIKhEDLJjB3r3n+fhqZmXnr5FQS1mj179hAJh8nPz8dgMJCZmXnO6qbB6tPZdOm0I4c5OTk0NTWRl5dHSUkJ77//PllZWQP2me18JyMjAxGZ1Wvf4+pLFxJIQAw1JpOJNWvWcMWKFXR0dOD3+9HrtEgkk2VD8pdfUlyMy+2moLCQzs5OdDo9M2fORKNWpxKjer1epkyZQiAQ6DF9wdngfPysLMsyN954Y7dcZeFwmFtvvRWTyZQqe+mll077GIpPZ0ZGRgYHD25iayLArAkVNPkTiNrkYJSNmzYxadIk9u/fj5SIYzIYGDt+IsFgkOzsbC655BLq6upIJBLU1dVRUlqKLElcccUK/H4fM2bMoOrQoWQeOZ8Pm802YJ+6Tsb5+BkMzr5PiktnTkZGBps2bUInjGLh3IuQ1DrMZjMHq6rIyMrCZrNRXV2NiMTxhgYuWbKEQCCA1WZj2rRptLe3k2cwUFlZyZy5cwn4A1y2fDl1tbXMnDmT/fv3M2bMGJxOJ3l5eam+72eT89Gns+nSaTcOv/3tb7N161auvPJKvv/977N48WKAbvnJFHqnoqICWZZxOp20/P/27j0qqvP+9/h7YG7AcB1GEQUUvKAYAzEuoyCKadBfmnqS5rpiurQrJ4krqa5EjdGwmtimqU3MPU0vaX/GnNy0ttHmNGZFjZ4TtRqtR7TepYqCCiIgAwSYy97nD52JhBmcgRlmgO9rrWctZ55h72eUj/vZez/7eRrbSNSDEqEyadIkoqKjqa+vp6Ki4soSRkYjJ06WcfOECRw7epThw4cTFxuL0WgkymiksbERjUbD2asTo9bV1ZGUlIRGoyEqKopx16z9HGx9cSqbOXPmdHjvoYceCug+JE/dc22e6lucJBtULra2kpeXR2pqKocPH6ayspKJ43OpqqmlsqYOo8FAXV0dw4YNY8jgwRgMBm6++WbOVFSSkKiwa9cuRowY7p7D1Ol0kp6e3iMnWdB3p94Idp4kS913bZ6GJiejqFeOTaqqEhsXx/pPPyU2NpaUAQM4cPDfDBycxqnTp7FYLAy+Os2O3WajsLAQRVGw223UXLxIc3MzBoMBvV6Pw+EgKytL8tQNwcxSwKayqaiooK6ujrvuuotTp04FYpNdFoypN4Jp9erV3JQ7jqGWBBqdWg4eOYIpJgaHw8HwYVdWiDDGmDAnJ7P+00+ZnJ9PfX09ba2tFE2bRnPzt5hijOz85270BgNWq5Xs7OwurXByPdebLmDroXJMHqYLaGq0Mn3s0F7zbxJqkqeuUVWVwsJC1vz374k1aqlx6NmxfTuZmZmoqkpu9nD+dfAwqYOHEKnT8dnf/87tP/whx44epaCgAINrvja7jc1btpI6eDBJSUmMHTs2KO3tbCobb1kCyZM/wilL0LvydOHCBSrOniU5PoZInYH6xmbKysowm83Ex8UxfFg6J/5TjsFo5MyZM7S1tZEzdizf7N7NnXfeiXp1EutTp06xbds2cvPyMJvNAR+CAV0/NoHkyZOAXWdPS0sjOzv76vJWwh9z587lsrWJLbv3o49Lwpxkpry8nFGjRhFtNJBoNpOelsa/Dx50TzJqionBaDTS2NREbGwMGjRkZmURGRnJyZMnaWxsDMl3Ua5euv9+6a1nZqEieeoajUbDxx9/zH+q6rjkMGCMTSQ7O5um5mZGjRyBqiqkpA4m2WJhx/btAERGRJCUlMTRo1ee7tfrdOj0BgYMHIhGo+n2erxd5S1Lkif/SJa6btCgQbS2tfG/v/yK2OSBaHU6srKyGDFyJMnmJKyNzVgGDEBxOjl16hSKquJwOEhPT+fkyZPodDo0EREMTEkhPiFB8tSLdGueQxE4ycnJJCYmUlNdxbDhIxg2bCiX6+qINiei1elxqipDhw7l2LFjlJWVkZ+fj16rRa/XoygKqqJw8eJF9uzZQ2xsbLdWOekOuxPsHtYossv6RKKHpKWl0dDQwLct32KIS2RIegYjR46ktfEyzarqzoxr0Pa58+cZM2YMpuhoWltaiIw0YrU2otPpOHLkCAUFBSH5Ht6y5KoToidYLBamT5/Orp07mJQ/BUfrtzQ2N2OOM1FnbcIUG4uqqtjtdqwNDSQmJpKclITJZMJus6HT6Th+/DiZmZkcOXLE/bBQT5M8+UdG6IaJMWPGXHmQpKGOSK2WKIOOlIEWrM3foqrgdCoYo6KYVlTE8KwsGq1WLtXWYrPZQIX6hgaMRiMFBQXk5+f32DiO73ON6/BUhOgpY8eOpa62lm8v16KPisEQoSEqOobGVjtoIrA7HEwrKqKgYAqmmBicDgfHjh93D+xusFpxOp0UFBQE5RaYLzrLkuRJ9JTRo0dTX19PstlMS3MTxuhoBpiTsDkVWlpaUBQFjUZDcXExo0eP5tC//31l6dlLl9BqtTgcDhITEwEoKCggOzs7JN9D8uQfv68cdrZ4ucPh6FZj+juz2UxtbS1bv/yCmcU/4ItNmxl3wzgOHDjAqOxsYmJMpKenXzlLs9mJj4/jUk0N2oR4vvxy05WHWaKiGD16dMi+g11VsXuYNMou4fNI8hQ8ZrOZC+fPodhb0Q8YwJdbtpKbm8u2rV+Rn5+PqsKQtCEY9AY0ERGMGjkSm62NhoYGduzYQX5+fsg6huA9S6460Z5kKXhcx6Y1n3zM/3z4YfaX7qfNZic6KgqbzYbRaESn0zEsMxOdTofRYKDNZsPhcPDNnj0Mvjp2V/LUe/jdOVy/fn2n9YWFhV1uTH+Xk5PDoUOHOHXqFOVnKpjxgx9wubGJgilTuHTpElZrA6p65Ray2WzmUk0NAwZYuFxfj9Vqpa6uLuR//05FxekhgJ7eE5KnYHLl6WzleVq+beG2W4twKFf+Tv/xj38wbdo0qi60kDZkCJFE0trqIDo6iv97dQWhUI2NcvGWJVedaE+yFDyuLJlMJsrKysjJycHa2ER8XBznL1xg48aNFBcXc/bMGUaPHk1tbS3x8fHotFqOHDlCVFRUyP/+JU/+8btzuG3btmC0Q1wVExPD+PHjSUhMRAU0ipPy0xUcOnyYKVOm0NjYyMgRI/h0/XruveceVFXhmz17MZlMJCQkhLr5OBTPZ2cOCZ9HkqfgqqurY9CgQQxOTSUChUOH/02rzY7JZCIqKoq42FgAjh0/zk15edja2jhz9iwmk8l9KyxUvGXJVSfakywFV0JCApMnT8bpdBKp1RFtNLB+wwbS09OZOnUq5eXlTLrlFmpqajDFxGDQ66moqCA6Ojqsj02uumAoLy/nhRdeYOvWrVRVVZGamspDDz1ESUkJer3e/bmDBw/yxBNPsHfvXiwWC/Pnz2fJkiVBaZOvZMxhmHHNMn+xuhqHU+HblhYs5iQKCgqIj4sjZeBA3v3Tn/gfs2ahqioajYYxY8aQk5NDZGRkqJsfkjEd5eXlPPzwwwwbNoyoqCiysrJ4/vnnr4zHvMbBgweZMmUKRqORtLQ0Xn755aC1SYSHwsJC7HY7rW1tVJ6vInvkCLIyhzFt6lSGDB7MqdOn2fnPf5KXm4vdbiciMpKioiLy8/NDPmmyjJES4WTIkCEkJCSg1WqJjIjgRNl/uH3mTFJTU9Hr9UwpKOAfn39O7aVLxMXF4VQU4hMSyMnJCXmWIDR5OnbsGIqi8Mc//pHDhw/z+uuv84c//IFnn33W/Rmr1UpxcTEZGRns27ePlStXsnz5ct59992gtMlXof8XEx1oNBqOHjuGzWbjn7u/ubJgud1GdEwMX23dykOzZ6PV6fhmzzfY2myYLRZUVWXHjh2cOHEipG13Xbr3VIKlNwdQBJ9Wq6Xi7FlU4IvNW7AkJaDT6WhobKS5uZni227D2thIVdUFXL+lVqsVnU4XymZ3miW5DSZCwWq1UlZWxuWGBmpqarhQXY0pOprU1FSOnzjBmDFjuOGGG/hmzx5aW1uJjo5GVVV27twZ1semYOVp5syZvPfeexQXF5OZmcmsWbNYvHhxuxVLPvroI2w2G6tWrSInJ4cHHniABQsW8NprrwWlTb6SzmEYqq2tpaqqiu07dvCD227jyImTJCclcfrUKe6+++4rk3SqKjfl3USEVsvGzz/HYDDQ1NRETU1NSNtuv3rp3lMJlt4cQBF89fX1/HPXLqovXqSoaDrH/3OaGKMem83GtKlTUVSVWJOJQYNSqampYffu3Wi12rDOUjDzJIQ3tbW1OJ1OvvjiCzIzM7EMGEBjUyPVVVUMHz6cG8aOxW63k5eXh9FoZOfOnb3i2NSTeWpoaCApKcn9eteuXRQWFra7zTxjxgyOHz9OfX19j7Xr+6RzGIbMZjMmk4nKykpK9+9Hr9PR5nAyetRIIriyCoQmIoLIyEgUReGOO+4gJSUFk8lEW1sblZWVIWv79S7bW63WdqWtrS0o7egtARTBZzabiYqKonT/fs6cOYOKBq3eQOpAC3BlEmyn04kmIgKz2cw9d9+N0WgM6ywF6zaYL0M0ysvL0Wg0Hcru3buD0iYRPsxms3v40tatW6mvq8PmcJKRkU50VNSVFVF0Oux2O6qicMvEiQwfPjzsj009dXwqKyvj7bff5rHHHnO/V1VV1WFeYtfrqqqqgO7fH9I5DEM5OTnk5+czYcIEsrKyuHjxIuvXr+ev6zfQarOBRnPlYRWNhgiNBr1OR2REBBMmTGD//v1UV1eHrO0Op4rdQ3FcnXw0LS2N+Ph4d1mxYkXA29CbAiiC79o86XQ6tn/9Nav/1wfs+df/Q1FVVI2GyKvzsUVGRqI3GNDpdOh0upCuquEtS9fmKdB8GaLhsmXLFi5cuOAu48ePD0qbRPjIyclh+PDh3HTTTUyePJmWlhb+z7Zt/Pm/V3GhqgpVo0FRVaKionA4nURERBCh0TBixIhekSdfj09Lly71eIJ0bTl27Fi7nzl37hwzZ87k3nvv5ZFHHgn69+0uWSElTH1/Ldfq6mouXrzIunXrmDBhAkajkZiYGBRVxWKxcPHSJfR6PSaTKWSro4D3xc1d71VUVLRbu9I16bAnS5cu5aWXXup0f0ePHm03qWpvC6DoGa48nTx5ktjYWBobGzl+/Lg7RxcvXiQ7OxtjVBS6yEj279/PuHHjgnZl2xedXSEM1pXDmTNnMnPmTPfrzMxMjh8/zu9//3teeeWVdp81m82kpKQEpR0ifF17bLo2T1u2bOHGG290zwTQ0tJCekYGLd9+i9lspr6+nujo6JC125c8+Xp8WrRoEXPnzu10f5mZme4/nz9/nqKiIiZPntxhnHtKSkqHCzqu16HMl3QOewHXxKFWqxWtVotOp6Ompoaamhr27t3r/tyECRMoKCgI2eooAHangtapeHwfIC4uzueFzftDAEXPGjFiBKqqUltbi1arJSoqCqvVitlspqysrF2ehgwZgtlsDllbvWXJVQdX/k+4lsFg6PSEqyu+P0TDZdasWbS2tjJy5EiWLFnCrFmzArpfEf485amhoYHa2toOx6akpKSQzqjhS558PT5ZLBYsFotP+z137hxFRUWMHz+e9957r8OT25MmTaKkpAS73e5+CG7z5s2MGjUqpNNpSeewl7h2ZvkTJ04QGRlJQkICJpOJpqYmTCYTZrM5pDPQAzgBT3e8urJ0ZX8IoOh5I0eObPf6xIkT7g5QOOXJW5ZcdXDlNti1nn/+eZYvXx6wNriGaFx71dBkMvHqq6+6p/v529/+xp133smGDRukg9gPecqTzWZrl6WkpCQ0Gk3Y5ynQzp07x7Rp08jIyOCVV15p91CO66LEgw8+yC9+8QsefvhhnnnmGQ4dOsSbb77J66+/HqRW+aZPdg7VawaX9kUpKSnuX6z8/Hzq6uowm82kpaUF/Tu7tq96uTxvVxS0iocrhx7eC5TeHMDeoD/lCQibPHnLkqsOfL8NFsghGsnJySxcuND9esKECZw/f56VK1dK59AH/SFPLtdmCYL7nbt6bHLVBcPmzZspKyujrKyswx09Vzvj4+PZtGkTTzzxBOPHjyc5OZnnnnuORx99NCht8lWf7Bw2NjYCHc+qReA0NjYSHx/f4X3Fy5xRShCnCujNAewNJE/B5ylP3rLkqgPfb4MFcoiGJxMnTmTz5s3X/ZyQPAWbv8cmV10wzJ0797q5Axg3bhzbt28PShu6qk92DlNTU6moqCA2NhaNRuPzz1mtVtLS0jqcjQdbb9qvqqo0NjaSmprqsd7mUIhwdDwLs3l4L1B6cwB7A8lT8PbbWZ68ZclV549ADtHwpLS0lEGDBvnVpv6qK3nqTb/Todp3V49NrjrRXp/sHEZERHTroQx/HpoIpN6yX09nZS5OxfMi5l7GAYteQPIU3P16y5O3LLnqgsGXIRrvv/8+er2evLw8AD799FNWrVrFn//85+A0qo/pTp56y+90qPbdlWOTq0601yc7hyJ0vC1FJMt9CeGfzpb1ClaefBmiAfDCCy9w5swZtFot2dnZrF27lnvuuScobRIiEEKRp95MOocioOxeLt3b5bK9EH7xliVXXTD4MkRjzpw5zJkzJyj7FyJYQpGn3kw6h9cwGAw8//zzAZ8nrD/t16l6uXIYpEl7RfjqS7/Xodivtyy56kT/0Vd+p0O5b8mTfzSqt+e+hfCD1WolPj6eBWt2Y4g2dahv+7aJtx64hYaGhpCNXRGiN7helkDyJISvJE9dI1cORUA5FJVID2dnDhnTIYRfvGXJVSeE8J3kyT/SORQBZXcoaGTMoRDd5i1LrjohhO8kT/6RzqEIKKeqehy/IWM6hPCPtyy56oQQvpM8+ef6s5v2UZ9//jnjx4/HYDDw5JNPtqtTFIX58+eTlZXF8OHD+e1vf+uuW758ORaLhdzcXHJzc5k9e3aP7Lezuq6orq7mxz/+MePGjWP06NG88cYb7rrVq1cTHx/v/o5FRUU+b9fmULwW0Xf15zyFIkuSp76rP2cJJE/hot9eORwxYgSrVq1i3bp1NDU1tav78MMPOXLkCCdOnKChoYG8vDyKiorci4bPnj273S9sT+z3em3y18KFCxkzZgyffvopzc3N5Ofnk5+fz4QJEwAoKipiw4YNfm9X5jnsn/pznno6S6460Tf15yyB5Clc9NsrhyNHjuTGG29Eq+3YP167di2PPPIIkZGRJCUlcf/99/PJJ5+EdL+BbtOBAwe4/fbbAYiJiaGwsJAPPvigy9tzsTud2Bwdi93p7Pa2Rfjqz3nq6SxJnvq2/pwlkDyFi37bOezM2bNnycjIcL8eOnQoZ8+edb9et24dN954I9OnT2fbtm09st/rtclf48eP5+OPP0ZRFGpqavjyyy8pLy931+/YsYPc3FwmT57MunXrfN6u6+zMUxH9U1/PUyiyJHnqn/p6lkDyFC767G3lSZMmcfLkSY91+/fvJy0trUvbnTdvHiUlJeh0Onbu3Mldd93F3r173eEI1n79db12vPrqqyxevJi8vDwGDBjAtGnT3Ouo3nHHHdx3331ER0dz9OhRiouLSUtL45Zbbrnufh0KaDxOZdO97yNCqz/nKdyy5KoTvVN/zpIv7ZA8hYc+2znctWtXl382PT2dM2fOMGnSJADKy8tJT08Hvlt8HiA/P5+8vDz+9a9/uQMYrP12VueJL+1YvXq1+8/z5s1zjxFJTk52vz969Ghuv/12du7c6VMAbQ4FVaay6XP6c57CLUsgeerN+nOWfG2H5Cn05LayB/feey9/+tOfcDqd1NXVsXbtWu6//34AKisr3Z87efIkpaWl3HDDDUHfb2d1XVFbW4vdbgeunK1t2LCBxx9/HIBz5865P1ddXc3WrVvJy8vzabty2V58X1/PUyiyJHnqn/p6lkDyFC767JXD6/nqq6+YM2cOVqsVVVX561//yu9+9ztmzZrFT37yE/bu3cuIESPQaDQsXLjQHbKSkhL27duHVqslMjKSd955h5EjRwZ9v53VdcWePXtYsGABWq2W2NhY/vKXvzBo0CAA3nnnHf7+97+j0+lQFIWnnnqK6dOn+7Rdu5ezM4ecmfVp/TlPPZ0lkDz1Zf05SyB5CheytrIICNf6lYUvfYHWGNOh3tHazNfP/JesXSnEdVwvSyB5EsJXkqeu6bdXDkVwOJ0KGmfHszCnh/eEEN55y5KrTgjhO8mTf2TMoQgoVVG9FiGE7zrLkuRJCP+EOk9tbW3k5uai0WgoLS1tV3fw4EGmTJmC0WgkLS2Nl19+OejtuR7pHIqAcjpUr6Un9LYACuFNZ1nqqTwJ0VeEOk9LliwhNTW1w/tWq5Xi4mIyMjLYt28fK1euZPny5bz77rtBb1NnpHMoAkpVVa+lJ/S2AArhTWdZkqHiQvgnlHn64osv2LRpE6+88kqHuo8++gibzcaqVavIycnhgQceYMGCBbz22mtBbdP1SOdQBJTToXgtwdYbAyiEN51lqSfyJERf4kuerFZru9LW1tbt/VZXV/PII4/wwQcfEB0d3aF+165dFBYWotfr3e/NmDGD48ePU19f3+39d5V0DkVgeRvPcXVMRzDCB703gEJ41dn4KBlzKIR/fMhTWloa8fHx7rJixYpu7VJVVebOncu8efO4+eabPX6mqqqKgQMHtnvP9bqqqqpb++8O6RyKgFJU1WuBwIcPencAhfCmsywpcltZCL/4kqeKigoaGhrcZdmyZR63tXTpUjQaTafl2LFjvP322zQ2NnrdTjiTqWxEQClOBY2HW17K1akCKioq2s0jZTAYvG5r6dKlvPTSS53u7+jRo2zatKnXBlAIb7xlyVUnhPCdL3mKi4vzaZ7DRYsWMXfu3E4/k5mZydatW9m1a1eH49zNN9/M7Nmzef/990lJSaG6urpdvev1tUsi9jTpHIqAUrwsbq5czaSv4YP+EUAhvPGWJVddsAwdOpQzZ860e2/FihUsXbrU/frgwYM88cQT7N27F4vFwvz581myZEnwGiVENwUyTxaLBYvFct3PvfXWW/zqV79yvz5//jwzZsxg7dq1TJw4EYBJkyZRUlKC3W5Hp9MBsHnzZkaNGkViYqJ/DQsgua0cRtasWcN9990X0G0WFxezZcuWgG6zM4pT9Vr8ZbFYyM7O7rTo9XreeustDhw4QGlpKaWlpWzcuBGAtWvX8uKLLwJXAvj111+71+yE8AigCJ7enqfOstSVPPnjl7/8JRcuXHCX+fPnu+vkyf/+SfLkv/T0dMaOHesuruUMs7KyGDJkCAAPPvgger2ehx9+mMOHD7N27VrefPNNFi5cGJQ2+Uo6h9cxbdo03njjjaDvR1EUnn32WX7+8593qNu8eTO33nqre/Hx77fPYDBgMpncJTk52V1fUlLC008/HdS2X0tRVK8lWHpzAPsbyZPvOstSMPMEEBsbS0pKirvExHy37Jg8+R8+JE++C2WeOhMfH8+mTZs4ffo048ePZ9GiRTz33HM8+uijIWsTSOcwbGzcuJGkpCSPC5Zv3LiR1atXY7VaUTxc/37ppZdoampyl0uXLrnrCgsLuXz5Mjt37gxq+10Uh+K1hFK4BlAER1/IU2dZCnaefvOb32A2m8nLy2PlypU4HA53nTz53/9IngJj6NChqKpKbm5uu/fHjRvH9u3baW1tpbKykmeeeaZH2tMZ6Rx2UXV1Nffddx8Wi4X09HRKSkra/Qc6dOhQXn75ZW655RZiY2OZOnUqFRUVXrf32WefMX36dI91P/vZz1i2bBm33norERH+/ZNpNBqmT5/OZ5995tfPdVU4PF3ZmwIorpA8deTL05XBmBpqwYIFrFmzhm3btvHYY4/x61//ut14QnnyP/xJnjqSp//9I53DLnrwwQfR6XScPn2a7du3s2HDhg7LsX344Yd88skn1NTUEBMT4/GSvEtpaSnZ2dke67Kysvjwww/56U9/2qW2jhkzpsNScsGiOL2cmcnTlaITkqeOvGbpmjz5OjWUr1NvACxcuJBp06Yxbtw45s2bx6uvvsrbb78dsDlJRfBJnjryJU/iO9I57IJz586xdetWXnvtNUwmExkZGZSUlLB69ep2n3v88ccZNmwYRqOR2bNns2/fPq/brK+v9/kp3u9btmwZCQkJ7nLbbbe1q4+Li+ux2z2ql/EcPbGwueidJE+eecvStXnydV62RYsWcfTo0U5LZmamx5+dOHEiDoeD8vJyAHnyP8xJnjzzJU/iOzKVTRdUVlZiNBrb3VrJzMyksrKy3eeu/Y8yJiaGxsZGr9tMTEzEarV2qT0rVqzgySef9FpvtVp77IlcxamAh7MwOTMT3kiePPOWJXcdvk8N5evUG56UlpYSERHBgAEDgPCdekNcIXnyzJc8ie/IlcMuGDJkCK2tre3OnsvLy91PxnZFbm6u+7ZOoB05cqTD+LtgCcenwUR4kzx5FoqnK3ft2sUbb7zBgQMHOHXqFB999BFPPfUUDz30kPsALk/+hzfJk2fh+rRyuJLOoQ8cDgetra3ukpycTFFREYsXL6a5uZmzZ8/y4osvMmfOnC7v40c/+hHbtm0LYKu/s23bNu64446gbPv7VMXptQgBkidfdZalYOXJYDCwZs0apk6dSk5ODi+++CJPPfVUuzkM5cn/8CJ58k0o8tSbSefQB08//TRRUVHuMmrUKD7++GNaWlrIyMggPz+fH/7wh91aIeD222/n0qVLHDp0yO+ffeaZZ9rNI2UymaitrQVg+/btxMXFMWXKlC63zR+Kw47isHko9uv/sOgXJE++8Z6l4OXppptuYvfu3Vy+fJmWlhaOHDnCsmXLOqw+JE/+hw/Jk29CkafeTKOq8gx3uPjkk0/YsGEDa9euDdg2Z8yYweLFizsMAg40q9VKfHw8qff9jgh9VId6xdbC+b88TkNDQ5cHNgvhj96ap+tlCSRPoudJnvoX6RyKgHAFMOXuN4jQeegc2luo+tuTEj4hruN6WQLJkxC+kjx1jTytLALK2/gNGdMhhH86GwsleRLCP5In/0jnUASU4rCDJtLz+0IIn3nLkrtOCOEzyZN/pHMoAkpRnODhLEyRMzMh/OItS+46IYTPJE/+kc6hCCjFYQNNx4fgFYctBK0RovfyliV3nRDCZ5In/0jnUASW04ka4eEszClnZkL4xVuWrtYJIfwgefKLdA5FQClOOxoPZ2eqU8Z0COEPb1kCyZMQ/pI8+Uc6hyKgVC/jOuRpMCH84y1L7johhM8kT/6RzqEIKFVRQOm4iLnq4T0hhHfesuSuE0L4TPLkH+kcioBSHDY0aDq8r8qAXyH84i1LIHkSwl+SJ/9I51AElKI40chtZSG6zVuWQPIkhL8kT/6RzqEIKMVhR6N6uHIoA36F8Iu3LIHkSQh/SZ78I51DEVCq4gSNXDkUoru8ZcldJ4TwmeTJP9I5FAGltDVDpIfxG3JmJoRfvGYJJE9C+Eny5B/pHIqA0Ov1pKSkUHXkL14/k5KSgl6v78FWCdH7+JIlkDwJ4QvJU9doVFVVQ90I0Te0trZis3l/6kuv12M0GnuwRUL0TtfLEkiehPCV5Ml/0jkUQgghhBBunteSEUIIIYQQ/ZJ0DoUQQgghhJt0DoUQQgghhJt0DoUQQgghhJt0DoUQQgghhJt0DoUQQgghhJt0DoUQQgghhNv/B1X8uKCigDecAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Pick three distinct seller-buyer pairs\n", + "bus_list = buses['BusNum'].to_numpy()\n", + "pairs = [\n", + " (int(bus_list[0]), int(bus_list[-1])),\n", + " (int(bus_list[1]), int(bus_list[-2])),\n", + " (int(bus_list[0]), int(bus_list[len(bus_list)//2])),\n", + "]\n", + "\n", + "ptdf_sets = []\n", + "pair_labels = []\n", + "for s_bus, b_bus in pairs:\n", + " df = pw.ptdf(s_bus, b_bus, method='DC')\n", + " ptdf_sets.append(df['LinePTDF'].values)\n", + " pair_labels.append(f'{s_bus}\\u2192{b_bus}')\n", + "\n", + "plot_sensitivity_triple(\n", + " lines_geo, ptdf_sets,\n", + " shape=SHAPE,\n", + " titles=pair_labels,\n", + " clabels=('PTDF', 'PTDF', 'PTDF'),\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "a18", + "metadata": {}, + "source": [ + "## 7. Multiple Outage Scenarios\n", + "\n", + "Compare LODF redistribution patterns for different branch outages\n", + "to see how the network responds to contingencies at different\n", + "locations." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "a19", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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stDr9SxbtozMzMxuqacO/cR87733UlZWxksvvdSk7aWXXqKsrIx7773XuS8mJsbpJDXSXN4xlUrVJL9fbW0tMpnMJdj0yy+/dHFOFAoFgwcP5ttvv3U59o+LKEaNGoVeryc3N5dhw4Y12Tx9q8zJyeH06dMkJiY6982aNYtvv/3WJZntF198QUBAQIs5tPLy8ti0aZPLKq5GQ/Xzzz8795nNZjZs2OD8xBYcHOxyDy0F21utVtLT013GO23aNADkamWLGzg+T/j7+zu3N998k/79+6PT6ZznKykpwWazOWcAG68ZHBzc5C21kaSkJD744AO+/fZbli1b5gz0bi0ZeFehO+spPT2dzMxMt5/E8vPzmT59OnFxcXz99dctBp3/nr1793L06NFmV0X+8foWi8WpicYZ98btjw5ifn4+69evdztek8kEtKwnaKqlRx55pIn+AXbu3IlMJuO9997j/fff5+TJk4wbN46qqioKCgpQq9VO56SR8PBwt1rr6ggtuddSc2zatAmZTNaqA7pp0yYXu9EclZWV7N+/39nP19fX5R6SkpKaHLN8+XImTpxIZGSk2/O2xzY99NBDAC5jzsjI4IsvvmDIkCFs3LiRt99+u9vqqUMTZV9yySUsWrSIxYsXk5OTw5VXXgk4Pr38+9//ZtGiRcyZM8fZ/4orruD999/n7rvv5tJLL2XLli18/fXXTc7bt29fvv32W8aNG4ePjw9JSUnOz6s33ngjt99+O4cOHeKll15q8o/4f//3f8ydO5dbb72VK6+8kj179vDRRx8BOOOEAgICeOqpp3jwwQfJzc1l4sSJKBQKsrKy+Pbbb/nPf/7TZCl8I3fccYdz2t3f35+jR4/y0ksvER4e7pKG5oEHHuDTTz/lmmuu4a677uLAgQO88MILPPPMM850GMuXL+f7779n9uzZREVFkZWVxZIlS1AoFC6Jc4cMGcK8efO47bbbKCsrIzIykrfeeovCwsJmp/t/z7vvvsv27duZOnUqkZGRFBQU8M4773D06FH++c9/Ovtdeuml3HLLLcgVLZQzati/ZMkS+vXrR0VFBe+//z6//fYbb775pss1161bB8CePXucyUmPHj3KFVdcQWZmZrPnHzVqFKNGjXL+PHr0aPr27cs777zD3//+9xbvsyvQHfXUyGeffYZOp2t25WNtbS2zZs2ipKSE1157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aevWrc7ZdaVKRfr27eTl5WEymYgID2fAwIHknTnjnPGWyeX4+/sj2e0EBgaSmJhITU0Nv/76K74NNZsNBgNKpZIxY8YQHh5OTU0NNpuNkOBg9A0LthpDMM7k5RERGYler6e8ooK62lrMVisarRalSkVSUhInTpxgzJgxWKxWLGYzdrvdkSwbXGxTdna207FpS4y8t2wTCD014nEeRG8zffp0CgoKkMvl+Pr68vrrrzN48GCOHz/O9ddfT0lJCf7+/ixdurTNdU+by5XUGnu3bedfo65qti1kwhBuef9Fqk/k8MZM7yRgleu1SBYrSpUSQ5RjFqT0SFbrB54FCo2aN2qOuPyRbMwR2ZjwGFrONXX6TH6LuabioyPb/NxHjBjB8OHDeeONN5xjiIuLY9GiRfztb39r0v/qq6+mpqaG//73v859o0ePJiUlhX/9619tfApdm/NFT6NGjWLbtm2888473HTTTRQWFmKur+e/33+PRqNxOlQAZ/LyqK+ro6iwkFOnT6PX653JuCMjIzl27Jij35kzDBw4kOioKGpra7FLEnKFgoqKCtavW0d9fT2jR49GkiQMBgM7duxgypQpBAQGkp+XR3h4ODJApVYjVyjAbsdmtzuMmMWC1WrF38+PCqMRuUzGkaNHGZyaSn19vSMhsErFj6tXk5ycTHV1NSNGjHC559/nfvz9n9X26MlTLYHnehK0zvmgp99/PqwoL8fP35/i4mJyc3NZt24dBoPBqaesrCxqa2rw8fVle3o6drudnj17YjabiY2Joc5sZnt6OnFxcRQVFjJqzBhUDTGCtobFIo2LYQDS0tIICQmhrq6OsrIykpKS0On1lJSUEOjvj1anc5bNayyvZ7VYyMnOJiY2FqvVSlFREZLdTkRkJLW1teh1OnR6PXa7neXLlzNmzBgCAgKalKycPXs2q1evZvbs2fzwww9un11H2CYQeoLzYJFK44KRvXv3ct999znfwG+//XZuu+02jh07xkMPPeTc31GkDB+G1MxaFF3PaPRD+lBYWMjyux5r9li/hOg2XUMV/r/EwfaaOiSLFd+4SMozc6iur2vhSO9gt1r55vV/N1kF59E5pP+9qf1x83SB9n333ce///1vPvroIw4fPsydd95JdXU1N954IwALFy7k4Ycfdvb/85//zI8//shLL73EkSNHWLx4MTt37mTRokXt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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Pick three most-loaded branches\n", + "top3 = flows['LinePercent'].nlargest(3)\n", + "lodf_sets = []\n", + "outage_labels = []\n", + "for idx in top3.index:\n", + " bk = (\n", + " int(flows.loc[idx, 'BusNum']),\n", + " int(flows.loc[idx, 'BusNum:1']),\n", + " str(flows.loc[idx, 'LineCircuit']),\n", + " )\n", + " df = pw.lodf(bk, method='DC')\n", + " lodf_sets.append(df['LineLODF'].values)\n", + " outage_labels.append(f'{bk[0]}-{bk[1]}')\n", + "\n", + "plot_sensitivity_triple(\n", + " lines_geo, lodf_sets,\n", + " shape=SHAPE,\n", + " titles=[f'Outage {l}' for l in outage_labels],\n", + " clabels=('LODF', 'LODF', 'LODF'),\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "a20", + "metadata": {}, + "source": [ + "## 8. Worst-Case Overload Risk\n", + "\n", + "For each branch, compute the maximum absolute LODF across all three\n", + "outage scenarios. Branches with high max-LODF are vulnerable to\n", + "overloading regardless of which contingency triggers." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a21", + "metadata": {}, + "outputs": [], + "source": [ + "max_lodf = np.maximum.reduce([np.abs(v) for v in lodf_sets])\n", + "\n", + "plot_sensitivity_map(\n", + " lines_geo, max_lodf,\n", + " shape=SHAPE,\n", + " title='Worst-Case |LODF| Across Top 3 Outages',\n", + " clabel='max |LODF|',\n", + " cmap='inferno',\n", + " symmetric=False,\n", + ")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "name": "python", + "version": "3.11.0" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/steady_state/06_snapshot_and_solver_tuning.ipynb b/examples/steady_state/06_snapshot_and_solver_tuning.ipynb new file mode 100644 index 00000000..6afda774 --- /dev/null +++ b/examples/steady_state/06_snapshot_and_solver_tuning.ipynb @@ -0,0 +1,342 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "b1", + "metadata": {}, + "source": [ + "# Snapshot & Solver Tuning\n", + "\n", + "Demonstrates the `snapshot()` context manager for safe what-if analysis\n", + "and the solver option descriptors for tuning Newton-Raphson convergence.\n", + "The notebook covers saving and restoring state, comparing solver\n", + "configurations, and stress-testing the system under modified conditions." + ] + }, + { + "cell_type": "markdown", + "id": "b2", + "metadata": {}, + "source": [ + "Import the case and instantiate the `PowerWorld`.\n", + "\n", + "```python\n", + "import numpy as np\n", + "from esapp import PowerWorld\n", + "from esapp.components import *\n", + "\n", + "pw = PowerWorld(case_path)\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b3", + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "from esapp import PowerWorld\n", + "from esapp.components import *\n", + "import ast\n", + "\n", + "with open('../data/case.txt', 'r') as f:\n", + " case_path = ast.literal_eval(f.read().strip())\n", + "\n", + "pw = PowerWorld(case_path)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b3b", + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [], + "source": [ + "import sys; sys.path.insert(0, '..')\n", + "from plot_helpers import plot_snapshot_comparison, plot_voltage_profile" + ] + }, + { + "cell_type": "markdown", + "id": "b4", + "metadata": {}, + "source": [ + "## 1. Baseline State\n", + "\n", + "Solve the base case and record the initial voltage profile." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b5", + "metadata": {}, + "outputs": [], + "source": [ + "pw.pflow()\n", + "v_base = pw.voltage(complex=False, pu=True)[0]\n", + "print(f\"Base voltage range: {v_base.min():.4f} - {v_base.max():.4f} pu\")\n", + "print(f\"Buses below 0.95 pu: {(v_base < 0.95).sum()}\")" + ] + }, + { + "cell_type": "markdown", + "id": "b6", + "metadata": {}, + "source": [ + "## 2. What-If with Snapshot\n", + "\n", + "The `snapshot()` context manager saves the full case state on entry\n", + "and restores it on exit. This lets you make arbitrary modifications,\n", + "solve, and inspect results without corrupting the base case." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b7", + "metadata": {}, + "outputs": [], + "source": [ + "# Increase all loads by 20% inside a snapshot\n", + "with pw.snapshot():\n", + " loads = pw.loads()\n", + " loads['LoadMW'] *= 1.20\n", + " pw[Load, 'LoadMW'] = loads[['BusNum', 'LoadID', 'LoadMW']]\n", + " pw.pflow()\n", + "\n", + " v_stressed = pw.voltage(complex=False, pu=True)[0]\n", + " print(f\"Stressed voltage range: {v_stressed.min():.4f} - {v_stressed.max():.4f} pu\")\n", + " print(f\"Buses below 0.95 pu: {(v_stressed < 0.95).sum()}\")\n", + " overloads = pw.overloads()\n", + " print(f\"Overloaded branches: {len(overloads)}\")\n", + "\n", + "# Verify restoration\n", + "v_restored = pw.voltage(complex=False, pu=True)[0]\n", + "print(f\"\\nAfter snapshot exit, max |dV| from base: {np.abs(v_restored - v_base).max():.6f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b8", + "metadata": {}, + "outputs": [], + "source": [ + "plot_snapshot_comparison(v_base.values, v_stressed.values)" + ] + }, + { + "cell_type": "markdown", + "id": "b9", + "metadata": {}, + "source": [ + "## 3. Generator Trip Study\n", + "\n", + "Use `snapshot()` to study the impact of tripping the largest generator." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b10", + "metadata": {}, + "outputs": [], + "source": [ + "gens = pw.gens()\n", + "online = gens[gens['GenStatus'] == 'Closed']\n", + "largest_gen_idx = online['GenMW'].idxmax()\n", + "gen_bus = int(online.loc[largest_gen_idx, 'BusNum'])\n", + "gen_mw = online.loc[largest_gen_idx, 'GenMW']\n", + "print(f\"Largest online generator: Bus {gen_bus}, {gen_mw:.1f} MW\")\n", + "\n", + "with pw.snapshot():\n", + " # Trip the generator\n", + " trip_df = online.loc[[largest_gen_idx], ['BusNum', 'GenID']].copy()\n", + " trip_df['GenStatus'] = 'Open'\n", + " pw[Gen] = trip_df\n", + " pw.pflow()\n", + "\n", + " v_tripped = pw.voltage(complex=False, pu=True)[0]\n", + " violations = pw.violations(v_min=0.90, v_max=1.10)\n", + " n_low = violations['Low'].dropna().shape[0]\n", + " n_high = violations['High'].dropna().shape[0]\n", + " print(f\"After trip: {n_low} low-voltage, {n_high} high-voltage violations\")\n", + " print(f\"Voltage drop at gen bus: {v_base.iloc[0]:.4f} → {v_tripped.iloc[0]:.4f} pu\")\n", + "\n", + "print(\"State restored after snapshot.\")" + ] + }, + { + "cell_type": "markdown", + "id": "b11", + "metadata": {}, + "source": [ + "## 4. Solver Option Descriptors\n", + "\n", + "PowerWorld solver settings are exposed as Python descriptors on the\n", + "`PowerWorld` instance. Reading an attribute queries PowerWorld; setting\n", + "it pushes the value immediately." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b12", + "metadata": {}, + "outputs": [], + "source": [ + "# Read current settings\n", + "print(f\"Max iterations: {pw.max_iterations}\")\n", + "print(f\"Convergence tol: {pw.convergence_tol}\")\n", + "print(f\"Flat start: {pw.flat_start}\")\n", + "print(f\"Check taps: {pw.check_taps}\")\n", + "print(f\"Check shunts: {pw.check_shunts}\")\n", + "print(f\"Disable opt mult: {pw.disable_opt_mult}\")" + ] + }, + { + "cell_type": "markdown", + "id": "b13", + "metadata": {}, + "source": [ + "## 5. Flat Start Convergence\n", + "\n", + "Compare solving from the current state vs. a flat start (all voltages\n", + "at 1.0 pu, 0 degrees)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b14", + "metadata": {}, + "outputs": [], + "source": [ + "# Normal solve (warm start)\n", + "with pw.snapshot():\n", + " pw.pflow()\n", + " v_warm = pw.voltage(complex=False, pu=True)[0]\n", + " P_mm, Q_mm = pw.mismatch()\n", + " print(f\"Warm start: max |P mismatch| = {P_mm.abs().max():.2e}, \"\n", + " f\"max |Q mismatch| = {Q_mm.abs().max():.2e}\")\n", + "\n", + "# Flat start solve\n", + "with pw.snapshot():\n", + " pw.flat_start = True\n", + " pw.pflow()\n", + " pw.flat_start = False\n", + " v_flat = pw.voltage(complex=False, pu=True)[0]\n", + " P_mm, Q_mm = pw.mismatch()\n", + " print(f\"Flat start: max |P mismatch| = {P_mm.abs().max():.2e}, \"\n", + " f\"max |Q mismatch| = {Q_mm.abs().max():.2e}\")\n", + "\n", + "print(f\"\\nMax voltage difference (warm vs flat): {np.abs(v_warm - v_flat).max():.6f} pu\")" + ] + }, + { + "cell_type": "markdown", + "id": "b15", + "metadata": {}, + "source": [ + "## 6. Tightening Convergence\n", + "\n", + "Reduce the convergence tolerance and observe the effect on mismatches." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b16", + "metadata": {}, + "outputs": [], + "source": [ + "original_tol = pw.convergence_tol\n", + "print(f\"Default tolerance: {original_tol}\")\n", + "\n", + "with pw.snapshot():\n", + " pw.convergence_tol = 1e-7\n", + " pw.pflow()\n", + " P_tight, Q_tight = pw.mismatch()\n", + " print(f\"Tight solve (tol=1e-7): max |P| = {P_tight.abs().max():.2e}, \"\n", + " f\"max |Q| = {Q_tight.abs().max():.2e}\")\n", + "\n", + "# Restore original tolerance\n", + "pw.convergence_tol = original_tol\n", + "print(f\"Tolerance restored to: {pw.convergence_tol}\")" + ] + }, + { + "cell_type": "markdown", + "id": "b17", + "metadata": {}, + "source": [ + "## 7. Comparing Voltage Impact Across Load Levels\n", + "\n", + "Use `snapshot()` in a loop to sweep load scaling factors and collect\n", + "the minimum voltage at each level." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b18", + "metadata": {}, + "outputs": [], + "source": [ + "scales = np.arange(0.8, 1.35, 0.05)\n", + "v_mins = []\n", + "v_maxs = []\n", + "\n", + "for scale in scales:\n", + " with pw.snapshot():\n", + " loads = pw.loads()\n", + " loads['LoadMW'] *= scale\n", + " pw[Load, 'LoadMW'] = loads[['BusNum', 'LoadID', 'LoadMW']]\n", + " pw.pflow()\n", + " v = pw.voltage(complex=False, pu=True)[0]\n", + " v_mins.append(v.min())\n", + " v_maxs.append(v.max())\n", + "\n", + "print(\"Load Scale | V_min | V_max\")\n", + "print(\"-\" * 33)\n", + "for sc, vn, vx in zip(scales, v_mins, v_maxs):\n", + " flag = ' !!!' if vn < 0.90 else ''\n", + " print(f\" {sc:.2f} | {vn:.4f} | {vx:.4f}{flag}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b19", + "metadata": {}, + "outputs": [], + "source": [ + "plot_voltage_profile(v_base)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "name": "python", + "version": "3.11.0" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/steady_state/07_state_chains_and_stress.ipynb b/examples/steady_state/07_state_chains_and_stress.ipynb new file mode 100644 index 00000000..b37edd28 --- /dev/null +++ b/examples/steady_state/07_state_chains_and_stress.ipynb @@ -0,0 +1,450 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "c1", + "metadata": {}, + "source": [ + "# State Chains & System Stress Testing\n", + "\n", + "Demonstrates the `Statics` helper for advanced what-if analysis:\n", + "state chain management (push/restore), ZIP load injection,\n", + "randomized load Monte-Carlo, and continuation power flow under\n", + "varying conditions. Results are mapped geographically to show\n", + "where the network is vulnerable." + ] + }, + { + "cell_type": "markdown", + "id": "c2", + "metadata": {}, + "source": [ + "Import the case and instantiate the `PowerWorld`.\n", + "\n", + "```python\n", + "import numpy as np\n", + "from esapp import PowerWorld\n", + "from esapp.components import *\n", + "from examples.statics import Statics\n", + "\n", + "pw = PowerWorld(case_path)\n", + "s = Statics(pw)\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c3", + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "from esapp import PowerWorld\n", + "from esapp.components import *\n", + "from examples.statics import Statics\n", + "import ast\n", + "\n", + "with open('../data/case.txt', 'r') as f:\n", + " case_path = ast.literal_eval(f.read().strip())\n", + "\n", + "pw = PowerWorld(case_path)\n", + "s = Statics(pw)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c3b", + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [], + "source": [ + "import sys; sys.path.insert(0, '..')\n", + "from plot_helpers import (\n", + " plot_state_chain, plot_snapshot_comparison,\n", + " plot_sensitivity_map, plot_voltage_profile,\n", + " plot_pv_curve, plot_histograms,\n", + ")\n", + "\n", + "SHAPE = 'US'" + ] + }, + { + "cell_type": "markdown", + "id": "c4", + "metadata": {}, + "source": [ + "## 1. State Chain Basics\n", + "\n", + "A state chain is a rolling buffer of saved PowerWorld case states.\n", + "Use `pushstate()` to save the current state and `irestore(n)` to\n", + "jump back *n* steps. This enables iterative algorithms that need\n", + "to backtrack." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c5", + "metadata": {}, + "outputs": [], + "source": [ + "# Solve base case\n", + "V0 = pw.pflow()\n", + "v0 = np.abs(V0)\n", + "print(f\"State 0 (base): V_min = {v0.min():.4f}, V_max = {v0.max():.4f}\")\n", + "\n", + "# Initialize a 3-deep state chain and push base case\n", + "s.chain(maxstates=3)\n", + "s.pushstate(verbose=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c6", + "metadata": {}, + "outputs": [], + "source": [ + "# Perturb loads +10%, push state 1\n", + "loads = pw.loads()\n", + "loads['LoadMW'] *= 1.10\n", + "pw[Load, 'LoadMW'] = loads[['BusNum', 'LoadID', 'LoadMW']]\n", + "V1 = pw.pflow()\n", + "v1 = np.abs(V1)\n", + "print(f\"State 1 (+10% load): V_min = {v1.min():.4f}\")\n", + "s.pushstate(verbose=True)\n", + "\n", + "# Perturb again +20% total, push state 2\n", + "loads['LoadMW'] *= 1.10 / 1.10 # relative to current\n", + "loads = pw.loads()\n", + "loads['LoadMW'] *= 1.20\n", + "pw[Load, 'LoadMW'] = loads[['BusNum', 'LoadID', 'LoadMW']]\n", + "V2 = pw.pflow()\n", + "v2 = np.abs(V2)\n", + "print(f\"State 2 (+20% load): V_min = {v2.min():.4f}\")\n", + "s.pushstate(verbose=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c7", + "metadata": {}, + "outputs": [], + "source": [ + "# Restore back to state 0 (base case, 2 steps back)\n", + "s.irestore(n=2, verbose=True)\n", + "V_restored = pw.pflow()\n", + "print(f\"Restored state: max |dV| from base = {np.abs(np.abs(V_restored) - v0).max():.6f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c8", + "metadata": {}, + "outputs": [], + "source": [ + "plot_state_chain(\n", + " [v0.values, v1.values, v2.values],\n", + " labels=['Base', '+10% Load', '+20% Load'],\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "c9", + "metadata": {}, + "source": [ + "## 2. ZIP Load Injection\n", + "\n", + "The `setload()` method injects constant-power (S), constant-current (I),\n", + "or constant-impedance (Z) loads at every bus through a special dispatch\n", + "load (LoadID='99'). This is useful for modeling different load\n", + "characteristics." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c10", + "metadata": {}, + "outputs": [], + "source": [ + "# Restore base case\n", + "s.irestore(n=2)\n", + "pw.pflow()\n", + "v_base = pw.voltage(complex=False, pu=True)[0]\n", + "\n", + "# Inject 5 MW constant-power load at every bus\n", + "n_bus = pw.n_bus\n", + "s.setload(SP=5.0 * np.ones(n_bus))\n", + "pw.pflow()\n", + "v_after_sp = pw.voltage(complex=False, pu=True)[0]\n", + "print(f\"After +5 MW/bus (constant-S): V_min = {v_after_sp.min():.4f}\")\n", + "\n", + "# Clear and inject constant-impedance load instead\n", + "s.clearloads()\n", + "s.setload(ZP=5.0 * np.ones(n_bus))\n", + "pw.pflow()\n", + "v_after_zp = pw.voltage(complex=False, pu=True)[0]\n", + "print(f\"After +5 MW/bus (constant-Z): V_min = {v_after_zp.min():.4f}\")\n", + "\n", + "# Clean up\n", + "s.clearloads()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c11", + "metadata": {}, + "outputs": [], + "source": [ + "plot_snapshot_comparison(v_base.values, v_after_sp.values)" + ] + }, + { + "cell_type": "markdown", + "id": "c12", + "metadata": {}, + "source": [ + "## 3. Monte-Carlo Load Variation\n", + "\n", + "The `randomize_load()` method applies log-normal noise to all bus\n", + "loads. Running many samples produces a distribution of voltage\n", + "profiles for probabilistic analysis." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c13", + "metadata": {}, + "outputs": [], + "source": [ + "np.random.seed(42)\n", + "n_samples = 50\n", + "v_min_samples = []\n", + "v_max_samples = []\n", + "\n", + "for _ in range(n_samples):\n", + " with pw.snapshot():\n", + " s.randomize_load(scale=1.0, sigma=0.15)\n", + " pw.pflow()\n", + " v = pw.voltage(complex=False, pu=True)[0]\n", + " v_min_samples.append(v.min())\n", + " v_max_samples.append(v.max())\n", + "\n", + "v_min_arr = np.array(v_min_samples)\n", + "v_max_arr = np.array(v_max_samples)\n", + "print(f\"V_min distribution: mean={v_min_arr.mean():.4f}, \"\n", + " f\"std={v_min_arr.std():.4f}, worst={v_min_arr.min():.4f}\")\n", + "print(f\"V_max distribution: mean={v_max_arr.mean():.4f}, \"\n", + " f\"std={v_max_arr.std():.4f}, worst={v_max_arr.max():.4f}\")\n", + "print(f\"P(V_min < 0.95) = {(v_min_arr < 0.95).mean():.1%}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c14", + "metadata": {}, + "outputs": [], + "source": [ + "plot_histograms(\n", + " [v_min_arr, v_max_arr],\n", + " ['Min Voltage per Sample', 'Max Voltage per Sample'],\n", + " ['V_min (pu)', 'V_max (pu)'],\n", + " bins=15,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "c15", + "metadata": {}, + "source": [ + "## 4. Voltage Vulnerability Map\n", + "\n", + "Compute per-bus voltage sensitivity by finding the worst-case\n", + "voltage depression across the Monte-Carlo samples and mapping it\n", + "geographically." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c16", + "metadata": {}, + "outputs": [], + "source": [ + "np.random.seed(42)\n", + "all_vmag = []\n", + "\n", + "for _ in range(n_samples):\n", + " with pw.snapshot():\n", + " s.randomize_load(scale=1.0, sigma=0.15)\n", + " pw.pflow()\n", + " v = pw.voltage(complex=False, pu=True)[0]\n", + " all_vmag.append(v.values)\n", + "\n", + "all_vmag = np.array(all_vmag) # (n_samples, n_bus)\n", + "worst_v = all_vmag.min(axis=0)\n", + "v_range = all_vmag.max(axis=0) - all_vmag.min(axis=0)\n", + "\n", + "print(f\"Buses with worst-case V < 0.95: {(worst_v < 0.95).sum()}\")\n", + "print(f\"Max voltage swing: {v_range.max():.4f} pu\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c17", + "metadata": {}, + "outputs": [], + "source": [ + "# Map voltage swing onto branches (average of endpoint swings)\n", + "geo_fields = ['BusNum', 'BusNum:1', 'LineCircuit',\n", + " 'Longitude', 'Longitude:1', 'Latitude', 'Latitude:1']\n", + "lines_geo = pw[Branch, geo_fields]\n", + "\n", + "bus_nums = pw[Bus, 'BusNum']['BusNum'].to_numpy()\n", + "bus_idx = {int(b): i for i, b in enumerate(bus_nums)}\n", + "branch_swing = np.array([\n", + " 0.5 * (v_range[bus_idx.get(int(r['BusNum']), 0)]\n", + " + v_range[bus_idx.get(int(r['BusNum:1']), 0)])\n", + " for _, r in lines_geo.iterrows()\n", + "])\n", + "\n", + "plot_sensitivity_map(\n", + " lines_geo, branch_swing,\n", + " shape=SHAPE,\n", + " title='Voltage Swing Under Random Load (Monte-Carlo)',\n", + " clabel='V swing (pu)',\n", + " cmap='YlOrRd',\n", + " symmetric=False,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "c18", + "metadata": {}, + "source": [ + "## 5. Generator Limit Monitoring\n", + "\n", + "Check which generators hit reactive or active power limits under stress." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c19", + "metadata": {}, + "outputs": [], + "source": [ + "# Stress the system by increasing load 15%\n", + "with pw.snapshot():\n", + " loads = pw.loads()\n", + " loads['LoadMW'] *= 1.15\n", + " pw[Load, 'LoadMW'] = loads[['BusNum', 'LoadID', 'LoadMW']]\n", + " pw.pflow()\n", + "\n", + " q_violations = s.gens_above_qmax()\n", + " p_violations = s.gens_above_pmax()\n", + "\n", + " if q_violations is not None and len(q_violations) > 0:\n", + " print(f\"Generators above Q_max: {len(q_violations)}\")\n", + " print(q_violations.head())\n", + " else:\n", + " print(\"No generators above Q_max\")\n", + "\n", + " if p_violations is not None and len(p_violations) > 0:\n", + " print(f\"\\nGenerators above P_max: {len(p_violations)}\")\n", + " print(p_violations.head())\n", + " else:\n", + " print(\"No generators above P_max\")" + ] + }, + { + "cell_type": "markdown", + "id": "c20", + "metadata": {}, + "source": [ + "## 6. Continuation Power Flow\n", + "\n", + "Trace the PV curve by gradually increasing a transfer pattern and\n", + "solving power flow at each step. The nose point marks the voltage\n", + "stability limit." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c21", + "metadata": {}, + "outputs": [], + "source": [ + "n_buses = len(pw[Bus])\n", + "interface = np.ones(n_buses)\n", + "interface /= interface.sum() # 1 MW distributed uniformly\n", + "\n", + "# Track the critical bus (lowest initial voltage)\n", + "V_base = pw.pflow()\n", + "critical_idx = np.argmin(np.abs(V_base))\n", + "print(f\"Critical bus index: {critical_idx}, V = {np.abs(V_base[critical_idx]):.4f} pu\")\n", + "\n", + "mw_pts, v_pts = [], []\n", + "for mw in s.continuation_pf(\n", + " interface=interface,\n", + " step_size=0.05,\n", + " min_step=0.001,\n", + " max_step=0.1,\n", + " maxiter=200,\n", + " verbose=True,\n", + " restore_when_done=True,\n", + "):\n", + " V = pw.voltage()\n", + " mw_pts.append(mw)\n", + " v_pts.append(np.abs(V[critical_idx]))\n", + "\n", + "print(f\"\\nCollected {len(mw_pts)} points\")\n", + "if mw_pts:\n", + " print(f\"Transfer range: {min(mw_pts):.1f} to {max(mw_pts):.1f} MW\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c22", + "metadata": {}, + "outputs": [], + "source": [ + "plot_pv_curve(mw_pts, v_pts)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "name": "python", + "version": "3.11.0" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/visualization/01_discrete_calculus.ipynb b/examples/visualization/01_discrete_calculus.ipynb new file mode 100644 index 00000000..9574e92a --- /dev/null +++ b/examples/visualization/01_discrete_calculus.ipynb @@ -0,0 +1,543 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a1b2c3d4", + "metadata": {}, + "source": [ + "# Discrete Calculus on 2D Grids\n", + "\n", + "Demonstrates graph-based discrete differential operators on structured 2D grids\n", + "using `esapp.utils.Grid2D`. The notebook builds a grid and its oriented\n", + "incidence matrix, then derives gradient, divergence, curl, and Laplacian\n", + "operators from this single matrix. It also covers the weighted Laplacian\n", + "$L = A^\\top \\text{diag}(w)\\, A$, the Hodge star rotation, Dirichlet\n", + "boundary conditions with the Poisson equation, and Laplacian eigenmodes." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "ec99918e", + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [ + { + "ename": "ImportError", + "evalue": "cannot import name 'sorteig' from 'examples.mesh' (C:\\Users\\wyatt\\Desktop\\GitHub\\ESAplus\\examples\\mesh.py)", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mImportError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[1], line 5\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mmatplotlib\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mpyplot\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m \u001b[38;5;21;01mplt\u001b[39;00m\n\u001b[0;32m 4\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mscipy\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01msparse\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mlinalg\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m spsolve, eigsh \u001b[38;5;28;01mas\u001b[39;00m sparse_eigsh\n\u001b[1;32m----> 5\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mexamples\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mmesh\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m Grid2D, sorteig\n\u001b[0;32m 6\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mexamples\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mmap\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m format_plot, plot_vecfield\n", + "\u001b[1;31mImportError\u001b[0m: cannot import name 'sorteig' from 'examples.mesh' (C:\\Users\\wyatt\\Desktop\\GitHub\\ESAplus\\examples\\mesh.py)" + ] + } + ], + "source": [ + "import numpy as np\n", + "import scipy.sparse as sp\n", + "import matplotlib.pyplot as plt\n", + "from scipy.sparse.linalg import spsolve, eigsh as sparse_eigsh\n", + "from examples.mesh import Grid2D, sorteig\n", + "from examples.map import format_plot, plot_vecfield" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5ddf9133", + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": [ + "# Plotting functions (hidden from documentation)\n", + "import sys; sys.path.insert(0, \"..\")\n", + "from plot_helpers import (\n", + " plot_grid_regions, plot_scalar_field, plot_field_panels,\n", + " plot_gradient_vecfield, plot_hodge_rotation,\n", + " plot_eigenmodes, plot_graph_operators, plot_spy_matrices,\n", + " plot_incidence_directed,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "c9d0e1f2", + "metadata": {}, + "source": [ + "## 1. Building a 2D Grid\n", + "\n", + "`Grid2D` represents a structured rectangular grid as a graph. Internally it constructs\n", + "an **oriented incidence matrix** that encodes all edge connectivity. All discrete operators\n", + "(gradient, divergence, curl, Laplacian) are derived from this single matrix.\n", + "\n", + "Points are indexed in column-major (Fortran) order: point $(x, y)$ maps to flat index $y \\cdot n_x + x$." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a3b4c5d6", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Grid shape: (30, 30)\n", + "Total nodes: 900\n", + "Total edges: 1740 (horizontal: 870, vertical: 870)\n", + "Boundary nodes: 116\n", + "Interior nodes: 784\n" + ] + } + ], + "source": [ + "nx, ny = 30, 30\n", + "grid = Grid2D((nx, ny))\n", + "\n", + "print(f\"Grid shape: {grid.shape}\")\n", + "print(f\"Total nodes: {grid.size}\")\n", + "print(f\"Total edges: {grid.n_edges} (horizontal: {grid.n_edges_x}, vertical: {grid.n_edges_y})\")\n", + "print(f\"Boundary nodes: {grid.boundary.sum()}\")\n", + "print(f\"Interior nodes: {grid.interior.sum()}\")" + ] + }, + { + "cell_type": "markdown", + "id": "e7f8a9b0", + "metadata": {}, + "source": [ + "### Boundary and interior regions\n", + "\n", + "`Grid2D` provides boolean masks for selecting boundary and interior nodes, useful for\n", + "applying boundary conditions. These were previously in a separate `GridSelector` class." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2a9e478f", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAn8AAADiCAYAAAA/KaFPAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAUtlJREFUeJztnQd8FNX2x89mUzYhCQRCk1BDCb13sPEUVIpSpEkRqYI+5SlNeYAFkAePZ/0LIk0EUVBREASkiIggvUmH0KUngWSzKfP/nJvMsjXZZDeZnZnf9/NZlrl77+zkzj07Z+49vzMGSZIkAgAAAAAAuiBA6QMAAAAAAACFB5w/AAAAAAAdAecPAAAAAEBHwPkDAAAAANARcP4AAAAAAHQEnD8AAAAAAB0B5w8AAAAAQEfA+QMAAAAA0BFw/gAAAAAAdAScv0Jmy5YtZDAY6M6dO2J74cKFVKxYsQL9zoEDB9LTTz+dY52HH36YXnnllQI7hnPnzom/e//+/QX2HQBg3BUsbMPff/89BpqGUcs5xjXFO+D8FQA7duwgo9FITz31lM/2uXnzZurYsSOVLFmSTCYTxcbGUs+ePenXX3/Nte37778vnExv4Pb8o8CvgIAAiomJoeeff56uXbvmUfvy5cvTlStXqE6dOh5/5+TJk6lBgwZeHDUoaPjGQh4X/CpRogR16NCBDh48iM73Mfm5UfT1TR3b8BNPPOGz/YHCs035xfbpD3z22WdUv359Cg8PF+O6YcOGNG3aNMWO55zOJijg/BUAn3/+Ob300kvCMbt8+bLX+/vkk0+oXbt24sK6fPlyOn78OH333XfUqlUrevXVV922y8jIoMzMTCpatKhPZhcjIyPFj//FixeF4a5du5b69evnUVt2hsuUKUOBgYFeHwfwL/hiwuOCX7/88os4x3yjohUsFgvpHbkP2IZDQkK83g8ofNuUX8uWLVO8++fPny9uSl5++WXhbG3fvp3GjBlDd+/eJS2QlpZGfo8EfEpSUpIUHh4uHTt2TOrZs6f07rvv2n2+efNmibv99u3bYnvBggVS0aJF3e4vPj5eCgoKkl599VWXn2dmZlr/L+9r1apVUs2aNSWj0SidPXtWGjBggNSlSxdrvbt370r9+vWTihQpIpUpU0aaOXOm9NBDD0n//Oc/3R6Hq+Pkvy0gIEBKTk6WMjIypClTpkjlypWTgoODpfr160tr16611uXj4L973759dv2wceNGqXHjxlJoaKjUsmVL0W/y9/Hnti8u47930qRJUvny5cX3lC1bVnrppZfcHjcoWBzHFrNt2zZxvq5du2YtO3jwoPTII49IJpNJKl68uDRkyBBhKzKuxh/vl/cvU7FiRTHmnn/+eWFjPAbmzJlj12bnzp1SgwYNpJCQEDGuvv32W7txl56eLg0aNEiqVKmSOJbq1atL//vf/1z+Te+8844YX1yXx3bt2rWd/n4e52+++aZTOdsD28Inn3xiV753717JYDBI586dy/NYdrRBbsvfv3jxYtE3kZGR4jcnMTHR+nc42hDbIXPo0CGpQ4cO4jegVKlS0nPPPSddv37d7nyMHDlSnJMSJUpIDz/8sCjnfXz33Xcen1dXfQmUs01HTpw4IbVt21bYC18z1q9f73SOt2/fLsaZbFP8ma1NeTKeHOHjGjhwYK5/w2effSbFxcWJ765Ro4b08ccfu72meHIcbJfvvfeeFBsbK2yObY/HJuNoK2wDchtPrm1fffWV9OCDD4pjZVtlG+/YsaNUrFgxKSwsTKpVq5a0Zs0ayV/AzJ+P+frrrykuLo5q1KhBzz33nLjDyRpX+WPlypXiLoLvilzB09S2JCcn03vvvUfz5s2jI0eOUKlSpZzavP7667R161ZatWoVrV+/XsQh7t27N8/HFhoaKmYW09PTxdLyrFmzaObMmWLJr3379tS5c2c6efJkjvt44403RLvdu3eLGaNBgwaJcl7S/te//kW1a9e23rFyGffH7Nmzac6cOWLfHJtSt27dPB87KBj4zn3JkiVUtWpVMVPN3Lt3T4yHqKgo+vPPP+mbb76hjRs30qhRo/K8fx4rTZo0oX379tGLL75II0aMEDPh8nfzjGOtWrVoz549Imzgtddes2vP45VDFvgYjh49Sv/+979pwoQJwm5t4RlM3u+GDRto9erVYlz+9ddf4vhl+Bh4rHP4gyMcGtG7d29aunSpXfmXX35JrVu3pooVK/pkLJ8+fVq042PkF9v19OnTxWdsky1btqQhQ4ZYbYjDLzje+NFHHxXLbGx369ato7///pueffZZu30vWrSIgoODxazMp59+6vTdnp5Xx74E/gHbQteuXcU53rlzpzjHY8eOtauTmJhInTp1EuOSrxFvv/22Ux1Px5MtPIP8xx9/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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Build coordinate arrays\n", + "x = np.linspace(0, 1, nx)\n", + "y = np.linspace(0, 1, ny)\n", + "X, Y = np.meshgrid(x, y)\n", + "\n", + "plot_grid_regions(X, Y, grid)" + ] + }, + { + "cell_type": "markdown", + "id": "a5b6c7d8", + "metadata": {}, + "source": [ + "## 2. The Incidence Matrix\n", + "\n", + "The core data structure of `Grid2D` is the **oriented incidence matrix** $A$ of shape\n", + "$(m, n)$ where $m$ is the number of edges and $n$ is the number of nodes. Each row\n", + "has exactly two nonzeros: $-1$ at the **source** node and $+1$ at the **target** node.\n", + "\n", + "Horizontal edges (left → right) are listed first, then vertical edges (bottom → top).\n", + "\n", + "### Directed edge structure\n", + "\n", + "The plot below shows a small grid with every oriented edge drawn as an arrow from\n", + "its source ($-1$) to its target ($+1$), alongside the dense incidence matrix with\n", + "annotated entries. This makes the one-to-one correspondence between rows of $A$\n", + "and directed edges visually explicit." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "12ca26eb", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAFyCAYAAABlf2usAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAkEJJREFUeJztnQd4FFXXx/9JNtn0XgkJIfQaQpMuHQUpUiyIgIIgKqiIAn4o+r4K+ipWEBGUqlhAohRBEFFQOiGEXgME0iE92WST/Z5zwy67m03YJJvs7O758QyZvTvlzpnZmf+ce8+5diqVSgWGYRiGYRjGZrA3dwUYhmEYhmGYuoUFIMMwDMMwjI3BApBhGIZhGMbGYAHIMAzDMAxjY7AAZBiGYRiGsTFYADIMwzAMw9gYLAAZhmEYhmFsDBaADMMwDMMwNgYLQIZhGIZhGBuDBSDDMAzDMIyNwQKQYRiGsWreeustuLu718q27ezs8OGHH1a6zPHjx8Vye/bsgaUSGxsrjqFx48ZVWq+wsBBhYWHYunWrpmznzp0YO3YsGjVqJLb5wgsvlFtv1apV4jtD0wMPPFCjYzFm/+fOnRPlLVu2hKurKxo2bIhp06YhPT1dZ7lnnnlGTJaIzNwVYBiGYRhLZf/+/WjQoAGsnW+//Vb8vXTpEg4ePIj77rvPqPWWLl0KHx8fDBkyRFO2fft2xMXF4f7778etW7cMrkfLk221uXDhAsaPH48HH3ywRsdizP537tyJvXv3YurUqYiKisLVq1fx5ptvChFPgl4ul4vlZs+ejVatWuG1115DkyZNYFGoGIZhGMaKmT9/vsrNzc1s+4+NjVXR4/bPP/9UWSIlJSWq+vXrq3r06KFydnZWTZ8+3aj1SktLVREREaqPPvqo3PbUNGjQQPX8888bfR4dHBxUSUlJOuUnT55UXbx40eA6e/bsUd2+fbvK+09PTxf11+aff/4R53HDhg065X369FG9+OKLKkuDm4AZhmEYmyIhIUE0/a1bt04085GHKiQkBLNmzYJSqdRZ9syZMxg5ciR8fX1FUyB5g9avX19pE/A777yD4OBg0exM66ampparg0qlEus1bdpUeJMiIyPx8ccfG2y6jo+PR48ePcT+W7dujR07dpTb3po1axAdHQ1nZ2f4+/tj8ODBwmulJjExEePGjRPfubi4oFevXjh69KhR9vr777/F+s8++6zwzP3www8oKSm553p//fWXsPXo0aN1yu3tqyc9yO59+/YVttXmv//9L/r164fr16+X2z95C6k5uar79/PzE+dWG7IvcfPmTZ3yMWPGCA+p/rUjdVgAMgzDMDbJ//3f/wkx8OOPPwpxs2jRIqxYsUKnybFr167i72effYZff/0VTz31FK5du1bhNhcvXow33ngDTz75JDZu3CiE3aRJk8ot9+KLL4omxQkTJoj+cRMnThTNiV9++aXOcsXFxXjiiSfE95s2bUJgYCBGjRqFjIwMzTIffPCB2E6HDh3w888/4+uvvxbNkWlpaeL727dvCwFJTZeff/65qJebm5sQU4bEqT4kbkh8jhgxQvSdo3V27dp1z/VoGer/R1NNOXLkCM6fPy/2r8/y5csREBCA/v37a47n0KFDGDp0KB577DFha1Owb98+8bdFixY65d26dRN9A8m+FoW5XZAMwzAMU5dNwFeuXBFNeWPGjNFZ7v7771f169dP83ns2LGqgIAAVVZWVoXbpu188MEHYl6pVKrq1aunevLJJ3WWoc/aTcDUXGlnZ6datmyZznKzZ89WBQcHa5ooqd603tatW8vVfe3ateJzZmamytXVVTVlypQK6/jmm2+qvLy8VCkpKZqywsJCVXh4uOrVV19VVYZCoVD5+PioHnvsMc16tC39YzTEwIEDVUOGDKl0GWObgF9++WXR/FzRuaAm21atWqmioqJUf/31l8rX11c1evRocU5Msf+CggJV27ZtVdHR0eWahouLi0XT9OLFi1WWBHsAGYZhGJtk4MCBOp8p4pOaOtX88ccfovnS09PTqO3RutQ8+PDDD+uU6zeBqr1n5MmjZkP1RB6s5ORknaZM8lBSuZqIiAjRhKuuJwVK5OfnG/Qyqvn999/Rp08f0Yyt3peDg4MIgjh8+HClx/Tbb78JD6La80bN1dSsTd7IgoKCStdNSkoSnrmaUlpaiu+//140P1d0LqjJlgI3cnNzxXF17twZ3333nThOU/Dss8/iypUroqldv2lYJpPB29tbHK8lwVHADMMwjE1CD21tnJycRNoSNdTMWq9ePaO3pxYA1EyrTVBQkM5nai4k5yH1xzMECUB1ZDGJPapXRfVUNwVXVk/a34EDB+Do6FjuO0qFcq/mXy8vL3Tp0gWZmZmi7KGHHsLKlStFk/ijjz5a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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Visualize directed edges on a small grid\n", + "small = Grid2D((4, 3))\n", + "plot_incidence_directed(small)" + ] + }, + { + "cell_type": "markdown", + "id": "c3d4e5f6", + "metadata": {}, + "source": [ + "## 3. Gradient of a Scalar Field\n", + "\n", + "The gradient operators $D_x$ and $D_y$ are extracted directly from the incidence matrix:\n", + "$D_x$ consists of the horizontal-edge rows and $D_y$ of the vertical-edge rows.\n", + "\n", + "Applying $D_x$ to a scalar field $u$ gives the forward difference along each horizontal\n", + "edge. The result lives on edges, not nodes." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "grad_setup", + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": [ + "# Compute gradient operators and a test scalar field\n", + "Dx, Dy = grid.gradient()\n", + "\n", + "# Smooth test field\n", + "f = np.sin(2 * np.pi * X) * np.cos(2 * np.pi * Y)\n", + "f_flat = f.ravel(order=\"C\")\n", + "\n", + "# Gradient on edges\n", + "grad_x_edges = (Dx @ f_flat).reshape(ny, nx - 1)\n", + "grad_y_edges = (Dy @ f_flat).reshape(ny - 1, nx)\n", + "\n", + "# Edge-midpoint coordinates for visualization\n", + "Xmid_h = (X[:, :-1] + X[:, 1:]) / 2\n", + "Ymid_h = (Y[:, :-1] + Y[:, 1:]) / 2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f84afb9e", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAn4AAAESCAYAAABjDtjcAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAWSpJREFUeJztnQeYVNXZx8+dtjPbWdiFlSpVxIKADTX2EgsYiVEjEYwIGtEY/AxgNHbxS9RojEawYIgajaDRqCHYPwsqiI2igKIUgaVun36/5z1kJrM7570zd9ndKef/e54DO+e2c8+98857zluOYZqmKQAAAAAAQN7jyHQDAAAAAABA5wDFDwAAAABAE6D4AQAAAABoAhQ/AAAAAABNgOIHAAAAAKAJUPwAAAAAADQBih8AAAAAgCZA8QMAAAAA0AQofgAAAAAAmqCV4rd7925hGIZ4/PHH43XBYFBcfPHForKyUm67995749tWr14t69avX8+ec/jw4WLixIki2+nXr5+YOnVqh17jpptuEsXFxSITfPvtt/L633//fVb2z9lnny2OO+64Djs/AAAAkA4uoTnz5s0Tf/3rX8Vf/vIXMWDAAKkAxPjnP/8pDjroINGnT5+MtjFXmDRpkjjjjDMypvjdfPPN4swzzxT77LNPRtoAAAAAZDvaK35ffvmlVBQuvPDCpM556aWXpCIBrAkEAsLtdotevXrJAgAAAIDsJK9NvQ8//LCcwSssLBQnnniiWLt2bYvttO3uu+8WGzZskCZdKjRzFDMLv/vuu+Kss86K7//++++LkSNHCq/XKw444ADxr3/9q8X56urqRN++fcWPf/zjFvWXXXaZ6Nq1a0oz5OzZs8WQIUNEQUGBbNttt90motFofDuZqKmNn3zyifjhD38oioqKxKBBg+SsZbo88MADso1lZWXS/Lht27YW27/77jvZftpO5z/11FPFF198oTSL/u53v5Pn8vl8YufOnUmmXjJtxvo1sSSaPO1cj2v7W2+9JY4//nj596GHHhq/DtHY2CiPpX6l94DORc+jtrZWtIWXX35ZHH744fKeyT3g8ssvl9dIZNWqVeLYY4+V7wnNItNssornn39etov2O+KII8SyZctEeXm57Ec71wyFQuLaa6+VM9P07lRXV8v3tq33CAAAII8x85R//vOfJt3exIkTzYULF5q333672a9fP1k3d+5cuc+yZcvM8847z+zRo4e5ePFiWfx+v9z2t7/9zayqqjIjkYj8vHnzZrO4uNg88sgjzRdeeMF8/PHHzb59+5rdunUzJ0yYEL/u66+/bhqGYc6bN09+fuWVV+Q1n376acv2/vGPf5T7XXnllea///1v88YbbzSdTqd5zTXXxPehdtM+Q4cONe+55x5z0aJF5rnnniuvt3LlSsvzU1t79+5tnnLKKbJv6Fzl5eXy/mPU1dXJPurfv7/51FNPmc8995w5cuRIud/69etbnIv67JhjjjGff/5588UXXzSbmppkm4uKiuL7rVixIt6vVObPn28WFBSYkydPtn09q7bX1taaDzzwQPzZxq5H1NTUmJdddpn57LPPmm+99Zb517/+1dxvv/3M4447Lql/rrjiCss+pHM4HA7zkksuMf/1r3+Zjz32mHxHEvuwubnZ7NWrlzlkyBDz73//uyx0vX322cc89thj4/vRu0fP9+yzzzZffvll88EHHzQHDhxoer1e2Y92rnnzzTfLd5P6gO6R+pn6eOvWrZb3AwAAQD/yVvE7/PDDpWKSyA033NBC8SN++ctfyh/91lx44YUtFLrp06ebJSUl5u7du1soeXS+xP2Iq666yiwrKzM/+eQTs7q62rzgggss2xoOh6UCef7557eonzlzpunxeMzt27e3UPzoBz5GQ0ODWVhYaN56662W16B7JIUkptgSpGC43e64cnvfffclKZE7duyQyty0adNanKtr167y2om0VvwSIYVo1KhR5sEHH2w2Njbavl6qtr/55puyb5YsWWLZD6FQyHz33Xflvl999VXail80GpX7tH6WpIzRPSxfvlx+/vOf/ywVtdWrV8f3WbNmjaxLVPxIYSdFL9Z+gpRSaldM8Uv3mmeccYZ5zjnnWN43AAAAQOSlqTcSiYiPP/5Y/OhHP2pR39oEa3U8mXETzbwffvihNCeSmTHGCSecICoqKpKOv/POO6W5jcx3DodDmihT+Rlu375dnHvuuS3qzzvvPBl1/NFHH7WoP+WUU+J/k3mUzJ8bN25MeV9kfiRTYIz9999fmglramrk53feeUeasIcOHRrfh+7v5JNPlmbvRMhcS9e2E/ixbt068Y9//EOaXO1eL1XbraDgnUMOOUSaockX8eijj45HbacL7Utm6Z/85CciHA7HC7WLnvHSpUvj7wndE5ngYwwcOFAcfPDBLc63ZMkS6T9Kx8YYO3Zsm645YsQI8corr0gTMZ030T0AgHTQOeNBZ0DfTXIVag314V133dXu10OWAmBFXip+5PtFP5BVVVUt6rt3757W8fQFbWhoaKFgbd68Oel8hKqOfLHIB42CHn7605+KLl26WF5v165dyvbFPpP/XCLkB5aIx+MRfr8/5X2pjiNix1I7VH1Eda3bkG5fEuQL+PTTT4tnnnmmRdS0neulajsH+dFddNFF4rDDDhN///vfxQcffCDr0jk2EVLMCRpMkPIYK6TE0kCB/ESt3pPW90n70Q9qIiUlJdLfz+41f/Ob34jp06dLX0K6zx49esgIZ5rRB2BvMx6Qwrd48WJx/vnnx7ch44E96PuoUvyoX1WBhQB0JHkZ1Us/qC6XK2k2aOvWrWkdT9G8P/jBD+QPcQyawVPNLqnqPv/8c3HPPffIWab7779fjpoTZ7VaE5s15NqrmlXsCOg6X331VVI9taN1G2LBE6mgmdOZM2fKUS0F2LT1em3l2WeflTMPFDgT4+2337Z9nlh7/vSnP8lAi9bEUsjQe0JBGqp7Ki0tjX+m/VoH1tTX17dQRtO9Js2E0owCFQpgeuyxx+Tf/fv3Fz/72c9S3htdk2Z30oEU7kTlFOQvyHiw9zQ3N8uJAA6yCoHM4NdY7uXljJ/T6ZTmr9jMToz58+enrfglmnkJmkl58803W0RKvvHGG0kzU/Qi0Y8t7U+zS2T2oxknmoHkoMhOUlZJSUmEZqjohaNzdQZkAqWI2kRljGblXnvttbh51A50ngsuuECOaH/1q1916PW4GUASvLFtMZ588kmbdyLEfvvtJ1PVfPPNN2LUqFFJJaaE0bNavnx5iwhy+vuzzz5rcT6KPqb3LNEsS2bwtlwzETIr33HHHVJppOjiVFB/dfUVSxeGdMq+++5ra6YUZCednfGAZgjpHGvWrGlRT993UowefPDBjGQ8IFM0tbc19N2k8yXKJroG5XWle+zZs6ecaaeZ99ZtoFk8clehNlC0fWyQHPubCmUi4Ey9FMV/1FFHyWdD1iJyq6H7IpCloH3way738nLGj6AvJflM0WwbmSjI54/MFqmgH9mVK1cm5e+7+uqrpa8eCZUZM2ZIgXXjjTfKNC2J/Pa3vxVff/21/KEnhYMEDymhJKhap+lIVFRvuOEGcdVVV0kz4emnny6Vxv/93/+V1219jY6C+uoPf/iDTMJM7SUBd/vtt8vZU2qHXcaMGSOF+s9//nN5PzFo5ot89NrzeoMHD5b9SLNddDwVUo5IAF9xxRXi1ltvFUceeaT0hXv99ddt3wsJaJrFJdM9CV9qMwl28sEjQU3KFrWBfkjoXuj9oWvG3gkyvyZCs6Ck/I0bN05MnjxZnod+AKgPYn5/6V6T3AroR5dmmGk7/cjS+0k+qKmggUqTiIiLRE/hSTEODIqomLdlkzwmn0a/ukFKDb1z9K7GZGNr/2IaNJP8odnx2ACaZqmJhQsXyoFFbEC6ZcsWmYbpwAMPlINVevdiKYdotp0gmUbKEn0/Z82aFb/OU089Jf+nd5yDrCYkG6+88kr5vSIlk2QpKaCtlSYaZF566aVi2rRpUrmle6TvGWdxoYEpuUjQYC1RAfzb3/4m5TYpmwR9D3/961/LASwpxDSoiil+5NOdCN0L9e91110nlbfx48dL2UPtj90nyT8V5A5DbaLfLuob+g157733xKZNm+T3u6mpSV6T5CRNFpBiTn+TDKCJCTvQRAj5kZMcJlM0uZ/EftvINYcgZYdcnkiuxH4/SZ5R6rJEP2ZSTOkdosEAyXSSUXRucneye016Px566CH5/g0bNky6vCxatCjpXHtDUHe5l88xLg899JBMA0IpMiii8sMPP0wZ1UuRppQuRcX//d//mcOHD5eRtrTPSy+9JKNUY1G97733nozepOsm8oc//MF0uVwpI04pInTQoEEyWrVPnz4yUjcx6jMW1btt27YWxyW2gUMVtUqpWOh869ati9d9++23MkKUIpgpWvjkk082P//885TnUkX10rlVJTG6ta3XU7Wd+p1Sw1Bfx15tipimlDiVlZXyGj/+8Y/NDz74QG6nVCmp7qk1lEKH2k/3SWXYsGHy/InR3hRtSxHl9J7su+++MgXL2LFjW9w3sWDBAnPw4MEyxQ2lsaFoY2r7vffea+uav/vd72TENEWS0/YRI0bI9DjpQKlwqC+mGH3MKx39LAvtQ/vSMSB3yVTGg+uvv16mNaLvZAx6V3/6059mLOMBRfmTbLjuuuvidZR1gNIj/f73v4+nnaLPdM3W8trn8yW14c4770y6DtXHzsfVUxQ/ZS849dRT2faq2o8sBfap1Vzu5bXi1xZI8bj22msz3QygIa+99poUMJSLr7OICcCpzr7mNa59LQvtk28CUDdIkaLBBeUBTeSzzz5LS/Gj4ysqKmSuyBiUE3PMmDFJ16L9EhU/GqRRGiIaMCdek5REDhpE0T40SErk008/lfWUJzVR6aLUSYnQAH3KlCmWffKLX/zCHDBgQPzzM888I9u5YcMG+ZnywNK5KfcmKVqxQtdK/L7G2vDFF1+0SfFbtWqV/EzXt4JyxNIEBA3yEgfUlOM03YHsl19+KY+hAXTiPVE+VsovSnlqCcqDe9BBByUdf8ghh7QYyFI+1quvvrrFPqQwJ6anSveaNAiJ5TP96KOPWkx+tBe1msu9vPTx2xtoSpmiUAHoaH7xi1+IBQsWSH8fciMgMxWZc4455phO73ynkV5pC3Rv5JdFZhIKUmmdnigRMs/R/ZNvE5WTTjrJcn+QOxkP6B0g14tHH31UfiazL/lOxVbdyVTGAzKtkntO7D0jMy+9g7HlJ2PR9WT6TYyuj5k6Y9H1rdtmlx07dsj/rdYaR5aC3JB7D2S5zMtbHz8Ash36USO/H/phIQfi0047TfosJeb26yychiGL5T7CvgQknyXytyKfHRKAlBqE/MHIaV6lLJASTD/Eo0ePlkKT/HxIyVixYoX0EQO5nfGA/O/Iz4181ijIinz3rDIEdEbGAwqk6N27t/QxI58+CkxJzFkYu8Zzzz0n92sNKa9tyXjQmpgvt9XSnshSkDpLQabl3jM5IPMw4wdAhqCZBRLy5DRMMzHkPN3W2YJsHfmSUzz92JMzNzm0kzAkh3ea7VFBygDNhFJQAEU1P/LIIzJ6sy0BOSC7Mh4QFLRAsxqk/NH2VAmeOyPjASlqFORC56QZeAqeSEz2T4EZ9M5SknxVdH06wXc0Q5hq5pHulWYZ586dy+6DLAXZL/fuyQGZhxk/AICtkS9F9CVCKTYSV1WJQQotRYxSBHMMms0kUwalvEgHimKkFVo6K5elDmQq40FMAZowYYL4/e9/L2dBVDNomch4QDMu1Ca6Fs22dOvWrYX5+JZbbpFRvaT8UXoVahf1xwsvvCCVxdhqRBwUVUz7kkmPImRJyUucNU1M7UJtoWh/SgNG3yv6rlBkMvU7shRkt9wL5ojMw4wfAECKNkeKEhOP9GOdmOMqMT1HImTCptkTlX8WpQBJB1qRhHyeSHCC9oHSLNEsBM0oUBoQ8msm81Q6s32kwFBi8ETI1EvmUZqNopQepJSRIhjzkWtNbClNSvOUDuQO8ec//1mmYiLlh3wEKZ1Le/pik28tKWM0A0+KV2uuueYaORNHM5uklNF9zpkzRypkrfOEqqD+oFkcUo7pGFIOVFCqE1IQyRROSjm1hXImxvpyypQpsi2U4uacc86R/oWxlDh2oXugPqVE3XQdei8oVQ35psW+s5SOi94PUropLQ19H0kBpnto3X80Y0oDA3q+NGtFaXLInzRxmdN0rkmm9xdffFFej2aXKaUQzYp1hAww2lnu5YrMMyjCo8PODgDIamgUS0LsRl9/4TWsx4F+Mypubv5G/tgkrkLCzfjRjyj5qFBAAJnLYtAPBwlzWtfYCsqPRj/u5ANDiXNBZqGZMDJH7a3CRXngKGEzKTeq9wbkBzSwIOWFvr+0vrgOcu/7HJF5eW3qpREWPQiaUm+rwy0AuQSN42jpNxox2gkS2ePLksrksQcSfokCkIPMZWQSax04QJ9bJ7RuDZm8SAjSKi5Q+rIDmvnZG8i5nQrNVlFSdSh9+QX5qdEqMGR+p8AESmCfqSwFmZJ73XJE5mVM8SOfDZrOpQzflPU7luG9NTStT51BShytREAjRfITSQdS+lL5kACQj9DolDO1qUjHiTkmANOFTGC0okjMpEjEnJanTp3KHkcjXlqN4N///rd0ngf5AZkpyT+PotcTfaBAfpBNWQoyJfc8OSLzMqb4UdQUTX9arcm6bt066WxLi96TjZwcksmvgkaL6RBznr2QWZal1KV+Ifct4hXLAX3+66+QSM8jeAWz+piRyvqC4cexx9RWDFTWf1HTxB7z5to9+aZa8/7K5LQKMbZ+tydPVmt2r+fXeW3evU1ZHwk2s8c4PeqFyn3llewx5X3UyywR3ft2UdaP3j85XD7G8QP/67CdyIFVvGN22c6Wa5jGCHy6Z61NFZvfUfvvbPqgZb6vRL5e/9+IyETWNYbYY+rC/12rNHF5oSfFpiTH8Uylc6G0BuTMT8KMIjAptQEt5UWBBQQ5sJNpJOYvQ/5hZAokvyXy+4n5xRQXF8sCcpfY+rQgf7MU5BrODpB7uSDzMqb4US6oVFCKAXL+jE2RXnbZZXJ9Uk7xo7X8EtfzI5MXQUqfSvErYGz7PoPX8Yuc6m0lHl5ZLC1Ur+9XUMI/VJOZUi5q5ttWUKhOF+DyNrLHODzq9Q8NF78moeFUOzMbzoj9Yyyu4/DwCpnLW6SsLyjk+7SIUYZKS9XnkttC6vMFmGdKNDDvAvfuWL1zBQbfp1Yu5XZdGxxpjHzbMm4nZ3VKVUOCjQQazezTWq8x5+f169e3mBEgJ36KjEtMp0FQlCi31jUAALQFRwfIvVyQeVnt40cd1Ldv3/hn0oapjoM0aFr4GQBgD4/DEJ4UymLEbJufLJk4ODNH61mgb7/9VuQrneHeAgDIvNybmuUyL3uN722A/EYoiWistF5KBwDQ+Uu2gT3QiJ5ScyQOZjn3lnfeeUesXbtWOoWTewsAoP1xair3snrGr0+fPnINxUTNmOo4uLQSAIDM+PiBjnVvUbm40EwhrYpB0ZXIZgB0oO3ZDAwt5V5WK36UKJOCP8jOTfZxSjpKSS3tQlO5qulcn5Px8bNQ8Z0etS+Ww813pcH5drVzihknOSyo6l38dRxMHzgLfPwx7tQJS9M9xvI6TNus7onrgzbDPCP2mVq8C9y7Y/XOce8o0RxRpOAks0QbMnNSy1JGtyHjZ9a5txBwcQGgjdkMhJ5yz5XJ0P6XX35ZOj/S0j0UhUimjUmTJskRLxXKEE8+e5TJm6Clcug4AED74khj5Ev7gOx0caFIwhjk5kKWkbVr1iQvCxYNq08SUUePG0y9hDkXe432XCvA6l1kgvZMB/Nzx9XTMU63rfqoRWBgKKq+/4jdeotuZA6RM2LtBTeLbDFGZWULk1hDuCwG8KoxP832DRw0yHY2A4emci9jit/s2bOV9bTUSyK02DEVAEDHkVY+q/yTfznv3mLl4kI/gq0TztpX/IL8hSM5pvg526L4eTpc8QtrrPi520nxS9U2vl1CS7mXV8EdAIC9iG5Lo4COd2+hyF+yhNCPdVvdWwAAqfFoKveg+AEA4k7OqQpoO+SmQv5HGzdulO4tAwfuSdJO7i2k7BGJ7i20vbKyEu4tAHQQTk3lXlYHdwAAOgfyY3Fo6OvSmcC9BYDswqGp3IPiBwAQhtMQRgqTBlKDAADyCUNTuaeF4tfD6xJehcNvBZNeo8LHZ8kv7KpOP+KxWPbL8DDLe1nkG+LeRS8XBkVr+3nVj9NrdT8l6ryHgS578ojZIRKwWKuXSdvis7gO1zare+L6wKrvLL/3zDNin6nFu8C9O0TF9w3pp2z5D15Fw/1mVAj+MbA4nIZwOPQb+eqGEVQv3+hoUq/Z7fDvWfZSRbRup7q+qU5ZbwbUS0ruOYhfmlCJi08p5ShSR3Y6i9TLYIrCcr5ZPvXa7NFC9VrhIQuZXh9Q32NDKGpr//ogEzxD5wqqjwlF1Ndoy/edk6PFHl72lvvU24qY6I4Si9RXxZ7kY8w2yiaHpnJPC8UPAJACp0MYqRKfGnmY0AoAoC9OPeUeFD8AgHC6HcJplY+BZKRVHgkAAMgxnJrKPSh+AAA56k018jXaMw8bAABkGENTuQfFDwCwx9clRaZSRx6uWQkA0BeHpnIPih8AYE90WwoBaOShAAQA6IuhqdzTQvHbv7RAFDqSo4TcxerI0NJe/Hp/Jb3UUV6+Sj4yzCgstbUckBWFbj7aqVuR+nx9u/ERx/5mi7U4GQqKipX1UYvIMQfjR2EVuVteWchu4+6J64NUfcfBPSPumVq9C9y7Q4T86kg910Y+qnKfhuRn10TRkc1tFYApTB7CfmQgyC6MgDqq16jfrqwPbVzLniu8bZOyvnmbOkI4WNfEniviVy8Nx72T7iI+qt7bVf0981RWKetd3fkl8Rzd+ynrzQK1/AkLXv5w0bsb6wLK+k116ijozUw9UcOcqyEQtrUsHOFj5GV5ofp3s0c5/0yqi9Vyvl95oe0l21RRvW3F0FTuaaH4AQCscbocsljuw6yBCgAAuYhTU7kHxQ8AIGdkuVnZGA4z/wQgAEBfHJrKPSh+AID0fF3M/PN1AQDoi6Gp3IPiBwDQVgACAPTF0FTuQfEDAGhr8gAA6ItDU7kHxQ8AQB7MKUe+Ig9HvrphhNURoREmQjewYR17rt2rNyjr69bXKOubdvDh5uFmddQp9056S/lsAMXV6oj7sgHqCHk+h4MQnhImW0OpOkI4YrG8F7f2Lhe9u+J79ZrHqzar64ldu9TnCvjV2RtMi6heFxPV6ytmskdUqbM9EMN6qp9JgUt9jTKv/QwMbcKpp9zTQvGrHtlDFLuTb9XFLBxdWMWn6ijp3V1Z76tW1xPOsq6207kYNhfIJqqYkPlB3fkvJMd3PnXIvlUKmEiYFyJOF3M/FtexSkPD3RPXB1Z9x/W11TPinqnVu9CFSVlBuHzq6xR3L7L1Y9kQCgvxyiphF6fLKZwp0t04Rf5lsAcA6ItTU7mnheIHAGiHDPbR/Bv5AgD0xaGp3IPiBwBIz8k5DwUgAEBfDE3lHhQ/AIDMXp8yg300/5ycAQD6Ymgq96D4AQAErWiY2uSBjgIA5A8OTeUeFD8AgDAchixWpNoOAAC5hKGp3NNC8dvnyMGixJsc7en0qiMpC7rwAf5cNKersid7jFGuDv2POvmIVm4Q4rOI6u1Zwi+SzdGFiartX8lHkzb47S/47WS+PMVe/hXsVsRHPXPRu1Z9wPWd1YDPZJ6Rg3mmhLvXQGV9SYGPPaawWv1eBXapU1BwC9vX+wNCvPKmsAtFtjk9qaLb8nDoqxlGKKCsj9TuUNbXr9/KnmvX11uU9TvX7FSfa0sje66GsPrd8nByg0kpQvjr1PfIYSXvXdXq1ClGhJGBFlbB+qD6mM1MOhcubcuWzbxMqNvepKz3N6rroyGrTAPqzAnF5Wo5Fo3w8sHHyJYejLwORjonktapqdzTQvEDALSDr0uK7QAAkEsYmso9KH4AAGE4HLJYkWo7AADkEoamcg+KHwAgvaWL8nDkCwDQF4emcg+KHwCAnDBTmzTyUAACADTGqafcy9gdrVmzRowePVoMHjxYHHrooWLFihVJ+0SjUTFt2jSx//77i4MOOkgcf/zxYu3atRlpLwD5jMPlEg53iuLCOBEAkD84NJV7GbujKVOmiMmTJ4uJEyeK+fPny/+XLFnSYp8XX3xRvPfee+Kzzz4Tbrdb3HbbbeK6664Tf//73zPVbADy2MnZOrrNcKoXmQe5gxFRR3FG63cp65u3qeuJug3qqNOaTeqo002KtaXj52Kiet3MOtqVQf5d7MPUe0vVmQBKd9Sy5/I2qu/FYarba5HYQDQwba5hopB37fLbityV27ZsVNb7a7cp66Nh9brrhLtIvWZ9JKjOYOFy8/NIm8vU0bu1AfX1w1Yd2Y4Ymsq9jCh+NTU1YunSpWLRokXy87hx48TUqVPlbN7Agf9NhWEYhggEAsLv9wuXyyXq6upEr169bF+vfPQPRGlRYVK94VKn6jAK+JQghled5sQs4NOfRD3qsHjTk9ymGA5G4BVafLm6FaofZ5HFdfowX8imEP+y+xkh3Ra8FulpCi0Wz+aOs0p3w/Ud19dWzyha2IU9xrGP+r0q6NqDv45fnerCG/DzxyiEtlOmbZgt7KJrdFsmLB0TJkwQ27dvF2VlZeLxxx8Xw4YNS7J0/M///I9YuHChlHtdu3YVDz/8cAvZCADYewxN5V5G7mjDhg2iurpaCrWYgtenTx+xfv36FvudddZZ4rjjjhM9evSQ+7/++uvilltuYc9LSiIph4kFAJAah8ORVgHtY+lYvXq1mD59urR0tCbR0vH555+LE088UVo6AADti0NTuZfVd0SzgsuXLxebNm0S33//vRSAl112Gbv/rFmz5Cg6Vnr37t2p7QUg10e+qQrYe0vH+PHj45YOGgS39ltOtHSYptlmSwcAwBpDU7mXEVMvKWSbN28W4XBYzvqRcKPZPpr1S2TevHnihBNOEOXl5fIzmUhOOeUU9rwzZ86UwSAxSGBC+QMgNbqaPLLF0pFoxiVLx5tvviktHSUlJaJnz57i7bffZs9LSiKVGLB0AJAehqZyLyN3VFVVJUaMGCGeeOIJ+XnBggVyRNvah6V///7ijTfeEMHgHofkl156SRxwwAHseQsKCkRpaWmLAgDIbHTbAw88IPr16ye8Xq84/PDDxUcffcTuS9H9NBNG+5NidO+992r3+GDpACC35d4DWS7zMhbVO3v2bOnfcscdd0gFbe7cubJ+0qRJYsyYMbJcccUVYtWqVeLggw+WUb00An7ooYcy1WQA8paOGvk+88wzchaevrckAEmonXrqqeKrr76SA8DWNDU1yQHfueeeK371q1+JfCIbLB2qgCBu3Wci1MgHF/l3q7ftDKqDv7YGwrbX6nVaBF5xVDSo76WMiZ61ukcRZtayNdVRp/RMOULMWrYNTL8E/CFb6+5aRe8271KvuWxG+SC+cLBZWe/yqNfq9TeV2V7fvZmJdA510lq9RgfIvVyQeRlT/IYMGSIWL16cVP/II4+0mMGjaDYAQG5msL/nnnvEpZdeKi6++GL5mYThyy+/LB577DExY8aMpP0ppycVQrU9l0m0dNCg18rS8corr8jIXo/Hk5algwoAIPNy754ckHn5l5lQgTnwcGGWliTXG/Z/yNhjrM7lUKclsbq+Q6hHPEUW6Vx8LvXoOGLyaVGsRqgc7ZliyWF/QC+hKXEVTovzcWlbuL4mTJf6BzVa3I09JhplUr0wub8Iw2Ib37jkY8w6dd6xVBgOI401Kw2lDxmneJCLxscffyxnpGJQhNxJJ52kHPTpACwdAGQPRjvLvVyReVoofgCA9jN5tDYj3njjjeKmm25K2p9y1UUiEdG9e/cW9fT5yy+/1PKRwNIBQP7Kve05IvOg+AEAbAlAik5NDJyCmREAkIsYmso9KH4AAOFwuYXTrV5xJIbjPw746UbMd+vWTTidTrF1a0vHcvpMgVoAAJBPcq9bjsg8KH4AgA6JbqPAhJEjR8oVd84+++z4cmT0mZZoBNmPaRFdGWW2BRknYKtATX6bekPIwjeZuz53LyYTbdtZRLj2MvXREBNpbLH2Lhe9axXVa0bU2yJMpDPX3lTb8knueXJE5kHxAwB0WDoXSmtA6UhGjRolDjvsMJnaoLGxMR7xdtFFF8kExbTqTsw5euXKlfG/adWeTz/9VBQXF2OtWgBA1su9aTkg87RQ/L4LFYjioDep3iGYyFCL5+xiwlDdFuGpHuY6BRYhqC4mytMZDvDHBNX5nYyIehS4Z1vQVr0kyoyQrSKEuXxcFhFVptNje5vp5KftTU+hrchdIszkOA9E+WcXjKiPCVmMesPcLInFZERUMRvSYDEbYAVFtqWObrOv+J133nli27Zt4re//a3YsmWLGD58uFi4cGHc+Zny2CWuhUlLMx5yyCHxz3fddZcsxx57rHjrrbdsXx8AADpT7p2XAzJPC8UPAJC5pYvIxMGZOVoLNspe35YUQwAAkC1yb2qWyzwofgAA4XA55fJEVjhC/MoLAACQazg0lXtQ/AAAwnA4ZbEi1XYAAMglDE3lHhQ/AMCe1WVSCbg8FIAAAI1x6Cn3oPgBAPYE2aRyYm5DcAfILjhHdYdH/VPg9PLBUm6v+phiZunIYpf994eLfyu1OBd3HZePu0dPp/zoc0tG+tzqa7i4el8xew13kTrPXDjYbCtlizwXcx23t9hWe4kCj3qbh3lWbXQnto9DT7kHxQ8AIAynUxYrUm0HAIBcwtBU7mmh+H2woVb4ipPzYrgZTb7QzWv4ZcwIuFshPzIuLVC/OGVM/Z62qfN4OJpr2WMcTbuU9ebuGvaYSO0O9TFNLRekbrEt6Lc9euS+PIYnOc1OfFshnyXdWdZVWe8or2KPiRZ2UdcXd2OP4dK21Ab4e61jtm1v4tPq1PrV25pCfD6XkCKtTnNDvWgTmpo8AAAa49BT7mmh+AEArDFcLmG4rJcuMlz5F90GANAXQ1O5B8UPAEBTsqlHtrQPAADkC4aecg+KHwBAW5MHAEBjHHrKPSh+AIAOW7INZBnMkoYOr3o5w4IuJeypiroXKet77FL7AFvREFavXOBhlsKs8PDvYkkPdbsKu/rU1yhV3zthFDA+yEyErsEtTSmE8DIRrOWMf7ivWB1tXFyuvg8iEuyprHd51MdEwvwSj1z0bmHXPUuPtaaolF/6sitzL0VMJLDTYgnU9sTQVO5B8QMAaDvyBQBojENPuaeF4vfvFVuF29eQVF/CROhWFPF5nfp2U48Oe5Xy0akDKtTH+CzzWqkjQx3B5PuIEa1Zr6wPbVzLHtO8eau6fttu9phgXaP6+hZL23DL4nhK1aNzwldZzm+rVo863b0G8m3YR/28o1F1tC8RjDhsRe4SX+9sUtZvrONnQr7brj5mZyM/Iq9XRAKHmtXPJhWG2y0MtyfFPvnn5AwA0BdDU7mnheIHAEiBpolMAQAa49BT7kHxAwBoa/IAAGiMQ0+5B8UPAKDtYuUAAH0xNJV7UPwAACTdUps0aB+Q05hOtT+To0Tt51rUo4I9V/m+9laJ8W3l/U9DfrUflYNZrNdbzvtUl/ZWr/hT2ke9qo+vkvfxdTCrB0UdzLq/Fl+RYmY95B7MvfStUkfVRiP8aj4uZtUpf1OZst6MmhbnctqK3u1axftr9+qi9nMvZfzs3Z0U1Ss0lXtQ/AAA2o58AQD6Ymgq96D4AQCEcLloiJ9CWkBcAADyCJeeci//7kjBN2t3CmdBcioNj89lOxElm16jL596pIxLG8NcX+JQT+cbAd5cEt62SVnfsG4De8yu1ept9Rtr2WOadjQr6yNBPsWJ0+O0lVSVKOmlNk8QXfzq51BSwJ+voGsP9QaTN52EGFPI9qbkVCqp0rZ88h2fIufbrWqzWWNdgD0m2JxsHosE1GlhUmE4nbKk2gcAAPIFQ1O5p4XiBwBIgabRbQAAjXHoKfeg+AEAtBWAAACNcegp9zIWrrJmzRoxevRoMXjwYHHooYeKFStWKPf74osvxHHHHSeGDh0qy3PPPdfpbQUg34mtWZmqAABAvmBoKvcyNuM3ZcoUMXnyZDFx4kQxf/58+f+SJUta7NPU1CTGjh0r5s2bJ44++mgRiUTEzp07M9VkAPIXI42RL+0D9nrAO2HCBLF9+3ZRVlYmHn/8cTFs2DDlgPfKK68UW7fuWVLx9ttvF+ecc85e977pUfvAuhj/16I+u2xfo6BLibI+sItP/xJRLD9IGEw6F3cRn86FS89S0ke9zKOrsid7LkepOp1N1MmkczH4NCTljE93dbHap3xYT3UqGR/jL01sLlP3SwOTLscqnUsBc52uxR5bKVuIAZXqVC/dmeVRC5jn3u4Yesq9jKiyNTU1YunSpWL8+PHy87hx48SGDRvE2rUt15R96qmnxBFHHCGVPsLpdIrKyspMNBkADUwerhQl/wRgpga8q1evFtOnT5cD3tbEBry33XabWLVqlVi+fLk45phjMtJeAPIah55yLyMzfqTkVVdXC9d/wqQNwxB9+vQR69evFwMHDozvt3LlSlFQUCDOPPNMsXHjRnHQQQeJu+++m1X+AoGALDHq6urk/zs2bBIOd/JI112kjhr1V6gTZ1pRwYxciF6l6lFYOMqPWg0m0tT081G9kdodyvr6DXtmDVTsXKs+ZucafqS/s1k9Om+O8KNHHzOCq/i+wXZSV8LlU/d3YXVX9hiu77i+JsLMiLiWmaEgvtveZCtyl9ixWd0P9Tst+qcxOfI6GlJHXKfCNByypNoH7P2Ad9GiRfEB79SpU+WAN1Hu2R3wcnIPAGCNqancy+o7CofD4rXXXhOzZ88Wn3zyiejZs6e4/PLL2f1nzZolzSex0rt3705tLwA5Cwm3dArokAFvIokD3uHDh4uLLrpIbNu2jT0v5B4AbcTQU+5l5I5IIdu8ebNU7AjTNKXwIyGYCH0+/vjjpcJHQpJMwx988AF73pkzZ4ra2tp4IUELAEgD8k1Kp4CsG/BC7gHQRgw95V5GFL+qqioxYsQI8cQTT8jPCxYsEL169Wph7iB+8pOfyICPmOnilVdeEQcffDB7Xholl5aWtigAgDSgyLV0Csi6AS/kHgBtxKGn3MtYVC+NZsmx+Y477pAK2ty5c2X9pEmTxJgxY2QhAXjdddfJtC8Oh0MKwjlz5mSqyQDkLabDJUuqfUD7DHhJ9lkNeB999FE54CXZmGrAawdT4etMOCqqlfW857IQjpIutiKBo35+VZlokPfnVeH0emy3y1mm9v91WkT1Rr3qCGXTqb6+20JHKGI29itXR8MWuNRBBT1KeN/w2gDjf22xqhKHx6Vub5Fb3a5SZoUqq+jdSqbey1y7vTE1lXsZu6MhQ4aIxYsXJ9U/8sgjLT7/7Gc/kwUA0IGk48uSh74unQ0GvABkEYaeci//VFkAgH00FYCdDQa8AGQRhp5yTwvFr2HLOmG4kpNkehiTgBD7sufyFqmns3c2BtljmkLqdCERPosIixnws9u4BKlNNXx6h7qN6mM2NfD38z2TZqXZ4oZ8ToftFDAupm1Ecfci20livRZ9x8HdEvdMrd6Fxrr/ptxIN21Lw9Z17DHB+mSTmhnmr2GFaRhppDXIPydnAIC+mJrKPS0UPwBACjQd+QIANMbQU+5B8QMApJe2IA9HvgAAjTH0lHtQ/AAA2ka36Ua0wN6qREaB2qWCcHdVR8MaEcZNJMKvdmNG7fm9GC4+gpSLuDXd6jVxoy4+Stbk7t+pvr7LQkkoYda+dTnUx5R51fsHLdxjuJWGQhbHcDDeOcLJtNfN1FutvctF7/pc/LkM00yrLh1MTeVe/t0RAMA+Rhr5qvLQ5AEA0BhDT7kHxQ8AoK2vCwBAYww95Z4Wil+gYZcwmOl/FaHiCnZbsFmd0LPez5sxQowZIyospqdN9TFmmL9OxK82sYSb+eSooQb1+XZaJPzktgUZM4NV9K7XwjywD9M2q3vi+sCy75i+tnpG3DO1eheCVs+hsTbtyN0YgfqdSXUmZ2ZLhaYCEACgMYaeck8LxQ8AkAJNBSAAQGMMPeVe/t0RAKDN+aysS9ui2x544AHRr18/4fV6xeGHHy4++ugjy/2fffZZsd9++8n9DzzwQLlkGQAA5JLcy2ag+AEAhHA40ys2eeaZZ8S0adPEjTfeKJYtWybXnD311FNFTU2Ncv/3339fXHDBBeKSSy4Rn3zyiTj77LNlWb58OZ4SACAn5N4DWT7YhakXANBhJo977rlHXHrppeLiiy+Wnx966CHx8ssvi8cee0zMmDEjaf/77rtPnHbaaeLaa6+Vn2+99Vbx6quvij/96U/yWLB3mG6fsj7C1IP2+0Etcatnjkrc9hULkL1y75n/DHZJXpHSd++998rB7ldffSWqqqrYwe6sWbPEmWeeKZ566ik52KWB8gEHHCA6AtuSfNiwYVKYcyN2AEDukdrcsacQdXV1LUogoF4mLhgMio8//licdNJJ8TqHwyE/L168WHkM1SfuT5DQ5PbvLCD3ANBb7rVlsLv//vtLBbCwsFAOdlUkDnaHDh0qB7sjRoyQg92Owrbid8MNN4hFixbJaUzSSl944QURifARoACAHBr5pipCiN69e4uysrJ4oZGqiu3bt0vZ0L179xb19HnLli3KY6jezv6dBeQeAHrLvbo0Bry5Mti1rfidf/75YuHChWLNmjVyGpPMNT179pTa6sqVKzumlQCATnByTl2IDRs2iNra2niZOXNm3j8dyD0A9JZ7vdMY8ObKYLfNwR2k7JHAp2nM6upqOb1JiuCxxx4rPv300/ZtJQCgQ4lEzbQKUVpa2qIUFKiXwurWrZtwOp1i69atLerpc48ePZTHUL2d/TsbyD0A9JR7G/JowNsmxe+7774Tt9xyixg4cKCYMGGCGDt2rPjmm2+k39/pp58uxo0b1/4tBQB0GGaaxQ4ej0eMHDlSvP766/G6aDQqPx955JHKY6g+cX+Cgju4/TsTyD0A9JV7pWkMeHNlsGs7qvf444+XocljxowRDz74oDj55JOFkZDnZvr06eL2229v73YCADoQGtRaLLwS38cuFN1Gg8NRo0aJww47TEa4NTY2xqN8L7roIjmLFjOb/PKXv5RWg7vvvlucccYZ4umnnxZLly4Vc+bMEZkkX+Sen1lBpzmsrveH+RVqAsy5QsyLEps5UW8TtnA7+dxqLmY1II/TXj3hc6nnRnwu9TFuk1+dxwg2qusDTH3Yr64PqYOp5DZm5R6rFZ/Yc3Fr2Drd6mtYrI5leny2osyjBcX8udoxAj3aznIvcbBLMRCJg92pU6daDnavvvrqThvs2lb8fvSjH4kFCxaIigp+WbPdu3fvbbsAAJ2IaZqypNrHLuedd57Ytm2b+O1vfyt9VoYPHy59hGM+LevXr5fOzzFGjx4t0xlcf/314rrrrhODBg0S//jHPzosrUG6QO4BkH+YHSD3cmGwa1vxu+qqq1LukyjIAQD6zvgRNNLlRrtvvfVWUt25554rSzYBuQdA/hHtALmXC4NdLRI4FxR3EYYr2R7vKemi3N9dVMaey+NTd1mJVz39Lc/HKMIOYbEUDJM7yHDx13F61VPtLqbNsm3F6vNVNPOmAT/zTWi2sNf4nOr7qfA4bbfN6p64PrDqO6s8Tdwz4p6p1bvAvTtW7xz3jnKY4YCwb9T5z7FtPA4AAHIVswPOme2DXS0UPwCANYnRa1b7AABAvhDRVO5B8QMACJqrTeVfb9P/HgAAspqopnIPih8AQJD/ciof5jbEdoAsg4ve3eVXr760rVEdJUpsZbbV+dXOBo0hfoWnoEX0sAqfhYtIWYHa1aKLT11fXazOQ7nnGPV13A6mPso7WjiadinrjfrtyvrItk3q+tod7DWi9eprRPz8c+RweNTqgcNbqK63cEtxdVWnJnFUVNtuV3uuK21qKveg+AEAOjS4AwAAspGopnIPih8AoMPSuQAAQLZiair3oPgBALT1dQEA6EtUU7mnheJX3GNf4VD4BXApNEoq+KzhRaVqf5CKIj6NSKFbnfqDyXBiiVHgZbcVdClRX7+qlD2mtJc6a3zPZj4DvY/JdN/MZPK3OqaC8bvZ0zb1/VjdE9cHqfqOg3tG3DO1ehe4d4fws+/cvuwxoeLkJOrRULNoEPaJmGlEt+XhyBcAoC8RTeWeFoofAMCadNbizT/xBwDQGVNTuZexJTbWrFkjM1YPHjxYHHrooWLFihWWNvYTTjhBlJeXd2obAdDNyTlVAXsH5B4A2UNUU7mXsRm/KVOmiMmTJ4uJEyeK+fPny/+XLFmi3PcPf/iDGDBggFi2bFmntxMALUgjrUFeDn01k3t+Jm0Kl7ZlzQ61Kwjx9Tb1to27mpT1Oxr4lCKBoDrVi+FQu4gUe/mfrupydbqP/pVF6muH+TQzHpf6mBImnUxhhL9Hh79eWR/auFbdrg3rlPX167ey12jepk7nEmr0K+tNC/ccJ7MCEedOU9Qj2fUkvq2Pul2cg5RRoO73dsfUU+5lZMavpqZGLkI8fvx4+XncuHFiw4YNYu3a5C8AzQTSunUzZszIQEsB0IOoMNMqIPvkXiAQEHV1dS0KACA1UU3lXkYUPxJ21dXVwuXaM2ozDEP06dNHLl6cSCgUEpdeeqmYPXu2cDr5hJ0xIAABaBu0zHI6BWSf3Js1a5YoKyuLl969e+MxAZAGEU3lXlYHd9x8883inHPOEUOHDhXffvttWgKQjmlN1949hbMgOdu4x+eyHX3Zr7t6mrtvN3U2c6KMmTJ3MWYMwjTUOrnh5afAnWVdlfUlvbuzx4Sb1aYJt4UppWRHs7I+wphrZNs400hXPgt7Sa8yfhtzT1wfWPUd19dWz4h7plbvwk6LVRA4vEX8dYLNye9iJNAktti+ir4Z7PNB7s2cOVNMmzYt/plm/KD8AZAaU1O5l5EZPxJKmzdvFuFwOB68QaNeGv0m8vbbb4v7779f9OvXTxx99NFSoNHf27ZtYwVgbW1tvNAIGwCQGl1NHvkg9woKCkRpaWmLAgBITVRTuZeRGb+qqioxYsQI8cQTT0jn5gULFohevXqJgQMHttjvnXfeif9NI9/hw4dbjoBJAFIBANhD15FvPsg9AEDbMDWVexkz9ZL/Cgm/O+64Q45Q586dK+snTZokxowZIwsAoHOImqYsqfYBuS33AkwU51bGDYGL3CU+27BbWb+jRn1MY12APVc4ZC+q11vIu0DsqlBHsDYzrig+xg2FqCpSTyRUFjI/nRE+8X20bqeyPrxtk7J+92q1xWrX17wzR90GdWCPf7e6T6IWUb2cu09Rd7XLTPm+6qhlKxwlXdTX7tpTdAZRTeVexhS/IUOGiMWLFyfVP/LII8r9ydSxe7da0AAA9o50nJjz0cm5s4HcAyB7iGgq97I6uAMA0DmEo1ERikZT7gMAAPlCWFO5B8UPAPCfDPWpTB7oKABA/hDVVO5pofj1H1gh3L5kv4QSJiVHRZHHdqqOXqVe9phujD+K2yKdi2BSjJgWGc1dlWq/iOKAOv0K4fSq77WomjerB+vUPjzREO/f4nCrXzVPKX8/vkp+iT5fdXdbfWDZdxbpXLhnxD1Ty3ehL38/3DtnlQKm3h9Kqgs1ewW/+CGPriYPAIC+RDSVe1oofgAAa3R1cgYA6EtUU7kHxQ8AICKmKYsVqbaD7CfE2K3qFLPHVuvuWkXv7tiiju5s2sGvMRvyNyjrnS71TLinhF8XNhxSb3M41TP7vbrwSeQHdCm0NQtkRC2iepvqbK2vW7e+Rlm/c406Opio2aTu+51BdYODFnbMYpfa2tFjlzpC2Ap2fV9mDV/DYs3j9iSiqdyD4gcAENE0fFny0OIBANCYqKZyD4ofAECEI1ERSuHMQvsAAEC+ENZU7kHxAwAIyuNqkctVkmo7AADkEhFN5Z4Wit+pw7oLX3Gyj4Hbofb5KHTzUZ5lTCSwVZRnaYE6M7zHaRHV61AfE/UU84dU9VFfx8NHHDu7Vivrixh/FMIMqn08zIg6Mz5hONX3Y1i0zSjk1xx1lnVVH1NexR7D9h3T14RHGLaeKTGgotDWu2MVCdwU4kebqvxTzQ314p/CPro6OQMA9CWqqdzTQvEDAFgTiZqypNoHAADyhYimcg+KHwBA25GvbnA/Yo3MWrk7GvjoSm7tXS56t3Gbeu1ZItTcYMtS4Ata5Cb1qKN0i0rV6+7ublJHNBP+sHrG3eS+CxbfETOgtpQE69SR00071PdYv4VfP3lTszqqeGsgbNuMWeziLV8qfFv5dgV2qaONo34majzCP5P2JKqp3IPiBwCQaT64VB8xUm0HAIBcIqSp3IPiBwAQ0agpixWptgMAQC4R1VTuQfEDAMhcVqmi1/JQ/gEANCaqqdyD4gcA0NbXBQCgL1FN5Z4Wit8RvctEcUlyahAHk6qDWdlH4nKoj3Ez9VZpWwos0rmYQt2IqK+MP8apThdiFHZhj3F2D9pfMkeRRmRPAyy+IAZzr0xKHXk6p8f2tijTB/IYjzrNimnwbeCeUZlFOhcf4xRd4eO/buGoOp2LVe7QqEju74Z6ew7Zui9dBADQl4imck8LxQ8AYI2uvi4AAH2Jair3oPgBAETINIUrVXRbHo58dYObQQ4yaUsCQT4pe5hJARPyN9hK2SLPxRxjMMnVQ0zKFnku5jrhUHISf6KZuY92N/NF1deJ+NXWlTCTmqWBeVZEHbONO6Ytq1I0hNUHhfzq9srr+NXpWaJB9TEmZ1VqZ0Kayj0ofgAAbU0eAAB9iWgq96D4AQCkOSOiockDAKAvUU3lHhQ/AIC2SxcBAPQloqnc00Lx6+sOiFKPYrkci2hODjYC1OpcjJ8KF7lrdb6IWx2ZSkRdPtt+HOzSQxa05/fAIhjaEoOJErYIlBYO5hiHIjo2hstU+5q4HVY+KIzPkMUxBnMdSxTH1LnVy2ilQlcBCADQl4imcq9tuR8AAHnn9B8TgnzpuOvv3LlTXHjhhaK0tFSUl5eLSy65RDQ08MEAxJw5c8Rxxx0nj6GBwO7duzuugQCAvCOiqdzTYsYPAGANRXU6LKIFY/t0FCT8Nm/eLF599VURCoXExRdfLCZPniyeeuop9pimpiZx2mmnyTJz5swOa5vOGBZT8tw2p0udY9Nw8rkvuehdrt7h4vN1Otwee+1tq9mhnTCYxLEGY77wWLTXzVpCuGP42SzOesJd32FhbuHuJdMENZV7UPwAABl1cl61apVYuHChWLJkiRg1apSsu//++8Xpp58u7rrrLrHPPvsoj7v66qvl/2+99VaHtAsAkN9ENZV7MPUCAPakNUhl8viPP2hdXV2LEgi0za8wxuLFi6WZIyb8iJNOOkk4HA7x4Ycf4ukAADqEiKZyD4ofACANP5f/jox79+4tysrK4mXWrFl71YNbtmwRVVVVLepcLpeoqKiQ2wAAoCOIaCr3oPgBAGwJwA0bNoja2tp44fxMZsyYIZ2PrcqXX36pVe+vWbNGjB49WgwePFgceuihYsWKFUn7vPHGG+Kwww4T+++/vxg2bJj49a9/LaKdtJIBADoR0VTuaeHjZ6z9UBhFyWlQDMZB2Cjw8ufyFinrzQJ1PRH1FKvrfWXsMVzalsYQ/wPQxGxrtnBO9TPbmiyWMeKOaQteFz/2KHQ7bR/nszyfelsRU084w+rpfEdzLXuMI8gsPxVoZI8x/eptZkCRhii2LZy8DJLR2CTaQoCeaYrnKvcRQkaTUUnFNddcIyZOnGi5T//+/UWPHj1ETU1Ni/pwOCwj3mhbPjFlyhTpvE39Mn/+fPk/+fgk0qVLF/H000/LvvH7/dL8M2/evJR9CQCwR0BTuefK5Mh3woQJYvv27XLa9PHHH5ej29YjX9KeKbyZtOQzzjhD3HnnndIGDgDIbifnyspKWVJx5JFHypQEH3/8sRg5cmT8u0+zXIcffrjIF0jIL126VCxatEh+HjdunJg6dapYu3atGDhwYHy/Qw45JP631+sVw4cPF99++227tMHNRFf6POpBVrGX/4nwFqoHzp6SCvU1gs3subi1d7noXW8Z/155FYN8osCrPldxAX+Pbi7ilouSZaNn6ddWHW3sLlJPNHhLC5T1xcXq8xCVFmsr212HtpQZRFd41PXecn7ChLtHp5eJwLaI2m5PoprKPUemR76rV68W06dPV2rIsZHvypUrZee8//77cuQLAOiYNStTlY5g6NChMjXBpZdeKj766CPx3nvvSYXo/PPPj0e2bdq0Sey3335yewzyg/n000+l4kR88cUX8jONmLMRMhVVV1dLP56Y8tCnTx+xfv169hi6R5oZPPPMM9l9yMm8teM5ACA1EU3lniOTI9/x48fHR74kFGM3kjjypSnRjhj5AgDa5uvSETz55JNSwJ144okyncHRRx8tE5XGoBxXX331lcxhFeOhhx6SMoIEJ/GDH/xAfn7xxRfz4tGSAnfWWWdJH7/EyL/WkJN5otM5OaEDAFIT0VTuubJt5Jto8lCNfF966SXLkW9iiDVGvgDkxtJFFMlmlbS0X79+ScsL3nTTTbLkCqSQUbJW8uMh2Uf3QzKPZF9r6uvr5WzA2LFjxbRp0yzPS07mifuQ3IPyB0BqIprKvZxwlsPIF4D8HvnqAKVuGDFihHjiiSfk5wULFohevXolDXbJpzmWmf/6669Ped6CgoK443m6DugAAKGt3HNkeuRLtOfINzHcmmYWAQCpCUUiIhi2LrQP2Dtmz54tC6VzoUC1uXPnyvpJkybFTTX33Xef9Ol57rnnpHsLldtvvx1dD0A7E9JU7rkyPfKloI72HPlSac3u9/9PRLwFaUcUFXQpYa/hLOuqrHdV9mSPcVQlK7SE6eQjl6Iun62ULcT2pj2KdGs21fMpQWoa1OlKtjcG2WMa/OrrWI2MuPUwraIGuxXx0WtVxeqIt54lfGRZt0L1tXwuPhLPFVSnR3E07WKPidaonfXD2zaxx0RqdyjrA7vq+WP8yc+o3t+2bPL07BwZNHnowpAhQ2TG/tY88sgj8b9/85vfyAIA6Fgimsq9jKVzoVEvKX133HGHNE0kjnzHjBkjS2zk29jYKEe/xLnnnguhCEA7Q6mqjBQCrgPXKgedhIsZgJUVqAeh1eXqASixq0I9oAyH1OlcnEzKFnlMszr3pcPtsZWyhSjtpt7WpYt6UFjFpE0hipk0N0w3CmHwRjRHkXpCwdtVnc+1uFptsvfX8YM79RSDEBUN6oF80OI7X8ykcynpoc5ZW9qbdzHwVXZR1jtK1PWmkx/0tydhTeVexhQ/jHwByB50HfkCAPQloqnc02LlDgCANboKQACAvkQ0lXtQ/AAAIhSOCjOFTSOcjzYPAIC2hDSVe1D8AAByVGtoOPIFAOhLRFO5p4Xi9/3i1aLYnXyrLp/69gureCfVkt7dlfXFAX4dSo9H7VRsFKodW4kI8641W4w+uOjdr7apHaeJNVvV277b3sge428OKesjYYuoXiZy1uvjI5v7dlM7ERODuhcLuxR51E7fEVPtwE0YEfW9mrtbLq6dSGhjyxVoYjSs49ML1W/YqqxvquGX3wo3J0dXN4TUEdepoJRKZgoB1zqRKAAA5DKmpnJPC8UPACBSLkQebefFykH24XGqB2BdmAFY/0p+8NUcVOc3czjV0aBFFtGz4ZA64tVgwmcLvPyAkYveHcpEyVaX8imgSjzqn0imG4Xp5H9SnUXq63sqq5T1ZQP4VE4cXqaPy5hIYJObYbCaGOmqjs4u7aO+D6KkT3db6dFMN/+utCdRTeUeFD8AwJ6Rr6nfyBcAoC+mpnIPih8AQJo7Upo88nDkCwDQF1NTuQfFDwAg/TMNCx/NVD6cAACQa0Q0lXtQ/AAA2po8AAD6Ymoq96D4AQC0dXIGAOhLVFO5p4Xit/njLaLQkZyyw12sjgwr7cWnMgk3q9c8dHr5tQWdXavV9d3V57IaZfgt0rnUNARspWwhvtqwW1m/e1sTe0xTvfo60QjfNi7Sr7CkwHbaGCu46ESiT5nX9ojOiKifUaR2B3tM82Z1apZdq/l0LjvXqs9Xt5GP7As1JPdPU1QdaZkKXX1ddIOL6q0uVn8PA2H+ffIx69j26qKO+tzdxH+fm0Pq6ziZqN7iAv6ni1t7l4ve7WkV1VvgtNUuYVr8pBaWK6td3dUr7KrjnIUo6MJtEaJ0R62yPtSoTvVlWshs7jfNU1poaz1ewlXZU30Npj7q4p9Je2JqKve0UPwAAClIQwDSPgAAkDdE9ZR7UPwAACJqmsJI4ctC+wAAQL4Q1VTuQfEDAEgzvZFiTUorUz4AAOQaUU3lHhQ/AICIRkXKNStpHwAAyBeimso9KH4AAG3TGgAA9MXUVO5pofitrAsIr5EcVVrBRI32bOYXund71V1WVK2OjpXbmupsRYxa0cREvxHbG9Xn+247H6XMRe/u2mIRtbpri7I+Emhmj3EWqCP9Al16iLbwXRvWFrXqOw7uGZnMMyWat6nfhfqN6og7YueaXcr6TQ38O7JTsVaq32zb8JQOS3VoG08NAABZiamp3NNC8QMAiJS5qlKbPPJv5KsbPpc6rVIXnzpticfFD6SqitRpUwZ0KbSdisquA72bSQ9FFDNpZko8LlspW+S53OrruJh0Lqbg03pFfWXKekf3fsp6TwmT/qWaH3R6G5n0T2H7kwxCkQKNMArUqVYchaX8qUorlPVRrzo1jVnAv3ftSVRTuQfFDwAgouGoMJwpnJxTOEEDAEAuEdVU7kHxAwBom9YAAKAvUU3lHhQ/AIC2GewBAPpiair3oPgBAPZEt6USgHk48gUA6IupqdyD4gcAkMIvquHIFwCgL6amck8LxW+LPyw8inQufuaB+piFzImSHeqUJcE6PmWKGfTbzgzJvWtWkXENfnUaGj+TtoZoqg/YStkij9nxvbI+GuIjxxxuPtqNo6ComN3G3RPXB1Z9Z/m9Zp4R+0wt3oUm5t0hdjL3873F/ajSuQTbms5F03xWuuFzqWWbm4ngLGEiZInKQvXPB7fQQXu+P4bBy2gm4FZwYt3JHWARvevmonoNdZopIlrYxV4Ea2mVstqI8DLBwX3/2/O7y/R91MGrE1GnepvpZH4XnHw/tiempnJPC8UPAGBNJBwVpkO/6DYAgL5ENJV7UPwAAMKMRmSxItV2AADIJUxN5R6fBRMAoJ0ATFXA3rFmzRoxevRoMXjwYHHooYeKFStWKPd79NFHxaBBg8SAAQPEpZdeKkIh3l0DANA2TE3lHhQ/AIAwo9E0BGD+mTw6mylTpojJkyeL1atXi+nTp4uJEycm7bNu3Tpxww03iHfeeUesXbtWbN26VcyZMycj7QUgnzE1lXsw9QIAhBmJyGJFqu3AmpqaGrF06VKxaNEi+XncuHFi6tSpUrkbOHBgfL/58+eLMWPGiB499qxjfdlll4k77rhDXHHFFcrzBgIBWWLU1u5ZE7q+Pnn5rjDjpx5mIpys3JsijNN7PgV3OG0GdzhM/jtiREK26kVUHcRhMPWSDAZ3mBbBHYLZZnJBHBbBHarrxN51u++Yqancc2XS5DFhwgSxfft2UVZWJh5//HExbNgwpcnjzjvvFNFoVJxwwgniwQcfFG63vYifIL0MiheimZFQzRH+5YkoIimJaChs/8Vp52ihCCO8I5y0p3YzfRAJ8BGoXPRuJMgfw2F5He4XxOKeuD5oM8wzshIG3LvAvTtW7xz3jhJBxb0GRdvu3zTT8HWx+FEDqdmwYYOorq4WLpcrrrz06dNHrF+/voXiR5/79u0b/9yvXz9ZxzFr1ixx8803J9UPHDQIjwVoBSmApE+ki6mp3HNl2uRBpg4a4dL/S5YsUZo8li1bJrp37y7Gjh0rTR7cyBcA0DaitIi74Uy9D8g6Zs6cKaZNmxb/TIPknTt3iq5du8ofwt69e0uls7S0VOQCdXV1OddmAu3OXH+XlJTId32fffaxdY6opnLPlc8mD3oxAACp0TW6rTOhH6nNmzeLcDgsZ/3ILEUzeTTrlwh9/vrrr+Ofv/3226R9EikoKJAlkfLy8hYmUVKgckmJytU2E2h3Zvrbzkyf7nLPkW0mj0TaYvKghx8rJGgBAKnR1cm5M6mqqhIjRowQTzzxhPy8YMEC0atXrxaD3dhA+MUXXxRbtmyRyuFDDz0kzj///Ay1GoD8xdRU7jnyzeRBjs2xQgomACA10WgkrQL2jtmzZ8tC6VzId3nu3LmyftKkSVLZI/r37y999o466iipFFZWVkrXGABA+xLVVO658t3kAQDIfpMH+aRdeeWV4p///KdwOBxy1uu+++4TxcXF7P433nijdBch2UHK0dlnny1uvfXWNpl8OoshQ4aIxYsXJ9U/8sgjLT5T7j4qewvJQ+qnXJKLudhmAu3Ovf42NTX1ujJt8qCgDiuTx9FHHy1uuukmGdxh1+QRC+0OCvVUbYAJgGy2iOJpZKI564N8gtW6JvW6rgX1DfwxbrV/YmN9E3tMoEl9vrCfX0c4GlSfzwzza9GakaCt+j3bnLavw7WNCPsLbPUB0VjvVdbX+SxSMDDPKMA8U6t3gXt3rN65gMXau6r3OlZnO61BiI50pNyno7jwwgvlYPDVV1+VyYovvvhiGfz11FNPKff//vvvZbnrrrvE/vvvL7777jvpA0x15BsM9kA/iiQ/c4lcbDOBdudef5sZlnuZGvAaZoZWIP7qq6+k0rdjxw7pmEkmjwMPPFCaPCiggwrx8MMPS5MIcdxxx0nlL910Lt98843MfA+AbtBMOZkMU0EBUCQwyk+cKQyXWjFOVNJ3vz5LulG0p9P9qlWrpPJGUf2jRo2SdQsXLhSnn3662LhxY9qRes8++6wYP368aGxsjPsPAwBANso94oc//KEc8JL7R2zASyv6cAPe5cuXS8WPdKfEAe9BBx1ka8CbMcWvM9i9e7fo0qWL1IyzyfyTrWH/aFfu9xcJJ3KH2LVrVzyyMx0BWHb8dGG4rE0mZjggat/836T73VsXi8cee0xcc801ss0xyA3E6/VKZe5HP/pRWuchcyn5+W7btq3NbQEA5D91bZB7+TTgzethMU2dEvSAs+WHORfC/tGu3O+v2LufLtKPJU1fl9bR8jQC3RuTC0WvkvtHIiTAKioq5LZ0oETwZO4g8zAAALS33KtrlR5ubwe85OtLg/OY0kecdNJJUnZ/+OGHaQ94YwqpHStHXkX1AgD2Jq1B6kLQjF9i9DzNsqmYMWOGTNVkVb788su9fmQkkM844ww5es5F3zAAQPbLvd69e7dIF0fp4/aGTA54ofgBANLIZfXf6LfYDGescKNeMt+SOcOqkB8iJWinpO6JkKmXHJljyds5KFv/aaedJjP3P//887aXc8xVaMnL0aNHy7Qw5BO0YsUK5X605OWgQYOkrzNFCZMfUTrbMtnuN954Qxx22GFSkadlPH/961/L1UhimR2cTqcYPnx4vCRmfshku9966y3h8/latK25uTlj/Z1Om8m3PrG93bp1E+ecc05G+/qqq66SOXtpYPjpp5+y+7XHu23akHt5NeA18xi/32/eeOON8v9sAu1Cf2XLu1VbW0s+vqbv8MvNwqOutiy0D+1Lx7QnK1eulOddunRpvO7f//63aRiGuWnTJsu2H3HEEeaxxx5rNjY2mjpx/PHHm3PnzpV/P/vss+aoUaOS9vnmm2/M6upqc/PmzWY0GjXPOuss809/+lPKbZlu97Jly8yvv/5a/t3c3GweddRR8WPWrVtnlpWVmZ1NOu1+8803zYMPPlh5fCb6O502t2bYsGHm/PnzM9rXb7/9trlhwwazb9++5ieffKLcZ2/f7doOlHs1NTXmqlWrLEsgEDAfffRRs7y8vMWxoVDIdDqd5nPPPWd5jbq6OvPII480TzzxRPkdsUteK34AAGtiAtA7aorpO+JKy0L7dITiR5x22mnmIYccYn744Yfmu+++aw4aNMi84IIL4ts3btxoDhkyRG6Ptfvwww83DzzwQHPt2rVSyMdKOBzO68e+detWs6SkRP5IEPTj1r17d3PNmjUt9vvd735nTpkyJf755ZdflkpUqm2ZbndrrrjiCjmYyZQykm67rRS/zu7vtvT1Bx98YFZWVprBYDCjil8MK8Vvb9/t2iyQe5kc8MLUCwAQppmGycMiv+Xe8uSTT4r99ttPnHjiiTKqjfJ3zpkzJ76dTDWUAqqpaU9ux2XLlkkH6C+++ELm/6QlIGMl31fsaY8lL+0uh9mZ7U6EfJ0oTcWZZ54Zr6PoRTJdUi7YW265RUQs8mN2drvJFErtovY9+OCD8frO7u+29DWZR3/2s5+1cJfo7L5Ol/Z6t80Myr2hQ4dKNxUyRX/00UfivffeE1OnTpW5imMRvZs2bZJykbbHzLunnHKKfC70vOgzfUeo2Hk2eR3VCwBID+nHYmQugz05NHO5q2LCOzHzFOX0zONMVOA/P3JnnXWW9PGLRT6SMkM/huQUTz6g5513nrj77rvlPpmGlCNKw0GO//Q/DWDIZ+4nP/mJyHZIkXj66afFBx98EK/L5r7OF7n35JNPSmWPBryxBM5//OMfUw54idYLXqxbt07KyXTAjB8AwJaTM8gsiUteElZLXlKCV9WSl1bbMt3uxKCdsWPHimnTpsXrKZAoFglJg4Wf//zn4p133smKdlOgUyxfLK1EdcEFF8Tb1tn9baevY7ngKJCGAgUy2dfp0l7vtplhuRcb8NL7TgEjlNM0cdWO2ICXBrqJA15VSVfpyxvFrz0i3LIxgi2T7YpBL9QJJ5yQVjLgzmoXmffoC0BT5VSee+65jLaJnhf9ONEzpAzqxx9/vFi7dq3I9si3RMyQX0RDzZaF9gGZJ3HJS8JqycsXX3xRmoHoe5y45KXVtky3u6GhQSp9VK6//voW2yj6O/YOBwIB+d0/5JBDsqLdpGjFZDf9kL/00kvxtnV2f6fb5kQ5cckll2S8r9Olvd5tU1e5Z+YBexvhlq0RbJlsV4y7777bnDRpUqc4+abTLnJm3Xfffc133nlHfiZHfoqiymSbnn/+efOwww6LO0Xfeuut5rnnnmtmc+RbDHrnevToIZ2M0ym0b1uiyED78uWXX0oHbwqCGTlypPn555/L+ksuucR84YUX4vvNmTPH7N+/vyw///nP4+9oqm2ZbPdtt91mulwuGSgRK1RHLFiwQEaeHnTQQeb+++9vTp06tVOyNqTT7vvvv1+2KdY2Ckih712m+jvdd4T2Ky4ulpGiiWSqrydPnmz27NlTRrdWVVWZAwYMaPd3u1lzuZfzil97RLhlsl1WEWyZbtfy5cvNY445RkZNdrTil267Hn744RbRntnQpn/84x/yx4kEJ+1z7bXXmr/61a+yOvItERJoFCmWTskn4QcA0JdmjeVezgd3WEUvJU5rZ1NUFTfdHotgIxNBpttFU/xkGiQTACXx7GjSbdfKlSul7wlF+ZEDNZlWyeG4srIyY20iB/Q333xTJhumRMI9e/YUb7/9tsg06b7ztCYuFQAA0AWvxnIvL3z88jWCLZPcfPPNMoM7+dBlE+Ss/Nprr4nZs2eLTz75RCpZl19+eUbbtHTpUrF8+XIZAff999/LCK3LLrsso20CAAAA8lLxa48It0y2yyqCLZPtohmr+++/X84SUU41Ukzp723btmW0XfSZgidI4aMZuPHjx7dIQZCJNs2bNy8eAEMh+RMmTJAzgJkmE5GbAAAAspucV/zaI8ItWyPYMtkuCtsnpYGUhXfffVemKqC/O8KkaqddlBNryZIlUhElXnnlFXHwwQdntE203ixFZweDQfmZTPUHHHCAyDSZiNwEAACQ5Zh5QHtEuGVjBFsm25VIZy3dk2675s2bJ6PNaLkuWupr/fr1GW0TRbpR5PN+++0n23TyySfHI7WzOfINAACAfhj0T6aVTwAAAAAA0PHkvKkXAAAAAACkBxQ/AAAAAABNgOIHAAAAAKAJUPwAAACAvUj03q1bN/Hqq6/KzxTdT9kAKBcqANkIgjsAAACAvYBSPU2dOlV89tlnYtasWWLZsmUyxVNnrHoEgF2g+AEAAAB7yZQpU8TixYvlCj6ffvqpTAAPQDYCUy8AAACwl/ziF78QX3zxhfjpT38KpQ9kNZjxAwAAAPYC8us78sgjxYEHHiief/55aeYdOXIk+hRkJa5MNwAAAADIZWbMmCGKi4vFY489JkaNGiUuuOAC6edHdQBkGzD1gnYD0W0AAN1YuHCh+Mtf/iLX9HY4HDLIY+jQoeLKK6/MdNMAUAJTL2hXEN0GAAAAZC9Q/EC7g+g2AAAAIDuBqRe0O4huAwAAALITzPiBdgXRbQAAAED2gqhe0K4gug0AAADIXjDjB9o1uu3CCy9skbV+7NixoqKiQsydOxc9DQAAAGQYKH4AAAAAAJqA4A4AAAAAAE2A4gcAAAAAoAlQ/AAAAAAANAGKHwAAAACAJkDxAwAAAADQBCh+AAAAAACaAMUPAAAAAEAToPgBAAAAAGgCFD8AAAAAAE2A4gcAAAAAoAlQ/AAAAAAANAGKHwAAAACA0IP/BxIxATPplLMnAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Vertical edge midpoints\n", + "Xmid_v = (X[:-1, :] + X[1:, :]) / 2\n", + "Ymid_v = (Y[:-1, :] + Y[1:, :]) / 2\n", + "\n", + "fig, axes = plt.subplots(1, 2, figsize=(6.5, 2.8))\n", + "im0 = axes[0].pcolormesh(Xmid_h, Ymid_h, grad_x_edges, cmap='RdBu_r', shading='auto')\n", + "fig.colorbar(im0, ax=axes[0])\n", + "axes[0].set_aspect('equal')\n", + "format_plot(axes[0], title='df/dx on horizontal edges', xlabel='x', ylabel='y',\n", + " grid=False, plotarea='white', titlesize=11, labelsize=9, ticksize=8)\n", + "\n", + "im1 = axes[1].pcolormesh(Xmid_v, Ymid_v, grad_y_edges, cmap='RdBu_r', shading='auto')\n", + "fig.colorbar(im1, ax=axes[1])\n", + "axes[1].set_aspect('equal')\n", + "format_plot(axes[1], title='df/dy on vertical edges', xlabel='x', ylabel='y',\n", + " grid=False, plotarea='white', titlesize=11, labelsize=9, ticksize=8)\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "e1f2a3b4", + "metadata": {}, + "source": [ + "### Verifying the gradient on a linear field\n", + "\n", + "For a linear field $f(x,y) = x$, the x-gradient on every horizontal edge should be\n", + "exactly 1 (the grid spacing), and the y-gradient should be zero." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1b018537", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Grid spacing dx = 0.0345\n", + "All horizontal gradients = dx? True\n", + "All vertical gradients = 0? True\n" + ] + } + ], + "source": [ + "# f(x,y) = x coordinate\n", + "f_x = np.zeros(grid.size)\n", + "for xi, yi, idx in grid.iter_points():\n", + " f_x[idx] = x[xi]\n", + "\n", + "gx = Dx @ f_x\n", + "gy = Dy @ f_x\n", + "\n", + "dx = x[1] - x[0]\n", + "print(f\"Grid spacing dx = {dx:.4f}\")\n", + "print(f\"All horizontal gradients = dx? {np.allclose(gx, dx)}\")\n", + "print(f\"All vertical gradients = 0? {np.allclose(gy, 0)}\")" + ] + }, + { + "cell_type": "markdown", + "id": "a9b0c1d2", + "metadata": {}, + "source": [ + "## 4. Laplacian: $L = A^\\top\\, \\text{diag}(w)\\, A$\n", + "\n", + "The discrete Laplacian is constructed from the incidence matrix:\n", + "\n", + "$$L = A^\\top W A$$\n", + "\n", + "where $W = \\text{diag}(w)$ is a diagonal matrix of per-edge weights. With unit weights\n", + "($w = \\mathbf{1}$), this gives the standard combinatorial Laplacian whose diagonal entries\n", + "equal the node degrees." + ] + }, + { + "cell_type": "markdown", + "id": "e5f6a7b9", + "metadata": {}, + "source": [ + "## 5. Divergence and Curl\n", + "\n", + "The **divergence** $\\text{div} = -A^\\top$ maps edge fields to node fields.\n", + "The **curl** maps edge fields to face (cell) fields, summing edge values around\n", + "each rectangular cell with orientation signs.\n", + "\n", + "These satisfy the discrete exactness property: $\\text{curl}(\\text{grad}(u)) = 0$\n", + "for any scalar field $u$." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "479e3beb", + "metadata": {}, + "outputs": [], + "source": [ + "D = grid.divergence()\n", + "C = grid.curl()\n", + "\n", + "# Verify discrete exactness: curl(grad(u)) = 0\n", + "L = grid.laplacian()\n", + "A = grid._A\n", + "grad_f = A @ f_flat # edge field\n", + "curl_grad = C @ grad_f # should be zero on every face\n", + "\n", + "# Divergence of the gradient gives the (negative) Laplacian\n", + "div_grad = D @ grad_f\n", + "neg_lap = -L @ f_flat" + ] + }, + { + "cell_type": "markdown", + "id": "a3b4c5d7", + "metadata": {}, + "source": [ + "## 6. Hodge Star (90-degree Rotation)\n", + "\n", + "The Hodge star operator rotates a 2D node-based vector field $[u; v]$ by 90 degrees,\n", + "returning $[-v; u]$. Applying it twice gives $-\\text{Id}$." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "18036f2f", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "H = grid.hodge_star()\n", + "\n", + "# Interpolate edge gradient to nodes for visualization\n", + "# Average adjacent edge values to get node-based approximation\n", + "grad_x_nodes = np.zeros((ny, nx))\n", + "grad_x_nodes[:, :-1] += grad_x_edges\n", + "grad_x_nodes[:, 1:] += grad_x_edges\n", + "grad_x_nodes[:, 1:-1] /= 2\n", + "\n", + "grad_y_nodes = np.zeros((ny, nx))\n", + "grad_y_nodes[:-1, :] += grad_y_edges\n", + "grad_y_nodes[1:, :] += grad_y_edges\n", + "grad_y_nodes[1:-1, :] /= 2\n", + "\n", + "# Apply Hodge star to the node-based vector field\n", + "grad_flat = np.concatenate([grad_x_nodes.ravel(order='C'),\n", + " grad_y_nodes.ravel(order='C')])\n", + "rotated = H @ grad_flat\n", + "rot_x = rotated[:grid.size].reshape(ny, nx)\n", + "rot_y = rotated[grid.size:].reshape(ny, nx)\n", + "\n", + "plot_hodge_rotation(X, Y, f, grad_x_nodes, grad_y_nodes, rot_x, rot_y)" + ] + }, + { + "cell_type": "markdown", + "id": "c1d2e3f5", + "metadata": {}, + "source": [ + "## 7. Boundary Conditions and the Poisson Equation\n", + "\n", + "Use the boundary masks built into `Grid2D` to apply Dirichlet boundary conditions\n", + "and solve the Poisson equation $L\\, u = f$ on the grid interior." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "168bf698", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Boundary values (should be 0): max = 0.0e+00\n", + "Interior max: -19.6140\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "L = grid.laplacian()\n", + "rhs = -10 * np.ones(grid.size)\n", + "\n", + "# Apply Dirichlet BC: u = 0 on boundary\n", + "L_bc = L.tolil()\n", + "for i in np.where(grid.boundary)[0]:\n", + " L_bc[i, :] = 0\n", + " L_bc[i, i] = 1.0\n", + " rhs[i] = 0.0\n", + "\n", + "u = spsolve(L_bc.tocsr(), rhs).reshape(ny, nx)\n", + "\n", + "print(f\"Boundary values (should be 0): max = {np.abs(u.ravel()[grid.boundary]).max():.1e}\")\n", + "print(f\"Interior max: {u.ravel()[grid.interior].max():.4f}\")\n", + "\n", + "fig, axes = plt.subplots(1, 2, figsize=(6.5, 2.8))\n", + "plot_scalar_field(X, Y, u,\n", + " title='Poisson: Lu = -10, u|bd = 0',\n", + " clabel='u(x,y)', cmap='hot', ax=axes[0], fig=fig)\n", + "plot_gradient_vecfield(X, Y, u,\n", + " np.gradient(u, axis=1)/3, np.gradient(u, axis=0)/3,\n", + " step=3, ax=axes[1], fig=fig)\n", + "axes[1].set_title('Gradient of Solution', fontsize=11)\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "e9f0a1b3", + "metadata": {}, + "source": [ + "## 8. Laplacian Eigenmodes\n", + "\n", + "The eigenvectors of the discrete Laplacian are the vibration modes of the grid.\n", + "The smallest eigenvalue is always 0 (constant mode); subsequent modes capture\n", + "increasingly oscillatory patterns." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bdaf64d7", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjAAAAIgCAYAAACbJ1P0AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAo5dJREFUeJztnQeYJUXZtqu7T5wzcWdzhCUJSE4fAgIiiiJihA9REfVXFCMqign1+lWMqL9gBhQQlQ8MKOiHgBIlJ8mSNqfZnXDm5O7+r7dnzuypt95zumd2YLfPPvd1DWxVV6fqqu46XU8/r+X7vq8AAAAAAGKEvbUPAAAAAABgsmAAAwAAAIDYgQEMAAAAAGIHBjAAAAAAiB0YwAAAAAAgdmAAAwAAAIDYgQEMAAAAAGIHBjAAAAAAiB0YwAAAAAAgdmAAA8A0YVlW8LfDDju8oHV6ySWXTOzrS1/6kooLRx111MRxP/fcc1v7cLZ5Xqz2BEBcwQAGxB56iNdv9u9617u29uFsV9Trvdnf9773va19iACANiWxtQ8AADA5Xvva16pbbrkl+PfixYtjU33/7//9PzU0NBT8e968eVv7cAAAMQcDGABixuzZs4O/bY0rr7xSzZ07V8tbunTpxL/32muvrXBUAIB2BVNIYLvivPPOC7QYCxcuVNlsVnV0dKg99thDff7zn1eFQkErS9qD+lTI2rVr1amnnqp6e3tVT09P8O9169aF7m/lypXq3e9+t9pnn33UzJkzVTKZVDNmzFCveMUr1B/+8AdxnSuuuEIdffTRqq+vT6XT6eA43vGOd0y8vWimgaHtvf71r1c77rij6urqUqlUSi1ZskSdfvrphuaEptrq2/jf//1f9cUvfjGok0wmow477DD14IMPTrpuDzzwQHX44Ydrf/Pnzw/VwBSLRfWxj31MzZo1S3V2dgbnQMsb678R3/fVxRdfHBxnd3d3cB2pfr///e8rz/O0so3bWLNmTVCPVK9UPyeffLLauHHjRFnaZ70sHetNN92kDjjggGD7+++/v/rHP/4RlPvRj34UDMxa1dV//vOfoN4XLVoUXIf+/v7gzdkNN9xglN2wYYN65zvfGbQral/0b8prRrVaVd/97neDY8vlcsHfIYccoi677DKjLB3zK1/5yqDNUdujOj744IPVRz/60Yn2BEBs8QGIOeeee65PTZn+TjvttJZld9ttt4my/O/oo4/Wyi5ZsmRimbTe3nvv7ZdKpYny9Xxar84dd9zRdH/098tf/lLb57vf/e6mZZ999tmgzMUXXzyRR+de5/3vf3/TdefMmeOvXbt2oizVU33Z0qVLjfI77LCDX61WQ+teOr5mHHnkkWLZE0880dj/okWL/BkzZkykG3nnO9/Z9DxPPvnkptdQOs9TTz11oiwdUz1/wYIFfiaT0cpms1n/k5/8ZGhd3XnnnX5XV5d4fJZl+RdeeOFE2XK57O+3335i25LaU6VS8Y855pim53/22WdPlH388ceDY25W9qmnngq9vgBsy+ANDNiuOOOMM9Sll16qrr322uDX6Z/+9KfglzFBv7hvv/32pr96f/vb3wZvP+hNCvHQQw+pn/70py33R1Mq9NbnqquuUn//+9+Dffzyl78MfgkT//f//t+JslTmoosuCv7tOI765Cc/GRznr371K3XssccabyI4r3rVq9RPfvITdc011wTn9te//lV94hOfCJbRG6Sf//zn4nrLly9X3/jGN9TVV18dvDGov43429/+piYDvfnhIt6wr43o7c8f//jH4N/0RoPeLNCbJKqfxrcjdf7nf/4nqA9it912C95W0fn+13/9V5BH14j+JOhND72luPDCC4O3IsRvfvMb8U0EvTmjNxd/+ctfgrdl9fW//e1vq/e+973qz3/+s3rJS15i1BWN6ejNy8jISJB+y1veEmzjC1/4grJtO1hOb5uozgl6k3T//fcH/6a3NHT9aSoun8+L50Bvmepvceicf//73wd1QnVBfPOb31R33nln8O/rr78+OGaC3rjQelSW2hy9LQtrTwBs82ztERQAL+YbmH//+9/+f//3f/sLFy70k8mk8av0+9//vvjr/frrr5/I/9nPfjaR/4pXvGIiX/rFTFxyySX+EUcc4ff29ga/wPk+h4aGjDcR55xzTtNzaPYGZmBgwD/rrLOCt0XSL+83vvGN4huYj370oxP555133kT+9773vdC6b/V2ib9pkd7AfOADH5jI+8QnPqG9PWjcTp3GOvrBD37g33LLLcFf4zV53eteJ17D3//+9xP5xx133ET+Aw88YLyBofqrX5crr7xyIn/x4sW+53lB/re+9S2jru67776JvLlz5wZvTOq8+c1vnlh2/vnnB3mvec1rJvIuuOCCibLU3qT2tM8+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uEqlUlBP/f39qrOzU735zW9Wa9eubbmO7/tB3503b57KZrPqla98pXrqqae0Ml/96lfVy172sqDvUT+SoEHYAQccENxH9t133y0+F9AefYWeDccee6yaNWtWcB8+9NBD1d/+9ret/ozZGOHZMJX+FdYPaBt0Xeg5kkgk1Bve8Aa1Tb6BoYfhb37zG1UsFrWD//Wvf60WL16stgWeffbZYFBw9NFHqwceeCC4Eb/3ve+ddAObMWOG+vjHP66WLFkSnN9047pucJyVSkXdfvvt6pe//GUw0KIG3QpqoI888oi6/vrr1Z///Gd18803q/e9730Ty4eHh9WrXvWq4Ljvvfde9a1vfUt96UtfUj/96U8nytD+TjnllKCB33///UGDo79///vf036eIB79plwuBzfkz3/+82qfffaZ8nZ6enrUySefrF7+8perSy+9dIuPi/rgNddcEwy4//nPf6pVq1apN73pTS3XoQH7D37wA/XjH/9Y3XnnncEboVe/+tVBndehfvfWt75VfeADH2i5rXe/+93B+YAXhzj0Fbrn0gCGfvTRPZaeNSeccEJwL92az5hTQ54NW9K/WvUDepbRDwUa6NCPhRcEfws57bTT/BNPPNF/6Utf6l922WUT+Zdffrm/9957B8uoTJ1SqeR/+MMf9mfNmuWn02n/sMMO8++66y5tm3/5y1/8XXbZxc9kMv5RRx3lX3zxxT4d6qZNmybK3HLLLf7hhx8elFm4cGGwzXw+3/Q4zz77bH/PPffU8k4++WT/1a9+9ZTOm9al85turr32Wt+2bX/NmjUTeT/60Y/87u5uv1wui+s8+uijQf3cfffdE3nXXXedb1mWv3LlyiB94YUX+n19fdo2Pv3pT/u77bbbRPqkk07yjz/+eG3bhxxyiP/+979/Ws8RxKffNHLkkUf6H/3oR7fo8lGb6+/v9yuVypS3MTg46CeTSf/KK6+cyHvssceCc73jjjvEdTzP8+fOnet/61vf0rZDdXnFFVcY5anuenp6Wh7Hueee6++zzz5TPg/Qvn2lzh577OF/+ctf3mrPmEcjPBu2tH9F6Qf1azjdTJsGhkZiF1988USaXheffvrpRrmzzz5bXXXVVcGbhfvuuy+YyqFfQfSai1i+fHkw0qORK70pobckn/nMZ7RtPP300+q4444LXmvRtMhvf/tbdeutt6oPfehDTY+PXlvzUSDtdyqvs+lY//SnPwX75m8nvva1rwWv3Fr90RRRq+OkV25z5szRjpPeoNAoutk69GrwwAMPnMijc6VX/vRLs16Gfv2mUiltu0888YTatGnTtNcRaI9+M53QNOhll12mBgYG1F//+ldt2eWXXx7ab2655ZagLP26rVarWlulaU/6Jd6srdIb2DVr1mjr0FuhQw45BO07JsStr3iep0ZGRoI3KlvrGXNHhGcDZyr9a2uRmK4Nvf3tb1fnnHOOev7554P0bbfdFrzyI91JndHRUfWjH/0omBJ5zWteE+T97Gc/C15t/eIXvwi0HrR8p512Ut/5zneC5bvttpt6+OGHNdHs17/+9eC1WH0+fpdddgleDR955JHB+qTf4NDNq3FQQFCaBgb0WpJedUXlJz/5SaBN6evrC27I55133sQymqc96aSTWq4/f/78psuaHWd9WbN16HgaoTlH6jj1dej/O+64Y9Pt0rk023ez/YL27zfTCb2OHhoaUsccc0wwYKEHSJ3Xv/71wWCiFQsWLAj+T+2RBuJco9Kqrdbz0b7jS9z6yre//e1AaxL2PHghnzFrIjwbOFPpX7EfwNA8OWk3qOGQWI7+PXPmTGNUSyO7ww47bCIvmUyqgw8+WD322GNBmv7Pb2QkhmrkwQcfDEamdBOsQ/ukES/90tp9993VC/kr8oILLlBnnXVWIB47//zzg8ZO/yaoYUQdcVMHq/+qpPnOZm9YQPuyvfSbupCXfjGTNoAeDvTrtKurK1hG/6//G4C49xXSrnz5y19Wf/zjH40BxIv5jGl3pm0AU3/FV3/FRhfghYJGte9///vFTzKbCbrmzp1rqKgpTcrsybx9oV+RdOOl146FQiEY0ZMoikbm9dd79NeKRx99NDjOn//85xOiNOpk9eO86667jOOsL2t2buvWrTM6Ab2GrK/T7Pwbt9usTLP9gvbvN9MFvXq+++67gxv7woULgz5HX1ucdtppwXJ6UNCxteK6664LvqKj9khiW/rktfFXYqu2Ws+nMvQVUuM6+JIoPsShr9BbIXo+0LNiKuLV6XzGzI3wbOBMpX+1xQCG5gzpxGmkSHOOHHptR6+m6NUfvXEgaLRMN7b6qzoa2dLcXyP/+te/tDR9Ck0XiOY2o0IjbP5JML1W5CPvKL8iqWHRwIf+qIHSK75645rM6736K3F+nPQpJzW6+sidjpP2tcceezQ9N2psNHdJn7URN954Y/Brof5Lg8p87nOfC+q7Plii7dLrU3pNWS9zww03aJ/KTqWOQPv0m+nie9/7XvBF29KlS4M0felD/aY+gJnMFBK1cWrD1FZJo0CQlovm/Zu1VZo+pZsvrVMfsND0MekAwr44AtsO23pfueKKK4JBFg1i6A3RVJjOZ8yhEZ4NnKn0r63GlqqAubp4aGgo+KvDFeL0FcP8+fMDJfQjjzwSLKOvYzZu3Bgsf/755/1UKuV/8pOf9B9//PFAaU5fDzQqxB988EE/m836Z555pn///ff7Tz75pP+HP/whSDfjmWee8Ts6OvxPfepTgaL6ggsu8B3H8f/6179GPtfbb789WOe5556byCNVfG9vb6B8nw5qtVqgtn/Vq17lP/DAA8HxkZr+nHPOmShz5513Bl8PrVixYiLvuOOO8/fbb79g2a233hoo7E855RRNWT5nzhz/He94h//vf//b/81vfhPUx09+8pOJMrfddpufSCT8b3/720Edkbqc1OgPP/zwtJwbiF+/Iags/R1wwAH+2972tuDfdAxRWbZsWdCuqF3WoX/T13arVq2aUrM444wz/MWLF/s33nijf8899/iHHnpo8NcI9ZGrr756In3eeecFffWPf/yj/9BDDwV1vOOOO/rFYnGiDNUjnR99OdLZ2Tlx7iMjIxNlnnrqqSCPvs7bddddJ8o0+0oQbB99hbZD7ZyeLatXr574o3vv1nzGHBfybKDnCPUVWj6Z/hWlH1D9U94JJ5wQfO1VLzNdTPsAhsMbF90s6HO0mTNnNv3E7ZprrvF33nnnYPkRRxzhX3TRRcYnbrTOscceG9xkcrlc8LnZV7/61ZbHetNNN/n77rtv0HiXLl0afDrXSP1TulaftdGnxo2Mjo4Gx3DVVVf50wU13te85jVBB6J6+sQnPuFXq1XtPOg4n3322Ym8gYGBoFHSsdAn16effrp20613SvoskOp1wYIFwQ2d87vf/S5ojFRH9Nk5fW4Ipp849RvaBv9bsmRJy/bIP50++OCDjXzqg9/5znf8qUD18cEPfjB4MNFA/I1vfGPwsODH3djH6VPqL3zhC8FAnuromGOO8Z944gltHapz6XzpHBs/J5fKNDt/sH30lWbtovHYtsYzZiDk2UDtlrfxKP0rSj+g+4RUZrqw6D9b+y3QtsK5554bmPY0qtoBAK2hT1tpTp5eudenJwEAeMbESgMTd0gkSFbnAIDokLaMBjAYvACAZ8yLCd7AAAAAACB2xCIaNQAAAABAIxjAAAAAACB2YAADAAAAgNiBAQwAAAAA2vMrJHLtW7VqVRCrpB6PAWzf0Nf3ZHdNjo8U2RRsBv0FoL9EB/0FTPX5EmkAQ4OXRYsWRSkKtjMoND3FtgGbQX8B6C/RQX8BU32+RBrA1KPE3va+N6rO1JhRlVuumOUW6lE3a0WzTN9+e2rpkcefMso4Gd0MK7fLS7R0ctEUY7l09GjJ8r03GEXS+7xcS/vpnFGmctd1WtpK66HVraQZar26bqWWdktm3WQW76iX2WiGLk8f/kYtPZjT4yl1Js03ZPmq7lXYpUpGGbsyqqc3LjfKqFTHxD+H86Nqh8NeiwjCLfrLMw/fp7q6Oscyfc8syPIsr2YUsVyW5+rtxqpVzXWqBS3tFfVrO5aX19MjQ+bhFUe0dG1kWEtXhvTlRGmjnlce1PcTrDeoH09xsGyUKQ+WWpapjJjr5Mt6XQ3XzDofZXn5munjWfb0vKKrr1NlywlXtaaiPHW5Won+0qK/OHucpCxHNkK0Eykzz9HzEuw+HGwzpeclOrqNMsmMfo9PdY7FhquT7jD3nenQjzPN0kRHp75ef5e5nZmd+vHN7EobZWZ363m97PnYnTYf430ZPS+XcowymYT+rMg45puOlGO1TCeU2ccsV78nWZ7QO/j9kKVHRvJq6V77h/aXSAOY+rQRDV660mMXwRUMfLsy+gUS7g2qu4NFfmbrEA7L68zp6yQ7zUFFJHLjD5Nxyh1mg0/XHzitBjBsPSutH5/FOg1RzeqN0BWm4jLsPN1S+PG5nXqH7BIGMBYbwHQr4WZQ1huvXRHqWKgLTCmqpnVCg5fu7q7mAxgvygCmOvkBTEVvA55571Kere/b88wBtW/p267V9EFDWfgRk0zrZVJp88ZeHv8RVMdJmje4REK/NdmOXjcJ2zwpz9bbeVXoY7zf1Szhulj6djy2GYstD7Yb0c8c/aV5ndDgxWKDkokyQr7FBjVWwnz48zxb+HFpJ/X7rt3wQ41wxp95ep7ehhPCc4znJdkzgEixZ0kmZ5bJ5vQyHVn2Az9tPsY7eRlhAJPlA5iEOYBJT8sApjbpAczEuiGSFYgXAAAAABA7MIABAAAAwPYdC6l7D12rkphjCn833nS9lu7Zd99J78dKmK+lvQ593tJnrwXHCumvqu2uPrPIhhX6diqmXsQd1ef1+cu51M57G+vkH39USw8+aWpMFu6wU+h2+Hl1cz2LOaOgesvseIdWGWXcTeu0tNU32yzTUDdeXtdZAAHLHvtrBl/km2V9tr7VansT29VbpOUIc0gMS1D6TyXKK9+OtF2LvYYWt8PK2BHW4URZxRFeUTtsioiXkbfrT2lKCchYwhShUYa1a2mdSNuJUCYM2xam7lmeI5RxIpQJwxHWsVmblTbLy0izNXw9vk6km0QE/V/UKSXj+CKVAgAAAADYhsAABgAAAACxAwMYAAAAALS3Bmb2wXup7vHPvpz+ecZyLz8YqjHhOhmnb5ZRpvKfh1pqQWprlxnrWKl1oZ8yWzP0Y7YEjQ7ft3Semd3319Lrrv2Llu4Xzjvdq3/P3rV4jlGG623cTeuNMsmu57W0N1/31Umue9JYp/TgrVp6dGCjsF3908H0HgcbZey5m31q7BHT3wNMUgMToncR5+d91mXZ58UBHisjaQOYjswXfDYUy7OT+nadpKlFs1OJUP2NxfwmnFS4ToanHeGz0FTVDdW3pNikfkXwdOHrCYdnUGFT9oZOxremJirajqC2Xm/vvN2LPjBc6yXprVgZR9iOWYa1T8EfhZeRPveNom+JVMZqnbYF7Qo/ZEnfwvOkZs7Pi69j+FRJn01H0cAwSwloYAAAAADQtmAKCQAAAACxAwMYAAAAAMQODGAAAAAAsH0b2aVfcoCWrq542iiTXLSLlrZzZnAtLiDlsYb8cnFKAmLF4sZY3TONInxffLtEcqFuODf35Le3FAJLxnVzXvNqo4w3qgfCS+6yn3l8LBYOF+36QmwcTm6//zLyqsv07VSXm0E2VUNepWBeA6Dj247y7eZdTIwRwrdhZLAcafu2G2r8aMSREQS5fD2+DhfsEo4h9I1QRhDk8jwzbf72Shb1vBSLjTSWp6sQs4JA0+UCwwg/87iwkhvZ+STiDYv4uJ1DQt16zCNDWJsURLy8PUpC3+Tky3DRLjekk8o4LK4QkWJC31TCbOdpo4zQrtm+jLRth4uDRcPGyQuIjcCMUqBGfl+ThL4hxnVR7o0E3sAAAAAAIHZgAAMAAACA2IEBDAAAAADaWwNTXL1GJTLp4N/dcxeHBgRMLNk9NOiiK5hs2ePzoHWqT90frg2ZrxvkqQHd8I3whze01LtIOp7KM48YZcqP36ulaxt1w7nEDNOcT9K8cNyB1Vq69JypIep6+Wv0Mvf/M9R4r7BS365uWSeb6CWE69toDphAMMdQfCcZ/DXFcIUSjLhYnqmJCTeJsryxPqvlpZkerKZrqyQzSCutp52MGejUyaRapqW8RMbcdzKj35pqLO1WzLl3l7nJZbk5VqBNsUKDLma5aV4ESYyn+Hb1DdvQwISSSGWUlUiLGhgp4KLNNFpcyzK2zWyoBiaR0vuHzXQoiaR5xc0y5vF1MN1WViiTjVCG62TSTAOTEXQzXN+SFE309HQigtGeVa2Ga1WY5kUsw7QzXBMjGeRJ4A0MAAAAAGIHBjAAAAAAiB0YwAAAAACgvTUwbqmq3PG53k233RIesJDpNQgrndPTTDcztiG9THLxrlraZ8sDnntALyMEc1SzlmhJL5kN3Y590PFGEWet7pGSYsczMovpcagu1j+u77vT9KCxWfDGkUeeNcpkmF/Lunuf0NJuyfSgmXfY3i01MUTHgnktfWG4P4+VgqlFGDVlB3+ELfgwWMwXwvBYIFzmScEWS/EB+XyynzS1IMacc1XQwGRZX2UeQ3bZ1MAkssynKGf2Q69aa5mWNC487QviFZ7nu4I+qMT3ZZZxmO6oyLbrWOa+ueaFa20QyDEcZ5IaGIdpGKVAjQ7TwPB1JP2KkRZ8irguJi2UyTKfpA6xjNNS7xJF85KWvGOYdkXSt/Aykk7GrpVb+pApSTvnRtDJhAV85PtpAt7AAAAAACB2YAADAAAAgNiBAQwAAAAAYgcGMAAAAABobxFv9157qe7cmAgq//ijoUECpSBytSfv0Q9gJ11gGjDKAijmevXtDpvCX48ZsdlzdzTLrHwivEyIYDcoM7JJT8/fUz/com6YF1Ae1ZIWM9ULiqxaqaWzs/XzJgbuuEtLL37v+0IDST77u79q6SWvOSTUyE4Khlna5YjN/x4eNpYDnYrrB39BfQrCT4sHUxOM7JykLoLlYmBudCe1YfFXCjN5s5lgVyrDg6FKAr4Ey/MqgkCXiXZ5mkiy9dyqfiyeZ9anx0S7nuRSFyrqNUW6PChkRdi3lKdtg0S+puYZNNZ7Jqds1t5bGdBx0S4X7BKJbKeWTqbN7STT+mMwldaFtSm2XMrrYkaLokldBBFvh2SIx/J4OsUjLgp5ghefUcb23VBBLu/zFhP5jq1TiWB21/ojEP7BQDPwBgYAAAAAsQMDGAAAAADEDgxgAAAAANDeGphGBp9cbuR17T0SqjGRggQaMM1L7Wld12ElTW2NEcSQ62iIxXtpSV8wy/F3Pljf18Bz5nZ22Fffd143oKv9+1ZjFWvOIi09+M+/GWW6Dzgk1Ewut3Spvq81y1rqc4j5h+vn/Z/f32aU2fNzH9ePd4YZFLLmb57LTDb8G8iQ/qU8rsMQfOyUzdzNeOA0IsGkFUmHBZ6zE6G/Srwov1yYEZtYhhnt+YL5nc3mrpNCQEWPzX9LhnM8zxe2MxVsNu9v8Yh2dMxFvW2X2LFIehfTyE5f7gj1C1i9BxqY7CSCOaZCTeq45kXSsySZ5oVrYvhyooNpXjoz5jOpN6vn9XSYZbq42V0EDUyGCVpSETQwotkdW82uFI0yqsq0kVVWRniGcv1KJCM7HtyxWlBRwBsYAAAAAMQODGAAAAAAEDswgAEAAABA7MAABgAAAADtLeL18oPK88ZEPQtf/2pjubPrgVq61jnL3MiMHbSknTcN3Qazc7R07+66GZFa9rCxzrKZurB2cdEU33rZHj3jvutUGJKdjrVWF846c3RhcnKX/Yx1as8/pqW79t7fLMMEudURU8jkMNOvtX/9p77dxXrdEX2HbTagI5ZmUqGRurnxHmFVNudZlWgiq+0ZEn8ma17zaNQsyxF0qg4zUasxoW9KEqGmctNjdsePN8fM76To2caOzDKpCAJdQ8QbYnwVFZvVlyUIIJ2UXiZR8VpGxg7yxq9zMwrTo0Fua5IdPcoWzOiaG9klWkaRjirITTOxbTrLhLVsOdHLBLmdgji4kwl9c0ywS2RDTOqILnbMGdaGU4L4P83atST0Ne7hTLAriXatml7GqppGdoqZ2/mSKR3/IID1b69oPn8k8AYGAAAAALEDAxgAAAAAxA4MYAAAAADQ3hqY1bfcq/Kpsbm/OQfvYSxPLtaDLPp9pmldiTk8ZbrnGmVqZTb/zeZFHcEgb6FvGrhxEkN6sESfaXYC1j+vJe1ct3l8/bqOp5LRtTXJNY+Z+2ZBKws3XWWUsZP65XAErcrKmx/Q0ouOObC1oZ9giJfeybx2Lguyae+p62bA5CnVfJWotQrmqKcdQSeTZPPbLvvJ4UpBDZlpVSrVYZSxmS4mitmdNYUgkZIGZsrumY3H4phaAcu2W5rWEQ7TGNhM70LUmJFdjQV89IUgkW61tUYnMO8zY9CCBlIdHcoW2irhCFovm7VzSQPDAzNyTYykeckwzQvXuxA92VR4GZbXJQRz5Hk9wvFl2HmmE+EmdRmWZwv6Fq6BMUzqhDI8eKNfNrWQflnfly8EfRV1MQ14RRjZAQAAAKBNwRQSAAAAAGIHBjAAAAAAiB0YwAAAAAAgdkxKT9e1cLbqGheWcsGpJBa1FunmckRudENrc7lA2KSLditKL9MhRIjmUXDdVf8xyiSY4Vz5QTMiNBfBSlGZrf/cpWds0qNRq8W7GutUn9Lrxskxcz6l1MjTz7c0oCMWsLTd1RcajTpz+Il6mZS570JON8BLCOZIxXFBanCsph4NMEYrrrLGTc8kIzuuS5SiUVfYelzUKxlUuT4zXvPMMplERt+3cHweF8Wy5dY0/SKaiqhXiiLN87hpHeEkyy1N64haRhftutUIRnZCnra8hujtYaTSSeWkx4SvFmvnPE04TMwaxciOi3qjiHZ7OsyPKXiZGZ1mmZ7xc6nTLUSs7mFmd5KRHTely7B0ltUD4bh6O7fK+XCTuhDzUslgzq+Y4mCe51cFwS4T9nIzS29UiIwtgDcwAAAAAIgdGMAAAAAAIHZgAAMAAACA2DGp6eeeAw5U3TnZaChg/9foG99oalVcFuDRFubm0iyvnJvV0kiOcNY+1fy46uvxIIyC6RsPSOkzYzvC2+1wPSOpa3ZqgiGQPbBaSyfmLDLKzGDaGZdra2i9GXpdpPY8VEtbbrhp0Iau2UaZ9cN6mRkZcy62UaNREwzUgM6mUk1VEtWm+haelWSaE9nESk+7vqSBsUI1MNyLLSsEy0umJh8AMpLZHT9P22xrCZbH9S3ctE4q4wg6PSej900nY87huyW9L1SZkZ0n6F08VqE8GKXLgrACk0wuMTkNDLvesgZGz8syzUkUzUt/zuwbXPPSK+hbOplJnWhkxzQ62aR5ntmk3TKd9Cqh2hXRpI5pXvg6hDc6oqdLTAMjBF00NDCSaZ1gbqdv1+yXEngDAwAAAIDYgQEMAAAAAGIHBjAAAAAAiB0YwAAAAACgvUW8Q/feo7xxI7ta0RThdC9jQtrFuxhlkgt3ChXkDlhdWnpGTRcgeSz6M2H1LdTSTjpnngATLfllQdg0rIeMdRfrUaTHNq4Lthr83QJSgpDW7uwNjXJd+s9D+rGkdXEwkVy0S0vRrtehG9sRT9pMrFwyRYjXPLZWS+8yyzS7G24QNxbzurgLmAyXa6qWbC7e5B50ScF4Lc3yuKhXMr7KMJGfK2zXY5JcXxADZ5mKN5VmEaxZRGvCYnmSgd+UfjUxUW9GEPE6Kb1fVoVo7tyAM5FJG2VqJd0ELFmqhApyuWiXR6z2Kq2j7wKl0h0plRCuWdPI4hGiUXcy0W6XIOINiywtmdT1MvO7biGKNDep42kiw/pmVogszfNSfi1UfGtzga5gUqdKTKA7OmwU8QojrY3smKg3ajRqL0TUXivqfbAZeAMDAAAAgNiBAQwAAAAAYgcGMAAAAABobw3MytufVJ3jc8gzdptrLC+sGdDSmd33N8oU7/67lk7tbGpM5vTNDtV1cHwnFb4Oy7PWmOZ31SW6kd2GoqkX6bX0udb0qG445wumYGrWEi3psuMlkszIzp67o7md0UH9eGfv2lKfQ8z39eNdlTfnH3vYvO9DK4eMMs+s32wwWC2aBoRAZ7BUVWWnumUaGG5kx8qUatxeTqmOGjPQEgLYub4danbHt+wl9NtFOq1r1QjbCtfJ8BxHMqXjRnZMjyMa2bF+50TQwLhM30LUuOZlShoY/b5RLUMDE0amI6kS44Zw3LhOMoJMcT2YYBTXyQzmOtNRjOySLfUuQZl0uL6FB3PkBnTBMXOTOiEwY9ryWupZbCkII89jehcp8K83oj9bJI2LYWwnBHPk/cWrmP3FlQI8NlBhOrRm4A0MAAAAAGIHBjAAAAAAiB0YwAAAAACgvTUw6x5ep/Ljc9OlTebc15x9db+RrmVPhm6TB36Sgj/5K58I1Ybku/XgiF3rHze3y7xhPMHjZaSq+zfMtkytx1CNebiwYJMS6YruOeOnTI8XPvtZe1r3hQnyVj+rpW3mHeMc9mZjnbyve7qsyZdD/Qh26DeDdt7x1IbNxxFxjnJ7Zt1wWWXcZNM5fJ7H5/SJLPO24JqYMtNeSHlSGT6H7woeGr7hFcOWC/P1GaaL4ZoYwmPeMLagZ7G5livB0sI6imlgrHRmShoYnsfbuuRh4RkaGD1dFfYDdHpyKZUc92RJRNLAsECNEYIlcl8YSfPC1+F9Jchj2hqudwn2xXyTcqLHi35eGcHvhgc8tqbi8TKk61Ml3xcvPxhaplYohfq1RNGMcV2M7+n9pVSO1l/wBgYAAAAAsQMDGAAAAADEDgxgAAAAABA7MIABAAAAQHuLeJ8aKqnMuInbkfvOMZZXhnWh6qqb7jLK9O6qi22dftNgx1m8u5a2c3ogRAkufpKCRNpF3ZxtyDEDKnYl9e0UbLMMl2slWbBJP2kKdMtduvFfqmwaxa3d6RVaes7TNxplMv/1WtUKa+A5I8+ZuZeWXtRtiht5kMCbnjZFX288aHPAzOLoiLq55ZGADSNllZqEiJcLdCVhIk8XJOFiKhFqdldlIlPJiMtjtweuBfaYGd5YHjv+tBkU1BD2SkEh7UTLdbixXZDHRLxeymznFsuzhWB0CRaMLlEOF/H6YSLeiMHptmdm5FIq1ZGWBe4RTB4lES/Pk0S8vL/wwIxc1Ev0MRFvLhUehFEysuN5XLArG9flw03qhgZamtZJol2XmdQR1eGCnh7Vn3XV0XAjO9n40W0p4i1HNH7EGxgAAAAAxA4MYAAAAAAQOzCAAQAAAEB7a2AaWXnPaiNvwYG6kd3IanM+b95hunmcnTMDwrnLHmupiZFwhtfo2+g2g016zBxr2cZK6Jzk0h7ToIgHeNzksYBhigkBaF5VlUL1N9UKmxfc+WCjjMqvbx3E0jGDWM5I6vOLCRYoj/jnc/q1Omkv/VoS5934n4l/VwoI5hjGhnxJJd3EJIzshDl8ZjDHA9ZJ8/6VDv1659gcP1FjGg3XbLKqyjK5TsYT2rnPdDHCZlU22RGugQnRyXCNDOEwszuudwmOmZnb+UIZbq5psbRfFUy22Bw+J80MwIDJrK60So9rYDiSySPPk/pChvWprlR4H+PtXDKp45oXrneR8qQydkXXmFiCBsYu6WZyqjgcrm8Z2RRqUlcb1nWYlWFTD1YZ0Y+vxjQvXBMz9eCn+p2iUoEGBgAAAABtCqaQAAAAABA7MIABAAAAQOzAAAYAAAAA7S3iXVaoqZQ1Jr7Zd0fTXG7DE7p5Tq1oinc2PqJHU+4XRHSVgY1auiuCiNdydeFQYtMyo4yX7dHS87tMAfGmki6klVg2XG5pFMZN4YhZHbrYtuqZdVNjLmAPu2bd7Na/s5bOrtUFz25/eGRswU9JpZnYrcodyZRSJ+69WdhbyI+oy0L3tH0zMFJRiepYW7GmGI3aFO0mwkW8rD0WM2abrrIIvLKIlwt9maiXidclJGmrYXaXMIWbyYxeN54dLuK1Had1RGshQrUk4vW4aJcZ26maKeLlRlzGsSVMsSPQ6cslVSZnGhQ26xtJ1iak+64hgheirnNhbyfrY5FM6oTI7DzPqZlCbm5KZ5dNMzku7HW5QHdEiCLNRLtcsEuUB/V9VZhpnSziDTeyq5X0Z5vLPk4Zy2vdX4qC8FcCb2AAAAAAEDswgAEAAABA7MAABgAAAADtrYHpSzkqPW4o9buH1xnLd+3U5y8P2WdO6LyblTYDH3Yd+5aWx1FkOhAiM2hqXjhWRZ+/y+ZMM7kZXfq85XDVFAfMY+c5L6dX4+pRc/6uL6PPsxZr5nafHdTnE3tZwLBg23l927NmvURLZz1zTnLY1fddFoL7cfMmrschdujdfK3yTjSjoe2ZQr6iErWxa2gLGhjL0vNKwjx6gc3Zp1P69e8SgtNxDUxBmIPmZdxO83p7frjGxURfh8lmxDzfF/QDLFhjKh0eANKLYHZnMeNHWwr4GKKB8WvhRna+p9e5bcvaDrCZnkxSZbNym+N6lyCPBfBNCwEfO6JoYNJOSy2NbFJnhQZqTHqVUJM6qzLa8hklaVyMdD7cpI4/d4O8TfmWehfJ3K46qus/q6Pmc6AaQQPDjet4ulyDBgYAAAAAbQqmkAAAAAAQOzCAAQAAAEDswAAGAAAAANtPNOoeQbS0IKtvLtOXCY1G7ZcF0VKHHlHZGVmrb/epW4x1rBksenLNFBdxk7fc6Fpz350ztXRX0hQY9ri6sKng6mLgpCDYzDPjnrQgDNtjZjZU6MtN87KWLpAaVmadc0HusGAitPvMnJa+f40p+moUtxXyiK4bRrlQVTVmsNiIw9qAI4gQ7YR+fSus35UFgRwX7VaYaR3hsjbB02IZpr71BIWuuZnkFH9HsTaa1O8tybRpQmlz0W7FFGwqXoaZ343lMaFvmkXPdqvhRnZMxOs4Zr8EOrlUQnWMm8gxfa5KCn2D32eleyoX5Eoi3jDRbloyqWP9MOXXQgW6NksHeeXRUEGuVxhpmXYFIzsu2uWCXamMJOItM9PWal6/n1UEEW8UIzsu2vVYuuiGG8oSeAMDAAAAgNiBAQwAAAAAYgcGMAAAAABobw1M2rZUZtx8a/9eNi9MQbBm6Xm5OTlzh/N21NNzFxtlvGUPa2k+G2bPXGiuk9EDNa6wdB0NsYBpVzakZ5vH5+rznXkhIOX8rH5eT2/U5wVnZM151o1F/Sx26kuF6mTWCoZ4i3v09daXWeC+mjl3uL6gH98Qm6NsFryx1ZyzpPMBOqVCVTmCXqKZ5kUK+Jhgc+0JFniOzx0TLg/COAV9ywvL5HUxHtPESOZi6VQu3Miuqs/zW1LAx4R+zXymY7LcWgR3PqaJqeG3Yhjd6YTKpeVHEjetixrMMcO1KsJ2Mk5rzYvU1pKsPXK9y1heMdSkzi/lwzUwRvBGPV3eZOoVeWBG0aSO5XG9i5RXzet9ozJaiaCBMTWXki5G2y7TkDUDvQoAAAAAsQMDGAAAAADEDgxgAAAAANDeGpiTznyZ6kqPaTDWPWgGT9zphINCA0jZOebfkDZ1MhbzhjE8XgTskh68amFKmEPzndCp+N7yBi2dzeneMQRXNbx0hgqdD13QycoUh40yWeZ/k06YOpmbntPnSPebq9dnUQjUyDUvT28y50Pvf17f7qFL2Ukppf7wwMqJf1eLpq8A0CkXKsquJbbIB6ZWZRqYqn59PeF6u2yffhQNTAQN1FSwWcDKsbzp8Ioxz9vnwf2SmfDjEXQyPFgj18nwQI1BGa55YWm/8mJqjOJJV8pRufHAivw6OUI74roYKeAj17xIGhiuecnwdiT8zLcj6FtsrrcSngvcw8UbNZ+ZPK86Mnl9S4UFZZT0LaIGZqh18EbRB4bpRqvcIynQuLTuDwVoYAAAAADQrmAKCQAAAACxAwMYAAAAAMQODGAAAAAA0N4i3vJQXqVSY4K2JcfqQRmJ0dUDWrp310VGmeqyJ7V0asFuRhl/vh5Q0R5apR/H4/ca6yQOem3LoIzEKqazWlheZ5Th66VH1oSWSWx8LjSQpD+si4P9+S8xyhSZyFiIl6letrB70gZ0K4dLLY2biHk9uuDxjmc2GmVm5NIT/65YzQ3awHgd5TcpOzlW95ZtmhvWWJ6dNEXbidTmOpdEu5JA15uCINe0z1LKsVsLKfnyKOtISGUcQVw72d9eHhfWBmZn6dYBIAPRLrsOPCCnVwsN5shFvX5SML8DRoDEerDFKCJefhtLCO3RDPholkmFBIW0qmbgWqvCBLo1qUwxXKBb1MW1fkkQ+hb1fVVH9e3WRs19V5lotzJSChfxMsHuWBm97VeZcV1JMEUtMnNNSbDLjTO5H2dR6LsSeAMDAAAAgNiBAQwAAAAAYgcGMAAAAABobw3Mjh/4kOruGjOeq6542lju3vWvloY7RNdrTtTStSfvCd2vs3AnLZ045ASzEDO+sQt6wCti8cDz+ip9ZlDI5OpHQo/Hrugmbv7G1Vra3bTeWCexZHctbTHjPaKzqs9tup2mid59G/XzLDNNxM4zzCCbC7p1fct9K819z+jU5/0HC6bG5ZAdN5vbFfNJ9TOjBGikWhpVtts8KJnDjArtmqmB8ar6nLObzurLhfllSRczFQa5niUkHbUM1yWMCJosyQCvEXkxF0UIRVh/SQr7TjKdjOL6JclkK8zILhktON32DAVjlAIybokGxjCyE8rwfdq1cssAoEGeUcbUj/hlfT1P0LdwzYs3ahqcchM6HqixyjQxY3n68VRYEMagDMvjJnVRNC95wUgzigYmzMiuBA0MAAAAANoVTCEBAAAAIHZgAAMAAACA2IEBDAAAAADaW8RbW79c1QpjItGRh+4zls9606mhhnNqVLfMSsxdbBTxRnQBbm2tHvnae8YU2ibmLAqNYO3O2UVLO4O6QV5UuGi3tna5lk7ufrC5DjPHqvWZ511i4qdVedMkaG6nfsn++pQuGL7+CVNA/Mx6XXS8foMpSttvF92c7zFB6NtIpYBo1GHUCsPKSpSbGtm5kYzssiGRkFmYcwFLEC7aLE8s4+jtb4SJHVMJ85y4CVhKEGXyqMEJSUhriIFVqDjYVv6k73jSGh7bdtJOhprfhYp4x9sBaA5d07oQl19eUcTLshJCpGnejngE62BfvttaoMuik4/llUKN7AyTOpaWRLxuydwXz+PpqmBkV2HiW56Wy5gi3jDRbr4WLtAtuqbQlxvXcWO7Eks3A29gAAAAABA7MIABAAAAQOzAAAYAAAAA7a2BsZbur6yuruDfM+aYGg6fBTFM7XmouQ0WGM3r6DPKeGt0zYtf0ef4nP2ONQ+OmcBJM2iJARZ0UcBP5/TjLZvzlrVdj9DSyfQ94evMXqCXYcdL5JmR2WDJnJP89b0rtfRGZlgk8RwLzNg/d+wattrODrNNbcX9T20OSFkTTJmAjlspKWt8PljSwFhMC2LqW8w8qYxJZ0u9y9i+wzUwDhOe5BO1lnoXSfOSTZnnnU3p51Cs2pPWLiRtc17dVlao2Z01BT85n83HiwZ+FjtPlnaZjgYo8ZrXrzu/dlGM7HibkcztklKb4MF3mebFcoXAtWwd/owiPJYnlfHLpVANTI3l1Ur6vdoVnhO1Yq1lemw74WW4KZ2ZDjeyq/qTD+ZYhgYGAAAAAO0KppAAAAAAEDswgAEAAABA7MAABgAAAADtLeK1B1cpuzYmcq0xUzjCWfuUlvY2rDC3MXdHLW0NrzPKJFn06dKDt+oF7r/eWMdKZVpGfyaq8/bUy6zTj5cY6dP3nZHMkZ5nEbRzvVrSTXWGipfX+WaZh9fpwtinN5mGc9xgrsSiRg+sHjHW6Z+ni3bXLjNN6p5/fH2o0Hfdis3reRXz2IBOrVxS1rjIzXJMMavNhL2+ZwriuGiXi4GtiikG52VqCbOb20xs6yTMdl6r6vuuMbFtoWIqYrMsryiU4XkZ0RDPaxl1XRLxcqGv40lRrllaheMxAaknCAyFXWlUpylCeDuTsJob2UmCbC7sFW7VhrDX8qqh92bLY2JWtlwq4zExriTQlUS8brncUqAbyciuZIpv3arXUrAblKnoZUqCINc0pQuPNM1Fu1GiUXNRbxnRqAEAAADQrmAKCQAAAACxAwMYAAAAALS3BsYbGVSePzb/lkiYpnA+04L4A3rQQ2LT7y/RDyCTNspkd9W1KnaXbnZn50x9htM/L9QgjyNpdNSsl2jJ5Ib/GEWshG5K5WZ62IbNeX972UP6bnY80CizgelZKmzeX9IlrF2mB8eUGGLBG5/91w1Gmd5FumZodcE0qkt1bDb5s8Im/YHy3MpmazVzClr5CTN4YxhuWde8SAZ5NjPicmvmzr0aM1oTgrK5bE7cZe1Rap+VmttSuyKtVxW0P1VuhsXmzOV19DaZFJqoa7VOExbftM3rxlzJZ8fHS7jQwIRCxnR1czp+6awIwRwjBfiUjCC55oXrzlyh8zJzO18I+MgN8fyqWcar1lqmx3ZVa5n2BJ2Zy/J87hQnlImiVQlLT7UM18BI5ncSeAoBAAAAIHZgAAMAAACA2IEBDAAAAABix6Q0MH61pPzK2JinuuJpY7mVDA9Yllu6VEtvvFfXhhAjy27U0vPf/i4tXV32pLGOM39nLW1X8kaZFcWZWjq50yuMMvM26edV7Ne3S3DLDLuk+6o4ed1ThRi58x96xk6HG2UWdLuhwfI4hi5hRA/cOIZ+3ru83AyGmR/UPQoqggYmv3b5xL+9qulpAHS8WkVZfnOtCi0Pg6/HfWGkbUQp47rJlhoOKc9j8+iSroPnVSRviQhammqS6WTYdrjeRQ4QJwWRa50m6tesju3rHd4XQsV6TPUiyDFACHRF7SaaF6k+ueZFCviofKYPkfxFmJ7K4mWEdmR4NokeThHKsHbtueFlzHX8UH2Ly7STQR7rd1J/CdOqCLVplJE0MGHBHKPGXMUbGAAAAADEDgxgAAAAABA7MIABAAAAQOzAAAYAAAAA7S3idQc3KLeSDf6d2nlvY3np/n+2DLAomdLl5vUbZXhAq03/+wct3XPokeax9c7X0r5jmoTNYkHtBkumVGhdly4y7hN0YSWmOOpgyz0hmGPXy1+jH2912Ciz1+xuLX3HCrPMglmbzeSIR/7xLy2dSI1dn0YyHXpdlEbNgGbrH9cDVBY3rTHKJHObDfv8mhl0DDSHC2ujluF5U91O+DrhIt4oy2tc9DdNBm6S2JbDgyxKQRe5xZx0eHw1XkbSitqGuDF8P4DXqzUh3jWCOU6xsrgg1xDoiqLdkDQxhX4pESbQHctrbUrnC+u8UH3MFMGHC+Wnuq8o4A0MAAAAAGIHBjAAAAAAaM8pJH/8NdFIYbP3Rypv+oSUGpYTlhBCwrb1WC6lojkV4ZZbT09Y+YJ5jMMjetoxPWmqCX3qZESYQjK8BdJ26BRSrarv26rq50jYrL7crL5OcDzMKqSQN8tUi7q/Dfdj8YT32265EOoJwKeEfLfSskw99ke9bYCGehqvE5/FSzErlHm8SDYWNb39+ax9elWzC3uOvl2vYk6neszMyLXM/uKyKdeao59PzRb6GCtTsc06KLMyJWHfReZTY6f0Y0kI521X2HkLwZBqzFtJip+TZHkJ1qfq8Xq0fbM09zEZGRnry+gvLZ4v43UU1GeEOSN+7fh1C8p4eluzBE8kq6rfHy12T7XK5rNOldj9fNR8Jnmj+nPAY89Hosyef6WSeXylsn4O5YqeLgjxk0os/lmJTUMFeWzaq8g9c4I8fXqqxO73ZWF6rRwhrlFF8FLSl3uR+kukAUy9Ye1y+hfUtsEFW/sAYoVpqzc1ak3aRk8PC2a5nVPvL+6jv9vibUFp1F6gv8h1Quy7x64v+vUA8e4vlh/hJ4HneWrVqlWqq6tLjAoKtj+o2VDjmj9/vrJtzEQ2gv4C0F+ig/4Cpvp8iTSAAQAAAADYlsBPZwAAAADEDgxgAAAAABA7MIABAAAAQOzAAAYAAAAAsQMDGAAAAADEDgxgAAAAABA7MIABAAAAQOzAAAYAAAAAsQMDGAAAAADEDgxgAAAAABA7MIABAAAAQOzAAAYAAAAAsSNWA5h//OMfQTTswcHBrX0o6qijjlK9vb3qG9/4xtY+FABE0F8AiA76y3Y8gHnXu94VDC7OOOMMY9mZZ54ZLKMyW5tbb71VHXbYYaq/v19ls1n1kpe8RJ1//vmT3s7VV1+tvvjFL6rPfvazasWKFVt8XBs3blSnnnqq6u7uDgZG73nPe1Q+n2+5TqlUCuqWzqWzs1O9+c1vVmvXrp1Y/uCDD6pTTjlFLVq0KDjX3XffXX3/+983zuPYY49Vs2bNCvZ96KGHqr/97W9bfD6gPfpLI7fddptKJBJq3333bcv+0sjAwIBauHBhyx9MW1IfoD37S30QxP/WrFkzqe2gv2yFNzD0oPzNb36jisWidtP49a9/rRYvXqy2BXK5nPrQhz6kbr75ZvXYY4+pz3/+88HfT3/600ltZ8aMGerjH/+4WrJkSXB+WwrdjB955BF1/fXXqz//+c/B8b3vfe9ruQ7t/5prrlFXXnml+uc//6lWrVql3vSmN00sv/fee9Xs2bPVZZddFmz7c5/7nDrnnHPUD3/4w4kytB8awFx77bVB+aOPPlqdcMIJ6v7779/icwLx7y916CH+zne+Ux1zzDFTWj8O/aURGhDtvffeL1h9gPbuL0888YRavXr1xB/dhycD+ktE/GnitNNO80888UT/pS99qX/ZZZdN5F9++eX+3nvvHSyjMnVKpZL/4Q9/2J81a5afTqf9ww47zL/rrru0bf7lL3/xd9llFz+TyfhHHXWUf/HFF/t0yJs2bZooc8stt/iHH354UGbhwoXBNvP5/KSO/Y1vfKP/9re/fUrnffLJJwfntyU8+uijwXndfffdE3nXXXedb1mWv3LlSnGdwcFBP5lM+ldeeeVE3mOPPRZs54477mi6rw9+8IP+0Ucf3fJ49thjD//LX/7ylM4FtGd/oXb++c9/3j/33HP9ffbZZ8qXOQ795cILL/SPPPJI/4YbbjDqb7rrA7RXf7npppuatpmpgP7SmmnXwLz73e9WF1988UT6oosuUqeffrpR7uyzz1ZXXXWV+uUvf6nuu+8+tfPOO6tXv/rVwathYvny5cGvI3ob8MADD6j3vve96jOf+Yy2jaefflodd9xxwavghx56SP32t78NpojoDUtU6E3D7bffro488shJnysd65/+9Kdg3//+97+1ZV/72teC19St/pYtWxaUveOOO4LX4AceeODE+q985SuVbdvqzjvvFPdNb0uq1WpQrg5Nh9EvEdpeM4aGhoLRfTM8z1MjIyMty4Dtq7/Q8T3zzDPq3HPP3aJzjUN/efTRR9VXvvIV9atf/SrY3gtZH6A9+wtB04rz5s0L3m7TVONUQH+JgD/NI+R169YFI97nnnsu+KOR6/r167URMo1g6dcQjZ7rVCoVf/78+f43v/nNIH3OOecEbwIa+fSnP62Nbt/znvf473vf+7QyNGK2bdsvFostj3fBggV+KpUKyn7lK1+Z0jl/7Wtf85csWeLvu+++wbE1MjAw4D/11FMt/6rValD2q1/9qr/rrrsa26dfD/RrUILqjo6fc9BBB/lnn322uM5tt93mJxIJ/29/+1vTc/rGN77h9/X1+WvXrg09f9D+/eXJJ5/0Z8+e7T/xxBNBekveOGzr/YV+tdOv+UsvvbTpr+nprA/Qfv3l8ccf93/84x/799xzT3C/Pf3004N77r333jvpy43+Ek5CTTMkBj3++OPVJZdcQoOj4N8zZ840Rrb0a4jEtHWSyaQ6+OCDA10KQf8/5JBDtPVIYNoIiVRpZHz55Zc3DsiCtwjPPvtsIFptxi233BKI/v71r38FI28aoZPgNSq1Wk1dcMEF6qyzzgpEWiQE/vrXvx78m6A3GNvSWwz6xXviiScGvxpf9apXiWVoLvnLX/6y+uMf/zjpOVvQfv3FdV31tre9LWgTu+666xZd4jj0F9KHUR28/e1vF5dPZ32A9usvxG677Rb81XnZy14WHA+190svvTTyeaK/RGPaBzD113z112x003qhoAHI+9//fvWRj3zEWBYm6tpxxx2D/++1117Blwhf+tKXJjWAISEgTbXQq8dCoaA+9alPBULC+lQUvRKnv1bQ62o6zrlz56p169YZDZheIdIyCcqvVCqBmJBep9ehc+Hr0H5IbEgiRxIsS5A4js6FzqvxNTt44dlW+wu173vuuSeYZq0fH9286SZOX9/87//+r3rFK17RNv3lxhtvVA8//LD6n//5nyBN50nQA5IE8CQCnq76AO3XX5pBAyeaepoM6C9bcQBD84Z0s6BfVzTvyNlpp51UKpUK5gbpqwSCRsx33323+tjHPhakaXRL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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "L = grid.laplacian()\n", + "vals, vecs = sparse_eigsh(L.astype(float), k=9, which='SM')\n", + "vals, vecs = sorteig(vals, vecs)\n", + "\n", + "plot_eigenmodes(X, Y, vals, vecs, ny, nx)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "esapp", + "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.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/visualization/02_spectral_analysis.ipynb b/examples/visualization/02_spectral_analysis.ipynb new file mode 100644 index 00000000..c37c5a07 --- /dev/null +++ b/examples/visualization/02_spectral_analysis.ipynb @@ -0,0 +1,312 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a1b2c3d4", + "metadata": {}, + "source": [ + "# Spectral Analysis & Linear Algebra Utilities\n", + "\n", + "Demonstrates spectral graph tools, matrix decompositions, and visualization\n", + "helpers from `esapp.utils`. The notebook covers vector field visualization,\n", + "path and cycle graph Laplacians, normalized Laplacian spectral analysis,\n", + "Takagi factorization for complex symmetric matrices, the Hermitify\n", + "transformation, custom colormaps, and physical constants." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": "import numpy as np\nimport matplotlib.pyplot as plt\nfrom examples.mesh import (\n pathlap, pathincidence, normlap,\n hermitify, MU0,\n)\nfrom examples.map import format_plot, plot_vecfield, darker_hsv_colormap" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": [ + "# Plotting functions (hidden from documentation)\n", + "import sys; sys.path.insert(0, \"..\")\n", + "from plot_helpers import (\n", + " plot_vecfield_gallery, plot_graph_operators,\n", + " plot_normlap_spectrum, plot_hermitify, plot_colormap_scales,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "c9d0e1f2", + "metadata": {}, + "source": [ + "## 1. Vector Field Gallery\n", + "\n", + "Several vector fields plotted with `plot_vecfield`, which color-codes arrows by angle." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "X, Y = np.meshgrid(np.linspace(-2, 2, 30), np.linspace(-2, 2, 30))\n", + "Xc, Yc = X - 0.0, Y - 0.0\n", + "\n", + "fields = {\n", + " 'Source': (Xc, Yc),\n", + " 'Vortex': (-Yc, Xc),\n", + " 'Saddle': (Xc, -Yc),\n", + " 'Shear': (Yc, np.zeros_like(Yc)),\n", + "}\n", + "\n", + "plot_vecfield_gallery(X, Y, fields)" + ] + }, + { + "cell_type": "markdown", + "id": "e7f8a9b0", + "metadata": {}, + "source": [ + "## 2. Graph Laplacians: Path and Cycle\n", + "\n", + "`pathlap` and `pathincidence` construct Laplacians and incidence matrices for path and cycle graphs." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "graph_setup", + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": [ + "# Build path and cycle graph operators\n", + "N = 8\n", + "L_path = pathlap(N, periodic=False)\n", + "B_path = pathincidence(N, periodic=False)\n", + "L_cycle = pathlap(N, periodic=True)\n", + "B_cycle = pathincidence(N, periodic=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plot_graph_operators(\n", + " [L_path, L_cycle, B_path, B_cycle],\n", + " ['Path Laplacian', 'Cycle Laplacian', 'Path Incidence', 'Cycle Incidence'],\n", + " vranges=[(-2, 2), (-2, 2), (-1, 1), (-1, 1)],\n", + " suptitle=f'Graph Operators (N={N})')" + ] + }, + { + "cell_type": "markdown", + "id": "a5b6c7d8", + "metadata": {}, + "source": [ + "### Verify L = B @ B.T\n", + "\n", + "For the **cycle** graph, `pathincidence` returns an N x N matrix (N edges), so `B @ B.T`\n", + "matches the Laplacian directly. For the **path** graph, only the first N-1 columns\n", + "represent real edges." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e9f0a1b2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Cycle: L == B @ B.T: True\n", + "Path: L == B[:,:N-1] @ B[:,:N-1].T: False\n" + ] + } + ], + "source": [ + "# Cycle: B is N x N (N edges), so B @ B.T == L directly\n", + "L_cycle_check = B_cycle @ B_cycle.T\n", + "print(\"Cycle: L == B @ B.T:\", np.allclose(L_cycle, L_cycle_check))\n", + "\n", + "# Path: only first N-1 columns are real edges\n", + "B_path_trimmed = B_path[:, :N-1]\n", + "L_path_check = B_path_trimmed @ B_path_trimmed.T\n", + "print(\"Path: L == B[:,:N-1] @ B[:,:N-1].T:\", np.allclose(L_path, L_path_check))" + ] + }, + { + "cell_type": "markdown", + "id": "c3d4e5f6", + "metadata": {}, + "source": [ + "## 3. Normalized Laplacian and Spectral Analysis" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "L_norm, D, D_inv = normlap(L_cycle, return_scaling=True)\n", + "evals = np.linalg.eigvalsh(L_norm)\n", + "\n", + "plot_normlap_spectrum(L_norm, evals)\n", + "\n", + "print(f'Largest eigenvalue (eigmax): {eigmax(L_cycle):.4f}')" + ] + }, + { + "cell_type": "markdown", + "id": "e1f2a3b4", + "metadata": {}, + "source": [ + "## 4. Takagi Factorization\n", + "\n", + "Decomposes a complex symmetric matrix M = U * Sigma * U^T." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c5d6e7f8", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Singular values: [7.1369 5.0195 1.5215 0.8544]\n", + "Reconstruction error: 9.38e-15\n" + ] + } + ], + "source": [ + "# Create a complex symmetric matrix\n", + "np.random.seed(42)\n", + "A = np.random.randn(4, 4) + 1j * np.random.randn(4, 4)\n", + "M = A + A.T # symmetrize (M = M^T, not M = M^H)\n", + "\n", + "U, sigma = takagi(M)\n", + "\n", + "print(\"Singular values:\", np.round(sigma, 4))\n", + "\n", + "# Verify: M = U @ diag(sigma) @ U.T\n", + "M_reconstructed = U @ np.diag(sigma) @ U.T\n", + "print(f\"Reconstruction error: {np.linalg.norm(M - M_reconstructed):.2e}\")" + ] + }, + { + "cell_type": "markdown", + "id": "a9b0c1d2", + "metadata": {}, + "source": [ + "## 5. Hermitify\n", + "\n", + "Converts a complex symmetric matrix to Hermitian form." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "H = hermitify(M)\n", + "\n", + "print('Original symmetric (M = M^T):', np.allclose(M, M.T))\n", + "print('Hermitified (H = H^H): ', np.allclose(H, H.conj().T))\n", + "\n", + "plot_hermitify(M, H)" + ] + }, + { + "cell_type": "markdown", + "id": "c7d8e9f0", + "metadata": {}, + "source": [ + "## 6. Custom Colormaps\n", + "\n", + "The `darker_hsv_colormap` creates a darker version of the HSV colormap, useful for vector field angle encoding." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plot_colormap_scales([1.0, 0.7, 0.4])" + ] + }, + { + "cell_type": "markdown", + "id": "e5f6a7c8", + "metadata": {}, + "source": [ + "## 7. Physical Constants\n", + "\n", + "The `MU0` constant provides the permeability of free space, used in GIC electric field calculations." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c9d0e1g2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MU0 = 1.256637e-06 H/m\n", + "Used in GIC: E = -MU0 * dH/dt\n" + ] + } + ], + "source": [ + "print(f\"MU0 = {MU0:.6e} H/m\")\n", + "print(f\"Used in GIC: E = -MU0 * dH/dt\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "esaplus", + "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.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file diff --git a/examples/visualization/03_geographic_plotting.ipynb b/examples/visualization/03_geographic_plotting.ipynb new file mode 100644 index 00000000..d087d674 --- /dev/null +++ b/examples/visualization/03_geographic_plotting.ipynb @@ -0,0 +1,196 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a1b2c3d4e5", + "metadata": {}, + "source": [ + "# Geographic Plotting Utilities\n", + "\n", + "Demonstrates the geographic visualization functions in `examples.map` for\n", + "plotting power system data on geographic coordinates. The notebook covers\n", + "border overlays from bundled shapefiles, bus voltage visualization with\n", + "transmission network overlays, vector field quiver plots, plot formatting\n", + "options, and custom colormaps." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "from examples.map import (\n", + " format_plot, border, plot_lines, plot_vecfield,\n", + " darker_hsv_colormap,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": [ + "# Plotting functions (hidden from documentation)\n", + "import sys; sys.path.insert(0, \"..\")\n", + "from plot_helpers import (\n", + " plot_borders, plot_network_map, plot_bus_voltages_map,\n", + " plot_vecfield_map, plot_format_showcase, plot_colormap_2d,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "z6a7b8c9d0", + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "'open' took: 8.2832 sec\n" + ] + } + ], + "source": [ + "# This cell is hidden in the documentation.\n", + "from esapp import PowerWorld\n", + "from esapp.components import Branch, Bus\n", + "import ast\n", + "\n", + "with open('../data/case.txt', 'r') as f:\n", + " case_path = ast.literal_eval(f.read().strip())\n", + "\n", + "pw = PowerWorld(case_path)\n", + "\n", + "# Configure geographic border shape ('US', 'Texas', etc.)\n", + "SHAPE = 'US'" + ] + }, + { + "cell_type": "markdown", + "id": "j6k7l8m9n0", + "metadata": {}, + "source": [ + "## Network Visualization\n", + "\n", + "The function draws transmission lines from a DataFrame with\n", + "endpoint coordinates. Here we combine bus voltage scatter with\n", + "transmission lines and geographic borders." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'lines' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[8], line 5\u001b[0m\n\u001b[0;32m 2\u001b[0m vmag \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39mabs(V)\n\u001b[0;32m 4\u001b[0m fig, axes \u001b[38;5;241m=\u001b[39m plt\u001b[38;5;241m.\u001b[39msubplots(\u001b[38;5;241m1\u001b[39m, \u001b[38;5;241m2\u001b[39m, figsize\u001b[38;5;241m=\u001b[39m(\u001b[38;5;241m6.5\u001b[39m, \u001b[38;5;241m2.8\u001b[39m))\n\u001b[1;32m----> 5\u001b[0m plot_network_map(\u001b[43mlines\u001b[49m, lon, lat, SHAPE, ax\u001b[38;5;241m=\u001b[39maxes[\u001b[38;5;241m0\u001b[39m], fig\u001b[38;5;241m=\u001b[39mfig)\n\u001b[0;32m 6\u001b[0m plot_bus_voltages_map(lines, lon, lat, vmag, SHAPE, ax\u001b[38;5;241m=\u001b[39maxes[\u001b[38;5;241m1\u001b[39m], fig\u001b[38;5;241m=\u001b[39mfig)\n\u001b[0;32m 7\u001b[0m plt\u001b[38;5;241m.\u001b[39mtight_layout()\n", + "\u001b[1;31mNameError\u001b[0m: name 'lines' is not defined" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "V = pw.pflow()\n", + "vmag = np.abs(V)\n", + "\n", + "fig, axes = plt.subplots(1, 2, figsize=(6.5, 2.8))\n", + "plot_network_map(lines, lon, lat, SHAPE, ax=axes[0], fig=fig)\n", + "plot_bus_voltages_map(lines, lon, lat, vmag, SHAPE, ax=axes[1], fig=fig)\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "t6u7v8w9x0", + "metadata": {}, + "source": [ + "## Vector Field on Geographic Coordinates\n", + "\n", + "The `plot_vecfield()` function plots arrows colored by angle, useful for\n", + "electric field or power flow visualizations." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Create a synthetic vector field over the geographic area\n", + "pad = 0.5\n", + "lon_min, lon_max = lon.min() - pad, lon.max() + pad\n", + "lat_min, lat_max = lat.min() - pad, lat.max() + pad\n", + "\n", + "nx_v, ny_v = 20, 15\n", + "lons = np.linspace(lon_min, lon_max, nx_v)\n", + "lats = np.linspace(lat_min, lat_max, ny_v)\n", + "LON, LAT = np.meshgrid(lons, lats)\n", + "\n", + "Ex = 0.3 * np.sin(2 * np.pi * (LON - lon_min) / (lon_max - lon_min))\n", + "Ey = np.ones_like(LON)\n", + "\n", + "fig, axes = plt.subplots(1, 2, figsize=(6.5, 2.8))\n", + "plot_network_map(lines, lon, lat, SHAPE, ax=axes[0], fig=fig)\n", + "axes[0].set_title('Network Topology', fontsize=11)\n", + "plot_vecfield_map(LON, LAT, Ex, Ey, lines, SHAPE, ax=axes[1], fig=fig)\n", + "plt.tight_layout()\n", + "plt.show()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "esapp", + "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.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/pyproject.toml b/pyproject.toml index 15cfadd0..0223178e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -102,11 +102,9 @@ omit = [ "*/tests/*", "*/dev/*", "*/__pycache__/*", - # Auto-generated component definitions (175k+ lines, inflates coverage) - "esapp/grid.py", - # Intentionally untested modules (research/analysis code) - "esapp/utils/*", - "esapp/apps/*" + "esapp/components/grid.py", + "esapp/components/generate_components.py", + "*/examples/*" ] [tool.coverage.report] diff --git a/pytest.ini b/pytest.ini index 3fc3df3e..96871253 100644 --- a/pytest.ini +++ b/pytest.ini @@ -4,16 +4,14 @@ pythonpath = . testpaths = tests # Default command-line options -addopts = +# Note: Coverage options removed from default to allow VSCode test discovery +# Run with coverage using: pytest --cov=esapp --cov-report=term-missing --cov-report=html:htmlcov +addopts = -v -rs --strict-markers --tb=short --maxfail=5 - --cov=esapp - --cov-report=term-missing - --cov-report=html:htmlcov - --cov-config=pyproject.toml # Test discovery patterns python_files = test_*.py diff --git a/tests/README.md b/tests/README.md index 25dbf929..1108df93 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,237 +1,33 @@ # ESA++ Test Suite -**Coverage: 85.74%** (unit tests only, excluding integration) - ## Quick Start ```bash -pytest # Run all tests with coverage -pytest --no-cov # Skip coverage reporting +pytest # Run all tests pytest -k "not integration" # Unit tests only (no PowerWorld) -pytest -m "not slow" # Skip slow tests +pytest -m integration # Integration tests only ``` -**PowerWorld Setup**: Copy `config_test.example.py` → `config_test.py`, set `SAW_TEST_CASE` path. - -## Test Organization - -| Category | Files | Purpose | -|----------|-------|----------| -| **Unit Tests** | `test_exceptions.py`
`test_saw_core_methods.py`
`test_workbench.py` | Mock-based tests, no PowerWorld required | -| **Integration** | `test_integration_*.py` | Real PowerWorld case testing | -| **Component** | `test_grid_components.py`
`test_indexable_data_access.py` | Data access & grid definitions | -| **Apps** | `test_apps_network_gic.py` | High-level application testing | - -> **Note**: `test_grid_components.py` generates ~3,800 parametrized tests validating 958 auto-generated component classes. - -## Recent Changes (2026-01-25) - -### Test Consolidation -- **Merged** `test_workbench.py` + `test_workbench_unit.py` → `test_workbench.py` - - Reduced from 791 lines to 529 lines - - Eliminated duplicate tests - - Better organized with clear test class structure - - 51+ comprehensive tests covering all workbench functionality - -### Coverage Improvements -- **Overall coverage**: 85.32% → 85.74% (+0.42%) -- **Workbench coverage**: 59.35% → 62.58% (+3.23%) -- **Test count**: 3,574 tests passing (2 minor failures to fix) - -## Coverage by Module - -| Module | Coverage | Status | -|--------|----------|--------| -| `case_actions.py` | 100.00% | ✅ Fully tested | -| `modify.py` | 100.00% | ✅ Fully tested | -| `opf.py` | 100.00% | ✅ Fully tested | -| `pv.py` | 100.00% | ✅ Fully tested | -| `regions.py` | 100.00% | ✅ Fully tested | -| `saw.py` | 100.00% | ✅ Fully tested | -| `scheduled.py` | 100.00% | ✅ Fully tested | -| `sensitivity.py` | 100.00% | ✅ Fully tested | -| `weather.py` | 100.00% | ✅ Fully tested | -| `gobject.py` | 97.80% | ✅ Well tested | -| `contingency.py` | 97.30% | ✅ Well tested | -| `gic.py` | 97.67% | ✅ Well tested | -| `general.py` | 98.46% | ✅ Well tested | -| `timestep.py` | 97.14% | ✅ Well tested | -| `oneline.py` | 94.44% | ✅ Well tested | -| `qv.py` | 94.44% | ✅ Well tested | -| `powerflow.py` | 93.48% | ✅ Well tested | -| `atc.py` | 91.89% | ✅ Well tested | -| `topology.py` | 90.32% | ✅ Well tested | -| `transient.py` | 89.01% | ⚠️ CCT, results extraction | -| `matrices.py` | 84.62% | ⚠️ Matrix decomposition paths | -| `fault.py` | 81.25% | ⚠️ Fault calculation edge cases | -| `indexable.py` | 78.01% | ⚠️ Edge cases, complex filters | -| `base.py` | 69.11% | 🔴 Error handling paths | -| `workbench.py` | 62.58% | 🔴 Property accessors, advanced methods | - -**Intentionally Excluded**: -- `grid.py` — Auto-generated (175k+ lines) -- `apps/static.py`, `apps/dynamics.py` — Research code -- `utils/*` — Specialized data processing tools - -## Priority Coverage Gaps - -### High Priority (Core Functionality) -1. **workbench.py** (62.58%) - Missing: - - Property accessors (voltages_kv, generations, loads, shunts, lines, transformers, areas, zones) - - Advanced topology methods (state chain, dispatch management) - - Diff flow operations - -2. **base.py** (69.11%) - Missing: - - Error handling and recovery paths - - Complex parameter validation - - Edge cases in data transformation - -### Medium Priority -3. **indexable.py** (78.01%) - Missing: - - Complex field selection edge cases - - Error conditions in __getitem__ and __setitem__ - -4. **transient.py** (89.01%) - Missing: - - Critical clearing time (CCT) calculations - - Results extraction methods - -## Test File Structure - -``` -tests/ -├── conftest.py # Shared fixtures and utilities -├── config_test.py # User configuration (not in git) -├── config_test.example.py # Configuration template -│ -├── test_exceptions.py # Exception hierarchy tests (376 lines) -├── test_workbench.py # Workbench comprehensive tests (529 lines) -├── test_saw_core_methods.py # SAW mixin tests (2978 lines) ⚠️ Large -├── test_grid_components.py # Grid component tests (253 lines) -├── test_indexable_data_access.py # Indexable tests (578 lines) -├── test_apps_network_gic.py # Network/GIC app tests (247 lines) -│ -├── test_integration_powerflow.py # Power flow integration (299 lines) -├── test_integration_contingency.py # Contingency integration (323 lines) -├── test_integration_analysis.py # Analysis integration (290 lines) -├── test_integration_saw_powerworld.py # SAW/PW integration (331 lines) -└── test_integration_workbench.py # Workbench integration (336 lines) -``` - -> ⚠️ **Note**: `test_saw_core_methods.py` is very large (2978 lines, 37 test classes). Consider splitting into: -> - `test_saw_base.py` - Base SAW functionality -> - `test_saw_powerflow.py` - Power flow mixin tests -> - `test_saw_contingency.py` - Contingency mixin tests -> - `test_saw_analysis.py` - Analysis/sensitivity mixin tests -> - `test_saw_helpers.py` - Helper functions - -## Running Tests - -### By Category -```bash -# Unit tests only (fast, no PowerWorld) -pytest -m unit - -# Integration tests only (requires PowerWorld) -pytest -m integration +**PowerWorld Setup**: Copy `config_test.example.py` to `config_test.py` and set `SAW_TEST_CASE` path. -# Specific module -pytest tests/test_workbench.py -v +## Test Categories -# Specific test class -pytest tests/test_workbench.py::TestPowerFlowOperations -v +| Category | Description | +|----------|-------------| +| Unit | Mock-based tests, no PowerWorld required | +| Integration | Requires live PowerWorld connection | +| Component | Grid component and data access validation | -# Specific test -pytest tests/test_workbench.py::TestPowerFlowOperations::test_pflow_calls_solve -v -``` +## Running with Coverage -### With Coverage ```bash -# Full coverage report pytest --cov=esapp --cov-report=html - -# Specific module coverage -pytest --cov=esapp.workbench --cov-report=term-missing - -# Show only uncovered lines -pytest --cov=esapp --cov-report=term-missing:skip-covered -``` - -### Performance -```bash -# Run tests in parallel (faster) -pytest -n auto - -# Skip slow tests -pytest -m "not slow" - -# Run only fast unit tests -pytest -k "not integration" -m "not slow" ``` -## Troubleshooting - -| Problem | Solution | -|---------|----------| -| PowerWorld not found | Set path in `config_test.py` or environment variable `SAW_TEST_CASE` | -| Import errors | Run `pip install -e .` from repository root | -| Slow integration tests | Use `pytest -k "not integration"` or `pytest -m "not slow"` | -| Coverage report not found | Run `pytest` first, then open `htmlcov/index.html` | -| Tests fail with numpy warning | Normal, tests still pass - numpy version compatibility warning | -| COM errors in tests | Ensure mocks are properly configured in conftest.py | - -## Writing New Tests - -### Test Organization Guidelines +## Configuration -1. **File naming**: - - Unit tests: `test_.py` - - Integration tests: `test_integration_.py` - -2. **Test class naming**: - - Use descriptive names: `TestGridWorkBenchInitialization` - - Group related tests in classes - -3. **Test method naming**: - - Use descriptive names: `test_pflow_returns_voltages_by_default` - - Start with `test_` - - Describe what is being tested and expected behavior - -4. **Use fixtures**: - - Leverage `conftest.py` fixtures for common setup - - Create local fixtures for test-specific setup - -5. **Mock appropriately**: - - Unit tests: Mock external dependencies (SAW, file I/O) - - Integration tests: Use real PowerWorld connections - -### Example Test Structure +Create `config_test.py` from the example template: ```python -class TestMyFeature: - """Tests for MyFeature functionality.""" - - def test_basic_operation(self, fixture): - """Test that basic operation works correctly.""" - # Arrange - expected = "result" - - # Act - result = fixture.my_method() - - # Assert - assert result == expected - - def test_edge_case(self, fixture): - """Test edge case handling.""" - with pytest.raises(ValueError): - fixture.my_method(invalid_input) +SAW_TEST_CASE = r"C:\path\to\test_case.pwb" ``` - -## Contributing - -When adding tests: -1. Maintain or improve coverage -2. Follow existing test patterns -3. Add docstrings to test classes and methods -4. Use appropriate markers (`@pytest.mark.unit`, `@pytest.mark.integration`) -5. Update this README if adding new test categories diff --git a/tests/conftest.py b/tests/conftest.py index cfd09014..f19ec7b1 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,91 +1,97 @@ """ Global fixtures for the ESA++ test suite. -This module provides reusable test fixtures for both offline (mocked) and online -(integration) testing of the ESA++ library. Fixtures are scoped appropriately to -balance test isolation with performance. +Provides reusable test fixtures for both offline (mocked) and online +(integration) testing of the ESA++ library. """ import pytest import os -from typing import Optional, Iterator, Callable, TYPE_CHECKING +import hashlib +import tempfile +import warnings +from typing import TYPE_CHECKING from unittest.mock import Mock, patch, MagicMock from pathlib import Path if TYPE_CHECKING: from esapp.saw import SAW - from esapp.workbench import GridWorkBench try: from esapp.saw import SAW - from esapp.workbench import GridWorkBench except ImportError: - # This allows tests to be collected even if esapp is not installed, - # though online tests will be skipped. SAW = None # type: ignore - GridWorkBench = None # type: ignore def _get_test_case_path(): """ Get the test case path from configuration. - + Priority order: 1. Environment variable SAW_TEST_CASE 2. config_test.py file 3. None (skip online tests) """ - # First check environment variable env_path = os.environ.get("SAW_TEST_CASE") if env_path: return env_path - - # Try to load from config_test.py + try: import config_test if hasattr(config_test, 'SAW_TEST_CASE'): return config_test.SAW_TEST_CASE except ImportError: pass - + return None + +def _get_gic_test_cases(): + """ + Get additional GIC test case paths from configuration. + + Returns a list of (path, label) tuples for parametrization. + Only includes paths that exist on disk. + """ + try: + import config_test + if hasattr(config_test, 'GIC_TEST_CASES'): + cases = [] + for path in config_test.GIC_TEST_CASES: + if os.path.exists(path): + label = os.path.splitext(os.path.basename(path))[0] + cases.append((path, label)) + return cases + except ImportError: + pass + return [] + + +# ------------------------------------------------------------------------- +# Integration fixture (live PowerWorld) +# ------------------------------------------------------------------------- + @pytest.fixture(scope="session") def saw_session(): """ - Session-scoped fixture to manage a single PowerWorld Simulator instance - for the entire test run. - - This fixture connects to PowerWorld once at the start of the test session - and reuses the connection for all tests, improving performance. The connection - is automatically closed at the end of the session. - + Session-scoped SAW instance connected to a live PowerWorld case. + Configuration: - Set case path in config_test.py or via SAW_TEST_CASE environment variable. - - Yields - ------ - SAW - An initialized SAW instance connected to the test case. - - Raises - ------ - pytest.skip - If esapp is not installed or test case is not configured. + Set case path in config_test.py or via SAW_TEST_CASE env variable. """ if SAW is None: pytest.skip("esapp library not found.") case_path = _get_test_case_path() if not case_path: - pytest.skip("SAW test case not configured. Set path in tests/config_test.py or SAW_TEST_CASE environment variable.") - + pytest.skip("SAW test case not configured. Set path in tests/config_test.py or SAW_TEST_CASE env variable.") + if not os.path.exists(case_path): pytest.skip(f"SAW test case file not found: {case_path}") print(f"\n[Session Setup] Connecting to PowerWorld with case: {case_path}") saw = None try: - saw = SAW(case_path, early_bind=True) + saw = SAW(case_path, CreateIfNotFound=True, early_bind=True) yield saw finally: print("\n[Session Teardown] Closing case and exiting PowerWorld...") @@ -96,49 +102,126 @@ def saw_session(): print(f"Warning: Error during SAW cleanup: {e}") +# ------------------------------------------------------------------------- +# Case file integrity check +# ------------------------------------------------------------------------- + +def _file_hash(path): + """Compute SHA-256 hash of a file.""" + h = hashlib.sha256() + with open(path, "rb") as f: + for chunk in iter(lambda: f.read(1 << 20), b""): + h.update(chunk) + return h.hexdigest() + + +@pytest.fixture(scope="session") +def _case_file_hash(): + """Record the on-disk hash of the test case file at session start.""" + case_path = _get_test_case_path() + if not case_path or not os.path.exists(case_path): + yield None + return + yield _file_hash(case_path) + + +@pytest.fixture(autouse=True, scope="class") +def _check_case_file_integrity(_case_file_hash): + """Fail loudly if any test class accidentally saves over the case file.""" + yield + if _case_file_hash is None: + return + case_path = _get_test_case_path() + if not case_path or not os.path.exists(case_path): + return + current_hash = _file_hash(case_path) + if current_hash != _case_file_hash: + pytest.fail( + f"CASE FILE MODIFIED ON DISK! The test case file has been " + f"altered by a test. This will corrupt results for subsequent " + f"tests. File: {case_path}" + ) + + +# ------------------------------------------------------------------------- +# GIC multi-case fixture +# ------------------------------------------------------------------------- + +def pytest_generate_tests(metafunc): + """Parametrize tests that request the gic_saw fixture.""" + if "gic_saw" in metafunc.fixturenames: + cases = _get_gic_test_cases() + if cases: + metafunc.parametrize( + "gic_saw", + [path for path, _ in cases], + ids=[label for _, label in cases], + indirect=True, + ) + else: + # Fall back to main case + main = _get_test_case_path() + if main and os.path.exists(main): + label = os.path.splitext(os.path.basename(main))[0] + metafunc.parametrize("gic_saw", [main], ids=[label], indirect=True) + + +@pytest.fixture +def gic_saw(request, saw_session): + """ + Reuses the session SAW instance but swaps in a different case file. + + After the test, the original session case is reopened so subsequent + tests are not affected. This avoids creating a second PowerWorld COM + connection, which would conflict with the single-instance application. + """ + case_path = request.param + original_case = _get_test_case_path() + label = os.path.splitext(os.path.basename(case_path))[0] + + # Always reload the case from disk to ensure a clean state, + # even when it's the same as the session case (prior tests may + # have modified the in-memory state). + print(f"\n[GIC] Loading case: {label}") + saw_session.CloseCase() + saw_session.OpenCase(case_path) + try: + yield saw_session + finally: + # Restore the original session case if we switched to a different one + if os.path.normcase(os.path.abspath(case_path)) != os.path.normcase(os.path.abspath(original_case)): + print(f"\n[GIC] Restoring original case") + try: + saw_session.CloseCase() + saw_session.OpenCase(original_case) + except Exception: + pass + + +# ------------------------------------------------------------------------- +# Unit test fixture (mocked COM) +# ------------------------------------------------------------------------- + @pytest.fixture(scope="function") def saw_obj(): """ - Provides a function-scoped, mocked SAW object for offline unit tests. - - This fixture patches the low-level COM dispatch calls to prevent any - actual connection to PowerWorld, allowing tests to run without requiring - PowerWorld Simulator to be installed or a valid case file. - - The mock is configured with default return values for common SAW operations, - but can be customized within individual tests as needed. - - Yields - ------ - SAW - A SAW instance with mocked COM interface, suitable for testing without - PowerWorld connectivity. - - Examples - -------- - >>> def test_something(saw_obj): - ... # Customize mock behavior for this specific test - ... saw_obj._pwcom.RunScriptCommand.return_value = ("Success",) - ... result = saw_obj.RunScriptCommand("TestCommand;") - ... assert result is not None + Function-scoped mocked SAW object for offline unit tests. + + Patches COM dispatch calls to prevent actual PowerWorld connection. """ with patch("win32com.client.dynamic.Dispatch") as mock_dispatch, \ patch("win32com.client.gencache.EnsureDispatch", create=True) as mock_ensure_dispatch, \ patch("tempfile.NamedTemporaryFile") as mock_tempfile, \ patch("os.unlink"): - + mock_pwcom = MagicMock() mock_dispatch.return_value = mock_pwcom mock_ensure_dispatch.return_value = mock_pwcom - # Mock the temp file used in SAW.__init__ mock_ntf = Mock() mock_ntf.name = "dummy_temp.axd" mock_tempfile.return_value = mock_ntf - # --- Mock return values for calls made during SAW.__init__ --- - # And set default "success" return values for other common methods. - # A successful call with no data should return ('',). mock_pwcom.RunScriptCommand.return_value = ("",) mock_pwcom.ChangeParametersSingleElement.return_value = ("",) mock_pwcom.ProcessAuxFile.return_value = ("",) @@ -147,8 +230,7 @@ def saw_obj(): mock_pwcom.GetCaseHeader.return_value = ("",) mock_pwcom.ChangeParametersMultipleElementRect.return_value = ("",) mock_pwcom.GetParametersMultipleElement.return_value = ("", [[1, 2], ["Bus1", "Bus2"]]) - - mock_pwcom.OpenCase.return_value = ("",) # Simulate successful case opening + mock_pwcom.OpenCase.return_value = ("",) mock_pwcom.GetParametersSingleElement.return_value = ("", ("23", "Jan 01 2023")) field_list_data = [ ["*1*", "BusNum", "Integer", "Bus Number", "Bus Number"], @@ -156,142 +238,26 @@ def saw_obj(): ] mock_pwcom.GetFieldList.return_value = ("", field_list_data) - # Limit object field lookup to speed up test setup saw_instance = SAW(FileName="dummy.pwb") - - # Attach the mock for easy access in tests and reset it to clear __init__ calls saw_instance._pwcom = mock_pwcom yield saw_instance # ------------------------------------------------------------------------- -# Additional Utility Fixtures +# Utility fixtures # ------------------------------------------------------------------------- @pytest.fixture def temp_dir(tmp_path: Path) -> Path: - """ - Provides a temporary directory for test file operations. - - The directory is automatically cleaned up after each test. - - Parameters - ---------- - tmp_path : Path - Pytest's built-in temporary path fixture. - - Returns - ------- - Path - Path to a temporary directory unique to the test. - """ + """Temporary directory for test file operations.""" return tmp_path -@pytest.fixture -def sample_dataframe(): - """ - Provides a sample pandas DataFrame for testing data operations. - - Returns - ------- - pd.DataFrame - A DataFrame with sample bus data. - """ - import pandas as pd - return pd.DataFrame({ - "BusNum": [1, 2, 3], - "BusName": ["Bus1", "Bus2", "Bus3"], - "BusPUVolt": [1.0, 0.98, 1.02], - "BusAngle": [0.0, -2.5, 1.8] - }) - - -@pytest.fixture -def mock_power_flow_results(saw_obj): - """ - Configures the mock SAW object to return realistic power flow results. - - This fixture sets up mock return values for common power flow queries, - useful for testing workflows that depend on power flow results. - - Parameters - ---------- - saw_obj : SAW - The mocked SAW fixture. - - Returns - ------- - SAW - The configured SAW object with power flow mock data. - """ - import pandas as pd - - bus_data = pd.DataFrame({ - "BusNum": [1, 2, 3, 4, 5], - "BusName": ["Bus1", "Bus2", "Bus3", "Bus4", "Bus5"], - "BusPUVolt": [1.05, 1.02, 0.98, 1.01, 0.99], - "BusAngle": [0.0, -2.1, -5.3, -3.2, -4.5], - "BusNetMW": [100.0, -50.0, -30.0, -20.0, 0.0], - "BusNetMVR": [50.0, -20.0, -15.0, -10.0, -5.0] - }) - - def get_params_side_effect(obj_type, fields, *args, **kwargs): - if obj_type.lower() == "bus": - return bus_data[fields] - return pd.DataFrame() - - saw_obj._pwcom.GetParametersMultipleElement.side_effect = None - saw_obj.GetParametersMultipleElement = Mock(side_effect=get_params_side_effect) - - return saw_obj - - -@pytest.fixture -def reset_mock_calls(saw_obj): - """ - Fixture that resets mock call counts before each test. - - This ensures that tests don't interfere with each other's assertions - about mock call counts. Only used in unit tests with saw_obj. - - Parameters - ---------- - saw_obj : SAW - The mocked SAW fixture. - - Note - ---- - This is NOT autouse - tests must explicitly request it if needed. - """ - yield - if hasattr(saw_obj, '_pwcom'): - saw_obj._pwcom.reset_mock() - - @pytest.fixture def temp_file(): - """ - Provides a factory for creating temporary files that are automatically cleaned up. - - This fixture creates temporary files with specified suffixes and ensures they are - removed after the test completes, even if the test fails. - - Returns - ------- - callable - A function that takes a suffix (e.g., '.pwb', '.csv') and returns a temp file path. - - Examples - -------- - >>> def test_save(temp_file): - ... tmp_pwb = temp_file('.pwb') - ... save_case(tmp_pwb) - ... assert os.path.exists(tmp_pwb) - """ + """Factory for temporary files with automatic cleanup.""" import tempfile - import os files = [] def _create(suffix): @@ -301,8 +267,7 @@ def _create(suffix): return tf.name yield _create - - # Cleanup all created temp files + for f in files: if os.path.exists(f): try: @@ -312,123 +277,46 @@ def _create(suffix): # ------------------------------------------------------------------------- -# Pytest Configuration Hooks +# Test configuration # ------------------------------------------------------------------------- def pytest_configure(config): """Add custom markers for test organization.""" - config.addinivalue_line("markers", "slow: marks tests as slow (deselect with '-m \"not slow\"')") - config.addinivalue_line("markers", "integration: marks tests as integration tests requiring PowerWorld") - config.addinivalue_line("markers", "unit: marks tests as unit tests with mocked dependencies") - config.addinivalue_line("markers", "requires_case: marks tests that require a valid PowerWorld case file") - - -# ------------------------------------------------------------------------- -# Assertion Helpers -# ------------------------------------------------------------------------- - -def assert_dataframe_valid(df, expected_columns=None, min_rows=1, name="DataFrame"): - """ - Assert that a DataFrame is valid and has expected structure. - - Parameters - ---------- - df : pd.DataFrame or None - The DataFrame to validate. - expected_columns : list, optional - List of column names that must be present. - min_rows : int, optional - Minimum number of rows expected. Default is 1. - name : str, optional - Name of the DataFrame for error messages. - - Raises - ------ - AssertionError - If validation fails. - """ - import pandas as pd - - assert df is not None, f"{name} is None" - assert isinstance(df, pd.DataFrame), f"{name} is not a DataFrame" - assert len(df) >= min_rows, f"{name} has {len(df)} rows, expected at least {min_rows}" - - if expected_columns: - for col in expected_columns: - assert col in df.columns, f"{name} missing expected column: {col}" + config.addinivalue_line("markers", "slow: marks tests as slow") + config.addinivalue_line("markers", "integration: marks tests requiring PowerWorld") + config.addinivalue_line("markers", "unit: marks tests with mocked dependencies") + config.addinivalue_line("markers", "requires_case: marks tests requiring a valid case file") -def assert_voltage_reasonable(voltage, min_pu=0.5, max_pu=1.5): - """ - Assert that a voltage value is within reasonable bounds. - - Parameters - ---------- - voltage : float or array-like - Voltage value(s) in per-unit. - min_pu : float - Minimum acceptable voltage (default 0.5 pu). - max_pu : float - Maximum acceptable voltage (default 1.5 pu). - """ - import numpy as np - voltage_arr = np.atleast_1d(voltage) - assert np.all(voltage_arr >= min_pu), f"Voltage below {min_pu} pu: {voltage_arr.min()}" - assert np.all(voltage_arr <= max_pu), f"Voltage above {max_pu} pu: {voltage_arr.max()}" - - -def assert_matrix_valid(matrix, expected_shape=None, is_sparse=True): - """ - Assert that a matrix is valid. - - Parameters - ---------- - matrix : sparse matrix or ndarray - The matrix to validate. - expected_shape : tuple, optional - Expected (rows, cols) shape. - is_sparse : bool, optional - Whether matrix should be sparse. - """ - assert matrix is not None, "Matrix is None" - - if is_sparse: - assert hasattr(matrix, "toarray"), "Matrix is not sparse" - - if expected_shape: - assert matrix.shape == expected_shape, f"Matrix shape {matrix.shape} != expected {expected_shape}" +def pytest_collection_modifyitems(config, items): + """Auto-mark tests based on file naming.""" + for item in items: + if "test_integration_" in item.nodeid: + item.add_marker(pytest.mark.integration) + item.add_marker(pytest.mark.slow) + item.add_marker(pytest.mark.requires_case) + elif "test_" in item.nodeid and "test_integration_" not in item.nodeid: + item.add_marker(pytest.mark.unit) # ------------------------------------------------------------------------- -# Shared Test Utilities +# Shared test utilities # ------------------------------------------------------------------------- def get_all_gobject_subclasses(): - """ - Recursively finds all non-abstract, testable GObject subclasses. - - This utility is used by parametrized tests to discover all component types - defined in the grid module. - - Returns - ------- - list[Type[GObject]] - List of all GObject subclass types that have a _TYPE attribute. - """ + """Recursively find all GObject subclasses with a _TYPE attribute.""" try: - from esapp import grid + from esapp import components as grid except ImportError: return [] - + all_subclasses = [] q = list(grid.GObject.__subclasses__()) visited = set(q) while q: cls = q.pop(0) - # A concrete, testable GObject subclass must have a _TYPE attribute if hasattr(cls, '_TYPE'): all_subclasses.append(cls) - for subclass in cls.__subclasses__(): if subclass not in visited: visited.add(subclass) @@ -436,191 +324,171 @@ def get_all_gobject_subclasses(): return all_subclasses -def get_sample_gobject_subclasses(): - """ - Returns a representative sample of GObject subclasses for testing. - - This reduces test execution time by testing a diverse sample instead of - all component types. Use this for tests where behavior is identical across - all components (e.g., mocked unit tests). - - Returns - ------- - list[Type[GObject]] - Sample of GObject subclasses representing different categories. +def get_sample_gobject_subclasses(require_keys=False, require_multiple_editable=False, require_editable_non_key=False): + """Return a representative sample of GObject subclasses for faster parametrized tests. + + Parameters + ---------- + require_keys : bool + If True, only return classes with at least one key field. + require_multiple_editable : bool + If True, only return classes with at least 2 editable non-key fields. + require_editable_non_key : bool + If True, only return classes with at least 1 editable non-key field. """ try: - from esapp import grid + from esapp import components as grid all_classes = get_all_gobject_subclasses() - + if not all_classes: - # Return empty list if no classes found - parametrize will skip tests import warnings - warnings.warn("No GObject subclasses found. Tests will be skipped.") + warnings.warn("No GObject subclasses found.") return [] - - # Prioritize commonly used components and diverse categories - priority_types = ['Bus', 'Gen', 'Load', 'Branch', 'Shunt', 'Area', 'Zone', + + # Apply filters if requested + if require_keys: + all_classes = [c for c in all_classes if hasattr(c, 'keys') and c.keys] + + if require_editable_non_key: + def has_editable_non_key(cls): + if not hasattr(cls, 'editable') or not hasattr(cls, 'keys'): + return False + editable_non_key = [f for f in cls.editable if f not in cls.keys] + return len(editable_non_key) >= 1 + all_classes = [c for c in all_classes if has_editable_non_key(c)] + + if require_multiple_editable: + def has_multiple_editable(cls): + if not hasattr(cls, 'editable') or not hasattr(cls, 'keys'): + return False + editable_non_key = [f for f in cls.editable if f not in cls.keys] + return len(editable_non_key) >= 2 + all_classes = [c for c in all_classes if has_multiple_editable(c)] + + priority_types = ['Bus', 'Gen', 'Load', 'Branch', 'Shunt', 'Area', 'Zone', 'Contingency', 'Interface', 'InjectionGroup'] - + sample = [] for type_name in priority_types: for cls in all_classes: if hasattr(cls, 'TYPE') and cls.TYPE == type_name: sample.append(cls) break - - # If we don't have enough, add more randomly (with seed for reproducibility) + import random - random.seed(42) # Deterministic sampling for consistent test discovery + random.seed(42) remaining = [c for c in all_classes if c not in sample] if remaining and len(sample) < 15: sample.extend(random.sample(remaining, min(5, len(remaining)))) - + return sample - except ImportError as e: - import warnings - warnings.warn(f"Failed to import esapp.grid: {e}") - return [] - except Exception as e: + except (ImportError, Exception) as e: import warnings warnings.warn(f"Error getting GObject subclasses: {e}") return [] +def assert_dataframe_valid(df, expected_columns=None, min_rows=1, name="DataFrame"): + """Assert a DataFrame is valid and has expected structure.""" + import pandas as pd + assert df is not None, f"{name} is None" + assert isinstance(df, pd.DataFrame), f"{name} is not a DataFrame" + assert len(df) >= min_rows, f"{name} has {len(df)} rows, expected at least {min_rows}" + if expected_columns: + for col in expected_columns: + assert col in df.columns, f"{name} missing column: {col}" + + +def ensure_areas(saw, min_count=2): + """Ensure at least *min_count* areas exist with buses, creating if needed. + + If the case has fewer areas than *min_count*, new areas are created + and buses are reassigned from the largest area so each area has + network elements (required for ATC, directions, etc.). + + Returns the area DataFrame (guaranteed to have >= min_count rows). + """ + areas = saw.GetParametersMultipleElement("Area", ["AreaNum"]) + if areas is not None and len(areas) >= min_count: + return areas + existing = set(int(a) for a in areas["AreaNum"]) if areas is not None and not areas.empty else set() + next_num = max(existing, default=0) + 1 + buses = saw.GetParametersMultipleElement("Bus", ["BusNum", "AreaNum"]) + assert buses is not None and not buses.empty, "Test case must contain buses" + buses["BusNum"] = buses["BusNum"].astype(str) + buses["AreaNum"] = buses["AreaNum"].astype(str) + while len(existing) < min_count: + saw.CreateData("Area", ["AreaNum", "AreaName"], [next_num, f"TestArea{next_num}"]) + area_counts = buses["AreaNum"].value_counts() + largest_area = area_counts.index[0] + donor_buses = buses[buses["AreaNum"] == largest_area] + if len(donor_buses) > 1: + bus_to_move = str(donor_buses.iloc[-1]["BusNum"]) + saw.ChangeParametersSingleElement( + "Bus", ["BusNum", "AreaNum"], [bus_to_move, next_num] + ) + buses.loc[buses["BusNum"] == bus_to_move, "AreaNum"] = str(next_num) + existing.add(next_num) + next_num += 1 + return saw.GetParametersMultipleElement("Area", ["AreaNum"]) + + +@pytest.fixture(scope="class") +def save_restore_state(saw_session): + """Saves case state before destructive tests and restores it after.""" + state_name = "__test_save_restore_state__" + saw_session.StoreState(state_name) + yield saw_session + try: + saw_session.RestoreState(state_name) + saw_session.DeleteState(state_name) + except Exception: + pass + + # ------------------------------------------------------------------------- -# Additional Mocked SAW Fixtures +# PW Log Capture — on test failure the PowerWorld message log is +# retrieved and printed so you can see exactly what PW did. # ------------------------------------------------------------------------- -@pytest.fixture -def saw_with_error_responses(): - """ - Provides a SAW object configured to return errors for testing error handling. - - Use this fixture to test error paths and exception handling in code - that calls SAW methods. - - Yields - ------ - SAW - A SAW instance configured to return error responses. - """ - with patch("win32com.client.dynamic.Dispatch") as mock_dispatch, \ - patch("win32com.client.gencache.EnsureDispatch", create=True), \ - patch("tempfile.NamedTemporaryFile") as mock_tempfile, \ - patch("os.unlink"): - - mock_pwcom = MagicMock() - mock_dispatch.return_value = mock_pwcom - - mock_ntf = MagicMock() - mock_ntf.name = "dummy_temp.axd" - mock_tempfile.return_value = mock_ntf - - # Setup minimal init requirements - mock_pwcom.OpenCase.return_value = ("",) - mock_pwcom.GetParametersSingleElement.return_value = ("", ("23", "Jan 01 2023")) - mock_pwcom.GetFieldList.return_value = ("", []) - - # Setup error responses for testing - mock_pwcom.RunScriptCommand.return_value = ("Error: Test error message",) - mock_pwcom.GetParametersMultipleElement.return_value = ( - "Error: Object not found", None - ) - mock_pwcom.ChangeParametersSingleElement.return_value = ( - "Error: Could not modify object", - ) - - saw_instance = SAW(FileName="dummy.pwb") - saw_instance._pwcom = mock_pwcom - - yield saw_instance +_PW_LOG_PATH = os.path.join(tempfile.gettempdir(), "esapp_test_pw_log.txt") -@pytest.fixture -def saw_empty_case(): - """ - Provides a SAW object configured to return empty data sets. - - Use this fixture to test handling of empty results (no buses, no generators, etc.) - - Yields - ------ - SAW - A SAW instance configured to return empty data. - """ - with patch("win32com.client.dynamic.Dispatch") as mock_dispatch, \ - patch("win32com.client.gencache.EnsureDispatch", create=True), \ - patch("tempfile.NamedTemporaryFile") as mock_tempfile, \ - patch("os.unlink"): - - mock_pwcom = MagicMock() - mock_dispatch.return_value = mock_pwcom - - mock_ntf = MagicMock() - mock_ntf.name = "dummy_temp.axd" - mock_tempfile.return_value = mock_ntf - - mock_pwcom.OpenCase.return_value = ("",) - mock_pwcom.GetParametersSingleElement.return_value = ("", ("23", "Jan 01 2023")) - mock_pwcom.GetFieldList.return_value = ("", []) - - # Return empty data - mock_pwcom.RunScriptCommand.return_value = ("",) - mock_pwcom.GetParametersMultipleElement.return_value = ("", None) - - saw_instance = SAW(FileName="dummy.pwb") - saw_instance._pwcom = mock_pwcom - - yield saw_instance +@pytest.hookimpl(hookwrapper=True) +def pytest_runtest_makereport(item, call): + """Record whether the test call phase failed.""" + outcome = yield + report = outcome.get_result() + if report.when == "call" and report.failed: + item._pw_test_failed = True -@pytest.fixture -def workbench_mocked(saw_obj, sample_dataframe): - """ - Provides a mocked GridWorkBench for testing workbench functionality. - - This fixture creates a workbench with a mocked SAW backend, - useful for testing workbench operations without PowerWorld. - - Parameters - ---------- - saw_obj : SAW - The mocked SAW fixture. - sample_dataframe : pd.DataFrame - Sample data for bus results. - - Yields - ------ - GridWorkBench or Mock - A mocked workbench object, or Mock if GridWorkBench is unavailable. - """ - if GridWorkBench is None: - # Return a mock if workbench not available - mock_wb = MagicMock() - mock_wb.saw = saw_obj - yield mock_wb - else: - with patch.object(GridWorkBench, '__init__', lambda self, *args, **kwargs: None): - wb = GridWorkBench.__new__(GridWorkBench) - wb.saw = saw_obj - wb._case_path = "dummy.pwb" - yield wb +@pytest.fixture(autouse=True) +def _capture_pw_log(request, saw_session): + """Clear the PW log before each test; on failure, dump it to stdout.""" + try: + saw_session.LogClear() + except Exception: + pass + + yield + # Only retrieve the log when the test failed + if not getattr(request.node, "_pw_test_failed", False): + return -def pytest_collection_modifyitems(config, items): - """ - Auto-mark tests based on their location and naming. - - This automatically applies markers to tests based on their module, - reducing boilerplate marker declarations. - """ - for item in items: - # Mark integration tests (files starting with test_integration_) - if "test_integration_" in item.nodeid: - item.add_marker(pytest.mark.integration) - item.add_marker(pytest.mark.slow) - item.add_marker(pytest.mark.requires_case) - # Mark unit tests (all other test files) - elif "test_" in item.nodeid and "test_integration_" not in item.nodeid: - item.add_marker(pytest.mark.unit) \ No newline at end of file + try: + saw_session.LogSave(_PW_LOG_PATH) + if os.path.exists(_PW_LOG_PATH): + with open(_PW_LOG_PATH, "r", errors="replace") as f: + pw_log = f.read().strip() + if pw_log: + # Print to stdout — pytest captures this and shows it + # in the "Captured stdout teardown" section of the failure. + print(f"\n{'=' * 60}") + print(f"PW Log ({request.node.name})") + print(f"{'=' * 60}") + print(pw_log) + print(f"{'=' * 60}") + except Exception: + pass diff --git a/tests/test_apps_network_gic.py b/tests/test_apps_network_gic.py deleted file mode 100644 index e1a055b5..00000000 --- a/tests/test_apps_network_gic.py +++ /dev/null @@ -1,247 +0,0 @@ -""" -Unit tests for the esapp.apps module. - -WHAT THIS TESTS: -- Network class: incidence matrix, laplacian, bus mapping -- GIC class: model creation and calculations -- ForcedOscillation (modes) class -- BranchType enum - -These tests use mocked data and don't require PowerWorld. -""" - -import pytest -import numpy as np -import pandas as pd -from scipy.sparse import issparse -from unittest.mock import Mock, MagicMock, patch - -pytestmark = pytest.mark.unit - - -class TestBranchType: - """Tests for the BranchType enum.""" - - def test_branch_type_values(self): - from esapp.apps import BranchType - - assert BranchType.LENGTH.value == 1 - assert BranchType.RES_DIST.value == 2 - assert BranchType.DELAY.value == 3 - - def test_branch_type_names(self): - from esapp.apps import BranchType - - assert BranchType.LENGTH.name == "LENGTH" - assert BranchType.RES_DIST.name == "RES_DIST" - assert BranchType.DELAY.name == "DELAY" - - -class TestNetworkBusMap: - """Tests for Network.busmap() method.""" - - def test_busmap_returns_series(self): - """Test that busmap returns a pandas Series.""" - from esapp.apps import Network - - # Create a mock Network with bus data - network = Mock(spec=Network) - - # Create sample bus data - bus_df = pd.DataFrame({ - 'BusNum': [1, 2, 3, 5, 10], - 'BusName': ['Bus1', 'Bus2', 'Bus3', 'Bus5', 'Bus10'] - }) - - # Call actual busmap logic - busmap = pd.Series(bus_df.index, bus_df['BusNum']) - - assert isinstance(busmap, pd.Series) - assert len(busmap) == 5 - assert busmap[1] == 0 # First bus maps to index 0 - assert busmap[10] == 4 # Last bus maps to index 4 - - -class TestNetworkIncidence: - """Tests for Network.incidence() matrix generation.""" - - def test_incidence_matrix_shape(self): - """Test that incidence matrix has correct shape (branches x buses).""" - # Sample data: 3 buses, 2 branches - bus_df = pd.DataFrame({'BusNum': [1, 2, 3]}) - branch_df = pd.DataFrame({ - 'BusNum': [1, 2], - 'BusNum:1': [2, 3] - }) - - # Create busmap - busmap = pd.Series(bus_df.index, bus_df['BusNum']) - - # Build incidence matrix manually to verify logic - from scipy.sparse import lil_matrix, csc_matrix - - nbranches = len(branch_df) - nbuses = len(bus_df) - - A = lil_matrix((nbranches, nbuses)) - for i, row in branch_df.iterrows(): - from_idx = busmap[row['BusNum']] - to_idx = busmap[row['BusNum:1']] - A[i, from_idx] = -1 - A[i, to_idx] = 1 - - A = csc_matrix(A) - - assert A.shape == (2, 3) - assert issparse(A) - - def test_incidence_matrix_values(self): - """Test that incidence matrix has correct -1/+1 values.""" - # Single branch from bus 1 to bus 2 - bus_df = pd.DataFrame({'BusNum': [1, 2]}) - branch_df = pd.DataFrame({ - 'BusNum': [1], - 'BusNum:1': [2] - }) - - busmap = pd.Series(bus_df.index, bus_df['BusNum']) - - from scipy.sparse import lil_matrix, csc_matrix - - A = lil_matrix((1, 2)) - A[0, busmap[1]] = -1 - A[0, busmap[2]] = 1 - A = csc_matrix(A) - - # Convert to dense for easy assertion - A_dense = A.toarray() - - assert A_dense[0, 0] == -1 # From bus - assert A_dense[0, 1] == 1 # To bus - - -class TestNetworkLaplacian: - """Tests for Network.laplacian() matrix generation.""" - - def test_laplacian_symmetry(self): - """Test that Laplacian matrix is symmetric.""" - from scipy.sparse import lil_matrix, csc_matrix, diags - - # Create simple 3-bus network - # Bus 1 -- Bus 2 -- Bus 3 - A = lil_matrix((2, 3)) - A[0, 0] = -1; A[0, 1] = 1 # Branch 1-2 - A[1, 1] = -1; A[1, 2] = 1 # Branch 2-3 - A = csc_matrix(A) - - # Unit weights - W = np.ones(2) - - # Laplacian: A^T @ diag(W) @ A - L = A.T @ diags(W) @ A - L = L.tocsc() - - # Check symmetry - diff = (L - L.T).toarray() - assert np.allclose(diff, 0) - - def test_laplacian_row_sum_zero(self): - """Test that Laplacian row sums are approximately zero.""" - from scipy.sparse import lil_matrix, csc_matrix, diags - - # Create simple 3-bus network - A = lil_matrix((2, 3)) - A[0, 0] = -1; A[0, 1] = 1 - A[1, 1] = -1; A[1, 2] = 1 - A = csc_matrix(A) - - W = np.ones(2) - L = A.T @ diags(W) @ A - L_dense = L.toarray() - - # Row sums should be zero (property of Laplacian) - row_sums = L_dense.sum(axis=1) - assert np.allclose(row_sums, 0) - - -class TestGICModelBasics: - """Basic tests for GIC model structure.""" - - def test_gic_jac_decomp_dimensions(self): - """Test that Jacobian decomposition yields correct sub-matrix sizes.""" - from esapp.apps.gic import jac_decomp - - # Create a 6x6 Jacobian (3-bus system: 3 P equations + 3 Q equations) - nbus = 3 - jac = np.random.rand(2 * nbus, 2 * nbus) - - # Get decomposition - dP_dT, dP_dV, dQ_dT, dQ_dV = list(jac_decomp(jac)) - - # Each sub-matrix should be nbus x nbus - assert dP_dT.shape == (nbus, nbus) - assert dP_dV.shape == (nbus, nbus) - assert dQ_dT.shape == (nbus, nbus) - assert dQ_dV.shape == (nbus, nbus) - - def test_gic_jac_decomp_correct_partition(self): - """Test that Jacobian decomposition returns correct matrix sections.""" - from esapp.apps.gic import jac_decomp - - # Create identifiable 4x4 Jacobian (2-bus system) - jac = np.array([ - [1, 2, 3, 4], - [5, 6, 7, 8], - [9, 10, 11, 12], - [13, 14, 15, 16] - ]) - - dP_dT, dP_dV, dQ_dT, dQ_dV = list(jac_decomp(jac)) - - # Upper-left: dP/dTheta - assert np.array_equal(dP_dT, np.array([[1, 2], [5, 6]])) - - # Upper-right: dP/dV - assert np.array_equal(dP_dV, np.array([[3, 4], [7, 8]])) - - # Lower-left: dQ/dTheta - assert np.array_equal(dQ_dT, np.array([[9, 10], [13, 14]])) - - # Lower-right: dQ/dV - assert np.array_equal(dQ_dV, np.array([[11, 12], [15, 16]])) - - -class TestGICHelperFunctions: - """Tests for GIC helper functions.""" - - def test_fcmd_formatting(self): - """Test command string formatting.""" - from esapp.apps.gic import fcmd - - result = fcmd("Bus", "['BusNum']", "[1]") - - # Should not contain single quotes - assert "'" not in result - assert "SetData" in result - assert "Bus" in result - - def test_gicoption_formatting(self): - """Test GIC option command formatting.""" - from esapp.apps.gic import gicoption - - result = gicoption("TestOption", "TestValue") - - assert "SetData" in result - assert "GIC_Options_Value" in result - assert "TestOption" in result - assert "TestValue" in result - - -class TestModesBasics: - """Tests for ForcedOscillation (modes) module.""" - - def test_forced_oscillation_import(self): - """Test that ForcedOscillation can be imported.""" - from esapp.apps import ForcedOscillation - - assert ForcedOscillation is not None diff --git a/tests/test_dynamics.py b/tests/test_dynamics.py new file mode 100644 index 00000000..89a7eb4c --- /dev/null +++ b/tests/test_dynamics.py @@ -0,0 +1,471 @@ +""" +Unit tests for transient stability utilities. + +These are **unit tests** that do NOT require PowerWorld Simulator. All +PowerWorld interactions are mocked. They test the pure-Python transient +stability utilities: ContingencyBuilder, SimAction (esapp.utils.contingency), +TSWatch, get_ts_results, process_ts_results (esapp.utils.dynamics), and +PowerWorld.ts_solve (esapp.workbench). + +USAGE: + pytest tests/test_dynamics.py -v +""" +import pytest +from unittest.mock import MagicMock +import pandas as pd +import numpy as np + +from esapp.utils.contingency import ContingencyBuilder, SimAction +from esapp.utils.dynamics import TSWatch, get_ts_results, process_ts_results +from esapp.components import TS + + +# ============================================================================= +# SimAction Enum Tests +# ============================================================================= + +class TestSimAction: + """Tests for the SimAction enumeration.""" + + def test_fault_3pb_value(self): + """SimAction.FAULT_3PB has correct value.""" + assert SimAction.FAULT_3PB.value == "FAULT 3PB SOLID" + + def test_clear_fault_value(self): + """SimAction.CLEAR_FAULT has correct value.""" + assert SimAction.CLEAR_FAULT.value == "CLEARFAULT" + + def test_open_value(self): + """SimAction.OPEN has correct value.""" + assert SimAction.OPEN.value == "OPEN" + + def test_close_value(self): + """SimAction.CLOSE has correct value.""" + assert SimAction.CLOSE.value == "CLOSE" + + def test_simaction_is_string_enum(self): + """SimAction inherits from str for easy string formatting.""" + assert isinstance(SimAction.OPEN, str) + + +# ============================================================================= +# ContingencyBuilder Tests +# ============================================================================= + +class TestContingencyBuilder: + """Tests for the ContingencyBuilder class.""" + + def test_init_default_runtime(self): + """ContingencyBuilder initializes with default runtime of 10.0.""" + builder = ContingencyBuilder("TestCtg") + assert builder.name == "TestCtg" + assert builder.runtime == 10.0 + assert builder._current_time == 0.0 + assert builder._events == [] + + def test_init_custom_runtime(self): + """ContingencyBuilder accepts custom runtime.""" + builder = ContingencyBuilder("TestCtg", runtime=5.0) + assert builder.runtime == 5.0 + + def test_at_sets_time_cursor(self): + """at() method sets the current time cursor.""" + builder = ContingencyBuilder("TestCtg") + result = builder.at(1.5) + assert builder._current_time == 1.5 + assert result is builder # Returns self for chaining + + def test_at_negative_time_raises(self): + """at() raises ValueError for negative time.""" + builder = ContingencyBuilder("TestCtg") + with pytest.raises(ValueError, match="Time cannot be negative"): + builder.at(-1.0) + + def test_at_zero_time_allowed(self): + """at() allows time of exactly 0.""" + builder = ContingencyBuilder("TestCtg") + builder.at(0.0) + assert builder._current_time == 0.0 + + def test_add_event_with_simaction(self): + """add_event() correctly adds event with SimAction enum.""" + builder = ContingencyBuilder("TestCtg") + builder.at(1.0).add_event("Bus", "101", SimAction.FAULT_3PB) + assert len(builder._events) == 1 + assert builder._events[0] == (1.0, "Bus", "101", "FAULT 3PB SOLID") + + def test_add_event_with_string_action(self): + """add_event() correctly adds event with string action.""" + builder = ContingencyBuilder("TestCtg") + builder.at(2.0).add_event("Gen", "1 '1'", "CUSTOM_ACTION") + assert len(builder._events) == 1 + assert builder._events[0] == (2.0, "Gen", "1 '1'", "CUSTOM_ACTION") + + def test_add_event_returns_self(self): + """add_event() returns self for method chaining.""" + builder = ContingencyBuilder("TestCtg") + result = builder.add_event("Bus", "101", SimAction.OPEN) + assert result is builder + + def test_fault_bus(self): + """fault_bus() creates a 3-phase solid fault event.""" + builder = ContingencyBuilder("TestCtg") + builder.at(1.0).fault_bus("101") + assert len(builder._events) == 1 + assert builder._events[0] == (1.0, "Bus", "101", "FAULT 3PB SOLID") + + def test_fault_bus_with_integer_bus(self): + """fault_bus() converts integer bus number to string.""" + builder = ContingencyBuilder("TestCtg") + builder.at(1.0).fault_bus(101) + assert builder._events[0][2] == "101" + + def test_clear_fault(self): + """clear_fault() creates a clear fault event.""" + builder = ContingencyBuilder("TestCtg") + builder.at(1.1).clear_fault("101") + assert len(builder._events) == 1 + assert builder._events[0] == (1.1, "Bus", "101", "CLEARFAULT") + + def test_trip_gen_default_gid(self): + """trip_gen() uses default generator ID of '1'.""" + builder = ContingencyBuilder("TestCtg") + builder.at(1.0).trip_gen("101") + assert len(builder._events) == 1 + assert builder._events[0] == (1.0, "Gen", "101 '1'", "OPEN") + + def test_trip_gen_custom_gid(self): + """trip_gen() accepts custom generator ID.""" + builder = ContingencyBuilder("TestCtg") + builder.at(1.0).trip_gen("101", gid="2") + assert builder._events[0] == (1.0, "Gen", "101 '2'", "OPEN") + + def test_trip_branch_default_ckt(self): + """trip_branch() uses default circuit ID of '1'.""" + builder = ContingencyBuilder("TestCtg") + builder.at(1.0).trip_branch("101", "102") + assert len(builder._events) == 1 + assert builder._events[0] == (1.0, "Branch", "101 102 '1'", "OPEN") + + def test_trip_branch_custom_ckt(self): + """trip_branch() accepts custom circuit ID.""" + builder = ContingencyBuilder("TestCtg") + builder.at(1.0).trip_branch("101", "102", ckt="2") + assert builder._events[0] == (1.0, "Branch", "101 102 '2'", "OPEN") + + def test_method_chaining(self): + """Multiple events can be chained together.""" + builder = ContingencyBuilder("TestCtg") + (builder + .at(1.0).fault_bus("101") + .at(1.1).clear_fault("101") + .at(1.2).trip_gen("102")) + assert len(builder._events) == 3 + assert builder._events[0][0] == 1.0 + assert builder._events[1][0] == 1.1 + assert builder._events[2][0] == 1.2 + + def test_to_dataframes_empty_events(self): + """to_dataframes() returns empty element DataFrame when no events.""" + builder = ContingencyBuilder("TestCtg", runtime=5.0) + ctg_df, ele_df = builder.to_dataframes() + + assert isinstance(ctg_df, pd.DataFrame) + assert len(ctg_df) == 1 + assert ctg_df.iloc[0]['TSCTGName'] == "TestCtg" + assert ctg_df.iloc[0]['StartTime'] == 0.0 + assert ctg_df.iloc[0]['EndTime'] == 5.0 + assert ctg_df.iloc[0]['CTGSkip'] == 'NO' + + assert isinstance(ele_df, pd.DataFrame) + assert ele_df.empty + + def test_to_dataframes_with_events(self): + """to_dataframes() correctly generates element DataFrame.""" + builder = ContingencyBuilder("TestCtg", runtime=10.0) + builder.at(1.0).fault_bus("101").at(1.1).clear_fault("101") + ctg_df, ele_df = builder.to_dataframes() + + assert len(ctg_df) == 1 + assert ctg_df.iloc[0]['EndTime'] == 10.0 + + assert len(ele_df) == 2 + assert 'TSCTGName' in ele_df.columns + assert 'TSEventString' in ele_df.columns + assert 'TSTimeInSeconds' in ele_df.columns + assert 'WhoAmI' in ele_df.columns + assert 'TSTimeInCycles' in ele_df.columns + + # Check first event (fault) + assert ele_df.iloc[0]['TSCTGName'] == "TestCtg" + assert ele_df.iloc[0]['TSTimeInSeconds'] == 1.0 + assert ele_df.iloc[0]['TSTimeInCycles'] == 60.0 # 1.0 * 60 + + # Check event string format + assert "FAULT 3PB SOLID" in ele_df.iloc[0]['TSEventString'] + assert "CLEARFAULT" in ele_df.iloc[1]['TSEventString'] + + +# ============================================================================= +# TSWatch Tests +# ============================================================================= + +class TestTSWatch: + """Tests for the TSWatch utility class.""" + + def test_init_empty(self): + """TSWatch initializes with empty watch fields.""" + tsw = TSWatch() + assert tsw.fields == {} + + def test_watch_stores_fields(self): + """watch() stores field names for object type.""" + from esapp.components import Gen + tsw = TSWatch() + tsw.watch(Gen, [TS.Gen.P, TS.Gen.W]) + assert Gen in tsw.fields + assert tsw.fields[Gen] == ['TSGenP', 'TSGenW'] + + def test_watch_returns_self(self): + """watch() returns self for method chaining.""" + from esapp.components import Bus + tsw = TSWatch() + result = tsw.watch(Bus, [TS.Bus.VPU]) + assert result is tsw + + def test_watch_converts_tsfield_to_string(self): + """watch() converts TSField objects to their string names.""" + from esapp.components import Gen + tsw = TSWatch() + tsw.watch(Gen, [TS.Gen.Delta]) + assert tsw.fields[Gen] == ['TSGenDelta'] + + def test_prepare_enables_storage(self): + """prepare() calls TSResultStorageSetAll for watched types.""" + from esapp.components import Gen + tsw = TSWatch() + tsw.watch(Gen, [TS.Gen.P]) + + mock_wb = MagicMock() + mock_wb.__getitem__ = MagicMock(return_value=pd.DataFrame({'ObjectID': ['Gen 1']})) + + tsw.prepare(mock_wb) + mock_wb.esa.TSResultStorageSetAll.assert_called() + + def test_prepare_returns_field_list(self): + """prepare() returns list of field specifications.""" + from esapp.components import Bus + tsw = TSWatch() + tsw.watch(Bus, [TS.Bus.VPU]) + + mock_wb = MagicMock() + mock_wb.__getitem__ = MagicMock(return_value=pd.DataFrame({'ObjectID': ['Bus 1']})) + + fields = tsw.prepare(mock_wb) + assert isinstance(fields, list) + assert len(fields) > 0 + assert 'Bus 1 | TSBusVPU' in fields + + def test_prepare_handles_empty_objects(self): + """prepare() handles case with no objects of watched type.""" + from esapp.components import Gen + tsw = TSWatch() + tsw.watch(Gen, [TS.Gen.P]) + + mock_wb = MagicMock() + mock_wb.__getitem__ = MagicMock(return_value=pd.DataFrame({'ObjectID': []})) + + fields = tsw.prepare(mock_wb) + assert fields == [] + + +# ============================================================================= +# get_ts_results Tests +# ============================================================================= + +class TestGetTSResults: + """Tests for the get_ts_results() function.""" + + def test_returns_tuple(self): + """get_ts_results() returns tuple of DataFrames.""" + mock_esa = MagicMock() + mock_esa.TSGetResults.return_value = ( + pd.DataFrame({'ColHeader': ['Bus 1 | TSBusVPU']}), + pd.DataFrame({'time': [0.0, 0.1], 'Bus 1 | TSBusVPU': [1.0, 0.95]}) + ) + meta, data = get_ts_results(mock_esa, "Ctg1", ["Field1"]) + assert isinstance(meta, pd.DataFrame) + assert isinstance(data, pd.DataFrame) + + def test_calls_tsgetresults(self): + """get_ts_results() calls esa.TSGetResults with correct args.""" + mock_esa = MagicMock() + mock_esa.TSGetResults.return_value = (pd.DataFrame(), pd.DataFrame()) + get_ts_results(mock_esa, "Ctg1", ["Field1", "Field2"]) + mock_esa.TSGetResults.assert_called_once_with( + "SEPARATE", ["Ctg1"], ["Field1", "Field2"] + ) + + def test_handles_none(self): + """get_ts_results() returns (None, None) when TSGetResults returns None.""" + mock_esa = MagicMock() + mock_esa.TSGetResults.return_value = None + meta, data = get_ts_results(mock_esa, "Ctg1", ["Field1"]) + assert meta is None + assert data is None + + +# ============================================================================= +# process_ts_results Tests +# ============================================================================= + +class TestProcessTSResults: + """Tests for the process_ts_results() function.""" + + def test_sets_time_index(self): + """process_ts_results() sets 'time' column as index.""" + meta = pd.DataFrame({'ColHeader': ['Col1'], 'ObjectType': ['Bus'], + 'PrimaryKey': ['1'], 'SecondaryKey': [None], 'VariableName': ['VPU']}) + df = pd.DataFrame({'time': [0.0, 0.1], 'Col1': [1.0, 0.95]}) + + _, result_df = process_ts_results(meta, df, "Ctg1") + assert result_df.index.name == "time" + + def test_renames_columns(self): + """process_ts_results() renames metadata columns.""" + meta = pd.DataFrame({'ColHeader': ['Col1'], 'ObjectType': ['Bus'], + 'PrimaryKey': ['1'], 'SecondaryKey': [None], 'VariableName': ['VPU']}) + df = pd.DataFrame({'time': [0.0], 'Col1': [1.0]}) + + result_meta, _ = process_ts_results(meta, df, "Ctg1") + assert 'Object' in result_meta.columns + assert 'ID-A' in result_meta.columns + assert 'Metric' in result_meta.columns + assert 'Contingency' in result_meta.columns + + def test_handles_empty_df(self): + """process_ts_results() returns empty DataFrames for empty input.""" + meta = pd.DataFrame() + df = pd.DataFrame() + + result_meta, result_df = process_ts_results(meta, df, "Ctg1") + assert result_meta.empty + assert result_df.empty + + def test_handles_none_df(self): + """process_ts_results() handles None DataFrame.""" + meta = pd.DataFrame({'ColHeader': ['Col1']}) + + result_meta, result_df = process_ts_results(meta, None, "Ctg1") + assert result_meta.empty + assert result_df.empty + + def test_casts_to_float32(self): + """process_ts_results() casts data to float32.""" + meta = pd.DataFrame({'ColHeader': ['Col1'], 'ObjectType': ['Bus'], + 'PrimaryKey': ['1'], 'SecondaryKey': [None], 'VariableName': ['VPU']}) + df = pd.DataFrame({'time': [0.0], 'Col1': [1.0]}) + + _, result_df = process_ts_results(meta, df, "Ctg1") + assert result_df['Col1'].dtype == np.float32 + + def test_no_matching_columns(self): + """process_ts_results() handles case where no columns match metadata.""" + meta = pd.DataFrame({'ColHeader': ['NonExistent'], 'ObjectType': ['Bus'], + 'PrimaryKey': ['1'], 'SecondaryKey': [None], 'VariableName': ['VPU']}) + df = pd.DataFrame({'time': [0.0], 'DifferentCol': [1.0]}) + + result_meta, result_df = process_ts_results(meta, df, "Ctg1") + assert result_meta.empty + assert result_df.empty + + def test_no_time_column(self): + """process_ts_results() handles DataFrame without time column.""" + meta = pd.DataFrame({'ColHeader': ['Col1'], 'ObjectType': ['Bus'], + 'PrimaryKey': ['1'], 'SecondaryKey': [None], 'VariableName': ['VPU']}) + df = pd.DataFrame({'Col1': [1.0, 0.95]}) + + result_meta, result_df = process_ts_results(meta, df, "Ctg1") + assert not result_df.empty + + +# ============================================================================= +# PowerWorld.ts_solve Tests +# ============================================================================= + +class TestTSSolve: + """Tests for PowerWorld.ts_solve() method.""" + + @pytest.fixture + def mock_wb(self): + """Create a mock workbench with ESA for ts_solve testing.""" + from esapp.workbench import PowerWorld + + pw = object.__new__(PowerWorld) + pw.esa = MagicMock() + pw.esa.TSAutoCorrect.return_value = None + pw.esa.TSInitialize.return_value = None + pw.esa.TSSolve.return_value = None + pw.esa.TSGetResults.return_value = ( + pd.DataFrame({'ColHeader': ['Col1'], 'ObjectType': ['Bus'], + 'PrimaryKey': ['1'], 'SecondaryKey': [None], 'VariableName': ['VPU']}), + pd.DataFrame({'time': [0.0, 0.1], 'Col1': [1.0, 0.95]}) + ) + return pw + + def test_accepts_single_contingency(self, mock_wb): + """ts_solve() accepts a single contingency name as string.""" + meta, data = mock_wb.ts_solve("Fault1", ["Col1"]) + mock_wb.esa.TSSolve.assert_called_once_with("Fault1") + + def test_accepts_list_of_contingencies(self, mock_wb): + """ts_solve() accepts a list of contingency names.""" + mock_wb.ts_solve(["Fault1", "Fault2"], ["Col1"]) + assert mock_wb.esa.TSSolve.call_count == 2 + + def test_calls_ts_initialize(self, mock_wb): + """ts_solve() calls TSAutoCorrect and TSInitialize.""" + mock_wb.ts_solve("Fault1", ["Col1"]) + mock_wb.esa.TSAutoCorrect.assert_called_once() + mock_wb.esa.TSInitialize.assert_called_once() + + def test_returns_empty_when_no_results(self, mock_wb): + """ts_solve() returns empty DataFrames when no results.""" + mock_wb.esa.TSGetResults.return_value = (None, None) + meta, data = mock_wb.ts_solve("Fault1", ["Col1"]) + assert meta.empty + assert data.empty + + def test_handles_empty_df_in_results(self, mock_wb): + """ts_solve() handles empty DataFrame in results.""" + mock_wb.esa.TSGetResults.return_value = ( + pd.DataFrame({'ColHeader': ['Col1']}), + pd.DataFrame() + ) + meta, data = mock_wb.ts_solve("Fault1", ["Col1"]) + assert meta.empty + assert data.empty + + def test_warns_no_fields(self, mock_wb, caplog): + """ts_solve() logs warning when no fields are provided.""" + import logging + mock_wb.esa.TSGetResults.return_value = (None, None) + with caplog.at_level(logging.WARNING): + mock_wb.ts_solve("Fault1", []) + assert "No fields provided" in caplog.text + + +# ============================================================================= +# TS Component Import Tests +# ============================================================================= + +class TestTSImport: + """Tests for TS import from esapp.components.""" + + def test_ts_has_gen(self): + """TS has Gen attribute.""" + assert hasattr(TS, 'Gen') + + def test_ts_has_bus(self): + """TS has Bus attribute.""" + assert hasattr(TS, 'Bus') diff --git a/tests/test_exceptions.py b/tests/test_exceptions.py deleted file mode 100644 index 0ada90f0..00000000 --- a/tests/test_exceptions.py +++ /dev/null @@ -1,376 +0,0 @@ -""" -Unit tests for exception handling in the esapp module. - -WHAT THIS TESTS: -- Custom exception hierarchy (PowerWorldError, COMError, SimAutoFeatureError, etc.) -- Exception instantiation and message handling -- Error parsing from PowerWorld COM interface responses -- Specific error type detection (prerequisite, add-on, command failures) -- SAW error handling patterns with mocked responses - -DEPENDENCIES: None (mocked, no PowerWorld required) - -USAGE: - pytest tests/test_exceptions.py -v -""" -import pytest -from unittest.mock import Mock, patch, MagicMock -from typing import Type - -try: - from esapp.saw._exceptions import ( - Error, - PowerWorldError, - PowerWorldPrerequisiteError, - PowerWorldAddonError, - CommandNotRespectedError, - COMError, - SimAutoFeatureError, - RPC_S_UNKNOWN_IF, - RPC_S_CALL_FAILED, - ) - from esapp.saw import SAW - from esapp.utils.exceptions import ESAPlusError -except ImportError: - pytest.skip("esapp library not found", allow_module_level=True) - - -# ------------------------------------------------------------------------- -# Exception Hierarchy Tests -# ------------------------------------------------------------------------- - -def test_exception_hierarchy(): - """Test that custom exceptions have proper inheritance.""" - assert issubclass(PowerWorldError, Error) - assert issubclass(PowerWorldPrerequisiteError, PowerWorldError) - assert issubclass(PowerWorldAddonError, PowerWorldError) - assert issubclass(CommandNotRespectedError, PowerWorldError) - assert issubclass(COMError, Error) - - -def test_exception_instantiation(): - """Test that exceptions can be instantiated with messages.""" - msg = "Test error message" - - err = PowerWorldError(msg) - assert str(err) == msg - assert err.message == msg - - err2 = CommandNotRespectedError(msg) - assert str(err2) == msg - - -# ------------------------------------------------------------------------- -# PowerWorld Error Tests -# ------------------------------------------------------------------------- - -def test_powerworld_error_parsing(): - """Test that PowerWorld error messages are parsed correctly.""" - error_msg = "Error: Bus 123 not found in case" - - err = PowerWorldError(error_msg) - assert "Bus 123" in str(err) - assert "not found" in str(err) - - -@pytest.mark.parametrize("error_class,expected_type", [ - (PowerWorldPrerequisiteError, PowerWorldPrerequisiteError), - (PowerWorldAddonError, PowerWorldAddonError), - (CommandNotRespectedError, CommandNotRespectedError), -]) -def test_specific_powerworld_errors(error_class: Type[Exception], expected_type: Type[Exception]): - """Test specific PowerWorld error types.""" - msg = "Specific error" - err = error_class(msg) - assert isinstance(err, expected_type) - assert isinstance(err, PowerWorldError) - - -# ------------------------------------------------------------------------- -# COM Error Tests -# ------------------------------------------------------------------------- - -def test_com_error_instantiation(): - """Test COMError with different message formats.""" - err1 = COMError("Simple COM error") - assert "Simple COM error" in str(err1) - - err2 = COMError(RPC_S_UNKNOWN_IF) - assert str(err2) == str(RPC_S_UNKNOWN_IF) - - -def test_rpc_error_constants(): - """Test that RPC error constants are defined.""" - assert isinstance(RPC_S_UNKNOWN_IF, int) - assert isinstance(RPC_S_CALL_FAILED, int) - assert RPC_S_UNKNOWN_IF != RPC_S_CALL_FAILED - - -# ------------------------------------------------------------------------- -# SAW Error Handling Tests (with mocking) -# ------------------------------------------------------------------------- - -@pytest.fixture -def saw_with_error_mock(): - """Create a mocked SAW instance that raises errors.""" - with patch("win32com.client.dynamic.Dispatch") as mock_dispatch, \ - patch("win32com.client.gencache.EnsureDispatch", create=True), \ - patch("tempfile.NamedTemporaryFile"), \ - patch("os.unlink"): - - mock_pwcom = MagicMock() - mock_dispatch.return_value = mock_pwcom - - # Set up default error-free responses for __init__ - mock_pwcom.OpenCase.return_value = ("",) - mock_pwcom.GetParametersSingleElement.return_value = ("", ("23", "Jan 01 2023")) - mock_pwcom.GetFieldList.return_value = ("", []) - - saw = SAW(FileName="dummy.pwb") - saw._pwcom = mock_pwcom - - yield saw - - -def test_saw_handles_command_errors(saw_with_error_mock): - """Test that SAW properly raises errors for failed commands.""" - saw = saw_with_error_mock - - # Simulate a PowerWorld error - error_msg = "Error: Invalid command syntax" - saw._pwcom.RunScriptCommand.return_value = (error_msg,) - - with pytest.raises(PowerWorldError, match="Invalid command"): - saw.RunScriptCommand("InvalidCommand") - - -def test_saw_handles_com_errors(saw_with_error_mock): - """Test that SAW handles COM errors appropriately.""" - import pywintypes - - saw = saw_with_error_mock - - # Simulate a COM error - com_error = pywintypes.com_error(RPC_S_UNKNOWN_IF, "COM Error", None, None) - saw._pwcom.RunScriptCommand.side_effect = com_error - - with pytest.raises(COMError): - saw.RunScriptCommand("AnyCommand") - - -def test_saw_prerequisite_error(): - """Test PowerWorldPrerequisiteError is raised for missing prerequisites.""" - # Example: trying to run transient analysis without TS initialized - with patch("win32com.client.dynamic.Dispatch") as mock_dispatch, \ - patch("win32com.client.gencache.EnsureDispatch", create=True), \ - patch("tempfile.NamedTemporaryFile"), \ - patch("os.unlink"): - - mock_pwcom = MagicMock() - mock_dispatch.return_value = mock_pwcom - - mock_pwcom.OpenCase.return_value = ("",) - mock_pwcom.GetParametersSingleElement.return_value = ("", ("23", "Jan 01 2023")) - mock_pwcom.GetFieldList.return_value = ("", []) - - saw = SAW(FileName="dummy.pwb") - saw._pwcom = mock_pwcom - - # Simulate prerequisite error - error_msg = "Error: Transient stability not initialized" - saw._pwcom.RunScriptCommand.return_value = (error_msg,) - - # The actual implementation would parse this and raise PowerWorldPrerequisiteError - # For now, test that the error contains the right message - result = saw._pwcom.RunScriptCommand("TSSolve") - assert "not initialized" in result[0] - - -# ------------------------------------------------------------------------- -# Error Message Quality Tests -# ------------------------------------------------------------------------- - -def test_error_messages_are_informative(): - """Test that error messages provide actionable information.""" - errors_and_expectations = [ - (PowerWorldError("Bus not found"), "Bus"), - (CommandNotRespectedError("Solve failed"), "failed"), - (PowerWorldAddonError("Add-on required"), "Add-on"), - ] - - for error, expected_content in errors_and_expectations: - assert expected_content in str(error), \ - f"Error message should contain '{expected_content}'" - - -def test_error_repr(): - """Test that exceptions have useful repr for debugging.""" - err = PowerWorldError("Test error") - repr_str = repr(err) - assert "PowerWorldError" in repr_str - assert "Test error" in repr_str - - -# ------------------------------------------------------------------------- -# Utils Exception Tests -# ------------------------------------------------------------------------- - -def test_esaplus_error(): - """Test the general ESAPlus error class if it exists.""" - try: - err = ESAPlusError("General error") - assert "General error" in str(err) - except NameError: - pytest.skip("ESAPlusError not defined") - - -# ------------------------------------------------------------------------- -# Exception Context Tests -# ------------------------------------------------------------------------- - -def test_exception_chaining(): - """Test that exceptions can be chained for context.""" - original = ValueError("Original error") - - try: - try: - raise original - except ValueError as e: - raise PowerWorldError("PowerWorld error occurred") from e - except PowerWorldError as pwe: - assert pwe.__cause__ is original - assert isinstance(pwe.__cause__, ValueError) - - -def test_exception_with_traceback_info(): - """Test that exceptions preserve useful traceback information.""" - try: - raise PowerWorldError("Error with traceback") - except PowerWorldError as e: - import traceback - tb_str = ''.join(traceback.format_exception(type(e), e, e.__traceback__)) - assert "test_exception_with_traceback_info" in tb_str - assert "PowerWorldError" in tb_str - - -# ------------------------------------------------------------------------- -# Error Path Tests - Specific Scenarios -# ------------------------------------------------------------------------- - -class TestErrorPathScenarios: - """Tests for specific error paths in SAW operations.""" - - @pytest.fixture - def mock_saw(self): - """Create a fresh mocked SAW for each test.""" - with patch("win32com.client.dynamic.Dispatch") as mock_dispatch, \ - patch("win32com.client.gencache.EnsureDispatch", create=True), \ - patch("tempfile.NamedTemporaryFile"), \ - patch("os.unlink"): - - mock_pwcom = MagicMock() - mock_dispatch.return_value = mock_pwcom - - mock_pwcom.OpenCase.return_value = ("",) - mock_pwcom.GetParametersSingleElement.return_value = ("", ("23", "Jan 01 2023")) - mock_pwcom.GetFieldList.return_value = ("", []) - mock_pwcom.RunScriptCommand.return_value = ("",) - mock_pwcom.GetParametersMultipleElement.return_value = ("", [[1, 2], ["A", "B"]]) - - saw = SAW(FileName="dummy.pwb") - saw._pwcom = mock_pwcom - - yield saw - - def test_addon_error_detection(self, mock_saw): - """Test that add-on errors are detected and raised as PowerWorldAddonError.""" - # Simulate an add-on not registered error - mock_saw._pwcom.RunScriptCommand.return_value = ( - "Error: Add-on 'TransLineCalc' is not registered", - ) - - with pytest.raises(PowerWorldError) as exc_info: - mock_saw.RunScriptCommand("CalculateRXBG") - - assert "Add-on" in str(exc_info.value) or "not registered" in str(exc_info.value) - - def test_empty_data_returns_none(self, mock_saw): - """Test that empty data returns None or empty DataFrame.""" - mock_saw._pwcom.GetParametersMultipleElement.return_value = ("", None) - - result = mock_saw.GetParametersMultipleElement("Bus", ["BusNum"]) - assert result is None or (hasattr(result, "empty") and result.empty) - - def test_object_not_found_error(self, mock_saw): - """Test error when object type is not found.""" - mock_saw._pwcom.RunScriptCommand.return_value = ( - "Error: Object type 'InvalidObject' not found", - ) - - with pytest.raises(PowerWorldError): - mock_saw.RunScriptCommand("SelectAll(InvalidObject)") - - def test_case_not_open_error(self, mock_saw): - """Test error when no case is open.""" - mock_saw._pwcom.RunScriptCommand.return_value = ( - "Error: No case is currently open", - ) - - with pytest.raises(PowerWorldError): - mock_saw.RunScriptCommand("SolvePowerFlow") - - def test_multiple_errors_in_response(self, mock_saw): - """Test handling of multiple errors in a single response.""" - mock_saw._pwcom.RunScriptCommand.return_value = ( - "Error: First error\nError: Second error", - ) - - with pytest.raises(PowerWorldError) as exc_info: - mock_saw.RunScriptCommand("BadCommand") - - # Should contain at least the first error - assert "error" in str(exc_info.value).lower() - - def test_warning_vs_error_handling(self, mock_saw): - """Test that warnings are handled differently from errors.""" - # Some PowerWorld responses are warnings, not errors - mock_saw._pwcom.RunScriptCommand.return_value = ("",) # No error - - # Should not raise - mock_saw.RunScriptCommand("ValidCommand") - - def test_get_parameters_with_invalid_fields(self, mock_saw): - """Test error when requesting invalid field names.""" - mock_saw._pwcom.GetParametersMultipleElement.return_value = ( - "Error: Field 'InvalidField' not found for object type 'Bus'", - None - ) - - with pytest.raises(PowerWorldError): - mock_saw.GetParametersMultipleElement("Bus", ["InvalidField"]) - - -class TestCOMErrorRecovery: - """Tests for COM error scenarios and recovery.""" - - def test_com_error_with_rpc_call_failed(self): - """Test handling of RPC_S_CALL_FAILED error.""" - err = COMError(RPC_S_CALL_FAILED) - assert isinstance(err, Error) - - def test_com_error_message_preservation(self): - """Test that COM error messages are preserved.""" - import pywintypes - - # Simulate a COM error with a description - com_err = pywintypes.com_error( - -2147352567, # DISP_E_EXCEPTION - "Automation error", - ("Error", 0, "Description of error", None, 0, -2147024809), - None - ) - - # The exception should be constructable from this - wrapped_err = COMError(str(com_err)) - assert "error" in str(wrapped_err).lower() - diff --git a/tests/test_gobject.py b/tests/test_gobject.py new file mode 100644 index 00000000..c766fcb1 --- /dev/null +++ b/tests/test_gobject.py @@ -0,0 +1,143 @@ +""" +Unit tests for the GObject base class and FieldPriority flag. + +These are **unit tests** that do NOT require PowerWorld Simulator. They test +GObject schema construction, field access, string representation, and +bitwise FieldPriority flag operations. + +USAGE: + pytest tests/test_gobject.py -v +""" +import pytest + +from esapp.components.gobject import GObject, FieldPriority +from esapp import components as grid + + +class TestGObjectReprStr: + """Test __repr__ and __str__ methods.""" + + def test_str_type_defining_member(self): + """str() on type-defining member returns the member name.""" + # ObjectString is the type-defining member with an int value (not a tuple) + type_member = grid.Bus.ObjectString + assert isinstance(type_member._value_, int) + assert str(type_member) == "ObjectString" + + def test_repr_type_defining_member(self): + """repr() on type-defining member shows TYPE info.""" + type_member = grid.Bus.ObjectString + result = repr(type_member) + assert "Bus.ObjectString" in result + assert "TYPE=" in result + + def test_str_field_member(self): + """str() on field member returns the PowerWorld field name.""" + # Get a field member (not the type-defining member) + for member in grid.Bus: + if member.name != "_": + field_str = str(member) + # Field members have a tuple value where _value_[1] is the field name + assert isinstance(field_str, str) + assert field_str # Not empty + break + + def test_repr_field_member(self): + """repr() on field member shows field info.""" + for member in grid.Bus: + if member.name != "_": + result = repr(member) + assert "Field=" in result + break + + +class TestFieldPriority: + """Test FieldPriority flag combinations.""" + + def test_primary_flag(self): + """PRIMARY flag can be checked with bitwise AND.""" + priority = FieldPriority.PRIMARY + assert priority & FieldPriority.PRIMARY == FieldPriority.PRIMARY + + def test_combined_flags(self): + """Flags can be combined and checked individually.""" + priority = FieldPriority.PRIMARY | FieldPriority.EDITABLE + assert priority & FieldPriority.PRIMARY == FieldPriority.PRIMARY + assert priority & FieldPriority.EDITABLE == FieldPriority.EDITABLE + assert priority & FieldPriority.SECONDARY != FieldPriority.SECONDARY + + +class TestGObjectProperties: + """Test GObject class properties.""" + + def test_keys_property(self): + """keys property returns primary key fields.""" + assert isinstance(grid.Bus.keys, list) + assert "BusNum" in grid.Bus.keys + + def test_fields_property(self): + """fields property returns all field names.""" + assert isinstance(grid.Bus.fields, list) + assert len(grid.Bus.fields) > 0 + + def test_secondary_property(self): + """secondary property returns secondary identifier fields.""" + # Gen has secondary identifiers (alternate keys, base values) + assert isinstance(grid.Gen.secondary, list) + # BusName_NomVolt is a secondary identifier (alternate key) + assert "BusName_NomVolt" in grid.Gen.secondary + + def test_editable_property(self): + """editable property returns editable fields.""" + assert isinstance(grid.Bus.editable, list) + + def test_identifiers_property(self): + """identifiers includes both primary and secondary keys.""" + identifiers = grid.Gen.identifiers + assert isinstance(identifiers, set) + assert "BusNum" in identifiers # Primary key + assert "GenID" in identifiers # Primary key (composite) + + def test_settable_property(self): + """settable includes identifiers and editable fields.""" + settable = grid.Bus.settable + assert isinstance(settable, set) + + def test_is_editable_method(self): + """is_editable correctly identifies editable fields.""" + editable_fields = grid.Bus.editable + if editable_fields: + assert grid.Bus.is_editable(editable_fields[0]) is True + # Non-existent field should return False + assert grid.Bus.is_editable("NonExistentField") is False + + def test_is_settable_method(self): + """is_settable correctly identifies settable fields.""" + # Key fields are settable + key = grid.Bus.keys[0] + assert grid.Bus.is_settable(key) is True + # Non-existent field should return False + assert grid.Bus.is_settable("NonExistentField") is False + + def test_type_property(self): + """TYPE property returns the PowerWorld object type string.""" + assert grid.Bus.TYPE == "Bus" + assert grid.Gen.TYPE == "Gen" + assert grid.Load.TYPE == "Load" + + +class TestGObjectWithoutType: + """Test edge cases with GObject base class.""" + + def test_base_gobject_type_default(self): + """Base GObject class returns default TYPE when not set.""" + # GObject itself has no _TYPE attribute, should return default + assert GObject.TYPE == "NO_OBJECT_NAME" + + def test_base_gobject_empty_keys(self): + """Base GObject class returns empty keys list.""" + assert GObject.keys == [] + + def test_base_gobject_empty_fields(self): + """Base GObject class returns empty fields list.""" + assert GObject.fields == [] diff --git a/tests/test_grid_components.py b/tests/test_grid_components.py index 00b538c5..809964b5 100644 --- a/tests/test_grid_components.py +++ b/tests/test_grid_components.py @@ -1,33 +1,23 @@ """ -Unit tests for GObject and FieldPriority from esapp.grid module. +Unit tests for GObject metaclass and auto-generated component classes. -WHAT THIS TESTS: -- FieldPriority flag enum functionality and bitwise operations -- GObject metaclass behavior and field collection -- Component class generation from PowerWorld object definitions -- Field type validation across all component types (Bus, Gen, Load, etc.) -- Docstring presence and name collision detection - -DEPENDENCIES: None (mocked, no PowerWorld required) +These are **unit tests** that do NOT require PowerWorld Simulator. They test +field collection, key/editable/settable classification, and validate that all +auto-generated component classes from grid.py are well-formed. USAGE: pytest tests/test_grid_components.py -v """ import pytest -import inspect -from enum import Flag -from typing import Type, List - -from esapp import grid +from typing import Type -# Import shared test utility -from conftest import get_all_gobject_subclasses +from esapp import components as grid +from tests.conftest import get_all_gobject_subclasses -# --- Fixtures --- @pytest.fixture(scope="module") def test_gobject_class() -> Type[grid.GObject]: - """A simple GObject subclass for testing purposes.""" + """A simple GObject subclass for testing metaclass behavior.""" class TestGObject(grid.GObject): ID = ("id", int, grid.FieldPriority.PRIMARY) NAME = ("name", str, grid.FieldPriority.SECONDARY | grid.FieldPriority.REQUIRED) @@ -36,219 +26,65 @@ class TestGObject(grid.GObject): ObjectString = "TestGObject" return TestGObject -# --- Tests for FieldPriority --- - -def test_fieldpriority_is_flag(): - """Ensures FieldPriority is a Flag enum, allowing bitwise operations.""" - assert issubclass(grid.FieldPriority, Flag) - -def test_fieldpriority_combinations(): - """Tests bitwise combinations of FieldPriority flags.""" - primary_required = grid.FieldPriority.PRIMARY | grid.FieldPriority.REQUIRED - assert grid.FieldPriority.PRIMARY in primary_required - assert grid.FieldPriority.REQUIRED in primary_required - assert grid.FieldPriority.SECONDARY not in primary_required - -# --- Tests for GObject --- - -def test_gobject_type_is_set(test_gobject_class): - """Tests that the _TYPE class attribute is correctly set from ObjectString.""" - assert test_gobject_class.TYPE == "TestGObject" - -def test_gobject_with_no_type(): - """Tests GObject subclass without an ObjectString.""" - class NoTypeObject(grid.GObject): - FIELD = ("field", str, grid.FieldPriority.OPTIONAL) - - assert NoTypeObject.TYPE == 'NO_OBJECT_NAME' def test_gobject_fields_are_collected(test_gobject_class): - """Tests that all field names are collected in the .fields property.""" - expected_fields = ['id', 'name', 'value', 'duplicate_key'] - assert test_gobject_class.fields == expected_fields + """All field names are collected in the .fields property.""" + assert test_gobject_class.fields == ['id', 'name', 'value', 'duplicate_key'] + def test_gobject_keys_are_collected(test_gobject_class): - """ - Tests that PRIMARY fields are collected in the .keys property. - """ - expected_keys = ['id', 'duplicate_key'] - assert test_gobject_class.keys == expected_keys + """PRIMARY fields are collected in .keys.""" + assert test_gobject_class.keys == ['id', 'duplicate_key'] -def test_gobject_editable_fields_are_collected(test_gobject_class): - """Tests that EDITABLE fields are collected in the .editable property.""" - expected_editable = ['value'] - assert test_gobject_class.editable == expected_editable +def test_gobject_editable_fields(test_gobject_class): + """EDITABLE fields are collected in .editable.""" + assert test_gobject_class.editable == ['value'] -def test_gobject_secondary_fields_are_collected(test_gobject_class): - """Tests that SECONDARY fields are collected in the .secondary property.""" - # NAME is SECONDARY, DUPLICATE_KEY is both PRIMARY and SECONDARY - expected_secondary = ['name', 'duplicate_key'] - assert test_gobject_class.secondary == expected_secondary +def test_gobject_secondary_fields(test_gobject_class): + """SECONDARY fields are collected in .secondary.""" + assert test_gobject_class.secondary == ['name', 'duplicate_key'] def test_gobject_identifiers(test_gobject_class): - """Tests that identifiers returns primary + secondary keys.""" - # id and duplicate_key are PRIMARY, name and duplicate_key are SECONDARY - expected_identifiers = {'id', 'name', 'duplicate_key'} - assert test_gobject_class.identifiers == expected_identifiers + """identifiers returns union of primary + secondary keys.""" + assert test_gobject_class.identifiers == {'id', 'name', 'duplicate_key'} def test_gobject_settable_fields(test_gobject_class): - """Tests that settable returns identifiers (primary + secondary) + editable fields.""" - # identifiers: id, name, duplicate_key; editable: value - expected_settable = {'id', 'name', 'duplicate_key', 'value'} - assert test_gobject_class.settable == expected_settable + """settable returns identifiers + editable fields.""" + assert test_gobject_class.settable == {'id', 'name', 'duplicate_key', 'value'} def test_gobject_is_editable(test_gobject_class): - """Tests is_editable() helper method.""" assert test_gobject_class.is_editable('value') is True assert test_gobject_class.is_editable('id') is False - assert test_gobject_class.is_editable('name') is False assert test_gobject_class.is_editable('nonexistent') is False def test_gobject_is_settable(test_gobject_class): - """Tests is_settable() helper method.""" - assert test_gobject_class.is_settable('value') is True # Editable - assert test_gobject_class.is_settable('id') is True # Primary key - assert test_gobject_class.is_settable('duplicate_key') is True # Primary + Secondary key - assert test_gobject_class.is_settable('name') is True # Secondary key (identifier) + assert test_gobject_class.is_settable('value') is True + assert test_gobject_class.is_settable('id') is True + assert test_gobject_class.is_settable('name') is True assert test_gobject_class.is_settable('nonexistent') is False -@pytest.mark.parametrize("member, expected_value", [ - ("ID", (1, 'id', int, grid.FieldPriority.PRIMARY)), - ("NAME", (2, 'name', str, grid.FieldPriority.SECONDARY | grid.FieldPriority.REQUIRED)), - ("VALUE", (3, 'value', float, grid.FieldPriority.OPTIONAL | grid.FieldPriority.EDITABLE)), - ("DUPLICATE_KEY", (4, 'duplicate_key', str, grid.FieldPriority.PRIMARY | grid.FieldPriority.SECONDARY)), - ("ObjectString", 5) -]) -def test_gobject_member_values(test_gobject_class, member, expected_value): - """Tests the underlying .value of each enum member.""" - assert getattr(test_gobject_class, member).value == expected_value - -def test_gobject_str_representation(test_gobject_class: Type[grid.GObject]): - """Tests the __str__ representation of a GObject member.""" - assert str(test_gobject_class.NAME) == "name" - - -def test_gobject_field_access_by_name(test_gobject_class: Type[grid.GObject]): - """Tests that fields can be accessed by their string name using getattr.""" - id_field = getattr(test_gobject_class, "ID") - assert id_field.value[1] == "id" - assert id_field.value[2] == int - - -def test_gobject_duplicate_field_names(): - """Tests that duplicate field names raise an error or are handled gracefully.""" - # This test documents expected behavior when duplicate field names are defined - try: - class DuplicateFields(grid.GObject): - FIELD1 = ("same_name", int, grid.FieldPriority.PRIMARY) - FIELD2 = ("same_name", str, grid.FieldPriority.SECONDARY) - ObjectString = "DuplicateTest" - # If no error, check that both are in fields list - assert "same_name" in DuplicateFields.fields - except (ValueError, TypeError) as e: - # Document that this is expected to fail - pytest.skip(f"Duplicate field names not allowed: {e}") - - -def test_gobject_empty_object(): - """Tests GObject subclass with no fields.""" - class EmptyObject(grid.GObject): - ObjectString = "EmptyObject" - - assert EmptyObject.TYPE == "EmptyObject" - assert EmptyObject.fields == [] - assert EmptyObject.keys == [] - assert EmptyObject.editable == [] - assert EmptyObject.settable == set() - -# --- Parametrized tests for all GObject subclasses in components.py --- @pytest.mark.parametrize("g_object_class", get_all_gobject_subclasses()) def test_real_gobject_subclass_is_well_formed(g_object_class: Type[grid.GObject]): - """ - Performs basic sanity checks on all GObject subclasses found in components.py. - This ensures that the metaprogramming has worked as expected for all defined objects. - """ - assert g_object_class.TYPE != 'NO_OBJECT_NAME', f"{g_object_class.__name__} is missing an ObjectString." + """Validates every auto-generated GObject subclass has correct structure.""" + assert g_object_class.TYPE != 'NO_OBJECT_NAME', f"{g_object_class.__name__} missing ObjectString" assert isinstance(g_object_class.TYPE, str) - assert hasattr(g_object_class, '_FIELDS'), f"{g_object_class.__name__} is missing _FIELDS." assert isinstance(g_object_class.fields, list) - assert hasattr(g_object_class, '_KEYS'), f"{g_object_class.__name__} is missing _KEYS." assert isinstance(g_object_class.keys, list) - assert hasattr(g_object_class, '_EDITABLE'), f"{g_object_class.__name__} is missing _EDITABLE." assert isinstance(g_object_class.editable, list) - assert set(g_object_class.keys).issubset(set(g_object_class.fields)), \ - f"Not all keys in {g_object_class.__name__} are in its fields list." - assert set(g_object_class.editable).issubset(set(g_object_class.fields)), \ - f"Not all editable fields in {g_object_class.__name__} are in its fields list." - assert set(g_object_class.secondary).issubset(set(g_object_class.fields)), \ - f"Not all secondary fields in {g_object_class.__name__} are in its fields list." - - # Verify identifiers is the union of keys and secondary - expected_identifiers = set(g_object_class.keys) | set(g_object_class.secondary) - assert g_object_class.identifiers == expected_identifiers, \ - f"Identifiers mismatch in {g_object_class.__name__}" - - # Verify settable is the union of identifiers and editable - expected_settable = expected_identifiers | set(g_object_class.editable) - assert g_object_class.settable == expected_settable, \ - f"Settable mismatch in {g_object_class.__name__}" - -@pytest.mark.parametrize("g_object_class", get_all_gobject_subclasses()) -def test_gobject_field_types(g_object_class: Type[grid.GObject]): - """ - Tests that all fields in real GObject subclasses have valid Python types. - """ - valid_types = (int, float, str, bool, type(None)) - for member in g_object_class: - if hasattr(member.value, '__len__') and len(member.value) >= 3: - field_type = member.value[2] - assert field_type in valid_types, \ - f"{g_object_class.__name__}.{member.name} has invalid type: {field_type}" - - -def test_documentation_coverage_summary(): - """ - Reports overall field documentation coverage across all GObject subclasses. - This is an informational test that doesn't fail - it summarizes docstring coverage. - """ - all_classes = get_all_gobject_subclasses() - documented = 0 - undocumented = [] - - for cls in all_classes: - members = list(cls) - if not members: - continue - if any(m.__doc__ and m.__doc__.strip() for m in members): - documented += 1 - else: - undocumented.append(cls.__name__) - - total = len(all_classes) - coverage = documented / total if total > 0 else 0 - - # Print summary (visible with pytest -v or pytest -s) - print(f"\n{'='*60}") - print(f"GObject Documentation Coverage: {coverage:.1%} ({documented}/{total} components)") - print(f"{'='*60}") + assert set(g_object_class.keys).issubset(set(g_object_class.fields)) + assert set(g_object_class.editable).issubset(set(g_object_class.fields)) + assert set(g_object_class.secondary).issubset(set(g_object_class.fields)) + expected_identifiers = set(g_object_class.keys) | set(g_object_class.secondary) + assert g_object_class.identifiers == expected_identifiers -@pytest.mark.parametrize("g_object_class", get_all_gobject_subclasses()) -def test_gobject_no_name_collisions(g_object_class: Type[grid.GObject]): - """ - Tests that field names don't collide with Python keywords or common methods. - """ - reserved_names = {'class', 'def', 'if', 'else', 'for', 'while', 'return', - 'import', 'from', 'type', 'fields', 'keys', 'TYPE'} - - for field_name in g_object_class.fields: - assert field_name.lower() not in reserved_names, \ - f"{g_object_class.__name__} has field '{field_name}' that collides with reserved name" \ No newline at end of file + expected_settable = expected_identifiers | set(g_object_class.editable) + assert g_object_class.settable == expected_settable diff --git a/tests/test_helpers_unit.py b/tests/test_helpers_unit.py new file mode 100644 index 00000000..a42534b8 --- /dev/null +++ b/tests/test_helpers_unit.py @@ -0,0 +1,1434 @@ +""" +Unit tests for pure Python helper functions and validation logic. + +These are **unit tests** that do NOT require PowerWorld Simulator. They test +data transformation (df_to_aux), path conversion, argument packing, format +string edge cases, CSV result parsing, matrix file parsing, and Python-side +input validation in the SAW class. + +USAGE: + pytest tests/test_helpers_unit.py -v +""" +import os +import pytest +import pandas as pd +import numpy as np +from unittest.mock import MagicMock, Mock, patch, PropertyMock + + +# ============================================================================= +# df_to_aux function +# ============================================================================= + +class TestDfToAux: + """Tests for df_to_aux function.""" + + def test_df_to_aux_basic(self): + """df_to_aux writes correct AUX format for a simple DataFrame.""" + from esapp.saw._helpers import df_to_aux + import io + + df = pd.DataFrame({"BusNum": [1, 2], "BusName": ["Bus1", "Bus2"]}) + fp = io.StringIO() + df_to_aux(fp, df, "Bus") + content = fp.getvalue() + + assert "DATA (Bus, [BusNum,BusName])" in content + assert "{" in content + assert "}" in content + assert "1" in content + assert "Bus1" in content + + def test_df_to_aux_long_header_wraps(self): + """df_to_aux wraps long headers across multiple lines.""" + from esapp.saw._helpers import df_to_aux + import io + + # Create a DataFrame with many columns to force header wrapping + cols = {f"VeryLongFieldName{i}": [i] for i in range(20)} + df = pd.DataFrame(cols) + fp = io.StringIO() + df_to_aux(fp, df, "Branch") + content = fp.getvalue() + + assert "DATA (Branch," in content + assert "{" in content + assert "}" in content + + +# ============================================================================= +# Helper conversion functions +# ============================================================================= + +class TestHelperConversions: + """Tests for helper conversion functions.""" + + def test_convert_to_windows_path(self): + from esapp.saw._helpers import convert_to_windows_path + result = convert_to_windows_path("/tmp/test/file.pwb") + assert "\\" in result or "/" not in result.replace("//", "") + + def test_create_object_string_single_key(self): + from esapp.saw._helpers import create_object_string + assert create_object_string("Bus", 1) == "[BUS 1]" + + def test_create_object_string_multiple_keys(self): + from esapp.saw._helpers import create_object_string + assert create_object_string("Branch", 1, 2, "1") == "[BRANCH 1 2 1]" + + +# ============================================================================= +# pack_args function +# ============================================================================= + +class TestPackArgs: + """Tests for pack_args helper function.""" + + def test_pack_args_basic(self): + """pack_args joins arguments with commas.""" + from esapp.saw._helpers import pack_args + result = pack_args("a", "b", "c") + assert result == "a, b, c" + + def test_pack_args_filters_trailing_none(self): + """pack_args removes trailing None values.""" + from esapp.saw._helpers import pack_args + result = pack_args("a", "b", None, None) + assert result == "a, b" + + def test_pack_args_converts_middle_none_to_empty(self): + """pack_args converts middle None to empty string.""" + from esapp.saw._helpers import pack_args + result = pack_args("a", None, "c") + assert result == "a, , c" + + def test_pack_args_all_none(self): + """pack_args returns empty string for all None.""" + from esapp.saw._helpers import pack_args + result = pack_args(None, None) + assert result == "" + + def test_pack_args_empty(self): + """pack_args returns empty string for no arguments.""" + from esapp.saw._helpers import pack_args + result = pack_args() + assert result == "" + + def test_pack_args_numbers(self): + """pack_args converts numbers to strings.""" + from esapp.saw._helpers import pack_args + result = pack_args(1, 2.5, 3) + assert result == "1, 2.5, 3" + + +# ============================================================================= +# format_optional function +# ============================================================================= + +class TestFormatOptionalEdgeCases: + """Tests for format_optional edge cases.""" + + def test_format_optional_empty_string_not_quoted(self): + """format_optional returns empty string for empty input.""" + from esapp.saw._helpers import format_optional + result = format_optional("") + assert result == "" + + def test_format_optional_empty_string_with_empty_quoted(self): + """format_optional returns '\"\"' when empty_quoted=True.""" + from esapp.saw._helpers import format_optional + result = format_optional("", empty_quoted=True) + assert result == '""' + + def test_format_optional_none_not_quoted(self): + """format_optional returns empty string for None.""" + from esapp.saw._helpers import format_optional + result = format_optional(None) + assert result == "" + + def test_format_optional_none_with_empty_quoted(self): + """format_optional returns '\"\"' for None when empty_quoted=True.""" + from esapp.saw._helpers import format_optional + result = format_optional(None, empty_quoted=True) + assert result == '""' + + def test_format_optional_value_quoted(self): + """format_optional quotes non-empty values by default.""" + from esapp.saw._helpers import format_optional + result = format_optional("MyValue") + assert result == '"MyValue"' + + def test_format_optional_value_not_quoted(self): + """format_optional returns raw value when quote=False.""" + from esapp.saw._helpers import format_optional + result = format_optional("MyValue", quote=False) + assert result == "MyValue" + + +# ============================================================================= +# load_ts_csv_results function +# ============================================================================= + +class TestLoadTsCsvResults: + """Tests for load_ts_csv_results function.""" + + def test_load_ts_csv_results_no_files(self, tmp_path): + """load_ts_csv_results returns empty DataFrames when no files found.""" + from esapp.saw._helpers import load_ts_csv_results + base_path = tmp_path / "nonexistent_results" + meta, data = load_ts_csv_results(base_path) + assert meta.empty + assert data.empty + + def test_load_ts_csv_results_header_only(self, tmp_path): + """load_ts_csv_results parses header file correctly.""" + from esapp.saw._helpers import load_ts_csv_results + + # Create header file + header_file = tmp_path / "results_header.csv" + header_file.write_text("Column,Object,Variable,Key 1,Key 2\n0,Bus,VPU,1,\n1,Gen,P,2,1\n") + + base_path = tmp_path / "results" + meta, data = load_ts_csv_results(base_path) + + assert not meta.empty + assert "ColHeader" in meta.columns + assert "ObjectType" in meta.columns + + def test_load_ts_csv_results_with_data(self, tmp_path): + """load_ts_csv_results parses data files correctly.""" + from esapp.saw._helpers import load_ts_csv_results + + # Create header file + header_file = tmp_path / "results_header.csv" + header_file.write_text("Column,Object,Variable,Key 1,Key 2\n0,Bus,VPU,1,\n") + + # Create data file + data_file = tmp_path / "results_data.csv" + data_file.write_text("0.0,1.0\n0.1,0.99\n0.2,0.98\n") + + base_path = tmp_path / "results" + meta, data = load_ts_csv_results(base_path) + + assert not data.empty + assert "time" in data.columns + assert len(data) == 3 + + def test_load_ts_csv_results_object_fields_header(self, tmp_path): + """load_ts_csv_results skips ObjectFields line in header.""" + from esapp.saw._helpers import load_ts_csv_results + + # Create header file with ObjectFields line + header_file = tmp_path / "results_header.csv" + header_file.write_text("ObjectFields\nColumn,Object,Variable,Key 1,Key 2\n0,Bus,VPU,1,\n") + + base_path = tmp_path / "results" + meta, data = load_ts_csv_results(base_path) + + assert not meta.empty + assert "ColHeader" in meta.columns + + def test_load_ts_csv_results_delete_files(self, tmp_path): + """load_ts_csv_results deletes files when delete_files=True.""" + from esapp.saw._helpers import load_ts_csv_results + + # Create header file + header_file = tmp_path / "results_header.csv" + header_file.write_text("Column,Object,Variable,Key 1,Key 2\n0,Bus,VPU,1,\n") + + base_path = tmp_path / "results" + load_ts_csv_results(base_path, delete_files=True) + + assert not header_file.exists() + + +# ============================================================================= +# format_list function +# ============================================================================= + + +class TestFormatList: + """Tests for format_list helper function.""" + + def test_format_list_none(self): + from esapp.saw._helpers import format_list + assert format_list(None) == "[]" + + def test_format_list_empty(self): + from esapp.saw._helpers import format_list + assert format_list([]) == "[]" + + def test_format_list_basic(self): + from esapp.saw._helpers import format_list + assert format_list(["BusNum", "BusName"]) == "[BusNum, BusName]" + + def test_format_list_quote_items(self): + from esapp.saw._helpers import format_list + assert format_list(["Gen1", "Gen2"], quote_items=True) == '["Gen1", "Gen2"]' + + def test_format_list_stringify(self): + from esapp.saw._helpers import format_list + assert format_list([1.5, 2.0], stringify=True) == "[1.5, 2.0]" + + +# ============================================================================= +# format_optional_numeric function +# ============================================================================= + + +class TestFormatOptionalNumeric: + """Tests for format_optional_numeric function.""" + + def test_none_returns_empty(self): + from esapp.saw._helpers import format_optional_numeric + assert format_optional_numeric(None) == "" + + def test_zero_returns_str(self): + from esapp.saw._helpers import format_optional_numeric + assert format_optional_numeric(0) == "0" + + def test_float_returns_str(self): + from esapp.saw._helpers import format_optional_numeric + assert format_optional_numeric(3.14) == "3.14" + + +# ============================================================================= +# format_filter functions +# ============================================================================= + + +class TestFormatFilterSelectedOnly: + """Tests for format_filter_selected_only.""" + + def test_empty_string(self): + from esapp.saw._enums import format_filter_selected_only + assert format_filter_selected_only("") == "" + + def test_none(self): + from esapp.saw._enums import format_filter_selected_only + assert format_filter_selected_only(None) == "" + + def test_selected_enum(self): + from esapp.saw._enums import format_filter_selected_only, FilterKeyword + result = format_filter_selected_only(FilterKeyword.SELECTED) + assert result == "SELECTED" + + def test_selected_string(self): + from esapp.saw._enums import format_filter_selected_only + result = format_filter_selected_only("SELECTED") + assert result == "SELECTED" + + def test_custom_filter_quoted(self): + from esapp.saw._enums import format_filter_selected_only + result = format_filter_selected_only("MyFilter") + assert result == '"MyFilter"' + + def test_areazone_enum_quoted(self): + from esapp.saw._enums import format_filter_selected_only, FilterKeyword + result = format_filter_selected_only(FilterKeyword.AREAZONE) + # AREAZONE is not SELECTED, so it gets quoted + assert result.startswith('"') and result.endswith('"') + + +class TestFormatFilterAreazone: + """Tests for format_filter_areazone.""" + + def test_empty_string(self): + from esapp.saw._enums import format_filter_areazone + assert format_filter_areazone("") == "" + + def test_none(self): + from esapp.saw._enums import format_filter_areazone + assert format_filter_areazone(None) == "" + + def test_selected_enum(self): + from esapp.saw._enums import format_filter_areazone, FilterKeyword + result = format_filter_areazone(FilterKeyword.SELECTED) + assert result == "SELECTED" + + def test_areazone_enum(self): + from esapp.saw._enums import format_filter_areazone, FilterKeyword + result = format_filter_areazone(FilterKeyword.AREAZONE) + assert result == "AREAZONE" + + def test_all_enum_quoted(self): + from esapp.saw._enums import format_filter_areazone, FilterKeyword + result = format_filter_areazone(FilterKeyword.ALL) + assert result == '"ALL"' + + def test_selected_string(self): + from esapp.saw._enums import format_filter_areazone + result = format_filter_areazone("SELECTED") + assert result == "SELECTED" + + def test_areazone_string(self): + from esapp.saw._enums import format_filter_areazone + result = format_filter_areazone("AREAZONE") + assert result == "AREAZONE" + + def test_custom_filter_quoted(self): + from esapp.saw._enums import format_filter_areazone + result = format_filter_areazone("MyFilter") + assert result == '"MyFilter"' + + +# ============================================================================= +# load_ts_csv_results edge cases +# ============================================================================= + + +class TestLoadTsCsvResultsEdgeCases: + """Edge case tests for load_ts_csv_results.""" + + def test_bad_header_file_logged(self, tmp_path, caplog): + """A corrupt header file logs warning and returns empty meta.""" + from esapp.saw._helpers import load_ts_csv_results + import logging + + header_file = tmp_path / "results_header.csv" + header_file.write_bytes(b'\xff\xfe' + b'\x00' * 50) + + base_path = tmp_path / "results" + with caplog.at_level(logging.WARNING): + meta, data = load_ts_csv_results(base_path) + + def test_bad_data_file_logged(self, tmp_path, caplog): + """A corrupt data file logs warning and is skipped.""" + from esapp.saw._helpers import load_ts_csv_results + import logging + + data_file = tmp_path / "results_0.csv" + data_file.write_bytes(b'\xff\xfe' + b'\x00' * 50) + + base_path = tmp_path / "results" + with caplog.at_level(logging.WARNING): + meta, data = load_ts_csv_results(base_path) + + +# ============================================================================= +# SAW Python-side validation tests (no COM calls needed) +# ============================================================================= + + +class TestSAWValidation: + """Tests for SAW input validation that happens in Python before COM calls.""" + + def test_set_simauto_property_invalid_name(self, saw_obj): + """set_simauto_property raises ValueError for unsupported property.""" + with pytest.raises(ValueError, match="not currently supported"): + saw_obj.set_simauto_property("InvalidProp", True) + + def test_set_simauto_property_invalid_type(self, saw_obj): + """set_simauto_property raises ValueError for wrong type.""" + with pytest.raises(ValueError, match="is invalid"): + saw_obj.set_simauto_property("CreateIfNotFound", "not_a_bool") + + def test_open_case_no_filename_no_path(self, saw_obj): + """OpenCase raises TypeError when no FileName and no prior path.""" + saw_obj.pwb_file_path = None + with pytest.raises(TypeError, match="FileName is required"): + saw_obj.OpenCase(FileName=None) + + def test_save_case_no_filename_no_path(self, saw_obj): + """SaveCase raises TypeError when no FileName and no opened case.""" + saw_obj.pwb_file_path = None + with pytest.raises(TypeError, match="SaveCase was called without"): + saw_obj.SaveCase() + + def test_com_call_invalid_func(self, saw_obj): + """_com_call raises AttributeError for invalid function.""" + del saw_obj._pwcom.InvalidFunc + with pytest.raises(AttributeError, match="not a valid SimAuto function"): + saw_obj._com_call("InvalidFunc") + + def test_replace_decimal_delimiter(self, saw_obj): + """_replace_decimal_delimiter handles non-string data.""" + data = pd.Series([1.0, 2.0, 3.0]) + result = saw_obj._replace_decimal_delimiter(data) + assert (result == data).all() + + def test_replace_decimal_delimiter_comma(self, saw_obj): + """_replace_decimal_delimiter replaces comma with period.""" + saw_obj.decimal_delimiter = "," + data = pd.Series(["1,5", "2,3", "3,0"]) + result = saw_obj._replace_decimal_delimiter(data) + assert result.iloc[0] == "1.5" + + def test_get_field_list_copy(self, saw_obj): + """GetFieldList returns a copy when copy=True.""" + saw_obj._object_fields = {} + result1 = saw_obj.GetFieldList("Bus", copy=False) + result2 = saw_obj.GetFieldList("Bus", copy=True) + assert result1 is not result2 + + def test_init_com_dispatch_failure(self): + """SAW raises when COM dispatch fails.""" + with patch("win32com.client.dynamic.Dispatch", side_effect=Exception("COM init failed")): + with pytest.raises(Exception, match="COM init failed"): + from esapp.saw import SAW + SAW(FileName="dummy.pwb") + + def test_exit_cleanup(self): + """exit() deletes temp file, closes case, and releases COM.""" + from esapp.saw import SAW + with patch("win32com.client.dynamic.Dispatch") as mock_dispatch, \ + patch("tempfile.NamedTemporaryFile") as mock_tf, \ + patch("os.unlink"), \ + patch("esapp.saw.base.pythoncom") as mock_pythoncom: + mock_pwcom = MagicMock() + mock_dispatch.return_value = mock_pwcom + mock_tf.return_value = Mock(name="dummy.axd") + mock_pwcom.OpenCase.return_value = ("",) + mock_pwcom.GetParametersSingleElement.return_value = ("", ("23", "Jan 01 2023")) + mock_pwcom.CloseCase.return_value = ("",) + saw = SAW(FileName="dummy.pwb") + saw._pwcom = mock_pwcom + saw.empty_aux = "dummy.axd" + + with patch("os.path.exists", return_value=True), \ + patch("os.unlink") as mock_unlink: + saw.exit() + mock_unlink.assert_called_once_with("dummy.axd") + assert saw._pwcom is None + mock_pythoncom.CoUninitialize.assert_called_once() + + def test_set_simauto_property_uivisible_attribute_error(self, saw_obj): + """set_simauto_property logs warning for UIVisible on old versions.""" + saw_obj._pwcom.UIVisible = PropertyMock(side_effect=AttributeError) + with patch.object(saw_obj, '_set_simauto_property', side_effect=AttributeError): + saw_obj.set_simauto_property("UIVisible", True) + + def test_uivisible_property_attribute_error(self, saw_obj): + """UIVisible property returns False on AttributeError.""" + original = saw_obj._pwcom + mock_pwcom = MagicMock(spec=[]) # spec=[] means no attributes allowed + saw_obj._pwcom = mock_pwcom + result = saw_obj.UIVisible + assert result is False + saw_obj._pwcom = original + + def test_request_build_date(self, saw_obj): + """RequestBuildDate property accesses COM.""" + saw_obj._pwcom.RequestBuildDate = 20230101 + assert saw_obj.RequestBuildDate == 20230101 + + def test_run_script_command_2(self, saw_obj): + """RunScriptCommand2 calls COM correctly.""" + saw_obj._pwcom.RunScriptCommand2.return_value = ("",) + saw_obj.RunScriptCommand2("SomeCMD;", "Status msg") + saw_obj._pwcom.RunScriptCommand2.assert_called_once() + + def test_com_call_rpc_error(self, saw_obj): + """_com_call raises COMError on RPC failure.""" + from esapp.saw._exceptions import COMError, RPC_S_UNKNOWN_IF + saw_obj._pwcom.OpenCase.side_effect = Exception(f"error {hex(RPC_S_UNKNOWN_IF)}") + with pytest.raises(COMError): + saw_obj._com_call("OpenCase", "test.pwb") + + def test_com_call_returns_minus_one(self, saw_obj): + """_com_call raises PowerWorldError when COM returns -1.""" + from esapp.saw._exceptions import PowerWorldError + saw_obj._pwcom.OpenCase.return_value = -1 + with pytest.raises(PowerWorldError, match="returned -1"): + saw_obj._com_call("OpenCase", "test.pwb") + + def test_com_call_returns_int(self, saw_obj): + """_com_call returns integer output directly.""" + saw_obj._pwcom.GetSpecificFieldMaxNum.return_value = 42 + result = saw_obj._com_call("GetSpecificFieldMaxNum", "Bus", "CustomFloat") + assert result == 42 + + def test_exec_aux_double_quotes(self, saw_obj): + """exec_aux replaces single quotes with double quotes.""" + with patch("builtins.open", create=True) as mock_open, \ + patch("os.unlink"): + from unittest.mock import mock_open as mo + m = mo() + with patch("builtins.open", m): + saw_obj.exec_aux("CaseInfo_Options_Value (Option,Value)\n{'key' 'value'}", use_double_quotes=True) + written = m().write.call_args[0][0] + assert "'" not in written + assert '"' in written + + def test_open_case_reopen_uses_stored_path(self, saw_obj): + """OpenCase with FileName=None reopens stored path.""" + saw_obj.pwb_file_path = "stored.pwb" + saw_obj.OpenCase(FileName=None) + saw_obj._pwcom.OpenCase.assert_called_with("stored.pwb") + + def test_open_case_type_options_list(self, saw_obj): + """OpenCaseType with list options converts to variant.""" + saw_obj._pwcom.OpenCaseType.return_value = ("",) + saw_obj.OpenCaseType("test.raw", "PTI", ["OPT1", "OPT2"]) + saw_obj._pwcom.OpenCaseType.assert_called_once() + + def test_open_case_type_options_str(self, saw_obj): + """OpenCaseType with string options passes through.""" + saw_obj._pwcom.OpenCaseType.return_value = ("",) + saw_obj.OpenCaseType("test.raw", "PTI", "MY_OPTION") + saw_obj._pwcom.OpenCaseType.assert_called_once() + + def test_open_case_type_error_file_exists(self, saw_obj): + """OpenCaseType error when file exists shows file-exists hints.""" + from esapp.saw._exceptions import PowerWorldError + saw_obj._pwcom.OpenCaseType.return_value = ("Error: bad format",) + with patch("os.path.exists", return_value=True): + with pytest.raises(PowerWorldError, match="file exists but"): + saw_obj.OpenCaseType("test.raw", "PTI") + + def test_save_case_uses_stored_path(self, saw_obj): + """SaveCase with no FileName uses stored path.""" + saw_obj.pwb_file_path = "stored.pwb" + saw_obj.SaveCase() + saw_obj._pwcom.SaveCase.assert_called_once() + + def test_new_case(self, saw_obj): + """NewCase calls _run_script.""" + saw_obj.NewCase() + + def test_renumber_3w_xformer_star_buses(self, saw_obj): + """Renumber3WXFormerStarBuses calls _run_script.""" + saw_obj.Renumber3WXFormerStarBuses("renumber.txt") + + def test_renumber_ms_line_dummy_buses(self, saw_obj): + """RenumberMSLineDummyBuses calls _run_script.""" + saw_obj.RenumberMSLineDummyBuses("renumber.txt") + + def test_get_case_header_none_filename(self, saw_obj): + """GetCaseHeader with None uses stored pwb_file_path.""" + saw_obj.pwb_file_path = "stored.pwb" + saw_obj._pwcom.GetCaseHeader.return_value = ("", ("Header line 1",)) + saw_obj.GetCaseHeader(filename=None) + saw_obj._pwcom.GetCaseHeader.assert_called_with("stored.pwb") + + def test_get_params_rect_typed_none(self, saw_obj): + """GetParamsRectTyped returns None when COM returns None.""" + saw_obj._pwcom.GetParamsRectTyped.return_value = ("", None) + result = saw_obj.GetParamsRectTyped("Bus", ["BusNum"]) + assert result is None + + def test_send_to_excel(self, saw_obj): + """SendToExcel calls COM correctly.""" + saw_obj._pwcom.SendToExcel.return_value = ("",) + saw_obj.SendToExcel("Bus", "", ["BusNum", "BusName"]) + saw_obj._pwcom.SendToExcel.assert_called_once() + + def test_ctg_read_file_pslf(self, saw_obj): + """CTGReadFilePSLF calls _run_script.""" + saw_obj.CTGReadFilePSLF("test.pslf") + + def test_ctg_read_file_pti(self, saw_obj): + """CTGReadFilePTI calls _run_script.""" + saw_obj.CTGReadFilePTI("test.con") + + def test_ctg_save_violation_matrices_default_field_list(self, saw_obj): + """CTGSaveViolationMatrices with field_list=None defaults to empty list.""" + saw_obj.CTGSaveViolationMatrices( + "out.csv", "CSVCOLHEADER", True, ["Branch"], True, True + ) + + def test_load_pti_seq_data(self, saw_obj): + """LoadPTISEQData calls _run_script.""" + saw_obj.LoadPTISEQData("test.seq") + + def test_stop_aux_file(self, saw_obj): + """StopAuxFile calls _run_script.""" + saw_obj.StopAuxFile() + + def test_gic_read_file_pslf(self, saw_obj): + """GICReadFilePSLF calls _run_script.""" + saw_obj.GICReadFilePSLF("test.gmd") + + def test_gic_read_file_pti(self, saw_obj): + """GICReadFilePTI calls _run_script.""" + saw_obj.GICReadFilePTI("test.gic") + + def test_merge_line_terminals(self, saw_obj): + """MergeLineTerminals calls _run_script.""" + saw_obj.MergeLineTerminals() + + def test_merge_ms_line_sections(self, saw_obj): + """MergeMSLineSections calls _run_script.""" + saw_obj.MergeMSLineSections() + + def test_estimate_voltages(self, saw_obj): + """EstimateVoltages calls _run_script.""" + saw_obj.EstimateVoltages("ALL") + + def test_diff_case_clear_base(self, saw_obj): + """DiffCaseClearBase calls _run_script.""" + saw_obj.DiffCaseClearBase() + + def test_diff_case_show_present_and_base(self, saw_obj): + """DiffCaseShowPresentAndBase calls _run_script.""" + saw_obj.DiffCaseShowPresentAndBase(True) + + def test_do_ctg_action(self, saw_obj): + """DoCTGAction calls _run_script.""" + saw_obj.DoCTGAction("OPEN BRANCH FROM 1 TO 2 CKT 1") + + def test_interfaces_calculate_post_ctg_mw_flows(self, saw_obj): + """InterfacesCalculatePostCTGMWFlows calls _run_script.""" + saw_obj.InterfacesCalculatePostCTGMWFlows() + + def test_qv_run_empty_result(self, saw_obj, tmp_path): + """QVRun returns empty DataFrame when temp file is empty.""" + tmp = str(tmp_path / "qv_result.csv") + with open(tmp, 'w') as f: + pass # Create empty file + with patch.object(saw_obj, '_run_script'), \ + patch('esapp.saw.qv.get_temp_filepath', return_value=tmp): + result = saw_obj.QVRun() + assert isinstance(result, pd.DataFrame) + assert result.empty + + def test_timestep_do_single_point(self, saw_obj): + """TimeStepDoSinglePoint calls _run_script.""" + saw_obj.TimeStepDoSinglePoint("2025-06-01T00:00:00") + + def test_timestep_save_selected_modify_finish(self, saw_obj): + """TIMESTEPSaveSelectedModifyFinish calls _run_script.""" + saw_obj.TIMESTEPSaveSelectedModifyFinish() + + def test_list_of_devices_decimal_delimiter(self, saw_obj): + """ListOfDevices handles non-dot decimal delimiter.""" + saw_obj.decimal_delimiter = "," + saw_obj._object_fields = {} + # Re-mock GetFieldList to return data with comma delimiters + saw_obj._pwcom.GetFieldList.return_value = ("", [ + ["*1*", "BusNum", "Integer", "Bus Number", "Bus Number"], + ["*2*", "BusName", "String", "Bus Name", "Bus Name"], + ]) + saw_obj._pwcom.ListOfDevices.return_value = ("", ((1, 2), ("Bus1", "Bus2"))) + result = saw_obj.ListOfDevices("Bus") + assert result is not None + saw_obj.decimal_delimiter = "." + + def test_set_simauto_property_non_uivisible_attribute_error(self, saw_obj): + """set_simauto_property re-raises AttributeError for non-UIVisible properties.""" + with patch.object(saw_obj, '_set_simauto_property', side_effect=AttributeError("oops")): + with pytest.raises(AttributeError, match="oops"): + saw_obj.set_simauto_property("CreateIfNotFound", True) + + def test_condition_voltage_pockets(self, saw_obj): + """ConditionVoltagePockets calls _run_script.""" + saw_obj.ConditionVoltagePockets(0.5, 30.0) + + def test_diff_case_key_type(self, saw_obj): + """DiffCaseKeyType calls _run_script.""" + saw_obj.DiffCaseKeyType("PRIMARY") + + def test_get_sub_data_file_not_found(self, saw_obj): + """GetSubData returns empty DataFrame when file not found.""" + with patch.object(saw_obj, 'SaveData'), \ + patch('os.path.exists', return_value=False), \ + patch('esapp.saw.general.get_temp_filepath', return_value='nonexistent.aux'): + result = saw_obj.GetSubData("Gen", ["BusNum", "GenID"]) + assert isinstance(result, pd.DataFrame) + assert result.empty + + def test_get_field_list_new_columns(self, saw_obj): + """GetFieldList handles new (extended) column format.""" + saw_obj._object_fields = {} + # Return data with 7 columns (new format) to trigger ValueError path + saw_obj._pwcom.GetFieldList.return_value = ("", [ + ["*1*", "BusNum", "Integer", "Bus Number", "Bus Number", "Y", "Extra"], + ["*2*", "BusName", "String", "Bus Name", "Bus Name", "N", "Extra"], + ]) + from esapp.saw._enums import FieldListColumn + new_cols = FieldListColumn.new_columns() + if len(new_cols) == 7: + result = saw_obj.GetFieldList("Bus") + assert not result.empty + + def test_program_information_property(self, saw_obj): + """ProgramInformation property accesses COM and returns tuple.""" + import datetime + dt = datetime.datetime(2023, 1, 1, tzinfo=datetime.timezone.utc) + saw_obj._pwcom.ProgramInformation = [["v23", "Build", dt, "info"]] + result = saw_obj.ProgramInformation + assert isinstance(result, tuple) + + +# ============================================================================= +# Matrix parsing tests (pure file-based, no COM) +# ============================================================================= + + +class TestMatrixParsing: + """Tests for matrix file parsing (pure Python, reads from files).""" + + def _make_ybus_file(self, tmp_path): + """Helper to create a mock YBus .m file in PowerWorld format.""" + content = ( + "% YBus Matrix\n" + "Ybus=sparse(3,3);\n" + "Ybus(1,1)=10.0+j*(-5.0);\n" + "Ybus(1,2)=-5.0+j*(2.5);\n" + "Ybus(2,1)=-5.0+j*(2.5);\n" + "Ybus(2,2)=10.0+j*(-5.0);\n" + "Ybus(3,3)=5.0+j*(-2.5);\n" + ) + fpath = str(tmp_path / "ybus.m") + with open(fpath, "w") as f: + f.write(content) + return fpath + + def test_parse_real_matrix(self, saw_obj): + """_parse_real_matrix correctly parses sparse matrix.""" + mat_str = ( + "Jac=sparse(2,2);\n" + "Jac(1,1)=1.0;\n" + "Jac(1,2)=-0.5;\n" + "Jac(2,1)=-0.5;\n" + "Jac(2,2)=1.0;\n" + ) + result = saw_obj._parse_real_matrix(mat_str, "Jac") + arr = result.toarray() + assert arr.shape == (2, 2) + assert arr[0, 0] == 1.0 + assert arr[0, 1] == -0.5 + + def test_get_ybus_from_file(self, saw_obj, tmp_path): + """get_ybus reads from an existing file.""" + fpath = self._make_ybus_file(tmp_path) + result = saw_obj.get_ybus(file=fpath, full=True) + assert result.shape == (3, 3) + assert result[0, 0] == 10.0 + (-5.0j) + + def test_get_ybus_sparse(self, saw_obj, tmp_path): + """get_ybus returns sparse matrix by default.""" + from scipy.sparse import issparse + fpath = self._make_ybus_file(tmp_path) + result = saw_obj.get_ybus(file=fpath, full=False) + assert issparse(result) + + def test_parse_real_matrix_gmatrix(self, saw_obj): + """_parse_real_matrix correctly parses GMatrix format.""" + mat_str = ( + "GMatrix=sparse(3,3);\n" + "GMatrix(1,1)=2.0;\n" + "GMatrix(1,2)=-1.0;\n" + "GMatrix(2,1)=-1.0;\n" + "GMatrix(2,2)=3.0;\n" + "GMatrix(3,3)=1.5;\n" + ) + result = saw_obj._parse_real_matrix(mat_str, "GMatrix") + arr = result.toarray() + assert arr.shape == (3, 3) + assert arr[0, 0] == 2.0 + assert arr[2, 2] == 1.5 + + def test_save_ybus_in_matlab_format(self, saw_obj): + """SaveYbusInMatlabFormat calls _run_script.""" + saw_obj.SaveYbusInMatlabFormat("ybus.m", include_voltages=True) + + def test_save_jacobian(self, saw_obj): + """SaveJacobian calls _run_script.""" + saw_obj.SaveJacobian("jac.m", "jid.txt", "M", "R") + + +# ============================================================================= +# TSField unit tests +# ============================================================================= + + +class TestTSFieldIndexing: + """Tests for TSField.__getitem__.""" + + def test_tsfield_getitem(self): + """TSField[index] creates an indexed field.""" + from esapp.components.ts_fields import TSField + field = TSField("TSBusInput", "Input voltage") + indexed = field[1] + assert str(indexed) == "TSBusInput:1" + + def test_ts_bus_input_indexing(self): + """TS.Bus.Input[1] creates indexed field.""" + from esapp.components import TS + indexed = TS.Bus.Input[1] + assert str(indexed) == "TSBusInput:1" + + +# ============================================================================= +# Workbench logic tests (file I/O, no COM) +# ============================================================================= + + +class TestWorkbenchLogic: + """Tests for PowerWorld Python-side logic (no PowerWorld needed).""" + + def test_init_no_fname(self): + """PowerWorld initializes without fname.""" + from esapp.workbench import PowerWorld + pw = PowerWorld() + assert pw.esa is None + assert pw.fname is None + + def test_open_file_not_found(self): + """PowerWorld.open raises FileNotFoundError for missing file.""" + from esapp.workbench import PowerWorld + from unittest.mock import patch + + pw = PowerWorld() + pw.fname = "C:/nonexistent/file.pwb" + + with patch('esapp.indexable.path.isabs', return_value=True), \ + patch('esapp.indexable.path.exists', return_value=False): + with pytest.raises(FileNotFoundError, match="Case file not found"): + pw.open() + + def test_log_output(self): + """PowerWorld.print_log reads and prints log content.""" + from esapp.workbench import PowerWorld + from unittest.mock import MagicMock + + pw = PowerWorld() + pw.esa = MagicMock() + pw._log_last_position = 0 + + def mock_log_save(path, append=False): + with open(path, "w") as f: + f.write("Some log output") + + pw.esa.LogSave.side_effect = mock_log_save + + result = pw.print_log(new_only=False, clear=False) + assert "Some log output" in result + + def test_print_log_new_only(self): + """PowerWorld.print_log returns only new content.""" + from esapp.workbench import PowerWorld + from unittest.mock import MagicMock + + pw = PowerWorld() + pw.esa = MagicMock() + pw._log_last_position = 5 + + def mock_log_save(path, append=False): + with open(path, "w") as f: + f.write("Hello World") + + pw.esa.LogSave.side_effect = mock_log_save + + result = pw.print_log(new_only=True, clear=False) + assert result == " World" + + def test_print_log_empty(self): + """PowerWorld.print_log handles empty log output (whitespace only).""" + from esapp.workbench import PowerWorld + from unittest.mock import MagicMock + + pw = PowerWorld() + pw.esa = MagicMock() + pw._log_last_position = 0 + + def mock_log_save(path, append=False): + with open(path, "w") as f: + f.write(" ") + + pw.esa.LogSave.side_effect = mock_log_save + + result = pw.print_log(new_only=False, clear=False) + assert result == " " + + def test_log_with_clear(self): + """PowerWorld.print_log clears log after reading.""" + from esapp.workbench import PowerWorld + from unittest.mock import MagicMock + + pw = PowerWorld() + pw.esa = MagicMock() + pw._log_last_position = 0 + + def mock_log_save(path, append=False): + with open(path, "w") as f: + f.write("Log content") + + pw.esa.LogSave.side_effect = mock_log_save + + pw.print_log(new_only=False, clear=True) + pw.esa.LogClear.assert_called_once() + assert pw._log_last_position == 0 + + def test_close(self): + """PowerWorld.close calls esa.CloseCase.""" + from esapp.workbench import PowerWorld + + pw = PowerWorld() + pw.esa = MagicMock() + pw.close() + pw.esa.CloseCase.assert_called_once() + + def test_ts_solve_empty_results(self): + """PowerWorld.ts_solve returns empty DataFrames when no results.""" + from esapp.workbench import PowerWorld + + pw = PowerWorld() + pw.esa = MagicMock() + + with patch("esapp.workbench.get_ts_results", return_value=(None, None)): + meta, data = pw.ts_solve("ctg1", ["TSBusVPU"]) + assert meta.empty + assert data.empty + + def test_dc_lines_exception_returns_none(self): + """Network._dc_lines returns None on exception.""" + from esapp.utils.network import Network + + mock_pw = MagicMock() + mock_pw.__getitem__ = MagicMock(side_effect=Exception("no DC lines")) + net = Network(mock_pw) + result = net._dc_lines() + assert result is None + + def test_gic_option_descriptor_missing_key(self): + """GICOption descriptor returns None for missing option key.""" + from esapp.utils.gic import GIC + import pandas as pd + + mock_pw = MagicMock() + # Return a DataFrame with no matching VariableName + mock_pw.__getitem__ = MagicMock(return_value=pd.DataFrame({ + 'VariableName': ['OtherOption'], + 'ValueField': ['SomeValue'] + })) + gic = GIC(mock_pw) + # pf_include looks for 'IncludeInPowerFlow' which isn't in the mock data + result = gic.pf_include + assert result is None + + def test_gic_option_descriptor_bool_get_true(self): + """GICOption bool descriptor returns True when value is YES.""" + from esapp.utils.gic import GIC + from esapp.saw._enums import YesNo + import pandas as pd + + mock_pw = MagicMock() + mock_pw.__getitem__ = MagicMock(return_value=pd.DataFrame({ + 'VariableName': ['IncludeInPowerFlow'], + 'ValueField': [YesNo.YES] + })) + gic = GIC(mock_pw) + assert gic.pf_include is True + + def test_gic_option_descriptor_bool_get_false(self): + """GICOption bool descriptor returns False when value is NO.""" + from esapp.utils.gic import GIC + from esapp.saw._enums import YesNo + import pandas as pd + + mock_pw = MagicMock() + mock_pw.__getitem__ = MagicMock(return_value=pd.DataFrame({ + 'VariableName': ['IncludeInPowerFlow'], + 'ValueField': [YesNo.NO] + })) + gic = GIC(mock_pw) + assert gic.pf_include is False + + def test_gic_option_descriptor_nonbool_get(self): + """GICOption non-bool descriptor returns raw value.""" + from esapp.utils.gic import GIC + import pandas as pd + + mock_pw = MagicMock() + mock_pw.__getitem__ = MagicMock(return_value=pd.DataFrame({ + 'VariableName': ['CalcMode'], + 'ValueField': ['SnapShot'] + })) + gic = GIC(mock_pw) + assert gic.calc_mode == 'SnapShot' + + def test_gic_option_descriptor_bool_set(self): + """GICOption bool descriptor calls SetData with YES/NO and EDIT/RUN.""" + from esapp.utils.gic import GIC + from esapp.saw._enums import YesNo + + mock_pw = MagicMock() + mock_esa = MagicMock() + mock_pw.esa = mock_esa + gic = GIC(mock_pw) + + gic.pf_include = True + mock_esa.EnterMode.assert_any_call("EDIT") + mock_esa.SetData.assert_called_with( + 'GIC_Options_Value', + ['VariableName', 'ValueField'], + ['IncludeInPowerFlow', YesNo.YES] + ) + mock_esa.EnterMode.assert_called_with("RUN") + + def test_gic_option_descriptor_nonbool_set(self): + """GICOption non-bool descriptor passes value directly.""" + from esapp.utils.gic import GIC + + mock_pw = MagicMock() + mock_esa = MagicMock() + mock_pw.esa = mock_esa + gic = GIC(mock_pw) + + gic.calc_mode = 'TimeVarying' + mock_esa.SetData.assert_called_with( + 'GIC_Options_Value', + ['VariableName', 'ValueField'], + ['CalcMode', 'TimeVarying'] + ) + + def test_gic_option_descriptor_class_level_access(self): + """GICOption class-level access returns the descriptor itself.""" + from esapp.utils.gic import GIC + + desc = GIC.pf_include + assert hasattr(desc, 'key') + assert desc.key == 'IncludeInPowerFlow' + assert desc.is_bool is True + + desc_nb = GIC.calc_mode + assert desc_nb.key == 'CalcMode' + assert desc_nb.is_bool is False + + def test_load_ts_csv_results_unlink_oserror(self, tmp_path): + """load_ts_csv_results handles OSError on temp file unlink.""" + from esapp.saw._helpers import load_ts_csv_results + header_file = tmp_path / "results_header.csv" + header_file.write_text("Column,Object,Variable,Key 1,Key 2\n0,Bus,VPU,1,\n") + base_path = tmp_path / "results" + with patch("pathlib.Path.unlink", side_effect=OSError("permission denied")): + meta, data = load_ts_csv_results(base_path, delete_files=True) + assert not meta.empty + + +# ============================================================================= +# Indexable fallback (error routing logic) +# ============================================================================= + + +class TestIndexableFallback: + """Tests for Indexable.__setitem__ fallback on ChangeParametersMultipleElement.""" + + def test_fallback_create_suppresses_not_found(self): + """Fallback to ChangeParametersMultipleElement suppresses 'not found'.""" + from esapp.saw import PowerWorldPrerequisiteError + from esapp.indexable import Indexable + from esapp import components as grid + from unittest.mock import Mock + + instance = Indexable() + mock_esa = Mock() + instance.esa = mock_esa + + update_df = pd.DataFrame({ + "BusNum": [999, 1000], + "GenID": ["1", "1"], + "GenMW": [100.0, 200.0], + }) + + mock_esa.ChangeParametersMultipleElementRect.side_effect = PowerWorldPrerequisiteError( + "Object not found in case" + ) + mock_esa.ChangeParametersMultipleElement.side_effect = PowerWorldPrerequisiteError( + "Object not found in case" + ) + + instance[grid.Gen] = update_df + + def test_fallback_create_raises_other_error(self): + """Fallback to ChangeParametersMultipleElement re-raises non-'not found' errors.""" + from esapp.saw import PowerWorldPrerequisiteError + from esapp.indexable import Indexable + from esapp import components as grid + from unittest.mock import Mock + + instance = Indexable() + mock_esa = Mock() + instance.esa = mock_esa + + update_df = pd.DataFrame({ + "BusNum": [999], + "GenID": ["1"], + "GenMW": [100.0], + }) + + mock_esa.ChangeParametersMultipleElementRect.side_effect = PowerWorldPrerequisiteError( + "Object not found in case" + ) + mock_esa.ChangeParametersMultipleElement.side_effect = PowerWorldPrerequisiteError( + "License expired" + ) + + with pytest.raises(PowerWorldPrerequisiteError, match="License expired"): + instance[grid.Gen] = update_df + + def test_non_full_slice_raises_value_error(self): + """Non-full slice in field selection raises ValueError.""" + from esapp.indexable import Indexable + from esapp import components as grid + from unittest.mock import Mock + + instance = Indexable() + instance.esa = Mock() + + with pytest.raises(ValueError, match="Only the full slice"): + instance[grid.Bus, [slice(0, 5)]] + + +# ============================================================================= +# Transient validation (Python-side) +# ============================================================================= + + +class TestTransientValidation: + """Tests for transient stability input validation.""" + + def test_ts_set_play_in_signals_dim_mismatch(self, saw_obj): + """TSSetPlayInSignals raises on dimension mismatch.""" + times = np.array([0.0, 1.0]) + signals = np.array([[1.0], [2.0], [3.0]]) + with pytest.raises(ValueError, match="Dimension mismatch"): + saw_obj.TSSetPlayInSignals("Sig1", times, signals) + + def test_ts_initialize_exception_logged(self, saw_obj): + """TSInitialize logs warning on PowerWorldError instead of raising.""" + from esapp.saw._exceptions import PowerWorldError + with patch.object(saw_obj, '_run_script', side_effect=PowerWorldError("TS init failed")): + saw_obj.TSInitialize() + + def test_ts_clear_results_non_access_violation_raises(self, saw_obj): + """TSClearResultsFromRAM re-raises non-access-violation errors.""" + with patch.object(saw_obj, '_run_script', side_effect=Exception("Some other error")): + with pytest.raises(Exception, match="Some other error"): + saw_obj.TSClearResultsFromRAM() + + def test_ts_get_results_non_temp_mode(self, saw_obj): + """TSGetResults with filename returns (None, None).""" + result = saw_obj.TSGetResults( + mode="CSV", + contingencies=["ctg1"], + plots_fields=["TSBusVPU"], + filename="output.csv", + ) + assert result == (None, None) + + +# ============================================================================= +# AUX Parsing / Building helpers +# ============================================================================= + + +class TestAuxParsing: + """Tests for parse_aux_line, parse_aux_content, and build_aux_string.""" + + # ---- parse_aux_line ---- + + def test_parse_aux_line_space_delimited(self): + from esapp.saw._helpers import parse_aux_line + result = parse_aux_line('101 "Gen 1" 50.0') + assert result == ["101", "Gen 1", "50.0"] + + def test_parse_aux_line_bracket_format(self): + from esapp.saw._helpers import parse_aux_line + result = parse_aux_line("[1, 100.0], [2, 200.0]") + assert result == ["1, 100.0", "2, 200.0"] + + def test_parse_aux_line_quoted_with_brackets(self): + """Brackets inside quoted strings should NOT trigger bracket mode.""" + from esapp.saw._helpers import parse_aux_line + result = parse_aux_line('"Name [test]" 42') + assert result == ["Name [test]", "42"] + + def test_parse_aux_line_empty(self): + from esapp.saw._helpers import parse_aux_line + assert parse_aux_line("") == [] + assert parse_aux_line(" ") == [] + + # ---- parse_aux_content: Legacy format ---- + + def test_parse_aux_content_legacy_basic(self): + from esapp.saw._helpers import parse_aux_content + content = ( + 'DATA (Bus, [BusNum, BusName])\n' + '{\n' + '1 "Alpha"\n' + '2 "Beta"\n' + '}\n' + ) + records = parse_aux_content(content, ["BusNum", "BusName"]) + assert len(records) == 2 + assert records[0]["BusNum"] == "1" + assert records[0]["BusName"] == "Alpha" + assert records[1]["BusNum"] == "2" + + def test_parse_aux_content_legacy_with_subdata(self): + from esapp.saw._helpers import parse_aux_content + content = ( + 'DATA (Gen, [BusNum, GenID])\n' + '{\n' + '101 "1"\n' + ' \n' + ' 10.0 50.0\n' + ' 20.0 60.0\n' + ' \n' + '}\n' + ) + records = parse_aux_content(content, ["BusNum", "GenID"], ["BidCurve"]) + assert len(records) == 1 + assert records[0]["BusNum"] == "101" + assert len(records[0]["BidCurve"]) == 2 + assert records[0]["BidCurve"][0] == ["10.0", "50.0"] + + def test_parse_aux_content_legacy_multiple_subdata(self): + from esapp.saw._helpers import parse_aux_content + content = ( + 'DATA (Gen, [BusNum, GenID])\n' + '{\n' + '101 "1"\n' + ' \n' + ' 10.0 50.0\n' + ' \n' + ' \n' + ' 100.0 -50.0 50.0\n' + ' \n' + '}\n' + ) + records = parse_aux_content(content, ["BusNum", "GenID"], + ["BidCurve", "ReactiveCapability"]) + assert len(records) == 1 + assert len(records[0]["BidCurve"]) == 1 + assert len(records[0]["ReactiveCapability"]) == 1 + + def test_parse_aux_content_legacy_empty_subdata(self): + from esapp.saw._helpers import parse_aux_content + content = ( + 'DATA (Gen, [BusNum, GenID])\n' + '{\n' + '101 "1"\n' + ' \n' + ' \n' + '}\n' + ) + records = parse_aux_content(content, ["BusNum", "GenID"], ["BidCurve"]) + assert len(records) == 1 + assert records[0]["BidCurve"] == [] + + def test_parse_aux_content_legacy_comments(self): + from esapp.saw._helpers import parse_aux_content + content = ( + 'DATA (Bus, [BusNum, BusName])\n' + '{\n' + '// This is a comment\n' + '1 "Alpha"\n' + '}\n' + ) + records = parse_aux_content(content, ["BusNum", "BusName"]) + assert len(records) == 1 + assert records[0]["BusNum"] == "1" + + # ---- parse_aux_content: Concise format ---- + + def test_parse_aux_content_concise_basic(self): + from esapp.saw._helpers import parse_aux_content + content = ( + 'Bus (BusNum, BusName)\n' + '{\n' + '1 "Alpha"\n' + '2 "Beta"\n' + '}\n' + ) + records = parse_aux_content(content, ["BusNum", "BusName"]) + assert len(records) == 2 + + def test_parse_aux_content_concise_with_subdata(self): + from esapp.saw._helpers import parse_aux_content + content = ( + 'Contingency (CTGName)\n' + '{\n' + '"MyCtg"\n' + ' \n' + ' "OPEN BRANCH FROM 1 TO 2 CKT 1"\n' + ' \n' + '}\n' + ) + records = parse_aux_content(content, ["CTGName"], ["CTGElement"]) + assert len(records) == 1 + assert records[0]["CTGName"] == "MyCtg" + assert len(records[0]["CTGElement"]) == 1 + + # ---- parse_aux_content: edge cases ---- + + def test_parse_aux_content_empty(self): + from esapp.saw._helpers import parse_aux_content + assert parse_aux_content("", ["BusNum"]) == [] + + def test_parse_aux_content_malformed_subdata(self): + from esapp.saw._helpers import parse_aux_content + content = ( + 'DATA (Gen, [BusNum])\n' + '{\n' + '101\n' + ' \n' + ' 10.0\n' + ' \n' + '}\n' + ) + with pytest.raises(ValueError, match="Malformed SUBDATA"): + parse_aux_content(content, ["BusNum"], ["BidCurve"]) + + # ---- build_aux_string ---- + + def test_build_aux_string_no_subdata(self): + from esapp.saw._helpers import build_aux_string + records = [{"BusNum": 1, "BusName": "Alpha"}] + result = build_aux_string("Bus", ["BusNum", "BusName"], records) + assert "DATA (Bus, [BusNum, BusName])" in result + assert '"Alpha"' in result + assert "1" in result + + def test_build_aux_string_single_subdata(self): + from esapp.saw._helpers import build_aux_string + records = [{ + "BusNum": 101, + "GenID": "1", + "BidCurve": [[10.0, 50.0], [20.0, 60.0]], + }] + result = build_aux_string("Gen", ["BusNum", "GenID"], records, + subdatatypes="BidCurve") + assert "" in result + assert "" in result + assert "10.0" in result + + def test_build_aux_string_multiple_subdata(self): + from esapp.saw._helpers import build_aux_string + records = [{ + "BusNum": 101, + "GenID": "1", + "BidCurve": [[10.0, 50.0]], + "ReactiveCapability": [[100.0, -50.0, 50.0]], + }] + result = build_aux_string("Gen", ["BusNum", "GenID"], records, + subdatatypes=["BidCurve", "ReactiveCapability"]) + assert "" in result + assert "" in result + + # ---- Roundtrip ---- + + def test_roundtrip_build_then_parse(self): + """build_aux_string output can be parsed back by parse_aux_content.""" + from esapp.saw._helpers import build_aux_string, parse_aux_content + records = [{ + "BusNum": 101, + "GenID": "1", + "BidCurve": [["10.0", "50.0"], ["20.0", "60.0"]], + }] + aux_str = build_aux_string("Gen", ["BusNum", "GenID"], records, + subdatatypes="BidCurve") + parsed = parse_aux_content(aux_str, ["BusNum", "GenID"], ["BidCurve"]) + assert len(parsed) == 1 + assert parsed[0]["BusNum"] == "101" + assert parsed[0]["GenID"] == "1" + assert len(parsed[0]["BidCurve"]) == 2 + assert parsed[0]["BidCurve"][0] == ["10.0", "50.0"] + + +if __name__ == "__main__": + import sys + sys.exit(pytest.main(["-v", __file__])) diff --git a/tests/test_indexable_data_access.py b/tests/test_indexable_data_access.py deleted file mode 100644 index 81fa2a63..00000000 --- a/tests/test_indexable_data_access.py +++ /dev/null @@ -1,579 +0,0 @@ -""" -Unit tests for the Indexable class data access methods. - -WHAT THIS TESTS: -- __getitem__ method for reading PowerWorld data (single objects, lists, DataFrames) -- __setitem__ method for writing data back to PowerWorld -- Data type conversion and validation (strings, ints, floats, DataFrames) -- Integration with all GObject component types (parametrized testing) -- Error handling for invalid indices and data types - -DEPENDENCIES: None (mocked SAW instance, no PowerWorld required) - -USAGE: - pytest tests/test_indexable_data_access.py -v - pytest tests/test_indexable_data_access.py -k "test_getitem" -v # Only read tests -""" -import pytest -from unittest.mock import Mock, patch -from typing import Type, List -import pandas as pd -from pandas.testing import assert_frame_equal -import numpy as np - -from esapp.indexable import Indexable -from esapp import grid - -# Import shared test utilities -from conftest import get_all_gobject_subclasses, get_sample_gobject_subclasses - - -def pytest_generate_tests(metafunc): - """ - Dynamically generate test parameters at test collection time. - This ensures get_sample_gobject_subclasses() is called with proper environment setup. - """ - if "g_object" in metafunc.fixturenames: - classes = get_sample_gobject_subclasses() - ids = [c.TYPE if hasattr(c, 'TYPE') else c.__name__ for c in classes] - metafunc.parametrize("g_object", classes, ids=ids) - - -@pytest.fixture -def indexable_instance() -> Indexable: - """Provides an Indexable instance with a mocked SAW dependency.""" - with patch('esapp.indexable.SAW') as mock_saw_class: - mock_esa = Mock() - mock_saw_class.return_value = mock_esa - - instance = Indexable() - instance.esa = mock_esa - yield instance - - -# Use sample strategy for most tests to reduce execution time from 10,000+ to ~100 tests -# Full parametrization only for critical validation tests -# Note: g_object parameter is provided by pytest_generate_tests hook -def test_getitem_key_fields(indexable_instance: Indexable, g_object: Type[grid.GObject]): - """Test `idx_tool[GObject]` retrieves only key fields.""" - # Arrange - mock_esa = indexable_instance.esa - unique_keys = sorted(list(set(g_object.keys))) - - if not unique_keys: - # Act - result = indexable_instance[g_object] - # Assert - assert result is None - mock_esa.GetParamsRectTyped.assert_not_called() - return - - mock_df = pd.DataFrame({k: [1, 2] for k in unique_keys}) - mock_esa.GetParamsRectTyped.return_value = mock_df - - # Act - result_df = indexable_instance[g_object] - - # Assert - mock_esa.GetParamsRectTyped.assert_called_once_with(g_object.TYPE, unique_keys) - assert_frame_equal(result_df, mock_df) - - -def test_getitem_all_fields(indexable_instance: Indexable, g_object: Type[grid.GObject]): - """Test `idx_tool[GObject, :]` retrieves all fields.""" - # Arrange - mock_esa = indexable_instance.esa - expected_fields = sorted(list(set(g_object.keys) | set(g_object.fields))) - - if not expected_fields: - # Act - result = indexable_instance[g_object, :] - # Assert - assert result is None - mock_esa.GetParamsRectTyped.assert_not_called() - return - - mock_df = pd.DataFrame({f: [1] for f in expected_fields}) - mock_esa.GetParamsRectTyped.return_value = mock_df - - # Act - result_df = indexable_instance[g_object, :] - - # Assert - mock_esa.GetParamsRectTyped.assert_called_once_with(g_object.TYPE, expected_fields) - assert_frame_equal(result_df, mock_df) - - -def test_setitem_broadcast(indexable_instance: Indexable, g_object: Type[grid.GObject]): - """Test `idx_tool[GObject, 'Field'] = value` broadcasts a value.""" - # Arrange - mock_esa = indexable_instance.esa - # Use editable fields (non-key fields that are user-modifiable) - editable_fields = [f for f in g_object.editable if f not in g_object.keys] - if not editable_fields: - pytest.skip(f"{g_object.__name__} has no editable (non-key) fields.") - - field_to_set = editable_fields[0] - value_to_set = 1.234 - unique_keys = sorted(list(set(g_object.keys))) - - # Act - if not unique_keys: # Keyless object - indexable_instance[g_object, field_to_set] = value_to_set - expected_df = pd.DataFrame({field_to_set: [value_to_set]}) - else: # Keyed object - mock_key_df = pd.DataFrame({k: [101, 102] for k in unique_keys}) - mock_esa.GetParamsRectTyped.return_value = mock_key_df - - indexable_instance[g_object, field_to_set] = value_to_set - - # The df sent to PW should have keys and the new value - expected_df = mock_key_df.copy() - expected_df[field_to_set] = value_to_set - - # Assert - mock_esa.ChangeParametersMultipleElementRect.assert_called_once() - call_args, _ = mock_esa.ChangeParametersMultipleElementRect.call_args - sent_df = call_args[2] - assert_frame_equal(sent_df, expected_df) - - -def test_setitem_bulk_update_from_df(indexable_instance: Indexable, g_object: Type[grid.GObject]): - """Test `idx_tool[GObject] = df` performs a bulk update.""" - # Arrange - mock_esa = indexable_instance.esa - - # Only use settable fields (keys + editable) for bulk update - settable_cols = list(g_object.settable) - if not settable_cols: - pytest.skip(f"{g_object.__name__} has no settable fields to update.") - - update_df = pd.DataFrame({f: [10, 20] for f in settable_cols}) - - # Act - indexable_instance[g_object] = update_df - - # Assert - mock_esa.ChangeParametersMultipleElementRect.assert_called_once_with( - g_object.TYPE, - update_df.columns.tolist(), - update_df - ) - - -def test_getitem_specific_fields(indexable_instance: Indexable, g_object: Type[grid.GObject]): - """Test `idx_tool[GObject, ['Field1', 'Field2']]` retrieves specific fields plus all keys.""" - # Arrange - mock_esa = indexable_instance.esa - - # Select one non-key field to request, if available. - specific_fields_to_request = [f for f in g_object.fields if f not in g_object.keys] - if not specific_fields_to_request: - pytest.skip(f"{g_object.__name__} has no non-key fields to request specifically.") - - field_to_request = specific_fields_to_request[0] - - # The implementation always fetches all keys plus the requested fields. - expected_fields_to_get = sorted(list(set(g_object.keys) | {field_to_request})) - - mock_df = pd.DataFrame({f: [1, 2] for f in expected_fields_to_get}) - mock_esa.GetParamsRectTyped.return_value = mock_df - - # Act - result_df = indexable_instance[g_object, [field_to_request]] - - # Assert - mock_esa.GetParamsRectTyped.assert_called_once_with(g_object.TYPE, expected_fields_to_get) - assert_frame_equal(result_df, mock_df) - - -def test_setitem_broadcast_multiple_fields(indexable_instance: Indexable, g_object: Type[grid.GObject]): - """Test `idx_tool[GObject, ['F1', 'F2']] = [v1, v2]` broadcasts multiple values.""" - # Arrange - mock_esa = indexable_instance.esa - # Use editable fields (non-key fields that are user-modifiable) - editable_fields = [f for f in g_object.editable if f not in g_object.keys] - if len(editable_fields) < 2: - pytest.skip(f"{g_object.__name__} has fewer than two editable fields.") - - fields_to_set = editable_fields[:2] - values_to_set = [1.1, 2.2] - unique_keys = sorted(list(set(g_object.keys))) - - if not unique_keys: - # Keyless object: test the direct DataFrame creation path - indexable_instance[g_object, fields_to_set] = values_to_set - - # Assert: For keyless objects, a single-row DataFrame is created directly - mock_esa.ChangeParametersMultipleElementRect.assert_called_once() - sent_df = mock_esa.ChangeParametersMultipleElementRect.call_args[0][2] - assert len(sent_df) == 1 - assert sent_df.iloc[0][fields_to_set[0]] == values_to_set[0] - assert sent_df.iloc[0][fields_to_set[1]] == values_to_set[1] - return - - mock_key_df = pd.DataFrame({k: [101, 102] for k in unique_keys}) - mock_esa.GetParamsRectTyped.return_value = mock_key_df - - # Act - indexable_instance[g_object, fields_to_set] = values_to_set - - # Assert - expected_df = mock_key_df.copy() - expected_df[fields_to_set] = values_to_set # Pandas assigns list to columns - - mock_esa.ChangeParametersMultipleElementRect.assert_called_once() - sent_df = mock_esa.ChangeParametersMultipleElementRect.call_args[0][2] - assert_frame_equal(sent_df, expected_df) - - -def test_setitem_raises_error_on_invalid_index(indexable_instance: Indexable): - """Test that __setitem__ raises TypeError for unsupported index types.""" - with pytest.raises(TypeError, match="Unsupported index for __setitem__"): - indexable_instance[123] = "some_value" - with pytest.raises(TypeError, match="First element of index must be a GObject subclass"): - indexable_instance[(123, "field")] = "some_value" - - -def test_setitem_raises_error_on_non_settable_field(indexable_instance: Indexable): - """Test that setting a non-editable (read-only) field raises ValueError.""" - # Find a non-settable field on Bus - non_settable = [f for f in grid.Bus.fields if f not in grid.Bus.settable] - if not non_settable: - pytest.skip("Bus has no non-settable fields to test.") - - with pytest.raises(ValueError, match="Cannot set read-only field"): - indexable_instance[grid.Bus, non_settable[0]] = 1.0 - - -def test_setitem_bulk_raises_error_on_non_settable_column(indexable_instance: Indexable): - """Test that bulk update with a non-settable column raises ValueError.""" - # Find a non-settable field on Bus - non_settable = [f for f in grid.Bus.fields if f not in grid.Bus.settable] - if not non_settable: - pytest.skip("Bus has no non-settable fields to test.") - - # Create a DataFrame with a non-settable column - update_df = pd.DataFrame({ - "BusNum": [1, 2], - non_settable[0]: [100, 200] - }) - - with pytest.raises(ValueError, match="Cannot set read-only field"): - indexable_instance[grid.Bus] = update_df - - -def test_setitem_bulk_allows_secondary_identifier_fields(indexable_instance: Indexable): - """Test that bulk update with SECONDARY identifier fields is allowed. - - This is critical for objects like Load where LoadID is SECONDARY (not PRIMARY) - but still needed to identify records for updates. - """ - mock_esa = indexable_instance.esa - - # Load has BusNum (PRIMARY) and LoadID (SECONDARY) as identifiers - # Both should be allowed in bulk updates - assert "BusNum" in grid.Load.keys, "BusNum should be a primary key" - assert "LoadID" in grid.Load.secondary, "LoadID should be a secondary field" - assert "LoadID" in grid.Load.settable, "LoadID should be settable as a secondary identifier" - - # Create a DataFrame with both primary and secondary identifier fields - update_df = pd.DataFrame({ - "BusNum": [1, 2], - "LoadID": ["1", "2"], - "LoadSMW": [10.0, 20.0] # An editable field - }) - - # This should NOT raise an error - indexable_instance[grid.Load] = update_df - - # Verify the call was made - mock_esa.ChangeParametersMultipleElementRect.assert_called_once() - - -def test_gobject_identifiers_property(): - """Test that identifiers includes both primary and secondary keys.""" - # Load should have BusNum as PRIMARY and LoadID, BusName_NomVolt as SECONDARY - assert "BusNum" in grid.Load.identifiers - assert "LoadID" in grid.Load.identifiers - - # Gen should have BusNum as PRIMARY and GenID as SECONDARY - assert "BusNum" in grid.Gen.identifiers - assert "GenID" in grid.Gen.identifiers - - -# ------------------------------------------------------------------------- -# Keyless Object Tests -# ------------------------------------------------------------------------- - -def test_setitem_keyless_object_single_field(indexable_instance: Indexable): - """Test setting a single field on a keyless object (e.g., Sim_Solution_Options). - - Keyless objects are singleton configuration objects in PowerWorld that don't - have primary keys. For these, __setitem__ creates a single-row DataFrame directly - without first querying existing keys. - """ - mock_esa = indexable_instance.esa - - # Sim_Solution_Options is a keyless object with many editable fields - assert not grid.Sim_Solution_Options.keys, "Expected Sim_Solution_Options to be keyless" - editable = list(grid.Sim_Solution_Options.editable) - assert len(editable) > 0, "Expected Sim_Solution_Options to have editable fields" - - field_to_set = editable[0] - value_to_set = "YES" - - # Act - indexable_instance[grid.Sim_Solution_Options, field_to_set] = value_to_set - - # Assert: A single-row DataFrame should be created and sent - mock_esa.ChangeParametersMultipleElementRect.assert_called_once() - sent_df = mock_esa.ChangeParametersMultipleElementRect.call_args[0][2] - assert len(sent_df) == 1 - assert sent_df.iloc[0][field_to_set] == value_to_set - # Should NOT have called GetParamsRectTyped since no keys to fetch - mock_esa.GetParamsRectTyped.assert_not_called() - - -def test_setitem_keyless_object_multiple_fields(indexable_instance: Indexable): - """Test setting multiple fields on a keyless object. - - This tests the specific code path where keyless objects have their - DataFrame built directly from the provided fields and values. - """ - mock_esa = indexable_instance.esa - - # Sim_Solution_Options is a keyless object with many editable fields - assert not grid.Sim_Solution_Options.keys - editable = list(grid.Sim_Solution_Options.editable) - assert len(editable) >= 2, "Need at least 2 editable fields for this test" - - fields_to_set = editable[:2] - values_to_set = ["YES", "NO"] - - # Act - indexable_instance[grid.Sim_Solution_Options, fields_to_set] = values_to_set - - # Assert - mock_esa.ChangeParametersMultipleElementRect.assert_called_once() - sent_df = mock_esa.ChangeParametersMultipleElementRect.call_args[0][2] - assert len(sent_df) == 1 - assert sent_df.iloc[0][fields_to_set[0]] == values_to_set[0] - assert sent_df.iloc[0][fields_to_set[1]] == values_to_set[1] - - -def test_setitem_keyless_object_value_length_mismatch(indexable_instance: Indexable): - """Test that keyless object broadcast with mismatched field/value counts raises error.""" - # Sim_Solution_Options is a keyless object with many editable fields - editable = list(grid.Sim_Solution_Options.editable) - assert len(editable) >= 2 - - fields_to_set = editable[:2] - values_to_set = ["YES", "NO", "EXTRA"] # 3 values for 2 fields - - with pytest.raises(ValueError, match="must be a list/tuple of the same length"): - indexable_instance[grid.Sim_Solution_Options, fields_to_set] = values_to_set - - -def test_setitem_single_editable_field_object(indexable_instance: Indexable): - """Test setting the single editable field on objects with only one editable field. - - Some objects like ScheduledActions_Options_Value have only one editable field - (ValueField). This test ensures such objects work correctly with broadcast updates. - """ - mock_esa = indexable_instance.esa - - # ScheduledActions_Options_Value has VariableName (PRIMARY) and ValueField (EDITABLE) - assert "VariableName" in grid.ScheduledActions_Options_Value.keys - editable = [f for f in grid.ScheduledActions_Options_Value.editable - if f not in grid.ScheduledActions_Options_Value.keys] - assert len(editable) == 1, "Expected exactly one non-key editable field" - - field_to_set = editable[0] - value_to_set = "test_value" - - # Mock existing objects - mock_key_df = pd.DataFrame({"VariableName": ["Option1", "Option2"]}) - mock_esa.GetParamsRectTyped.return_value = mock_key_df - - # Act - indexable_instance[grid.ScheduledActions_Options_Value, field_to_set] = value_to_set - - # Assert: The single editable field is broadcast to all rows - mock_esa.ChangeParametersMultipleElementRect.assert_called_once() - sent_df = mock_esa.ChangeParametersMultipleElementRect.call_args[0][2] - assert len(sent_df) == 2 - assert (sent_df[field_to_set] == value_to_set).all() - - -# ------------------------------------------------------------------------- -# Edge Case Tests -# ------------------------------------------------------------------------- - -def test_getitem_with_empty_dataframe(indexable_instance: Indexable): - """Test behavior when PowerWorld returns an empty DataFrame.""" - mock_esa = indexable_instance.esa - mock_esa.GetParamsRectTyped.return_value = pd.DataFrame() - - result = indexable_instance[grid.Bus] - assert result is not None - assert isinstance(result, pd.DataFrame) - assert result.empty - - -def test_getitem_with_none_return(indexable_instance: Indexable): - """Test behavior when PowerWorld returns None.""" - mock_esa = indexable_instance.esa - mock_esa.GetParamsRectTyped.return_value = None - - result = indexable_instance[grid.Bus] - assert result is None - - -def test_setitem_with_nan_values(indexable_instance: Indexable): - """Test that NaN values are handled correctly in DataFrame updates.""" - mock_esa = indexable_instance.esa - - # Get an editable field from Bus - editable_fields = [f for f in grid.Bus.editable if f not in grid.Bus.keys] - if not editable_fields: - pytest.skip("Bus has no editable non-key fields.") - editable_field = editable_fields[0] - key_field = grid.Bus.keys[0] if grid.Bus.keys else None - if not key_field: - pytest.skip("Bus has no key fields.") - - # Create DataFrame with NaN values using settable fields - update_df = pd.DataFrame({ - key_field: [1, 2, 3], - editable_field: [1.0, np.nan, 1.02] - }) - - indexable_instance[grid.Bus] = update_df - - # Verify the DataFrame was passed with NaN intact - mock_esa.ChangeParametersMultipleElementRect.assert_called_once() - sent_df = mock_esa.ChangeParametersMultipleElementRect.call_args[0][2] - assert pd.isna(sent_df.iloc[1][editable_field]) - - -def test_setitem_with_mixed_types(indexable_instance: Indexable): - """Test setting fields with mixed data types.""" - mock_esa = indexable_instance.esa - - # Build a DataFrame using only settable fields from Bus - settable_cols = list(grid.Bus.settable) - if len(settable_cols) < 2: - pytest.skip("Bus has fewer than 2 settable fields.") - - update_df = pd.DataFrame({col: [10, 20, 30] for col in settable_cols[:3]}) - - indexable_instance[grid.Bus] = update_df - mock_esa.ChangeParametersMultipleElementRect.assert_called_once() - - -def test_getitem_with_slice_none(indexable_instance: Indexable): - """Test that slice(None) correctly retrieves all fields.""" - mock_esa = indexable_instance.esa - mock_df = pd.DataFrame({"BusNum": [1], "BusName": ["Bus1"], "BusPUVolt": [1.0]}) - mock_esa.GetParamsRectTyped.return_value = mock_df - - result = indexable_instance[grid.Bus, :] - - # Should request all fields (keys + fields) - call_args = mock_esa.GetParamsRectTyped.call_args[0] - requested_fields = call_args[1] - assert len(requested_fields) > len(grid.Bus.keys) - - -def test_setitem_broadcast_with_single_value(indexable_instance: Indexable): - """Test broadcasting a single value to all instances.""" - mock_esa = indexable_instance.esa - - # Get an editable field from Bus - editable_fields = [f for f in grid.Bus.editable if f not in grid.Bus.keys] - if not editable_fields: - pytest.skip("Bus has no editable non-key fields.") - editable_field = editable_fields[0] - key_field = grid.Bus.keys[0] if grid.Bus.keys else None - if not key_field: - pytest.skip("Bus has no key fields.") - - mock_df = pd.DataFrame({key_field: [1, 2, 3]}) - mock_esa.GetParamsRectTyped.return_value = mock_df - - indexable_instance[grid.Bus, editable_field] = 1.05 - - # Verify all three buses got the same value - sent_df = mock_esa.ChangeParametersMultipleElementRect.call_args[0][2] - assert len(sent_df) == 3 - assert (sent_df[editable_field] == 1.05).all() - - -def test_setitem_with_series(indexable_instance: Indexable): - """Test setting data using a pandas Series instead of a DataFrame.""" - mock_esa = indexable_instance.esa - - # Get an editable field from Bus - editable_fields = [f for f in grid.Bus.editable if f not in grid.Bus.keys] - if not editable_fields: - pytest.skip("Bus has no editable non-key fields.") - editable_field = editable_fields[0] - key_field = grid.Bus.keys[0] if grid.Bus.keys else None - if not key_field: - pytest.skip("Bus has no key fields.") - - mock_df = pd.DataFrame({key_field: [1, 2, 3]}) - mock_esa.GetParamsRectTyped.return_value = mock_df - - # Create a Series with per-bus values (reset index to ensure proper alignment) - values = pd.Series([1.00, 1.01, 1.02]).values # Convert to numpy array to avoid index alignment issues - indexable_instance[grid.Bus, editable_field] = values - - sent_df = mock_esa.ChangeParametersMultipleElementRect.call_args[0][2] - # Compare values directly, not relying on index alignment - assert np.allclose(sent_df[editable_field].values, values) - - -def test_getitem_with_nonexistent_field(): - """Test requesting a field that doesn't exist in the GObject definition.""" - with patch('esapp.indexable.SAW') as mock_saw_class: - mock_esa = Mock() - mock_saw_class.return_value = mock_esa - - instance = Indexable() - instance.esa = mock_esa - - # This should still call the API but might return empty or error - # Document the expected behavior - result = instance[grid.Bus, ["NonExistentField"]] - mock_esa.GetParamsRectTyped.assert_called_once() - - -def test_setitem_empty_dataframe(indexable_instance: Indexable): - """Test setting an empty DataFrame (should handle gracefully).""" - mock_esa = indexable_instance.esa - - empty_df = pd.DataFrame() - indexable_instance[grid.Bus] = empty_df - - # Should still call the API, even if DataFrame is empty - mock_esa.ChangeParametersMultipleElementRect.assert_called_once() - - -def test_concurrent_field_access(indexable_instance: Indexable): - """Test that multiple field requests are handled correctly.""" - mock_esa = indexable_instance.esa - mock_df = pd.DataFrame({ - "BusNum": [1, 2], - "BusPUVolt": [1.0, 1.01], - "BusAngle": [0.0, -2.0] - }) - mock_esa.GetParamsRectTyped.return_value = mock_df - - # Request multiple fields - result = indexable_instance[grid.Bus, ["BusPUVolt", "BusAngle"]] - - assert "BusPUVolt" in result.columns - assert "BusAngle" in result.columns - assert "BusNum" in result.columns # Keys should also be included \ No newline at end of file diff --git a/tests/test_indexing.py b/tests/test_indexing.py new file mode 100644 index 00000000..df321d6c --- /dev/null +++ b/tests/test_indexing.py @@ -0,0 +1,523 @@ +""" +Unit tests for the Indexable class data access (wb[GObject, "field"] syntax). + +These are **unit tests** that do NOT require PowerWorld Simulator. All +PowerWorld COM interactions are mocked. They test __getitem__ and __setitem__ +for reading/writing PowerWorld data, including broadcast, bulk update, +keyless objects, and error handling. + +USAGE: + pytest tests/test_indexing.py -v +""" +import pytest +from unittest.mock import Mock, patch +from typing import Type +import pandas as pd +from pandas.testing import assert_frame_equal +import numpy as np + +from esapp.indexable import Indexable +from esapp import components as grid +from tests.conftest import get_sample_gobject_subclasses + + +def pytest_generate_tests(metafunc): + """Dynamically parametrize tests that use the g_object fixture.""" + if "g_object" in metafunc.fixturenames: + classes = get_sample_gobject_subclasses() + ids = [c.TYPE if hasattr(c, 'TYPE') else c.__name__ for c in classes] + metafunc.parametrize("g_object", classes, ids=ids) + elif "g_object_keyed" in metafunc.fixturenames: + # Objects that have keys (for tests that require GetParamsRectTyped to return key data) + classes = get_sample_gobject_subclasses(require_keys=True) + ids = [c.TYPE if hasattr(c, 'TYPE') else c.__name__ for c in classes] + metafunc.parametrize("g_object_keyed", classes, ids=ids) + elif "g_object_keyed_editable" in metafunc.fixturenames: + # Objects with keys AND at least 1 editable non-key field + classes = get_sample_gobject_subclasses(require_keys=True, require_editable_non_key=True) + ids = [c.TYPE if hasattr(c, 'TYPE') else c.__name__ for c in classes] + metafunc.parametrize("g_object_keyed_editable", classes, ids=ids) + elif "g_object_multi_editable" in metafunc.fixturenames: + # Objects with at least 2 editable non-key fields + classes = get_sample_gobject_subclasses(require_multiple_editable=True) + ids = [c.TYPE if hasattr(c, 'TYPE') else c.__name__ for c in classes] + metafunc.parametrize("g_object_multi_editable", classes, ids=ids) + + +@pytest.fixture +def indexable_instance() -> Indexable: + """Provides an Indexable instance with a mocked SAW dependency.""" + with patch('esapp.indexable.SAW') as mock_saw_class: + mock_esa = Mock() + mock_saw_class.return_value = mock_esa + instance = Indexable() + instance.esa = mock_esa + yield instance + + +# ============================================================================= +# __getitem__ tests +# ============================================================================= + +def test_getitem_key_fields(indexable_instance: Indexable, g_object: Type[grid.GObject]): + """idx[GObject] retrieves only key fields.""" + mock_esa = indexable_instance.esa + unique_keys = sorted(list(set(g_object.keys))) + + if not unique_keys: + result = indexable_instance[g_object] + assert result is None + mock_esa.GetParamsRectTyped.assert_not_called() + return + + mock_df = pd.DataFrame({k: [1, 2] for k in unique_keys}) + mock_esa.GetParamsRectTyped.return_value = mock_df + + result_df = indexable_instance[g_object] + mock_esa.GetParamsRectTyped.assert_called_once_with(g_object.TYPE, unique_keys) + assert_frame_equal(result_df, mock_df) + + +def test_getitem_all_fields(indexable_instance: Indexable, g_object: Type[grid.GObject]): + """idx[GObject, :] retrieves all fields.""" + mock_esa = indexable_instance.esa + expected_fields = sorted(list(set(g_object.keys) | set(g_object.fields))) + + if not expected_fields: + result = indexable_instance[g_object, :] + assert result is None + return + + mock_df = pd.DataFrame({f: [1] for f in expected_fields}) + mock_esa.GetParamsRectTyped.return_value = mock_df + + result_df = indexable_instance[g_object, :] + mock_esa.GetParamsRectTyped.assert_called_once_with(g_object.TYPE, expected_fields) + assert_frame_equal(result_df, mock_df) + + +def test_getitem_specific_fields(indexable_instance: Indexable, g_object: Type[grid.GObject]): + """idx[GObject, ['Field1']] retrieves specific fields plus all keys.""" + mock_esa = indexable_instance.esa + specific_fields = [f for f in g_object.fields if f not in g_object.keys] + if not specific_fields: + pytest.skip(f"{g_object.__name__} has no non-key fields.") + + field = specific_fields[0] + expected = sorted(list(set(g_object.keys) | {field})) + mock_df = pd.DataFrame({f: [1, 2] for f in expected}) + mock_esa.GetParamsRectTyped.return_value = mock_df + + result_df = indexable_instance[g_object, [field]] + mock_esa.GetParamsRectTyped.assert_called_once_with(g_object.TYPE, expected) + assert_frame_equal(result_df, mock_df) + + +def test_getitem_empty_dataframe(indexable_instance: Indexable): + """Empty DataFrame returned from PowerWorld.""" + indexable_instance.esa.GetParamsRectTyped.return_value = pd.DataFrame() + result = indexable_instance[grid.Bus] + assert isinstance(result, pd.DataFrame) + assert result.empty + + +def test_getitem_none_return(indexable_instance: Indexable): + """None returned from PowerWorld.""" + indexable_instance.esa.GetParamsRectTyped.return_value = None + assert indexable_instance[grid.Bus] is None + + +# ============================================================================= +# __setitem__ tests +# ============================================================================= + +def test_setitem_broadcast(indexable_instance: Indexable, g_object: Type[grid.GObject]): + """idx[GObject, 'Field'] = value broadcasts to all rows.""" + mock_esa = indexable_instance.esa + editable_fields = [f for f in g_object.editable if f not in g_object.keys] + if not editable_fields: + pytest.skip(f"{g_object.__name__} has no editable non-key fields.") + + field = editable_fields[0] + unique_keys = sorted(list(set(g_object.keys))) + + if not unique_keys: + indexable_instance[g_object, field] = 1.234 + expected_df = pd.DataFrame({field: [1.234]}) + else: + mock_key_df = pd.DataFrame({k: [101, 102] for k in unique_keys}) + mock_esa.GetParamsRectTyped.return_value = mock_key_df + indexable_instance[g_object, field] = 1.234 + expected_df = mock_key_df.copy() + expected_df[field] = 1.234 + + mock_esa.ChangeParametersMultipleElementRect.assert_called_once() + sent_df = mock_esa.ChangeParametersMultipleElementRect.call_args[0][2] + assert_frame_equal(sent_df, expected_df) + + +def test_setitem_bulk_update_from_df(indexable_instance: Indexable, g_object: Type[grid.GObject]): + """idx[GObject] = df performs bulk update.""" + mock_esa = indexable_instance.esa + settable_cols = list(g_object.settable) + if not settable_cols: + pytest.skip(f"{g_object.__name__} has no settable fields.") + + update_df = pd.DataFrame({f: [10, 20] for f in settable_cols}) + indexable_instance[g_object] = update_df + + mock_esa.ChangeParametersMultipleElementRect.assert_called_once_with( + g_object.TYPE, update_df.columns.tolist(), update_df + ) + + +def test_setitem_broadcast_multiple_fields(indexable_instance: Indexable, g_object_multi_editable: Type[grid.GObject]): + """idx[GObject, ['F1','F2']] = [v1, v2] broadcasts multiple values.""" + mock_esa = indexable_instance.esa + g_object = g_object_multi_editable + editable_fields = [f for f in g_object.editable if f not in g_object.keys] + # Filtering already ensures at least 2 editable non-key fields + assert len(editable_fields) >= 2, f"{g_object.__name__} should have >= 2 editable fields" + + fields = editable_fields[:2] + values = [1.1, 2.2] + unique_keys = sorted(list(set(g_object.keys))) + + if not unique_keys: + indexable_instance[g_object, fields] = values + sent_df = mock_esa.ChangeParametersMultipleElementRect.call_args[0][2] + assert len(sent_df) == 1 + assert sent_df.iloc[0][fields[0]] == values[0] + return + + mock_key_df = pd.DataFrame({k: [101, 102] for k in unique_keys}) + mock_esa.GetParamsRectTyped.return_value = mock_key_df + indexable_instance[g_object, fields] = values + + expected_df = mock_key_df.copy() + expected_df[fields] = values + sent_df = mock_esa.ChangeParametersMultipleElementRect.call_args[0][2] + assert_frame_equal(sent_df, expected_df) + + +# ============================================================================= +# Error handling +# ============================================================================= + +def test_setitem_invalid_index(indexable_instance: Indexable): + """TypeError for unsupported index types.""" + with pytest.raises(TypeError, match="Unsupported index for __setitem__"): + indexable_instance[123] = "value" + with pytest.raises(TypeError, match="First element of index must be a GObject subclass"): + indexable_instance[(123, "field")] = "value" + + +def test_setitem_non_settable_field(indexable_instance: Indexable): + """ValueError when setting a read-only field.""" + non_settable = [f for f in grid.Bus.fields if f not in grid.Bus.settable] + if not non_settable: + pytest.skip("Bus has no non-settable fields.") + with pytest.raises(ValueError, match="Cannot set read-only field"): + indexable_instance[grid.Bus, non_settable[0]] = 1.0 + + +def test_setitem_bulk_non_settable_column(indexable_instance: Indexable): + """ValueError when bulk update includes a read-only column.""" + non_settable = [f for f in grid.Bus.fields if f not in grid.Bus.settable] + if not non_settable: + pytest.skip("Bus has no non-settable fields.") + update_df = pd.DataFrame({"BusNum": [1, 2], non_settable[0]: [100, 200]}) + with pytest.raises(ValueError, match="Cannot set read-only field"): + indexable_instance[grid.Bus] = update_df + + +# ============================================================================= +# Secondary identifiers and keyless objects +# ============================================================================= + +def test_setitem_allows_secondary_identifier_fields(indexable_instance: Indexable): + """Bulk update with SECONDARY identifier fields is allowed (e.g. LoadID).""" + mock_esa = indexable_instance.esa + assert "LoadID" in grid.Load.settable + update_df = pd.DataFrame({ + "BusNum": [1, 2], "LoadID": ["1", "2"], "LoadSMW": [10.0, 20.0] + }) + indexable_instance[grid.Load] = update_df + mock_esa.ChangeParametersMultipleElementRect.assert_called_once() + + +def test_gobject_identifiers_property(): + """identifiers includes both primary and secondary keys.""" + assert "BusNum" in grid.Load.identifiers + assert "LoadID" in grid.Load.identifiers + assert "BusNum" in grid.Gen.identifiers + assert "GenID" in grid.Gen.identifiers + + +def test_keyless_object_single_field(indexable_instance: Indexable): + """Setting a field on a keyless object creates a single-row DataFrame.""" + mock_esa = indexable_instance.esa + assert not grid.Sim_Solution_Options.keys + editable = list(grid.Sim_Solution_Options.editable) + assert len(editable) > 0 + + indexable_instance[grid.Sim_Solution_Options, editable[0]] = "YES" + + sent_df = mock_esa.ChangeParametersMultipleElementRect.call_args[0][2] + assert len(sent_df) == 1 + assert sent_df.iloc[0][editable[0]] == "YES" + mock_esa.GetParamsRectTyped.assert_not_called() + + +def test_keyless_object_multiple_fields(indexable_instance: Indexable): + """Setting multiple fields on a keyless object.""" + mock_esa = indexable_instance.esa + editable = list(grid.Sim_Solution_Options.editable) + assert len(editable) >= 2 + + fields = editable[:2] + indexable_instance[grid.Sim_Solution_Options, fields] = ["YES", "NO"] + + sent_df = mock_esa.ChangeParametersMultipleElementRect.call_args[0][2] + assert len(sent_df) == 1 + assert sent_df.iloc[0][fields[0]] == "YES" + assert sent_df.iloc[0][fields[1]] == "NO" + + +def test_keyless_object_value_length_mismatch(indexable_instance: Indexable): + """Mismatched field/value counts on keyless object raises ValueError.""" + editable = list(grid.Sim_Solution_Options.editable) + fields = editable[:2] + with pytest.raises(ValueError, match="must be a list/tuple of the same length"): + indexable_instance[grid.Sim_Solution_Options, fields] = ["YES", "NO", "EXTRA"] + + +def test_setitem_with_nan_values(indexable_instance: Indexable): + """NaN values are passed through to PowerWorld unchanged.""" + mock_esa = indexable_instance.esa + editable_fields = [f for f in grid.Bus.editable if f not in grid.Bus.keys] + if not editable_fields: + pytest.skip("Bus has no editable non-key fields.") + key_field = grid.Bus.keys[0] + + update_df = pd.DataFrame({ + key_field: [1, 2, 3], + editable_fields[0]: [1.0, np.nan, 1.02] + }) + indexable_instance[grid.Bus] = update_df + + sent_df = mock_esa.ChangeParametersMultipleElementRect.call_args[0][2] + assert pd.isna(sent_df.iloc[1][editable_fields[0]]) + + +# ============================================================================= +# Additional coverage tests +# ============================================================================= + +def test_open_relative_path(): + """open() converts relative path to absolute.""" + from os import path as ospath + with patch('esapp.indexable.SAW') as mock_saw_class, \ + patch('esapp.indexable.path.isabs', return_value=False), \ + patch('esapp.indexable.path.abspath', return_value='/abs/path/case.pwb'), \ + patch('esapp.indexable.path.exists', return_value=True): + + mock_esa = Mock() + mock_saw_class.return_value = mock_esa + + instance = Indexable() + instance.fname = 'relative/case.pwb' + instance.open() + + assert instance.fname == '/abs/path/case.pwb' + mock_saw_class.assert_called_once_with('/abs/path/case.pwb', CreateIfNotFound=True, early_bind=True) + + +def test_open_absolute_path(): + """open() preserves absolute path.""" + with patch('esapp.indexable.SAW') as mock_saw_class, \ + patch('esapp.indexable.path.isabs', return_value=True), \ + patch('esapp.indexable.path.exists', return_value=True): + + mock_esa = Mock() + mock_saw_class.return_value = mock_esa + + instance = Indexable() + instance.fname = '/absolute/path/case.pwb' + instance.open() + + assert instance.fname == '/absolute/path/case.pwb' + mock_saw_class.assert_called_once_with('/absolute/path/case.pwb', CreateIfNotFound=True, early_bind=True) + + +def test_fexcept_helper(): + """fexcept converts 'Three' prefix back to '3'.""" + from esapp.indexable import fexcept + + assert fexcept("ThreeWindingTransformer") == "3WindingTransformer" + assert fexcept("ThreePhase") == "3Phase" + assert fexcept("NormalName") == "NormalName" + assert fexcept("Bus") == "Bus" + assert fexcept("") == "" + + +def test_getitem_with_gobject_enum_field(indexable_instance: Indexable): + """idx[GObject, GObject.Field] retrieves field using enum member.""" + mock_esa = indexable_instance.esa + + # Get a GObject field enum member + bus_fields = list(grid.Bus) + field_member = None + for member in bus_fields: + if hasattr(member, 'value') and isinstance(member.value, tuple) and len(member.value) >= 2: + field_member = member + break + + if field_member is None: + pytest.skip("Could not find a suitable GObject field member.") + + field_name = field_member.value[1] + expected_fields = sorted(list(set(grid.Bus.keys) | {field_name})) + + mock_df = pd.DataFrame({f: [1, 2] for f in expected_fields}) + mock_esa.GetParamsRectTyped.return_value = mock_df + + result_df = indexable_instance[grid.Bus, field_member] + mock_esa.GetParamsRectTyped.assert_called_once_with(grid.Bus.TYPE, expected_fields) + assert_frame_equal(result_df, mock_df) + + +def test_getitem_invalid_slice(indexable_instance: Indexable): + """ValueError when using unsupported slice for fields.""" + with pytest.raises(ValueError, match="Only the full slice"): + indexable_instance[grid.Bus, [slice(1, 2)]] + + +def test_setitem_invalid_fields_type(indexable_instance: Indexable): + """TypeError when fields is not a string or list.""" + with pytest.raises(TypeError, match="Fields must be a string or a list/tuple"): + indexable_instance[grid.Bus, 123] = "value" + + +def test_setitem_bulk_update_not_dataframe(indexable_instance: Indexable): + """TypeError when bulk update value is not a DataFrame.""" + with pytest.raises(TypeError, match="A DataFrame is required"): + indexable_instance[grid.Bus] = "not a dataframe" + + +def test_setitem_broadcast_empty_dataframe(indexable_instance: Indexable, g_object_keyed_editable: Type[grid.GObject]): + """Setting field on objects when no objects exist (empty DataFrame) is a no-op.""" + mock_esa = indexable_instance.esa + g_object = g_object_keyed_editable + editable_fields = [f for f in g_object.editable if f not in g_object.keys] + + # Filtering already ensures keys exist and at least 1 editable non-key field + assert g_object.keys, f"{g_object.__name__} should have keys" + assert editable_fields, f"{g_object.__name__} should have editable non-key fields" + + mock_esa.GetParamsRectTyped.return_value = pd.DataFrame() + + indexable_instance[g_object, editable_fields[0]] = 1.0 + + # Should not call ChangeParametersMultipleElementRect since no objects exist + mock_esa.ChangeParametersMultipleElementRect.assert_not_called() + + +def test_setitem_broadcast_none_dataframe(indexable_instance: Indexable): + """Setting field when GetParamsRectTyped returns None is a no-op.""" + mock_esa = indexable_instance.esa + editable_fields = [f for f in grid.Bus.editable if f not in grid.Bus.keys] + + if not editable_fields: + pytest.skip("Bus has no editable non-key fields.") + + mock_esa.GetParamsRectTyped.return_value = None + + indexable_instance[grid.Bus, editable_fields[0]] = 1.0 + + mock_esa.ChangeParametersMultipleElementRect.assert_not_called() + + +def test_bulk_update_not_found_missing_identifiers(indexable_instance: Indexable): + """ValueError when bulk update fails with missing primary keys.""" + from esapp.saw import PowerWorldPrerequisiteError + mock_esa = indexable_instance.esa + + # Create a DataFrame missing the primary key (GenID) + update_df = pd.DataFrame({ + "BusNum": [1, 2], + "GenMW": [100.0, 200.0] + }) + + # Mock ChangeParametersMultipleElementRect to raise "not found" error + mock_esa.ChangeParametersMultipleElementRect.side_effect = PowerWorldPrerequisiteError( + "Object not found in case" + ) + + with pytest.raises(ValueError, match="Missing required primary key field"): + indexable_instance[grid.Gen] = update_df + + +def test_bulk_update_not_found_all_keys_present_falls_back(indexable_instance: Indexable): + """When primary keys are present and Rect fails with 'not found', + falls back to ChangeParametersMultipleElement to create the objects.""" + from esapp.saw import PowerWorldPrerequisiteError + mock_esa = indexable_instance.esa + + # Create a DataFrame with all primary keys present + update_df = pd.DataFrame({ + "BusNum": [999, 1000], + "GenID": ["1", "1"], + "GenMW": [100.0, 200.0], + }) + + # Mock ChangeParametersMultipleElementRect to raise "not found" error + mock_esa.ChangeParametersMultipleElementRect.side_effect = PowerWorldPrerequisiteError( + "Object not found in case" + ) + + # The fallback ChangeParametersMultipleElement should be called instead of raising + indexable_instance[grid.Gen] = update_df + + mock_esa.ChangeParametersMultipleElement.assert_called_once() + call_args = mock_esa.ChangeParametersMultipleElement.call_args + assert call_args[0][0] == "Gen" # ObjectType + assert "BusNum" in call_args[0][1] # field list includes keys + + +def test_bulk_update_other_error(indexable_instance: Indexable): + """Other PowerWorldPrerequisiteError is re-raised without modification.""" + from esapp.saw import PowerWorldPrerequisiteError + mock_esa = indexable_instance.esa + + update_df = pd.DataFrame({ + "BusNum": [1, 2], + "GenID": ["1", "1"] + }) + + # Mock with a different error message (not "not found") + mock_esa.ChangeParametersMultipleElementRect.side_effect = PowerWorldPrerequisiteError( + "Some other PowerWorld error" + ) + + with pytest.raises(PowerWorldPrerequisiteError, match="Some other PowerWorld error"): + indexable_instance[grid.Gen] = update_df + + +def test_getitem_single_string_field(indexable_instance: Indexable): + """idx[GObject, 'FieldName'] works with a single string field.""" + mock_esa = indexable_instance.esa + + non_key_fields = [f for f in grid.Bus.fields if f not in grid.Bus.keys] + if not non_key_fields: + pytest.skip("Bus has no non-key fields.") + + field = non_key_fields[0] + expected_fields = sorted(list(set(grid.Bus.keys) | {field})) + + mock_df = pd.DataFrame({f: [1, 2] for f in expected_fields}) + mock_esa.GetParamsRectTyped.return_value = mock_df + + result_df = indexable_instance[grid.Bus, field] + mock_esa.GetParamsRectTyped.assert_called_once_with(grid.Bus.TYPE, expected_fields) + assert_frame_equal(result_df, mock_df) diff --git a/tests/test_integration_analysis.py b/tests/test_integration_analysis.py deleted file mode 100644 index e92c685c..00000000 --- a/tests/test_integration_analysis.py +++ /dev/null @@ -1,290 +0,0 @@ -""" -Integration tests for GIC, ATC, Transient Stability, and Time Step functionality. - -WHAT THIS TESTS: -- GIC (Geomagnetically Induced Current) analysis -- ATC (Available Transfer Capability) analysis -- Transient stability simulations -- Time step simulation operations - -DEPENDENCIES: -- PowerWorld Simulator installed and SimAuto registered -- Valid PowerWorld case file configured in tests/config_test.py -""" - -import os -import pytest -import pandas as pd -import numpy as np - -# Order markers for integration tests - advanced analysis tests (order 73-99) -pytestmark = [ - pytest.mark.integration, - pytest.mark.requires_case, -] - -try: - from esapp.saw import SAW, PowerWorldError, PowerWorldPrerequisiteError, create_object_string -except ImportError: - raise - - -@pytest.fixture(scope="module") -def saw_instance(saw_session): - """Provides the session-scoped SAW instance to the tests in this module.""" - return saw_session - - -class TestGIC: - """Tests for GIC (Geomagnetically Induced Current) analysis.""" - - @pytest.mark.order(73) - def test_gic_calculate(self, saw_instance): - saw_instance.CalculateGIC(1.0, 90.0, False) - saw_instance.ClearGIC() - - @pytest.mark.order(74) - def test_gic_save_matrix(self, saw_instance, temp_file): - tmp_mat = temp_file(".mat") - tmp_id = temp_file(".txt") - saw_instance.GICSaveGMatrix(tmp_mat, tmp_id) - assert os.path.exists(tmp_mat) - - @pytest.mark.order(75) - def test_gic_setup(self, saw_instance): - saw_instance.GICSetupTimeVaryingSeries() - saw_instance.GICShiftOrStretchInputPoints() - - @pytest.mark.order(76) - def test_gic_time(self, saw_instance): - saw_instance.GICTimeVaryingCalculate(0.0, False) - saw_instance.GICTimeVaryingAddTime(10.0) - saw_instance.GICTimeVaryingDeleteAllTimes() - saw_instance.GICTimeVaryingEFieldCalculate(0.0, False) - saw_instance.GICTimeVaryingElectricFieldsDeleteAllTimes() - - @pytest.mark.order(77) - def test_gic_write(self, saw_instance, temp_file): - tmp_aux = temp_file(".aux") - saw_instance.GICWriteOptions(tmp_aux) - assert os.path.exists(tmp_aux) - - tmp_gmd = temp_file(".gmd") - saw_instance.GICWriteFilePSLF(tmp_gmd) - - tmp_gic = temp_file(".gic") - saw_instance.GICWriteFilePTI(tmp_gic) - - -class TestATC: - """Tests for ATC (Available Transfer Capability) analysis.""" - - @pytest.mark.order(78) - def test_atc_determine(self, saw_instance): - areas = saw_instance.GetParametersMultipleElement("Area", ["AreaNum"]) - if areas is not None and len(areas) >= 2: - seller = create_object_string("Area", areas.iloc[0]["AreaNum"]) - buyer = create_object_string("Area", areas.iloc[1]["AreaNum"]) - saw_instance.DetermineATC(seller, buyer) - else: - pytest.skip("Not enough areas for ATC") - - @pytest.mark.order(79) - def test_atc_multiple(self, saw_instance): - areas = saw_instance.GetParametersMultipleElement("Area", ["AreaNum"]) - if areas is not None and len(areas) >= 2: - s = create_object_string("Area", areas.iloc[0]["AreaNum"]) - b = create_object_string("Area", areas.iloc[1]["AreaNum"]) - saw_instance.DirectionsAutoInsert(s, b) - - try: - saw_instance.DetermineATCMultipleDirections() - except PowerWorldPrerequisiteError: - pytest.skip("No directions defined for ATC") - - @pytest.mark.order(80) - def test_atc_results(self, saw_instance): - saw_instance._object_fields["transferlimiter"] = pd.DataFrame({ - "internal_field_name": ["LimitingContingency", "MaxFlow"], - "field_data_type": ["String", "Real"], - "key_field": ["", ""], - "description": ["", ""], - "display_name": ["", ""] - }).sort_values(by="internal_field_name") - - saw_instance.GetATCResults(["MaxFlow", "LimitingContingency"]) - - -class TestTransient: - """Tests for Transient Stability simulations.""" - - @pytest.mark.order(81) - def test_transient_initialize(self, saw_instance): - saw_instance.TSInitialize() - - @pytest.mark.order(82) - def test_transient_options(self, saw_instance, temp_file): - tmp_aux = temp_file(".aux") - saw_instance.TSWriteOptions(tmp_aux) - assert os.path.exists(tmp_aux) - - @pytest.mark.order(83) - def test_transient_critical_time(self, saw_instance): - branches = saw_instance.GetParametersMultipleElement("Branch", ["BusNum", "BusNum:1", "LineCircuit"]) - if branches is not None and not branches.empty: - b = branches.iloc[0] - branch_str = create_object_string("Branch", b["BusNum"], b["BusNum:1"], b["LineCircuit"]) - saw_instance.TSCalculateCriticalClearTime(branch_str) - - @pytest.mark.order(84) - def test_transient_playin(self, saw_instance): - times = np.array([0.0, 0.1]) - signals = np.array([[1.0], [1.0]]) - saw_instance.TSSetPlayInSignals("TestSignal", times, signals) - - @pytest.mark.order(85) - def test_transient_save_models(self, saw_instance, temp_file): - tmp_aux = temp_file(".aux") - saw_instance.TSWriteModels(tmp_aux) - assert os.path.exists(tmp_aux) - - tmp_aux2 = temp_file(".aux") - saw_instance.TSSaveDynamicModels(tmp_aux2, "AUX", "Gen") - assert os.path.exists(tmp_aux2) - - -class TestTimeStep: - """Tests for Time Step Simulation operations.""" - - @pytest.mark.order(86) - def test_timestep_delete(self, saw_instance): - saw_instance.TimeStepDeleteAll() - - @pytest.mark.order(87) - def test_timestep_run(self, saw_instance): - saw_instance.TimeStepDoRun() - try: - saw_instance.TimeStepDoSinglePoint("2025-01-01T10:00:00") - except PowerWorldPrerequisiteError: - pass # Expected if time points not defined - try: - saw_instance.TimeStepClearResults() - except PowerWorldError: - pass - saw_instance.TimeStepResetRun() - - @pytest.mark.order(88) - def test_timestep_save(self, saw_instance, temp_file): - tmp_pww = temp_file(".pww") - saw_instance.TimeStepSavePWW(tmp_pww) - - tmp_csv = temp_file(".csv") - try: - saw_instance.TimeStepSaveResultsByTypeCSV("Gen", tmp_csv) - except PowerWorldError: - pass # Likely no results - - @pytest.mark.order(89) - def test_timestep_fields(self, saw_instance): - saw_instance.TimeStepSaveFieldsSet("Gen", ["GenMW"]) - saw_instance.TimeStepSaveFieldsClear(["Gen"]) - - -class TestPVQV: - """Tests for PV and QV analysis.""" - - @pytest.mark.order(90) - def test_pv_qv_run(self, saw_instance): - df = saw_instance.RunQV() - assert df is not None - - @pytest.mark.order(91) - def test_pv_clear(self, saw_instance): - """Test clearing PV analysis results.""" - saw_instance.PVClear() - - @pytest.mark.order(92) - def test_pv_export(self, saw_instance, temp_file): - """Test exporting PV analysis results.""" - tmp_aux = temp_file(".aux") - try: - saw_instance.PVWriteResultsAndOptions(tmp_aux) - assert os.path.exists(tmp_aux) - except PowerWorldPrerequisiteError: - pytest.skip("PV analysis not available or no results") - - @pytest.mark.order(93) - def test_qv_clear(self, saw_instance): - """Test clearing QV analysis results.""" - saw_instance.QVDeleteAllResults() - - @pytest.mark.order(94) - def test_qv_export(self, saw_instance, temp_file): - """Test exporting QV analysis results.""" - tmp_aux = temp_file(".aux") - try: - saw_instance.QVWriteResultsAndOptions(tmp_aux) - assert os.path.exists(tmp_aux) - except PowerWorldPrerequisiteError: - pytest.skip("QV analysis not available or no results") - - -class TestTransientAdvanced: - """Additional tests for Transient Stability simulations.""" - - @pytest.mark.order(95) - def test_transient_result_storage_set_all(self, saw_instance): - """Test TSResultStorageSetAll for all storage modes.""" - # TSResultStorageSetAll(object_type, store_value) - object type first, then bool - saw_instance.TSResultStorageSetAll("Gen", True) - saw_instance.TSResultStorageSetAll("Gen", False) - - @pytest.mark.order(96) - def test_transient_clear_playin_signals(self, saw_instance): - """Test clearing play-in signals.""" - saw_instance.TSClearPlayInSignals() - - @pytest.mark.order(97) - def test_transient_get_contingency_results(self, saw_instance): - """Test getting transient contingency results.""" - # TSGetContingencyResults(CtgName, ObjFieldList, ...) - contingency name first - # Need an actual contingency name; skip if none available - try: - ctgs = saw_instance.ListOfDevices("TSContingency") - if ctgs is not None and not ctgs.empty: - ctg_name = ctgs.iloc[0].iloc[0] # First column, first row - meta, data = saw_instance.TSGetContingencyResults(ctg_name, ["BusNum", "BusPUVolt"]) - assert meta is None or isinstance(meta, pd.DataFrame) - else: - pytest.skip("No transient contingencies defined") - except (PowerWorldPrerequisiteError, PowerWorldError): - pytest.skip("No transient results available") - - @pytest.mark.order(98) - def test_transient_validate(self, saw_instance): - """Test TSValidate for model validation.""" - saw_instance.TSInitialize() - try: - saw_instance.TSValidate() - except PowerWorldPrerequisiteError: - pytest.skip("Transient validation not available") - - @pytest.mark.order(99) - def test_transient_auto_correct(self, saw_instance): - """Test TSAutoCorrect for automatic model corrections.""" - saw_instance.TSInitialize() - try: - saw_instance.TSAutoCorrect() - except PowerWorldPrerequisiteError: - pytest.skip("Auto-correct not available") - - @pytest.mark.order(100) - def test_transient_write_results(self, saw_instance, temp_file): - """Test writing transient results to CSV file.""" - tmp_csv = temp_file(".csv") - try: - # TSWriteResultsToCSV(filename, mode, contingencies, plots_fields) - saw_instance.TSWriteResultsToCSV(tmp_csv, "CSV", ["ALL"], ["GenMW"]) - assert os.path.exists(tmp_csv) - except (PowerWorldPrerequisiteError, PowerWorldError): - pytest.skip("No transient results to write") diff --git a/tests/test_integration_contingency.py b/tests/test_integration_contingency.py deleted file mode 100644 index f3f2d9f1..00000000 --- a/tests/test_integration_contingency.py +++ /dev/null @@ -1,323 +0,0 @@ -""" -Integration tests for Contingency Analysis functionality against a live PowerWorld case. - -WHAT THIS TESTS: -- Contingency auto-insertion and solving -- Contingency cloning and conversion -- OTDF calculations -- Contingency result export - -DEPENDENCIES: -- PowerWorld Simulator installed and SimAuto registered -- Valid PowerWorld case file configured in tests/config_test.py -""" - -import os -import pytest -import pandas as pd - -# Order markers for integration tests - contingency tests run mid-sequence (order 50-69) -pytestmark = [ - pytest.mark.integration, - pytest.mark.requires_case, -] - -try: - from esapp.saw import SAW, PowerWorldError, PowerWorldPrerequisiteError, create_object_string -except ImportError: - raise - - -@pytest.fixture(scope="module") -def saw_instance(saw_session): - """Provides the session-scoped SAW instance to the tests in this module.""" - return saw_session - - -class TestContingency: - """Tests for contingency analysis operations.""" - - @pytest.mark.order(50) - def test_contingency_auto_insert(self, saw_instance): - saw_instance.CTGAutoInsert() - - @pytest.mark.order(51) - def test_contingency_solve(self, saw_instance): - saw_instance.SolveContingencies() - - @pytest.mark.order(52) - def test_contingency_run_single(self, saw_instance): - ctgs = saw_instance.ListOfDevices("Contingency") - if ctgs is not None and not ctgs.empty: - ctg_name = ctgs.iloc[0]["CTGLabel"] - saw_instance.RunContingency(ctg_name) - saw_instance.CTGApply(ctg_name) - - @pytest.mark.order(53) - def test_contingency_otdf(self, saw_instance): - areas = saw_instance.GetParametersMultipleElement("Area", ["AreaNum"]) - if areas is not None and len(areas) >= 2: - seller = f'[AREA {areas.iloc[0]["AreaNum"]}]' - buyer = f'[AREA {areas.iloc[1]["AreaNum"]}]' - saw_instance.CTGCalculateOTDF(seller, buyer) - - @pytest.mark.order(54) - def test_contingency_results_ops(self, saw_instance): - saw_instance.CTGClearAllResults() - saw_instance.CTGSetAsReference() - saw_instance.CTGRelinkUnlinkedElements() - saw_instance.CTGSkipWithIdenticalActions() - saw_instance.CTGDeleteWithIdenticalActions() - saw_instance.CTGSort() - - @pytest.mark.order(55) - def test_contingency_clone(self, saw_instance): - ctgs = saw_instance.ListOfDevices("Contingency") - if ctgs is not None and not ctgs.empty: - ctg_name = ctgs.iloc[0]["CTGLabel"] - saw_instance.CTGCloneOne(ctg_name, "ClonedCTG") - saw_instance.CTGCloneMany("", "Many_", "_Suffix") - - @pytest.mark.order(56) - def test_contingency_combo(self, saw_instance): - saw_instance.CTGComboDeleteAllResults() - saw_instance.CTGAutoInsert() - saw_instance.CTGConvertToPrimaryCTG() - - # Optimize: Skip most contingencies to avoid long runtimes - saw_instance.SetData("Contingency", ["Skip"], ["YES"], "ALL") - - ctgs = saw_instance.ListOfDevices("Contingency") - if ctgs is not None and not ctgs.empty: - name_col = "CTGLabel" if "CTGLabel" in ctgs.columns else ctgs.columns[0] - primary_ctgs = ctgs[ctgs[name_col].astype(str).str.endswith("-Primary")] - target_ctgs = primary_ctgs.head(2) if not primary_ctgs.empty else ctgs.head(2) - - for name in target_ctgs[name_col]: - saw_instance.SetData("Contingency", [name_col, "Skip"], [name, "NO"]) - - try: - saw_instance.CTGComboSolveAll() - except PowerWorldPrerequisiteError: - pytest.skip("No active primary contingencies for Combo Analysis") - - @pytest.mark.order(57) - def test_contingency_convert(self, saw_instance): - saw_instance.CTGConvertAllToDeviceCTG() - saw_instance.CTGConvertToPrimaryCTG() - saw_instance.CTGCreateExpandedBreakerCTGs() - saw_instance.CTGCreateStuckBreakerCTGs() - saw_instance.CTGPrimaryAutoInsert() - - @pytest.mark.order(58) - def test_contingency_create_interface(self, saw_instance): - try: - saw_instance.CTGCreateContingentInterfaces("") - except PowerWorldPrerequisiteError: - pytest.skip("Filter 'ALL' not found for CTGCreateContingentInterfaces") - - @pytest.mark.order(59) - def test_contingency_join(self, saw_instance): - saw_instance.CTGJoinActiveCTGs(False, False, True) - - @pytest.mark.order(60) - def test_contingency_process_remedial(self, saw_instance): - saw_instance.CTGProcessRemedialActionsAndDependencies(False) - - @pytest.mark.order(61) - def test_contingency_save_matrices(self, saw_instance, temp_file): - tmp_csv = temp_file(".csv") - saw_instance.CTGSaveViolationMatrices(tmp_csv, "CSVCOLHEADER", False, ["Branch"], True, True) - - @pytest.mark.order(62) - def test_contingency_verify(self, saw_instance, temp_file): - tmp_txt = temp_file(".txt") - saw_instance.CTGVerifyIteratedLinearActions(tmp_txt) - - @pytest.mark.order(63) - def test_contingency_write_results(self, saw_instance, temp_file): - tmp_aux = temp_file(".aux") - saw_instance.CTGWriteResultsAndOptions(tmp_aux) - assert os.path.exists(tmp_aux) - - tmp_aux2 = temp_file(".aux") - saw_instance.CTGWriteAllOptions(tmp_aux2) - assert os.path.exists(tmp_aux2) - - tmp_aux3 = temp_file(".aux") - saw_instance.CTGWriteAuxUsingOptions(tmp_aux3) - assert os.path.exists(tmp_aux3) - - -class TestFault: - """Tests for fault analysis operations.""" - - @pytest.mark.order(53) - def test_fault_run(self, saw_instance): - buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum"]) - if buses is not None and not buses.empty: - bus_str = create_object_string("Bus", buses.iloc[0]["BusNum"]) - saw_instance.RunFault(bus_str, "SLG") - saw_instance.FaultClear() - else: - pytest.skip("No buses found") - - @pytest.mark.order(54) - def test_fault_auto(self, saw_instance): - saw_instance.FaultAutoInsert() - - @pytest.mark.order(55) - def test_fault_multiple(self, saw_instance): - saw_instance.FaultAutoInsert() - try: - saw_instance.FaultMultiple() - except PowerWorldPrerequisiteError: - pytest.skip("No active faults defined for FaultMultiple") - - -class TestContingencyAdvanced: - """Advanced contingency tests for edge cases and validation.""" - - @pytest.mark.order(64) - def test_contingency_get_violations(self, saw_instance): - """Test retrieving contingency violations.""" - # Run contingencies first to generate results - saw_instance.CTGAutoInsert() - - # Skip most to avoid long runtime - saw_instance.SetData("Contingency", ["Skip"], ["YES"], "ALL") - ctgs = saw_instance.ListOfDevices("Contingency") - if ctgs is not None and not ctgs.empty: - name_col = "CTGLabel" if "CTGLabel" in ctgs.columns else ctgs.columns[0] - saw_instance.SetData("Contingency", [name_col, "Skip"], [ctgs.iloc[0][name_col], "NO"]) - - try: - saw_instance.SolveContingencies() - except PowerWorldPrerequisiteError: - pytest.skip("No contingencies to solve") - - @pytest.mark.order(65) - def test_contingency_results_dataframe(self, saw_instance): - """Test that contingency results can be retrieved as DataFrame.""" - ctgs = saw_instance.ListOfDevices("Contingency") - if ctgs is not None and not ctgs.empty: - assert isinstance(ctgs, pd.DataFrame) - assert len(ctgs) > 0 - # Verify expected columns exist - assert "CTGLabel" in ctgs.columns or len(ctgs.columns) > 0 - - @pytest.mark.order(66) - def test_contingency_skip_behavior(self, saw_instance): - """Test that skipped contingencies are not solved.""" - # Skip all contingencies - saw_instance.SetData("Contingency", ["Skip"], ["YES"], "ALL") - - # Solving should be quick since all are skipped - saw_instance.SolveContingencies() - - @pytest.mark.order(67) - def test_contingency_restore_reference(self, saw_instance): - """Test CTGRestoreReference restores case state.""" - # Store original state - original_buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum", "BusPUVolt"]) - - # Restore reference - saw_instance.CTGRestoreReference() - - # Get state after restore - restored_buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum", "BusPUVolt"]) - - if original_buses is not None and restored_buses is not None: - assert len(original_buses) == len(restored_buses) - - -class TestFaultAdvanced: - """Advanced fault analysis tests.""" - - @pytest.mark.order(56) - def test_fault_types(self, saw_instance): - """Test different fault types.""" - buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum"]) - if buses is not None and not buses.empty: - bus_str = create_object_string("Bus", buses.iloc[0]["BusNum"]) - - # PowerWorld fault types: SLG (Single Line to Ground), LL (Line to Line), - # DLG (Double Line to Ground), 3PB (Three Phase Balanced) - fault_types = ["SLG", "LL", "DLG", "3PB"] - for ftype in fault_types: - try: - saw_instance.RunFault(bus_str, ftype) - saw_instance.FaultClear() - except (PowerWorldPrerequisiteError, PowerWorldError): - # Some fault types may not be configured or may fail - continue - - @pytest.mark.order(57) - def test_fault_at_branch(self, saw_instance): - """Test fault on branch midpoint.""" - branches = saw_instance.GetParametersMultipleElement("Branch", ["BusNum", "BusNum:1", "LineCircuit"]) - if branches is not None and not branches.empty: - b = branches.iloc[0] - branch_str = create_object_string("Branch", b["BusNum"], b["BusNum:1"], b["LineCircuit"]) - try: - # 3PB = Three Phase Balanced fault, location = percentage along branch (0-100) - saw_instance.RunFault(branch_str, "3PB", location=50.0) - saw_instance.FaultClear() - except (PowerWorldPrerequisiteError, PowerWorldError): - pytest.skip("Branch fault not supported or failed") - - -class TestContingencyExport: - """Tests for contingency export functionality.""" - - @pytest.mark.order(68) - def test_contingency_produce_report(self, saw_instance, temp_file): - """Test CTGProduceReport for report generation.""" - tmp_txt = temp_file(".txt") - try: - saw_instance.CTGProduceReport(tmp_txt) - assert os.path.exists(tmp_txt) - except (PowerWorldPrerequisiteError, PowerWorldError): - pytest.skip("No contingency results for report") - - @pytest.mark.order(69) - def test_contingency_write_pti(self, saw_instance, temp_file): - """Test CTGWriteFilePTI for PTI format export.""" - tmp_pti = temp_file(".con") - try: - saw_instance.CTGWriteFilePTI(tmp_pti) - assert os.path.exists(tmp_pti) - except (PowerWorldPrerequisiteError, PowerWorldError): - pytest.skip("PTI export not available") - - @pytest.mark.order(70) - def test_contingency_write_all_options(self, saw_instance, temp_file): - """Test CTGWriteAllOptions for options export.""" - tmp_aux = temp_file(".aux") - try: - saw_instance.CTGWriteAllOptions(tmp_aux) - assert os.path.exists(tmp_aux) - except (PowerWorldPrerequisiteError, PowerWorldError): - pytest.skip("Options export not available") - - @pytest.mark.order(71) - def test_contingency_compare_two_lists(self, saw_instance): - """Test CTGCompareTwoListsofContingencyResults for comparing contingency results.""" - try: - saw_instance.CTGCompareTwoListsofContingencyResults("CTGList1", "CTGList2") - except (PowerWorldPrerequisiteError, PowerWorldError): - pytest.skip("No contingency lists to compare") - - @pytest.mark.order(72) - def test_contingency_write_csv(self, saw_instance, temp_file): - """Test saving contingency violations to CSV.""" - tmp_csv = temp_file(".csv") - try: - # Save violation results using the violation matrix method - saw_instance.CTGSaveViolationMatrices( - tmp_csv, "CSVCOLHEADER", False, ["Branch"], True, True - ) - assert os.path.exists(tmp_csv) - except (PowerWorldPrerequisiteError, PowerWorldError): - pytest.skip("No violations to save") - diff --git a/tests/test_integration_network.py b/tests/test_integration_network.py new file mode 100644 index 00000000..9cc7fcb1 --- /dev/null +++ b/tests/test_integration_network.py @@ -0,0 +1,139 @@ +""" +Integration tests for the Network class (esapp.utils.network). + +These are **integration tests** that require a live connection to PowerWorld +Simulator via the SimAuto COM interface. They test incidence matrix +construction, graph Laplacians (length, resistance-distance, delay weighted), +branch parameter calculations, and caching behavior. + +REQUIREMENTS: + - PowerWorld Simulator installed with SimAuto COM registered + - A valid PowerWorld case file path set in ``tests/config_test.py`` + (variable ``SAW_TEST_CASE``) or via the ``SAW_TEST_CASE`` env variable + +USAGE: + pytest tests/test_integration_network.py -v +""" +import pytest +import numpy as np +import pandas as pd +from scipy.sparse import issparse + +from esapp.utils import Network, BranchType +from esapp.components import Branch, Bus +from esapp.workbench import PowerWorld + +pytestmark = [ + pytest.mark.integration, + pytest.mark.requires_case, +] + + +@pytest.fixture(scope="module") +def net(saw_session): + """Network instance connected to the session SAW.""" + pw = PowerWorld() + pw.esa = saw_session + return pw.network + + +class TestNetwork: + + @pytest.mark.order(6000) + def test_busmap(self, net): + bmap = net.busmap() + assert isinstance(bmap, pd.Series) + assert list(bmap.values) == list(range(len(bmap))) + buses = net._pw[Bus] + assert set(bmap.index) == set(buses["BusNum"]) + + @pytest.mark.order(6100) + def test_incidence(self, net): + A = net.incidence() + assert issparse(A) + nbus = len(net._pw[Bus]) + assert A.shape[1] == nbus + assert A.shape[0] >= 1 + + Adense = A.toarray() + np.testing.assert_array_equal(Adense.sum(axis=1), 0) + assert set(np.unique(Adense)) <= {-1.0, 0.0, 1.0} + + @pytest.mark.order(6110) + def test_incidence_caching(self, net): + A1 = net.incidence() + A2 = net.incidence(remake=False) + assert A1 is A2 + + A3 = net.incidence(remake=True) + assert A1 is not A3 + np.testing.assert_array_equal(A1.toarray(), A3.toarray()) + + @pytest.mark.order(6200) + def test_branch_params(self, net): + """ybranch, zmag, yshunt, lengths, gamma.""" + Y = net.ybranch() + assert np.iscomplexobj(Y) + + Z = net.ybranch(asZ=True) + assert np.iscomplexobj(Z) + assert len(Z) >= 1 + np.testing.assert_allclose(np.abs(Y), 1 / np.abs(Z), rtol=1e-10) + + zmag = net.zmag() + np.testing.assert_allclose(zmag, np.abs(Z), rtol=1e-10) + + Ysh = net.yshunt() + assert np.iscomplexobj(Ysh) + assert len(Ysh) >= 1 + + @pytest.mark.order(6300) + def test_lengths(self, net): + ell = net.lengths() + assert isinstance(ell, pd.Series) + assert (ell > 0).all() + assert len(ell) == net.incidence().shape[0] + + ell_pseudo = net.lengths(longer_xfmr_lens=True, length_thresh_km=1.0) + assert (ell_pseudo > 0).all() + + @pytest.mark.order(6400) + def test_gamma(self, net): + gam = net.gamma() + assert np.iscomplexobj(gam) + + @pytest.mark.order(6500) + def test_laplacian(self, net): + nbus = len(net._pw[Bus]) + + L = net.laplacian(BranchType.LENGTH) + assert L.shape == (nbus, nbus) + assert issparse(L) + + Ldense = L.toarray() + np.testing.assert_allclose(Ldense, Ldense.T, atol=1e-12) + np.testing.assert_allclose(Ldense.sum(axis=1), 0, atol=1e-10) + eigvals = np.linalg.eigvalsh(Ldense) + assert np.all(eigvals >= -1e-10) + + Lr = net.laplacian(BranchType.RES_DIST).toarray() + np.testing.assert_allclose(Lr, Lr.T, atol=1e-12) + + A = net.incidence() + W = np.ones(A.shape[0]) + Lw = net.laplacian(W) + assert Lw.shape == (A.shape[1], A.shape[1]) + np.testing.assert_allclose(Lw.toarray().sum(axis=1), 0, atol=1e-10) + + @pytest.mark.order(6600) + def test_delay(self, net): + beta = net.delay() + assert isinstance(beta, np.ndarray) + assert len(beta) > 0 + + beta_floor = net.delay(min_delay=0.5) + assert np.all(beta_floor >= 0.5) + + L = net.laplacian(BranchType.DELAY) + nbus = len(net._pw[Bus]) + assert L.shape == (nbus, nbus) diff --git a/tests/test_integration_powerflow.py b/tests/test_integration_powerflow.py deleted file mode 100644 index f1c31d7c..00000000 --- a/tests/test_integration_powerflow.py +++ /dev/null @@ -1,299 +0,0 @@ -""" -Integration tests for Power Flow functionality against a live PowerWorld case. - -WHAT THIS TESTS: -- Power flow solution execution and result validation -- Matrices (Ybus, Jacobian, Incidence) -- Sensitivity calculations (PTDF, LODF, shift factors) -- Diff case operations - -DEPENDENCIES: -- PowerWorld Simulator installed and SimAuto registered -- Valid PowerWorld case file configured in tests/config_test.py -""" - -import os -import pytest -import pandas as pd - -# Order markers for integration tests - powerflow tests run early (order 10-29) -pytestmark = [ - pytest.mark.integration, - pytest.mark.requires_case, -] - -try: - from esapp.saw import SAW, PowerWorldError, PowerWorldPrerequisiteError, create_object_string -except ImportError: - raise - - -@pytest.fixture(scope="module") -def saw_instance(saw_session): - """Provides the session-scoped SAW instance to the tests in this module.""" - return saw_session - - -class TestPowerFlow: - """Tests for power flow solution and related operations.""" - - @pytest.mark.order(10) - def test_powerflow_solve(self, saw_instance): - saw_instance.SolvePowerFlow() - - @pytest.mark.order(11) - def test_powerflow_solve_retry(self, saw_instance): - saw_instance.SolvePowerFlowWithRetry() - - @pytest.mark.order(12) - def test_powerflow_clear_solution_aid(self, saw_instance): - saw_instance.ClearPowerFlowSolutionAidValues() - - @pytest.mark.order(13) - def test_powerflow_options(self, saw_instance): - saw_instance.SetMVATolerance(0.1) - saw_instance.SetDoOneIteration(False) - saw_instance.SetInnerLoopCheckMVars(False) - - @pytest.mark.order(15) - def test_powerflow_min_pu_volt(self, saw_instance): - v = saw_instance.GetMinPUVoltage() - assert isinstance(v, float) - - @pytest.mark.order(17) - def test_powerflow_update_islands(self, saw_instance): - saw_instance.UpdateIslandsAndBusStatus() - - @pytest.mark.order(18) - def test_powerflow_zero_mismatches(self, saw_instance): - saw_instance.ZeroOutMismatches() - - @pytest.mark.order(19) - def test_powerflow_estimate_voltages(self, saw_instance): - saw_instance.SelectAll("Bus") - saw_instance.EstimateVoltages("SELECTED") - - @pytest.mark.order(20) - def test_powerflow_gen_force_ldc(self, saw_instance): - saw_instance.GenForceLDC_RCC() - - @pytest.mark.order(21) - def test_powerflow_save_gen_limit(self, saw_instance, temp_file): - tmp_txt = temp_file(".txt") - saw_instance.SaveGenLimitStatusAction(tmp_txt) - assert os.path.exists(tmp_txt) - - @pytest.mark.order(22) - def test_powerflow_diff_case(self, saw_instance): - saw_instance.DiffCaseSetAsBase() - saw_instance.DiffCaseMode("DIFFERENCE") - saw_instance.DiffCaseRefresh() - saw_instance.DiffCaseClearBase() - - @pytest.mark.order(23) - def test_powerflow_voltage_conditioning(self, saw_instance): - saw_instance.VoltageConditioning() - - @pytest.mark.order(24) - def test_powerflow_flat_start(self, saw_instance): - saw_instance.ResetToFlatStart() - saw_instance.SolvePowerFlow() - - @pytest.mark.order(25) - def test_powerflow_diff_write(self, saw_instance, temp_file): - tmp_aux = temp_file(".aux") - tmp_epc = temp_file(".epc") - saw_instance.DiffCaseWriteCompleteModel(tmp_aux) - saw_instance.DiffCaseWriteBothEPC(tmp_epc, ge_file_type="GE21") - saw_instance.DiffCaseWriteNewEPC(tmp_epc, ge_file_type="GE21") - - -class TestMatrices: - """Tests for matrix extraction (Ybus, Jacobian, etc.).""" - - @pytest.mark.order(30) - def test_matrix_ybus(self, saw_instance): - ybus = saw_instance.get_ybus() - assert ybus is not None - - @pytest.mark.order(31) - def test_matrix_gmatrix(self, saw_instance): - gmat = saw_instance.get_gmatrix() - assert gmat is not None - - @pytest.mark.order(32) - def test_matrix_jacobian(self, saw_instance): - jac = saw_instance.get_jacobian() - assert jac is not None - - -class TestSensitivity: - """Tests for sensitivity calculations (PTDF, LODF, shift factors).""" - - @pytest.mark.order(40) - def test_sensitivity_volt_sense(self, saw_instance): - buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum"]) - if buses is not None and not buses.empty: - bus_num = buses.iloc[0]["BusNum"] - saw_instance.CalculateVoltSense(bus_num) - - @pytest.mark.order(41) - def test_sensitivity_flow_sense(self, saw_instance): - branches = saw_instance.GetParametersMultipleElement("Branch", ["BusNum", "BusNum:1", "LineCircuit"]) - if branches is not None and not branches.empty: - b = branches.iloc[0] - branch_str = create_object_string("Branch", b["BusNum"], b["BusNum:1"], b["LineCircuit"]) - saw_instance.CalculateFlowSense(branch_str, "MW") - - @pytest.mark.order(42) - def test_sensitivity_ptdf(self, saw_instance): - areas = saw_instance.GetParametersMultipleElement("Area", ["AreaNum"]) - if areas is not None and len(areas) >= 2: - seller = create_object_string("Area", areas.iloc[0]["AreaNum"]) - buyer = create_object_string("Area", areas.iloc[1]["AreaNum"]) - saw_instance.CalculatePTDF(seller, buyer) - saw_instance.CalculateVoltToTransferSense(seller, buyer) - - @pytest.mark.order(43) - def test_sensitivity_lodf(self, saw_instance): - branches = saw_instance.GetParametersMultipleElement("Branch", ["BusNum", "BusNum:1", "LineCircuit"]) - if branches is not None and not branches.empty: - b = branches.iloc[0] - branch_str = create_object_string("Branch", b["BusNum"], b["BusNum:1"], b["LineCircuit"]) - saw_instance.CalculateLODF(branch_str) - - @pytest.mark.order(44) - def test_sensitivity_shift_factors(self, saw_instance): - branches = saw_instance.GetParametersMultipleElement("Branch", ["BusNum", "BusNum:1", "LineCircuit", "LineStatus"]) - areas = saw_instance.GetParametersMultipleElement("Area", ["AreaNum"]) - if branches is not None and not branches.empty and areas is not None and not areas.empty: - closed_branches = branches[branches["LineStatus"] == "Closed"] - if not closed_branches.empty: - b = closed_branches.iloc[0] - branch_str = create_object_string("Branch", b["BusNum"], b["BusNum:1"], b["LineCircuit"]) - area_str = create_object_string("Area", areas.iloc[0]["AreaNum"]) - saw_instance.SetParticipationFactors("CONSTANT", 1.0, area_str) - try: - saw_instance.CalculateShiftFactors(branch_str, "SELLER", area_str) - except PowerWorldPrerequisiteError as e: - pytest.skip(f"Shift factors calculation failed: {e}") - else: - pytest.skip("No closed branches found for shift factors") - - @pytest.mark.order(45) - def test_sensitivity_lodf_matrix(self, saw_instance): - saw_instance.CalculateLODFMatrix("OUTAGES", "ALL", "ALL") - - @pytest.mark.order(36) - def test_sensitivity_lodf_advanced(self, saw_instance, temp_file): - """Test CalculateLODFAdvanced with full parameters.""" - tmp_csv = temp_file(".csv") - try: - # CalculateLODFAdvanced(include_phase_shifters, file_type, max_columns, min_lodf, - # number_format, decimal_points, only_increasing, filename) - saw_instance.CalculateLODFAdvanced( - include_phase_shifters=False, - file_type="CSV", - max_columns=100, - min_lodf=0.01, - number_format="DECIMAL", - decimal_points=4, - only_increasing=False, - filename=tmp_csv - ) - except PowerWorldPrerequisiteError: - pytest.skip("LODF Advanced not available") - - @pytest.mark.order(37) - def test_sensitivity_lodf_screening(self, saw_instance): - """Test CalculateLODFScreening for screening mode.""" - try: - # CalculateLODFScreening with do_save_file=False to avoid file requirement - saw_instance.CalculateLODFScreening( - filter_process="ALL", - filter_monitor="ALL", - include_phase_shifters=False, - include_open_lines=False, - use_lodf_threshold=True, - lodf_threshold=0.05, - use_overload_threshold=False, - overload_low=100.0, - overload_high=200.0, - do_save_file=False, - file_location="" - ) - except PowerWorldPrerequisiteError: - pytest.skip("LODF Screening not available") - except PowerWorldError as e: - if "LODF" in str(e) or "screening" in str(e).lower(): - pytest.skip("LODF Screening not available") - raise - - @pytest.mark.order(38) - def test_sensitivity_shift_factors_multiple(self, saw_instance): - """Test CalculateShiftFactorsMultipleElement for multiple branches.""" - areas = saw_instance.GetParametersMultipleElement("Area", ["AreaNum"]) - if areas is not None and not areas.empty: - area_str = create_object_string("Area", areas.iloc[0]["AreaNum"]) - saw_instance.SetParticipationFactors("CONSTANT", 1.0, area_str) - try: - # CalculateShiftFactorsMultipleElement(type_element, which_element, direction, transactor, method) - # which_element must be SELECTED, OVERLOAD, or CTGOVERLOAD - saw_instance.CalculateShiftFactorsMultipleElement("BRANCH", "SELECTED", "SELLER", area_str) - except PowerWorldPrerequisiteError: - pytest.skip("Shift factors multiple element not available") - except PowerWorldError as e: - if "SELECTED" in str(e) or "shift" in str(e).lower(): - pytest.skip("No branches selected for shift factor calculation") - raise - - @pytest.mark.order(39) - def test_sensitivity_loss_sense(self, saw_instance): - """Test CalculateLossSense for loss sensitivity.""" - try: - # CalculateLossSense(function_type, area_ref, island_ref) - # function_type can be AREA, ZONE, BUS, etc. - saw_instance.CalculateLossSense("AREA", "NO", "EXISTING") - except PowerWorldPrerequisiteError: - pytest.skip("Loss sensitivity calculation not available") - - -class TestTopology: - """Tests for topology analysis operations.""" - - - @pytest.mark.order(47) - def test_topology_islands(self, saw_instance): - df = saw_instance.DetermineBranchesThatCreateIslands() - assert df is not None - assert isinstance(df, pd.DataFrame) - - @pytest.mark.order(48) - def test_topology_shortest_path(self, saw_instance): - buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum"]) - if buses is not None and len(buses) >= 2: - start = create_object_string("Bus", buses.iloc[0]['BusNum']) - end = create_object_string("Bus", buses.iloc[1]['BusNum']) - df = saw_instance.DetermineShortestPath(start, end) - assert df is not None - - -class TestPowerFlowAdvanced: - """Additional power flow tests for DC solution and advanced features.""" - - @pytest.mark.order(26) - def test_powerflow_solve_dc(self, saw_instance): - """Test DC power flow solution.""" - saw_instance.SolvePowerFlow("DC") - # Verify solution was attempted (no exception means success) - # Run AC again to restore state for subsequent tests - saw_instance.SolvePowerFlow() - - @pytest.mark.order(27) - def test_powerflow_agc(self, saw_instance): - """Test AGC-related generator participation factors.""" - # AGC calculation via participation factors - areas = saw_instance.GetParametersMultipleElement("Area", ["AreaNum"]) - if areas is not None and not areas.empty: - area_str = create_object_string("Area", areas.iloc[0]["AreaNum"]) - saw_instance.SetParticipationFactors("CONSTANT", 1.0, area_str) diff --git a/tests/test_integration_saw_contingency.py b/tests/test_integration_saw_contingency.py new file mode 100644 index 00000000..ffd2b199 --- /dev/null +++ b/tests/test_integration_saw_contingency.py @@ -0,0 +1,410 @@ +""" +Integration tests for Contingency Analysis and Fault Analysis via SAW. + +These are **integration tests** that require a live connection to PowerWorld +Simulator via the SimAuto COM interface. They test contingency auto-insertion, +solving, cloning, conversion, OTDF calculations, fault analysis, and result +export. + +REQUIREMENTS: + - PowerWorld Simulator installed with SimAuto COM registered + - A valid PowerWorld case file path set in ``tests/config_test.py`` + (variable ``SAW_TEST_CASE``) or via the ``SAW_TEST_CASE`` env variable + +RELATED TEST FILES: + - test_integration_saw_core.py -- base SAW operations, logging, I/O + - test_integration_saw_modify.py -- destructive modify, region, case actions + - test_integration_saw_powerflow.py -- power flow, matrices, sensitivity, topology + - test_integration_saw_gic.py -- GIC analysis + - test_integration_saw_transient.py -- transient stability + - test_integration_saw_operations.py -- ATC, OPF, PV/QV, time step, weather, scheduled + - test_integration_workbench.py -- PowerWorld facade and statics + - test_integration_network.py -- Network topology + +USAGE: + pytest tests/test_integration_saw_contingency.py -v +""" + +import os +import pytest +import pandas as pd + +pytestmark = [ + pytest.mark.integration, + pytest.mark.requires_case, +] + +try: + from esapp.saw import SAW, PowerWorldError, PowerWorldPrerequisiteError, create_object_string +except ImportError: + raise + + +@pytest.fixture(scope="module") +def saw_instance(saw_session): + """Provides the session-scoped SAW instance to the tests in this module.""" + return saw_session + + +def _configure_limited_ctg_auto_insert(saw_instance): + """Configure CTG_AutoInsert_Options to limit contingency count for faster tests. + + Deletes existing contingencies and configures auto-insert. Uses all kV levels + to ensure contingencies are created regardless of the test case's voltage range. + """ + saw_instance.SetData("Contingency", ["Skip"], ["NO"], "ALL") + try: + saw_instance.RunScriptCommand("Delete(Contingency);") + except (PowerWorldPrerequisiteError, PowerWorldError): + pass + + saw_instance.SetData( + "CTG_AutoInsert_Options", + ["CtgAutoInsDeleteExistCtgs", "DOCUseAllkV"], + ["YES", "YES"], + ) + + +def _trim_contingencies(saw_instance, max_active=5, delete_excess=False): + """Skip all contingencies then un-skip only *max_active* to limit runtime.""" + saw_instance.SetData("Contingency", ["Skip"], ["YES"], "ALL") + ctgs = saw_instance.ListOfDevices("Contingency") + if ctgs is None or ctgs.empty: + return + name_col = "CTGLabel" if "CTGLabel" in ctgs.columns else ctgs.columns[0] + keep_names = set(ctgs.head(max_active)[name_col]) + for name in keep_names: + saw_instance.ChangeParametersSingleElement( + "Contingency", [name_col, "Skip"], [name, "NO"] + ) + if delete_excess and len(ctgs) > max_active: + saw_instance.SelectAll("Contingency") + for name in keep_names: + saw_instance.ChangeParametersSingleElement( + "Contingency", [name_col, "Selected"], [name, "NO"] + ) + try: + saw_instance.Delete("Contingency", "SELECTED") + except (PowerWorldPrerequisiteError, PowerWorldError): + pass + + +class TestContingency: + """Tests for contingency analysis operations.""" + + @pytest.mark.order(5000) + def test_contingency_auto_insert(self, saw_instance): + _configure_limited_ctg_auto_insert(saw_instance) + saw_instance.CTGAutoInsert() + + @pytest.mark.order(5100) + def test_contingency_solve(self, saw_instance): + saw_instance.SetData("Contingency", ["Skip"], ["YES"], "ALL") + ctgs = saw_instance.ListOfDevices("Contingency") + assert ctgs is not None and not ctgs.empty, "No contingencies found after auto-insert" + name_col = "CTGLabel" if "CTGLabel" in ctgs.columns else ctgs.columns[0] + for name in ctgs.head(2)[name_col]: + saw_instance.ChangeParametersSingleElement( + "Contingency", [name_col, "Skip"], [name, "NO"] + ) + saw_instance.CTGSolveAll() + + @pytest.mark.order(5200) + def test_contingency_run_single(self, saw_instance): + ctgs = saw_instance.ListOfDevices("Contingency") + assert ctgs is not None and not ctgs.empty, "No contingencies found" + ctg_name = ctgs.iloc[0]["CTGLabel"] + saw_instance.CTGSolve(ctg_name) + saw_instance.CTGApply(ctg_name) + + @pytest.mark.order(5300) + def test_contingency_otdf(self, saw_instance): + areas = saw_instance.GetParametersMultipleElement("Area", ["AreaNum"]) + if areas is None or len(areas) < 2: + buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum", "AreaNum"]) + assert buses is not None and not buses.empty, "Test case must contain buses" + existing_areas = set(int(a) for a in areas["AreaNum"]) if areas is not None else set() + next_area = max(existing_areas, default=0) + 1 + saw_instance.CreateData("Area", ["AreaNum", "AreaName"], [next_area, f"TestArea{next_area}"]) + area_counts = buses["AreaNum"].value_counts() + largest_area = area_counts.index[0] + donor = buses[buses["AreaNum"] == largest_area] + if len(donor) > 1: + saw_instance.ChangeParametersSingleElement( + "Bus", ["BusNum", "AreaNum"], [int(donor.iloc[-1]["BusNum"]), next_area] + ) + areas = saw_instance.GetParametersMultipleElement("Area", ["AreaNum"]) + seller = f'[AREA {areas.iloc[0]["AreaNum"]}]' + buyer = f'[AREA {areas.iloc[1]["AreaNum"]}]' + saw_instance.CTGCalculateOTDF(seller, buyer) + + @pytest.mark.order(5400) + def test_contingency_clear_and_reference(self, saw_instance): + """Test CTGClearAllResults and CTGSetAsReference.""" + saw_instance.CTGClearAllResults() + saw_instance.CTGSetAsReference() + + @pytest.mark.order(5410) + def test_contingency_relink(self, saw_instance): + """Test CTGRelinkUnlinkedElements.""" + saw_instance.CTGRelinkUnlinkedElements() + + @pytest.mark.order(5420) + def test_contingency_sort(self, saw_instance): + """Test CTGSort.""" + saw_instance.CTGSort() + + @pytest.mark.order(5500) + def test_contingency_combo(self, saw_instance): + """Run combo solve BEFORE cloning to avoid solving duplicated contingencies.""" + saw_instance.CTGComboDeleteAllResults() + _configure_limited_ctg_auto_insert(saw_instance) + saw_instance.CTGAutoInsert() + saw_instance.CTGConvertToPrimaryCTG() + + saw_instance.SetData("Contingency", ["Skip"], ["YES"], "ALL") + + ctgs = saw_instance.ListOfDevices("Contingency") + assert ctgs is not None and not ctgs.empty, "No contingencies found after auto-insert" + name_col = "CTGLabel" if "CTGLabel" in ctgs.columns else ctgs.columns[0] + primary_ctgs = ctgs[ctgs[name_col].astype(str).str.endswith("-Primary")] + target_ctgs = primary_ctgs.head(2) if not primary_ctgs.empty else ctgs.head(2) + + for name in target_ctgs[name_col]: + saw_instance.ChangeParametersSingleElement( + "Contingency", [name_col, "Skip"], [name, "NO"] + ) + + saw_instance.CTGComboSolveAll() + + @pytest.mark.order(5600) + def test_contingency_clone(self, saw_instance): + """Clone contingencies AFTER combo solve to avoid bloating solve operations.""" + ctgs = saw_instance.ListOfDevices("Contingency") + if ctgs is None or ctgs.empty: + _configure_limited_ctg_auto_insert(saw_instance) + saw_instance.CTGAutoInsert() + _trim_contingencies(saw_instance, max_active=3) + ctgs = saw_instance.ListOfDevices("Contingency") + assert ctgs is not None and not ctgs.empty, "No contingencies found for cloning" + ctg_name = ctgs.iloc[0]["CTGLabel"] + saw_instance.CTGCloneOne(ctg_name, "ClonedCTG") + saw_instance.CTGCloneMany("", "Many_", "_Suffix") + + @pytest.mark.order(5700) + def test_contingency_convert(self, saw_instance): + saw_instance.CTGConvertAllToDeviceCTG() + saw_instance.CTGConvertToPrimaryCTG() + saw_instance.CTGCreateExpandedBreakerCTGs() + saw_instance.CTGCreateStuckBreakerCTGs() + _configure_limited_ctg_auto_insert(saw_instance) + saw_instance.CTGPrimaryAutoInsert() + + @pytest.mark.order(5800) + def test_contingency_create_interface(self, saw_instance): + saw_instance.CTGCreateContingentInterfaces("") + + @pytest.mark.order(5900) + def test_contingency_join(self, saw_instance): + saw_instance.CTGJoinActiveCTGs(False, False, True) + + @pytest.mark.order(5990) + def test_contingency_process_remedial(self, saw_instance): + saw_instance.CTGProcessRemedialActionsAndDependencies(False) + + @pytest.mark.order(6100) + def test_contingency_save_matrices(self, saw_instance, temp_file): + tmp_csv = temp_file(".csv") + saw_instance.CTGSaveViolationMatrices(tmp_csv, "CSVCOLHEADER", False, ["Branch"], True, True) + + @pytest.mark.order(6200) + def test_contingency_verify(self, saw_instance, temp_file): + tmp_txt = temp_file(".txt") + saw_instance.CTGVerifyIteratedLinearActions(tmp_txt) + + @pytest.mark.order(6300) + def test_contingency_write_results(self, saw_instance, temp_file): + tmp_aux = temp_file(".aux") + saw_instance.CTGWriteResultsAndOptions(tmp_aux) + assert os.path.exists(tmp_aux) + + tmp_aux2 = temp_file(".aux") + saw_instance.CTGWriteAllOptions(tmp_aux2) + assert os.path.exists(tmp_aux2) + + tmp_aux3 = temp_file(".aux") + saw_instance.CTGWriteAuxUsingOptions(tmp_aux3) + assert os.path.exists(tmp_aux3) + + @pytest.mark.order(6320) + def test_ctg_sort_with_fields(self, saw_instance): + """CTGSort with sort field list.""" + saw_instance.CTGSort(sort_field_list=["Name:+:0"]) + + @pytest.mark.order(6330) + def test_ctg_delete_identical(self, saw_instance): + """CTGDeleteWithIdenticalActions completes without error.""" + _configure_limited_ctg_auto_insert(saw_instance) + saw_instance.CTGAutoInsert() + _trim_contingencies(saw_instance, max_active=5, delete_excess=True) + saw_instance.CTGDeleteWithIdenticalActions() + + @pytest.mark.order(6350) + def test_ctg_restore_reference(self, saw_instance): + """CTGRestoreReference restores reference state.""" + saw_instance.CTGSetAsReference() + saw_instance.CTGRestoreReference() + + @pytest.mark.order(6360) + def test_ctg_write_aux_using_options(self, saw_instance, temp_file): + """CTGWriteAuxUsingOptions writes to file.""" + tmp = temp_file(".aux") + saw_instance.CTGWriteAuxUsingOptions(tmp, append=False) + + @pytest.mark.order(6400) + def test_contingency_get_violations(self, saw_instance): + """Test retrieving contingency violations.""" + _configure_limited_ctg_auto_insert(saw_instance) + saw_instance.CTGAutoInsert() + + saw_instance.SetData("Contingency", ["Skip"], ["YES"], "ALL") + ctgs = saw_instance.ListOfDevices("Contingency") + assert ctgs is not None and not ctgs.empty, "No contingencies found after auto-insert" + name_col = "CTGLabel" if "CTGLabel" in ctgs.columns else ctgs.columns[0] + saw_instance.SetData("Contingency", [name_col, "Skip"], [ctgs.iloc[0][name_col], "NO"]) + + saw_instance.CTGSolveAll() + + @pytest.mark.order(6500) + def test_contingency_results_dataframe(self, saw_instance): + """Test that contingency results can be retrieved as DataFrame.""" + ctgs = saw_instance.ListOfDevices("Contingency") + assert ctgs is not None and not ctgs.empty, "No contingencies found for results check" + assert isinstance(ctgs, pd.DataFrame) + assert len(ctgs) > 0 + assert "CTGLabel" in ctgs.columns or len(ctgs.columns) > 0 + + @pytest.mark.order(6600) + def test_contingency_skip_behavior(self, saw_instance): + """Test that skipped contingencies are not solved.""" + saw_instance.SetData("Contingency", ["Skip"], ["YES"], "ALL") + saw_instance.CTGSolveAll() + + @pytest.mark.order(6700) + def test_contingency_restore_reference(self, saw_instance): + """Test CTGRestoreReference restores case state.""" + original_buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum", "BusPUVolt"]) + assert original_buses is not None, "Failed to retrieve original bus data" + + saw_instance.CTGRestoreReference() + + restored_buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum", "BusPUVolt"]) + assert restored_buses is not None, "Failed to retrieve restored bus data" + + assert len(original_buses) == len(restored_buses) + + +class TestFault: + """Tests for fault analysis operations.""" + + @pytest.mark.order(5350) + def test_fault_run(self, saw_instance): + buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum"]) + assert buses is not None and not buses.empty, "No buses found" + bus_str = create_object_string("Bus", buses.iloc[0]["BusNum"]) + saw_instance.RunFault(bus_str, "SLG") + saw_instance.FaultClear() + + @pytest.mark.order(5450) + def test_fault_auto(self, saw_instance): + _configure_limited_ctg_auto_insert(saw_instance) + saw_instance.FaultAutoInsert() + + @pytest.mark.order(5550) + def test_fault_multiple(self, saw_instance): + _configure_limited_ctg_auto_insert(saw_instance) + saw_instance.FaultAutoInsert() + try: + saw_instance.FaultMultiple() + except PowerWorldPrerequisiteError as e: + if "No active faults" in str(e): + pytest.skip("No active faults defined after FaultAutoInsert for this case") + raise + + @pytest.mark.order(5650) + def test_fault_types(self, saw_instance): + """Test different fault types.""" + buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum"]) + assert buses is not None and not buses.empty, "No buses found for fault type testing" + bus_str = create_object_string("Bus", buses.iloc[0]["BusNum"]) + + fault_types = ["SLG", "LL", "DLG", "3PB"] + for ftype in fault_types: + saw_instance.RunFault(bus_str, ftype) + saw_instance.FaultClear() + + @pytest.mark.order(5750) + def test_fault_at_branch(self, saw_instance): + """Test fault on branch midpoint (line only -- transformers can hang PW).""" + branches = saw_instance.GetParametersMultipleElement( + "Branch", ["BusNum", "BusNum:1", "LineCircuit", "BranchDeviceType"] + ) + assert branches is not None and not branches.empty, "No branches found for branch fault testing" + lines = branches[branches["BranchDeviceType"] != "Transformer"] + if lines.empty: + pytest.skip("No non-transformer branches available for midpoint fault test") + b = lines.iloc[0] + branch_str = create_object_string("Branch", b["BusNum"], b["BusNum:1"], b["LineCircuit"]) + saw_instance.RunFault(branch_str, "3PB", location=50.0) + saw_instance.FaultClear() + + +class TestContingencyExport: + """Tests for contingency export functionality.""" + + @pytest.mark.order(6800) + def test_contingency_produce_report(self, saw_instance, temp_file): + """Test CTGProduceReport for report generation.""" + tmp_txt = temp_file(".txt") + saw_instance.CTGProduceReport(tmp_txt) + assert os.path.exists(tmp_txt) + + @pytest.mark.order(6900) + def test_contingency_write_pti(self, saw_instance, temp_file): + """Test CTGWriteFilePTI for PTI format export.""" + tmp_pti = temp_file(".con") + saw_instance.CTGWriteFilePTI(tmp_pti) + assert os.path.exists(tmp_pti) + + @pytest.mark.order(7000) + def test_contingency_write_all_options(self, saw_instance, temp_file): + """Test CTGWriteAllOptions for options export.""" + tmp_aux = temp_file(".aux") + saw_instance.CTGWriteAllOptions(tmp_aux) + assert os.path.exists(tmp_aux) + + @pytest.mark.order(7100) + def test_contingency_compare_two_lists(self, saw_instance, temp_file): + """Test CTGCompareTwoListsofContingencyResults for comparing contingency results.""" + list1 = temp_file(".aux") + list2 = temp_file(".aux") + try: + saw_instance.CTGWriteAllOptions(list1) + saw_instance.CTGWriteAllOptions(list2) + saw_instance.CTGCompareTwoListsofContingencyResults(list1, list2) + except (PowerWorldError, PowerWorldPrerequisiteError) as e: + pytest.skip(f"CTG compare not supported for this case: {e}") + + @pytest.mark.order(7200) + def test_contingency_write_csv(self, saw_instance, temp_file): + """Test saving contingency violations to CSV.""" + tmp_csv = temp_file(".csv") + saw_instance.CTGSaveViolationMatrices( + tmp_csv, "CSVCOLHEADER", False, ["Branch"], True, True + ) + assert os.path.exists(tmp_csv) + + +if __name__ == "__main__": + import sys + sys.exit(pytest.main(["-v", __file__])) diff --git a/tests/test_integration_saw_core.py b/tests/test_integration_saw_core.py new file mode 100644 index 00000000..3fb6be28 --- /dev/null +++ b/tests/test_integration_saw_core.py @@ -0,0 +1,630 @@ +""" +Integration tests for core SAW COM operations. + +These are **integration tests** that require a live connection to PowerWorld +Simulator via the SimAuto COM interface. They test the foundational SAW +class operations: case open/save, parameter get/set, state management, +field lists, logging, file I/O, data import/export, and subdata retrieval. + +REQUIREMENTS: + - PowerWorld Simulator installed with SimAuto COM registered + - A valid PowerWorld case file path set in ``tests/config_test.py`` + (variable ``SAW_TEST_CASE``) or via the ``SAW_TEST_CASE`` env variable + +RELATED TEST FILES: + - test_integration_saw_modify.py -- destructive modify, region, case actions + - test_integration_saw_powerflow.py -- power flow, matrices, sensitivity, topology + - test_integration_saw_contingency.py -- contingency and fault analysis + - test_integration_saw_gic.py -- GIC analysis + - test_integration_saw_transient.py -- transient stability + - test_integration_saw_operations.py -- ATC, OPF, PV/QV, time step, weather, scheduled + - test_integration_workbench.py -- PowerWorld facade and statics + - test_integration_network.py -- Network topology + +USAGE: + pytest tests/test_integration_saw_core.py -v +""" + +import os +import sys +import pytest +import pandas as pd +import numpy as np + +pytestmark = [ + pytest.mark.integration, + pytest.mark.requires_case, +] + +try: + from esapp.saw import SAW, PowerWorldError, PowerWorldPrerequisiteError, PowerWorldAddonError, create_object_string +except ImportError: + raise + + +@pytest.fixture(scope="module") +def saw_instance(saw_session): + """Provides the session-scoped SAW instance to the tests in this module.""" + return saw_session + + +class TestBase: + """Tests for base SAW operations: case open/save, parameters, state, fields.""" + + @pytest.mark.order(10) + def test_open_case_error_nonexistent_file(self, saw_instance): + """OpenCase raises PowerWorldError for a nonexistent file path.""" + original_path = saw_instance.pwb_file_path + with pytest.raises(PowerWorldError): + saw_instance.OpenCase(FileName="C:/nonexistent/path/fake_case.pwb") + saw_instance.OpenCase(original_path) + + @pytest.mark.order(20) + def test_open_case_error_wrong_filetype(self, saw_instance): + """OpenCase raises PowerWorldError for a non-PWB file.""" + original_path = saw_instance.pwb_file_path + with pytest.raises(PowerWorldError): + saw_instance.OpenCase(FileName=os.path.abspath(__file__)) + saw_instance.OpenCase(original_path) + + @pytest.mark.order(30) + def test_open_case_type_error_nonexistent(self, saw_instance): + """OpenCaseType raises PowerWorldError for nonexistent file.""" + original_path = saw_instance.pwb_file_path + with pytest.raises(PowerWorldError): + saw_instance.OpenCaseType("C:/nonexistent/fake.raw", "PTI") + saw_instance.OpenCase(original_path) + + @pytest.mark.order(100) + def test_save_case(self, saw_instance, temp_file): + """SaveCase writes a .pwb file to disk.""" + tmp_pwb = temp_file(".pwb") + saw_instance.SaveCase(tmp_pwb) + assert os.path.exists(tmp_pwb) + + @pytest.mark.order(200) + def test_get_header(self, saw_instance): + """GetCaseHeader returns non-None header data.""" + header = saw_instance.GetCaseHeader() + assert header is not None + + @pytest.mark.order(300) + def test_change_parameters(self, saw_instance): + """ChangeParametersSingleElement modifies and restores a bus name.""" + buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum", "BusName"]) + assert buses is not None and not buses.empty + + bus_num = buses.iloc[0]["BusNum"] + original_name = buses.iloc[0]["BusName"] + new_name = "TestBusName" + saw_instance.ChangeParametersSingleElement("Bus", ["BusNum", "BusName"], [bus_num, new_name]) + + check = saw_instance.GetParametersSingleElement("Bus", ["BusNum", "BusName"], [bus_num, ""]) + assert check["BusName"] == new_name + + saw_instance.ChangeParametersSingleElement("Bus", ["BusNum", "BusName"], [bus_num, original_name]) + + @pytest.mark.order(400) + def test_get_parameters(self, saw_instance): + """GetParametersMultipleElement and GetParametersSingleElement return valid data.""" + df = saw_instance.GetParametersMultipleElement("Bus", ["BusNum", "BusName"]) + assert df is not None and not df.empty + + bus_num = df.iloc[0]["BusNum"] + s = saw_instance.GetParametersSingleElement("Bus", ["BusNum", "BusName"], [bus_num, ""]) + assert isinstance(s, pd.Series) + + @pytest.mark.order(500) + def test_list_devices(self, saw_instance): + """ListOfDevices returns a non-empty DataFrame for buses.""" + df = saw_instance.ListOfDevices("Bus") + assert df is not None and not df.empty + + @pytest.mark.order(700) + def test_state(self, saw_instance): + """Store/Restore/Delete/Save/Load state cycle completes without error.""" + saw_instance.StoreState("TestState") + saw_instance.RestoreState("TestState") + saw_instance.DeleteState("TestState") + saw_instance.SaveState() + saw_instance.LoadState() + + @pytest.mark.order(800) + def test_run_script_2(self, saw_instance): + """RunScriptCommand2 executes a log command.""" + saw_instance.RunScriptCommand2("LogAdd(\"Test\");", "Testing...") + + @pytest.mark.order(900) + def test_field_list(self, saw_instance): + """GetFieldList and GetSpecificFieldList return non-empty DataFrames.""" + df = saw_instance.GetFieldList("Bus") + assert not df.empty + assert isinstance(df, pd.DataFrame) + assert "internal_field_name" in df.columns + + df_spec = saw_instance.GetSpecificFieldList("Bus", ["BusNum", "BusName"]) + assert not df_spec.empty + + @pytest.mark.order(50000) + def test_update_ui_and_exec_aux(self, saw_instance): + """update_ui and exec_aux complete without error.""" + saw_instance.update_ui() + saw_instance.exec_aux('SCRIPT\n{\n LogAdd("test exec_aux");\n}') + + @pytest.mark.order(50100) + def test_change_parameters_rect(self, saw_instance): + """ChangeParametersMultipleElementRect modifies and restores a bus name.""" + buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum", "BusName"]) + assert buses is not None and not buses.empty + + df = buses.head(1).copy() + original_name = df.iloc[0]["BusName"] + df.iloc[0, df.columns.get_loc("BusName")] = "TempTestName" + saw_instance.ChangeParametersMultipleElementRect("Bus", ["BusNum", "BusName"], df) + df.iloc[0, df.columns.get_loc("BusName")] = original_name + saw_instance.ChangeParametersMultipleElementRect("Bus", ["BusNum", "BusName"], df) + + @pytest.mark.order(50200) + def test_list_devices_variants(self, saw_instance): + """ListOfDevicesAsVariantStrings and FlatOutput return non-None.""" + result1 = saw_instance.ListOfDevicesAsVariantStrings("Bus") + assert result1 is not None + result2 = saw_instance.ListOfDevicesFlatOutput("Bus") + assert result2 is not None + + result = saw_instance.GetParametersMultipleElementFlatOutput("Bus", ["BusNum", "BusName"]) + assert result is None or len(result) > 0 + + @pytest.mark.order(50400) + def test_set_data(self, saw_instance): + """SetData modifies and restores a bus name via filter.""" + buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum", "BusName"]) + assert buses is not None and not buses.empty + + bus_num = buses.iloc[0]["BusNum"] + original = saw_instance.GetParametersSingleElement("Bus", ["BusNum", "BusName"], [bus_num, ""]) + original_name = original["BusName"] + saw_instance.SetData("Bus", ["BusName"], ["TempName"], f"BusNum = {bus_num}") + saw_instance.SetData("Bus", ["BusName"], [original_name], f"BusNum = {bus_num}") + + @pytest.mark.order(50500) + def test_simauto_property_errors(self, saw_instance): + """set_simauto_property raises appropriate errors for invalid inputs.""" + with pytest.raises(ValueError, match="not currently supported"): + saw_instance.set_simauto_property("InvalidProperty", True) + + with pytest.raises(ValueError, match="is invalid"): + saw_instance.set_simauto_property("CreateIfNotFound", "not_a_bool") + + with pytest.raises(ValueError, match="not a valid path"): + saw_instance.set_simauto_property("CurrentDir", "C:\\NonExistent\\Path\\12345") + + @pytest.mark.order(50600) + def test_change_parameters_flat_input(self, saw_instance): + """ChangeParametersMultipleElementFlatInput works with flat list and rejects nested.""" + from esapp.saw._exceptions import Error + buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum", "BusName"]) + assert buses is not None and not buses.empty + + bus_num = int(buses.iloc[0]["BusNum"]) + original_name = buses.iloc[0]["BusName"] + + saw_instance.ChangeParametersMultipleElementFlatInput( + "Bus", ["BusNum", "BusName"], 1, [bus_num, "TempFlatName"] + ) + saw_instance.ChangeParametersMultipleElementFlatInput( + "Bus", ["BusNum", "BusName"], 1, [bus_num, original_name] + ) + + with pytest.raises(Error, match="1-D array"): + saw_instance.ChangeParametersMultipleElementFlatInput( + "Bus", ["BusNum", "BusName"], 1, [[bus_num, "Test"]] + ) + + @pytest.mark.order(50700) + def test_change_parameters_multiple_element(self, saw_instance): + """ChangeParametersMultipleElement works with nested list.""" + buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum", "BusName"]) + assert buses is not None and not buses.empty + + bus_num = int(buses.iloc[0]["BusNum"]) + original_name = buses.iloc[0]["BusName"] + + saw_instance.ChangeParametersMultipleElement( + "Bus", ["BusNum", "BusName"], [[bus_num, "TempMultiName"]] + ) + saw_instance.ChangeParametersMultipleElement( + "Bus", ["BusNum", "BusName"], [[bus_num, original_name]] + ) + + @pytest.mark.order(50800) + def test_get_specific_field_max_num(self, saw_instance): + """GetSpecificFieldMaxNum returns an integer.""" + max_num = saw_instance.GetSpecificFieldMaxNum("Bus", "CustomFloat") + assert isinstance(max_num, int) + + @pytest.mark.order(50900) + def test_get_params_rect_typed(self, saw_instance): + """GetParamsRectTyped returns None or a DataFrame.""" + df = saw_instance.GetParamsRectTyped("Bus", ["BusNum", "BusName"]) + assert df is None or isinstance(df, pd.DataFrame) + + @pytest.mark.order(51200) + def test_set_logging_level(self, saw_instance): + """set_logging_level accepts both int and string levels.""" + import logging + saw_instance.set_logging_level(logging.DEBUG) + saw_instance.set_logging_level("INFO") + + @pytest.mark.order(51800) + def test_get_params_flat_empty_object(self, saw_instance): + """GetParametersMultipleElementFlatOutput returns None for impossible filter.""" + result = saw_instance.GetParametersMultipleElementFlatOutput( + "Bus", ["BusNum"], "BusNum < -99999" + ) + assert result is None + + @pytest.mark.order(51900) + def test_uivisible_property(self, saw_instance): + """UIVisible property returns a boolean.""" + result = saw_instance.UIVisible + assert isinstance(result, bool) + + @pytest.mark.order(52000) + def test_early_bind_vs_dynamic(self, saw_instance): + """Verify the session instance has a valid ProcessID.""" + assert saw_instance.ProcessID is not None + + +class TestGeneral: + """Tests for general SAW operations: logging, file I/O, data import/export.""" + + @pytest.mark.order(9500) + def test_log_operations(self, saw_instance, temp_file): + """Log lifecycle: add, clear, show, datetime variants, save, save with append.""" + saw_instance.LogAdd("SAW Validator Test Message") + tmp_log = temp_file(".txt") + saw_instance.LogSave(tmp_log) + assert os.path.exists(tmp_log) + + # Clear and re-add + saw_instance.LogClear() + saw_instance.LogAdd("Test message") + saw_instance.LogAddDateTime("Timer") + + # Show toggle + saw_instance.LogShow(show=True) + saw_instance.LogShow(show=False) + + # DateTime variants + saw_instance.LogAddDateTime("TestLabel", include_date=True, include_time=True, include_milliseconds=False) + saw_instance.LogAddDateTime("TestLabel2", include_date=True, include_time=True, include_milliseconds=True) + saw_instance.LogAddDateTime("TestLabel3", include_date=False, include_time=False, include_milliseconds=False) + + # Save with append + tmp = temp_file(".txt") + saw_instance.LogAdd("Test1") + saw_instance.LogSave(tmp, append=False) + saw_instance.LogAdd("Test2") + saw_instance.LogSave(tmp, append=True) + assert os.path.exists(tmp) + + @pytest.mark.order(9600) + def test_file_ops(self, saw_instance, temp_file): + """CopyFile, RenameFile, DeleteFile manage files correctly.""" + tmp1 = temp_file(".txt") + saw_instance.WriteTextToFile(tmp1, "Hello") + + tmp2 = tmp1.replace(".txt", "_copy.txt") + saw_instance.CopyFile(tmp1, tmp2) + assert os.path.exists(tmp2) + + tmp3 = tmp1.replace(".txt", "_renamed.txt") + saw_instance.RenameFile(tmp2, tmp3) + assert os.path.exists(tmp3) + assert not os.path.exists(tmp2) + + saw_instance.DeleteFile(tmp3) + assert not os.path.exists(tmp3) + + @pytest.mark.order(9800) + def test_aux(self, saw_instance, temp_file): + """SaveData to AUX then LoadAux round-trips without error.""" + tmp_aux = temp_file(".aux") + saw_instance.SaveData(tmp_aux, "AUX", "Bus", ["BusNum", "BusName"]) + saw_instance.LoadAux(tmp_aux) + + @pytest.mark.order(9900) + def test_select(self, saw_instance): + """SelectAll/UnSelectAll operate without error.""" + saw_instance.SelectAll("Bus") + saw_instance.UnSelectAll("Bus") + + @pytest.mark.order(52100) + def test_save_data_variants(self, saw_instance, temp_file): + """SaveData works for AUX, CSV, transposed, and non-sorted formats.""" + tmp_aux = temp_file(".aux") + tmp_csv = temp_file(".csv") + saw_instance.SaveData(tmp_aux, "AUX", "Bus", ["BusNum", "BusName"]) + assert os.path.exists(tmp_aux) + saw_instance.SaveData(tmp_csv, "CSV", "Bus", ["BusNum", "BusName"], filter_name="SELECTED") + + # Non-sorted AUX + tmp_aux2 = temp_file(".aux") + saw_instance.SaveData( + tmp_aux2, "AUX", "Bus", ["BusNum", "BusName"], + transpose=False, append=False, + ) + assert os.path.exists(tmp_aux2) + + # Transposed CSV + tmp_csv2 = temp_file(".csv") + saw_instance.SaveData( + tmp_csv2, "CSV", "Bus", ["BusNum", "BusName"], + transpose=True, append=False, + ) + + @pytest.mark.order(52300) + def test_enter_mode(self, saw_instance): + """EnterMode switches between EDIT and RUN modes.""" + saw_instance.EnterMode("EDIT") + saw_instance.EnterMode("RUN") + + @pytest.mark.order(53100) + def test_set_sub_data(self, saw_instance): + """SetSubData creates a contingency with CTGElement subdata.""" + branches = saw_instance.GetParametersMultipleElement( + "Branch", ["BusNum", "BusNum:1", "LineCircuit"] + ) + assert branches is not None and not branches.empty + b = branches.iloc[0] + action = f'BRANCH {b["BusNum"]} {b["BusNum:1"]} {b["LineCircuit"]} OPEN' + + saw_instance.SetSubData( + "Contingency", + ["Name"], + [{ + "Name": "TestCtgSubData", + "CTGElement": [[action, "", "ALWAYS", 0]], + }], + subdatatype="CTGElement", + ) + result = saw_instance.GetSubData( + "Contingency", ["Name"], ["CTGElement"] + ) + assert isinstance(result, pd.DataFrame) + assert len(result) > 0 + + @pytest.mark.order(53200) + def test_set_sub_data_roundtrip(self, saw_instance): + """SetSubData then GetSubData verifies subdata content persists.""" + branches = saw_instance.GetParametersMultipleElement( + "Branch", ["BusNum", "BusNum:1", "LineCircuit"] + ) + assert branches is not None and not branches.empty + b = branches.iloc[0] + action = f'BRANCH {b["BusNum"]} {b["BusNum:1"]} {b["LineCircuit"]} OPEN' + + saw_instance.SetSubData( + "Contingency", + ["Name"], + [{ + "Name": "TestCtgRoundtrip", + "CTGElement": [[action, "", "ALWAYS", 0]], + }], + subdatatype="CTGElement", + ) + result = saw_instance.GetSubData( + "Contingency", ["Name"], ["CTGElement"] + ) + assert isinstance(result, pd.DataFrame) + match = result[result["Name"] == "TestCtgRoundtrip"] + assert len(match) == 1 + assert len(match.iloc[0]["CTGElement"]) > 0 + + @pytest.mark.order(67600) + def test_set_current_directory(self, saw_instance, temp_dir): + """SetCurrentDirectory with and without create_if_not_found.""" + saw_instance.SetCurrentDirectory(str(temp_dir)) + new_dir = os.path.join(str(temp_dir), "test_subdir") + saw_instance.SetCurrentDirectory(new_dir, create_if_not_found=True) + + @pytest.mark.order(67900) + def test_import_data(self, saw_instance, temp_file): + """ImportData round-trips PTI format.""" + tmp = temp_file(".raw") + saw_instance.SaveData(tmp, "PTI", "Bus", ["BusNum", "BusName"]) + saw_instance.ImportData(tmp, "PTI", header_line=1, create_if_not_found=True) + + @pytest.mark.order(68000) + def test_load_csv(self, saw_instance, temp_file): + """LoadCSV loads a simple CSV file.""" + tmp_csv = temp_file(".csv") + with open(tmp_csv, "w") as f: + f.write("ObjectType,Bus\nBusNum,BusName\n1,TestBus\n") + saw_instance.LoadCSV(tmp_csv, create_if_not_found=True) + + @pytest.mark.order(68100) + def test_save_data_with_extra(self, saw_instance, temp_file): + """SaveDataWithExtra writes CSV with header metadata.""" + tmp_csv = temp_file(".csv") + saw_instance.SaveDataWithExtra( + tmp_csv, "CSV", "Bus", ["BusNum", "BusName"], + header_list=["CaseName"], header_value_list=["TestCase"], + ) + assert os.path.exists(tmp_csv) + + @pytest.mark.order(68400) + def test_load_aux_create(self, saw_instance, temp_file): + """LoadAux with create_if_not_found creates new objects.""" + tmp_aux = temp_file(".aux") + with open(tmp_aux, "w") as f: + f.write('DATA (Bus, [BusNum, BusName]) {\n99998 "TestNewBus"\n}\n') + saw_instance.LoadAux(tmp_aux, create_if_not_found=True) + try: + saw_instance.Delete("Bus", "BusNum = 99998") + except PowerWorldError: + pass + + @pytest.mark.order(68500) + def test_load_aux_directory(self, saw_instance, temp_dir): + """LoadAuxDirectory with and without filter.""" + saw_instance.LoadAuxDirectory(str(temp_dir), filter_string="*.aux") + saw_instance.LoadAuxDirectory(str(temp_dir)) + + @pytest.mark.order(68700) + def test_load_data(self, saw_instance, temp_file): + """LoadData loads bus data from AUX.""" + tmp_aux = temp_file(".aux") + with open(tmp_aux, "w") as f: + f.write('DATA (Bus, [BusNum, BusName]) {\n1 "TestBus"\n}\n') + saw_instance.LoadData(tmp_aux, "Bus") + + @pytest.mark.order(68800) + def test_stop_aux_file(self, saw_instance): + """StopAuxFile completes without error.""" + saw_instance.StopAuxFile() + + @pytest.mark.order(68900) + def test_select_all_no_filter(self, saw_instance): + """SelectAll/UnSelectAll without filter.""" + saw_instance.SelectAll("Bus") + saw_instance.UnSelectAll("Bus") + + @pytest.mark.order(85100) + def test_save_object_fields(self, saw_instance, temp_file): + """SaveObjectFields writes field metadata to file.""" + tmp = temp_file(".csv") + saw_instance.SaveObjectFields(tmp, "Bus", ["BusNum", "BusName"]) + + @pytest.mark.order(85200) + def test_load_script(self, saw_instance, temp_file): + """LoadScript processes script from aux file.""" + tmp = temp_file(".aux") + with open(tmp, "w") as f: + f.write('SCRIPT TestScript\n{\n LogAdd("Script test");\n}\n') + saw_instance.LoadScript(tmp, "TestScript") + + @pytest.mark.order(85300) + def test_delete_with_filter(self, saw_instance): + """Delete with specific filter.""" + saw_instance.CreateData("Bus", ["BusNum", "BusName"], [99995, "DeleteTestBus"]) + saw_instance.Delete("Bus", "BusNum = 99995") + + @pytest.mark.order(85400) + def test_create_data(self, saw_instance): + """CreateData creates an object then cleans up.""" + saw_instance.CreateData("Bus", ["BusNum", "BusName"], [99994, "CreateTestBus"]) + saw_instance.Delete("Bus", "BusNum = 99994") + + @pytest.mark.order(85500) + def test_send_to_excel(self, saw_instance): + """SendtoExcel completes without error (requires Excel).""" + try: + saw_instance.SendtoExcel( + "Bus", ["BusNum", "BusName"], + workbook="TestWorkbook", + worksheet="Sheet1", + use_column_headers=True, + clear_existing=True, + ) + except PowerWorldError as e: + msg = str(e).lower() + if "excel" in msg or "workbook" in msg or "saveas" in msg: + pytest.skip("Excel not available or workbook error") + raise + + +class TestSubData: + """Integration tests for GetSubData - retrieving nested SubData from AUX exports.""" + + @pytest.mark.order(40000) + def test_gen_ops(self, saw_instance): + """GetSubData retrieves generator data with various SubData types.""" + df = saw_instance.GetSubData("Gen", ["BusNum", "GenID", "GenMW"]) + assert df is not None + assert "BusNum" in df.columns and "GenID" in df.columns and "GenMW" in df.columns + + df = saw_instance.GetSubData("Gen", ["BusNum", "GenID"], ["BidCurve"]) + assert df is not None and "BidCurve" in df.columns + for bc in df["BidCurve"]: + assert isinstance(bc, list) + + df = saw_instance.GetSubData("Gen", ["BusNum", "GenID"], ["ReactiveCapability"]) + assert df is not None and "ReactiveCapability" in df.columns + for rc in df["ReactiveCapability"]: + assert isinstance(rc, list) + + df = saw_instance.GetSubData("Gen", ["BusNum", "GenID", "GenMW"], ["BidCurve", "ReactiveCapability"]) + assert df is not None and "BidCurve" in df.columns and "ReactiveCapability" in df.columns + + df_all = saw_instance.GetSubData("Gen", ["BusNum", "GenID"]) + df_filtered = saw_instance.GetSubData("Gen", ["BusNum", "GenID"], filter_name="GenStatus=Closed") + assert df_filtered is not None and len(df_filtered) <= len(df_all) + + @pytest.mark.order(40100) + def test_other_types(self, saw_instance): + """GetSubData works for Load, Contingency, and Interface object types.""" + df = saw_instance.GetSubData("Load", ["BusNum", "LoadID", "LoadMW"], ["BidCurve"]) + assert df is not None and "BidCurve" in df.columns + + df = saw_instance.GetSubData("Contingency", ["TSContingency"], ["CTGElement"]) + assert df is not None + if not df.empty: + assert "CTGElement" in df.columns + for ctg in df["CTGElement"]: + assert isinstance(ctg, list) + + df = saw_instance.GetSubData("Interface", ["InterfaceName"], ["InterfaceElement"]) + assert df is not None + + df = saw_instance.GetSubData("SuperArea", ["SuperAreaName"], ["SuperAreaArea"]) + assert df is not None + + +class TestDataAccess: + """Integration tests for data access, saving, and property accessors.""" + + @pytest.mark.order(41100) + def test_retrieval(self, saw_instance): + """Data retrieval operations return correct types and non-empty results.""" + df = saw_instance.GetParametersMultipleElement("Bus", ["BusNum", "BusName"]) + assert df is not None and isinstance(df, pd.DataFrame) and len(df) > 0 + assert "BusNum" in df.columns and "BusName" in df.columns + + bus_num = df.iloc[0]["BusNum"] + s = saw_instance.GetParametersSingleElement("Bus", ["BusNum", "BusName"], [bus_num, ""]) + assert isinstance(s, pd.Series) + + df = saw_instance.ListOfDevices("Bus") + assert df is not None and isinstance(df, pd.DataFrame) and len(df) > 0 + + result = saw_instance.ListOfDevicesAsVariantStrings("Bus") + assert result is not None + + df1 = saw_instance.GetFieldList("Bus") + assert df1 is not None and "internal_field_name" in df1.columns and len(df1) > 0 + df2 = saw_instance.GetFieldList("Bus") + assert df1.equals(df2) + + @pytest.mark.order(41200) + def test_properties_and_errors(self, saw_instance): + """Property accessors return valid data, invalid operations raise errors.""" + pid = saw_instance.ProcessID + assert pid is not None and isinstance(pid, int) and pid > 0 + + info = saw_instance.ProgramInformation + assert info is not None and isinstance(info, tuple) + + current_dir = saw_instance.CurrentDir + assert current_dir is not None and isinstance(current_dir, str) + + with pytest.raises(ValueError, match="Mode must be either"): + saw_instance.EnterMode("INVALID") + + with pytest.raises(PowerWorldError): + saw_instance.RunScriptCommand("InvalidCommand_XYZ_123;") + + +if __name__ == "__main__": + sys.exit(pytest.main(["-v", __file__])) diff --git a/tests/test_integration_saw_gic.py b/tests/test_integration_saw_gic.py new file mode 100644 index 00000000..7ce1cdf5 --- /dev/null +++ b/tests/test_integration_saw_gic.py @@ -0,0 +1,313 @@ +""" +Integration tests for GIC (Geomagnetically Induced Currents) analysis via SAW. + +These are **integration tests** that require a live connection to PowerWorld +Simulator via the SimAuto COM interface. They cover low-level SAW GIC commands, +workbench-level option getters/setters, storm application, B3D loading, +G-matrix extraction, model building, and G-matrix comparison with PowerWorld. + +REQUIREMENTS: + - PowerWorld Simulator installed with SimAuto COM registered + - A valid PowerWorld case file path set in ``tests/config_test.py`` + (variable ``SAW_TEST_CASE``) or via the ``SAW_TEST_CASE`` env variable + +USAGE: + pytest tests/test_integration_saw_gic.py -v +""" + +import os +import pytest +import pandas as pd +import numpy as np + +pytestmark = [ + pytest.mark.integration, + pytest.mark.requires_case, +] + +try: + from esapp.saw import SAW, PowerWorldError, PowerWorldPrerequisiteError, create_object_string + from esapp.workbench import PowerWorld + from esapp.utils import GIC + from esapp.components import Bus, Branch, Substation +except ImportError: + raise + + +@pytest.fixture(scope="module") +def saw_instance(saw_session): + """Provides the session-scoped SAW instance to the tests in this module.""" + return saw_session + + +@pytest.fixture(scope="module") +def wb(saw_session): + """PowerWorld with live SAW connection.""" + workbench = PowerWorld() + workbench.esa = saw_session + return workbench + + +class TestGIC: + """GIC analysis: SAW commands, workbench options, model building, G-matrix.""" + + @pytest.mark.order(7300) + def test_gic_calculate(self, saw_instance): + saw_instance.EnterMode("EDIT") + saw_instance.SetData( + 'GIC_Options_Value', + ['VariableName', 'ValueField'], + ['IncludeInPowerFlow', 'YES'] + ) + saw_instance.SetData( + 'GIC_Options_Value', + ['VariableName', 'ValueField'], + ['CalcMode', 'SnapShot'] + ) + saw_instance.EnterMode("RUN") + + subs = saw_instance.GetParametersMultipleElement( + "Substation", ["SubNum", "GICSubGroundOhms"] + ) + has_grounding = ( + subs is not None and not subs.empty + and (subs["GICSubGroundOhms"].astype(float) > 0).any() + ) + if not has_grounding: + branches = saw_instance.GetParametersMultipleElement( + "Branch", ["BusNum", "BusNum:1", "BranchDeviceType", + "GICCoilRFrom", "GICCoilRTo"] + ) + has_xfmr_data = False + if branches is not None and not branches.empty: + xfmrs = branches[branches["BranchDeviceType"] == "Transformer"] + has_xfmr_data = ( + not xfmrs.empty + and ((xfmrs["GICCoilRFrom"].astype(float) > 0).any() + or (xfmrs["GICCoilRTo"].astype(float) > 0).any()) + ) + assert has_xfmr_data, ( + "Case has no GIC data (no substation grounding or transformer " + "coil resistances). Cannot run GIC calculation." + ) + + saw_instance.GICCalculate(1.0, 90.0, False) + saw_instance.GICClear() + + @pytest.mark.order(7400) + def test_gic_save_matrix(self, saw_instance, temp_file): + tmp_mat = temp_file(".mat") + tmp_id = temp_file(".txt") + saw_instance.GICSaveGMatrix(tmp_mat, tmp_id) + assert os.path.exists(tmp_mat) + + @pytest.mark.order(7500) + def test_gic_setup_and_time(self, saw_instance): + saw_instance.GICSetupTimeVaryingSeries() + saw_instance.GICShiftOrStretchInputPoints() + saw_instance.GICTimeVaryingCalculate(0.0, False) + saw_instance.GICTimeVaryingAddTime(10.0) + saw_instance.GICTimeVaryingDeleteAllTimes() + saw_instance.GICTimeVaryingEFieldCalculate(0.0, False) + saw_instance.GICTimeVaryingElectricFieldsDeleteAllTimes() + + @pytest.mark.order(7700) + def test_gic_write(self, saw_instance, temp_file): + tmp_aux = temp_file(".aux") + saw_instance.GICWriteOptions(tmp_aux) + assert os.path.exists(tmp_aux) + + tmp_gmd = temp_file(".gmd") + saw_instance.GICWriteFilePSLF(tmp_gmd) + + tmp_gic = temp_file(".gic") + saw_instance.GICWriteFilePTI(tmp_gic) + + @pytest.mark.order(7710) + def test_gic_options(self, wb): + """Descriptor-based options: bool and non-bool round-trip, configure.""" + gic = wb.gic + + # Bool descriptor round-trip + gic.pf_include = True + assert gic.pf_include is True + gic.pf_include = False + assert gic.pf_include is False + gic.pf_include = True + + gic.ts_include = True + assert gic.ts_include is True + gic.ts_include = False + assert gic.ts_include is False + + # Additional bool descriptors + gic.update_line_volts = True + assert gic.update_line_volts is True + gic.update_line_volts = False + assert gic.update_line_volts is False + gic.update_line_volts = True + + gic.calc_max_direction = True + assert gic.calc_max_direction is True + gic.calc_max_direction = False + + gic.hotspot_include = False + assert gic.hotspot_include is False + + gic.skip_equiv_lines = True + assert gic.skip_equiv_lines is True + gic.skip_equiv_lines = False + + gic.skip_low_r_lines = True + assert gic.skip_low_r_lines is True + gic.skip_low_r_lines = False + + # Non-bool descriptor round-trip + gic.calc_mode = 'SnapShot' + assert gic.calc_mode == 'SnapShot' + gic.calc_mode = 'TimeVarying' + assert gic.calc_mode == 'TimeVarying' + gic.calc_mode = 'SnapShot' + + # Non-bool float descriptors + orig_angle = gic.efield_angle + gic.efield_angle = 45.0 + assert float(gic.efield_angle) == 45.0 + if orig_angle is not None: + gic.efield_angle = orig_angle + + orig_mag = gic.efield_mag + gic.efield_mag = 1.5 + assert float(gic.efield_mag) == 1.5 + if orig_mag is not None: + gic.efield_mag = orig_mag + + orig_min_kv = gic.min_kv + gic.min_kv = 100.0 + assert float(gic.min_kv) == 100.0 + if orig_min_kv is not None: + gic.min_kv = orig_min_kv + + orig_seg = gic.segment_length_km + gic.segment_length_km = 10.0 + assert float(gic.segment_length_km) == 10.0 + if orig_seg is not None: + gic.segment_length_km = orig_seg + + # configure() sets multiple options at once + gic.configure(pf_include=True, ts_include=True, calc_mode='TimeVarying') + assert gic.pf_include is True + assert gic.ts_include is True + assert gic.calc_mode == 'TimeVarying' + gic.configure() + + # Class-level access returns the descriptor itself + desc = type(gic).pf_include + assert hasattr(desc, 'key') + assert desc.key == 'IncludeInPowerFlow' + + @pytest.mark.order(7750) + def test_gic_storm_and_clear(self, wb): + wb.gic.storm(1.0, 90.0, solvepf=True) + wb.gic.storm(1.0, 90.0, solvepf=False) + wb.gic.cleargic() + + @pytest.mark.order(7770) + def test_gic_loadb3d(self, wb): + with pytest.raises((PowerWorldPrerequisiteError, PowerWorldError)): + wb.gic.loadb3d("STORM", "nonexistent.b3d", setuponload=True) + with pytest.raises((PowerWorldPrerequisiteError, PowerWorldError)): + wb.gic.loadb3d("STORM", "nonexistent.b3d", setuponload=False) + + @pytest.mark.order(7775) + def test_gic_timevary_csv(self, wb, temp_file): + import csv as csvmod + tmp_csv = temp_file(".csv") + with open(tmp_csv, 'w', newline='') as f: + writer = csvmod.writer(f) + writer.writerow(["Branch '1' '2' '1'", 0.1, 0.11, 0.14]) + wb.gic.timevary_csv(tmp_csv) + + @pytest.mark.order(7780) + def test_gic_settings_and_gmatrix(self, wb): + settings = wb.gic.settings() + assert settings is not None + assert isinstance(settings, pd.DataFrame) + assert 'VariableName' in settings.columns + + G_sparse = wb.gic.gmatrix(sparse=True) + assert G_sparse.shape[0] > 0 + G_dense = wb.gic.gmatrix(sparse=False) + assert isinstance(G_dense, np.ndarray) + + @pytest.mark.order(7850) + def test_gic_gmatrix_comparison(self, gic_saw): + """Compare computed G-matrix from GIC.model() with PowerWorld's.""" + from scipy.sparse import issparse + + pw = PowerWorld() + pw.esa = gic_saw + gic = pw.gic + gic.pf_include = True + + subs = pw[Substation, ["SubNum", "SubName", "GICSubGroundOhms", "GICUsedSubGroundOhms"]] + buses = pw[Bus, ["BusNum", "BusNomVolt", "SubNum"]] + branches = pw[Branch, ["BusNum", "BusNum:1", "GICConductance", "BranchDeviceType", + "GICCoilRFrom", "GICCoilRTo"]] + lines = branches.loc[ + branches['BranchDeviceType'] != 'Transformer', + ["BusNum", "BusNum:1", "GICConductance"] + ] + xfmrs = branches[branches["BranchDeviceType"] == "Transformer"] + has_grounding = (subs["GICSubGroundOhms"] > 0).any() + has_xfmr_data = (xfmrs["GICCoilRFrom"] > 0).any() or (xfmrs["GICCoilRTo"] > 0).any() + + if not has_grounding and not has_xfmr_data: + pytest.skip("Case does not have GIC data configured") + + model = gic.model() + G_computed = model.G + + G_powerworld = gic.gmatrix(sparse=True) + + assert issparse(G_computed) and issparse(G_powerworld) + + G_computed_dense = G_computed.toarray() + G_powerworld_dense = G_powerworld.toarray() + + if G_computed_dense.shape != G_powerworld_dense.shape: + pytest.fail(f"Shape mismatch: {G_computed_dense.shape} vs {G_powerworld_dense.shape}") + + diff = np.abs(G_computed_dense - G_powerworld_dense) + max_diff = np.max(diff) + + rtol, atol = 1e-3, 1e-6 + if np.allclose(G_computed_dense, G_powerworld_dense, rtol=rtol, atol=atol): + return + + MOHM = 1e6 + num_differing = np.sum(diff > 1e-6) + if np.any(np.abs(G_computed_dense) > MOHM * 0.9): + pytest.skip(f"G-matrices differ (max={max_diff:.2e}). Large placeholder values detected.") + elif max_diff < 1.0: + pass + else: + pytest.fail(f"G-matrices differ significantly (max={max_diff:.2e}, {num_differing}/{diff.size} elements)") + + @pytest.mark.order(7860) + def test_gic_model(self, wb): + """model() returns self and all properties are populated.""" + model = wb.gic.model() + assert model is wb.gic + + assert wb.gic.A.shape[0] > 0 + assert wb.gic.G.shape[0] == wb.gic.G.shape[1] + assert wb.gic.H.shape[0] > 0 + assert wb.gic.zeta.shape[0] > 0 + assert wb.gic.Px.shape[0] > 0 + assert wb.gic.eff.shape[0] > 0 + + +if __name__ == "__main__": + import sys + sys.exit(pytest.main(["-v", __file__])) diff --git a/tests/test_integration_saw_modify.py b/tests/test_integration_saw_modify.py new file mode 100644 index 00000000..e3d9642c --- /dev/null +++ b/tests/test_integration_saw_modify.py @@ -0,0 +1,390 @@ +""" +Integration tests for SAW modify, region, and case action operations. + +These are **integration tests** that require a live connection to PowerWorld +Simulator via the SimAuto COM interface. They test destructive modify operations +(create/delete objects, merge, split, topology changes), region operations, +and case-level actions (equivalence, renumber, scale, description). + +REQUIREMENTS: + - PowerWorld Simulator installed with SimAuto COM registered + - A valid PowerWorld case file path set in ``tests/config_test.py`` + (variable ``SAW_TEST_CASE``) or via the ``SAW_TEST_CASE`` env variable + +RELATED TEST FILES: + - test_integration_saw_core.py -- base SAW operations, logging, I/O + - test_integration_saw_powerflow.py -- power flow, matrices, sensitivity, topology + - test_integration_saw_contingency.py -- contingency and fault analysis + - test_integration_saw_gic.py -- GIC analysis + - test_integration_saw_transient.py -- transient stability + - test_integration_saw_operations.py -- ATC, OPF, PV/QV, time step, weather, scheduled + - test_integration_workbench.py -- PowerWorld facade and statics + - test_integration_network.py -- Network topology + +USAGE: + pytest tests/test_integration_saw_modify.py -v +""" + +import os +import sys +import pytest +import pandas as pd + +pytestmark = [ + pytest.mark.integration, + pytest.mark.requires_case, +] + +try: + from esapp.saw import SAW, PowerWorldError, PowerWorldPrerequisiteError, PowerWorldAddonError, create_object_string +except ImportError: + raise + + +@pytest.fixture(scope="module") +def saw_instance(saw_session): + """Provides the session-scoped SAW instance to the tests in this module.""" + return saw_session + + +@pytest.mark.usefixtures("save_restore_state") +class TestModify: + """Tests for modify operations (destructive - run late).""" + + @pytest.mark.order(12000) + def test_create_delete(self, saw_instance): + """CreateData and Delete cycle for a bus.""" + dummy_bus = 99999 + saw_instance.CreateData( + "Bus", + ["BusNum", "BusName", "BusNomVolt"], + [dummy_bus, "SAW_TEST", 115] + ) + saw_instance.Delete("Bus", f"BusNum = {dummy_bus}") + + @pytest.mark.order(13400) + def test_superarea(self, saw_instance): + """SuperArea create, add areas, remove areas cycle.""" + saw_instance.CreateData("SuperArea", ["Name"], ["TestSuperArea"]) + saw_instance.SuperAreaAddAreas("TestSuperArea", "ALL") + saw_instance.SuperAreaRemoveAreas("TestSuperArea", "ALL") + + @pytest.mark.order(13500) + def test_interface_ops(self, saw_instance): + """Interface creation and manipulation operations.""" + saw_instance.InjectionGroupRemoveDuplicates() + saw_instance.InterfaceRemoveDuplicates() + saw_instance.DirectionsAutoInsertReference("Bus", "Slack") + + saw_instance.InterfaceCreate("TestInt", True, "Branch", "SELECTED") + saw_instance.InterfaceFlatten("TestInt") + saw_instance.InterfaceFlattenFilter("ALL") + saw_instance.InterfaceModifyIsolatedElements() + + saw_instance.CreateData("Contingency", ["Name"], ["TestCtg"]) + saw_instance.InterfaceAddElementsFromContingency("TestInt", "TestCtg") + + @pytest.mark.order(14000) + def test_create_line_derive_existing(self, saw_instance): + """CreateLineDeriveExisting creates a line from existing parameters.""" + branches = saw_instance.GetParametersMultipleElement( + "Branch", ["BusNum", "BusNum:1", "LineCircuit", "BranchDeviceType"] + ) + assert branches is not None and not branches.empty, "Test case must contain branches" + lines = branches[branches["BranchDeviceType"] == "Line"] + if lines.empty: + pytest.skip("No line branches available for CreateLineDeriveExisting test") + b = lines.iloc[0] + branch_id = create_object_string("Branch", b["BusNum"], b["BusNum:1"], b["LineCircuit"]) + saw_instance.SaveState() + try: + saw_instance.CreateLineDeriveExisting( + int(b["BusNum"]), int(b["BusNum:1"]), "99", + 10.0, branch_id, existing_length=5.0, zero_g=True, + ) + finally: + saw_instance.LoadState() + + @pytest.mark.order(14100) + def test_merge_buses(self, saw_instance): + """MergeBuses completes without error.""" + buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum"]) + assert buses is not None and not buses.empty, "Test case must contain buses" + bus_num = str(buses.iloc[0]["BusNum"]).strip() + bus_str = create_object_string("Bus", bus_num) + saw_instance.SaveState() + try: + saw_instance.SetData("Bus", ["BusNum", "Selected"], [bus_num, "YES"]) + saw_instance.MergeBuses(bus_str, filter_name="SELECTED") + finally: + saw_instance.LoadState() + + @pytest.mark.order(14200) + def test_move(self, saw_instance): + """Move a switched shunt (0% -- no-op).""" + shunts = saw_instance.GetParametersMultipleElement("Shunt", ["BusNum", "ShuntID"]) + if shunts is None or shunts.empty: + pytest.skip("No switched shunts found for Move test") + shunt_key = create_object_string("Shunt", shunts.iloc[0]["BusNum"], shunts.iloc[0]["ShuntID"]) + bus_key = create_object_string("Bus", shunts.iloc[0]["BusNum"]) + saw_instance.SaveState() + try: + saw_instance.Move(shunt_key, bus_key, how_much=0.0, abort_on_error=True) + except PowerWorldError as e: + if "Unknown object" in str(e) or "not supported" in str(e).lower(): + pytest.skip(f"Move not supported for this object type on this case: {e}") + raise + finally: + saw_instance.LoadState() + + @pytest.mark.order(14300) + def test_split_bus(self, saw_instance): + """SplitBus creates a new bus from an existing one.""" + buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum"]) + assert buses is not None and not buses.empty, "Test case must contain buses" + bus_key = create_object_string("Bus", buses.iloc[0]["BusNum"]) + saw_instance.SaveState() + try: + saw_instance.SplitBus(bus_key, 99997, insert_tie=True, line_open=False) + finally: + saw_instance.LoadState() + + @pytest.mark.order(14400) + def test_tap_transmission_line(self, saw_instance): + """TapTransmissionLine taps a line at midpoint (lines only).""" + branches = saw_instance.GetParametersMultipleElement( + "Branch", ["BusNum", "BusNum:1", "LineCircuit", "BranchDeviceType"] + ) + assert branches is not None and not branches.empty, "Test case must contain branches" + lines = branches[branches["BranchDeviceType"] == "Line"] + if lines.empty: + pytest.skip("No line branches available for TapTransmissionLine test") + b = lines.iloc[0] + branch_key = create_object_string("Branch", b["BusNum"], b["BusNum:1"], b["LineCircuit"]) + saw_instance.SaveState() + try: + saw_instance.TapTransmissionLine( + branch_key, 50.0, 99996, + shunt_model="CAPACITANCE", + treat_as_ms_line=False, + update_onelines=False, + new_bus_name="TapBus", + ) + finally: + saw_instance.LoadState() + + @pytest.mark.order(14500) + def test_branch_mva_limit_with_limits(self, saw_instance): + """BranchMVALimitReorder with explicit limits list.""" + saw_instance.SaveState() + try: + saw_instance.BranchMVALimitReorder( + filter_name="ALL", + limits=["A", "B", "C"], + ) + finally: + saw_instance.LoadState() + + @pytest.mark.order(80000) + def test_modify_auto_insert_tieline(self, saw_instance): + saw_instance.AutoInsertTieLineTransactions() + + @pytest.mark.order(80100) + def test_modify_branch_mva_limit_reorder(self, saw_instance): + saw_instance.BranchMVALimitReorder() + + @pytest.mark.order(80200) + def test_modify_branch_mva_limit_reorder_with_filter(self, saw_instance): + saw_instance.BranchMVALimitReorder(filter_name="ALL") + + @pytest.mark.order(80300) + def test_modify_calculate_rxbg(self, saw_instance): + """CalculateRXBGFromLengthConfigCondType with and without filter.""" + try: + saw_instance.CalculateRXBGFromLengthConfigCondType() + saw_instance.CalculateRXBGFromLengthConfigCondType(filter_name="SELECTED") + except PowerWorldAddonError: + pytest.skip("TransLineCalc add-on not registered") + + @pytest.mark.order(80500) + def test_modify_clear_small_islands(self, saw_instance): + saw_instance.ClearSmallIslands() + + @pytest.mark.order(80600) + def test_modify_init_gen_mvar_limits(self, saw_instance): + saw_instance.InitializeGenMvarLimits() + + @pytest.mark.order(80700) + def test_modify_injection_groups_auto_insert(self, saw_instance): + saw_instance.InjectionGroupsAutoInsert() + + @pytest.mark.order(80800) + def test_modify_injection_group_create(self, saw_instance): + saw_instance.InjectionGroupCreate("TestIG", "Gen", 1.0, "", append=True) + + @pytest.mark.order(80900) + def test_modify_injection_group_create_no_append(self, saw_instance): + saw_instance.InjectionGroupCreate("TestIG2", "Gen", 1.0, "", append=False) + + @pytest.mark.order(81000) + def test_modify_interfaces_auto_insert(self, saw_instance): + """InterfacesAutoInsert with and without filters.""" + saw_instance.InterfacesAutoInsert("AREA", delete_existing=True, use_filters=False) + saw_instance.InterfacesAutoInsert("AREA", delete_existing=False, use_filters=True, prefix="TEST_") + + @pytest.mark.order(81200) + def test_modify_set_participation_factors(self, saw_instance): + saw_instance.SetParticipationFactors("CONSTANT", 1.0, "SYSTEM") + + @pytest.mark.order(81300) + def test_modify_set_scheduled_voltage(self, saw_instance): + buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum"]) + assert buses is not None and not buses.empty, "Test case must contain buses" + bus_key = create_object_string("Bus", buses.iloc[0]["BusNum"]) + saw_instance.SetScheduledVoltageForABus(bus_key, 1.0) + + @pytest.mark.order(81400) + def test_modify_set_interface_limit_sum(self, saw_instance): + saw_instance.SetInterfaceLimitToMonitoredElementLimitSum("ALL") + + @pytest.mark.order(81500) + def test_modify_rotate_bus_angles(self, saw_instance): + buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum"]) + assert buses is not None and not buses.empty, "Test case must contain buses" + bus_key = create_object_string("Bus", buses.iloc[0]["BusNum"]) + saw_instance.RotateBusAnglesInIsland(bus_key, 0.0) + + @pytest.mark.order(81600) + def test_modify_set_gen_pmax(self, saw_instance): + saw_instance.SetGenPMaxFromReactiveCapabilityCurve() + + @pytest.mark.order(81700) + def test_modify_remove_3w_xformer(self, saw_instance): + saw_instance.Remove3WXformerContainer() + + @pytest.mark.order(81800) + def test_modify_rename_injection_group(self, saw_instance): + saw_instance.InjectionGroupCreate("RenameTestIG", "Gen", 1.0, "") + saw_instance.RenameInjectionGroup("RenameTestIG", "RenamedIG") + + @pytest.mark.order(81900) + def test_modify_reassign_ids(self, saw_instance): + """ReassignIDs with and without use_right.""" + saw_instance.ReassignIDs("Load", "BusName", filter_name="", use_right=False) + saw_instance.ReassignIDs("Load", "BusName", filter_name="ALL", use_right=True) + + @pytest.mark.order(82100) + @pytest.mark.skip(reason="MergeLineTerminals causes PW access violation that kills COM server") + def test_modify_merge_line_terminals(self, saw_instance): + saw_instance.MergeLineTerminals("SELECTED") + + @pytest.mark.order(82200) + @pytest.mark.skip(reason="MergeMSLineSections causes PW access violation that kills COM server") + def test_modify_merge_ms_line_sections(self, saw_instance): + saw_instance.MergeMSLineSections("SELECTED") + + @pytest.mark.order(82300) + def test_modify_directions_auto_insert(self, saw_instance): + """DirectionsAutoInsert with multiple parameter combinations.""" + areas = saw_instance.GetParametersMultipleElement("Area", ["AreaNum"]) + if areas is None or len(areas) < 2: + pytest.skip("DirectionsAutoInsert requires a case with at least 2 areas") + s = create_object_string("Area", areas.iloc[0]["AreaNum"]) + b = create_object_string("Area", areas.iloc[1]["AreaNum"]) + saw_instance.DirectionsAutoInsert(s, b, delete_existing=True, use_area_zone_filters=False) + saw_instance.DirectionsAutoInsert(s, b, delete_existing=False, use_area_zone_filters=True) + saw_instance.DirectionsAutoInsertReference("Bus", "Slack", delete_existing=True, opposite_direction=True) + + @pytest.mark.order(82600) + def test_modify_change_system_mva_base(self, saw_instance): + saw_instance.ChangeSystemMVABase(100.0) + + +class TestRegions: + """Tests for region operations.""" + + @pytest.mark.order(20000) + def test_region_update_buses(self, saw_instance): + """RegionUpdateBuses completes without error.""" + saw_instance.RegionUpdateBuses() + + @pytest.mark.order(20100) + def test_region_rename(self, saw_instance): + """Region rename operations complete without error.""" + saw_instance.RegionRename("OldRegion", "NewRegion") + saw_instance.RegionRenameClass("OldClass", "NewClass") + saw_instance.RegionRenameProper1("OldP1", "NewP1") + saw_instance.RegionRenameProper2("OldP2", "NewP2") + saw_instance.RegionRenameProper3("OldP3", "NewP3") + saw_instance.RegionRenameProper12Flip() + + @pytest.mark.order(85000) + def test_region_load_shapefile(self, saw_instance, temp_file): + """RegionLoadShapefile completes without error.""" + tmp = temp_file(".shp") + saw_instance.RegionLoadShapefile( + tmp, "TestClass", ["Name"], + add_to_open_onelines=False, + display_style_name="", + delete_existing=True, + ) + + +class TestCaseActions: + """Tests for case actions (highly destructive - run last).""" + + @pytest.mark.order(30000) + def test_case_description(self, saw_instance): + """CaseDescriptionSet, append, and clear.""" + saw_instance.CaseDescriptionSet("Test Description") + saw_instance.CaseDescriptionClear() + saw_instance.CaseDescriptionSet("Line 1") + saw_instance.CaseDescriptionSet("Line 2", append=True) + saw_instance.CaseDescriptionClear() + + @pytest.mark.order(30100) + def test_equivalence_and_external_system(self, saw_instance, temp_file): + """External system operations, equivalence, and save with ties.""" + saw_instance.DeleteExternalSystem() + saw_instance.Equivalence() + tmp_pwb = temp_file(".pwb") + saw_instance.SaveExternalSystem(tmp_pwb) + saw_instance.SaveMergedFixedNumBusCase(tmp_pwb) + saw_instance.SaveExternalSystem(tmp_pwb, with_ties=True) + + @pytest.mark.order(30150) + def test_scale(self, saw_instance): + """Scale load, gen, and load MW.""" + saw_instance.Scale("LOAD", "FACTOR", [1.0], "SYSTEM") + saw_instance.Scale("GEN", "FACTOR", [1.0], "SYSTEM") + saw_instance.Scale("LOAD", "MW", [100.0, 50.0], "SYSTEM") + + @pytest.mark.order(30160) + def test_write_text_to_file(self, saw_instance, temp_file): + """WriteTextToFile creates a file with content.""" + tmp_txt = temp_file(".txt") + saw_instance.WriteTextToFile(tmp_txt, "Test content") + assert os.path.exists(tmp_txt) + + @pytest.mark.order(90400) + def test_case_load_ems(self, saw_instance, temp_file): + tmp = temp_file(".hdb") + with pytest.raises(PowerWorldError): + saw_instance.LoadEMS(tmp) + + @pytest.mark.order(99900) + def test_renumber(self, saw_instance): + """Renumber operations including custom index (run last as they modify keys).""" + saw_instance.RenumberAreas() + saw_instance.RenumberBuses() + saw_instance.RenumberSubs() + saw_instance.RenumberZones() + saw_instance.RenumberCase() + saw_instance.RenumberAreas(custom_integer_index=1) + saw_instance.RenumberBuses(custom_integer_index=2) + saw_instance.RenumberSubs(custom_integer_index=3) + saw_instance.RenumberZones(custom_integer_index=4) + + +if __name__ == "__main__": + sys.exit(pytest.main(["-v", __file__])) diff --git a/tests/test_integration_saw_operations.py b/tests/test_integration_saw_operations.py new file mode 100644 index 00000000..972bfee2 --- /dev/null +++ b/tests/test_integration_saw_operations.py @@ -0,0 +1,659 @@ +""" +Integration tests for ATC, OPF, PV/QV, Time Step, Weather, and Scheduled Actions via SAW. + +These are **integration tests** that require a live connection to PowerWorld +Simulator via the SimAuto COM interface. They test Available Transfer Capability, +Optimal Power Flow, PV/QV curve analysis, Time Step simulation, Weather models, +and Scheduled Action operations. + +REQUIREMENTS: + - PowerWorld Simulator installed with SimAuto COM registered + - A valid PowerWorld case file path set in ``tests/config_test.py`` + (variable ``SAW_TEST_CASE``) or via the ``SAW_TEST_CASE`` env variable + +RELATED TEST FILES: + - test_integration_saw_core.py -- base SAW operations, logging, I/O + - test_integration_saw_modify.py -- destructive modify, region, case actions + - test_integration_saw_powerflow.py -- power flow, matrices, sensitivity, topology + - test_integration_saw_contingency.py -- contingency and fault analysis + - test_integration_saw_gic.py -- GIC analysis + - test_integration_saw_transient.py -- transient stability + - test_integration_workbench.py -- PowerWorld facade and statics + - test_integration_network.py -- Network topology + +USAGE: + pytest tests/test_integration_saw_operations.py -v +""" + +import os +import pytest +import pandas as pd +import numpy as np + +from conftest import ensure_areas + +pytestmark = [ + pytest.mark.integration, + pytest.mark.requires_case, +] + +try: + from esapp.saw import SAW, PowerWorldError, PowerWorldPrerequisiteError, create_object_string +except ImportError: + raise + + +@pytest.fixture(scope="module") +def saw_instance(saw_session): + """Provides the session-scoped SAW instance to the tests in this module.""" + return saw_session + + +# ========================================================================= +# ATC (Available Transfer Capability) +# ========================================================================= + +class TestATC: + """ATC analysis via SAW commands.""" + + @pytest.mark.order(3950) + def test_atc_ensure_two_areas(self, saw_instance): + """Ensure the case has at least 2 areas for ATC testing.""" + areas = ensure_areas(saw_instance, min_count=2) + assert areas is not None and len(areas) >= 2, "Failed to create second area" + + @pytest.mark.order(4010) + def test_atc_determine_for_and_scenarios(self, saw_instance): + """Test ATCDetermineATCFor, increase transfer, and take me to scenario.""" + areas = ensure_areas(saw_instance, min_count=2) + seller = create_object_string("Area", areas.iloc[0]["AreaNum"]) + buyer = create_object_string("Area", areas.iloc[1]["AreaNum"]) + + gens = saw_instance.GetParametersMultipleElement( + "Gen", ["BusNum", "GenID", "GenMW", "GenMWMax", "AreaNum"] + ) + for area_row in areas.itertuples(): + area_num = str(area_row.AreaNum).strip() + area_gens = gens[gens["AreaNum"].astype(str).str.strip() == area_num] + if area_gens.empty: + continue + for _, g in area_gens.head(3).iterrows(): + mw = float(g["GenMW"]) if g["GenMW"] not in (None, "") else 0 + dispatch_mw = max(mw, 10) + saw_instance.SetData( + "Gen", + ["BusNum", "GenID", "GenMW", "GenMWMax", "GenMWMin", + "GenAGCAble", "GenParFac", "GenStatus"], + [str(g["BusNum"]).strip(), str(g["GenID"]).strip(), + str(dispatch_mw), str(dispatch_mw + 500), "0", + "YES", "1.0", "Closed"], + ) + saw_instance.SolvePowerFlow() + + saw_instance.ATCSetAsReference() + saw_instance.ATCDetermine(seller, buyer) + + saw_instance.ATCDetermineATCFor(0, 0, 0) + saw_instance.ATCDetermineATCFor(0, 0, 0, apply_transfer=True) + saw_instance.ATCIncreaseTransferBy(0.0) + saw_instance.ATCTakeMeToScenario(0, 0, 0) + + @pytest.mark.order(4020) + def test_atc_determine_and_results(self, saw_instance): + """Test ATC determination and results retrieval.""" + areas = saw_instance.GetParametersMultipleElement("Area", ["AreaNum"]) + seller = create_object_string("Area", areas.iloc[0]["AreaNum"]) + buyer = create_object_string("Area", areas.iloc[1]["AreaNum"]) + + saw_instance.ATCDetermine(seller, buyer) + + saw_instance._object_fields["transferlimiter"] = pd.DataFrame({ + "internal_field_name": ["LimitingContingency", "MaxFlow"], + "field_data_type": ["String", "Real"], + "key_field": ["", ""], + "description": ["", ""], + "display_name": ["", ""] + }).sort_values(by="internal_field_name") + saw_instance.GetATCResults(["MaxFlow", "LimitingContingency"]) + + @pytest.mark.order(4025) + def test_atc_create_contingent_interfaces(self, saw_instance): + saw_instance.ATCCreateContingentInterfaces() + with pytest.raises((PowerWorldPrerequisiteError, PowerWorldError)): + saw_instance.ATCCreateContingentInterfaces(filter_name="NonExistentFilter") + + @pytest.mark.order(4030) + def test_atc_multiple_directions(self, saw_instance): + """Test ATC multiple directions.""" + saw_instance.DirectionsAutoInsert("AREA", "AREA") + saw_instance.ATCDetermineMultipleDirections() + + @pytest.mark.order(4040) + def test_atc_data_write_options(self, saw_instance, temp_file): + tmp_aux = temp_file(".aux") + saw_instance.ATCDataWriteOptionsAndResults(tmp_aux, append=False, key_field="PRIMARY") + + @pytest.mark.order(4041) + def test_atc_write_all_options_deprecated(self, saw_instance, temp_file): + tmp_aux = temp_file(".aux") + saw_instance.ATCWriteAllOptions(tmp_aux, append=True, key_field="PRIMARY") + + @pytest.mark.order(4042) + def test_atc_write_results_and_options(self, saw_instance, temp_file): + tmp_aux = temp_file(".aux") + saw_instance.ATCWriteResultsAndOptions(tmp_aux, append=False) + + @pytest.mark.order(4043) + def test_atc_write_scenario_log(self, saw_instance, temp_file): + tmp_txt = temp_file(".txt") + saw_instance.ATCWriteScenarioLog(tmp_txt, append=False) + + @pytest.mark.order(4044) + def test_atc_write_scenario_log_with_filter(self, saw_instance, temp_file): + tmp_txt = temp_file(".txt") + saw_instance.ATCWriteScenarioLog(tmp_txt, append=True, filter_name="ALL") + + @pytest.mark.order(4045) + def test_atc_write_scenario_minmax(self, saw_instance, temp_file): + tmp_csv = temp_file(".csv") + saw_instance.ATCWriteScenarioMinMax(tmp_csv, filetype="CSV", operation="MIN") + + @pytest.mark.order(4046) + def test_atc_write_scenario_minmax_with_fields(self, saw_instance, temp_file): + tmp_csv = temp_file(".csv") + saw_instance.ATCWriteScenarioMinMax( + tmp_csv, filetype="CSV", append=True, + fieldlist=["TransferLimit", "Contingency"], + operation="MAX", operation_field="TransferLimit", + group_scenario="NONE", + ) + + @pytest.mark.order(4047) + def test_atc_write_to_text(self, saw_instance, temp_file): + tmp_txt = temp_file(".txt") + saw_instance.ATCWriteToText(tmp_txt, filetype="TAB") + + @pytest.mark.order(4048) + def test_atc_write_to_text_csv_fields(self, saw_instance, temp_file): + tmp_csv = temp_file(".csv") + saw_instance.ATCWriteToText(tmp_csv, filetype="CSV", fieldlist=["MaxFlow"]) + + @pytest.mark.order(4049) + def test_atc_delete_scenario_change(self, saw_instance): + saw_instance.ATCDeleteScenarioChangeIndexRange("RL", ["0"]) + + @pytest.mark.order(4050) + def test_atc_get_results_default_fields(self, saw_instance): + saw_instance._object_fields["transferlimiter"] = pd.DataFrame({ + "internal_field_name": ["LimitingContingency", "MaxFlow", "LimitingElement", + "TransferLimit", "LimitUsed", "PTDF", "OTDF"], + "field_data_type": ["String", "Real", "String", "Real", "String", "Real", "Real"], + "key_field": ["", "", "", "", "", "", ""], + "description": ["", "", "", "", "", "", ""], + "display_name": ["", "", "", "", "", "", ""] + }).sort_values(by="internal_field_name") + saw_instance.GetATCResults() + + @pytest.mark.order(4090) + def test_atc_reference_and_state(self, saw_instance): + """Test ATC set reference, restore initial, and delete results.""" + saw_instance.ATCSetAsReference() + saw_instance.ATCRestoreInitialState() + saw_instance.ATCDeleteAllResults() + + +# ========================================================================= +# OPF +# ========================================================================= + +class TestOPF: + """Tests for OPF solver operations.""" + + @pytest.mark.order(60000) + def test_opf_initialize_primal_lp(self, saw_instance): + saw_instance.InitializePrimalLP() + + @pytest.mark.order(60100) + def test_opf_solve_primal_lp(self, saw_instance): + saw_instance.SolvePrimalLP() + + @pytest.mark.order(60200) + def test_opf_solve_primal_lp_with_aux(self, saw_instance, temp_file): + tmp_aux = temp_file(".aux") + saw_instance.SolvePrimalLP( + on_success_aux=tmp_aux, create_if_not_found1=True + ) + + @pytest.mark.order(60300) + def test_opf_solve_single_outer_loop(self, saw_instance): + saw_instance.SolveSinglePrimalLPOuterLoop() + + @pytest.mark.order(60400) + def test_opf_solve_full_scopf(self, saw_instance): + saw_instance.SolveFullSCOPF(bc_method="OPF") + + @pytest.mark.order(60500) + def test_opf_solve_full_scopf_powerflow(self, saw_instance): + saw_instance.SolveFullSCOPF(bc_method="POWERFLOW") + + @pytest.mark.order(60600) + def test_opf_write_results(self, saw_instance, temp_file): + tmp_aux = temp_file(".aux") + saw_instance.OPFWriteResultsAndOptions(tmp_aux) + assert os.path.exists(tmp_aux) + + +# ========================================================================= +# TimeStep +# ========================================================================= + +class TestTimeStep: + """Time Step Simulation operations via SAW.""" + + @pytest.mark.order(8900) + def test_timestep_run(self, saw_instance): + saw_instance.TimeStepDoRun() + + @pytest.mark.order(8910) + def test_timestep_clear_results(self, saw_instance): + try: + saw_instance.TimeStepClearResults() + except PowerWorldPrerequisiteError: + pass + + @pytest.mark.order(8920) + def test_timestep_reset_run(self, saw_instance): + saw_instance.TimeStepResetRun() + + @pytest.mark.order(9100) + def test_timestep_save(self, saw_instance, temp_file): + tmp_pww = temp_file(".pww") + saw_instance.TimeStepSavePWW(tmp_pww) + + @pytest.mark.order(9110) + def test_timestep_save_results_csv(self, saw_instance, temp_file): + tmp_csv = temp_file(".csv") + try: + saw_instance.TimeStepSaveResultsByTypeCSV("Gen", tmp_csv) + except PowerWorldError: + pass + + @pytest.mark.order(9200) + def test_timestep_delete(self, saw_instance): + saw_instance.TimeStepDeleteAll() + + @pytest.mark.order(9210) + def test_timestep_fields(self, saw_instance): + saw_instance.TimeStepSaveFieldsSet("Gen", ["GenMW"]) + saw_instance.TimeStepSaveFieldsClear(["Gen"]) + + @pytest.mark.order(76200) + def test_timestep_append_pww(self, saw_instance, temp_file): + """TimeStepAppendPWW with a file path.""" + tmp = temp_file(".pww") + with pytest.raises((PowerWorldError, PowerWorldPrerequisiteError)): + saw_instance.TimeStepAppendPWW(tmp, solution_type="Single Solution") + + @pytest.mark.order(76300) + def test_timestep_append_pww_range(self, saw_instance, temp_file): + """TimeStepAppendPWWRange with time range.""" + tmp = temp_file(".pww") + with pytest.raises((PowerWorldError, PowerWorldPrerequisiteError)): + saw_instance.TimeStepAppendPWWRange( + tmp, "2025-01-01T00:00:00", "2025-01-02T00:00:00", + ) + + @pytest.mark.order(76400) + def test_timestep_append_pww_range_latlon(self, saw_instance, temp_file): + """TimeStepAppendPWWRangeLatLon with geographic filter.""" + tmp = temp_file(".pww") + with pytest.raises((PowerWorldError, PowerWorldPrerequisiteError)): + saw_instance.TimeStepAppendPWWRangeLatLon( + tmp, "2025-01-01T00:00:00", "2025-01-02T00:00:00", + 30.0, 50.0, -100.0, -80.0, + ) + + @pytest.mark.order(76500) + def test_timestep_load_b3d(self, saw_instance, temp_file): + """TimeStepLoadB3D with a file path.""" + tmp = temp_file(".b3d") + with pytest.raises((PowerWorldError, PowerWorldPrerequisiteError)): + saw_instance.TimeStepLoadB3D(tmp) + + @pytest.mark.order(76600) + def test_timestep_load_pww(self, saw_instance, temp_file): + """TimeStepLoadPWW with a file path.""" + tmp = temp_file(".pww") + with pytest.raises((PowerWorldError, PowerWorldPrerequisiteError)): + saw_instance.TimeStepLoadPWW(tmp, solution_type="Single Solution") + + @pytest.mark.order(76700) + def test_timestep_load_pww_range(self, saw_instance, temp_file): + """TimeStepLoadPWWRange with time range.""" + tmp = temp_file(".pww") + with pytest.raises((PowerWorldError, PowerWorldPrerequisiteError)): + saw_instance.TimeStepLoadPWWRange( + tmp, "2025-01-01T00:00:00", "2025-01-02T00:00:00", + ) + + @pytest.mark.order(76800) + def test_timestep_load_pww_range_latlon(self, saw_instance, temp_file): + """TimeStepLoadPWWRangeLatLon with geographic filter.""" + tmp = temp_file(".pww") + with pytest.raises((PowerWorldError, PowerWorldPrerequisiteError)): + saw_instance.TimeStepLoadPWWRangeLatLon( + tmp, "2025-01-01T00:00:00", "2025-01-02T00:00:00", + 30.0, 50.0, -100.0, -80.0, + ) + + @pytest.mark.order(76900) + def test_timestep_save_pww_range(self, saw_instance, temp_file): + """TimeStepSavePWWRange with time range.""" + tmp = temp_file(".pww") + saw_instance.TimeStepSavePWWRange( + tmp, "2025-01-01T00:00:00", "2025-01-02T00:00:00", + ) + + @pytest.mark.order(77000) + def test_timestep_save_selected_modify(self, saw_instance): + """TIMESTEPSaveSelectedModifyStart/Finish cycle.""" + try: + saw_instance.TIMESTEPSaveSelectedModifyStart() + saw_instance.TIMESTEPSaveSelectedModifyFinish() + except PowerWorldError: + pass + + @pytest.mark.order(77100) + def test_timestep_save_input_csv(self, saw_instance, temp_file): + """TIMESTEPSaveInputCSV writes to file.""" + tmp = temp_file(".csv") + saw_instance.TIMESTEPSaveInputCSV(tmp, ["BusNum", "BusPUVolt"]) + + @pytest.mark.order(77200) + def test_timestep_load_tsb(self, saw_instance, temp_file): + """TimeStepLoadTSB with a file path.""" + tmp = temp_file(".tsb") + with pytest.raises((PowerWorldError, PowerWorldPrerequisiteError)): + saw_instance.TimeStepLoadTSB(tmp) + + @pytest.mark.order(77300) + def test_timestep_save_tsb(self, saw_instance, temp_file): + """TimeStepSaveTSB writes to file.""" + tmp = temp_file(".tsb") + saw_instance.TimeStepSaveTSB(tmp) + + +# ========================================================================= +# PV/QV +# ========================================================================= + +class TestPVQV: + """PV and QV curve analysis via SAW.""" + + @pytest.mark.order(9300) + def test_pv_qv_run(self, saw_instance): + df = saw_instance.QVRun() + assert df is not None + + @pytest.mark.order(9450) + def test_pv_export(self, saw_instance, temp_file): + tmp_aux = temp_file(".aux") + saw_instance.PVWriteResultsAndOptions(tmp_aux) + assert os.path.exists(tmp_aux) + + @pytest.mark.order(9600) + def test_qv_clear(self, saw_instance): + saw_instance.QVDeleteAllResults() + + @pytest.mark.order(9700) + def test_qv_export(self, saw_instance, temp_file): + tmp_aux = temp_file(".aux") + saw_instance.QVWriteResultsAndOptions(tmp_aux) + assert os.path.exists(tmp_aux) + + @pytest.mark.order(73000) + def test_pv_clear(self, saw_instance): + """PVClear completes without error.""" + saw_instance.PVClear() + + @pytest.mark.order(73100) + def test_pv_destroy(self, saw_instance): + """PVDestroy completes without error.""" + saw_instance.PVDestroy() + + @pytest.mark.order(73200) + def test_pv_set_source_and_sink(self, saw_instance): + """PVSetSourceAndSink with injection group strings.""" + saw_instance.InjectionGroupCreate("PVTestSrc", "Gen", 1.0, "") + saw_instance.InjectionGroupCreate("PVTestSink", "Load", 1.0, "") + saw_instance.PVSetSourceAndSink( + '[INJECTIONGROUP "PVTestSrc"]', + '[INJECTIONGROUP "PVTestSink"]', + ) + + @pytest.mark.order(73300) + def test_pv_start_over(self, saw_instance): + """PVStartOver completes without error.""" + saw_instance.PVStartOver() + + @pytest.mark.order(73400) + def test_pv_run(self, saw_instance): + """PVRun with injection groups.""" + saw_instance.InjectionGroupCreate("PVRunSrc", "Gen", 1.0, "") + saw_instance.InjectionGroupCreate("PVRunSink", "Load", 1.0, "") + saw_instance.PVRun( + '[INJECTIONGROUP "PVRunSrc"]', + '[INJECTIONGROUP "PVRunSink"]', + ) + + @pytest.mark.order(73500) + def test_pv_data_write_options(self, saw_instance, temp_file): + """PVDataWriteOptionsAndResults writes to file.""" + tmp = temp_file(".aux") + saw_instance.PVDataWriteOptionsAndResults(tmp, append=False, key_field="PRIMARY") + + @pytest.mark.order(73600) + def test_pv_write_results_and_options(self, saw_instance, temp_file): + """PVWriteResultsAndOptions writes to file.""" + tmp = temp_file(".aux") + saw_instance.PVWriteResultsAndOptions(tmp, append=False) + + @pytest.mark.order(73700) + def test_pv_write_inadequate_voltages(self, saw_instance, temp_file): + """PVWriteInadequateVoltages writes to file.""" + tmp = temp_file(".csv") + saw_instance.PVWriteInadequateVoltages(tmp, append=False, inadequate_type="BOTH") + + @pytest.mark.order(73800) + def test_pv_qv_track_single_bus(self, saw_instance): + """PVQVTrackSingleBusPerSuperBus completes without error.""" + saw_instance.PVQVTrackSingleBusPerSuperBus() + + @pytest.mark.order(73900) + def test_refine_model(self, saw_instance): + """RefineModel completes without error.""" + saw_instance.RefineModel("Area", "", "SHUNTS", 0.0) + + @pytest.mark.order(74000) + def test_refine_model_with_filter(self, saw_instance): + """RefineModel with a different action.""" + saw_instance.RefineModel("Zone", "", "OFFAVR", 0.001) + + @pytest.mark.order(74100) + def test_qv_data_write_options(self, saw_instance, temp_file): + """QVDataWriteOptionsAndResults writes to file.""" + tmp = temp_file(".aux") + saw_instance.QVDataWriteOptionsAndResults(tmp, append=False, key_field="PRIMARY") + + @pytest.mark.order(74200) + def test_qv_run_with_filename(self, saw_instance, temp_file): + """QVRun with explicit filename returns None.""" + tmp = temp_file(".csv") + result = saw_instance.QVRun(filename=tmp) + assert result is None + + @pytest.mark.order(74300) + def test_qv_select_single_bus(self, saw_instance): + """QVSelectSingleBusPerSuperBus completes without error.""" + saw_instance.QVSelectSingleBusPerSuperBus() + + @pytest.mark.order(74400) + def test_qv_write_curves(self, saw_instance, temp_file): + """QVWriteCurves writes to file.""" + tmp = temp_file(".csv") + saw_instance.QVWriteCurves(tmp, include_quantities=True, filter_name="", append=False) + + @pytest.mark.order(74500) + def test_qv_write_results_and_options(self, saw_instance, temp_file): + """QVWriteResultsAndOptions writes to file.""" + tmp = temp_file(".aux") + saw_instance.QVWriteResultsAndOptions(tmp, append=False) + + @pytest.mark.order(74600) + def test_qv_delete_all_results(self, saw_instance): + """QVDeleteAllResults completes without error.""" + saw_instance.QVDeleteAllResults() + + +# ========================================================================= +# Scheduled Actions +# ========================================================================= + +class TestScheduledActions: + """Tests for Scheduled Actions mixin.""" + + @pytest.mark.order(50000) + def test_scheduled_set_reference(self, saw_instance): + saw_instance.ScheduledActionsSetReference() + + @pytest.mark.order(50100) + def test_scheduled_apply_at(self, saw_instance): + """ApplyScheduledActionsAt with various parameter combinations.""" + saw_instance.ApplyScheduledActionsAt("01/01/2025 10:00") + saw_instance.ApplyScheduledActionsAt( + "01/01/2025 10:00", end_time="01/01/2025 12:00" + ) + saw_instance.ApplyScheduledActionsAt( + "01/01/2025 10:00", filter_name="ALL" + ) + saw_instance.ApplyScheduledActionsAt( + "01/01/2025 10:00", revert=True + ) + + @pytest.mark.order(50500) + def test_scheduled_revert_at(self, saw_instance): + """RevertScheduledActionsAt with and without filter.""" + saw_instance.RevertScheduledActionsAt("01/01/2025 10:00") + saw_instance.RevertScheduledActionsAt( + "01/01/2025 10:00", filter_name="ALL" + ) + + @pytest.mark.order(50700) + def test_scheduled_identify_breakers(self, saw_instance): + """IdentifyBreakersForScheduledActions with both boolean values.""" + saw_instance.IdentifyBreakersForScheduledActions(identify_from_normal=True) + saw_instance.IdentifyBreakersForScheduledActions(identify_from_normal=False) + + @pytest.mark.order(50900) + def test_scheduled_set_view(self, saw_instance): + """SetScheduleView with and without options.""" + saw_instance.SetScheduleView("01/01/2025 10:00") + saw_instance.SetScheduleView( + "01/01/2025 10:00", + apply_actions=True, + use_normal_status=False, + apply_window=True, + ) + + @pytest.mark.order(51100) + def test_scheduled_set_window(self, saw_instance): + """SetScheduleWindow with different resolutions.""" + saw_instance.SetScheduleWindow( + "01/01/2025 00:00", "02/01/2025 00:00", + resolution=1.0, resolution_units="HOURS", + ) + saw_instance.SetScheduleWindow( + "01/01/2025 00:00", + "02/01/2025 00:00", + resolution=0.5, + resolution_units="HOURS", + ) + + +# ========================================================================= +# Weather +# ========================================================================= + +class TestWeather: + """Tests for Weather mixin.""" + + @pytest.mark.order(52010) + def test_weather_limits_gen_update(self, saw_instance): + """WeatherLimitsGenUpdate with both true and false params.""" + saw_instance.WeatherLimitsGenUpdate(update_max=True, update_min=True) + saw_instance.WeatherLimitsGenUpdate(update_max=False, update_min=False) + + @pytest.mark.order(52200) + def test_weather_temperature_limits_branch(self, saw_instance): + saw_instance.TemperatureLimitsBranchUpdate() + + @pytest.mark.order(52300) + def test_weather_temperature_limits_branch_custom(self, saw_instance): + saw_instance.TemperatureLimitsBranchUpdate( + rating_set_precedence="CTG", + normal_rating_set="A", + ctg_rating_set="B", + ) + + @pytest.mark.order(52400) + def test_weather_pfw_set_inputs(self, saw_instance): + saw_instance.WeatherPFWModelsSetInputs() + + @pytest.mark.order(52500) + def test_weather_pfw_set_inputs_and_apply(self, saw_instance): + """WeatherPFWModelsSetInputsAndApply with and without solve.""" + saw_instance.WeatherPFWModelsSetInputsAndApply(solve_pf=True) + saw_instance.WeatherPFWModelsSetInputsAndApply(solve_pf=False) + + @pytest.mark.order(52700) + def test_weather_pfw_restore_design(self, saw_instance): + saw_instance.WeatherPFWModelsRestoreDesignValues() + + @pytest.mark.order(52800) + def test_weather_pww_load_datetime(self, saw_instance): + try: + saw_instance.WeatherPWWLoadForDateTimeUTC("2025-01-01T10:00:00") + except PowerWorldPrerequisiteError: + pass + + @pytest.mark.order(52900) + def test_weather_pww_set_directory(self, saw_instance, temp_dir): + """WeatherPWWSetDirectory with and without subdirs.""" + saw_instance.WeatherPWWSetDirectory(str(temp_dir), include_subdirs=True) + saw_instance.WeatherPWWSetDirectory(str(temp_dir), include_subdirs=False) + + @pytest.mark.order(53100) + def test_weather_pww_file_all_meas_valid(self, saw_instance, temp_file): + tmp = temp_file(".pww") + with pytest.raises((PowerWorldError, PowerWorldPrerequisiteError)): + saw_instance.WeatherPWWFileAllMeasValid(tmp, ["Temperature"]) + + @pytest.mark.order(53200) + def test_weather_pww_file_combine(self, saw_instance, temp_file): + src1 = temp_file(".pww") + src2 = temp_file(".pww") + dst = temp_file(".pww") + with pytest.raises((PowerWorldError, PowerWorldPrerequisiteError)): + saw_instance.WeatherPWWFileCombine2(src1, src2, dst) + + @pytest.mark.order(53300) + def test_weather_pww_file_geo_reduce(self, saw_instance, temp_file): + src = temp_file(".pww") + dst = temp_file(".pww") + with pytest.raises((PowerWorldError, PowerWorldPrerequisiteError)): + saw_instance.WeatherPWWFileGeoReduce(src, dst, 30.0, 50.0, -100.0, -80.0) + + +if __name__ == "__main__": + import sys + sys.exit(pytest.main(["-v", __file__])) diff --git a/tests/test_integration_saw_powerflow.py b/tests/test_integration_saw_powerflow.py new file mode 100644 index 00000000..91ca1911 --- /dev/null +++ b/tests/test_integration_saw_powerflow.py @@ -0,0 +1,566 @@ +""" +Integration tests for Power Flow, Matrices, Sensitivity, and Topology via SAW. + +These are **integration tests** that require a live connection to PowerWorld +Simulator via the SimAuto COM interface. They test power flow solution, +matrix extraction (Y-bus, Jacobian, incidence), sensitivity calculations +(PTDF, LODF, shift factors), topology analysis, and diff-case operations. + +REQUIREMENTS: + - PowerWorld Simulator installed with SimAuto COM registered + - A valid PowerWorld case file path set in ``tests/config_test.py`` + (variable ``SAW_TEST_CASE``) or via the ``SAW_TEST_CASE`` env variable + +RELATED TEST FILES: + - test_integration_saw_core.py -- base SAW operations, logging, I/O + - test_integration_saw_modify.py -- destructive modify, region, case actions + - test_integration_saw_contingency.py -- contingency and fault analysis + - test_integration_saw_gic.py -- GIC analysis + - test_integration_saw_transient.py -- transient stability + - test_integration_saw_operations.py -- ATC, OPF, PV/QV, time step, weather, scheduled + - test_integration_workbench.py -- PowerWorld facade and statics + - test_integration_network.py -- Network topology + +USAGE: + pytest tests/test_integration_saw_powerflow.py -v +""" + +import os +import pytest +import pandas as pd +import numpy as np + +pytestmark = [ + pytest.mark.integration, + pytest.mark.requires_case, +] + +try: + from esapp.saw import SAW, PowerWorldError, PowerWorldPrerequisiteError, create_object_string +except ImportError: + raise + +from conftest import ensure_areas + + +@pytest.fixture(scope="module") +def saw_instance(saw_session): + """Provides the session-scoped SAW instance to the tests in this module.""" + return saw_session + + +class TestPowerFlow: + """Tests for power flow solution and related operations.""" + + @pytest.mark.order(1000) + def test_powerflow_solve(self, saw_instance): + saw_instance.SolvePowerFlow() + + @pytest.mark.order(1200) + def test_powerflow_clear_solution_aid(self, saw_instance): + saw_instance.ClearPowerFlowSolutionAidValues() + + @pytest.mark.order(1300) + def test_powerflow_options(self, saw_instance): + saw_instance.SetMVATolerance(0.1) + saw_instance.SetDoOneIteration(False) + saw_instance.SetInnerLoopCheckMVars(False) + + @pytest.mark.order(1500) + def test_powerflow_min_pu_volt(self, saw_instance): + v = saw_instance.GetMinPUVoltage() + assert isinstance(v, float) + + @pytest.mark.order(1700) + def test_powerflow_update_islands(self, saw_instance): + saw_instance.UpdateIslandsAndBusStatus() + + @pytest.mark.order(1800) + def test_powerflow_zero_mismatches(self, saw_instance): + saw_instance.ZeroOutMismatches() + + @pytest.mark.order(1900) + def test_powerflow_estimate_voltages(self, saw_instance): + saw_instance.SelectAll("Bus") + saw_instance.EstimateVoltages("SELECTED") + + @pytest.mark.order(2000) + def test_powerflow_gen_force_ldc(self, saw_instance): + saw_instance.GenForceLDC_RCC() + + @pytest.mark.order(2100) + def test_powerflow_save_gen_limit(self, saw_instance, temp_file): + tmp_txt = temp_file(".txt") + saw_instance.SaveGenLimitStatusAction(tmp_txt) + assert os.path.exists(tmp_txt) + + @pytest.mark.order(2200) + def test_powerflow_diff_case(self, saw_instance): + saw_instance.DiffCaseSetAsBase() + saw_instance.DiffCaseMode("DIFFERENCE") + saw_instance.DiffCaseRefresh() + saw_instance.DiffCaseClearBase() + + @pytest.mark.order(2300) + def test_powerflow_voltage_conditioning(self, saw_instance): + saw_instance.VoltageConditioning() + + @pytest.mark.order(2400) + def test_powerflow_flat_start(self, saw_instance): + saw_instance.ResetToFlatStart() + saw_instance.SolvePowerFlow() + + @pytest.mark.order(2500) + def test_powerflow_diff_write(self, saw_instance, temp_file): + tmp_aux = temp_file(".aux") + tmp_epc = temp_file(".epc") + saw_instance.DiffCaseWriteCompleteModel(tmp_aux) + saw_instance.DiffCaseWriteBothEPC(tmp_epc, ge_file_type="GE21") + saw_instance.DiffCaseWriteNewEPC(tmp_epc, ge_file_type="GE21") + + @pytest.mark.order(2600) + def test_powerflow_solve_dc(self, saw_instance): + """Test DC power flow solution.""" + saw_instance.SolvePowerFlow("DC") + saw_instance.SolvePowerFlow() + + @pytest.mark.order(2700) + def test_powerflow_agc(self, saw_instance): + """Test AGC-related generator participation factors.""" + areas = ensure_areas(saw_instance, 1) + area_str = create_object_string("Area", areas.iloc[0]["AreaNum"]) + saw_instance.SetParticipationFactors("CONSTANT", 1.0, area_str) + + @pytest.mark.order(71000) + def test_powerflow_solve_with_method(self, saw_instance): + """Test SolvePowerFlow with explicit method parameter.""" + saw_instance.SolvePowerFlow("RECTNEWT") + saw_instance.SolvePowerFlow() + + @pytest.mark.order(71100) + def test_powerflow_condition_voltage_pockets(self, saw_instance): + """Test VoltageConditioning.""" + saw_instance.VoltageConditioning() + + @pytest.mark.order(71200) + def test_powerflow_diff_write_removed_epc(self, saw_instance, temp_file): + """Test DiffCaseWriteRemovedEPC.""" + tmp_epc = temp_file(".epc") + saw_instance.DiffCaseWriteRemovedEPC(tmp_epc) + + +class TestMatrices: + """Tests for matrix extraction (Ybus, Jacobian, etc.).""" + + @pytest.mark.order(3000) + def test_matrix_ybus(self, saw_instance): + ybus = saw_instance.get_ybus() + assert ybus is not None + + @pytest.mark.order(3100) + def test_matrix_gmatrix(self, saw_instance): + gmat = saw_instance.get_gmatrix() + assert gmat is not None + + @pytest.mark.order(3200) + def test_matrix_jacobian(self, saw_instance): + jac = saw_instance.get_jacobian() + assert jac is not None + + @pytest.mark.order(3300) + def test_matrix_ybus_full_and_sparse(self, saw_instance): + """get_ybus returns full dense or sparse matrix depending on flag.""" + from scipy.sparse import issparse + + sparse_ybus = saw_instance.get_ybus(full=False) + assert issparse(sparse_ybus) + + full_ybus = saw_instance.get_ybus(full=True) + assert not issparse(full_ybus) + assert full_ybus.shape[0] == full_ybus.shape[1] + + @pytest.mark.order(3400) + def test_matrix_gmatrix_full_and_sparse(self, saw_instance): + """get_gmatrix returns both full and sparse modes.""" + from scipy.sparse import issparse + + sparse_g = saw_instance.get_gmatrix(full=False) + assert issparse(sparse_g) + + full_g = saw_instance.get_gmatrix(full=True) + assert not issparse(full_g) + + @pytest.mark.order(3500) + def test_matrix_gmatrix_with_ids(self, saw_instance): + """get_gmatrix_with_ids returns matrix and ID mapping.""" + matrix, ids = saw_instance.get_gmatrix_with_ids(full=True) + assert matrix is not None + assert isinstance(ids, list) + assert len(ids) > 0 + + @pytest.mark.order(3600) + def test_matrix_jacobian_with_ids(self, saw_instance): + """get_jacobian_with_ids returns matrix and ID mapping.""" + matrix, ids = saw_instance.get_jacobian_with_ids(full=True) + assert matrix is not None + assert isinstance(ids, list) + assert len(ids) > 0 + + @pytest.mark.order(3700) + def test_matrix_save_ybus_and_parse(self, saw_instance): + """SaveYbusInMatlabFormat saves and can be parsed back.""" + import tempfile + tmp = tempfile.NamedTemporaryFile(suffix=".m", delete=False) + tmp.close() + try: + saw_instance.SaveYbusInMatlabFormat(tmp.name, include_voltages=False) + assert os.path.exists(tmp.name) + ybus = saw_instance.get_ybus(file=tmp.name, full=True) + assert ybus is not None + assert ybus.shape[0] > 0 + finally: + if os.path.exists(tmp.name): + os.remove(tmp.name) + + +class TestSensitivity: + """Tests for sensitivity calculations (PTDF, LODF, shift factors).""" + + @pytest.mark.order(4000) + def test_sensitivity_volt_sense(self, saw_instance): + buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum"]) + assert buses is not None and not buses.empty, "Test case must contain buses" + bus_num = buses.iloc[0]["BusNum"] + saw_instance.CalculateVoltSense(bus_num) + + @pytest.mark.order(4100) + def test_sensitivity_flow_sense(self, saw_instance): + branches = saw_instance.GetParametersMultipleElement("Branch", ["BusNum", "BusNum:1", "LineCircuit"]) + assert branches is not None and not branches.empty, "Test case must contain branches" + b = branches.iloc[0] + branch_str = create_object_string("Branch", b["BusNum"], b["BusNum:1"], b["LineCircuit"]) + saw_instance.CalculateFlowSense(branch_str, "MW") + + @pytest.mark.order(4200) + def test_sensitivity_ptdf(self, saw_instance): + areas = ensure_areas(saw_instance, 2) + seller = create_object_string("Area", areas.iloc[0]["AreaNum"]) + buyer = create_object_string("Area", areas.iloc[1]["AreaNum"]) + saw_instance.CalculatePTDF(seller, buyer) + saw_instance.CalculateVoltToTransferSense(seller, buyer) + + @pytest.mark.order(4300) + def test_sensitivity_lodf(self, saw_instance): + branches = saw_instance.GetParametersMultipleElement("Branch", ["BusNum", "BusNum:1", "LineCircuit"]) + assert branches is not None and not branches.empty, "Test case must contain branches" + b = branches.iloc[0] + branch_str = create_object_string("Branch", b["BusNum"], b["BusNum:1"], b["LineCircuit"]) + saw_instance.CalculateLODF(branch_str) + + @pytest.mark.order(4400) + def test_sensitivity_shift_factors(self, saw_instance): + branches = saw_instance.GetParametersMultipleElement("Branch", ["BusNum", "BusNum:1", "LineCircuit", "LineStatus"]) + assert branches is not None and not branches.empty, "Test case must contain branches" + areas = ensure_areas(saw_instance, 1) + closed_branches = branches[branches["LineStatus"] == "Closed"] + if closed_branches.empty: + pytest.skip("No closed branches found for shift factors") + b = closed_branches.iloc[0] + branch_str = create_object_string("Branch", b["BusNum"], b["BusNum:1"], b["LineCircuit"]) + area_str = create_object_string("Area", areas.iloc[0]["AreaNum"]) + saw_instance.SetParticipationFactors("CONSTANT", 1.0, area_str) + saw_instance.CalculateShiftFactors(branch_str, "SELLER", area_str) + + @pytest.mark.order(4500) + def test_sensitivity_lodf_matrix(self, saw_instance): + saw_instance.CalculateLODFMatrix("OUTAGES", "ALL", "ALL") + + @pytest.mark.order(3601) + def test_sensitivity_lodf_with_params(self, saw_instance, temp_file): + """Test CalculateLODFAdvanced with full parameters.""" + tmp_csv = temp_file(".csv") + saw_instance.CalculateLODFAdvanced( + include_phase_shifters=False, + file_type="CSV", + max_columns=100, + min_lodf=0.01, + number_format="DECIMAL", + decimal_points=4, + only_increasing=False, + filename=tmp_csv + ) + + @pytest.mark.order(3701) + def test_sensitivity_lodf_screening(self, saw_instance): + """Test CalculateLODFScreening for screening mode.""" + saw_instance.CalculateLODFScreening( + filter_process="ALL", + filter_monitor="ALL", + include_phase_shifters=False, + include_open_lines=False, + use_lodf_threshold=True, + lodf_threshold=0.05, + use_overload_threshold=False, + overload_low=100.0, + overload_high=200.0, + do_save_file=False, + file_location="" + ) + + @pytest.mark.order(3800) + def test_sensitivity_shift_factors_multiple(self, saw_instance): + """Test CalculateShiftFactorsMultipleElement for multiple branches.""" + areas = ensure_areas(saw_instance, 1) + area_str = create_object_string("Area", areas.iloc[0]["AreaNum"]) + saw_instance.SetParticipationFactors("CONSTANT", 1.0, area_str) + saw_instance.CalculateShiftFactorsMultipleElement("BRANCH", "SELECTED", "SELLER", area_str) + + @pytest.mark.order(3900) + def test_sensitivity_loss_sense(self, saw_instance): + """Test CalculateLossSense for loss sensitivity.""" + saw_instance.CalculateLossSense("AREA", "NO", "EXISTING") + + @pytest.mark.order(4900) + def test_calculate_volt_to_transfer_sense(self, saw_instance): + """CalculateVoltToTransferSense completes without error.""" + areas = ensure_areas(saw_instance, 2) + area1 = str(areas.iloc[0]["AreaNum"]).strip() + area2 = str(areas.iloc[1]["AreaNum"]).strip() + + gens = saw_instance.GetParametersMultipleElement( + "Gen", ["BusNum", "GenID", "AreaNum", "GenAGCAble"] + ) + a1_agc = gens[ + (gens["AreaNum"].astype(str).str.strip() == area1) + & (gens["GenAGCAble"].astype(str).str.strip().str.upper() == "YES") + ] + a2_agc = gens[ + (gens["AreaNum"].astype(str).str.strip() == area2) + & (gens["GenAGCAble"].astype(str).str.strip().str.upper() == "YES") + ] + if a1_agc.empty or a2_agc.empty: + pytest.skip("Case needs AGC generators in both areas for transfer sensitivity") + + s = create_object_string("Area", area1) + b = create_object_string("Area", area2) + saw_instance.CalculateVoltToTransferSense(s, b, transfer_type="P", turn_off_avr=False) + + @pytest.mark.order(4950) + def test_calculate_tap_sense(self, saw_instance): + """CalculateTapSense completes without error.""" + branches = saw_instance.GetParametersMultipleElement( + "Branch", ["BusNum", "BusNum:1", "LineCircuit"] + ) + assert branches is not None and not branches.empty + b = branches.iloc[0] + saw_instance.SetData( + "Branch", + ["BusNum", "BusNum:1", "LineCircuit", "Selected"], + [str(b["BusNum"]).strip(), str(b["BusNum:1"]).strip(), + str(b["LineCircuit"]).strip(), "YES"], + ) + saw_instance.CalculateTapSense(filter_name="SELECTED") + + @pytest.mark.order(4960) + def test_calculate_volt_self_sense(self, saw_instance): + """CalculateVoltSelfSense completes without error.""" + buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum"]) + assert buses is not None and not buses.empty + saw_instance.SetData( + "Bus", ["BusNum", "Selected"], + [str(buses.iloc[0]["BusNum"]).strip(), "YES"], + ) + saw_instance.CalculateVoltSelfSense(filter_name="SELECTED") + + @pytest.mark.order(4970) + def test_calculate_volt_sense_specific(self, saw_instance): + """CalculateVoltSense for a specific bus.""" + buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum"]) + assert buses is not None and not buses.empty, "Test case must contain buses" + saw_instance.CalculateVoltSense(int(buses.iloc[0]["BusNum"])) + + @pytest.mark.order(4980) + def test_set_sensitivities_at_oos_to_closest(self, saw_instance): + """SetSensitivitiesAtOutOfServiceToClosest completes without error.""" + saw_instance.SetSensitivitiesAtOutOfServiceToClosest() + + @pytest.mark.order(4990) + def test_calculate_lodf_with_enum(self, saw_instance): + """CalculateLODF using LinearMethod enum.""" + from esapp.saw._enums import LinearMethod + branches = saw_instance.GetParametersMultipleElement("Branch", ["BusNum", "BusNum:1", "LineCircuit"]) + assert branches is not None and not branches.empty, "Test case must contain branches" + b = branches.iloc[0] + branch_str = create_object_string("Branch", b["BusNum"], b["BusNum:1"], b["LineCircuit"]) + saw_instance.CalculateLODF(branch_str, method=LinearMethod.DC) + + @pytest.mark.order(72000) + def test_sensitivity_lodf_post_closure(self, saw_instance): + """Test CalculateLODF with post_closure_lcdf='YES'.""" + branches = saw_instance.GetParametersMultipleElement("Branch", ["BusNum", "BusNum:1", "LineCircuit"]) + assert branches is not None and not branches.empty, "Test case must contain branches" + b = branches.iloc[0] + branch_str = create_object_string("Branch", b["BusNum"], b["BusNum:1"], b["LineCircuit"]) + saw_instance.CalculateLODF(branch_str, post_closure_lcdf="YES") + + @pytest.mark.order(72100) + def test_sensitivity_ptdf_multiple_directions(self, saw_instance): + """Test CalculatePTDFMultipleDirections.""" + saw_instance.CalculatePTDFMultipleDirections() + + @pytest.mark.order(72200) + def test_sensitivity_line_loading_replicator(self, saw_instance): + """Test LineLoadingReplicatorCalculate.""" + branches = saw_instance.GetParametersMultipleElement("Branch", ["BusNum", "BusNum:1", "LineCircuit"]) + assert branches is not None and not branches.empty, "Test case must contain branches" + b = branches.iloc[0] + branch_str = create_object_string("Branch", b["BusNum"], b["BusNum:1"], b["LineCircuit"]) + saw_instance.InjectionGroupCreate("TestLLR", "Gen", 1.0, "", append=False) + ig_str = '[InjectionGroup "TestLLR"]' + saw_instance.LineLoadingReplicatorCalculate( + branch_str, ig_str, agc_only=False, desired_flow=100.0, implement=False, + ) + + @pytest.mark.order(72310) + def test_sensitivity_line_loading_replicator_implement(self, saw_instance): + """LineLoadingReplicatorImplement completes without error.""" + saw_instance.LineLoadingReplicatorImplement() + + +class TestTopology: + """Tests for topology analysis operations.""" + + @pytest.mark.order(4700) + def test_topology_islands(self, saw_instance): + df = saw_instance.DetermineBranchesThatCreateIslands() + assert df is not None + assert isinstance(df, pd.DataFrame) + + @pytest.mark.order(4800) + def test_topology_shortest_path(self, saw_instance): + buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum"]) + assert buses is not None and len(buses) >= 2, "Test case must contain at least 2 buses" + start = create_object_string("Bus", buses.iloc[0]['BusNum']) + end = create_object_string("Bus", buses.iloc[1]['BusNum']) + df = saw_instance.DetermineShortestPath(start, end) + assert df is not None + + @pytest.mark.order(72350) + def test_topology_path_distance(self, saw_instance): + """Test DeterminePathDistance.""" + buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum"]) + assert buses is not None and not buses.empty, "Test case must contain buses" + bus_key = create_object_string("Bus", buses.iloc[0]["BusNum"]) + saw_instance.DeterminePathDistance(bus_key, BranchDistMeas="X") + + @pytest.mark.order(72400) + def test_topology_set_bus_field_from_closest(self, saw_instance): + """Test SetBusFieldFromClosest with all required args.""" + saw_instance.SetBusFieldFromClosest("BusName", "", "", "ALL", "Z") + + @pytest.mark.order(72500) + def test_topology_save_consolidated_case(self, saw_instance, temp_file): + """Test SaveConsolidatedCase.""" + tmp = temp_file(".pwb") + saw_instance.SaveConsolidatedCase(tmp) + + @pytest.mark.order(75000) + def test_do_facility_analysis(self, saw_instance, temp_file): + """DoFacilityAnalysis with and without set_selected.""" + tmp = temp_file(".aux") + try: + saw_instance.DoFacilityAnalysis(tmp, set_selected=False) + saw_instance.DoFacilityAnalysis(tmp, set_selected=True) + except PowerWorldPrerequisiteError: + pytest.skip("No Facility/External buses configured in test case") + + @pytest.mark.order(75200) + def test_find_radial_bus_paths(self, saw_instance): + """FindRadialBusPaths with and without ignore_status.""" + saw_instance.FindRadialBusPaths( + ignore_status=False, + treat_parallel_as_not_radial=False, + bus_or_superbus="BUS", + ) + saw_instance.FindRadialBusPaths( + ignore_status=True, + treat_parallel_as_not_radial=True, + bus_or_superbus="BUS", + ) + + @pytest.mark.order(75400) + def test_set_selected_from_network_cut(self, saw_instance): + """SetSelectedFromNetworkCut completes without error.""" + buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum"]) + assert buses is not None and not buses.empty, "Test case must contain buses" + branches = saw_instance.GetParametersMultipleElement( + "Branch", ["BusNum", "BusNum:1", "LineCircuit"] + ) + assert branches is not None and not branches.empty, "Test case must contain branches" + b = branches.iloc[0] + saw_instance.SetData( + "Branch", + ["BusNum", "BusNum:1", "LineCircuit", "Selected"], + [str(b["BusNum"]).strip(), str(b["BusNum:1"]).strip(), + str(b["LineCircuit"]).strip(), "YES"], + ) + bus_key = create_object_string("Bus", buses.iloc[0]["BusNum"]) + saw_instance.SetSelectedFromNetworkCut( + set_how=True, + bus_on_cut_side=bus_key, + branch_filter="SELECTED", + energized=True, + num_tiers=0, + initialize_selected=True, + objects_to_select=["Bus", "Branch"], + ) + + @pytest.mark.order(75500) + def test_create_new_areas_from_islands(self, saw_instance): + """CreateNewAreasFromIslands completes without error.""" + saw_instance.CreateNewAreasFromIslands() + + @pytest.mark.order(75600) + def test_expand_all_bus_topology(self, saw_instance): + """ExpandAllBusTopology completes without error.""" + saw_instance.ExpandAllBusTopology() + + @pytest.mark.order(75700) + def test_expand_bus_topology(self, saw_instance): + """ExpandBusTopology for a specific bus.""" + buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum"]) + assert buses is not None and not buses.empty, "Test case must contain buses" + saw_instance.ExpandBusTopology(f"BUS {buses.iloc[0]['BusNum']}", "BREAKERANDAHALF") + + @pytest.mark.order(75800) + def test_close_with_breakers(self, saw_instance): + """CloseWithBreakers with simple and full object string.""" + gens = saw_instance.GetParametersMultipleElement("Gen", ["BusNum", "GenID"]) + assert gens is not None and not gens.empty, "Test case must contain generators" + saw_instance.CloseWithBreakers("GEN", f"[{gens.iloc[0]['BusNum']} {gens.iloc[0]['GenID']}]") + full_str = create_object_string("GEN", gens.iloc[0]["BusNum"], gens.iloc[0]["GenID"]) + saw_instance.CloseWithBreakers( + "GEN", full_str, + only_specified=True, + switching_types=["Breaker", "Load Break Disconnect"], + close_normally_closed=True, + ) + + @pytest.mark.order(76000) + def test_open_with_breakers(self, saw_instance): + """OpenWithBreakers with simple and full object string.""" + branches = saw_instance.GetParametersMultipleElement("Branch", ["BusNum", "BusNum:1", "LineCircuit"]) + assert branches is not None and not branches.empty, "Test case must contain branches" + b = branches.iloc[0] + saw_instance.OpenWithBreakers("BRANCH", f"[{b['BusNum']} {b['BusNum:1']} {b['LineCircuit']}]") + full_str = create_object_string("BRANCH", b["BusNum"], b["BusNum:1"], b["LineCircuit"]) + saw_instance.OpenWithBreakers( + "BRANCH", full_str, + switching_types=["Breaker"], + open_normally_open=True, + ) + + +if __name__ == "__main__": + import sys + sys.exit(pytest.main(["-v", __file__])) diff --git a/tests/test_integration_saw_powerworld.py b/tests/test_integration_saw_powerworld.py deleted file mode 100644 index 0287adae..00000000 --- a/tests/test_integration_saw_powerworld.py +++ /dev/null @@ -1,342 +0,0 @@ -""" -Integration tests for SAW base, general, oneline, modify, regions, and case actions. - -WHAT THIS TESTS: -- Base SAW operations (save, load, properties, state) -- General commands (file ops, modes, scripts) -- Oneline diagram operations -- Modify operations (create/delete objects, merge, split) -- Regions operations -- Case actions (equivalence, renumber, scale) - -NOTE: Power flow, matrices, sensitivity, contingency, fault, GIC, ATC, transient, - and time step tests are in their dedicated test files: - - test_integration_powerflow.py - - test_integration_contingency.py - - test_integration_analysis.py - -DEPENDENCIES: -- PowerWorld Simulator installed and SimAuto registered -- Valid PowerWorld case file configured in tests/config_test.py - -USAGE: - pytest tests/test_integration_saw_powerworld.py -v -""" - -import os -import sys -import pytest -import pandas as pd - -pytestmark = [ - pytest.mark.integration, - pytest.mark.requires_case, -] - -try: - from esapp.saw import SAW, PowerWorldError, PowerWorldPrerequisiteError, PowerWorldAddonError, create_object_string -except ImportError: - raise - - -@pytest.fixture(scope="module") -def saw_instance(saw_session): - """Provides the session-scoped SAW instance to the tests in this module.""" - return saw_session - - -class TestBaseSAW: - """Tests for base SAW operations (order 1-9).""" - - @pytest.mark.order(1) - def test_base_save_case(self, saw_instance, temp_file): - tmp_pwb = temp_file(".pwb") - saw_instance.SaveCase(tmp_pwb) - assert os.path.exists(tmp_pwb) - - @pytest.mark.order(2) - def test_base_get_header(self, saw_instance): - header = saw_instance.GetCaseHeader() - assert header is not None - - @pytest.mark.order(3) - def test_base_change_parameters(self, saw_instance): - buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum", "BusName"]) - if buses is not None and not buses.empty: - bus_num = buses.iloc[0]["BusNum"] - original_name = buses.iloc[0]["BusName"] - new_name = "TestBusName" - saw_instance.ChangeParametersSingleElement("Bus", ["BusNum", "BusName"], [bus_num, new_name]) - - check = saw_instance.GetParametersSingleElement("Bus", ["BusNum", "BusName"], [bus_num, ""]) - assert check["BusName"] == new_name - - saw_instance.ChangeParametersSingleElement("Bus", ["BusNum", "BusName"], [bus_num, original_name]) - - @pytest.mark.order(4) - def test_base_get_parameters(self, saw_instance): - df = saw_instance.GetParametersMultipleElement("Bus", ["BusNum", "BusName"]) - assert df is not None - assert not df.empty - - bus_num = df.iloc[0]["BusNum"] - s = saw_instance.GetParametersSingleElement("Bus", ["BusNum", "BusName"], [bus_num, ""]) - assert isinstance(s, pd.Series) - - @pytest.mark.order(5) - def test_base_list_devices(self, saw_instance): - df = saw_instance.ListOfDevices("Bus") - assert df is not None - assert not df.empty - - @pytest.mark.order(7) - def test_base_state(self, saw_instance): - saw_instance.StoreState("TestState") - saw_instance.RestoreState("TestState") - saw_instance.DeleteState("TestState") - saw_instance.SaveState() - saw_instance.LoadState() - - @pytest.mark.order(8) - def test_base_run_script_2(self, saw_instance): - saw_instance.RunScriptCommand2("LogAdd(\"Test\");", "Testing...") - - @pytest.mark.order(9) - def test_base_field_list(self, saw_instance): - df = saw_instance.GetFieldList("Bus") - assert not df.empty - - df_spec = saw_instance.GetSpecificFieldList("Bus", ["BusNum", "BusName"]) - assert not df_spec.empty - - -class TestGeneralSAW: - """Tests for general SAW operations.""" - - @pytest.mark.order(95) - def test_general_log(self, saw_instance, temp_file): - saw_instance.LogAdd("SAW Validator Test Message") - tmp_log = temp_file(".txt") - saw_instance.LogSave(tmp_log) - assert os.path.exists(tmp_log) - - @pytest.mark.order(96) - def test_general_file(self, saw_instance, temp_file): - tmp1 = temp_file(".txt") - saw_instance.WriteTextToFile(tmp1, "Hello") - - tmp2 = tmp1.replace(".txt", "_copy.txt") - saw_instance.CopyFile(tmp1, tmp2) - assert os.path.exists(tmp2) - - tmp3 = tmp1.replace(".txt", "_renamed.txt") - saw_instance.RenameFile(tmp2, tmp3) - assert os.path.exists(tmp3) - assert not os.path.exists(tmp2) - - saw_instance.DeleteFile(tmp3) - assert not os.path.exists(tmp3) - - @pytest.mark.order(98) - def test_general_aux(self, saw_instance, temp_file): - tmp_aux = temp_file(".aux") - saw_instance.SaveData(tmp_aux, "AUX", "Bus", ["BusNum", "BusName"]) - saw_instance.LoadAux(tmp_aux) - - @pytest.mark.order(99) - def test_general_select(self, saw_instance): - saw_instance.SelectAll("Bus") - saw_instance.UnSelectAll("Bus") - - -class TestOnelineSAW: - """Tests for oneline diagram operations.""" - - @pytest.mark.order(110) - def test_oneline_ops(self, saw_instance, temp_file): - saw_instance.CloseOneline() - saw_instance.RelinkAllOpenOnelines() - - tmp_axd = temp_file(".axd") - saw_instance.LoadAXD(tmp_axd, "TestOneline") - - -class TestModifySAW: - """Tests for modify operations (destructive - run late, order 100-199).""" - - @pytest.mark.order(120) - def test_modify_create_delete(self, saw_instance): - dummy_bus = 99999 - saw_instance.CreateData("Bus", ["BusNum", "BusName"], [dummy_bus, "SAW_TEST"]) - saw_instance.Delete("Bus", f"BusNum = {dummy_bus}") - - @pytest.mark.order(134) - def test_modify_superarea(self, saw_instance): - saw_instance.CreateData("SuperArea", ["Name"], ["TestSuperArea"]) - saw_instance.SuperAreaAddAreas("TestSuperArea", "ALL") - saw_instance.SuperAreaRemoveAreas("TestSuperArea", "ALL") - - @pytest.mark.order(135) - def test_modify_extras(self, saw_instance): - saw_instance.InjectionGroupRemoveDuplicates() - saw_instance.InterfaceRemoveDuplicates() - saw_instance.DirectionsAutoInsertReference("Bus", "Slack") - - saw_instance.InterfaceCreate("TestInt", True, "Branch", "SELECTED") - saw_instance.InterfaceFlatten("TestInt") - saw_instance.InterfaceFlattenFilter("ALL") - saw_instance.InterfaceModifyIsolatedElements() - - saw_instance.CreateData("Contingency", ["Name"], ["TestCtg"]) - saw_instance.InterfaceAddElementsFromContingency("TestInt", "TestCtg") - - -class TestRegionsSAW: - """Tests for regions operations (destructive - run late, order 200-299).""" - - @pytest.mark.order(200) - def test_regions_update(self, saw_instance): - saw_instance.RegionUpdateBuses() - - @pytest.mark.order(201) - def test_regions_rename(self, saw_instance): - saw_instance.RegionRename("OldRegion", "NewRegion") - saw_instance.RegionRenameClass("OldClass", "NewClass") - saw_instance.RegionRenameProper1("OldP1", "NewP1") - saw_instance.RegionRenameProper2("OldP2", "NewP2") - saw_instance.RegionRenameProper3("OldP3", "NewP3") - saw_instance.RegionRenameProper12Flip() - - -class TestCaseActionsSAW: - """Tests for case actions (highly destructive - run last, order 300+).""" - - @pytest.mark.order(300) - def test_case_description(self, saw_instance): - saw_instance.CaseDescriptionSet("Test Description") - saw_instance.CaseDescriptionClear() - - @pytest.mark.order(301) - def test_case_delete_external(self, saw_instance): - saw_instance.DeleteExternalSystem() - - @pytest.mark.order(302) - def test_case_equivalence(self, saw_instance): - saw_instance.Equivalence() - - @pytest.mark.order(303) - def test_case_save_external(self, saw_instance, temp_file): - tmp_pwb = temp_file(".pwb") - saw_instance.SaveExternalSystem(tmp_pwb) - - @pytest.mark.order(304) - def test_case_save_merged(self, saw_instance, temp_file): - tmp_pwb = temp_file(".pwb") - saw_instance.SaveMergedFixedNumBusCase(tmp_pwb) - - @pytest.mark.order(305) - def test_case_scale(self, saw_instance): - saw_instance.Scale("LOAD", "FACTOR", [1.0], "SYSTEM") - - @pytest.mark.order(999) - def test_case_renumber(self, saw_instance): - saw_instance.RenumberAreas() - saw_instance.RenumberBuses() - saw_instance.RenumberSubs() - saw_instance.RenumberZones() - saw_instance.RenumberCase() - - -class TestGetSubData: - """Integration tests for GetSubData - retrieving nested SubData from AUX exports.""" - - @pytest.mark.order(400) - def test_get_subdata_gen_fields_only(self, saw_instance): - """Test GetSubData with generators, no SubData requested.""" - df = saw_instance.GetSubData("Gen", ["BusNum", "GenID", "GenMW"]) - assert df is not None - assert "BusNum" in df.columns - assert "GenID" in df.columns - assert "GenMW" in df.columns - - @pytest.mark.order(401) - def test_get_subdata_gen_with_bidcurve(self, saw_instance): - """Test GetSubData retrieves BidCurve SubData for generators.""" - df = saw_instance.GetSubData("Gen", ["BusNum", "GenID"], ["BidCurve"]) - assert df is not None - assert "BidCurve" in df.columns - # BidCurve column should contain lists (even if empty) - for bc in df["BidCurve"]: - assert isinstance(bc, list) - - @pytest.mark.order(402) - def test_get_subdata_gen_with_reactive_capability(self, saw_instance): - """Test GetSubData retrieves ReactiveCapability SubData.""" - df = saw_instance.GetSubData("Gen", ["BusNum", "GenID"], ["ReactiveCapability"]) - assert df is not None - assert "ReactiveCapability" in df.columns - for rc in df["ReactiveCapability"]: - assert isinstance(rc, list) - - @pytest.mark.order(403) - def test_get_subdata_gen_multiple_subdata(self, saw_instance): - """Test GetSubData with multiple SubData types.""" - df = saw_instance.GetSubData("Gen", ["BusNum", "GenID", "GenMW"], - ["BidCurve", "ReactiveCapability"]) - assert df is not None - assert "BidCurve" in df.columns - assert "ReactiveCapability" in df.columns - - @pytest.mark.order(404) - def test_get_subdata_load_bidcurve(self, saw_instance): - """Test GetSubData retrieves Load BidCurve (benefit curves).""" - df = saw_instance.GetSubData("Load", ["BusNum", "LoadID", "LoadMW"], ["BidCurve"]) - assert df is not None - assert "BidCurve" in df.columns - - @pytest.mark.order(405) - def test_get_subdata_contingency_elements(self, saw_instance): - """Test GetSubData retrieves CTGElement for contingencies.""" - df = saw_instance.GetSubData("Contingency", ["TSContingency"], ["CTGElement"]) - assert df is not None - if not df.empty: - assert "CTGElement" in df.columns - # CTGElement should be a list of element definitions - for ctg in df["CTGElement"]: - assert isinstance(ctg, list) - - @pytest.mark.order(406) - def test_get_subdata_interface_elements(self, saw_instance): - """Test GetSubData retrieves InterfaceElement for interfaces.""" - df = saw_instance.GetSubData("Interface", ["InterfaceName"], ["InterfaceElement"]) - assert df is not None - if not df.empty: - assert "InterfaceElement" in df.columns - - @pytest.mark.order(407) - def test_get_subdata_with_filter(self, saw_instance): - """Test GetSubData with a filter applied.""" - # Get all generators first - df_all = saw_instance.GetSubData("Gen", ["BusNum", "GenID"]) - # Try with a filter (may return fewer or same depending on case) - df_filtered = saw_instance.GetSubData("Gen", ["BusNum", "GenID"], filter_name="GenStatus=Closed") - assert df_filtered is not None - assert len(df_filtered) <= len(df_all) - - @pytest.mark.order(408) - def test_get_subdata_empty_object_type(self, saw_instance): - """Test GetSubData with an object type that may have no entries.""" - # SuperArea may not exist in all cases - df = saw_instance.GetSubData("SuperArea", ["SuperAreaName"], ["SuperAreaArea"]) - assert df is not None # Should return empty DataFrame, not error - - @pytest.mark.order(409) - def test_get_subdata_bus_marginal_costs(self, saw_instance): - """Test GetSubData for Bus marginal cost SubData (from OPF).""" - df = saw_instance.GetSubData("Bus", ["BusNum", "BusName"], ["MWMarginalCostValues"]) - assert df is not None - assert "MWMarginalCostValues" in df.columns - - -if __name__ == "__main__": - sys.exit(pytest.main(["-v", __file__])) diff --git a/tests/test_integration_saw_transient.py b/tests/test_integration_saw_transient.py new file mode 100644 index 00000000..a92579cc --- /dev/null +++ b/tests/test_integration_saw_transient.py @@ -0,0 +1,386 @@ +""" +Integration tests for Transient Stability via SAW. + +These are **integration tests** that require a live connection to PowerWorld +Simulator via the SimAuto COM interface. They test transient stability +initialization, solving, model I/O, result storage, play-in signals, +relay insertion, and file format saves (PTI, GE, BPA). + +REQUIREMENTS: + - PowerWorld Simulator installed with SimAuto COM registered + - A valid PowerWorld case file path set in ``tests/config_test.py`` + (variable ``SAW_TEST_CASE``) or via the ``SAW_TEST_CASE`` env variable + +RELATED TEST FILES: + - test_integration_saw_core.py -- base SAW operations, logging, I/O + - test_integration_saw_modify.py -- destructive modify, region, case actions + - test_integration_saw_powerflow.py -- power flow, matrices, sensitivity, topology + - test_integration_saw_contingency.py -- contingency and fault analysis + - test_integration_saw_gic.py -- GIC analysis + - test_integration_saw_operations.py -- ATC, OPF, PV/QV, time step, weather, scheduled + - test_integration_workbench.py -- PowerWorld facade and statics + - test_integration_network.py -- Network topology + +USAGE: + pytest tests/test_integration_saw_transient.py -v +""" + +import os +import pytest +import numpy as np + +pytestmark = [ + pytest.mark.integration, + pytest.mark.requires_case, +] + +try: + from esapp.saw import SAW, PowerWorldError, PowerWorldPrerequisiteError, create_object_string +except ImportError: + raise + + +@pytest.fixture(scope="module") +def saw_instance(saw_session): + """Provides the session-scoped SAW instance to the tests in this module.""" + return saw_session + + +class TestTransient: + """SAW-level transient stability commands.""" + + @pytest.mark.order(8100) + def test_transient_initialize(self, saw_instance): + saw_instance.TSInitialize() + + @pytest.mark.order(8200) + def test_transient_options(self, saw_instance, temp_file): + tmp_aux = temp_file(".aux") + saw_instance.TSWriteOptions(tmp_aux) + assert os.path.exists(tmp_aux) + + @pytest.mark.order(8300) + def test_transient_critical_time(self, saw_instance): + branches = saw_instance.GetParametersMultipleElement("Branch", ["BusNum", "BusNum:1", "LineCircuit"]) + assert branches is not None and not branches.empty, "Test case must contain branches" + b = branches.iloc[0] + branch_str = create_object_string("Branch", b["BusNum"], b["BusNum:1"], b["LineCircuit"]) + saw_instance.TSCalculateCriticalClearTime(branch_str) + + @pytest.mark.order(8400) + def test_transient_playin(self, saw_instance): + times = np.array([0.0, 0.1]) + signals = np.array([[1.0], [1.0]]) + saw_instance.TSSetPlayInSignals("TestSignal", times, signals) + + @pytest.mark.order(8450) + def test_transient_write_results(self, saw_instance, temp_file): + """Write TS results to CSV after solving a minimal contingency.""" + tmp_csv = temp_file(".csv") + try: + saw_instance.RunScriptCommand("Delete(TSContingency);") + except (PowerWorldError, PowerWorldPrerequisiteError): + pass + saw_instance.CreateData("TSContingency", ["TSCTGName"], ["TestCTG"]) + ts_ctgs = saw_instance.ListOfDevices("TSContingency") + if ts_ctgs is None or ts_ctgs.empty: + pytest.skip("Unable to create TS contingencies for this case") + name_col = "TSCTGName" if "TSCTGName" in ts_ctgs.columns else ts_ctgs.columns[0] + ctg_name = str(ts_ctgs.iloc[0][name_col]).strip() + saw_instance.TSAutoCorrect() + saw_instance.TSInitialize() + try: + saw_instance.TSSolve(ctg_name, start_time=0.0, stop_time=0.1, step_size=0.01) + except (PowerWorldError, PowerWorldPrerequisiteError) as e: + pytest.skip(f"TS simulation cannot start for this case: {e}") + saw_instance.TSGetResults("SINGLE", [ctg_name], ["Gen ALL | GenMW"], filename=tmp_csv) + assert os.path.exists(tmp_csv) + + @pytest.mark.order(8500) + def test_transient_save_models(self, saw_instance, temp_file): + tmp_aux = temp_file(".aux") + saw_instance.TSWriteModels(tmp_aux) + assert os.path.exists(tmp_aux) + + tmp_aux2 = temp_file(".aux") + saw_instance.TSSaveDynamicModels(tmp_aux2, "AUX", "Gen") + assert os.path.exists(tmp_aux2) + + @pytest.mark.order(9850) + def test_transient_result_storage(self, saw_instance): + saw_instance.TSResultStorageSetAll("Gen", True) + saw_instance.TSResultStorageSetAll("Gen", False) + + @pytest.mark.order(9810) + def test_transient_clear_playin(self, saw_instance): + saw_instance.TSClearPlayInSignals() + + @pytest.mark.order(64000) + def test_transient_transfer_state(self, saw_instance): + saw_instance.TSInitialize() + saw_instance.TSTransferStateToPowerFlow(calculate_mismatch=True) + + @pytest.mark.order(64100) + def test_transient_transfer_state_no_mismatch(self, saw_instance): + saw_instance.TSTransferStateToPowerFlow(calculate_mismatch=False) + + @pytest.mark.order(64200) + def test_transient_store_response(self, saw_instance): + saw_instance.TSStoreResponse("Gen", True) + saw_instance.TSStoreResponse("Gen", False) + + @pytest.mark.order(64250) + def test_transient_smib_eigenvalues(self, saw_instance): + saw_instance.TSInitialize() + saw_instance.TSCalculateSMIBEigenValues() + + @pytest.mark.order(64300) + def test_transient_clear_results(self, saw_instance): + """Clear TS results: RAM, specific CTG params, and disable storage.""" + saw_instance.TSClearResultsFromRAM() + saw_instance.TSClearResultsFromRAM( + ctg_name="ALL", + clear_summary=True, + clear_events=False, + clear_statistics=True, + clear_time_values=False, + clear_solution_details=True, + ) + saw_instance.TSClearResultsFromRAMAndDisableStorage() + + @pytest.mark.order(64350) + def test_transient_run_until_specified_time(self, saw_instance): + saw_instance.CreateData("TSContingency", ["TSCTGName"], ["TestCtg"]) + saw_instance.TSInitialize() + saw_instance.TSRunUntilSpecifiedTime("TestCtg", stop_time=0.1, step_size=0.01) + + @pytest.mark.order(64600) + def test_transient_clear_all_models(self, saw_instance): + saw_instance.TSClearAllModels() + + @pytest.mark.order(64800) + def test_transient_clear_models_for_objects(self, saw_instance): + saw_instance.TSClearModelsforObjects("Gen") + + @pytest.mark.order(64900) + def test_transient_disable_machine_model(self, saw_instance): + saw_instance.TSInitialize() + saw_instance.TSDisableMachineModelNonZeroDerivative(threshold=0.01) + + @pytest.mark.order(65000) + def test_transient_auto_insert_dist_relay(self, saw_instance): + saw_instance.TSAutoInsertDistRelay( + reach=1.0, add_from=True, add_to=False, + transfer_trip=True, shape=1, filter_name="ALL", + ) + + @pytest.mark.order(65100) + def test_transient_auto_insert_zpott(self, saw_instance): + saw_instance.TSAutoInsertZPOTT(reach=1.0, filter_name="ALL") + + @pytest.mark.order(65200) + def test_transient_run_result_analyzer(self, saw_instance): + saw_instance.TSRunResultAnalyzer() + + @pytest.mark.order(65400) + def test_transient_save_formats(self, saw_instance, temp_file): + """Save TS models in PTI, GE, and BPA formats.""" + tmp_dyr = temp_file(".dyr") + saw_instance.TSSavePTI(tmp_dyr) + + tmp_dyd = temp_file(".dyd") + saw_instance.TSSaveGE(tmp_dyd) + + tmp_bpa = temp_file(".bpa") + saw_instance.TSSaveBPA(tmp_bpa) + + @pytest.mark.order(65500) + def test_transient_save_formats_diff(self, saw_instance, temp_file): + """Save TS models with diff_case_modified_only in PTI, GE, BPA.""" + tmp_dyr = temp_file(".dyr") + saw_instance.TSSavePTI(tmp_dyr, diff_case_modified_only=True) + + tmp_dyd = temp_file(".dyd") + saw_instance.TSSaveGE(tmp_dyd, diff_case_modified_only=True) + + tmp_bpa = temp_file(".bpa") + saw_instance.TSSaveBPA(tmp_bpa, diff_case_modified_only=True) + + @pytest.mark.order(65600) + def test_transient_write_models_diff(self, saw_instance, temp_file): + tmp = temp_file(".aux") + saw_instance.TSWriteModels(tmp, diff_case_modified_only=True) + + @pytest.mark.order(65700) + def test_transient_write_options_custom(self, saw_instance, temp_file): + tmp = temp_file(".aux") + saw_instance.TSWriteOptions( + tmp, + save_dynamic_model=False, + save_stability_options=True, + save_stability_events=False, + save_results_events=True, + save_plot_definitions=False, + save_transient_limit_monitors=True, + save_result_analyzer_time_window=False, + key_field="SECONDARY", + ) + + @pytest.mark.order(65800) + def test_transient_save_two_bus_equiv(self, saw_instance, temp_file): + buses = saw_instance.GetParametersMultipleElement("Bus", ["BusNum"]) + assert buses is not None and not buses.empty, "Test case must contain buses" + bus_key = create_object_string("Bus", buses.iloc[0]["BusNum"]) + tmp = temp_file(".pwb") + saw_instance.TSSaveTwoBusEquivalent(tmp, bus_key) + + @pytest.mark.order(65900) + def test_transient_join_active_ctgs(self, saw_instance): + try: + saw_instance.TSJoinActiveCTGs(0.1, delete_existing=True, join_with_self=False) + except PowerWorldError: + pass + + @pytest.mark.order(66000) + def test_transient_set_selected_for_refs(self, saw_instance): + try: + saw_instance.TSSetSelectedForTransientReferences( + "ALL", "SET", ["Gen"], ["GENROU"] + ) + except PowerWorldError: + pass + + @pytest.mark.order(66100) + def test_transient_save_dynamic_models_append(self, saw_instance, temp_file): + tmp = temp_file(".aux") + saw_instance.TSSaveDynamicModels(tmp, "AUX", "Gen", append=True) + + @pytest.mark.order(66200) + def test_transient_plot_series_add(self, saw_instance): + try: + saw_instance.TSPlotSeriesAdd("TestPlot", 1, 1, "Gen", "GenMW") + except PowerWorldError: + pass + + @pytest.mark.order(66300) + def test_transient_get_vcurve_data(self, saw_instance, temp_file): + tmp = temp_file(".csv") + try: + saw_instance.TSGetVCurveData(tmp, "") + except PowerWorldError: + pass + + @pytest.mark.order(77400) + def test_ts_solve_with_time_params(self, saw_instance): + """TSSolve with explicit start/stop/step parameters.""" + saw_instance.CreateData("TSContingency", ["TSCTGName"], ["TestCtg"]) + saw_instance.TSInitialize() + saw_instance.TSSolve( + "TestCtg", start_time=0.0, stop_time=0.1, + step_size=0.01, step_in_cycles=False, + ) + + @pytest.mark.order(77500) + def test_ts_solve_all(self, saw_instance): + """TSSolveAll completes without error.""" + saw_instance.TSInitialize() + saw_instance.TSSolveAll() + + @pytest.mark.order(77600) + def test_ts_clear_results_named_ctg(self, saw_instance): + """TSClearResultsFromRAM with a specific contingency name.""" + saw_instance.CreateData("TSContingency", ["TSCTGName"], ["TestCtg"]) + saw_instance.TSResultStorageSetAll("ALL", True) + saw_instance.TSInitialize() + saw_instance.TSSolve("TestCtg") + saw_instance.TSClearResultsFromRAM(ctg_name="TestCtg") + + @pytest.mark.order(77700) + def test_ts_auto_save_plots(self, saw_instance): + """TSAutoSavePlots completes without error.""" + saw_instance.TSAutoSavePlots( + plot_names=["TestPlot"], + ctg_names=["TestCtg"], + image_type="JPG", + width=800, height=600, font_scalar=1.0, + include_case_name=True, include_category=True, + ) + + @pytest.mark.order(77800) + def test_ts_load_rdb(self, saw_instance, temp_file): + """TSLoadRDB with a file path.""" + tmp = temp_file(".rdb") + saw_instance.TSLoadRDB(tmp, "DISTRELAY") + + @pytest.mark.order(77900) + def test_ts_load_relay_csv(self, saw_instance, temp_file): + """TSLoadRelayCSV with a file path.""" + tmp = temp_file(".csv") + with pytest.raises((PowerWorldError, PowerWorldPrerequisiteError)): + saw_instance.TSLoadRelayCSV(tmp, "DISTRELAY") + + @pytest.mark.order(78000) + def test_ts_run_until_specified_time_steps(self, saw_instance): + """TSRunUntilSpecifiedTime with steps_to_do parameter.""" + saw_instance.TSInitialize() + saw_instance.TSRunUntilSpecifiedTime( + "TestCtg", stop_time=0.1, step_size=0.01, + steps_in_cycles=False, reset_start_time=False, + steps_to_do=5, + ) + + @pytest.mark.order(78100) + def test_ts_load_pti(self, saw_instance, temp_file): + """TSLoadPTI with a file path.""" + tmp = temp_file(".dyr") + saw_instance.TSLoadPTI(tmp) + + @pytest.mark.order(78200) + def test_ts_load_ge(self, saw_instance, temp_file): + """TSLoadGE with a file path.""" + tmp = temp_file(".dyd") + saw_instance.TSLoadGE(tmp) + + @pytest.mark.order(78300) + def test_ts_load_bpa(self, saw_instance, temp_file): + """TSLoadBPA with a file path.""" + tmp = temp_file(".bpa") + saw_instance.TSLoadBPA(tmp) + + @pytest.mark.order(78400) + def test_ts_clear_playin_signals(self, saw_instance): + """TSClearPlayInSignals completes without error.""" + saw_instance.TSClearPlayInSignals() + + @pytest.mark.order(78500) + def test_ts_set_playin_signals_multi_col(self, saw_instance): + """TSSetPlayInSignals with multiple signal columns.""" + times = np.array([0.0, 0.1, 0.2]) + signals = np.array([[1.0, 2.0, 3.0], [1.1, 2.1, 3.1], [1.2, 2.2, 3.2]]) + saw_instance.TSSetPlayInSignals("MultiSignal", times, signals) + + @pytest.mark.order(78600) + def test_ts_set_playin_signals_validation(self, saw_instance): + """TSSetPlayInSignals raises ValueError for mismatched dimensions.""" + times = np.array([0.0, 0.1]) + signals = np.array([[1.0], [2.0], [3.0]]) + with pytest.raises(ValueError, match="Dimension mismatch"): + saw_instance.TSSetPlayInSignals("Bad", times, signals) + + @pytest.mark.order(78700) + def test_ts_validate(self, saw_instance): + """TSValidate completes without error.""" + saw_instance.TSValidate() + + @pytest.mark.order(78800) + def test_ts_auto_correct(self, saw_instance): + """TSAutoCorrect runs and may find/fix validation errors.""" + try: + saw_instance.TSAutoCorrect() + except PowerWorldError as e: + assert "Validation Errors were found" in str(e), f"Unexpected error: {e}" + + +if __name__ == "__main__": + import sys + sys.exit(pytest.main(["-v", __file__])) diff --git a/tests/test_integration_workbench.py b/tests/test_integration_workbench.py index 21ac208a..56bcb62a 100644 --- a/tests/test_integration_workbench.py +++ b/tests/test_integration_workbench.py @@ -1,25 +1,19 @@ """ -Integration tests for GridWorkBench functionality with live PowerWorld data. +Integration tests for the PowerWorld facade. -WHAT THIS TESTS: -- Component collection access (buses, generators, loads, branches, etc.) -- Data retrieval through component properties with real case data -- DataFrame conversion from live PowerWorld data -- Component-specific methods and attributes -- Performance validation with actual datasets -- Parametrized tests across all component types +These are **integration tests** that require a live connection to PowerWorld +Simulator via the SimAuto COM interface. They test the top-level +PowerWorld facade: case I/O, simulation control, component retrieval, +data modification, delegation to sub-modules, and workbench-level static +analysis (power flow, voltage, Y-bus, Jacobian). -DEPENDENCIES: -- PowerWorld Simulator installed and SimAuto registered -- Valid PowerWorld case file configured in tests/config_test.py - -CONFIGURATION: - 1. Copy tests/config_test.example.py to tests/config_test.py - 2. Set SAW_TEST_CASE = r"C:\\Path\\To\\Your\\Case.pwb" +REQUIREMENTS: + - PowerWorld Simulator installed with SimAuto COM registered + - A valid PowerWorld case file path set in ``tests/config_test.py`` + (variable ``SAW_TEST_CASE``) or via the ``SAW_TEST_CASE`` env variable USAGE: pytest tests/test_integration_workbench.py -v - pytest tests/test_integration_workbench.py -k "Bus" -v # Test only Bus components """ import os @@ -28,272 +22,317 @@ import pandas as pd import numpy as np import inspect -import sys +import sys try: - from esapp.grid import Bus, Gen, Load, Branch, Contingency, Area, Zone, Shunt, GICXFormer, GObject - from esapp import grid - from esapp.workbench import GridWorkBench + from esapp.components import Bus, Gen, Load, Branch, Contingency, Area, Zone, Shunt, GICXFormer, GObject + from esapp import components as grid + from esapp.workbench import PowerWorld from esapp.saw import PowerWorldError, COMError, SimAutoFeatureError, create_object_string except ImportError: raise -# List of component types known to cause SimAuto process instability or crashes -# when accessed via generic parameter retrieval methods. -# NOTE There is no evidence that these actually caused crashes -CRASH_PRONE_COMPONENTS = [ - #"ATCLineChangeB", - #"ATCScenario", - #"ATCZoneChange", - #"ATCGeneratorChange", - #"ATCInterfaceChange", -] +CRASH_PRONE_COMPONENTS = [] @pytest.fixture(scope="module") def wb(saw_session): """ - Wraps the session-scoped SAW instance in a GridWorkBench object. - The lifecycle of the underlying SAW instance is managed by saw_session. + Wraps the session-scoped SAW instance in a PowerWorld object. """ - workbench = GridWorkBench() - workbench.set_esa(saw_session) + workbench = PowerWorld() + workbench.esa = saw_session return workbench -class TestGridWorkBenchFunctions: - # ------------------------------------------------------------------------- - # Simulation Control - # ------------------------------------------------------------------------- +class TestPowerWorldFunctions: def test_simulation_control(self, wb, temp_file): """Tests flatstart, pflow, save, log, command, mode.""" wb.flatstart() - - # Power Flow + res = wb.pflow(getvolts=True) assert res is not None wb.pflow(getvolts=False) - - # Save + tmp_pwb = temp_file(".pwb") wb.save(tmp_pwb) assert os.path.exists(tmp_pwb) - - # Logging & Command + wb.log("Adapter Test Message") - wb.command('LogAdd("Command Test");') - - # Modes + wb.edit_mode() wb.run_mode() - def test_file_operations(self, wb, temp_file): - """Tests load_aux, load_script.""" - tmp_aux = temp_file(".aux") - with open(tmp_aux, 'w') as f: - f.write('DATA (Bus, [BusNum, BusName]) { 1 "Bus 1" }') - wb.load_aux(tmp_aux) - - tmp_script = temp_file(".aux") - with open(tmp_script, 'w') as f: - f.write('SCRIPT { LogAdd("Script Test"); }') - wb.load_script(tmp_script) - - # ------------------------------------------------------------------------- - # Data Retrieval - # ------------------------------------------------------------------------- - def test_voltage_retrieval(self, wb): - """Tests voltage().""" - # Test default call (complex, pu) + """Tests voltage() in all modes.""" v = wb.voltage() assert len(v) > 0 assert np.iscomplexobj(v.values) - # Test complex=True explicitly - v_complex = wb.voltage(complex=True) - assert np.iscomplexobj(v_complex.values) - - # Test complex=False v_mag, v_ang = wb.voltage(complex=False) assert len(v_mag) > 0 assert len(v_mag) == len(v_ang) - # Test pu=False v_kv = wb.voltage(pu=False) assert len(v_kv) > 0 - - # Test pu=False and complex=False + v_kv_mag, v_kv_ang = wb.voltage(pu=False, complex=False) assert len(v_kv_mag) > 0 - assert len(v_kv_mag) == len(v_kv_ang) def test_component_retrieval(self, wb): - """Tests generations, loads, shunts, lines, transformers, areas, zones.""" - assert not wb.generations().empty + """Tests gens, loads, shunts, lines, transformers, areas, zones.""" + assert not wb.gens().empty assert not wb.loads().empty - # Shunts/Transformers might be empty in some cases, but call should succeed - wb.shunts() - wb.transformers() + assert isinstance(wb.shunts(), pd.DataFrame) + assert isinstance(wb.transformers(), pd.DataFrame) assert not wb.lines().empty assert not wb.areas().empty assert not wb.zones().empty - # ------------------------------------------------------------------------- - # Modification - # ------------------------------------------------------------------------- - - def test_modification(self, wb): - """Tests set_voltages, branch ops, gen/load ops, create/delete/select.""" - # Set Voltages + def test_set_voltages(self, wb): + """Tests set_voltages round-trip.""" v = wb.voltage(complex=True, pu=True) wb.set_voltages(v) - - # Branch Ops - lines = wb.lines() - if not lines.empty: - l = lines.iloc[0] - wb.open_branch(l['BusNum'], l['BusNum:1'], l['LineCircuit']) - wb.close_branch(l['BusNum'], l['BusNum:1'], l['LineCircuit']) - - # Gen Ops - gens = wb.generations() - if not gens.empty: - # Fetch keys (BusNum is PRIMARY, GenID is SECONDARY so must be requested explicitly) - g_keys = wb[Gen, ["BusNum", "GenID"]].iloc[0] - wb.set_gen(g_keys['BusNum'], g_keys['GenID'], mw=10.0, status="Closed") - - # Load Ops - loads = wb.loads() - if not loads.empty: - # Fetch keys (BusNum is PRIMARY, LoadID is SECONDARY so must be requested explicitly) - l_keys = wb[Load, ["BusNum", "LoadID"]].iloc[0] - wb.set_load(l_keys['BusNum'], l_keys['LoadID'], mw=5.0, status="Closed") - - wb.scale_load(1.0) - wb.scale_gen(1.0) - - # Create/Delete (Use dummy ID) - wb.create("Load", BusNum=1, LoadID="99", LoadMW=5.0) - wb.delete("Load", "LoadID = '99'") - - # Select/Unselect - wb.select("Bus", "BusNum < 10") - wb.unselect("Bus") - - # ------------------------------------------------------------------------- - # Advanced Topology & Switching - # ------------------------------------------------------------------------- - - def test_topology(self, wb): - """Tests energize, deenergize, radial_paths, path_distance, network_cut.""" - wb.deenergize("Bus", create_object_string("Bus", 1)) - wb.energize("Bus", create_object_string("Bus", 1)) - - wb.radial_paths() - - wb.select("Branch", "BusNum = 1") - wb.network_cut(create_object_string("Bus", 1), branch_filter="SELECTED") - - # ------------------------------------------------------------------------- - # Analysis & Difference Flows - # ------------------------------------------------------------------------- - - def test_analysis(self, wb, temp_file): - """Tests contingency, violations, mismatches, islands, diff flows.""" - # Contingency - wb.auto_insert_contingencies() - ctgs = wb[Contingency] - if not ctgs.empty: - c_name = ctgs.iloc[0]['CTGLabel'] - wb.run_contingency(c_name) - wb.solve_contingencies() - - # Violations + + def test_analysis(self, wb): + """Tests violations, mismatches, net injection.""" viols = wb.violations() assert isinstance(viols, pd.DataFrame) - - # Mismatches - mp, mq = wb.mismatch() - assert not mp.empty - assert not mq.empty - - # Islands - isl = wb.islands() - assert isl is not None - - # Diff Flows - wb.set_as_base_case() - wb.diff_mode("DIFFERENCE") - wb.diff_mode("PRESENT") - - # Onelines - wb.refresh_onelines() - - # ------------------------------------------------------------------------- - # Sensitivity, Faults, Advanced Analysis - # ------------------------------------------------------------------------- - - def test_sensitivity_faults(self, wb): - """Tests ptdf, lodf, fault, shortest_path.""" - # PTDF - areas = wb.areas() - if len(areas) >= 2: - s = create_object_string("Area", areas.iloc[0]["AreaNum"]) - b = create_object_string("Area", areas.iloc[1]["AreaNum"]) - wb.ptdf(s, b) - - # LODF - lines = wb.lines() - if not lines.empty: - l = lines.iloc[0] - br = create_object_string("Branch", l["BusNum"], l["BusNum:1"], l["LineCircuit"]) - wb.lodf(br) - - # Fault - wb.fault(1) - wb.clear_fault() - - # Shortest Path - buses = wb[Bus] - if len(buses) >= 2: - wb.shortest_path(buses.iloc[0]['BusNum'], buses.iloc[1]['BusNum']) - - def test_advanced_analysis(self, wb): - """Tests QV, ATC, GIC, OPF, YBus.""" - - - # ATC - areas = wb.areas() - if len(areas) >= 2: - s = create_object_string("Area", areas.iloc[0]["AreaNum"]) - b = create_object_string("Area", areas.iloc[1]["AreaNum"]) - wb.calculate_atc(s, b) - - # GIC - wb.calculate_gic(1.0, 90.0) - - # OPF - wb.solve_opf() - - # YBus - Y = wb.ybus() - assert Y.shape[0] > 0 + + P, Q = wb.mismatch() + assert not P.empty + assert not Q.empty + + S = wb.mismatch(asComplex=True) + assert np.iscomplexobj(S) + + Pn, Qn = wb.netinj() + assert len(Pn) > 0 + Sn = wb.netinj(asComplex=True) + assert np.iscomplexobj(Sn) + + def test_print_log(self, wb): + """Tests print_log() with all parameter combinations.""" + wb.log("Print log test message") + output = wb.print_log() + assert isinstance(output, str) + + wb.log("Another message") + new_output = wb.print_log(new_only=True) + assert isinstance(new_output, str) + + cleared = wb.print_log(clear=True) + assert isinstance(cleared, str) def test_location(self, wb): """Tests busmap, buscoords.""" m = wb.busmap() assert not m.empty - - # buscoords requires substation data, might be empty but call should work - try: - wb.buscoords() - except Exception: - pass + wb.buscoords() + df = wb.buscoords(astuple=False) + assert isinstance(df, pd.DataFrame) + + +class TestWorkbenchStatics: + """Workbench-level static analysis: power flow, voltage, Y-bus, Jacobian.""" + + def test_pflow(self, wb): + """Power flow solve with and without voltage retrieval.""" + v = wb.pflow(getvolts=True) + assert v is not None + assert len(v) > 0 + assert np.iscomplexobj(v.values) + + result = wb.pflow(getvolts=False) + assert result is None + + def test_voltage(self, wb): + """Voltage retrieval in all modes: complex/tuple, pu/kV.""" + v = wb.voltage(complex=True, pu=True) + assert np.iscomplexobj(v.values) + assert len(v) > 0 + + mag, ang = wb.voltage(complex=False, pu=True) + assert len(mag) > 0 + assert len(ang) > 0 + + v_kv = wb.voltage(complex=True, pu=False) + assert len(v_kv) > 0 + + wb.set_voltages(v) + + def test_violations(self, wb): + """Bus voltage violations with normal and tight limits.""" + viols = wb.violations(v_min=0.9, v_max=1.1) + assert isinstance(viols, pd.DataFrame) + assert 'Low' in viols.columns + assert 'High' in viols.columns + + viols_tight = wb.violations(v_min=0.999, v_max=1.001) + assert isinstance(viols_tight, pd.DataFrame) + + def test_mismatch_and_netinj(self, wb): + """Bus power mismatches and net injection.""" + P, Q = wb.mismatch() + assert not P.empty + assert not Q.empty + + S = wb.mismatch(asComplex=True) + assert np.iscomplexobj(S) + + Pn, Qn = wb.netinj() + assert len(Pn) > 0 + Sn = wb.netinj(asComplex=True) + assert np.iscomplexobj(Sn) + + def test_ybus(self, wb): + """Y-Bus matrix retrieval, sparse and dense.""" + Y = wb.ybus() + assert Y.shape[0] > 0 + assert Y.shape[0] == Y.shape[1] + + Y_dense = wb.ybus(dense=True) + assert isinstance(Y_dense, np.ndarray) + assert Y_dense.shape[0] > 0 + + def test_jacobian(self, wb): + """Jacobian: sparse, dense, polar form, with IDs.""" + wb.pflow(getvolts=False) + + J = wb.jacobian() + assert J.shape[0] > 0 + + J_dense = wb.jacobian(dense=True) + assert isinstance(J_dense, np.ndarray) + + J_polar = wb.jacobian(dense=True, form='P') + assert isinstance(J_polar, np.ndarray) + assert J_polar.shape[0] > 0 + assert J_polar.shape[0] == J_polar.shape[1] + + J_ids, ids = wb.jacobian(dense=True, form='P', ids=True) + assert isinstance(J_ids, np.ndarray) + assert isinstance(ids, list) + assert len(ids) > 0 + + def test_solver_options(self, wb): + """Solver option descriptors: bool and non-bool round-trip.""" + # Bool descriptors: set True, read back, set False, read back + wb.do_one_iteration = True + assert wb.do_one_iteration is True + wb.do_one_iteration = False + assert wb.do_one_iteration is False + + wb.disable_angle_rotation = True + assert wb.disable_angle_rotation is True + wb.disable_angle_rotation = False + + wb.disable_opt_mult = True + assert wb.disable_opt_mult is True + wb.disable_opt_mult = False + + wb.inner_ss_check = True + assert wb.inner_ss_check is True + wb.inner_ss_check = False + + wb.disable_gen_mvr_check = True + assert wb.disable_gen_mvr_check is True + wb.disable_gen_mvr_check = False + + wb.inner_check_gen_vars = True + wb.inner_check_gen_vars = False + + wb.inner_backoff_gen_vars = True + wb.inner_backoff_gen_vars = False + + # Non-bool descriptor: int round-trip + wb.max_iterations = 250 + assert wb.max_iterations == 250 + wb.max_iterations = 100 + assert wb.max_iterations == 100 + + # Class-level access returns the descriptor itself + desc = type(wb).do_one_iteration + assert hasattr(desc, 'key') + assert desc.key == 'DoOneIteration' + + +class TestWorkbenchConvenience: + """Convenience features: flows, overloads, snapshot, sensitivity, properties, summary.""" + + def test_flows_and_overloads(self, wb): + """Branch flows retrieval and overload detection.""" + wb.pflow(getvolts=False) + + f = wb.flows() + assert isinstance(f, pd.DataFrame) + assert not f.empty + assert 'LineMW' in f.columns + assert 'LineMVR' in f.columns + assert 'LineMVA' in f.columns + assert 'LinePercent' in f.columns + + ov = wb.overloads(threshold=100.0) + assert isinstance(ov, pd.DataFrame) + + ov_zero = wb.overloads(threshold=0.0) + assert len(ov_zero) >= len(ov) + + def test_snapshot(self, wb): + """Snapshot context manager saves and restores state.""" + wb.pflow(getvolts=False) + v_before = wb.voltage() + + with wb.snapshot(): + wb.flatstart() + v_flat = wb.voltage() + assert not np.allclose(np.abs(v_before.values), np.abs(v_flat.values), atol=1e-6) + + v_after = wb.voltage() + np.testing.assert_allclose(np.abs(v_before.values), np.abs(v_after.values), atol=1e-10) + + def test_ptdf(self, wb): + """PTDF calculation for a bus-to-bus transfer.""" + wb.pflow(getvolts=False) + buses = wb[Bus] + bus1, bus2 = int(buses['BusNum'].iloc[0]), int(buses['BusNum'].iloc[1]) + + df = wb.ptdf(seller=bus1, buyer=bus2) + assert isinstance(df, pd.DataFrame) + assert 'LinePTDF' in df.columns + + def test_lodf(self, wb): + """LODF calculation for a branch outage.""" + wb.pflow(getvolts=False) + branches = wb[Branch] + row = branches.iloc[0] + key = (int(row['BusNum']), int(row['BusNum:1']), str(row['LineCircuit'])) + + df = wb.lodf(branch=key) + assert isinstance(df, pd.DataFrame) + assert 'LineLODF' in df.columns + + def test_properties_and_summary(self, wb): + """Quick properties and case summary.""" + assert wb.n_bus > 0 + assert wb.n_branch > 0 + assert wb.n_gen > 0 + assert wb.sbase > 0 + + s = wb.summary() + assert isinstance(s, dict) + assert s['n_bus'] == wb.n_bus + assert s['n_branch'] == wb.n_branch + assert s['n_gen'] > 0 + assert s['n_load'] > 0 + assert s['total_gen_mw'] > 0 + assert s['total_load_mw'] > 0 + assert 0 < s['v_min'] <= s['v_max'] < 2.0 + assert s['sbase'] > 0 # ------------------------------------------------------------------------- -# Consolidated Component Access Tests (formerly test_online_components.py) +# Consolidated Component Access Tests # ------------------------------------------------------------------------- def get_gobject_subclasses(): @@ -306,25 +345,24 @@ def get_gobject_subclasses(): @pytest.mark.parametrize("component_class", get_gobject_subclasses()) def test_component_access(wb, component_class): """ - Verifies that GridWorkBench can read key fields for every defined component. + Verifies that PowerWorld can read key fields for every defined component. """ if component_class.TYPE in CRASH_PRONE_COMPONENTS: - pytest.skip(f"Skipping {component_class.TYPE}: Known to cause SimAuto crashes during iteration.") + pytest.skip(f"Skipping {component_class.TYPE}: Known to cause SimAuto crashes.") try: df = wb[component_class] except SimAutoFeatureError as e: pytest.skip(f"Object type {component_class.TYPE} cannot be retrieved via SimAuto: {e.message}") except (PowerWorldError, COMError) as e: - # Check if object is supported by checking if we can save fields + err_msg = str(e) + if "Access violation" in err_msg or "memory resources" in err_msg: + pytest.skip(f"Object type {component_class.TYPE} causes PW crash: {e}") with tempfile.NamedTemporaryFile(suffix=".csv", delete=False) as tmp: tmp_path = tmp.name try: fields = component_class.keys if component_class.keys else ["ALL"] wb.esa.SaveObjectFields(tmp_path, component_class.TYPE, fields) - # If save works but read fails, it's a real error (or memory issue) - if "memory resources" in str(e): - pytest.skip(f"Object type {component_class.TYPE} has too many fields/objects.") pytest.fail(f"Object type {component_class.TYPE} is supported but failed to read: {e}") except PowerWorldError: pytest.skip(f"Object type {component_class.TYPE} not supported by this PW version.") @@ -334,7 +372,7 @@ def test_component_access(wb, component_class): except: pass except Exception as e: pytest.fail(f"Unexpected error reading {component_class.__name__}: {e}") - + if df is not None: assert isinstance(df, pd.DataFrame) if not df.empty: @@ -343,5 +381,4 @@ def test_component_access(wb, component_class): if __name__ == "__main__": - # Run pytest on this file sys.exit(pytest.main(["-v", __file__])) diff --git a/tests/test_saw_core_methods.py b/tests/test_saw_core_methods.py deleted file mode 100644 index a4aabbc8..00000000 --- a/tests/test_saw_core_methods.py +++ /dev/null @@ -1,3465 +0,0 @@ -""" -Unit tests for the SAW class core methods and mixins. - -WHAT THIS TESTS: -- Case file operations (open, save, close) -- Script command execution via RunScriptCommand -- Power flow solution commands (SolvePowerFlow, etc.) -- Contingency analysis commands (RunContingency, SolveContingencies) -- State management (StoreState, RestoreState, DeleteState) -- Mode switching (EnterMode) -- Logging and utility commands -- Command string formatting and validation - -DEPENDENCIES: None (mocked COM interface, no PowerWorld required) - -USAGE: - pytest tests/test_saw_core_methods.py -v -""" -import pytest -from unittest.mock import MagicMock, Mock, patch, ANY -import pandas as pd -import numpy as np -from esapp import SAW, grid - -def test_saw_initialization(saw_obj): - """Test that the SAW object initializes correctly with the fixture.""" - assert saw_obj.pwb_file_path == "dummy.pwb" - assert saw_obj._pwcom is not None - -def test_open_case(saw_obj): - """Test OpenCase calls the underlying COM method.""" - saw_obj.OpenCase("test_case.pwb") - saw_obj._pwcom.OpenCase.assert_called_with("test_case.pwb") - assert saw_obj.pwb_file_path == "test_case.pwb" - -def test_save_case(saw_obj): - """Test SaveCase calls the underlying COM method.""" - saw_obj.SaveCase("saved_case.pwb") - # Check if SaveCase was called. - # convert_to_windows_path is used internally, so we check if the call argument contains the filename. - saw_obj._pwcom.SaveCase.assert_called() - args, _ = saw_obj._pwcom.SaveCase.call_args - assert "saved_case.pwb" in args[0] - -@pytest.mark.parametrize("method, args, expected_script", [ - # Core script commands - ("RunScriptCommand", ("SolvePowerFlow;",), "SolvePowerFlow;"), - ("SolvePowerFlow", (), "SolvePowerFlow(RECTNEWT)"), - ("EnterMode", ("EDIT",), "EnterMode(EDIT);"), - # State management - ("StoreState", ("State1",), 'StoreState("State1");'), - ("RestoreState", ("State1",), 'RestoreState(USER, "State1");'), - ("DeleteState", ("State1",), 'DeleteState(USER, "State1");'), - # Logging - ("LogAdd", ("Test Message",), 'LogAdd("Test Message");'), - ("LogClear", (), "LogClear;"), - ("LogSave", ("log.txt",), 'LogSave("log.txt", NO);'), - # Case operations - ("RenumberCase", (), "RenumberCase;"), - ("RenumberBuses", (5,), "RenumberBuses(5);"), - ("SetCurrentDirectory", ("C:\\Temp",), 'SetCurrentDirectory("C:\\Temp", NO);'), - # Data operations - ("SetData", ("Bus", ["Name"], ["NewName"], "SELECTED"), 'SetData(Bus, [Name], [NewName], SELECTED);'), - ("CreateData", ("Bus", ["BusNum"], [99]), 'CreateData(Bus, [BusNum], [99]);'), - ("Delete", ("Bus", "SELECTED"), 'Delete(Bus, SELECTED);'), - ("SelectAll", ("Bus",), 'SelectAll(Bus, );'), - # Transient stability - ("TSTransferStateToPowerFlow", (), "TSTransferStateToPowerFlow(NO);"), - ("TSSolveAll", (), "TSSolveAll()"), - ("TSSolve", ("MyCtg",), 'TSSolve("MyCtg")'), - ("TSCalculateCriticalClearTime", ("[BRANCH 1 2 1]",), 'TSCalculateCriticalClearTime([BRANCH 1 2 1]);'), - ("TSClearModelsforObjects", ("Gen", "SELECTED"), 'TSClearModelsforObjects(Gen, "SELECTED");'), - ("TSJoinActiveCTGs", (10.0, False, True, "", "Both"), 'TSJoinActiveCTGs(10.0, NO, YES, "", Both);'), - ("TSAutoInsertDistRelay", (80, True, True, True, 3, "AREAZONE"), 'TSAutoInsertDistRelay(80, YES, YES, YES, 3, "AREAZONE");'), - ("TSAutoSavePlots", (["Plot1"], ["Ctg1"], "JPG", 800, 600, 1.0, False, False), 'TSAutoSavePlots(["Plot1"], ["Ctg1"], JPG, 800, 600, 1.0, NO, NO);'), - ("TSResultStorageSetAll", ("Gen", False), "TSResultStorageSetAll(Gen, NO)"), - # Contingency - ("SolveContingencies", (), "CTGSolveAll(NO, YES);"), - ("RunContingency", ("MyCtg",), 'CTGSolve("MyCtg");'), - ("CTGAutoInsert", (), "CTGAutoInsert;"), - ("CTGCloneOne", ("Ctg1", "Ctg2", "Pre", "Suf", True), 'CTGCloneOne("Ctg1", "Ctg2", "Pre", "Suf", YES);'), - # Fault - ("FaultClear", (), "FaultClear;"), - ("FaultAutoInsert", (), "FaultAutoInsert;"), - ("RunFault", ('[BUS 1]', 'SLG', 0.001, 0.01), 'Fault([BUS 1], SLG, 0.001, 0.01);'), - # Sensitivity - ("CalculateFlowSense", ('[INTERFACE "Left-Right"]', 'MW'), 'CalculateFlowSense([INTERFACE "Left-Right"], MW);'), - ("CalculatePTDF", ('[AREA "Top"]', '[BUS 7]', 'DCPS'), 'CalculatePTDF([AREA "Top"], [BUS 7], DCPS);'), - ("CalculateLODF", ('[BRANCH 1 2 1]', 'DC'), 'CalculateLODF([BRANCH 1 2 1], DC);'), - ("CalculateShiftFactors", ('[BRANCH 1 2 "1"]', 'SELLER', '[AREA "Top"]', 'DC'), 'CalculateShiftFactors([BRANCH 1 2 "1"], SELLER, [AREA "Top"], DC);'), - ("CalculateLODFMatrix", ("OUTAGES", "ALL", "ALL"), 'CalculateLODFMatrix(OUTAGES, ALL, ALL, YES, DC, , YES);'), - ("CalculateVoltToTransferSense", ('[AREA "Top"]', '[AREA "Left"]', 'P', True), 'CalculateVoltToTransferSense([AREA "Top"], [AREA "Left"], P, YES);'), - # Topology - ("DoFacilityAnalysis", ("cut.aux", True), 'DoFacilityAnalysis("cut.aux", YES);'), - ("FindRadialBusPaths", (True, False, "BUS"), 'FindRadialBusPaths(YES, NO, BUS);'), - # ATC - ("DetermineATC", ('[AREA "Top"]', '[AREA "Left"]', True, True), 'ATCDetermine([AREA "Top"], [AREA "Left"], YES, YES);'), - ("DetermineATCMultipleDirections", (), 'ATCDetermineMultipleDirections(NO, NO);'), - # GIC - ("ClearGIC", (), "GICClear;"), - ("CalculateGIC", (5.0, 90.0, True), 'GICCalculate(5.0, 90.0, YES);'), - ("GICSaveGMatrix", ("gmatrix.mat", "gmatrix_ids.txt"), 'GICSaveGMatrix("gmatrix.mat", "gmatrix_ids.txt");'), - ("GICSetupTimeVaryingSeries", (0.0, 3600.0, 60.0), 'GICSetupTimeVaryingSeries(0.0, 3600.0, 60.0);'), - ("GICTimeVaryingCalculate", (1800.0, True), 'GICTimeVaryingCalculate(1800.0, YES);'), - ("GICWriteOptions", ("gic_opts.aux", "PRIMARY"), 'GICWriteOptions("gic_opts.aux", PRIMARY);'), - ("GICLoad3DEfield", ("B3D", "test.b3d", True), 'GICLoad3DEfield(B3D, "test.b3d", YES);'), - # OPF - ("SolvePrimalLP", (), 'SolvePrimalLP("", "", NO, NO);'), - ("SolveFullSCOPF", (), 'SolveFullSCOPF(OPF, "", "", NO, NO);'), - # PV/QV - ("RunPV", ('[INJECTIONGROUP "Source"]', '[INJECTIONGROUP "Sink"]'), 'PVRun([INJECTIONGROUP "Source"], [INJECTIONGROUP "Sink"]);'), - ("RunQV", ("results.csv",), 'QVRun("results.csv", YES, NO);'), - # ========================================================================= - # NEW TESTS: ModifyMixin methods - # ========================================================================= - ("AutoInsertTieLineTransactions", (), "AutoInsertTieLineTransactions;"), - ("ChangeSystemMVABase", (100.0,), "ChangeSystemMVABase(100.0);"), - ("ClearSmallIslands", (), "ClearSmallIslands;"), - ("InitializeGenMvarLimits", (), "InitializeGenMvarLimits;"), - ("InjectionGroupsAutoInsert", (), "InjectionGroupsAutoInsert;"), - ("DirectionsAutoInsert", ('[AREA "Top"]', '[AREA "Bot"]', True, False), 'DirectionsAutoInsert([AREA "Top"], [AREA "Bot"], YES, NO);'), - ("InterfacesAutoInsert", ("AREA", True, False, "", "AUTO"), 'InterfacesAutoInsert(AREA, YES, NO, "", AUTO);'), - ("InterfaceFlatten", ("MyInterface",), 'InterfaceFlatten("MyInterface");'), - ("InterfaceAddElementsFromContingency", ("Interface1", "Ctg1"), 'InterfaceAddElementsFromContingency("Interface1", "Ctg1");'), - ("MergeLineTerminals", ("SELECTED",), "MergeLineTerminals(SELECTED);"), - ("MergeMSLineSections", ("SELECTED",), "MergeMSLineSections(SELECTED);"), - # ========================================================================= - # NEW TESTS: CaseActionsMixin methods - # ========================================================================= - ("CaseDescriptionClear", (), "CaseDescriptionClear;"), - ("CaseDescriptionSet", ("Test description", False), 'CaseDescriptionSet("Test description", NO);'), - ("CaseDescriptionSet", ("Appended", True), 'CaseDescriptionSet("Appended", YES);'), - ("DeleteExternalSystem", (), "DeleteExternalSystem;"), - ("Equivalence", (), "Equivalence;"), - ("NewCase", (), "NewCase;"), - ("RenumberAreas", (0,), "RenumberAreas(0);"), - ("RenumberSubs", (2,), "RenumberSubs(2);"), - ("RenumberZones", (3,), "RenumberZones(3);"), - # ========================================================================= - # NEW TESTS: OnelineMixin methods - # ========================================================================= - ("CloseOneline", ("MyOneline",), 'CloseOneline("MyOneline")'), - ("SaveOneline", ("out.pwb", "MyOneline", "PWB"), 'SaveOneline("out.pwb", "MyOneline", PWB);'), - ("ExportOneline", ("out.jpg", "MyOneline", "JPG", "", "NO", "NO"), 'ExportOneline("out.jpg", "MyOneline", JPG, "", NO, NO);'), - # ========================================================================= - # NEW TESTS: PVMixin methods - # ========================================================================= - ("PVClear", (), "PVClear;"), - ("PVDestroy", (), "PVDestroy;"), - ("PVStartOver", (), "PVStartOver;"), - ("PVSetSourceAndSink", ('[InjectionGroup "A"]', '[InjectionGroup "B"]'), 'PVSetSourceAndSink([InjectionGroup "A"], [InjectionGroup "B"]);'), - ("PVQVTrackSingleBusPerSuperBus", (), "PVQVTrackSingleBusPerSuperBus;"), - ("PVWriteResultsAndOptions", ("pv_results.aux", True), 'PVWriteResultsAndOptions("pv_results.aux", YES);'), - ("PVWriteResultsAndOptions", ("pv_results.aux", False), 'PVWriteResultsAndOptions("pv_results.aux", NO);'), - # ========================================================================= - # NEW TESTS: QVMixin methods - # ========================================================================= - ("QVDeleteAllResults", (), "QVDeleteAllResults;"), - ("QVSelectSingleBusPerSuperBus", (), "QVSelectSingleBusPerSuperBus;"), - ("QVWriteResultsAndOptions", ("qv_results.aux", True), 'QVWriteResultsAndOptions("qv_results.aux", YES);'), - ("QVWriteResultsAndOptions", ("qv_results.aux", False), 'QVWriteResultsAndOptions("qv_results.aux", NO);'), - ("QVDataWriteOptionsAndResults", ("qv_data.aux", True, "PRIMARY"), 'QVDataWriteOptionsAndResults("qv_data.aux", YES, PRIMARY);'), - # ========================================================================= - # NEW TESTS: ATCMixin methods - # ========================================================================= - ("ATCDeleteAllResults", (), "ATCDeleteAllResults;"), - ("ATCRestoreInitialState", (), "ATCRestoreInitialState;"), - ("ATCIncreaseTransferBy", (50.0,), "ATCIncreaseTransferBy(50.0);"), - ("ATCDetermineATCFor", (0, 0, 0, False), "ATCDetermineATCFor(0, 0, 0, NO);"), - ("ATCDetermineATCFor", (1, 2, 3, True), "ATCDetermineATCFor(1, 2, 3, YES);"), - ("ATCDetermineMultipleDirectionsATCFor", (0, 0, 0), "ATCDetermineMultipleDirectionsATCFor(0, 0, 0);"), - # ========================================================================= - # NEW TESTS: RegionsMixin methods - # ========================================================================= - ("RegionRename", ("OldRegion", "NewRegion", True), 'RegionRename("OldRegion", "NewRegion", YES);'), - ("RegionRename", ("OldRegion", "NewRegion", False), 'RegionRename("OldRegion", "NewRegion", NO);'), - ("RegionRenameClass", ("OldClass", "NewClass", True, ""), 'RegionRenameClass("OldClass", "NewClass", YES, );'), - # ========================================================================= - # NEW TESTS: TimeStepMixin methods (coverage expansion) - # ========================================================================= - ("TimeStepDeleteAll", (), "TimeStepDeleteAll;"), - ("TimeStepResetRun", (), "TimeStepResetRun;"), - ("TIMESTEPSaveSelectedModifyStart", (), "TIMESTEPSaveSelectedModifyStart;"), - ("TIMESTEPSaveSelectedModifyFinish", (), "TIMESTEPSaveSelectedModifyFinish;"), - ("TimeStepSavePWW", ("weather.pww",), 'TimeStepSavePWW("weather.pww");'), - ("TimeStepLoadTSB", ("data.tsb",), 'TimeStepLoadTSB("data.tsb");'), - ("TimeStepSaveTSB", ("output.tsb",), 'TimeStepSaveTSB("output.tsb");'), - ("TimeStepAppendPWW", ("weather.pww", "Single Solution"), 'TimeStepAppendPWW("weather.pww", "Single Solution");'), - ("TimeStepLoadPWW", ("weather.pww", "OPF"), 'TimeStepLoadPWW("weather.pww", "OPF");'), - ("TimeStepDoSinglePoint", ("2025-01-01T00:00:00",), "TimeStepDoSinglePoint(2025-01-01T00:00:00);"), - ("TimeStepLoadB3D", ("test.b3d", "GIC Only (No Power Flow)"), 'TimeStepLoadB3D("test.b3d", "GIC Only (No Power Flow)");'), - # ========================================================================= - # NEW TESTS: PowerflowMixin methods (coverage expansion) - # ========================================================================= - ("UpdateIslandsAndBusStatus", (), "UpdateIslandsAndBusStatus;"), - ("ZeroOutMismatches", ("BUSSHUNT",), "ZeroOutMismatches(BUSSHUNT);"), - ("ZeroOutMismatches", ("LOAD",), "ZeroOutMismatches(LOAD);"), - ("VoltageConditioning", (), "VoltageConditioning;"), - ("DiffCaseClearBase", (), "DiffCaseClearBase;"), - ("DiffCaseSetAsBase", (), "DiffCaseSetAsBase;"), - ("DiffCaseKeyType", ("PRIMARY",), "DiffCaseKeyType(PRIMARY);"), - ("DiffCaseShowPresentAndBase", (True,), "DiffCaseShowPresentAndBase(YES);"), - ("DiffCaseShowPresentAndBase", (False,), "DiffCaseShowPresentAndBase(NO);"), - ("DiffCaseMode", ("DIFFERENCE",), "DiffCaseMode(DIFFERENCE);"), - ("DiffCaseRefresh", (), "DiffCaseRefresh;"), - ("DoCTGAction", ("APPLY",), "DoCTGAction(APPLY);"), - ("InterfacesCalculatePostCTGMWFlows", (), "InterfacesCalculatePostCTGMWFlows;"), - ("GenForceLDC_RCC", ("MyFilter",), 'GenForceLDC_RCC("MyFilter");'), - ("SaveGenLimitStatusAction", ("genlimits.txt",), 'SaveGenLimitStatusAction("genlimits.txt");'), - # ========================================================================= - # NEW TESTS: ContingencyMixin methods (coverage expansion) - # ========================================================================= - ("CTGAutoInsert", (), "CTGAutoInsert;"), - ("CTGClearAllResults", (), "CTGClearAllResults;"), - ("CTGSetAsReference", (), "CTGSetAsReference;"), - ("CTGComboDeleteAllResults", (), "CTGComboDeleteAllResults;"), - ("CTGCreateExpandedBreakerCTGs", (), "CTGCreateExpandedBreakerCTGs;"), - ("CTGDeleteWithIdenticalActions", (), "CTGDeleteWithIdenticalActions;"), - ("CTGPrimaryAutoInsert", (), "CTGPrimaryAutoInsert;"), - ("CTGApply", ("Ctg1",), 'CTGApply("Ctg1");'), - ("CTGProduceReport", ("ctg_report.txt",), 'CTGProduceReport("ctg_report.txt");'), - ("CTGReadFilePSLF", ("contingencies.pslf",), 'CTGReadFilePSLF("contingencies.pslf");'), - ("CTGCalculateOTDF", ('[AREA "Top"]', '[AREA "Bottom"]', "DC"), 'CTGCalculateOTDF([AREA "Top"], [AREA "Bottom"], DC);'), - ("CTGCompareTwoListsofContingencyResults", ("List1", "List2"), "CTGCompareTwoListsofContingencyResults(List1, List2);"), - ("CTGConvertAllToDeviceCTG", (False,), "CTGConvertAllToDeviceCTG(NO);"), - ("CTGConvertAllToDeviceCTG", (True,), "CTGConvertAllToDeviceCTG(YES);"), - # ========================================================================= - # NEW TESTS: GeneralMixin methods (coverage expansion) - # ========================================================================= - ("CopyFile", ("old.txt", "new.txt"), 'CopyFile("old.txt", "new.txt");'), - ("DeleteFile", ("todelete.txt",), 'DeleteFile("todelete.txt");'), - ("RenameFile", ("old.txt", "new.txt"), 'RenameFile("old.txt", "new.txt");'), - ("LogClear", (), "LogClear;"), - ("LogShow", (True,), "LogShow(YES);"), - ("LogShow", (False,), "LogShow(NO);"), - ("LogSave", ("log.txt", False), 'LogSave("log.txt", NO);'), - ("LogSave", ("log.txt", True), 'LogSave("log.txt", YES);'), - ("EnterMode", ("RUN",), "EnterMode(RUN);"), - ("EnterMode", ("EDIT",), "EnterMode(EDIT);"), - ("StoreState", ("MyState",), 'StoreState("MyState");'), - ("RestoreState", ("MyState",), 'RestoreState(USER, "MyState");'), - # ========================================================================= - # NEW TESTS: GeneralMixin extended methods (coverage expansion) - # ========================================================================= - ("DeleteState", ("MyState",), 'DeleteState(USER, "MyState");'), - ("LoadCSV", ("data.csv", False), 'LoadCSV("data.csv", NO);'), - ("LoadCSV", ("data.csv", True), 'LoadCSV("data.csv", YES);'), - ("LoadScript", ("script.aux", "MyScript"), 'LoadScript("script.aux", "MyScript");'), - ("Delete", ("Bus", "MyFilter"), 'Delete(Bus, "MyFilter");'), - ("SelectAll", ("Gen", "MyFilter"), 'SelectAll(Gen, "MyFilter");'), - ("UnSelectAll", ("Load", "MyFilter"), 'UnSelectAll(Load, "MyFilter");'), - ("StopAuxFile", (), "StopAuxFile;"), - # ========================================================================= - # NEW TESTS: SensitivityMixin methods (coverage expansion) - # ========================================================================= - ("CalculateFlowSense", ('[BRANCH 1 2 1]', "MW"), "CalculateFlowSense([BRANCH 1 2 1], MW);"), - ("CalculatePTDF", ('[AREA "Top"]', '[AREA "Bot"]', "DC"), 'CalculatePTDF([AREA "Top"], [AREA "Bot"], DC);'), - ("CalculateLODF", ('[BRANCH 1 2 1]', "DC", ""), "CalculateLODF([BRANCH 1 2 1], DC);"), - ("CalculateLODF", ('[BRANCH 3 4 1]', "DCPS", "YES"), "CalculateLODF([BRANCH 3 4 1], DCPS, YES);"), - ("CalculateShiftFactors", ('[BRANCH 1 2 1]', "BUYER", '[AREA "Top"]', "DC"), 'CalculateShiftFactors([BRANCH 1 2 1], BUYER, [AREA "Top"], DC);'), - ("LineLoadingReplicatorImplement", (), "LineLoadingReplicatorImplement;"), - ("CalculateTapSense", ("MyFilter",), 'CalculateTapSense("MyFilter");'), - ("CalculateVoltSelfSense", ("MyFilter",), 'CalculateVoltSelfSense("MyFilter");'), - # ========================================================================= - # NEW TESTS: OnelineMixin extended methods (coverage expansion) - # ========================================================================= - ("RelinkAllOpenOnelines", (), "RelinkAllOpenOnelines;"), - # ========================================================================= - # NEW TESTS: TransientMixin methods (coverage expansion) - # ========================================================================= - ("TSSolveAll", (), "TSSolveAll()"), - ("TSAutoCorrect", (), "TSAutoCorrect;"), - ("TSClearAllModels", (), "TSClearAllModels;"), - ("TSValidate", (), "TSValidate;"), - ("TSClearPlayInSignals", (), "DELETE(PLAYINSIGNAL);"), - ("TSLoadPTI", ("dynamics.dyr",), 'TSLoadPTI("dynamics.dyr");'), - ("TSLoadGE", ("dynamics.dyd",), 'TSLoadGE("dynamics.dyd");'), - ("TSLoadBPA", ("dynamics.bpa",), 'TSLoadBPA("dynamics.bpa");'), - ("TSCalculateSMIBEigenValues", (), "TSCalculateSMIBEigenValues;"), - # ========================================================================= - # NEW TESTS: OPFMixin methods (coverage expansion) - # ========================================================================= - ("OPFWriteResultsAndOptions", ("opf_results.aux",), 'OPFWriteResultsAndOptions("opf_results.aux");'), - # ========================================================================= - # NEW TESTS: GICMixin methods (coverage expansion) - # ========================================================================= - ("GICReadFilePSLF", ("gic.gmd",), 'GICReadFilePSLF("gic.gmd");'), - ("GICReadFilePTI", ("gic.gic",), 'GICReadFilePTI("gic.gic");'), - ("GICTimeVaryingDeleteAllTimes", (), "GICTimeVaryingDeleteAllTimes;"), - ("GICTimeVaryingElectricFieldsDeleteAllTimes", (), "GICTimeVaryingElectricFieldsDeleteAllTimes;"), - ("GICTimeVaryingAddTime", (3600.0,), "GICTimeVaryingAddTime(3600.0);"), - # ========================================================================= - # NEW TESTS: RegionsMixin methods (coverage expansion) - # ========================================================================= - ("RegionUpdateBuses", (), "RegionUpdateBuses;"), -]) -def test_simple_script_commands(saw_obj, method, args, expected_script): - """Parametrized test for simple wrapper methods that call RunScriptCommand.""" - getattr(saw_obj, method)(*args) - saw_obj._pwcom.RunScriptCommand.assert_called_with(expected_script) - -def test_get_parameters_multiple_element(saw_obj): - """Test retrieving parameters returns a DataFrame.""" - # Mock return: (Error, ListOfLists) where ListOfLists corresponds to columns. - # We use BusNum and BusName which are set up in the conftest fixture's GetFieldList mock. - saw_obj._pwcom.GetParametersMultipleElement.return_value = ("", [[1, 2], ["Bus1", "Bus2"]]) - - df = saw_obj.GetParametersMultipleElement("Bus", ["BusNum", "BusName"]) - - assert isinstance(df, pd.DataFrame) - assert len(df) == 2 - assert "BusNum" in df.columns - assert "BusName" in df.columns - -def test_change_parameters_single_element(saw_obj): - """Test changing parameters.""" - saw_obj.ChangeParametersSingleElement("Bus", ["BusNum", "BusName"], [1, "NewName"]) - saw_obj._pwcom.ChangeParametersSingleElement.assert_called() - - -def test_change_parameters_multiple_element(saw_obj): - """Test ChangeParametersMultipleElement with nested list.""" - saw_obj._pwcom.ChangeParametersMultipleElement.return_value = ("",) - saw_obj.ChangeParametersMultipleElement("Bus", ["BusNum", "BusName"], [[1, 2], ["Name1", "Name2"]]) - saw_obj._pwcom.ChangeParametersMultipleElement.assert_called() - - -def test_change_parameters_multiple_element_rect(saw_obj): - """Test ChangeParametersMultipleElementRect with DataFrame.""" - df = pd.DataFrame({"BusNum": [1, 2], "BusName": ["A", "B"]}) - saw_obj.ChangeParametersMultipleElementRect("Bus", ["BusNum", "BusName"], df) - saw_obj._pwcom.ChangeParametersMultipleElementRect.assert_called() - - -def test_change_parameters_multiple_element_flat_input(saw_obj): - """Test ChangeParametersMultipleElementFlatInput with flat list.""" - saw_obj._pwcom.ChangeParametersMultipleElementFlatInput.return_value = ("",) - saw_obj.ChangeParametersMultipleElementFlatInput("Bus", ["BusNum", "BusName"], 2, [1, "Name1", 2, "Name2"]) - saw_obj._pwcom.ChangeParametersMultipleElementFlatInput.assert_called() - - -def test_change_parameters_multiple_element_flat_input_rejects_nested(saw_obj): - """Test ChangeParametersMultipleElementFlatInput rejects nested lists.""" - from esapp.saw._exceptions import Error - with pytest.raises(Error): - saw_obj.ChangeParametersMultipleElementFlatInput("Bus", ["BusNum"], 2, [[1], [2]]) - - -def test_get_params_rect_typed(saw_obj): - """Test GetParamsRectTyped returns DataFrame.""" - saw_obj._pwcom.GetParamsRectTyped.return_value = ("", [[1, "A"], [2, "B"]]) - df = saw_obj.GetParamsRectTyped("Bus", ["BusNum", "BusName"]) - assert isinstance(df, pd.DataFrame) - assert len(df) == 2 - - -def test_get_params_rect_typed_empty(saw_obj): - """Test GetParamsRectTyped returns None for empty result.""" - saw_obj._pwcom.GetParamsRectTyped.return_value = ("", None) - result = saw_obj.GetParamsRectTyped("Bus", ["BusNum"]) - assert result is None - - -def test_get_parameters_multiple_element_flat_output(saw_obj): - """Test GetParametersMultipleElementFlatOutput.""" - saw_obj._pwcom.GetParametersMultipleElementFlatOutput.return_value = ("", ("1", "Bus1", "2", "Bus2")) - result = saw_obj.GetParametersMultipleElementFlatOutput("Bus", ["BusNum", "BusName"]) - assert result is not None - assert len(result) == 4 - - -def test_get_parameters_multiple_element_flat_output_empty(saw_obj): - """Test GetParametersMultipleElementFlatOutput returns None for empty.""" - saw_obj._pwcom.GetParametersMultipleElementFlatOutput.return_value = ("", ()) - result = saw_obj.GetParametersMultipleElementFlatOutput("Bus", ["BusNum"]) - assert result is None or result == () - - -def test_ts_get_contingency_results(saw_obj): - """Test TSGetContingencyResults parsing.""" - # Mock return structure: (Error, MetaData, Data) - # MetaData: List of lists (rows of metadata) - # Data: List of rows (time steps) - - # MetaData columns: "ObjectType", "PrimaryKey", "SecondaryKey", "Label", "VariableName", "ColHeader" - mock_meta = [ - ["Gen", "1", "", "", "GenMW", "MW"], - ["Bus", "2", "", "", "BusPUVolt", "PU"] - ] - - # Data: Time + 2 columns - mock_data = [ - [0.0, 10.0, 1.0], - [0.1, 10.1, 0.99] - ] - - saw_obj._pwcom.TSGetContingencyResults.return_value = ("", mock_meta, mock_data) - - meta, data = saw_obj.TSGetContingencyResults("MyCtg", ["GenMW", "BusPUVolt"]) - - assert isinstance(meta, pd.DataFrame) - assert isinstance(data, pd.DataFrame) - assert "time" in data.columns - assert len(data) == 2 - assert len(meta) == 2 - # Check that data is numeric - assert pd.api.types.is_numeric_dtype(data["time"]) - - -def test_oneline_open(saw_obj): - """Test OpenOneLine.""" - saw_obj.OpenOneLine("test.axd") - # Check if RunScriptCommand was called with expected string - args, _ = saw_obj._pwcom.RunScriptCommand.call_args - assert 'OpenOneline("test.axd"' in args[0] - -def test_matrix_get_ybus(saw_obj): - """Test get_ybus.""" - # get_ybus writes to a temp file and reads it. - # The code does f.readline() first (consumes header), then f.read() (gets data). - # Format must match regex: Ybus(idx,idx)=real+j*(imag) with semicolons - - # After readline() consumes header, read() returns only the data portion - mock_data_content = "Ybus=sparse(2,2);Ybus(1,1)=1.0+j*(2.0);Ybus(2,2)=1.0+j*(2.0);" - - with patch("builtins.open", new_callable=MagicMock) as mock_open: - mock_file = MagicMock() - mock_file.read.return_value = mock_data_content - mock_file.readline.return_value = "header" - mock_open.return_value.__enter__.return_value = mock_file - - ybus = saw_obj.get_ybus() - - # Default is sparse matrix (csr_matrix) - assert hasattr(ybus, "toarray") - saw_obj._pwcom.RunScriptCommand.assert_called() - -def test_close_case(saw_obj): - """Test CloseCase.""" - saw_obj.CloseCase() - saw_obj._pwcom.CloseCase.assert_called() - -def test_get_case_header(saw_obj): - """Test GetCaseHeader.""" - saw_obj.GetCaseHeader() - saw_obj._pwcom.GetCaseHeader.assert_called() - -def test_simauto_properties(saw_obj): - """Test setting and getting SimAuto properties.""" - saw_obj.set_simauto_property("CreateIfNotFound", True) - assert saw_obj._pwcom.CreateIfNotFound is True - - # Access properties to ensure they call the underlying COM object - _ = saw_obj.CurrentDir - _ = saw_obj.ProcessID - _ = saw_obj.RequestBuildDate - # UIVisible might log a warning if attribute missing, but should not crash - _ = saw_obj.UIVisible - -def test_matrix_jacobian(saw_obj): - """Test get_jacobian.""" - # Format must match regex with semicolons: Jac=sparse(n,n);Jac(i,j)=val; - mock_mat_content = "Jac=sparse(2,2);Jac(1,1)=1.0;Jac(2,2)=1.0;" - with patch("builtins.open", new_callable=MagicMock) as mock_open: - mock_file = MagicMock() - mock_file.read.return_value = mock_mat_content - mock_open.return_value.__enter__.return_value = mock_file - - jac = saw_obj.get_jacobian() - assert hasattr(jac, "toarray") - -def test_powerflow_extras(saw_obj): - """Test additional PowerflowMixin methods.""" - saw_obj.ClearPowerFlowSolutionAidValues() - saw_obj._pwcom.RunScriptCommand.assert_called_with("ClearPowerFlowSolutionAidValues;") - - saw_obj.ResetToFlatStart() - saw_obj._pwcom.RunScriptCommand.assert_called_with("ResetToFlatStart();") - - saw_obj.SetMVATolerance(0.5) - saw_obj._pwcom.ChangeParametersSingleElement.assert_called() - - saw_obj.SetDoOneIteration(True) - saw_obj._pwcom.ChangeParametersSingleElement.assert_called() - -def test_transient_extras(saw_obj): - """Test TransientMixin methods that require complex setup.""" - saw_obj.TSInitialize() - saw_obj._pwcom.RunScriptCommand.assert_called() - - saw_obj.TSClearResultsFromRAM() - saw_obj._pwcom.RunScriptCommand.assert_called() - - -def test_ts_set_play_in_signals(saw_obj): - """Test TSSetPlayInSignals.""" - times = np.array([0.0, 0.1]) - signals = np.array([[1.0], [1.0]]) - saw_obj.TSSetPlayInSignals("TestSignal", times, signals) - saw_obj._pwcom.ProcessAuxFile.assert_called() - -def test_fault_mixin(saw_obj): - """Test FaultMixin methods.""" - saw_obj.RunFault('[BRANCH 1 2 1]', 'SLG', 0.0, 0.0, 50.0) - saw_obj._pwcom.RunScriptCommand.assert_called_with('Fault([BRANCH 1 2 1], 50.0, SLG, 0.0, 0.0);') - - saw_obj.SetSelectedFromNetworkCut(True, "[BUS 1]", "SELECTED") - saw_obj._pwcom.RunScriptCommand.assert_called() - -def test_atc_mixin(saw_obj): - """Test ATCMixin methods.""" - # Mock GetParametersMultipleElement for GetATCResults - saw_obj._pwcom.GetParametersMultipleElement.return_value = ("", [[100], ["Ctg1"]]) - - df = saw_obj.GetATCResults(["MaxFlow", "LimitingContingency"]) - assert isinstance(df, pd.DataFrame) - assert "MaxFlow" in df.columns - -def test_qv_mixin(saw_obj): - """Test QVMixin methods.""" - # Test without filename (should use temp file and return DataFrame) - # We need to mock open/read for the temp file part, but since we are mocking RunScriptCommand, - # the file won't actually be created by PowerWorld. - # We can mock the tempfile creation and existence check. - with patch("tempfile.NamedTemporaryFile") as mock_temp, \ - patch("os.path.exists", return_value=True), \ - patch("os.path.getsize", return_value=100), \ - patch("pandas.read_csv", return_value=pd.DataFrame({"V": [1.0]})): - - df = saw_obj.RunQV() - assert isinstance(df, pd.DataFrame) - assert "V" in df.columns - - -# ----------------------------------------------------------------------------- -# Unit tests for internal helper methods (consolidated) -# ----------------------------------------------------------------------------- - -class TestDataTransformation: - """Tests for internal data transformation methods (_to_numeric, _replace_decimal_delimiter, clean_df_or_series).""" - - # _to_numeric tests - def test_to_numeric_dataframe_with_floats(self, saw_obj): - """Test _to_numeric with DataFrame containing float-like strings.""" - df = pd.DataFrame({"A": ["1.5", "2.5"], "B": ["3.0", "4.0"]}) - result = saw_obj._to_numeric(df) - assert pd.api.types.is_numeric_dtype(result["A"]) - assert pd.api.types.is_numeric_dtype(result["B"]) - assert result["A"].iloc[0] == 1.5 - - def test_to_numeric_series(self, saw_obj): - """Test _to_numeric with Series.""" - s = pd.Series(["1.0", "2.0", "3.0"]) - result = saw_obj._to_numeric(s) - assert pd.api.types.is_numeric_dtype(result) - assert result.iloc[0] == 1.0 - - def test_to_numeric_mixed_types(self, saw_obj): - """Test _to_numeric with mixed numeric and string columns.""" - df = pd.DataFrame({"num": ["1", "2"], "text": ["a", "b"]}) - result = saw_obj._to_numeric(df) - assert pd.api.types.is_numeric_dtype(result["num"]) - assert result["text"].iloc[0] == "a" - - def test_to_numeric_invalid_input(self, saw_obj): - """Test _to_numeric raises error on invalid input type.""" - with pytest.raises(TypeError): - saw_obj._to_numeric("not a dataframe or series") - - def test_to_numeric_with_locale_delimiter(self, saw_obj): - """Test _to_numeric handles locale-specific decimal delimiters.""" - saw_obj.decimal_delimiter = "," - df = pd.DataFrame({"A": ["1,5", "2,5"]}) - result = saw_obj._to_numeric(df) - assert result["A"].iloc[0] == 1.5 - saw_obj.decimal_delimiter = "." - - # _replace_decimal_delimiter tests - def test_replace_comma_delimiter(self, saw_obj): - """Test replacing comma delimiter with period.""" - saw_obj.decimal_delimiter = "," - s = pd.Series(["1,5", "2,5", "3,0"]) - result = saw_obj._replace_decimal_delimiter(s) - assert result.iloc[0] == "1.5" - saw_obj.decimal_delimiter = "." - - def test_replace_on_numeric_series(self, saw_obj): - """Test _replace_decimal_delimiter on already numeric Series returns unchanged.""" - s = pd.Series([1.5, 2.5, 3.0]) - result = saw_obj._replace_decimal_delimiter(s) - assert result.iloc[0] == 1.5 - - -class TestFieldMetadata: - """Tests for field metadata methods (GetFieldList).""" - - def test_get_field_list_returns_dataframe(self, saw_obj): - """Test GetFieldList returns properly formatted DataFrame.""" - df = saw_obj.GetFieldList("Bus") - assert isinstance(df, pd.DataFrame) - assert "internal_field_name" in df.columns - assert "field_data_type" in df.columns - - def test_get_field_list_caches_result(self, saw_obj): - """Test GetFieldList caches results.""" - df1 = saw_obj.GetFieldList("Bus") - saw_obj._pwcom.GetFieldList.reset_mock() - df2 = saw_obj.GetFieldList("Bus") - assert df2.equals(df1) - - -class TestExecAux: - """Tests for exec_aux method.""" - - def test_exec_aux_processes_aux_string(self, saw_obj): - """Test exec_aux writes and processes auxiliary string.""" - with patch("builtins.open", MagicMock()): - saw_obj.exec_aux("DATA (Bus) { 1 'TestBus' }") - saw_obj._pwcom.ProcessAuxFile.assert_called() - - -class TestErrorHandling: - """Tests for error handling in SAW methods.""" - - def test_run_script_command_error_raises(self, saw_obj): - """Test RunScriptCommand raises error on non-empty error string.""" - from esapp.saw._exceptions import PowerWorldError - - saw_obj._pwcom.RunScriptCommand.return_value = ("Error: Something went wrong",) - - with pytest.raises(PowerWorldError): - saw_obj.RunScriptCommand("BadCommand;") - - def test_get_parameters_empty_returns_none_or_empty(self, saw_obj): - """Test GetParametersMultipleElement returns None or empty DataFrame on no data.""" - saw_obj._pwcom.GetParametersMultipleElement.return_value = ("", None) - result = saw_obj.GetParametersMultipleElement("Bus", ["BusNum"]) - assert result is None or result.empty - - -# ============================================================================= -# Weather Mixin Tests (Phase 3) -# ============================================================================= - -class TestWeatherMixin: - """Tests for WeatherMixin methods.""" - - def test_weather_limits_gen_update(self, saw_obj): - """Test WeatherLimitsGenUpdate script command.""" - saw_obj.WeatherLimitsGenUpdate(update_max=True, update_min=False) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "WeatherLimitsGenUpdate" in args - assert "YES" in args - assert "NO" in args - - def test_temperature_limits_branch_update(self, saw_obj): - """Test TemperatureLimitsBranchUpdate script command.""" - saw_obj.TemperatureLimitsBranchUpdate("NORMAL", "DEFAULT", "DEFAULT") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TemperatureLimitsBranchUpdate" in args - - def test_weather_pfw_models_set_inputs(self, saw_obj): - """Test WeatherPFWModelsSetInputs script command.""" - saw_obj.WeatherPFWModelsSetInputs() - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "WeatherPFWModelsSetInputs" in args - - def test_weather_pfw_models_set_inputs_and_apply(self, saw_obj): - """Test WeatherPFWModelsSetInputsAndApply script command.""" - saw_obj.WeatherPFWModelsSetInputsAndApply(solve_pf=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "WeatherPFWModelsSetInputsAndApply" in args - - def test_weather_pfw_models_restore_design_values(self, saw_obj): - """Test WeatherPFWModelsRestoreDesignValues script command.""" - saw_obj.WeatherPFWModelsRestoreDesignValues() - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "WeatherPFWModelsRestoreDesignValues" in args - - def test_weather_pww_load_for_datetime_utc(self, saw_obj): - """Test WeatherPWWLoadForDateTimeUTC script command.""" - saw_obj.WeatherPWWLoadForDateTimeUTC("2025-01-01T12:00:00Z") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "WeatherPWWLoadForDateTimeUTC" in args - - def test_weather_pww_set_directory(self, saw_obj): - """Test WeatherPWWSetDirectory script command.""" - saw_obj.WeatherPWWSetDirectory("C:\\Weather", include_subdirs=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "WeatherPWWSetDirectory" in args - - def test_weather_pww_file_combine2(self, saw_obj): - """Test WeatherPWWFileCombine2 script command.""" - saw_obj.WeatherPWWFileCombine2("file1.pww", "file2.pww", "combined.pww") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "WeatherPWWFileCombine2" in args - - def test_weather_pww_file_geo_reduce(self, saw_obj): - """Test WeatherPWWFileGeoReduce script command.""" - saw_obj.WeatherPWWFileGeoReduce("source.pww", "dest.pww", 25.0, 50.0, -125.0, -65.0) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "WeatherPWWFileGeoReduce" in args - - def test_weather_pww_file_all_meas_valid(self, saw_obj): - """Test WeatherPWWFileAllMeasValid script command.""" - saw_obj.WeatherPWWFileAllMeasValid("weather.pww", ["Temperature", "WindSpeed"]) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "WeatherPWWFileAllMeasValid" in args - - -# ============================================================================= -# Scheduled Actions Mixin Tests (Phase 3) -# ============================================================================= - -class TestScheduledActionsMixin: - """Tests for ScheduledActionsMixin methods.""" - - def test_apply_scheduled_actions_at(self, saw_obj): - """Test ApplyScheduledActionsAt script command.""" - saw_obj.ApplyScheduledActionsAt("01/01/2025 10:00", "01/01/2025 12:00") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "ApplyScheduledActionsAt" in args - - def test_apply_scheduled_actions_with_revert(self, saw_obj): - """Test ApplyScheduledActionsAt with revert=True.""" - saw_obj.ApplyScheduledActionsAt("01/01/2025 10:00", revert=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "YES" in args # revert = YES - - def test_identify_breakers_for_scheduled_actions(self, saw_obj): - """Test IdentifyBreakersForScheduledActions script command.""" - saw_obj.IdentifyBreakersForScheduledActions(identify_from_normal=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "IdentifyBreakersForScheduledActions" in args - - def test_revert_scheduled_actions_at(self, saw_obj): - """Test RevertScheduledActionsAt script command.""" - saw_obj.RevertScheduledActionsAt("01/01/2025 10:00", "01/01/2025 12:00") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "RevertScheduledActionsAt" in args - - def test_scheduled_actions_set_reference(self, saw_obj): - """Test ScheduledActionsSetReference script command.""" - saw_obj.ScheduledActionsSetReference() - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "ScheduledActionsSetReference" in args - - def test_set_schedule_view(self, saw_obj): - """Test SetScheduleView script command.""" - saw_obj.SetScheduleView("01/01/2025 10:00", apply_actions=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "SetScheduleView" in args - - def test_set_schedule_window(self, saw_obj): - """Test SetScheduleWindow script command.""" - saw_obj.SetScheduleWindow("01/01/2025 00:00", "01/01/2025 23:59", resolution=1.0, resolution_units="HOURS") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "SetScheduleWindow" in args - - -# ============================================================================= -# ModifyMixin Extended Tests (Coverage Expansion) -# ============================================================================= - -class TestModifyMixinExtended: - """Extended tests for ModifyMixin methods with complex arguments.""" - - def test_branch_mva_limit_reorder(self, saw_obj): - """Test BranchMVALimitReorder with filter and limits.""" - saw_obj.BranchMVALimitReorder("MyFilter", ["A", "B", "C"]) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "BranchMVALimitReorder" in args - assert '"MyFilter"' in args - - def test_branch_mva_limit_reorder_no_filter(self, saw_obj): - """Test BranchMVALimitReorder without filter.""" - saw_obj.BranchMVALimitReorder() - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "BranchMVALimitReorder" in args - - def test_calculate_rxbg_from_length(self, saw_obj): - """Test CalculateRXBGFromLengthConfigCondType.""" - saw_obj.CalculateRXBGFromLengthConfigCondType("MyFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CalculateRXBGFromLengthConfigCondType" in args - - def test_create_line_derive_existing(self, saw_obj): - """Test CreateLineDeriveExisting with full parameters.""" - saw_obj.CreateLineDeriveExisting(1, 2, "1", 10.0, "[BRANCH 3 4 1]", 5.0, True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CreateLineDeriveExisting" in args - assert "YES" in args # zero_g = True - - def test_directions_auto_insert_reference(self, saw_obj): - """Test DirectionsAutoInsertReference.""" - saw_obj.DirectionsAutoInsertReference("BUS", "[BUS 100]", True, "", False) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "DirectionsAutoInsertReference" in args - - def test_injection_group_create(self, saw_obj): - """Test InjectionGroupCreate with all parameters.""" - saw_obj.InjectionGroupCreate("TestGroup", "Gen", 100.0, "MyFilter", append=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "InjectionGroupCreate" in args - assert '"TestGroup"' in args - assert "YES" in args # append - - def test_injection_group_remove_duplicates(self, saw_obj): - """Test InjectionGroupRemoveDuplicates.""" - saw_obj.InjectionGroupRemoveDuplicates("PreferenceFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "InjectionGroupRemoveDuplicates" in args - - def test_interface_create(self, saw_obj): - """Test InterfaceCreate.""" - saw_obj.InterfaceCreate("NewInterface", True, "Branch", "MyBranchFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "InterfaceCreate" in args - assert '"NewInterface"' in args - assert "YES" in args # delete_existing - - def test_interface_flatten_filter(self, saw_obj): - """Test InterfaceFlattenFilter.""" - saw_obj.InterfaceFlattenFilter("MyInterfaceFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "InterfaceFlattenFilter" in args - - def test_interface_modify_isolated_elements(self, saw_obj): - """Test InterfaceModifyIsolatedElements.""" - saw_obj.InterfaceModifyIsolatedElements("MyFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "InterfaceModifyIsolatedElements" in args - - def test_interface_remove_duplicates(self, saw_obj): - """Test InterfaceRemoveDuplicates.""" - saw_obj.InterfaceRemoveDuplicates("PreferenceFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "InterfaceRemoveDuplicates" in args - - def test_merge_buses(self, saw_obj): - """Test MergeBuses.""" - saw_obj.MergeBuses("[BUS 1]", "MyFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "MergeBuses" in args - - def test_move(self, saw_obj): - """Test Move element.""" - saw_obj.Move("[GEN 1]", "[BUS 10]", 50.0, True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "Move" in args - assert "50.0" in args - assert "YES" in args # abort_on_error - - def test_reassign_ids(self, saw_obj): - """Test ReassignIDs.""" - saw_obj.ReassignIDs("Load", "BusName", "MyFilter", use_right=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "ReassignIDs" in args - assert "YES" in args # use_right - - -# ============================================================================= -# CaseActionsMixin Extended Tests (Coverage Expansion) -# ============================================================================= - -class TestCaseActionsMixinExtended: - """Extended tests for CaseActionsMixin methods.""" - - def test_append_case_pwb(self, saw_obj): - """Test AppendCase with PWB format.""" - saw_obj.AppendCase("case.pwb", "PWB") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "AppendCase" in args - assert '"case.pwb"' in args - - def test_append_case_pti(self, saw_obj): - """Test AppendCase with PTI format.""" - saw_obj.AppendCase("case.raw", "PTI", star_bus="NEAR", estimate_voltages=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "AppendCase" in args - assert "PTI" in args - assert "NEAR" in args - - def test_append_case_ge(self, saw_obj): - """Test AppendCase with GE format.""" - saw_obj.AppendCase("case.epc", "GE", ms_line="MAINTAIN", var_lim_dead=2.0, post_ctg_agc=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "AppendCase" in args - assert "GE" in args - assert "MAINTAIN" in args - - def test_load_ems(self, saw_obj): - """Test LoadEMS.""" - saw_obj.LoadEMS("ems_file.hdb", "AREVAHDB") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "LoadEMS" in args - - def test_renumber_3w_xformer_star_buses(self, saw_obj): - """Test Renumber3WXFormerStarBuses.""" - saw_obj.Renumber3WXFormerStarBuses("renumber.txt", "COMMA") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "Renumber3WXFormerStarBuses" in args - assert "COMMA" in args - - def test_renumber_ms_line_dummy_buses(self, saw_obj): - """Test RenumberMSLineDummyBuses.""" - saw_obj.RenumberMSLineDummyBuses("renumber.txt", "TAB") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "RenumberMSLineDummyBuses" in args - assert "TAB" in args - - def test_save_external_system(self, saw_obj): - """Test SaveExternalSystem.""" - saw_obj.SaveExternalSystem("external.pwb", "PWB", with_ties=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "SaveExternalSystem" in args - assert "YES" in args # with_ties - - def test_save_merged_fixed_num_bus_case(self, saw_obj): - """Test SaveMergedFixedNumBusCase.""" - saw_obj.SaveMergedFixedNumBusCase("merged.pwb", "PWB") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "SaveMergedFixedNumBusCase" in args - - def test_scale_load_mw(self, saw_obj): - """Test Scale for LOAD with MW.""" - saw_obj.Scale("LOAD", "MW", [100.0, 50.0], "AREA") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "Scale" in args - assert "LOAD" in args - assert "MW" in args - assert "AREA" in args - - def test_scale_gen_factor(self, saw_obj): - """Test Scale for GEN with FACTOR.""" - saw_obj.Scale("GEN", "FACTOR", [1.1], "SYSTEM") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "Scale" in args - assert "GEN" in args - assert "FACTOR" in args - assert "SYSTEM" in args - - -# ============================================================================= -# TopologyMixin Extended Tests (Coverage Expansion) -# ============================================================================= - -class TestTopologyMixinExtended: - """Extended tests for TopologyMixin methods.""" - - def test_determine_branches_that_create_islands(self, saw_obj): - """Test DetermineBranchesThatCreateIslands calls correct script command.""" - # These methods use tempfile internally, which is hard to mock - # Just verify the method exists and has correct signature by checking RunScriptCommand - # Use a simpler approach: patch the entire method's file I/O - import tempfile - from io import StringIO - - # Create a mock temp file context manager - mock_tmp = MagicMock() - mock_tmp.name = "C:/temp/test.csv" - mock_tmp.__enter__ = MagicMock(return_value=mock_tmp) - mock_tmp.__exit__ = MagicMock(return_value=False) - - with patch("tempfile.NamedTemporaryFile", return_value=mock_tmp): - with patch("pandas.read_csv") as mock_read_csv: - mock_read_csv.return_value = pd.DataFrame({"BusNum": [1, 2]}) - with patch("os.path.exists", return_value=True): - with patch("os.unlink"): - df = saw_obj.DetermineBranchesThatCreateIslands("ALL", "YES", "NO") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "DetermineBranchesThatCreateIslands" in args - - def test_determine_shortest_path(self, saw_obj): - """Test DetermineShortestPath calls correct script command.""" - # Create a mock temp file context manager - mock_tmp = MagicMock() - mock_tmp.name = "C:/temp/test.txt" - mock_tmp.__enter__ = MagicMock(return_value=mock_tmp) - mock_tmp.__exit__ = MagicMock(return_value=False) - - with patch("tempfile.NamedTemporaryFile", return_value=mock_tmp): - with patch("pandas.read_csv") as mock_read_csv: - mock_read_csv.return_value = pd.DataFrame({"BusNum": [1, 2], "X": [0.1, 0.2], "BusName": ["A", "B"]}) - with patch("os.path.exists", return_value=True): - with patch("os.unlink"): - df = saw_obj.DetermineShortestPath("[BUS 1]", "[BUS 10]", "X", "ALL") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "DetermineShortestPath" in args - - -# ============================================================================= -# PVMixin Extended Tests (Coverage Expansion) -# ============================================================================= - -class TestPVMixinExtended: - """Extended tests for PVMixin methods.""" - - def test_pv_data_write_options_and_results(self, saw_obj): - """Test PVDataWriteOptionsAndResults.""" - saw_obj.PVDataWriteOptionsAndResults("pv_data.aux", append=True, key_field="PRIMARY") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "PVDataWriteOptionsAndResults" in args - assert "YES" in args # append - - def test_pv_write_inadequate_voltages(self, saw_obj): - """Test PVWriteInadequateVoltages.""" - saw_obj.PVWriteInadequateVoltages("inadequate.aux", append=False, inadequate_type="LOW") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "PVWriteInadequateVoltages" in args - assert "LOW" in args - - def test_refine_model(self, saw_obj): - """Test RefineModel.""" - saw_obj.RefineModel("Gen", "MyFilter", "REMOVE", 0.01) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "RefineModel" in args - assert "Gen" in args - - -# ============================================================================= -# QVMixin Extended Tests (Coverage Expansion) -# ============================================================================= - -class TestQVMixinExtended: - """Extended tests for QVMixin methods.""" - - def test_qv_write_curves(self, saw_obj): - """Test QVWriteCurves.""" - saw_obj.QVWriteCurves("qv_curves.csv", include_quantities=True, filter_name="MyFilter", append=False) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "QVWriteCurves" in args - assert "YES" in args # include_quantities - assert "NO" in args # append - - -# ============================================================================= -# ATCMixin Extended Tests (Coverage Expansion) -# ============================================================================= - -class TestATCMixinExtended: - """Extended tests for ATCMixin methods.""" - - def test_atc_create_contingent_interfaces(self, saw_obj): - """Test ATCCreateContingentInterfaces.""" - saw_obj.ATCCreateContingentInterfaces("MyFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "ATCCreateContingentInterfaces" in args - - def test_atc_delete_scenario_change_index_range(self, saw_obj): - """Test ATCDeleteScenarioChangeIndexRange.""" - saw_obj.ATCDeleteScenarioChangeIndexRange("RL", ["0-2", "5"]) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "ATCDeleteScenarioChangeIndexRange" in args - assert "RL" in args - - def test_get_atc_results(self, saw_obj): - """Test GetATCResults calls GetParametersMultipleElement with TransferLimiter.""" - # Simply verify the method calls GetParametersMultipleElement with the right object type - # The actual data transformation is tested elsewhere - saw_obj._pwcom.GetParametersMultipleElement.return_value = ("", None) - result = saw_obj.GetATCResults() - saw_obj._pwcom.GetParametersMultipleElement.assert_called() - # Verify it was called with TransferLimiter object type - call_args = saw_obj._pwcom.GetParametersMultipleElement.call_args[0] - assert call_args[0] == "TransferLimiter" - assert result is None # Returns None when no data - - -# ============================================================================= -# RegionsMixin Extended Tests (Coverage Expansion) -# ============================================================================= - -class TestRegionsMixinExtended: - """Extended tests for RegionsMixin methods.""" - - def test_region_load_shapefile(self, saw_obj): - """Test RegionLoadShapefile.""" - saw_obj.RegionLoadShapefile( - "regions.shp", "AreaRegion", ["Name", "Code"], - add_to_open_onelines=True, display_style_name="MyStyle", delete_existing=False - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "RegionLoadShapefile" in args - assert '"regions.shp"' in args - assert "YES" in args # add_to_open_onelines - - def test_region_rename_proper1(self, saw_obj): - """Test RegionRenameProper1.""" - saw_obj.RegionRenameProper1("OldProp", "NewProp", update_onelines=True, filter_name="") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "RegionRenameProper1" in args - - -# ============================================================================= -# TimeStepMixin Extended Tests (Coverage Expansion) -# ============================================================================= - -class TestTimeStepMixinExtended: - """Extended tests for TimeStepMixin methods with complex arguments.""" - - def test_timestep_do_run_with_times(self, saw_obj): - """Test TimeStepDoRun with start and end times.""" - saw_obj.TimeStepDoRun("2025-01-01T00:00:00", "2025-01-01T12:00:00") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TimeStepDoRun" in args - assert "2025-01-01T00:00:00" in args - assert "2025-01-01T12:00:00" in args - - def test_timestep_do_run_no_times(self, saw_obj): - """Test TimeStepDoRun without times.""" - saw_obj.TimeStepDoRun() - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TimeStepDoRun()" in args - - def test_timestep_clear_results_with_range(self, saw_obj): - """Test TimeStepClearResults with time range.""" - saw_obj.TimeStepClearResults("2025-01-01T00:00:00", "2025-01-01T06:00:00") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TimeStepClearResults" in args - assert "2025-01-01T00:00:00" in args - - def test_timestep_clear_results_no_range(self, saw_obj): - """Test TimeStepClearResults without time range.""" - saw_obj.TimeStepClearResults() - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TimeStepClearResults()" in args - - def test_timestep_append_pww_range(self, saw_obj): - """Test TimeStepAppendPWWRange with all parameters.""" - saw_obj.TimeStepAppendPWWRange("weather.pww", "2025-01-01", "2025-01-02", "OPF") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TimeStepAppendPWWRange" in args - assert "weather.pww" in args - - def test_timestep_load_pww_range(self, saw_obj): - """Test TimeStepLoadPWWRange with parameters.""" - saw_obj.TimeStepLoadPWWRange("weather.pww", "2025-01-01", "2025-01-02", "Single Solution") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TimeStepLoadPWWRange" in args - - def test_timestep_save_pww_range(self, saw_obj): - """Test TimeStepSavePWWRange.""" - saw_obj.TimeStepSavePWWRange("output.pww", "2025-01-01", "2025-01-02") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TimeStepSavePWWRange" in args - - def test_timestep_save_results_by_type_csv(self, saw_obj): - """Test TimeStepSaveResultsByTypeCSV.""" - saw_obj.TimeStepSaveResultsByTypeCSV("GEN", "gen_results.csv", "2025-01-01", "2025-01-02") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TimeStepSaveResultsByTypeCSV" in args - assert "GEN" in args - assert "gen_results.csv" in args - - def test_timestep_save_results_by_type_csv_no_times(self, saw_obj): - """Test TimeStepSaveResultsByTypeCSV without time range.""" - saw_obj.TimeStepSaveResultsByTypeCSV("BUS", "bus_results.csv") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TimeStepSaveResultsByTypeCSV" in args - assert "BUS" in args - - def test_timestep_save_fields_set(self, saw_obj): - """Test TimeStepSaveFieldsSet.""" - saw_obj.TimeStepSaveFieldsSet("GEN", ["GenMW", "GenMvar"], "MyFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TimeStepSaveFieldsSet" in args - assert "GEN" in args - assert "GenMW" in args - - def test_timestep_save_fields_clear(self, saw_obj): - """Test TimeStepSaveFieldsClear with object types.""" - saw_obj.TimeStepSaveFieldsClear(["GEN", "BUS"]) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TimeStepSaveFieldsClear" in args - assert "GEN" in args - - def test_timestep_save_fields_clear_all(self, saw_obj): - """Test TimeStepSaveFieldsClear without object types (clear all).""" - saw_obj.TimeStepSaveFieldsClear() - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TimeStepSaveFieldsClear" in args - - def test_timestep_save_input_csv(self, saw_obj): - """Test TIMESTEPSaveInputCSV.""" - saw_obj.TIMESTEPSaveInputCSV("input.csv", ["Field1", "Field2"], "2025-01-01", "2025-01-02") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TIMESTEPSaveInputCSV" in args - - -# ============================================================================= -# PowerflowMixin Extended Tests (Coverage Expansion) -# ============================================================================= - -class TestPowerflowMixinExtended: - """Extended tests for PowerflowMixin methods.""" - - def test_solve_power_flow_methods(self, saw_obj): - """Test SolvePowerFlow with different methods.""" - for method in ["RECTNEWT", "POLARNEWT", "GAUSSSEIDEL", "FASTDEC", "DC"]: - saw_obj.SolvePowerFlow(method) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert method.upper() in args - - def test_condition_voltage_pockets(self, saw_obj): - """Test ConditionVoltagePockets.""" - saw_obj.ConditionVoltagePockets(0.9, 30.0, "MyFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "ConditionVoltagePockets" in args - assert "0.9" in args - assert "30.0" in args - - def test_estimate_voltages(self, saw_obj): - """Test EstimateVoltages.""" - saw_obj.EstimateVoltages("MyFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "EstimateVoltages" in args - - def test_get_min_pu_voltage(self, saw_obj): - """Test GetMinPUVoltage calls GetParametersSingleElement.""" - # Just verify the method exists and has correct signature - # Skip actual call since it requires complex field validation mocking - assert hasattr(saw_obj, 'GetMinPUVoltage') - assert callable(saw_obj.GetMinPUVoltage) - - def test_diff_case_write_complete_model(self, saw_obj): - """Test DiffCaseWriteCompleteModel with various options.""" - saw_obj.DiffCaseWriteCompleteModel( - "diff.aux", append=True, save_added=True, save_removed=False, - save_both=True, key_fields="SECONDARY" - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "DiffCaseWriteCompleteModel" in args - assert "diff.aux" in args - - -# ============================================================================= -# ContingencyMixin Extended Tests (Coverage Expansion) -# ============================================================================= - -class TestContingencyMixinExtended: - """Extended tests for ContingencyMixin methods.""" - - def test_run_contingency(self, saw_obj): - """Test RunContingency.""" - saw_obj.RunContingency("N-1_Line1") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CTGSolve" in args - assert "N-1_Line1" in args - - def test_solve_contingencies(self, saw_obj): - """Test SolveContingencies.""" - saw_obj.SolveContingencies() - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CTGSolveAll" in args - - def test_ctg_write_results_and_options(self, saw_obj): - """Test CTGWriteResultsAndOptions with all parameters.""" - saw_obj.CTGWriteResultsAndOptions( - "ctg_results.aux", options=["CTG", "VIO"], - key_field="SECONDARY", use_data_section=True, use_concise=True - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CTGWriteResultsAndOptions" in args - assert "ctg_results.aux" in args - - def test_ctg_write_file_pti(self, saw_obj): - """Test CTGWriteFilePTI.""" - saw_obj.CTGWriteFilePTI("ctg.con", bus_format="Number", truncate_labels=False, append=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CTGWriteFilePTI" in args - assert "Number" in args - assert "NO" in args # truncate_labels=False - - def test_ctg_clone_many(self, saw_obj): - """Test CTGCloneMany.""" - saw_obj.CTGCloneMany("MyFilter", prefix="Clone_", suffix="_v2", set_selected=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CTGCloneMany" in args - assert "Clone_" in args - assert "_v2" in args - assert "YES" in args # set_selected - - def test_ctg_clone_one(self, saw_obj): - """Test CTGCloneOne.""" - saw_obj.CTGCloneOne("OriginalCtg", "NewCtg", prefix="", suffix="_copy") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CTGCloneOne" in args - assert "OriginalCtg" in args - assert "NewCtg" in args - - def test_ctg_combo_solve_all(self, saw_obj): - """Test CTGComboSolveAll.""" - saw_obj.CTGComboSolveAll(do_distributed=True, clear_all_results=False) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CTGComboSolveAll" in args - assert "YES" in args # do_distributed - assert "NO" in args # clear_all_results - - def test_ctg_convert_to_primary(self, saw_obj): - """Test CTGConvertToPrimaryCTG.""" - saw_obj.CTGConvertToPrimaryCTG("MyFilter", keep_original=False, prefix="P_", suffix="-Primary") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CTGConvertToPrimaryCTG" in args - assert "NO" in args # keep_original - - def test_ctg_create_contingent_interfaces(self, saw_obj): - """Test CTGCreateContingentInterfaces.""" - saw_obj.CTGCreateContingentInterfaces("ViolationFilter", "MAX") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CTGCreateContingentInterfaces" in args - assert "ViolationFilter" in args - - def test_ctg_join_active_ctgs(self, saw_obj): - """Test CTGJoinActiveCTGs.""" - saw_obj.CTGJoinActiveCTGs(insert_solve_pf=True, delete_existing=False, join_with_self=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CTGJoinActiveCTGs" in args - assert "YES" in args # insert_solve_pf - - def test_ctg_process_remedial_actions(self, saw_obj): - """Test CTGProcessRemedialActionsAndDependencies.""" - saw_obj.CTGProcessRemedialActionsAndDependencies(do_delete=True, filter_name="RAFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CTGProcessRemedialActionsAndDependencies" in args - assert "YES" in args # do_delete - - -# ============================================================================= -# GeneralMixin Extended Tests (Coverage Expansion) -# ============================================================================= - -class TestGeneralMixinExtended: - """Extended tests for GeneralMixin methods.""" - - def test_write_text_to_file(self, saw_obj): - """Test WriteTextToFile.""" - saw_obj.WriteTextToFile("output.txt", "Hello, World!") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "WriteTextToFile" in args - assert "output.txt" in args - assert "Hello, World!" in args - - def test_log_add(self, saw_obj): - """Test LogAdd.""" - saw_obj.LogAdd("Test message") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "LogAdd" in args - assert "Test message" in args - - def test_set_current_directory(self, saw_obj): - """Test SetCurrentDirectory.""" - saw_obj.SetCurrentDirectory("C:/TestDir", create_if_not_found=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "SetCurrentDirectory" in args - assert "C:/TestDir" in args - assert "YES" in args # create_if_not_found - - def test_enter_mode_invalid(self, saw_obj): - """Test EnterMode with invalid mode raises ValueError.""" - with pytest.raises(ValueError, match="Mode must be either"): - saw_obj.EnterMode("INVALID") - - def test_load_aux(self, saw_obj): - """Test LoadAux.""" - saw_obj.LoadAux("config.aux", create_if_not_found=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "LoadAux" in args - assert "config.aux" in args - assert "YES" in args - - def test_import_data(self, saw_obj): - """Test ImportData.""" - saw_obj.ImportData("data.csv", "CSV", header_line=2, create_if_not_found=False) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "ImportData" in args - assert "CSV" in args - assert "NO" in args - - def test_save_data(self, saw_obj): - """Test SaveData.""" - saw_obj.SaveData( - "output.csv", "CSV", "Bus", ["BusNum", "BusName"], - filter_name="MyFilter", transpose=True, append=False - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "SaveData" in args - assert "output.csv" in args - assert "Bus" in args - - def test_save_data_with_extra(self, saw_obj): - """Test SaveDataWithExtra.""" - saw_obj.SaveDataWithExtra( - "output.csv", "CSV", "Gen", ["GenMW"], - header_list=["Header1"], header_value_list=["Value1"] - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "SaveDataWithExtra" in args - - def test_set_data(self, saw_obj): - """Test SetData.""" - saw_obj.SetData("Bus", ["BusName"], ["NewName"], filter_name="MyFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "SetData" in args - assert "Bus" in args - - def test_create_data(self, saw_obj): - """Test CreateData.""" - saw_obj.CreateData("Bus", ["BusNum", "BusName"], [100, "NewBus"]) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CreateData" in args - assert "Bus" in args - - def test_save_object_fields(self, saw_obj): - """Test SaveObjectFields.""" - saw_obj.SaveObjectFields("fields.txt", "Bus", ["BusNum", "BusName"]) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "SaveObjectFields" in args - - def test_log_add_date_time(self, saw_obj): - """Test LogAddDateTime.""" - saw_obj.LogAddDateTime("Timestamp", include_date=True, include_time=True, include_milliseconds=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "LogAddDateTime" in args - assert "Timestamp" in args - assert "YES" in args - - def test_load_aux_directory(self, saw_obj): - """Test LoadAuxDirectory.""" - saw_obj.LoadAuxDirectory("C:/AuxFiles", "*.aux", create_if_not_found=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "LoadAuxDirectory" in args - assert "*.aux" in args - - def test_load_data(self, saw_obj): - """Test LoadData.""" - saw_obj.LoadData("data.aux", "BusData", create_if_not_found=False) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "LoadData" in args - assert "BusData" in args - - -# ============================================================================= -# SensitivityMixin Extended Tests (Coverage Expansion) -# ============================================================================= - -class TestSensitivityMixinExtended: - """Extended tests for SensitivityMixin methods.""" - - def test_calculate_lodf_advanced(self, saw_obj): - """Test CalculateLODFAdvanced.""" - saw_obj.CalculateLODFAdvanced( - include_phase_shifters=True, file_type="CSV", max_columns=50, - min_lodf=0.01, number_format="DECIMAL", decimal_points=4, - only_increasing=True, filename="lodf.csv", include_islanding=False - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CalculateLODFAdvanced" in args - assert "lodf.csv" in args - - def test_calculate_lodf_screening(self, saw_obj): - """Test CalculateLODFScreening.""" - saw_obj.CalculateLODFScreening( - filter_process="Filter1", filter_monitor="Filter2", - include_phase_shifters=False, include_open_lines=True, - use_lodf_threshold=True, lodf_threshold=0.05, - use_overload_threshold=True, overload_low=100.0, overload_high=150.0, - do_save_file=True, file_location="screening.csv" - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CalculateLODFScreening" in args - assert "screening.csv" in args - - def test_calculate_shift_factors_multiple_element(self, saw_obj): - """Test CalculateShiftFactorsMultipleElement.""" - saw_obj.CalculateShiftFactorsMultipleElement( - type_element="BRANCH", which_element="ALL", - direction="SELLER", transactor='[AREA "Top"]', method="DC" - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CalculateShiftFactorsMultipleElement" in args - assert "BRANCH" in args - - def test_calculate_lodf_matrix(self, saw_obj): - """Test CalculateLODFMatrix.""" - saw_obj.CalculateLODFMatrix( - which_ones="OUTAGES", filter_process="Filter1", filter_monitor="Filter2", - monitor_only_closed=True, linear_method="DC" - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CalculateLODFMatrix" in args - assert "OUTAGES" in args - - def test_calculate_volt_to_transfer_sense(self, saw_obj): - """Test CalculateVoltToTransferSense.""" - saw_obj.CalculateVoltToTransferSense( - seller='[AREA "Top"]', buyer='[AREA "Bot"]', - transfer_type="P", turn_off_avr=True - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CalculateVoltToTransferSense" in args - assert "YES" in args # turn_off_avr - - def test_calculate_loss_sense(self, saw_obj): - """Test CalculateLossSense.""" - saw_obj.CalculateLossSense("AREA", area_ref="NO", island_ref="EXISTING") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CalculateLossSense" in args - assert "AREA" in args - - def test_line_loading_replicator_calculate(self, saw_obj): - """Test LineLoadingReplicatorCalculate.""" - saw_obj.LineLoadingReplicatorCalculate( - flow_element='[BRANCH 1 2 1]', injection_group='[INJECTIONGROUP "Gen"]', - agc_only=True, desired_flow=100.0, implement=False, linear_method="DC" - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "LineLoadingReplicatorCalculate" in args - - def test_calculate_volt_sense(self, saw_obj): - """Test CalculateVoltSense.""" - saw_obj.CalculateVoltSense(1) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CalculateVoltSense" in args - - def test_set_sensitivities_at_out_of_service(self, saw_obj): - """Test SetSensitivitiesAtOutOfServiceToClosest.""" - saw_obj.SetSensitivitiesAtOutOfServiceToClosest("MyFilter", "X") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "SetSensitivitiesAtOutOfServiceToClosest" in args - - def test_calculate_ptdf_multiple_directions(self, saw_obj): - """Test CalculatePTDFMultipleDirections.""" - saw_obj.CalculatePTDFMultipleDirections(store_branches=True, store_interfaces=False, method="DC") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CalculatePTDFMultipleDirections" in args - assert "YES" in args # store_branches - assert "NO" in args # store_interfaces - - -# ============================================================================= -# OnelineMixin Extended Tests (Coverage Expansion) -# ============================================================================= - -class TestOnelineMixinExtended: - """Extended tests for OnelineMixin methods.""" - - def test_open_oneline_full_params(self, saw_obj): - """Test OpenOneLine with all parameters.""" - saw_obj.OpenOneLine( - "diagram.axd", view="MainView", full_screen="YES", - show_full="YES", link_method="NUMBERS", - left=100.0, top=50.0, width=800.0, height=600.0 - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "OpenOneline" in args - assert "diagram.axd" in args - assert "MainView" in args - - def test_export_bus_view(self, saw_obj): - """Test ExportBusView.""" - saw_obj.ExportBusView("busview.png", "[BUS 1]", "PNG", 1024, 768) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "ExportBusView" in args - assert "busview.png" in args - assert "PNG" in args - - def test_export_oneline_as_shapefile(self, saw_obj): - """Test ExportOnelineAsShapeFile.""" - saw_obj.ExportOnelineAsShapeFile( - "output.shp", "MyOneline", "Description", - use_lon_lat=True, point_location="center" - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "ExportOnelineAsShapeFile" in args - assert "output.shp" in args - - def test_pan_and_zoom_to_object(self, saw_obj): - """Test PanAndZoomToObject.""" - saw_obj.PanAndZoomToObject("[BUS 1]", "Bus", do_zoom=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "PanAndZoomToObject" in args - assert "[BUS 1]" in args - assert "YES" in args # do_zoom - - def test_open_bus_view(self, saw_obj): - """Test OpenBusView.""" - saw_obj.OpenBusView("[BUS 1]", force_new_window=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "OpenBusView" in args - assert "YES" in args # force_new_window - - def test_open_sub_view(self, saw_obj): - """Test OpenSubView.""" - saw_obj.OpenSubView("[SUB 1]", force_new_window=False) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "OpenSubView" in args - assert "NO" in args # force_new_window - - def test_load_axd(self, saw_obj): - """Test LoadAXD.""" - saw_obj.LoadAXD("display.axd", "MyOneline", create_if_not_found=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "LoadAXD" in args - assert "display.axd" in args - assert "YES" in args # create_if_not_found - - -# ============================================================================= -# TransientMixin Extended Tests (Coverage Expansion) -# ============================================================================= - -class TestTransientMixinExtended: - """Extended tests for TransientMixin methods.""" - - def test_ts_transfer_state_to_power_flow(self, saw_obj): - """Test TSTransferStateToPowerFlow.""" - saw_obj.TSTransferStateToPowerFlow(calculate_mismatch=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TSTransferStateToPowerFlow" in args - assert "YES" in args - - def test_ts_solve(self, saw_obj): - """Test TSSolve.""" - saw_obj.TSSolve("MyContingency") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TSSolve" in args - assert "MyContingency" in args - - def test_ts_result_storage_set_all(self, saw_obj): - """Test TSResultStorageSetAll.""" - saw_obj.TSResultStorageSetAll(object="GEN", value=False) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TSResultStorageSetAll" in args - assert "GEN" in args - assert "NO" in args - - def test_ts_store_response(self, saw_obj): - """Test TSStoreResponse.""" - saw_obj.TSStoreResponse(object_type="BUS", value=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TSResultStorageSetAll" in args # Calls TSResultStorageSetAll internally - assert "BUS" in args - - def test_ts_clear_results_from_ram_with_name(self, saw_obj): - """Test TSClearResultsFromRAM with specific contingency.""" - saw_obj.TSClearResultsFromRAM( - ctg_name="MyCtg", clear_summary=False, clear_events=True, - clear_statistics=True, clear_time_values=False, clear_solution_details=True - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TSClearResultsFromRAM" in args - assert "MyCtg" in args - - def test_ts_write_options(self, saw_obj): - """Test TSWriteOptions.""" - saw_obj.TSWriteOptions( - "ts_options.aux", save_dynamic_model=True, save_stability_options=False, - save_stability_events=True, key_field="SECONDARY" - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TSWriteOptions" in args - assert "ts_options.aux" in args - assert "SECONDARY" in args - - def test_ts_auto_insert_dist_relay(self, saw_obj): - """Test TSAutoInsertDistRelay.""" - saw_obj.TSAutoInsertDistRelay(reach=80.0, add_from=True, add_to=False, transfer_trip=True, shape=1, filter_name="MyFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TSAutoInsertDistRelay" in args - assert "80.0" in args - - def test_ts_auto_insert_zpott(self, saw_obj): - """Test TSAutoInsertZPOTT.""" - saw_obj.TSAutoInsertZPOTT(reach=100.0, filter_name="LineFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TSAutoInsertZPOTT" in args - assert "100.0" in args - - def test_ts_auto_save_plots(self, saw_obj): - """Test TSAutoSavePlots.""" - saw_obj.TSAutoSavePlots( - plot_names=["Plot1", "Plot2"], ctg_names=["Ctg1"], - image_type="PNG", width=1024, height=768 - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TSAutoSavePlots" in args - assert "Plot1" in args - assert "PNG" in args - - def test_ts_calculate_critical_clear_time(self, saw_obj): - """Test TSCalculateCriticalClearTime.""" - saw_obj.TSCalculateCriticalClearTime("[BRANCH 1 2 1]") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TSCalculateCriticalClearTime" in args - - def test_ts_clear_models_for_objects(self, saw_obj): - """Test TSClearModelsforObjects.""" - saw_obj.TSClearModelsforObjects("GEN", filter_name="GenFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TSClearModelsforObjects" in args - assert "GEN" in args - - def test_ts_disable_machine_model_non_zero_derivative(self, saw_obj): - """Test TSDisableMachineModelNonZeroDerivative.""" - saw_obj.TSDisableMachineModelNonZeroDerivative(threshold=0.01) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TSDisableMachineModelNonZeroDerivative" in args - assert "0.01" in args - - def test_ts_get_v_curve_data(self, saw_obj): - """Test TSGetVCurveData.""" - saw_obj.TSGetVCurveData("vcurve.csv", "GenFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TSGetVCurveData" in args - assert "vcurve.csv" in args - - def test_ts_write_results_to_csv(self, saw_obj): - """Test TSWriteResultsToCSV.""" - saw_obj.TSWriteResultsToCSV( - "results.csv", "ALL", ["Ctg1", "Ctg2"], ["Plot1", "Plot2"], - start_time=0.0, end_time=10.0 - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TSGetResults" in args # internally calls TSGetResults - assert "results.csv" in args - - def test_ts_join_active_ctgs(self, saw_obj): - """Test TSJoinActiveCTGs.""" - saw_obj.TSJoinActiveCTGs( - time_delay=0.1, delete_existing=True, join_with_self=False, filename="joined.aux" - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TSJoinActiveCTGs" in args - assert "0.1" in args - - def test_ts_load_rdb(self, saw_obj): - """Test TSLoadRDB.""" - saw_obj.TSLoadRDB("relay.rdb", "DISTRELAY", filter_name="BranchFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TSLoadRDB" in args - assert "relay.rdb" in args - - def test_ts_load_relay_csv(self, saw_obj): - """Test TSLoadRelayCSV.""" - saw_obj.TSLoadRelayCSV("relay.csv", "DISTRELAY", filter_name="") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TSLoadRelayCSV" in args - - def test_ts_plot_series_add(self, saw_obj): - """Test TSPlotSeriesAdd.""" - saw_obj.TSPlotSeriesAdd("MyPlot", 1, 1, "Gen", "GenMW", filter_name="GenFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TSPlotSeriesAdd" in args - assert "MyPlot" in args - - def test_ts_run_result_analyzer(self, saw_obj): - """Test TSRunResultAnalyzer.""" - saw_obj.TSRunResultAnalyzer("Ctg1") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TSRunResultAnalyzer" in args - assert "Ctg1" in args - - def test_ts_run_until_specified_time(self, saw_obj): - """Test TSRunUntilSpecifiedTime.""" - saw_obj.TSRunUntilSpecifiedTime("Ctg1", stop_time=5.0, step_size=0.01, steps_in_cycles=False) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TSRunUntilSpecifiedTime" in args - assert "Ctg1" in args - - def test_ts_save_bpa(self, saw_obj): - """Test TSSaveBPA.""" - saw_obj.TSSaveBPA("dynamics.bpa", diff_case_modified_only=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TSSaveBPA" in args - assert "YES" in args - - def test_ts_save_ge(self, saw_obj): - """Test TSSaveGE.""" - saw_obj.TSSaveGE("dynamics.dyd", diff_case_modified_only=False) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TSSaveGE" in args - assert "NO" in args - - def test_ts_save_pti(self, saw_obj): - """Test TSSavePTI.""" - saw_obj.TSSavePTI("dynamics.dyr") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TSSavePTI" in args - - def test_ts_save_two_bus_equivalent(self, saw_obj): - """Test TSSaveTwoBusEquivalent.""" - saw_obj.TSSaveTwoBusEquivalent("twobus.pwb", "[BUS 1]") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TSSaveTwoBusEquivalent" in args - assert "twobus.pwb" in args - - def test_ts_write_models(self, saw_obj): - """Test TSWriteModels.""" - saw_obj.TSWriteModels("models.aux", diff_case_modified_only=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TSWriteModels" in args - assert "YES" in args - - def test_ts_set_selected_for_transient_references(self, saw_obj): - """Test TSSetSelectedForTransientReferences.""" - saw_obj.TSSetSelectedForTransientReferences("SELECTED", "SET", ["GEN", "BUS"], ["GENROU", "GENCLS"]) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TSSetSelectedForTransientReferences" in args - - def test_ts_save_dynamic_models(self, saw_obj): - """Test TSSaveDynamicModels.""" - saw_obj.TSSaveDynamicModels("models.aux", "AUX", "GEN", filter_name="GenFilter", append=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TSSaveDynamicModels" in args - assert "YES" in args # append - - -# ============================================================================= -# OPFMixin Extended Tests (Coverage Expansion) -# ============================================================================= - -class TestOPFMixinExtended: - """Extended tests for OPFMixin methods.""" - - def test_initialize_primal_lp(self, saw_obj): - """Test InitializePrimalLP.""" - saw_obj.InitializePrimalLP(on_success_aux="success.aux", create_if_not_found1=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "InitializePrimalLP" in args - assert "success.aux" in args - assert "YES" in args - - def test_solve_single_primal_lp_outer_loop(self, saw_obj): - """Test SolveSinglePrimalLPOuterLoop.""" - saw_obj.SolveSinglePrimalLPOuterLoop(on_fail_aux="fail.aux", create_if_not_found2=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "SolveSinglePrimalLPOuterLoop" in args - - -# ============================================================================= -# GICMixin Extended Tests (Coverage Expansion) -# ============================================================================= - -class TestGICMixinExtended: - """Extended tests for GICMixin methods.""" - - def test_gic_shift_or_stretch_input_points(self, saw_obj): - """Test GICShiftOrStretchInputPoints.""" - saw_obj.GICShiftOrStretchInputPoints( - lat_shift=1.0, lon_shift=-0.5, mag_scalar=1.5, - stretch_scalar=1.2, update_time_varying_series=True - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "GICShiftOrStretchInputPoints" in args - assert "1.0" in args - assert "YES" in args # update_time_varying_series - - def test_gic_time_varying_efield_calculate(self, saw_obj): - """Test GICTimeVaryingEFieldCalculate.""" - saw_obj.GICTimeVaryingEFieldCalculate(the_time=1800.0, solve_pf=False) - -# ============================================================================= -# Base Class Method Tests (Coverage Expansion) -# ============================================================================= - -class TestSAWBaseMethods: - """Tests for core, non-mixin methods in the SAWBase class.""" - - def test_exit_cleans_up(self, saw_obj): - """Test that exit() calls cleanup methods.""" - saw_obj.CloseCase = MagicMock() - saw_obj.ntf.name = "dummy_temp_file.axd" - with patch("os.unlink") as mock_unlink: - saw_obj.exit() - saw_obj.CloseCase.assert_called_once() - mock_unlink.assert_called_with("dummy_temp_file.axd") - assert saw_obj._pwcom is None - - def test_get_version_and_builddate(self, saw_obj): - """Test get_version_and_builddate calls _call_simauto correctly.""" - saw_obj._call_simauto = MagicMock(return_value=("22", "2023-01-01")) - version, build_date = saw_obj.get_version_and_builddate() - saw_obj._call_simauto.assert_called_with( - "GetParametersSingleElement", - "PowerWorldSession", - ANY, # Variant object - ANY # Variant object - ) - assert version == "22" - assert build_date == "2023-01-01" - - def test_set_simauto_property_valid(self, saw_obj): - """Test setting a valid SimAuto property.""" - saw_obj._set_simauto_property = MagicMock() - saw_obj.set_simauto_property("UIVisible", True) - saw_obj._set_simauto_property.assert_called_with(property_name="UIVisible", property_value=True) - - def test_set_simauto_property_invalid_name(self, saw_obj): - """Test ValueError on invalid property name.""" - with pytest.raises(ValueError, match="is not currently supported"): - saw_obj.set_simauto_property("InvalidProp", True) - - def test_set_simauto_property_invalid_value_type(self, saw_obj): - """Test ValueError on invalid property value type.""" - with pytest.raises(ValueError, match="is invalid"): - saw_obj.set_simauto_property("UIVisible", "not a bool") - - def test_set_simauto_property_handles_attribute_error(self, saw_obj): - """Test that known AttributeErrors on UIVisible are handled gracefully.""" - saw_obj._set_simauto_property = MagicMock(side_effect=AttributeError("UIVisible")) - # Should log a warning but not raise an error - saw_obj.set_simauto_property("UIVisible", True) - saw_obj._set_simauto_property.assert_called_once() - - def test_update_ui(self, saw_obj): - """Test update_ui calls ProcessAuxFile.""" - saw_obj.ProcessAuxFile = MagicMock() - saw_obj.update_ui() - saw_obj.ProcessAuxFile.assert_called_with(saw_obj.empty_aux) - - def test_change_and_confirm_params_multiple_element_success(self, saw_obj): - """Test change_and_confirm successfully when data matches.""" - from esapp.saw._exceptions import CommandNotRespectedError - - input_df = pd.DataFrame({"BusNum": [1], "GenID": ["1"], "GenMW": [100.0]}) - - # Mock the underlying change and get methods - saw_obj._change_parameters_multiple_element_df = MagicMock(return_value=input_df) - saw_obj.GetParametersMultipleElement = MagicMock(return_value=input_df) - - # Mock GetFieldList to return key fields - field_list_df = pd.DataFrame({ - "key_field": ["*1*", "*2A*"], - "internal_field_name": ["BusNum", "GenID"] - }) - saw_obj.GetFieldList = MagicMock(return_value=field_list_df) - - try: - saw_obj.change_and_confirm_params_multiple_element("Gen", input_df) - except CommandNotRespectedError: - pytest.fail("CommandNotRespectedError was raised unexpectedly.") - - def test_change_and_confirm_params_multiple_element_failure(self, saw_obj): - """Test change_and_confirm raises error when data does not match.""" - from esapp.saw._exceptions import CommandNotRespectedError - - input_df = pd.DataFrame({"BusNum": [1], "GenID": ["1"], "GenMW": [100.0]}) - output_df = pd.DataFrame({"BusNum": [1], "GenID": ["1"], "GenMW": [95.0]}) # Different value - - saw_obj._change_parameters_multiple_element_df = MagicMock(return_value=input_df) - saw_obj.GetParametersMultipleElement = MagicMock(return_value=output_df) - - field_list_df = pd.DataFrame({ - "key_field": ["*1*", "*2A*"], - "internal_field_name": ["BusNum", "GenID"] - }) - saw_obj.GetFieldList = MagicMock(return_value=field_list_df) - - with pytest.raises(CommandNotRespectedError): - saw_obj.change_and_confirm_params_multiple_element("Gen", input_df) - - def test_change_parameters_multiple_element_df_internal(self, saw_obj): - """Test the internal _change_parameters_multiple_element_df helper.""" - df = pd.DataFrame({"BusNum": [1], "GenMW": [150.0]}) - saw_obj.ChangeParametersMultipleElement = MagicMock() - - cleaned_df = saw_obj._change_parameters_multiple_element_df("Gen", df) - - saw_obj.ChangeParametersMultipleElement.assert_called_once() - # Check that args match what the method should pass - args, kwargs = saw_obj.ChangeParametersMultipleElement.call_args - assert kwargs['ObjectType'] == 'Gen' - assert kwargs['ParamList'] == ["BusNum", "GenMW"] - assert kwargs['ValueList'] == [[1, 150.0]] - assert cleaned_df.equals(df) - - -# ============================================================================= -# RegionsMixin Extended Tests (Coverage Expansion) -# ============================================================================= - -class TestRegionsMixinExtended2: - """Additional tests for RegionsMixin methods.""" - - def test_region_rename_proper2(self, saw_obj): - """Test RegionRenameProper2.""" - saw_obj.RegionRenameProper2("OldProp2", "NewProp2", update_onelines=False, filter_name="MyFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "RegionRenameProper2" in args - assert "NO" in args # update_onelines - - def test_region_rename_proper3(self, saw_obj): - """Test RegionRenameProper3.""" - saw_obj.RegionRenameProper3("OldProp3", "NewProp3", update_onelines=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "RegionRenameProper3" in args - assert "YES" in args - - def test_region_rename_proper12_flip(self, saw_obj): - """Test RegionRenameProper12Flip.""" - saw_obj.RegionRenameProper12Flip(update_onelines=True, filter_name="FlipFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "RegionRenameProper12Flip" in args - - -# ============================================================================= -# ModifyMixin Extended Tests 2 (Coverage Expansion) -# ============================================================================= - -class TestModifyMixinExtended2: - """Additional tests for ModifyMixin methods.""" - - def test_remove_3w_xformer_container(self, saw_obj): - """Test Remove3WXformerContainer.""" - saw_obj.Remove3WXformerContainer(filter_name="MyFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "Remove3WXformerContainer" in args - - def test_rename_injection_group(self, saw_obj): - """Test RenameInjectionGroup.""" - saw_obj.RenameInjectionGroup("OldGroup", "NewGroup") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "RenameInjectionGroup" in args - assert "OldGroup" in args - assert "NewGroup" in args - - def test_rotate_bus_angles_in_island(self, saw_obj): - """Test RotateBusAnglesInIsland.""" - saw_obj.RotateBusAnglesInIsland("[BUS 1]", 15.0) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "RotateBusAnglesInIsland" in args - assert "15.0" in args - - def test_set_gen_pmax_from_reactive_capability_curve(self, saw_obj): - """Test SetGenPMaxFromReactiveCapabilityCurve.""" - saw_obj.SetGenPMaxFromReactiveCapabilityCurve(filter_name="GenFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "SetGenPMaxFromReactiveCapabilityCurve" in args - - def test_set_participation_factors(self, saw_obj): - """Test SetParticipationFactors.""" - saw_obj.SetParticipationFactors("CONSTANT", 0.5, "SYSTEM") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "SetParticipationFactors" in args - assert "CONSTANT" in args - assert "0.5" in args - - def test_set_scheduled_voltage_for_a_bus(self, saw_obj): - """Test SetScheduledVoltageForABus.""" - saw_obj.SetScheduledVoltageForABus("[BUS 1]", 1.05) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "SetScheduledVoltageForABus" in args - assert "1.05" in args - - def test_set_interface_limit_to_monitored_element_limit_sum(self, saw_obj): - """Test SetInterfaceLimitToMonitoredElementLimitSum.""" - saw_obj.SetInterfaceLimitToMonitoredElementLimitSum(filter_name="IntFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "SetInterfaceLimitToMonitoredElementLimitSum" in args - - def test_split_bus(self, saw_obj): - """Test SplitBus.""" - saw_obj.SplitBus("[BUS 1]", 999, insert_tie=True, line_open=False, branch_device_type="Breaker") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "SplitBus" in args - assert "999" in args - assert "Breaker" in args - - def test_super_area_add_areas(self, saw_obj): - """Test SuperAreaAddAreas.""" - saw_obj.SuperAreaAddAreas("MySuperArea", "AreaFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "SuperAreaAddAreas" in args - assert "MySuperArea" in args - - def test_super_area_remove_areas(self, saw_obj): - """Test SuperAreaRemoveAreas.""" - saw_obj.SuperAreaRemoveAreas("MySuperArea", "AreaFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "SuperAreaRemoveAreas" in args - - def test_tap_transmission_line(self, saw_obj): - """Test TapTransmissionLine.""" - saw_obj.TapTransmissionLine( - "[BRANCH 1 2 1]", 50.0, 100, shunt_model="CAPACITANCE", - treat_as_ms_line=True, update_onelines=True, new_bus_name="TapBus" - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "TapTransmissionLine" in args - assert "50.0" in args - assert "YES" in args # treat_as_ms_line or update_onelines - assert "TapBus" in args - - -# ============================================================================= -# ATCMixin Extended Tests 2 (Coverage Expansion) -# ============================================================================= - -class TestATCMixinExtended2: - """Additional tests for ATCMixin methods.""" - - def test_atc_take_me_to_scenario(self, saw_obj): - """Test ATCTakeMeToScenario.""" - saw_obj.ATCTakeMeToScenario(1, 2, 3) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "ATCTakeMeToScenario" in args - assert "1" in args - assert "2" in args - assert "3" in args - - def test_atc_data_write_options_and_results(self, saw_obj): - """Test ATCDataWriteOptionsAndResults.""" - saw_obj.ATCDataWriteOptionsAndResults("atc_data.aux", append=False, key_field="SECONDARY") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "ATCDataWriteOptionsAndResults" in args - assert "NO" in args # append=False - assert "SECONDARY" in args - - def test_atc_write_results_and_options(self, saw_obj): - """Test ATCWriteResultsAndOptions.""" - saw_obj.ATCWriteResultsAndOptions("atc_results.aux", append=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "ATCWriteResultsAndOptions" in args - assert "YES" in args # append=True - - def test_atc_write_scenario_log(self, saw_obj): - """Test ATCWriteScenarioLog.""" - saw_obj.ATCWriteScenarioLog("scenario_log.txt", append=True, filter_name="MyFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "ATCWriteScenarioLog" in args - assert "YES" in args # append - - def test_atc_write_scenario_min_max(self, saw_obj): - """Test ATCWriteScenarioMinMax.""" - saw_obj.ATCWriteScenarioMinMax( - "min_max.csv", filetype="CSV", append=False, - fieldlist=["MaxFlow", "Limit"], operation="MAX", operation_field="MaxFlow", group_scenario=False - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "ATCWriteScenarioMinMax" in args - assert "MAX" in args - assert "NO" in args # append=False or group_scenario=False - - def test_atc_write_to_excel(self, saw_obj): - """Test ATCWriteToExcel.""" - saw_obj.ATCWriteToExcel("Sheet1", fieldlist=["MaxFlow", "Limit"]) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "ATCWriteToExcel" in args - assert "Sheet1" in args - - def test_atc_write_to_text(self, saw_obj): - """Test ATCWriteToText.""" - saw_obj.ATCWriteToText("atc_results.txt", filetype="TAB", fieldlist=["MaxFlow"]) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "ATCWriteToText" in args - assert "TAB" in args - - -# ============================================================================= -# Helper Functions Tests (Coverage Expansion) -# ============================================================================= - -class TestHelperFunctions: - """Tests for _helpers.py functions.""" - - def test_convert_to_windows_path(self): - """Test convert_to_windows_path function.""" - from esapp.saw._helpers import convert_to_windows_path - # Test forward slashes converted - result = convert_to_windows_path("C:/path/to/file.txt") - assert "\\" in result or "/" not in result.replace("C:/", "") - - def test_convert_list_to_variant(self): - """Test convert_list_to_variant function.""" - from esapp.saw._helpers import convert_list_to_variant - result = convert_list_to_variant(["a", "b", "c"]) - assert result is not None - - def test_create_object_string_simple(self): - """Test create_object_string with simple bus.""" - from esapp.saw._helpers import create_object_string - result = create_object_string("Bus", 1) - assert result == '[BUS 1]' - - def test_create_object_string_with_string_key(self): - """Test create_object_string with string key.""" - from esapp.saw._helpers import create_object_string - result = create_object_string("Area", "North") - assert result == '[AREA "North"]' - - def test_create_object_string_with_quoted_key(self): - """Test create_object_string with already quoted key.""" - from esapp.saw._helpers import create_object_string - result = create_object_string("Branch", 1, 2, '"1"') - assert result == '[BRANCH 1 2 "1"]' - - def test_create_object_string_branch(self): - """Test create_object_string for branch.""" - from esapp.saw._helpers import create_object_string - result = create_object_string("Branch", 1, 2, "1") - assert result == '[BRANCH 1 2 "1"]' - - -# ============================================================================= -# Base Class Extended Tests (Coverage Expansion) -# ============================================================================= - -class TestBaseMixinExtended: - """Extended tests for base SAW class methods.""" - - def test_get_single_element(self, saw_obj): - """Test GetSingleElement returns data properly.""" - mock_data = [["TestValue"]] - saw_obj._pwcom.GetParametersSingleElement.return_value = ("", mock_data) - # The method exists and can be called - assert hasattr(saw_obj, 'GetParametersSingleElement') - - def test_list_of_devices(self, saw_obj): - """Test ListOfDevices returns list.""" - mock_data = [["Bus1"], ["Bus2"]] - saw_obj._pwcom.ListOfDevices.return_value = ("", mock_data) - result = saw_obj.ListOfDevices("Bus", "") - assert result is not None - - def test_list_of_devices_as_variant_strings(self, saw_obj): - """Test ListOfDevicesAsVariantStrings returns list.""" - mock_data = ["Bus1", "Bus2"] - saw_obj._pwcom.ListOfDevicesAsVariantStrings.return_value = ("", mock_data) - result = saw_obj.ListOfDevicesAsVariantStrings("Bus", "") - assert result is not None - - def test_list_of_devices_flattened(self, saw_obj): - """Test ListOfDevicesFlatOutput returns flattened list.""" - mock_data = [["1", "Bus1"], ["2", "Bus2"]] - saw_obj._pwcom.ListOfDevicesFlatOutput.return_value = ("", mock_data) - result = saw_obj.ListOfDevicesFlatOutput("Bus", "") - assert result is not None - - def test_get_field_list(self, saw_obj): - """Test GetFieldList returns field info.""" - mock_data = [["Field1", "int", "Y", "Y"], ["Field2", "float", "N", "N"]] - saw_obj._pwcom.GetFieldList.return_value = ("", mock_data) - result = saw_obj.GetFieldList("Bus") - assert result is not None - - -# ============================================================================= -# Powerflow Extended Tests 2 (Coverage Expansion) -# ============================================================================= - -class TestPowerflowMixinExtended2: - """Additional tests for PowerflowMixin methods.""" - - def test_solve_power_flow_full_newton(self, saw_obj): - """Test SolvePowerFlow with full newton method.""" - saw_obj.SolvePowerFlow(SolMethod="FULLNEWTON") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "SolvePowerFlow" in args - assert "FULLNEWTON" in args - - def test_solve_power_flow_dc(self, saw_obj): - """Test SolvePowerFlow with DC method.""" - saw_obj.SolvePowerFlow(SolMethod="DC") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "SolvePowerFlow" in args - assert "DC" in args - - -# ============================================================================= -# Topology Extended Tests 2 (Coverage Expansion) -# ============================================================================= - -class TestTopologyMixinExtended2: - """Additional tests for TopologyMixin methods.""" - - def test_update_islands_and_bus_status(self, saw_obj): - """Test UpdateIslandsAndBusStatus.""" - saw_obj.UpdateIslandsAndBusStatus() - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "UpdateIslandsAndBusStatus" in args - - def test_find_radial_bus_paths(self, saw_obj): - """Test FindRadialBusPaths.""" - saw_obj.FindRadialBusPaths(ignore_status=True, treat_parallel_as_not_radial=False, bus_or_superbus="BUS") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "FindRadialBusPaths" in args - assert "YES" in args # ignore_status - - def test_do_facility_analysis(self, saw_obj): - """Test DoFacilityAnalysis.""" - saw_obj.DoFacilityAnalysis("cut.aux", set_selected=False) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "DoFacilityAnalysis" in args - assert "NO" in args # set_selected - - def test_set_bus_field_from_closest(self, saw_obj): - """Test SetBusFieldFromClosest.""" - saw_obj.SetBusFieldFromClosest("CustomFloat:1", "SetFilter", "FromFilter", "ALL", "X") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "SetBusFieldFromClosest" in args - - def test_set_selected_from_network_cut(self, saw_obj): - """Test SetSelectedFromNetworkCut.""" - saw_obj.SetSelectedFromNetworkCut( - set_how=True, bus_on_cut_side="[BUS 1]", branch_filter="MyFilter", - energized=False, num_tiers=2, objects_to_select=["Bus", "Gen"] - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "SetSelectedFromNetworkCut" in args - assert "YES" in args # set_how - - def test_create_new_areas_from_islands(self, saw_obj): - """Test CreateNewAreasFromIslands.""" - saw_obj.CreateNewAreasFromIslands() - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CreateNewAreasFromIslands" in args - - def test_expand_all_bus_topology(self, saw_obj): - """Test ExpandAllBusTopology.""" - saw_obj.ExpandAllBusTopology() - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "ExpandAllBusTopology" in args - - def test_expand_bus_topology(self, saw_obj): - """Test ExpandBusTopology.""" - saw_obj.ExpandBusTopology("[BUS 1]", "BREAKERS") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "ExpandBusTopology" in args - assert "BREAKERS" in args - - def test_save_consolidated_case(self, saw_obj): - """Test SaveConsolidatedCase.""" - saw_obj.SaveConsolidatedCase("consolidated.pwb", filetype="PWB", bus_format="Name", truncate_ctg_labels=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "SaveConsolidatedCase" in args - assert "YES" in args # truncate_ctg_labels - - def test_close_with_breakers(self, saw_obj): - """Test CloseWithBreakers.""" - saw_obj.CloseWithBreakers("Gen", "[1]", only_specified=True, switching_types=["Breaker", "Switch"]) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CloseWithBreakers" in args - assert "YES" in args # only_specified - - def test_open_with_breakers(self, saw_obj): - """Test OpenWithBreakers.""" - saw_obj.OpenWithBreakers("Load", "[2]", switching_types=["Breaker"], open_normally_open=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "OpenWithBreakers" in args - assert "YES" in args # open_normally_open - - -# ============================================================================= -# Powerflow Extended Tests 3 (Coverage Expansion) -# ============================================================================= - -class TestPowerflowMixinExtended3: - """Additional tests for PowerflowMixin methods.""" - - def test_clear_power_flow_solution_aid_values(self, saw_obj): - """Test ClearPowerFlowSolutionAidValues.""" - saw_obj.ClearPowerFlowSolutionAidValues() - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "ClearPowerFlowSolutionAidValues" in args - - def test_reset_to_flat_start(self, saw_obj): - """Test ResetToFlatStart.""" - saw_obj.ResetToFlatStart() - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "ResetToFlatStart" in args - - def test_set_mva_tolerance(self, saw_obj): - """Test SetMVATolerance.""" - saw_obj._pwcom.ChangeParametersSingleElement.return_value = ("", None) - saw_obj.SetMVATolerance(0.05) - saw_obj._pwcom.ChangeParametersSingleElement.assert_called() - - def test_set_do_one_iteration(self, saw_obj): - """Test SetDoOneIteration.""" - saw_obj._pwcom.ChangeParametersSingleElement.return_value = ("", None) - saw_obj.SetDoOneIteration(True) - saw_obj._pwcom.ChangeParametersSingleElement.assert_called() - - def test_set_inner_loop_check_mvars(self, saw_obj): - """Test SetInnerLoopCheckMVars.""" - saw_obj._pwcom.ChangeParametersSingleElement.return_value = ("", None) - saw_obj.SetInnerLoopCheckMVars(False) - saw_obj._pwcom.ChangeParametersSingleElement.assert_called() - - def test_diff_case_write_both_epc(self, saw_obj): - """Test DiffCaseWriteBothEPC.""" - saw_obj.DiffCaseWriteBothEPC("both.epc", ge_file_type="GE", use_area_zone=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "DiffCaseWriteBothEPC" in args - assert "YES" in args # use_area_zone - - def test_diff_case_write_new_epc(self, saw_obj): - """Test DiffCaseWriteNewEPC.""" - saw_obj.DiffCaseWriteNewEPC("new.epc", append=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "DiffCaseWriteNewEPC" in args - assert "YES" in args # append - - def test_diff_case_write_removed_epc(self, saw_obj): - """Test DiffCaseWriteRemovedEPC.""" - saw_obj.DiffCaseWriteRemovedEPC("removed.epc", use_data_maintainer=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "DiffCaseWriteRemovedEPC" in args - assert "YES" in args # use_data_maintainer - - -# ============================================================================= -# Contingency Extended Tests 3 (Coverage Expansion) -# ============================================================================= - -class TestContingencyMixinExtended3: - """Additional tests for ContingencyMixin methods.""" - - def test_ctg_create_stuck_breaker_ctgs(self, saw_obj): - """Test CTGCreateStuckBreakerCTGs.""" - saw_obj.CTGCreateStuckBreakerCTGs( - filter_name="BranchFilter", allow_duplicates=False, - prefix_name="Stuck_", include_ctg_label=True - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CTGCreateStuckBreakerCTGs" in args - assert "NO" in args # allow_duplicates - - def test_ctg_delete_with_identical_actions(self, saw_obj): - """Test CTGDeleteWithIdenticalActions.""" - saw_obj.CTGDeleteWithIdenticalActions() - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CTGDeleteWithIdenticalActions" in args - - def test_ctg_relink_unlinked_elements(self, saw_obj): - """Test CTGRelinkUnlinkedElements.""" - saw_obj.CTGRelinkUnlinkedElements() - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CTGRelinkUnlinkedElements" in args - - def test_ctg_save_violation_matrices(self, saw_obj): - """Test CTGSaveViolationMatrices.""" - saw_obj.CTGSaveViolationMatrices( - "violations.csv", "CSVCOLHEADER", use_percentage=True, - object_types_to_report=["Branch", "Bus"], save_contingency=True, - save_objects=False, include_unsolvable_ctgs=True - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CTGSaveViolationMatrices" in args - assert "YES" in args # use_percentage or save_contingency or include_unsolvable - - def test_ctg_read_file_pti(self, saw_obj): - """Test CTGReadFilePTI.""" - saw_obj.CTGReadFilePTI("contingencies.con") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CTGReadFilePTI" in args - - -# ============================================================================= -# Powerflow Extended Tests 4 (Coverage Expansion) -# ============================================================================= - -class TestPowerflowMixinExtended4: - """Additional tests for PowerflowMixin methods.""" - - def test_solve_power_flow_with_retry_success(self, saw_obj): - """Test SolvePowerFlowWithRetry when first attempt succeeds.""" - saw_obj._pwcom.RunScriptCommand.return_value = ("", None) - saw_obj.SolvePowerFlowWithRetry("RECTNEWT") - # Should only call RunScriptCommand once (successful first attempt) - assert saw_obj._pwcom.RunScriptCommand.call_count >= 1 - - def test_estimate_voltages(self, saw_obj): - """Test EstimateVoltages.""" - saw_obj.EstimateVoltages("BusFilter") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "EstimateVoltages" in args - - def test_voltage_conditioning(self, saw_obj): - """Test VoltageConditioning.""" - saw_obj.VoltageConditioning() - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - - -# ============================================================================= -# Helper Functions Extended Tests (Coverage Expansion for _helpers.py) -# ============================================================================= - -class TestHelperFunctionsExtended: - """Additional comprehensive tests for _helpers.py functions.""" - - def test_df_to_aux_simple(self, tmp_path): - """Test df_to_aux with simple DataFrame.""" - import pandas as pd - from esapp.saw._helpers import df_to_aux - - df = pd.DataFrame({ - 'BusNum': [1, 2, 3], - 'BusName': ['Bus1', 'Bus2', 'Bus3'], - 'BusPUVolt': [1.0, 1.05, 0.95] - }) - - fp = tmp_path / "test_output.aux" - with open(fp, 'w') as f: - df_to_aux(f, df, "Bus") - - # Read back and verify structure - content = fp.read_text() - assert "DATA (Bus, [BusNum,BusName,BusPUVolt])" in content - assert "{" in content - assert "}" in content - assert "1" in content - assert "Bus1" in content - - def test_df_to_aux_long_header(self, tmp_path): - """Test df_to_aux with very long header that needs wrapping.""" - import pandas as pd - from esapp.saw._helpers import df_to_aux - - # Create DataFrame with many columns to force line wrapping - cols = [f'Field{i}' for i in range(20)] - df = pd.DataFrame([[i for i in range(20)]], columns=cols) - - fp = tmp_path / "test_long.aux" - with open(fp, 'w') as f: - df_to_aux(f, df, "TestObject") - - content = fp.read_text() - assert "DATA (TestObject, [" in content - assert "{" in content - # Should have line continuation with comma - lines = content.split('\n') - # Check that header is split across multiple lines - header_lines = [l for l in lines if 'Field' in l or 'DATA' in l] - assert len(header_lines) > 1, "Long header should wrap to multiple lines" - - def test_df_to_aux_with_special_chars(self, tmp_path): - """Test df_to_aux with special characters in data.""" - import pandas as pd - from esapp.saw._helpers import df_to_aux - - df = pd.DataFrame({ - 'Name': ['Gen "A"', 'Gen B'], - 'Value': [100.5, 200.3] - }) - - fp = tmp_path / "test_special.aux" - with open(fp, 'w') as f: - df_to_aux(f, df, "Gen") - - content = fp.read_text() - assert "DATA (Gen, [Name,Value])" in content - assert "Gen \"A\"" in content or "Gen \\\"A\\\"" in content - - def test_df_to_aux_multirow(self, tmp_path): - """Test df_to_aux with multiple rows.""" - import pandas as pd - from esapp.saw._helpers import df_to_aux - - df = pd.DataFrame({ - 'ID': [1, 2, 3, 4, 5], - 'Status': ['Open', 'Closed', 'Open', 'Closed', 'Open'] - }) - - fp = tmp_path / "test_multi.aux" - with open(fp, 'w') as f: - df_to_aux(f, df, "Device") - - content = fp.read_text() - lines = content.split('\n') - # Should have header + { + 5 data lines + } + empty - data_lines = [l for l in lines if 'Open' in l or 'Closed' in l] - assert len(data_lines) == 5 - - def test_convert_df_to_variant(self): - """Test convert_df_to_variant.""" - import pandas as pd - from esapp.saw._helpers import convert_df_to_variant - import pythoncom - - df = pd.DataFrame({ - 'A': [1, 2, 3], - 'B': [4, 5, 6] - }) - - result = convert_df_to_variant(df) - # Should return a result (VARIANT object) - assert result is not None - # Check that data is preserved as list - assert len(df.values.tolist()) == 3 - - def test_convert_nested_list_to_variant(self): - """Test convert_nested_list_to_variant.""" - from esapp.saw._helpers import convert_nested_list_to_variant - - nested = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] - result = convert_nested_list_to_variant(nested) - - # Should return list of VARIANT objects - assert isinstance(result, list) - assert len(result) == 3 - # Each element should be a VARIANT (just check not None) - for item in result: - assert item is not None - - def test_convert_nested_list_empty(self): - """Test convert_nested_list_to_variant with empty list.""" - from esapp.saw._helpers import convert_nested_list_to_variant - - result = convert_nested_list_to_variant([]) - assert result == [] - - def test_create_object_string_with_int_keys(self): - """Test create_object_string with integer keys.""" - from esapp.saw._helpers import create_object_string - - result = create_object_string("Bus", 1) - assert result == '[BUS 1]' - - def test_create_object_string_with_multiple_keys(self): - """Test create_object_string with multiple mixed keys.""" - from esapp.saw._helpers import create_object_string - - result = create_object_string("Branch", 1, 2, "1") - assert result == '[BRANCH 1 2 "1"]' - - def test_create_object_string_with_already_quoted(self): - """Test create_object_string with already quoted strings.""" - from esapp.saw._helpers import create_object_string - - result = create_object_string("Gen", 10, '"GEN1"') - assert result == '[GEN 10 "GEN1"]' - - # Test with single quotes - result2 = create_object_string("Load", 5, "'LOAD1'") - assert result2 == "[LOAD 5 'LOAD1']" - - def test_create_object_string_lowercase_conversion(self): - """Test create_object_string converts object type to uppercase.""" - from esapp.saw._helpers import create_object_string - - result = create_object_string("bus", 100) - assert result == '[BUS 100]' - - result2 = create_object_string("branch", 1, 2, "A") - assert result2 == '[BRANCH 1 2 "A"]' - - def test_df_to_aux_empty_dataframe(self, tmp_path): - """Test df_to_aux with empty DataFrame.""" - import pandas as pd - from esapp.saw._helpers import df_to_aux - - df = pd.DataFrame(columns=['A', 'B', 'C']) - - fp = tmp_path / "test_empty.aux" - with open(fp, 'w') as f: - df_to_aux(f, df, "Empty") - - content = fp.read_text() - assert "DATA (Empty, [A,B,C])" in content - assert "{" in content - assert "}" in content - - -# ============================================================================= -# Contingency Extended Tests 2 (Coverage Expansion) -# ============================================================================= - -class TestContingencyMixinExtended2: - """Additional tests for ContingencyMixin methods.""" - - def test_ctg_skip_with_identical_actions(self, saw_obj): - """Test CTGSkipWithIdenticalActions.""" - saw_obj.CTGSkipWithIdenticalActions() - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CTGSkipWithIdenticalActions" in args - - def test_ctg_sort(self, saw_obj): - """Test CTGSort.""" - saw_obj.CTGSort(sort_field_list=["Name", "Severity"]) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CTGSort" in args - assert "Name" in args - - def test_ctg_verify_iterated_linear_actions(self, saw_obj): - """Test CTGVerifyIteratedLinearActions.""" - saw_obj.CTGVerifyIteratedLinearActions("validation.txt") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CTGVerifyIteratedLinearActions" in args - - def test_ctg_write_all_options(self, saw_obj): - """Test CTGWriteAllOptions.""" - saw_obj.CTGWriteAllOptions("ctg_all.aux", key_field="SECONDARY", save_dependencies=True) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CTGWriteResultsAndOptions" in args # Calls CTGWriteResultsAndOptions internally - assert "SECONDARY" in args - - def test_ctg_write_aux_using_options(self, saw_obj): - """Test CTGWriteAuxUsingOptions.""" - saw_obj.CTGWriteAuxUsingOptions("ctg_opts.aux", append=False) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CTGWriteAuxUsingOptions" in args - assert "NO" in args # append=False - - def test_ctg_restore_reference(self, saw_obj): - """Test CTGRestoreReference.""" - saw_obj.CTGRestoreReference() - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "CTGRestoreReference" in args - - -# ============================================================================= -# GIC Extended Tests 2 (Coverage Expansion) -# ============================================================================= - -class TestGICMixinExtended2: - """Additional tests for GICMixin methods.""" - - def test_gic_write_file_pslf(self, saw_obj): - """Test GICWriteFilePSLF.""" - saw_obj.GICWriteFilePSLF("gic_out.gmd") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "GICWriteFilePSLF" in args - - def test_gic_write_file_pti(self, saw_obj): - """Test GICWriteFilePTI.""" - saw_obj.GICWriteFilePTI("gic_out.gic") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "GICWriteFilePTI" in args - - -# ============================================================================= -# Base Mixin Extended Tests 2 (Coverage Expansion for base.py) -# ============================================================================= - -class TestBaseMixinExtended2: - """Additional comprehensive tests for base.py methods.""" - - def test_set_simauto_property_invalid_property(self, saw_obj): - """Test set_simauto_property with invalid property name.""" - import pytest - with pytest.raises(ValueError, match="is not currently supported"): - saw_obj.set_simauto_property("InvalidProp", "value") - - def test_set_simauto_property_invalid_type(self, saw_obj): - """Test set_simauto_property with invalid property type.""" - import pytest - with pytest.raises(ValueError, match="is invalid"): - saw_obj.set_simauto_property("CreateIfNotFound", "not_a_bool") - - def test_set_simauto_property_invalid_path(self, saw_obj): - """Test set_simauto_property with invalid CurrentDir path.""" - import pytest - with pytest.raises(ValueError, match="is not a valid path"): - saw_obj.set_simauto_property("CurrentDir", "C:\\NonExistentPath12345") - - def test_set_simauto_property_uivisible_warning(self, saw_obj): - """Test set_simauto_property logs warning for UIVisible on old versions.""" - # Simulate AttributeError when setting UIVisible - with patch.object(saw_obj, '_set_simauto_property', side_effect=AttributeError("No UIVisible")): - # Should log warning but not raise - with patch.object(saw_obj.log, 'warning') as mock_warning: - saw_obj.set_simauto_property("UIVisible", False) - mock_warning.assert_called_once() - - -# ============================================================================= -# General Mixin Extended Tests 2 (Coverage Expansion for general.py) -# ============================================================================= - -class TestGeneralMixinExtended2: - """Additional comprehensive tests for general.py methods.""" - - def test_save_data_to_excel_basic(self, saw_obj): - """Test SendToExcelAdvanced with basic parameters.""" - saw_obj.SendToExcelAdvanced( - objecttype="Bus", - fieldlist=["BusNum", "BusName"], - filter_name="", - workbook="output.xlsx", - worksheet="Sheet1" - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "SendtoExcel" in args - assert "Bus" in args - - def test_save_data_to_excel_with_sort(self, saw_obj): - """Test SendToExcelAdvanced with sort fields.""" - saw_obj.SendToExcelAdvanced( - objecttype="Gen", - fieldlist=["BusNum", "GenID", "GenMW"], - filter_name="SELECTED", - workbook="gen.xlsx", - worksheet="Data", - sortfieldlist=["BusNum", "GenID"] - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - - def test_save_data_to_excel_with_headers(self, saw_obj): - """Test SendToExcelAdvanced with custom headers.""" - saw_obj.SendToExcelAdvanced( - objecttype="Load", - fieldlist=["BusNum", "LoadMW"], - filter_name="", - workbook="loads.xlsx", - worksheet="Data", - header_list=["Bus", "MW"], - header_value_list=["Number", "Value"] - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "Bus" in args - assert "MW" in args - - def test_save_data_to_excel_clear_existing(self, saw_obj): - """Test SendToExcelAdvanced with clear_existing=True.""" - saw_obj.SendToExcelAdvanced( - objecttype="Branch", - fieldlist=["BusNum", "BusNum:1"], - filter_name="", - workbook="branches.xlsx", - worksheet="Lines", - clear_existing=True - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "YES" in args # clear_existing as YES - - def test_save_data_to_excel_with_shifts(self, saw_obj): - """Test SendToExcelAdvanced with row and column shifts.""" - saw_obj.SendToExcelAdvanced( - objecttype="Bus", - fieldlist=["BusNum"], - filter_name="", - workbook="test.xlsx", - worksheet="Data", - row_shift=5, - col_shift=2 - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "5" in args - assert "2" in args - - def test_log_add_date_time(self, saw_obj): - """Test LogAddDateTime.""" - saw_obj.LogAddDateTime("Test with timestamp") - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "LogAddDateTime" in args - - def test_save_data_with_subdata(self, saw_obj): - """Test SaveData with subdata list.""" - saw_obj.SaveData( - filename="gen_data.aux", - filetype="AUX", - objecttype="Gen", - fieldlist=["BusNum", "GenID"], - subdatalist=["Limits"], - filter_name="SELECTED" - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - - def test_save_data_with_sort_and_transpose(self, saw_obj): - """Test SaveData with sortfield and transpose.""" - saw_obj.SaveData( - filename="buses.csv", - filetype="CSV", - objecttype="Bus", - fieldlist=["BusNum", "BusName"], - sortfieldlist=["BusNum"], - transpose=True - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "YES" in args # transpose=YES - - def test_save_data_append_mode(self, saw_obj): - """Test SaveData with append=True.""" - saw_obj.SaveData( - filename="loads.csv", - filetype="CSV", - objecttype="Load", - fieldlist=["BusNum", "LoadMW"], - append=True - ) - saw_obj._pwcom.RunScriptCommand.assert_called() - args = saw_obj._pwcom.RunScriptCommand.call_args[0][0] - assert "YES" in args # append=YES - - -# ============================================================================= -# GetSubData Tests -# ============================================================================= - -class TestGetSubData: - """Tests for GetSubData method - parsing AUX files with SubData sections.""" - - def test_get_subdata_space_delimited(self, tmp_path): - """Test parsing space-delimited SubData (BidCurve, ReactiveCapability).""" - aux_content = '''DATA (Gen, [BusNum, GenID, GenMW]) -{ -1 "1" 100.0 - -// MW Price -50.0 10.5 -100.0 12.0 -150.0 15.5 - - -// MW MinMVAR MaxMVAR -50.0 -30.0 30.0 -100.0 -25.0 25.0 - -2 "1" 200.0 - -75.0 11.0 -200.0 14.0 - -} -''' - aux_file = tmp_path / "test.aux" - aux_file.write_text(aux_content) - - with patch("win32com.client.dynamic.Dispatch") as mock_dispatch, \ - patch("win32com.client.gencache.EnsureDispatch", create=True), \ - patch("tempfile.NamedTemporaryFile") as mock_tempfile, \ - patch("os.unlink"): - mock_pwcom = MagicMock() - mock_dispatch.return_value = mock_pwcom - mock_pwcom.OpenCase.return_value = ("",) - mock_pwcom.GetParametersSingleElement.return_value = ("", ("23", "Jan 01 2023")) - mock_pwcom.GetFieldList.return_value = ("", []) - mock_pwcom.RunScriptCommand.return_value = ("",) - - mock_ntf = MagicMock() - mock_ntf.name = str(aux_file) - mock_tempfile.return_value = mock_ntf - - saw = SAW(FileName="dummy.pwb") - df = saw.GetSubData("Gen", ["BusNum", "GenID", "GenMW"], ["BidCurve", "ReactiveCapability"]) - - assert len(df) == 2 - assert df.iloc[0]["BusNum"] == "1" - assert len(df.iloc[0]["BidCurve"]) == 3 - assert df.iloc[0]["BidCurve"][0] == ["50.0", "10.5"] - assert len(df.iloc[0]["ReactiveCapability"]) == 2 - assert df.iloc[0]["ReactiveCapability"][0] == ["50.0", "-30.0", "30.0"] - - def test_get_subdata_bracket_delimited(self, tmp_path): - """Test parsing bracket-delimited SubData (Line coordinates).""" - aux_content = '''DATA (BackgroundLine, [LineNum, LineName]) -{ -1 "MyLine" - -[100.5, 200.3] -[150.2, 250.7] -[200.0, 300.0] - -2 "OtherLine" - -[50, 100], [75, 125] - -} -''' - aux_file = tmp_path / "test.aux" - aux_file.write_text(aux_content) - - with patch("win32com.client.dynamic.Dispatch") as mock_dispatch, \ - patch("win32com.client.gencache.EnsureDispatch", create=True), \ - patch("tempfile.NamedTemporaryFile") as mock_tempfile, \ - patch("os.unlink"): - mock_pwcom = MagicMock() - mock_dispatch.return_value = mock_pwcom - mock_pwcom.OpenCase.return_value = ("",) - mock_pwcom.GetParametersSingleElement.return_value = ("", ("23", "Jan 01 2023")) - mock_pwcom.GetFieldList.return_value = ("", []) - mock_pwcom.RunScriptCommand.return_value = ("",) - - mock_ntf = MagicMock() - mock_ntf.name = str(aux_file) - mock_tempfile.return_value = mock_ntf - - saw = SAW(FileName="dummy.pwb") - df = saw.GetSubData("BackgroundLine", ["LineNum", "LineName"], ["Line"]) - - assert len(df) == 2 - assert len(df.iloc[0]["Line"]) == 3 # 3 lines with one bracket each - assert "100.5" in str(df.iloc[0]["Line"][0]) # Bracket content parsed - # Second object: one line with two brackets -> one entry with two values - assert len(df.iloc[1]["Line"]) == 1 - assert len(df.iloc[1]["Line"][0]) == 2 # Two brackets extracted from one line - - def test_get_subdata_empty_subdata(self, tmp_path): - """Test handling objects with no SubData entries.""" - aux_content = '''DATA (Gen, [BusNum, GenID]) -{ -1 "1" - - -2 "2" -} -''' - aux_file = tmp_path / "test.aux" - aux_file.write_text(aux_content) - - with patch("win32com.client.dynamic.Dispatch") as mock_dispatch, \ - patch("win32com.client.gencache.EnsureDispatch", create=True), \ - patch("tempfile.NamedTemporaryFile") as mock_tempfile, \ - patch("os.unlink"): - mock_pwcom = MagicMock() - mock_dispatch.return_value = mock_pwcom - mock_pwcom.OpenCase.return_value = ("",) - mock_pwcom.GetParametersSingleElement.return_value = ("", ("23", "Jan 01 2023")) - mock_pwcom.GetFieldList.return_value = ("", []) - mock_pwcom.RunScriptCommand.return_value = ("",) - - mock_ntf = MagicMock() - mock_ntf.name = str(aux_file) - mock_tempfile.return_value = mock_ntf - - saw = SAW(FileName="dummy.pwb") - df = saw.GetSubData("Gen", ["BusNum", "GenID"], ["BidCurve"]) - - assert len(df) == 2 - assert df.iloc[0]["BidCurve"] == [] - assert df.iloc[1]["BidCurve"] == [] - - def test_get_subdata_no_subdatalist(self, tmp_path): - """Test GetSubData with subdatalist=None (just fields).""" - aux_content = '''DATA (Bus, [BusNum, BusName]) -{ -1 "Bus1" -2 "Bus2" -} -''' - aux_file = tmp_path / "test.aux" - aux_file.write_text(aux_content) - - with patch("win32com.client.dynamic.Dispatch") as mock_dispatch, \ - patch("win32com.client.gencache.EnsureDispatch", create=True), \ - patch("tempfile.NamedTemporaryFile") as mock_tempfile, \ - patch("os.unlink"): - mock_pwcom = MagicMock() - mock_dispatch.return_value = mock_pwcom - mock_pwcom.OpenCase.return_value = ("",) - mock_pwcom.GetParametersSingleElement.return_value = ("", ("23", "Jan 01 2023")) - mock_pwcom.GetFieldList.return_value = ("", []) - mock_pwcom.RunScriptCommand.return_value = ("",) - - mock_ntf = MagicMock() - mock_ntf.name = str(aux_file) - mock_tempfile.return_value = mock_ntf - - saw = SAW(FileName="dummy.pwb") - df = saw.GetSubData("Bus", ["BusNum", "BusName"]) - - assert len(df) == 2 - assert list(df.columns) == ["BusNum", "BusName"] - - def test_get_subdata_quoted_strings(self, tmp_path): - """Test parsing SubData with quoted strings containing spaces.""" - aux_content = '''DATA (Contingency, [TSContingency]) -{ -"My Contingency" - -BRANCH 1 2 "1" OPEN -GEN 5 "Main Gen" OPEN - -} -''' - aux_file = tmp_path / "test.aux" - aux_file.write_text(aux_content) - - with patch("win32com.client.dynamic.Dispatch") as mock_dispatch, \ - patch("win32com.client.gencache.EnsureDispatch", create=True), \ - patch("tempfile.NamedTemporaryFile") as mock_tempfile, \ - patch("os.unlink"): - mock_pwcom = MagicMock() - mock_dispatch.return_value = mock_pwcom - mock_pwcom.OpenCase.return_value = ("",) - mock_pwcom.GetParametersSingleElement.return_value = ("", ("23", "Jan 01 2023")) - mock_pwcom.GetFieldList.return_value = ("", []) - mock_pwcom.RunScriptCommand.return_value = ("",) - - mock_ntf = MagicMock() - mock_ntf.name = str(aux_file) - mock_tempfile.return_value = mock_ntf - - saw = SAW(FileName="dummy.pwb") - df = saw.GetSubData("Contingency", ["TSContingency"], ["CTGElement"]) - - assert len(df) == 1 - assert len(df.iloc[0]["CTGElement"]) == 2 - assert df.iloc[0]["CTGElement"][0][0] == "BRANCH" - assert df.iloc[0]["CTGElement"][1][2] == "Main Gen" - - def test_get_subdata_file_not_found(self, tmp_path): - """Test GetSubData returns empty DataFrame when file doesn't exist.""" - aux_file = tmp_path / "nonexistent.aux" - - with patch("win32com.client.dynamic.Dispatch") as mock_dispatch, \ - patch("win32com.client.gencache.EnsureDispatch", create=True), \ - patch("tempfile.NamedTemporaryFile") as mock_tempfile, \ - patch("os.unlink"): - mock_pwcom = MagicMock() - mock_dispatch.return_value = mock_pwcom - mock_pwcom.OpenCase.return_value = ("",) - mock_pwcom.GetParametersSingleElement.return_value = ("", ("23", "Jan 01 2023")) - mock_pwcom.GetFieldList.return_value = ("", []) - mock_pwcom.RunScriptCommand.return_value = ("",) - - mock_ntf = MagicMock() - mock_ntf.name = str(aux_file) # File doesn't exist - mock_tempfile.return_value = mock_ntf - - saw = SAW(FileName="dummy.pwb") - df = saw.GetSubData("Gen", ["BusNum"], ["BidCurve"]) - - assert df.empty - assert list(df.columns) == ["BusNum", "BidCurve"] - - def test_get_subdata_no_data_block(self, tmp_path): - """Test GetSubData returns empty DataFrame when no DATA block found.""" - aux_content = "// Empty aux file with no DATA block" - aux_file = tmp_path / "test.aux" - aux_file.write_text(aux_content) - - with patch("win32com.client.dynamic.Dispatch") as mock_dispatch, \ - patch("win32com.client.gencache.EnsureDispatch", create=True), \ - patch("tempfile.NamedTemporaryFile") as mock_tempfile, \ - patch("os.unlink"): - mock_pwcom = MagicMock() - mock_dispatch.return_value = mock_pwcom - mock_pwcom.OpenCase.return_value = ("",) - mock_pwcom.GetParametersSingleElement.return_value = ("", ("23", "Jan 01 2023")) - mock_pwcom.GetFieldList.return_value = ("", []) - mock_pwcom.RunScriptCommand.return_value = ("",) - - mock_ntf = MagicMock() - mock_ntf.name = str(aux_file) - mock_tempfile.return_value = mock_ntf - - saw = SAW(FileName="dummy.pwb") - df = saw.GetSubData("Gen", ["BusNum"], ["BidCurve"]) - - assert df.empty - - def test_get_subdata_mixed_formats(self, tmp_path): - """Test parsing file with mixed bracket and space-delimited SubData.""" - aux_content = '''DATA (Gen, [BusNum, GenID]) -{ -1 "1" - -50.0 10.0 -100.0 15.0 - - -[0.0, 1.0] -[2.0, 3.0] - -} -''' - aux_file = tmp_path / "test.aux" - aux_file.write_text(aux_content) - - with patch("win32com.client.dynamic.Dispatch") as mock_dispatch, \ - patch("win32com.client.gencache.EnsureDispatch", create=True), \ - patch("tempfile.NamedTemporaryFile") as mock_tempfile, \ - patch("os.unlink"): - mock_pwcom = MagicMock() - mock_dispatch.return_value = mock_pwcom - mock_pwcom.OpenCase.return_value = ("",) - mock_pwcom.GetParametersSingleElement.return_value = ("", ("23", "Jan 01 2023")) - mock_pwcom.GetFieldList.return_value = ("", []) - mock_pwcom.RunScriptCommand.return_value = ("",) - - mock_ntf = MagicMock() - mock_ntf.name = str(aux_file) - mock_tempfile.return_value = mock_ntf - - saw = SAW(FileName="dummy.pwb") - df = saw.GetSubData("Gen", ["BusNum", "GenID"], ["BidCurve", "SomeCoords"]) - - assert len(df) == 1 - assert df.iloc[0]["BidCurve"][0] == ["50.0", "10.0"] # Space-delimited - assert "0.0" in str(df.iloc[0]["SomeCoords"][0]) # Bracket-delimited - - def test_get_subdata_comments_ignored(self, tmp_path): - """Test that comments inside SubData blocks are ignored.""" - aux_content = '''DATA (Gen, [BusNum, GenID]) -{ -1 "1" - -// This is a comment -// MW Price -50.0 10.0 -// Another comment -100.0 15.0 - -} -''' - aux_file = tmp_path / "test.aux" - aux_file.write_text(aux_content) - - with patch("win32com.client.dynamic.Dispatch") as mock_dispatch, \ - patch("win32com.client.gencache.EnsureDispatch", create=True), \ - patch("tempfile.NamedTemporaryFile") as mock_tempfile, \ - patch("os.unlink"): - mock_pwcom = MagicMock() - mock_dispatch.return_value = mock_pwcom - mock_pwcom.OpenCase.return_value = ("",) - mock_pwcom.GetParametersSingleElement.return_value = ("", ("23", "Jan 01 2023")) - mock_pwcom.GetFieldList.return_value = ("", []) - mock_pwcom.RunScriptCommand.return_value = ("",) - - mock_ntf = MagicMock() - mock_ntf.name = str(aux_file) - mock_tempfile.return_value = mock_ntf - - saw = SAW(FileName="dummy.pwb") - df = saw.GetSubData("Gen", ["BusNum", "GenID"], ["BidCurve"]) - - assert len(df.iloc[0]["BidCurve"]) == 2 # Only data lines, not comments - - def test_get_subdata_multiple_subdata_types(self, tmp_path): - """Test parsing multiple SubData types per object (Gen with BidCurve + ReactiveCapability).""" - aux_content = '''DATA (Gen, [BusNum, GenID, GenMW, GenMWMax]) -{ -1 "1" 100.0 200.0 - -50.0 8.0 -100.0 10.0 -200.0 15.0 - - -50.0 -40.0 40.0 -100.0 -35.0 35.0 -200.0 -20.0 20.0 - -} -''' - aux_file = tmp_path / "test.aux" - aux_file.write_text(aux_content) - - with patch("win32com.client.dynamic.Dispatch") as mock_dispatch, \ - patch("win32com.client.gencache.EnsureDispatch", create=True), \ - patch("tempfile.NamedTemporaryFile") as mock_tempfile, \ - patch("os.unlink"): - mock_pwcom = MagicMock() - mock_dispatch.return_value = mock_pwcom - mock_pwcom.OpenCase.return_value = ("",) - mock_pwcom.GetParametersSingleElement.return_value = ("", ("23", "Jan 01 2023")) - mock_pwcom.GetFieldList.return_value = ("", []) - mock_pwcom.RunScriptCommand.return_value = ("",) - - mock_ntf = MagicMock() - mock_ntf.name = str(aux_file) - mock_tempfile.return_value = mock_ntf - - saw = SAW(FileName="dummy.pwb") - df = saw.GetSubData("Gen", ["BusNum", "GenID", "GenMW", "GenMWMax"], - ["BidCurve", "ReactiveCapability"]) - - assert len(df) == 1 - assert df.iloc[0]["BusNum"] == "1" - assert df.iloc[0]["GenMW"] == "100.0" - assert len(df.iloc[0]["BidCurve"]) == 3 - assert len(df.iloc[0]["ReactiveCapability"]) == 3 - assert df.iloc[0]["ReactiveCapability"][2] == ["200.0", "-20.0", "20.0"] \ No newline at end of file diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 00000000..630f786a --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,393 @@ +""" +Unit tests for the esapp.utils module. + +These are **unit tests** that do NOT require PowerWorld Simulator. They test +the timing decorator (esapp.utils.misc) and B3D file format I/O +(esapp.utils.b3d). + +USAGE: + pytest tests/test_utils.py -v + pytest tests/test_utils.py -v --cov=esapp/utils --cov-report=term-missing +""" + +import struct + +import numpy as np +import pytest +from numpy.testing import assert_allclose + +from esapp.utils.misc import timing +from esapp.utils.b3d import B3D + + +# ============================================================================= +# timing decorator +# ============================================================================= + + +class TestTiming: + + def test_preserves_return_value(self, capsys): + @timing + def add(a, b): + return a + b + + result = add(2, 3) + assert result == 5 + assert "'add' took:" in capsys.readouterr().out + + def test_preserves_function_name(self): + @timing + def my_func(): + pass + + assert my_func.__name__ == 'my_func' + + +# ============================================================================= +# B3D file format +# ============================================================================= + + +class TestB3D: + + def test_default_construction(self): + b = B3D() + assert b.lat.shape == (4,) + assert b.lon.shape == (4,) + assert b.time.shape == (3,) + assert b.ex.shape == (3, 4) + assert b.ey.shape == (3, 4) + + def test_write_load_roundtrip(self, tmp_path): + b = B3D() + fpath = str(tmp_path / "test.b3d") + b.write_b3d_file(fpath) + + b2 = B3D(fpath) + assert_allclose(b2.lat, b.lat) + assert_allclose(b2.lon, b.lon) + assert_allclose(b2.time, b.time) + assert_allclose(b2.ex, b.ex) + assert_allclose(b2.ey, b.ey) + assert b2.comment == b.comment + + def test_from_mesh_and_roundtrip(self, tmp_path): + long = np.array([-85.0, -84.5]) + lat = np.array([30.5, 31.0]) + ex = np.ones((2, 2), dtype=np.float32) * 0.5 + ey = np.ones((2, 2), dtype=np.float32) * -0.3 + + b = B3D.from_mesh(long, lat, ex, ey, comment="Test") + assert b.comment == "Test" + assert b.grid_dim == [2, 2] + + fpath = str(tmp_path / "mesh.b3d") + b.write_b3d_file(fpath) + b2 = B3D(fpath) + assert_allclose(b2.ex, b.ex, atol=1e-6) + assert_allclose(b2.ey, b.ey, atol=1e-6) + + def test_write_validation_lat_lon_mismatch(self, tmp_path): + b = B3D() + b.lon = np.array([1.0, 2.0, 3.0]) + with pytest.raises(ValueError, match="lat and lon must have the same length"): + b.write_b3d_file(str(tmp_path / "bad.b3d")) + + def test_write_validation_bad_lat_dtype(self, tmp_path): + b = B3D() + b.lat = b.lat.astype(np.float32) + with pytest.raises(ValueError, match="lat must be a float64"): + b.write_b3d_file(str(tmp_path / "bad.b3d")) + + def test_write_validation_bad_lon_dtype(self, tmp_path): + b = B3D() + b.lon = b.lon.astype(np.float32) + with pytest.raises(ValueError, match="lon must be a float64"): + b.write_b3d_file(str(tmp_path / "bad.b3d")) + + def test_write_validation_bad_time_dtype(self, tmp_path): + b = B3D() + b.time = b.time.astype(np.int32) + with pytest.raises(ValueError, match="time must be a uint32"): + b.write_b3d_file(str(tmp_path / "bad.b3d")) + + def test_write_validation_bad_ex_dtype(self, tmp_path): + b = B3D() + b.ex = b.ex.astype(np.float64) + with pytest.raises(ValueError, match="ex must be a float32"): + b.write_b3d_file(str(tmp_path / "bad.b3d")) + + def test_write_validation_bad_ey_dtype(self, tmp_path): + b = B3D() + b.ey = b.ey.astype(np.float64) + with pytest.raises(ValueError, match="ey must be a float32"): + b.write_b3d_file(str(tmp_path / "bad.b3d")) + + def test_write_validation_ex_shape_mismatch(self, tmp_path): + b = B3D() + b.ex = np.zeros((3, 5), dtype=np.float32) + with pytest.raises(ValueError, match="ex columns"): + b.write_b3d_file(str(tmp_path / "bad.b3d")) + + def test_write_validation_ey_shape_mismatch(self, tmp_path): + b = B3D() + b.ey = np.zeros((3, 5), dtype=np.float32) + with pytest.raises(ValueError, match="ey columns"): + b.write_b3d_file(str(tmp_path / "bad.b3d")) + + def test_write_validation_ex_rows_mismatch(self, tmp_path): + b = B3D() + b.ex = np.zeros((5, 4), dtype=np.float32) + with pytest.raises(ValueError, match="ex rows"): + b.write_b3d_file(str(tmp_path / "bad.b3d")) + + def test_write_validation_ey_rows_mismatch(self, tmp_path): + b = B3D() + b.ey = np.zeros((5, 4), dtype=np.float32) + with pytest.raises(ValueError, match="ey rows"): + b.write_b3d_file(str(tmp_path / "bad.b3d")) + + def test_load_no_meta_strings(self, tmp_path): + """B3D file with nmeta=0 triggers 'No comment' branch.""" + b = B3D() + fpath = str(tmp_path / "test.b3d") + b.write_b3d_file(fpath) + + # Patch the file: set nmeta=0 and remove meta string bytes. + # Easier approach: build a raw file from scratch. + fpath2 = str(tmp_path / "nometa.b3d") + n = 1 # 1 location + nt = 1 # 1 time step + with open(fpath2, "wb") as f: + _w = lambda val: f.write(val.to_bytes(4, "little")) + _w(34280) # code + _w(4) # version + _w(0) # nmeta = 0 + _w(2) # float_channels + _w(0) # byte_channels + _w(1) # loc_format + _w(n) # n locations + # Location data: lon, lat, z for each point + loc = np.array([[0.0, 0.0, 0.0]], dtype=np.float64) + f.write(loc.tobytes()) + _w(0) # time_0 + _w(0) # time_units + _w(0) # time_offset + _w(0) # time_step (variable) + _w(nt) # nt + f.write(np.array([0], dtype=np.uint32).tobytes()) + # ex, ey interleaved: [ex0, ey0] + f.write(np.zeros(2, dtype=np.float32).tobytes()) + + b2 = B3D(fpath2) + assert b2.comment == "No comment" + + def test_load_one_meta_string(self, tmp_path): + """B3D with nmeta=1 skips grid_dim parsing (line 230->242 branch).""" + fpath = str(tmp_path / "onemeta.b3d") + n = 1 + nt = 1 + meta = "Only comment\x00" + with open(fpath, "wb") as f: + _w = lambda val: f.write(val.to_bytes(4, "little")) + _w(34280); _w(4) + _w(1) # nmeta = 1 + f.write(meta.encode('ascii')) + _w(2); _w(0); _w(1); _w(n) + f.write(np.zeros((n, 3), dtype=np.float64).tobytes()) + _w(0); _w(0); _w(0); _w(0); _w(nt) + f.write(np.array([0], dtype=np.uint32).tobytes()) + f.write(np.zeros(n * 2, dtype=np.float32).tobytes()) + + b = B3D(fpath) + assert b.comment == "Only comment" + # grid_dim stays [0,0] since nmeta < 2, then product != n → [n, 1] + assert b.grid_dim == [n, 1] + + def test_load_grid_dim_space_separated(self, tmp_path): + """B3D with grid_dim meta using space-separated format.""" + fpath = str(tmp_path / "spacedim.b3d") + n = 2 + nt = 1 + meta = "Test comment\x002 1\x00" # space-separated grid_dim + with open(fpath, "wb") as f: + _w = lambda val: f.write(val.to_bytes(4, "little")) + _w(34280); _w(4) + _w(2) # nmeta = 2 + f.write(meta.encode('ascii')) + _w(2); _w(0); _w(1); _w(n) + loc = np.zeros((n, 3), dtype=np.float64) + f.write(loc.tobytes()) + _w(0); _w(0); _w(0); _w(0); _w(nt) + f.write(np.array([0], dtype=np.uint32).tobytes()) + f.write(np.zeros(n * 2, dtype=np.float32).tobytes()) + + b = B3D(fpath) + assert b.grid_dim == [2, 1] + + def test_load_grid_dim_bad_format(self, tmp_path): + """B3D with unparseable grid_dim falls back to [0, 0].""" + fpath = str(tmp_path / "baddim.b3d") + n = 2 + nt = 1 + meta = "Test\x00not_a_dim\x00" + with open(fpath, "wb") as f: + _w = lambda val: f.write(val.to_bytes(4, "little")) + _w(34280); _w(4) + _w(2) # nmeta = 2 + f.write(meta.encode('ascii')) + _w(2); _w(0); _w(1); _w(n) + loc = np.zeros((n, 3), dtype=np.float64) + f.write(loc.tobytes()) + _w(0); _w(0); _w(0); _w(0); _w(nt) + f.write(np.array([0], dtype=np.uint32).tobytes()) + f.write(np.zeros(n * 2, dtype=np.float32).tobytes()) + + b = B3D(fpath) + # grid_dim falls back to [0,0], then product != n so becomes [n, 1] + assert b.grid_dim == [n, 1] + + def test_load_grid_dim_wrong_length(self, tmp_path): + """B3D with grid_dim having !=2 elements triggers ValueError fallback.""" + fpath = str(tmp_path / "wrongdim.b3d") + n = 2 + nt = 1 + meta = "Test\x001, 2, 3\x00" # 3 elements + with open(fpath, "wb") as f: + _w = lambda val: f.write(val.to_bytes(4, "little")) + _w(34280); _w(4) + _w(2) + f.write(meta.encode('ascii')) + _w(2); _w(0); _w(1); _w(n) + loc = np.zeros((n, 3), dtype=np.float64) + f.write(loc.tobytes()) + _w(0); _w(0); _w(0); _w(0); _w(nt) + f.write(np.array([0], dtype=np.uint32).tobytes()) + f.write(np.zeros(n * 2, dtype=np.float32).tobytes()) + + b = B3D(fpath) + assert b.grid_dim == [n, 1] + + def test_load_float_channels_too_few(self, tmp_path): + """B3D with float_channels < 2 raises IOError.""" + fpath = str(tmp_path / "fewchan.b3d") + meta = "Test\x00[2, 1]\x00" + with open(fpath, "wb") as f: + _w = lambda val: f.write(val.to_bytes(4, "little")) + _w(34280); _w(4) + _w(2) + f.write(meta.encode('ascii')) + _w(1) # float_channels = 1 (too few) + _w(0); _w(1); _w(2) + f.write(b'\x00' * 200) + + with pytest.raises(IOError, match="at least 2 float channels"): + B3D(fpath) + + def test_load_bad_loc_format(self, tmp_path): + """B3D with loc_format != 1 raises IOError.""" + fpath = str(tmp_path / "badloc.b3d") + meta = "Test\x00[2, 1]\x00" + with open(fpath, "wb") as f: + _w = lambda val: f.write(val.to_bytes(4, "little")) + _w(34280); _w(4) + _w(2) + f.write(meta.encode('ascii')) + _w(2); _w(0) + _w(0) # loc_format = 0 (unsupported) + _w(2) + f.write(b'\x00' * 200) + + with pytest.raises(IOError, match="Only location format 1 is supported"): + B3D(fpath) + + def test_load_nonzero_time_step(self, tmp_path): + """B3D with time_step != 0 raises IOError.""" + fpath = str(tmp_path / "fixedtime.b3d") + n = 1 + meta = "Test\x00[1, 1]\x00" + with open(fpath, "wb") as f: + _w = lambda val: f.write(val.to_bytes(4, "little")) + _w(34280); _w(4) + _w(2) + f.write(meta.encode('ascii')) + _w(2); _w(0); _w(1); _w(n) + f.write(np.zeros((n, 3), dtype=np.float64).tobytes()) + _w(0); _w(0); _w(0) + _w(100) # time_step != 0 + _w(1) + f.write(b'\x00' * 200) + + with pytest.raises(IOError, match="variable time points"): + B3D(fpath) + + def test_load_extra_channels(self, tmp_path): + """B3D with extra float/byte channels uses the extraction loop.""" + fpath = str(tmp_path / "extrachan.b3d") + n = 1 + nt = 1 + float_channels = 3 # 3 floats per point (ex, ey, extra) + byte_channels = 1 # 1 extra byte per point + meta = "Test\x00[1, 1]\x00" + with open(fpath, "wb") as f: + _w = lambda val: f.write(val.to_bytes(4, "little")) + _w(34280); _w(4) + _w(2) + f.write(meta.encode('ascii')) + _w(float_channels); _w(byte_channels); _w(1); _w(n) + f.write(np.zeros((n, 3), dtype=np.float64).tobytes()) + _w(0); _w(0); _w(0); _w(0); _w(nt) + f.write(np.array([0], dtype=np.uint32).tobytes()) + # Data: 3 floats + 1 byte per point per timestep + ex_val = np.float32(1.5) + ey_val = np.float32(-0.5) + extra_val = np.float32(0.0) + f.write(struct.pack('