Skip to content

RDKit → chematic migration cheatsheet

Side-by-side API reference for users coming from RDKit. chematic is pure Rust with zero C/C++ dependencies — install with pip install chematic, no conda required.

Installation

# RDKit
conda install -c conda-forge rdkit   # or: pip install rdkit

# chematic
pip install chematic                  # no extra dependencies

Basic I/O

RDKit chematic Notes
Chem.MolFromSmiles(smi) chematic.from_smiles(smi) SMILES → Mol
Chem.MolToSmiles(mol) mol.smiles Mol → canonical SMILES
Chem.MolFromMolBlock(block) chematic.from_mol_block(block) MOL block → Mol
Chem.inchi.MolFromInchi(inchi) chematic.from_inchi(inchi) InChI → Mol
Chem.inchi.MolToInchi(mol) mol.inchi Mol → InChI
Chem.inchi.InchiToInchiKey(inchi) mol.inchikey InChIKey
Chem.MolToSmiles(mol) str(mol) string conversion

Descriptors

RDKit chematic
Descriptors.MolWt(mol) mol.mw
Descriptors.ExactMolWt(mol) mol.exact_mass
Descriptors.MolLogP(mol) mol.logp
Descriptors.TPSA(mol) mol.tpsa
Descriptors.NumHDonors(mol) mol.hbd
Descriptors.NumHAcceptors(mol) mol.hba
Descriptors.NumRotatableBonds(mol) mol.rotatable_bonds
Descriptors.FractionCSP3(mol) mol.fsp3
Descriptors.HeavyAtomCount(mol) mol.heavy_atoms
Descriptors.RingCount(mol) mol.ring_count
Descriptors.NumAromaticRings(mol) mol.aromatic_ring_count
Descriptors.MolMR(mol) mol.molar_refractivity
Descriptors.qed(mol) mol.qed
rdMolDescriptors.CalcTPSA(mol) mol.tpsa
rdMolDescriptors.CalcNumStereocenters(mol) mol.num_stereocenters
rdMolDescriptors.CalcMolFormula(mol) mol.formula
sascorer.calculateScore(mol) mol.sa_score
Descriptors.ESOL(mol) (rdkit-contrib) mol.esol

Drug-likeness filters

RDKit chematic
FilterCatalog.FilterCatalogParams(PAINS) mol.pains_passes
(manual implementation) mol.lipinski_passes
(manual implementation) mol.veber_passes
(manual implementation) mol.ghose_passes
(manual implementation) mol.egan_passes
(manual implementation) mol.reos_passes
(manual implementation) mol.brenk_passes

Fingerprints

RDKit chematic
AllChem.GetMorganFingerprintAsBitVect(mol, 2, 2048) mol.ecfp4()
AllChem.GetMorganFingerprintAsBitVect(mol, 3, 2048) mol.ecfp6()
AllChem.GetMorganFingerprintAsBitVect(mol, 2, 2048, useFeatures=True) mol.fcfp4()
AllChem.GetMACCSKeysFingerprint(mol) mol.maccs()
rdMolDescriptors.GetAtomPairFingerprintAsBitVect(mol) mol.atom_pair_fp()
rdMolDescriptors.GetTopologicalTorsionFingerprintAsBitVect(mol) mol.torsion_fp()
rdMolDescriptors.GetHashedTopologicalTorsionFingerprintAsBitVect(mol) mol.layered_fp()

Return values are bytes (chematic) or DataStructs.ExplicitBitVect (RDKit). Pass chematic bytes directly to chematic.tanimoto().

Similarity

# RDKit
from rdkit.DataStructs import TanimotoSimilarity
sim = TanimotoSimilarity(fp1, fp2)

# chematic
sim = chematic.tanimoto(mol1.ecfp4(), mol2.ecfp4())

Bulk processing

# RDKit (single-threaded)
mols = [Chem.MolFromSmiles(s) for s in smiles_list]
fps  = [AllChem.GetMorganFingerprintAsBitVect(m, 2, 2048) for m in mols]

# chematic (automatic multi-core parallelism via Rayon)
fps = chematic.bulk.ecfp4(smiles_list)  # numpy array (N, 2048)

Similarity matrix

# RDKit
from rdkit.DataStructs import BulkTanimotoSimilarity
matrix = [[TanimotoSimilarity(fp, fp2) for fp2 in fps] for fp in fps]

# chematic
matrix = chematic.bulk.tanimoto(smiles_a, smiles_b)  # numpy (M, N) float32
# RDKit
query = Chem.MolFromSmarts("[OH]")
matches = mol.GetSubstructMatches(query)

