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())