| name | rdkit |
| description | Cheminformatics toolkit for fine-grained molecular control. SMILES/SDF parsing, descriptors (MW, LogP, TPSA), fingerprints, substructure search, 2D/3D generation, similarity, reactions. For standard workflows with simpler interface, use datamol (wrapper around RDKit). Use rdkit for advanced control, custom sanitization, specialized algorithms. |
RDKit Cheminformatics Toolkit
Overview
RDKit is a comprehensive cheminformatics library providing Python APIs for molecular analysis and manipulation. This skill provides guidance for reading/writing molecular structures, calculating descriptors, fingerprinting, substructure searching, chemical reactions, 2D/3D coordinate generation, and molecular visualization. Use this skill for drug discovery, computational chemistry, and cheminformatics research tasks.
Core Capabilities
1. Molecular I/O and Creation
Reading Molecules:
Read molecular structures from various formats:
from rdkit import Chem
mol = Chem.MolFromSmiles('Cc1ccccc1')
mol = Chem.MolFromMolFile('path/to/file.mol')
mol = Chem.MolFromMolBlock(mol_block_string)
mol = Chem.MolFromInchi('InChI=1S/C6H6/c1-2-4-6-5-3-1/h1-6H')
Writing Molecules:
Convert molecules to text representations:
smiles = Chem.MolToSmiles(mol)
mol_block = Chem.MolToMolBlock(mol)
inchi = Chem.MolToInchi(mol)
Batch Processing:
For processing multiple molecules, use Supplier/Writer objects:
suppl = Chem.SDMolSupplier('molecules.sdf')
for mol in suppl:
if mol is not None:
pass
suppl = Chem.SmilesMolSupplier('molecules.smi', titleLine=False)
with gzip.open('molecules.sdf.gz') as f:
suppl = Chem.ForwardSDMolSupplier(f)
for mol in suppl:
pass
suppl = Chem.MultithreadedSDMolSupplier('molecules.sdf')
writer = Chem.SDWriter('output.sdf')
for mol in molecules:
writer.write(mol)
writer.close()
Important Notes:
- All
MolFrom* functions return None on failure with error messages
- Always check for
None before processing molecules
- Molecules are automatically sanitized on import (validates valence, perceives aromaticity)
2. Molecular Sanitization and Validation
RDKit automatically sanitizes molecules during parsing, executing 13 steps including valence checking, aromaticity perception, and chirality assignment.
Sanitization Control:
mol = Chem.MolFromSmiles('C1=CC=CC=C1', sanitize=False)
Chem.SanitizeMol(mol)
problems = Chem.DetectChemistryProblems(mol)
for problem in problems:
print(problem.GetType(), problem.Message())
from rdkit.Chem import rdMolStandardize
Chem.SanitizeMol(mol, sanitizeOps=Chem.SANITIZE_ALL ^ Chem.SANITIZE_PROPERTIES)
Common Sanitization Issues:
- Atoms with explicit valence exceeding maximum allowed will raise exceptions
- Invalid aromatic rings will cause kekulization errors
- Radical electrons may not be properly assigned without explicit specification
3. Molecular Analysis and Properties
Accessing Molecular Structure:
for atom in mol.GetAtoms():
print(atom.GetSymbol(), atom.GetIdx(), atom.GetDegree())
for bond in mol.GetBonds():
print(bond.GetBeginAtomIdx(), bond.GetEndAtomIdx(), bond.GetBondType())
ring_info = mol.GetRingInfo()
ring_info.NumRings()
ring_info.AtomRings()
atom = mol.GetAtomWithIdx(0)
atom.IsInRing()
atom.IsInRingSize(6)
from rdkit.Chem import GetSymmSSSR
rings = GetSymmSSSR(mol)
Stereochemistry:
from rdkit.Chem import FindMolChiralCenters
chiral_centers = FindMolChiralCenters(mol, includeUnassigned=True)
from rdkit.Chem import AssignStereochemistryFrom3D
AssignStereochemistryFrom3D(mol)
bond = mol.GetBondWithIdx(0)
stereo = bond.GetStereo()
Fragment Analysis:
frags = Chem.GetMolFrags(mol, asMols=True)
from rdkit.Chem import FragmentOnBonds
frag_mol = FragmentOnBonds(mol, [bond_idx1, bond_idx2])
from rdkit.Chem.Scaffolds import MurckoScaffold
scaffold = MurckoScaffold.GetScaffoldForMol(mol)
4. Molecular Descriptors and Properties
Basic Descriptors:
from rdkit.Chem import Descriptors
mw = Descriptors.MolWt(mol)
exact_mw = Descriptors.ExactMolWt(mol)
logp = Descriptors.MolLogP(mol)
tpsa = Descriptors.TPSA(mol)
hbd = Descriptors.NumHDonors(mol)
hba = Descriptors.NumHAcceptors(mol)
rot_bonds = Descriptors.NumRotatableBonds(mol)
aromatic_rings = Descriptors.NumAromaticRings(mol)
Batch Descriptor Calculation:
all_descriptors = Descriptors.CalcMolDescriptors(mol)
descriptor_names = [desc[0] for desc in Descriptors._descList]
Lipinski's Rule of Five:
mw = Descriptors.MolWt(mol) <= 500
logp = Descriptors.MolLogP(mol) <= 5
hbd = Descriptors.NumHDonors(mol) <= 5
hba = Descriptors.NumHAcceptors(mol) <= 10
is_drug_like = mw and logp and hbd and hba
5. Fingerprints and Molecular Similarity
Fingerprint Types:
from rdkit.Chem import AllChem, RDKFingerprint
from rdkit.Chem.AtomPairs import Pairs, Torsions
from rdkit.Chem import MACCSkeys
fp = Chem.RDKFingerprint(mol)
fp = AllChem.GetMorganFingerprint(mol, radius=2)
fp_bits = AllChem.GetMorganFingerprintAsBitVect(mol, radius=2, nBits=2048)
fp = MACCSkeys.GenMACCSKeys(mol)
fp = Pairs.GetAtomPairFingerprint(mol)
fp = Torsions.GetTopologicalTorsionFingerprint(mol)
from rdkit.Avalon import pyAvalonTools
fp = pyAvalonTools.GetAvalonFP(mol)
Similarity Calculation:
from rdkit import DataStructs
fp1 = AllChem.GetMorganFingerprintAsBitVect(mol1, radius=2)
fp2 = AllChem.GetMorganFingerprintAsBitVect(mol2, radius=2)
similarity = DataStructs.TanimotoSimilarity(fp1, fp2)
similarities = DataStructs.BulkTanimotoSimilarity(fp1, [fp2, fp3, fp4])
dice = DataStructs.DiceSimilarity(fp1, fp2)
cosine = DataStructs.CosineSimilarity(fp1, fp2)
Clustering and Diversity:
from rdkit.ML.Cluster import Butina
dists = []
fps = [AllChem.GetMorganFingerprintAsBitVect(mol, 2) for mol in mols]
for i in range(len(fps)):
sims = DataStructs.BulkTanimotoSimilarity(fps[i], fps[:i])
dists.extend([1-sim for sim in sims])
clusters = Butina.ClusterData(dists, len(fps), distThresh=0.3, isDistData=True)
6. Substructure Searching and SMARTS
Basic Substructure Matching:
query = Chem.MolFromSmarts('[#6]1:[#6]:[#6]:[#6]:[#6]:[#6]:1')
has_match = mol.HasSubstructMatch(query)
matches = mol.GetSubstructMatches(query)
match = mol.GetSubstructMatch(query)
Common SMARTS Patterns:
primary_alcohol = Chem.MolFromSmarts('[CH2][OH1]')
carboxylic_acid = Chem.MolFromSmarts('C(=O)[OH]')
amide = Chem.MolFromSmarts('C(=O)N')
aromatic_n = Chem.MolFromSmarts('[nR]')
macrocycle = Chem.MolFromSmarts('[r{12-}]')
Matching Rules:
- Unspecified properties in query match any value in target
- Hydrogens are ignored unless explicitly specified
- Charged query atom won't match uncharged target atom
- Aromatic query atom won't match aliphatic target atom (unless query is generic)
7. Chemical Reactions
Reaction SMARTS:
from rdkit.Chem import AllChem
rxn = AllChem.ReactionFromSmarts('[C:1]=[O:2]>>[C:1][O:2]')
reactants = (mol1,)
products = rxn.RunReactants(reactants)
for product_set in products:
for product in product_set:
Chem.SanitizeMol(product)
Reaction Features:
- Atom mapping preserves specific atoms between reactants and products
- Dummy atoms in products are replaced by corresponding reactant atoms
- "Any" bonds inherit bond order from reactants
- Chirality preserved unless explicitly changed
Reaction Similarity:
fp = AllChem.CreateDifferenceFingerprintForReaction(rxn)
similarity = DataStructs.TanimotoSimilarity(fp1, fp2)
8. 2D and 3D Coordinate Generation
2D Coordinate Generation:
from rdkit.Chem import AllChem
AllChem.Compute2DCoords(mol)
template = Chem.MolFromSmiles('c1ccccc1')
AllChem.Compute2DCoords(template)
AllChem.GenerateDepictionMatching2DStructure(mol, template)
3D Coordinate Generation and Conformers:
AllChem.EmbedMolecule(mol, randomSeed=42)
conf_ids = AllChem.EmbedMultipleConfs(mol, numConfs=10, randomSeed=42)
AllChem.UFFOptimizeMolecule(mol)
AllChem.MMFFOptimizeMolecule(mol)
for conf_id in conf_ids:
AllChem.MMFFOptimizeMolecule(mol, confId=conf_id)
from rdkit.Chem import AllChem
rms = AllChem.GetConformerRMS(mol, conf_id1, conf_id2)
AllChem.AlignMol(probe_mol, ref_mol)
Constrained Embedding:
AllChem.ConstrainedEmbed(mol, core_mol)
9. Molecular Visualization
Basic Drawing:
from rdkit.Chem import Draw
img = Draw.MolToImage(mol, size=(300, 300))
img.save('molecule.png')
Draw.MolToFile(mol, 'molecule.png')
mols = [mol1, mol2, mol3, mol4]
img = Draw.MolsToGridImage(mols, molsPerRow=2, subImgSize=(200, 200))
Highlighting Substructures:
query = Chem.MolFromSmarts('c1ccccc1')
match = mol.GetSubstructMatch(query)
img = Draw.MolToImage(mol, highlightAtoms=match)
highlight_colors = {atom_idx: (1, 0, 0) for atom_idx in match}
img = Draw.MolToImage(mol, highlightAtoms=match,
highlightAtomColors=highlight_colors)
Customizing Visualization:
from rdkit.Chem.Draw import rdMolDraw2D
drawer = rdMolDraw2D.MolDraw2DCairo(300, 300)
opts = drawer.drawOptions()
opts.addAtomIndices = True
opts.addStereoAnnotation = True
opts.bondLineWidth = 2
drawer.DrawMolecule(mol)
drawer.FinishDrawing()
with open('molecule.png', 'wb') as f:
f.write(drawer.GetDrawingText())
Jupyter Notebook Integration:
from rdkit.Chem.Draw import IPythonConsole
IPythonConsole.ipython_useSVG = True
IPythonConsole.molSize = (300, 300)
mol
Visualizing Fingerprint Bits:
from rdkit.Chem import Draw
bit_info = {}
fp = AllChem.GetMorganFingerprintAsBitVect(mol, radius=2, bitInfo=bit_info)
img = Draw.DrawMorganBit(mol, bit_id, bit_info)
10. Molecular Modification
Adding/Removing Hydrogens:
mol_h = Chem.AddHs(mol)
mol = Chem.RemoveHs(mol_h)
Kekulization and Aromaticity:
Chem.Kekulize(mol)
Chem.SetAromaticity(mol)
Replacing Substructures:
query = Chem.MolFromSmarts('c1ccccc1')
replacement = Chem.MolFromSmiles('C1CCCCC1')
new_mol = Chem.ReplaceSubstructs(mol, query, replacement)[0]
Neutralizing Charges:
from rdkit.Chem.MolStandardize import rdMolStandardize
uncharger = rdMolStandardize.Uncharger()
mol_neutral = uncharger.uncharge(mol)
11. Working with Molecular Hashes and Standardization