pandahub 0.4.2__zip → 0.4.3__zip

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 (50) hide show
  1. {pandahub-0.4.2 → pandahub-0.4.3}/PKG-INFO +1 -1
  2. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub/lib/PandaHub.py +143 -94
  3. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub.egg-info/PKG-INFO +1 -1
  4. {pandahub-0.4.2 → pandahub-0.4.3}/pyproject.toml +1 -1
  5. {pandahub-0.4.2 → pandahub-0.4.3}/CHANGELOG.md +0 -0
  6. {pandahub-0.4.2 → pandahub-0.4.3}/CONTRIBUTING.rst +0 -0
  7. {pandahub-0.4.2 → pandahub-0.4.3}/LICENSE +0 -0
  8. {pandahub-0.4.2 → pandahub-0.4.3}/MANIFEST.in +0 -0
  9. {pandahub-0.4.2 → pandahub-0.4.3}/README.md +0 -0
  10. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub/__init__.py +0 -0
  11. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub/api/__init__.py +0 -0
  12. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub/api/dependencies.py +0 -0
  13. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub/api/internal/__init__.py +0 -0
  14. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub/api/internal/db.py +0 -0
  15. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub/api/internal/schemas.py +0 -0
  16. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub/api/internal/settings.py +0 -0
  17. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub/api/internal/toolbox.py +0 -0
  18. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub/api/internal/users.py +0 -0
  19. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub/api/main.py +0 -0
  20. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub/api/routers/__init__.py +0 -0
  21. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub/api/routers/auth.py +0 -0
  22. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub/api/routers/net.py +0 -0
  23. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub/api/routers/projects.py +0 -0
  24. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub/api/routers/timeseries.py +0 -0
  25. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub/api/routers/users.py +0 -0
  26. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub/api/routers/variants.py +0 -0
  27. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub/lib/__init__.py +0 -0
  28. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub/lib/database_toolbox.py +0 -0
  29. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub/lib/datatypes.py +0 -0
  30. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub/lib/mongo_client.py +0 -0
  31. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub/lib/mongodb_indexes.py +0 -0
  32. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub/lib/timeseries/__init__.py +0 -0
  33. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub/lib/timeseries/data_sources/__init__.py +0 -0
  34. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub/lib/timeseries/data_sources/mongo_data.py +0 -0
  35. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub/lib/timeseries/output_writer_mongodb.py +0 -0
  36. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub.egg-info/SOURCES.txt +0 -0
  37. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub.egg-info/dependency_links.txt +0 -0
  38. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub.egg-info/requires.txt +0 -0
  39. {pandahub-0.4.2 → pandahub-0.4.3}/pandahub.egg-info/top_level.txt +0 -0
  40. {pandahub-0.4.2 → pandahub-0.4.3}/requirements.txt +0 -0
  41. {pandahub-0.4.2 → pandahub-0.4.3}/setup.cfg +0 -0
  42. {pandahub-0.4.2 → pandahub-0.4.3}/setup.py +0 -0
  43. {pandahub-0.4.2 → pandahub-0.4.3}/test/__init__.py +0 -0
  44. {pandahub-0.4.2 → pandahub-0.4.3}/test/conftest.py +0 -0
  45. {pandahub-0.4.2 → pandahub-0.4.3}/test/performance_test.py +0 -0
  46. {pandahub-0.4.2 → pandahub-0.4.3}/test/test_client.py +0 -0
  47. {pandahub-0.4.2 → pandahub-0.4.3}/test/test_networks.py +0 -0
  48. {pandahub-0.4.2 → pandahub-0.4.3}/test/test_projects.py +0 -0
  49. {pandahub-0.4.2 → pandahub-0.4.3}/test/test_timeseries.py +0 -0
  50. {pandahub-0.4.2 → pandahub-0.4.3}/tutorials/config.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pandahub
3
- Version: 0.4.2
3
+ Version: 0.4.3
4
4
  Summary: Data hub for pandapower and pandapipes networks based on MongoDB
5
5
  Author-email: Jan Ulffers <jan.ulffers@iee.fraunhofer.de>, Leon Thurner <leon.thurner@retoflow.de>, Jannis Kupka <jannis.kupka@retoflow.de>, Mike Vogt <mike.vogt@iee.fraunhofer.de>, Joschka Thurner <joschka.thurner@retoflow.de>, Alexander Scheidler <alexander.scheidler@iee.fraunhofer.de>
6
6
  License: Copyright (c) 2022 by University of Kassel, Fraunhofer Institute for Energy Economics
@@ -878,8 +878,8 @@ class PandaHub:
878
878
  variant=None,
