epyt-flow 0.14.2__py3-none-any.whl → 0.15.0__py3-none-any.whl

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 (100) hide show
  1. epyt_flow/VERSION +1 -1
  2. epyt_flow/__init__.py +0 -37
  3. epyt_flow/data/benchmarks/battledim.py +2 -2
  4. epyt_flow/data/benchmarks/leakdb.py +12 -9
  5. epyt_flow/gym/scenario_control_env.py +32 -33
  6. epyt_flow/simulation/events/actuator_events.py +24 -18
  7. epyt_flow/simulation/events/leakages.py +59 -57
  8. epyt_flow/simulation/events/quality_events.py +21 -30
  9. epyt_flow/simulation/events/system_event.py +3 -3
  10. epyt_flow/simulation/scada/complex_control.py +14 -12
  11. epyt_flow/simulation/scada/custom_control.py +22 -21
  12. epyt_flow/simulation/scada/scada_data.py +107 -104
  13. epyt_flow/simulation/scada/simple_control.py +38 -31
  14. epyt_flow/simulation/scenario_simulator.py +368 -395
  15. epyt_flow/simulation/sensor_config.py +31 -32
  16. epyt_flow/topology.py +11 -10
  17. epyt_flow/uncertainty/model_uncertainty.py +146 -122
  18. {epyt_flow-0.14.2.dist-info → epyt_flow-0.15.0.dist-info}/METADATA +14 -19
  19. epyt_flow-0.15.0.dist-info/RECORD +65 -0
  20. epyt_flow/EPANET/EPANET/SRC_engines/AUTHORS +0 -28
  21. epyt_flow/EPANET/EPANET/SRC_engines/LICENSE +0 -21
  22. epyt_flow/EPANET/EPANET/SRC_engines/Readme_SRC_Engines.txt +0 -18
  23. epyt_flow/EPANET/EPANET/SRC_engines/enumstxt.h +0 -134
  24. epyt_flow/EPANET/EPANET/SRC_engines/epanet.c +0 -5578
  25. epyt_flow/EPANET/EPANET/SRC_engines/epanet2.c +0 -865
  26. epyt_flow/EPANET/EPANET/SRC_engines/epanet2.def +0 -131
  27. epyt_flow/EPANET/EPANET/SRC_engines/errors.dat +0 -73
  28. epyt_flow/EPANET/EPANET/SRC_engines/funcs.h +0 -193
  29. epyt_flow/EPANET/EPANET/SRC_engines/genmmd.c +0 -1000
  30. epyt_flow/EPANET/EPANET/SRC_engines/hash.c +0 -177
  31. epyt_flow/EPANET/EPANET/SRC_engines/hash.h +0 -28
  32. epyt_flow/EPANET/EPANET/SRC_engines/hydcoeffs.c +0 -1151
  33. epyt_flow/EPANET/EPANET/SRC_engines/hydraul.c +0 -1117
  34. epyt_flow/EPANET/EPANET/SRC_engines/hydsolver.c +0 -720
  35. epyt_flow/EPANET/EPANET/SRC_engines/hydstatus.c +0 -476
  36. epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2.h +0 -431
  37. epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2_2.h +0 -1786
  38. epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2_enums.h +0 -468
  39. epyt_flow/EPANET/EPANET/SRC_engines/inpfile.c +0 -810
  40. epyt_flow/EPANET/EPANET/SRC_engines/input1.c +0 -707
  41. epyt_flow/EPANET/EPANET/SRC_engines/input2.c +0 -864
  42. epyt_flow/EPANET/EPANET/SRC_engines/input3.c +0 -2170
  43. epyt_flow/EPANET/EPANET/SRC_engines/main.c +0 -93
  44. epyt_flow/EPANET/EPANET/SRC_engines/mempool.c +0 -142
  45. epyt_flow/EPANET/EPANET/SRC_engines/mempool.h +0 -24
  46. epyt_flow/EPANET/EPANET/SRC_engines/output.c +0 -852
  47. epyt_flow/EPANET/EPANET/SRC_engines/project.c +0 -1359
  48. epyt_flow/EPANET/EPANET/SRC_engines/quality.c +0 -685
  49. epyt_flow/EPANET/EPANET/SRC_engines/qualreact.c +0 -743
  50. epyt_flow/EPANET/EPANET/SRC_engines/qualroute.c +0 -694
  51. epyt_flow/EPANET/EPANET/SRC_engines/report.c +0 -1489
  52. epyt_flow/EPANET/EPANET/SRC_engines/rules.c +0 -1362
  53. epyt_flow/EPANET/EPANET/SRC_engines/smatrix.c +0 -871
  54. epyt_flow/EPANET/EPANET/SRC_engines/text.h +0 -497
  55. epyt_flow/EPANET/EPANET/SRC_engines/types.h +0 -874
  56. epyt_flow/EPANET/EPANET-MSX/MSX_Updates.txt +0 -53
  57. epyt_flow/EPANET/EPANET-MSX/Src/dispersion.h +0 -27
  58. epyt_flow/EPANET/EPANET-MSX/Src/hash.c +0 -107
  59. epyt_flow/EPANET/EPANET-MSX/Src/hash.h +0 -28
  60. epyt_flow/EPANET/EPANET-MSX/Src/include/epanetmsx.h +0 -102
  61. epyt_flow/EPANET/EPANET-MSX/Src/include/epanetmsx_export.h +0 -42
  62. epyt_flow/EPANET/EPANET-MSX/Src/mathexpr.c +0 -937
  63. epyt_flow/EPANET/EPANET-MSX/Src/mathexpr.h +0 -39
  64. epyt_flow/EPANET/EPANET-MSX/Src/mempool.c +0 -204
  65. epyt_flow/EPANET/EPANET-MSX/Src/mempool.h +0 -24
  66. epyt_flow/EPANET/EPANET-MSX/Src/msxchem.c +0 -1285
  67. epyt_flow/EPANET/EPANET-MSX/Src/msxcompiler.c +0 -368
  68. epyt_flow/EPANET/EPANET-MSX/Src/msxdict.h +0 -42
  69. epyt_flow/EPANET/EPANET-MSX/Src/msxdispersion.c +0 -586
  70. epyt_flow/EPANET/EPANET-MSX/Src/msxerr.c +0 -116
  71. epyt_flow/EPANET/EPANET-MSX/Src/msxfile.c +0 -260
  72. epyt_flow/EPANET/EPANET-MSX/Src/msxfuncs.c +0 -175
  73. epyt_flow/EPANET/EPANET-MSX/Src/msxfuncs.h +0 -35
  74. epyt_flow/EPANET/EPANET-MSX/Src/msxinp.c +0 -1504
  75. epyt_flow/EPANET/EPANET-MSX/Src/msxout.c +0 -401
  76. epyt_flow/EPANET/EPANET-MSX/Src/msxproj.c +0 -791
  77. epyt_flow/EPANET/EPANET-MSX/Src/msxqual.c +0 -2010
  78. epyt_flow/EPANET/EPANET-MSX/Src/msxrpt.c +0 -400
  79. epyt_flow/EPANET/EPANET-MSX/Src/msxtank.c +0 -422
  80. epyt_flow/EPANET/EPANET-MSX/Src/msxtoolkit.c +0 -1164
  81. epyt_flow/EPANET/EPANET-MSX/Src/msxtypes.h +0 -551
  82. epyt_flow/EPANET/EPANET-MSX/Src/msxutils.c +0 -524
  83. epyt_flow/EPANET/EPANET-MSX/Src/msxutils.h +0 -56
  84. epyt_flow/EPANET/EPANET-MSX/Src/newton.c +0 -158
  85. epyt_flow/EPANET/EPANET-MSX/Src/newton.h +0 -34
  86. epyt_flow/EPANET/EPANET-MSX/Src/rk5.c +0 -287
  87. epyt_flow/EPANET/EPANET-MSX/Src/rk5.h +0 -39
  88. epyt_flow/EPANET/EPANET-MSX/Src/ros2.c +0 -293
  89. epyt_flow/EPANET/EPANET-MSX/Src/ros2.h +0 -35
  90. epyt_flow/EPANET/EPANET-MSX/Src/smatrix.c +0 -816
  91. epyt_flow/EPANET/EPANET-MSX/Src/smatrix.h +0 -29
  92. epyt_flow/EPANET/EPANET-MSX/readme.txt +0 -14
  93. epyt_flow/EPANET/compile_linux.sh +0 -4
  94. epyt_flow/EPANET/compile_macos.sh +0 -4
  95. epyt_flow/simulation/backend/__init__.py +0 -1
  96. epyt_flow/simulation/backend/my_epyt.py +0 -1101
  97. epyt_flow-0.14.2.dist-info/RECORD +0 -142
  98. {epyt_flow-0.14.2.dist-info → epyt_flow-0.15.0.dist-info}/WHEEL +0 -0
  99. {epyt_flow-0.14.2.dist-info → epyt_flow-0.15.0.dist-info}/licenses/LICENSE +0 -0
  100. {epyt_flow-0.14.2.dist-info → epyt_flow-0.15.0.dist-info}/top_level.txt +0 -0
