Repository navigation
Qualitative MO correlation diagrams: central atom orbitals, terminal atom symmetry orbitals (TASOs), and symmetry labels #132
Description
Build the qualitative MO correlation diagram a chemist actually draws: central
atom orbitals on the left, ligand SALCs on the right, the molecular orbitals in
the middle, with the correlation lines and symmetry labels between them.
TASO = terminal atom symmetry orbitals -- the symmetry-adapted combinations
built from the outer atoms' orbitals, as opposed to the central atom's, which
enter the diagram on their own. (An earlier revision of this issue guessed
"SALC"; TASO is the term Andy used and is the more specific one, since it names
which atoms the combinations are built from.)
Fine to restrict the first implementation to small, high-symmetry molecules --
AH_n, octahedral and tetrahedral ML_n. That is where the diagram is taught and
where it is worth the most.
Why this is more than a drawing
ECCE already has the hard parts. Orbital energies, occupancies and symmetry
labels are extracted for several codes (ORBENG, ORBOCC, ORBSYM), and
MoPanel already lists them with their irreducible representation. What is
missing is the decomposition: which fragment orbitals each MO is built from,
and how much of each. With the AO coefficients in hand that is a projection --
form the TASOs for the terminal set, project each MO onto them and onto the
central atom's AOs, and the correlation lines and their weights fall out.
The MOPAC orbital work (#128) makes the AO coefficients available for a
semiempirical code, which is the cheap end where a user can iterate on a
structure in seconds. That is a good match for a teaching diagram.
What would have to be built
-
A point group table. Character tables for at least the common groups
(C_2v, C_3v, D_2h, D_3h, D_4h, T_d, O_h), with irrep labels, symmetry
operations and the reduction formula. This is a data file, not code -- the
same shape asdata/client/config/properties. ECCE already carries
symmetry labels from the codes but has no understanding of them; it cannot
answer "is a1 symmetric under C_2" today. -
Symmetry detection, or trust the code. The point group is already known
to the calculation in most cases -- the codereg dialogs are handed a
symmetry group inglobals.py's argv, and several parsers extract it. Start
by trusting that rather than writing a perception algorithm. -
TASO construction. Apply the projection operator to the terminal atoms'
AO set to get the symmetry-adapted combinations and their irreps. The
central atom's own orbitals need no such treatment -- they already
transform as irreps of the full group, which is the asymmetry that makes
the two sides of the diagram different objects rather than one procedure
applied twice. -
Projection and the diagram itself. A new property panel, in the family
ofMoPanel; clicking a level should show that MO in the viewer, which is
the wiringVizPropertyPanelalready provides.
Worth deciding early
- Core orbitals. Worth showing as a separate, collapsed block rather than
as diagram levels -- they are on every diagram as a footnote and would
otherwise compress the valence region that matters. Note that semiempirical
codes have no core orbitals at all, so the panel must be honest about which
it is showing rather than implying they are absent. - Degenerate sets must be drawn as one level of the right multiplicity, and
the multiplicity must come from the irrep, not from counting near-equal
energies -- an accidental near-degeneracy is not a degenerate set.
Andy's framing: "This is something exciting." Agreed -- it is the one thing in
this area that a general-purpose viewer does not already do better.
Activity
[-]Qualitative MO correlation diagrams: central atom orbitals, ligand SALCs, and symmetry labels[/-][+]Qualitative MO correlation diagrams: central atom orbitals, terminal atom symmetry orbitals (TASOs), and symmetry labels[/+]ohlincha commentedon Sep 24, 2026
Roadmap
What already exists (surveyed before planning, and it changes the shape of this)
SymmetryOps::find(Fragment&, threshold)returns the Schoenflies name. It shells out to
src/apps/symmetry/autosym.f,NWChem's symmetry library. So no perception algorithm has to be written.
gensym.f,dosymops.f,symops(maxops*3,4)), but only to generate and cleanstructures. They are not exposed to C++.
data/client/config/PointGroups,loaded by
PointGroup. Names only — no classes, no characters.ORBSYMis already extracted for several codes, andMoPanelalreadydisplays it.
So the missing pieces are narrower than "understand symmetry": characters,
operations reachable from C++, projection, and the drawing.
The oracle, decided first
Every phase below has something to be checked against, which matters because a
wrong correlation diagram looks like a correlation diagram.
the data file self-verifying: rows orthogonal, columns orthogonal, the sum
of |chi|^2 over operations equal to the group order, the squared dimensions
summing to the order. A transcription error cannot survive that, which is
the right property for a hand-entered table of 46 groups.
ORBSYMis a free, independent oracle for the whole symmetry pipeline.The code has already labelled every MO with its irrep. If our own projection
assigns an MO to a different irrep than NWChem or Gaussian did, one of us is
wrong and it is almost certainly us. This checks detection, orientation,
characters and projection in one comparison, on any existing job, with
no new fixtures.
water's two to a1 + b2, SF6's six to a1g + eg + t1u. Unambiguous and in
every inorganic text.
Phase 1 -- character tables
Extend
data/client/config/PointGroups(or a sibling file, to avoiddisturbing a format other code reads) with, per group: the classes with their
operation counts, and the character of each irrep in each class.
Start with the groups the target molecules need: C2v, C3v, C4v, D2h, D3h, D4h,
Td, Oh, plus C1 and Cs as trivial cases. The other 36 can follow.
Deliverable:
PointGroup::characters(),classes(),order(), and thereduction formula
n_i = (1/h) sum_R chi_i(R)* chi(R).Test: orthogonality, as above. Self-verifying, so this phase is cheap and
low risk despite being data entry.
Phase 2 -- symmetry operations in the molecule's frame
The characters are abstract; projection needs the actual 3x3 matrices oriented
to this molecule -- where the C3 axis really points.
Two routes, and the choice matters:
gensym.fbuilds exactlythese matrices. Adding an entry point that returns them alongside the group
name is much less work than reimplementing, and it cannot disagree with the
detector, since it is the detector.
Recommend (a), and note that the existing
find()already writes and readsa temporary file, so extending that exchange is a small change rather than new
plumbing. Only if the Fortran turns out not to expose the frame should (b) be
considered.
Test: every operation must map the molecule onto itself -- for each atom,
R x_iis another atom of the same element within tolerance. That is acomplete check and needs no reference data.
Phase 3 -- TASOs
Partition the atoms into orbits under the group. The central atom is the orbit
of size one lying on all the elements; the terminal atoms form the others.
For each orbit and each AO type, build the reducible representation (the
character of an operation is the number of basis functions it leaves in place,
with sign), reduce it, then apply the projection operator to get the actual
combinations, orthonormalising within each irrep.
Deliverable: a list of TASOs, each with an irrep and coefficients over the
terminal AOs.
Test: the textbook reductions above.
The central atom needs no such treatment -- its orbitals already transform
as irreps of the full group. That asymmetry is why the two sides of the diagram
are different objects rather than one procedure run twice, and it is worth
encoding as such rather than generalising prematurely.
Phase 4 -- projecting the real MOs
For each MO, its overlap with each central AO and each TASO, weighted
Mulliken-style through the overlap matrix S.
S is nearly free now. The Gaussian overlap integral is a strict
simplification of the Coulomb integral added for #129 -- same Hermite
expansion, no Boys function -- so this is roughly forty lines in
CoulombIntegrals, testable the same way against the closed form for twoGaussians, which
tests/slateralready computes.Deliverable: per-MO fragment decomposition, which is what sets the weight of
each correlation line.
Test: oracle 2. The irrep carrying the largest weight must match the
code's own
ORBSYMlabel, for every MO of every test job.Phase 5 -- the diagram
A
VizPropertyPanelsubclass, inMoPanel's family, so clicking a level showsthat orbital in the viewer through wiring that already exists.
Decisions worth making deliberately rather than by default:
the irrep's dimension, never from counting near-equal energies. An accidental
near-degeneracy is not a degenerate set.
are not, and textbook diagrams place them from estimated valence orbital
ionization energies. Either ship a small VOIE table as data and label the
axis as qualitative for those columns, or place them purely by connectivity.
This is the one place where the diagram is a drawing rather than a
measurement, and it should say so on the panel.
compress the valence region that matters. Semiempirical codes have none at
all, so the panel must state which it is showing rather than let their
absence read as a result.
Ordering, and where the risk actually is
Phases 1 and 2 are prerequisites with complete mechanical tests, so they are
safe to do first and cheap to verify. Phase 3 has a textbook oracle. Phase 4 is
where the whole pipeline gets checked against
ORBSYM, and is therefore thepoint at which we learn whether any of this is right -- worth reaching early,
even with a crude diagram, rather than after the drawing is polished.
Phase 5 is the only part with no automated oracle. It goes last and should stay
small.
The likeliest failure is not the group theory but the frame: a detected
group whose operations are expressed in a standard orientation that does not
match the coordinates the MO coefficients were computed in. Phase 2's
self-check (every operation maps the molecule onto itself) catches a wrong
frame immediately, which is why it is worth doing even though it looks like a
formality.
Scope
Restrict the first implementation to a clear central atom with equivalent
terminal atoms -- AH_n and ML_n. Detect that shape and decline gracefully
otherwise; benzene and ethene have no central atom and are a different diagram,
not a harder case of this one.
Character tables, verified by the orthogonality theorem (#132)
CharacterTable: the reduction formula, in C++ (#132)
ohlincha commentedon Sep 24, 2026
Phases 1 and 2 are done, and cheaper than the roadmap estimated
Phase 1 — character tables. Thirteen groups (C1, Cs, Ci, C2, C2v, C3v, C4v, C2h, D2h, D3h, D4h, Td, Oh), plus
CharacterTablein C++ with the reduction formula. 987 checks.Phase 2 — the operations. Not the reimplementation the roadmap allowed for.
gensymhas always turned a group name into its operation matrices;spgenholds the generators, andcleansym/genmol/genmollat/getfragall use the result. Nothing ever exposed them.src/apps/symmetry/symops.fis a forty-line wrapper, so the operations are the ones the structure tools have always used and cannot drift from them.Three findings worth recording
1.
gensymdoes not return the identity. It hands back the other h−1 operations — what the structure tools need, and not a complete group. Found by checking rather than reading: all thirteen groups came back exactly one short, consistently, which is a different thing from a bug.symopswrites it first.2. The two data sources cross-validate. PNNL's Fortran generator tables and the hand-entered character tables are independent, and neither was derived from the other. They agree for every group on:
The matrices are also checked to be a group — determinants ±1, identity present, and closure under multiplication. Self-tested by corrupting one operation and watching closure fail.
3. The frame problem is already solved — but there is a trap.
The roadmap called the frame the likeliest failure: a detected group whose operations are in an orientation that doesn't match the coordinates the MO coefficients were computed in.
autosymreturns the molecule in the group's standard frame, andSymmetryOps::readSymmetry()writes those coordinates back into the fragment. So the operations and the coordinates already agree.The trap is that
SymmetryOps::find()mutates the fragment. That is deliberate —FindSymmetryCmdis the Builder's "Find Symmetry", whose job is to symmetrise the structure. But MO analysis must never do it: the MO coefficients were computed against the original coordinates, and reorienting the molecule moves the AO centres out from under them, silently.So Phase 3 has to:
T⁻¹ R TThe roadmap's Phase 2 test — every operation maps the molecule onto itself — is exactly the check for that, and now has something concrete to check.
Next
Phase 3, TASO construction: atom orbits under the group, then the projection operator. The textbook oracle stands (CH₄'s four H 1s → a₁ + t₂, SF₆'s six → a₁g + eg + t₁ᵤ).
symops: make the symmetry operations reachable (#132)
ohlincha commentedon Sep 24, 2026
Phase 3 design note: matching operations to named classes
Checked before building on it, because it looked like it might be a blocker and is not.
The reduction formula needs, for each operation, the character of the irrep — which means knowing which named class each matrix belongs to. Conjugacy classes are easy to compute from the matrices, but naming them is not automatic: several groups have two classes with the same size, trace and determinant.
The worked cases:
diag(1,-1,1)vsdiag(-1,1,1). The class names inCharacterTablesalready encode this (sv_xz,sv_yz), deliberately.diag(-1,-1,1)= C₂(z), thendiag(-1,1,-1)anddiag(1,-1,-1)= the axis-aligned 2C₂′, and two with zero x/y diagonal entries = the diagonal 2C₂″. The standard convention (primed along the axes, double-primed along the diagonals) is recoverable straight from the matrices.So the rule is: conjugacy class → (determinant, trace, size) for the operation type, then axis orientation where that is not unique. Not ambiguous, but not free either — it needs a per-group convention rather than a generic matcher, and getting it wrong swaps B1/B2 (or B1g/B2g) silently.
This is also exactly where
ORBSYMearns its place as the oracle: a swapped convention shows up immediately as a disagreement with the code's own label, on any existing job. Worth noting that codes themselves sometimes differ here, so a disagreement wants checking rather than assuming we are wrong.Phase 3 can proceed on that basis. The first target stays CH₄: four H 1s orbitals give χ = (4, 1, 0, 0, 2) over (E, 8C₃, 3C₂, 6S₄, 6σd), which reduces to a₁ + t₂ — none of the ambiguous cases above, so it exercises the machinery without depending on the convention work.
Orbits and terminal-atom symmetry orbitals (#132)
Overlap integrals, for projecting orbitals onto fragments (#132)
Install symops (#132)
All the character tables, parsed from the 5KE195 compendium (#132)
The symmetry orbitals themselves, not just which irreps appear (#132)
The AO basis as a whole, and the ORBSYM checkpoint it enables (#132)
The MO diagram, drawn (#132)
24 remaining items
tests/symmetry: add SF6/Oh to the full-orbital-irrep oracle (#147/#132)
SymmetryAnalysis: independent no-gensym-frame subgroup cross-check (#147
MoDiagramPanel: draw the FULL point group when the cross-check passes (…
MO diagram: wire the composition fallback for homonuclear diatomics (#…
MO diagram: classify by overlap population for no-central-atom builds…
MO diagram: merge alpha/beta into one open-shell column; accept compu…
MO diagram: accept computed labels when only the DRAWN window is full…
MO diagram: draw TASOs for structures the code symmetrised (#132)
ohlincha commentedon Oct 11, 2026
Decision (2026-10-11): where G16 or ORCA ran a slightly unsymmetric structure in a lower group (e.g. water in Cs), the diagram draws the higher group found on its symmetrised copy (C2v), with labels computed from the orbitals and cross-checked against the code's labels, and a note saying so (d790f1d).
Character tables for C3-C6, C3h-C6h, S4/S6/S8, T, Th, O, I, Ih (#132)
ohlincha commentedon Oct 11, 2026
Character tables added (d3ce098): C3–C6, C3h–C6h, S4, S6, S8, T, Th, O, I, Ih (43 groups in all). Complex-conjugate pairs are stored as one real two-dimensional E (2cos(2πk/n)), flagged separable, with norm 2h in the checks and in reduce(). All groups pass the orthogonality, dimension, class-count and Cartesian checks and the symops cross-check; Gaussian 16 labels for C3 and C3h match. The MO diagram now falls back to C1 only for groups still without a table (C7, C8, D8h …).
MO diagram: ECCE-QM homonuclear diatomics draw their TASOs again (#132)
ohlincha commentedon Oct 11, 2026
Homonuclear diatomics, ECCE-QM C2 (after b84c402), Andy's review 2026-10-11, to fix after 9.0.0-beta.2:
Tests: the ecceqm-c2/n2/he2 goldens plus the G16/ORCA N2/CO fixtures; counts and pairs asserted.
MO diagram: homonuclear diatomics classified by phase, paired g/u; He…