diff --git a/docs/simulation/gdm.ipynb b/docs/simulation/gdm.ipynb index 0b7603c6..6772230d 100644 --- a/docs/simulation/gdm.ipynb +++ b/docs/simulation/gdm.ipynb @@ -20,7 +20,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": { "execution": { "iopub.execute_input": "2026-03-06T14:37:17.199116Z", @@ -44,92 +44,113 @@ "\n", "Please upgrade Plotly to version 6.1.1 or greater, or downgrade Kaleido to version 0.2.1.\n", "\n", - "\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "WARNING\tTask(Task-2) google.auth.compute_engine._metadata:_metadata.py:ping()- Compute Engine Metadata server unavailable on attempt 1 of 3. Reason: [Errno 65] No route to host\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "WARNING\tTask(Task-2) google.auth.compute_engine._metadata:_metadata.py:ping()- Compute Engine Metadata server unavailable on attempt 2 of 3. Reason: [Errno 64] Host is down\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "WARNING\tTask(Task-2) google.auth.compute_engine._metadata:_metadata.py:ping()- Compute Engine Metadata server unavailable on attempt 3 of 3. Reason: [Errno 64] Host is down\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "WARNING\tTask(Task-2) google.auth._default:_default.py:_get_gce_credentials()- Authentication failed using Compute Engine authentication due to unavailable metadata server.\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "WARNING\tTask(Task-2) google.auth.compute_engine._metadata:_metadata.py:get()- Compute Engine Metadata server unavailable on attempt 1 of 5. Reason: HTTPConnectionPool(host='metadata.google.internal', port=80): Max retries exceeded with url: /computeMetadata/v1/instance/service-accounts/default/?recursive=true (Caused by NameResolutionError(\": Failed to resolve 'metadata.google.internal' ([Errno 8] nodename nor servname provided, or not known)\"))\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "WARNING\tTask(Task-2) google.auth.compute_engine._metadata:_metadata.py:get()- Compute Engine Metadata server unavailable on attempt 2 of 5. Reason: HTTPConnectionPool(host='metadata.google.internal', port=80): Max retries exceeded with url: /computeMetadata/v1/instance/service-accounts/default/?recursive=true (Caused by NameResolutionError(\": Failed to resolve 'metadata.google.internal' ([Errno 8] nodename nor servname provided, or not known)\"))\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "WARNING\tTask(Task-2) google.auth.compute_engine._metadata:_metadata.py:get()- Compute Engine Metadata server unavailable on attempt 3 of 5. Reason: HTTPConnectionPool(host='metadata.google.internal', port=80): Max retries exceeded with url: /computeMetadata/v1/instance/service-accounts/default/?recursive=true (Caused by NameResolutionError(\": Failed to resolve 'metadata.google.internal' ([Errno 8] nodename nor servname provided, or not known)\"))\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "WARNING\tTask(Task-2) google.auth.compute_engine._metadata:_metadata.py:get()- Compute Engine Metadata server unavailable on attempt 4 of 5. Reason: HTTPConnectionPool(host='metadata.google.internal', port=80): Max retries exceeded with url: /computeMetadata/v1/instance/service-accounts/default/?recursive=true (Caused by NameResolutionError(\": Failed to resolve 'metadata.google.internal' ([Errno 8] nodename nor servname provided, or not known)\"))\n" + "\n", + "WARNING\tTask(Task-2) google.auth.compute_engine._metadata:_metadata.py:ping()- Compute Engine Metadata server unavailable on attempt 1 of 3. Reason: timed out\n", + "WARNING\tTask(Task-2) google.auth.compute_engine._metadata:_metadata.py:ping()- Compute Engine Metadata server unavailable on attempt 2 of 3. Reason: timed out\n", + "WARNING\tTask(Task-2) google.auth.compute_engine._metadata:_metadata.py:ping()- Compute Engine Metadata server unavailable on attempt 3 of 3. Reason: [Errno 64] Host is down\n", + "WARNING\tTask(Task-2) google.auth._default:_default.py:_get_gce_credentials()- Authentication failed using Compute Engine authentication due to unavailable metadata server.\n", + "WARNING\tTask(Task-2) google.auth.compute_engine._metadata:_metadata.py:get()- Compute Engine Metadata server unavailable on attempt 1 of 5. Reason: HTTPConnectionPool(host='metadata.google.internal', port=80): Max retries exceeded with url: /computeMetadata/v1/instance/service-accounts/default/?recursive=true (Caused by NameResolutionError(\": Failed to resolve 'metadata.google.internal' ([Errno 8] nodename nor servname provided, or not known)\"))\n", + "WARNING\tTask(Task-2) google.auth.compute_engine._metadata:_metadata.py:get()- Compute Engine Metadata server unavailable on attempt 2 of 5. Reason: HTTPConnectionPool(host='metadata.google.internal', port=80): Max retries exceeded with url: /computeMetadata/v1/instance/service-accounts/default/?recursive=true (Caused by NameResolutionError(\": Failed to resolve 'metadata.google.internal' ([Errno 8] nodename nor servname provided, or not known)\"))\n", + "WARNING\tTask(Task-2) google.auth.compute_engine._metadata:_metadata.py:get()- Compute Engine Metadata server unavailable on attempt 3 of 5. Reason: HTTPConnectionPool(host='metadata.google.internal', port=80): Max retries exceeded with url: /computeMetadata/v1/instance/service-accounts/default/?recursive=true (Caused by NameResolutionError(\": Failed to resolve 'metadata.google.internal' ([Errno 8] nodename nor servname provided, or not known)\"))\n", + "WARNING\tTask(Task-2) google.auth.compute_engine._metadata:_metadata.py:get()- Compute Engine Metadata server unavailable on attempt 4 of 5. Reason: HTTPConnectionPool(host='metadata.google.internal', port=80): Max retries exceeded with url: /computeMetadata/v1/instance/service-accounts/default/?recursive=true (Caused by NameResolutionError(\": Failed to resolve 'metadata.google.internal' ([Errno 8] nodename nor servname provided, or not known)\"))\n", + "WARNING\tTask(Task-2) google.auth.compute_engine._metadata:_metadata.py:get()- Compute Engine Metadata server unavailable on attempt 5 of 5. Reason: HTTPConnectionPool(host='metadata.google.internal', port=80): Max retries exceeded with url: /computeMetadata/v1/instance/service-accounts/default/?recursive=true (Caused by NameResolutionError(\": Failed to resolve 'metadata.google.internal' ([Errno 8] nodename nor servname provided, or not known)\"))\n" ] }, { - "name": "stderr", - "output_type": "stream", - "text": [ - "WARNING\tTask(Task-2) google.auth.compute_engine._metadata:_metadata.py:get()- Compute Engine Metadata server unavailable on attempt 5 of 5. Reason: HTTPConnectionPool(host='metadata.google.internal', port=80): Max retries exceeded with url: /computeMetadata/v1/instance/service-accounts/default/?recursive=true (Caused by NameResolutionError(\": Failed to resolve 'metadata.google.internal' ([Errno 8] nodename nor servname provided, or not known)\"))\n" - ] + "data": { + "text/html": [ + "
System                                            \n",
+       "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┓\n",
+       "┃ Property                                Value ┃\n",
+       "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━┩\n",
+       "│ System name                      │ p1rhs7_1247 │\n",
+       "│ Data format version              │       2.2.1 │\n",
+       "│ Components attached              │       13370 │\n",
+       "│ Time Series attached             │           0 │\n",
+       "│ Supplemental Attributes attached │           0 │\n",
+       "│ Description                      │             │\n",
+       "└──────────────────────────────────┴─────────────┘\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1mSystem \u001b[0m\n", + "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┓\n", + "┃\u001b[1m \u001b[0m\u001b[1mProperty \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m Value\u001b[0m\u001b[1m \u001b[0m┃\n", + "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━┩\n", + "│ System name │ p1rhs7_1247 │\n", + "│ Data format version │ 2.2.1 │\n", + "│ Components attached │ 13370 │\n", + "│ Time Series attached │ 0 │\n", + "│ Supplemental Attributes attached │ 0 │\n", + "│ Description │ │\n", + "└──────────────────────────────────┴─────────────┘\n" + ] + }, + "metadata": {}, + "output_type": "display_data" }, { - "ename": "ValidationError", - "evalue": "1 validation error for MatrixImpedanceBranch\n Value error, Length of matrix mat= did not match number of phases self.phases=[, , ] [type=value_error, input_value={'uuid': '42a039ae-76dd-4...tity(115.0, 'ampere')>)}, input_type=dict]\n For further information visit https://errors.pydantic.dev/2.12/v/value_error", - "output_type": "error", - "traceback": [ - "\u001b[31m---------------------------------------------------------------------------\u001b[39m", - "\u001b[31mValidationError\u001b[39m Traceback (most recent call last)", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[1]\u001b[39m\u001b[32m, line 14\u001b[39m\n\u001b[32m 11\u001b[39m gdm_loader = SystemLoader()\n\u001b[32m 12\u001b[39m gdm_loader.add_source(GCS_CASE_SOURCE)\n\u001b[32m---> \u001b[39m\u001b[32m14\u001b[39m distribution_system: DistributionSystem = \u001b[43mgdm_loader\u001b[49m\u001b[43m.\u001b[49m\u001b[43mload_dataset\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 15\u001b[39m \u001b[43m \u001b[49m\u001b[43msource_name\u001b[49m\u001b[43m=\u001b[49m\u001b[43mGCS_CASE_SOURCE\u001b[49m\u001b[43m.\u001b[49m\u001b[43mname\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 16\u001b[39m \u001b[43m \u001b[49m\u001b[43msystem_type\u001b[49m\u001b[43m=\u001b[49m\u001b[43mDistributionSystem\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 17\u001b[39m \u001b[43m \u001b[49m\u001b[43mdataset_name\u001b[49m\u001b[43m=\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mp1rhs7_1247\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 18\u001b[39m \u001b[43m \u001b[49m\u001b[43mversion\u001b[49m\u001b[43m=\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43m2_1_2\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 19\u001b[39m \u001b[43m)\u001b[49m\n\u001b[32m 20\u001b[39m distribution_system.name = \u001b[33m\"\u001b[39m\u001b[33mp1rhs7_1247\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 21\u001b[39m distribution_system.info()\n", - "\u001b[36mFile \u001b[39m\u001b[32m/opt/homebrew/Caskroom/miniconda/base/envs/erad/lib/python3.12/site-packages/gdmloader/source.py:129\u001b[39m, in \u001b[36mSystemLoader.load_dataset\u001b[39m\u001b[34m(self, system_type, source_name, dataset_name, version)\u001b[39m\n\u001b[32m 126\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(msg)\n\u001b[32m 128\u001b[39m system_file = \u001b[38;5;28mlist\u001b[39m(dataset_folder.rglob(\u001b[33m\"\u001b[39m\u001b[33m*.json\u001b[39m\u001b[33m\"\u001b[39m))[\u001b[32m0\u001b[39m]\n\u001b[32m--> \u001b[39m\u001b[32m129\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43msystem_type\u001b[49m\u001b[43m.\u001b[49m\u001b[43mfrom_json\u001b[49m\u001b[43m(\u001b[49m\u001b[43msystem_file\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/opt/homebrew/Caskroom/miniconda/base/envs/erad/lib/python3.12/site-packages/infrasys/system.py:272\u001b[39m, in \u001b[36mSystem.from_json\u001b[39m\u001b[34m(cls, filename, upgrade_handler, **kwargs)\u001b[39m\n\u001b[32m 270\u001b[39m data = orjson.loads(f_in.read())\n\u001b[32m 271\u001b[39m time_series_parent_dir = Path(filename).parent\n\u001b[32m--> \u001b[39m\u001b[32m272\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mcls\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mfrom_dict\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 273\u001b[39m \u001b[43m \u001b[49m\u001b[43mdata\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtime_series_parent_dir\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mupgrade_handler\u001b[49m\u001b[43m=\u001b[49m\u001b[43mupgrade_handler\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\n\u001b[32m 274\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/opt/homebrew/Caskroom/miniconda/base/envs/erad/lib/python3.12/site-packages/infrasys/system.py:494\u001b[39m, in \u001b[36mSystem.from_dict\u001b[39m\u001b[34m(cls, data, time_series_parent_dir, upgrade_handler, **kwargs)\u001b[39m\n\u001b[32m 492\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m component_needs_metadata_migration(system_data[\u001b[33m\"\u001b[39m\u001b[33mcomponents\u001b[39m\u001b[33m\"\u001b[39m][\u001b[32m0\u001b[39m]):\n\u001b[32m 493\u001b[39m system_data[\u001b[33m\"\u001b[39m\u001b[33mcomponents\u001b[39m\u001b[33m\"\u001b[39m] = migrate_component_metadata(system_data[\u001b[33m\"\u001b[39m\u001b[33mcomponents\u001b[39m\u001b[33m\"\u001b[39m])\n\u001b[32m--> \u001b[39m\u001b[32m494\u001b[39m \u001b[43msystem\u001b[49m\u001b[43m.\u001b[49m\u001b[43m_deserialize_components\u001b[49m\u001b[43m(\u001b[49m\u001b[43msystem_data\u001b[49m\u001b[43m[\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mcomponents\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 495\u001b[39m system._deserialize_supplemental_attributes(system_data[\u001b[33m\"\u001b[39m\u001b[33msupplemental_attributes\u001b[39m\u001b[33m\"\u001b[39m])\n\u001b[32m 496\u001b[39m logger.info(\u001b[33m\"\u001b[39m\u001b[33mDeserialized system \u001b[39m\u001b[38;5;132;01m{}\u001b[39;00m\u001b[33m\"\u001b[39m, system.label)\n", - "\u001b[36mFile \u001b[39m\u001b[32m/opt/homebrew/Caskroom/miniconda/base/envs/erad/lib/python3.12/site-packages/infrasys/system.py:1592\u001b[39m, in \u001b[36mSystem._deserialize_components\u001b[39m\u001b[34m(self, components)\u001b[39m\n\u001b[32m 1590\u001b[39m skipped_types = \u001b[38;5;28mself\u001b[39m._deserialize_components_first_pass(components, cached_types)\n\u001b[32m 1591\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m skipped_types:\n\u001b[32m-> \u001b[39m\u001b[32m1592\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_deserialize_components_nested\u001b[49m\u001b[43m(\u001b[49m\u001b[43mskipped_types\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcached_types\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/opt/homebrew/Caskroom/miniconda/base/envs/erad/lib/python3.12/site-packages/infrasys/system.py:1626\u001b[39m, in \u001b[36mSystem._deserialize_components_nested\u001b[39m\u001b[34m(self, skipped_types, cached_types)\u001b[39m\n\u001b[32m 1624\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(components) > \u001b[32m1\u001b[39m:\n\u001b[32m 1625\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m component_dict \u001b[38;5;129;01min\u001b[39;00m components[\u001b[32m1\u001b[39m:]:\n\u001b[32m-> \u001b[39m\u001b[32m1626\u001b[39m component = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_try_deserialize_component\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcomponent_dict\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcached_types\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1627\u001b[39m \u001b[38;5;28;01massert\u001b[39;00m component \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m 1628\u001b[39m deserialized_types.add(component_type)\n", - "\u001b[36mFile \u001b[39m\u001b[32m/opt/homebrew/Caskroom/miniconda/base/envs/erad/lib/python3.12/site-packages/infrasys/system.py:1648\u001b[39m, in \u001b[36mSystem._try_deserialize_component\u001b[39m\u001b[34m(self, component, cached_types)\u001b[39m\n\u001b[32m 1646\u001b[39m metadata = SerializedTypeMetadata.validate_python(component[TYPE_METADATA])\n\u001b[32m 1647\u001b[39m component_type = cached_types.get_type(metadata)\n\u001b[32m-> \u001b[39m\u001b[32m1648\u001b[39m actual_component = \u001b[43mcomponent_type\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mvalues\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1649\u001b[39m \u001b[38;5;28mself\u001b[39m._components.add(actual_component, deserialization_in_progress=\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[32m 1650\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m actual_component\n", - "\u001b[36mFile \u001b[39m\u001b[32m/opt/homebrew/Caskroom/miniconda/base/envs/erad/lib/python3.12/site-packages/pydantic/main.py:250\u001b[39m, in \u001b[36mBaseModel.__init__\u001b[39m\u001b[34m(self, **data)\u001b[39m\n\u001b[32m 248\u001b[39m \u001b[38;5;66;03m# `__tracebackhide__` tells pytest and some other tools to omit this function from tracebacks\u001b[39;00m\n\u001b[32m 249\u001b[39m __tracebackhide__ = \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m250\u001b[39m validated_self = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m__pydantic_validator__\u001b[49m\u001b[43m.\u001b[49m\u001b[43mvalidate_python\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdata\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mself_instance\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[32m 251\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m validated_self:\n\u001b[32m 252\u001b[39m warnings.warn(\n\u001b[32m 253\u001b[39m \u001b[33m'\u001b[39m\u001b[33mA custom validator is returning a value other than `self`.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[33m'\u001b[39m\n\u001b[32m 254\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mReturning anything other than `self` from a top level model validator isn\u001b[39m\u001b[33m'\u001b[39m\u001b[33mt supported when validating via `__init__`.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[33m\"\u001b[39m\n\u001b[32m 255\u001b[39m \u001b[33m'\u001b[39m\u001b[33mSee the `model_validator` docs (https://docs.pydantic.dev/latest/concepts/validators/#model-validators) for more details.\u001b[39m\u001b[33m'\u001b[39m,\n\u001b[32m 256\u001b[39m stacklevel=\u001b[32m2\u001b[39m,\n\u001b[32m 257\u001b[39m )\n", - "\u001b[31mValidationError\u001b[39m: 1 validation error for MatrixImpedanceBranch\n Value error, Length of matrix mat= did not match number of phases self.phases=[, , ] [type=value_error, input_value={'uuid': '42a039ae-76dd-4...tity(115.0, 'ampere')>)}, input_type=dict]\n For further information visit https://errors.pydantic.dev/2.12/v/value_error" - ] + "data": { + "text/html": [ + "
Component Information                       \n",
+       "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓\n",
+       "┃ Type                              Count ┃\n",
+       "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━┩\n",
+       "│ DistributionBus                  │  2510 │\n",
+       "│ DistributionLoad                 │  1896 │\n",
+       "│ DistributionTransformer          │   503 │\n",
+       "│ DistributionTransformerEquipment │    10 │\n",
+       "│ DistributionVoltageSource        │     1 │\n",
+       "│ LoadEquipment                    │  1896 │\n",
+       "│ Location                         │  2510 │\n",
+       "│ MatrixImpedanceBranch            │  1841 │\n",
+       "│ MatrixImpedanceBranchEquipment   │    38 │\n",
+       "│ MatrixImpedanceFuse              │    81 │\n",
+       "│ MatrixImpedanceFuseEquipment     │     6 │\n",
+       "│ MatrixImpedanceSwitch            │    84 │\n",
+       "│ MatrixImpedanceSwitchEquipment   │    15 │\n",
+       "│ PhaseLoadEquipment               │  1948 │\n",
+       "│ PhaseVoltageSourceEquipment      │     3 │\n",
+       "│ TimeCurrentCurve                 │     1 │\n",
+       "│ VoltageLimitSet                  │     8 │\n",
+       "│ VoltageSourceEquipment           │     1 │\n",
+       "│ WindingEquipment                 │    18 │\n",
+       "└──────────────────────────────────┴───────┘\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1mComponent Information \u001b[0m\n", + "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓\n", + "┃\u001b[1m \u001b[0m\u001b[1mType \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mCount\u001b[0m\u001b[1m \u001b[0m┃\n", + "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━┩\n", + "│ DistributionBus │ 2510 │\n", + "│ DistributionLoad │ 1896 │\n", + "│ DistributionTransformer │ 503 │\n", + "│ DistributionTransformerEquipment │ 10 │\n", + "│ DistributionVoltageSource │ 1 │\n", + "│ LoadEquipment │ 1896 │\n", + "│ Location │ 2510 │\n", + "│ MatrixImpedanceBranch │ 1841 │\n", + "│ MatrixImpedanceBranchEquipment │ 38 │\n", + "│ MatrixImpedanceFuse │ 81 │\n", + "│ MatrixImpedanceFuseEquipment │ 6 │\n", + "│ MatrixImpedanceSwitch │ 84 │\n", + "│ MatrixImpedanceSwitchEquipment │ 15 │\n", + "│ PhaseLoadEquipment │ 1948 │\n", + "│ PhaseVoltageSourceEquipment │ 3 │\n", + "│ TimeCurrentCurve │ 1 │\n", + "│ VoltageLimitSet │ 8 │\n", + "│ VoltageSourceEquipment │ 1 │\n", + "│ WindingEquipment │ 18 │\n", + "└──────────────────────────────────┴───────┘\n" + ] + }, + "metadata": {}, + "output_type": "display_data" } ], "source": [ + "from importlib.metadata import version as pkg_version\n", "from IPython.display import display, HTML\n", "import plotly.graph_objects as go\n", "import plotly.io as pio\n", @@ -143,12 +164,41 @@ "gdm_loader = SystemLoader()\n", "gdm_loader.add_source(GCS_CASE_SOURCE)\n", "\n", - "distribution_system: DistributionSystem = gdm_loader.load_dataset(\n", - " source_name=GCS_CASE_SOURCE.name,\n", - " system_type=DistributionSystem,\n", - " dataset_name=\"p1rhs7_1247\",\n", - ")\n", - "distribution_system.name = \"p1rhs7_1247\"\n", + "dataset_name = \"p1rhs7_1247\"\n", + "\n", + "# Match gdmloader's dataset version to the installed grid-data-models/gdm package version.\n", + "candidate_versions = []\n", + "for package_name in (\"grid-data-models\", \"gdm\"):\n", + " try:\n", + " candidate_versions.append(pkg_version(package_name).replace(\".\", \"_\"))\n", + " except Exception:\n", + " pass\n", + "\n", + "candidate_versions.extend([\"2_2_1\", None])\n", + "candidate_versions = tuple(dict.fromkeys(candidate_versions))\n", + "last_error = None\n", + "\n", + "for candidate_version in candidate_versions:\n", + " try:\n", + " kwargs = {}\n", + " if candidate_version is not None:\n", + " kwargs[\"version\"] = candidate_version\n", + " distribution_system: DistributionSystem = gdm_loader.load_dataset(\n", + " source_name=GCS_CASE_SOURCE.name,\n", + " system_type=DistributionSystem,\n", + " dataset_name=dataset_name,\n", + " **kwargs,\n", + " )\n", + " break\n", + " except Exception as exc:\n", + " last_error = exc\n", + "else:\n", + " raise RuntimeError(\n", + " f\"Unable to load {dataset_name} from {GCS_CASE_SOURCE.name}. \"\n", + " \"Try a different dataset or update gdm/gdmloader versions.\"\n", + " ) from last_error\n", + "\n", + "distribution_system.name = dataset_name\n", "distribution_system.info()" ] },