M-METAL Phase 2 (MET.1, MET.7) + M-PROGRESS D2 (TD-DFT root progress) - #61
Merged
Merged
Conversation
… (MET.1, MET.7) MET.1: pubchem.sdf_to_xyz now detects a coordination-complex metal centre (connectivity.is_metal) and, when the source SDF has any conformer, keeps its coordinates rather than re-embedding. RDKit's valence-based bond perception draws no bond between a metal and its donor atoms, so a real complex's GetMolFrags looks like several disconnected fragments -- exactly the shape _separate_fragments (built for genuine salts) exists to push apart, which previously scattered a real complex's ligands away from the metal on every 2D-source re-embed. cactus.fetch_from_cactus needed no separate change; it already delegates to sdf_to_xyz. MET.7: tests/test_m_metal_regression.py parametrizes over all 14 bundled inorganic entries, exercising connectivity, the charge/multiplicity and basis guards, the PlotlyMol fallback, pre-opt honesty, and (generalized from the cisplatin-only case) that scattering any entry's metal still trips the disconnection warning -- plus a real PySCF RHF/def2-SVP single point on cisplatin. Claude (Sonnet 5) Co-authored-by: Claude <noreply@anthropic.com>
… label tddft_calc.py bumps td.verbose 3->5 (PySCF's DEBUG level), which is what surfaces the Davidson solver's "root %d converged ... e= ... max|de|= ..." lines during the excited-state solve -- verified against the installed PySCF (2.14.0) by running a real solve and reading its actual stdout. _LogCapture.write in app.py gains _RE_TD_ROOT alongside the existing _RE_CYCLE/_RE_Q_STATUS regexes, turning each match into a "TD-DFT root N converged * X eV" status update. Before this, TD-DFT's per-root progress was invisible during the run -- the Phase D1 heartbeat covers "is it still alive" generically, but not "how far along is the excited-state solve." End-to-end verified: a real water/STO-3G TDHF run left the status label reading "TD-DFT root 3 converged * 16.663 eV", matching the third excitation energy exactly. Claude (Sonnet 5) Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
pubchem.sdf_to_xyzis now metal-aware. RDKit's valence-based bond perception draws no bond between a metal centre and its donor atoms, so a real coordination complex'sGetMolFragslooks like several disconnected fragments — exactly the shape_separate_fragments(built for genuine salts) exists to push apart, which previously scattered a real complex's ligands away from the metal on every 2D-source re-embed. Fix: when a metal centre is detected and the source SDF has any conformer, keep those coordinates instead of re-embedding, and skip fragment separation in the rare from-scratch-embed case.cactus.fetch_from_cactusneeded no separate change — it already delegates tosdf_to_xyz.tests/test_m_metal_regression.py: a consolidated regression set parametrized over all 14 bundled inorganic entries, covering connectivity, the charge/multiplicity and basis guards, the PlotlyMol non-crash fallback, pre-opt honesty, and (generalized from a cisplatin-only case) that scattering any entry's metal still trips the disconnection warning — plus a real PySCF RHF/def2-SVP single point on cisplatin.tddft_calc.pyraisestd.verboseto PySCF's DEBUG level, which is what emits the Davidson solver's per-root convergence lines;app.py's_LogCaptureparses them into a"TD-DFT root N converged · X eV"status update, verified end-to-end against a real TDHF run.Test plan
pytest -m "not network"— full suite passingruff/black/mypy— cleanAuthorship
Generated by Claude Code