System Graphs

System Graphs#

We start by loading a sample distribution system.

from gdm.distribution import DistributionSystem
from gdmloader.constants import GCS_CASE_SOURCE
from gdmloader.source import SystemLoader

gdm_loader = SystemLoader()
gdm_loader.add_source(GCS_CASE_SOURCE)

distribution_system: DistributionSystem = gdm_loader.load_dataset(
    source_name=GCS_CASE_SOURCE.name,
    system_type=DistributionSystem,
    dataset_name="three_feeder_switch",
)
distribution_system.name = "three_feeder_switch"
---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
File /opt/hostedtoolcache/Python/3.12.12/x64/lib/python3.12/site-packages/gdmloader/source.py:124, in SystemLoader.load_dataset(self, system_type, source_name, dataset_name, version)
    123 try:
--> 124     source.fs.get(
    125         remote_folder,
    126         str(local_folder),
    127         recursive=True,
    128     )
    129 except FileNotFoundError:

File /opt/hostedtoolcache/Python/3.12.12/x64/lib/python3.12/site-packages/fsspec/asyn.py:118, in sync_wrapper.<locals>.wrapper(*args, **kwargs)
    117 self = obj or args[0]
--> 118 return sync(self.loop, func, *args, **kwargs)

File /opt/hostedtoolcache/Python/3.12.12/x64/lib/python3.12/site-packages/fsspec/asyn.py:103, in sync(loop, func, timeout, *args, **kwargs)
    102 elif isinstance(return_result, BaseException):
--> 103     raise return_result
    104 else:

File /opt/hostedtoolcache/Python/3.12.12/x64/lib/python3.12/site-packages/fsspec/asyn.py:56, in _runner(event, coro, result, timeout)
     55 try:
---> 56     result[0] = await coro
     57 except Exception as ex:

File /opt/hostedtoolcache/Python/3.12.12/x64/lib/python3.12/site-packages/fsspec/asyn.py:645, in AsyncFileSystem._get(self, rpath, lpath, recursive, callback, maxdepth, **kwargs)
    644 rpath = self._strip_protocol(rpath)
--> 645 rpaths = await self._expand_path(
    646     rpath, recursive=recursive, maxdepth=maxdepth
    647 )
    648 if source_is_str and (not recursive or maxdepth is not None):
    649     # Non-recursive glob does not copy directories

File /opt/hostedtoolcache/Python/3.12.12/x64/lib/python3.12/site-packages/fsspec/asyn.py:883, in AsyncFileSystem._expand_path(self, path, recursive, maxdepth)
    882 if isinstance(path, str):
--> 883     out = await self._expand_path([path], recursive, maxdepth)
    884 else:

File /opt/hostedtoolcache/Python/3.12.12/x64/lib/python3.12/site-packages/fsspec/asyn.py:912, in AsyncFileSystem._expand_path(self, path, recursive, maxdepth)
    911 if not out:
--> 912     raise FileNotFoundError(path)
    913 return sorted(out)

FileNotFoundError: ['gdm_data/data/DistributionSystem/2_2_0/three_feeder_switch']

During handling of the above exception, another exception occurred:

ValueError                                Traceback (most recent call last)
Cell In[1], line 8
      5 gdm_loader = SystemLoader()
      6 gdm_loader.add_source(GCS_CASE_SOURCE)
----> 8 distribution_system: DistributionSystem = gdm_loader.load_dataset(
      9     source_name=GCS_CASE_SOURCE.name,
     10     system_type=DistributionSystem,
     11     dataset_name="three_feeder_switch",
     12 )
     13 distribution_system.name = "three_feeder_switch"

File /opt/hostedtoolcache/Python/3.12.12/x64/lib/python3.12/site-packages/gdmloader/source.py:131, in SystemLoader.load_dataset(self, system_type, source_name, dataset_name, version)
    129     except FileNotFoundError:
    130         msg = f"{remote_folder=} not found! Check the URL: {source.url}/{remote_folder}"
--> 131         raise ValueError(msg)
    133 system_file = list(dataset_folder.rglob("*.json"))[0]
    134 return system_type.from_json(system_file)

ValueError: remote_folder='gdm_data/data/DistributionSystem/2_2_0/three_feeder_switch' not found! Check the URL: https://storage.googleapis.com/gdm_data/gdm_data/data/DistributionSystem/2_2_0/three_feeder_switch

Distribution systems have helper functions that return either undirected or directed graphs. These graph representations are useful for understanding model connectivity, such as when building constraints in CADET-OPT.

Warning

Undirected graphs contain complete connectivity information. If there are cycles in the undirected graphs (e.g., an open switch connected between two buses), edges will be removed to create a directed radial graph.

undirected_graph = distribution_system.get_undirected_graph()
print(undirected_graph)

directed_graph = distribution_system.get_directed_graph()
print(directed_graph)
Graph with 86 nodes and 88 edges
DiGraph with 86 nodes and 85 edges

Graphs are lightweight and contain limited information, such as bus and edge names. Helper functions are provided to efficiently retrieve connectivity information for a particular node.

from gdm.distribution.components import DistributionLoad

loads = distribution_system.get_bus_connected_components(
    bus_name="fdr1_2_load", component_type=DistributionLoad
)
for load in loads:
    print(load.name, load.bus.name)
fdr1_load1 fdr1_2_load