epyt-flow 0.1.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 (131) hide show
  1. epyt_flow/EPANET/EPANET/SRC_engines/AUTHORS +28 -0
  2. epyt_flow/EPANET/EPANET/SRC_engines/LICENSE +21 -0
  3. epyt_flow/EPANET/EPANET/SRC_engines/Readme_SRC_Engines.txt +18 -0
  4. epyt_flow/EPANET/EPANET/SRC_engines/enumstxt.h +134 -0
  5. epyt_flow/EPANET/EPANET/SRC_engines/epanet.c +5578 -0
  6. epyt_flow/EPANET/EPANET/SRC_engines/epanet2.c +865 -0
  7. epyt_flow/EPANET/EPANET/SRC_engines/epanet2.def +131 -0
  8. epyt_flow/EPANET/EPANET/SRC_engines/errors.dat +73 -0
  9. epyt_flow/EPANET/EPANET/SRC_engines/funcs.h +193 -0
  10. epyt_flow/EPANET/EPANET/SRC_engines/genmmd.c +1000 -0
  11. epyt_flow/EPANET/EPANET/SRC_engines/hash.c +177 -0
  12. epyt_flow/EPANET/EPANET/SRC_engines/hash.h +28 -0
  13. epyt_flow/EPANET/EPANET/SRC_engines/hydcoeffs.c +1151 -0
  14. epyt_flow/EPANET/EPANET/SRC_engines/hydraul.c +1117 -0
  15. epyt_flow/EPANET/EPANET/SRC_engines/hydsolver.c +720 -0
  16. epyt_flow/EPANET/EPANET/SRC_engines/hydstatus.c +476 -0
  17. epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2.h +431 -0
  18. epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2_2.h +1786 -0
  19. epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2_enums.h +468 -0
  20. epyt_flow/EPANET/EPANET/SRC_engines/inpfile.c +810 -0
  21. epyt_flow/EPANET/EPANET/SRC_engines/input1.c +707 -0
  22. epyt_flow/EPANET/EPANET/SRC_engines/input2.c +864 -0
  23. epyt_flow/EPANET/EPANET/SRC_engines/input3.c +2170 -0
  24. epyt_flow/EPANET/EPANET/SRC_engines/main.c +93 -0
  25. epyt_flow/EPANET/EPANET/SRC_engines/mempool.c +142 -0
  26. epyt_flow/EPANET/EPANET/SRC_engines/mempool.h +24 -0
  27. epyt_flow/EPANET/EPANET/SRC_engines/output.c +852 -0
  28. epyt_flow/EPANET/EPANET/SRC_engines/project.c +1359 -0
  29. epyt_flow/EPANET/EPANET/SRC_engines/quality.c +685 -0
  30. epyt_flow/EPANET/EPANET/SRC_engines/qualreact.c +743 -0
  31. epyt_flow/EPANET/EPANET/SRC_engines/qualroute.c +694 -0
  32. epyt_flow/EPANET/EPANET/SRC_engines/report.c +1489 -0
  33. epyt_flow/EPANET/EPANET/SRC_engines/rules.c +1362 -0
  34. epyt_flow/EPANET/EPANET/SRC_engines/smatrix.c +871 -0
  35. epyt_flow/EPANET/EPANET/SRC_engines/text.h +497 -0
  36. epyt_flow/EPANET/EPANET/SRC_engines/types.h +874 -0
  37. epyt_flow/EPANET/EPANET-MSX/MSX_Updates.txt +53 -0
  38. epyt_flow/EPANET/EPANET-MSX/Src/dispersion.h +27 -0
  39. epyt_flow/EPANET/EPANET-MSX/Src/hash.c +107 -0
  40. epyt_flow/EPANET/EPANET-MSX/Src/hash.h +28 -0
  41. epyt_flow/EPANET/EPANET-MSX/Src/include/epanetmsx.h +102 -0
  42. epyt_flow/EPANET/EPANET-MSX/Src/include/epanetmsx_export.h +42 -0
  43. epyt_flow/EPANET/EPANET-MSX/Src/mathexpr.c +937 -0
  44. epyt_flow/EPANET/EPANET-MSX/Src/mathexpr.h +39 -0
  45. epyt_flow/EPANET/EPANET-MSX/Src/mempool.c +204 -0
  46. epyt_flow/EPANET/EPANET-MSX/Src/mempool.h +24 -0
  47. epyt_flow/EPANET/EPANET-MSX/Src/msxchem.c +1285 -0
  48. epyt_flow/EPANET/EPANET-MSX/Src/msxcompiler.c +368 -0
  49. epyt_flow/EPANET/EPANET-MSX/Src/msxdict.h +42 -0
  50. epyt_flow/EPANET/EPANET-MSX/Src/msxdispersion.c +586 -0
  51. epyt_flow/EPANET/EPANET-MSX/Src/msxerr.c +116 -0
  52. epyt_flow/EPANET/EPANET-MSX/Src/msxfile.c +260 -0
  53. epyt_flow/EPANET/EPANET-MSX/Src/msxfuncs.c +175 -0
  54. epyt_flow/EPANET/EPANET-MSX/Src/msxfuncs.h +35 -0
  55. epyt_flow/EPANET/EPANET-MSX/Src/msxinp.c +1504 -0
  56. epyt_flow/EPANET/EPANET-MSX/Src/msxout.c +401 -0
  57. epyt_flow/EPANET/EPANET-MSX/Src/msxproj.c +791 -0
  58. epyt_flow/EPANET/EPANET-MSX/Src/msxqual.c +2010 -0
  59. epyt_flow/EPANET/EPANET-MSX/Src/msxrpt.c +400 -0
  60. epyt_flow/EPANET/EPANET-MSX/Src/msxtank.c +422 -0
  61. epyt_flow/EPANET/EPANET-MSX/Src/msxtoolkit.c +1164 -0
  62. epyt_flow/EPANET/EPANET-MSX/Src/msxtypes.h +551 -0
  63. epyt_flow/EPANET/EPANET-MSX/Src/msxutils.c +524 -0
  64. epyt_flow/EPANET/EPANET-MSX/Src/msxutils.h +56 -0
  65. epyt_flow/EPANET/EPANET-MSX/Src/newton.c +158 -0
  66. epyt_flow/EPANET/EPANET-MSX/Src/newton.h +34 -0
  67. epyt_flow/EPANET/EPANET-MSX/Src/rk5.c +287 -0
  68. epyt_flow/EPANET/EPANET-MSX/Src/rk5.h +39 -0
  69. epyt_flow/EPANET/EPANET-MSX/Src/ros2.c +293 -0
  70. epyt_flow/EPANET/EPANET-MSX/Src/ros2.h +35 -0
  71. epyt_flow/EPANET/EPANET-MSX/Src/smatrix.c +816 -0
  72. epyt_flow/EPANET/EPANET-MSX/Src/smatrix.h +29 -0
  73. epyt_flow/EPANET/EPANET-MSX/readme.txt +14 -0
  74. epyt_flow/EPANET/compile.sh +4 -0
  75. epyt_flow/VERSION +1 -0
  76. epyt_flow/__init__.py +24 -0
  77. epyt_flow/data/__init__.py +0 -0
  78. epyt_flow/data/benchmarks/__init__.py +11 -0
  79. epyt_flow/data/benchmarks/batadal.py +257 -0
  80. epyt_flow/data/benchmarks/batadal_data.py +28 -0
  81. epyt_flow/data/benchmarks/battledim.py +473 -0
  82. epyt_flow/data/benchmarks/battledim_data.py +51 -0
  83. epyt_flow/data/benchmarks/gecco_water_quality.py +267 -0
  84. epyt_flow/data/benchmarks/leakdb.py +592 -0
  85. epyt_flow/data/benchmarks/leakdb_data.py +18923 -0
  86. epyt_flow/data/benchmarks/water_usage.py +123 -0
  87. epyt_flow/data/networks.py +650 -0
  88. epyt_flow/gym/__init__.py +4 -0
  89. epyt_flow/gym/control_gyms.py +47 -0
  90. epyt_flow/gym/scenario_control_env.py +101 -0
  91. epyt_flow/metrics.py +404 -0
  92. epyt_flow/models/__init__.py +2 -0
  93. epyt_flow/models/event_detector.py +31 -0
  94. epyt_flow/models/sensor_interpolation_detector.py +118 -0
  95. epyt_flow/rest_api/__init__.py +4 -0
  96. epyt_flow/rest_api/base_handler.py +70 -0
  97. epyt_flow/rest_api/res_manager.py +95 -0
  98. epyt_flow/rest_api/scada_data_handler.py +476 -0
  99. epyt_flow/rest_api/scenario_handler.py +352 -0
  100. epyt_flow/rest_api/server.py +106 -0
  101. epyt_flow/serialization.py +438 -0
  102. epyt_flow/simulation/__init__.py +5 -0
  103. epyt_flow/simulation/events/__init__.py +6 -0
  104. epyt_flow/simulation/events/actuator_events.py +259 -0
  105. epyt_flow/simulation/events/event.py +81 -0
  106. epyt_flow/simulation/events/leakages.py +404 -0
  107. epyt_flow/simulation/events/sensor_faults.py +267 -0
  108. epyt_flow/simulation/events/sensor_reading_attack.py +185 -0
  109. epyt_flow/simulation/events/sensor_reading_event.py +170 -0
  110. epyt_flow/simulation/events/system_event.py +88 -0
  111. epyt_flow/simulation/parallel_simulation.py +147 -0
  112. epyt_flow/simulation/scada/__init__.py +3 -0
  113. epyt_flow/simulation/scada/advanced_control.py +134 -0
  114. epyt_flow/simulation/scada/scada_data.py +1589 -0
  115. epyt_flow/simulation/scada/scada_data_export.py +255 -0
  116. epyt_flow/simulation/scenario_config.py +608 -0
  117. epyt_flow/simulation/scenario_simulator.py +1897 -0
  118. epyt_flow/simulation/scenario_visualizer.py +61 -0
  119. epyt_flow/simulation/sensor_config.py +1289 -0
  120. epyt_flow/topology.py +290 -0
  121. epyt_flow/uncertainty/__init__.py +3 -0
  122. epyt_flow/uncertainty/model_uncertainty.py +302 -0
  123. epyt_flow/uncertainty/sensor_noise.py +73 -0
  124. epyt_flow/uncertainty/uncertainties.py +555 -0
  125. epyt_flow/uncertainty/utils.py +206 -0
  126. epyt_flow/utils.py +306 -0
  127. epyt_flow-0.1.0.dist-info/LICENSE +21 -0
  128. epyt_flow-0.1.0.dist-info/METADATA +139 -0
  129. epyt_flow-0.1.0.dist-info/RECORD +131 -0
  130. epyt_flow-0.1.0.dist-info/WHEEL +5 -0
  131. epyt_flow-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,255 @@
