Grouper.exports module
3D conformer generation and chemical-file-format export for GroupGraphs.
The functions here turn a GroupGraph (or a SMILES string) into the file formats that downstream tools — molecular dynamics packages (GROMACS, LAMMPS, OpenMM), docking programs (AutoDock Vina, Glide), and visualizers (PyMOL, VMD) — actually consume:
SDF multi-molecule with optional 3D coords + arbitrary properties MOL single-molecule V2000 mol block, like SDF without the $$$$ XYZ bare element + 3D coords; used by quantum chemistry codes PDB Protein Data Bank format; used by visualizers and docking
3D coordinates are generated via RDKit’s ETKDG distance-geometry embedding followed by force-field minimization. We default to MMFF94 (more accurate where parameters exist) and fall back to UFF (covers all atom types in Joback’s element scope) if MMFF fails.
Methods on GroupGraph (added via monkey-patch in Grouper/__init__.py):
gG.to_3d(seed=42, force_field=”mmff94”) -> rdkit.Chem.Mol gG.to_sdf(path=None, embed_3d=True) -> str | None gG.to_mol(path=None, embed_3d=True) -> str | None gG.to_xyz(path=None) -> str | None (always 3D) gG.to_pdb(path=None) -> str | None (always 3D)
The same to_sdf function also handles a whole library — pass any iterable of graphs/SMILES instead of a single target:
from Grouper.exports import to_sdf to_sdf(results, path=”library.sdf”) # multi-mol SDF to_sdf([“CCO”, “CC”], path=”out.sdf”) # raw SMILES list
- exception Grouper.exports.EmbedError
Bases:
GrouperErrorRaised when 3D coordinate generation fails for a molecule.
Common causes: highly strained ring systems where ETKDG can’t find a feasible geometry, or molecules with element/valence combinations RDKit’s force fields don’t parameterize. The message includes the SMILES so the caller can reproduce.
- exception Grouper.exports.GrouperError
Bases:
ExceptionBase class for errors raised by Grouper. Catch this to distinguish failures originating in Grouper from those bubbling up from dependencies (RDKit, NumPy, etc.).
Future Grouper-raised exceptions should inherit from this so a single
except GrouperErrorhandler covers them all.
- Grouper.exports.to_3d_mol(target, seed=42, force_field='mmff94', max_iters=200)
Embed and minimize 3D coordinates for target. Returns an RDKit Mol with explicit hydrogens and one conformer.
- Return type:
Mol
- force_field:
- “mmff94” — Merck molecular force field (default; more
accurate where parameters exist).
- “uff” — Universal Force Field (covers everything but
less accurate for typical organics).
“none” — embed only, skip minimization.
Falls back to UFF automatically if MMFF94 fails (e.g., the molecule has an atom type MMFF doesn’t parameterize) — typical organics in Joback’s element scope are well-covered by either.
Raises EmbedError if ETKDG distance-geometry can’t find a feasible geometry. Common with strained polycyclics or unusual bond patterns; the SMILES is included in the message.
- Grouper.exports.to_inchi(target)
Return the IUPAC InChI string. InChI is a layered, deterministic identifier that’s standard across cheminformatics databases — two drawings of the same molecule produce the same InChI even when their canonical SMILES differ across implementations.
Used to look molecules up in PubChem, ChEMBL, NIST WebBook, etc. For shorter primary-key use, prefer to_inchi_key.
- Return type:
- Grouper.exports.to_inchi_key(target)
Return the 27-character InChIKey hash of the InChI. This is the primary-key form most chemistry databases use — fixed length, URL-safe, and deterministic across implementations.
Format: XXXXXXXXXXXXXX-YYYYYYYYYY-Z where the dashes separate the structural-skeleton hash, the stereochemistry/isotope hash, and a final disambiguation block.
- Return type:
- Grouper.exports.to_mol(target, path=None, embed_3d=True, **embed_kwargs)
Render the molecule as a V2000 MOL block (single-molecule). For multi-molecule output use to_sdf with an iterable target.
- Grouper.exports.to_pdb(target, path=None, **embed_kwargs)
Render the molecule as PDB. Always 3D. Used by structural biology / visualizer tools (PyMOL, VMD, ChimeraX) and many docking programs.
- Grouper.exports.to_sdf(target, path=None, embed_3d=True, name=None, properties=None, skip_failures=False, **embed_kwargs)
Render one molecule or a library as SDF — single function for both cases, since SDF natively supports one-or-many molecules per file.
- target may be:
a single GroupGraph or SMILES string, or
any iterable of those (e.g. a GroupGraphSet, a list of SMILES, a generator).
- path:
None (default) — return the SDF text as a string.
a filesystem path — write to disk; return the number of molecules successfully written.
- properties:
None — no extra property tags.
dict — apply the same key→value pairs to every molecule.
callable(target) -> dict — invoked per molecule; useful for attaching per-molecule predictions, e.g.:
to_sdf( results, "library.sdf", properties=lambda g: dict(JobackEstimate.from_group_graph(g)), )
name is set as the SDF _Name field for the single-target case. For iterables, names default to
mol_<index>and name is ignored.skip_failures=True continues past molecules that fail to embed (e.g., strained rings ETKDG can’t solve) or parse, emitting a warning for each. Default is to stop and re-raise.
embed_3d=True (default) runs ETKDG + MMFF94 for 3D coords. Set False for a 2D-only SDF.
- Grouper.exports.to_smarts(target)
Return the SMARTS pattern for the molecule, as produced by RDKit’s
Chem.MolToSmarts. Useful when a generated structure becomes a query pattern for substructure searching elsewhere in a pipeline.Note: a molecule has infinitely many valid SMARTS renderings; this returns RDKit’s canonical form, which may differ from the output of other toolkits (OpenEye, Daylight, etc.). For exact string equality across tools, normalize through a shared canonicalizer.
- Return type: