grid-data-models 2.3.0__tar.gz → 2.3.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/.gitignore +4 -0
  2. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/PKG-INFO +8 -7
  3. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/README.md +5 -5
  4. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/pyproject.toml +3 -2
  5. grid_data_models-2.3.2/src/gdm/cli/cli.py +5 -0
  6. grid_data_models-2.3.2/src/gdm/cli/reducer.py +53 -0
  7. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/components/matrix_impedance_branch.py +1 -1
  8. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/distribution_system.py +62 -9
  9. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/enums.py +15 -0
  10. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/equipment/phase_capacitor_equipment.py +13 -4
  11. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/market/tariff.py +5 -5
  12. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/model_reduction/reducer.py +41 -17
  13. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/sys_functools.py +61 -46
  14. grid_data_models-2.3.2/src/gdm/distribution/upgrade_handler/from__2_3_0__to__2_3_1.py +15 -0
  15. grid_data_models-2.3.2/src/gdm/distribution/upgrade_handler/from__2_3_1__to__2_3_2.py +15 -0
  16. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/upgrade_handler/upgrade_handler.py +12 -0
  17. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/exceptions.py +9 -4
  18. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/mcp/server.py +450 -90
  19. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/version.py +1 -1
  20. grid_data_models-2.3.0/src/gdm/cli/cli.py +0 -10
  21. grid_data_models-2.3.0/src/gdm/cli/reducer.py +0 -59
  22. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/LICENSE.txt +0 -0
  23. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/__init__.py +0 -0
  24. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/constants.py +0 -0
  25. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/dataset/__init__.py +0 -0
  26. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/dataset/cost_model.py +0 -0
  27. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/dataset/dataset_system.py +0 -0
  28. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/__init__.py +0 -0
  29. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/catalog_system.py +0 -0
  30. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/common/__init__.py +0 -0
  31. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/common/curve.py +0 -0
  32. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/common/limitset.py +0 -0
  33. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/common/sequence_pair.py +0 -0
  34. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/components/__init__.py +0 -0
  35. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/components/base/__init__.py +0 -0
  36. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/components/base/distribution_branch_base.py +0 -0
  37. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/components/base/distribution_component_base.py +0 -0
  38. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/components/base/distribution_switch_base.py +0 -0
  39. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/components/base/distribution_transformer_base.py +0 -0
  40. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/components/distribution_battery.py +0 -0
  41. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/components/distribution_bus.py +0 -0
  42. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/components/distribution_capacitor.py +0 -0
  43. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/components/distribution_feeder.py +0 -0
  44. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/components/distribution_load.py +0 -0
  45. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/components/distribution_regulator.py +0 -0
  46. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/components/distribution_solar.py +0 -0
  47. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/components/distribution_substation.py +0 -0
  48. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/components/distribution_transformer.py +0 -0
  49. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/components/distribution_vsource.py +0 -0
  50. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/components/geometry_branch.py +0 -0
  51. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/components/matrix_impedance_fuse.py +0 -0
  52. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/components/matrix_impedance_recloser.py +0 -0
  53. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/components/matrix_impedance_switch.py +0 -0
  54. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/components/sequence_impedance_branch.py +0 -0
  55. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/controllers/__init__.py +0 -0
  56. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/controllers/base/__init__.py +0 -0
  57. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/controllers/base/capacitor_controller_base.py +0 -0
  58. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/controllers/base/inverter_controller_base.py +0 -0
  59. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/controllers/distribution_capacitor_controller.py +0 -0
  60. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/controllers/distribution_inverter_controller.py +0 -0
  61. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/controllers/distribution_recloser_controller.py +0 -0
  62. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/controllers/distribution_regulator_controller.py +0 -0
  63. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/controllers/distribution_switch_controller.py +0 -0
  64. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/distribution_graph.py +0 -0
  65. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/equipment/__init__.py +0 -0
  66. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/equipment/bare_conductor_equipment.py +0 -0
  67. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/equipment/base/__init__.py +0 -0
  68. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/equipment/base/matrix_impedance_branch_equipment_base.py +0 -0
  69. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/equipment/battery_equipment.py +0 -0
  70. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/equipment/capacitor_equipment.py +0 -0
  71. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/equipment/concentric_cable_equipment.py +0 -0
  72. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/equipment/distribution_transformer_equipment.py +0 -0
  73. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/equipment/geometry_branch_equipment.py +0 -0
  74. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/equipment/inverter_equipment.py +0 -0
  75. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/equipment/load_equipment.py +0 -0
  76. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/equipment/matrix_impedance_branch_equipment.py +0 -0
  77. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/equipment/matrix_impedance_fuse_equipment.py +0 -0
  78. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/equipment/matrix_impedance_recloser_equipment.py +0 -0
  79. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/equipment/matrix_impedance_switch_equipment.py +0 -0
  80. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/equipment/phase_load_equipment.py +0 -0
  81. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/equipment/phase_voltagesource_equipment.py +0 -0
  82. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/equipment/recloser_controller_equipment.py +0 -0
  83. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/equipment/sequence_impedance_branch_equipment.py +0 -0
  84. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/equipment/solar_equipment.py +0 -0
  85. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/equipment/voltagesource_equipment.py +0 -0
  86. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/market/__init__.py +0 -0
  87. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/model_reduction/__init__.py +0 -0
  88. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/upgrade_handler/__init__.py +0 -0
  89. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/upgrade_handler/from__2_0_1__to__2_1_2.py +0 -0
  90. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/upgrade_handler/from__2_1_2__to__2_1_3.py +0 -0
  91. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/upgrade_handler/from__2_1_3__to__2_1_4.py +0 -0
  92. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/upgrade_handler/from__2_1_4__to__2_1_5.py +0 -0
  93. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/upgrade_handler/from__2_1_5__to__2_2_0.py +0 -0
  94. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/upgrade_handler/from__2_2_0__to__2_2_1.py +0 -0
  95. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/distribution/upgrade_handler/from__2_2_1__to__2_3_0.py +0 -0
  96. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/hashing_utils.py +0 -0
  97. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/mcp/__init__.py +0 -0
  98. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/mcp/exceptions.py +0 -0
  99. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/mcp/inspection/__init__.py +0 -0
  100. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/mcp/inspection/inspector.py +0 -0
  101. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/mcp/inspection/relationships.py +0 -0
  102. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/mcp/inspection/topology.py +0 -0
  103. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/mcp/knowledge/__init__.py +0 -0
  104. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/mcp/knowledge/documentation.py +0 -0
  105. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/mcp/operations/__init__.py +0 -0
  106. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/mcp/operations/merger.py +0 -0
  107. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/mcp/operations/splitter.py +0 -0
  108. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/mcp/schemas.py +0 -0
  109. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/mcp/utilities/__init__.py +0 -0
  110. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/mcp/utilities/subsystem.py +0 -0
  111. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/mcp/utilities/timeseries.py +0 -0
  112. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/mcp/validation/__init__.py +0 -0
  113. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/mcp/validation/auto_fixer.py +0 -0
  114. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/mcp/validation/diagnostics.py +0 -0
  115. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/mcp/validation/suggestions.py +0 -0
  116. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/mcp/version.py +0 -0
  117. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/quantities.py +0 -0
  118. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/structural/__init__.py +0 -0
  119. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/structural/components/__init__.py +0 -0
  120. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/structural/components/base.py +0 -0
  121. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/structural/components/building.py +0 -0
  122. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/structural/components/overhead_line_segment.py +0 -0
  123. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/structural/components/pole.py +0 -0
  124. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/structural/components/pvsystem.py +0 -0
  125. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/structural/components/transformer.py +0 -0
  126. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/structural/components/underground_cable.py +0 -0
  127. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/structural/components/underground_junction.py +0 -0
  128. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/structural/structural_system.py +0 -0
  129. {grid_data_models-2.3.0 → grid_data_models-2.3.2}/src/gdm/tracked_changes.py +0 -0
