epyt-flow 0.6.0__py3-none-any.whl → 0.7.1__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/VERSION +1 -1
- epyt_flow/data/benchmarks/leakdb.py +1 -0
- epyt_flow/metrics.py +66 -4
- epyt_flow/serialization.py +33 -0
- epyt_flow/simulation/scada/scada_data.py +715 -16
- epyt_flow/simulation/scada/scada_data_export.py +5 -1
- epyt_flow/simulation/scenario_simulator.py +306 -99
- epyt_flow/simulation/sensor_config.py +49 -2
- epyt_flow/topology.py +3 -3
- epyt_flow/uncertainty/model_uncertainty.py +11 -5
- epyt_flow/uncertainty/uncertainties.py +8 -0
- epyt_flow/utils.py +69 -2
- {epyt_flow-0.6.0.dist-info → epyt_flow-0.7.1.dist-info}/METADATA +50 -7
- {epyt_flow-0.6.0.dist-info → epyt_flow-0.7.1.dist-info}/RECORD +17 -17
- {epyt_flow-0.6.0.dist-info → epyt_flow-0.7.1.dist-info}/WHEEL +1 -1
- {epyt_flow-0.6.0.dist-info → epyt_flow-0.7.1.dist-info}/LICENSE +0 -0
- {epyt_flow-0.6.0.dist-info → epyt_flow-0.7.1.dist-info}/top_level.txt +0 -0
|
@@ -112,7 +112,7 @@ def massunit_to_str(unit_id: int) -> str:
|
|
|
112
112
|
Parameters
|
|
113
113
|
----------
|
|
114
114
|
unit_id : `int`
|
|
115
|
-
ID of the
|
|
115
|
+
ID of the mass unit.
|
|
116
116
|
|
|
117
117
|
Must be one of the following constant:
|
|
118
118
|
|
|
@@ -284,7 +284,7 @@ def is_flowunit_simetric(unit_id: int) -> bool:
|
|
|
284
284
|
`bool`
|
|
285
285
|
True if the fiven unit is a SI metric unit, False otherwise.
|
|
286
286
|
"""
|
|
287
|
-
return unit_id in [ToolkitConstants.EN_LPM, ToolkitConstants.EN_MLD,
|
|
287
|
+
return unit_id in [ToolkitConstants.EN_LPS, ToolkitConstants.EN_LPM, ToolkitConstants.EN_MLD,
|
|
288
288
|
ToolkitConstants.EN_CMH, ToolkitConstants.EN_CMD]
|
|
289
289
|
|
|
290
290
|
|
|
@@ -1916,6 +1916,53 @@ class SensorConfig(JsonSerializable):
|
|
|
1916
1916
|
f"{list(map(massunit_to_str, self.__surface_species_mass_unit))} " +\
|
|
1917
1917
|
f"surface_species_area_unit: {areaunit_to_str(self.__surface_species_area_unit)}"
|
|
1918
1918
|
|
|
1919
|
+
def get_bulk_species_mass_unit_id(self, bulk_species_id: str) -> int:
|
|
1920
|
+
"""
|
|
1921
|
+
Returns the mass unit of a given bulk species.
|
|
1922
|
+
|
|
1923
|
+
Parameters
|
|
1924
|
+
----------
|
|
1925
|
+
bulk_species_id : `str`
|
|
1926
|
+
ID of the bulk species.
|
|
1927
|
+
|
|
1928
|
+
Returns
|
|
1929
|
+
-------
|
|
1930
|
+
`int`
|
|
1931
|
+
ID of the mass unit.
|
|
1932
|
+
|
|
1933
|
+
Will be one of the following constant:
|
|
1934
|
+
|
|
1935
|
+
- MASS_UNIT_MG = 4
|
|
1936
|
+
- MASS_UNIT_UG = 5
|
|
1937
|
+
- MASS_UNIT_MOL = 6
|
|
1938
|
+
- MASS_UNIT_MMOL = 7
|
|
1939
|
+
"""
|
|
1940
|
+
return self.__bulk_species_mass_unit[self.map_bulkspecies_id_to_idx(bulk_species_id)]
|
|
1941
|
+
|
|
1942
|
+
def get_surface_species_mass_unit_id(self, surface_species_id: str) -> int:
|
|
1943
|
+
"""
|
|
1944
|
+
Returns the mass unit of a given surface species.
|
|
1945
|
+
|
|
1946
|
+
Parameters
|
|
1947
|
+
----------
|
|
1948
|
+
surface_species_id : `str`
|
|
1949
|
+
ID of the surface species.
|
|
1950
|
+
|
|
1951
|
+
Returns
|
|
1952
|
+
-------
|
|
1953
|
+
`int`
|
|
1954
|
+
ID of the mass unit.
|
|
1955
|
+
|
|
1956
|
+
Will be one of the following constant:
|
|
1957
|
+
|
|
1958
|
+
- MASS_UNIT_MG = 4
|
|
1959
|
+
- MASS_UNIT_UG = 5
|
|
1960
|
+
- MASS_UNIT_MOL = 6
|
|
1961
|
+
- MASS_UNIT_MMOL = 7
|
|
1962
|
+
"""
|
|
1963
|
+
return self.__surface_species_mass_unit[self.map_surfacespecies_id_to_idx(
|
|
1964
|
+
surface_species_id)]
|
|
1965
|
+
|
|
1919
1966
|
def compute_readings(self, pressures: np.ndarray, flows: np.ndarray, demands: np.ndarray,
|
|
1920
1967
|
nodes_quality: np.ndarray, links_quality: np.ndarray,
|
|
1921
1968
|
pumps_state: np.ndarray, pumps_efficiency: np.ndarray,
|
epyt_flow/topology.py
CHANGED
|
@@ -507,11 +507,11 @@ class NetworkTopology(nx.Graph, JsonSerializable):
|
|
|
507
507
|
|
|
508
508
|
return super().__eq__(other) and \
|
|
509
509
|
self.get_all_nodes() == other.get_all_nodes() \
|
|
510
|
-
and all(link_a[0] == link_b[0] and
|
|
510
|
+
and all(link_a[0] == link_b[0] and link_a[1] == link_b[1]
|
|
511
511
|
for link_a, link_b in zip(self.get_all_links(), other.get_all_links())) \
|
|
512
512
|
and self.__units == other.units \
|
|
513
|
-
and self.
|
|
514
|
-
and self.
|
|
513
|
+
and self.get_all_pumps() == other.get_all_pumps() \
|
|
514
|
+
and self.get_all_valves() == other.get_all_valves()
|
|
515
515
|
|
|
516
516
|
def __str__(self) -> str:
|
|
517
517
|
return f"f_inp: {self.name} nodes: {self.__nodes} links: {self.__links} " +\
|
|
@@ -293,17 +293,23 @@ class ModelUncertainty(JsonSerializable):
|
|
|
293
293
|
epanet_api.setNodeElevations(elevations)
|
|
294
294
|
|
|
295
295
|
if self.__constants is not None:
|
|
296
|
-
constants = epanet_api.getMSXConstantsValue()
|
|
296
|
+
constants = np.array(epanet_api.getMSXConstantsValue())
|
|
297
297
|
constants = self.__constants.apply_batch(constants)
|
|
298
298
|
epanet_api.setMSXConstantsValue(constants)
|
|
299
299
|
|
|
300
300
|
if self.__parameters is not None:
|
|
301
301
|
parameters_pipes = epanet_api.getMSXParametersPipesValue()
|
|
302
302
|
for i, pipe_idx in enumerate(epanet_api.getLinkPipeIndex()):
|
|
303
|
-
|
|
304
|
-
|
|
303
|
+
if len(parameters_pipes[i]) == 0:
|
|
304
|
+
continue
|
|
305
|
+
|
|
306
|
+
parameters_pipes_val = self.__parameters.apply_batch(np.array(parameters_pipes[i]))
|
|
307
|
+
epanet_api.setMSXParametersPipesValue(pipe_idx, parameters_pipes_val)
|
|
305
308
|
|
|
306
309
|
parameters_tanks = epanet_api.getMSXParametersTanksValue()
|
|
307
310
|
for i, tank_idx in enumerate(epanet_api.getNodeTankIndex()):
|
|
308
|
-
parameters_tanks[i]
|
|
309
|
-
|
|
311
|
+
if parameters_tanks[i] is None or len(parameters_tanks[i]) == 0:
|
|
312
|
+
continue
|
|
313
|
+
|
|
314
|
+
parameters_tanks_val = self.__parameters.apply_batch(np.array(parameters_tanks[i]))
|
|
315
|
+
epanet_api.setMSXParametersTanksValue(tank_idx, parameters_tanks_val)
|
|
@@ -334,8 +334,16 @@ class PercentageDeviationUncertainty(UniformUncertainty, JsonSerializable):
|
|
|
334
334
|
if not 0 < deviation_percentage < 1:
|
|
335
335
|
raise ValueError("'deviation_percentage' must be in (0,1)")
|
|
336
336
|
|
|
337
|
+
if "low" in kwds:
|
|
338
|
+
del kwds["low"]
|
|
339
|
+
if "high" in kwds:
|
|
340
|
+
del kwds["high"]
|
|
341
|
+
|
|
337
342
|
super().__init__(low=1. - deviation_percentage, high=1. + deviation_percentage, **kwds)
|
|
338
343
|
|
|
344
|
+
def get_attributes(self) -> dict:
|
|
345
|
+
return super().get_attributes() | {"deviation_percentage": self.high - 1.}
|
|
346
|
+
|
|
339
347
|
def apply(self, data: float) -> float:
|
|
340
348
|
data *= np.random.uniform(low=self.low, high=self.high)
|
|
341
349
|
|
epyt_flow/utils.py
CHANGED
|
@@ -68,7 +68,8 @@ def volume_to_level(tank_volume: float, tank_diameter: float) -> float:
|
|
|
68
68
|
|
|
69
69
|
|
|
70
70
|
def plot_timeseries_data(data: np.ndarray, labels: list[str] = None, x_axis_label: str = None,
|
|
71
|
-
y_axis_label: str = None,
|
|
71
|
+
y_axis_label: str = None, y_ticks: tuple[list[float], list[str]] = None,
|
|
72
|
+
show: bool = True, save_to_file: str = None,
|
|
72
73
|
ax: matplotlib.axes.Axes = None) -> matplotlib.axes.Axes:
|
|
73
74
|
"""
|
|
74
75
|
Plots a single or multiple time series.
|
|
@@ -89,6 +90,10 @@ def plot_timeseries_data(data: np.ndarray, labels: list[str] = None, x_axis_labe
|
|
|
89
90
|
y_axis_label : `str`, optional
|
|
90
91
|
Y axis label.
|
|
91
92
|
|
|
93
|
+
The default is None.
|
|
94
|
+
y_ticks: `(list[float], list[str])`, optional
|
|
95
|
+
Tuple of ticks (numbers) and labels (strings) for the y-axis.
|
|
96
|
+
|
|
92
97
|
The default is None.
|
|
93
98
|
show : `bool`, optional
|
|
94
99
|
If True, the plot/figure is shown in a window.
|
|
@@ -96,6 +101,13 @@ def plot_timeseries_data(data: np.ndarray, labels: list[str] = None, x_axis_labe
|
|
|
96
101
|
Only considered when 'ax' is None.
|
|
97
102
|
|
|
98
103
|
The default is True.
|
|
104
|
+
save_to_file : `str`, optional
|
|
105
|
+
File to which the plot is saved.
|
|
106
|
+
|
|
107
|
+
If specified, 'show' must be set to False --
|
|
108
|
+
i.e. a plot can not be shown and saved to a file at the same time!
|
|
109
|
+
|
|
110
|
+
The default is None.
|
|
99
111
|
ax : `matplotlib.axes.Axes`, optional
|
|
100
112
|
If not None, 'ax' is used for plotting.
|
|
101
113
|
|
|
@@ -122,8 +134,18 @@ def plot_timeseries_data(data: np.ndarray, labels: list[str] = None, x_axis_labe
|
|
|
122
134
|
if not isinstance(y_axis_label, str):
|
|
123
135
|
raise TypeError("'y_axis_label' must be an instance of 'str' " +
|
|
124
136
|
f"but not of '{type(y_axis_label)}'")
|
|
137
|
+
if y_ticks is not None:
|
|
138
|
+
if len(y_ticks) != 2:
|
|
139
|
+
raise ValueError("'y_ticks' must be a tuple ticks (numbers) and labels (strings)")
|
|
125
140
|
if not isinstance(show, bool):
|
|
126
141
|
raise TypeError(f"'show' must be an instance of 'bool' but not of '{type(show)}'")
|
|
142
|
+
if save_to_file is not None:
|
|
143
|
+
if show is True:
|
|
144
|
+
raise ValueError("'show' must be False if 'save_to_file' is set")
|
|
145
|
+
|
|
146
|
+
if not isinstance(save_to_file, str):
|
|
147
|
+
raise TypeError("'save_to_file' must be an instance of 'str' but not of " +
|
|
148
|
+
f"'{type(save_to_file)}'")
|
|
127
149
|
if ax is not None:
|
|
128
150
|
if not isinstance(ax, matplotlib.axes.Axes):
|
|
129
151
|
raise TypeError("ax' must be an instance of 'matplotlib.axes.Axes'" +
|
|
@@ -145,9 +167,20 @@ def plot_timeseries_data(data: np.ndarray, labels: list[str] = None, x_axis_labe
|
|
|
145
167
|
ax.set_xlabel(x_axis_label)
|
|
146
168
|
if y_axis_label is not None:
|
|
147
169
|
ax.set_ylabel(y_axis_label)
|
|
170
|
+
if y_ticks is not None:
|
|
171
|
+
yticks_pos, yticks_labels = y_ticks
|
|
172
|
+
ax.set_yticks(yticks_pos, labels=yticks_labels)
|
|
148
173
|
|
|
149
174
|
if show is True and fig is not None:
|
|
150
175
|
plt.show()
|
|
176
|
+
if save_to_file is not None:
|
|
177
|
+
folder_path = str(Path(save_to_file).parent.absolute())
|
|
178
|
+
create_path_if_not_exist(folder_path)
|
|
179
|
+
|
|
180
|
+
if fig is None:
|
|
181
|
+
plt.savefig(save_to_file, bbox_inches='tight')
|
|
182
|
+
else:
|
|
183
|
+
fig.savefig(save_to_file, bbox_inches='tight')
|
|
151
184
|
|
|
152
185
|
return ax
|
|
153
186
|
|
|
@@ -155,7 +188,9 @@ def plot_timeseries_data(data: np.ndarray, labels: list[str] = None, x_axis_labe
|
|
|
155
188
|
def plot_timeseries_prediction(y: np.ndarray, y_pred: np.ndarray,
|
|
156
189
|
confidence_interval: np.ndarray = None,
|
|
157
190
|
x_axis_label: str = None, y_axis_label: str = None,
|
|
158
|
-
|
|
191
|
+
y_ticks: tuple[list[float], list[str]] = None,
|
|
192
|
+
show: bool = True, save_to_file: str = None,
|
|
193
|
+
ax: matplotlib.axes.Axes = None
|
|
159
194
|
) -> matplotlib.axes.Axes:
|
|
160
195
|
"""
|
|
161
196
|
Plots the prediction (e.g. forecast) of *single* time series together with the
|
|
@@ -179,6 +214,10 @@ def plot_timeseries_prediction(y: np.ndarray, y_pred: np.ndarray,
|
|
|
179
214
|
y_axis_label : `str`, optional
|
|
180
215
|
Y axis label.
|
|
181
216
|
|
|
217
|
+
The default is None.
|
|
218
|
+
y_ticks: `(list[float], list[str])`, optional
|
|
219
|
+
Tuple of ticks (numbers) and labels (strings) for the y-axis.
|
|
220
|
+
|
|
182
221
|
The default is None.
|
|
183
222
|
show : `bool`, optional
|
|
184
223
|
If True, the plot/figure is shown in a window.
|
|
@@ -186,6 +225,13 @@ def plot_timeseries_prediction(y: np.ndarray, y_pred: np.ndarray,
|
|
|
186
225
|
Only considered when 'ax' is None.
|
|
187
226
|
|
|
188
227
|
The default is True.
|
|
228
|
+
save_to_file : `str`, optional
|
|
229
|
+
File to which the plot is saved.
|
|
230
|
+
|
|
231
|
+
If specified, 'show' must be set to False --
|
|
232
|
+
i.e. a plot can not be shown and saved to a file at the same time!
|
|
233
|
+
|
|
234
|
+
The default is None.
|
|
189
235
|
ax : `matplotlib.axes.Axes`, optional
|
|
190
236
|
If not None, 'axes' is used for plotting.
|
|
191
237
|
|
|
@@ -216,8 +262,18 @@ def plot_timeseries_prediction(y: np.ndarray, y_pred: np.ndarray,
|
|
|
216
262
|
if not isinstance(y_axis_label, str):
|
|
217
263
|
raise TypeError("'y_axis_label' must be an instance of 'str' " +
|
|
218
264
|
f"but not of '{type(y_axis_label)}'")
|
|
265
|
+
if y_ticks is not None:
|
|
266
|
+
if len(y_ticks) != 2:
|
|
267
|
+
raise ValueError("'y_ticks' must be a tuple ticks (numbers) and labels (strings)")
|
|
219
268
|
if not isinstance(show, bool):
|
|
220
269
|
raise TypeError(f"'show' must be an instance of 'bool' but not of '{type(show)}'")
|
|
270
|
+
if save_to_file is not None:
|
|
271
|
+
if show is True:
|
|
272
|
+
raise ValueError("'show' must be False if 'save_to_file' is set")
|
|
273
|
+
|
|
274
|
+
if not isinstance(save_to_file, str):
|
|
275
|
+
raise TypeError("'save_to_file' must be an instance of 'str' but not of " +
|
|
276
|
+
f"'{type(save_to_file)}'")
|
|
221
277
|
if ax is not None:
|
|
222
278
|
if not isinstance(ax, matplotlib.axes.Axes):
|
|
223
279
|
raise TypeError("ax' must be an instance of 'matplotlib.axes.Axes'" +
|
|
@@ -240,9 +296,20 @@ def plot_timeseries_prediction(y: np.ndarray, y_pred: np.ndarray,
|
|
|
240
296
|
ax.set_xlabel(x_axis_label)
|
|
241
297
|
if y_axis_label is not None:
|
|
242
298
|
ax.set_ylabel(y_axis_label)
|
|
299
|
+
if y_ticks is not None:
|
|
300
|
+
yticks_pos, yticks_labels = y_ticks
|
|
301
|
+
ax.set_yticks(yticks_pos, labels=yticks_labels)
|
|
243
302
|
|
|
244
303
|
if show is True and fig is not None:
|
|
245
304
|
plt.show()
|
|
305
|
+
if save_to_file is not None:
|
|
306
|
+
folder_path = str(Path(save_to_file).parent.absolute())
|
|
307
|
+
create_path_if_not_exist(folder_path)
|
|
308
|
+
|
|
309
|
+
if fig is None:
|
|
310
|
+
plt.savefig(save_to_file, bbox_inches='tight')
|
|
311
|
+
else:
|
|
312
|
+
fig.savefig(save_to_file, bbox_inches='tight')
|
|
246
313
|
|
|
247
314
|
return ax
|
|
248
315
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: epyt-flow
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.1
|
|
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: MIT License
|
|
7
7
|
Project-URL: Homepage, https://github.com/WaterFutures/EPyT-Flow
|
|
8
|
-
Project-URL: Documentation, https://epyt-flow.readthedocs.io/en/
|
|
8
|
+
Project-URL: Documentation, https://epyt-flow.readthedocs.io/en/stable/
|
|
9
9
|
Project-URL: Repository, https://github.com/WaterFutures/EPyT-Flow.git
|
|
10
10
|
Project-URL: Issues, https://github.com/WaterFutures/EPyT-Flow/issues
|
|
11
11
|
Keywords: epanet,water,networks,hydraulics,quality,simulations
|
|
@@ -20,7 +20,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
20
20
|
Requires-Python: >=3.9
|
|
21
21
|
Description-Content-Type: text/markdown
|
|
22
22
|
License-File: LICENSE
|
|
23
|
-
Requires-Dist: epyt >=1.
|
|
23
|
+
Requires-Dist: epyt >=1.2.0
|
|
24
24
|
Requires-Dist: requests >=2.31.0
|
|
25
25
|
Requires-Dist: scipy >=1.11.4
|
|
26
26
|
Requires-Dist: u-msgpack-python >=2.8.0
|
|
@@ -121,7 +121,7 @@ pip install .
|
|
|
121
121
|
```python
|
|
122
122
|
from epyt_flow.data.benchmarks import load_leakdb_scenarios
|
|
123
123
|
from epyt_flow.simulation import ScenarioSimulator
|
|
124
|
-
from epyt_flow.utils import to_seconds
|
|
124
|
+
from epyt_flow.utils import to_seconds, plot_timeseries_data
|
|
125
125
|
|
|
126
126
|
|
|
127
127
|
if __name__ == "__main__":
|
|
@@ -142,14 +142,49 @@ if __name__ == "__main__":
|
|
|
142
142
|
# Run entire simulation
|
|
143
143
|
scada_data = sim.run_simulation()
|
|
144
144
|
|
|
145
|
-
#
|
|
145
|
+
# Print & plot sensor readings over the entire simulation
|
|
146
146
|
print(f"Pressure readings: {scada_data.get_data_pressures()}")
|
|
147
|
+
plot_timeseries_data(scada_data.get_data_pressures().T,
|
|
148
|
+
labels=[f"Node {n_id}" for n_id in
|
|
149
|
+
scada_data.sensor_config.pressure_sensors],
|
|
150
|
+
x_axis_label="Time (30min steps)",
|
|
151
|
+
y_axis_label="Pressure in $m$")
|
|
152
|
+
|
|
147
153
|
print(f"Flow readings: {scada_data.get_data_flows()}")
|
|
154
|
+
plot_timeseries_data(scada_data.get_data_flows().T,
|
|
155
|
+
x_axis_label="Time (30min steps)",
|
|
156
|
+
y_axis_label="Flow rate in $m^3/h$")
|
|
148
157
|
```
|
|
158
|
+
### Generated plots
|
|
159
|
+
|
|
160
|
+
<div>
|
|
161
|
+
<img src="https://github.com/WaterFutures/EPyT-Flow/blob/dev/docs/_static/examples_basic_usage_pressure.png?raw=true" width="49%"/>
|
|
162
|
+
<img src="https://github.com/WaterFutures/EPyT-Flow/blob/dev/docs/_static/examples_basic_usage_flow.png?raw=true" width="49%"/>
|
|
163
|
+
</div>
|
|
149
164
|
|
|
150
165
|
## Documentation
|
|
151
166
|
|
|
152
|
-
Documentation is available on readthedocs:[https://epyt-flow.readthedocs.io/en/latest/](https://epyt-flow.readthedocs.io/en/stable)
|
|
167
|
+
Documentation is available on readthedocs: [https://epyt-flow.readthedocs.io/en/latest/](https://epyt-flow.readthedocs.io/en/stable)
|
|
168
|
+
|
|
169
|
+
## How to Get Started?
|
|
170
|
+
|
|
171
|
+
EPyT-Flow is accompanied by an extensive documentation
|
|
172
|
+
[https://epyt-flow.readthedocs.io/en/latest/](https://epyt-flow.readthedocs.io/en/stable)
|
|
173
|
+
(including many [examples](https://epyt-flow.readthedocs.io/en/stable/#examples)).
|
|
174
|
+
|
|
175
|
+
If you are new to water distribution networks, we recommend first to read the chapter on
|
|
176
|
+
[Modeling of Water Distribution Networks](https://epyt-flow.readthedocs.io/en/stable/tut.intro.html).
|
|
177
|
+
You might also want to check out some lecture notes on
|
|
178
|
+
[Smart Water Systems](https://github.com/KIOS-Research/ece808-smart-water-systems).
|
|
179
|
+
|
|
180
|
+
If you are already familiar with WDNs (and software such as EPANET), we recommend checking out
|
|
181
|
+
our [WDSA CCWI 2024 tutorial](https://github.com/WaterFutures/EPyT-and-EPyT-Flow-Tutorial) which
|
|
182
|
+
not only teaches you how to use EPyT and EPyT-Flow but also contains some examples of applying
|
|
183
|
+
Machine Learning in WDNs.
|
|
184
|
+
Besides that, you can read in-depth about the different functionalities of EPyT-Flow in the
|
|
185
|
+
[In-depth Tutorial](https://epyt-flow.readthedocs.io/en/stable/tutorial.html) of the documentation --
|
|
186
|
+
we recommend reading the chapters in the order in which they are presented;
|
|
187
|
+
you might decide to skip some of the last chapters if their content is not relevant to you.
|
|
153
188
|
|
|
154
189
|
## License
|
|
155
190
|
|
|
@@ -170,6 +205,14 @@ If you use this software, please cite it as follows:
|
|
|
170
205
|
}
|
|
171
206
|
```
|
|
172
207
|
|
|
208
|
+
## How to get Support?
|
|
209
|
+
|
|
210
|
+
If you come across any bug or need assistance please feel free to open a new
|
|
211
|
+
[issue](https://github.com/WaterFutures/EPyT-Flow/issues/)
|
|
212
|
+
if non of the existing issues answers your questions.
|
|
213
|
+
|
|
173
214
|
## How to Contribute?
|
|
174
215
|
|
|
175
|
-
Contributions (e.g. creating issues, pull-requests, etc.) are welcome --
|
|
216
|
+
Contributions (e.g. creating issues, pull-requests, etc.) are welcome --
|
|
217
|
+
please make sure to read the [code of conduct](CODE_OF_CONDUCT.md) and
|
|
218
|
+
follow the [developers' guidelines](DEVELOPERS.md).
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
epyt_flow/VERSION,sha256=
|
|
1
|
+
epyt_flow/VERSION,sha256=kCMRx7s4-hZY_0A972FY7nN4_p1uLihPocOHNcMb0ws,6
|
|
2
2
|
epyt_flow/__init__.py,sha256=KNDiPWiHdB9a5ZF1ipjA1uoq61TwU2ThjaStpvSLBtY,1742
|
|
3
|
-
epyt_flow/metrics.py,sha256=
|
|
4
|
-
epyt_flow/serialization.py,sha256=
|
|
5
|
-
epyt_flow/topology.py,sha256=
|
|
6
|
-
epyt_flow/utils.py,sha256=
|
|
3
|
+
epyt_flow/metrics.py,sha256=W-dolnrmWfoanyvg-knoe2QMUtFwV1xODp4D4EwsQ00,14261
|
|
4
|
+
epyt_flow/serialization.py,sha256=ltWcLiTw62s0KG2DSgkQBkn6CCkxy9soDGq_ENohkrI,13998
|
|
5
|
+
epyt_flow/topology.py,sha256=8gqgJrKxw0zY69sIKo4NxrQAoXHP1Ni00U2DV09vR6g,25275
|
|
6
|
+
epyt_flow/utils.py,sha256=GJDktl7ciUPJxqMg9f2nCnQf6DosNd2mxeKOy7omkik,15196
|
|
7
7
|
epyt_flow/EPANET/compile_linux.sh,sha256=wcrDyiB8NkivmaC-X9FI2WxhY3IJqDLiyIbVTv2XEPY,489
|
|
8
8
|
epyt_flow/EPANET/compile_macos.sh,sha256=1K33-bPdgr01EIf87YUvmOFHXyOkBWI6mKXQ8x1Hzmo,504
|
|
9
9
|
epyt_flow/EPANET/EPANET/SRC_engines/AUTHORS,sha256=yie5yAsEEPY0984PmkSRUdqEU9rVvRSGGWmjxdwCYMU,925
|
|
@@ -87,7 +87,7 @@ epyt_flow/data/benchmarks/batadal_data.py,sha256=oIzcysGivMPAgrfzrk5l8i-j6Ii96DP
|
|
|
87
87
|
epyt_flow/data/benchmarks/battledim.py,sha256=yLwiQB0x7yq197XSM77tjHm7E7ucTbrybFaNxZx2TtM,20448
|
|
88
88
|
epyt_flow/data/benchmarks/battledim_data.py,sha256=0vHm-2eAiLv6U-n5dqUUWS1o_szFRy9mVJ3eqDRp4PE,3373
|
|
89
89
|
epyt_flow/data/benchmarks/gecco_water_quality.py,sha256=1buZRJiNf4jsqWYg4Ud90GhqaiLVo4yij3RAZJkzsqE,10985
|
|
90
|
-
epyt_flow/data/benchmarks/leakdb.py,sha256=
|
|
90
|
+
epyt_flow/data/benchmarks/leakdb.py,sha256=bhqdJkFMBNdgvQyYWYIpFHFA5ly9Tt51z6nGkyo56-g,25117
|
|
91
91
|
epyt_flow/data/benchmarks/leakdb_data.py,sha256=FNssgMkC1wqWVlaOrrihr4Od9trEZY7KeK5KuBeRMvM,507058
|
|
92
92
|
epyt_flow/data/benchmarks/water_usage.py,sha256=FLqjff3pha33oEU9ZM3UGPXn9eJJumsJH8Gdj7YFX3A,4778
|
|
93
93
|
epyt_flow/gym/__init__.py,sha256=KNTDtPTEtHwZ4ehHfj9qGw81Z9acFqPIgMzYUzH5_uM,115
|
|
@@ -112,9 +112,9 @@ epyt_flow/rest_api/scenario/uncertainty_handlers.py,sha256=uuu6AP11ZZUp2P3Dnukjg
|
|
|
112
112
|
epyt_flow/simulation/__init__.py,sha256=VGGJqJRUoXZjKJ0-m6KPp3JQqD_1TFW0pofLgkwZJ8M,164
|
|
113
113
|
epyt_flow/simulation/parallel_simulation.py,sha256=VmC7xemjxRB_N0fx1AAQ7ux82tnyTi7jk7jfFpeg7gM,6523
|
|
114
114
|
epyt_flow/simulation/scenario_config.py,sha256=NyadeCihpR4bpsWVPj7J-1DU2w1CEN0pAo2yh0t8Xkg,26751
|
|
115
|
-
epyt_flow/simulation/scenario_simulator.py,sha256=
|
|
115
|
+
epyt_flow/simulation/scenario_simulator.py,sha256=RnPvgEvEZO2rxXPu3jpBGTCjl7LQ6pnSjjPrRhvsMgY,110315
|
|
116
116
|
epyt_flow/simulation/scenario_visualizer.py,sha256=fpj67zl69q-byg7Oxocqhmu1S3P7B3ROCkSYzWyM--0,2187
|
|
117
|
-
epyt_flow/simulation/sensor_config.py,sha256=
|
|
117
|
+
epyt_flow/simulation/sensor_config.py,sha256=1YduJTNpEhbndIxRXGGx9_nNxH45RIA9bSNJQFXRatA,92255
|
|
118
118
|
epyt_flow/simulation/events/__init__.py,sha256=tIdqzs7_Cus4X2kbZG4Jl2zs-zsk_4rnajFOCvL0zlI,185
|
|
119
119
|
epyt_flow/simulation/events/actuator_events.py,sha256=2_MPYbYO9As6fMkm5Oy9pjSB9kCvFuKpGu8ykYDAydg,7903
|
|
120
120
|
epyt_flow/simulation/events/event.py,sha256=kARPV20XCAl6zxnJwI9U7ICtZUPACO_rgAmtHm1mGCs,2603
|
|
@@ -125,15 +125,15 @@ epyt_flow/simulation/events/sensor_reading_event.py,sha256=rQ-CmdpSUyZzDFYwNUGH2
|
|
|
125
125
|
epyt_flow/simulation/events/system_event.py,sha256=0KI2iaAaOyC9Y-FIfFVazeKT_4ORQRp26gWyMBUu_3c,2396
|
|
126
126
|
epyt_flow/simulation/scada/__init__.py,sha256=ZFAxJVqwEVsgiyFilFetnb13gPhZg1JEOPWYvKIJT4c,90
|
|
127
127
|
epyt_flow/simulation/scada/advanced_control.py,sha256=5h7dmSMcNlTE7TMZa8gQVnOCGMf7uZy60r9aOfKDxMc,4487
|
|
128
|
-
epyt_flow/simulation/scada/scada_data.py,sha256=
|
|
129
|
-
epyt_flow/simulation/scada/scada_data_export.py,sha256=
|
|
128
|
+
epyt_flow/simulation/scada/scada_data.py,sha256=hwXoZafhd8vrB3Rug_bldNmMfiAeZhGK-ZNKDrHhJxg,139708
|
|
129
|
+
epyt_flow/simulation/scada/scada_data_export.py,sha256=ohAn6vB9UEHesLBFg1lUZ6OgsYkJjYI4q3iTb-tL0fU,11501
|
|
130
130
|
epyt_flow/uncertainty/__init__.py,sha256=ZRjuJL9rDpWVSdPwObPxFpEmMTcgAl3VmPOsS6cIyGg,89
|
|
131
|
-
epyt_flow/uncertainty/model_uncertainty.py,sha256
|
|
131
|
+
epyt_flow/uncertainty/model_uncertainty.py,sha256=SD2sYGqj7K0Ys0Lvak4HsbP18A0SmwsK5Mnys_pZilg,14191
|
|
132
132
|
epyt_flow/uncertainty/sensor_noise.py,sha256=zJVULxnxVPSSqc6UW0iwZ9O-HGf9dn4CwScPqf4yCY0,2324
|
|
133
|
-
epyt_flow/uncertainty/uncertainties.py,sha256=
|
|
133
|
+
epyt_flow/uncertainty/uncertainties.py,sha256=jzaAwv5--HGc-H4-SwB0s-pAnzhhFuc06IXck7rC5l8,17902
|
|
134
134
|
epyt_flow/uncertainty/utils.py,sha256=gq66c9-QMOxOqI6wgWLyFxjVV0fbG0_8Yzd6mQjNYNo,5315
|
|
135
|
-
epyt_flow-0.
|
|
136
|
-
epyt_flow-0.
|
|
137
|
-
epyt_flow-0.
|
|
138
|
-
epyt_flow-0.
|
|
139
|
-
epyt_flow-0.
|
|
135
|
+
epyt_flow-0.7.1.dist-info/LICENSE,sha256=-4hYIY2BLmCkdOv2_PehEwlnMKTCes8_oyIUXjKtkug,1076
|
|
136
|
+
epyt_flow-0.7.1.dist-info/METADATA,sha256=t8szo6HkAXOXM1sWpoOUvx1zqkzZoWjm8dhgC_6CTms,9420
|
|
137
|
+
epyt_flow-0.7.1.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
|
138
|
+
epyt_flow-0.7.1.dist-info/top_level.txt,sha256=Wh_kd7TRL8ownCw3Y3dxx-9C0iTSk6wNauv_NX9JcrY,10
|
|
139
|
+
epyt_flow-0.7.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|