879
879
  additional_filters: dict[
880
880
  str, Callable[[pp.auxiliary.pandapowerNet | pps.pandapipesNet], dict]
881
- ] = {},
882
- ) -> pp.auxiliary.pandapowerNet | pps.pandapipesNet:
881
+ ] | None = None,
882
+ ) -> (pp.pandapowerNet | pps.pandapipesNet) | (tuple[pp.pandapowerNet | pps.pandapipesNet, list] | None):
883
883
  self.check_permission("read")
884
884
  db = self._get_project_database()
885
885
  net_id = self._get_net_id_from_name(name, db)
@@ -908,7 +908,13 @@ class PandaHub:
908
908
  additional_filters: dict[
909
909
  str, Callable[[pp.auxiliary.pandapowerNet | pps.pandapipesNet], dict]
910
910
  ] | None = None,
911
- additional_branch_node_cols: dict[str, list[str]] | None = None,
911
+ additional_edge_filters: dict[
912
+ str, tuple[
913
+ list[str] | tuple[str, ...] | None,
914
+ bool,
915
+ dict | None,
916
+ Callable[[pp.auxiliary.pandapowerNet | pps.pandapipesNet], dict] | None
917
+ ]] | None = None,
912
918
  *,
913
919
  return_edge_branch_nodes: bool = False
914
920
  ) -> (pp.pandapowerNet | pps.pandapipesNet) | (tuple[pp.pandapowerNet | pps.pandapipesNet, list]):
@@ -920,78 +926,26 @@ class PandaHub:
920
926
 
921
927
  if additional_filters is None:
922
928
  additional_filters = {}
923
- if additional_branch_node_cols is None:
924
- additional_branch_node_cols = {}
925
-
926
- def switch_filter(bus_filter):
927
- return {
928
- "$and": [
929
- {"et": "b"},
930
- bus_filter,
931
- ]
932
- }
933
-
934
- def get_nodes_from_element(ntw, element, nd_cols):
935
- return [ntw[element][ndc].to_numpy() for ndc in nd_cols]
936
-
937
- def get_nodes_from_switch(ntw, _, _nd_cols):
938
- return [ntw.switch.bus.to_numpy(), ntw.switch.loc[ntw.switch.et == "b", "element"].to_numpy()]
929
+ if additional_edge_filters is None:
930
+ additional_edge_filters = {}
939
931
 
932
+ filtered_elements = set(additional_filters.keys()) | set(additional_edge_filters.keys())
940
933
  if is_power:
941
934
  net = pp.create_empty_network()
942
- node_name = "bus"
943
- default_branches = ["line", "trafo", "trafo3w", "switch"]
944
- default_node_cols = [
945
- ("from_bus", "to_bus"),
946
- ("hv_bus", "lv_bus"),
947
- ("hv_bus", "lv_bus", "mv_bus"),
948
- ("bus", "element")
949
- ]
950
- special_filters = {"switch": switch_filter}
951
- get_nodes_func = {br: get_nodes_from_element for br in default_branches}
952
- get_nodes_func["switch"] = get_nodes_from_switch
953
- # add node elements
954
- node_elements = [
955
- "load",
956
- "asymmetric_load",
957
- "sgen",
958
- "asymmetric_sgen",
959
- "gen",
960
- "ext_grid",
961
- "shunt",
962
- "xward",
963
- "ward",
964
- "motor",
965
- "storage",
966
- ]
967
- branch_elements = ["trafo", "line", "trafo3w", "switch", "impedance"]
968
- all_elements = (
969
- node_elements + branch_elements + ["bus"] + list(additional_filters.keys())
970
- )
971
- all_elements = list(set(all_elements) - set(ignore_elements))
935
+ data_func = get_subnet_filter_data_power
936
+ args = [filtered_elements]
972
937
  else:
973
938
  net = pps.create_empty_network()
974
- node_name = "junction"
975
- component_list = []
976
- if "data" in meta and "component_list" in meta["data"]:
977
- component_list = json.loads(
978
- meta["data"]["component_list"][11:], cls=io_pp.PPJSONDecoder,
979
- registry_class=FromSerializableRegistryPpipe
980
- )
981
- default_branches = []
982
- default_node_cols = []
983
- node_elements = []
984
- all_elements = []
985
- for c in component_list:
986
- pps.add_new_component(net, c)
987
- all_elements.append(c.table_name())
988
- if issubclass(c, BranchComponent):
989
- default_branches.append(c.table_name())
990
- default_node_cols.append(c.from_to_node_cols())
991
- if issubclass(c, NodeElementComponent):
992
- node_elements.append(c.table_name())
993
- special_filters = dict()
994
- get_nodes_func = {br: get_nodes_from_element for br in default_branches}
939
+ data_func = get_subnet_filter_data_pipe
940
+ args = [net, filtered_elements, meta]
941
+ (
942
+ node_name,
943
+ branch_tables,
944
+ branch_node_cols,
945
+ special_filters,
946
+ get_nodes_func,
947
+ node_elements,
948
+ ) = data_func(*args)
995
949
 