@@ -7,6 +7,8 @@ __pycache__/
7
7
  *.so
8
8
  *.code-workspace
9
9
  *.sqlite
10
+ *.db
11
+ *.sql
10
12
  *.ruff_cache/
11
13
 
12
14
  # Distribution / packaging
@@ -163,3 +165,5 @@ cython_debug/
163
165
  #.idea/
164
166
  .qodo
165
167
  .DS_Store
168
+ *.dump
169
+ uv.lock
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: grid-data-models
3
- Version: 2.3.0
3
+ Version: 2.3.2
4
4
  Project-URL: Documentation, https://github.com/NREL-Distribution-Suites/grid-data-models#readme
5
5
  Project-URL: Issues, https://github.com/NREL-Distribution-Suites/grid-data-models/issues
6
6
  Project-URL: Source, https://github.com/NREL-Distribution-Suites/grid-data-models
@@ -11,7 +11,6 @@ Classifier: License :: OSI Approved :: BSD License
11
11
  Classifier: Operating System :: OS Independent
12
12
  Classifier: Programming Language :: Python :: 3.11
13
13
  Requires-Python: >=3.11
14
- Requires-Dist: click~=8.1.7
15
14
  Requires-Dist: geopandas
16
15
  Requires-Dist: importlib-metadata
17
16
  Requires-Dist: infrasys~=1.0
@@ -20,6 +19,7 @@ Requires-Dist: pandas~=2.2.3
20
19
  Requires-Dist: plotly
21
20
  Requires-Dist: pydantic
22
21
  Requires-Dist: semver
22
+ Requires-Dist: typer
23
23
  Provides-Extra: dev
24
24
  Requires-Dist: docutils; extra == 'dev'
25
25
  Requires-Dist: pre-commit; extra == 'dev'
@@ -30,6 +30,7 @@ Requires-Dist: pytest-doctestplus; extra == 'dev'
30
30
  Requires-Dist: ruff; extra == 'dev'
31
31
  Provides-Extra: doc
32
32
  Requires-Dist: autodoc-pydantic[erdantic]; extra == 'doc'
33
+ Requires-Dist: jupyter-book<3,>=2; extra == 'doc'
33
34
  Requires-Dist: myst-parser; extra == 'doc'
34
35
  Requires-Dist: pydata-sphinx-theme; extra == 'doc'
35
36
  Requires-Dist: sphinx; extra == 'doc'
