orthonym.validation.e1_certificate#
Note
Internal API. Names and behaviour may change between releases.
: E1 atom-coverage certificate.
Verifies a GeneralEngineResult’s atom->token partition: every heavy atom of the molecule is bound by EXACTLY ONE token, every token occurs in the emitted name, and (G1 scope) the molecule is neutral. Pure Python + RDKit – no Java, no OPSIN. This is the load-bearing “no silent atom drop” gate the legacy count-based validation/atom_coverage.py never was; that legacy module is untouched and unrelated.
- class orthonym.validation.e1_certificate.E1Verdict(ok: 'bool', reason: 'str')#
Bases:
object- ok: bool#
- reason: str#
- orthonym.validation.e1_certificate.verify_atom_coverage(mol, name, atom_id_groups, allow_charged=True)#
Producer-side atom-COVERAGE close (the task-W2 reusable template).
A thin wrapper over:func:_verify_partition for the recurring producer situation the W2 jar-absent-proper fix addresses: “here are the atom groups my emitted ``name`` accounts for — confirm together they cover EVERY heavy atom of ``mol``, else I must decline (fail-closed) rather than ship a name that silently dropped atoms.”
This is the OPSIN-free, jar-independent guard that catches an atom-drop at CONSTRUCTION (defense-in-depth: jar-present would also catch it, but only after a JVM round-trip; jar-absent nothing else does). It reuses the E1 partition primitive rather than duplicating a coverage check (a project rule: extend, don’t duplicate) and is deliberately scoped to the COVERAGE axis:
Groups are DEDUPLICATED before binding, so a benign double-listing of an atom never trips the partition’s
bound twicerefusal (a false void that would cost breadth — the fix must void ONLY genuine drops).Each group is bound under the EMPTY token, so the token-in-name and element_soundness chemistry checks are SKIPPED here. Those two checks presuppose a
GeneralEngineResult-style(token, atom_ids)stream whose token strings are reconstructable; a legacy composer producer building the partition from atom-index data alone cannot supply faithful token strings (locants/elision/enclosing-marks are added around morphemes at assembly time), and a mismatched token would false-void a CORRECT name. Coverage is the only axis this template owns.allow_chargeddefaults True: this template checks atom coverage, not the G1 charge scope, so a legitimately-charged parent is never voided for a reason unrelated to an atom drop.
- Parameters:
indices (* atom_id_groups -- iterable of iterables of heavy-atom) – name-piece the producer emitted (ring atoms, each named substituent’s atoms, suffix atoms,…). Their UNION is the accounted set.
per (one) – name-piece the producer emitted (ring atoms, each named substituent’s atoms, suffix atoms,…). Their UNION is the accounted set.
Returns an:class:E1Verdict;
.okis False (with anunbound heavy atomsreason) when any heavy atom is left unaccounted. Callers decline (returnNone/ abstain) on a non-ok verdict.
- orthonym.validation.e1_certificate.verify_certificate(mol, result, allow_charged=False)#
Atom-partition certificate for a GeneralEngineResult.
:
allow_charged(set only undercomplete) lifts the net-formal-charge refusal – the charge is expressed as a-ylium/-ide/-uide/-iumsuffix on an already-bound skeletal atom, so it introduces NO new atom and the partition is still complete. Default False -> byte-identical (the G1 neutral-scope guard still fires).Thin object-shape wrapper over
_verify_partition: unpacks eachresult.bindingselement’s.token/.atom_idsinto a(token, atom_ids)2-tuple. Byte-identical logic to the historical body.