floodmodeller-api 0.5.1__py3-none-any.whl → 0.5.2__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 +10 -0
- floodmodeller_api/_base.py +29 -20
- floodmodeller_api/backup.py +12 -10
- floodmodeller_api/dat.py +162 -91
- floodmodeller_api/diff.py +1 -1
- floodmodeller_api/hydrology_plus/hydrology_plus_export.py +1 -1
- floodmodeller_api/ied.py +2 -4
- floodmodeller_api/ief.py +29 -17
- floodmodeller_api/ief_flags.py +1 -1
- floodmodeller_api/inp.py +4 -6
- floodmodeller_api/logs/lf.py +18 -12
- floodmodeller_api/logs/lf_helpers.py +2 -2
- floodmodeller_api/logs/lf_params.py +1 -5
- floodmodeller_api/mapping.py +9 -2
- floodmodeller_api/test/test_conveyance.py +9 -4
- floodmodeller_api/test/test_dat.py +166 -18
- floodmodeller_api/test/test_data/EX18_DAT_expected.json +164 -144
- floodmodeller_api/test/test_data/EX3_DAT_expected.json +6 -2
- floodmodeller_api/test/test_data/EX6_DAT_expected.json +12 -46
- floodmodeller_api/test/test_data/encoding_test_cp1252.dat +1081 -0
- floodmodeller_api/test/test_data/encoding_test_utf8.dat +1081 -0
- floodmodeller_api/test/test_data/integrated_bridge/AR_NoSP_NoBl_2O_NO_OneFRC.ied +33 -0
- floodmodeller_api/test/test_data/integrated_bridge/AR_vSP_25pc_1O.ied +32 -0
- floodmodeller_api/test/test_data/integrated_bridge/PL_vSP_25pc_1O.ied +34 -0
- floodmodeller_api/test/test_data/integrated_bridge/SBTwoFRCsStaggered.IED +32 -0
- floodmodeller_api/test/test_data/integrated_bridge/US_NoSP_NoBl_OR_RN.ied +28 -0
- floodmodeller_api/test/test_data/integrated_bridge/US_SP_NoBl_OR_frc_PT2-5_RN.ied +34 -0
- floodmodeller_api/test/test_data/integrated_bridge/US_fSP_NoBl_1O.ied +30 -0
- floodmodeller_api/test/test_data/integrated_bridge/US_nSP_NoBl_1O.ied +49 -0
- floodmodeller_api/test/test_data/integrated_bridge/US_vSP_NoBl_2O_Para.ied +35 -0
- floodmodeller_api/test/test_data/integrated_bridge.dat +40 -0
- floodmodeller_api/test/test_data/network.ied +2 -2
- floodmodeller_api/test/test_data/network_dat_expected.json +141 -243
- floodmodeller_api/test/test_data/network_ied_expected.json +2 -2
- floodmodeller_api/test/test_data/network_with_comments.ied +2 -2
- floodmodeller_api/test/test_ied.py +1 -1
- floodmodeller_api/test/test_ief.py +10 -2
- floodmodeller_api/test/test_integrated_bridge.py +159 -0
- floodmodeller_api/test/test_json.py +9 -3
- floodmodeller_api/test/test_logs_lf.py +45 -24
- floodmodeller_api/test/test_river.py +1 -1
- floodmodeller_api/test/test_toolbox_structure_log.py +0 -1
- floodmodeller_api/test/test_xml2d.py +5 -5
- floodmodeller_api/to_from_json.py +1 -1
- floodmodeller_api/tool.py +3 -5
- floodmodeller_api/toolbox/model_build/add_siltation_definition.py +1 -1
- floodmodeller_api/toolbox/model_build/structure_log/structure_log.py +12 -8
- floodmodeller_api/units/__init__.py +15 -0
- floodmodeller_api/units/_base.py +73 -10
- floodmodeller_api/units/_helpers.py +343 -0
- floodmodeller_api/units/boundaries.py +59 -71
- floodmodeller_api/units/comment.py +1 -1
- floodmodeller_api/units/conduits.py +57 -54
- floodmodeller_api/units/connectors.py +112 -0
- floodmodeller_api/units/controls.py +107 -0
- floodmodeller_api/units/iic.py +2 -9
- floodmodeller_api/units/losses.py +42 -42
- floodmodeller_api/units/sections.py +40 -43
- floodmodeller_api/units/structures.py +360 -530
- floodmodeller_api/units/units.py +25 -26
- floodmodeller_api/units/unsupported.py +5 -7
- floodmodeller_api/units/variables.py +2 -2
- floodmodeller_api/urban1d/_base.py +7 -8
- floodmodeller_api/urban1d/conduits.py +11 -21
- floodmodeller_api/urban1d/general_parameters.py +1 -1
- floodmodeller_api/urban1d/junctions.py +7 -11
- floodmodeller_api/urban1d/losses.py +13 -17
- floodmodeller_api/urban1d/outfalls.py +16 -21
- floodmodeller_api/urban1d/raingauges.py +3 -9
- floodmodeller_api/urban1d/subsections.py +3 -4
- floodmodeller_api/urban1d/xsections.py +11 -15
- floodmodeller_api/util.py +7 -4
- floodmodeller_api/validation/parameters.py +7 -3
- floodmodeller_api/validation/urban_parameters.py +1 -4
- floodmodeller_api/validation/validation.py +9 -4
- floodmodeller_api/version.py +1 -1
- floodmodeller_api/xml2d.py +9 -11
- floodmodeller_api/xml2d_template.py +1 -1
- floodmodeller_api/zz.py +7 -6
- {floodmodeller_api-0.5.1.dist-info → floodmodeller_api-0.5.2.dist-info}/LICENSE.txt +1 -1
- {floodmodeller_api-0.5.1.dist-info → floodmodeller_api-0.5.2.dist-info}/METADATA +11 -3
- {floodmodeller_api-0.5.1.dist-info → floodmodeller_api-0.5.2.dist-info}/RECORD +85 -70
- {floodmodeller_api-0.5.1.dist-info → floodmodeller_api-0.5.2.dist-info}/WHEEL +1 -1
- floodmodeller_api/units/helpers.py +0 -121
- {floodmodeller_api-0.5.1.dist-info → floodmodeller_api-0.5.2.dist-info}/entry_points.txt +0 -0
- {floodmodeller_api-0.5.1.dist-info → floodmodeller_api-0.5.2.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Flood Modeller Python API
|
|
3
|
-
Copyright (C)
|
|
3
|
+
Copyright (C) 2025 Jacobs U.K. Limited
|
|
4
4
|
|
|
5
5
|
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
|
|
6
6
|
as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
@@ -16,22 +16,22 @@ address: Jacobs UK Limited, Flood Modeller, Cottons Centre, Cottons Lane, London
|
|
|
16
16
|
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
import logging
|
|
20
20
|
|
|
21
21
|
import pandas as pd
|
|
22
22
|
|
|
23
23
|
from floodmodeller_api.validation import _validate_unit
|
|
24
24
|
|
|
25
25
|
from ._base import Unit
|
|
26
|
-
from .
|
|
27
|
-
from .helpers import (
|
|
28
|
-
_to_float,
|
|
29
|
-
_to_int,
|
|
26
|
+
from ._helpers import (
|
|
30
27
|
join_10_char,
|
|
31
28
|
join_n_char_ljust,
|
|
32
29
|
split_10_char,
|
|
33
30
|
split_n_char,
|
|
31
|
+
to_float,
|
|
32
|
+
to_int,
|
|
34
33
|
)
|
|
34
|
+
from .conveyance import calculate_cross_section_conveyance_cached
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
class RIVER(Unit):
|
|
@@ -58,7 +58,7 @@ class RIVER(Unit):
|
|
|
58
58
|
"""
|
|
59
59
|
|
|
60
60
|
_unit = "RIVER"
|
|
61
|
-
_required_columns
|
|
61
|
+
_required_columns = (
|
|
62
62
|
"X",
|
|
63
63
|
"Y",
|
|
64
64
|
"Mannings n",
|
|
@@ -69,7 +69,7 @@ class RIVER(Unit):
|
|
|
69
69
|
"Northing",
|
|
70
70
|
"Deactivation",
|
|
71
71
|
"SP. Marker",
|
|
72
|
-
|
|
72
|
+
)
|
|
73
73
|
|
|
74
74
|
def _create_from_blank( # noqa: PLR0913
|
|
75
75
|
self,
|
|
@@ -104,24 +104,18 @@ class RIVER(Unit):
|
|
|
104
104
|
}.items():
|
|
105
105
|
setattr(self, param, val)
|
|
106
106
|
|
|
107
|
-
self._data = (
|
|
108
|
-
data
|
|
109
|
-
if isinstance(data, pd.DataFrame)
|
|
110
|
-
else pd.DataFrame(
|
|
111
|
-
[],
|
|
112
|
-
columns=self._required_columns,
|
|
113
|
-
)
|
|
114
|
-
)
|
|
107
|
+
self._data = self._enforce_dataframe(data, self._required_columns)
|
|
115
108
|
self._active_data = None
|
|
116
109
|
|
|
117
110
|
def _read(self, riv_block):
|
|
118
111
|
"""Function to read a given RIVER block and store data as class attributes."""
|
|
119
112
|
|
|
120
113
|
self._subtype = riv_block[1].split(" ")[0].strip()
|
|
114
|
+
# Extends label line to be correct length before splitting to pick up blank labels
|
|
115
|
+
labels = split_n_char(f"{riv_block[2]:<{7*self._label_len}}", self._label_len)
|
|
116
|
+
|
|
121
117
|
# Only supporting 'SECTION' subtype for now
|
|
122
118
|
if self.subtype == "SECTION":
|
|
123
|
-
# Extends label line to be correct length before splitting to pick up blank labels
|
|
124
|
-
labels = split_n_char(f"{riv_block[2]:<{7*self._label_len}}", self._label_len)
|
|
125
119
|
self.name = labels[0]
|
|
126
120
|
self.spill1 = labels[1]
|
|
127
121
|
self.spill2 = labels[2]
|
|
@@ -129,19 +123,19 @@ class RIVER(Unit):
|
|
|
129
123
|
self.lat2 = labels[4]
|
|
130
124
|
self.lat3 = labels[5]
|
|
131
125
|
self.lat4 = labels[6]
|
|
132
|
-
self.comment = riv_block[0]
|
|
126
|
+
self.comment = self._remove_unit_name(riv_block[0])
|
|
133
127
|
|
|
134
128
|
params = split_10_char(f"{riv_block[3]:<40}")
|
|
135
|
-
self.dist_to_next =
|
|
136
|
-
self.slope =
|
|
137
|
-
self.density =
|
|
129
|
+
self.dist_to_next = to_float(params[0])
|
|
130
|
+
self.slope = to_float(params[2], 0.0001)
|
|
131
|
+
self.density = to_float(params[3], 1000.0)
|
|
138
132
|
self.nrows = int(split_10_char(riv_block[4])[0])
|
|
139
133
|
data_list = []
|
|
140
134
|
for row in riv_block[5:]:
|
|
141
135
|
row_split = split_10_char(f"{row:<100}")
|
|
142
|
-
x =
|
|
143
|
-
y =
|
|
144
|
-
n =
|
|
136
|
+
x = to_float(row_split[0]) # chainage
|
|
137
|
+
y = to_float(row_split[1]) # elevation
|
|
138
|
+
n = to_float(row_split[2]) # Mannings
|
|
145
139
|
try:
|
|
146
140
|
# panel marker
|
|
147
141
|
panel = row_split[3][0] == "*"
|
|
@@ -150,15 +144,15 @@ class RIVER(Unit):
|
|
|
150
144
|
|
|
151
145
|
try:
|
|
152
146
|
# relative path length
|
|
153
|
-
rpl =
|
|
147
|
+
rpl = to_float(row_split[3][1 if panel else 0 :].strip())
|
|
154
148
|
except IndexError:
|
|
155
149
|
rpl = 0.000
|
|
156
150
|
marker = row_split[4] # Marker
|
|
157
|
-
easting =
|
|
158
|
-
northing =
|
|
151
|
+
easting = to_float(row_split[5]) # easting
|
|
152
|
+
northing = to_float(row_split[6]) # northing
|
|
159
153
|
|
|
160
154
|
deactivation = row_split[7] # deactivation marker
|
|
161
|
-
sp_marker =
|
|
155
|
+
sp_marker = to_int(row_split[8]) # special marker
|
|
162
156
|
data_list.append(
|
|
163
157
|
[
|
|
164
158
|
x,
|
|
@@ -180,11 +174,14 @@ class RIVER(Unit):
|
|
|
180
174
|
|
|
181
175
|
else:
|
|
182
176
|
# This else block is triggered for river subtypes which aren't yet supported, and just keeps the 'riv_block' in it's raw state to write back.
|
|
183
|
-
|
|
184
|
-
|
|
177
|
+
logging.warning(
|
|
178
|
+
"This River sub-type: '%s' is currently unsupported for reading/editing",
|
|
179
|
+
self.subtype,
|
|
185
180
|
)
|
|
186
181
|
self._raw_block = riv_block
|
|
187
182
|
self.name = riv_block[2][: self._label_len].strip()
|
|
183
|
+
self.dist_to_next = to_float(riv_block[3][:10])
|
|
184
|
+
self.labels = labels
|
|
188
185
|
|
|
189
186
|
self._active_data = None
|
|
190
187
|
|
|
@@ -194,7 +191,7 @@ class RIVER(Unit):
|
|
|
194
191
|
if self.subtype == "SECTION":
|
|
195
192
|
# Function to check the params are valid for RIVER SECTION unit
|
|
196
193
|
_validate_unit(self)
|
|
197
|
-
header =
|
|
194
|
+
header = self._create_header()
|
|
198
195
|
labels = join_n_char_ljust(
|
|
199
196
|
self._label_len,
|
|
200
197
|
self.name,
|
|
@@ -384,19 +381,19 @@ class INTERPOLATE(Unit):
|
|
|
384
381
|
self.lat2 = labels[4]
|
|
385
382
|
self.lat3 = labels[5]
|
|
386
383
|
self.lat4 = labels[6]
|
|
387
|
-
self.comment = block[0]
|
|
384
|
+
self.comment = self._remove_unit_name(block[0])
|
|
388
385
|
|
|
389
386
|
# First parameter line
|
|
390
387
|
params1 = split_10_char(f"{block[2]:<30}")
|
|
391
|
-
self.dist_to_next =
|
|
392
|
-
self.easting =
|
|
393
|
-
self.northing =
|
|
388
|
+
self.dist_to_next = to_float(params1[0])
|
|
389
|
+
self.easting = to_float(params1[1])
|
|
390
|
+
self.northing = to_float(params1[2])
|
|
394
391
|
|
|
395
392
|
def _write(self):
|
|
396
393
|
"""Function to write a valid INTERPOLATE block"""
|
|
397
394
|
|
|
398
395
|
_validate_unit(self)
|
|
399
|
-
header =
|
|
396
|
+
header = self._create_header()
|
|
400
397
|
labels = join_n_char_ljust(
|
|
401
398
|
self._label_len,
|
|
402
399
|
self.name,
|
|
@@ -480,20 +477,20 @@ class REPLICATE(Unit):
|
|
|
480
477
|
self.lat3 = labels[5]
|
|
481
478
|
self.lat4 = labels[6]
|
|
482
479
|
|
|
483
|
-
self.comment = block[0]
|
|
480
|
+
self.comment = self._remove_unit_name(block[0])
|
|
484
481
|
|
|
485
482
|
# First parameter line
|
|
486
483
|
params1 = split_10_char(f"{block[2]:<40}")
|
|
487
|
-
self.dist_to_next =
|
|
488
|
-
self.bed_level_drop =
|
|
489
|
-
self.easting =
|
|
490
|
-
self.northing =
|
|
484
|
+
self.dist_to_next = to_float(params1[0])
|
|
485
|
+
self.bed_level_drop = to_float(params1[1])
|
|
486
|
+
self.easting = to_float(params1[2])
|
|
487
|
+
self.northing = to_float(params1[3])
|
|
491
488
|
|
|
492
489
|
def _write(self):
|
|
493
490
|
"""Function to write a valid REPLICATE block"""
|
|
494
491
|
|
|
495
492
|
_validate_unit(self)
|
|
496
|
-
header =
|
|
493
|
+
header = self._create_header()
|
|
497
494
|
labels = join_n_char_ljust(
|
|
498
495
|
self._label_len,
|
|
499
496
|
self.name,
|