orthonym.perception.centres_mancude#

Note

Internal API. Names and behaviour may change between releases.

Ring atoms the centres labeller must not average.

“Mancude rings and ring systems” (the Blue Book): “Mancude rings, i.e.,

rings or ring systems having the maximum number of noncumulative double bonds, are treated as Kekulé structures. For mancude heterocycles, each duplicate atom is given an atomic number that is the mean of what it would have if the double bonds were located at each of the possible positions.” The mean belongs to mancude rings only; a ring whose double bonds are fixed below that maximum keeps the atomic numbers of its own Kekulé structure.

centres 1.2.1 (com.simolecule.centres.Mancude, read with javap -c) does not judge that. It gives each ring atom whose valence signature fits a mancude ring (C, Si, Ge with one double bond and two single ones; N, P, As with one double bond and one single one, or charged as an iminium; O+) a type, drops by repeated pruning the atoms left with a single typed neighbour, and takes the connected groups of what remains (its “parts”). The duplicate atom that a double bond adds to an atom of a part then gets the mean atomic number of that atom’s neighbours in the part, whatever the atom’s double bond actually is (measured on a digraph dump: the duplicate of N on a ring carbon of such a part carries 12/2, not 7). A ring atom that bears an exocyclic double bond has the signature, so a ring with two ylidene or imino groups (two ring double bonds against the three a six-membered mancude ring has) is averaged as if it were mancude, and the labels beside it come out as those of another stereoisomer. rdCIPLabeler, to which the engine falls back only when centres is unavailable (no JVM), is a separate implementation that treats these rings in its own way (on the labels this module changes it gives the Kekulé label for every centre and for about half of the double bonds); this module does not reach that fallback.

The only per-atom inputs Mancude reads are the element, the valence and the formal charge; no sequence rule reads a charge. getCharge / getFormalCharge is called by Mancude.SeedTypes, by Digraph (for a negative charge on an averaged atom) and by CdkLabeller.handleSruRepeat (the copy of a ctab structure-repeat-unit Sgroup, never reached from a SMILES). So the bridge tells centres that an atom is not part of a mancude system by raising its formal charge by one in the string it labels (centres_bridge.centres_label_mol): no typed signature has a charge one higher, and the pruning then removes what hangs on it.

This module decides which atoms those are. It repeats SeedTypes, RelaxTypes and VisitParts (the check of that repetition is in tests/integration/test_centres_mancude_parts.py), and for every part in which the mean would change an atomic number asks the definition above: the part is mancude when the double bonds the structure holds inside it are a maximum matching of its atoms (the predicate of perception.mancude). Of a part that is not, the atoms whose double bond leaves it (the ylidene and imino carbons) are fixed in place; the pruning is run again and the remaining parts are asked in turn, so a benzo ring beside a quinoid ring keeps its own mean.

orthonym.perception.centres_mancude.STATS: Counter = {}#

the number of double bonds the part holds would depend on the Kekulé structure chosen, or an atom has two fixed double bonds; parts_odd: its atoms cannot all be matched). The bridge serves repeats of one molecule from a cache, so each is counted once per molecule and process.

Type:

Parts left alone because they cannot be judged, by cause (parts_not_judged

orthonym.perception.centres_mancude.non_mancude_ring_atoms(mol)#

Atom indices of mol that centres would average as part of a mancude system but that are not part of one, sorted; empty when there are none.

Never raises: a molecule the analysis cannot read gets the empty answer, which leaves centres as it was.