Automatic profile generation workflow#

Reset generated-profile state, configure generation settings, and generate profiles from the mean profile template.

  1"""
  2Automatic profile generation workflow using the installed rsseismic package.
  3
  4  python examples/example_auto_profile_workflow.py "E:\\path\\to\\Test_Auto_Profile.rsseismicfile"
  5  python examples/example_auto_profile_workflow.py --port 60058 --num-profiles 10 --seed 12345 project.rsseismicfile
  6"""
  7
  8from __future__ import annotations
  9
 10import argparse
 11import os
 12import sys
 13
 14from rsseismic import RSSeismicApplication
 15from rsseismic._client import DEFAULT_SCRIPTING_PORT
 16from rsseismic.Model import GenerateProfilesResult, ResetGeneratedProfilesResult
 17
 18
 19DEFAULT_NUM_PROFILES = 20
 20DEFAULT_GENERATE_TIMEOUT_SECONDS = 60 * 60
 21
 22
 23def run_auto_profile_workflow(
 24    project_path: str,
 25    port: int = DEFAULT_SCRIPTING_PORT,
 26    num_profiles: int = DEFAULT_NUM_PROFILES,
 27    seed: int = 0,
 28    timeout: float | None = DEFAULT_GENERATE_TIMEOUT_SECONDS,
 29    save_on_close: bool = False,
 30) -> tuple[ResetGeneratedProfilesResult, GenerateProfilesResult]:
 31    """
 32    Open a project, reset generated profiles, set numProfiles, and generate profiles.
 33
 34    Returns (resetResult, generateResult). Raises on missing file or RPC/scripting errors.
 35    """
 36    project_path = os.path.abspath(project_path.strip())
 37    if not os.path.isfile(project_path):
 38        raise FileNotFoundError(f"Project file not found: {project_path}")
 39
 40    if num_profiles < 1:
 41        raise ValueError("num_profiles must be at least 1.")
 42
 43    app = RSSeismicApplication(port=port)
 44    model = None
 45
 46    try:
 47        app.ping()
 48        model = app.openFile(project_path)
 49
 50        reset_result = model.resetGeneratedProfiles()
 51        model.ProfileGenerationSettings.setProfilesToGenerate(num_profiles)
 52        generate_result = model.generateProfiles(seed=seed, timeout=timeout)
 53
 54        return reset_result, generate_result
 55    finally:
 56        if model is not None:
 57            model.close(saveProject=save_on_close)
 58        app.close()
 59
 60
 61def parse_args() -> argparse.Namespace:
 62    parser = argparse.ArgumentParser(
 63        description="Reset generated profiles, set numProfiles, and run GenerateProfiles.",
 64    )
 65    parser.add_argument(
 66        "project",
 67        help="Absolute path to a .rsseismicfile configured for automatic profile generation",
 68    )
 69    parser.add_argument(
 70        "--port",
 71        "-p",
 72        type=int,
 73        default=int(os.environ.get("RSSEISMIC_SCRIPTING_PORT", DEFAULT_SCRIPTING_PORT)),
 74        help=f"gRPC port (default: {DEFAULT_SCRIPTING_PORT}, or RSSEISMIC_SCRIPTING_PORT env)",
 75    )
 76    parser.add_argument(
 77        "--num-profiles",
 78        "-n",
 79        type=int,
 80        default=DEFAULT_NUM_PROFILES,
 81        help=f"Number of profiles to generate (default: {DEFAULT_NUM_PROFILES})",
 82    )
 83    parser.add_argument(
 84        "--seed",
 85        type=int,
 86        default=0,
 87        help="RNG seed for GenerateProfiles (0 = server picks a random seed)",
 88    )
 89    parser.add_argument(
 90        "--timeout",
 91        type=float,
 92        default=DEFAULT_GENERATE_TIMEOUT_SECONDS,
 93        help=f"GenerateProfiles timeout in seconds (default: {DEFAULT_GENERATE_TIMEOUT_SECONDS})",
 94    )
 95    parser.add_argument(
 96        "--save-on-close",
 97        action="store_true",
 98        help="Save project before Close (default: close without saving)",
 99    )
100    return parser.parse_args()
101
102
103def main() -> int:
104    args = parse_args()
105    try:
106        reset_result, generate_result = run_auto_profile_workflow(
107            args.project,
108            port=args.port,
109            num_profiles=args.num_profiles,
110            seed=args.seed,
111            timeout=args.timeout,
112            save_on_close=args.save_on_close,
113        )
114    except Exception as ex:
115        print(f"Workflow failed: {ex}", file=sys.stderr)
116        return 1
117
118    print(f"ResetGeneratedProfiles OK (hasBeenGenerated={reset_result.hasBeenGenerated})")
119    print(
120        f"GenerateProfiles OK (profileCount={generate_result.profileCount}, "
121        f"hasBeenGenerated={generate_result.hasBeenGenerated})"
122    )
123    for name in generate_result.profileNames:
124        print(f"  - {name}")
125    return 0
126
127
128if __name__ == "__main__":
129    raise SystemExit(main())