@@ -4,8 +4,7 @@ Module provides a class for implementing model uncertainty.
4
4
  from typing import Optional
5
5
  from copy import deepcopy
6
6
  import warnings
7
- import epyt
8
- from epyt.epanet import ToolkitConstants
7
+ from epanet_plus import EPyT, EpanetConstants
9
8
  import numpy as np
10
9
 
11
10
  from ..serialization import serializable, JsonSerializable, MODEL_UNCERTAINTY_ID
@@ -627,7 +626,7 @@ class ModelUncertainty(JsonSerializable):
627
626
  f"local_patterns: {self._local_patterns} " + \
628
627
  f"local_msx_patterns: {self._local_msx_patterns} + seed: {self.__seed}"
629
628
 
630
- def undo(self, epanet_api: epyt.epanet) -> None:
629
+ def undo(self, epanet_api: EPyT) -> None:
631
630
  """
632
631
  Undo all applied uncertainties -- i.e, resets the properties to their original value.
633
632
 
@@ -636,278 +635,303 @@ class ModelUncertainty(JsonSerializable):
636
635
 
637
636
  Parameters
638
637
  ----------
639
- epanet_api : `epyt.epanet <https://epanet-python-toolkit-epyt.readthedocs.io/en/stable/api.html#epyt.epanet.epanet>`_
638
+ epanet_api : `epanet_plus.EPyT <https://epanet-plus.readthedocs.io/en/stable/api.html#epanet_plus.epanet_toolkit.EPyT>`_
640
639
  Interface to EPANET and EPANET-MSX
641
640
  """
642
641
  if self.__cache_original is False:
643
642
  raise ValueError("Caching was disabled by the user")
644
643
 
645
644
  if self._cache_links_length is not None:
646
- epanet_api.setLinkLength(self._cache_links_length)
645
+ for link_idx, link_len in zip(epanet_api.get_all_links_idx(),
646
+ self._cache_links_length):
647
+ epanet_api.setlinkvalue(link_idx, EpanetConstants.EN_LENGTH, link_len)
647
648
 
648
649
  if self._cache_links_diameter is not None:
649
- epanet_api.setLinkDiameter(self._cache_links_diameter)
650
+ for link_idx, link_diam in zip(epanet_api.get_all_links_idx(),
651
+ self._cache_links_diameter):
652
+ epanet_api.setlinkvalue(link_idx, EpanetConstants.EN_DIAMETER, link_diam)
650
653
 
651
654
  if self._cache_links_roughness_coeff is not None:
652
- epanet_api.setLinkRoughnessCoeff(self._cache_links_roughness_coeff)
655
+ for link_idx, link_roughness in zip(epanet_api.get_all_links_idx(),
656
+ self._cache_links_roughness_coeff):
657
+ epanet_api.setlinkvalue(link_idx, EpanetConstants.EN_ROUGHNESS, link_roughness)
653
658
 
654
659
  if self._cache_nodes_base_demand is not None:
655
660
  for node_idx in self._cache_nodes_base_demand.keys():
656
661
  for demand_category, base_demand in self._cache_nodes_base_demand[node_idx].items():
657
- epanet_api.setNodeBaseDemands(node_idx, demand_category + 1, base_demand)
662
+ epanet_api.setbasedemand(node_idx, demand_category + 1, base_demand)
658
663
 
659
664
  if self._cache_nodes_demand_pattern is not None:
660
- for pattern_id, demand_pattern in self._cache_nodes_demand_pattern.items():
661
- for t, v in enumerate(demand_pattern):
662
- epanet_api.setPatternValue(pattern_id, t+1, v)
665
+ for pattern_idx, demand_pattern in self._cache_nodes_demand_pattern.items():
666
+ epanet_api.set_pattern(pattern_idx, demand_pattern.tolist())
663
667
 
664
668
  if self._cache_nodes_elevation is not None:
665
- epanet_api.setNodeElevations(self._cache_nodes_elevation)
669
+ for node_idx, node_elev in zip(epanet_api.get_all_nodes_idx(),
670
+ self._cache_nodes_elevation):
671
+ epanet_api.setnodevalue(node_idx, EpanetConstants.EN_ELEVATION, node_elev)
666
672
 
667
673
  if self._cache_patterns is not None:
668
674
  for pattern_idx, pattern in self._cache_patterns.items():
669
- epanet_api.setPattern(pattern_idx, pattern)
675
+ epanet_api.set_pattern(pattern_idx, pattern.tolist())
670
676
 
671
677
  if self._cache_msx_constants is not None:
