orthonym.data.resonance_templates#

Note

Internal API. Names and behaviour may change between releases.

Resonance-shifted (bond_orders, charges) chain templates for terminal nitrogen chains: azido, diazo, diazonium (a phase).

RDKit does NOT normalise resonance forms on MolFromSmiles – each drawing keeps its own literal bond orders / formal charges. Two independently-valid resonance drawings exist for each of these three // classes; a single closed 3-set of six (bond_orders, charges) vectors over the ordered attach->terminal nitrogen chain distinguishes all of them (a phase a trace, internal notes Q3):

class | drawing | bond_orders | charges ———–|---------------------------------|————-|—————— azido | R-N=[N+]=[N-] (canonical) | (1, 2, 2) | (0, 0, +1, -1) azido | R-[N-]-[N+]#N (charge-sep. alt) | (1, 1, 3) | (0, -1, +1, 0) diazonium | R-N+#N (canonical) | (1, 3) | (0, +1, 0) diazonium | R-N=N+ (charge-on-terminal alt) | (1, 2) | (0, 0, +1) diazo | R2C=[N+]=[N-] (canonical) | (2, 2) | (0, +1, -1) diazo | R2[C-]-[N+]#N (carbanion alt) | (1, 3) | (-1, +1, 0)

Resonance-template table (independent implementation) – a per-cell shape: key / bond_orders / charges as per-cell None wildcard / frozenset alternatives / exact int, with first-match priority. This table has no wildcard cells today: the six rows are pairwise distinct as exact tuples (chain length alone separates azido’s 4-atom chain from diazonium/diazo’s 3-atom chain; diazonium vs diazo then separate on the attach-bond order, 1 vs 2).

The chain is always (attach_atom, n1, n2, (n3)) – attach_atom is the first NON-nitrogen atom reached walking outward from the charged nitrogen group, and is a structural requirement of the walk (never a wildcarded cell): a free azide/diazonium anion, with no organic attachment, has no non-nitrogen atom to seed a walk from and can therefore never match (Q3 nuance) – [N-]=[N+]=[N-] alone never enters find_resonance_chains.

class orthonym.data.resonance_templates.ResonanceChainTemplate(key, bond_orders, charges)#

Bases: object

One row of the closed 3-set. matches is a per-cell AND across bond_orders and charges: None wildcards a cell, a frozenset accepts any listed alternative, an int requires an exact match. First-match wins in table order (a defined-order match) – today every cell is an exact int so no two rows can double-match the same vector, but the priority contract is kept for any future wildcarded row.

key: str#
bond_orders: Tuple[int | FrozenSet[int] | None, ...]#
charges: Tuple[int | FrozenSet[int] | None, ...]#
matches(bond_orders, charges)#
orthonym.data.resonance_templates.classify_resonance_chain(bond_orders, charges)#

First-match lookup: (bond_orders, charges) -> 'azido' / 'diazo' / 'diazonium', or None if the vector matches none of the six rows – fail closed: an ordinary amine / nitro / hydrazine / hydrazinium chain returns None, never a guess.

orthonym.data.resonance_templates.chain_vector(mol, chain)#

(bond_orders, charges) for an ordered atom-index chain. None on any bond type the closed set never uses (aromatic / dative / quadruple), or if consecutive atoms in chain are not bonded.

orthonym.data.resonance_templates.find_resonance_chains(mol)#