orthonym.assembly.group_splitting#

Note

Internal API. Names and behaviour may change between releases.

a phase Plan-02: Group-splitting polyfunctional rescue (/02).

When a non-principal composite functional group (today only the empirically-firing ester / thioester — see data/group_split_rules) has no clean strict-IUPAC prefix and would otherwise be dropped at the polyfunctional.py:get_fg_prefix_form / substituent_no_prefix_form site (internal notes /F2), split_composite_fg decomposes it into its ordered sub-group prefix components instead of dropping it:

  • ester -C(=O)-O-R → oxo (the =O chalcogen) + R-oxy (the -O-R linker, e.g. ethoxy)

  • thioester -C(=O)-S-R → oxo + R-sulfanyl (e.g. ethylsulfanyl)

The carbonyl carbon stays in the chain and carries the locant; both components share it (internal notes worked example 4-(ethylsulfanyl)-4-oxobutanoic acid). The caller appends each component to all_prefixes so they re-enter the EXISTING format_fg_prefix + alpha_sort_key pipeline (native).

Single source of truth (internal notes): every component’s prefix STRING is resolved through the EXISTING authority — oxo via seniority.get_prefix, the alkoxy/sulfanyl forms via assembly.substituent_prefix_forms — NEVER hardcoded and NEVER a string-rewrite (no regex substitution, no string-replace call, no postprocessor pass; internal notes). The decomposition acts at the FG-prefix-resolution layer and returns structured components.

RT safety (internal notes, FAIL-CLOSED): when an OpsinOracle is supplied (flag-ON only), the FULL assembled split name is OPSIN-round-trip-checked; a split that does not round-trip (incl. the FAIL-CLOSED oracle._jar is None case) is rejected and the caller behaves exactly as today’s substituent_no_prefix_form continue — never emits a worse name (favorable asymmetry: the status-quo dropped-FG name already fails RT, so a rejected split only preserves it).

Source: 169-internal notes.., F2; internal notes “Architecture Patterns” + “Code Examples”; internal notes “group_splitting.py”.

orthonym.assembly.group_splitting.split_composite_fg(fg_name, mol, atoms, principal_chain, oracle=None)#

Decompose a table-listed composite loser into ordered sub-group prefix components.

Returns None (the caller then behaves exactly as today’s substituent_no_prefix_form continue) when:

  • fg_name is not in the split table (deny-path — functional-class FGs stay dropped, internal notes), OR

  • the structural decomposition cannot resolve a clean component string, OR

  • the per-split OPSIN-RT gate rejects the assembled split name (FAIL-CLOSED, internal notes — never a worse name).

Otherwise returns the ordered [SplitComponent,...] list (e.g. [oxo, ethoxy]) the caller appends to all_prefixes (native).

class orthonym.assembly.group_splitting.SplitComponent(role, prefix_form, locants=None, count=1)#

Bases: object

One resolved sub-group prefix of a split composite (TOPOLOGY → STRING).

prefix_form is the RESOLVED string from the existing authority (seniority.get_prefix / substituent_prefix_forms), never from the JSON table. locants=None means “use the caller’s central-carbon locants” so both components share the carbonyl-carbon locant.

role: str#
prefix_form: str#
locants: List[int] | None = None#
count: int = 1#
class orthonym.assembly.group_splitting.SplitEvent(kind, fg_name, encoding=None, rt_oracle_result=None, p_section_cite=None)#

Bases: object

a phase diagnostic event (the reach-report data source).

kind: str#
fg_name: str#
encoding: str | None = None#
rt_oracle_result: bool | None = None#
p_section_cite: str | None = None#