orthonym.data.fused_heterocycles#

Note

Internal API. Names and behaviour may change between releases.

Retained names for fused heterocyclic systems.

IUPAC 2013 prefers retained names (indole over benzo[b]pyrrole) for these common fused heterocycles. ALWAYS check this lookup before applying systematic fusion naming rules.

Keys are canonical SMILES (verified with RDKit), values contain: - name: The IUPAC retained name - tautomer_locant: Position of indicated hydrogen (e.g., 1 for 1H-indole), or None - ring_system: Classification (benzo-5-membered, benzo-6-membered, tricyclic, etc.) - parent_atoms: Number of heavy atoms in parent ring system - iupac_locants: Mapping from canonical atom index to IUPAC peripheral locant

orthonym.data.fused_heterocycles.get_fused_heterocycle_prefix(core_smiles, attachment_atom_idx, atom_mapping)#

Get prefix form for a fused heterocycle substituent.

Static O(1) dict lookup — no recursive naming calls. Returns the IUPAC systematic prefix form:

stem-locant-yl (e.g., “quinolin-2-yl”, “1H-indol-3-yl”)

Parameters:
  • core_smiles (str) – Canonical SMILES of the matched fused heterocycle core.

  • attachment_atom_idx (int) – Mol atom index where the ring attaches to parent.

  • atom_mapping (Dict[int, int | str]) – Mapping from mol atom index → IUPAC locant (from match_fused_heterocycle_core).

Returns:

Prefix string like “quinolin-2-yl” or None if core_smiles not recognized or attachment atom not mapped.

Return type:

str | None

orthonym.data.fused_heterocycles.get_substituted_fused_het_prefix(core_smiles, attachment_atom_idx, atom_mapping, inner_substituent_prefixes)#

Get compound prefix for a substituted fused heterocycle substituent.

When a fused heterocycle ring has its own substituents (e.g., 5-methyl on indole) AND the whole ring is a substituent on another parent, this produces the compound prefix form like “(5-methyl-1H-indol-3-yl)”.

Static O(1) dict lookup for the stem — no recursive naming calls.

Parameters:
  • core_smiles (str) – Canonical SMILES of the fused heterocycle core.

  • attachment_atom_idx (int) – Mol atom index where the ring attaches to parent.

  • atom_mapping (Dict[int, int | str]) – Mapping from mol atom index → IUPAC locant.

  • inner_substituent_prefixes (str) – Pre-formatted inner substituent string (e.g., “5-methyl-” or “5,6-dimethyl-“). Already includes locants and multiplicative prefixes. May or may not end with hyphen.

Returns:

Compound prefix in parentheses, e.g., “(5-methyl-1H-indol-3-yl)” or None if core_smiles not recognized.

Return type:

str | None

orthonym.data.fused_heterocycles.ring_skeleton_key(mol)#

Return the RDKit canonical SMILES of the molecule’s ring system (key).

Extracts the subgraph induced by ring atoms + ring bonds and canonicalises it — a path-independent identifier for the ring skeleton of a (possibly substituted) molecule. This is the substructure analogue of the whole-molecule canonical-SMILES key used by get_fused_heterocycle_name, and the key ‘s O(1) fast path looks up. Returns None for acyclic input.

orthonym.data.fused_heterocycles.get_fused_heterocycle_name(mol)#

Get retained name for an exact fused heterocycle match.

Checks if the molecule is an unsubstituted fused heterocycle with a retained name. For substituted molecules, use match_fused_heterocycle_core.

Parameters:

mol (Mol) – RDKit molecule object

Returns:

Tuple of (name, tautomer_locant) if found, None otherwise. tautomer_locant is the position of indicated hydrogen (e.g., 1 for 1H-indole), or None if no tautomeric hydrogen.

Return type:

Tuple[str, int | None] | None

Example

>>> mol = Chem.MolFromSmiles('c1ccc2[nH]ccc2c1') # indole
>>> get_fused_heterocycle_name(mol)
('1H-indole', 1)
>>> mol = Chem.MolFromSmiles('c1ccc2ncccc2c1') # quinoline
>>> get_fused_heterocycle_name(mol)
('quinoline', None)
orthonym.data.fused_heterocycles.match_fused_heterocycle_core(mol)#