672
- epanet_api.setMSXConstantsValue(self._cache_msx_constants)
678
+ for constant_idx, constant_value in enumerate(self._cache_msx_constants):
679
+ epanet_api.MSXsetconstant(constant_idx + 1, constant_value)
673
680
 
674
681
  if self._cache_msx_links_parameters is not None:
675
682
  for pipe_idx, parameters_pipes_val in self._cache_msx_links_parameters.items():
676
- epanet_api.setMSXParametersPipesValue(pipe_idx, parameters_pipes_val)
683
+ for param_idx, param_value in enumerate(parameters_pipes_val):
684
+ epanet_api.MSXsetparameter(EpanetConstants.MSX_LINK, pipe_idx,
685
+ param_idx + 1, param_value)
677
686
 
678
687
  if self._cache_msx_tanks_parameters is not None:
679
688
  for tank_idx, parameters_tanks_val in self._cache_msx_tanks_parameters.items():
680
- epanet_api.setMSXParametersTanksValue(tank_idx, parameters_tanks_val)
689
+ for param_idx, param_value in enumerate(parameters_tanks_val):
690
+ epanet_api.MSXsetparameter(EpanetConstants.MSX_NODE, tank_idx,
691
+ param_idx + 1, param_value)
681
692
 
682
693
  if self._cache_msx_patterns is not None:
683
694
  for pattern_idx, pattern in self._cache_msx_patterns:
684
- epanet_api.setMSXPattern(pattern_idx, pattern)
695
+ epanet_api.MSXsetpattern(pattern_idx, pattern.tolist(), len(pattern))
685
696
 
686
- def apply(self, epanet_api: epyt.epanet) -> None:
697
+ def apply(self, epanet_api: EPyT) -> None:
687
698
  """
688
699
  Applies the specified model uncertainties to the scenario.
689
700
 
690
701
  Parameters
691
702
  ----------
692
- epanet_api : `epyt.epanet <https://epanet-python-toolkit-epyt.readthedocs.io/en/stable/api.html#epyt.epanet.epanet>`_
703
+ epanet_api : `epanet_plus.EPyT <https://epanet-plus.readthedocs.io/en/stable/api.html#epanet_plus.epanet_toolkit.EPyT>`_
693
704
  Interface to EPANET and EPANET-MSX.
694
705
  """
695
706
  np_rand_gen = np.random.default_rng(seed=self.__seed)
696
707
 
708
+ all_links_idx = epanet_api.get_all_links_idx()
709
+ all_nodes_idx = epanet_api.get_all_nodes_idx()
710
+
697
711
  if self._global_pipe_length is not None:
698
712
  self._global_pipe_length.set_random_generator(np_rand_gen)
699
713
 
700
- link_length = epanet_api.getLinkLength()
714
+ link_length = np.array([epanet_api.getlinkvalue(link_idx, EpanetConstants.EN_LENGTH)
715
+ for link_idx in all_links_idx])
701
716
  self._cache_links_length = np.copy(link_length)
702
717
 
703
718
  link_length = self._global_pipe_length.apply_batch(link_length)
704
- epanet_api.setLinkLength(link_length)
719
+ for link_idx, link_value in zip(all_links_idx, link_length):
720
+ epanet_api.setlinkvalue(link_idx, EpanetConstants.EN_LENGTH, link_value)
705
721
 
706
722
  if self._local_pipe_length is not None:
707
723
  self._local_pipe_length.set_random_generator(np_rand_gen)
708
- self._cache_links_length = epanet_api.getLinkLength()
724
+ self._cache_links_length = np.array([epanet_api.getlinkvalue(link_idx, EpanetConstants.EN_LENGTH)
725
+ for link_idx in all_links_idx])
709
726
 
710
727
  for pipe_id, uncertainty in self._local_pipe_length.items():
711
- link_idx = epanet_api.getLinkIndex(pipe_id)
712
- link_length = epanet_api.getLinkLength(link_idx)
728
+ link_idx = epanet_api.get_link_idx(pipe_id)
729
+ link_length = epanet_api.getlinkvalue(link_idx, EpanetConstants.EN_LENGTH)
713
730
 
714
731
  link_length = uncertainty.apply(link_length)
715
- epanet_api.setLinkLength(link_idx, link_length)
732
+ epanet_api.setlinkvalue(link_idx, EpanetConstants.EN_LENGTH, link_length)
716
733
 
717
734
  if self._global_pipe_diameter is not None:
718
735
  self._global_pipe_diameter.set_random_generator(np_rand_gen)
719
736
 
720
- link_diameters = epanet_api.getLinkDiameter()
737
+ link_diameters = np.array([epanet_api.getlinkvalue(link_idx, EpanetConstants.EN_DIAMETER)
738
+ for link_idx in all_links_idx])
721
739
  self._cache_links_diameter = np.copy(link_diameters)
722
740
 
723
741
  link_diameters = self._global_pipe_diameter.apply_batch(link_diameters)
724
- epanet_api.setLinkDiameter(link_diameters)
742
+ for link_idx, link_value in zip(all_links_idx, link_diameters):
743
+ epanet_api.setlinkvalue(link_idx, EpanetConstants.EN_DIAMETER, link_value)
725
744
 
726
745
  if self._local_pipe_diameter is not None:
727
746
  self._local_pipe_diameter.set_random_generator(np_rand_gen)
728
- self._cache_links_diameter = epanet_api.getLinkDiameter()
747
+ self._cache_links_diameter = np.array([epanet_api.getlinkvalue(link_idx,
748
+ EpanetConstants.EN_DIAMETER)
749
+ for link_idx in all_links_idx])
729
750
 
730
751
  for pipe_id, uncertainty in self._local_pipe_diameter.items():
731
- link_idx = epanet_api.getLinkIndex(pipe_id)
732
- link_diameter = epanet_api.getLinkDiameter(link_idx)
752
+ link_idx = epanet_api.get_link_idx(pipe_id)
753
+ link_diameter = epanet_api.getlinkvalue(link_idx, EpanetConstants.EN_DIAMETER)
733
754
 
734
755
  link_diameter = uncertainty.apply(link_diameter)
735
- epanet_api.setLinkDiameter(link_idx, link_diameter)
756
+ epanet_api.setlinkvalue(link_idx, EpanetConstants.EN_DIAMETER, link_diameter)
736
757
 
737
758
  if self._global_pipe_roughness is not None:
738
759
  self._global_pipe_roughness.set_random_generator(np_rand_gen)
739
760
 
740
- coeffs = epanet_api.getLinkRoughnessCoeff()
761
+ coeffs = np.array([epanet_api.getlinkvalue(link_idx, EpanetConstants.EN_ROUGHNESS)
762
+ for link_idx in all_links_idx])
741
763
  self._cache_links_roughness_coeff = np.copy(coeffs)
742
764
 
743
765
  coeffs = self._global_pipe_roughness.apply_batch(coeffs)
