epyt-flow 0.5.0__py3-none-any.whl → 0.7.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/benchmarks/battledim.py +6 -2
- epyt_flow/data/benchmarks/leakdb.py +11 -9
- epyt_flow/data/networks.py +1 -2
- epyt_flow/gym/scenario_control_env.py +101 -6
- epyt_flow/metrics.py +66 -4
- epyt_flow/serialization.py +46 -3
- epyt_flow/simulation/scada/advanced_control.py +1 -1
- epyt_flow/simulation/scada/scada_data.py +160 -62
- epyt_flow/simulation/scenario_config.py +6 -2
- epyt_flow/simulation/scenario_simulator.py +362 -65
- epyt_flow/simulation/sensor_config.py +186 -15
- epyt_flow/topology.py +93 -5
- epyt_flow/uncertainty/uncertainties.py +8 -0
- epyt_flow/utils.py +69 -2
- {epyt_flow-0.5.0.dist-info → epyt_flow-0.7.0.dist-info}/METADATA +49 -6
- {epyt_flow-0.5.0.dist-info → epyt_flow-0.7.0.dist-info}/RECORD +20 -20
- {epyt_flow-0.5.0.dist-info → epyt_flow-0.7.0.dist-info}/WHEEL +1 -1
- {epyt_flow-0.5.0.dist-info → epyt_flow-0.7.0.dist-info}/LICENSE +0 -0
- {epyt_flow-0.5.0.dist-info → epyt_flow-0.7.0.dist-info}/top_level.txt +0 -0
|
@@ -12,6 +12,7 @@ from ..sensor_config import SensorConfig, is_flowunit_simetric, massunit_to_str,
|
|
|
12
12
|
AREA_UNIT_CM2, AREA_UNIT_FT2, AREA_UNIT_M2, \
|
|
13
13
|
SENSOR_TYPE_LINK_FLOW, SENSOR_TYPE_LINK_QUALITY, SENSOR_TYPE_NODE_DEMAND, \
|
|
14
14
|
SENSOR_TYPE_NODE_PRESSURE, SENSOR_TYPE_NODE_QUALITY, SENSOR_TYPE_PUMP_STATE, \
|
|
15
|
+
SENSOR_TYPE_PUMP_EFFICIENCY, SENSOR_TYPE_PUMP_ENERGYCONSUMPTION, \
|
|
15
16
|
SENSOR_TYPE_TANK_VOLUME, SENSOR_TYPE_VALVE_STATE, SENSOR_TYPE_NODE_BULK_SPECIES, \
|
|
16
17
|
SENSOR_TYPE_LINK_BULK_SPECIES, SENSOR_TYPE_SURFACE_SPECIES
|
|
17
18
|
from ..events import SensorFault, SensorReadingAttack, SensorReadingEvent
|
|
@@ -92,11 +93,11 @@ class ScadaData(Serializable):
|
|
|
92
93
|
third dimension denotes species concentrations at nodes.
|
|
93
94
|
|
|
94
95
|
The default is None.
|
|
95
|
-
|
|
96
|
+
pumps_energy_usage_data_raw : `numpy.ndarray`, optional
|
|
96
97
|
Energy usage data of each pump.
|
|
97
98
|
|
|
98
99
|
The default is None.
|
|
99
|
-
|
|
100
|
+
pumps_efficiency_data_raw : `numpy.ndarray`, optional
|
|
100
101
|
Pump efficiency data of each pump.
|
|
101
102
|
|
|
102
103
|
The default is None.
|
|
@@ -130,8 +131,10 @@ class ScadaData(Serializable):
|
|
|
130
131
|
surface_species_concentration_raw: np.ndarray = None,
|
|
131
132
|
bulk_species_node_concentration_raw: np.ndarray = None,
|
|
132
133
|
bulk_species_link_concentration_raw: np.ndarray = None,
|
|
133
|
-
pump_energy_usage_data
|
|
134
|
-
pump_efficiency_data
|
|
134
|
+
pump_energy_usage_data = None,
|
|
135
|
+
pump_efficiency_data = None,
|
|
136
|
+
pumps_energy_usage_data_raw: np.ndarray = None,
|
|
137
|
+
pumps_efficiency_data_raw: np.ndarray = None,
|
|
135
138
|
sensor_faults: list[SensorFault] = [],
|
|
136
139
|
sensor_reading_attacks: list[SensorReadingAttack] = [],
|
|
137
140
|
sensor_reading_events: list[SensorReadingEvent] = [],
|
|
@@ -195,14 +198,14 @@ class ScadaData(Serializable):
|
|
|
195
198
|
raise TypeError("'bulk_species_link_concentration_raw' must be an instance of " +
|
|
196
199
|
"'numpy.ndarray' but not of " +
|
|
197
200
|
f"'{type(bulk_species_link_concentration_raw)}'")
|
|
198
|
-
if
|
|
199
|
-
if not isinstance(
|
|
200
|
-
raise TypeError("'
|
|
201
|
-
f"but not of '{type(
|
|
202
|
-
if
|
|
203
|
-
if not isinstance(
|
|
204
|
-
raise TypeError("'
|
|
205
|
-
f"but not of '{type(
|
|
201
|
+
if pumps_energy_usage_data_raw is not None:
|
|
202
|
+
if not isinstance(pumps_energy_usage_data_raw, np.ndarray):
|
|
203
|
+
raise TypeError("'pumps_energy_usage_data_raw' must be an instance of 'numpy.ndarray' " +
|
|
204
|
+
f"but not of '{type(pumps_energy_usage_data_raw)}'")
|
|
205
|
+
if pumps_efficiency_data_raw is not None:
|
|
206
|
+
if not isinstance(pumps_efficiency_data_raw, np.ndarray):
|
|
207
|
+
raise TypeError("'pumps_efficiency_data_raw' must be an instance of 'numpy.ndarray' " +
|
|
208
|
+
f"but not of '{type(pumps_efficiency_data_raw)}'")
|
|
206
209
|
if len(sensor_faults) != 0:
|
|
207
210
|
if any(not isinstance(f, SensorFault) for f in sensor_faults):
|
|
208
211
|
raise TypeError("'sensor_faults' must be a list of " +
|
|
@@ -223,6 +226,11 @@ class ScadaData(Serializable):
|
|
|
223
226
|
raise TypeError("'frozen_sensor_config' must be an instance of 'bool' " +
|
|
224
227
|
f"but not of '{type(frozen_sensor_config)}'")
|
|
225
228
|
|
|
229
|
+
if pump_efficiency_data is not None or pump_energy_usage_data is not None:
|
|
230
|
+
warnings.warn("Loading a file that was created with an outdated version of EPyT-Flow" +
|
|
231
|
+
" -- support of such old files will be removed in the next release!",
|
|
232
|
+
DeprecationWarning)
|
|
233
|
+
|
|
226
234
|
def __raise_shape_mismatch(var_name: str) -> None:
|
|
227
235
|
raise ValueError(f"Shape mismatch in '{var_name}' -- " +
|
|
228
236
|
"i.e number of time steps in 'sensor_readings_time' " +
|
|
@@ -271,12 +279,12 @@ class ScadaData(Serializable):
|
|
|
271
279
|
if surface_species_concentration_raw is not None:
|
|
272
280
|
if surface_species_concentration_raw.shape[0] != n_time_steps:
|
|
273
281
|
__raise_shape_mismatch("surface_species_concentration_raw")
|
|
274
|
-
if
|
|
275
|
-
if
|
|
276
|
-
__raise_shape_mismatch("
|
|
277
|
-
if
|
|
278
|
-
if
|
|
279
|
-
__raise_shape_mismatch("
|
|
282
|
+
if pumps_energy_usage_data_raw is not None:
|
|
283
|
+
if pumps_energy_usage_data_raw.shape[0] != n_time_steps:
|
|
284
|
+
__raise_shape_mismatch("pumps_energy_usage_data_raw")
|
|
285
|
+
if pumps_efficiency_data_raw is not None:
|
|
286
|
+
if pumps_efficiency_data_raw.shape[0] != n_time_steps:
|
|
287
|
+
__raise_shape_mismatch("pumps_efficiency_data_raw")
|
|
280
288
|
|
|
281
289
|
self.__sensor_config = sensor_config
|
|
282
290
|
self.__sensor_noise = sensor_noise
|
|
@@ -286,8 +294,6 @@ class ScadaData(Serializable):
|
|
|
286
294
|
self.__sensor_readings = None
|
|
287
295
|
self.__frozen_sensor_config = frozen_sensor_config
|
|
288
296
|
self.__sensor_readings_time = sensor_readings_time
|
|
289
|
-
self.__pump_energy_usage_data = pump_energy_usage_data
|
|
290
|
-
self.__pump_efficiency_data = pump_efficiency_data
|
|
291
297
|
|
|
292
298
|
if self.__frozen_sensor_config is False:
|
|
293
299
|
self.__pressure_data_raw = pressure_data_raw
|
|
@@ -301,6 +307,8 @@ class ScadaData(Serializable):
|
|
|
301
307
|
self.__surface_species_concentration_raw = surface_species_concentration_raw
|
|
302
308
|
self.__bulk_species_node_concentration_raw = bulk_species_node_concentration_raw
|
|
303
309
|
self.__bulk_species_link_concentration_raw = bulk_species_link_concentration_raw
|
|
310
|
+
self.__pumps_energy_usage_data_raw = pumps_energy_usage_data_raw
|
|
311
|
+
self.__pumps_efficiency_data_raw = pumps_efficiency_data_raw
|
|
304
312
|
else:
|
|
305
313
|
sensor_config = self.__sensor_config
|
|
306
314
|
|
|
@@ -338,6 +346,14 @@ class ScadaData(Serializable):
|
|
|
338
346
|
self.__pumps_state_data_raw = __reduce_data(data=pumps_state_data_raw,
|
|
339
347
|
item_to_idx=pump_to_idx,
|
|
340
348
|
sensors=sensor_config.pump_state_sensors)
|
|
349
|
+
self.__pumps_energy_usage_data_raw = \
|
|
350
|
+
__reduce_data(data=pumps_energy_usage_data_raw,
|
|
351
|
+
item_to_idx=pump_to_idx,
|
|
352
|
+
sensors=sensor_config.pump_enegeryconsumption_sensors)
|
|
353
|
+
self.__pumps_efficiency_data_raw = \
|
|
354
|
+
__reduce_data(data=pumps_efficiency_data_raw,
|
|
355
|
+
item_to_idx=pump_to_idx,
|
|
356
|
+
sensors=sensor_config.pump_efficiency_sensors)
|
|
341
357
|
self.__valves_state_data_raw = __reduce_data(data=valves_state_data_raw,
|
|
342
358
|
item_to_idx=valve_to_idx,
|
|
343
359
|
sensors=sensor_config.valve_state_sensors)
|
|
@@ -881,6 +897,10 @@ class ScadaData(Serializable):
|
|
|
881
897
|
quality_link_sensors=self.__sensor_config.quality_link_sensors,
|
|
882
898
|
valve_state_sensors=self.__sensor_config.valve_state_sensors,
|
|
883
899
|
pump_state_sensors=self.__sensor_config.pump_state_sensors,
|
|
900
|
+
pump_efficiency_sensors=
|
|
901
|
+
self.__sensor_config.pump_efficiency_sensors,
|
|
902
|
+
pump_energyconsumption_sensors=
|
|
903
|
+
self.__sensor_config.pump_energyconsumption_sensors,
|
|
884
904
|
tank_volume_sensors=self.__sensor_config.tank_volume_sensors,
|
|
885
905
|
bulk_species_node_sensors=
|
|
886
906
|
self.__sensor_config.bulk_species_node_sensors,
|
|
@@ -906,8 +926,8 @@ class ScadaData(Serializable):
|
|
|
906
926
|
pumps_state_data_raw=self.pumps_state_data_raw,
|
|
907
927
|
valves_state_data_raw=self.valves_state_data_raw,
|
|
908
928
|
tanks_volume_data_raw=tanks_volume_data,
|
|
909
|
-
|
|
910
|
-
|
|
929
|
+
pumps_energy_usage_data_raw=self.pumps_energyconsumption_data_raw,
|
|
930
|
+
pumps_efficiency_data_raw=self.pumps_efficiency_data_raw,
|
|
911
931
|
bulk_species_node_concentration_raw=bulk_species_node_concentrations,
|
|
912
932
|
bulk_species_link_concentration_raw=bulk_species_link_concentrations,
|
|
913
933
|
surface_species_concentration_raw=surface_species_concentrations)
|
|
@@ -1154,44 +1174,28 @@ class ScadaData(Serializable):
|
|
|
1154
1174
|
return deepcopy(self.__bulk_species_link_concentration_raw)
|
|
1155
1175
|
|
|
1156
1176
|
@property
|
|
1157
|
-
def
|
|
1177
|
+
def pumps_energyconsumption_data_raw(self) -> np.ndarray:
|
|
1158
1178
|
"""
|
|
1159
|
-
Gets the energy
|
|
1160
|
-
|
|
1161
|
-
.. note::
|
|
1162
|
-
This attribute is NOT included in
|
|
1163
|
-
:func:`~epyt_flow.simulation.scada.scada_data.ScadaData.get_data` --
|
|
1164
|
-
calling this function is the only way of accessing the energy usage of each pump.
|
|
1165
|
-
|
|
1166
|
-
The odering in the returned NumPy array corresponds to the ordering
|
|
1167
|
-
of the pumps in EPANET.
|
|
1179
|
+
Gets the raw energy consumption of each pump.
|
|
1168
1180
|
|
|
1169
1181
|
Returns
|
|
1170
1182
|
-------
|
|
1171
1183
|
`numpy.ndarray`
|
|
1172
|
-
Energy
|
|
1184
|
+
Energy consumption of each pump.
|
|
1173
1185
|
"""
|
|
1174
|
-
return deepcopy(self.
|
|
1186
|
+
return deepcopy(self.__pumps_energy_usage_data_raw)
|
|
1175
1187
|
|
|
1176
1188
|
@property
|
|
1177
|
-
def
|
|
1189
|
+
def pumps_efficiency_data_raw(self) -> np.ndarray:
|
|
1178
1190
|
"""
|
|
1179
|
-
Gets the
|
|
1180
|
-
|
|
1181
|
-
.. note::
|
|
1182
|
-
This attribute is NOT included in
|
|
1183
|
-
:func:`~epyt_flow.simulation.scada.scada_data.ScadaData.get_data` --
|
|
1184
|
-
calling this function is the only way of accessing the pumps' efficiency.
|
|
1185
|
-
|
|
1186
|
-
The odering in the returned NumPy array corresponds to the ordering
|
|
1187
|
-
of the pumps in EPANET.
|
|
1191
|
+
Gets the raw efficiency of each pump.
|
|
1188
1192
|
|
|
1189
1193
|
Returns
|
|
1190
1194
|
-------
|
|
1191
1195
|
`numpy.ndarray`
|
|
1192
1196
|
Pumps' efficiency.
|
|
1193
1197
|
"""
|
|
1194
|
-
return deepcopy(self.
|
|
1198
|
+
return deepcopy(self.__pumps_efficiency_data_raw)
|
|
1195
1199
|
|
|
1196
1200
|
def __init(self):
|
|
1197
1201
|
self.__apply_sensor_noise = lambda x: x
|
|
@@ -1222,6 +1226,12 @@ class ScadaData(Serializable):
|
|
|
1222
1226
|
elif sensor_event.sensor_type == SENSOR_TYPE_PUMP_STATE:
|
|
1223
1227
|
idx = self.__sensor_config.get_index_of_reading(
|
|
1224
1228
|
pump_state_sensor=sensor_event.sensor_id)
|
|
1229
|
+
elif sensor_event.sensor_type == SENSOR_TYPE_PUMP_EFFICIENCY:
|
|
1230
|
+
idx = self.__sensor_config.get_index_of_reading(
|
|
1231
|
+
pump_efficiency_sensor=sensor_event.sensor_id)
|
|
1232
|
+
elif sensor_event.sensor_type == SENSOR_TYPE_PUMP_ENERGYCONSUMPTION:
|
|
1233
|
+
idx = self.__sensor_config.get_index_of_reading(
|
|
1234
|
+
pump_energyconsumption_sensor=sensor_event.sensor_id)
|
|
1225
1235
|
elif sensor_event.sensor_type == SENSOR_TYPE_TANK_VOLUME:
|
|
1226
1236
|
idx = self.__sensor_config.get_index_of_reading(
|
|
1227
1237
|
tank_volume_sensor=sensor_event.sensor_id)
|
|
@@ -1256,8 +1266,8 @@ class ScadaData(Serializable):
|
|
|
1256
1266
|
"surface_species_concentration_raw": self.__surface_species_concentration_raw,
|
|
1257
1267
|
"bulk_species_node_concentration_raw": self.__bulk_species_node_concentration_raw,
|
|
1258
1268
|
"bulk_species_link_concentration_raw": self.__bulk_species_link_concentration_raw,
|
|
1259
|
-
"
|
|
1260
|
-
"
|
|
1269
|
+
"pumps_energy_usage_data_raw": self.__pumps_energy_usage_data_raw,
|
|
1270
|
+
"pumps_efficiency_data_raw": self.__pumps_efficiency_data_raw}
|
|
1261
1271
|
|
|
1262
1272
|
return super().get_attributes() | attr
|
|
1263
1273
|
|
|
@@ -1286,8 +1296,9 @@ class ScadaData(Serializable):
|
|
|
1286
1296
|
other.bulk_species_node_concentration_raw) \
|
|
1287
1297
|
and np.all(self.__bulk_species_link_concentration_raw ==
|
|
1288
1298
|
other.bulk_species_link_concentration_raw) \
|
|
1289
|
-
and np.all(self.
|
|
1290
|
-
|
|
1299
|
+
and np.all(self.__pumps_energy_usage_data_raw ==
|
|
1300
|
+
other.pumps_energyconsumption_data_raw) \
|
|
1301
|
+
and np.all(self.__pumps_efficiency_data_raw == other.pumps_efficiency_data_raw)
|
|
1291
1302
|
except Exception as ex:
|
|
1292
1303
|
warnings.warn(ex.__str__())
|
|
1293
1304
|
return False
|
|
@@ -1308,8 +1319,8 @@ class ScadaData(Serializable):
|
|
|
1308
1319
|
f"surface_species_concentration_raw: {self.__surface_species_concentration_raw} " + \
|
|
1309
1320
|
f"bulk_species_node_concentration_raw: {self.__bulk_species_node_concentration_raw}" +\
|
|
1310
1321
|
f" bulk_species_link_concentration_raw: {self.__bulk_species_link_concentration_raw}" +\
|
|
1311
|
-
f"
|
|
1312
|
-
f"
|
|
1322
|
+
f" pumps_efficiency_data_raw: {self.__pumps_efficiency_data_raw} " + \
|
|
1323
|
+
f"pumps_energy_usage_data_raw: {self.__pumps_energy_usage_data_raw}"
|
|
1313
1324
|
|
|
1314
1325
|
def change_sensor_config(self, sensor_config: SensorConfig) -> None:
|
|
1315
1326
|
"""
|
|
@@ -1491,11 +1502,13 @@ class ScadaData(Serializable):
|
|
|
1491
1502
|
self.__sensor_config.surface_species_sensors = \
|
|
1492
1503
|
other.sensor_config.surface_species_sensors
|
|
1493
1504
|
|
|
1494
|
-
if self.
|
|
1495
|
-
|
|
1505
|
+
if self.__pumps_energy_usage_data_raw is None and \
|
|
1506
|
+
other.pumps_energy_usage_data_raw is not None:
|
|
1507
|
+
self.__pumps_energy_usage_data_raw = other.pumps_energy_usage_data_raw
|
|
1496
1508
|
|
|
1497
|
-
if self.
|
|
1498
|
-
|
|
1509
|
+
if self.__pumps_efficiency_data_raw is None and \
|
|
1510
|
+
other.pumps_efficiency_data_raw is not None:
|
|
1511
|
+
self.__pumps_efficiency_data_raw = other.pumps_efficiency_data_raw
|
|
1499
1512
|
|
|
1500
1513
|
self.__init()
|
|
1501
1514
|
|
|
@@ -1581,14 +1594,14 @@ class ScadaData(Serializable):
|
|
|
1581
1594
|
other.bulk_species_link_concentration_raw),
|
|
1582
1595
|
axis=0)
|
|
1583
1596
|
|
|
1584
|
-
if self.
|
|
1585
|
-
self.
|
|
1586
|
-
(self.
|
|
1597
|
+
if self.__pumps_energy_usage_data_raw is not None:
|
|
1598
|
+
self.__pumps_energy_usage_data_raw = np.concatenate(
|
|
1599
|
+
(self.__pumps_energy_usage_data_raw, other.pumps_energy_usage_data_raw),
|
|
1587
1600
|
axis=0)
|
|
1588
1601
|
|
|
1589
|
-
if self.
|
|
1590
|
-
self.
|
|
1591
|
-
(self.
|
|
1602
|
+
if self.__pumps_efficiency_data_raw is not None:
|
|
1603
|
+
self.__pumps_efficiency_data_raw = np.concatenate(
|
|
1604
|
+
(self.__pumps_efficiency_data_raw, other.pumps_efficiency_data_raw),
|
|
1592
1605
|
axis=0)
|
|
1593
1606
|
|
|
1594
1607
|
def get_data(self) -> np.ndarray:
|
|
@@ -1609,6 +1622,8 @@ class ScadaData(Serializable):
|
|
|
1609
1622
|
"nodes_quality": self.__node_quality_data_raw,
|
|
1610
1623
|
"links_quality": self.__link_quality_data_raw,
|
|
1611
1624
|
"pumps_state": self.__pumps_state_data_raw,
|
|
1625
|
+
"pumps_efficiency": self.__pumps_efficiency_data_raw,
|
|
1626
|
+
"pumps_energyconsumption": self.__pumps_energy_usage_data_raw,
|
|
1612
1627
|
"valves_state": self.__valves_state_data_raw,
|
|
1613
1628
|
"tanks_volume": self.__tanks_volume_data_raw,
|
|
1614
1629
|
"bulk_species_node_concentrations": self.__bulk_species_node_concentration_raw,
|
|
@@ -1632,6 +1647,10 @@ class ScadaData(Serializable):
|
|
|
1632
1647
|
data.append(self.__valves_state_data_raw)
|
|
1633
1648
|
if self.__pumps_state_data_raw is not None:
|
|
1634
1649
|
data.append(self.__pumps_state_data_raw)
|
|
1650
|
+
if self.__pumps_efficiency_data_raw is not None:
|
|
1651
|
+
data.append(self.__pumps_efficiency_data_raw)
|
|
1652
|
+
if self.__pumps_energy_usage_data_raw is not None:
|
|
1653
|
+
data.append(self.__pumps_energy_usage_data_raw)
|
|
1635
1654
|
if self.__tanks_volume_data_raw is not None:
|
|
1636
1655
|
data.append(self.__tanks_volume_data_raw)
|
|
1637
1656
|
if self.__surface_species_concentration_raw is not None:
|
|
@@ -1896,6 +1915,85 @@ class ScadaData(Serializable):
|
|
|
1896
1915
|
for s_id in sensor_locations]
|
|
1897
1916
|
return self.__sensor_readings[:, idx]
|
|
1898
1917
|
|
|
1918
|
+
def get_data_pumps_efficiency(self, sensor_locations: list[str] = None) -> np.ndarray:
|
|
1919
|
+
"""
|
|
1920
|
+
Gets the final pump efficiency sensor readings -- note that those might be subject to
|
|
1921
|
+
given sensor faults and sensor noise/uncertainty.
|
|
1922
|
+
|
|
1923
|
+
Parameters
|
|
1924
|
+
----------
|
|
1925
|
+
sensor_locations : `list[str]`, optional
|
|
1926
|
+
Existing pump efficiency sensor locations for which the sensor readings are requested.
|
|
1927
|
+
If None, the readings from all pump efficiency sensors are returned.
|
|
1928
|
+
|
|
1929
|
+
The default is None.
|
|
1930
|
+
|
|
1931
|
+
Returns
|
|
1932
|
+
-------
|
|
1933
|
+
`numpy.ndarray`
|
|
1934
|
+
Pump efficiency sensor readings.
|
|
1935
|
+
"""
|
|
1936
|
+
if self.__sensor_config.pump_efficiency_sensors == []:
|
|
1937
|
+
raise ValueError("No pump efficiency sensors set")
|
|
1938
|
+
if sensor_locations is not None:
|
|
1939
|
+
if not isinstance(sensor_locations, list):
|
|
1940
|
+
raise TypeError("'sensor_locations' must be an instance of 'list[str]' " +
|
|
1941
|
+
f"but not of '{type(sensor_locations)}'")
|
|
1942
|
+
if any(s_id not in self.__sensor_config.pump_efficiency_sensors
|
|
1943
|
+
for s_id in sensor_locations):
|
|
1944
|
+
raise ValueError("Invalid sensor ID in 'sensor_locations' -- note that all " +
|
|
1945
|
+
"sensors in 'sensor_locations' must be set in the current " +
|
|
1946
|
+
"pump efficiency sensor configuration")
|
|
1947
|
+
else:
|
|
1948
|
+
sensor_locations = self.__sensor_config.pump_efficiency_sensors
|
|
1949
|
+
|
|
1950
|
+
if self.__sensor_readings is None:
|
|
1951
|
+
self.get_data()
|
|
1952
|
+
|
|
1953
|
+
idx = [self.__sensor_config.get_index_of_reading(pump_efficiency_sensor=s_id)
|
|
1954
|
+
for s_id in sensor_locations]
|
|
1955
|
+
return self.__sensor_readings[:, idx]
|
|
1956
|
+
|
|
1957
|
+
def get_data_pumps_energyconsumption(self, sensor_locations: list[str] = None) -> np.ndarray:
|
|
1958
|
+
"""
|
|
1959
|
+
Gets the final pump energy consumption sensor readings -- note that those might be subject
|
|
1960
|
+
to given sensor faults and sensor noise/uncertainty.
|
|
1961
|
+
|
|
1962
|
+
Parameters
|
|
1963
|
+
----------
|
|
1964
|
+
sensor_locations : `list[str]`, optional
|
|
1965
|
+
Existing pump energy consumption sensor locations for which
|
|
1966
|
+
the sensor readings are requested.
|
|
1967
|
+
If None, the readings from all pump energy consumption sensors are returned.
|
|
1968
|
+
|
|
1969
|
+
The default is None.
|
|
1970
|
+
|
|
1971
|
+
Returns
|
|
1972
|
+
-------
|
|
1973
|
+
`numpy.ndarray`
|
|
1974
|
+
Pump energy consumption sensor readings.
|
|
1975
|
+
"""
|
|
1976
|
+
if self.__sensor_config.pump_energyconsumption_sensors == []:
|
|
1977
|
+
raise ValueError("No pump energy consumption sensors set")
|
|
1978
|
+
if sensor_locations is not None:
|
|
1979
|
+
if not isinstance(sensor_locations, list):
|
|
1980
|
+
raise TypeError("'sensor_locations' must be an instance of 'list[str]' " +
|
|
1981
|
+
f"but not of '{type(sensor_locations)}'")
|
|
1982
|
+
if any(s_id not in self.__sensor_config.pump_energyconsumption_sensors
|
|
1983
|
+
for s_id in sensor_locations):
|
|
1984
|
+
raise ValueError("Invalid sensor ID in 'sensor_locations' -- note that all " +
|
|
1985
|
+
"sensors in 'sensor_locations' must be set in the current " +
|
|
1986
|
+
"pump efficiency sensor configuration")
|
|
1987
|
+
else:
|
|
1988
|
+
sensor_locations = self.__sensor_config.pump_energyconsumption_sensors
|
|
1989
|
+
|
|
1990
|
+
if self.__sensor_readings is None:
|
|
1991
|
+
self.get_data()
|
|
1992
|
+
|
|
1993
|
+
idx = [self.__sensor_config.get_index_of_reading(pump_energyconsumption_sensor=s_id)
|
|
1994
|
+
for s_id in sensor_locations]
|
|
1995
|
+
return self.__sensor_readings[:, idx]
|
|
1996
|
+
|
|
1899
1997
|
def get_data_valves_state(self, sensor_locations: list[str] = None) -> np.ndarray:
|
|
1900
1998
|
"""
|
|
1901
1999
|
Gets the final valve state sensor readings -- note that those might be subject to
|
|
@@ -2052,7 +2150,7 @@ class ScadaData(Serializable):
|
|
|
2052
2150
|
raise TypeError("'bulk_species_sensor_locations' must be an instance of 'dict'" +
|
|
2053
2151
|
f" but not of '{type(bulk_species_sensor_locations)}'")
|
|
2054
2152
|
for species_id in bulk_species_sensor_locations:
|
|
2055
|
-
if species_id not in self.__sensor_config.
|
|
2153
|
+
if species_id not in self.__sensor_config.bulk_species_node_sensors:
|
|
2056
2154
|
raise ValueError(f"Species '{species_id}' is not included in the " +
|
|
2057
2155
|
"sensor configuration")
|
|
2058
2156
|
|
|
@@ -3,6 +3,7 @@ Module provides a class for specifying scenario configurations.
|
|
|
3
3
|
"""
|
|
4
4
|
from typing import Any
|
|
5
5
|
from copy import deepcopy
|
|
6
|
+
import os
|
|
6
7
|
import json
|
|
7
8
|
import numpy as np
|
|
8
9
|
|
|
@@ -219,7 +220,7 @@ class ScenarioConfig(Serializable):
|
|
|
219
220
|
`str`
|
|
220
221
|
Path to the .inp file.
|
|
221
222
|
"""
|
|
222
|
-
return self.__f_inp_in
|
|
223
|
+
return os.path.join(self._parent_path, self.__f_inp_in)
|
|
223
224
|
|
|
224
225
|
@property
|
|
225
226
|
def f_msx_in(self) -> str:
|
|
@@ -231,7 +232,10 @@ class ScenarioConfig(Serializable):
|
|
|
231
232
|
`str`
|
|
232
233
|
Path to the .msx file.
|
|
233
234
|
"""
|
|
234
|
-
|
|
235
|
+
if self.__f_msx_in is None:
|
|
236
|
+
return None
|
|
237
|
+
else:
|
|
238
|
+
return os.path.join(self._parent_path, self.__f_msx_in)
|
|
235
239
|
|
|
236
240
|
@property
|
|
237
241
|
def general_params(self) -> dict:
|