floodmodeller-api 0.4.2__py3-none-any.whl → 0.4.3__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.
- floodmodeller_api/__init__.py +8 -9
- floodmodeller_api/_base.py +184 -176
- floodmodeller_api/backup.py +273 -273
- floodmodeller_api/dat.py +909 -838
- floodmodeller_api/diff.py +136 -119
- floodmodeller_api/ied.py +307 -311
- floodmodeller_api/ief.py +647 -646
- floodmodeller_api/ief_flags.py +253 -253
- floodmodeller_api/inp.py +266 -268
- floodmodeller_api/libs/libifcoremd.dll +0 -0
- floodmodeller_api/libs/libifcoremt.so.5 +0 -0
- floodmodeller_api/libs/libifport.so.5 +0 -0
- floodmodeller_api/{libmmd.dll → libs/libimf.so} +0 -0
- floodmodeller_api/libs/libintlc.so.5 +0 -0
- floodmodeller_api/libs/libmmd.dll +0 -0
- floodmodeller_api/libs/libsvml.so +0 -0
- floodmodeller_api/libs/libzzn_read.so +0 -0
- floodmodeller_api/libs/zzn_read.dll +0 -0
- floodmodeller_api/logs/__init__.py +2 -2
- floodmodeller_api/logs/lf.py +320 -314
- floodmodeller_api/logs/lf_helpers.py +354 -346
- floodmodeller_api/logs/lf_params.py +643 -529
- floodmodeller_api/mapping.py +84 -0
- floodmodeller_api/test/__init__.py +4 -4
- floodmodeller_api/test/conftest.py +9 -8
- floodmodeller_api/test/test_backup.py +117 -117
- floodmodeller_api/test/test_dat.py +221 -92
- floodmodeller_api/test/test_data/All Units 4_6.DAT +1081 -1081
- floodmodeller_api/test/test_data/All Units 4_6.feb +1081 -1081
- floodmodeller_api/test/test_data/BRIDGE.DAT +926 -926
- floodmodeller_api/test/test_data/Culvert_Inlet_Outlet.dat +36 -36
- floodmodeller_api/test/test_data/Culvert_Inlet_Outlet.feb +36 -36
- floodmodeller_api/test/test_data/DamBreakADI.xml +52 -52
- floodmodeller_api/test/test_data/DamBreakFAST.xml +58 -58
- floodmodeller_api/test/test_data/DamBreakFAST_dy.xml +53 -53
- floodmodeller_api/test/test_data/DamBreakTVD.xml +55 -55
- floodmodeller_api/test/test_data/DefenceBreach.xml +53 -53
- floodmodeller_api/test/test_data/DefenceBreachFAST.xml +60 -60
- floodmodeller_api/test/test_data/DefenceBreachFAST_dy.xml +55 -55
- floodmodeller_api/test/test_data/Domain1+2_QH.xml +76 -76
- floodmodeller_api/test/test_data/Domain1_H.xml +41 -41
- floodmodeller_api/test/test_data/Domain1_Q.xml +41 -41
- floodmodeller_api/test/test_data/Domain1_Q_FAST.xml +48 -48
- floodmodeller_api/test/test_data/Domain1_Q_FAST_dy.xml +48 -48
- floodmodeller_api/test/test_data/Domain1_Q_xml_expected.json +263 -0
- floodmodeller_api/test/test_data/Domain1_W.xml +41 -41
- floodmodeller_api/test/test_data/EX1.DAT +321 -321
- floodmodeller_api/test/test_data/EX1.ext +107 -107
- floodmodeller_api/test/test_data/EX1.feb +320 -320
- floodmodeller_api/test/test_data/EX1.gxy +107 -107
- floodmodeller_api/test/test_data/EX17.DAT +421 -422
- floodmodeller_api/test/test_data/EX17.ext +213 -213
- floodmodeller_api/test/test_data/EX17.feb +422 -422
- floodmodeller_api/test/test_data/EX18.DAT +375 -375
- floodmodeller_api/test/test_data/EX18_DAT_expected.json +3876 -0
- floodmodeller_api/test/test_data/EX2.DAT +302 -302
- floodmodeller_api/test/test_data/EX3.DAT +926 -926
- floodmodeller_api/test/test_data/EX3_DAT_expected.json +16235 -0
- floodmodeller_api/test/test_data/EX3_IEF_expected.json +61 -0
- floodmodeller_api/test/test_data/EX6.DAT +2084 -2084
- floodmodeller_api/test/test_data/EX6.ext +532 -532
- floodmodeller_api/test/test_data/EX6.feb +2084 -2084
- floodmodeller_api/test/test_data/EX6_DAT_expected.json +31647 -0
- floodmodeller_api/test/test_data/Event Data Example.DAT +336 -336
- floodmodeller_api/test/test_data/Event Data Example.ext +107 -107
- floodmodeller_api/test/test_data/Event Data Example.feb +336 -336
- floodmodeller_api/test/test_data/Linked1D2D.xml +52 -52
- floodmodeller_api/test/test_data/Linked1D2DFAST.xml +53 -53
- floodmodeller_api/test/test_data/Linked1D2DFAST_dy.xml +48 -48
- floodmodeller_api/test/test_data/Linked1D2D_xml_expected.json +313 -0
- floodmodeller_api/test/test_data/blockage.dat +50 -50
- floodmodeller_api/test/test_data/blockage.ext +45 -45
- floodmodeller_api/test/test_data/blockage.feb +9 -9
- floodmodeller_api/test/test_data/blockage.gxy +71 -71
- floodmodeller_api/test/test_data/defaultUnits.dat +127 -127
- floodmodeller_api/test/test_data/defaultUnits.ext +45 -45
- floodmodeller_api/test/test_data/defaultUnits.feb +9 -9
- floodmodeller_api/test/test_data/defaultUnits.fmpx +58 -58
- floodmodeller_api/test/test_data/defaultUnits.gxy +85 -85
- floodmodeller_api/test/test_data/ex3.ief +20 -20
- floodmodeller_api/test/test_data/ex3.lf1 +2800 -2800
- floodmodeller_api/test/test_data/ex4.DAT +1374 -1374
- floodmodeller_api/test/test_data/ex4_changed.DAT +1374 -1374
- floodmodeller_api/test/test_data/example1.inp +329 -329
- floodmodeller_api/test/test_data/example2.inp +158 -158
- floodmodeller_api/test/test_data/example3.inp +297 -297
- floodmodeller_api/test/test_data/example4.inp +388 -388
- floodmodeller_api/test/test_data/example5.inp +147 -147
- floodmodeller_api/test/test_data/example6.inp +154 -154
- floodmodeller_api/test/test_data/jump.dat +176 -176
- floodmodeller_api/test/test_data/network.dat +1374 -1374
- floodmodeller_api/test/test_data/network.ext +45 -45
- floodmodeller_api/test/test_data/network.exy +1 -1
- floodmodeller_api/test/test_data/network.feb +45 -45
- floodmodeller_api/test/test_data/network.ied +45 -45
- floodmodeller_api/test/test_data/network.ief +20 -20
- floodmodeller_api/test/test_data/network.inp +147 -147
- floodmodeller_api/test/test_data/network.pxy +57 -57
- floodmodeller_api/test/test_data/network.zzd +122 -122
- floodmodeller_api/test/test_data/network_dat_expected.json +21837 -0
- floodmodeller_api/test/test_data/network_from_tabularCSV.csv +87 -87
- floodmodeller_api/test/test_data/network_ied_expected.json +287 -0
- floodmodeller_api/test/test_data/rnweir.dat +9 -9
- floodmodeller_api/test/test_data/rnweir.ext +45 -45
- floodmodeller_api/test/test_data/rnweir.feb +9 -9
- floodmodeller_api/test/test_data/rnweir.gxy +45 -45
- floodmodeller_api/test/test_data/rnweir_default.dat +74 -74
- floodmodeller_api/test/test_data/rnweir_default.ext +45 -45
- floodmodeller_api/test/test_data/rnweir_default.feb +9 -9
- floodmodeller_api/test/test_data/rnweir_default.fmpx +58 -58
- floodmodeller_api/test/test_data/rnweir_default.gxy +53 -53
- floodmodeller_api/test/test_data/unit checks.dat +16 -16
- floodmodeller_api/test/test_ied.py +29 -29
- floodmodeller_api/test/test_ief.py +125 -24
- floodmodeller_api/test/test_inp.py +47 -48
- floodmodeller_api/test/test_json.py +114 -0
- floodmodeller_api/test/test_logs_lf.py +48 -51
- floodmodeller_api/test/test_tool.py +165 -154
- floodmodeller_api/test/test_toolbox_structure_log.py +234 -239
- floodmodeller_api/test/test_xml2d.py +151 -156
- floodmodeller_api/test/test_zzn.py +36 -34
- floodmodeller_api/to_from_json.py +218 -0
- floodmodeller_api/tool.py +332 -330
- floodmodeller_api/toolbox/__init__.py +5 -5
- floodmodeller_api/toolbox/example_tool.py +45 -45
- floodmodeller_api/toolbox/model_build/__init__.py +2 -2
- floodmodeller_api/toolbox/model_build/add_siltation_definition.py +100 -94
- floodmodeller_api/toolbox/model_build/structure_log/__init__.py +1 -1
- floodmodeller_api/toolbox/model_build/structure_log/structure_log.py +287 -289
- floodmodeller_api/toolbox/model_build/structure_log_definition.py +76 -72
- floodmodeller_api/units/__init__.py +10 -10
- floodmodeller_api/units/_base.py +214 -209
- floodmodeller_api/units/boundaries.py +467 -469
- floodmodeller_api/units/comment.py +52 -55
- floodmodeller_api/units/conduits.py +382 -403
- floodmodeller_api/units/helpers.py +123 -132
- floodmodeller_api/units/iic.py +107 -101
- floodmodeller_api/units/losses.py +305 -308
- floodmodeller_api/units/sections.py +444 -445
- floodmodeller_api/units/structures.py +1690 -1684
- floodmodeller_api/units/units.py +93 -102
- floodmodeller_api/units/unsupported.py +44 -44
- floodmodeller_api/units/variables.py +87 -89
- floodmodeller_api/urban1d/__init__.py +11 -11
- floodmodeller_api/urban1d/_base.py +188 -177
- floodmodeller_api/urban1d/conduits.py +93 -85
- floodmodeller_api/urban1d/general_parameters.py +58 -58
- floodmodeller_api/urban1d/junctions.py +81 -79
- floodmodeller_api/urban1d/losses.py +81 -74
- floodmodeller_api/urban1d/outfalls.py +114 -107
- floodmodeller_api/urban1d/raingauges.py +111 -108
- floodmodeller_api/urban1d/subsections.py +92 -93
- floodmodeller_api/urban1d/xsections.py +147 -141
- floodmodeller_api/util.py +77 -21
- floodmodeller_api/validation/parameters.py +660 -660
- floodmodeller_api/validation/urban_parameters.py +388 -404
- floodmodeller_api/validation/validation.py +110 -112
- floodmodeller_api/version.py +1 -1
- floodmodeller_api/xml2d.py +688 -684
- floodmodeller_api/xml2d_template.py +37 -37
- floodmodeller_api/zzn.py +387 -365
- {floodmodeller_api-0.4.2.dist-info → floodmodeller_api-0.4.3.dist-info}/LICENSE.txt +13 -13
- {floodmodeller_api-0.4.2.dist-info → floodmodeller_api-0.4.3.dist-info}/METADATA +82 -82
- floodmodeller_api-0.4.3.dist-info/RECORD +179 -0
- {floodmodeller_api-0.4.2.dist-info → floodmodeller_api-0.4.3.dist-info}/WHEEL +1 -1
- floodmodeller_api-0.4.3.dist-info/entry_points.txt +3 -0
- floodmodeller_api/libifcoremd.dll +0 -0
- floodmodeller_api/test/test_data/EX3.bmp +0 -0
- floodmodeller_api/test/test_data/test_output.csv +0 -87
- floodmodeller_api/zzn_read.dll +0 -0
- floodmodeller_api-0.4.2.data/scripts/fmapi-add_siltation.bat +0 -2
- floodmodeller_api-0.4.2.data/scripts/fmapi-add_siltation.py +0 -3
- floodmodeller_api-0.4.2.data/scripts/fmapi-structure_log.bat +0 -2
- floodmodeller_api-0.4.2.data/scripts/fmapi-structure_log.py +0 -3
- floodmodeller_api-0.4.2.data/scripts/fmapi-toolbox.bat +0 -2
- floodmodeller_api-0.4.2.data/scripts/fmapi-toolbox.py +0 -41
- floodmodeller_api-0.4.2.dist-info/RECORD +0 -169
- {floodmodeller_api-0.4.2.dist-info → floodmodeller_api-0.4.3.dist-info}/top_level.txt +0 -0
|
@@ -1,346 +1,354 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Flood Modeller Python API
|
|
3
|
-
Copyright (C)
|
|
4
|
-
|
|
5
|
-
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
|
|
6
|
-
as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
7
|
-
|
|
8
|
-
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
|
9
|
-
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
10
|
-
|
|
11
|
-
You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.
|
|
12
|
-
|
|
13
|
-
If you have any query about this program or this License, please contact us at support@floodmodeller.com or write to the following
|
|
14
|
-
address: Jacobs UK Limited, Flood Modeller, Cottons Centre, Cottons Lane, London, SE1 2QG, United Kingdom.
|
|
15
|
-
"""
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
import
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
self.
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
return
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
"""
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
self
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
self.
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
self.
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
def
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
def
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
return
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
class FloatSplitParser(Parser):
|
|
283
|
-
"""Extra argument from superclass split: list"""
|
|
284
|
-
|
|
285
|
-
def __init__(self, *args, **kwargs):
|
|
286
|
-
self._split = kwargs.pop("split")
|
|
287
|
-
super().__init__(*args, **kwargs)
|
|
288
|
-
self._nan = float("nan")
|
|
289
|
-
|
|
290
|
-
def _process_line(self, raw: str):
|
|
291
|
-
"""Converts string to float, removing everything after split"""
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
1
|
+
"""
|
|
2
|
+
Flood Modeller Python API
|
|
3
|
+
Copyright (C) 2024 Jacobs U.K. Limited
|
|
4
|
+
|
|
5
|
+
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
|
|
6
|
+
as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
7
|
+
|
|
8
|
+
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
|
9
|
+
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
10
|
+
|
|
11
|
+
You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.
|
|
12
|
+
|
|
13
|
+
If you have any query about this program or this License, please contact us at support@floodmodeller.com or write to the following
|
|
14
|
+
address: Jacobs UK Limited, Flood Modeller, Cottons Centre, Cottons Lane, London, SE1 2QG, United Kingdom.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import datetime as dt
|
|
20
|
+
from abc import ABC, abstractmethod
|
|
21
|
+
|
|
22
|
+
import pandas as pd
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class Data(ABC):
|
|
26
|
+
def __init__(self, header: str, subheaders: list | None):
|
|
27
|
+
self.header = header
|
|
28
|
+
self.no_values = 0
|
|
29
|
+
self._subheaders = subheaders
|
|
30
|
+
|
|
31
|
+
@abstractmethod
|
|
32
|
+
def update(self):
|
|
33
|
+
pass
|
|
34
|
+
|
|
35
|
+
@abstractmethod
|
|
36
|
+
def get_value(self):
|
|
37
|
+
pass
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class LastData(Data):
|
|
41
|
+
def __init__(self, header: str, subheaders: list | None):
|
|
42
|
+
super().__init__(header, subheaders)
|
|
43
|
+
self._value = None # single value
|
|
44
|
+
|
|
45
|
+
def update(self, data):
|
|
46
|
+
self._value = data
|
|
47
|
+
self.no_values = 1
|
|
48
|
+
|
|
49
|
+
def get_value(self, index_key=None, index_df=None):
|
|
50
|
+
return self._value
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class AllData(Data):
|
|
54
|
+
def __init__(self, header: str, subheaders: list | None):
|
|
55
|
+
super().__init__(header, subheaders)
|
|
56
|
+
self._value: list[object] = []
|
|
57
|
+
|
|
58
|
+
def update(self, data):
|
|
59
|
+
self._value.append(data)
|
|
60
|
+
self.no_values += 1
|
|
61
|
+
|
|
62
|
+
def get_value(
|
|
63
|
+
self,
|
|
64
|
+
index_key: str | None = None,
|
|
65
|
+
index_df: pd.Series | None = None,
|
|
66
|
+
) -> pd.DataFrame:
|
|
67
|
+
df = pd.DataFrame(self._value)
|
|
68
|
+
|
|
69
|
+
# do nothing to empty dataframes
|
|
70
|
+
if df.empty:
|
|
71
|
+
return df
|
|
72
|
+
|
|
73
|
+
# overall header
|
|
74
|
+
if self._subheaders is None:
|
|
75
|
+
df.rename(columns={df.columns[0]: self.header}, inplace=True)
|
|
76
|
+
|
|
77
|
+
elif index_key is not None:
|
|
78
|
+
# subheaders
|
|
79
|
+
df = df.set_axis(self._subheaders, axis=1)
|
|
80
|
+
|
|
81
|
+
# remove duplicate of index
|
|
82
|
+
# sometimes it includes extra values
|
|
83
|
+
# it also has different precision
|
|
84
|
+
index_duplicate = index_key + "_duplicate"
|
|
85
|
+
if index_duplicate in df.columns:
|
|
86
|
+
try:
|
|
87
|
+
index_df = df[index_duplicate].dt.round("1s")
|
|
88
|
+
df.drop(index_duplicate, axis=1, inplace=True)
|
|
89
|
+
except AttributeError:
|
|
90
|
+
df = df.drop(columns=index_duplicate)
|
|
91
|
+
|
|
92
|
+
# there is no index because *this* is the index
|
|
93
|
+
if index_key is None:
|
|
94
|
+
return df
|
|
95
|
+
|
|
96
|
+
# made lf index the dataframe index
|
|
97
|
+
df[index_key] = index_df
|
|
98
|
+
df.dropna(inplace=True)
|
|
99
|
+
df.drop_duplicates(subset=index_key, keep="last", inplace=True)
|
|
100
|
+
df.set_index(index_key, inplace=True)
|
|
101
|
+
|
|
102
|
+
return df
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def data_factory(data_type: str, header: str, subheaders: list | None = None):
|
|
106
|
+
if data_type == "last":
|
|
107
|
+
return LastData(header, subheaders)
|
|
108
|
+
if data_type == "all":
|
|
109
|
+
return AllData(header, subheaders)
|
|
110
|
+
raise ValueError(f'Unexpected data "{data_type}"')
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class State(ABC):
|
|
114
|
+
@abstractmethod
|
|
115
|
+
def __init__(self, extracted_data):
|
|
116
|
+
pass
|
|
117
|
+
|
|
118
|
+
@abstractmethod
|
|
119
|
+
def report_progress(self):
|
|
120
|
+
pass
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
class UnsteadyState(State):
|
|
124
|
+
def __init__(self, extracted_data):
|
|
125
|
+
self._progress_data = extracted_data["progress"].data
|
|
126
|
+
|
|
127
|
+
def report_progress(self) -> float:
|
|
128
|
+
"""Returns last progress percentage"""
|
|
129
|
+
|
|
130
|
+
progress = self._progress_data.get_value()
|
|
131
|
+
|
|
132
|
+
if progress is None:
|
|
133
|
+
return 0
|
|
134
|
+
|
|
135
|
+
return progress
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class SteadyState(State):
|
|
139
|
+
def __init__(self, extracted_data):
|
|
140
|
+
pass
|
|
141
|
+
|
|
142
|
+
def report_progress(self):
|
|
143
|
+
raise NotImplementedError("No progress reporting for steady simulations")
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def state_factory(steady: bool, extracted_data: Data) -> State:
|
|
147
|
+
if steady is True:
|
|
148
|
+
return SteadyState(extracted_data)
|
|
149
|
+
return UnsteadyState(extracted_data)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
class Parser(ABC):
|
|
153
|
+
"""Abstract base class for processing and storing different types of line
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
name
|
|
157
|
+
prefix
|
|
158
|
+
data_type
|
|
159
|
+
exclude
|
|
160
|
+
is_index
|
|
161
|
+
before_index
|
|
162
|
+
"""
|
|
163
|
+
|
|
164
|
+
_nan: object
|
|
165
|
+
|
|
166
|
+
def __init__( # noqa: PLR0913
|
|
167
|
+
self,
|
|
168
|
+
name: str,
|
|
169
|
+
prefix: str,
|
|
170
|
+
data_type: str,
|
|
171
|
+
exclude: str | None = None,
|
|
172
|
+
is_index: bool | None = False,
|
|
173
|
+
before_index: bool | None = False,
|
|
174
|
+
):
|
|
175
|
+
self._name = name
|
|
176
|
+
|
|
177
|
+
self.prefix = prefix
|
|
178
|
+
self.is_index = is_index
|
|
179
|
+
self.before_index = before_index
|
|
180
|
+
|
|
181
|
+
self._exclude = exclude
|
|
182
|
+
|
|
183
|
+
self.no_values = 0
|
|
184
|
+
|
|
185
|
+
self.data_type = data_type
|
|
186
|
+
self.data = data_factory(data_type, name)
|
|
187
|
+
|
|
188
|
+
def process_line(self, raw_line: str) -> None:
|
|
189
|
+
"""self._process_line with exception handling of expected nan values"""
|
|
190
|
+
|
|
191
|
+
try:
|
|
192
|
+
processed_line = self._process_line(raw_line)
|
|
193
|
+
|
|
194
|
+
except ValueError as e:
|
|
195
|
+
if self._exclude and raw_line in self._exclude:
|
|
196
|
+
processed_line = self._nan
|
|
197
|
+
else:
|
|
198
|
+
raise e
|
|
199
|
+
|
|
200
|
+
self.data.update(processed_line)
|
|
201
|
+
|
|
202
|
+
@abstractmethod
|
|
203
|
+
def _process_line(self, raw: str) -> object:
|
|
204
|
+
"""Converts string to meaningful data"""
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
class DateTimeParser(Parser):
|
|
208
|
+
"""Extra argument from superclass code: str"""
|
|
209
|
+
|
|
210
|
+
def __init__(self, *args, **kwargs):
|
|
211
|
+
self._code = kwargs.pop("code")
|
|
212
|
+
super().__init__(*args, **kwargs)
|
|
213
|
+
self._nan = pd.NaT
|
|
214
|
+
|
|
215
|
+
def _process_line(self, raw: str) -> dt.datetime:
|
|
216
|
+
"""Converts string to datetime"""
|
|
217
|
+
return dt.datetime.strptime(raw, self._code)
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
class TimeParser(Parser):
|
|
221
|
+
"""Extra argument from superclass code: str"""
|
|
222
|
+
|
|
223
|
+
def __init__(self, *args, **kwargs):
|
|
224
|
+
self._code = kwargs.pop("code")
|
|
225
|
+
super().__init__(*args, **kwargs)
|
|
226
|
+
self._nan = pd.NaT
|
|
227
|
+
|
|
228
|
+
def _process_line(self, raw: str) -> dt.time:
|
|
229
|
+
"""Converts string to time"""
|
|
230
|
+
|
|
231
|
+
raw, _, _ = raw.partition(" ") # Temp fix to ignore '(+n d)' in EFT
|
|
232
|
+
return dt.datetime.strptime(raw, self._code).time()
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
class TimeDeltaHMSParser(Parser):
|
|
236
|
+
def __init__(self, *args, **kwargs):
|
|
237
|
+
super().__init__(*args, **kwargs)
|
|
238
|
+
self._nan = pd.NaT
|
|
239
|
+
|
|
240
|
+
def _process_line(self, raw: str) -> dt.timedelta:
|
|
241
|
+
"""Converts string HH:MM:SS to timedelta"""
|
|
242
|
+
|
|
243
|
+
h, m, s = raw.split(":")
|
|
244
|
+
return dt.timedelta(hours=int(h), minutes=int(m), seconds=int(s))
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
class TimeDeltaHParser(Parser):
|
|
248
|
+
def __init__(self, *args, **kwargs):
|
|
249
|
+
super().__init__(*args, **kwargs)
|
|
250
|
+
self._nan = pd.NaT
|
|
251
|
+
|
|
252
|
+
def _process_line(self, raw: str) -> dt.timedelta:
|
|
253
|
+
"""Converts string H (with decimal place and "hrs") to timedelta"""
|
|
254
|
+
|
|
255
|
+
h = raw.split("hrs")[0]
|
|
256
|
+
return dt.timedelta(hours=float(h))
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
class TimeDeltaSParser(Parser):
|
|
260
|
+
def __init__(self, *args, **kwargs):
|
|
261
|
+
super().__init__(*args, **kwargs)
|
|
262
|
+
self._nan = pd.NaT
|
|
263
|
+
|
|
264
|
+
def _process_line(self, raw: str) -> dt.timedelta:
|
|
265
|
+
"""Converts string S (with decimal place and "s") to timedelta"""
|
|
266
|
+
|
|
267
|
+
s = raw.split("s")[0] # TODO: not necessary for simulation time
|
|
268
|
+
return dt.timedelta(seconds=float(s))
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
class FloatParser(Parser):
|
|
272
|
+
def __init__(self, *args, **kwargs):
|
|
273
|
+
super().__init__(*args, **kwargs)
|
|
274
|
+
self._nan = float("nan")
|
|
275
|
+
|
|
276
|
+
def _process_line(self, raw: str) -> float:
|
|
277
|
+
"""Converts string to float"""
|
|
278
|
+
|
|
279
|
+
return float(raw)
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
class FloatSplitParser(Parser):
|
|
283
|
+
"""Extra argument from superclass split: list"""
|
|
284
|
+
|
|
285
|
+
def __init__(self, *args, **kwargs):
|
|
286
|
+
self._split = kwargs.pop("split")
|
|
287
|
+
super().__init__(*args, **kwargs)
|
|
288
|
+
self._nan = float("nan")
|
|
289
|
+
|
|
290
|
+
def _process_line(self, raw: str) -> float:
|
|
291
|
+
"""Converts string to float, removing everything after split"""
|
|
292
|
+
|
|
293
|
+
return float(raw.split(self._split)[0])
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
class StringParser(Parser):
|
|
297
|
+
def __init__(self, *args, **kwargs):
|
|
298
|
+
super().__init__(*args, **kwargs)
|
|
299
|
+
self._nan = ""
|
|
300
|
+
|
|
301
|
+
def _process_line(self, raw: str) -> str:
|
|
302
|
+
"""No conversion necessary"""
|
|
303
|
+
|
|
304
|
+
return raw
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
class StringSplitParser(Parser):
|
|
308
|
+
"""Extra argument from superclass split: str"""
|
|
309
|
+
|
|
310
|
+
def __init__(self, *args, **kwargs):
|
|
311
|
+
self._split = kwargs.pop("split")
|
|
312
|
+
super().__init__(*args, **kwargs)
|
|
313
|
+
self._nan = ""
|
|
314
|
+
|
|
315
|
+
def _process_line(self, raw: str) -> str:
|
|
316
|
+
"""Removes everything after split"""
|
|
317
|
+
|
|
318
|
+
return raw.split(self._split)[0]
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
class TimeFloatMultParser(Parser):
|
|
322
|
+
"""Extra argument from superclass names: list"""
|
|
323
|
+
|
|
324
|
+
def __init__(self, *args, **kwargs):
|
|
325
|
+
self._subheaders = kwargs.pop("subheaders")
|
|
326
|
+
super().__init__(*args, **kwargs)
|
|
327
|
+
|
|
328
|
+
self._nan = []
|
|
329
|
+
for _ in self._subheaders:
|
|
330
|
+
self._nan.append(float("nan"))
|
|
331
|
+
|
|
332
|
+
self.data = data_factory(self.data_type, self._name, self._subheaders) # overwrite
|
|
333
|
+
|
|
334
|
+
def _process_line(self, raw: str) -> list[dt.timedelta | float]:
|
|
335
|
+
"""Converts string to list of one timedelta and then floats"""
|
|
336
|
+
|
|
337
|
+
as_float = [float(x) for x in raw.split()]
|
|
338
|
+
first_as_timedelta = dt.timedelta(hours=float(as_float[0]))
|
|
339
|
+
return [first_as_timedelta] + as_float[1:]
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
class TimeSplitParser(Parser):
|
|
343
|
+
"""Extra argument from superclass code: str, split: str"""
|
|
344
|
+
|
|
345
|
+
def __init__(self, *args, **kwargs):
|
|
346
|
+
self._code = kwargs.pop("code")
|
|
347
|
+
self._split = kwargs.pop("split")
|
|
348
|
+
super().__init__(*args, **kwargs)
|
|
349
|
+
self._nan = pd.NaT
|
|
350
|
+
|
|
351
|
+
def _process_line(self, raw: str) -> dt.time:
|
|
352
|
+
"""Converts string to time, removing everything after split"""
|
|
353
|
+
|
|
354
|
+
return dt.datetime.strptime(raw.split(self._split)[0].strip(), self._code).time()
|