Skip to content

Plan Execution

RAS Commander provides three modes for executing HEC-RAS plans, each optimized for different workflows.

Lean Batch Installation

Batch workers that only need project inventory, plan computation, computation messages, and HDF result extraction can install the compute dependency profile:

Bash
pip install "ras-commander[compute]"

Use the intentionally narrow facade in integration code:

Python
from ras_commander.compute import (
    HdfResultsPlan,
    RasCmdr,
    ResultsParser,
    init_ras_project,
)

This facade does not export RasControl or RasControlResult. Call RasCmdr.compute_plan() rather than constructing a Ras.exe -c command in the integrating application. The method retains normal ras-commander behavior: command construction, process and dialog supervision, compute-message handling, caller-controlled semantic verification, and post-compute project/result DataFrame refresh.

Single Plan Execution

Execute one plan with full parameter control using RasCmdr.compute_plan().

Python
from ras_commander import init_ras_project, RasCmdr

init_ras_project("/path/to/project", "6.5")

# Basic execution
success = RasCmdr.compute_plan("01")

Parameters

Parameter Type Description
plan_number str Plan identifier ("01", "02", etc.)
dest_folder str/Path Directory for computation (None = in-place)
ras_object RasPrj Project object (default: global ras)
clear_geompre bool Clear geometry preprocessor files first
num_cores int Number of CPU cores to use
overwrite_dest bool Overwrite destination if exists
max_runtime float/None Optional positive finite execution limit in seconds

Examples

Python
# Execute with specific core count
success = RasCmdr.compute_plan("01", num_cores=4)

# Execute to separate folder (preserves original)
success = RasCmdr.compute_plan(
    "01",
    dest_folder="/results/run1",
    overwrite_dest=True
)

# Force geometry preprocessing
success = RasCmdr.compute_plan("01", clear_geompre=True)

Bounded Execution and Launch Evidence

max_runtime is an additive execution-safety option for direct RasCmdr.compute_plan() runs. Supply a positive finite number of seconds when the caller needs a hard plan-specific engine deadline:

Python
result = RasCmdr.compute_plan(
    "01",
    force_rerun=True,
    verify=True,
    max_runtime=900,
)

details = result.execution_details
if details["runtime_timed_out"]:
    print(details["failure_stage"], details["cancellation_details"])

Boolean values, strings, zero, negative values, NaN, infinity, and values above 4,294,967.294 seconds are rejected before project access or execution begins. The upper limit keeps the value representable by the Windows subprocess wait API. An explicit value establishes one monotonic engine deadline immediately before Ras.exe launch, after executable proof, process preflight, and result-artifact preparation. The remaining budget is shared by compute-message callback monitoring, the direct launcher wait, asynchronous solver completion, and exact-plan quiescence confirmation; each phase does not receive a fresh timeout.

max_runtime=None is the compatibility default. It does not add a deadline to the direct Ras.exe launcher wait. The existing 7,200-second bound for an asynchronous RasUnsteady.exe solver that outlives its launcher remains in place.

When an explicit deadline expires, ras-commander records the timeout and calls only RasCmdr.cancel_plan_exact() for that initialized project and plan. It does not fall back to a process-name kill. Opposing result-family artifacts are finalized only when the structured cancellation or final process inspection positively confirms exact-plan quiescence. An uncertain cancellation therefore returns a failed ComputeResult and leaves potentially active artifacts untouched. Exact-plan cancellation and terminal evidence collection can extend the method's wall-clock return time beyond max_runtime; the deadline limits the engine attempt, not the safety work needed to prove what remains running.

Plan-specific cancellation currently has qualified command signatures for the core steady and unsteady launchers/solvers. Sediment, quasi-unsteady, and water-quality engines are inventoried and make quiescence fail closed when they can be linked to the plan, but they are not signalled until their exact native command signatures are qualified. A timeout involving one of these engines can therefore return an uncertain, failed cancellation while leaving the process running for manual review.

ComputeResult.execution_details provides JSON-safe audit evidence, including:

  • max_runtime_seconds and runtime_timed_out;
  • launch_details, with the exact command, working directory, executable path and SHA-256, project and plan paths, and launcher PID/create-time identity;
  • launcher_returncode, which can remain nonzero when a delegated modern solver nevertheless produces a verified final HDF;
  • failure_stage, failure_type, and failure_detail;
  • structured cancellation_details, including tri-state quiescence evidence; and
  • artifact_preparation_cleanup and artifact_finalization_cleanup, which report the exact removed and already-missing target paths before and after execution; and
  • result_artifacts_finalized plus artifact_finalization_failure, which keep a cleanup defect separate from an earlier timeout or execution failure.