744
- epanet_api.setLinkRoughnessCoeff(coeffs)
766
+ for link_idx, link_value in zip(all_links_idx, coeffs):
767
+ epanet_api.setlinkvalue(link_idx, EpanetConstants.EN_ROUGHNESS, link_value)
745
768
 
746
769
  if self._local_pipe_roughness is not None:
747
770
  self._local_pipe_roughness.set_random_generator(np_rand_gen)
748
- self._cache_links_roughness_coeff = epanet_api.getLinkRoughnessCoeff()
771
+ self._cache_links_roughness_coeff = \
772
+ np.array([epanet_api.getlinkvalue(link_idx, EpanetConstants.EN_ROUGHNESS)
773
+ for link_idx in all_links_idx])
749
774
 
750
775
  for pipe_id, uncertainty in self._local_pipe_roughness.items():
751
- link_idx = epanet_api.getLinkIndex(pipe_id)
752
- link_roughness_coeff = epanet_api.getLinkRoughnessCoeff(link_idx)
776
+ link_idx = epanet_api.get_link_idx(pipe_id)
777
+ link_roughness_coeff = epanet_api.getlinkvalue(link_idx,
778
+ EpanetConstants.EN_ROUGHNESS)
753
779
 
754
780
  link_roughness_coeff = uncertainty.apply(link_roughness_coeff)
755
- epanet_api.setLinkRoughnessCoeff(link_idx, link_roughness_coeff)
781
+ epanet_api.setlinkvalue(link_idx, EpanetConstants.EN_ROUGHNESS,
782
+ link_roughness_coeff)
756
783
 
757
784
  if self._global_base_demand is not None:
758
785
  self._global_base_demand.set_random_generator(np_rand_gen)
759
786
 
760
787
  self._cache_nodes_base_demand = {}
761
- all_nodes_idx = epanet_api.getNodeIndex()
762
788
  for node_idx in all_nodes_idx:
763
789
  self._cache_nodes_base_demand[node_idx] = {}
764
- n_demand_categories = epanet_api.getNodeDemandCategoriesNumber(node_idx)
765
- for demand_category in range(n_demand_categories):
766
- base_demand = epanet_api.getNodeBaseDemands(node_idx)[demand_category + 1]
767
- self._cache_nodes_base_demand[node_idx][demand_category] = base_demand
790
+ n_demand_categories = epanet_api.getnumdemands(node_idx)
791
+ for demand_idx in range(n_demand_categories):
792
+ base_demand = epanet_api.getbasedemand(node_idx, demand_idx + 1)
793
+ self._cache_nodes_base_demand[node_idx][demand_idx] = base_demand
768
794
 
769
795
  base_demand = self._global_base_demand.apply(base_demand)
770
- epanet_api.setNodeBaseDemands(node_idx, demand_category + 1, base_demand)
796
+ epanet_api.setbasedemand(node_idx, demand_idx + 1, base_demand)
771
797
 
772
798
  if self._local_base_demand is not None:
773
799
  self._local_base_demand.set_random_generator(np_rand_gen)
774
800
 
775
801
  self._cache_nodes_base_demand = {}
776
802
  for node_id, uncertainty in self._local_base_demand.items():
777
- node_idx = epanet_api.getNodeIndex(node_id)
803
+ node_idx = epanet_api.get_node_idx(node_id)
778
804
  self._cache_nodes_base_demand[node_idx] = {}
779
- n_demand_categories = epanet_api.getNodeDemandCategoriesNumber(node_idx)
780
- for demand_category in range(n_demand_categories):
781
- base_demand = epanet_api.getNodeBaseDemands(node_idx)[demand_category + 1]
782
- self._cache_nodes_base_demand[node_idx][demand_category] = base_demand
805
+ n_demand_categories = epanet_api.getnumdemands(node_idx)
806
+ for demand_idx in range(n_demand_categories):
807
+ base_demand = epanet_api.getbasedemand(node_idx, demand_idx + 1)
808
+ self._cache_nodes_base_demand[node_idx][demand_idx] = base_demand
783
809
 
784
810
  base_demand = uncertainty.apply(base_demand)
785
- epanet_api.setNodeBaseDemands(node_idx, demand_category + 1, base_demand)
811
+ epanet_api.setbasedemand(node_idx, demand_idx + 1, base_demand)
786
812
 
787
813
  if self._global_demand_pattern is not None:
788
814
  self._global_demand_pattern.set_random_generator(np_rand_gen)
789
815
 
790
816
  self._cache_nodes_demand_pattern = {}
791
- demand_patterns_idx = epanet_api.getNodeDemandPatternIndex()
792
- demand_patterns_id = np.unique([demand_patterns_idx[k]
793
- for k in demand_patterns_idx.keys()])
794
- for pattern_id in demand_patterns_id:
795
- if pattern_id == 0:
796
- continue
797
-
798
- pattern_length = epanet_api.getPatternLengths(pattern_id)
799
- demand_pattern = np.zeros(pattern_length)
800
-
801
- for t in range(pattern_length):
802
- v = epanet_api.getPatternValue(pattern_id, t+1)
803
- demand_pattern[t] = v
817
+ demand_patterns_idx = np.array([epanet_api.getdemandpattern(node_idx, demand_idx + 1)
818
+ for node_idx in epanet_api.get_all_nodes_idx()
819
+ for demand_idx in range(epanet_api.getnumdemands(node_idx))])
804
820
 
805
- v_ = self._global_demand_pattern.apply(v)
806
- epanet_api.setPatternValue(pattern_id, t+1, v_)
821
+ for pattern_idx in list(set(demand_patterns_idx)):
822
+ demand_pattern = np.array(epanet_api.get_pattern(pattern_idx))
823
+ self._cache_nodes_demand_pattern[pattern_idx] = np.copy(demand_pattern)
807
824
 
808
- self._cache_nodes_demand_pattern[pattern_id] = demand_pattern
825
+ demand_pattern = self._global_demand_pattern.apply_batch(demand_pattern)
826
+ epanet_api.set_pattern(pattern_idx, demand_pattern.tolist())
809
827
 
810
828
  if self._local_demand_pattern is not None:
811
829
  self._local_demand_pattern.set_random_generator(np_rand_gen)
812
830
 
813
831
  self._cache_nodes_demand_pattern = {}
814
- patterns_id = epanet_api.getPatternNameID()
815
- paterns_idx = epanet_api.getPatternIndex()
816
832
 
817
833
  for pattern_id, uncertainty in self._local_demand_pattern.items():
818
- pattern_idx = paterns_idx[patterns_id.index(pattern_id)]
819
- pattern_length, = epanet_api.getPatternLengths(pattern_id)
820
- demand_pattern = np.zeros(pattern_length)
821
-
822
- for t in range(pattern_length):
823
- v = epanet_api.getPatternValue(pattern_idx, t+1)
824
- demand_pattern[t] = v
825
-
826
- v_ = uncertainty.apply(v)
827
- epanet_api.setPatternValue(pattern_idx, t+1, v_)
834
+ pattern_idx = epanet_api.getpatternindex(pattern_id)
835
+ demand_pattern = np.array(epanet_api.get_pattern(pattern_idx))
836
+ self._cache_nodes_demand_pattern[pattern_id] = np.copy(demand_pattern)
828
837
 
