Source code for eon.status_codes

"""Process-search termination codes shared with the C++ client.

Mirror of ``client/StatusTypes.h``. The integer values are wire format
written to ``results.dat`` by eonclient, so they MUST match the C++
``eonc::SaddleStatus`` enumerators byte-for-byte. The Python side
exposes them as ``IntEnum`` members so server code can compare against
``SaddleStatus.Good`` instead of the magic literal ``0``, while still
accepting raw ints transparently from ``parse_results``.

Whenever ``client/StatusTypes.h`` adds, removes, or renumbers a code,
update this module in the same commit and add a row to the label /
slug tables.
"""

from __future__ import annotations

from enum import IntEnum


[docs] class SaddleStatus(IntEnum): """Saddle-search termination reason. Wire-equivalent to ``eonc::SaddleStatus`` in ``client/StatusTypes.h``.""" Good = 0 Init = 1 BadNoConvex = 2 BadHighEnergy = 3 BadMaxConcaveIterations = 4 BadMaxIterations = 5 BadNotConnected = 6 BadPrefactor = 7 BadHighBarrier = 8 BadMinima = 9 FailedPrefactor = 10 PotentialFailed = 11 NonnegativeAbort = 12 NonlocalAbort = 13 NegativeBarrier = 14 BadMdTrajectoryTooShort = 15 BadNoNegativeModeAtSaddle = 16 BadNoBarrier = 17 ZeromodeAbort = 18 OptimizerError = 19 DimerLostMode = 20 DimerRestoredBest = 21 BadArtnError = 22
[docs] class MinimizationStatus(IntEnum): """Minimizer termination as reported in ``results.dat`` for ``job_type == 'minimization'``. Distinct from the broader ``SaddleStatus`` -- the minimizer only emits these three.""" Good = 0 MaxIterations = 1 PotentialFailed = 2
_UNKNOWN = "unknown_exit_code" # Display labels (title case) used by akmc bad-saddle bookkeeping. SADDLE_STATUS_LABELS: dict[SaddleStatus, str] = { SaddleStatus.Good: "Good", SaddleStatus.Init: "Init", SaddleStatus.BadNoConvex: "Saddle Search No Convex Region", SaddleStatus.BadHighEnergy: "Saddle Search Terminated High Energy", SaddleStatus.BadMaxConcaveIterations: "Saddle Search Terminated Concave Iterations", SaddleStatus.BadMaxIterations: "Saddle Search Terminated Total Iterations", SaddleStatus.BadNotConnected: "Not Connected", SaddleStatus.BadPrefactor: "Bad Prefactor", SaddleStatus.BadHighBarrier: "Bad Barrier", SaddleStatus.BadMinima: "Minimum Not Converged", SaddleStatus.FailedPrefactor: "Failed Prefactor Calculation", SaddleStatus.PotentialFailed: "Potential Failed", SaddleStatus.NonnegativeAbort: "Nonnegative Displacement Abort", SaddleStatus.NonlocalAbort: "Nonlocal Abort", SaddleStatus.NegativeBarrier: "Negative Barrier", SaddleStatus.BadMdTrajectoryTooShort: "MD Trajectory Too Short", SaddleStatus.BadNoNegativeModeAtSaddle: "No Negative Mode at Saddle", SaddleStatus.BadNoBarrier: "No Forward Barrier in Minimized Band", SaddleStatus.ZeromodeAbort: "MinMode Zero Mode Abort", SaddleStatus.OptimizerError: "Optimizer Error", SaddleStatus.DimerLostMode: "Dimer Lost Mode", SaddleStatus.DimerRestoredBest: "Dimer Restored Best Mode", SaddleStatus.BadArtnError: "ARTn Error", } # Slug-case labels (snake_case) used by explorer.py for routing # decisions. Codes that the legacy table left as ``unknown_exit_code`` # stay that way to preserve downstream string-equality semantics. SADDLE_STATUS_SLUGS: dict[SaddleStatus, str] = { SaddleStatus.Good: "good", SaddleStatus.Init: _UNKNOWN, SaddleStatus.BadNoConvex: "no_convex", SaddleStatus.BadHighEnergy: "high_energy", SaddleStatus.BadMaxConcaveIterations: "max_concave_iterations", SaddleStatus.BadMaxIterations: "max_iterations", SaddleStatus.BadNotConnected: _UNKNOWN, SaddleStatus.BadPrefactor: _UNKNOWN, SaddleStatus.BadHighBarrier: _UNKNOWN, SaddleStatus.BadMinima: _UNKNOWN, SaddleStatus.FailedPrefactor: _UNKNOWN, SaddleStatus.PotentialFailed: "potential_failed", SaddleStatus.NonnegativeAbort: "nonnegative_abort", SaddleStatus.NonlocalAbort: "nonlocal_abort", SaddleStatus.NegativeBarrier: _UNKNOWN, SaddleStatus.BadMdTrajectoryTooShort: "md_trajectory_too_short", SaddleStatus.BadNoNegativeModeAtSaddle: "no_negative_mode_at_saddle", SaddleStatus.BadNoBarrier: "no_barrier", SaddleStatus.ZeromodeAbort: "zero_mode_abort", SaddleStatus.OptimizerError: "optimizer_error", SaddleStatus.DimerLostMode: "dimer_lost_mode", SaddleStatus.DimerRestoredBest: "dimer_restored_best", SaddleStatus.BadArtnError: "artn_error", } MINIMIZATION_STATUS_SLUGS: dict[MinimizationStatus, str] = { MinimizationStatus.Good: "good", MinimizationStatus.MaxIterations: "max_iterations", MinimizationStatus.PotentialFailed: "potential_failed", }
[docs] def saddle_status_label(code: int) -> str: """Human-readable label for a saddle-search termination code. Tolerant of unknown codes -- returns a generic placeholder rather than raising, so a future C++ rev cannot cause an IndexError or KeyError to crash long-running akmc jobs. """ try: return SADDLE_STATUS_LABELS[SaddleStatus(code)] except (ValueError, KeyError): return f"Unknown termination code ({code})"
[docs] def saddle_status_slug(code: int) -> str: """Slug-case label for a saddle-search termination code, with the same unknown-code tolerance as :func:`saddle_status_label`.""" try: return SADDLE_STATUS_SLUGS[SaddleStatus(code)] except (ValueError, KeyError): return _UNKNOWN
[docs] def minimization_status_slug(code: int) -> str: """Slug-case label for a minimization termination code.""" try: return MINIMIZATION_STATUS_SLUGS[MinimizationStatus(code)] except (ValueError, KeyError): return _UNKNOWN