996
950
  if db[self._collection_name_of_element(node_name)].find_one() is None:
997
951
  net["empty"] = True
@@ -1014,14 +968,23 @@ class PandaHub:
1014
968
 
1015
969
  if isinstance(add_edge_branches, bool):
1016
970
  if add_edge_branches:
1017
- add_edge_branches = default_branches
971
+ add_edge_branches = branch_tables
1018
972
  else:
1019
973
  add_edge_branches = []
1020
974
  elif not isinstance(add_edge_branches, list):
1021
975
  raise ValueError("add_edge_branches must be a list or a boolean")
1022
976
 
977
+ for tbl, (node_cols, add_edge, filter_func, node_getter) in additional_edge_filters.items():
978
+ branch_tables.append(tbl)
979
+ branch_node_cols.append(tuple(node_cols))
980
+ if add_edge:
981
+ add_edge_branches.append(tbl)
982
+ if filter_func is not None:
983
+ special_filters[tbl] = filter_func
984
+ get_nodes_func[tbl] = node_getter if node_getter is not None else get_nodes_from_element
985
+
1023
986
  branch_nodes = set()
1024
- for branch_name, node_cols in zip(default_branches, default_node_cols):
987
+ for branch_name, node_cols in zip(branch_tables, branch_node_cols):
1025
988
  operator = "$or" if branch_name in add_edge_branches else "$and"
1026
989
  # Add branch elements connected to at least one node
1027
990
  filter_ = {operator: [{b: {"$in": nodes}} for b in node_cols]}
@@ -1032,13 +995,6 @@ class PandaHub:
1032
995
  get_nd_func = get_nodes_func[branch_name]
1033
996
  branch_nodes.update(set(chain.from_iterable(get_nd_func(net, branch_name, node_cols))))
1034
997
 
1035
- for branch_name, node_cols in additional_branch_node_cols.items():
1036
- if branch_name not in net:
1037
- continue
1038
- branch_nodes.update(
1039
- set(chain.from_iterable(get_nodes_from_element(net, branch_name, node_cols)))
1040
- )
1041
-
1042
998
  branch_nodes_outside = []
1043
999
  if branch_nodes:
1044
1000
  # Add buses on the other side of the branches
@@ -1048,18 +1004,7 @@ class PandaHub:
1048
1004
  nodes = net[node_name].index.tolist()
1049
1005
 
1050
1006
  if is_power:
1051
- add_args["filter"] = {
1052
- "$or": [
1053
- {"$and": [{"et": "t"}, {"element": {"$in": net.trafo.index.tolist()}}]},
1054
- {"$and": [{"et": "l"}, {"element": {"$in": net.line.index.tolist()}}]},
1055
- {
1056
- "$and": [
1057
- {"et": "t3"},
1058
- {"element": {"$in": net.trafo3w.index.tolist()}},
1059
- ]
1060
- },
1061
- ]
1062
- }
1007
+ add_args["filter"] = filter_switch_for_element(net)
1063
1008
  self._add_element_from_collection(element_type="switch", **add_args)
1064
1009
 
1065
1010
  # add all node elements that are connected to buses within the network
@@ -1079,11 +1024,10 @@ class PandaHub:
1079
1024
  for collection in collection_names:
1080
1025
  table_name = self._element_name_of_collection(collection)
1081
1026
  # skip all element tables that we have already added
1082
- if (table_name in all_elements or table_name in ignore_elements
1083
- or table_name in additional_filters.keys()):
1027
+ if table_name in filtered_elements or table_name in ignore_elements:
1084
1028
  continue
1085
1029
  # for tables that share an index with an element (e.g. load->res_load) load only relevant entries
1086
- for element in all_elements:
1030
+ for element in filtered_elements:
1087
1031
  if table_name.startswith(element + "_") or table_name.startswith(
1088
1032
  "net_res_" + element
1089
1033
  ):
@@ -3196,6 +3140,111 @@ class PandaHub:
3196
3140
  return self.get_net_collections(db, with_areas)
3197
3141
 
3198
3142
 
