Skip to content

Clarify that calibration is required (not just recommended) for pKa - #117

Merged
galjos merged 2 commits into
mainfrom
clarify-pka-calibration-necessity
Jul 9, 2026
Merged

Clarify that calibration is required (not just recommended) for pKa#117
galjos merged 2 commits into
mainfrom
clarify-pka-calibration-necessity

Conversation

@galjos

@galjos galjos commented Jul 9, 2026

Copy link
Copy Markdown
Member

Found by running real xtb-cli calculations on the pKa helper from #115, the same "test with real data" pattern used for the QM-import engines this session.

The finding

The docs said the raw direct-method pKa has "several-pKa-unit systematic error" (citing DFT+continuum-solvent literature) and suggested calibration for "quantitative accuracy." Running it for real on GFN2-xTB (phenol/phenolate, water) tells a very different story: the raw pKa comes out at ≈-100 against the experimental 9.99 — an error of ~110 pKa units, not "several."

This isn't a bug — I verified the arithmetic is internally self-consistent (the ~150 kcal/mol calibration shift needed exactly accounts for the gap). It's a real, well-known property of semiempirical tight-binding methods: they don't preserve an absolute ab-initio/experimental energy scale, so mixing their electronic energies directly with a literature constant derived assuming DFT/ab-initio-quality absolute energies is fundamentally invalid — not just imprecise.

Calibrating against one reference compound completely fixes this (it's a molecule-independent additive offset): hydroquinone calibrated against phenol (pKa_exp = 9.99) came out at 11.00 vs. the experimental 10.35 — a good result for a cheap semiempirical method.

The fix

  • pka.py: strengthen the Notes sections — calibration is required, not merely recommended, for GFN-xTB/DFTB, with the real verified numbers.
  • docs/usage.rst: replace the old placeholder calibration example (calibrate_proton_reference(ref_acid, ref_base, experimental_pKa=4.20), using undefined variables — not even runnable) with this real, working, verified phenol/hydroquinone example.
  • Tests: a skippable real-xtb-cli integration test reproducing both numbers end to end, gated on the native xtb binary (matching test_reactions.py's existing pattern).

Verification

Ran locally with the real xtb binary: 10/10 tests pass including the new real-engine test. Full suite: 391 passed, 13 skipped (correctly gated when xtb is absent). 100% patch coverage. Docs build clean.

Closes #116

galjos added 2 commits July 9, 2026 11:23
Verified with real xtb-cli (GFN2-xTB + ALPB water) calculations, not just
the closed-form unit tests: phenol's raw pKa with the default literature
proton reference comes out at approximately -100 against the experimental
9.99 -- an error of ~110 pKa units, not the "several units" DFT+
continuum-solvent methods show. This isn't a bug (the arithmetic is
internally consistent, verified by back-computing the calibration shift);
semiempirical tight-binding methods don't preserve an absolute
ab-initio/experimental energy scale, so their energies can't be mixed
directly with a literature constant derived assuming DFT/ab-initio-quality
absolute energies.

Calibrating against one reference compound absorbs the offset completely:
hydroquinone calibrated against phenol (pKa_exp=9.99) comes out at 11.00
vs. the experimental 10.35.

- pka.py: strengthen the Notes to state calibration is required (not just
  recommended) for GFN-xTB/DFTB, with the verified real numbers.
- docs/usage.rst: replace the placeholder calibration example
  (calibrate_proton_reference(ref_acid, ref_base, experimental_pKa=4.20),
  which used undefined variables) with this real, working, verified
  phenol/hydroquinone example.
- tests: a skippable real-xtb-cli integration test reproducing both
  results end to end (gated on the native xtb binary, matching the
  existing pattern in test_reactions.py).

Closes #116
@codecov

codecov Bot commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.31%. Comparing base (17fa876) to head (6eb7810).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #117   +/-   ##
=======================================
  Coverage   97.31%   97.31%           
=======================================
  Files          32       32           
  Lines        1935     1935           
=======================================
  Hits         1883     1883           
  Misses         52       52           
Flag Coverage Δ
unittests 97.31% <ø> (ø)

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 923a4c4 into main Jul 9, 2026
6 of 11 checks passed
@galjos
galjos deleted the clarify-pka-calibration-necessity branch July 9, 2026 10:01
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.

pKa docs undersell how necessary calibration is for semiempirical engines

1 participant