Skip to content

feat: add Psi4 and Tinker backend engines with SN2 test data#53

Merged
ericchansen merged 6 commits intomasterfrom
feat/backends
Mar 18, 2026
Merged

feat: add Psi4 and Tinker backend engines with SN2 test data#53
ericchansen merged 6 commits intomasterfrom
feat/backends

Conversation

@ericchansen
Copy link
Copy Markdown
Owner

Summary

Add Psi4 and Tinker backend engines with validated SN2 transition state reference data and integration tests.

Backend Engines

Psi4Engine (q2mm/backends/qm/psi4.py)

  • Wraps Psi4 Python API for QM calculations
  • Methods: energy(), hessian(), optimize(), frequencies()
  • Supports loading molecules from XYZ files or (atoms, coords) tuples
  • Configurable method, basis set, charge, multiplicity

TinkerEngine (q2mm/backends/mm/tinker.py)

  • Wraps Tinker executables (analyze, minimize, vibrate) via subprocess
  • Auto-detects Tinker installation directory
  • Converts standard XYZ to Tinker format with bond detection
  • Methods: energy(), minimize(), hessian(), frequencies()

SN2 Reference Data (examples/sn2-test/)

Generated at B3LYP/6-31+G(d) using Psi4 1.10, validated against literature:

Parameter Our Value Literature Status
C-F (TS) 1.85 A 1.83-1.85 A In range
Imaginary freq -461.7 cm-1 ~400-550 Good
Barrier (vs complex) 9.5 kcal/mol ~13-15 B3LYP underestimates (known)
CH3F C-F 1.399 A 1.382 (expt) Good

Fixtures saved

  • qm-reference/: optimized TS + CH3F geometries, Hessians (.npy), frequencies, ion-dipole complex
  • mm-reference/: Tinker MM3 energy and vibrational analysis

Integration Tests

23 new tests across 3 files:

  • test_tinker_backend.py (10 tests): energy, frequencies, minimize on CH3F and SN2 TS
  • test_psi4_backend.py (9 tests): 3 fixture validation (no Psi4 needed), 6 Psi4-dependent (skip without conda)
  • test_pipeline.py (10 tests): Hessian analysis, eigenvalue decomposition roundtrip via Q2MM core, geometry/frequency cross-validation

Test Results

51 passed, 22 skipped, 1 xfailed (up from 28 in previous PR)

ericchansen and others added 3 commits March 17, 2026 18:03
Backend implementations:
- Psi4Engine (q2mm/backends/qm/psi4.py): wraps Psi4 Python API
  for energy, hessian, optimize, frequencies calculations
- TinkerEngine (q2mm/backends/mm/tinker.py): wraps Tinker executables
  (analyze, minimize, vibrate) with auto-detection, bond detection,
  and Tinker XYZ format conversion

SN2 F- + CH3F reference data (B3LYP/6-31+G(d)):
- Optimized TS geometry (C-F = 1.85 A, 1 imaginary freq at -461.7 cm-1)
- TS Hessian (18x18) and frequencies
- CH3F ground state geometry, Hessian, frequencies
- Ion-dipole complex for barrier height (9.5 kcal/mol vs complex)
- Tinker MM3 energy and frequencies for comparison
- All saved as permanent test fixtures in examples/sn2-test/

Both backends verified working:
- TinkerEngine: energy + frequencies on CH3F and SN2 TS
- Psi4Engine: energy on CH3F (requires conda env q2mm)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Tinker tests (10 tests, all pass without conda):
- Engine availability and name
- Energy calculation on CH3F (returns float, is finite)
- Frequency analysis on SN2 TS (18 modes, has imaginary)
- Minimization of CH3F (returns tuple, preserves atoms, lowers energy)

Psi4 tests (9 tests, 3 run without Psi4, 6 skip):
- Hessian fixture validation (shape 18x18, symmetric, 1 negative eigenvalue)
- Energy reproducibility against saved reference (requires Psi4)
- Molecule loading from XYZ file and atoms+coords tuple

Total test suite: 41 passed, 22 skipped, 1 xfailed

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
10 tests validating the full QM reference data pipeline:
- Hessian shape, symmetry, eigenvalue decomposition roundtrip
- Single negative eigenvalue confirms valid TS
- Frequency validation (12 modes TS, 9 modes CH3F, 1 imaginary)
- Geometry validation (C-F TS ~1.85 A, CH3F ~1.39 A)
- Cross-consistency between Hessian eigenvalues and frequencies

