Skip to content

Add generate_thermo_ensemble: charge-state-aware conformers with auto-retry - #121

Merged
galjos merged 1 commit into
mainfrom
robust-conformer-ensemble
Jul 11, 2026
Merged

Add generate_thermo_ensemble: charge-state-aware conformers with auto-retry#121
galjos merged 1 commit into
mainfrom
robust-conformer-ensemble

Conversation

@galjos

@galjos galjos commented Jul 11, 2026

Copy link
Copy Markdown
Member

Building a conformer ensemble for a charged species (radical anion, dianion -- the exact pattern `pKa`/`reduction_potential`/`EnsembleThermo` exist for) currently means hand-rolling a loop around `conformers.generate()` plus a `Thermo` engine, manually reseeding whenever a conformer optimizes onto a saddle point instead of a true minimum (`TSValueError`) or the engine's CLI process fails outright (`RuntimeError`).

The fix

`generate_thermo_ensemble(smiles, thermo_fn, charge=0.0, max_conformers=10, max_attempts=5, ...)` does that loop once: generate conformers, compute `Thermo` for each via a caller-supplied engine callable (e.g. `xtb_cli_thermo`), skip conformers that raise `TSValueError`/`RuntimeError`, and reseed+retry (up to `max_attempts` distinct random seeds) until enough succeed. Returns a plain list of `Thermo`, ready for `EnsembleThermo`.

Engine-agnostic by design (like the rest of the pKa/redox/ensemble helpers) -- `thermo_fn` is just called as `thermo_fn(atoms, charge=charge, **thermo_kwargs)`, so it works with `xtb_cli_thermo`, `dftbplus_thermo`, or any custom callable with that signature.

Verification

Unit tests cover: respecting `max_conformers`, forwarding `charge`/kwargs, skipping+retrying past both failure types, stopping mid-attempt once the target is reached (not over-computing), raising a clear `ValueError` when nothing succeeds within `max_attempts`, and NOT swallowing unrelated exceptions. A real end-to-end test (skippable, gated on the native `xtb` binary, matching the existing pattern) builds a real ensemble for 4-hydroxybutanoic acid's anion and feeds it into `EnsembleThermo`.

Full suite: 410 passed, 10 skipped with a real `xtb` binary. 98% coverage on `conformers.py` (the one uncovered line pre-dates this change). Docs build clean.

Closes #120

…-retry

Building a conformer ensemble for a charged species currently means
hand-rolling a loop around conformers.generate() plus a Thermo engine,
manually reseeding whenever a conformer optimizes onto a saddle point
(TSValueError) or the engine's process fails outright (RuntimeError).
generate_thermo_ensemble does that loop once: generate, compute Thermo,
skip failures, reseed and retry up to a cap, returning a plain list of
Thermo ready for EnsembleThermo.
@codecov

codecov Bot commented Jul 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.34%. Comparing base (0636de4) to head (caf56e3).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #121      +/-   ##
==========================================
+ Coverage   97.31%   97.34%   +0.02%     
==========================================
  Files          32       32              
  Lines        1940     1957      +17     
==========================================
+ Hits         1888     1905      +17     
  Misses         52       52              
Flag Coverage Δ
unittests 97.34% <100.00%> (+0.02%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@galjos
galjos merged commit 7793902 into main Jul 11, 2026
5 checks passed
@galjos
galjos deleted the robust-conformer-ensemble branch July 11, 2026 16:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a charge-state-aware conformer ensemble helper with auto-retry

1 participant