Skill Tracer
Skills › Scientific Agent Skills › datamol › conformers_module.md

conformers_module.md

84 lines · skills/datamol/references/conformers_module.md at 5f2bc03

Open on GitHub
1# Datamol conformers (0.13.0)
2
3Checked against [the conformer API](https://docs.datamol.io/stable/api/datamol.conformers.html)
4and released source. Coordinates are in angstrom; SASA is in square angstrom.
5

Datamol conformers (0.13.0)

Checked against the conformer API and released source. Coordinates are in angstrom; SASA is in square angstrom.

Raw lines 1 to 5
6## Generate and validate
7
8`dm.conformers.generate` defaults to `minimize_energy=False`, `forcefield="UFF"`,
9`method=None` (selects ETKDGv3), `random_seed=19`, `num_threads=1`, and `add_hs=True`.
10Hydrogens are added for embedding and removed from the returned molecule. Do not assume
11explicit hydrogens survive. With `n_confs=None`, the requested count depends on rotatable
12bonds. Requested counts are upper targets, not guaranteed surviving counts.
14```python
15import datamol as dm
16import numpy as np
17mol = dm.to_mol("CC(C)CCO") # 3-methylbutan-1-ol
18mol.SetProp("source_id", "compound-001")
19mol_3d = dm.conformers.generate(
20 mol, n_confs=10, rms_cutoff=0.5, minimize_energy=True,
21 method="ETKDGv3", forcefield="UFF", random_seed=19, num_threads=1,
23assert mol_3d is not None and mol_3d.GetNumConformers() > 0
24coords = dm.conformers.get_coords(mol_3d)
25assert coords.shape == (mol_3d.GetNumAtoms(), 3) and np.isfinite(coords).all()
26energies = [c.GetDoubleProp("rdkit_UFF_energy") for c in mol_3d.GetConformers()]
27assert np.isfinite(energies).all()
28```
30Other embedding methods are ETDG, ETKDG and ETKDGv2. Available forcefield choices are
31UFF, MMFF94s and MMFF94s_noEstat. Check parameter coverage and convergence; finite energies
32are not proof of converged minima, equilibrium populations, or bioactive conformations.
33Set `verbose=True, warning_not_converged=1` when minimization diagnostics matter.
34Embedding failure raises unless `ignore_failure=True`, which can return `None`.
360.13 uses optimal symmetry-aware alignment for RMS pruning. `rms_cutoff` is applied after
37minimization when enabled; larger thresholds generally keep fewer representatives. A seed
38supports reproducibility within a pinned environment, not identical output across RDKit releases.

Generate and validate

dm.conformers.generate defaults to minimize_energy=False, forcefield="UFF", method=None (selects ETKDGv3), random_seed=19, num_threads=1, and add_hs=True. Hydrogens are added for embedding and removed from the returned molecule. Do not assume explicit hydrogens survive. With n_confs=None, the requested count depends on rotatable bonds. Requested counts are upper targets, not guaranteed surviving counts.

import datamol as dm
import numpy as np
mol = dm.to_mol("CC(C)CCO")  # 3-methylbutan-1-ol
mol.SetProp("source_id", "compound-001")
mol_3d = dm.conformers.generate(
    mol, n_confs=10, rms_cutoff=0.5, minimize_energy=True,
    method="ETKDGv3", forcefield="UFF", random_seed=19, num_threads=1,
)
assert mol_3d is not None and mol_3d.GetNumConformers() > 0
coords = dm.conformers.get_coords(mol_3d)
assert coords.shape == (mol_3d.GetNumAtoms(), 3) and np.isfinite(coords).all()
energies = [c.GetDoubleProp("rdkit_UFF_energy") for c in mol_3d.GetConformers()]
assert np.isfinite(energies).all()

Other embedding methods are ETDG, ETKDG and ETKDGv2. Available forcefield choices are UFF, MMFF94s and MMFF94s_noEstat. Check parameter coverage and convergence; finite energies are not proof of converged minima, equilibrium populations, or bioactive conformations. Set verbose=True, warning_not_converged=1 when minimization diagnostics matter. Embedding failure raises unless ignore_failure=True, which can return None.

0.13 uses optimal symmetry-aware alignment for RMS pruning. rms_cutoff is applied after minimization when enabled; larger thresholds generally keep fewer representatives. A seed supports reproducibility within a pinned environment, not identical output across RDKit releases.

Raw lines 6 to 39
40## Cluster output is molecular
42```python
43for conformer in mol_3d.GetConformers():
44 conformer.SetIntProp("source_conformer_id", conformer.GetId())
45cluster_molecules = dm.conformers.cluster(mol_3d, rms_cutoff=1.0, centroids=False)
46centroid_molecule = dm.conformers.cluster(mol_3d, rms_cutoff=1.0, centroids=True)
47assert sum(m.GetNumConformers() for m in cluster_molecules) == mol_3d.GetNumConformers()
48assert centroid_molecule.GetNumConformers() == len(cluster_molecules)
49assert centroid_molecule.GetProp("source_id") == "compound-001"
50selected_source_ids = [c.GetIntProp("source_conformer_id") for c in centroid_molecule.GetConformers()]
51```
53Clustering assigns new conformer IDs. Keep a per-conformer source-ID property as above
54when linking selected conformers to energies or upstream metadata.
56`centroids=True` is the default: one Mol containing representative conformers. False
57returns a list of Mol, one per cluster, containing every cluster member. It does **not**
58return index tuples. `dm.conformers.return_centroids(mol, conf_clusters)` is a lower-level
59helper for precomputed integer index groups, not the output of `cluster`; its default path
60mutates the supplied molecule. Prefer `cluster`, which copies the input.
61`already_aligned=True` uses distances in the existing common frame instead of optimal
62pairwise alignment. `dm.conformers.rmsd(mol, num_threads=1)` returns a square RMSD array.

Cluster output is molecular

for conformer in mol_3d.GetConformers():
    conformer.SetIntProp("source_conformer_id", conformer.GetId())
cluster_molecules = dm.conformers.cluster(mol_3d, rms_cutoff=1.0, centroids=False)
centroid_molecule = dm.conformers.cluster(mol_3d, rms_cutoff=1.0, centroids=True)
assert sum(m.GetNumConformers() for m in cluster_molecules) == mol_3d.GetNumConformers()
assert centroid_molecule.GetNumConformers() == len(cluster_molecules)
assert centroid_molecule.GetProp("source_id") == "compound-001"
selected_source_ids = [c.GetIntProp("source_conformer_id") for c in centroid_molecule.GetConformers()]

Clustering assigns new conformer IDs. Keep a per-conformer source-ID property as above when linking selected conformers to energies or upstream metadata.

centroids=True is the default: one Mol containing representative conformers. False returns a list of Mol, one per cluster, containing every cluster member. It does not return index tuples. dm.conformers.return_centroids(mol, conf_clusters) is a lower-level helper for precomputed integer index groups, not the output of cluster; its default path mutates the supplied molecule. Prefer cluster, which copies the input. already_aligned=True uses distances in the existing common frame instead of optimal pairwise alignment. dm.conformers.rmsd(mol, num_threads=1) returns a square RMSD array.

Raw lines 40 to 63
64## SASA and coordinates
66```python
67# Serial execution also stores properties on the original conformers.
68sasa_values = dm.conformers.sasa(mol_3d, n_jobs=1)
69assert len(sasa_values) == mol_3d.GetNumConformers()
70assert np.isfinite(sasa_values).all()
71assert mol_3d.GetConformer(0).HasProp("rdkit_free_sasa")
72center = dm.conformers.center_of_mass(mol_3d, use_atoms=True, digits=4)
73moved = dm.copy_mol(mol_3d)
74dm.conformers.translate(moved, new_centroid=np.zeros(3), conf_id=0)
75```
77SASA uses RDKit FreeSASA with van der Waals radii. Datamol disables it on Windows.
78Supply existing conformer IDs when using `conf_id`; generated conformers have contiguous
79IDs, but arbitrary imported IDs need explicit handling. Parallel workers can return values
80without propagating per-conformer property mutation back to the parent; use returned values.
81`get_coords(mol, conf_id=-1)` returns an atom-by-3 array; `-1` selects the default conformer.
82`center_of_mass(..., use_atoms=False)` computes the geometric center of represented atoms;
83`digits` controls rounding. `translate(mol, new_centroid, conf_id=-1)` moves the conformer
84in place to the new RDKit centroid; it does not accept a transformation matrix.

SASA and coordinates

# Serial execution also stores properties on the original conformers.
sasa_values = dm.conformers.sasa(mol_3d, n_jobs=1)
assert len(sasa_values) == mol_3d.GetNumConformers()
assert np.isfinite(sasa_values).all()
assert mol_3d.GetConformer(0).HasProp("rdkit_free_sasa")
center = dm.conformers.center_of_mass(mol_3d, use_atoms=True, digits=4)
moved = dm.copy_mol(mol_3d)
dm.conformers.translate(moved, new_centroid=np.zeros(3), conf_id=0)

SASA uses RDKit FreeSASA with van der Waals radii. Datamol disables it on Windows. Supply existing conformer IDs when using conf_id; generated conformers have contiguous IDs, but arbitrary imported IDs need explicit handling. Parallel workers can return values without propagating per-conformer property mutation back to the parent; use returned values. get_coords(mol, conf_id=-1) returns an atom-by-3 array; -1 selects the default conformer. center_of_mass(..., use_atoms=False) computes the geometric center of represented atoms; digits controls rounding. translate(mol, new_centroid, conf_id=-1) moves the conformer in place to the new RDKit centroid; it does not accept a transformation matrix.

Raw lines 64 to 84