ras-commander 0.48.0__py3-none-any.whl → 0.49.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.
- ras_commander/Decorators.py +18 -1
- ras_commander/HdfBase.py +307 -197
- ras_commander/HdfBndry.py +94 -287
- ras_commander/HdfFluvialPluvial.py +155 -247
- ras_commander/HdfInfiltration.py +410 -0
- ras_commander/HdfMesh.py +117 -36
- ras_commander/HdfPipe.py +127 -175
- ras_commander/HdfPlan.py +144 -58
- ras_commander/HdfPlot.py +104 -0
- ras_commander/HdfPump.py +76 -28
- ras_commander/HdfResultsMesh.py +186 -167
- ras_commander/HdfResultsPlan.py +76 -220
- ras_commander/HdfResultsPlot.py +182 -0
- ras_commander/HdfResultsXsec.py +185 -145
- ras_commander/HdfStruc.py +65 -35
- ras_commander/HdfUtils.py +435 -518
- ras_commander/HdfXsec.py +137 -127
- ras_commander/RasCmdr.py +13 -0
- ras_commander/RasExamples.py +14 -0
- ras_commander/RasGeo.py +11 -0
- ras_commander/RasGpt.py +8 -0
- ras_commander/RasMapper.py +105 -0
- ras_commander/RasPlan.py +30 -0
- ras_commander/RasPrj.py +34 -0
- ras_commander/RasToGo.py +16 -0
- ras_commander/RasUnsteady.py +15 -0
- ras_commander/RasUtils.py +31 -0
- ras_commander/__init__.py +10 -0
- {ras_commander-0.48.0.dist-info → ras_commander-0.49.0.dist-info}/METADATA +73 -8
- ras_commander-0.49.0.dist-info/RECORD +34 -0
- ras_commander-0.48.0.dist-info/RECORD +0 -30
- {ras_commander-0.48.0.dist-info → ras_commander-0.49.0.dist-info}/LICENSE +0 -0
- {ras_commander-0.48.0.dist-info → ras_commander-0.49.0.dist-info}/WHEEL +0 -0
- {ras_commander-0.48.0.dist-info → ras_commander-0.49.0.dist-info}/top_level.txt +0 -0
ras_commander/HdfMesh.py
CHANGED
@@ -1,11 +1,26 @@
|
|
1
1
|
"""
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
2
|
+
A static class for handling mesh-related operations on HEC-RAS HDF files.
|
3
|
+
|
4
|
+
This class provides static methods to extract and analyze mesh data from HEC-RAS HDF files,
|
5
|
+
including mesh area names, mesh areas, cell polygons, cell points, cell faces, and
|
6
|
+
2D flow area attributes. No instantiation is required to use these methods.
|
7
|
+
|
8
|
+
All methods are designed to work with the mesh geometry data stored in
|
9
|
+
HEC-RAS HDF files, providing functionality to retrieve and process various aspects
|
10
|
+
of the 2D flow areas and their associated mesh structures.
|
11
|
+
|
12
|
+
List of Functions:
|
13
|
+
-----------------
|
14
|
+
get_mesh_area_names()
|
15
|
+
Returns list of 2D mesh area names
|
16
|
+
get_mesh_areas()
|
17
|
+
Returns 2D flow area perimeter polygons
|
18
|
+
mesh_cell_polygons()
|
19
|
+
Returns 2D flow mesh cell polygons
|
20
|
+
[etc...]
|
21
|
+
|
22
|
+
Each function is decorated with @standardize_input and @log_call for consistent
|
23
|
+
input handling and logging functionality.
|
9
24
|
"""
|
10
25
|
from pathlib import Path
|
11
26
|
import h5py
|
@@ -44,9 +59,9 @@ class HdfMesh:
|
|
44
59
|
|
45
60
|
@staticmethod
|
46
61
|
@standardize_input(file_type='plan_hdf')
|
47
|
-
def
|
62
|
+
def get_mesh_area_names(hdf_path: Path) -> List[str]:
|
48
63
|
"""
|
49
|
-
Return a list of the 2D mesh area names
|
64
|
+
Return a list of the 2D mesh area names from the RAS geometry.
|
50
65
|
|
51
66
|
Parameters
|
52
67
|
----------
|
@@ -56,7 +71,8 @@ class HdfMesh:
|
|
56
71
|
Returns
|
57
72
|
-------
|
58
73
|
List[str]
|
59
|
-
A list of the 2D mesh area names
|
74
|
+
A list of the 2D mesh area names within the RAS geometry.
|
75
|
+
Returns an empty list if no 2D areas exist or if there's an error.
|
60
76
|
"""
|
61
77
|
try:
|
62
78
|
with h5py.File(hdf_path, 'r') as hdf_file:
|
@@ -64,7 +80,7 @@ class HdfMesh:
|
|
64
80
|
return list()
|
65
81
|
return list(
|
66
82
|
[
|
67
|
-
HdfUtils.
|
83
|
+
HdfUtils.convert_ras_string(n.decode('utf-8'))
|
68
84
|
for n in hdf_file["Geometry/2D Flow Areas/Attributes"][()]["Name"]
|
69
85
|
]
|
70
86
|
)
|
@@ -74,7 +90,7 @@ class HdfMesh:
|
|
74
90
|
|
75
91
|
@staticmethod
|
76
92
|
@standardize_input(file_type='geom_hdf')
|
77
|
-
def
|
93
|
+
def get_mesh_areas(hdf_path: Path) -> GeoDataFrame:
|
78
94
|
"""
|
79
95
|
Return 2D flow area perimeter polygons.
|
80
96
|
|
@@ -90,7 +106,7 @@ class HdfMesh:
|
|
90
106
|
"""
|
91
107
|
try:
|
92
108
|
with h5py.File(hdf_path, 'r') as hdf_file:
|
93
|
-
mesh_area_names = HdfMesh.
|
109
|
+
mesh_area_names = HdfMesh.get_mesh_area_names(hdf_path)
|
94
110
|
if not mesh_area_names:
|
95
111
|
return GeoDataFrame()
|
96
112
|
mesh_area_polygons = [
|
@@ -100,7 +116,7 @@ class HdfMesh:
|
|
100
116
|
return GeoDataFrame(
|
101
117
|
{"mesh_name": mesh_area_names, "geometry": mesh_area_polygons},
|
102
118
|
geometry="geometry",
|
103
|
-
crs=
|
119
|
+
crs=HdfBase.get_projection(hdf_file),
|
104
120
|
)
|
105
121
|
except Exception as e:
|
106
122
|
logger.error(f"Error reading mesh areas from {hdf_path}: {str(e)}")
|
@@ -108,7 +124,7 @@ class HdfMesh:
|
|
108
124
|
|
109
125
|
@staticmethod
|
110
126
|
@standardize_input(file_type='geom_hdf')
|
111
|
-
def
|
127
|
+
def get_mesh_cell_polygons(hdf_path: Path) -> GeoDataFrame:
|
112
128
|
"""
|
113
129
|
Return 2D flow mesh cell polygons.
|
114
130
|
|
@@ -120,15 +136,19 @@ class HdfMesh:
|
|
120
136
|
Returns
|
121
137
|
-------
|
122
138
|
GeoDataFrame
|
123
|
-
A GeoDataFrame containing the 2D flow mesh cell polygons
|
139
|
+
A GeoDataFrame containing the 2D flow mesh cell polygons with columns:
|
140
|
+
- mesh_name: name of the mesh area
|
141
|
+
- cell_id: unique identifier for each cell
|
142
|
+
- geometry: polygon geometry of the cell
|
143
|
+
Returns an empty GeoDataFrame if no 2D areas exist or if there's an error.
|
124
144
|
"""
|
125
145
|
try:
|
126
146
|
with h5py.File(hdf_path, 'r') as hdf_file:
|
127
|
-
mesh_area_names = HdfMesh.
|
147
|
+
mesh_area_names = HdfMesh.get_mesh_area_names(hdf_path)
|
128
148
|
if not mesh_area_names:
|
129
149
|
return GeoDataFrame()
|
130
150
|
|
131
|
-
face_gdf = HdfMesh.
|
151
|
+
face_gdf = HdfMesh.get_mesh_cell_faces(hdf_path)
|
132
152
|
|
133
153
|
cell_dict = {"mesh_name": [], "cell_id": [], "geometry": []}
|
134
154
|
for i, mesh_name in enumerate(mesh_area_names):
|
@@ -170,13 +190,14 @@ class HdfMesh:
|
|
170
190
|
)
|
171
191
|
)(face_id_lists)
|
172
192
|
)
|
173
|
-
return GeoDataFrame(cell_dict, geometry="geometry", crs=
|
193
|
+
return GeoDataFrame(cell_dict, geometry="geometry", crs=HdfBase.get_projection(hdf_file))
|
174
194
|
except Exception as e:
|
175
195
|
logger.error(f"Error reading mesh cell polygons from {hdf_path}: {str(e)}")
|
176
196
|
return GeoDataFrame()
|
197
|
+
|
177
198
|
@staticmethod
|
178
199
|
@standardize_input(file_type='plan_hdf')
|
179
|
-
def
|
200
|
+
def get_mesh_cell_points(hdf_path: Path) -> GeoDataFrame:
|
180
201
|
"""
|
181
202
|
Return 2D flow mesh cell center points.
|
182
203
|
|
@@ -192,7 +213,7 @@ class HdfMesh:
|
|
192
213
|
"""
|
193
214
|
try:
|
194
215
|
with h5py.File(hdf_path, 'r') as hdf_file:
|
195
|
-
mesh_area_names = HdfMesh.
|
216
|
+
mesh_area_names = HdfMesh.get_mesh_area_names(hdf_path)
|
196
217
|
if not mesh_area_names:
|
197
218
|
return GeoDataFrame()
|
198
219
|
|
@@ -208,14 +229,14 @@ class HdfMesh:
|
|
208
229
|
cell_center_coords
|
209
230
|
)
|
210
231
|
)
|
211
|
-
return GeoDataFrame(pnt_dict, geometry="geometry", crs=
|
232
|
+
return GeoDataFrame(pnt_dict, geometry="geometry", crs=HdfBase.get_projection(hdf_path))
|
212
233
|
except Exception as e:
|
213
234
|
logger.error(f"Error reading mesh cell points from {hdf_path}: {str(e)}")
|
214
235
|
return GeoDataFrame()
|
215
236
|
|
216
237
|
@staticmethod
|
217
238
|
@standardize_input(file_type='plan_hdf')
|
218
|
-
def
|
239
|
+
def get_mesh_cell_faces(hdf_path: Path) -> GeoDataFrame:
|
219
240
|
"""
|
220
241
|
Return 2D flow mesh cell faces.
|
221
242
|
|
@@ -231,7 +252,7 @@ class HdfMesh:
|
|
231
252
|
"""
|
232
253
|
try:
|
233
254
|
with h5py.File(hdf_path, 'r') as hdf_file:
|
234
|
-
mesh_area_names = HdfMesh.
|
255
|
+
mesh_area_names = HdfMesh.get_mesh_area_names(hdf_path)
|
235
256
|
if not mesh_area_names:
|
236
257
|
return GeoDataFrame()
|
237
258
|
face_dict = {"mesh_name": [], "face_id": [], "geometry": []}
|
@@ -262,14 +283,14 @@ class HdfMesh:
|
|
262
283
|
)
|
263
284
|
coordinates.append(facepoints_coordinates[pnt_b_index])
|
264
285
|
face_dict["geometry"].append(LineString(coordinates))
|
265
|
-
return GeoDataFrame(face_dict, geometry="geometry", crs=
|
286
|
+
return GeoDataFrame(face_dict, geometry="geometry", crs=HdfBase.get_projection(hdf_path))
|
266
287
|
except Exception as e:
|
267
288
|
self.logger.error(f"Error reading mesh cell faces from {hdf_path}: {str(e)}")
|
268
289
|
return GeoDataFrame()
|
269
290
|
|
270
291
|
@staticmethod
|
271
292
|
@standardize_input(file_type='geom_hdf')
|
272
|
-
def
|
293
|
+
def get_mesh_area_attributes(hdf_path: Path) -> pd.DataFrame:
|
273
294
|
"""
|
274
295
|
Return geometry 2D flow area attributes from a HEC-RAS HDF file.
|
275
296
|
|
@@ -280,8 +301,8 @@ class HdfMesh:
|
|
280
301
|
|
281
302
|
Returns
|
282
303
|
-------
|
283
|
-
|
284
|
-
A
|
304
|
+
pd.DataFrame
|
305
|
+
A DataFrame containing the 2D flow area attributes.
|
285
306
|
"""
|
286
307
|
try:
|
287
308
|
with h5py.File(hdf_path, 'r') as hdf_file:
|
@@ -293,20 +314,20 @@ class HdfMesh:
|
|
293
314
|
value = d2_flow_area[name][()]
|
294
315
|
if isinstance(value, bytes):
|
295
316
|
value = value.decode('utf-8') # Decode as UTF-8
|
296
|
-
result[name] = value
|
317
|
+
result[name] = value if not isinstance(value, bytes) else value.decode('utf-8')
|
297
318
|
except Exception as e:
|
298
319
|
logger.warning(f"Error converting attribute '{name}': {str(e)}")
|
299
|
-
return result
|
320
|
+
return pd.DataFrame.from_dict(result, orient='index', columns=['Value'])
|
300
321
|
else:
|
301
322
|
logger.info("No 2D Flow Area attributes found or invalid dataset.")
|
302
|
-
return
|
323
|
+
return pd.DataFrame() # Return an empty DataFrame
|
303
324
|
except Exception as e:
|
304
325
|
logger.error(f"Error reading 2D flow area attributes from {hdf_path}: {str(e)}")
|
305
|
-
return
|
326
|
+
return pd.DataFrame() # Return an empty DataFrame
|
306
327
|
|
307
328
|
@staticmethod
|
308
329
|
@standardize_input(file_type='geom_hdf')
|
309
|
-
def
|
330
|
+
def get_mesh_face_property_tables(hdf_path: Path) -> Dict[str, pd.DataFrame]:
|
310
331
|
"""
|
311
332
|
Extract Face Property Tables for each Face in all 2D Flow Areas.
|
312
333
|
|
@@ -318,12 +339,19 @@ class HdfMesh:
|
|
318
339
|
Returns
|
319
340
|
-------
|
320
341
|
Dict[str, pd.DataFrame]
|
321
|
-
A dictionary where
|
322
|
-
|
342
|
+
A dictionary where:
|
343
|
+
- keys: mesh area names (str)
|
344
|
+
- values: DataFrames with columns:
|
345
|
+
- Face ID: unique identifier for each face
|
346
|
+
- Z: elevation
|
347
|
+
- Area: face area
|
348
|
+
- Wetted Perimeter: wetted perimeter length
|
349
|
+
- Manning's n: Manning's roughness coefficient
|
350
|
+
Returns an empty dictionary if no 2D areas exist or if there's an error.
|
323
351
|
"""
|
324
352
|
try:
|
325
353
|
with h5py.File(hdf_path, 'r') as hdf_file:
|
326
|
-
mesh_area_names = HdfMesh.
|
354
|
+
mesh_area_names = HdfMesh.get_mesh_area_names(hdf_path)
|
327
355
|
if not mesh_area_names:
|
328
356
|
return {}
|
329
357
|
|
@@ -351,3 +379,56 @@ class HdfMesh:
|
|
351
379
|
except Exception as e:
|
352
380
|
logger.error(f"Error extracting face property tables from {hdf_path}: {str(e)}")
|
353
381
|
return {}
|
382
|
+
|
383
|
+
@staticmethod
|
384
|
+
@standardize_input(file_type='geom_hdf')
|
385
|
+
def get_mesh_cell_property_tables(hdf_path: Path) -> Dict[str, pd.DataFrame]:
|
386
|
+
"""
|
387
|
+
Extract Cell Property Tables for each Cell in all 2D Flow Areas.
|
388
|
+
|
389
|
+
Parameters
|
390
|
+
----------
|
391
|
+
hdf_path : Path
|
392
|
+
Path to the HEC-RAS geometry HDF file.
|
393
|
+
|
394
|
+
Returns
|
395
|
+
-------
|
396
|
+
Dict[str, pd.DataFrame]
|
397
|
+
A dictionary where:
|
398
|
+
- keys: mesh area names (str)
|
399
|
+
- values: DataFrames with columns:
|
400
|
+
- Cell ID: unique identifier for each cell
|
401
|
+
- Z: elevation
|
402
|
+
- Volume: cell volume
|
403
|
+
- Surface Area: cell surface area
|
404
|
+
Returns an empty dictionary if no 2D areas exist or if there's an error.
|
405
|
+
"""
|
406
|
+
try:
|
407
|
+
with h5py.File(hdf_path, 'r') as hdf_file:
|
408
|
+
mesh_area_names = HdfMesh.get_mesh_area_names(hdf_path)
|
409
|
+
if not mesh_area_names:
|
410
|
+
return {}
|
411
|
+
|
412
|
+
result = {}
|
413
|
+
for mesh_name in mesh_area_names:
|
414
|
+
cell_elevation_info = hdf_file[f"Geometry/2D Flow Areas/{mesh_name}/Cells Elevation Volume Info"][()]
|
415
|
+
cell_elevation_values = hdf_file[f"Geometry/2D Flow Areas/{mesh_name}/Cells Elevation Volume Values"][()]
|
416
|
+
|
417
|
+
cell_data = []
|
418
|
+
for cell_id, (start_index, count) in enumerate(cell_elevation_info):
|
419
|
+
cell_values = cell_elevation_values[start_index:start_index+count]
|
420
|
+
for z, volume, surface_area in cell_values:
|
421
|
+
cell_data.append({
|
422
|
+
'Cell ID': cell_id,
|
423
|
+
'Z': str(z),
|
424
|
+
'Volume': str(volume),
|
425
|
+
'Surface Area': str(surface_area)
|
426
|
+
})
|
427
|
+
|
428
|
+
result[mesh_name] = pd.DataFrame(cell_data)
|
429
|
+
|
430
|
+
return result
|
431
|
+
|
432
|
+
except Exception as e:
|
433
|
+
logger.error(f"Error extracting cell property tables from {hdf_path}: {str(e)}")
|
434
|
+
return {}
|