Within either cleanup record, result_format is the result family targeted for deletion—the opposing family—not the run's selected output format. On a successful cleanup, removed_paths and missing_paths are disjoint and their union is the complete plan-scoped target set. Both cleanup fields are None when calculation is skipped before cleanup.

completion_verified is independent of overall ComputeResult.success. For example, a complete HDF may verify and then result-family finalization may fail; that outcome is success=False, completion_verified=True, and remains safe to inspect as a failed execution receipt when exact-plan quiescence is proven.

Advanced supervisors can implement the optional duck-typed on_exec_launched(plan_number, launch_details) callback to persist the launch identity immediately after it is captured. This additive hook does not change the exported ExecutionCallback protocol.

Sequential Execution

Run multiple plans in order using RasCmdr.compute_test_mode(). Plans execute in a copy of the project.

Python
results = RasCmdr.compute_test_mode(
    plan_number=["01", "02", "03"],
    dest_folder_suffix="[Test]"
)

for plan, success in results.items():
    print(f"Plan {plan}: {'OK' if success else 'FAILED'}")

When to Use

  • Plans have dependencies (e.g., plan 02 needs results from 01)
  • Controlled resource usage is needed
  • Debugging complex multi-plan workflows

Parameters

Parameter Type Description
plan_number list Plans to run in order
dest_folder_suffix str Suffix for test folder name
clear_geompre bool Clear preprocessor before each plan
num_cores int Cores per plan
overwrite_dest bool Overwrite test folder

Parallel Execution

Run multiple independent plans simultaneously using RasCmdr.compute_parallel(). Creates temporary worker folders.

Python
results = RasCmdr.compute_parallel(
    plan_number=["01", "02", "03"],
    max_workers=3,
    num_cores=2,
    dest_folder="/results/parallel_run"
)

Resource Optimization

Balance workers and cores based on your system:

Python
import psutil

# Calculate optimal configuration
physical_cores = psutil.cpu_count(logical=False)
cores_per_worker = 2
max_workers = physical_cores // cores_per_worker