1
+ """
2
+ Module provides classes for exporting SCADA data stored in
3
+ :class:`~epyt_flow.simulation.scada.scada_data.ScadaData`.
4
+ """
5
+ from abc import abstractmethod
6
+ import numpy as np
7
+ from scipy.io import savemat
8
+ import pandas as pd
9
+
10
+ from .scada_data import ScadaData
11
+ from ..sensor_config import SensorConfig
12
+
13
+
14
+ class ScadaDataExport():
15
+ """
16
+ Base class for exporting SCADA data stored in
17
+ :class:`~epyt_flow.simulation.scada.scada_data.ScadaData`.
18
+
19
+ Parameters
20
+ ----------
21
+ f_out : `str`
22
+ Path to the file to which the SCADA data will be exported.
23
+ export_raw_data : `bool`, optional
24
+ If True, the raw measurements (i.e. sensor reading without any noise or faults)
25
+ are exported instead of the final sensor readings.
26
+
27
+ The default is False.
28
+ """
29
+
30
+ def __init__(self, f_out: str, export_raw_data: bool = False, **kwds):
31
+ self.__f_out = f_out
32
+ self.__export_raw_data = export_raw_data
33
+
34
+ super().__init__(**kwds)
35
+
36
+ @property
37
+ def f_out(self) -> str:
38
+ """
39
+ Gets the path to the file to which the SCADA data will be exported.
40
+
41
+ Returns
42
+ -------
43
+ `str`
44
+ Path to the file to which the SCADA data will be exported.
45
+ """
46
+ return self.__f_out
47
+
48
+ @property
49
+ def export_raw_data(self) -> bool:
50
+ """
51
+ True if the raw measurements instead of the final sensor readings are requested.
52
+
53
+ Returns
54
+ -------
55
+ `bool`
56
+ True if the raw measurements instead of the final sensor readings are requested.
57
+ """
58
+ return self.__export_raw_data
59
+
60
+ def create_global_sensor_config(self, scada_data: ScadaData) -> SensorConfig:
61
+ """
62
+ Creates a global sensor configuration with sensors placed everywhere.
63
+
64
+ Parameters
65
+ ----------
66
+ scada_data : :class:`~epyt_flow.simulation.scada.scada_data.ScadaData`
67
+ SCADA data for which the global sensor configuration is to be created.
68
+
69
+ Returns
70
+ -------
71
+ :class:`~epyt_flow.simulation.sensor_config.SensorConfig`
72
+ Global sensor configuration.
73
+ """
74
+ old_sensor_config = scada_data.sensor_config
75
+
76
+ sensor_config = SensorConfig(nodes=old_sensor_config.nodes,
77
+ links=old_sensor_config.links,
78
+ valves=old_sensor_config.valves,
79
+ pumps=old_sensor_config.pumps,
80
+ tanks=old_sensor_config.tanks,
81
+ bulk_species=old_sensor_config.bulk_species,
82
+ surface_species=old_sensor_config.surface_species)
83
+ sensor_config.pressure_sensors = sensor_config.nodes
84
+ sensor_config.flow_sensors = sensor_config.links
85
+ sensor_config.demand_sensors = sensor_config.nodes
86
+ sensor_config.quality_node_sensors = sensor_config.nodes
87
+ sensor_config.quality_link_sensors = sensor_config.links
88
+ sensor_config.valve_state_sensors = sensor_config.valves
89
+ sensor_config.tank_level_sensors = sensor_config.tanks
90
+ sensor_config.pump_state_sensors = sensor_config.pumps
91
+ sensor_config.bulk_species_node_sensors = sensor_config.bulk_species_node_sensors
92
+ sensor_config.bulk_species_link_sensors = sensor_config.bulk_species_link_sensors
93
+ sensor_config.surface_species_sensors = sensor_config.surface_species_sensors
94
+
95
+ return sensor_config
96
+
97
+ def create_column_desc(self, scada_data: ScadaData) -> np.ndarray:
98
+ """
99
+ Creates column descriptions -- i.e. sensor type and location for each column
100
+
101
+ Parameters
102
+ ----------
103
+ scada_data : :class:`~epyt_flow.simulation.scada.scada_data.ScadaData`
104
+ SCADA data to be described.
105
+
106
+ Returns
107
+ -------
108
+ `numpy.ndarray`
109
+ 2-dimensional array describing all columns of the sensor readings:
110
+ The first dimension describes the sensor type, and the second dimension
111
+ describes the sensor location.
112
+ """
113
+ sensor_readings = scada_data.get_data()
114
+
115
+ col_desc = [None for _ in range(sensor_readings.shape[1])]
116
+ sensor_config = scada_data.sensor_config
117
+ sensors_id_to_idx = sensor_config.sensors_id_to_idx
118
+ for sensor_type in sensors_id_to_idx:
119
+ for item_id in sensors_id_to_idx[sensor_type]:
120
+ col_id = sensors_id_to_idx[sensor_type][item_id]
121
+ col_desc[col_id] = [sensor_type, item_id]
122
+
123
+ return np.array(col_desc, dtype=object)
124
+
125
+ @abstractmethod
126
+ def export(self, scada_data: ScadaData) -> None:
127
+ """
128
+ Exports given SCADA data.
129
+
130
+ Parameters
131
+ ----------
132
+ scada_data : :class:`~epyt_flow.simulation.scada.scada_data.ScadaData`
133
+ SCADA data to be exported.
134
+ """
135
+ raise NotImplementedError()
136
+
137
+
138
+ class ScadaDataNumpyExport(ScadaDataExport):
139
+ """
140
+ Class for exporting SCADA data to numpy (.npz file).
141
+ """
142
+
143
+ def export(self, scada_data: ScadaData) -> None:
144
+ """
145
+ Exports given SCADA data.
146
+
147
+ Parameters
148
+ ----------
149
+ scada_data : :class:`~epyt_flow.simulation.scada.scada_data.ScadaData`
150
+ SCADA data to be exported.
151
+ """
152
+ if not isinstance(scada_data, ScadaData):
153
+ raise TypeError("'scada_data' must be an instance of " +
154
+ "'epyt_flow.simulation.scada_data.ScadaData' and not of " +
155
+ f"'{type(scada_data)}'")
156
+
157
+ old_sensor_config = None
158
+ if self.export_raw_data is True:
159
+ # Backup old sensor config and set a new one with sensors everywhere
160
+ old_sensor_config = scada_data.sensor_config
161
+ scada_data.change_sensor_config(self.create_global_sensor_config(scada_data))
162
+
163
+ sensor_readings = scada_data.get_data()
164
+ col_desc = self.create_column_desc(scada_data)
165
+ sensor_readings_time = scada_data.sensor_readings_time
166
+
167
+ if self.export_raw_data is True:
168
+ # Restore old sensor config
169
+ scada_data.change_sensor_config(old_sensor_config)
170
+
171
+ np.savez(self.f_out, sensor_readings=sensor_readings, col_desc=col_desc,
172
+ sensor_readings_time=sensor_readings_time)
173
+
174
+
175
+ class ScadaDataXlsxExport(ScadaDataExport):
176
+ """
177
+ Class for exporting SCADA data to Excel (.xlsx file).
178
+ """
179
+
180
+ def export(self, scada_data: ScadaData) -> None:
181
+ """
182
+ Exports given SCADA data.
183
+
184
+ Parameters
185
+ ----------
186
+ scada_data : :class:`~epyt_flow.simulation.scada.scada_data.ScadaData`
187
+ SCADA data to be exported.
188
+ """
189
+ if not isinstance(scada_data, ScadaData):
190
+ raise TypeError("'scada_data' must be an instance of " +
191
+ "'epyt_flow.simulation.scada_data.ScadaData' and not of " +
192
+ f"'{type(scada_data)}'")
193
+
194
+ old_sensor_config = None
195
+ if self.export_raw_data is True:
196
+ # Backup old sensor config and set a new one with sensors everywhere
197
+ old_sensor_config = scada_data.sensor_config
198
+ scada_data.change_sensor_config(self.create_global_sensor_config(scada_data))
199
+
200
+ sensor_readings = scada_data.get_data()
201
+ sensor_readings_time = scada_data.sensor_readings_time
202
+ col_desc = self.create_column_desc(scada_data)
203
+ sensors_name = np.array([f"Sensor {i}" for i in range(1, sensor_readings.shape[1] + 1)],
204
+ dtype=object).reshape(-1, 1)
205
+ col_desc = np.concatenate((sensors_name, col_desc), axis=1)
206
+
207
+ if self.export_raw_data is True:
208
+ # Restore old sensor config
209
+ scada_data.change_sensor_config(old_sensor_config)
210
+
211
+ with pd.ExcelWriter(self.f_out) as writer:
212
+ pd.DataFrame(sensor_readings, columns=[f"Sensor {i}" for i in
213
+ range(1, sensor_readings.shape[1] + 1)]). \
214
+ to_excel(writer, sheet_name="Sensor readings", index=False)
215
+ pd.DataFrame(sensor_readings_time, columns=["Time (s)"]). \
216
+ to_excel(writer, sheet_name="Sensor readings time", index=False)
217
+ pd.DataFrame(col_desc, columns=["Name", "Type", "Location"]). \
218
+ to_excel(writer, sheet_name="Sensors description", index=False)
219
+
220
+
221
+ class ScadaDataMatlabExport(ScadaDataExport):
222
+ """
223
+ Class for exporting SCADA data to MATLAB (.mat file).
224
+ """
225
+
226
+ def export(self, scada_data: ScadaData) -> None:
227
+ """
228
+ Exports given SCADA data.
229
+
230
+ Parameters
231
+ ----------
232
+ scada_data : :class:`~epyt_flow.simulation.scada.scada_data.ScadaData`
233
+ SCADA data to be exported.
234
+ """
235
+ if not isinstance(scada_data, ScadaData):
236
+ raise TypeError("'scada_data' must be an instance of " +
237
+ "'epyt_flow.simulation.scada_data.ScadaData' and not of " +
238
+ f"'{type(scada_data)}'")
239
+
240
+ old_sensor_config = None
241
+ if self.export_raw_data is True:
242
+ # Backup old sensor config and set a new one with sensors everywhere
243
+ old_sensor_config = scada_data.sensor_config
244
+ scada_data.change_sensor_config(self.create_global_sensor_config(scada_data))
245
+
246
+ sensor_readings = scada_data.get_data()
247
+ sensor_readings_time = scada_data.sensor_readings_time
248
+ col_desc = self.create_column_desc(scada_data)
249
+
250
+ if self.export_raw_data is True:
251
+ # Restore old sensor config
252
+ scada_data.change_sensor_config(old_sensor_config)
253
+
254
+ savemat(self.f_out, {"sensor_readings": sensor_readings,
255
+ "sensor_readings_time": sensor_readings_time, "col_desc": col_desc})