Total test suite: 51 passed, 22 skipped, 1 xfailed

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@ericchansen ericchansen requested a review from Copilot March 17, 2026 23:24
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds two new computational backends (Psi4 QM and Tinker MM) and introduces SN2 transition-state reference fixtures plus integration tests to validate the new engines and the end-to-end QM→Hessian analysis pipeline.

Changes:

  • Added Psi4Engine and TinkerEngine backends with energy/optimization/frequency (and partial Hessian) capabilities.
  • Added SN2 example/reference datasets (QM geometries, Hessians/frequencies; MM vibrational outputs).
  • Added integration tests covering backend availability, basic calculations, and Hessian/frequency consistency.

Reviewed changes

Copilot reviewed 35 out of 40 changed files in this pull request and generated 16 comments.

Show a summary per file
File Description
timer.dat Adds a runtime timer output file (appears to be generated artifact).
test/integration/test_tinker_backend.py Adds integration tests for Tinker backend energy/minimize/frequencies.
test/integration/test_psi4_backend.py Adds integration tests for Psi4 backend and fixture validation.
test/integration/test_pipeline.py Adds fixture-based Hessian/frequency pipeline consistency tests.
q2mm/backends/qm/psi4.py Introduces Psi4 QM backend wrapper.
q2mm/backends/mm/tinker.py Introduces Tinker MM backend wrapper via subprocess.
examples/sn2-test/test_backends.py Adds a quick manual script to exercise both backends.
examples/sn2-test/sn2-ts-guess.xyz Adds an SN2 TS initial-guess geometry.
examples/sn2-test/qm-reference/sn2-ts-optimized.xyz Adds optimized SN2 TS geometry fixture.
examples/sn2-test/qm-reference/complex-optimized.xyz Adds optimized ion-dipole complex geometry fixture.
examples/sn2-test/qm-reference/ch3f-optimized.xyz Adds optimized CH3F geometry fixture.
examples/sn2-test/mm-reference/sn2-ts.xyz Adds Tinker-format TS geometry fixture.
examples/sn2-test/mm-reference/sn2-ts.key Adds Tinker key fixture (currently absolute path).
examples/sn2-test/mm-reference/sn2-ts.018 Adds MM vibrational displacement/scan output fixture.
examples/sn2-test/mm-reference/sn2-ts.017 Adds MM vibrational displacement/scan output fixture.
examples/sn2-test/mm-reference/sn2-ts.016 Adds MM vibrational displacement/scan output fixture.
examples/sn2-test/mm-reference/sn2-ts.015 Adds MM vibrational displacement/scan output fixture.
examples/sn2-test/mm-reference/sn2-ts.014 Adds MM vibrational displacement/scan output fixture.
examples/sn2-test/mm-reference/sn2-ts.013 Adds MM vibrational displacement/scan output fixture.
examples/sn2-test/mm-reference/sn2-ts.012 Adds MM vibrational displacement/scan output fixture.
examples/sn2-test/mm-reference/sn2-ts.011 Adds MM vibrational displacement/scan output fixture.
examples/sn2-test/mm-reference/sn2-ts.010 Adds MM vibrational displacement/scan output fixture.
examples/sn2-test/mm-reference/sn2-ts.009 Adds MM vibrational displacement/scan output fixture.
examples/sn2-test/mm-reference/sn2-ts.008 Adds MM vibrational displacement/scan output fixture.
examples/sn2-test/mm-reference/sn2-ts.007 Adds MM vibrational displacement/scan output fixture.
examples/sn2-test/mm-reference/sn2-ts.006 Adds MM vibrational displacement/scan output fixture.
examples/sn2-test/mm-reference/sn2-ts.005 Adds MM vibrational displacement/scan output fixture.
examples/sn2-test/mm-reference/sn2-ts.004 Adds MM vibrational displacement/scan output fixture.
examples/sn2-test/mm-reference/sn2-ts.003 Adds MM vibrational displacement/scan output fixture.
examples/sn2-test/mm-reference/sn2-ts.002 Adds MM vibrational displacement/scan output fixture.
examples/sn2-test/mm-reference/sn2-ts.001 Adds MM vibrational displacement/scan output fixture.
examples/sn2-test/generate_qm_data_v2.py Adds script to regenerate QM reference data with corrected basis.
examples/sn2-test/generate_qm_data.py Adds original QM reference generation script.
examples/sn2-test/generate_mm_data.py Adds script to generate MM reference outputs using Tinker.
examples/sn2-test/compute_barrier.py Adds script to compute barrier height for comparison.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread timer.dat Outdated
Comment thread q2mm/backends/mm/tinker.py
Comment thread q2mm/backends/mm/tinker.py
Comment thread q2mm/backends/mm/tinker.py Outdated
Comment thread q2mm/backends/mm/tinker.py
Comment thread test/integration/test_psi4_backend.py Outdated
Comment thread test/integration/test_psi4_backend.py Outdated
Comment thread test/integration/test_psi4_backend.py
Comment thread test/integration/test_pipeline.py
Comment thread examples/sn2-test/test_backends.py Outdated
ericchansen and others added 2 commits March 17, 2026 18:38
- Fix F541 f-string lint errors in generate_qm_data scripts (ruff --fix)
- Force-add gitignored .txt fixture files (frequencies, energy, summary)
- Remove timer.dat from tracking and add to .gitignore
- Remove mm-reference/sn2-ts.key (runtime artifact with hardcoded path)
- Add params_file validation in TinkerEngine.__init__
- Add subprocess return code check in TinkerEngine._run_tinker
- Add energy parse validation in TinkerEngine.minimize
- Replace TinkerEngine.hessian with NotImplementedError
- Auto-detect RHF/UHF reference from multiplicity in Psi4Engine
- Replace Psi4Engine.__del__ with context manager + close()
- Fix test_psi4_backend docstring and tolerance documentation
- Add skipUnless decorators to test_pipeline fixture-dependent tests
- Wrap test_backends.py in __main__ guard

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
str | None, list[str], tuple[list[str], ...] syntax requires
Python 3.10+. Adding from __future__ import annotations makes
these work on 3.9 as well.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds two new computational backends (Psi4 for QM, Tinker for MM) plus an SN2 transition-state reference dataset and integration tests to validate the end-to-end workflow using stored fixtures.