3143
+ def switch_filter(bus_filter):
3144
+ return {
3145
+ "$and": [
3146
+ {"et": "b"},
3147
+ bus_filter,
3148
+ ]
3149
+ }
3150
+
3151
+
3152
+ def filter_switch_for_element(net):
3153
+ return {
3154
+ "$or": [
3155
+ {"$and": [{"et": "t"}, {"element": {"$in": net.trafo.index.tolist()}}]},
3156
+ {"$and": [{"et": "l"}, {"element": {"$in": net.line.index.tolist()}}]},
3157
+ {
3158
+ "$and": [
3159
+ {"et": "t3"},
3160
+ {"element": {"$in": net.trafo3w.index.tolist()}},
3161
+ ]
3162
+ },
3163
+ ]
3164
+ }
3165
+
3166
+
3167
+ def get_nodes_from_element(ntw, element, nd_cols):
3168
+ if element not in ntw:
3169
+ return [[] for _ in nd_cols]
3170
+ return [ntw[element][ndc].tolist() for ndc in nd_cols]
3171
+
3172
+
3173
+ def get_nodes_from_switch(ntw, _, _nd_cols):
3174
+ return [ntw.switch.bus.to_numpy(), ntw.switch.loc[ntw.switch.et == "b", "element"].to_numpy()]
3175
+
3176
+
3177
+ def get_subnet_filter_data_power(filtered_elements):
3178
+ node_name = "bus"
3179
+ branch_tables = ["line", "trafo", "trafo3w", "switch"]
3180
+ branch_node_cols = [
3181
+ ("from_bus", "to_bus"),
3182
+ ("hv_bus", "lv_bus"),
3183
+ ("hv_bus", "lv_bus", "mv_bus"),
3184
+ ("bus", "element"),
3185
+ ]
3186
+ special_filters = {"switch": switch_filter}
3187
+ get_nodes_func = {br: get_nodes_from_element for br in branch_tables}
3188
+ get_nodes_func["switch"] = get_nodes_from_switch
3189
+ # add node elements
3190
+ node_elements = [
3191
+ "load",
3192
+ "asymmetric_load",
3193
+ "sgen",
3194
+ "asymmetric_sgen",
3195
+ "gen",
3196
+ "ext_grid",
3197
+ "shunt",
3198
+ "xward",
3199
+ "ward",
3200
+ "motor",
3201
+ "storage",
3202
+ ]
3203
+ branch_elements = ["trafo", "line", "trafo3w", "switch", "impedance"]
3204
+ filtered_elements |= set(node_elements) | set(branch_elements) | {"bus"}
3205
+ return (
3206
+ node_name,
3207
+ branch_tables,
3208
+ branch_node_cols,
3209
+ special_filters,
3210
+ get_nodes_func,
3211
+ node_elements,
3212
+ )
3213
+
3214
+
3215
+ def get_subnet_filter_data_pipe(net, filtered_elements, metadata):
3216
+ node_name = "junction"
3217
+ component_list = []
3218
+ if "data" in metadata and "component_list" in metadata["data"]:
3219
+ component_list = json.loads(
3220
+ metadata["data"]["component_list"][11:],
3221
+ cls=io_pp.PPJSONDecoder,
3222
+ registry_class=FromSerializableRegistryPpipe,
3223
+ )
3224
+ branch_tables = []
3225
+ branch_node_cols = []
3226
+ node_elements = []
3227
+ for c in component_list:
3228
+ pps.add_new_component(net, c)
3229
+ filtered_elements.add(c.table_name())
3230
+ if issubclass(c, BranchComponent):
3231
+ branch_tables.append(c.table_name())
3232
+ branch_node_cols.append(c.from_to_node_cols())
3233
+ if issubclass(c, NodeElementComponent):
3234
+ node_elements.append(c.table_name())
3235
+ special_filters = dict()
3236
+ get_nodes_func = {br: get_nodes_from_element for br in branch_tables}
3237
+ return (
3238
+ node_name,
3239
+ branch_tables,
3240
+ branch_node_cols,
3241
+ special_filters,
3242
+ get_nodes_func,
3243
+ node_elements,
3244
+ )
3245
+
3246
+
3247
+
3199
3248
  if __name__ == "__main__":
3200
3249
  self = PandaHub()
3201
3250
  project_name = "test_project"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pandahub
3
- Version: 0.4.2
3
+ Version: 0.4.3
4
4
  Summary: Data hub for pandapower and pandapipes networks based on MongoDB
5
5
  Author-email: Jan Ulffers <jan.ulffers@iee.fraunhofer.de>, Leon Thurner <leon.thurner@retoflow.de>, Jannis Kupka <jannis.kupka@retoflow.de>, Mike Vogt <mike.vogt@iee.fraunhofer.de>, Joschka Thurner <joschka.thurner@retoflow.de>, Alexander Scheidler <alexander.scheidler@iee.fraunhofer.de>
6
6
  License: Copyright (c) 2022 by University of Kassel, Fraunhofer Institute for Energy Economics
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pandahub"
7
- version = "0.4.2" # File format version '__format_version__' is tracked in __init__.py
7
+ version = "0.4.3" # File format version '__format_version__' is tracked in __init__.py
8
8
  authors=[
9
9
  { name = "Jan Ulffers", email = "jan.ulffers@iee.fraunhofer.de" },
10
10
  { name = "Leon Thurner", email = "leon.thurner@retoflow.de" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes