ras-commander 0.41.0__py3-none-any.whl → 0.43.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/RasHdf.py DELETED
@@ -1,644 +0,0 @@
1
- """
2
- RasHdf Module
3
-
4
- This module provides utilities for working with RESULTS (Plan) HDF files in HEC-RAS projects.
5
- It contains the RasHdf class, which offers various static methods for extracting,
6
- analyzing, and manipulating data from HEC-RAS RESULTS HDF files.
7
-
8
- Note:
9
- This method is decorated with @hdf_operation, which handles the opening and closing of the HDF file.
10
- The decorator should be used for all methods that directly interact with HDF files.
11
- It ensures proper file handling and error management.
12
-
13
- When using the @hdf_operation decorator:
14
- - The method receives an open h5py.File object as its first argument after 'cls'.
15
- - Error handling for file operations is managed by the decorator.
16
- - The HDF file is automatically closed after the method execution.
17
-
18
- Methods without this decorator must manually handle file opening, closing, and error management.
19
- Failure to use the decorator or properly manage the file can lead to resource leaks or file access errors.
20
-
21
- Example:
22
- @classmethod
23
- @hdf_operation
24
- def example_method(cls, hdf_file: h5py.File, other_args):
25
- # Method implementation using hdf_file
26
-
27
- This module is part of the ras-commander library and uses a centralized logging configuration.
28
-
29
- Logging Configuration:
30
- - The logging is set up in the logging_config.py file.
31
- - A @log_call decorator is available to automatically log function calls.
32
- - Log levels: DEBUG, INFO, WARNING, ERROR, CRITICAL
33
- - Logs are written to both console and a rotating file handler.
34
- - The default log file is 'ras_commander.log' in the 'logs' directory.
35
- - The default log level is INFO.
36
-
37
- To use logging in this module:
38
- 1. Use the @log_call decorator for automatic function call logging.
39
- 2. For additional logging, use logger.[level]() calls (e.g., logger.info(), logger.debug()).
40
- 3. Obtain the logger using: logger = logging.getLogger(__name__)
41
-
42
- Example:
43
- @log_call
44
- def my_function():
45
- logger = logging.getLogger(__name__)
46
- logger.debug("Additional debug information")
47
- # Function logic here
48
- """
49
- import h5py
50
- import numpy as np
51
- import pandas as pd
52
- from typing import Union, List, Optional, Dict, Tuple, Any, Callable
53
- from scipy.spatial import KDTree
54
- from pathlib import Path
55
- from datetime import datetime
56
- import logging
57
- from functools import wraps
58
- from .RasPrj import RasPrj, ras, init_ras_project
59
-
60
- # If you're using RasPrj in type hints, you might need to use string literals to avoid circular imports
61
- from typing import TYPE_CHECKING
62
- if TYPE_CHECKING:
63
- from .RasPrj import RasPrj
64
- from ras_commander import get_logger
65
- from ras_commander.logging_config import log_call
66
-
67
- logger = get_logger(__name__)
68
-
69
- class RasHdf:
70
- """
71
- A utility class for working with HDF files in HEC-RAS projects.
72
-
73
- This class provides static methods for various operations on HDF files,
74
- including listing paths, extracting data, and performing analyses on
75
- HEC-RAS project data stored in HDF format.
76
- """
77
-
78
-
79
- @staticmethod
80
- def hdf_operation(func):
81
- """
82
- A decorator for HDF file operations in the RasHdf class.
83
-
84
- This decorator wraps methods that perform operations on HDF files. It handles:
85
- 1. Resolving the HDF filename from various input types.
86
- 2. Opening and closing the HDF file.
87
- 3. Error handling and logging.
88
- 4. Applying the decorated function as a class method.
89
-
90
- Args:
91
- func (Callable): The function to be decorated.
92
-
93
- Returns:
94
- Callable: A wrapped version of the input function as a class method.
95
-
96
- Raises:
97
- ValueError: If the HDF file is not found.
98
-
99
- Usage:
100
- @RasHdf.hdf_operation
101
- def some_hdf_method(cls, hdf_file, ...):
102
- # Method implementation
103
- """
104
- @wraps(func)
105
- def wrapper(cls, hdf_input: Union[str, Path], *args: Any, **kwargs: Any) -> Any:
106
- from ras_commander import ras # Import here to avoid circular import
107
- ras_obj = kwargs.pop('ras_object', None) or ras
108
- try:
109
- hdf_filename = cls._get_hdf_filename(hdf_input, ras_obj)
110
- if hdf_filename is None:
111
- raise ValueError(f"HDF file {hdf_input} not found. Use a try-except block to catch this error.")
112
- with h5py.File(hdf_filename, 'r') as hdf_file:
113
- return func(cls, hdf_file, *args, **kwargs)
114
- except Exception as e:
115
- logger.error(f"Error in {func.__name__}: {e}")
116
- return None
117
- return classmethod(wrapper)
118
-
119
-
120
- @classmethod
121
- @log_call
122
- def get_runtime_data(cls, hdf_input: Union[str, Path], ras_object=None) -> Optional[pd.DataFrame]:
123
- """
124
- Extract runtime and compute time data from a single HDF file.
125
-
126
- Args:
127
- hdf_input (Union[str, Path]): The plan number or full path to the HDF file.
128
- ras_object (RasPrj, optional): The RAS project object. If None, uses the global ras instance.
129
-
130
- Returns:
131
- Optional[pd.DataFrame]: DataFrame containing runtime and compute time data, or None if data extraction fails.
132
-
133
- Example:
134
- >>> runtime_df = RasHdf.get_runtime_data("path/to/file.hdf")
135
- >>> if runtime_df is not None:
136
- ... print(runtime_df.head())
137
- """
138
- with h5py.File(cls._get_hdf_filename(hdf_input, ras_object), 'r') as hdf_file:
139
- logger.info(f"Extracting Plan Information from: {Path(hdf_file.filename).name}")
140
- plan_info = hdf_file.get('/Plan Data/Plan Information')
141
- if plan_info is None:
142
- logger.warning("Group '/Plan Data/Plan Information' not found.")
143
- return None
144
-
145
- plan_name = plan_info.attrs.get('Plan Name', 'Unknown')
146
- plan_name = plan_name.decode('utf-8') if isinstance(plan_name, bytes) else plan_name
147
- logger.info(f"Plan Name: {plan_name}")
148
-
149
- start_time_str = plan_info.attrs.get('Simulation Start Time', 'Unknown')
150
- end_time_str = plan_info.attrs.get('Simulation End Time', 'Unknown')
151
- start_time_str = start_time_str.decode('utf-8') if isinstance(start_time_str, bytes) else start_time_str
152
- end_time_str = end_time_str.decode('utf-8') if isinstance(end_time_str, bytes) else end_time_str
153
-
154
- start_time = datetime.strptime(start_time_str, "%d%b%Y %H:%M:%S")
155
- end_time = datetime.strptime(end_time_str, "%d%b%Y %H:%M:%S")
156
- simulation_duration = end_time - start_time
157
- simulation_hours = simulation_duration.total_seconds() / 3600
158
-
159
- logger.info(f"Simulation Start Time: {start_time_str}")
160
- logger.info(f"Simulation End Time: {end_time_str}")
161
- logger.info(f"Simulation Duration (hours): {simulation_hours}")
162
-
163
- compute_processes = hdf_file.get('/Results/Summary/Compute Processes')
164
- if compute_processes is None:
165
- logger.warning("Dataset '/Results/Summary/Compute Processes' not found.")
166
- return None
167
-
168
- process_names = [name.decode('utf-8') for name in compute_processes['Process'][:]]
169
- filenames = [filename.decode('utf-8') for filename in compute_processes['Filename'][:]]
170
- completion_times = compute_processes['Compute Time (ms)'][:]
171
-
172
- compute_processes_df = pd.DataFrame({
173
- 'Process': process_names,
174
- 'Filename': filenames,
175
- 'Compute Time (ms)': completion_times,
176
- 'Compute Time (s)': completion_times / 1000,
177
- 'Compute Time (hours)': completion_times / (1000 * 3600)
178
- })
179
-
180
- logger.debug("Compute processes DataFrame:")
181
- logger.debug(compute_processes_df)
182
-
183
- compute_processes_summary = {
184
- 'Plan Name': [plan_name],
185
- 'File Name': [Path(hdf_file.filename).name],
186
- 'Simulation Start Time': [start_time_str],
187
- 'Simulation End Time': [end_time_str],
188
- 'Simulation Duration (s)': [simulation_duration.total_seconds()],
189
- 'Simulation Time (hr)': [simulation_hours],
190
- 'Completing Geometry (hr)': [compute_processes_df[compute_processes_df['Process'] == 'Completing Geometry']['Compute Time (hours)'].values[0] if 'Completing Geometry' in compute_processes_df['Process'].values else 'N/A'],
191
- 'Preprocessing Geometry (hr)': [compute_processes_df[compute_processes_df['Process'] == 'Preprocessing Geometry']['Compute Time (hours)'].values[0] if 'Preprocessing Geometry' in compute_processes_df['Process'].values else 'N/A'],
192
- 'Completing Event Conditions (hr)': [compute_processes_df[compute_processes_df['Process'] == 'Completing Event Conditions']['Compute Time (hours)'].values[0] if 'Completing Event Conditions' in compute_processes_df['Process'].values else 'N/A'],
193
- 'Unsteady Flow Computations (hr)': [compute_processes_df[compute_processes_df['Process'] == 'Unsteady Flow Computations']['Compute Time (hours)'].values[0] if 'Unsteady Flow Computations' in compute_processes_df['Process'].values else 'N/A'],
194
- 'Complete Process (hr)': [compute_processes_df['Compute Time (hours)'].sum()]
195
- }
196
-
197
- compute_processes_summary['Unsteady Flow Speed (hr/hr)'] = [simulation_hours / compute_processes_summary['Unsteady Flow Computations (hr)'][0] if compute_processes_summary['Unsteady Flow Computations (hr)'][0] != 'N/A' else 'N/A']
198
- compute_processes_summary['Complete Process Speed (hr/hr)'] = [simulation_hours / compute_processes_summary['Complete Process (hr)'][0] if compute_processes_summary['Complete Process (hr)'][0] != 'N/A' else 'N/A']
199
-
200
- compute_summary_df = pd.DataFrame(compute_processes_summary)
201
- logger.debug("Compute summary DataFrame:")
202
- logger.debug(compute_summary_df)
203
-
204
- return compute_summary_df
205
-
206
- # List 2D Flow Area Groups (needed for later functions that extract specific datasets)
207
-
208
- @classmethod
209
- @log_call
210
- def get_2d_flow_area_names(cls, hdf_input: Union[str, Path], ras_object=None) -> Optional[List[str]]:
211
- """
212
- List 2D Flow Area names from the HDF file.
213
-
214
- Args:
215
- hdf_input (Union[str, Path]): The plan number or full path to the HDF file.
216
- ras_object (RasPrj, optional): The RAS project object. If None, uses the global ras instance.
217
-
218
- Returns:
219
- Optional[List[str]]: List of 2D Flow Area names, or None if no 2D Flow Areas are found.
220
-
221
- Raises:
222
- ValueError: If no 2D Flow Areas are found in the HDF file.
223
- """
224
- with h5py.File(cls._get_hdf_filename(hdf_input, ras_object), 'r') as hdf_file:
225
- if 'Geometry/2D Flow Areas' in hdf_file:
226
- group = hdf_file['Geometry/2D Flow Areas']
227
- group_names = [name for name in group.keys() if isinstance(group[name], h5py.Group)]
228
- if not group_names:
229
- logger.warning("No 2D Flow Areas found in the HDF file")
230
- return None
231
- logger.info(f"Found {len(group_names)} 2D Flow Areas")
232
- return group_names
233
- else:
234
- logger.warning("No 2D Flow Areas found in the HDF file")
235
- return None
236
- @classmethod
237
- @log_call
238
- def get_2d_flow_area_attributes(cls, hdf_input: Union[str, Path], ras_object=None) -> Optional[pd.DataFrame]:
239
- """
240
- Extract 2D Flow Area Attributes from the HDF file.
241
-
242
- Args:
243
- hdf_input (Union[str, Path]): The plan number or full path to the HDF file.
244
- ras_object (RasPrj, optional): The RAS project object. If None, uses the global ras instance.
245
-
246
- Returns:
247
- Optional[pd.DataFrame]: DataFrame containing 2D Flow Area Attributes, or None if attributes are not found.
248
-
249
- Example:
250
- >>> attributes_df = RasHdf.get_2d_flow_area_attributes("path/to/file.hdf")
251
- >>> if attributes_df is not None:
252
- ... print(attributes_df.head())
253
- ... else:
254
- ... print("No 2D Flow Area attributes found")
255
- """
256
- with h5py.File(cls._get_hdf_filename(hdf_input, ras_object), 'r') as hdf_file:
257
- if 'Geometry/2D Flow Areas/Attributes' in hdf_file:
258
- attributes = hdf_file['Geometry/2D Flow Areas/Attributes'][()]
259
- attributes_df = pd.DataFrame(attributes)
260
- return attributes_df
261
- else:
262
- return None
263
-
264
- @classmethod
265
- @log_call
266
- def get_cell_info(cls, hdf_input: Union[str, Path], ras_object=None) -> Optional[pd.DataFrame]:
267
- """
268
- Extract Cell Info from the HDF file.
269
-
270
- Args:
271
- hdf_input (Union[str, Path]): The plan number or full path to the HDF file.
272
- ras_object (RasPrj, optional): The RAS project object. If None, uses the global ras instance.
273
-
274
- Returns:
275
- Optional[pd.DataFrame]: DataFrame containing Cell Info, or None if the data is not found.
276
-
277
- Example:
278
- >>> cell_info_df = RasHdf.get_cell_info("path/to/file.hdf")
279
- >>> if cell_info_df is not None:
280
- ... print(cell_info_df.head())
281
- ... else:
282
- ... print("No Cell Info found")
283
- """
284
- with h5py.File(cls._get_hdf_filename(hdf_input, ras_object), 'r') as hdf_file:
285
- cell_info_df = cls._extract_dataset(hdf_file, 'Geometry/2D Flow Areas/Cell Info', ['Start', 'End'])
286
- return cell_info_df
287
-
288
- @classmethod
289
- @log_call
290
- def get_cell_points(cls, hdf_input: Union[str, Path], ras_object=None) -> Optional[pd.DataFrame]:
291
- """
292
- Extract Cell Points from the HDF file.
293
-
294
- Args:
295
- hdf_input (Union[str, Path]): The plan number or full path to the HDF file.
296
- ras_object (RasPrj, optional): The RAS project object. If None, uses the global ras instance.
297
-
298
- Returns:
299
- Optional[pd.DataFrame]: DataFrame containing Cell Points, or None if the data is not found.
300
-
301
- Example:
302
- >>> cell_points_df = RasHdf.get_cell_points("path/to/file.hdf")
303
- >>> if cell_points_df is not None:
304
- ... print(cell_points_df.head())
305
- ... else:
306
- ... print("No Cell Points found")
307
- """
308
- with h5py.File(cls._get_hdf_filename(hdf_input, ras_object), 'r') as hdf_file:
309
- cell_points_df = cls._extract_dataset(hdf_file, 'Geometry/2D Flow Areas/Cell Points', ['X', 'Y'])
310
- return cell_points_df
311
-
312
- @classmethod
313
- @log_call
314
- def get_polygon_info_and_parts(cls, hdf_input: Union[str, Path], area_name: Optional[str] = None, ras_object=None) -> Tuple[Optional[pd.DataFrame], Optional[pd.DataFrame]]:
315
- """
316
- Extract Polygon Info and Parts from the HDF file.
317
-
318
- Args:
319
- hdf_input (Union[str, Path]): The plan number or full path to the HDF file.
320
- area_name (Optional[str]): Name of the 2D Flow Area to extract data from.
321
- If None, uses the first 2D Area Name found.
322
- ras_object (RasPrj, optional): The RAS project object. If None, uses the global ras instance.
323
-
324
- Returns:
325
- Tuple[Optional[pd.DataFrame], Optional[pd.DataFrame]]:
326
- Two DataFrames containing Polygon Info and Polygon Parts respectively,
327
- or None for each if the corresponding data is not found.
328
-
329
- Example:
330
- >>> polygon_info_df, polygon_parts_df = RasHdf.get_polygon_info_and_parts("path/to/file.hdf")
331
- >>> if polygon_info_df is not None and polygon_parts_df is not None:
332
- ... print("Polygon Info:")
333
- ... print(polygon_info_df.head())
334
- ... print("Polygon Parts:")
335
- ... print(polygon_parts_df.head())
336
- ... else:
337
- ... print("Polygon data not found")
338
- """
339
- with h5py.File(cls._get_hdf_filename(hdf_input, ras_object), 'r') as hdf_file:
340
- area_name = cls._get_area_name(hdf_file, area_name, hdf_file.filename)
341
- base_path = f'Geometry/2D Flow Areas'
342
- polygon_info_df = cls._extract_dataset(hdf_file, f'{base_path}/Polygon Info', ['Column1', 'Column2', 'Column3', 'Column4'])
343
- polygon_parts_df = cls._extract_dataset(hdf_file, f'{base_path}/Polygon Parts', ['Start', 'Count'])
344
- return polygon_info_df, polygon_parts_df
345
-
346
- @classmethod
347
- @log_call
348
- def get_polygon_points(cls, hdf_input: Union[str, Path], area_name: Optional[str] = None, ras_object=None) -> Optional[pd.DataFrame]:
349
- """
350
- Extract Polygon Points from the HDF file.
351
-
352
- Args:
353
- hdf_input (Union[str, Path]): The plan number or full path to the HDF file.
354
- area_name (Optional[str]): Name of the 2D Flow Area to extract data from.
355
- If None, uses the first 2D Area Name found.
356
- ras_object (RasPrj, optional): The RAS project object. If None, uses the global ras instance.
357
-
358
- Returns:
359
- Optional[pd.DataFrame]: DataFrame containing Polygon Points, or None if the data is not found.
360
- """
361
- with h5py.File(cls._get_hdf_filename(hdf_input, ras_object), 'r') as hdf_file:
362
- area_name = cls._get_area_name(hdf_file, area_name, hdf_file.filename)
363
- polygon_points_path = f'Geometry/2D Flow Areas/Polygon Points'
364
- if polygon_points_path in hdf_file:
365
- polygon_points = hdf_file[polygon_points_path][()]
366
- polygon_points_df = pd.DataFrame(polygon_points, columns=['X', 'Y'])
367
- return polygon_points_df
368
- else:
369
- return None
370
-
371
- @classmethod
372
- @log_call
373
- def get_cells_center_data(cls, hdf_input: Union[str, Path], area_name: Optional[str] = None, ras_object=None) -> Tuple[Optional[pd.DataFrame], Optional[pd.DataFrame]]:
374
- """
375
- Extract Cells Center Coordinates and Manning's n from the HDF file.
376
-
377
- Args:
378
- hdf_input (Union[str, Path]): The plan number or full path to the HDF file.
379
- area_name (Optional[str]): Name of the 2D Flow Area to extract data from.
380
- If None, uses the first 2D Area Name found.
381
- ras_object (RasPrj, optional): The RAS project object. If None, uses the global ras instance.
382
-
383
- Returns:
384
- Tuple[Optional[pd.DataFrame], Optional[pd.DataFrame]]:
385
- Two DataFrames containing Cells Center Coordinates and Manning's n respectively,
386
- or None for each if the corresponding data is not found.
387
-
388
- Example:
389
- >>> coords_df, mannings_df = RasHdf.get_cells_center_data("path/to/file.hdf")
390
- >>> if coords_df is not None and mannings_df is not None:
391
- ... print("Cell Center Coordinates:")
392
- ... print(coords_df.head())
393
- ... print("Manning's n:")
394
- ... print(mannings_df.head())
395
- ... else:
396
- ... print("Cell center data not found")
397
- """
398
- try:
399
- hdf_filename = cls._get_hdf_filename(hdf_input, ras_object)
400
- with h5py.File(hdf_filename, 'r') as hdf_file:
401
- area_name = cls._get_area_name(hdf_file, area_name, hdf_file.filename)
402
- base_path = f'Geometry/2D Flow Areas/{area_name}'
403
- cells_center_coord_path = f'{base_path}/Cells Center Coordinate'
404
- cells_manning_n_path = f'{base_path}/Cells Center Manning\'s n'
405
- cells_center_coord_df = cls._extract_dataset(hdf_file, cells_center_coord_path, ['X', 'Y'])
406
- cells_manning_n_df = cls._extract_dataset(hdf_file, cells_manning_n_path, ['Manning\'s n'])
407
- return cells_center_coord_df, cells_manning_n_df
408
- except Exception as e:
409
- return None, None
410
-
411
- @classmethod
412
- @log_call
413
- def get_faces_area_elevation_data(cls, hdf_input: Union[str, Path], area_name: Optional[str] = None, ras_object=None) -> Optional[pd.DataFrame]:
414
- """
415
- Extract Faces Area Elevation Values from the HDF file.
416
-
417
- Args:
418
- hdf_input (Union[str, Path]): The plan number or full path to the HDF file.
419
- area_name (Optional[str]): Name of the 2D Flow Area to extract data from.
420
- If None, uses the first 2D Area Name found.
421
- ras_object (RasPrj, optional): The RAS project object. If None, uses the global ras instance.
422
-
423
- Returns:
424
- Optional[pd.DataFrame]: DataFrame containing Faces Area Elevation Values, or None if the data is not found.
425
-
426
- Example:
427
- >>> elevation_df = RasHdf.get_faces_area_elevation_data("path/to/file.hdf")
428
- >>> if elevation_df is not None:
429
- ... print(elevation_df.head())
430
- ... else:
431
- ... print("No Faces Area Elevation data found")
432
- """
433
- with h5py.File(cls._get_hdf_filename(hdf_input, ras_object), 'r') as hdf_file:
434
- area_name = cls._get_area_name(hdf_file, area_name, hdf_file.filename)
435
- base_path = f'Geometry/2D Flow Areas/{area_name}'
436
- area_elev_values_path = f'{base_path}/Faces Area Elevation Values'
437
-
438
- if area_elev_values_path in hdf_file:
439
- area_elev_values = hdf_file[area_elev_values_path][()]
440
- area_elev_values_df = pd.DataFrame(area_elev_values, columns=['Elevation', 'Area', 'Wetted Perimeter', 'Manning\'s n'])
441
- return area_elev_values_df
442
- else:
443
- return None
444
-
445
- @classmethod
446
- @log_call
447
- def get_faces_indexes(cls, hdf_input: Union[str, Path], area_name: Optional[str] = None, ras_object=None) -> Tuple[Optional[pd.DataFrame], Optional[pd.DataFrame]]:
448
- """
449
- Extract Faces Cell and FacePoint Indexes from the HDF file.
450
-
451
- Args:
452
- hdf_input (Union[str, Path]): The plan number or full path to the HDF file.
453
- area_name (Optional[str]): Name of the 2D Flow Area to extract data from.
454
- If None, uses the first 2D Area Name found.
455
- ras_object (RasPrj, optional): The RAS project object. If None, uses the global ras instance.
456
-
457
- Returns:
458
- Tuple[Optional[pd.DataFrame], Optional[pd.DataFrame]]:
459
- Two DataFrames containing Faces Cell Indexes and FacePoint Indexes respectively,
460
- or None for each if the corresponding data is not found.
461
-
462
- Example:
463
- >>> cell_indexes_df, facepoint_indexes_df = RasHdf.get_faces_indexes("path/to/file.hdf")
464
- >>> if cell_indexes_df is not None and facepoint_indexes_df is not None:
465
- ... print("Faces Cell Indexes:")
466
- ... print(cell_indexes_df.head())
467
- ... print("Faces FacePoint Indexes:")
468
- ... print(facepoint_indexes_df.head())
469
- ... else:
470
- ... print("Faces indexes data not found")
471
- """
472
- with h5py.File(cls._get_hdf_filename(hdf_input, ras_object), 'r') as hdf_file:
473
- area_name = cls._get_area_name(hdf_file, area_name, hdf_file.filename)
474
-
475
- base_path = f'Geometry/2D Flow Areas/{area_name}'
476
- cell_indexes_path = f'{base_path}/Faces Cell Indexes'
477
- facepoint_indexes_path = f'{base_path}/Faces FacePoint Indexes'
478
-
479
- cell_indexes_df = cls._extract_dataset(hdf_file, cell_indexes_path, ['Left Cell', 'Right Cell'])
480
- facepoint_indexes_df = cls._extract_dataset(hdf_file, facepoint_indexes_path, ['Start FacePoint', 'End FacePoint'])
481
-
482
- return cell_indexes_df, facepoint_indexes_df
483
-
484
- @classmethod
485
- @log_call
486
- def get_faces_elevation_data(cls, hdf_input: Union[str, Path], area_name: Optional[str] = None, ras_object=None) -> Tuple[Optional[pd.DataFrame], Optional[pd.DataFrame]]:
487
- """
488
- Extract Faces Low Elevation Centroid and Minimum Elevation from the HDF file.
489
-
490
- Args:
491
- hdf_input (Union[str, Path]): The plan number or full path to the HDF file.
492
- area_name (Optional[str]): Name of the 2D Flow Area to extract data from.
493
- If None, uses the first 2D Area Name found.
494
- ras_object (RasPrj, optional): The RAS project object. If None, uses the global ras instance.
495
-
496
- Returns:
497
- Tuple[Optional[pd.DataFrame], Optional[pd.DataFrame]]:
498
- DataFrames containing Faces Low Elevation Centroid and Minimum Elevation.
499
- """
500
- with h5py.File(cls._get_hdf_filename(hdf_input, ras_object), 'r') as hdf_file:
501
- area_name = cls._get_area_name(hdf_file, area_name, hdf_file.filename)
502
-
503
- base_path = f'Geometry/2D Flow Areas/{area_name}'
504
- low_elev_centroid = cls._extract_dataset(hdf_file, f'{base_path}/Faces Low Elevation Centroid', ['Low Elevation Centroid'])
505
- min_elevation = cls._extract_dataset(hdf_file, f'{base_path}/Faces Minimum Elevation', ['Minimum Elevation'])
506
-
507
- return low_elev_centroid, min_elevation
508
-
509
- @classmethod
510
- @log_call
511
- def get_faces_vector_data(
512
- cls,
513
- hdf_input: Union[str, Path],
514
- area_name: Optional[str] = None,
515
- ras_object=None
516
- ) -> Optional[pd.DataFrame]:
517
- """
518
- Extract Faces NormalUnitVector and Length from the HDF file.
519
-
520
- Args:
521
- hdf_input (Union[str, Path]): The plan number or full path to the HDF file.
522
- area_name (Optional[str]): Name of the 2D Flow Area to extract data from.
523
- If None, uses the first 2D Area Name found.
524
- ras_object (RasPrj, optional): The RAS project object. If None, uses the global ras instance.
525
-
526
- Returns:
527
- Optional[pd.DataFrame]: DataFrame containing Faces NormalUnitVector and Length.
528
- """
529
- with h5py.File(cls._get_hdf_filename(hdf_input, ras_object), 'r') as hdf_file:
530
- area_name = cls._get_area_name(hdf_file, area_name, hdf_file.filename)
531
-
532
- base_path = f'Geometry/2D Flow Areas/{area_name}'
533
- vector_data = cls._extract_dataset(hdf_file, f'{base_path}/Faces NormalUnitVector and Length', ['NormalX', 'NormalY', 'Length'])
534
-
535
- return vector_data
536
-
537
- @classmethod
538
- @log_call
539
- def get_faces_perimeter_data(
540
- cls,
541
- hdf_input: Union[str, Path],
542
- area_name: Optional[str] = None,
543
- ras_object=None
544
- ) -> Tuple[Optional[pd.DataFrame], Optional[pd.DataFrame]]:
545
- """
546
- Extract Faces Perimeter Info and Values from the HDF file.
547
-
548
- Args:
549
- hdf_input (Union[str, Path]): The plan number or full path to the HDF file.
550
- area_name (Optional[str]): Name of the 2D Flow Area to extract data from.
551
- If None, uses the first 2D Area Name found.
552
- ras_object (RasPrj, optional): The RAS project object. If None, uses the global ras instance.
553
-
554
- Returns:
555
- Tuple[Optional[pd.DataFrame], Optional[pd.DataFrame]]:
556
- DataFrames containing Faces Perimeter Info and Values.
557
-
558
- Raises:
559
- ValueError: If no HDF file is found for the given plan number.
560
- FileNotFoundError: If the specified HDF file does not exist.
561
-
562
- Example:
563
- >>> perimeter_info_df, perimeter_values_df = RasHdf.get_faces_perimeter_data("path/to/file.hdf")
564
- >>> if perimeter_info_df is not None and perimeter_values_df is not None:
565
- ... print("Perimeter Info:")
566
- ... print(perimeter_info_df.head())
567
- ... print("Perimeter Values:")
568
- ... print(perimeter_values_df.head())
569
- ... else:
570
- ... print("Perimeter data not found")
571
- """
572
- with h5py.File(cls._get_hdf_filename(hdf_input, ras_object), 'r') as hdf_file:
573
- area_name = cls._get_area_name(hdf_file, area_name, hdf_file.filename)
574
-
575
- base_path = f'Geometry/2D Flow Areas/{area_name}'
576
- perimeter_info = cls._extract_dataset(hdf_file, f'{base_path}/Faces Perimeter Info', ['Start', 'Count'])
577
- perimeter_values = cls._extract_dataset(hdf_file, f'{base_path}/Faces Perimeter Values', ['X', 'Y'])
578
-
579
- return perimeter_info, perimeter_values
580
-
581
- @classmethod
582
- @log_call
583
- def get_infiltration_data(
584
- cls,
585
- hdf_input: Union[str, Path],
586
- area_name: Optional[str] = None,
587
- ras_object=None
588
- ) -> Tuple[Optional[pd.DataFrame], Optional[pd.DataFrame], Optional[pd.DataFrame], Optional[pd.DataFrame], Optional[pd.DataFrame]]:
589
- """
590
- Extract Infiltration Data from the HDF file.
591
-
592
- Args:
593
- hdf_input (Union[str, Path]): The plan number or full path to the HDF file.
594
- area_name (Optional[str]): Name of the 2D Flow Area to extract data from.
595
- If None, uses the first 2D Area Name found.
596
- ras_object (RasPrj, optional): The RAS project object. If None, uses the global ras instance.
597
-
598
- Returns:
599
- Tuple[Optional[pd.DataFrame], Optional[pd.DataFrame], Optional[pd.DataFrame], Optional[pd.DataFrame], Optional[pd.DataFrame]]:
600
- DataFrames containing various Infiltration Data
601
- """
602
- with h5py.File(cls._get_hdf_filename(hdf_input, ras_object), 'r') as hdf_file:
603
- area_name = cls._get_area_name(hdf_file, area_name, hdf_file.filename)
604
-
605
- base_path = f'Geometry/2D Flow Areas/{area_name}/Infiltration'
606
-
607
- cell_classifications = cls._extract_dataset(hdf_file, f'{base_path}/Cell Center Classifications', ['Cell Classification'])
608
- face_classifications = cls._extract_dataset(hdf_file, f'{base_path}/Face Center Classifications', ['Face Classification'])
609
- initial_deficit = cls._extract_dataset(hdf_file, f'{base_path}/Initial Deficit', ['Initial Deficit'])
610
- maximum_deficit = cls._extract_dataset(hdf_file, f'{base_path}/Maximum Deficit', ['Maximum Deficit'])
611
- potential_percolation_rate = cls._extract_dataset(hdf_file, f'{base_path}/Potential Percolation Rate', ['Potential Percolation Rate'])
612
-
613
- return cell_classifications, face_classifications, initial_deficit, maximum_deficit, potential_percolation_rate
614
-
615
- @classmethod
616
- @log_call
617
- def get_percent_impervious_data(
618
- cls,
619
- hdf_input: Union[str, Path],
620
- area_name: Optional[str] = None,
621
- ras_object=None
622
- ) -> Tuple[Optional[pd.DataFrame], Optional[pd.DataFrame], Optional[pd.DataFrame]]:
623
- """
624
- Extract Percent Impervious Data from the HDF file.
625
-
626
- Args:
627
- hdf_input (Union[str, Path]): The plan number or full path to the HDF file.
628
- area_name (Optional[str]): Name of the 2D Flow Area to extract data from.
629
- If None, uses the first 2D Area Name found.
630
- ras_object (RasPrj, optional): The RAS project object. If None, uses the global ras instance.
631
-
632
- Returns:
633
- Tuple[Optional[pd.DataFrame], Optional[pd.DataFrame], Optional[pd.DataFrame]]:
634
- DataFrames containing Cell Classifications, Face Classifications, and Percent Impervious Data
635
- """
636
- with h5py.File(cls._get_hdf_filename(hdf_input, ras_object), 'r') as hdf_file:
637
- area_name = cls._get_area_name(hdf_file, area_name, hdf_file.filename)
638
-
639
- base_path = f'Geometry/2D Flow Areas/{area_name}/Percent Impervious'
640
- cell_classifications = cls._extract_dataset(hdf_file, f'{base_path}/Cell Center Classifications', ['Cell Classification'])
641
- face_classifications = cls._extract_dataset(hdf_file, f'{base_path}/Face Center Classifications', ['Face Classification'])
642
- percent_impervious = cls._extract_dataset(hdf_file, f'{base_path}/Percent Impervious', ['Percent Impervious'])
643
-
644
- return cell_classifications, face_classifications, percent_impervious
@@ -1,16 +0,0 @@
1
- ras_commander/RasCmdr.py,sha256=_opzPdFuja2wXmFu2iayP6igJqGeILAavPC1XsCC6ks,25010
2
- ras_commander/RasExamples.py,sha256=XKnbqQTc5t43iFkjJLF3lgqZW4YaGh-79sGYDAmtqiU,19245
3
- ras_commander/RasGeo.py,sha256=GiRtgRg0JsuCDkpYS6SkJoaLksPUskHGDRpJLYVUMz8,5411
4
- ras_commander/RasGpt.py,sha256=-524sU_PBPxCmjDKJbDXg6Q3k1-Uhk2tYj6HeW8QFJ8,4201
5
- ras_commander/RasHdf.py,sha256=Und1QcOpuHD2dCZvxPiwNXCoEQs_XG9WFGBlNwMDDrE,32689
6
- ras_commander/RasPlan.py,sha256=GT8-2X_Or6ufrfpQPv6G3WMLuTNsOO0OCYh1jrbsqZ0,40303
7
- ras_commander/RasPrj.py,sha256=-iEltmz7B-wXrs4R3iuj6tXX9i-6u_yEl7ZcLmasoWs,33980
8
- ras_commander/RasUnsteady.py,sha256=37GKaYNJZ39y-khhy01LbHwZnf7HT0V2XKQ-UUaJHlY,4639
9
- ras_commander/RasUtils.py,sha256=vA3DzvNMeKH3A4cMQLK2a3dihftXBGypYvoi-ckMlSs,29480
10
- ras_commander/__init__.py,sha256=h4xld8gpvjTTpOOJcPKXwsRMUVGtg8tRqf64AHwZB3k,1051
11
- ras_commander/logging_config.py,sha256=5bYd_5KMlf81bXsiu2mABBlw0USMhcu5uRv8DIYJSFE,2317
12
- ras_commander-0.41.0.dist-info/LICENSE,sha256=_pbd6qHnlsz1iQ-ozDW_49r86BZT6CRwO2iBtw0iN6M,457
13
- ras_commander-0.41.0.dist-info/METADATA,sha256=wYlsP7QFa-lYa5CUKg8Mbi6VFwojfJm_l1GK_TVgCew,15671
14
- ras_commander-0.41.0.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
15
- ras_commander-0.41.0.dist-info/top_level.txt,sha256=i76S7eKLFC8doKcXDl3aiOr9RwT06G8adI6YuKbQDaA,14
16
- ras_commander-0.41.0.dist-info/RECORD,,
File without changes