ras-commander 0.70.0__py3-none-any.whl → 0.72.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/HdfInfiltration.py +696 -416
- ras_commander/RasCmdr.py +189 -40
- ras_commander/RasGeo.py +407 -21
- ras_commander/RasMap.py +252 -0
- ras_commander/RasPlan.py +28 -25
- ras_commander/RasPrj.py +243 -79
- ras_commander/RasUnsteady.py +162 -68
- ras_commander/__init__.py +1 -1
- {ras_commander-0.70.0.dist-info → ras_commander-0.72.0.dist-info}/METADATA +15 -5
- {ras_commander-0.70.0.dist-info → ras_commander-0.72.0.dist-info}/RECORD +13 -15
- {ras_commander-0.70.0.dist-info → ras_commander-0.72.0.dist-info}/WHEEL +1 -1
- ras_commander/RasGpt.py +0 -27
- ras_commander/RasMapper.py +0 -24
- ras_commander/RasToGo.py +0 -37
- {ras_commander-0.70.0.dist-info → ras_commander-0.72.0.dist-info/licenses}/LICENSE +0 -0
- {ras_commander-0.70.0.dist-info → ras_commander-0.72.0.dist-info}/top_level.txt +0 -0
ras_commander/RasCmdr.py
CHANGED
@@ -99,23 +99,66 @@ class RasCmdr:
|
|
99
99
|
overwrite_dest=False
|
100
100
|
):
|
101
101
|
"""
|
102
|
-
Execute a HEC-RAS plan.
|
102
|
+
Execute a single HEC-RAS plan in a specified location.
|
103
|
+
|
104
|
+
This function runs a HEC-RAS plan by launching the HEC-RAS executable through command line,
|
105
|
+
allowing for destination folder specification, core count control, and geometry preprocessor management.
|
103
106
|
|
104
107
|
Args:
|
105
108
|
plan_number (str, Path): The plan number to execute (e.g., "01", "02") or the full path to the plan file.
|
109
|
+
Recommended to use two-digit strings for plan numbers for consistency (e.g., "01" instead of 1).
|
106
110
|
dest_folder (str, Path, optional): Name of the folder or full path for computation.
|
107
111
|
If a string is provided, it will be created in the same parent directory as the project folder.
|
108
112
|
If a full path is provided, it will be used as is.
|
113
|
+
If None, computation occurs in the original project folder, modifying the original project.
|
109
114
|
ras_object (RasPrj, optional): Specific RAS object to use. If None, uses the global ras instance.
|
115
|
+
Useful when working with multiple projects simultaneously.
|
110
116
|
clear_geompre (bool, optional): Whether to clear geometry preprocessor files. Defaults to False.
|
111
|
-
|
117
|
+
Set to True when geometry has been modified to force recomputation of preprocessor files.
|
118
|
+
num_cores (int, optional): Number of cores to use for the plan execution.
|
119
|
+
If None, the current setting in the plan file is not changed.
|
120
|
+
Generally, 2-4 cores provides good performance for most models.
|
112
121
|
overwrite_dest (bool, optional): If True, overwrite the destination folder if it exists. Defaults to False.
|
122
|
+
Set to True to replace an existing destination folder with the same name.
|
113
123
|
|
114
124
|
Returns:
|
115
125
|
bool: True if the execution was successful, False otherwise.
|
116
126
|
|
117
127
|
Raises:
|
118
128
|
ValueError: If the specified dest_folder already exists and is not empty, and overwrite_dest is False.
|
129
|
+
FileNotFoundError: If the plan file or project file cannot be found.
|
130
|
+
PermissionError: If there are issues accessing or writing to the destination folder.
|
131
|
+
subprocess.CalledProcessError: If the HEC-RAS execution fails.
|
132
|
+
|
133
|
+
Examples:
|
134
|
+
# Run a plan in the original project folder
|
135
|
+
RasCmdr.compute_plan("01")
|
136
|
+
|
137
|
+
# Run a plan in a separate folder
|
138
|
+
RasCmdr.compute_plan("01", dest_folder="computation_folder")
|
139
|
+
|
140
|
+
# Run a plan with a specific number of cores
|
141
|
+
RasCmdr.compute_plan("01", num_cores=4)
|
142
|
+
|
143
|
+
# Run a plan in a specific folder, overwriting if it exists
|
144
|
+
RasCmdr.compute_plan("01", dest_folder="computation_folder", overwrite_dest=True)
|
145
|
+
|
146
|
+
# Run a plan in a specific folder with multiple options
|
147
|
+
RasCmdr.compute_plan(
|
148
|
+
"01",
|
149
|
+
dest_folder="computation_folder",
|
150
|
+
num_cores=2,
|
151
|
+
clear_geompre=True,
|
152
|
+
overwrite_dest=True
|
153
|
+
)
|
154
|
+
|
155
|
+
Notes:
|
156
|
+
- For executing multiple plans, consider using compute_parallel() or compute_test_mode().
|
157
|
+
- Setting num_cores appropriately is important for performance:
|
158
|
+
* 1-2 cores: Highest efficiency per core, good for small models
|
159
|
+
* 3-8 cores: Good balance for most models
|
160
|
+
* >8 cores: May have diminishing returns due to overhead
|
161
|
+
- This function updates the RAS object's dataframes (plan_df, geom_df, etc.) after execution.
|
119
162
|
"""
|
120
163
|
try:
|
121
164
|
ras_obj = ras_object if ras_object is not None else ras
|
@@ -202,8 +245,6 @@ class RasCmdr:
|
|
202
245
|
|
203
246
|
|
204
247
|
|
205
|
-
@staticmethod
|
206
|
-
@log_call
|
207
248
|
@staticmethod
|
208
249
|
@log_call
|
209
250
|
def compute_parallel(
|
@@ -216,19 +257,83 @@ class RasCmdr:
|
|
216
257
|
overwrite_dest: bool = False
|
217
258
|
) -> Dict[str, bool]:
|
218
259
|
"""
|
219
|
-
|
260
|
+
Execute multiple HEC-RAS plans in parallel using multiple worker instances.
|
261
|
+
|
262
|
+
This method creates separate worker folders for each parallel process, runs plans
|
263
|
+
in those folders, and then consolidates results to a final destination folder.
|
264
|
+
It's ideal for running independent plans simultaneously to make better use of system resources.
|
220
265
|
|
221
266
|
Args:
|
222
|
-
plan_number (Union[str, List[str], None]): Plan number(s) to compute.
|
223
|
-
|
267
|
+
plan_number (Union[str, List[str], None]): Plan number(s) to compute.
|
268
|
+
If None, all plans in the project are computed.
|
269
|
+
If string, only that plan will be computed.
|
270
|
+
If list, all specified plans will be computed.
|
271
|
+
Recommended to use two-digit strings for plan numbers for consistency (e.g., "01" instead of 1).
|
272
|
+
max_workers (int): Maximum number of parallel workers (separate HEC-RAS instances).
|
273
|
+
Each worker gets a separate folder with a copy of the project.
|
274
|
+
Optimal value depends on CPU cores and memory available.
|
275
|
+
A good starting point is: max_workers = floor(physical_cores / num_cores).
|
224
276
|
num_cores (int): Number of cores to use per plan computation.
|
225
|
-
|
226
|
-
|
277
|
+
Controls computational resources allocated to each individual HEC-RAS instance.
|
278
|
+
For parallel execution, 2-4 cores per worker often provides the best balance.
|
279
|
+
clear_geompre (bool): Whether to clear geometry preprocessor files before computation.
|
280
|
+
Set to True when geometry has been modified to force recomputation.
|
281
|
+
ras_object (Optional[RasPrj]): RAS project object. If None, uses global 'ras' instance.
|
282
|
+
Useful when working with multiple projects simultaneously.
|
227
283
|
dest_folder (Union[str, Path, None]): Destination folder for computed results.
|
284
|
+
If None, creates a "[Computed]" folder adjacent to the project folder.
|
285
|
+
If string, creates folder in the project's parent directory.
|
286
|
+
If Path, uses the exact path provided.
|
228
287
|
overwrite_dest (bool): Whether to overwrite existing destination folder.
|
288
|
+
Set to True to replace an existing destination folder with the same name.
|
229
289
|
|
230
290
|
Returns:
|
231
291
|
Dict[str, bool]: Dictionary of plan numbers and their execution success status.
|
292
|
+
Keys are plan numbers and values are boolean success indicators.
|
293
|
+
|
294
|
+
Raises:
|
295
|
+
ValueError: If the destination folder already exists, is not empty, and overwrite_dest is False.
|
296
|
+
FileNotFoundError: If project files cannot be found.
|
297
|
+
PermissionError: If there are issues accessing or writing to folders.
|
298
|
+
RuntimeError: If worker initialization fails.
|
299
|
+
|
300
|
+
Examples:
|
301
|
+
# Run all plans in parallel with default settings
|
302
|
+
RasCmdr.compute_parallel()
|
303
|
+
|
304
|
+
# Run all plans with 4 workers, 2 cores per worker
|
305
|
+
RasCmdr.compute_parallel(max_workers=4, num_cores=2)
|
306
|
+
|
307
|
+
# Run specific plans in parallel
|
308
|
+
RasCmdr.compute_parallel(plan_number=["01", "03"], max_workers=2)
|
309
|
+
|
310
|
+
# Run all plans with dynamic worker allocation based on system resources
|
311
|
+
import psutil
|
312
|
+
physical_cores = psutil.cpu_count(logical=False)
|
313
|
+
cores_per_worker = 2
|
314
|
+
max_workers = max(1, physical_cores // cores_per_worker)
|
315
|
+
RasCmdr.compute_parallel(max_workers=max_workers, num_cores=cores_per_worker)
|
316
|
+
|
317
|
+
# Run all plans in a specific destination folder
|
318
|
+
RasCmdr.compute_parallel(dest_folder="parallel_results", overwrite_dest=True)
|
319
|
+
|
320
|
+
Notes:
|
321
|
+
- Worker Assignment: Plans are assigned to workers in a round-robin fashion.
|
322
|
+
For example, with 3 workers and 5 plans, assignment would be:
|
323
|
+
Worker 1: Plans 1 & 4, Worker 2: Plans 2 & 5, Worker 3: Plan 3.
|
324
|
+
|
325
|
+
- Resource Management: Each HEC-RAS instance (worker) typically requires:
|
326
|
+
* 2-4 GB of RAM
|
327
|
+
* 2-4 cores for optimal performance
|
328
|
+
|
329
|
+
- When to use parallel vs. sequential:
|
330
|
+
* Parallel: For independent plans, faster overall completion
|
331
|
+
* Sequential: For dependent plans, consistent resource usage, easier debugging
|
332
|
+
|
333
|
+
- The function creates worker folders during execution and consolidates results
|
334
|
+
to the destination folder upon completion.
|
335
|
+
|
336
|
+
- This function updates the RAS object's dataframes (plan_df, geom_df, etc.) after execution.
|
232
337
|
"""
|
233
338
|
try:
|
234
339
|
ras_obj = ras_object or ras
|
@@ -251,11 +356,17 @@ class RasCmdr:
|
|
251
356
|
logger.info(f"Copied project folder to destination: {dest_folder_path}")
|
252
357
|
project_folder = dest_folder_path
|
253
358
|
|
359
|
+
# Store filtered plan numbers separately to ensure only these are executed
|
360
|
+
filtered_plan_numbers = []
|
361
|
+
|
254
362
|
if plan_number:
|
255
363
|
if isinstance(plan_number, str):
|
256
364
|
plan_number = [plan_number]
|
257
365
|
ras_obj.plan_df = ras_obj.plan_df[ras_obj.plan_df['plan_number'].isin(plan_number)]
|
258
|
-
|
366
|
+
filtered_plan_numbers = list(ras_obj.plan_df['plan_number'])
|
367
|
+
logger.info(f"Filtered plans to execute: {filtered_plan_numbers}")
|
368
|
+
else:
|
369
|
+
filtered_plan_numbers = list(ras_obj.plan_df['plan_number'])
|
259
370
|
|
260
371
|
num_plans = len(ras_obj.plan_df)
|
261
372
|
max_workers = min(max_workers, num_plans) if num_plans > 0 else 1
|
@@ -282,8 +393,9 @@ class RasCmdr:
|
|
282
393
|
logger.critical(f"Failed to initialize RAS project for worker {worker_id}: {str(e)}")
|
283
394
|
worker_ras_objects[worker_id] = None
|
284
395
|
|
396
|
+
# Explicitly use the filtered plan numbers for assignments
|
285
397
|
worker_cycle = cycle(range(1, max_workers + 1))
|
286
|
-
plan_assignments = [(next(worker_cycle), plan_num) for plan_num in
|
398
|
+
plan_assignments = [(next(worker_cycle), plan_num) for plan_num in filtered_plan_numbers]
|
287
399
|
|
288
400
|
execution_results: Dict[str, bool] = {}
|
289
401
|
|
@@ -397,49 +509,86 @@ class RasCmdr:
|
|
397
509
|
overwrite_dest=False
|
398
510
|
):
|
399
511
|
"""
|
400
|
-
Execute HEC-RAS plans in
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
copies the project there, and executes the specified plans in sequential order.
|
406
|
-
|
407
|
-
For most purposes, just copying the project folder, initing that new folder, then running each plan
|
408
|
-
with compute_plan is a simpler and more flexible approach. This is shown in the examples provided
|
409
|
-
in the ras-commander library.
|
512
|
+
Execute HEC-RAS plans sequentially in a separate test folder.
|
513
|
+
|
514
|
+
This function creates a separate test folder, copies the project there, and executes
|
515
|
+
the specified plans in sequential order. It's useful for batch processing plans that
|
516
|
+
need to be run in a specific order or when you want to ensure consistent resource usage.
|
410
517
|
|
411
518
|
Args:
|
412
519
|
plan_number (str, list[str], optional): Plan number or list of plan numbers to execute.
|
413
520
|
If None, all plans will be executed. Default is None.
|
414
|
-
|
521
|
+
Recommended to use two-digit strings for plan numbers for consistency (e.g., "01" instead of 1).
|
522
|
+
dest_folder_suffix (str, optional): Suffix to append to the test folder name.
|
415
523
|
Defaults to "[Test]".
|
416
|
-
|
524
|
+
The test folder is always created in the project folder's parent directory.
|
417
525
|
clear_geompre (bool, optional): Whether to clear geometry preprocessor files.
|
418
526
|
Defaults to False.
|
419
|
-
|
420
|
-
|
527
|
+
Set to True when geometry has been modified to force recomputation.
|
528
|
+
num_cores (int, optional): Number of cores to use for each plan.
|
529
|
+
If None, the current setting in the plan file is not changed. Default is None.
|
530
|
+
For sequential execution, 4-8 cores often provides good performance.
|
421
531
|
ras_object (RasPrj, optional): Specific RAS object to use. If None, uses the global ras instance.
|
422
|
-
|
532
|
+
Useful when working with multiple projects simultaneously.
|
533
|
+
overwrite_dest (bool, optional): If True, overwrite the destination folder if it exists.
|
534
|
+
Defaults to False.
|
535
|
+
Set to True to replace an existing test folder with the same name.
|
423
536
|
|
424
537
|
Returns:
|
425
538
|
Dict[str, bool]: Dictionary of plan numbers and their execution success status.
|
539
|
+
Keys are plan numbers and values are boolean success indicators.
|
540
|
+
|
541
|
+
Raises:
|
542
|
+
ValueError: If the destination folder already exists, is not empty, and overwrite_dest is False.
|
543
|
+
FileNotFoundError: If project files cannot be found.
|
544
|
+
PermissionError: If there are issues accessing or writing to folders.
|
426
545
|
|
427
|
-
|
428
|
-
Run all plans
|
429
|
-
|
430
|
-
|
431
|
-
Run
|
432
|
-
|
433
|
-
|
546
|
+
Examples:
|
547
|
+
# Run all plans sequentially
|
548
|
+
RasCmdr.compute_test_mode()
|
549
|
+
|
550
|
+
# Run a specific plan
|
551
|
+
RasCmdr.compute_test_mode(plan_number="01")
|
552
|
+
|
553
|
+
# Run multiple specific plans
|
554
|
+
RasCmdr.compute_test_mode(plan_number=["01", "03", "05"])
|
555
|
+
|
556
|
+
# Run plans with a custom folder suffix
|
557
|
+
RasCmdr.compute_test_mode(dest_folder_suffix="[SequentialRun]")
|
558
|
+
|
559
|
+
# Run plans with a specific number of cores
|
560
|
+
RasCmdr.compute_test_mode(num_cores=4)
|
434
561
|
|
562
|
+
# Run specific plans with multiple options
|
563
|
+
RasCmdr.compute_test_mode(
|
564
|
+
plan_number=["01", "02"],
|
565
|
+
dest_folder_suffix="[SpecificSequential]",
|
566
|
+
clear_geompre=True,
|
567
|
+
num_cores=6,
|
568
|
+
overwrite_dest=True
|
569
|
+
)
|
570
|
+
|
435
571
|
Notes:
|
436
|
-
- This function
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
572
|
+
- This function was created to replicate the original HEC-RAS command line -test flag,
|
573
|
+
which does not work in recent versions of HEC-RAS.
|
574
|
+
|
575
|
+
- Key differences from other compute functions:
|
576
|
+
* compute_plan: Runs a single plan, with option for destination folder
|
577
|
+
* compute_parallel: Runs multiple plans simultaneously in worker folders
|
578
|
+
* compute_test_mode: Runs multiple plans sequentially in a single test folder
|
579
|
+
|
580
|
+
- Use cases:
|
581
|
+
* Running plans in a specific order
|
582
|
+
* Ensuring consistent resource usage
|
583
|
+
* Easier debugging (one plan at a time)
|
584
|
+
* Isolated test environment
|
585
|
+
|
586
|
+
- Performance considerations:
|
587
|
+
* Sequential execution is generally slower overall than parallel execution
|
588
|
+
* Each plan gets consistent resource usage
|
589
|
+
* Execution time scales linearly with the number of plans
|
590
|
+
|
591
|
+
- This function updates the RAS object's dataframes (plan_df, geom_df, etc.) after execution.
|
443
592
|
"""
|
444
593
|
try:
|
445
594
|
ras_obj = ras_object or ras
|