aXqua 1.0.1__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.
Files changed (206) hide show
  1. axqua/__init__.py +238 -0
  2. axqua/__main__.py +16 -0
  3. axqua/bayescal.py +714 -0
  4. axqua/boundary.py +19 -0
  5. axqua/calibration.py +464 -0
  6. axqua/campaigns.py +249 -0
  7. axqua/casecli.py +164 -0
  8. axqua/cleanup.py +668 -0
  9. axqua/cleanupcli.py +75 -0
  10. axqua/cli.py +816 -0
  11. axqua/config.py +2708 -0
  12. axqua/convergence.py +1368 -0
  13. axqua/core/__init__.py +31 -0
  14. axqua/core/boundaries.py +128 -0
  15. axqua/core/capabilities.py +399 -0
  16. axqua/core/casecheck.py +271 -0
  17. axqua/core/casefile.py +62 -0
  18. axqua/core/diagnostics.py +85 -0
  19. axqua/core/environment.py +512 -0
  20. axqua/core/errors.py +168 -0
  21. axqua/core/examples.py +343 -0
  22. axqua/core/geodata.py +463 -0
  23. axqua/core/machine.py +250 -0
  24. axqua/core/profile.py +858 -0
  25. axqua/core/raster.py +53 -0
  26. axqua/core/registry.py +373 -0
  27. axqua/core/schema.py +223 -0
  28. axqua/core/schema_meta.py +583 -0
  29. axqua/core/selafin.py +405 -0
  30. axqua/core/structures.py +604 -0
  31. axqua/core/surfaces.py +730 -0
  32. axqua/dem.py +341 -0
  33. axqua/docscli.py +208 -0
  34. axqua/env.py +240 -0
  35. axqua/examplecli.py +62 -0
  36. axqua/exportcli.py +183 -0
  37. axqua/flowtracker.py +366 -0
  38. axqua/flux_convergence.py +19 -0
  39. axqua/fortran.py +19 -0
  40. axqua/gainlose.py +19 -0
  41. axqua/georef.py +273 -0
  42. axqua/ground_truth.py +681 -0
  43. axqua/ground_truth_qa.py +239 -0
  44. axqua/gui/__init__.py +5 -0
  45. axqua/gui/app.py +914 -0
  46. axqua/gui/launch.py +30 -0
  47. axqua/hbc.py +319 -0
  48. axqua/hydraulics.py +209 -0
  49. axqua/install/__init__.py +12 -0
  50. axqua/install/host.py +144 -0
  51. axqua/install/recipes.py +1374 -0
  52. axqua/install/runner.py +637 -0
  53. axqua/install/telemac_examples.py +188 -0
  54. axqua/install/vendor/OpenFOAM-installer/LICENSE +24 -0
  55. axqua/install/vendor/OpenFOAM-installer/LICENSES/GPL-3.0-or-later.txt +674 -0
  56. axqua/install/vendor/OpenFOAM-installer/README.md +47 -0
  57. axqua/install/vendor/OpenFOAM-installer/THIRD_PARTY.md +20 -0
  58. axqua/install/vendor/OpenFOAM-installer/VENDORED.md +14 -0
  59. axqua/install/vendor/OpenFOAM-installer/cpp/olsenRatingCurve.H +343 -0
  60. axqua/install/vendor/OpenFOAM-installer/docs/RATING_CURVE.md +34 -0
  61. axqua/install/vendor/OpenFOAM-installer/docs/RECOVERY.md +144 -0
  62. axqua/install/vendor/OpenFOAM-installer/docs/VISUALIZATION.md +40 -0
  63. axqua/install/vendor/OpenFOAM-installer/examples/ratingCurveProperties +27 -0
  64. axqua/install/vendor/OpenFOAM-installer/install.ps1 +61 -0
  65. axqua/install/vendor/OpenFOAM-installer/install.py +6 -0
  66. axqua/install/vendor/OpenFOAM-installer/olsen-sources/README.md +13 -0
  67. axqua/install/vendor/OpenFOAM-installer/olsen-sources/sediDriftFoam/Make/files +3 -0
  68. axqua/install/vendor/OpenFOAM-installer/olsen-sources/sediDriftFoam/Make/options +18 -0
  69. axqua/install/vendor/OpenFOAM-installer/olsen-sources/sediDriftFoam/UEqn.H +24 -0
  70. axqua/install/vendor/OpenFOAM-installer/olsen-sources/sediDriftFoam/createFields.H +168 -0
  71. axqua/install/vendor/OpenFOAM-installer/olsen-sources/sediDriftFoam/createPhiC.H +82 -0
  72. axqua/install/vendor/OpenFOAM-installer/olsen-sources/sediDriftFoam/pEqn.H +50 -0
  73. axqua/install/vendor/OpenFOAM-installer/olsen-sources/sediDriftFoam/sediDriftFoam.C +194 -0
  74. axqua/install/vendor/OpenFOAM-installer/olsen-sources/sediDriftFoam/sediDriftFoam1.C +218 -0
  75. axqua/install/vendor/OpenFOAM-installer/olsen-sources/sediDriftFoam2/Make/files +3 -0
  76. axqua/install/vendor/OpenFOAM-installer/olsen-sources/sediDriftFoam2/Make/options +29 -0
  77. axqua/install/vendor/OpenFOAM-installer/olsen-sources/sediDriftFoam2/UEqn.H +24 -0
  78. axqua/install/vendor/OpenFOAM-installer/olsen-sources/sediDriftFoam2/computevx.h +66 -0
  79. axqua/install/vendor/OpenFOAM-installer/olsen-sources/sediDriftFoam2/computevx1.h +36 -0
  80. axqua/install/vendor/OpenFOAM-installer/olsen-sources/sediDriftFoam2/computevx2.h +34 -0
  81. axqua/install/vendor/OpenFOAM-installer/olsen-sources/sediDriftFoam2/computevx3.h +53 -0
  82. axqua/install/vendor/OpenFOAM-installer/olsen-sources/sediDriftFoam2/computevx4.h +36 -0
  83. axqua/install/vendor/OpenFOAM-installer/olsen-sources/sediDriftFoam2/createFields.H +134 -0
  84. axqua/install/vendor/OpenFOAM-installer/olsen-sources/sediDriftFoam2/createPhiC.H +82 -0
  85. axqua/install/vendor/OpenFOAM-installer/olsen-sources/sediDriftFoam2/pEqn.H +50 -0
  86. axqua/install/vendor/OpenFOAM-installer/olsen-sources/sediDriftFoam2/sediDriftFoam2.C +456 -0
  87. axqua/install/vendor/OpenFOAM-installer/postprocess.py +144 -0
  88. axqua/install/vendor/OpenFOAM-installer/sediment_installer/__init__.py +1 -0
  89. axqua/install/vendor/OpenFOAM-installer/sediment_installer/core.py +269 -0
  90. axqua/install/vendor/OpenFOAM-installer/sediment_installer/installer.py +565 -0
  91. axqua/install/vendor/OpenFOAM-installer/sediment_installer/olsen_patch.py +156 -0
  92. axqua/install/vendor/OpenFOAM-installer/sediment_installer/olsen_sources.json +27 -0
  93. axqua/install/vendor/OpenFOAM-installer/sediment_installer/visualization.py +170 -0
  94. axqua/install/vendor/OpenFOAM-installer/tests/test_archive_cache.py +184 -0
  95. axqua/install/vendor/OpenFOAM-installer/tests/test_core.py +533 -0
  96. axqua/install/vendor/OpenFOAM-installer/tests/test_olsen_bundle.py +56 -0
  97. axqua/install/vendor/OpenFOAM-installer/tests/test_olsen_patch.py +120 -0
  98. axqua/install/vendor/OpenFOAM-installer/tests/test_shell_env.py +336 -0
  99. axqua/install/vendor/OpenFOAM-installer/tests/test_smoke_rerun.py +79 -0
  100. axqua/install/vendor/OpenFOAM-installer/tests/test_upstream_environment.py +263 -0
  101. axqua/install/vendor/OpenFOAM-installer/tests/test_visualization.py +172 -0
  102. axqua/install/vendor/OpenFOAM-installer/undo_installation.sh +8 -0
  103. axqua/installcli.py +325 -0
  104. axqua/jobcli.py +674 -0
  105. axqua/jobs/__init__.py +110 -0
  106. axqua/jobs/events.py +291 -0
  107. axqua/jobs/executor.py +535 -0
  108. axqua/jobs/ids.py +92 -0
  109. axqua/jobs/index.py +346 -0
  110. axqua/jobs/interaction.py +99 -0
  111. axqua/jobs/launcher.py +240 -0
  112. axqua/jobs/launchers/__init__.py +6 -0
  113. axqua/jobs/launchers/posix.py +135 -0
  114. axqua/jobs/launchers/systemd.py +183 -0
  115. axqua/jobs/launchers/windows.py +227 -0
  116. axqua/jobs/launchers/wsl.py +173 -0
  117. axqua/jobs/lock.py +185 -0
  118. axqua/jobs/logs.py +153 -0
  119. axqua/jobs/model.py +843 -0
  120. axqua/jobs/paths.py +295 -0
  121. axqua/jobs/procs.py +214 -0
  122. axqua/jobs/profiles.py +350 -0
  123. axqua/jobs/reaper.py +137 -0
  124. axqua/jobs/results.py +165 -0
  125. axqua/jobs/store.py +206 -0
  126. axqua/jobs/submit.py +271 -0
  127. axqua/jobs/workspace.py +237 -0
  128. axqua/labdata.py +294 -0
  129. axqua/logsetup.py +135 -0
  130. axqua/mesh.py +19 -0
  131. axqua/mesh_quality.py +19 -0
  132. axqua/mesh_validity.py +255 -0
  133. axqua/model_column.py +285 -0
  134. axqua/openfoam.py +24 -0
  135. axqua/pipeline.py +19 -0
  136. axqua/positional_error.py +161 -0
  137. axqua/postproc/__init__.py +57 -0
  138. axqua/postproc/dataset.py +65 -0
  139. axqua/postproc/profiles.py +173 -0
  140. axqua/postproc/render.py +179 -0
  141. axqua/postproc/scenes.py +156 -0
  142. axqua/postproc/selafin_vtk.py +420 -0
  143. axqua/postproc/visit.py +400 -0
  144. axqua/prerun.py +535 -0
  145. axqua/profilecli.py +157 -0
  146. axqua/progress.py +227 -0
  147. axqua/rating.py +472 -0
  148. axqua/sections.py +19 -0
  149. axqua/selafin.py +16 -0
  150. axqua/solvers/__init__.py +12 -0
  151. axqua/solvers/openfoam/__init__.py +98 -0
  152. axqua/solvers/openfoam/backend.py +511 -0
  153. axqua/solvers/openfoam/calibration.py +991 -0
  154. axqua/solvers/openfoam/case.py +539 -0
  155. axqua/solvers/openfoam/convergence.py +171 -0
  156. axqua/solvers/openfoam/dicts.py +931 -0
  157. axqua/solvers/openfoam/fields.py +576 -0
  158. axqua/solvers/openfoam/hotstart.py +468 -0
  159. axqua/solvers/openfoam/layout.py +110 -0
  160. axqua/solvers/openfoam/mesh.py +1313 -0
  161. axqua/solvers/openfoam/planview.py +296 -0
  162. axqua/solvers/openfoam/polymesh.py +401 -0
  163. axqua/solvers/openfoam/potential.py +459 -0
  164. axqua/solvers/openfoam/quality.py +446 -0
  165. axqua/solvers/openfoam/report.py +730 -0
  166. axqua/solvers/openfoam/runtime.py +294 -0
  167. axqua/solvers/openfoam/sediment.py +1484 -0
  168. axqua/solvers/openfoam/spec.py +178 -0
  169. axqua/solvers/telemac/__init__.py +40 -0
  170. axqua/solvers/telemac/backend.py +565 -0
  171. axqua/solvers/telemac/boundary.py +680 -0
  172. axqua/solvers/telemac/flux_convergence.py +482 -0
  173. axqua/solvers/telemac/fortran.py +700 -0
  174. axqua/solvers/telemac/gainlose.py +176 -0
  175. axqua/solvers/telemac/mesh.py +946 -0
  176. axqua/solvers/telemac/mesh_quality.py +315 -0
  177. axqua/solvers/telemac/pipeline.py +297 -0
  178. axqua/solvers/telemac/sections.py +213 -0
  179. axqua/solvers/telemac/sortie.py +608 -0
  180. axqua/solvers/telemac/spec.py +192 -0
  181. axqua/solvers/telemac/steering.py +1421 -0
  182. axqua/solvers/telemac/threed.py +584 -0
  183. axqua/solvers/telemac/unsteady.py +315 -0
  184. axqua/solvers/telemac/watertable.py +303 -0
  185. axqua/solvers/telemac/wetting.py +443 -0
  186. axqua/sortie.py +19 -0
  187. axqua/steering.py +19 -0
  188. axqua/surface_stage.py +433 -0
  189. axqua/targets.py +820 -0
  190. axqua/threed.py +19 -0
  191. axqua/unsteady.py +19 -0
  192. axqua/validation.py +614 -0
  193. axqua/validationcli.py +103 -0
  194. axqua/vertical_convergence.py +460 -0
  195. axqua/watertable.py +19 -0
  196. axqua/wetting.py +19 -0
  197. axqua/workflow.py +457 -0
  198. axqua-1.0.1.dist-info/METADATA +118 -0
  199. axqua-1.0.1.dist-info/RECORD +206 -0
  200. axqua-1.0.1.dist-info/WHEEL +5 -0
  201. axqua-1.0.1.dist-info/entry_points.txt +7 -0
  202. axqua-1.0.1.dist-info/licenses/LICENSE +28 -0
  203. axqua-1.0.1.dist-info/licenses/NOTICE +43 -0
  204. axqua-1.0.1.dist-info/licenses/src/axqua/install/vendor/OpenFOAM-installer/LICENSE +24 -0
  205. axqua-1.0.1.dist-info/licenses/src/axqua/install/vendor/OpenFOAM-installer/LICENSES/GPL-3.0-or-later.txt +674 -0
  206. axqua-1.0.1.dist-info/top_level.txt +1 -0
