Interoperability#

Geometry stays deliberately minimal — symbols, coordinates, charge, and spin — so that conversions to other libraries’ representations live outside the core model. automol.geom provides the Geometry-facing conversions; automol.rd.mol provides the lower-level RDKit building blocks they’re built from.

RDKit#

from automol import geom

mol = geom.rdkit_mol(water)         # Geometry -> rdkit.Chem.Mol
water_rt = geom.from_rdkit_mol(mol)  # rdkit.Chem.Mol -> Geometry

from_rdkit_mol works whether or not the Mol already has 3D coordinates — if it doesn’t, coordinates are embedded automatically before extraction.

For lower-level RDKit work that doesn’t go through Geometry at all, automol.rd.mol operates directly on rdkit.Chem.Mol objects:

from automol.rd import mol

water_mol = mol.from_smiles("O", with_coords=True)
mol.smiles(water_mol)         # canonical SMILES
mol.inchi(water_mol)          # InChI
mol.symbols(water_mol)        # ["O", "H", "H"]
mol.coordinates(water_mol)    # (N, 3) array; raises GeometryConversionError
                               # if the Mol has no coordinates

Other utilities in this module include add_atom_numbers (for RDKit atom labels), canonical_ranks (RDKit’s canonical atom ranking), and assign_stereochemistry/chiral_centers (stereochemistry from 3D coordinates).

ASE#

atoms = geom.to_ase(water)  # Geometry -> ase.Atoms

charge and spin are carried over in atoms.info. There is currently no from_ase; go through xyz or RDKit if you need the reverse direction.

StereoMolGraph#

smg = geom.stereo_mol_graph(water)  # Geometry -> stereomolgraph.StereoMolGraph

This is what rdkit_mol uses internally to infer connectivity and stereochemistry from coordinates before building the RDKit Mol.

Adding a new conversion#

automol enforces a module layering (view > ident > geom > rd > utils; see the import-linter contract in pyproject.toml) where each module may only depend on modules below it. geom/core.py depends on rd (not the reverse) precisely because rd sits below geom in that layering, which is why the RDKit conversions (rdkit_mol/from_rdkit_mol) live in geom/core.py while the lower-level, Geometry-agnostic RDKit utilities they’re built from live in rd/mol.py.

If you’re adding support for another third-party library, follow that same split: put library-specific, Mol/Atoms/etc.-facing utilities in their own module beneath geom in the layering, and put the Geometry-facing conversion functions in geom itself (as rdkit_mol/from_rdkit_mol and to_ase already do) — rather than adding a new top-level dependency to the Geometry model itself.