# Also consider RAM (each HEC-RAS instance needs 2-4GB+)
available_ram_gb = psutil.virtual_memory().available / (1024**3)
ram_limited_workers = int(available_ram_gb // 4)

# Use the more restrictive limit
optimal_workers = min(max_workers, ram_limited_workers)

results = RasCmdr.compute_parallel(
    plan_number=["01", "02", "03", "04"],
    max_workers=optimal_workers,
    num_cores=cores_per_worker
)

Parameters

Parameter Type Description
plan_number list Plans to run concurrently
max_workers int Maximum parallel HEC-RAS instances
num_cores int Cores assigned to each worker
dest_folder str/Path Final results location
clear_geompre bool Clear preprocessor in worker folders
overwrite_dest bool Overwrite destination folder

How It Works

  1. Creates temporary worker folders (copies of project)
  2. Assigns plans to workers
  3. Executes plans in parallel
  4. Consolidates results to destination folder
  5. Cleans up worker folders

Execution Mode Comparison

Feature Single Sequential Parallel
Speed Fast (1 plan) Moderate Fastest (many plans)
Resource Usage Low Low High
Dependencies N/A Supported Not supported
Disk Space Low Medium High (temp folders)
Use Case Testing, debugging Dependent plans Batch processing

Plan Modification Before Execution

Modify plan parameters programmatically before running:

Python
from ras_commander import RasPlan, RasCmdr

# Clone and modify
new_plan = RasPlan.clone_plan("01", new_plan_shortid="Modified Run")

# Change parameters
RasPlan.set_num_cores(new_plan, 4)
RasPlan.set_computation_interval(new_plan, "5MIN")
RasPlan.set_description(new_plan, "Run with finer timestep")

# Execute modified plan
success = RasCmdr.compute_plan(new_plan)

Native Flow Hydrograph Optimization

HEC-RAS native automated flow optimization scales selected flow hydrographs until a stage or flow target is met at a reference point or line. RAS Commander exposes this through RasFlowOptimization while keeping execution inside RasCmdr.

Python
from ras_commander import init_ras_project, RasFlowOptimization, RasCmdr

init_ras_project("/path/to/tutorial-13-project", "6.5")

# Copy a plan and enable native HEC-RAS flow optimization on the copy.
opt_plan = RasFlowOptimization.copy_plan_with_optimization(
    "01",
    new_plan_shortid="Native Flow Opt",
    mode="stage",
    reference_location="Yosemite Falls Vantage Point",
    target_value=3963.5,
    tolerance=0.1,
    hydrographs=["BCLine: Inflow"],
    min_ratio=0.5,
    max_ratio=1.0,
    max_iterations=10,
)

# Execute through RAS Commander, not a direct Ras.exe call.
success = RasCmdr.compute_plan(opt_plan)

# After compute, read native trial output from the plan HDF or compute messages.
trials = RasFlowOptimization.get_trial_results(opt_plan)
print(trials[["trial", "ratio", "difference", "target", "computed"]])

Use RasFlowOptimization.get_settings() to audit an existing plan and RasFlowOptimization.list_flow_hydrographs() to discover flow hydrographs that can be selected for scaling. RasFlowOptimization.compute_plan_and_get_trials() is a convenience wrapper around RasCmdr.compute_plan() followed by trial extraction. See examples/301_flow_hydrograph_optimization.ipynb for the Tutorial 13 workflow and fallback guidance.

RasCalibrate remains the ras-commander-native calibration/search API for broader parameter sweeps, arbitrary model edits, and custom objective metrics. Native flow optimization is narrower: it delegates HEC-RAS' built-in flow-ratio trial loop to HEC-RAS and reports the resulting trial table where available. See the official HEC-RAS flow hydrograph optimization tutorial for the corresponding GUI workflow.

Checking Results

After execution, verify results were generated and the run completed without errors. This is critical for determining if the simulation succeeded.

Structured Mechanical Evidence

Use inspect_execution_evidence() when automation must distinguish an inspected false value from an unavailable, uninspected, or unreadable channel. The method is read-only: it does not run HEC-RAS, preprocess the plan, or open the legacy COM controller.

Python
from ras_commander import RasCmdr

evidence = RasCmdr.inspect_execution_evidence(
    "01",
    ras_object=ras,
    hash_files=True,
)

completion = evidence.mechanical_completion
print(completion.state, completion.value, completion.reason_code)

errors = evidence.observations["message_error_count"]
print(errors.state, errors.value, errors.source_locator)

The four observation states have distinct meanings:

  • available means inspection produced a value, including False or zero.
  • not_available_in_version is used only for a positively established producer-version limitation.
  • not_inspected means no trustworthy observation was possible or requested.
  • failed means inspection was attempted but the source was unreadable, malformed, unstable, or contradictory.

If result_modified_after is supplied, pass a timezone-aware datetime so the freshness comparison is reproducible across machines. Message-health counts prefer embedded HDF messages and fall back to stored messages; the two completion-message observations remain separate.

Result-family selection reads Program Version= from the current .p## bytes, not from cached plan_df metadata. When only one result family exists, that artifact is selected even if its family differs from the declaration; the evidence records unexpected_result_format. This supports a copied legacy plan that was cleanly rerun by a newer engine without rewriting its declaration.

When both .p##.hdf and .O## exist, the inspector applies stricter rules:

Plan declaration Selection
HEC-RAS 5 or newer, .O## timestamp after HDF Raise ResultArtifactAmbiguityError.
HEC-RAS 5 or newer, .O## timestamp equal to or before HDF Select HDF, warn, and record multiple_result_formats_present. Legacy output does not contribute to the selected evidence.
HEC-RAS 4 or older, HDF timestamp after .O## Raise ResultArtifactAmbiguityError. The timestamp is only a conservative ambiguity trigger, not proof of run chronology.
HEC-RAS 4 or older, HDF timestamp equal to or before .O## Select .O##, warn, and record multiple_result_formats_present. HDF completion and runtime do not contribute to the selected evidence.
Missing or unreadable declaration Raise ResultArtifactAmbiguityError.
flowchart TD
    A["Inspect existing project"] --> B{"Both HDF and .O##?"}
    B -- "No" --> C["Read sole existing format<br/>record a conflict if unexpected"]
    B -- "Yes" --> D{"Declared plan family"}
    D -- "HEC-RAS 5+" --> E{"HDF mtime >= .O## mtime?"}
    E -- "Yes" --> F["Select HDF<br/>warn about ignored .O##"]
    E -- "No" --> G["Raise ResultArtifactAmbiguityError"]
    D -- "HEC-RAS 4 or older" --> H{".O## mtime >= HDF mtime?"}
    H -- "Yes" --> I["Select .O##<br/>warn about ignored HDF"]
    H -- "No" --> G
    D -- "Unresolved" --> G

Copied-folder timestamps can be misleading. The error therefore asks the user to resolve the formats rather than claiming which computation is newest.

An actual ras-commander computation does not use those timestamps to decide what to remove. It normalizes artifacts using the selected HEC-RAS executable or controller, not the plan declaration: HEC-RAS 5+ runs preserve HDF and remove .O##; legacy runs preserve .O## and remove the plan HDF. Cleanup is coupled to the real launch after skip decisions, plan preparation, callbacks, watchdog startup, and log creation have succeeded. It runs again after every launched attempt once solver completion or termination is confirmed, because modern HEC-RAS 1D engines recreate .O## during computation. If solver quiescence cannot be confirmed, the run fails and leaves the opposing artifact visible rather than racing an active writer. Remote PsExec staging is also retained when completion is unconfirmed. Skipped runs do not change plan bytes or delete result artifacts.

flowchart TD
    A["Resolve selected executable or controller"] --> B{"Engine family reliable?"}
    B -- "No or conflicting" --> C["Fail without deleting results"]
    B -- "Yes" --> D{"Skip calculation?"}
    D -- "Yes" --> E["Return without changing<br/>plan bytes or results"]
    D -- "No" --> F["Finish plan preparation,<br/>callbacks, watchdog, and log setup"]
    F --> G{"Selected engine family"}
    G -- "HEC-RAS 5+" --> H["Remove exact .O##<br/>and stale messages"]
    G -- "HEC-RAS 3-4" --> I["Remove exact plan HDF<br/>and stale messages"]
    H --> J["Launch calculation"]
    I --> J
    J --> K["Wait for launcher, solver children,<br/>and temporary HDF state"]
    K --> L{"Solver quiescence confirmed?"}
    L -- "No" --> M["Fail and preserve visible conflict<br/>and remote staging"]
    L -- "Yes" --> N["Remove any opposing result<br/>recreated during execution"]
    N --> O["Return normalized result set"]

For command-line execution, a versioned ras_exe_path is authoritative and ras_version is the fallback for an unversioned executable name. If both are resolvable but imply different result families, automatic cleanup fails closed without deleting either family. RasControl.run_plan() instead follows the version of the selected COM controller. An unversioned Ras.exe path with no resolvable version is not assumed to be modern, because that guess could permanently remove a valid legacy result.

This automatic normalization belongs to full plan-calculation APIs. RasPreprocess.preprocess_plan() and GeomPreprocessor.run_geometry_preprocessor() are preflight/preprocessing operations that attempt to stop before hydraulic computation; they do not delete either family of final results and must not be used to normalize an ambiguous project.

To resolve an existing project manually, explicitly select the family to remove:

Python
from ras_commander import RasCmdr

# Permanent, exact plan-scoped removal. Geometry HDF, DSS, terrain, and
# .p##.tmp.hdf preprocessing files are never included.
cleanup = RasCmdr.remove_plan_execution_artifacts(
    "01",
    result_format="legacy",  # or "hdf" / "both"
    include_message_sidecars=False,
    ras_object=ras,
)
print(cleanup.removed_paths)

The helper validates its complete, project-contained target list before the first deletion. If an operating-system error occurs during deletion, PlanExecutionCleanupError.cleanup records any paths already removed and failed_path identifies the file that could not be removed.

Alternatively, rerun with the intended HEC-RAS version through RasCmdr.compute_plan() or RasControl.run_plan(); the execution path removes the opposing result family and stale compute-message sidecars.

Mechanical completion is deliberately independent from message errors, warnings, result freshness, volume accounting, convergence quality, and hydraulic acceptance. Review those observations separately.

For native Linux unsteady runs, an HDF Event Conditions completion attribute can be inherited from the prepared .tmp.hdf. An available / True observation from that attribute describes the file; it does not establish that the subsequent native calculation finished. Native results may also omit the Windows Complete Process message. Use the native execution API's solver-log and populated-result checks, then verify the requested output time window, array dimensions, and finite values. Keep the structured observations alongside these checks rather than using the inherited attribute as the acceptance gate.

Quick Verification

Python
from ras_commander import init_ras_project, ras, HdfResultsPlan

# Refresh project data to see new results
init_ras_project(ras.project_folder, "6.5")

# Check for HDF results
hdf_entries = ras.get_hdf_entries()
print(f"Found {len(hdf_entries)} HDF result files")

Check Compute Messages for Errors

The compute messages contain the HEC-RAS log output. Always check for errors:

Python
from ras_commander import HdfResultsPlan

# Get computation messages (accepts plan number or HDF path)
msgs = HdfResultsPlan.get_compute_messages("01")

if msgs:
    # Check for error keywords
    if 'ERROR' in msgs.upper() or 'FAILED' in msgs.upper():
        print("ERRORS DETECTED in computation!")
        # Print error lines
        for line in msgs.split('\n'):
            if 'ERROR' in line.upper() or 'FAILED' in line.upper():
                print(f"  {line}")
    else:
        print("Computation completed without errors")
else:
    print("No compute messages - run may not have completed")

Check Volume Accounting

Volume accounting verifies mass conservation. A large imbalance indicates problems:

Python
from ras_commander import HdfResultsPlan

volume_df = HdfResultsPlan.get_volume_accounting("01")

if volume_df is not None:
    print("Volume Accounting Data:")
    # Display as transposed for readability
    print(volume_df.T)
else:
    print("No volume accounting - run may have failed")

Check Unsteady Results Exist

Verify unsteady results were written to the HDF:

Python
from ras_commander import HdfResultsPlan

# Basic unsteady info
try:
    info = HdfResultsPlan.get_unsteady_info("01")
    print("Unsteady results present")
    print(info.T)
except KeyError:
    print("No unsteady results found")

# Detailed unsteady summary
try:
    summary = HdfResultsPlan.get_unsteady_summary("01")
    print("\nUnsteady Summary:")
    print(summary.T)
except KeyError:
    print("No unsteady summary - check if run completed")

Check Runtime Performance

Review computation timing and performance:

Python
from ras_commander import HdfResultsPlan

runtime = HdfResultsPlan.get_runtime_data("01")

if runtime is not None:
    print(f"Plan: {runtime['Plan Name'].iloc[0]}")
    print(f"Simulation: {runtime['Simulation Time (hr)'].iloc[0]:.1f} hr")
    print(f"Compute Time: {runtime['Complete Process (hr)'].iloc[0]:.3f} hr")
    print(f"Speed: {runtime['Complete Process Speed (hr/hr)'].iloc[0]:.0f}x realtime")

Complete Verification Example

Python
from ras_commander import init_ras_project, HdfResultsPlan

init_ras_project("/path/to/project", "6.5")

def check_run_success(plan_number):
    """Check if a plan run was successful."""
    print(f"\n{'='*50}")
    print(f"Verifying Plan {plan_number}")
    print('='*50)

    success = True

    # 1. Check compute messages
    msgs = HdfResultsPlan.get_compute_messages(plan_number)
    if msgs:
        has_errors = any(kw in msgs.upper()
                        for kw in ['ERROR', 'FAILED', 'UNSTABLE'])
        if has_errors:
            print("[FAIL] Errors found in compute messages")
            success = False
        else:
            print("[OK] No errors in compute messages")
    else:
        print("[FAIL] No compute messages found")
        success = False

    # 2. Check volume accounting
    volume = HdfResultsPlan.get_volume_accounting(plan_number)
    if volume is not None:
        print("[OK] Volume accounting data present")
    else:
        print("[WARN] No volume accounting data")

    # 3. Check unsteady results
    try:
        HdfResultsPlan.get_unsteady_summary(plan_number)
        print("[OK] Unsteady results present")
    except:
        print("[WARN] No unsteady summary")

    # 4. Runtime data
    runtime = HdfResultsPlan.get_runtime_data(plan_number)
    if runtime is not None:
        speed = runtime['Complete Process Speed (hr/hr)'].iloc[0]
        print(f"[INFO] Compute speed: {speed:.0f}x realtime")

    print(f"\nOverall: {'SUCCESS' if success else 'NEEDS REVIEW'}")
    return success

# Usage
check_run_success("01")

See Workflows and Patterns for more detailed verification patterns including batch verification.

Detailed Compute Message Logging

Monitor HEC-RAS execution in real-time with stream callbacks. This provides live feedback during computation and enables automated error detection.

Stream Callbacks

The stream_callback parameter accepts callback objects for real-time monitoring:

Python
from ras_commander import RasCmdr
from ras_commander.callbacks import ConsoleCallback

# Monitor execution with console output
success = RasCmdr.compute_plan(
    "01",
    stream_callback=ConsoleCallback(verbose=True)
)

Available Callbacks

Python
from ras_commander.callbacks import (
    ConsoleCallback,      # Print to console
    FileLoggerCallback,   # Log to file
    ProgressBarCallback,  # Show progress bar (requires tqdm)
    SynchronizedCallback  # Thread-safe wrapper for parallel execution
)

# Console callback
RasCmdr.compute_plan("01", stream_callback=ConsoleCallback(verbose=True))

# File logger callback
RasCmdr.compute_plan("01", stream_callback=FileLoggerCallback("run.log"))

# Progress bar (requires: pip install tqdm)
RasCmdr.compute_plan("01", stream_callback=ProgressBarCallback())

Custom Callbacks

Create custom callbacks for specialized monitoring:

Python
from ras_commander.callbacks import ExecutionCallback

class ErrorDetectionCallback(ExecutionCallback):
    """Callback that stops execution on first error."""

    def on_exec_message(self, message):
        # Check for error keywords
        if any(kw in message.upper() for kw in ['ERROR', 'FAILED', 'UNSTABLE']):
            print(f"❌ ERROR DETECTED: {message}")
            # Could raise exception, send alert, etc.
        elif 'warning' in message.lower():
            print(f"⚠ WARNING: {message}")
        else:
            # Normal message
            print(f"ℹ {message}")

# Use custom callback
RasCmdr.compute_plan("01", stream_callback=ErrorDetectionCallback())

Callback Methods

Custom callbacks can implement these methods:

Python
class MyCallback(ExecutionCallback):
    def on_start(self, plan_number):
        """Called when execution starts."""
        print(f"Starting plan {plan_number}")

    def on_exec_message(self, message):
        """Called for each HEC-RAS message during execution."""
        print(f"HEC-RAS: {message}")

    def on_complete(self, success):
        """Called when execution completes."""
        if success:
            print("✓ Execution completed successfully")
        else:
            print("✗ Execution failed")

    def on_error(self, error):
        """Called if exception occurs."""
        print(f"Exception: {error}")

Parallel Execution with Callbacks

Use SynchronizedCallback wrapper for thread-safe logging:

Python
from ras_commander.callbacks import ConsoleCallback, SynchronizedCallback

# Wrap callback for thread safety
safe_callback = SynchronizedCallback(ConsoleCallback(verbose=True))

# Use with parallel execution
results = RasCmdr.compute_parallel(
    plan_number=["01", "02", "03"],
    max_workers=3,
    stream_callback=safe_callback  # Thread-safe logging
)

Post-Execution Message Review

Review compute messages after execution completes:

Python
from ras_commander import HdfResultsPlan

# Get all compute messages
msgs = HdfResultsPlan.get_compute_messages("01")

# Parse for specific information
for line in msgs.split('\n'):
    if 'time step' in line.lower():
        print(line)  # Timestep information
    elif 'iterations' in line.lower():
        print(line)  # Iteration counts
    elif 'error' in line.lower():
        print(f"⚠ {line}")  # Errors

Error Handling

Python
from ras_commander import RasCmdr
import logging

# Enable debug logging
logging.getLogger('ras_commander').setLevel(logging.DEBUG)

try:
    success = RasCmdr.compute_plan("01")
    if not success:
        print("Plan execution failed - check HEC-RAS logs")
except FileNotFoundError as e:
    print(f"Plan file not found: {e}")
except ValueError as e:
    print(f"Invalid parameter: {e}")

Best Practices

  1. Test first: Use compute_plan() with dest_folder to test without modifying original
  2. Monitor resources: Watch CPU and RAM during parallel execution
  3. Clear preprocessor: Use clear_geompre=True after geometry changes
  4. Check return values: Always verify execution success
  5. Use logging: Enable DEBUG level for troubleshooting