MolecularDiffusion.runmodes.analyze.conformer_metrics

Paired generated-vs-reference conformer metrics.

This is the home for every metric that needs a pair of structures – a generated one and the reference it is supposed to correspond to – rather than a bare directory of samples. It replaces the old analyze compare command and the dead --check-strain flag, and adds the one genuinely missing metric: stereochemistry preservation.

Two input layouts are accepted, detected from the directory:

  1. SDF pairs (primary), as written by runmodes/generate/tasks_conformer.py:ConformerFactory:

    <input>/conformers.csv
    <input>/mol_0000/{conformers.sdf,reference.sdf,conformer_000.xyz,...}
    

    Both molecules of a pair come from the same graph3d item via build_rdkit_mol, so atom and bond ordering match by construction – which is what makes stereo descriptors comparable.

  2. xyz + optimized (legacy), what analyze compare consumed:

    <input>/*.xyz
    <input>/optimized_xyz/<stem>_opt.xyz
    

    Here the two molecules are perceived independently from coordinates, so the orderings are not guaranteed to agree and stereo columns are not emitted.

Layout 1 is never routed through xyz2mol/openbabel: re-perceiving bonds from coordinates destroys exactly the stereochemistry this group measures.

Attributes

Functions

compare_stereo(→ dict | None)

Score one generated molecule against its reference.

compute_conformer_metrics(→ tuple[pandas.DataFrame, dict])

Per-conformer metrics table plus the summary payload.

detect_layout(→ str)

"sdf_pairs" or "xyz_optimized"; raises for anything else.

get_stereochemistry_descriptor(→ tuple[str, str, str])

(rs, inverted_rs, ez) descriptor strings for one molecule.

prepare_mol_for_conformer_eval(→ Any)

Sanitized, Kekule-form copy with CIP tags assigned. None if bad.

stereo_scores(→ dict)

RS / EZ preservation scores over paired lists.

xtb_available(→ bool)

Explicit probe -- get_xtb_energy swallows a missing binary.

Module Contents

MolecularDiffusion.runmodes.analyze.conformer_metrics.compare_stereo(mol: Any, ref_mol: Any) dict | None

Score one generated molecule against its reference.

Returns None when either molecule cannot be prepared. rs_ok / ez_ok are None when the reference has nothing of that kind to preserve – that is “not applicable”, not “wrong”.

MolecularDiffusion.runmodes.analyze.conformer_metrics.compute_conformer_metrics(input_path: str | pathlib.Path, rmsd_threshold: float = 0.5, charge: int = 0, level: str = 'gfn2', timeout: int = 120) tuple[pandas.DataFrame, dict]

Per-conformer metrics table plus the summary payload.

MolecularDiffusion.runmodes.analyze.conformer_metrics.detect_layout(input_path: str | pathlib.Path) str

"sdf_pairs" or "xyz_optimized"; raises for anything else.

MolecularDiffusion.runmodes.analyze.conformer_metrics.get_stereochemistry_descriptor(mol: Any) tuple[str, str, str]

(rs, inverted_rs, ez) descriptor strings for one molecule.

MolecularDiffusion.runmodes.analyze.conformer_metrics.prepare_mol_for_conformer_eval(mol: Any, *, assign_from_3d: bool = True) Any

Sanitized, Kekule-form copy with CIP tags assigned. None if bad.

MolecularDiffusion.runmodes.analyze.conformer_metrics.stereo_scores(molecules: list, reference_molecules: list) dict

RS / EZ preservation scores over paired lists.

Scores are None when nothing in the reference set carried that kind of stereochemistry, so an empty denominator can never masquerade as 0.0.

MolecularDiffusion.runmodes.analyze.conformer_metrics.xtb_available() bool

Explicit probe – get_xtb_energy swallows a missing binary.

MolecularDiffusion.runmodes.analyze.conformer_metrics.HARTREE_TO_KCAL = 627.5094740631
MolecularDiffusion.runmodes.analyze.conformer_metrics.logger