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,445 +1,444 @@
|
|
|
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
|
-
import pandas as pd
|
|
18
|
-
|
|
19
|
-
from floodmodeller_api.validation import _validate_unit
|
|
20
|
-
|
|
21
|
-
from ._base import Unit
|
|
22
|
-
from .helpers import (
|
|
23
|
-
_to_float,
|
|
24
|
-
_to_int,
|
|
25
|
-
join_10_char,
|
|
26
|
-
join_n_char_ljust,
|
|
27
|
-
split_10_char,
|
|
28
|
-
split_n_char,
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
class RIVER(Unit):
|
|
33
|
-
"""Class to hold and process RIVER unit type. Currently only river units that are 'SECTION' types are supported.
|
|
34
|
-
Other river unit types such as Muskingham will be included in a future release.
|
|
35
|
-
|
|
36
|
-
Args:
|
|
37
|
-
name (str, optional): River section name
|
|
38
|
-
comment (str, optional): Comment included in unit
|
|
39
|
-
data (pandas.Dataframe): Dataframe object containing all the cross section data as well as all other relevant data.
|
|
40
|
-
Columns are ``'X', 'Y', 'Mannings n', 'Panel', 'RPL', 'Marker', 'Easting', 'Northing', 'Deactivation', 'SP. Marker'``
|
|
41
|
-
spill1, spill2 (str, optional): Spill label
|
|
42
|
-
lat1, lat2, lat3, lat4 (str, optional): Lateral inflow label
|
|
43
|
-
dist_to_next (float, optional): Distance to next section in metres
|
|
44
|
-
slope (float, optional): Slope used in normal depth calculations
|
|
45
|
-
density (float, optional): Density in kg/m3
|
|
46
|
-
|
|
47
|
-
Raises:
|
|
48
|
-
NotImplementedError: Raised if class is initialised without existing river block (i.e. if attempting to create new River unit).
|
|
49
|
-
This will be an option for future releases
|
|
50
|
-
|
|
51
|
-
Returns:
|
|
52
|
-
RIVER: Flood Modeller RIVER Unit class object
|
|
53
|
-
|
|
54
|
-
Methods:
|
|
55
|
-
convert_to_muskingham: Not currently supported but planned for future release
|
|
56
|
-
"""
|
|
57
|
-
|
|
58
|
-
_unit = "RIVER"
|
|
59
|
-
|
|
60
|
-
def _create_from_blank(
|
|
61
|
-
self,
|
|
62
|
-
name="new_section",
|
|
63
|
-
comment="",
|
|
64
|
-
spill1="",
|
|
65
|
-
spill2="",
|
|
66
|
-
lat1="",
|
|
67
|
-
lat2="",
|
|
68
|
-
lat3="",
|
|
69
|
-
lat4="",
|
|
70
|
-
dist_to_next=0,
|
|
71
|
-
slope=0.0001,
|
|
72
|
-
density=1000.0,
|
|
73
|
-
data=None,
|
|
74
|
-
):
|
|
75
|
-
# Initiate new SECTION (currently hardcoding this as default)
|
|
76
|
-
self._subtype = "SECTION"
|
|
77
|
-
|
|
78
|
-
for param, val in {
|
|
79
|
-
"name": name,
|
|
80
|
-
"comment": comment,
|
|
81
|
-
"spill1": spill1,
|
|
82
|
-
"spill2": spill2,
|
|
83
|
-
"lat1": lat1,
|
|
84
|
-
"lat2": lat2,
|
|
85
|
-
"lat3": lat3,
|
|
86
|
-
"lat4": lat4,
|
|
87
|
-
"dist_to_next": dist_to_next,
|
|
88
|
-
"slope": slope,
|
|
89
|
-
"density": density,
|
|
90
|
-
"data": data,
|
|
91
|
-
}.items():
|
|
92
|
-
setattr(self, param, val)
|
|
93
|
-
|
|
94
|
-
self.data = (
|
|
95
|
-
data
|
|
96
|
-
if isinstance(data, pd.DataFrame)
|
|
97
|
-
else pd.DataFrame(
|
|
98
|
-
[],
|
|
99
|
-
columns=[
|
|
100
|
-
"X",
|
|
101
|
-
"Y",
|
|
102
|
-
"Mannings n",
|
|
103
|
-
"Panel",
|
|
104
|
-
"RPL",
|
|
105
|
-
"Marker",
|
|
106
|
-
"Easting",
|
|
107
|
-
"Northing",
|
|
108
|
-
"Deactivation",
|
|
109
|
-
"SP. Marker",
|
|
110
|
-
],
|
|
111
|
-
)
|
|
112
|
-
)
|
|
113
|
-
|
|
114
|
-
def _read(self, riv_block):
|
|
115
|
-
"""Function to read a given RIVER block and store data as class attributes."""
|
|
116
|
-
|
|
117
|
-
self._subtype = riv_block[1].split(" ")[0].strip()
|
|
118
|
-
# Only supporting 'SECTION' subtype for now
|
|
119
|
-
if self.subtype == "SECTION":
|
|
120
|
-
# Extends label line to be correct length before splitting to pick up blank labels
|
|
121
|
-
labels = split_n_char(f"{riv_block[2]:<{7*self._label_len}}", self._label_len)
|
|
122
|
-
self.name = labels[0]
|
|
123
|
-
self.spill1 = labels[1]
|
|
124
|
-
self.spill2 = labels[2]
|
|
125
|
-
self.lat1 = labels[3]
|
|
126
|
-
self.lat2 = labels[4]
|
|
127
|
-
self.lat3 = labels[5]
|
|
128
|
-
self.lat4 = labels[6]
|
|
129
|
-
self.comment = riv_block[0].replace("RIVER", "").strip()
|
|
130
|
-
|
|
131
|
-
params = split_10_char(f"{riv_block[3]:<40}")
|
|
132
|
-
self.dist_to_next = _to_float(params[0])
|
|
133
|
-
self.slope = _to_float(params[2], 0.0001)
|
|
134
|
-
self.density = _to_float(params[3], 1000.0)
|
|
135
|
-
self.nrows = int(split_10_char(riv_block[4])[0])
|
|
136
|
-
data_list = []
|
|
137
|
-
for row in riv_block[5:]:
|
|
138
|
-
row_split = split_10_char(f"{row:<100}")
|
|
139
|
-
x = _to_float(row_split[0]) # chainage
|
|
140
|
-
y = _to_float(row_split[1]) # elevation
|
|
141
|
-
n = _to_float(row_split[2]) # Mannings
|
|
142
|
-
try:
|
|
143
|
-
# panel marker
|
|
144
|
-
panel =
|
|
145
|
-
except IndexError:
|
|
146
|
-
panel = False
|
|
147
|
-
|
|
148
|
-
try:
|
|
149
|
-
# relative path length
|
|
150
|
-
rpl = _to_float(row_split[3][1 if panel else 0 :].strip())
|
|
151
|
-
except IndexError:
|
|
152
|
-
rpl = 0.000
|
|
153
|
-
marker = row_split[4] # Marker
|
|
154
|
-
easting = _to_float(row_split[5]) # easting
|
|
155
|
-
northing = _to_float(row_split[6]) # northing
|
|
156
|
-
|
|
157
|
-
deactivation = row_split[7] # deactivation marker
|
|
158
|
-
sp_marker = _to_int(row_split[8]) # special marker
|
|
159
|
-
data_list.append(
|
|
160
|
-
[
|
|
161
|
-
x,
|
|
162
|
-
y,
|
|
163
|
-
n,
|
|
164
|
-
panel,
|
|
165
|
-
rpl,
|
|
166
|
-
marker,
|
|
167
|
-
easting,
|
|
168
|
-
northing,
|
|
169
|
-
deactivation,
|
|
170
|
-
sp_marker,
|
|
171
|
-
]
|
|
172
|
-
)
|
|
173
|
-
self.data = pd.DataFrame(
|
|
174
|
-
data_list,
|
|
175
|
-
columns=[
|
|
176
|
-
"X",
|
|
177
|
-
"Y",
|
|
178
|
-
"Mannings n",
|
|
179
|
-
"Panel",
|
|
180
|
-
"RPL",
|
|
181
|
-
"Marker",
|
|
182
|
-
"Easting",
|
|
183
|
-
"Northing",
|
|
184
|
-
"Deactivation",
|
|
185
|
-
"SP. Marker",
|
|
186
|
-
],
|
|
187
|
-
)
|
|
188
|
-
|
|
189
|
-
else:
|
|
190
|
-
# 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.
|
|
191
|
-
print(
|
|
192
|
-
f'This River sub-type: "{self.subtype}" is currently unsupported for reading/editing'
|
|
193
|
-
)
|
|
194
|
-
self._raw_block = riv_block
|
|
195
|
-
self.name = riv_block[2][: self._label_len].strip()
|
|
196
|
-
|
|
197
|
-
def _write(self):
|
|
198
|
-
"""Function to write a valid RIVER block"""
|
|
199
|
-
|
|
200
|
-
if self.subtype == "SECTION":
|
|
201
|
-
# Function to check the params are valid for RIVER SECTION unit
|
|
202
|
-
_validate_unit(self)
|
|
203
|
-
header = "RIVER " + self.comment
|
|
204
|
-
labels = join_n_char_ljust(
|
|
205
|
-
self._label_len,
|
|
206
|
-
self.name,
|
|
207
|
-
self.spill1,
|
|
208
|
-
self.spill2,
|
|
209
|
-
self.lat1,
|
|
210
|
-
self.lat2,
|
|
211
|
-
self.lat3,
|
|
212
|
-
self.lat4,
|
|
213
|
-
)
|
|
214
|
-
# Manual so slope can have more sf
|
|
215
|
-
params = f'{self.dist_to_next:>10.3f}{"":>10}{self.slope:>10.6f}{self.density:>10.3f}'
|
|
216
|
-
self.nrows = len(self.data)
|
|
217
|
-
riv_block = [header, self.subtype, labels, params, f"{str(self.nrows):>10}"]
|
|
218
|
-
|
|
219
|
-
riv_data = []
|
|
220
|
-
for (
|
|
221
|
-
_,
|
|
222
|
-
x,
|
|
223
|
-
y,
|
|
224
|
-
n,
|
|
225
|
-
panel,
|
|
226
|
-
rpl,
|
|
227
|
-
marker,
|
|
228
|
-
easting,
|
|
229
|
-
northing,
|
|
230
|
-
deactivation,
|
|
231
|
-
sp_marker,
|
|
232
|
-
) in self.data.itertuples():
|
|
233
|
-
row = join_10_char(x, y, n)
|
|
234
|
-
if panel:
|
|
235
|
-
row += "*"
|
|
236
|
-
else:
|
|
237
|
-
row += " "
|
|
238
|
-
row += f"{rpl:>9.3f}{join_10_char(marker, easting, northing, deactivation, str(sp_marker))}"
|
|
239
|
-
riv_data.append(row)
|
|
240
|
-
|
|
241
|
-
riv_block.extend(riv_data)
|
|
242
|
-
|
|
243
|
-
return riv_block
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
self.
|
|
276
|
-
self.
|
|
277
|
-
self.
|
|
278
|
-
self.
|
|
279
|
-
self.
|
|
280
|
-
self.
|
|
281
|
-
self.
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
self.
|
|
287
|
-
self.
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
self.
|
|
297
|
-
self.
|
|
298
|
-
self.
|
|
299
|
-
self.
|
|
300
|
-
self.
|
|
301
|
-
self.
|
|
302
|
-
self.
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
params1
|
|
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
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
self.
|
|
371
|
-
self.
|
|
372
|
-
self.
|
|
373
|
-
self.
|
|
374
|
-
self.
|
|
375
|
-
self.
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
self.
|
|
383
|
-
self.
|
|
384
|
-
self.
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
self.
|
|
394
|
-
self.
|
|
395
|
-
self.
|
|
396
|
-
self.
|
|
397
|
-
self.
|
|
398
|
-
self.
|
|
399
|
-
self.
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
self.
|
|
408
|
-
|
|
409
|
-
self.
|
|
410
|
-
|
|
411
|
-
)
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
"
|
|
433
|
-
"
|
|
434
|
-
"
|
|
435
|
-
"
|
|
436
|
-
"
|
|
437
|
-
"
|
|
438
|
-
"
|
|
439
|
-
"
|
|
440
|
-
"
|
|
441
|
-
"
|
|
442
|
-
"
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
setattr(self, param, val)
|
|
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
|
+
import pandas as pd
|
|
18
|
+
|
|
19
|
+
from floodmodeller_api.validation import _validate_unit
|
|
20
|
+
|
|
21
|
+
from ._base import Unit
|
|
22
|
+
from .helpers import (
|
|
23
|
+
_to_float,
|
|
24
|
+
_to_int,
|
|
25
|
+
join_10_char,
|
|
26
|
+
join_n_char_ljust,
|
|
27
|
+
split_10_char,
|
|
28
|
+
split_n_char,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class RIVER(Unit):
|
|
33
|
+
"""Class to hold and process RIVER unit type. Currently only river units that are 'SECTION' types are supported.
|
|
34
|
+
Other river unit types such as Muskingham will be included in a future release.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
name (str, optional): River section name
|
|
38
|
+
comment (str, optional): Comment included in unit
|
|
39
|
+
data (pandas.Dataframe): Dataframe object containing all the cross section data as well as all other relevant data.
|
|
40
|
+
Columns are ``'X', 'Y', 'Mannings n', 'Panel', 'RPL', 'Marker', 'Easting', 'Northing', 'Deactivation', 'SP. Marker'``
|
|
41
|
+
spill1, spill2 (str, optional): Spill label
|
|
42
|
+
lat1, lat2, lat3, lat4 (str, optional): Lateral inflow label
|
|
43
|
+
dist_to_next (float, optional): Distance to next section in metres
|
|
44
|
+
slope (float, optional): Slope used in normal depth calculations
|
|
45
|
+
density (float, optional): Density in kg/m3
|
|
46
|
+
|
|
47
|
+
Raises:
|
|
48
|
+
NotImplementedError: Raised if class is initialised without existing river block (i.e. if attempting to create new River unit).
|
|
49
|
+
This will be an option for future releases
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
RIVER: Flood Modeller RIVER Unit class object
|
|
53
|
+
|
|
54
|
+
Methods:
|
|
55
|
+
convert_to_muskingham: Not currently supported but planned for future release
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
_unit = "RIVER"
|
|
59
|
+
|
|
60
|
+
def _create_from_blank( # noqa: PLR0913
|
|
61
|
+
self,
|
|
62
|
+
name="new_section",
|
|
63
|
+
comment="",
|
|
64
|
+
spill1="",
|
|
65
|
+
spill2="",
|
|
66
|
+
lat1="",
|
|
67
|
+
lat2="",
|
|
68
|
+
lat3="",
|
|
69
|
+
lat4="",
|
|
70
|
+
dist_to_next=0,
|
|
71
|
+
slope=0.0001,
|
|
72
|
+
density=1000.0,
|
|
73
|
+
data=None,
|
|
74
|
+
):
|
|
75
|
+
# Initiate new SECTION (currently hardcoding this as default)
|
|
76
|
+
self._subtype = "SECTION"
|
|
77
|
+
|
|
78
|
+
for param, val in {
|
|
79
|
+
"name": name,
|
|
80
|
+
"comment": comment,
|
|
81
|
+
"spill1": spill1,
|
|
82
|
+
"spill2": spill2,
|
|
83
|
+
"lat1": lat1,
|
|
84
|
+
"lat2": lat2,
|
|
85
|
+
"lat3": lat3,
|
|
86
|
+
"lat4": lat4,
|
|
87
|
+
"dist_to_next": dist_to_next,
|
|
88
|
+
"slope": slope,
|
|
89
|
+
"density": density,
|
|
90
|
+
"data": data,
|
|
91
|
+
}.items():
|
|
92
|
+
setattr(self, param, val)
|
|
93
|
+
|
|
94
|
+
self.data = (
|
|
95
|
+
data
|
|
96
|
+
if isinstance(data, pd.DataFrame)
|
|
97
|
+
else pd.DataFrame(
|
|
98
|
+
[],
|
|
99
|
+
columns=[
|
|
100
|
+
"X",
|
|
101
|
+
"Y",
|
|
102
|
+
"Mannings n",
|
|
103
|
+
"Panel",
|
|
104
|
+
"RPL",
|
|
105
|
+
"Marker",
|
|
106
|
+
"Easting",
|
|
107
|
+
"Northing",
|
|
108
|
+
"Deactivation",
|
|
109
|
+
"SP. Marker",
|
|
110
|
+
],
|
|
111
|
+
)
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
def _read(self, riv_block):
|
|
115
|
+
"""Function to read a given RIVER block and store data as class attributes."""
|
|
116
|
+
|
|
117
|
+
self._subtype = riv_block[1].split(" ")[0].strip()
|
|
118
|
+
# Only supporting 'SECTION' subtype for now
|
|
119
|
+
if self.subtype == "SECTION":
|
|
120
|
+
# Extends label line to be correct length before splitting to pick up blank labels
|
|
121
|
+
labels = split_n_char(f"{riv_block[2]:<{7*self._label_len}}", self._label_len)
|
|
122
|
+
self.name = labels[0]
|
|
123
|
+
self.spill1 = labels[1]
|
|
124
|
+
self.spill2 = labels[2]
|
|
125
|
+
self.lat1 = labels[3]
|
|
126
|
+
self.lat2 = labels[4]
|
|
127
|
+
self.lat3 = labels[5]
|
|
128
|
+
self.lat4 = labels[6]
|
|
129
|
+
self.comment = riv_block[0].replace("RIVER", "").strip()
|
|
130
|
+
|
|
131
|
+
params = split_10_char(f"{riv_block[3]:<40}")
|
|
132
|
+
self.dist_to_next = _to_float(params[0])
|
|
133
|
+
self.slope = _to_float(params[2], 0.0001)
|
|
134
|
+
self.density = _to_float(params[3], 1000.0)
|
|
135
|
+
self.nrows = int(split_10_char(riv_block[4])[0])
|
|
136
|
+
data_list = []
|
|
137
|
+
for row in riv_block[5:]:
|
|
138
|
+
row_split = split_10_char(f"{row:<100}")
|
|
139
|
+
x = _to_float(row_split[0]) # chainage
|
|
140
|
+
y = _to_float(row_split[1]) # elevation
|
|
141
|
+
n = _to_float(row_split[2]) # Mannings
|
|
142
|
+
try:
|
|
143
|
+
# panel marker
|
|
144
|
+
panel = row_split[3][0] == "*"
|
|
145
|
+
except IndexError:
|
|
146
|
+
panel = False
|
|
147
|
+
|
|
148
|
+
try:
|
|
149
|
+
# relative path length
|
|
150
|
+
rpl = _to_float(row_split[3][1 if panel else 0 :].strip())
|
|
151
|
+
except IndexError:
|
|
152
|
+
rpl = 0.000
|
|
153
|
+
marker = row_split[4] # Marker
|
|
154
|
+
easting = _to_float(row_split[5]) # easting
|
|
155
|
+
northing = _to_float(row_split[6]) # northing
|
|
156
|
+
|
|
157
|
+
deactivation = row_split[7] # deactivation marker
|
|
158
|
+
sp_marker = _to_int(row_split[8]) # special marker
|
|
159
|
+
data_list.append(
|
|
160
|
+
[
|
|
161
|
+
x,
|
|
162
|
+
y,
|
|
163
|
+
n,
|
|
164
|
+
panel,
|
|
165
|
+
rpl,
|
|
166
|
+
marker,
|
|
167
|
+
easting,
|
|
168
|
+
northing,
|
|
169
|
+
deactivation,
|
|
170
|
+
sp_marker,
|
|
171
|
+
],
|
|
172
|
+
)
|
|
173
|
+
self.data = pd.DataFrame(
|
|
174
|
+
data_list,
|
|
175
|
+
columns=[
|
|
176
|
+
"X",
|
|
177
|
+
"Y",
|
|
178
|
+
"Mannings n",
|
|
179
|
+
"Panel",
|
|
180
|
+
"RPL",
|
|
181
|
+
"Marker",
|
|
182
|
+
"Easting",
|
|
183
|
+
"Northing",
|
|
184
|
+
"Deactivation",
|
|
185
|
+
"SP. Marker",
|
|
186
|
+
],
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
else:
|
|
190
|
+
# 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.
|
|
191
|
+
print(
|
|
192
|
+
f'This River sub-type: "{self.subtype}" is currently unsupported for reading/editing',
|
|
193
|
+
)
|
|
194
|
+
self._raw_block = riv_block
|
|
195
|
+
self.name = riv_block[2][: self._label_len].strip()
|
|
196
|
+
|
|
197
|
+
def _write(self):
|
|
198
|
+
"""Function to write a valid RIVER block"""
|
|
199
|
+
|
|
200
|
+
if self.subtype == "SECTION":
|
|
201
|
+
# Function to check the params are valid for RIVER SECTION unit
|
|
202
|
+
_validate_unit(self)
|
|
203
|
+
header = "RIVER " + self.comment
|
|
204
|
+
labels = join_n_char_ljust(
|
|
205
|
+
self._label_len,
|
|
206
|
+
self.name,
|
|
207
|
+
self.spill1,
|
|
208
|
+
self.spill2,
|
|
209
|
+
self.lat1,
|
|
210
|
+
self.lat2,
|
|
211
|
+
self.lat3,
|
|
212
|
+
self.lat4,
|
|
213
|
+
)
|
|
214
|
+
# Manual so slope can have more sf
|
|
215
|
+
params = f'{self.dist_to_next:>10.3f}{"":>10}{self.slope:>10.6f}{self.density:>10.3f}'
|
|
216
|
+
self.nrows = len(self.data)
|
|
217
|
+
riv_block = [header, self.subtype, labels, params, f"{str(self.nrows):>10}"]
|
|
218
|
+
|
|
219
|
+
riv_data = []
|
|
220
|
+
for (
|
|
221
|
+
_,
|
|
222
|
+
x,
|
|
223
|
+
y,
|
|
224
|
+
n,
|
|
225
|
+
panel,
|
|
226
|
+
rpl,
|
|
227
|
+
marker,
|
|
228
|
+
easting,
|
|
229
|
+
northing,
|
|
230
|
+
deactivation,
|
|
231
|
+
sp_marker,
|
|
232
|
+
) in self.data.itertuples():
|
|
233
|
+
row = join_10_char(x, y, n)
|
|
234
|
+
if panel:
|
|
235
|
+
row += "*"
|
|
236
|
+
else:
|
|
237
|
+
row += " "
|
|
238
|
+
row += f"{rpl:>9.3f}{join_10_char(marker, easting, northing, deactivation, str(sp_marker))}"
|
|
239
|
+
riv_data.append(row)
|
|
240
|
+
|
|
241
|
+
riv_block.extend(riv_data)
|
|
242
|
+
|
|
243
|
+
return riv_block
|
|
244
|
+
|
|
245
|
+
return self._raw_block
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
class INTERPOLATE(Unit):
|
|
249
|
+
"""Class to hold and process INTERPOLATE unit type
|
|
250
|
+
|
|
251
|
+
Args:
|
|
252
|
+
name (str, optional): Unit name.
|
|
253
|
+
comment (str, optional): Comment included in unit.
|
|
254
|
+
first_spill (str, optional): Spill label if required.
|
|
255
|
+
second_spill (str, optional): Spill label if required.
|
|
256
|
+
lat1 (str, optional): First lateral inflow label.
|
|
257
|
+
lat2 (str, optional): Second lateral inflow label.
|
|
258
|
+
lat3 (str, optional): Third lateral inflow label.
|
|
259
|
+
lat4 (str, optional): Fourth lateral inflow label.
|
|
260
|
+
dist_to_next (float, optional): Chainage downstream to following section (m).
|
|
261
|
+
easting (float, optional): Easting coordinate of interpolated section (not used in hydraulic calculations).
|
|
262
|
+
northing (float, optional): Northing coordinate of interpolated section (not used in hydraulic calculations).
|
|
263
|
+
|
|
264
|
+
Returns:
|
|
265
|
+
INTERPOLATE: Flood Modeller INTERPOLATE Unit class object"""
|
|
266
|
+
|
|
267
|
+
_unit = "INTERPOLATE"
|
|
268
|
+
|
|
269
|
+
def _read(self, block):
|
|
270
|
+
"""Function to read a given INTERPOLATE WEIR block and store data as class attributes"""
|
|
271
|
+
|
|
272
|
+
# Extends label line to be correct length before splitting to pick up blank labels
|
|
273
|
+
labels = split_n_char(f"{block[1]:<{7*self._label_len}}", self._label_len)
|
|
274
|
+
self.name = labels[0]
|
|
275
|
+
self.first_spill = labels[1]
|
|
276
|
+
self.second_spill = labels[2]
|
|
277
|
+
self.lat1 = labels[3]
|
|
278
|
+
self.lat2 = labels[4]
|
|
279
|
+
self.lat3 = labels[5]
|
|
280
|
+
self.lat4 = labels[6]
|
|
281
|
+
self.comment = block[0].replace("INTERPOLATE", "").strip()
|
|
282
|
+
|
|
283
|
+
# First parameter line
|
|
284
|
+
params1 = split_10_char(f"{block[2]:<30}")
|
|
285
|
+
self.dist_to_next = _to_float(params1[0])
|
|
286
|
+
self.easting = _to_float(params1[1])
|
|
287
|
+
self.northing = _to_float(params1[2])
|
|
288
|
+
|
|
289
|
+
def _write(self):
|
|
290
|
+
"""Function to write a valid INTERPOLATE block"""
|
|
291
|
+
|
|
292
|
+
_validate_unit(self)
|
|
293
|
+
header = "INTERPOLATE " + self.comment
|
|
294
|
+
labels = join_n_char_ljust(
|
|
295
|
+
self._label_len,
|
|
296
|
+
self.name,
|
|
297
|
+
self.first_spill,
|
|
298
|
+
self.second_spill,
|
|
299
|
+
self.lat1,
|
|
300
|
+
self.lat2,
|
|
301
|
+
self.lat3,
|
|
302
|
+
self.lat4,
|
|
303
|
+
)
|
|
304
|
+
block = [header, labels]
|
|
305
|
+
|
|
306
|
+
# First parameter line
|
|
307
|
+
params1 = join_10_char(self.dist_to_next, self.easting, self.northing)
|
|
308
|
+
block.append(params1)
|
|
309
|
+
|
|
310
|
+
return block
|
|
311
|
+
|
|
312
|
+
def _create_from_blank( # noqa: PLR0913
|
|
313
|
+
self,
|
|
314
|
+
name="new_interp",
|
|
315
|
+
comment="",
|
|
316
|
+
first_spill="",
|
|
317
|
+
second_spill="",
|
|
318
|
+
lat1="",
|
|
319
|
+
lat2="",
|
|
320
|
+
lat3="",
|
|
321
|
+
lat4="",
|
|
322
|
+
dist_to_next=0,
|
|
323
|
+
easting=0,
|
|
324
|
+
northing=0,
|
|
325
|
+
):
|
|
326
|
+
for param, val in {
|
|
327
|
+
"name": name,
|
|
328
|
+
"comment": comment,
|
|
329
|
+
"first_spill": first_spill,
|
|
330
|
+
"second_spill": second_spill,
|
|
331
|
+
"lat1": lat1,
|
|
332
|
+
"lat2": lat2,
|
|
333
|
+
"lat3": lat3,
|
|
334
|
+
"lat4": lat4,
|
|
335
|
+
"dist_to_next": dist_to_next,
|
|
336
|
+
"easting": easting,
|
|
337
|
+
"northing": northing,
|
|
338
|
+
}.items():
|
|
339
|
+
setattr(self, param, val)
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
class REPLICATE(Unit):
|
|
343
|
+
"""Class to hold and process REPLICATE unit type
|
|
344
|
+
|
|
345
|
+
Args:
|
|
346
|
+
name (str, optional): Unit name.
|
|
347
|
+
comment (str, optional): Comment included in unit.
|
|
348
|
+
first_spill (str, optional): Spill label if required.
|
|
349
|
+
second_spill (str, optional): Spill label if required.
|
|
350
|
+
lat1 (str, optional): First lateral inflow label.
|
|
351
|
+
lat2 (str, optional): Second lateral inflow label.
|
|
352
|
+
lat3 (str, optional): Third lateral inflow label.
|
|
353
|
+
lat4 (str, optional): Fourth lateral inflow label.
|
|
354
|
+
dist_to_next (float, optional): Chainage downstream to following section (m).
|
|
355
|
+
easting (float, optional): Easting coordinate of interpolated section (not used in hydraulic calculations).
|
|
356
|
+
northing (float, optional): Northing coordinate of interpolated section (not used in hydraulic calculations).
|
|
357
|
+
bed_level_drop (float, optional): Drop in bed level from previous section (m).
|
|
358
|
+
|
|
359
|
+
Returns:
|
|
360
|
+
REPLICATE: Flood Modeller REPLICATE Unit class object"""
|
|
361
|
+
|
|
362
|
+
_unit = "REPLICATE"
|
|
363
|
+
|
|
364
|
+
def _read(self, block: list[str]):
|
|
365
|
+
"""Function to read a given REPLICATE block and store data as class attributes"""
|
|
366
|
+
|
|
367
|
+
# Extends label line to be correct length before splitting to pick up blank labels
|
|
368
|
+
labels = split_n_char(f"{block[1]:<{7*self._label_len}}", self._label_len)
|
|
369
|
+
self.name = labels[0]
|
|
370
|
+
self.first_spill = labels[1]
|
|
371
|
+
self.second_spill = labels[2]
|
|
372
|
+
self.lat1 = labels[3]
|
|
373
|
+
self.lat2 = labels[4]
|
|
374
|
+
self.lat3 = labels[5]
|
|
375
|
+
self.lat4 = labels[6]
|
|
376
|
+
|
|
377
|
+
self.comment = block[0].replace("REPLICATE", "").strip()
|
|
378
|
+
|
|
379
|
+
# First parameter line
|
|
380
|
+
params1 = split_10_char(f"{block[2]:<40}")
|
|
381
|
+
self.dist_to_next = _to_float(params1[0])
|
|
382
|
+
self.bed_level_drop = _to_float(params1[1])
|
|
383
|
+
self.easting = _to_float(params1[2])
|
|
384
|
+
self.northing = _to_float(params1[3])
|
|
385
|
+
|
|
386
|
+
def _write(self):
|
|
387
|
+
"""Function to write a valid REPLICATE block"""
|
|
388
|
+
|
|
389
|
+
_validate_unit(self)
|
|
390
|
+
header = "REPLICATE " + self.comment
|
|
391
|
+
labels = join_n_char_ljust(
|
|
392
|
+
self._label_len,
|
|
393
|
+
self.name,
|
|
394
|
+
self.first_spill,
|
|
395
|
+
self.second_spill,
|
|
396
|
+
self.lat1,
|
|
397
|
+
self.lat2,
|
|
398
|
+
self.lat3,
|
|
399
|
+
self.lat4,
|
|
400
|
+
)
|
|
401
|
+
block = [header, labels]
|
|
402
|
+
|
|
403
|
+
# First parameter line
|
|
404
|
+
|
|
405
|
+
params1 = join_10_char(
|
|
406
|
+
self.dist_to_next,
|
|
407
|
+
f"{self.bed_level_drop:>10.4f}", # allowing 4dp
|
|
408
|
+
self.easting,
|
|
409
|
+
self.northing,
|
|
410
|
+
)
|
|
411
|
+
block.append(params1)
|
|
412
|
+
|
|
413
|
+
return block
|
|
414
|
+
|
|
415
|
+
def _create_from_blank( # noqa: PLR0913
|
|
416
|
+
self,
|
|
417
|
+
name="new_repl",
|
|
418
|
+
comment="",
|
|
419
|
+
first_spill="",
|
|
420
|
+
second_spill="",
|
|
421
|
+
lat1="",
|
|
422
|
+
lat2="",
|
|
423
|
+
lat3="",
|
|
424
|
+
lat4="",
|
|
425
|
+
dist_to_next=0,
|
|
426
|
+
bed_level_drop=0,
|
|
427
|
+
easting=0,
|
|
428
|
+
northing=0,
|
|
429
|
+
):
|
|
430
|
+
for param, val in {
|
|
431
|
+
"name": name,
|
|
432
|
+
"comment": comment,
|
|
433
|
+
"first_spill": first_spill,
|
|
434
|
+
"second_spill": second_spill,
|
|
435
|
+
"lat1": lat1,
|
|
436
|
+
"lat2": lat2,
|
|
437
|
+
"lat3": lat3,
|
|
438
|
+
"lat4": lat4,
|
|
439
|
+
"dist_to_next": dist_to_next,
|
|
440
|
+
"bed_level_drop": bed_level_drop,
|
|
441
|
+
"easting": easting,
|
|
442
|
+
"northing": northing,
|
|
443
|
+
}.items():
|
|
444
|
+
setattr(self, param, val)
|