# chematic — bool
chematic.smarts_match("[OH]", mol)

# chematic — atom indices
chematic.smarts_find("[OH]", mol)   # [[3], [7], ...]

Reaction SMARTS

# RDKit
from rdkit.Chem import rdChemReactions
rxn = rdChemReactions.ReactionFromSmarts("[OH]>>[O-]")
matches = rxn.RunReactants((mol,))

# chematic
chematic.reaction_smarts_match("[OH]>>[O-]", "CCO>>CC[O-]")  # bool

Maximum Common Substructure (MCS)

# RDKit
from rdkit.Chem import rdFMCS
result = rdFMCS.FindMCS([mol1, mol2])
mcs_mol = Chem.MolFromSmarts(result.smartsString)

# chematic
mcs = chematic.find_mcs([mol1, mol2])
print(mcs.smiles)

SMIRKS reactions

# RDKit
from rdkit.Chem import AllChem
rxn = AllChem.ReactionFromSmarts("[OH:1]>>[O-:1]")
products = rxn.RunReactants((mol,))

# chematic
products = chematic.run_smirks("[OH:1]>>[O-:1]", [mol])

Standardisation

# RDKit
from rdkit.Chem.MolStandardize import rdMolStandardize
clean = rdMolStandardize.Cleanup(mol)
frags = rdMolStandardize.LargestFragmentChooser().choose(clean)
uncharge = rdMolStandardize.Uncharger().uncharge(frags)

# chematic (one-liner)
clean = mol.standardize()

# individual steps
mol.largest_fragment()
mol.neutralize()
mol.remove_stereo()
mol.remove_isotopes()

Tautomers

# RDKit
from rdkit.Chem.MolStandardize import rdMolStandardize
enumerator = rdMolStandardize.TautomerEnumerator()
canonical = enumerator.Canonicalize(mol)
all_tautomers = enumerator.Enumerate(mol)

# chematic
canonical = mol.canonical_tautomer()
all_tautomers = mol.enumerate_tautomers()

Murcko scaffold

# RDKit
from rdkit.Chem.Scaffolds import MurckoScaffold
scaffold = MurckoScaffold.GetScaffoldForMol(mol)
generic = MurckoScaffold.MakeScaffoldGeneric(scaffold)

# chematic
scaffold = mol.scaffold()
generic  = mol.generic_scaffold()

SDF file reading

# RDKit
from rdkit.Chem import SDMolSupplier
for mol in SDMolSupplier("library.sdf"):
    if mol: print(Descriptors.MolWt(mol))

# chematic
for record in chematic.iter_sdf("library.sdf"):
    print(record.mol.mw)

2D depiction

# RDKit (Jupyter, returns PIL image)
from rdkit.Chem import Draw
Draw.MolToImage(mol)

# chematic (Jupyter, SVG)
from IPython.display import SVG
SVG(mol.svg())

# with atom highlighting
SVG(mol.svg_highlighted([0, 1, 2], color="#FF6B6B"))

# grid
SVG(chematic.depict_grid([mol1, mol2, mol3], cols=3))

SASA (3D solvent-accessible surface area)

# RDKit
from rdkit.Chem import rdFreeSASA
rdFreeSASA.CalcSASA(mol_with_3d_coords)

# chematic (generates 3D coords internally)
mol.sasa()           # total SASA in A^2
mol.sasa_per_atom()  # per-atom list

pKa prediction

# RDKit — not in the standard library (external tools required)

# chematic — built-in
pka = mol.pka()
print(pka["most_acidic"])   # 3.49
print(pka["most_basic"])    # None

ADMET profile

# RDKit — not in the standard library (pkasolver, SwissADME, etc. required)

# chematic — built-in
profile = mol.admet()
# {"bbb": False, "bbb_score": -1.2, "caco2": -5.1, "herg_risk": 0.3, "cyp3a4_risk": 0.4}

All descriptors to a DataFrame

# RDKit
from rdkit.Chem import Descriptors
import pandas as pd
desc_names = [x[0] for x in Descriptors._descList]
data = [{name: Descriptors.__dict__[name](mol) for name in desc_names} for mol in mols]
df = pd.DataFrame(data)

# chematic
df = pd.DataFrame(chematic.bulk.descriptors(smiles_list))

Features only in chematic

  • pKa prediction — built-in, no external tools
  • ADMET profile — BBB, Caco-2, hERG, CYP3A4 in a single call
  • WASM support — runs in the browser (719 KB bundle)
  • MCP server — direct integration with AI agents
  • Pure Rust — no conda, works in Docker / serverless / CI without extra setup
  • Atropisomer detectionmol.atropisomers() detects biaryl and allene axes