orthonym.perception.stereo#

Note

Internal API. Names and behaviour may change between releases.

Stereochemistry perception and CIP assignment.

CRITICAL: Always use rdCIPLabeler.AssignCIPLabels, not the legacy Chem.AssignStereochemistry which fails on complex molecules.

orthonym.perception.stereo.assign_stereochemistry(mol)#

Assign CIP stereochemistry labels to a molecule (idempotent guard).

Uses a private marker property to track whether rdCIPLabeler has already been called on this mol object. This is more reliable than checking for _CIPCode because RDKit’s MolFromSmiles automatically sets atom _CIPCode from @/@@ notation, but does NOT set bond _CIPCode for E/Z – so an atom-based check would short-circuit and skip the bond labels.

The authoritative call site in namer.py:_perceive sets the marker after calling rdCIPLabeler. Handler modules call this function for safety (e.g., natural_products runs BEFORE _perceive).

Parameters:

mol – RDKit Mol object (modified in place)

orthonym.perception.stereo.get_stereocenters(mol)#

Get all stereocenters with their CIP labels.

Parameters:

mol – RDKit Mol object (stereochemistry should be assigned first)

Returns:

List of dicts with keys –

  • idx: atom index

  • cip: ‘R’ or ‘S’

  • symbol: atom element symbol

  • neighbors: list of neighbor atom indices

Return type:

List[Dict]

orthonym.perception.stereo.get_double_bond_stereo(mol)#

Get E/Z configuration of double bonds.

Uses the _CIPCode property set by rdCIPLabeler as the sole source of E/Z labels. BondStereo fallback was removed in a phase-03.

Parameters:

mol – RDKit Mol object (stereochemistry should be assigned via rdCIPLabeler.AssignCIPLabels BEFORE calling this function)

Returns:

List of dicts with keys –

  • idx: bond index

  • stereo: ‘E’ or ‘Z’

  • atoms: (begin_atom_idx, end_atom_idx)

Return type:

List[Dict]

orthonym.perception.stereo.has_stereochemistry(mol)#

Check if molecule has any defined stereochemistry.

Parameters:

mol – RDKit Mol object

Returns:

True if molecule has stereocenters or double bond stereo

Return type:

bool

orthonym.perception.stereo.get_stereodescriptor_string(mol, locant_map=None)#

Generate stereodescriptor string for name prefix.

DEPRECATED: Prefer collect_stereodescriptors + format_stereodescriptor_string from orthonym.rules.stereochemistry directly.

Delegates to the production pipeline. When locant_map is None, uses an identity mapping (atom_idx -> idx+1) for backward compatibility with test call sites.

Parameters:
  • mol – RDKit Mol object

  • locant_map (Dict[int, int] | None) – Optional mapping from atom index to locant number. If None, uses identity mapping (idx+1).

Returns:

Stereodescriptor string like “(2R,3S)-” or empty string if no stereochemistry.

Return type:

str

orthonym.perception.stereo.count_stereocenters(mol)#

Count the number of stereocenters in a molecule.

Parameters:

mol – RDKit Mol object

Returns:

Number of defined stereocenters

Return type:

int

orthonym.perception.stereo.count_double_bond_stereo(mol)#

Count the number of double bonds with defined E/Z stereochemistry.

Parameters:

mol – RDKit Mol object

Returns:

Number of E/Z defined double bonds

Return type:

int

orthonym.perception.stereo.is_chiral(mol)#

Check if molecule has any chiral centers.

Parameters:

mol – RDKit Mol object

Returns:

True if molecule has at least one defined stereocenter

Return type:

bool

orthonym.perception.stereo.get_undefined_stereocenters(mol)#

Find potential stereocenters without defined stereochemistry.

Parameters:

mol – RDKit Mol object

Returns:

List of atom indices that are potential stereocenters but don’t have defined R/S configuration

Return type:

List[int]

orthonym.perception.stereo.input_stereo_undefined(mol, atom_indices=None)#

True iff mol leaves a REAL stereo feature UNDEFINED: a tetrahedral stereocentre flagged possible but carrying no CIP configuration, or a stereogenic double bond left undirected. When atom_indices is given, the tetrahedral check is restricted to those atoms (bond check is unrestricted).

The shared stereo-honesty predicate for a phase: a config-implying retained name (steroid cholest-/androst-, amino acid S-methylcysteine) asserts a specific configuration, so it must not be emitted when this returns True – that would fabricate stereo the input never defined /. Fail-CLOSED: any failure returns True, so an uncomputable case never lets a fabrication through.

orthonym.perception.stereo.AXIAL_GENERAL_FORM = {'M': 'Sa', 'P': 'Ra'}#

The axial descriptor in GENERAL nomenclature, keyed by the PIN (helicity) descriptor. “Cahn-Ingold-Prelog (CIP) stereodescriptors” (the Blue Book) lists under “The following stereodescriptors are used as preferred stereodescriptors” clause (c) (:44588) “‘M’ and ‘P’, to specify the absolute configuration of an axial or planar entity using the helicity rule”; ‘Ra’/’Sa’ appear only under “The following stereodescriptors are recommended for general nomenclature” (:44594). The two describe the same sense: “The helicity rule: stereodescriptors ‘M’ and ‘P’” (:44812) – “the chirality is described by the symbols ‘M’ if the path is anticlockwise; the symbol is ‘P’ if the path is clockwise” – is the same clockwise/anticlockwise test the Ra/Sa elongated-tetrahedron model applies, so Ra == P and Sa == M.

orthonym.perception.stereo.detect_axial_chirality(mol, style='pin')#

Detect allene and atropisomer axial chirality in a molecule.

Identifies two types of axial chirality encoded in the input: 1. Atropisomers: bonds with STEREOATROPCW or STEREOATROPCCW stereo 2. Allenes: atoms with CHI_ALLENE chiral tag on central C of C=C=C

Only detects chirality that is explicitly encoded in the molecular representation. Does NOT attempt to infer chirality where the input is silent.

Descriptor,:44582 – see AXIAL_GENERAL_FORM): the helicity letters ‘M’/’P’ are the PREFERRED (PIN) stereodescriptors for an axial entity, so they are what this returns by default. ‘Ra’/’Sa’ are recommended for GENERAL nomenclature only and are produced with style="general".

Parameters:
  • mol – RDKit Mol object

  • style (str) – ‘pin’ (default) -> ‘M’/’P’; ‘general’ -> ‘Sa’/’Ra’.

Returns:

List of dicts with keys –

  • type: ‘allene’ or ‘atropisomer’

  • idx: atom index (allene) or bond index (atropisomer)

  • cip: ‘M’/’P’ (‘Sa’/’Ra’ when style=’general’), or None if undetermined

  • locant_atom: atom index to use for IUPAC locant mapping

Return type:

List[Dict]