orca-auto-workflows 6.0.0__tar.gz

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.
Files changed (150) hide show
  1. orca_auto_workflows-6.0.0/LICENSE +21 -0
  2. orca_auto_workflows-6.0.0/PKG-INFO +69 -0
  3. orca_auto_workflows-6.0.0/README.md +31 -0
  4. orca_auto_workflows-6.0.0/pyproject.toml +28 -0
  5. orca_auto_workflows-6.0.0/setup.cfg +4 -0
  6. orca_auto_workflows-6.0.0/src/orca_auto/flow/__init__.py +5 -0
  7. orca_auto_workflows-6.0.0/src/orca_auto/flow/_orca_stage_materialization.py +469 -0
  8. orca_auto_workflows-6.0.0/src/orca_auto/flow/_orca_stage_payloads.py +128 -0
  9. orca_auto_workflows-6.0.0/src/orca_auto/flow/activity/__init__.py +1 -0
  10. orca_auto_workflows-6.0.0/src/orca_auto/flow/activity/_workflow_records.py +250 -0
  11. orca_auto_workflows-6.0.0/src/orca_auto/flow/adapters/__init__.py +1 -0
  12. orca_auto_workflows-6.0.0/src/orca_auto/flow/adapters/_engine_adapter_helpers.py +438 -0
  13. orca_auto_workflows-6.0.0/src/orca_auto/flow/adapters/_orca_contract_assembly.py +312 -0
  14. orca_auto_workflows-6.0.0/src/orca_auto/flow/adapters/_orca_contract_context.py +173 -0
  15. orca_auto_workflows-6.0.0/src/orca_auto/flow/adapters/_orca_local_lookup.py +78 -0
  16. orca_auto_workflows-6.0.0/src/orca_auto/flow/adapters/_orca_path_helpers.py +159 -0
  17. orca_auto_workflows-6.0.0/src/orca_auto/flow/adapters/_orca_tracking.py +111 -0
  18. orca_auto_workflows-6.0.0/src/orca_auto/flow/adapters/crest.py +129 -0
  19. orca_auto_workflows-6.0.0/src/orca_auto/flow/adapters/orca.py +49 -0
  20. orca_auto_workflows-6.0.0/src/orca_auto/flow/cli/__init__.py +1 -0
  21. orca_auto_workflows-6.0.0/src/orca_auto/flow/cli/run_dir.py +98 -0
  22. orca_auto_workflows-6.0.0/src/orca_auto/flow/cli/worker_options.py +93 -0
  23. orca_auto_workflows-6.0.0/src/orca_auto/flow/cli/workflow.py +314 -0
  24. orca_auto_workflows-6.0.0/src/orca_auto/flow/cli/workflow_output.py +112 -0
  25. orca_auto_workflows-6.0.0/src/orca_auto/flow/conformer_selection.py +577 -0
  26. orca_auto_workflows-6.0.0/src/orca_auto/flow/contracts/__init__.py +34 -0
  27. orca_auto_workflows-6.0.0/src/orca_auto/flow/contracts/crest.py +205 -0
  28. orca_auto_workflows-6.0.0/src/orca_auto/flow/contracts/orca.py +61 -0
  29. orca_auto_workflows-6.0.0/src/orca_auto/flow/contracts/workflow.py +450 -0
  30. orca_auto_workflows-6.0.0/src/orca_auto/flow/engine_options.py +48 -0
  31. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/__init__.py +1 -0
  32. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/crest/__init__.py +1 -0
  33. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/crest/artifacts.py +211 -0
  34. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/crest/engine.py +25 -0
  35. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/crest/execution.py +713 -0
  36. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/crest/job_inputs.py +129 -0
  37. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/crest/job_locations.py +62 -0
  38. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/crest/queue_runtime.py +485 -0
  39. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/crest/runner.py +751 -0
  40. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/crest/state.py +78 -0
  41. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/crest/submission.py +273 -0
  42. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/crest/terminal.py +212 -0
  43. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/crest/worker_context.py +116 -0
  44. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/queue_runtime_common.py +346 -0
  45. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/scratch.py +210 -0
  46. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/submission_snapshot.py +71 -0
  47. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/xtb/__init__.py +1 -0
  48. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/xtb/artifacts.py +212 -0
  49. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/xtb/engine.py +26 -0
  50. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/xtb/execution.py +833 -0
  51. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/xtb/job_inputs.py +294 -0
  52. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/xtb/job_locations.py +82 -0
  53. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/xtb/queue_runtime.py +678 -0
  54. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/xtb/ranking_artifacts.py +109 -0
  55. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/xtb/ranking_execution.py +150 -0
  56. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/xtb/ranking_inputs.py +73 -0
  57. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/xtb/ranking_models.py +59 -0
  58. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/xtb/ranking_results.py +145 -0
  59. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/xtb/ranking_selection.py +166 -0
  60. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/xtb/runner.py +655 -0
  61. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/xtb/runner_artifacts.py +145 -0
  62. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/xtb/runner_ranking.py +75 -0
  63. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/xtb/state.py +89 -0
  64. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/xtb/submission.py +332 -0
  65. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/xtb/terminal.py +390 -0
  66. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/xtb/worker_context.py +222 -0
  67. orca_auto_workflows-6.0.0/src/orca_auto/flow/engines/xtb/worker_terminal.py +121 -0
  68. orca_auto_workflows-6.0.0/src/orca_auto/flow/manifest.py +573 -0
  69. orca_auto_workflows-6.0.0/src/orca_auto/flow/orca_stage_evidence.py +483 -0
  70. orca_auto_workflows-6.0.0/src/orca_auto/flow/orca_stage_validation.py +228 -0
  71. orca_auto_workflows-6.0.0/src/orca_auto/flow/orchestration/__init__.py +90 -0
  72. orca_auto_workflows-6.0.0/src/orca_auto/flow/orchestration/advance.py +260 -0
  73. orca_auto_workflows-6.0.0/src/orca_auto/flow/orchestration/advance_phases.py +239 -0
  74. orca_auto_workflows-6.0.0/src/orca_auto/flow/orchestration/builders.py +47 -0
  75. orca_auto_workflows-6.0.0/src/orca_auto/flow/orchestration/charge_spin.py +90 -0
  76. orca_auto_workflows-6.0.0/src/orca_auto/flow/orchestration/crest_orca_materialization.py +248 -0
  77. orca_auto_workflows-6.0.0/src/orca_auto/flow/orchestration/factories.py +139 -0
  78. orca_auto_workflows-6.0.0/src/orca_auto/flow/orchestration/interaction_energy_materialization.py +653 -0
  79. orca_auto_workflows-6.0.0/src/orca_auto/flow/orchestration/lifecycle.py +174 -0
  80. orca_auto_workflows-6.0.0/src/orca_auto/flow/orchestration/requests.py +76 -0
  81. orca_auto_workflows-6.0.0/src/orca_auto/flow/orchestration/services.py +142 -0
  82. orca_auto_workflows-6.0.0/src/orca_auto/flow/orchestration/stage_builders.py +259 -0
  83. orca_auto_workflows-6.0.0/src/orca_auto/flow/orchestration/stage_runtime/__init__.py +1 -0
  84. orca_auto_workflows-6.0.0/src/orca_auto/flow/orchestration/stage_runtime/crest.py +229 -0
  85. orca_auto_workflows-6.0.0/src/orca_auto/flow/orchestration/stage_runtime/orca.py +326 -0
  86. orca_auto_workflows-6.0.0/src/orca_auto/flow/orchestration/stage_runtime/shared.py +329 -0
  87. orca_auto_workflows-6.0.0/src/orca_auto/flow/orchestration/stage_view_mutators.py +156 -0
  88. orca_auto_workflows-6.0.0/src/orca_auto/flow/orchestration/stage_views.py +250 -0
  89. orca_auto_workflows-6.0.0/src/orca_auto/flow/orchestration/support.py +77 -0
  90. orca_auto_workflows-6.0.0/src/orca_auto/flow/orchestration/template_builders.py +145 -0
  91. orca_auto_workflows-6.0.0/src/orca_auto/flow/orchestration/workflow_builders.py +322 -0
  92. orca_auto_workflows-6.0.0/src/orca_auto/flow/orchestration/workflow_cancellation.py +572 -0
  93. orca_auto_workflows-6.0.0/src/orca_auto/flow/py.typed +0 -0
  94. orca_auto_workflows-6.0.0/src/orca_auto/flow/registry/__init__.py +55 -0
  95. orca_auto_workflows-6.0.0/src/orca_auto/flow/registry/_markers.py +137 -0
  96. orca_auto_workflows-6.0.0/src/orca_auto/flow/registry/_notifications.py +324 -0
  97. orca_auto_workflows-6.0.0/src/orca_auto/flow/registry/journal.py +290 -0
  98. orca_auto_workflows-6.0.0/src/orca_auto/flow/registry/store.py +587 -0
  99. orca_auto_workflows-6.0.0/src/orca_auto/flow/registry/worker_state_store.py +117 -0
  100. orca_auto_workflows-6.0.0/src/orca_auto/flow/restart/__init__.py +97 -0
  101. orca_auto_workflows-6.0.0/src/orca_auto/flow/restart/mutation.py +398 -0
  102. orca_auto_workflows-6.0.0/src/orca_auto/flow/restart/orca_input.py +517 -0
  103. orca_auto_workflows-6.0.0/src/orca_auto/flow/restart/settings.py +797 -0
  104. orca_auto_workflows-6.0.0/src/orca_auto/flow/restart/stage_ops.py +371 -0
  105. orca_auto_workflows-6.0.0/src/orca_auto/flow/restart/stages.py +153 -0
  106. orca_auto_workflows-6.0.0/src/orca_auto/flow/run_dir/__init__.py +1 -0
  107. orca_auto_workflows-6.0.0/src/orca_auto/flow/run_dir/layout.py +40 -0
  108. orca_auto_workflows-6.0.0/src/orca_auto/flow/run_dir/manifest.py +124 -0
  109. orca_auto_workflows-6.0.0/src/orca_auto/flow/run_dir/options.py +374 -0
  110. orca_auto_workflows-6.0.0/src/orca_auto/flow/runtime/__init__.py +375 -0
  111. orca_auto_workflows-6.0.0/src/orca_auto/flow/runtime/admission.py +178 -0
  112. orca_auto_workflows-6.0.0/src/orca_auto/flow/runtime/advance.py +352 -0
  113. orca_auto_workflows-6.0.0/src/orca_auto/flow/runtime/cycle.py +78 -0
  114. orca_auto_workflows-6.0.0/src/orca_auto/flow/runtime/models.py +145 -0
  115. orca_auto_workflows-6.0.0/src/orca_auto/flow/runtime/results.py +118 -0
  116. orca_auto_workflows-6.0.0/src/orca_auto/flow/scaffold.py +277 -0
  117. orca_auto_workflows-6.0.0/src/orca_auto/flow/stage_event_metadata.py +109 -0
  118. orca_auto_workflows-6.0.0/src/orca_auto/flow/stage_transition_events.py +243 -0
  119. orca_auto_workflows-6.0.0/src/orca_auto/flow/state.py +47 -0
  120. orca_auto_workflows-6.0.0/src/orca_auto/flow/submitters/__init__.py +1 -0
  121. orca_auto_workflows-6.0.0/src/orca_auto/flow/submitters/crest.py +58 -0
  122. orca_auto_workflows-6.0.0/src/orca_auto/flow/submitters/internal_engine_builder.py +65 -0
  123. orca_auto_workflows-6.0.0/src/orca_auto/flow/submitters/internal_engine_cancellation.py +269 -0
  124. orca_auto_workflows-6.0.0/src/orca_auto/flow/submitters/internal_engine_models.py +27 -0
  125. orca_auto_workflows-6.0.0/src/orca_auto/flow/submitters/internal_engine_submission.py +765 -0
  126. orca_auto_workflows-6.0.0/src/orca_auto/flow/submitters/orca.py +246 -0
  127. orca_auto_workflows-6.0.0/src/orca_auto/flow/submitters/xtb.py +76 -0
  128. orca_auto_workflows-6.0.0/src/orca_auto/flow/templates.py +92 -0
  129. orca_auto_workflows-6.0.0/src/orca_auto/flow/workflow/__init__.py +1 -0
  130. orca_auto_workflows-6.0.0/src/orca_auto/flow/workflow/_phases.py +289 -0
  131. orca_auto_workflows-6.0.0/src/orca_auto/flow/workflow/machine.py +310 -0
  132. orca_auto_workflows-6.0.0/src/orca_auto/flow/workflow/notifications.py +317 -0
  133. orca_auto_workflows-6.0.0/src/orca_auto/flow/workflow/report_collection.py +353 -0
  134. orca_auto_workflows-6.0.0/src/orca_auto/flow/workflow/report_diagnostics.py +217 -0
  135. orca_auto_workflows-6.0.0/src/orca_auto/flow/workflow/report_energy_evidence.py +269 -0
  136. orca_auto_workflows-6.0.0/src/orca_auto/flow/workflow/report_rendering.py +388 -0
  137. orca_auto_workflows-6.0.0/src/orca_auto/flow/workflow/si/__init__.py +1 -0
  138. orca_auto_workflows-6.0.0/src/orca_auto/flow/workflow/si/collection.py +1222 -0
  139. orca_auto_workflows-6.0.0/src/orca_auto/flow/workflow/si/publication.py +106 -0
  140. orca_auto_workflows-6.0.0/src/orca_auto/flow/workflow/si/rendering.py +454 -0
  141. orca_auto_workflows-6.0.0/src/orca_auto/flow/workflow/stage_summary.py +115 -0
  142. orca_auto_workflows-6.0.0/src/orca_auto/flow/workflow/status.py +31 -0
  143. orca_auto_workflows-6.0.0/src/orca_auto/flow/workflow/store.py +160 -0
  144. orca_auto_workflows-6.0.0/src/orca_auto/flow/workflow/summary.py +171 -0
  145. orca_auto_workflows-6.0.0/src/orca_auto/flow/xyz_utils.py +505 -0
  146. orca_auto_workflows-6.0.0/src/orca_auto_workflows.egg-info/PKG-INFO +69 -0
  147. orca_auto_workflows-6.0.0/src/orca_auto_workflows.egg-info/SOURCES.txt +148 -0
  148. orca_auto_workflows-6.0.0/src/orca_auto_workflows.egg-info/dependency_links.txt +1 -0
  149. orca_auto_workflows-6.0.0/src/orca_auto_workflows.egg-info/requires.txt +1 -0
  150. orca_auto_workflows-6.0.0/src/orca_auto_workflows.egg-info/top_level.txt +1 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Daehyup Sohn
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,69 @@
1
+ Metadata-Version: 2.4
2
+ Name: orca_auto_workflows
3
+ Version: 6.0.0
4
+ Summary: Optional CREST, xTB and multi-stage workflow extension for ORCA_auto
5
+ Author: Daehyup Sohn
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 Daehyup Sohn
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/dhsohn/orca_auto
29
+ Project-URL: Repository, https://github.com/dhsohn/orca_auto
30
+ Project-URL: Issues, https://github.com/dhsohn/orca_auto/issues
31
+ Project-URL: Documentation, https://github.com/dhsohn/orca_auto/blob/v6.0.0/docs/INSTALLATION.md
32
+ Project-URL: Changelog, https://github.com/dhsohn/orca_auto/blob/v6.0.0/CHANGELOG.md
33
+ Requires-Python: >=3.11
34
+ Description-Content-Type: text/markdown
35
+ License-File: LICENSE
36
+ Requires-Dist: orca_auto==6.0.0
37
+ Dynamic: license-file
38
+
39
+ # ORCA_auto workflows
40
+
41
+ The optional workflow distribution for [ORCA_auto](https://github.com/dhsohn/orca_auto).
42
+ It provides CREST-based conformer screening, ORCA refinement, and supervised
43
+ workflow workers while the core distribution owns the `orca_auto` command,
44
+ shared queue infrastructure and standalone ORCA execution. Python imports remain
45
+ `orca_auto.flow`.
46
+
47
+ Version `6.0.0` supports only `conformer_screening`
48
+ (`orca_auto scaffold conformer_search <path>`). The former TS
49
+ workflows are removed without compatibility or automatic migration; see the
50
+ [cutover warning](https://github.com/dhsohn/orca_auto/blob/v6.0.0/docs/RELEASE.md#removing-ts-workflows-in-60).
51
+
52
+ Both distributions must have exactly the same version. In a fresh environment,
53
+ install the matching pair from PyPI:
54
+
55
+ ```bash
56
+ python -m pip install 'orca_auto[workflows]==6.0.0'
57
+ ```
58
+
59
+ For an editable development installation from the repository root:
60
+
61
+ ```bash
62
+ python -m pip install -e . -e ./extensions/workflows
63
+ ```
64
+
65
+ Follow the [installation guide](https://github.com/dhsohn/orca_auto/blob/v6.0.0/docs/INSTALLATION.md)
66
+ to configure engines and systemd templates; installing a wheel alone does not
67
+ deploy services. The historical
68
+ [5.0.0 release](https://github.com/dhsohn/orca_auto/releases/tag/v5.0.0)
69
+ predates the TS-workflow removal and does not represent the 6.0 workflow scope.
@@ -0,0 +1,31 @@
1
+ # ORCA_auto workflows
2
+
3
+ The optional workflow distribution for [ORCA_auto](https://github.com/dhsohn/orca_auto).
4
+ It provides CREST-based conformer screening, ORCA refinement, and supervised
5
+ workflow workers while the core distribution owns the `orca_auto` command,
6
+ shared queue infrastructure and standalone ORCA execution. Python imports remain
7
+ `orca_auto.flow`.
8
+
9
+ Version `6.0.0` supports only `conformer_screening`
10
+ (`orca_auto scaffold conformer_search <path>`). The former TS
11
+ workflows are removed without compatibility or automatic migration; see the
12
+ [cutover warning](https://github.com/dhsohn/orca_auto/blob/v6.0.0/docs/RELEASE.md#removing-ts-workflows-in-60).
13
+
14
+ Both distributions must have exactly the same version. In a fresh environment,
15
+ install the matching pair from PyPI:
16
+
17
+ ```bash
18
+ python -m pip install 'orca_auto[workflows]==6.0.0'
19
+ ```
20
+
21
+ For an editable development installation from the repository root:
22
+
23
+ ```bash
24
+ python -m pip install -e . -e ./extensions/workflows
25
+ ```
26
+
27
+ Follow the [installation guide](https://github.com/dhsohn/orca_auto/blob/v6.0.0/docs/INSTALLATION.md)
28
+ to configure engines and systemd templates; installing a wheel alone does not
29
+ deploy services. The historical
30
+ [5.0.0 release](https://github.com/dhsohn/orca_auto/releases/tag/v5.0.0)
31
+ predates the TS-workflow removal and does not represent the 6.0 workflow scope.
@@ -0,0 +1,28 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "orca_auto_workflows"
7
+ version = "6.0.0"
8
+ description = "Optional CREST, xTB and multi-stage workflow extension for ORCA_auto"
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = { file = "LICENSE" }
12
+ authors = [{ name = "Daehyup Sohn" }]
13
+ dependencies = ["orca_auto==6.0.0"]
14
+
15
+ [project.urls]
16
+ Homepage = "https://github.com/dhsohn/orca_auto"
17
+ Repository = "https://github.com/dhsohn/orca_auto"
18
+ Issues = "https://github.com/dhsohn/orca_auto/issues"
19
+ Documentation = "https://github.com/dhsohn/orca_auto/blob/v6.0.0/docs/INSTALLATION.md"
20
+ Changelog = "https://github.com/dhsohn/orca_auto/blob/v6.0.0/CHANGELOG.md"
21
+
22
+ [tool.setuptools.packages.find]
23
+ where = ["src"]
24
+ include = ["orca_auto", "orca_auto.flow", "orca_auto.flow.*"]
25
+ namespaces = true
26
+
27
+ [tool.setuptools.package-data]
28
+ "orca_auto.flow" = ["py.typed"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,5 @@
1
+ """Workflow implementation package."""
2
+
3
+ from orca_auto.core.extensions import validate_workflow_installation
4
+
5
+ validate_workflow_installation()
@@ -0,0 +1,469 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, replace
4
+ from pathlib import Path
5
+ from typing import Any
6
+
7
+ from orca_auto.core.app_ids import (
8
+ ORCA_AUTO_CLI_COMMAND,
9
+ ORCA_AUTO_CLI_MODULE,
10
+ ORCA_AUTO_ORCA_SUBMITTER,
11
+ )
12
+ from orca_auto.core.engine_process import (
13
+ atomic_write_confined_bytes,
14
+ ensure_confined_directory,
15
+ require_confined_regular_file,
16
+ )
17
+ from orca_auto.core.utils import atomic_write_json, normalize_text
18
+ from orca_auto.core.utils.coercion import safe_int
19
+ from orca_auto.orca.resource_directives import maxcore_mb_per_core
20
+
21
+ from . import _orca_stage_payloads
22
+ from . import orca_stage_validation as _orca_stage_validation
23
+ from .contracts import WorkflowArtifactRef, WorkflowStage, WorkflowStageInput, WorkflowTask
24
+ from .manifest import require_int
25
+ from .xyz_utils import write_orca_ready_xyz
26
+
27
+
28
+ def safe_name(value: str, *, fallback: str) -> str:
29
+ cleaned = "".join(
30
+ ch if ch.isalnum() or ch in {"_", "-", "."} else "_" for ch in normalize_text(value)
31
+ )
32
+ cleaned = cleaned.strip("._-").lower()
33
+ return cleaned or fallback
34
+
35
+
36
+ def _positive_multiplicity(value: int) -> int:
37
+ return require_int(value, field="multiplicity", minimum=1)
38
+
39
+
40
+ def render_orca_input(
41
+ *,
42
+ route_line: str,
43
+ charge: int,
44
+ multiplicity: int,
45
+ max_cores: int,
46
+ max_memory_gb: int,
47
+ xyz_filename: str,
48
+ ) -> str:
49
+ parsed_charge = require_int(charge, field="charge")
50
+ parsed_multiplicity = _positive_multiplicity(multiplicity)
51
+ return "\n".join(
52
+ [
53
+ _orca_stage_validation.ensure_route_line(route_line),
54
+ "",
55
+ "%pal",
56
+ f" nprocs {max(1, int(max_cores))}",
57
+ "end",
58
+ f"%maxcore {maxcore_mb_per_core(max_memory_gb=max_memory_gb, max_cores=max_cores)}",
59
+ "",
60
+ f"* xyzfile {parsed_charge} {parsed_multiplicity} {xyz_filename}",
61
+ "",
62
+ ]
63
+ )
64
+
65
+
66
+ def build_orca_enqueue_payload(
67
+ *,
68
+ workflow_id: str,
69
+ stage_id: str,
70
+ reaction_dir: str,
71
+ selected_inp: str,
72
+ priority: int,
73
+ resource_request: dict[str, int],
74
+ source_job_id: str,
75
+ reaction_key: str,
76
+ ) -> dict[str, Any]:
77
+ config_placeholder = "<orca_auto_config>"
78
+ resources = _enqueue_resource_values(resource_request)
79
+ command_argv = _orca_enqueue_command_argv(
80
+ config_placeholder=config_placeholder,
81
+ reaction_dir=reaction_dir,
82
+ priority=priority,
83
+ resources=resources,
84
+ )
85
+ command = _orca_enqueue_command(
86
+ config_placeholder=config_placeholder,
87
+ reaction_dir=reaction_dir,
88
+ priority=priority,
89
+ resources=resources,
90
+ )
91
+ return {
92
+ "submitter": ORCA_AUTO_ORCA_SUBMITTER,
93
+ "command": command,
94
+ "command_argv": command_argv,
95
+ "requires_config": True,
96
+ "config_argument_placeholder": config_placeholder,
97
+ "reaction_dir": reaction_dir,
98
+ "selected_inp": selected_inp,
99
+ "priority": int(priority),
100
+ "force": False,
101
+ "max_cores": resources["max_cores"],
102
+ "max_memory_gb": resources["max_memory_gb"],
103
+ "workflow_id": workflow_id,
104
+ "workflow_stage_id": stage_id,
105
+ "source_job_id": source_job_id,
106
+ "reaction_key": reaction_key,
107
+ "resource_request": dict(resource_request),
108
+ }
109
+
110
+
111
+ def _enqueue_resource_values(resource_request: dict[str, int]) -> dict[str, int]:
112
+ return {
113
+ "max_cores": int(resource_request.get("max_cores", 0) or 0),
114
+ "max_memory_gb": int(resource_request.get("max_memory_gb", 0) or 0),
115
+ }
116
+
117
+
118
+ def _resource_override_argv(resources: dict[str, int]) -> list[str]:
119
+ argv: list[str] = []
120
+ if resources["max_cores"] > 0:
121
+ argv.extend(["--max-cores", str(resources["max_cores"])])
122
+ if resources["max_memory_gb"] > 0:
123
+ argv.extend(["--max-memory-gb", str(resources["max_memory_gb"])])
124
+ return argv
125
+
126
+
127
+ def _resource_override_command_parts(resources: dict[str, int]) -> list[str]:
128
+ parts: list[str] = []
129
+ if resources["max_cores"] > 0:
130
+ parts.append(f"--max-cores {resources['max_cores']}")
131
+ if resources["max_memory_gb"] > 0:
132
+ parts.append(f"--max-memory-gb {resources['max_memory_gb']}")
133
+ return parts
134
+
135
+
136
+ def _orca_enqueue_command_argv(
137
+ *,
138
+ config_placeholder: str,
139
+ reaction_dir: str,
140
+ priority: int,
141
+ resources: dict[str, int],
142
+ ) -> list[str]:
143
+ return [
144
+ "python",
145
+ "-m",
146
+ ORCA_AUTO_CLI_MODULE,
147
+ "--config",
148
+ config_placeholder,
149
+ "run-dir",
150
+ reaction_dir,
151
+ "--priority",
152
+ str(int(priority)),
153
+ *_resource_override_argv(resources),
154
+ ]
155
+
156
+
157
+ def _orca_enqueue_command(
158
+ *,
159
+ config_placeholder: str,
160
+ reaction_dir: str,
161
+ priority: int,
162
+ resources: dict[str, int],
163
+ ) -> str:
164
+ command_parts = [
165
+ f"{ORCA_AUTO_CLI_COMMAND} --config {config_placeholder}",
166
+ "run-dir",
167
+ f"'{reaction_dir}'",
168
+ f"--priority {int(priority)}",
169
+ *_resource_override_command_parts(resources),
170
+ ]
171
+ return " ".join(command_parts)
172
+
173
+
174
+ @dataclass(frozen=True)
175
+ class OrcaStageMaterialization:
176
+ reaction_dir: str
177
+ selected_inp: str
178
+ selected_xyz: str
179
+ stage_workspace_dir: str
180
+
181
+
182
+ @dataclass(frozen=True)
183
+ class OrcaStageMaterializationRequest:
184
+ workspace_dir: Path
185
+ stage_key: str
186
+ source_artifact_path: str
187
+ candidate_kind: str
188
+ route_line: str
189
+ charge: int
190
+ multiplicity: int
191
+ max_cores: int
192
+ max_memory_gb: int
193
+ xyz_filename: str = "input.xyz"
194
+ inp_filename: str = "input.inp"
195
+ source_frame_index: int = 0
196
+ extra_source_payload: dict[str, Any] | None = None
197
+ source_artifact_identity: dict[str, Any] | None = None
198
+
199
+
200
+ @dataclass(frozen=True)
201
+ class OrcaStageBuildContext:
202
+ workflow_id: str
203
+ template_name: str
204
+ stage_id: str
205
+ stage_key: str
206
+ workspace_dir: Path
207
+ input_artifact_kind: str
208
+ candidate: WorkflowStageInput
209
+ task_kind: str
210
+ route_line: str
211
+ charge: int
212
+ multiplicity: int
213
+ max_cores: int
214
+ max_memory_gb: int
215
+ priority: int
216
+ xyz_filename: str
217
+ inp_filename: str
218
+ input_label: str | None = None
219
+
220
+ @property
221
+ def resource_request(self) -> dict[str, int]:
222
+ return {
223
+ "max_cores": max(1, int(self.max_cores)),
224
+ "max_memory_gb": max(1, int(self.max_memory_gb)),
225
+ }
226
+
227
+ @property
228
+ def selected_input_label(self) -> str:
229
+ return self.input_label or Path(self.candidate.artifact_path).name
230
+
231
+ def materialization_request(
232
+ self, *, extra_source_payload: dict[str, Any] | None = None
233
+ ) -> OrcaStageMaterializationRequest:
234
+ source_identity_raw = self.candidate.metadata.get("output_identity")
235
+ source_identity = (
236
+ dict(source_identity_raw) if isinstance(source_identity_raw, dict) else None
237
+ )
238
+ return OrcaStageMaterializationRequest(
239
+ workspace_dir=self.workspace_dir,
240
+ stage_key=self.stage_key,
241
+ source_artifact_path=self.candidate.artifact_path,
242
+ candidate_kind=self.candidate.kind,
243
+ route_line=self.route_line,
244
+ charge=self.charge,
245
+ multiplicity=self.multiplicity,
246
+ max_cores=self.max_cores,
247
+ max_memory_gb=self.max_memory_gb,
248
+ xyz_filename=self.xyz_filename,
249
+ inp_filename=self.inp_filename,
250
+ source_frame_index=_candidate_source_frame_index(self.candidate),
251
+ extra_source_payload=extra_source_payload,
252
+ source_artifact_identity=source_identity,
253
+ )
254
+
255
+
256
+ def _candidate_source_frame_index(candidate: WorkflowStageInput) -> int:
257
+ metadata = candidate.metadata if isinstance(candidate.metadata, dict) else {}
258
+ return max(0, safe_int(metadata.get("source_frame_index", 0), default=0))
259
+
260
+
261
+ def materialize_orca_stage_from_request(
262
+ request: OrcaStageMaterializationRequest,
263
+ ) -> OrcaStageMaterialization:
264
+ source_xyz = Path(request.source_artifact_path).expanduser()
265
+ source_xyz = require_confined_regular_file(
266
+ source_xyz.parent,
267
+ source_xyz,
268
+ label="ORCA stage source artifact",
269
+ )
270
+
271
+ stage_dir = _orca_stage_dir(request)
272
+ reaction_dir = ensure_confined_directory(
273
+ request.workspace_dir,
274
+ stage_dir,
275
+ label="ORCA stage directory",
276
+ )
277
+
278
+ target_xyz, geometry_metadata = _materialize_orca_geometry(
279
+ request=request,
280
+ source_xyz=source_xyz,
281
+ reaction_dir=reaction_dir,
282
+ )
283
+ target_inp = _write_orca_input_file(
284
+ request=request,
285
+ reaction_dir=reaction_dir,
286
+ xyz_filename=target_xyz.name,
287
+ )
288
+ extra_source_payload = dict(request.extra_source_payload or {})
289
+ _write_source_candidate_payload(
290
+ stage_dir=stage_dir,
291
+ source_xyz=source_xyz,
292
+ geometry_metadata=geometry_metadata,
293
+ extra_source_payload=extra_source_payload,
294
+ )
295
+ return OrcaStageMaterialization(
296
+ reaction_dir=str(reaction_dir),
297
+ selected_inp=str(target_inp),
298
+ selected_xyz=str(target_xyz),
299
+ stage_workspace_dir=str(stage_dir),
300
+ )
301
+
302
+
303
+ def _orca_stage_dir(request: OrcaStageMaterializationRequest) -> Path:
304
+ return request.workspace_dir / request.stage_key
305
+
306
+
307
+ def _materialize_orca_geometry(
308
+ *,
309
+ request: OrcaStageMaterializationRequest,
310
+ source_xyz: Path,
311
+ reaction_dir: Path,
312
+ ) -> tuple[Path, dict[str, Any]]:
313
+ target_xyz = reaction_dir / request.xyz_filename
314
+ geometry_metadata = write_orca_ready_xyz(
315
+ source_path=source_xyz,
316
+ target_path=target_xyz,
317
+ candidate_kind=request.candidate_kind,
318
+ source_frame_index=request.source_frame_index,
319
+ source_identity=request.source_artifact_identity,
320
+ )
321
+ return target_xyz, dict(geometry_metadata)
322
+
323
+
324
+ def _write_orca_input_file(
325
+ *,
326
+ request: OrcaStageMaterializationRequest,
327
+ reaction_dir: Path,
328
+ xyz_filename: str,
329
+ ) -> Path:
330
+ target_inp = reaction_dir / request.inp_filename
331
+ atomic_write_confined_bytes(
332
+ reaction_dir,
333
+ target_inp,
334
+ render_orca_input(
335
+ route_line=request.route_line,
336
+ charge=request.charge,
337
+ multiplicity=request.multiplicity,
338
+ max_cores=request.max_cores,
339
+ max_memory_gb=request.max_memory_gb,
340
+ xyz_filename=xyz_filename,
341
+ ).encode("utf-8"),
342
+ label="ORCA materialized input",
343
+ )
344
+ return target_inp
345
+
346
+
347
+ def _write_source_candidate_payload(
348
+ *,
349
+ stage_dir: Path,
350
+ source_xyz: Path,
351
+ geometry_metadata: dict[str, Any],
352
+ extra_source_payload: dict[str, Any] | None,
353
+ ) -> None:
354
+ source_payload = {
355
+ "source_artifact_path": str(source_xyz),
356
+ "geometry_materialization": dict(geometry_metadata),
357
+ **dict(extra_source_payload or {}),
358
+ }
359
+ atomic_write_json(
360
+ stage_dir / "source_candidate.json", source_payload, ensure_ascii=True, indent=2
361
+ )
362
+
363
+
364
+ def build_materialized_orca_stage(
365
+ *,
366
+ workflow_id: str,
367
+ template_name: str,
368
+ stage_id: str,
369
+ stage_key: str,
370
+ workspace_dir: Path,
371
+ input_artifact_kind: str,
372
+ candidate: WorkflowStageInput,
373
+ task_kind: str,
374
+ route_line: str,
375
+ charge: int,
376
+ multiplicity: int,
377
+ max_cores: int,
378
+ max_memory_gb: int,
379
+ priority: int,
380
+ xyz_filename: str,
381
+ inp_filename: str,
382
+ input_label: str | None = None,
383
+ ) -> WorkflowStage:
384
+ ctx = OrcaStageBuildContext(
385
+ workflow_id=workflow_id,
386
+ template_name=template_name,
387
+ stage_id=stage_id,
388
+ stage_key=stage_key,
389
+ workspace_dir=workspace_dir,
390
+ input_artifact_kind=input_artifact_kind,
391
+ candidate=candidate,
392
+ task_kind=task_kind,
393
+ route_line=route_line,
394
+ charge=charge,
395
+ multiplicity=multiplicity,
396
+ max_cores=max_cores,
397
+ max_memory_gb=max_memory_gb,
398
+ priority=priority,
399
+ xyz_filename=xyz_filename,
400
+ inp_filename=inp_filename,
401
+ input_label=input_label,
402
+ )
403
+ ctx = replace(
404
+ ctx,
405
+ route_line=_orca_stage_validation.validate_workflow_orca_route(
406
+ task_kind=ctx.task_kind,
407
+ route_line=ctx.route_line,
408
+ ),
409
+ )
410
+ resource_request = ctx.resource_request
411
+ materialized = materialize_orca_stage_from_request(
412
+ ctx.materialization_request(
413
+ extra_source_payload=_orca_stage_payloads.candidate_source_payload(ctx.candidate)
414
+ )
415
+ )
416
+ _orca_stage_validation.validate_workflow_orca_input(
417
+ task_kind=ctx.task_kind,
418
+ inp_path=Path(materialized.selected_inp),
419
+ )
420
+ enqueue_payload = build_orca_enqueue_payload(
421
+ workflow_id=ctx.workflow_id,
422
+ stage_id=ctx.stage_id,
423
+ reaction_dir=materialized.reaction_dir,
424
+ selected_inp=materialized.selected_inp,
425
+ priority=ctx.priority,
426
+ resource_request=resource_request,
427
+ source_job_id=ctx.candidate.source_job_id,
428
+ reaction_key=ctx.candidate.reaction_key,
429
+ )
430
+ task_payload = _orca_stage_payloads.task_payload(
431
+ ctx=ctx,
432
+ materialized=materialized,
433
+ resource_request=resource_request,
434
+ cli_command=ORCA_AUTO_CLI_COMMAND,
435
+ )
436
+ task = _orca_stage_payloads.workflow_task(
437
+ ctx=ctx,
438
+ materialized=materialized,
439
+ resource_request=resource_request,
440
+ enqueue_payload=enqueue_payload,
441
+ task_payload=task_payload,
442
+ workflow_task_cls=WorkflowTask,
443
+ )
444
+ atomic_write_json(
445
+ Path(materialized.stage_workspace_dir) / "enqueue_payload.json",
446
+ enqueue_payload,
447
+ ensure_ascii=True,
448
+ indent=2,
449
+ )
450
+ return _orca_stage_payloads.workflow_stage(
451
+ ctx=ctx,
452
+ materialized=materialized,
453
+ task=task,
454
+ workflow_stage_cls=WorkflowStage,
455
+ artifact_ref_cls=WorkflowArtifactRef,
456
+ )
457
+
458
+
459
+ __all__ = [
460
+ "build_materialized_orca_stage",
461
+ "build_orca_enqueue_payload",
462
+ "materialize_orca_stage_from_request",
463
+ "normalize_text",
464
+ "OrcaStageBuildContext",
465
+ "OrcaStageMaterialization",
466
+ "OrcaStageMaterializationRequest",
467
+ "render_orca_input",
468
+ "safe_name",
469
+ ]