Changes:

  • Introduce Psi4Engine (Psi4 Python API wrapper) and TinkerEngine (Tinker CLI wrapper) under q2mm/backends/.
  • Add SN2 QM/MM reference fixtures under examples/sn2-test/ (geometries, Hessians, frequencies, outputs, summary).
  • Add integration tests for both backends and a Hessian→linalg pipeline test suite.

Reviewed changes

Copilot reviewed 42 out of 48 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
.gitignore Ignores a runtime artifact (timer.dat).
q2mm/backends/base.py Enables postponed evaluation of annotations for backend ABCs.
q2mm/backends/qm/psi4.py Adds Psi4Engine implementing energy/hessian/optimize/frequencies and temp output management.
q2mm/backends/mm/tinker.py Adds TinkerEngine implementing energy/minimize/frequencies via subprocess + format conversion.
test/integration/__init__.py Integration test package marker.
test/integration/test_psi4_backend.py Psi4 integration tests + fixture-only Hessian validation tests.
test/integration/test_tinker_backend.py Tinker integration tests for energy/minimize/frequencies (skipped if unavailable).
test/integration/test_pipeline.py Pipeline tests using saved QM fixtures (Hessian properties + linalg roundtrip + fixture sanity checks).
examples/sn2-test/test_backends.py Manual “quick test” script for both backends.
examples/sn2-test/compute_barrier.py Script computing barrier quantities for literature comparison.
examples/sn2-test/generate_qm_data.py Script generating original QM fixture set (older basis).
examples/sn2-test/generate_qm_data_v2.py Script generating updated QM fixture set (6-31+G(d) + complex).
examples/sn2-test/generate_mm_data.py Script generating MM3/Tinker reference outputs for the TS geometry.
examples/sn2-test/sn2-ts-guess.xyz Initial TS guess geometry.
examples/sn2-test/qm-reference/summary.txt Human-readable QM reference summary (energies, barrier metrics, key distances, imaginary freq).
examples/sn2-test/qm-reference/sn2-ts-optimized.xyz QM-optimized TS geometry fixture.
examples/sn2-test/qm-reference/sn2-ts-hessian.npy QM TS Hessian fixture (NumPy binary).
examples/sn2-test/qm-reference/sn2-ts-frequencies.txt QM TS vibrational frequencies fixture.
examples/sn2-test/qm-reference/sn2-ts-energy.txt QM TS energy fixture.
examples/sn2-test/qm-reference/complex-optimized.xyz QM ion-dipole complex geometry fixture.
examples/sn2-test/qm-reference/ch3f-optimized.xyz QM CH3F optimized geometry fixture.
examples/sn2-test/qm-reference/ch3f-hessian.npy QM CH3F Hessian fixture (NumPy binary).
examples/sn2-test/qm-reference/ch3f-frequencies.txt QM CH3F vibrational frequencies fixture.
examples/sn2-test/qm-reference/ch3f-energy.txt QM CH3F energy fixture.
examples/sn2-test/mm-reference/analyze-energy.txt Tinker analyze output fixture for TS energy breakdown.
examples/sn2-test/mm-reference/vibrate-output.txt Tinker vibrate output fixture for TS normal modes/frequencies.
examples/sn2-test/mm-reference/mm-frequencies.txt Parsed Tinker MM3 frequencies fixture.
examples/sn2-test/mm-reference/sn2-ts.xyz Tinker-format TS structure fixture.
examples/sn2-test/mm-reference/sn2-ts.001 Tinker vibrational mode displacement output fixture (mode 1).
examples/sn2-test/mm-reference/sn2-ts.002 Tinker vibrational mode displacement output fixture (mode 2).
examples/sn2-test/mm-reference/sn2-ts.003 Tinker vibrational mode displacement output fixture (mode 3).
examples/sn2-test/mm-reference/sn2-ts.004 Tinker vibrational mode displacement output fixture (mode 4).
examples/sn2-test/mm-reference/sn2-ts.005 Tinker vibrational mode displacement output fixture (mode 5).
examples/sn2-test/mm-reference/sn2-ts.006 Tinker vibrational mode displacement output fixture (mode 6).
examples/sn2-test/mm-reference/sn2-ts.007 Tinker vibrational mode displacement output fixture (mode 7).
examples/sn2-test/mm-reference/sn2-ts.008 Tinker vibrational mode displacement output fixture (mode 8).
examples/sn2-test/mm-reference/sn2-ts.009 Tinker vibrational mode displacement output fixture (mode 9).
examples/sn2-test/mm-reference/sn2-ts.010 Tinker vibrational mode displacement output fixture (mode 10).
examples/sn2-test/mm-reference/sn2-ts.011 Tinker vibrational mode displacement output fixture (mode 11).
examples/sn2-test/mm-reference/sn2-ts.012 Tinker vibrational mode displacement output fixture (mode 12).
examples/sn2-test/mm-reference/sn2-ts.013 Tinker vibrational mode displacement output fixture (mode 13).
examples/sn2-test/mm-reference/sn2-ts.014 Tinker vibrational mode displacement output fixture (mode 14).
examples/sn2-test/mm-reference/sn2-ts.015 Tinker vibrational mode displacement output fixture (mode 15).
examples/sn2-test/mm-reference/sn2-ts.016 Tinker vibrational mode displacement output fixture (mode 16).
examples/sn2-test/mm-reference/sn2-ts.017 Tinker vibrational mode displacement output fixture (mode 17).
examples/sn2-test/mm-reference/sn2-ts.018 Tinker vibrational mode displacement output fixture (mode 18).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread q2mm/backends/mm/tinker.py
Comment thread q2mm/backends/mm/tinker.py
Comment thread examples/sn2-test/generate_mm_data.py Outdated
Comment thread examples/sn2-test/compute_barrier.py Outdated
Comment thread test/integration/test_psi4_backend.py Outdated
Comment thread test/integration/test_pipeline.py
- generate_mm_data.py: use env vars + expanduser instead of hardcoded path
- compute_barrier.py: use os.devnull instead of Windows-specific 'NUL'
- test_psi4_backend.py: import psi4 directly instead of private _HAS_PSI4
- test_pipeline.py: add frequency fixture files to skipUnless condition

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@ericchansen ericchansen merged commit ff55927 into master Mar 18, 2026
6 checks passed
ericchansen added a commit that referenced this pull request Mar 18, 2026
- Fix F541 f-string lint errors in generate_qm_data scripts (ruff --fix)
- Force-add gitignored .txt fixture files (frequencies, energy, summary)
- Remove timer.dat from tracking and add to .gitignore
- Remove mm-reference/sn2-ts.key (runtime artifact with hardcoded path)
- Add params_file validation in TinkerEngine.__init__
- Add subprocess return code check in TinkerEngine._run_tinker
- Add energy parse validation in TinkerEngine.minimize
- Replace TinkerEngine.hessian with NotImplementedError
- Auto-detect RHF/UHF reference from multiplicity in Psi4Engine
- Replace Psi4Engine.__del__ with context manager + close()
- Fix test_psi4_backend docstring and tolerance documentation
- Add skipUnless decorators to test_pipeline fixture-dependent tests
- Wrap test_backends.py in __main__ guard

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@ericchansen ericchansen deleted the feat/backends branch March 18, 2026 13:58
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.

2 participants