Skip to content

Support Turbomole's multi-file output in read_cclib/cclib_thermo - #110

Merged
galjos merged 2 commits into
mainfrom
fix-cclib-turbomole-multifile
Jul 8, 2026
Merged

Support Turbomole's multi-file output in read_cclib/cclib_thermo#110
galjos merged 2 commits into
mainfrom
fix-cclib-turbomole-multifile

Conversation

@galjos

@galjos galjos commented Jul 8, 2026

Copy link
Copy Markdown
Member

Found by fetching a real Turbomole calculation from cclib's own public regression-test data (cclib/cclib-data) and running it through cclib_thermo — the first genuine (non-mocked) Turbomole test this reader has ever had.

The bug

Turbomole splits a job's output across many small files instead of one logfile (control, coord, aoforce.out, ...). cclib's own ccread/ccopen documents exactly this case — source: str | list[str], "a single logfile, a list of logfiles (for a single job)" — but read_cclib/cclib_thermo always did cclib.io.ccread(str(path)), which converts a list to its string repr rather than passing it through. So despite Turbomole being named in the docs and the module docstring as a supported program, it could not actually be read at all.

The fix

read_cclib(path) / cclib_thermo(output_file, ...) now accept either a single path or a list of paths (_normalize_source), passed to cclib unmodified for the list case, with a readable _describe_source for error messages either way. Single-file callers (Gaussian/ORCA/Psi4/NWChem) are unaffected.

Verification

Downloaded a real Turbomole 7.2 aoforce frequency calculation (a 7-atom Au/N/Cl complex) from cclib's own public test-data repository and ran it through the actual code:

INFO:cclib:Identified logfile to be in Turbomole format
symbols: ['Cl', 'Au', 'N', 'N', 'Au', 'N', 'N']
15 frequencies (3*7-6), all real — a genuine minimum
electronic_energy(): -951.0820621320888 Hartree
entropy: 110.13 cal/(mol*K)  — physically sensible for this heavier, larger complex

Committed the real captured files as test fixtures (tests/data/calculator/turbomole/, ~160 KB, with a provenance README) and added tests: exact-value parsing, the full cclib_thermo pipeline end-to-end, a mock proving the list reaches cclib.io.ccread unmodified, and unit tests for the new helpers. Full suite passes (377 passed, 12 pre-existing skips), 100% patch coverage on qm.py. Docs updated with a Turbomole multi-file example.

Closes #109

Verified against a real Turbomole 7.2 aoforce (frequency) calculation,
fetched from cclib's own public regression-test data (cclib/cclib-data).

Turbomole splits a job's output across many small files instead of one
logfile (control, coord, aoforce.out, ...). cclib's own ccread/ccopen
supports this via its documented multi-file mode (source: str | list[str]),
but read_cclib/cclib_thermo always did cclib.io.ccread(str(path)), which
silently cannot accept a list -- so despite the docs/module docstring
listing Turbomole as supported, it could not actually be used at all.

Accept path/output_file as a single path or a list of paths (_normalize_source),
passed through to cclib unmodified for the list case, with a readable
_describe_source for error messages either way.

Add the real captured Turbomole aoforce.out + companion files as test
fixtures (a 7-atom Au/N/Cl complex) and tests parsing them end to end
through read_cclib and cclib_thermo, plus unit tests for the new helpers.

Closes #109
@codecov

codecov Bot commented Jul 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.28%. Comparing base (bcb49f1) to head (467d002).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #110      +/-   ##
==========================================
+ Coverage   97.27%   97.28%   +0.01%     
==========================================
  Files          31       31              
  Lines        1910     1918       +8     
==========================================
+ Hits         1858     1866       +8     
  Misses         52       52              
Flag Coverage Δ
unittests 97.28% <100.00%> (+0.01%) ⬆️

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.

Review nit: the 'No energy' TSValueError used the raw output_file (a
Python list repr for the Turbomole multi-file case) instead of
_describe_source's clean comma-joined format.
@galjos
galjos merged commit b43fa52 into main Jul 8, 2026
5 checks passed
@galjos
galjos deleted the fix-cclib-turbomole-multifile branch July 8, 2026 12:21
galjos added a commit that referenced this pull request Jul 8, 2026
Small docs-only addition following the ORCA/Gaussian/Turbomole
real-software validation work (#108, #110, #112): a brief note in the
QM-import usage section stating that `orca_thermo`/`cclib_thermo` are
validated against genuine program output, and that unparseable files
raise `TSValueError` rather than an arbitrary parser exception.

Verified by building the docs locally and visually checking the rendered
note (Furo's styled admonition) in the browser. No code changes.
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.

cclib_thermo cannot actually read Turbomole output (needs multi-file support)

1 participant