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
molthatcentreswould 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
centresas it was.