829
- self._cache_nodes_demand_pattern[pattern_id] = demand_pattern
838
+ demand_pattern = uncertainty.apply_batch(demand_pattern)
839
+ epanet_api.set_pattern(pattern_idx, demand_pattern.tolist())
830
840
 
831
841
  if self._global_elevation is not None:
832
842
  self._global_elevation.set_random_generator(np_rand_gen)
833
843
 
834
- elevations = epanet_api.getNodeElevations()
844
+ elevations = np.array([epanet_api.get_node_elevation(node_idx)
845
+ for node_idx in epanet_api.get_all_nodes_idx()])
835
846
  self._cache_nodes_elevation = np.copy(elevations)
836
847
 
837
848
  elevations = self._global_elevation.apply_batch(elevations)
838
- epanet_api.setNodeElevations(elevations)
849
+ for node_idx, node_elev in enumerate(elevations):
850
+ epanet_api.setnodevalue(node_idx + 1, EpanetConstants.EN_ELEVATION, node_elev)
839
851
 
840
852
  if self._local_elevation is not None:
841
853
  self._local_elevation.set_random_generator(np_rand_gen)
842
- self._cache_nodes_elevation = epanet_api.getNodeElevations()
854
+ self._cache_nodes_elevation = np.array([epanet_api.get_node_elevation(node_idx)
855
+ for node_idx in epanet_api.get_all_nodes_idx()])
843
856
 
844
857
  for node_id, uncertainty in self._local_elevation.items():
845
- node_idx = epanet_api.getNodeIndex(node_id)
846
- elevation = epanet_api.getNodeElevations(node_idx)
858
+ node_idx = epanet_api.get_node_idx(node_id)
859
+ elevation = epanet_api.get_node_elevation(node_idx)
847
860
 
848
861
  elevation = uncertainty.apply(elevation)
849
- epanet_api.setNodeElevations(node_idx, elevation)
862
+ epanet_api.setnodevalue(node_idx, EpanetConstants.EN_ELEVATION, elevation)
850
863
 
851
864
  if self._local_patterns is not None:
852
865
  self._local_patterns.set_random_generator(np_rand_gen)
853
866
  self._cache_patterns = {}
854
867
 
855
868
  for pattern_id, uncertainty in self._local_patterns.items():
856
- pattern_idx = epanet_api.getPatternIndex(pattern_id)
857
- pattern_length = epanet_api.getPatternLengths(pattern_idx)
858
- pattern = np.array([epanet_api.getPatternValue(pattern_idx, t+1)
859
- for t in range(pattern_length)])
860
- self._cache_patterns[pattern_idx] = pattern
869
+ pattern_idx = epanet_api.getpatternindex(pattern_id)
870
+ pattern = np.array(epanet_api.get_pattern(pattern_idx))
871
+ self._cache_patterns[pattern_idx] = np.copy(pattern)
861
872
 
862
873
  pattern = uncertainty.apply_batch(pattern)
863
- epanet_api.setPattern(pattern_idx, pattern)
874
+ epanet_api.set_pattern(pattern_idx, pattern.tolist())
864
875
 
865
- if epanet_api.MSXFile is not None:
876
+ if epanet_api.msx_file is not None:
866
877
  if self._global_constants is not None:
867
878
  self._global_constants.set_random_generator(np_rand_gen)
868
879
 
869
- constants = np.array(epanet_api.getMSXConstantsValue())
880
+ constants = np.array([epanet_api.MSXgetconstant(const_idx + 1)
881
+ for const_idx in range(epanet_api.MSXgetcount(EpanetConstants.MSX_CONSTANT))])
870
882
  self._cache_msx_patterns = np.copy(constants)
871
883
 
872
884
  constants = self._global_constants.apply_batch(constants)
873
- epanet_api.setMSXConstantsValue(constants)
885
+ for const_idx, const_value in enumerate(constants):
886
+ epanet_api.MSXsetconstant(const_idx + 1, const_value)
874
887
 
875
888
  if self._local_constants:
876
889
  self._local_constants.set_random_generator(np_rand_gen)
877
890
 
878
- self._cache_msx_patterns = np.array(epanet_api.getMSXConstantsValue())
891
+ self._cache_msx_patterns = np.array([epanet_api.MSXgetconstant(const_idx + 1)
892
+ for const_idx in range(epanet_api.MSXgetcount(EpanetConstants.MSX_CONSTANT))])
879
893
 
880
894
  for constant_id, uncertainty in self._local_constants.items():
881
- idx = epanet_api.MSXgetindex(ToolkitConstants.MSX_CONSTANT, constant_id)
882
- constant = epanet_api.msx.MSXgetconstant(idx)
895
+ idx = epanet_api.MSXgetindex(EpanetConstants.MSX_CONSTANT, constant_id)
896
+ constant = epanet_api.MSXgetconstant(idx)
883
897
 
884
898
  constant = uncertainty.apply(constant)
885
- epanet_api.msx.MSXsetconstant(idx, constant)
899
+ epanet_api.MSXsetconstant(idx, constant)
886
900
 
887
901
  if self._global_parameters is not None:
888
902
  self._global_parameters.set_random_generator(np_rand_gen)
889
903
 
890
904
  self._cache_msx_links_parameters = {}
891
- parameters_pipes = epanet_api.getMSXParametersPipesValue()
892
- for i, pipe_idx in enumerate(epanet_api.getLinkPipeIndex()):
905
+ num_params = epanet_api.MSXgetcount(EpanetConstants.MSX_PARAMETER)
906
+ parameters_pipes = [np.array([epanet_api.MSXgetparameter(EpanetConstants.MSX_LINK,
907
+ pipe_idx,
908
+ param_idx + 1)
909
+ for param_idx in range(num_params)])
910
+ for pipe_idx in epanet_api.get_all_pipes_idx()]
911
+ for i, pipe_idx in enumerate(epanet_api.get_all_pipes_idx()):
893
912
  if len(parameters_pipes[i]) == 0:
894
913
  continue
895
914
 
896
- self._cache_msx_links_parameters[pipe_idx] = np.array(parameters_pipes[i])
897
- parameters_pipes_val = self._global_parameters.apply_batch(
898
- np.array(parameters_pipes[i]))
899
- epanet_api.setMSXParametersPipesValue(pipe_idx, parameters_pipes_val)
915
+ self._cache_msx_links_parameters[pipe_idx] = parameters_pipes[i]
916
+ parameters_pipes_val = self._global_parameters.apply_batch(parameters_pipes[i])
917
+ for param_idx, param_value in enumerate(parameters_pipes_val):
918
+ epanet_api.MSXsetparameter(EpanetConstants.MSX_LINK, pipe_idx,
919
+ param_idx + 1, param_value)
900
920
 