Match a molecule against the cataloged fused ring-system cores.

Thin coverage-guarded wrapper over _match_fused_heterocycle_core_impl: a catalog match is accepted ONLY if it covers the whole fused ring system it touches — a base/retained ring system name must span the entire fused system, not a sub-part). Without this, a larger non-cataloged PAH whose skeleton contains a cataloged subset (pentacene contains naphthacene, picene contains chrysene) spuriously matched the smaller entry. 13B(a) S1.

: also verifies the input’s indicated hydrogen matches the matched

entry’s, correcting a clean single-locant tautomer swap (1H- -> 3H-) and rejecting an ambiguous mismatch — see _correct_indicated_h_tautomer.

orthonym.data.fused_heterocycles.core_numberings(mol, core_smiles, atom_mapping)#

Every established numbering of an already-matched catalog core, over the SAME molecule atoms: [(match, atom_mapping, core_name),...].

match_fused_heterocycle_core picks one automorphism by the substituent locant set and the alphanumerical tier (_select_lowest_locant_match); it cannot see which exocyclic group will be the principal characteristic group, so a caller that knows that (c), suffixes before prefixes) re-selects among these. Each core name is re-checked with _correct_indicated_h_tautomer for its numbering; a numbering it rejects is left out. Empty for an unknown core.

orthonym.data.fused_heterocycles.numbering_held_by_drawn_alternation(mol, core_smiles, atom_mapping)#

True iff the drawn Kekule alternation keeps a matched core’s substituted atoms from the lowest locants the core’s numbering gives them.

A catalog core written as a localized alternation (pentalene, heptalene, s-indacene: RDKit perceives no aromatic sextet over the whole system) matches only the numberings whose double bonds sit where the input draws them, so for one of the two bond-shift drawings the substituent gets a higher locant: ‘5-methylheptalene’ where the other drawing is ‘1-methylheptalene’. The two drawings are distinct compounds (rules.isotopes._kekule_forms_of_one_compound, a 4n circuit), which the Blue Book tells apart by a Delta descriptor:

“Localized double bonds” (the Blue Book), “If it is necessary

to identify isomers that differ only by virtue of the location of localized double bonds, this differentiation is indicated by the use of the Greek letter Delta” (:14597), ‘1,6-dimethyl-Delta1(10a)-heptalene (PIN)’ (:14601). A name that carries the higher locant and no Delta is then not the PIN of that drawing

(f),:3301, lowest locants to the detachable prefixes). Decided by

matching the core with its bonds made generic: the substituted core atoms’ locant set under the drawn match against the lowest one under any match of the skeleton. False for an aromatic core, a core with a saturated position, or when the drawn alternation excludes no numbering.

orthonym.data.fused_heterocycles.select_lowest_locant_match(mol, matches, core_smiles)#

Public entry to _select_lowest_locant_match for one catalog core.

orthonym.data.fused_heterocycles.get_fused_heterocycle_info(canonical_smiles)#

Get full information about a fused heterocycle from canonical SMILES.

Parameters:

canonical_smiles (str) – Canonical SMILES string

Returns:

Dict with name, tautomer_locant, ring_system, parent_atoms, iupac_locants or None if not found.

Return type:

Dict[str, Any] | None

orthonym.data.fused_heterocycles.is_fused_heterocycle(mol)#

Check if molecule is a known fused heterocycle (exact match only).

Parameters:

mol (Mol) – RDKit molecule object

Returns:

True if molecule is a known fused heterocycle

Return type:

bool

orthonym.data.fused_heterocycles.get_ring_system_type(mol)#

Get the ring system type classification for a fused heterocycle.

Parameters:

mol (Mol) – RDKit molecule object

Returns:

Ring system type string (e.g., ‘benzo-5-membered’, ‘tricyclic’), or None if not a known fused heterocycle

Return type:

str | None