orthonym.validation.atom_coverage#

Note

Internal API. Names and behaviour may change between releases.

Atom coverage validator for Orthonym.

Validates how completely a generated IUPAC name describes the input molecule by parsing the name back to a structure (OPSIN) and comparing that structure to the input.

residue, Task X – this module used to compare heavy-atom COUNTS, which

made it unsound in three separate ways, all measured:

  • ratio = min(parsed_heavy / total_heavy, 1.0) clamped away atom GAIN, so a name that INVENTS atoms could never score below 1.0 (CNCC(=O)N -> 2-amino-2-(methylamino)acetamide scored 1.000);

  • is_complete = ratio >= 0.80 passed a genuine atom DROP (CS(=O)(=O)NC -> methanesulfonamide scored 0.833 -> complete);

  • a count cannot distinguish the same atoms from the same number of atoms. CNCC(=O)O (sarcosine) named 2-aminopropanoic acid (alanine) matches on heavy count AND on molecular formula AND on the heavy-atom element multiset, and is a different molecule.

is_complete is therefore decided by CONSTITUTION – the InChIKey skeleton block of the input compared with that of the parse-back – and never by a threshold on a count. The counts survive only as diagnostics, and atom gain is reported explicitly as extra_atoms.

DECLARED SCOPE. The skeleton block fixes the molecular formula, the connectivity and the hydrogen layer. It does NOT fix stereochemistry, isotopes or net charge, which live in the second InChIKey block; a stereo-blind name still covers every atom and is reported complete here. Both full InChIKeys are exposed on the result so a caller needing the stricter comparison can make it without re-parsing. This module answers “are these the same atoms, bonded the same way” and nothing more.

This is a diagnostic tool – it reports coverage but never blocks naming output. The load-bearing in-process no-silent-atom-drop gate is the E1 atom->token partition certificate in validation/e1_certificate.py; E1 needs a GeneralEngineResult and so cannot serve callers that hold only (mol, name), which is what this module is for.

Two validation approaches:
  1. Parse-back (OPSIN): parse name via OPSIN JAR, compare constitution.

  2. Fallback: if OPSIN unavailable or parse fails, return ‘unavailable’ (ratio 0.0, incomplete) – fail-closed by design.

class orthonym.validation.atom_coverage.CoverageResult(total_heavy_atoms, claimed_atoms, unclaimed_atoms, coverage_ratio, is_complete, method, claimed_atom_indices=<factory>, unclaimed_atom_indices=<factory>, extra_atoms=0, parsed_heavy_atoms=0, constitution_match=False, input_inchikey='', parsed_inchikey='', parsed_smiles='')#

Bases: object

Result of atom coverage validation.

Variables:
  • total_heavy_atoms (int) – Heavy atom count of the input molecule.

  • claimed_atoms (int) – Input heavy atoms with a counterpart in the parse-back, counted as the size of the element-multiset intersection.

  • unclaimed_atoms (int) – Input heavy atoms with NO counterpart (atoms the name dropped) = total_heavy_atoms - claimed_atoms.

  • coverage_ratio (float) – claimed / total (0.0 to 1.0). Diagnostic only – it is NOT what decides is_complete, and by construction it cannot see atom gain (see extra_atoms) or a rearrangement (see constitution_match).

  • is_complete (bool) – True only when the parse-back has the SAME CONSTITUTION as the input, i.e. constitution_match. Never a threshold on a count.

  • method (str) – ‘parse_back’, ‘trivial’, ‘parse_back_no_inchi’, or ‘unavailable’.

  • claimed_atom_indices (Set[int]) – Indices of atoms accounted for. Empty on the parse-back path, which compares whole structures rather than mapping atom to atom.

  • unclaimed_atom_indices (Set[int]) – Indices of atoms NOT accounted for. Empty on the parse-back path, as above.

  • extra_atoms (int) – Heavy atoms present in the parse-back that the INPUT does not have – atoms the name invented. Zero for a faithful name.

  • parsed_heavy_atoms (int) – Raw heavy-atom count of the parse-back, unclamped, so a caller can recover the true count ratio (which may exceed 1).

  • constitution_match (bool) – InChIKey skeleton block of input == that of the parse-back. Fixes formula, connectivity and H layer; does not fix stereo, isotopes or charge (module docstring, DECLARED SCOPE).

  • input_inchikey (str) – Full InChIKey of the input molecule (’’ if unavailable).

  • parsed_inchikey (str) – Full InChIKey of the parse-back (’’ if unavailable).

  • parsed_smiles (str) – OPSIN’s SMILES of the parse-back (’’ if unavailable).

total_heavy_atoms: int#
claimed_atoms: int#
unclaimed_atoms: int#
coverage_ratio: float#
is_complete: bool#
method: str#
claimed_atom_indices: Set[int]#
unclaimed_atom_indices: Set[int]#
extra_atoms: int = 0#
parsed_heavy_atoms: int = 0#
constitution_match: bool = False#
input_inchikey: str = ''#
parsed_inchikey: str = ''#
parsed_smiles: str = ''#
orthonym.validation.atom_coverage.find_opsin_jar()#

Path to the pinned OPSIN jar (orthonym.jars).

Raises orthonym.jars.JarUnavailable when it is missing; None in opt-in reduced mode.

orthonym.validation.atom_coverage.validate_atom_coverage(mol, name, opsin_jar=None)#

Validate how completely name describes mol.

Parses name back to a molecule via OPSIN and compares that molecule to mol by CONSTITUTION (InChIKey skeleton block). Heavy-atom counts are reported as diagnostics – dropped atoms as unclaimed_atoms, invented atoms as extra_atoms – but never decide is_complete, because a count cannot distinguish the same atoms from the same number of atoms.

Parameters:
  • mol – RDKit Mol object for the input molecule.

  • name (str) – Generated IUPAC name to validate.

  • opsin_jar (str | None) – Path to OPSIN JAR. If None, attempts auto-discovery. If OPSIN is unavailable, returns a result with method=’unavailable’.

Returns:

A:class:CoverageResult with coverage metrics.

Return type:

CoverageResult