Skip to content

Pass optimized ASE atoms through run_thermo - #52

Merged
galjos merged 1 commit into
mainfrom
feed-ase-atoms-to-run-thermo
Jun 26, 2026
Merged

Pass optimized ASE atoms through run_thermo#52
galjos merged 1 commit into
mainfrom
feed-ase-atoms-to-run-thermo

Conversation

@galjos

@galjos galjos commented Jun 26, 2026

Copy link
Copy Markdown
Member

Closes #34.

dftbplus_thermo already optimizes the geometry and gets the result as an ASE Atoms object (optimized_atoms = geoopt.read()), but then discarded it and called run_thermo(coord_file="geo_opt.xyz") — a file DFTB+ never writes (it emits geo_opt.gen). The disk round-trip was both wasteful and fragile.

Change

  • Add an optional atoms argument to run_thermo; when given, it builds the Atom list, cell and pbc directly from the ASE Atoms object (_atoms_from_ase) instead of reading coord_file.
  • Wire dftbplus_thermo to pass optimized_atoms directly.
  • File-based inputs are unchanged when atoms is not provided, so existing workflows keep working.

Tests

Equivalence test on the real geo_opt.gen + frequency.txt fixtures: the ASE-atoms path and the file path produce identical total energy, entropy, and Gibbs free energy.

145 passed, 0 skipped (suite run with DFTB+ binaries); pylint 7.99/10.

dftbplus_thermo optimized the geometry, obtained the ASE Atoms via geoopt.read(),
then discarded it and called run_thermo(coord_file="geo_opt.xyz") — a file DFTB+
never writes (it emits geo_opt.gen). Add an optional atoms argument to run_thermo
that builds the Atom list, cell and pbc directly from an ASE Atoms object, and
wire dftbplus_thermo to use it. File-based inputs are unchanged when atoms is not
given.
@codecov

codecov Bot commented Jun 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.27%. Comparing base (abda77a) to head (8039bd7).

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #52      +/-   ##
==========================================
+ Coverage   93.83%   94.27%   +0.44%     
==========================================
  Files          21       21              
  Lines        1200     1206       +6     
==========================================
+ Hits         1126     1137      +11     
+ Misses         74       69       -5     
Flag Coverage Δ
unittests 94.27% <100.00%> (+0.44%) ⬆️

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 c7d2b83 into main Jun 26, 2026
3 checks passed
galjos added a commit that referenced this pull request Jun 26, 2026
Closes #53. Stacked on #52 (retargets to main once that merges) — it
depends on #52 because the pipeline now runs on the in-memory optimized
atoms rather than re-reading a file from the working directory.

The DFTB+ steps read and write fixed filenames (`geo_opt.gen`,
`hessian.out`, `vibrations.tag`, `modes_in.hsd`, ...) in the current
directory, so running more than one molecule in the same directory
clobbers the previous molecule's geometry/Hessian/frequencies. This
blocks any batch/screening loop (#33).

## Change
- Add a `directory` argument to `dftbplus_thermo`; the pipeline runs
there via a `_run_in_directory` context manager that creates the
directory and restores the previous working directory afterwards
(including on error).
- Backward-compatible: defaults to the current directory, so existing
single-molecule workflows are unchanged.
- chdir-based, so correct for sequential and multi-process batches;
per-thread parallelism within one process would need the calculators to
thread a directory through (follow-up).

## Tests
- Unit tests for `_run_in_directory`: isolates into the target dir and
restores the cwd, restores on exception, and is a no-op for `None`.
- Verified locally with the real DFTB+ binaries: two molecules run into
separate directories, the cwd is untouched, and results are independent
and physically sensible (H2O 45.05, NH3 45.97 cal/(mol*K)).

148 passed, 0 skipped (suite run with DFTB+ binaries); pylint 8.04/10.
galjos added a commit that referenced this pull request Jun 26, 2026
Closes #53. Re-targets the work from #54 onto main: #54 was stacked on
the #52 branch and got merged into that branch instead of main (which
was squash-merged separately), so the change never landed. These are the
same commits, cleanly rebased onto current main.

The DFTB+ steps read and write fixed filenames (`geo_opt.gen`,
`hessian.out`, `vibrations.tag`, `modes_in.hsd`, ...) in the current
directory, so running more than one molecule in the same directory
clobbers the previous molecule's geometry/Hessian/frequencies. This
blocks any batch/screening loop (#33).

## Change
- Add a `directory` argument to `dftbplus_thermo`; the pipeline runs
there via a `_run_in_directory` context manager that creates the
directory and restores the previous working directory afterwards
(including on error).
- Backward-compatible: defaults to the current directory, so existing
single-molecule workflows are unchanged.
- chdir-based, so correct for sequential and multi-process batches;
per-thread parallelism within one process would need the calculators to
thread a directory through (follow-up).

## Tests
- Unit tests for `_run_in_directory`: isolates into the target dir and
restores the cwd, restores on exception, no-op for `None`.
- A mocked-pipeline test drives `dftbplus_thermo(..., directory=...)`
without the binaries, covering the directory wiring in CI (api.py
coverage 87% -> 93%).
- Verified locally with the real DFTB+ binaries: two molecules run into
separate directories, the cwd is untouched, results independent and
physically sensible (H2O 45.05, NH3 45.97 cal/(mol*K)).

144 passed, 5 skipped (no binaries); pylint 8.04/10.
galjos added a commit that referenced this pull request Jun 29, 2026
Implements the core screening framework from #33 (first slice). Builds
on the per-job directory isolation (#55) and ASE-atoms passthrough
(#52).

## What it does
A \`screen()\` entry point (exported as \`ThermoScreening.screen\`) and
a \`thermo screen\` CLI subcommand that, for each molecule, run the
DFTB+ geometry-optimisation/Hessian/modes pipeline in its own working
directory and collect the key thermochemistry into \`results.csv\` and
\`results.json\`.

- **Input (both):** a directory of \`.xyz\`/\`.gen\` structures (run at
a global \`--charge\`), or a CSV manifest with \`path\` plus optional
\`name\`/\`charge\` columns (per-molecule charge — e.g. anthraquinone at
-1/-2).
- **Output (both):** a CSV summary table and a JSON file (name, path,
charge, status, E/H/G in Hartree, S/Cv in cal/(mol*K), error).
- **Error isolation:** a molecule that fails is recorded with
\`status=error\` and does not abort the run.
- **Per-job isolation:** each molecule runs in \`<directory>/<name>\`.

```
# Python
from ThermoScreening import screen
screen("molecules.csv", out="results")

# CLI
thermo screen ./structures/ -o results --charge 0
thermo screen molecules.csv -o results
```

## Tests
- Job loading from a directory and a CSV manifest (per-row + default
charge, relative path resolution), and rejection of empty/unknown
inputs.
- \`screen()\` with the pipeline mocked: collects results, writes CSV +
JSON, runs each molecule in its own directory, and isolates a failing
molecule.
- CLI routing for the \`screen\` subcommand and the failure-count return
code.
- Verified locally with the real DFTB+ binaries over a directory of
CH4/H2O/NH3 plus a deliberately broken structure: the three succeed
(entropies 44.44 / 45.05 / 45.97 cal/(mol*K), matching literature), the
broken one is isolated as an error.

152 passed, 5 skipped (no binaries); pylint 8.09/10.

## Deferred to follow-ups (not in this PR)
- Resume/checkpoint (this PR always recomputes, per the agreed scope).
- Parallel execution (chdir-based isolation is correct for sequential
and multi-process batches; per-thread parallelism would need the
calculators to thread a directory through).
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.

Pass ASE atoms through thermochemistry workflow

1 participant