@@ -40,7 +41,7 @@ Description-Content-Type: text/markdown
40
41
 
41
42
 
42
43
 
43
- [![Upload to PyPi](https://github.com/NLR-Distribution-Suite/grid-data-models/actions/workflows/publish_to_pypi.yml/badge.svg)](https://github.com/NLR-Distribution-Suite/grid-data-models/actions/workflows/publish_to_pypi.yml) • [![Pytest](https://github.com/NLR-Distribution-Suite/grid-data-models/actions/workflows/pull_request_tests.yml/badge.svg)](https://github.com/NLR-Distribution-Suite/grid-data-models/actions/workflows/pull_request_tests.yml) • [![deploy-book](https://github.com/NLR-Distribution-Suite/grid-data-models/actions/workflows/deploy.yml/badge.svg)](https://github.com/NLR-Distribution-Suite/grid-data-models/actions/workflows/deploy.yml) • ![PyPI - Downloads](https://img.shields.io/pypi/dm/grid-data-models) • [![codecov](https://codecov.io/github/NLR-Distribution-Suite/grid-data-models/branch/main/graph/badge.svg?token=K0X11EXOX8)](https://codecov.io/github/NLR-Distribution-Suite/grid-data-models) • [![CodeFactor](https://www.codefactor.io/repository/github/nlr-distribution-suite/grid-data-models/badge)](https://www.codefactor.io/repository/github/nlr-distribution-suite/grid-data-models) • ![MCP Server](https://img.shields.io/badge/MCP_Server-enabled-brightgreen) • ![MCP Tools](https://img.shields.io/badge/MCP_Tools-20-blue)
44
+ [![Upload to PyPi](https://github.com/NLR-Distribution-Suite/grid-data-models/actions/workflows/publish_to_pypi.yml/badge.svg)](https://github.com/NLR-Distribution-Suite/grid-data-models/actions/workflows/publish_to_pypi.yml) • [![Pytest](https://github.com/NLR-Distribution-Suite/grid-data-models/actions/workflows/pull_request_tests.yml/badge.svg)](https://github.com/NLR-Distribution-Suite/grid-data-models/actions/workflows/pull_request_tests.yml) • [![deploy-book](https://github.com/NLR-Distribution-Suite/grid-data-models/actions/workflows/deploy.yml/badge.svg)](https://github.com/NLR-Distribution-Suite/grid-data-models/actions/workflows/deploy.yml) • ![PyPI - Downloads](https://img.shields.io/pypi/dm/grid-data-models) • [![codecov](https://codecov.io/github/NLR-Distribution-Suite/grid-data-models/branch/main/graph/badge.svg?token=K0X11EXOX8)](https://codecov.io/github/NLR-Distribution-Suite/grid-data-models) • [![CodeFactor](https://www.codefactor.io/repository/github/nlr-distribution-suite/grid-data-models/badge)](https://www.codefactor.io/repository/github/nlr-distribution-suite/grid-data-models) • ![MCP Server](https://img.shields.io/badge/MCP_Server-enabled-brightgreen) • ![MCP Tools](https://img.shields.io/badge/MCP_Tools-20-blue) • [![GitHub issues](https://img.shields.io/github/issues/NLR-Distribution-Suite/grid-data-models)](https://github.com/NLR-Distribution-Suite/grid-data-models/issues) • [![License](https://img.shields.io/github/license/NLR-Distribution-Suite/grid-data-models)](https://github.com/NLR-Distribution-Suite/grid-data-models/blob/main/LICENSE.txt)
44
45
 
45
46
  # Grid Data Models (GDM)
46
47
 
@@ -61,7 +62,7 @@ In an effort to reduce code duplication and provide client packages a standard i
61
62
  - **Built-in validation layer:** Use of [pydantic](https://docs.pydantic.dev/latest/) allows us to validate model fields.
62
63
  - **Time series data management:** GDM uses [infrasys](https://github.nrel.gov/CADET/infrastructure_systems) package which enables [efficient time series data management](https://nrel.github.io/infrasys/explanation/time_series.html) by sharing arrays across components and offloading system memory. For example, we can attach time series power consumption data to a load profile.
63
64
  - **Built-in unit conversion:** GDM leverages [pint](https://pint.readthedocs.io/en/stable/) for unit conversion for power system quantities. For example, power, voltage, time, etc.
64
- - **JSON serialization/deserialization:** GDM uses [infrasys](https://github.com/NREL/infrasys) to serialize and deserialize distribution system components to/from JSON.
65
+ - **JSON serialization/deserialization:** GDM uses [infrasys](https://github.com/NatLabRockies/infrasys) to serialize and deserialize distribution system components to/from JSON.
65
66
  - **Track System Changes:** Supports tracking changes within a distribution model (both temporal and scenario-based static updates), enabling powerful scenario management capabilities.
66
67
  - **Graph-Based Analysis:** Exposes a connectivity graph using NetworkX, allowing advanced graph-based algorithms and visualizations.
67
68
  - **Interoperability:** Easily integrates with existing tools.
@@ -97,9 +98,9 @@ For more details, see the [MCP documentation](docs/mcp/).
97
98
 
98
99
  ## Contributors
99
100
 
100
- - **Kapil Duwadi**
101
101
  - **Aadil Latif**
102
- - **Tarek Elgindy**
103
- - **Pedro Andres Sanchez Perez**
104
102
  - **Daniel Thom**
105
103
  - **Jeremy Keen**
104
+ - **Kapil Duwadi**
105
+ - **Tarek Elgindy**
106
+ - **Pedro Andres Sanchez Perez**
@@ -1,6 +1,6 @@
1
1
 
2
2
 
3
- [![Upload to PyPi](https://github.com/NLR-Distribution-Suite/grid-data-models/actions/workflows/publish_to_pypi.yml/badge.svg)](https://github.com/NLR-Distribution-Suite/grid-data-models/actions/workflows/publish_to_pypi.yml) • [![Pytest](https://github.com/NLR-Distribution-Suite/grid-data-models/actions/workflows/pull_request_tests.yml/badge.svg)](https://github.com/NLR-Distribution-Suite/grid-data-models/actions/workflows/pull_request_tests.yml) • [![deploy-book](https://github.com/NLR-Distribution-Suite/grid-data-models/actions/workflows/deploy.yml/badge.svg)](https://github.com/NLR-Distribution-Suite/grid-data-models/actions/workflows/deploy.yml) • ![PyPI - Downloads](https://img.shields.io/pypi/dm/grid-data-models) • [![codecov](https://codecov.io/github/NLR-Distribution-Suite/grid-data-models/branch/main/graph/badge.svg?token=K0X11EXOX8)](https://codecov.io/github/NLR-Distribution-Suite/grid-data-models) • [![CodeFactor](https://www.codefactor.io/repository/github/nlr-distribution-suite/grid-data-models/badge)](https://www.codefactor.io/repository/github/nlr-distribution-suite/grid-data-models) • ![MCP Server](https://img.shields.io/badge/MCP_Server-enabled-brightgreen) • ![MCP Tools](https://img.shields.io/badge/MCP_Tools-20-blue)
3
+ [![Upload to PyPi](https://github.com/NLR-Distribution-Suite/grid-data-models/actions/workflows/publish_to_pypi.yml/badge.svg)](https://github.com/NLR-Distribution-Suite/grid-data-models/actions/workflows/publish_to_pypi.yml) • [![Pytest](https://github.com/NLR-Distribution-Suite/grid-data-models/actions/workflows/pull_request_tests.yml/badge.svg)](https://github.com/NLR-Distribution-Suite/grid-data-models/actions/workflows/pull_request_tests.yml) • [![deploy-book](https://github.com/NLR-Distribution-Suite/grid-data-models/actions/workflows/deploy.yml/badge.svg)](https://github.com/NLR-Distribution-Suite/grid-data-models/actions/workflows/deploy.yml) • ![PyPI - Downloads](https://img.shields.io/pypi/dm/grid-data-models) • [![codecov](https://codecov.io/github/NLR-Distribution-Suite/grid-data-models/branch/main/graph/badge.svg?token=K0X11EXOX8)](https://codecov.io/github/NLR-Distribution-Suite/grid-data-models) • [![CodeFactor](https://www.codefactor.io/repository/github/nlr-distribution-suite/grid-data-models/badge)](https://www.codefactor.io/repository/github/nlr-distribution-suite/grid-data-models) • ![MCP Server](https://img.shields.io/badge/MCP_Server-enabled-brightgreen) • ![MCP Tools](https://img.shields.io/badge/MCP_Tools-20-blue) • [![GitHub issues](https://img.shields.io/github/issues/NLR-Distribution-Suite/grid-data-models)](https://github.com/NLR-Distribution-Suite/grid-data-models/issues) • [![License](https://img.shields.io/github/license/NLR-Distribution-Suite/grid-data-models)](https://github.com/NLR-Distribution-Suite/grid-data-models/blob/main/LICENSE.txt)
4
4
 
5
5
  # Grid Data Models (GDM)
6
6
 
@@ -21,7 +21,7 @@ In an effort to reduce code duplication and provide client packages a standard i
21
21
  - **Built-in validation layer:** Use of [pydantic](https://docs.pydantic.dev/latest/) allows us to validate model fields.
22
22
  - **Time series data management:** GDM uses [infrasys](https://github.nrel.gov/CADET/infrastructure_systems) package which enables [efficient time series data management](https://nrel.github.io/infrasys/explanation/time_series.html) by sharing arrays across components and offloading system memory. For example, we can attach time series power consumption data to a load profile.
23
23
  - **Built-in unit conversion:** GDM leverages [pint](https://pint.readthedocs.io/en/stable/) for unit conversion for power system quantities. For example, power, voltage, time, etc.
24
- - **JSON serialization/deserialization:** GDM uses [infrasys](https://github.com/NREL/infrasys) to serialize and deserialize distribution system components to/from JSON.
24
+ - **JSON serialization/deserialization:** GDM uses [infrasys](https://github.com/NatLabRockies/infrasys) to serialize and deserialize distribution system components to/from JSON.
25
25
  - **Track System Changes:** Supports tracking changes within a distribution model (both temporal and scenario-based static updates), enabling powerful scenario management capabilities.
26
26
  - **Graph-Based Analysis:** Exposes a connectivity graph using NetworkX, allowing advanced graph-based algorithms and visualizations.
27
27
  - **Interoperability:** Easily integrates with existing tools.
@@ -57,9 +57,9 @@ For more details, see the [MCP documentation](docs/mcp/).
57
57
 
58
58
  ## Contributors
59
59
 
60
- - **Kapil Duwadi**
61
60
  - **Aadil Latif**
62
- - **Tarek Elgindy**
63
- - **Pedro Andres Sanchez Perez**
64
61
  - **Daniel Thom**
65
62
  - **Jeremy Keen**
63
+ - **Kapil Duwadi**
64
+ - **Tarek Elgindy**
65
+ - **Pedro Andres Sanchez Perez**
@@ -26,7 +26,7 @@ dependencies = [
26
26
  "pydantic",
27
27
  "infrasys~=1.0",
28
28
  "importlib_metadata",
29
- "click~=8.1.7",
29
+ "typer",
30
30
  "pandas~=2.2.3",
31
31
  "geopandas",
32
32
  "plotly",
@@ -36,6 +36,7 @@ dependencies = [
36
36
  mcp = ["mcp>=1.0.0"]
37
37
  dev = ["pre-commit", "pytest", "pytest-cov", "pytest-doctestplus", "pytest-asyncio", "ruff", "docutils"]
38
38
  doc = [
39
+ "jupyter-book>=2,<3",
39
40
  "sphinx",
40
41
  "pydata-sphinx-theme",
41
42
  "myst-parser",
@@ -44,7 +45,7 @@ doc = [
44
45
  ]
45
46
 
46
47
  [project.scripts]
47
- gdm = "gdm.cli.cli:cli"
48
+ gdm = "gdm.cli.cli:app"
48
49
  gdm-mcp-server = "gdm.mcp.server:main"
49
50
 
50
51
  [project.urls]
@@ -0,0 +1,5 @@
1
+ import typer
2
+ from gdm.cli.reducer import reduce
3
+
4
+ app = typer.Typer()
5
+ app.command()(reduce)
@@ -0,0 +1,53 @@
1
+ from enum import Enum
2
+ from pathlib import Path
3
+ import shutil
4
+ from typing import Annotated
5
+
6
+ import typer
7
+
8
+ from gdm.distribution.model_reduction.reducer import reduce_to_three_phase_system
9
+ from gdm.distribution.distribution_system import DistributionSystem
10
+ from gdm.exceptions import FolderAlreadyExistsError
11
+
12
+
13
+ class ReducerType(str, Enum):
14
+ three_phase = "three_phase"
15
+
16
+
17
+ def reduce(
18
+ gdm_file: Annotated[str, typer.Option("-g", "--gdm-file", help="GDM system JSON file path.")],
19
+ target_file: Annotated[
20
+ str, typer.Option("-t", "--target-file", help="Target GDM system JSON file path.")
21
+ ],
22
+ force: Annotated[
23
+ bool,
24
+ typer.Option(
25
+ "-f", "--force", help="Force delete the target GDM system file if already exists."
26
+ ),
27
+ ] = False,
28
+ reducer: Annotated[
29
+ ReducerType, typer.Option("-r", "--reducer", help="Reducer type to apply.")
30
+ ] = ReducerType.three_phase,
31
+ time_series: Annotated[
32
+ bool,
33
+ typer.Option(
34
+ "-ts", "--time-series", help="Include time series data in the reduced system."
35
+ ),
36
+ ] = False,
37
+ ):
38
+ """Reduce a GDM distribution system."""
39
+ target_path = Path(target_file)
40
+ if force and target_path.exists():
41
+ shutil.rmtree(target_path.parent / f"{target_path.stem}_time_series")
42
+ target_path.unlink()
43
+
44
+ if not force and target_path.exists():
45
+ raise FolderAlreadyExistsError(
46
+ f"{target_path} already exists. Consider deleting it first."
47
+ )
48
+ sys = DistributionSystem.from_json(gdm_file)
49
+ reducer_func = {"three_phase": reduce_to_three_phase_system}
50
+ new_sys_name = sys.name + "_reduced" if sys.name else None
51
+ new_sys = reducer_func[reducer.value](sys, new_sys_name, time_series)
52
+ new_sys.to_json(target_path)
53
+ typer.echo(str(target_path))
@@ -41,7 +41,7 @@ class MatrixImpedanceBranch(DistributionBranchBase):
41
41
  """Kron reduce the branch to remove neutral."""
42
42
 
43
43
  self.equipment.kron_reduce(self.phases)
44
- self.phases = [p for p in self.phases if p != Phase.N]
44
+ object.__setattr__(self, "phases", [p for p in self.phases if p != Phase.N])
45
45
 
46
46
  @classmethod
47
47
  def example(cls) -> "MatrixImpedanceBranch":
@@ -220,8 +220,41 @@ class DistributionSystem(System):
220
220
  edge.buses[1].name,
221
221
  **data,
222
222
  )
223
+
224
+ # Validate that every phase on each bus is served by at least one connected component.
225
+ self._warn_uncovered_bus_phases(edges)
226
+
223
227
  return graph
224
228
 
229
+ def _warn_uncovered_bus_phases(
230
+ self,
231
+ edges: list,
232
+ ) -> None:
233
+ """Log a warning if any bus has phases not connected to any component."""
234
+ bus_covered_phases: dict[str, set] = {
235
+ node.name: set() for node in self.get_components(DistributionBus)
236
+ }
237
+ for edge in edges:
238
+ if isinstance(edge, DistributionBranchBase):
239
+ edge_phase_set = set(edge.phases)
240
+ for bus in edge.buses:
241
+ bus_covered_phases[bus.name] |= edge_phase_set
242
+ elif isinstance(edge, DistributionTransformerBase):
243
+ for bus, winding_phases in zip(edge.buses, edge.winding_phases):
244
+ bus_covered_phases[bus.name] |= set(winding_phases)
245
+
246
+ uncovered: dict[str, list] = {}
247
+ for bus in self.get_components(DistributionBus):
248
+ missing = set(bus.phases) - bus_covered_phases[bus.name]
249
+ if missing:
250
+ uncovered[bus.name] = sorted(p.value for p in missing)
251
+
252
+ if uncovered:
253
+ details = "; ".join(f"{name}: {phases}" for name, phases in uncovered.items())
254
+ logger.warning(
255
+ f"The following buses have phases not connected to any component: {details}"
256
+ )
257
+
225
258
  def _add_to_subsystem(
226
259
  self,
227
260
  subtree_system: "DistributionSystem",
@@ -243,8 +276,10 @@ class DistributionSystem(System):
243
276
  self,
244
277
  bus_names: list[str],
245
278
  name: str,
246
- keep_timeseries: bool = False,
279
+ keep_time_series: bool = False,
280
+ keep_timeseries: bool | None = None,
247
281
  time_series_type: Type[TimeSeriesData] = SingleTimeSeries,
282
+ directed_graph: nx.DiGraph | None = None,
248
283
  ) -> "DistributionSystem":
249
284
  """Method to get subsystem from list of buses.
250
285
 
@@ -254,15 +289,23 @@ class DistributionSystem(System):
254
289
  List of bus names
255
290
  name: str
256
291
  Name of the subsystem.
257
- keep_timeseries: bool
258
- Set this flag to retain timeseries data associated with the component.
292
+ keep_time_series: bool
293
+ Set this flag to retain time series data associated with the component.
294
+ keep_timeseries: bool | None
295
+ Deprecated alias for keep_time_series.
259
296
  time_series_type: Type[TimeSeriesData]
260
297
  Type of time series data. Defaults to: SingleTimeSeries
298
+ directed_graph: nx.DiGraph | None
299
+ Optional precomputed directed graph for this system. When provided,
300
+ it is reused instead of rebuilding the directed graph.
261
301
  Returns
262
302
  -------
263
303
  DistributionSystem
264
304
  """
265
- tree = self.get_directed_graph()
305
+ if keep_timeseries is not None:
306
+ keep_time_series = keep_timeseries
307
+
308
+ tree = directed_graph if directed_graph is not None else self.get_directed_graph()
266
309
  subtree = tree.subgraph(bus_names)
267
310
  subtree_system = DistributionSystem(auto_add_composed_components=True, name=name)
268
311
  for u, v, _ in subtree.edges(data=True):
@@ -275,7 +318,7 @@ class DistributionSystem(System):
275
318
  parent_components = self.list_parent_components(self.get_component(DistributionBus, u))
276
319
  self._add_to_subsystem(subtree_system, parent_components, bus_names)
277
320
 
278
- if keep_timeseries:
321
+ if keep_time_series:
279
322
  for comp in subtree_system.get_components(
280
323
  Component,
281
324
  filter_func=lambda x: self.has_time_series(x, time_series_type=time_series_type),
@@ -437,7 +480,6 @@ class DistributionSystem(System):
437
480
  bus_1 = cycle[i]
438
481
  bus_2 = cycle[(i + 1) % len(cycle)]
439
482
  edge_data = self.get_undirected_graph().get_edge_data(bus_1, bus_2)
440
- print(bus_1, bus_2, edge_data)
441
483
  if edge_data:
442
484
  for key, data in edge_data.items():
443
485
  if issubclass(data.get("type"), MatrixImpedanceSwitch):
@@ -447,7 +489,10 @@ class DistributionSystem(System):
447
489
  break
448
490
  return list(set(switch_buses))
449
491
 
450
- def get_split_phase_mapping(self) -> dict[str, set[Phase]]:
492
+ def get_split_phase_mapping(
493
+ self,
494
+ directed_graph: nx.DiGraph | None = None,
495
+ ) -> dict[str, set[Phase]]:
451
496
  """Generates a mapping of components to their split-phase configurations.
452
497
 
453
498
  This method identifies distribution transformers with center-tapped windings and
@@ -461,6 +506,12 @@ class DistributionSystem(System):
461
506
  A dictionary where keys are component names and values are sets of phases
462
507
  associated with the high-voltage bus.
463
508
 
509
+ Parameters
510
+ ----------
511
+ directed_graph: nx.DiGraph | None
512
+ Optional precomputed directed graph for this system. When provided,
513
+ it is reused instead of rebuilding the directed graph.
514
+
464
515
  Notes
465
516
  -----
466
517
  - The method uses the directed graph representation of the distribution system to
@@ -472,7 +523,7 @@ class DistributionSystem(System):
472
523
  - Logs the process of identifying and mapping split-phase transformers.
473
524
  """
474
525
  split_phase_map = {}
475
- original_tree = self.get_directed_graph()
526
+ original_tree = directed_graph if directed_graph is not None else self.get_directed_graph()
476
527
  split_phase_trs: list[DistributionTransformer] = list(
477
528
  self.get_components(
478
529
  DistributionTransformer,
@@ -485,7 +536,9 @@ class DistributionSystem(System):
485
536
  }.pop()
486
537
  hv_bus = (set([bus.name for bus in tr.buses]) - set([lv_bus])).pop()
487
538
  lv_system = self.get_subsystem(
488
- list(nx.descendants(original_tree, lv_bus)) + [lv_bus], name=""
539
+ list(nx.descendants(original_tree, lv_bus)) + [lv_bus],
540
+ name="",
541
+ directed_graph=original_tree,
489
542
  )
490
543
  bus_model_types = self.get_model_types_with_field_type(DistributionBus)
491
544
  for model_type in bus_model_types:
@@ -118,6 +118,21 @@ class TOUPeriodType(str, Enum):
118
118
  MID_PEAK = "mid_peak"
119
119
 
120
120
 
121
+ class Month(str, Enum):
122
+ JANUARY = "january"
123
+ FEBRUARY = "february"
124
+ MARCH = "march"
125
+ APRIL = "april"
126
+ MAY = "may"
127
+ JUNE = "june"
128
+ JULY = "july"
129
+ AUGUST = "august"
130
+ SEPTEMBER = "september"
131
+ OCTOBER = "october"
132
+ NOVEMBER = "november"
133
+ DECEMBER = "december"
134
+
135
+
121
136
  class Season(str, Enum):
122
137
  SUMMER = "summer"
123
138
  WINTER = "winter"
@@ -54,13 +54,22 @@ class PhaseCapacitorEquipment(Component):
54
54
  def aggregate(
55
55
  cls, instances: list["PhaseCapacitorEquipment"], name: str
56
56
  ) -> "PhaseCapacitorEquipment":
57
+ resistance_inverse_sum = sum(
58
+ 1 / inst.resistance for inst in instances if inst.resistance.magnitude
59
+ )
60
+ reactance_inverse_sum = sum(
61
+ 1 / inst.reactance for inst in instances if inst.reactance.magnitude
62
+ )
63
+
57
64
  return PhaseCapacitorEquipment(
58
65
  name=name,
59
66
  rated_reactive_power=sum(inst.rated_reactive_power for inst in instances),
60
- resistance=1
61
- / sum(1 / inst.resistance if inst.resistance.magnitude else 0 for inst in instances),
62
- reactance=1
63
- / sum(1 / inst.reactance if inst.reactance.magnitude else 0 for inst in instances),
67
+ resistance=(
68
+ 1 / resistance_inverse_sum if resistance_inverse_sum else Resistance(0, "ohm")
69
+ ),
70
+ reactance=(
71
+ 1 / reactance_inverse_sum if reactance_inverse_sum else Reactance(0, "ohm")
72
+ ),
64
73
  num_banks=sum(inst.num_banks for inst in instances),
65
74
  num_banks_on=sum(inst.num_banks_on for inst in instances),
66
75
  )
@@ -4,7 +4,7 @@ from pydantic import Field, model_validator
4
4
  from typing import List, Optional
5
5
  from infrasys import Component
6
6
 
7
- from gdm.distribution.enums import BillingDemandBasis, CustomerClass, TOUPeriodType, Season
7
+ from gdm.distribution.enums import BillingDemandBasis, CustomerClass, Month, TOUPeriodType
8
8
 
9
9
 
10
10
  class TOURatePeriod(Component):
@@ -50,13 +50,13 @@ class DemandCharge(Component):
50
50
 
51
51
  class SeasonalTOURates(Component):
52
52
  name: str = ""
53
- season: Season = Field(..., description="Season for the TOU rates")
54
- tou_periods: List[TOURatePeriod] = Field(..., description="List of TOU periods for the season")
53
+ season: Month = Field(..., description="Month for the TOU rates")
54
+ tou_periods: List[TOURatePeriod] = Field(..., description="List of TOU periods for the month")
55
55
 
56
56
  @classmethod
57
57
  def example(cls) -> "SeasonalTOURates":
58
58
  return SeasonalTOURates(
59
- season=Season.SUMMER,
59
+ season=Month.JULY,
60
60
  tou_periods=[
61
61
  TOURatePeriod.example(),
62
62
  TOURatePeriod(
@@ -114,7 +114,7 @@ class DistributionTariff(Component):
114
114
  seasonal_tou=[
115
115
  SeasonalTOURates.example(),
116
116
  SeasonalTOURates(
117
- season=Season.WINTER,
117
+ season=Month.JANUARY,
118
118
  tou_periods=[
119
119
  TOURatePeriod.example(),
120
120
  TOURatePeriod(
@@ -14,9 +14,9 @@ from gdm.distribution.distribution_system import (
14
14
  )
15
15
  from gdm.distribution.enums import Phase
16
16
  from gdm.distribution.sys_functools import (
17
- get_aggregated_load_timeseries,
18
- get_aggregated_solar_timeseries,
19
- get_aggregated_battery_timeseries,
17
+ get_aggregated_load_time_series,
18
+ get_aggregated_solar_time_series,
19
+ get_aggregated_battery_time_series,
20
20
  )
21
21
 
22
22
 
@@ -74,23 +74,28 @@ def _reduce_system(
74
74
  dist_system: DistributionSystem,
75
75
  bus_subset: list[DistributionBus],
76
76
  name: str,
77
- agg_timeseries: bool = False,
77
+ agg_time_series: bool = False,
78
+ agg_timeseries: bool | None = None,
78
79
  time_series_type: Type[TimeSeriesData] = SingleTimeSeries,
79
80
  ) -> DistributionSystem:
81
+ if agg_timeseries is not None:
82
+ agg_time_series = agg_timeseries
83
+
84
+ original_tree = dist_system.get_directed_graph()
80
85
  reduced_system = dist_system.get_subsystem(
81
86
  bus_subset,
82
87
  name,
83
- keep_timeseries=agg_timeseries,
88
+ keep_time_series=agg_time_series,
84
89
  time_series_type=time_series_type,
90
+ directed_graph=original_tree,
85
91
  )
86
92
 
87
- split_phase_mapping = dist_system.get_split_phase_mapping()
88
- original_tree = dist_system.get_directed_graph()
93
+ split_phase_mapping = dist_system.get_split_phase_mapping(directed_graph=original_tree)
89
94
  reduced_network_tree = original_tree.subgraph(bus_subset)
90
95
  ts_agg_func_mapper: dict[Union[Type[DistributionLoad], Type[DistributionSolar]], Callable] = {
91
- DistributionLoad: get_aggregated_load_timeseries,
92
- DistributionSolar: get_aggregated_solar_timeseries,
93
- DistributionBattery: get_aggregated_battery_timeseries,
96
+ DistributionLoad: get_aggregated_load_time_series,
97
+ DistributionSolar: get_aggregated_solar_time_series,
98
+ DistributionBattery: get_aggregated_battery_time_series,
94
99
  }
95
100
  for node in reduced_network_tree.nodes():
96
101
  if reduced_network_tree.out_degree(node) < original_tree.out_degree(node):
@@ -103,7 +108,11 @@ def _reduce_system(
103
108
  for snode in nx.descendants(original_tree, successor)
104
109
  ] + list(sucessors_diff)
105
110
  subtree = original_tree.subgraph(successors_descendants)
106
- subtree_system = dist_system.get_subsystem(subtree.nodes, "")
111
+ subtree_system = dist_system.get_subsystem(
112
+ list(subtree.nodes),
113
+ "",
114
+ directed_graph=original_tree,
115
+ )
107
116
  model_types = subtree_system.get_model_types_with_field_type(DistributionBus)
108
117
  for model_type in model_types:
109
118
  agg_component = _get_aggregated_bus_component(
@@ -112,10 +121,9 @@ def _reduce_system(
112
121
  model_type=model_type,
113
122
  split_phase_mapping=split_phase_mapping,
114
123
  )
115
- # print(model_type.__name__, agg_component)
116
124
  reduced_system.add_component(agg_component)
117
125
  agg_comp = reduced_system.get_component(model_type, agg_component.name)
118
- if agg_timeseries:
126
+ if agg_time_series:
119
127
  comps = list(subtree_system.get_components(model_type))
120
128
  ts_metadata = dist_system.list_time_series_metadata(
121
129
  comps[0], time_series_type=time_series_type
@@ -135,18 +143,34 @@ def _reduce_system(
135
143
  def reduce_to_three_phase_system(
136
144
  dist_system: DistributionSystem,
137
145
  name: str,
138
- agg_timeseries: bool = False,
146
+ agg_time_series: bool = False,
147
+ agg_timeseries: bool | None = None,
139
148
  time_series_type: Type[TimeSeriesData] = SingleTimeSeries,
140
149
  ) -> DistributionSystem:
141
150
  three_phase_buses = _get_three_phase_buses(dist_system)
142
- return _reduce_system(dist_system, three_phase_buses, name, agg_timeseries, time_series_type)
151
+ return _reduce_system(
152
+ dist_system,
153
+ three_phase_buses,
154
+ name,
155
+ agg_time_series,
156
+ agg_timeseries,
157
+ time_series_type,
158
+ )
143
159
 
144
160
 
145
161
  def reduce_to_primary_system(
146
162
  dist_system: DistributionSystem,
147
163
  name: str,
148
- agg_timeseries: bool = False,
164
+ agg_time_series: bool = False,
165
+ agg_timeseries: bool | None = None,
149
166
  time_series_type: Type[TimeSeriesData] = SingleTimeSeries,
150
167
  ) -> DistributionSystem:
151
168
  primary_buses = _get_primary_buses(dist_system)
152
- return _reduce_system(dist_system, primary_buses, name, agg_timeseries, time_series_type)
169
+ return _reduce_system(
170
+ dist_system,
171
+ primary_buses,
172
+ name,
173
+ agg_time_series,
174
+ agg_timeseries,
175
+ time_series_type,
176
+ )