axqua/__init__.py ADDED
@@ -0,0 +1,238 @@
1
+ """axqua - automated setup of calibration-ready river models.
2
+
3
+ axqua turns user-provided geodata and hydraulic data (DEM, ROI boundary,
4
+ inflow/outflow, measurements) into a production-ready simulation case, plus the
5
+ artifacts a surrogate-assisted Bayesian calibration needs. Two simulation backends
6
+ ship with it - TELEMAC-2D/3D (+GAIA) and OpenFOAM ``interFoam`` - and both are driven
7
+ from **one** case configuration describing the river and the modeling intent.
8
+
9
+ Layering
10
+ --------
11
+ * :mod:`axqua.core` - solver-agnostic: the configuration, the geodata, the
12
+ boundary conditions, the ground truth, the convergence maths, and the
13
+ capability/registry machinery. **Nothing here imports a solver.**
14
+ * :mod:`axqua.solvers` - one subpackage per simulation code, each supplying only
15
+ what is genuinely its own and taking the rest from the core.
16
+
17
+ Everything is driven by a single YAML config (:mod:`axqua.config`); what a given
18
+ case can actually do is recorded in its ``MODEL=<SOLVER>_<ENABLED|DISABLED>`` marker
19
+ files (:mod:`axqua.core.capabilities`).
20
+
21
+ Lazy imports
22
+ ------------
23
+ Attribute access is resolved on demand (PEP 562), so ``import axqua`` costs
24
+ almost nothing and only the modules actually used are loaded. This is not
25
+ micro-optimisation: asking *what can this case do?* must not drag in numpy, pandas,
26
+ gmsh or rasterio, because that question gets asked far more often than "now go and
27
+ mesh it" - and a future QGIS plugin will ask it inside the QGIS Python process. The
28
+ public API is unchanged; ``from axqua import build_mesh`` works exactly as before.
29
+ """
30
+
31
+ from __future__ import annotations
32
+
33
+ import importlib
34
+ from typing import TYPE_CHECKING
35
+
36
+ # Single source of truth: whatever was installed. The literal is the fallback for a
37
+ # source checkout that was never `pip install`ed, and is kept in step with
38
+ # pyproject.toml by a test.
39
+ _FALLBACK_VERSION = "1.0.1"
40
+
41
+ try:
42
+ from importlib.metadata import version as _pkg_version
43
+
44
+ __version__ = _pkg_version("aXqua")
45
+ except Exception: # noqa: BLE001 - a checkout that was never installed
46
+ __version__ = _FALLBACK_VERSION
47
+
48
+ # Public name -> defining module. Grouped by module so the mapping stays legible and
49
+ # a new export is one word in the right tuple.
50
+ _EXPORTS: dict[str, tuple[str, ...]] = {
51
+ "core.capabilities": ("Capability", "CapabilityState", "CaseStatus",
52
+ "SolverStatus", "Support", "read_marker"),
53
+ "core.registry": ("BackendSpec", "CapabilitySpec", "SolverBackend", "backends",
54
+ "supporting"),
55
+ "config": ("Config", "dump_config", "load_config"),
56
+ "core.errors": ("ConfigError", "ErrorRecord", "GeodataError",
57
+ "AxquaError", "MeshError", "SolverError"),
58
+ "core.schema": ("Layer", "classify_setting"),
59
+ "core.casefile": ("find_case_file",),
60
+ "core.profile": ("AxquaProfile",),
61
+ "core.diagnostics": ("Finding",),
62
+ "core.geodata": ("read_roughness_table", "read_roughness_zones", "ZoneRoughness"),
63
+ "dem": ("clip_dem_to_roi", "clip_to_roi", "dem_of_difference", "propagated_lod",
64
+ "resolve_lod"),
65
+ "ground_truth": ("compile_ground_truth", "read_tidy"),
66
+ "targets": ("read_target_parameters", "read_targets", "write_target_template"),
67
+ "flowtracker": ("fill_template_hydraulics", "read_flowtracker", "read_flowtrackers"),
68
+ "solvers.telemac.mesh": ("build_mesh", "channel_node_mask", "interpolate_elevations",
69
+ "interpolate_roughness", "write_mesh"),
70
+ "solvers.telemac.mesh_quality": ("assess_quality",),
71
+ "core.selafin": ("extract_hotstart",),
72
+ "mesh_validity": ("MeshValidity", "channel_ks", "check_level"),
73
+ "solvers.telemac.steering": ("select_turbulence_model", "eddy_viscosity_estimate"),
74
+ "solvers.telemac.threed": ("build_3d_cas", "build_3d_cases", "infer_vertical_layers",
75
+ "select_3d_turbulence"),
76
+ "vertical_convergence": ("layer_levels", "run_vertical_convergence"),
77
+ "rating": ("generate_stage_discharge", "normal_depth", "section_rating",
78
+ "stage_for_discharge", "synthesize_outflow_rating",
79
+ "synthesize_outflow_rating_from_section"),
80
+ "solvers.telemac.sections": ("line_discharges", "write_line_discharges"),
81
+ "solvers.telemac.wetting": ("outlet_profile", "OutletProfile", "wetting_report", "WettingReport"),
82
+ "solvers.telemac.watertable": ("fit_phreatic_plane", "patch_node_mask", "PhreaticPlane",
83
+ "water_table_depth"),
84
+ "convergence": ("percent_levels", "ratio_levels", "run_mesh_convergence"),
85
+ "solvers.telemac.unsteady": ("build_unsteady_case", "build_unsteady_3d_case", "load_hydrograph",
86
+ "write_control_sections"),
87
+ "solvers.telemac.flux_convergence": ("analyze_flux_convergence", "convergence_index",
88
+ "convergence_rate", "FluxConvergence", "relative_imbalance"),
89
+ "solvers.telemac.sortie": ("find_lines", "latest_sortie", "read_sortie", "sediment_mass_profile",
90
+ "Sortie", "tracer_mass_profile"),
91
+ "workflow": ("format_3d_cases", "format_flux_convergence", "mesh_from_geometry",
92
+ "prepare_steady_inputs", "report_sections", "report_wetting",
93
+ "resolve_discharge", "synthesize_constant_inflow",
94
+ "synthesize_rating_if_missing", "run_solver_streaming",
95
+ "expected_duration", "water_table_mask"),
96
+ "prerun": ("SeedResult", "ensure_seed"),
97
+ "progress": ("SolverProgress", "ProgressBar"),
98
+ "logsetup": ("setup_logging", "log_step", "logging_to"),
99
+ "bayescal": ("FlowSpec", "run_single_flow_calibration",
100
+ "run_multiflow_calibration", "build_velocity_csv", "require_hbc"),
101
+ }
102
+
103
+ # submodules reachable as attributes without an explicit import
104
+ # Historic module names stay listed: they are shims (see axqua/mesh.py and
105
+ # friends) that alias the moved modules, so `from axqua import pipeline`
106
+ # keeps working for case scripts written before the backends were split out.
107
+ _SUBMODULES = ("core", "solvers", "campaigns", "hbc", "openfoam", "config", "pipeline",
108
+ "cli", "mesh", "steering", "selafin")
109
+
110
+ _NAME_TO_MODULE = {name: module
111
+ for module, names in _EXPORTS.items()
112
+ for name in names}
113
+
114
+ # Spelled out rather than computed from _EXPORTS: linters, type checkers and IDEs
115
+ # read __all__ statically, and with lazy attribute access it is the only thing that
116
+ # tells them these names exist. tests/test_capabilities.py asserts it stays in step
117
+ # with _EXPORTS, so the duplication cannot drift.
118
+ __all__ = [
119
+ "AxquaProfile", "BackendSpec", "Capability", "CapabilitySpec", "CapabilityState",
120
+ "CaseStatus", "Finding", "find_case_file",
121
+ "Config", "ConfigError", "ErrorRecord", "FlowSpec", "FluxConvergence",
122
+ "GeodataError", "AxquaError", "hbc", "Layer", "MeshError", "MeshValidity",
123
+ "OutletProfile", "SolverError", "ZoneRoughness",
124
+ "PhreaticPlane", "ProgressBar", "SolverBackend", "SolverProgress",
125
+ "SeedResult", "SolverStatus", "Sortie", "Support", "WettingReport",
126
+ "analyze_flux_convergence", "assess_quality", "backends", "build_3d_cas",
127
+ "build_3d_cases", "build_mesh", "build_unsteady_3d_case", "build_unsteady_case",
128
+ "build_velocity_csv", "channel_ks", "channel_node_mask", "check_level",
129
+ "clip_dem_to_roi", "clip_to_roi", "compile_ground_truth", "convergence_index",
130
+ "classify_setting", "convergence_rate", "dem_of_difference",
131
+ "dump_config", "eddy_viscosity_estimate",
132
+ "ensure_seed", "expected_duration", "extract_hotstart",
133
+ "fill_template_hydraulics", "find_lines",
134
+ "fit_phreatic_plane", "format_3d_cases", "format_flux_convergence",
135
+ "generate_stage_discharge", "infer_vertical_layers", "interpolate_elevations",
136
+ "interpolate_roughness", "latest_sortie", "layer_levels", "line_discharges",
137
+ "load_config", "load_hydrograph", "log_step", "logging_to",
138
+ "mesh_from_geometry", "normal_depth", "outlet_profile", "patch_node_mask",
139
+ "percent_levels", "prepare_steady_inputs", "propagated_lod", "ratio_levels",
140
+ "read_flowtracker", "read_flowtrackers", "read_marker",
141
+ "read_roughness_table", "read_roughness_zones", "read_sortie",
142
+ "read_target_parameters", "read_targets", "read_tidy", "relative_imbalance",
143
+ "report_sections", "report_wetting", "require_hbc", "resolve_discharge",
144
+ "resolve_lod", "run_mesh_convergence", "run_multiflow_calibration",
145
+ "run_single_flow_calibration", "run_solver_streaming",
146
+ "run_vertical_convergence", "section_rating", "sediment_mass_profile",
147
+ "select_3d_turbulence", "select_turbulence_model", "setup_logging",
148
+ "stage_for_discharge", "supporting", "synthesize_constant_inflow",
149
+ "synthesize_outflow_rating", "synthesize_outflow_rating_from_section",
150
+ "synthesize_rating_if_missing", "tracer_mass_profile", "water_table_depth",
151
+ "water_table_mask", "wetting_report", "write_control_sections",
152
+ "write_line_discharges", "write_mesh", "write_target_template", "campaigns",
153
+ "cli", "config", "core", "mesh", "openfoam", "pipeline", "selafin", "solvers",
154
+ "steering", "__version__",
155
+ ]
156
+
157
+
158
+ def __getattr__(name: str):
159
+ """Resolve a public name (PEP 562) by importing only the module that defines it."""
160
+ module = _NAME_TO_MODULE.get(name)
161
+ if module is not None:
162
+ return getattr(importlib.import_module(f"axqua.{module}"), name)
163
+ if name in _SUBMODULES:
164
+ return importlib.import_module(f"axqua.{name}")
165
+ raise AttributeError(f"module 'axqua' has no attribute {name!r}")
166
+
167
+
168
+ def __dir__() -> list[str]:
169
+ return sorted(__all__)
170
+
171
+
172
+ if TYPE_CHECKING: # give type checkers and IDEs the real names
173
+ from axqua.bayescal import (
174
+ build_velocity_csv, FlowSpec, require_hbc, run_multiflow_calibration,
175
+ run_single_flow_calibration,
176
+ )
177
+ from axqua.config import Config, load_config
178
+ from axqua.convergence import (
179
+ percent_levels, ratio_levels, run_mesh_convergence,
180
+ )
181
+ from axqua.core.capabilities import (
182
+ Capability, CapabilityState, CaseStatus, read_marker, SolverStatus, Support,
183
+ )
184
+ from axqua.core.registry import (
185
+ backends, BackendSpec, CapabilitySpec, SolverBackend, supporting,
186
+ )
187
+ from axqua.dem import (
188
+ clip_dem_to_roi, clip_to_roi, dem_of_difference, propagated_lod, resolve_lod,
189
+ )
190
+ from axqua.flowtracker import (
191
+ fill_template_hydraulics, read_flowtracker, read_flowtrackers,
192
+ )
193
+ from axqua.solvers.telemac.flux_convergence import (
194
+ analyze_flux_convergence, convergence_index, convergence_rate,
195
+ FluxConvergence, relative_imbalance,
196
+ )
197
+ from axqua.ground_truth import compile_ground_truth, read_tidy
198
+ from axqua.logsetup import log_step, logging_to, setup_logging
199
+ from axqua.solvers.telemac.mesh import (
200
+ build_mesh, channel_node_mask, interpolate_elevations, interpolate_roughness,
201
+ write_mesh,
202
+ )
203
+ from axqua.solvers.telemac.mesh_quality import assess_quality
204
+ from axqua.mesh_validity import channel_ks, check_level, MeshValidity
205
+ from axqua.progress import ProgressBar, SolverProgress
206
+ from axqua.rating import (
207
+ generate_stage_discharge, normal_depth, section_rating, stage_for_discharge,
208
+ synthesize_outflow_rating, synthesize_outflow_rating_from_section,
209
+ )
210
+ from axqua.solvers.telemac.sections import line_discharges, write_line_discharges
211
+ from axqua.solvers.telemac.sortie import (
212
+ find_lines, latest_sortie, read_sortie, sediment_mass_profile, Sortie,
213
+ tracer_mass_profile,
214
+ )
215
+ from axqua.solvers.telemac.steering import eddy_viscosity_estimate, select_turbulence_model
216
+ from axqua.targets import (
217
+ read_target_parameters, read_targets, write_target_template,
218
+ )
219
+ from axqua.solvers.telemac.threed import (
220
+ build_3d_cas, build_3d_cases, infer_vertical_layers, select_3d_turbulence,
221
+ )
222
+ from axqua.solvers.telemac.unsteady import (
223
+ build_unsteady_3d_case, build_unsteady_case, load_hydrograph,
224
+ write_control_sections,
225
+ )
226
+ from axqua.vertical_convergence import layer_levels, run_vertical_convergence
227
+ from axqua.solvers.telemac.watertable import (
228
+ fit_phreatic_plane, patch_node_mask, PhreaticPlane, water_table_depth,
229
+ )
230
+ from axqua.solvers.telemac.wetting import (
231
+ outlet_profile, OutletProfile, wetting_report, WettingReport,
232
+ )
233
+ from axqua.workflow import (
234
+ expected_duration, format_3d_cases, format_flux_convergence,
235
+ mesh_from_geometry, prepare_steady_inputs, report_sections, report_wetting,
236
+ resolve_discharge, run_solver_streaming, synthesize_constant_inflow,
237
+ synthesize_rating_if_missing, water_table_mask,
238
+ )
axqua/__main__.py ADDED
@@ -0,0 +1,16 @@
1
+ """``python -m axqua`` - the CLI, without needing the console script on ``PATH``.
2
+
3
+ A detached job is started with an environment captured from the solver's setup script,
4
+ and that environment's ``PATH`` is the solver's, not the user's shell's. The
5
+ ``axqua`` console script is often absent from it, so the launcher falls back to
6
+ ``[sys.executable, "-m", "axqua", ...]`` - which only works because this file exists.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import sys
12
+
13
+ from axqua.cli import main
14
+
15
+ if __name__ == "__main__":
16
+ sys.exit(main())