901
921
  self._cache_msx_tanks_parameters = {}
902
- parameters_tanks = epanet_api.getMSXParametersTanksValue()
903
- for i, tank_idx in enumerate(epanet_api.getNodeTankIndex()):
922
+ num_params = epanet_api.MSXgetcount(EpanetConstants.MSX_PARAMETER)
923
+ parameters_tanks = [np.array([epanet_api.MSXgetparameter(EpanetConstants.MSX_NODE,
924
+ tank_idx + 1, param_idx + 1)
925
+ for param_idx in range(num_params)])
926
+ for tank_idx in range(epanet_api.get_num_tanks())]
927
+ for i, tank_idx in enumerate(epanet_api.get_all_tanks_idx()):
904
928
  if parameters_tanks[i] is None or len(parameters_tanks[i]) == 0:
905
929
  continue
906
930
 
907
- self._cache_msx_tanks_parameters[tank_idx] = np.array(parameters_tanks[i])
908
- parameters_tanks_val = self._global_parameters.apply_batch(
909
- np.array(parameters_tanks[i]))
910
- epanet_api.setMSXParametersTanksValue(tank_idx, parameters_tanks_val)
931
+ self._cache_msx_tanks_parameters[tank_idx] = parameters_tanks[i]
932
+ parameters_tanks_val = self._global_parameters.apply_batch(parameters_tanks[i])
933
+ for idx, val in enumerate(parameters_tanks_val):
934
+ epanet_api.MSXsetparameter(EpanetConstants.MSX_NODE, tank_idx, idx + 1, val)
911
935
 
912
936
  if self._local_parameters is not None:
913
937
  self._local_parameters.set_random_generator(np_rand_gen)
@@ -915,36 +939,36 @@ class ModelUncertainty(JsonSerializable):
915
939
  self._cache_msx_tanks_parameters = {}
916
940
 
917
941
  for (param_id, item_type, item_id), uncertainty in self._local_parameters.items():
918
- idx, = epanet_api.getMSXParametersIndex([param_id])
942
+ idx, = epanet_api.MSXgetindex(EpanetConstants.MSX_PARAMETER, param_id)
919
943
 
920
- if item_type == ToolkitConstants.MSX_NODE:
921
- item_idx = epanet_api.getNodeIndex(item_id)
922
- elif item_type == ToolkitConstants.MSX_LINK:
923
- item_idx = epanet_api.getLinkIndex(item_id)
944
+ if item_type == EpanetConstants.MSX_NODE:
945
+ item_idx = epanet_api.get_node_idx(item_id)
946
+ elif item_type == EpanetConstants.MSX_LINK:
947
+ item_idx = epanet_api.get_link_idx(item_id)
924
948
  else:
925
949
  raise ValueError(f"Unknown item type '{item_type}' must be either " +
926
- "ToolkitConstants.MSX_NODE or ToolkitConstants.MSX_LINK")
950
+ "EpanetConstants.MSX_NODE or EpanetConstants.MSX_LINK")
927
951
 
928
- parameter = epanet_api.msx.MSXgetparameter(item_type, item_idx, idx)
929
- if item_type == ToolkitConstants.MSX_NODE:
952
+ parameter = epanet_api.MSXgetparameter(item_type, item_idx, idx)
953
+ if item_type == EpanetConstants.MSX_NODE:
930
954
  self._cache_msx_tanks_parameters[item_idx] = parameter
931
- elif item_type == ToolkitConstants.MSX_LINK:
955
+ elif item_type == EpanetConstants.MSX_LINK:
932
956
  self._cache_msx_links_parameters[item_idx] = parameter
933
957
 
934
958
  parameter = uncertainty.apply(parameter)
935
- epanet_api.msx.MSXsetparameter(item_type, item_idx, idx, parameter)
959
+ epanet_api.MSXsetparameter(item_type, item_idx, idx, parameter)
936
960
 
937
961
  if self._local_msx_patterns is not None:
938
962
  self._local_msx_patterns.set_random_generator(np_rand_gen)
939
963
  self._cache_msx_patterns = {}
940
964
 
941
965
  for pattern_id, uncertainty in self._local_msx_patterns.items():
942
- pattern_idx, = epanet_api.getMSXPatternsIndex([pattern_id])
943
- pattern = epanet_api.getMSXConstantsValue([pattern_idx])
966
+ pattern_idx = epanet_api.MSXgetindex(EpanetConstants.MSX_PATTERN, pattern_id)
967
+ pattern = np.array(epanet_api.get_msx_pattern(pattern_idx))
944
968
  self._cache_msx_patterns[pattern_idx] = np.copy(pattern)
945
969
 
946
970
  pattern = uncertainty.apply_batch(pattern)
947
- epanet_api.setMSXPattern(pattern_idx, pattern)
971
+ epanet_api.MSXsetpattern(pattern_idx, pattern.tolist(), len(pattern))
948
972
  else:
949
973
  if self._local_msx_patterns is not None or self._local_parameters is not None or \
950
974
  self._local_constants is not None or self._global_constants is not None or \
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: epyt-flow
3
- Version: 0.14.2
3
+ Version: 0.15.0
4
4
  Summary: EPyT-Flow -- EPANET Python Toolkit - Flow
5
5
  Author-email: André Artelt <aartelt@techfak.uni-bielefeld.de>, "Marios S. Kyriakou" <kiriakou.marios@ucy.ac.cy>, "Stelios G. Vrachimis" <vrachimis.stelios@ucy.ac.cy>
6
6
  License-Expression: MIT
@@ -17,10 +17,11 @@ Classifier: Programming Language :: Python :: 3.10
17
17
  Classifier: Programming Language :: Python :: 3.11
18
18
  Classifier: Programming Language :: Python :: 3.12
19
19
  Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
20
21
  Requires-Python: >=3.9
21
22
  Description-Content-Type: text/markdown
22
23
  License-File: LICENSE
23
- Requires-Dist: epyt>=1.2.2
24
+ Requires-Dist: epanet-plus>=0.1.2
24
25
  Requires-Dist: requests>=2.31.0
25
26
  Requires-Dist: scipy>=1.11.4
26
27
  Requires-Dist: u-msgpack-python>=2.8.0
@@ -49,11 +50,13 @@ Dynamic: license-file
49
50
 
50
51
  <img src="https://github.com/WaterFutures/EPyT-Flow/blob/main/docs/_static/net1_plot.png?raw=true" align="right" height="230px"/>
51
52
 
