epyt-flow 0.10.0__py3-none-any.whl → 0.11.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/VERSION +1 -1
- epyt_flow/data/networks.py +27 -14
- epyt_flow/gym/control_gyms.py +8 -0
- epyt_flow/gym/scenario_control_env.py +8 -3
- epyt_flow/metrics.py +5 -0
- epyt_flow/models/event_detector.py +5 -0
- epyt_flow/models/sensor_interpolation_detector.py +5 -0
- epyt_flow/serialization.py +1 -0
- epyt_flow/simulation/__init__.py +0 -1
- epyt_flow/simulation/events/actuator_events.py +7 -1
- epyt_flow/simulation/scada/scada_data.py +527 -5
- epyt_flow/simulation/scenario_config.py +1 -40
- epyt_flow/simulation/scenario_simulator.py +511 -68
- epyt_flow/simulation/sensor_config.py +18 -2
- epyt_flow/topology.py +16 -0
- epyt_flow/uncertainty/model_uncertainty.py +80 -62
- epyt_flow/uncertainty/sensor_noise.py +15 -4
- epyt_flow/uncertainty/uncertainties.py +71 -18
- epyt_flow/uncertainty/utils.py +40 -13
- epyt_flow/utils.py +15 -1
- epyt_flow/visualization/__init__.py +2 -0
- epyt_flow/{simulation → visualization}/scenario_visualizer.py +429 -586
- epyt_flow/visualization/visualization_utils.py +611 -0
- {epyt_flow-0.10.0.dist-info → epyt_flow-0.11.0.dist-info}/METADATA +12 -1
- {epyt_flow-0.10.0.dist-info → epyt_flow-0.11.0.dist-info}/RECORD +28 -26
- {epyt_flow-0.10.0.dist-info → epyt_flow-0.11.0.dist-info}/WHEEL +1 -1
- {epyt_flow-0.10.0.dist-info → epyt_flow-0.11.0.dist-info}/LICENSE +0 -0
- {epyt_flow-0.10.0.dist-info → epyt_flow-0.11.0.dist-info}/top_level.txt +0 -0
epyt_flow/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.11.0
|
epyt_flow/data/networks.py
CHANGED
|
@@ -154,8 +154,9 @@ def load_net1(download_dir: str = get_temp_folder(), verbose: bool = True,
|
|
|
154
154
|
"""
|
|
155
155
|
f_in = os.path.join(download_dir, "Net1.inp")
|
|
156
156
|
url = "https://filedn.com/lumBFq2P9S74PNoLPWtzxG4/EPyT-Flow/Networks/Net1.inp"
|
|
157
|
+
backup_urls = ["https://raw.githubusercontent.com/OpenWaterAnalytics/EPyT/refs/heads/dev/epyt/networks/asce-tf-wdst/Net1.inp"]
|
|
157
158
|
|
|
158
|
-
download_if_necessary(f_in, url, verbose)
|
|
159
|
+
download_if_necessary(f_in, url, verbose, backup_urls)
|
|
159
160
|
return load_inp(f_in, flow_units_id=flow_units_id)
|
|
160
161
|
|
|
161
162
|
|
|
@@ -201,8 +202,9 @@ def load_net2(download_dir: str = get_temp_folder(), verbose: bool = True,
|
|
|
201
202
|
"""
|
|
202
203
|
f_in = os.path.join(download_dir, "Net2.inp")
|
|
203
204
|
url = "https://filedn.com/lumBFq2P9S74PNoLPWtzxG4/EPyT-Flow/Networks/Net2.inp"
|
|
205
|
+
backup_urls = ["https://raw.githubusercontent.com/OpenWaterAnalytics/EPyT/refs/heads/dev/epyt/networks/asce-tf-wdst/Net2.inp"]
|
|
204
206
|
|
|
205
|
-
download_if_necessary(f_in, url, verbose)
|
|
207
|
+
download_if_necessary(f_in, url, verbose, backup_urls)
|
|
206
208
|
return load_inp(f_in, flow_units_id=flow_units_id)
|
|
207
209
|
|
|
208
210
|
|
|
@@ -248,8 +250,9 @@ def load_net3(download_dir: str = get_temp_folder(), verbose: bool = True,
|
|
|
248
250
|
"""
|
|
249
251
|
f_in = os.path.join(download_dir, "Net3.inp")
|
|
250
252
|
url = "https://filedn.com/lumBFq2P9S74PNoLPWtzxG4/EPyT-Flow/Networks/Net3.inp"
|
|
253
|
+
backup_urls = ["https://raw.githubusercontent.com/OpenWaterAnalytics/EPyT/refs/heads/dev/epyt/networks/asce-tf-wdst/Net3.inp"]
|
|
251
254
|
|
|
252
|
-
download_if_necessary(f_in, url, verbose)
|
|
255
|
+
download_if_necessary(f_in, url, verbose, backup_urls)
|
|
253
256
|
return load_inp(f_in, flow_units_id=flow_units_id)
|
|
254
257
|
|
|
255
258
|
|
|
@@ -342,8 +345,9 @@ def load_richmond(download_dir: str = get_temp_folder(), verbose: bool = True,
|
|
|
342
345
|
"""
|
|
343
346
|
f_in = os.path.join(download_dir, "Richmond_standard.inp")
|
|
344
347
|
url = "https://filedn.com/lumBFq2P9S74PNoLPWtzxG4/EPyT-Flow/Networks/Richmond_standard.inp"
|
|
348
|
+
backup_urls = ["https://raw.githubusercontent.com/KIOS-Research/EPANET-Benchmarks/refs/heads/master/collect-epanet-inp/Richmond_standard.inp"]
|
|
345
349
|
|
|
346
|
-
download_if_necessary(f_in, url, verbose)
|
|
350
|
+
download_if_necessary(f_in, url, verbose, backup_urls)
|
|
347
351
|
return load_inp(f_in, flow_units_id=flow_units_id)
|
|
348
352
|
|
|
349
353
|
|
|
@@ -389,8 +393,9 @@ def load_micropolis(download_dir: str = get_temp_folder(), verbose: bool = True,
|
|
|
389
393
|
"""
|
|
390
394
|
f_in = os.path.join(download_dir, "MICROPOLIS_v1.inp")
|
|
391
395
|
url = "https://filedn.com/lumBFq2P9S74PNoLPWtzxG4/EPyT-Flow/Networks/MICROPOLIS_v1.inp"
|
|
396
|
+
backup_urls = ["https://raw.githubusercontent.com/KIOS-Research/EPANET-Benchmarks/refs/heads/master/collect-epanet-inp/MICROPOLIS_v1.inp"]
|
|
392
397
|
|
|
393
|
-
download_if_necessary(f_in, url, verbose)
|
|
398
|
+
download_if_necessary(f_in, url, verbose, backup_urls)
|
|
394
399
|
return load_inp(f_in, flow_units_id=flow_units_id)
|
|
395
400
|
|
|
396
401
|
|
|
@@ -436,8 +441,9 @@ def load_balerma(download_dir: str = get_temp_folder(), verbose: bool = True,
|
|
|
436
441
|
"""
|
|
437
442
|
f_in = os.path.join(download_dir, "Balerma.inp")
|
|
438
443
|
url = "https://filedn.com/lumBFq2P9S74PNoLPWtzxG4/EPyT-Flow/Networks/Balerma.inp"
|
|
444
|
+
backup_urls = ["https://raw.githubusercontent.com/KIOS-Research/EPANET-Benchmarks/refs/heads/master/collect-epanet-inp/Balerma.inp"]
|
|
439
445
|
|
|
440
|
-
download_if_necessary(f_in, url, verbose)
|
|
446
|
+
download_if_necessary(f_in, url, verbose, backup_urls)
|
|
441
447
|
return load_inp(f_in, flow_units_id=flow_units_id)
|
|
442
448
|
|
|
443
449
|
|
|
@@ -483,8 +489,9 @@ def load_rural(download_dir: str = get_temp_folder(), verbose: bool = True,
|
|
|
483
489
|
"""
|
|
484
490
|
f_in = os.path.join(download_dir, "RuralNetwork.inp")
|
|
485
491
|
url = "https://filedn.com/lumBFq2P9S74PNoLPWtzxG4/EPyT-Flow/Networks/RuralNetwork.inp"
|
|
492
|
+
backup_urls = ["https://raw.githubusercontent.com/KIOS-Research/EPANET-Benchmarks/refs/heads/master/collect-epanet-inp/RuralNetwork.inp"]
|
|
486
493
|
|
|
487
|
-
download_if_necessary(f_in, url, verbose)
|
|
494
|
+
download_if_necessary(f_in, url, verbose, backup_urls)
|
|
488
495
|
return load_inp(f_in, flow_units_id=flow_units_id)
|
|
489
496
|
|
|
490
497
|
|
|
@@ -530,8 +537,9 @@ def load_bwsn1(download_dir: str = get_temp_folder(), verbose: bool = True,
|
|
|
530
537
|
"""
|
|
531
538
|
f_in = os.path.join(download_dir, "BWSN_Network_1.inp")
|
|
532
539
|
url = "https://filedn.com/lumBFq2P9S74PNoLPWtzxG4/EPyT-Flow/Networks/BWSN_Network_1.inp"
|
|
540
|
+
backup_urls = ["https://raw.githubusercontent.com/KIOS-Research/EPANET-Benchmarks/refs/heads/master/collect-epanet-inp/BWSN_Network_1.inp"]
|
|
533
541
|
|
|
534
|
-
download_if_necessary(f_in, url, verbose)
|
|
542
|
+
download_if_necessary(f_in, url, verbose, backup_urls)
|
|
535
543
|
return load_inp(f_in, flow_units_id=flow_units_id)
|
|
536
544
|
|
|
537
545
|
|
|
@@ -577,8 +585,9 @@ def load_bwsn2(download_dir: str = get_temp_folder(), verbose: bool = True,
|
|
|
577
585
|
"""
|
|
578
586
|
f_in = os.path.join(download_dir, "BWSN_Network_2.inp")
|
|
579
587
|
url = "https://filedn.com/lumBFq2P9S74PNoLPWtzxG4/EPyT-Flow/Networks/BWSN_Network_2.inp"
|
|
588
|
+
backup_urls = ["https://raw.githubusercontent.com/KIOS-Research/EPANET-Benchmarks/refs/heads/master/collect-epanet-inp/BWSN_Network_2.inp"]
|
|
580
589
|
|
|
581
|
-
download_if_necessary(f_in, url, verbose)
|
|
590
|
+
download_if_necessary(f_in, url, verbose, backup_urls)
|
|
582
591
|
return load_inp(f_in, flow_units_id=flow_units_id)
|
|
583
592
|
|
|
584
593
|
|
|
@@ -624,8 +633,9 @@ def load_anytown(download_dir: str = get_temp_folder(), verbose: bool = True,
|
|
|
624
633
|
"""
|
|
625
634
|
f_in = os.path.join(download_dir, "Anytown.inp")
|
|
626
635
|
url = "https://filedn.com/lumBFq2P9S74PNoLPWtzxG4/EPyT-Flow/Networks/Anytown.inp"
|
|
636
|
+
backup_urls = ["https://raw.githubusercontent.com/OpenWaterAnalytics/EPyT/refs/heads/dev/epyt/networks/asce-tf-wdst/Anytown.inp"]
|
|
627
637
|
|
|
628
|
-
download_if_necessary(f_in, url, verbose)
|
|
638
|
+
download_if_necessary(f_in, url, verbose, backup_urls)
|
|
629
639
|
return load_inp(f_in, flow_units_id=flow_units_id)
|
|
630
640
|
|
|
631
641
|
|
|
@@ -670,9 +680,10 @@ def load_dtown(download_dir: str = get_temp_folder(), verbose: bool = True,
|
|
|
670
680
|
:class:`~epyt_flow.simulation.scenario_simulator.ScenarioSimulator`.
|
|
671
681
|
"""
|
|
672
682
|
f_in = os.path.join(download_dir, "d-town.inp")
|
|
673
|
-
url = "https://
|
|
683
|
+
url = "https://filedn.com/lumBFq2P9S74PNoLPWtzxG4/EPyT-Flow/Networks/d-town.inp"
|
|
684
|
+
backup_urls = ["https://raw.githubusercontent.com/KIOS-Research/EPANET-Benchmarks/refs/heads/master/collect-epanet-inp/d-town.inp"]
|
|
674
685
|
|
|
675
|
-
download_if_necessary(f_in, url, verbose)
|
|
686
|
+
download_if_necessary(f_in, url, verbose, backup_urls)
|
|
676
687
|
return load_inp(f_in, flow_units_id=flow_units_id)
|
|
677
688
|
|
|
678
689
|
|
|
@@ -774,8 +785,9 @@ def load_kentucky(wdn_id: int = 1, download_dir: str = get_temp_folder(),
|
|
|
774
785
|
|
|
775
786
|
f_in = os.path.join(download_dir, f"ky{wdn_id}.inp")
|
|
776
787
|
url = f"https://filedn.com/lumBFq2P9S74PNoLPWtzxG4/EPyT-Flow/Networks/ky{wdn_id}.inp"
|
|
788
|
+
backup_urls = [f"https://raw.githubusercontent.com/OpenWaterAnalytics/EPyT/refs/heads/dev/epyt/networks/asce-tf-wdst/ky{wdn_id}.inp"]
|
|
777
789
|
|
|
778
|
-
download_if_necessary(f_in, url, verbose)
|
|
790
|
+
download_if_necessary(f_in, url, verbose, backup_urls)
|
|
779
791
|
return load_inp(f_in, flow_units_id=flow_units_id)
|
|
780
792
|
|
|
781
793
|
|
|
@@ -826,8 +838,9 @@ def load_hanoi(download_dir: str = get_temp_folder(),
|
|
|
826
838
|
"""
|
|
827
839
|
f_in = os.path.join(download_dir, "Hanoi.inp")
|
|
828
840
|
url = "https://filedn.com/lumBFq2P9S74PNoLPWtzxG4/EPyT-Flow/Networks/Hanoi.inp"
|
|
841
|
+
backup_urls = ["https://raw.githubusercontent.com/OpenWaterAnalytics/EPyT/refs/heads/dev/epyt/networks/asce-tf-wdst/Hanoi.inp"]
|
|
829
842
|
|
|
830
|
-
download_if_necessary(f_in, url, verbose)
|
|
843
|
+
download_if_necessary(f_in, url, verbose, backup_urls)
|
|
831
844
|
config = load_inp(f_in, flow_units_id=flow_units_id)
|
|
832
845
|
|
|
833
846
|
if include_default_sensor_placement is True:
|
epyt_flow/gym/control_gyms.py
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Module provides functions for registering and creating control environments.
|
|
3
3
|
"""
|
|
4
|
+
import warnings
|
|
5
|
+
|
|
4
6
|
from .scenario_control_env import ScenarioControlEnv
|
|
5
7
|
|
|
6
8
|
|
|
@@ -18,6 +20,9 @@ def register(env_name: str, env: ScenarioControlEnv) -> None:
|
|
|
18
20
|
env : :class:`~epyt_flow.gym.scenario_control_env.ScenarioControlEnv`
|
|
19
21
|
Environment.
|
|
20
22
|
"""
|
|
23
|
+
warnings.warn("'register()' is deprecated and will be removed in future releases -- " +
|
|
24
|
+
"please consider switching to the EPyT-Control package")
|
|
25
|
+
|
|
21
26
|
if env_name in environments:
|
|
22
27
|
raise ValueError(f"Environment '{env_name}' already exists.")
|
|
23
28
|
if not issubclass(env, ScenarioControlEnv):
|
|
@@ -41,6 +46,9 @@ def make(env_name: str, **kwds) -> ScenarioControlEnv:
|
|
|
41
46
|
:class:`~epyt_flow.gym.scenario_control_env.ScenarioControlEnv`
|
|
42
47
|
Environment.
|
|
43
48
|
"""
|
|
49
|
+
warnings.warn("'make()' is deprecated and will be removed in future releases -- " +
|
|
50
|
+
"please consider switching to the EPyT-Control package")
|
|
51
|
+
|
|
44
52
|
if env_name not in environments:
|
|
45
53
|
raise ValueError(f"Unknown environment '{env_name}'.")
|
|
46
54
|
|
|
@@ -177,9 +177,14 @@ class ScenarioControlEnv(ABC):
|
|
|
177
177
|
raise RuntimeError("Can not execute actions affecting the hydraulics "+
|
|
178
178
|
"when running EPANET-MSX")
|
|
179
179
|
|
|
180
|
-
pump_idx = self._scenario_sim.epanet_api.getLinkPumpNameID().index(pump_id)
|
|
181
|
-
pump_link_idx = self._scenario_sim.epanet_api.getLinkPumpIndex(pump_idx
|
|
182
|
-
|
|
180
|
+
pump_idx = self._scenario_sim.epanet_api.getLinkPumpNameID().index(pump_id) + 1
|
|
181
|
+
pump_link_idx = self._scenario_sim.epanet_api.getLinkPumpIndex(pump_idx)
|
|
182
|
+
|
|
183
|
+
pattern_idx = self._scenario_sim.epanet_api.getLinkPumpPatternIndex(pump_idx)
|
|
184
|
+
if pattern_idx != 0:
|
|
185
|
+
warnings.warn(f"Can not set pump state of pump {pump_id} because a pump pattern exists")
|
|
186
|
+
else:
|
|
187
|
+
self._scenario_sim.epanet_api.setLinkStatus(pump_link_idx, status)
|
|
183
188
|
|
|
184
189
|
def set_pump_speed(self, pump_id: str, speed: float) -> None:
|
|
185
190
|
"""
|
epyt_flow/metrics.py
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
"""
|
|
2
2
|
This module provides different metrics for evaluation.
|
|
3
3
|
"""
|
|
4
|
+
import warnings
|
|
4
5
|
import numpy as np
|
|
5
6
|
from sklearn.metrics import roc_auc_score as skelarn_roc_auc_score, f1_score as skelarn_f1_scpre, \
|
|
6
7
|
mean_absolute_error, root_mean_squared_error, r2_score as sklearn_r2_score
|
|
7
8
|
|
|
8
9
|
|
|
10
|
+
warnings.warn("'epyt_flow.metrics' is deprecated in favor of EPyT-Control " +
|
|
11
|
+
"and will be removed in future releases.")
|
|
12
|
+
|
|
13
|
+
|
|
9
14
|
def r2_score(y_pred: np.ndarray, y: np.ndarray) -> float:
|
|
10
15
|
"""
|
|
11
16
|
Computes the R^2 score (also called the coefficient of determination).
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Module provides a base class for event detectors.
|
|
3
3
|
"""
|
|
4
|
+
import warnings
|
|
4
5
|
from abc import abstractmethod, ABC
|
|
5
6
|
|
|
6
7
|
from ..simulation.scada import ScadaData
|
|
7
8
|
|
|
8
9
|
|
|
10
|
+
warnings.warn("'epyt_flow.models' is deprecated in favor of EPyT-Control " +
|
|
11
|
+
"and will be removed in future releases.")
|
|
12
|
+
|
|
13
|
+
|
|
9
14
|
class EventDetector(ABC):
|
|
10
15
|
"""
|
|
11
16
|
Base class for event detectors.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Module provides a simple residual-based event detector that performs sensor interpolation.
|
|
3
3
|
"""
|
|
4
|
+
import warnings
|
|
4
5
|
from typing import Any, Union
|
|
5
6
|
from copy import deepcopy
|
|
6
7
|
import numpy as np
|
|
@@ -10,6 +11,10 @@ from .event_detector import EventDetector
|
|
|
10
11
|
from ..simulation.scada import ScadaData
|
|
11
12
|
|
|
12
13
|
|
|
14
|
+
warnings.warn("'epyt_flow.models' is deprecated in favor of EPyT-Control " +
|
|
15
|
+
"and will be removed in future releases.")
|
|
16
|
+
|
|
17
|
+
|
|
13
18
|
class SensorInterpolationDetector(EventDetector):
|
|
14
19
|
"""
|
|
15
20
|
Class implementing a residual-based event detector based on sensor interpolation.
|
epyt_flow/serialization.py
CHANGED
epyt_flow/simulation/__init__.py
CHANGED
|
@@ -134,7 +134,13 @@ class PumpStateEvent(PumpEvent, JsonSerializable):
|
|
|
134
134
|
def apply(self, cur_time: int) -> None:
|
|
135
135
|
pump_idx = self._epanet_api.getLinkPumpNameID().index(self.pump_id) + 1
|
|
136
136
|
pump_link_idx = self._epanet_api.getLinkPumpIndex(pump_idx)
|
|
137
|
-
|
|
137
|
+
|
|
138
|
+
pattern_idx = self._epanet_api.getLinkPumpPatternIndex(pump_idx)
|
|
139
|
+
if pattern_idx != 0:
|
|
140
|
+
warnings.warn(f"Can not set pump state of pump {self.pump_id} " +
|
|
141
|
+
"because a pump pattern exists")
|
|
142
|
+
else:
|
|
143
|
+
self._epanet_api.setLinkStatus(pump_link_idx, self.__pump_state)
|
|
138
144
|
|
|
139
145
|
|
|
140
146
|
@serializable(PUMP_SPEED_EVENT_ID, ".epytflow_pump_speed_event")
|