epyt-flow 0.13.0__py3-none-any.whl → 0.14.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.
- epyt_flow/EPANET/compile_macos.sh +2 -2
- epyt_flow/VERSION +1 -1
- epyt_flow/__init__.py +1 -1
- epyt_flow/simulation/backend/my_epyt.py +58 -13
- epyt_flow/simulation/scada/scada_data.py +9 -13
- epyt_flow/simulation/scenario_simulator.py +99 -22
- epyt_flow/uncertainty/uncertainties.py +2 -2
- {epyt_flow-0.13.0.dist-info → epyt_flow-0.14.0.dist-info}/METADATA +3 -3
- {epyt_flow-0.13.0.dist-info → epyt_flow-0.14.0.dist-info}/RECORD +12 -12
- {epyt_flow-0.13.0.dist-info → epyt_flow-0.14.0.dist-info}/WHEEL +1 -1
- {epyt_flow-0.13.0.dist-info → epyt_flow-0.14.0.dist-info}/licenses/LICENSE +0 -0
- {epyt_flow-0.13.0.dist-info → epyt_flow-0.14.0.dist-info}/top_level.txt +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
mkdir -p "../customlibs/"
|
|
3
|
-
gcc-
|
|
4
|
-
gcc-
|
|
3
|
+
gcc-15 -w -O3 -march=native -dynamiclib -fPIC -install_name libepanet2_2.dylib -o "../customlibs/libepanet2_2.dylib" EPANET/SRC_engines/*.c -IEPANET/SRC_engines/include -lc -lm -pthread
|
|
4
|
+
gcc-15 -w -O3 -march=native -dynamiclib -fPIC -install_name libepanetmsx2_2_0.dylib -o "../customlibs/libepanetmsx2_2_0.dylib" -fopenmp -Depanetmsx_EXPORTS -IEPANET-MSX/Src/include -IEPANET/SRC_engines/include EPANET-MSX/Src/*.c -L'../customlibs' -lepanet2_2 -lm -lgomp -lpthread
|
epyt_flow/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.14.0
|
epyt_flow/__init__.py
CHANGED
|
@@ -39,4 +39,4 @@ def compile_libraries_unix(lib_epanet_name: str, compile_script_name: str,
|
|
|
39
39
|
if sys.platform.startswith("linux"):
|
|
40
40
|
compile_libraries_unix("libepanet2_2.so", "compile_linux.sh")
|
|
41
41
|
elif sys.platform.startswith("darwin"):
|
|
42
|
-
compile_libraries_unix("libepanet2_2.dylib", "compile_macos.sh", gcc_name="gcc-
|
|
42
|
+
compile_libraries_unix("libepanet2_2.dylib", "compile_macos.sh", gcc_name="gcc-15")
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
This module contains a wrapper for EPyT that allows a better error/warning handling.
|
|
3
3
|
"""
|
|
4
|
+
import warnings
|
|
4
5
|
from ctypes import byref, create_string_buffer
|
|
5
6
|
from epyt import epanet
|
|
6
7
|
from epyt.epanet import epanetapi, epanetmsxapi
|
|
@@ -30,6 +31,10 @@ class EPyT(epanet):
|
|
|
30
31
|
self.LibEPANETpath = self.api.LibEPANETpath
|
|
31
32
|
self.LibEPANET = self.api.LibEPANET
|
|
32
33
|
|
|
34
|
+
def _logFunctionError(self, function_name):
|
|
35
|
+
# Do not print warnings.
|
|
36
|
+
pass
|
|
37
|
+
|
|
33
38
|
def loadMSXFile(self, msxname, customMSXlib=None, ignore_properties=False):
|
|
34
39
|
super().loadMSXFile(msxname, customMSXlib, ignore_properties)
|
|
35
40
|
|
|
@@ -40,17 +45,25 @@ class EPyT(epanet):
|
|
|
40
45
|
msxrealfile=self.MSXFile)
|
|
41
46
|
return self.msx
|
|
42
47
|
|
|
43
|
-
def set_error_handling(self, raise_exception_on_error: bool
|
|
48
|
+
def set_error_handling(self, raise_exception_on_error: bool, warn_on_error: bool,
|
|
49
|
+
ignore_error_codes: list[int]) -> None:
|
|
44
50
|
"""
|
|
45
51
|
Specifies the behavior in the case of an error/warning --
|
|
46
|
-
i.e. should an exception be raised or not?
|
|
52
|
+
i.e. should an exception or warning be raised or not?
|
|
47
53
|
|
|
48
54
|
Parameters
|
|
49
55
|
----------
|
|
50
56
|
raise_exception_on_error : `bool`
|
|
51
57
|
True if an exception should be raise, False otherwise.
|
|
58
|
+
warn_on_error : `bool`
|
|
59
|
+
True if a warning should be generated, False otherwise.
|
|
60
|
+
ignore_error_codes : `list[int]`
|
|
61
|
+
List of error codes that should be ignored -- i.e., no exception or
|
|
62
|
+
warning will be generated.
|
|
52
63
|
"""
|
|
53
|
-
self.api.set_error_handling(raise_exception_on_error)
|
|
64
|
+
self.api.set_error_handling(raise_exception_on_error, warn_on_error, ignore_error_codes)
|
|
65
|
+
if self.msx is not None:
|
|
66
|
+
self.msx.set_error_handling(raise_exception_on_error, warn_on_error, ignore_error_codes)
|
|
54
67
|
|
|
55
68
|
def was_last_func_successful(self) -> bool:
|
|
56
69
|
"""
|
|
@@ -96,24 +109,39 @@ class MyEpanetMsxAPI(epanetmsxapi):
|
|
|
96
109
|
Wrapper for the `epyt.epanet.epanetmsxapi <https://epanet-python-toolkit-epyt.readthedocs.io/en/latest/api.html#epyt.epanet.epanetmsxapi>`_
|
|
97
110
|
class adding error/warning storage functionalities.
|
|
98
111
|
"""
|
|
99
|
-
def __init__(self, raise_on_error: bool = True,
|
|
112
|
+
def __init__(self, raise_on_error: bool = True, warn_on_error: bool = False,
|
|
113
|
+
ignore_error_codes: list[int] = [], **kwds):
|
|
100
114
|
self.__raise_on_error = raise_on_error
|
|
115
|
+
self.__warn_on_error = warn_on_error
|
|
116
|
+
self.__ignore_error_codes = ignore_error_codes
|
|
101
117
|
self.__last_error_code = None
|
|
102
118
|
self.__last_error_desc = None
|
|
103
119
|
|
|
104
120
|
super().__init__(**kwds)
|
|
105
121
|
|
|
106
|
-
def
|
|
122
|
+
def _logFunctionError(self, function_name):
|
|
123
|
+
# Do not print warnings.
|
|
124
|
+
pass
|
|
125
|
+
|
|
126
|
+
def set_error_handling(self, raise_on_error: bool, warn_on_error: bool,
|
|
127
|
+
ignore_error_codes: list[int] = []) -> None:
|
|
107
128
|
"""
|
|
108
129
|
Specifies the behavior in the case of an error/warning --
|
|
109
|
-
i.e. should an exception be raised or not?
|
|
130
|
+
i.e. should an exception or warning be raised or not?
|
|
110
131
|
|
|
111
132
|
Parameters
|
|
112
133
|
----------
|
|
113
134
|
raise_exception_on_error : `bool`
|
|
114
135
|
True if an exception should be raise, False otherwise.
|
|
136
|
+
warn_on_error : `bool`
|
|
137
|
+
True if a warning should be generated, False otherwise.
|
|
138
|
+
ignore_error_codes : `list[int]`
|
|
139
|
+
List of error codes that should be ignored -- i.e., no exception or
|
|
140
|
+
warning will be generated.
|
|
115
141
|
"""
|
|
116
142
|
self.__raise_on_error = raise_on_error
|
|
143
|
+
self.__warn_on_error = warn_on_error
|
|
144
|
+
self.__ignore_error_codes = ignore_error_codes
|
|
117
145
|
|
|
118
146
|
def get_last_error_desc(self) -> str:
|
|
119
147
|
"""
|
|
@@ -161,8 +189,11 @@ class MyEpanetMsxAPI(epanetmsxapi):
|
|
|
161
189
|
self.__last_error_code = err_code
|
|
162
190
|
self.__last_error_desc = error_desc.value.decode()
|
|
163
191
|
|
|
164
|
-
if self.
|
|
165
|
-
|
|
192
|
+
if self.__last_error_code not in self.__ignore_error_codes:
|
|
193
|
+
if self.__warn_on_error:
|
|
194
|
+
warnings.warn(self.__last_error_desc, RuntimeWarning)
|
|
195
|
+
if self.__raise_on_error:
|
|
196
|
+
raise RuntimeError(self.__last_error_desc)
|
|
166
197
|
|
|
167
198
|
def MSXopen(self, msxfile, msxrealfile):
|
|
168
199
|
self._reset_error()
|
|
@@ -286,24 +317,35 @@ class MyEpanetAPI(epanetapi):
|
|
|
286
317
|
Wrapper for the `epyt.epanet.epanetapi <https://epanet-python-toolkit-epyt.readthedocs.io/en/latest/api.html#epyt.epanet.epanetapi>`_
|
|
287
318
|
class adding error/warning storage functionalities.
|
|
288
319
|
"""
|
|
289
|
-
def __init__(self, raise_on_error: bool = True,
|
|
320
|
+
def __init__(self, raise_on_error: bool = True, warn_on_error: bool = False,
|
|
321
|
+
ignore_error_codes: list[int] = [], **kwds):
|
|
290
322
|
self.__raise_on_error = raise_on_error
|
|
323
|
+
self.__warn_on_error = warn_on_error
|
|
324
|
+
self.__ignore_error_codes = ignore_error_codes
|
|
291
325
|
self.__last_error_code = None
|
|
292
326
|
self.__last_error_desc = None
|
|
293
327
|
|
|
294
328
|
super().__init__(**kwds)
|
|
295
329
|
|
|
296
|
-
def set_error_handling(self, raise_on_error: bool
|
|
330
|
+
def set_error_handling(self, raise_on_error: bool, warn_on_error: bool,
|
|
331
|
+
ignore_error_codes: list[int] = []) -> None:
|
|
297
332
|
"""
|
|
298
333
|
Specifies the behavior in the case of an error/warning --
|
|
299
|
-
i.e. should an exception be raised or not?
|
|
334
|
+
i.e. should an exception or warning be raised or not?
|
|
300
335
|
|
|
301
336
|
Parameters
|
|
302
337
|
----------
|
|
303
338
|
raise_exception_on_error : `bool`
|
|
304
339
|
True if an exception should be raise, False otherwise.
|
|
340
|
+
warn_on_error : `bool`
|
|
341
|
+
True if a warning should be generated, False otherwise.
|
|
342
|
+
ignore_error_codes : `list[int]`
|
|
343
|
+
List of error codes that should be ignored -- i.e., no exception or
|
|
344
|
+
warning will be generated.
|
|
305
345
|
"""
|
|
306
346
|
self.__raise_on_error = raise_on_error
|
|
347
|
+
self.__warn_on_error = warn_on_error
|
|
348
|
+
self.__ignore_error_codes = ignore_error_codes
|
|
307
349
|
|
|
308
350
|
def get_last_error_desc(self) -> str:
|
|
309
351
|
"""
|
|
@@ -353,8 +395,11 @@ class MyEpanetAPI(epanetapi):
|
|
|
353
395
|
self.__last_error_code = self.errcode
|
|
354
396
|
self.__last_error_desc = error_desc.value.decode()
|
|
355
397
|
|
|
356
|
-
if self.
|
|
357
|
-
|
|
398
|
+
if self.__last_error_code not in self.__ignore_error_codes:
|
|
399
|
+
if self.__warn_on_error:
|
|
400
|
+
warnings.warn(self.__last_error_desc, RuntimeWarning)
|
|
401
|
+
if self.__raise_on_error:
|
|
402
|
+
raise RuntimeError(self.__last_error_desc)
|
|
358
403
|
|
|
359
404
|
def ENepanet(self, inpfile="", rptfile="", binfile=""):
|
|
360
405
|
self._reset_error()
|
|
@@ -167,9 +167,7 @@ class ScadaData(Serializable):
|
|
|
167
167
|
raise TypeError("'sensor_readings_time' must be an instance of 'numpy.ndarray' " +
|
|
168
168
|
f"but not of '{type(sensor_readings_time)}'")
|
|
169
169
|
if warnings_code is None:
|
|
170
|
-
|
|
171
|
-
" -- support of such old files will be removed in the next release!",
|
|
172
|
-
DeprecationWarning)
|
|
170
|
+
warnings_code = [0] * len(sensor_readings_time)
|
|
173
171
|
else:
|
|
174
172
|
if not isinstance(warnings_code, np.ndarray):
|
|
175
173
|
raise TypeError("'warnings_code' must be an instance of 'numpy.ndarray' " +
|
|
@@ -376,6 +374,8 @@ class ScadaData(Serializable):
|
|
|
376
374
|
self.__sensor_readings = None
|
|
377
375
|
self.__frozen_sensor_config = frozen_sensor_config
|
|
378
376
|
self.__sensor_readings_time = sensor_readings_time
|
|
377
|
+
self.__sensor_readings_time_to_idx = {time: idx for idx, time in
|
|
378
|
+
enumerate(self.__sensor_readings_time)}
|
|
379
379
|
|
|
380
380
|
if self.__frozen_sensor_config is False:
|
|
381
381
|
self.__pressure_data_raw = pressure_data_raw
|
|
@@ -1748,8 +1748,8 @@ class ScadaData(Serializable):
|
|
|
1748
1748
|
else:
|
|
1749
1749
|
end_time = self.__sensor_readings_time[-1]
|
|
1750
1750
|
|
|
1751
|
-
start_idx = self.
|
|
1752
|
-
end_idx = self.
|
|
1751
|
+
start_idx = self.__sensor_readings_time_to_idx[start_time]
|
|
1752
|
+
end_idx = self.__sensor_readings_time_to_idx[end_time] + 1
|
|
1753
1753
|
|
|
1754
1754
|
pressure_data_raw = None
|
|
1755
1755
|
if self.__pressure_data_raw is not None:
|
|
@@ -2375,11 +2375,10 @@ class ScadaData(Serializable):
|
|
|
2375
2375
|
mask = np.zeros(len(self.__sensor_config.nodes))
|
|
2376
2376
|
node_features = np.array([[default_missing_value] * len(self.__sensor_config.nodes)
|
|
2377
2377
|
for _ in range(len(self.__sensor_readings_time))])
|
|
2378
|
-
nodes_id = self.__network_topo.get_all_nodes()
|
|
2379
2378
|
|
|
2380
2379
|
pressure_readings = self.get_data_pressures()
|
|
2381
2380
|
for pressures_idx, node_id in enumerate(self.__sensor_config.pressure_sensors):
|
|
2382
|
-
idx =
|
|
2381
|
+
idx = self.__sensor_config.map_node_id_to_idx(node_id)
|
|
2383
2382
|
node_features[:, idx] = pressure_readings[:, pressures_idx]
|
|
2384
2383
|
mask[idx] = 1
|
|
2385
2384
|
|
|
@@ -2617,11 +2616,10 @@ class ScadaData(Serializable):
|
|
|
2617
2616
|
mask = np.zeros(len(self.__sensor_config.nodes))
|
|
2618
2617
|
node_features = np.array([[default_missing_value] * len(self.__sensor_config.nodes)
|
|
2619
2618
|
for _ in range(len(self.__sensor_readings_time))])
|
|
2620
|
-
nodes_id = self.__network_topo.get_all_nodes()
|
|
2621
2619
|
|
|
2622
2620
|
demand_readings = self.get_data_demands()
|
|
2623
2621
|
for demands_idx, node_id in enumerate(self.__sensor_config.demand_sensors):
|
|
2624
|
-
idx =
|
|
2622
|
+
idx = self.__sensor_config.map_node_id_to_idx(node_id)
|
|
2625
2623
|
node_features[:, idx] = demand_readings[:, demands_idx]
|
|
2626
2624
|
mask[idx] = 1
|
|
2627
2625
|
|
|
@@ -2737,11 +2735,10 @@ class ScadaData(Serializable):
|
|
|
2737
2735
|
mask = np.zeros(len(self.__sensor_config.nodes))
|
|
2738
2736
|
node_features = np.array([[default_missing_value] * len(self.__sensor_config.nodes)
|
|
2739
2737
|
for _ in range(len(self.__sensor_readings_time))])
|
|
2740
|
-
nodes_id = self.__network_topo.get_all_nodes()
|
|
2741
2738
|
|
|
2742
2739
|
node_quality_readings = self.get_data_nodes_quality()
|
|
2743
2740
|
for quality_idx, node_id in enumerate(self.__sensor_config.quality_node_sensors):
|
|
2744
|
-
idx =
|
|
2741
|
+
idx = self.__sensor_config.map_node_id_to_idx(node_id)
|
|
2745
2742
|
node_features[:, idx] = node_quality_readings[:, quality_idx]
|
|
2746
2743
|
mask[idx] = 1
|
|
2747
2744
|
|
|
@@ -3752,7 +3749,6 @@ class ScadaData(Serializable):
|
|
|
3752
3749
|
masks = []
|
|
3753
3750
|
results = []
|
|
3754
3751
|
|
|
3755
|
-
all_nodes_id = self.__network_topo.get_all_nodes()
|
|
3756
3752
|
bulk_species_sensor_locations = self.__sensor_config.bulk_species_node_sensors
|
|
3757
3753
|
|
|
3758
3754
|
for species_id, nodes_id in bulk_species_sensor_locations.items():
|
|
@@ -3762,7 +3758,7 @@ class ScadaData(Serializable):
|
|
|
3762
3758
|
|
|
3763
3759
|
sensor_readings = self.get_data_bulk_species_node_concentration({species_id: nodes_id})
|
|
3764
3760
|
for sensor_readings_idx, node_id in enumerate(nodes_id):
|
|
3765
|
-
idx =
|
|
3761
|
+
idx = self.__sensor_config.map_node_id_to_idx(node_id)
|
|
3766
3762
|
node_features[:, idx] = sensor_readings[:, sensor_readings_idx]
|
|
3767
3763
|
mask[idx] = 1
|
|
3768
3764
|
|
|
@@ -59,6 +59,20 @@ class ScenarioSimulator():
|
|
|
59
59
|
If True, EPyT is verbose and might print messages from time to time.
|
|
60
60
|
|
|
61
61
|
The default is False.
|
|
62
|
+
raise_exception_on_error : `bool`, optional
|
|
63
|
+
If True, an exception is raised whenever an error occurs in EPANET or EPANET-MSX.
|
|
64
|
+
|
|
65
|
+
The default is False.
|
|
66
|
+
warn_on_error : `bool`, optional
|
|
67
|
+
If True, a warning is generated whenever an error occurs in EPANET or EPANET-MSX.
|
|
68
|
+
|
|
69
|
+
The default is True.
|
|
70
|
+
ignore_error_codes : `list[int]`, optional
|
|
71
|
+
List of error codes that should be ignored -- i.e., no exception or
|
|
72
|
+
warning will be generated.
|
|
73
|
+
However, error codes will still be included in the SCADA data.
|
|
74
|
+
|
|
75
|
+
The default is [].
|
|
62
76
|
|
|
63
77
|
Attributes
|
|
64
78
|
----------
|
|
@@ -83,7 +97,9 @@ class ScenarioSimulator():
|
|
|
83
97
|
"""
|
|
84
98
|
|
|
85
99
|
def __init__(self, f_inp_in: str = None, f_msx_in: str = None,
|
|
86
|
-
scenario_config: ScenarioConfig = None, epanet_verbose: bool = False
|
|
100
|
+
scenario_config: ScenarioConfig = None, epanet_verbose: bool = False,
|
|
101
|
+
raise_exception_on_error: bool = False, warn_on_error: bool = True,
|
|
102
|
+
ignore_error_codes: list[int] = []):
|
|
87
103
|
if f_msx_in is not None and f_inp_in is None:
|
|
88
104
|
raise ValueError("'f_inp_in' must be set if 'f_msx_in' is set.")
|
|
89
105
|
if f_inp_in is None and scenario_config is None:
|
|
@@ -118,6 +134,7 @@ class ScenarioSimulator():
|
|
|
118
134
|
self._system_events = []
|
|
119
135
|
self._sensor_reading_events = []
|
|
120
136
|
self.__running_simulation = False
|
|
137
|
+
self.__uncertainties_applied = False
|
|
121
138
|
|
|
122
139
|
# Check availability of custom EPANET libraries
|
|
123
140
|
custom_epanet_lib = None
|
|
@@ -176,7 +193,9 @@ class ScenarioSimulator():
|
|
|
176
193
|
self.epanet_api.loadMSXFile(my_f_msx_in, customMSXlib=custom_epanetmsx_lib)
|
|
177
194
|
|
|
178
195
|
# Do not raise exceptions in the case of EPANET warnings and errors
|
|
179
|
-
self.epanet_api.set_error_handling(
|
|
196
|
+
self.epanet_api.set_error_handling(raise_exception_on_error=raise_exception_on_error,
|
|
197
|
+
warn_on_error=warn_on_error,
|
|
198
|
+
ignore_error_codes=ignore_error_codes)
|
|
180
199
|
|
|
181
200
|
# Parse and initialize scenario
|
|
182
201
|
self._simple_controls = self._parse_simple_control_rules()
|
|
@@ -1943,11 +1962,13 @@ class ScenarioSimulator():
|
|
|
1943
1962
|
"""
|
|
1944
1963
|
self._sensor_config.place_sensors_everywhere()
|
|
1945
1964
|
|
|
1946
|
-
def _prepare_simulation(self) -> None:
|
|
1965
|
+
def _prepare_simulation(self, reapply_uncertainties: bool = False) -> None:
|
|
1947
1966
|
self._adapt_to_network_changes()
|
|
1948
1967
|
|
|
1949
1968
|
if self._model_uncertainty is not None:
|
|
1950
|
-
self.
|
|
1969
|
+
if self.__uncertainties_applied is True and reapply_uncertainties is True:
|
|
1970
|
+
self._model_uncertainty.apply(self.epanet_api)
|
|
1971
|
+
self.__uncertainties_applied = True
|
|
1951
1972
|
|
|
1952
1973
|
for event in self._system_events:
|
|
1953
1974
|
event.reset()
|
|
@@ -1958,7 +1979,8 @@ class ScenarioSimulator():
|
|
|
1958
1979
|
|
|
1959
1980
|
def run_advanced_quality_simulation(self, hyd_file_in: str, verbose: bool = False,
|
|
1960
1981
|
frozen_sensor_config: bool = False,
|
|
1961
|
-
use_quality_time_step_as_reporting_time_step: bool = False
|
|
1982
|
+
use_quality_time_step_as_reporting_time_step: bool = False,
|
|
1983
|
+
reapply_uncertainties: bool = False
|
|
1962
1984
|
) -> ScadaData:
|
|
1963
1985
|
"""
|
|
1964
1986
|
Runs an advanced quality analysis using EPANET-MSX.
|
|
@@ -1983,6 +2005,10 @@ class ScenarioSimulator():
|
|
|
1983
2005
|
As a consequence, the simualtion results can not be merged
|
|
1984
2006
|
with the hydraulic simulation.
|
|
1985
2007
|
|
|
2008
|
+
The default is False.
|
|
2009
|
+
reapply_uncertainties: bool = False : `bool`, optional
|
|
2010
|
+
If True, the uncertainties are re-applied.
|
|
2011
|
+
|
|
1986
2012
|
The default is False.
|
|
1987
2013
|
|
|
1988
2014
|
Returns
|
|
@@ -2004,7 +2030,8 @@ class ScenarioSimulator():
|
|
|
2004
2030
|
return_as_dict=True,
|
|
2005
2031
|
frozen_sensor_config=frozen_sensor_config,
|
|
2006
2032
|
use_quality_time_step_as_reporting_time_step=
|
|
2007
|
-
use_quality_time_step_as_reporting_time_step
|
|
2033
|
+
use_quality_time_step_as_reporting_time_step,
|
|
2034
|
+
reapply_uncertainties=reapply_uncertainties):
|
|
2008
2035
|
if result is None:
|
|
2009
2036
|
result = {}
|
|
2010
2037
|
for data_type, data in scada_data.items():
|
|
@@ -2032,6 +2059,7 @@ class ScenarioSimulator():
|
|
|
2032
2059
|
return_as_dict: bool = False,
|
|
2033
2060
|
frozen_sensor_config: bool = False,
|
|
2034
2061
|
use_quality_time_step_as_reporting_time_step: bool = False,
|
|
2062
|
+
reapply_uncertainties: bool = False
|
|
2035
2063
|
) -> Generator[Union[tuple[ScadaData, bool], tuple[dict, bool]], bool, None]:
|
|
2036
2064
|
"""
|
|
2037
2065
|
Runs an advanced quality analysis using EPANET-MSX.
|
|
@@ -2060,6 +2088,10 @@ class ScenarioSimulator():
|
|
|
2060
2088
|
As a consequence, the simualtion results can not be merged
|
|
2061
2089
|
with the hydraulic simulation.
|
|
2062
2090
|
|
|
2091
|
+
The default is False.
|
|
2092
|
+
reapply_uncertainties: bool = False : `bool`, optional
|
|
2093
|
+
If True, the uncertainties are re-applied.
|
|
2094
|
+
|
|
2063
2095
|
The default is False.
|
|
2064
2096
|
|
|
2065
2097
|
Returns
|
|
@@ -2074,6 +2106,8 @@ class ScenarioSimulator():
|
|
|
2074
2106
|
if self.__f_msx_in is None:
|
|
2075
2107
|
raise ValueError("No .msx file specified")
|
|
2076
2108
|
|
|
2109
|
+
self._prepare_simulation(reapply_uncertainties)
|
|
2110
|
+
|
|
2077
2111
|
# Load pre-computed hydraulics
|
|
2078
2112
|
self.epanet_api.useMSXHydraulicFile(hyd_file_in)
|
|
2079
2113
|
|
|
@@ -2171,12 +2205,14 @@ class ScenarioSimulator():
|
|
|
2171
2205
|
pass
|
|
2172
2206
|
|
|
2173
2207
|
if reporting_time_start == 0:
|
|
2208
|
+
msx_error_code = self.epanet_api.msx.get_last_error_code()
|
|
2209
|
+
|
|
2174
2210
|
if return_as_dict is True:
|
|
2175
2211
|
data = {"bulk_species_node_concentration_raw": bulk_species_node_concentrations,
|
|
2176
2212
|
"bulk_species_link_concentration_raw": bulk_species_link_concentrations,
|
|
2177
2213
|
"surface_species_concentration_raw": surface_species_concentrations,
|
|
2178
2214
|
"sensor_readings_time": np.array([0]),
|
|
2179
|
-
"warnings_code": np.array([
|
|
2215
|
+
"warnings_code": np.array([msx_error_code])
|
|
2180
2216
|
}
|
|
2181
2217
|
else:
|
|
2182
2218
|
data = ScadaData(network_topo=network_topo, sensor_config=self._sensor_config,
|
|
@@ -2184,7 +2220,7 @@ class ScenarioSimulator():
|
|
|
2184
2220
|
bulk_species_link_concentration_raw=bulk_species_link_concentrations,
|
|
2185
2221
|
surface_species_concentration_raw=surface_species_concentrations,
|
|
2186
2222
|
sensor_readings_time=np.array([0]),
|
|
2187
|
-
warnings_code=np.array([
|
|
2223
|
+
warnings_code=np.array([msx_error_code]),
|
|
2188
2224
|
sensor_reading_events=self._sensor_reading_events,
|
|
2189
2225
|
sensor_noise=self._sensor_noise,
|
|
2190
2226
|
frozen_sensor_config=frozen_sensor_config)
|
|
@@ -2199,9 +2235,13 @@ class ScenarioSimulator():
|
|
|
2199
2235
|
# Run step-by-step simulation
|
|
2200
2236
|
tleft = 1
|
|
2201
2237
|
total_time = 0
|
|
2238
|
+
last_msx_error_code = 0
|
|
2202
2239
|
while tleft > 0:
|
|
2203
2240
|
# Compute current time step
|
|
2204
2241
|
total_time, tleft = self.epanet_api.stepMSXQualityAnalysisTimeLeft()
|
|
2242
|
+
msx_error_code = self.epanet_api.msx.get_last_error_code()
|
|
2243
|
+
if last_msx_error_code == 0:
|
|
2244
|
+
last_msx_error_code = msx_error_code
|
|
2205
2245
|
|
|
2206
2246
|
# Fetch data at regular time intervals
|
|
2207
2247
|
if total_time % hyd_time_step == 0:
|
|
@@ -2223,7 +2263,7 @@ class ScenarioSimulator():
|
|
|
2223
2263
|
bulk_species_link_concentrations,
|
|
2224
2264
|
"surface_species_concentration_raw": surface_species_concentrations,
|
|
2225
2265
|
"sensor_readings_time": np.array([total_time]),
|
|
2226
|
-
"warnings_code": np.array([
|
|
2266
|
+
"warnings_code": np.array([last_msx_error_code]),
|
|
2227
2267
|
}
|
|
2228
2268
|
else:
|
|
2229
2269
|
data = ScadaData(network_topo=network_topo,
|
|
@@ -2235,7 +2275,7 @@ class ScenarioSimulator():
|
|
|
2235
2275
|
surface_species_concentration_raw=
|
|
2236
2276
|
surface_species_concentrations,
|
|
2237
2277
|
sensor_readings_time=np.array([total_time]),
|
|
2238
|
-
warnings_code=np.array([
|
|
2278
|
+
warnings_code=np.array([last_msx_error_code]),
|
|
2239
2279
|
sensor_reading_events=self._sensor_reading_events,
|
|
2240
2280
|
sensor_noise=self._sensor_noise,
|
|
2241
2281
|
frozen_sensor_config=frozen_sensor_config)
|
|
@@ -2388,6 +2428,7 @@ class ScenarioSimulator():
|
|
|
2388
2428
|
total_time = 0
|
|
2389
2429
|
tstep = 1
|
|
2390
2430
|
first_itr = True
|
|
2431
|
+
last_error_code = 0
|
|
2391
2432
|
while tstep > 0:
|
|
2392
2433
|
if first_itr is True: # Fix current time in the first iteration
|
|
2393
2434
|
tstep = 0
|
|
@@ -2406,6 +2447,8 @@ class ScenarioSimulator():
|
|
|
2406
2447
|
|
|
2407
2448
|
# Fetch data
|
|
2408
2449
|
error_code = self.epanet_api.get_last_error_code()
|
|
2450
|
+
if last_error_code == 0:
|
|
2451
|
+
last_error_code = error_code
|
|
2409
2452
|
quality_node_data = self.epanet_api.getNodeActualQuality().reshape(1, -1)
|
|
2410
2453
|
quality_link_data = self.epanet_api.getLinkActualQuality().reshape(1, -1)
|
|
2411
2454
|
|
|
@@ -2415,14 +2458,14 @@ class ScenarioSimulator():
|
|
|
2415
2458
|
data = {"node_quality_data_raw": quality_node_data,
|
|
2416
2459
|
"link_quality_data_raw": quality_link_data,
|
|
2417
2460
|
"sensor_readings_time": np.array([total_time]),
|
|
2418
|
-
"warnings_code": np.array([
|
|
2461
|
+
"warnings_code": np.array([last_error_code])}
|
|
2419
2462
|
else:
|
|
2420
2463
|
data = ScadaData(network_topo=network_topo,
|
|
2421
2464
|
sensor_config=self._sensor_config,
|
|
2422
2465
|
node_quality_data_raw=quality_node_data,
|
|
2423
2466
|
link_quality_data_raw=quality_link_data,
|
|
2424
2467
|
sensor_readings_time=np.array([total_time]),
|
|
2425
|
-
warnings_code=np.array([
|
|
2468
|
+
warnings_code=np.array([last_error_code]),
|
|
2426
2469
|
sensor_reading_events=self._sensor_reading_events,
|
|
2427
2470
|
sensor_noise=self._sensor_noise,
|
|
2428
2471
|
frozen_sensor_config=frozen_sensor_config)
|
|
@@ -2432,15 +2475,19 @@ class ScenarioSimulator():
|
|
|
2432
2475
|
if abort is True:
|
|
2433
2476
|
break
|
|
2434
2477
|
|
|
2435
|
-
yield (data, total_time
|
|
2478
|
+
yield (data, total_time >= requested_total_time)
|
|
2436
2479
|
|
|
2437
2480
|
# Next
|
|
2438
2481
|
tstep = self.epanet_api.api.ENstepQ()
|
|
2482
|
+
error_code = self.epanet_api.get_last_error_code()
|
|
2483
|
+
if last_error_code == 0:
|
|
2484
|
+
last_error_code = error_code
|
|
2439
2485
|
|
|
2440
2486
|
self.epanet_api.closeQualityAnalysis()
|
|
2441
2487
|
|
|
2442
2488
|
def run_hydraulic_simulation(self, hyd_export: str = None, verbose: bool = False,
|
|
2443
|
-
frozen_sensor_config: bool = False
|
|
2489
|
+
frozen_sensor_config: bool = False,
|
|
2490
|
+
reapply_uncertainties: bool = False) -> ScadaData:
|
|
2444
2491
|
"""
|
|
2445
2492
|
Runs the hydraulic simulation of this scenario (incl. basic quality if set).
|
|
2446
2493
|
|
|
@@ -2463,6 +2510,10 @@ class ScenarioSimulator():
|
|
|
2463
2510
|
If True, the sensor config can not be changed and only the required sensor nodes/links
|
|
2464
2511
|
will be stored -- this usually leads to a significant reduction in memory consumption.
|
|
2465
2512
|
|
|
2513
|
+
The default is False.
|
|
2514
|
+
reapply_uncertainties: bool = False : `bool`, optional
|
|
2515
|
+
If True, the uncertainties are re-applied.
|
|
2516
|
+
|
|
2466
2517
|
The default is False.
|
|
2467
2518
|
|
|
2468
2519
|
Returns
|
|
@@ -2482,7 +2533,8 @@ class ScenarioSimulator():
|
|
|
2482
2533
|
for scada_data, _ in gen(hyd_export=hyd_export,
|
|
2483
2534
|
verbose=verbose,
|
|
2484
2535
|
return_as_dict=True,
|
|
2485
|
-
frozen_sensor_config=frozen_sensor_config
|
|
2536
|
+
frozen_sensor_config=frozen_sensor_config,
|
|
2537
|
+
reapply_uncertainties=reapply_uncertainties):
|
|
2486
2538
|
if result is None:
|
|
2487
2539
|
result = {}
|
|
2488
2540
|
for data_type, data in scada_data.items():
|
|
@@ -2507,6 +2559,7 @@ class ScenarioSimulator():
|
|
|
2507
2559
|
support_abort: bool = False,
|
|
2508
2560
|
return_as_dict: bool = False,
|
|
2509
2561
|
frozen_sensor_config: bool = False,
|
|
2562
|
+
reapply_uncertainties: bool = False
|
|
2510
2563
|
) -> Generator[Union[tuple[ScadaData, bool], tuple[dict, bool]], bool, None]:
|
|
2511
2564
|
"""
|
|
2512
2565
|
Runs the hydraulic simulation of this scenario (incl. basic quality if set) and
|
|
@@ -2542,6 +2595,10 @@ class ScenarioSimulator():
|
|
|
2542
2595
|
If True, the sensor config can not be changed and only the required sensor nodes/links
|
|
2543
2596
|
will be stored -- this usually leads to a significant reduction in memory consumption.
|
|
2544
2597
|
|
|
2598
|
+
The default is False.
|
|
2599
|
+
reapply_uncertainties: bool = False : `bool`, optional
|
|
2600
|
+
If True, the uncertainties are re-applied.
|
|
2601
|
+
|
|
2545
2602
|
The default is False.
|
|
2546
2603
|
|
|
2547
2604
|
Returns
|
|
@@ -2555,7 +2612,7 @@ class ScenarioSimulator():
|
|
|
2555
2612
|
|
|
2556
2613
|
self._adapt_to_network_changes()
|
|
2557
2614
|
|
|
2558
|
-
self._prepare_simulation()
|
|
2615
|
+
self._prepare_simulation(reapply_uncertainties)
|
|
2559
2616
|
|
|
2560
2617
|
self.__running_simulation = True
|
|
2561
2618
|
|
|
@@ -2582,6 +2639,7 @@ class ScenarioSimulator():
|
|
|
2582
2639
|
total_time = 0
|
|
2583
2640
|
tstep = 1
|
|
2584
2641
|
first_itr = True
|
|
2642
|
+
last_error_code = 0
|
|
2585
2643
|
while tstep > 0:
|
|
2586
2644
|
if first_itr is True: # Fix current time in the first iteration
|
|
2587
2645
|
tstep = 0
|
|
@@ -2606,6 +2664,8 @@ class ScenarioSimulator():
|
|
|
2606
2664
|
if error_code == 0:
|
|
2607
2665
|
error_code = self.epanet_api.get_last_error_code()
|
|
2608
2666
|
total_time = t
|
|
2667
|
+
if last_error_code == 0:
|
|
2668
|
+
last_error_code = error_code
|
|
2609
2669
|
|
|
2610
2670
|
# Fetch data
|
|
2611
2671
|
pressure_data = self.epanet_api.getNodePressure().reshape(1, -1)
|
|
@@ -2636,7 +2696,7 @@ class ScenarioSimulator():
|
|
|
2636
2696
|
pumps_energy_usage_data_raw=pumps_energy_usage_data,
|
|
2637
2697
|
pumps_efficiency_data_raw=pumps_efficiency_data,
|
|
2638
2698
|
sensor_readings_time=np.array([total_time]),
|
|
2639
|
-
warnings_code=np.array([
|
|
2699
|
+
warnings_code=np.array([last_error_code]),
|
|
2640
2700
|
sensor_reading_events=self._sensor_reading_events,
|
|
2641
2701
|
sensor_noise=self._sensor_noise,
|
|
2642
2702
|
frozen_sensor_config=frozen_sensor_config)
|
|
@@ -2655,16 +2715,18 @@ class ScenarioSimulator():
|
|
|
2655
2715
|
"pumps_energy_usage_data_raw": pumps_energy_usage_data,
|
|
2656
2716
|
"pumps_efficiency_data_raw": pumps_efficiency_data,
|
|
2657
2717
|
"sensor_readings_time": np.array([total_time]),
|
|
2658
|
-
"warnings_code": np.array([
|
|
2718
|
+
"warnings_code": np.array([last_error_code])}
|
|
2659
2719
|
else:
|
|
2660
2720
|
data = scada_data
|
|
2661
2721
|
|
|
2722
|
+
last_error_code = 0
|
|
2723
|
+
|
|
2662
2724
|
if support_abort is True: # Can the simulation be aborted? If so, handle it.
|
|
2663
2725
|
abort = yield
|
|
2664
2726
|
if abort is True:
|
|
2665
2727
|
break
|
|
2666
2728
|
|
|
2667
|
-
yield (data, total_time
|
|
2729
|
+
yield (data, total_time >= requested_total_time)
|
|
2668
2730
|
|
|
2669
2731
|
# Apply control modules
|
|
2670
2732
|
for control in self._custom_controls:
|
|
@@ -2672,7 +2734,14 @@ class ScenarioSimulator():
|
|
|
2672
2734
|
|
|
2673
2735
|
# Next
|
|
2674
2736
|
tstep = self.epanet_api.api.ENnextH()
|
|
2737
|
+
error_code = self.epanet_api.get_last_error_code()
|
|
2738
|
+
if last_error_code == 0:
|
|
2739
|
+
last_error_code = error_code
|
|
2740
|
+
|
|
2675
2741
|
self.epanet_api.api.ENnextQ()
|
|
2742
|
+
error_code = self.epanet_api.get_last_error_code()
|
|
2743
|
+
if last_error_code == 0:
|
|
2744
|
+
last_error_code = error_code
|
|
2676
2745
|
|
|
2677
2746
|
self.epanet_api.api.ENcloseQ()
|
|
2678
2747
|
self.epanet_api.api.ENcloseH()
|
|
@@ -2686,7 +2755,8 @@ class ScenarioSimulator():
|
|
|
2686
2755
|
raise ex
|
|
2687
2756
|
|
|
2688
2757
|
def run_simulation(self, hyd_export: str = None, verbose: bool = False,
|
|
2689
|
-
frozen_sensor_config: bool = False
|
|
2758
|
+
frozen_sensor_config: bool = False,
|
|
2759
|
+
reapply_uncertainties: bool = False) -> ScadaData:
|
|
2690
2760
|
"""
|
|
2691
2761
|
Runs the simulation of this scenario.
|
|
2692
2762
|
|
|
@@ -2707,6 +2777,10 @@ class ScenarioSimulator():
|
|
|
2707
2777
|
If True, the sensor config can not be changed and only the required sensor nodes/links
|
|
2708
2778
|
will be stored -- this usually leads to a significant reduction in memory consumption.
|
|
2709
2779
|
|
|
2780
|
+
The default is False.
|
|
2781
|
+
reapply_uncertainties: bool = False : `bool`, optional
|
|
2782
|
+
If True, the uncertainties are re-applied.
|
|
2783
|
+
|
|
2710
2784
|
The default is False.
|
|
2711
2785
|
|
|
2712
2786
|
Returns
|
|
@@ -2727,14 +2801,16 @@ class ScenarioSimulator():
|
|
|
2727
2801
|
|
|
2728
2802
|
# Run hydraulic simulation step-by-step
|
|
2729
2803
|
result = self.run_hydraulic_simulation(hyd_export=hyd_export, verbose=verbose,
|
|
2730
|
-
frozen_sensor_config=frozen_sensor_config
|
|
2804
|
+
frozen_sensor_config=frozen_sensor_config,
|
|
2805
|
+
reapply_uncertainties=reapply_uncertainties)
|
|
2731
2806
|
|
|
2732
2807
|
# If necessary, run advanced quality simulation utilizing the computed hydraulics
|
|
2733
2808
|
if self.f_msx_in is not None:
|
|
2734
2809
|
gen = self.run_advanced_quality_simulation
|
|
2735
2810
|
result_msx = gen(hyd_file_in=hyd_export,
|
|
2736
2811
|
verbose=verbose,
|
|
2737
|
-
frozen_sensor_config=frozen_sensor_config
|
|
2812
|
+
frozen_sensor_config=frozen_sensor_config,
|
|
2813
|
+
reapply_uncertainties=reapply_uncertainties)
|
|
2738
2814
|
result.join(result_msx)
|
|
2739
2815
|
|
|
2740
2816
|
if hyd_export_old is not None:
|
|
@@ -2768,6 +2844,7 @@ class ScenarioSimulator():
|
|
|
2768
2844
|
f"'{type(model_uncertainty)}'")
|
|
2769
2845
|
|
|
2770
2846
|
self._model_uncertainty = model_uncertainty
|
|
2847
|
+
self.__uncertainties_applied = False
|
|
2771
2848
|
|
|
2772
2849
|
def set_sensor_noise(self, sensor_noise: SensorNoise) -> None:
|
|
2773
2850
|
"""
|
|
@@ -126,9 +126,9 @@ class Uncertainty(ABC):
|
|
|
126
126
|
Clipped data.
|
|
127
127
|
"""
|
|
128
128
|
if self.__min_value is not None:
|
|
129
|
-
data = np.
|
|
129
|
+
data = np.max([data, self.__min_value])
|
|
130
130
|
if self.__max_value is not None:
|
|
131
|
-
data = np.
|
|
131
|
+
data = np.min([data, self.__max_value])
|
|
132
132
|
|
|
133
133
|
return data
|
|
134
134
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: epyt-flow
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.14.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
|
|
@@ -85,12 +85,12 @@ By this, we not only aim to achieve a better performance of the simulations but
|
|
|
85
85
|
compatibility issues of pre-compiled binaries.
|
|
86
86
|
|
|
87
87
|
#### Prerequisites for macOS users
|
|
88
|
-
The "true" *gcc* compiler (version
|
|
88
|
+
The "true" *gcc* compiler (version 15) is needed which is not the
|
|
89
89
|
*clang* compiler that is shipped with Xcode and is linked to gcc!
|
|
90
90
|
|
|
91
91
|
The correct version of the "true" *gcc* can be installed via [brew](https://brew.sh/):
|
|
92
92
|
```
|
|
93
|
-
brew install gcc@
|
|
93
|
+
brew install gcc@15
|
|
94
94
|
```
|
|
95
95
|
|
|
96
96
|
### PyPI
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
epyt_flow/VERSION,sha256=
|
|
2
|
-
epyt_flow/__init__.py,sha256=
|
|
1
|
+
epyt_flow/VERSION,sha256=BlWCZVqs1vyD_3QqVxXAS7Slc5W_PuRVl5j6QsLORYk,7
|
|
2
|
+
epyt_flow/__init__.py,sha256=wktX10SXX9GEamDUWR-tcm-8T4d5s6j6aPYr_x4EpOc,1768
|
|
3
3
|
epyt_flow/serialization.py,sha256=uGGN1iZ21ek1u6Xzs4z2xum5Qt8554Wem-wEMGEaa7I,14574
|
|
4
4
|
epyt_flow/topology.py,sha256=Ih6m_tMT1JlPOJv8rHDVBtNayFOarPyAmCbMyojJtQg,26037
|
|
5
5
|
epyt_flow/utils.py,sha256=R_IE6uuTF2MRjUkgWDEa3xOYk8iorieHCqqQ0tDUZ40,17476
|
|
6
6
|
epyt_flow/EPANET/compile_linux.sh,sha256=wcrDyiB8NkivmaC-X9FI2WxhY3IJqDLiyIbVTv2XEPY,489
|
|
7
|
-
epyt_flow/EPANET/compile_macos.sh,sha256=
|
|
7
|
+
epyt_flow/EPANET/compile_macos.sh,sha256=JfXkCDe5OHhNXgukU13_ViCsD7KPV8qClzSXGLH1HVk,504
|
|
8
8
|
epyt_flow/EPANET/EPANET/SRC_engines/AUTHORS,sha256=yie5yAsEEPY0984PmkSRUdqEU9rVvRSGGWmjxdwCYMU,925
|
|
9
9
|
epyt_flow/EPANET/EPANET/SRC_engines/LICENSE,sha256=8SIIcPPO-ga2HotvptcK3uRccZOEGCeUOIU0Asiq7CU,1070
|
|
10
10
|
epyt_flow/EPANET/EPANET/SRC_engines/Readme_SRC_Engines.txt,sha256=7LWHGbghkYJb18wkIskUzYswRq0ZTMu_m6nV0IfvCOs,1005
|
|
@@ -108,10 +108,10 @@ epyt_flow/rest_api/scenario/uncertainty_handlers.py,sha256=Pdo2YmiawOqKXWcLs2P-l
|
|
|
108
108
|
epyt_flow/simulation/__init__.py,sha256=nihvZ8O2rJjYQkv7JhtVMqNacO5bA38VtS8Y_0BWrVQ,129
|
|
109
109
|
epyt_flow/simulation/parallel_simulation.py,sha256=ph4KXw9jCt-hiJFJbmC6fNvEsrbQoWV-tFKE5-qSfoQ,6523
|
|
110
110
|
epyt_flow/simulation/scenario_config.py,sha256=uHHwwzCRwooVdODxDNoCOUgfrlol1K-TS8P8_Ja9Coc,30435
|
|
111
|
-
epyt_flow/simulation/scenario_simulator.py,sha256=
|
|
111
|
+
epyt_flow/simulation/scenario_simulator.py,sha256=pEHpV_HJkgwPmnPlvBzJCAXaTNIBBRIVmTdkopcgxEc,165155
|
|
112
112
|
epyt_flow/simulation/sensor_config.py,sha256=AGAIC5vqcu2UZsglSCwv2pvZ3E0kbTtdaqtFPEMBwSw,94262
|
|
113
113
|
epyt_flow/simulation/backend/__init__.py,sha256=tkJb2NB_hruTv39sYHAq9ffazyA-UzZzFmiy2nYVTqA,23
|
|
114
|
-
epyt_flow/simulation/backend/my_epyt.py,sha256=
|
|
114
|
+
epyt_flow/simulation/backend/my_epyt.py,sha256=9zcHUo-shPuUNewsuxFpbBgtAbbTu7ppSaK6x4Xgt50,34414
|
|
115
115
|
epyt_flow/simulation/events/__init__.py,sha256=gv8ZcvwjJN0Z5MwRXEOVFRNq4X5NPyyqXIQnhBxszQ0,215
|
|
116
116
|
epyt_flow/simulation/events/actuator_events.py,sha256=gNOIZL9WNiIhEANi8yEyGxKx4vSMBZiRpiSJ4BbDL60,8171
|
|
117
117
|
epyt_flow/simulation/events/event.py,sha256=kARPV20XCAl6zxnJwI9U7ICtZUPACO_rgAmtHm1mGCs,2603
|
|
@@ -124,19 +124,19 @@ epyt_flow/simulation/events/system_event.py,sha256=IGypfTL-miosmwKd4DGTYvByyBcl8
|
|
|
124
124
|
epyt_flow/simulation/scada/__init__.py,sha256=pfJhg-tM5DaiZTXs0_1qJsY2R6Py_LwSz6BUFJexfQM,150
|
|
125
125
|
epyt_flow/simulation/scada/complex_control.py,sha256=p2ehLyScJbj2jbyevXf7T3Ot8jnBYWgRR3Cz-m3boB0,22107
|
|
126
126
|
epyt_flow/simulation/scada/custom_control.py,sha256=QzkKcn7t53GcTaRofRDbY-HErcDReMF4utWkck6bN60,4681
|
|
127
|
-
epyt_flow/simulation/scada/scada_data.py,sha256=
|
|
127
|
+
epyt_flow/simulation/scada/scada_data.py,sha256=fzcy35rSwoTcIsZpda9JOU17SpR-cV4DZ1tb6qFGpEc,203267
|
|
128
128
|
epyt_flow/simulation/scada/scada_data_export.py,sha256=WNAFn_WNfzYAEFbl2Al-cOIx-A0ozY4AI60-i_qEHdc,11643
|
|
129
129
|
epyt_flow/simulation/scada/simple_control.py,sha256=wUsxsrgqmYxXR93_atcKbV9E-t3hgqj60ZeTvoBBnoQ,12215
|
|
130
130
|
epyt_flow/uncertainty/__init__.py,sha256=ZRjuJL9rDpWVSdPwObPxFpEmMTcgAl3VmPOsS6cIyGg,89
|
|
131
131
|
epyt_flow/uncertainty/model_uncertainty.py,sha256=Bfc9OgecJbX2qOiANhTSKdK_m95aRuXkIGyc22b8d30,41183
|
|
132
132
|
epyt_flow/uncertainty/sensor_noise.py,sha256=-AnBfuW1VAx7Ya-q_gJ9bAr7Kx6pzP_y0PvNeuRjXIg,6477
|
|
133
|
-
epyt_flow/uncertainty/uncertainties.py,sha256=
|
|
133
|
+
epyt_flow/uncertainty/uncertainties.py,sha256=QBRbI3zIzkeFScyYD5Dy0TBxuL9jPV4SnVU8QwOrJq8,20495
|
|
134
134
|
epyt_flow/uncertainty/utils.py,sha256=K-ZhyO6Bg7UmNPgpfND0JLa_wRwyrtUUgGTWyWwy-fo,8029
|
|
135
135
|
epyt_flow/visualization/__init__.py,sha256=uQ7lO6AsgLc88X48Te3QhBQY-iDKGvdPtxKCl4b-Mfw,70
|
|
136
136
|
epyt_flow/visualization/scenario_visualizer.py,sha256=vkP0J_OfjvePUz_HehXJkH4CGKR3chAHe_UTx4hQ6XI,57860
|
|
137
137
|
epyt_flow/visualization/visualization_utils.py,sha256=l-EQ9UlY9MDBcOhK-uUZ9c-tX9emVqlo4xSqR-Sg17M,27525
|
|
138
|
-
epyt_flow-0.
|
|
139
|
-
epyt_flow-0.
|
|
140
|
-
epyt_flow-0.
|
|
141
|
-
epyt_flow-0.
|
|
142
|
-
epyt_flow-0.
|
|
138
|
+
epyt_flow-0.14.0.dist-info/licenses/LICENSE,sha256=YRJC2kcAhMlpEeHwUF0lzE-GRXLFyAjXNErI8L5UwYk,1071
|
|
139
|
+
epyt_flow-0.14.0.dist-info/METADATA,sha256=M7BM9VPwrVrFRzuBSVAFnimiOoPsCgjbiGiAjeSFw-A,9713
|
|
140
|
+
epyt_flow-0.14.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
141
|
+
epyt_flow-0.14.0.dist-info/top_level.txt,sha256=Wh_kd7TRL8ownCw3Y3dxx-9C0iTSk6wNauv_NX9JcrY,10
|
|
142
|
+
epyt_flow-0.14.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|