52
- EPyT-Flow is a Python package building on top of [EPyT](https://github.com/OpenWaterAnalytics/EPyT)
53
+ EPyT-Flow is a Python package building on top of [EPANET-PLUS](https://github.com/WaterFutures/EPANET-PLUS) --
54
+ an extension and interface of [EPANET](https://github.com/OpenWaterAnalytics/EPANET)
55
+ and [EPANET-MSX](https://github.com/OpenWaterAnalytics/epanet-msx) --
53
56
  for providing easy access to water distribution network simulations.
54
57
  It aims to provide a high-level interface for the easy generation of hydraulic and water quality scenario data.
55
- However, it also provides access to low-level functions by [EPANET](https://github.com/USEPA/EPANET2.2)
56
- and [EPANET-MSX](https://github.com/USEPA/EPANETMSX/).
58
+ However, it also provides access to all functions of EPANET
59
+ and EPANET-MSX.
57
60
 
58
61
  EPyT-Flow provides easy access to popular benchmark data sets for event detection and localization.
59
62
  Furthermore, it also provides an environment for developing and testing control algorithms.
@@ -77,21 +80,13 @@ Unique features of EPyT-Flow that make it superior to other (Python) toolboxes a
77
80
 
78
81
  ## Installation
79
82
 
80
- EPyT-Flow supports Python 3.9 - 3.13
83
+ EPyT-Flow supports Python 3.9 - 3.14
81
84
 
82
- Note that [EPANET and EPANET-MSX sources](epyt_flow/EPANET/) are compiled and overwrite the binaries
83
- shipped by EPyT **IF** EPyT-Flow is installed on a Unix system and the *gcc* compiler is available.
84
- By this, we not only aim to achieve a better performance of the simulations but also avoid any
85
- compatibility issues of pre-compiled binaries.
86
-
87
- #### Prerequisites for macOS users
88
- The "true" *gcc* compiler (version 15) is needed which is not the
89
- *clang* compiler that is shipped with Xcode and is linked to gcc!
90
-
91
- The correct version of the "true" *gcc* can be installed via [brew](https://brew.sh/):
92
- ```
93
- brew install gcc@15
94
- ```
85
+ Note that EPyT-Flow builds upon [EPANET-PLUS](https://github.com/WaterFutures/EPANET-PLUS) which
86
+ constitutes a C extension and Python package.
87
+ In the rare case that the pre-build package of EPANET-PLUS does not work on your system,
88
+ you have to build and install it manually -- please follow the instructions provided
89
+ [here](https://epanet-plus.readthedocs.io/en/stable/installation.html).
95
90
 
96
91
  ### PyPI
97
92
 
@@ -0,0 +1,65 @@
1
+ epyt_flow/VERSION,sha256=-EBaczDChwKNRww-41Bvh48a2F7XnB0a3BnfL_c5iRU,7
2
+ epyt_flow/__init__.py,sha256=mXQNlqjdqYKRiKCYnSCflFAJFEVlke7o-_ln6wZPAmY,154
3
+ epyt_flow/serialization.py,sha256=uGGN1iZ21ek1u6Xzs4z2xum5Qt8554Wem-wEMGEaa7I,14574
4
+ epyt_flow/topology.py,sha256=GKWugRj386E-uYMwLDPxZtg5KD27-nkQArSAZEYhde4,26571
5
+ epyt_flow/utils.py,sha256=dCEx7FwgTmU8T-ajI-abbrLzJu8llhgn0QDewfTuqHk,20074
6
+ epyt_flow/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ epyt_flow/data/networks.py,sha256=fZLv3yv_iDS23H-7KNMxNhCvfvrr9WdO7VNR5K3e94U,39842
8
+ epyt_flow/data/benchmarks/__init__.py,sha256=nJ6hqPaPNp8YMizniev3fwOWpzvvNUBMoRF16wACUkE,754
9
+ epyt_flow/data/benchmarks/batadal.py,sha256=E9kl0gI5HyL6LZ9ZoLZwdQBNHXKblWW1QV4E8ucr99s,11247
10
+ epyt_flow/data/benchmarks/batadal_data.py,sha256=oIzcysGivMPAgrfzrk5l8i-j6Ii96DPcFa6sL4TSaw8,880
11
+ epyt_flow/data/benchmarks/battledim.py,sha256=sVV8w4ESjybD__jrmKFhQxuBjtmLoBQmSmU2Wp-v76w,20790
12
+ epyt_flow/data/benchmarks/battledim_data.py,sha256=0vHm-2eAiLv6U-n5dqUUWS1o_szFRy9mVJ3eqDRp4PE,3373
13
+ epyt_flow/data/benchmarks/gecco_water_quality.py,sha256=xYN-xrcx409IhTJjvaMbZABORru3XQNnble76aAOKQ8,11414
14
+ epyt_flow/data/benchmarks/leakdb.py,sha256=1EtGshPwnAGJFRrd9B8RqRCnABsCtAoG2kvg1Q0xxic,26894
15
+ epyt_flow/data/benchmarks/leakdb_data.py,sha256=FNssgMkC1wqWVlaOrrihr4Od9trEZY7KeK5KuBeRMvM,507058
16
+ epyt_flow/data/benchmarks/water_usage.py,sha256=RiLGLof1HT0luwn7_dG11_nP5U5r9B3L8vDLuwsIKTM,4962
17
+ epyt_flow/gym/__init__.py,sha256=gDIP9VGjKraajsJo6MnPN-TaEUTLnnJNj2c_7jrb8Bg,36
18
+ epyt_flow/gym/scenario_control_env.py,sha256=LIU1NJ6lnrPeIA2daNJ-runiSLiyMreGLCObe1j3bk4,13909
19
+ epyt_flow/rest_api/__init__.py,sha256=4HilmXhdh6H56UHJBB2WUSULlEBUDnI1FPTP11ft3HE,126
20
+ epyt_flow/rest_api/base_handler.py,sha256=HDLXrMXqgWvxWAsB-3G4plyTyCv27_eBbq4eRl_FeBo,2609
21
+ epyt_flow/rest_api/res_manager.py,sha256=j6-3FUBZNLKM9bCsIDZzSytfDYJbDLRwjn1mIPstTqI,2342
22
+ epyt_flow/rest_api/server.py,sha256=cPQM17rdbXLFlPRePb0Y7OcCyfJUN9SX7cv0etHtfvo,8727
23
+ epyt_flow/rest_api/scada_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
+ epyt_flow/rest_api/scada_data/data_handlers.py,sha256=VGw3uakxhFgqLMYRC5OaAuCbp0SnGxdPXWruUVEBiJc,11895
25
+ epyt_flow/rest_api/scada_data/export_handlers.py,sha256=W-T2WgPuG8cNVzA8h3e0lwi-nSKFi11PPyuNQWTMwzg,4624
26
+ epyt_flow/rest_api/scada_data/handlers.py,sha256=jcGw91TjjhRQm_hJvjbWvSTBLpvMJDOA4bQw5iOpSUw,7673
27
+ epyt_flow/rest_api/scenario/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
+ epyt_flow/rest_api/scenario/control_handlers.py,sha256=ouxc54V_yJyoO2yPJEJqcPbZs7CXgM_CWKGj5RvkABQ,4585
29
+ epyt_flow/rest_api/scenario/event_handlers.py,sha256=wgKWFHJPwF4celetSb-_jTlrcicoxDbC7GpZ9uw-BJY,8969
30
+ epyt_flow/rest_api/scenario/handlers.py,sha256=v1V6gsBh2HLtPTnl9_53W13Awo5YjG681Urp24yXelY,14993
31
+ epyt_flow/rest_api/scenario/simulation_handlers.py,sha256=A59Iv-6k7SlGF_RDQgoFlvHWM1mScvfCobXBW4Rhh6E,6511
32
+ epyt_flow/rest_api/scenario/uncertainty_handlers.py,sha256=Pdo2YmiawOqKXWcLs2P-lv5qN-OKHS3sDgkAFQeRzK8,4568
33
+ epyt_flow/simulation/__init__.py,sha256=nihvZ8O2rJjYQkv7JhtVMqNacO5bA38VtS8Y_0BWrVQ,129
34
+ epyt_flow/simulation/parallel_simulation.py,sha256=ph4KXw9jCt-hiJFJbmC6fNvEsrbQoWV-tFKE5-qSfoQ,6523
35
+ epyt_flow/simulation/scenario_config.py,sha256=uHHwwzCRwooVdODxDNoCOUgfrlol1K-TS8P8_Ja9Coc,30435
36
+ epyt_flow/simulation/scenario_simulator.py,sha256=OIkEjPIFXg16kGXRngzMVJrSQpuyfrOcDvpkEYrhzII,165937
37
+ epyt_flow/simulation/sensor_config.py,sha256=5_KNgPMP-z176KeX2KBtTxrqhd8hzVYMH3AJxpBIXp4,94363
38
+ epyt_flow/simulation/events/__init__.py,sha256=gv8ZcvwjJN0Z5MwRXEOVFRNq4X5NPyyqXIQnhBxszQ0,215
39
+ epyt_flow/simulation/events/actuator_events.py,sha256=-WP8n8WOWJOJm2oz78HiwCZMQsyJ5dGS9ZvaeCnesi8,8405
40
+ epyt_flow/simulation/events/event.py,sha256=kARPV20XCAl6zxnJwI9U7ICtZUPACO_rgAmtHm1mGCs,2603
41
+ epyt_flow/simulation/events/leakages.py,sha256=tBgxKJGLbjEQ7TOSMjzVGF20-Z5qZAY104MP0AEZaWs,18297
42
+ epyt_flow/simulation/events/quality_events.py,sha256=LA9KUlO5hJ1OuneNMsZu4Wl26U6ZiGmz7oUpWXVyvI4,7854
43
+ epyt_flow/simulation/events/sensor_faults.py,sha256=RFR8LjePkDEkCgENHEgCGT7iKYYtr_qq87-IIwN6ezg,8423
44
+ epyt_flow/simulation/events/sensor_reading_attack.py,sha256=2E8q6yWnLxeLgYxW0MHw0GSjlUDjIIZ2GybVRLA7FJQ,7967
45
+ epyt_flow/simulation/events/sensor_reading_event.py,sha256=OWMRWPsvgMgaynMayJ-hQotP9zV5sDIYrOfY0fOCuvc,7586
46
+ epyt_flow/simulation/events/system_event.py,sha256=kyj6--D457vlbiVyg0M9yAXMs7GFHpcY8YZns3Aeo8c,2616
47
+ epyt_flow/simulation/scada/__init__.py,sha256=pfJhg-tM5DaiZTXs0_1qJsY2R6Py_LwSz6BUFJexfQM,150
48
+ epyt_flow/simulation/scada/complex_control.py,sha256=06c_cPUetOso2SNDWXS-uhfqYeWtb1Or0U5B4e3dZtA,22132
49
+ epyt_flow/simulation/scada/custom_control.py,sha256=HNO5WmRhN9BtMEzC82DKreAym1SC6xdLhNQ-cSOfU2c,4758
50
+ epyt_flow/simulation/scada/scada_data.py,sha256=ufaxv_1bFg2WCYQ8IQt1duQ7_fuGINiIL53HYzVa9hM,203288
51
+ epyt_flow/simulation/scada/scada_data_export.py,sha256=WNAFn_WNfzYAEFbl2Al-cOIx-A0ozY4AI60-i_qEHdc,11643
52
+ epyt_flow/simulation/scada/simple_control.py,sha256=BO9u7gUYdNlGqkWdY_DIiGUWpfQZrL2blx0W805GvIo,12600
53
+ epyt_flow/uncertainty/__init__.py,sha256=ZRjuJL9rDpWVSdPwObPxFpEmMTcgAl3VmPOsS6cIyGg,89
54
+ epyt_flow/uncertainty/model_uncertainty.py,sha256=cqK9XGWcVL6uA-xG_r6rbyJgFkKdtrHhS8YyRicQrG8,50858
55
+ epyt_flow/uncertainty/sensor_noise.py,sha256=-AnBfuW1VAx7Ya-q_gJ9bAr7Kx6pzP_y0PvNeuRjXIg,6477
56
+ epyt_flow/uncertainty/uncertainties.py,sha256=QBRbI3zIzkeFScyYD5Dy0TBxuL9jPV4SnVU8QwOrJq8,20495
57
+ epyt_flow/uncertainty/utils.py,sha256=K-ZhyO6Bg7UmNPgpfND0JLa_wRwyrtUUgGTWyWwy-fo,8029
58
+ epyt_flow/visualization/__init__.py,sha256=uQ7lO6AsgLc88X48Te3QhBQY-iDKGvdPtxKCl4b-Mfw,70
59
+ epyt_flow/visualization/scenario_visualizer.py,sha256=vkP0J_OfjvePUz_HehXJkH4CGKR3chAHe_UTx4hQ6XI,57860
60
+ epyt_flow/visualization/visualization_utils.py,sha256=-_Hs3FKQz--iVJ10ZeEv1Co9OSbayZmHjxyhKsnzalE,27629
61
+ epyt_flow-0.15.0.dist-info/licenses/LICENSE,sha256=YRJC2kcAhMlpEeHwUF0lzE-GRXLFyAjXNErI8L5UwYk,1071
62
+ epyt_flow-0.15.0.dist-info/METADATA,sha256=aRbELLILtji0kntYVXehD_dYmGGxGkkdKb4v16RJtww,9615
63
+ epyt_flow-0.15.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
64
+ epyt_flow-0.15.0.dist-info/top_level.txt,sha256=Wh_kd7TRL8ownCw3Y3dxx-9C0iTSk6wNauv_NX9JcrY,10
65
+ epyt_flow-0.15.0.dist-info/RECORD,,