[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71GDPJD12AZ0JEBC31ATFGF":3,"skill-same:01M71GDPJD12AZ0JEBC31ATFGF":91},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":37,"linkOnly":38,"markdownContent":39,"markdownBody":40,"frontMatter":41,"refName":42,"commitSha":43,"skillDirectory":44,"forksCount":45,"repositoryHtmlUrl":46,"repositoryHomepageUrl":6,"ownerHtmlUrl":47,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":48,"install":49,"resources":62},"01M71GDPJD12AZ0JEBC31ATFGF","rdkit",null,"Cheminformatics toolkit for fine-grained molecular control. SMILES\u002FSDF parsing, descriptors (MW, LogP, TPSA), fingerprints, substructure search, 2D\u002F3D generation, similarity, reactions. For standard workflows with simpler interface, use datamol (wrapper around RDKit). Use rdkit for advanced control, custom sanitization, specialized algorithms.","JSGforever\u002Fskillguard","JSGforever","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F85541948?v=4","01M71FQD3E132VMR5F4TAYX3YS","01M71FQD4DYW0XJ4XQ4YQH75Y9",2,"GPL-3.0","https:\u002F\u002Fgithub.com\u002FJSGforever\u002Fskillguard\u002Fblob\u002Fmain\u002Fbenchmarks\u002Ffinal\u002Fskills\u002Fasset1__Microck--claude-scientific-skills\u002Fscientific-skills\u002Frdkit\u002FSKILL.md",[],[5,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36],"algorithms","Fingerprints","custom","2d","for","sanitization","advanced","interface","molecular","reactions","workflows","Wrapper","use","specialized","3D","parsing","datamol","search","toolkit","2026-11-10 10:12:30",false,"---\nname: rdkit\ndescription: \"Cheminformatics toolkit for fine-grained molecular control. SMILES\u002FSDF parsing, descriptors (MW, LogP, TPSA), fingerprints, substructure search, 2D\u002F3D generation, similarity, reactions. For standard workflows with simpler interface, use datamol (wrapper around RDKit). Use rdkit for advanced control, custom sanitization, specialized algorithms.\"\n---\n\n# RDKit Cheminformatics Toolkit\n\n## Overview\n\nRDKit is a comprehensive cheminformatics library providing Python APIs for molecular analysis and manipulation. This skill provides guidance for reading\u002Fwriting molecular structures, calculating descriptors, fingerprinting, substructure searching, chemical reactions, 2D\u002F3D coordinate generation, and molecular visualization. Use this skill for drug discovery, computational chemistry, and cheminformatics research tasks.\n\n## Core Capabilities\n\n### 1. Molecular I\u002FO and Creation\n\n**Reading Molecules:**\n\nRead molecular structures from various formats:\n\n```python\nfrom rdkit import Chem\n\n# From SMILES strings\nmol = Chem.MolFromSmiles('Cc1ccccc1')  # Returns Mol object or None\n\n# From MOL files\nmol = Chem.MolFromMolFile('path\u002Fto\u002Ffile.mol')\n\n# From MOL blocks (string data)\nmol = Chem.MolFromMolBlock(mol_block_string)\n\n# From InChI\nmol = Chem.MolFromInchi('InChI=1S\u002FC6H6\u002Fc1-2-4-6-5-3-1\u002Fh1-6H')\n```\n\n**Writing Molecules:**\n\nConvert molecules to text representations:\n\n```python\n# To canonical SMILES\nsmiles = Chem.MolToSmiles(mol)\n\n# To MOL block\nmol_block = Chem.MolToMolBlock(mol)\n\n# To InChI\ninchi = Chem.MolToInchi(mol)\n```\n\n**Batch Processing:**\n\nFor processing multiple molecules, use Supplier\u002FWriter objects:\n\n```python\n# Read SDF files\nsuppl = Chem.SDMolSupplier('molecules.sdf')\nfor mol in suppl:\n    if mol is not None:  # Check for parsing errors\n        # Process molecule\n        pass\n\n# Read SMILES files\nsuppl = Chem.SmilesMolSupplier('molecules.smi', titleLine=False)\n\n# For large files or compressed data\nwith gzip.open('molecules.sdf.gz') as f:\n    suppl = Chem.ForwardSDMolSupplier(f)\n    for mol in suppl:\n        # Process molecule\n        pass\n\n# Multithreaded processing for large datasets\nsuppl = Chem.MultithreadedSDMolSupplier('molecules.sdf')\n\n# Write molecules to SDF\nwriter = Chem.SDWriter('output.sdf')\nfor mol in molecules:\n    writer.write(mol)\nwriter.close()\n```\n\n**Important Notes:**\n- All `MolFrom*` functions return `None` on failure with error messages\n- Always check for `None` before processing molecules\n- Molecules are automatically sanitized on import (validates valence, perceives aromaticity)\n\n### 2. Molecular Sanitization and Validation\n\nRDKit automatically sanitizes molecules during parsing, executing 13 steps including valence checking, aromaticity perception, and chirality assignment.\n\n**Sanitization Control:**\n\n```python\n# Disable automatic sanitization\nmol = Chem.MolFromSmiles('C1=CC=CC=C1', sanitize=False)\n\n# Manual sanitization\nChem.SanitizeMol(mol)\n\n# Detect problems before sanitization\nproblems = Chem.DetectChemistryProblems(mol)\nfor problem in problems:\n    print(problem.GetType(), problem.Message())\n\n# Partial sanitization (skip specific steps)\nfrom rdkit.Chem import rdMolStandardize\nChem.SanitizeMol(mol, sanitizeOps=Chem.SANITIZE_ALL ^ Chem.SANITIZE_PROPERTIES)\n```\n\n**Common Sanitization Issues:**\n- Atoms with explicit valence exceeding maximum allowed will raise exceptions\n- Invalid aromatic rings will cause kekulization errors\n- Radical electrons may not be properly assigned without explicit specification\n\n### 3. Molecular Analysis and Properties\n\n**Accessing Molecular Structure:**\n\n```python\n# Iterate atoms and bonds\nfor atom in mol.GetAtoms():\n    print(atom.GetSymbol(), atom.GetIdx(), atom.GetDegree())\n\nfor bond in mol.GetBonds():\n    print(bond.GetBeginAtomIdx(), bond.GetEndAtomIdx(), bond.GetBondType())\n\n# Ring information\nring_info = mol.GetRingInfo()\nring_info.NumRings()\nring_info.AtomRings()  # Returns tuples of atom indices\n\n# Check if atom is in ring\natom = mol.GetAtomWithIdx(0)\natom.IsInRing()\natom.IsInRingSize(6)  # Check for 6-membered rings\n\n# Find smallest set of smallest rings (SSSR)\nfrom rdkit.Chem import GetSymmSSSR\nrings = GetSymmSSSR(mol)\n```\n\n**Stereochemistry:**\n\n```python\n# Find chiral centers\nfrom rdkit.Chem import FindMolChiralCenters\nchiral_centers = FindMolChiralCenters(mol, includeUnassigned=True)\n# Returns list of (atom_idx, chirality) tuples\n\n# Assign stereochemistry from 3D coordinates\nfrom rdkit.Chem import AssignStereochemistryFrom3D\nAssignStereochemistryFrom3D(mol)\n\n# Check bond stereochemistry\nbond = mol.GetBondWithIdx(0)\nstereo = bond.GetStereo()  # STEREONONE, STEREOZ, STEREOE, etc.\n```\n\n**Fragment Analysis:**\n\n```python\n# Get disconnected fragments\nfrags = Chem.GetMolFrags(mol, asMols=True)\n\n# Fragment on specific bonds\nfrom rdkit.Chem import FragmentOnBonds\nfrag_mol = FragmentOnBonds(mol, [bond_idx1, bond_idx2])\n\n# Count ring systems\nfrom rdkit.Chem.Scaffolds import MurckoScaffold\nscaffold = MurckoScaffold.GetScaffoldForMol(mol)\n```\n\n### 4. Molecular Descriptors and Properties\n\n**Basic Descriptors:**\n\n```python\nfrom rdkit.Chem import Descriptors\n\n# Molecular weight\nmw = Descriptors.MolWt(mol)\nexact_mw = Descriptors.ExactMolWt(mol)\n\n# LogP (lipophilicity)\nlogp = Descriptors.MolLogP(mol)\n\n# Topological polar surface area\ntpsa = Descriptors.TPSA(mol)\n\n# Number of hydrogen bond donors\u002Facceptors\nhbd = Descriptors.NumHDonors(mol)\nhba = Descriptors.NumHAcceptors(mol)\n\n# Number of rotatable bonds\nrot_bonds = Descriptors.NumRotatableBonds(mol)\n\n# Number of aromatic rings\naromatic_rings = Descriptors.NumAromaticRings(mol)\n```\n\n**Batch Descriptor Calculation:**\n\n```python\n# Calculate all descriptors at once\nall_descriptors = Descriptors.CalcMolDescriptors(mol)\n# Returns dictionary: {'MolWt': 180.16, 'MolLogP': 1.23, ...}\n\n# Get list of available descriptor names\ndescriptor_names = [desc[0] for desc in Descriptors._descList]\n```\n\n**Lipinski's Rule of Five:**\n\n```python\n# Check drug-likeness\nmw = Descriptors.MolWt(mol) \u003C= 500\nlogp = Descriptors.MolLogP(mol) \u003C= 5\nhbd = Descriptors.NumHDonors(mol) \u003C= 5\nhba = Descriptors.NumHAcceptors(mol) \u003C= 10\n\nis_drug_like = mw and logp and hbd and hba\n```\n\n### 5. Fingerprints and Molecular Similarity\n\n**Fingerprint Types:**\n\n```python\nfrom rdkit.Chem import AllChem, RDKFingerprint\nfrom rdkit.Chem.AtomPairs import Pairs, Torsions\nfrom rdkit.Chem import MACCSkeys\n\n# RDKit topological fingerprint\nfp = Chem.RDKFingerprint(mol)\n\n# Morgan fingerprints (circular fingerprints, similar to ECFP)\nfp = AllChem.GetMorganFingerprint(mol, radius=2)\nfp_bits = AllChem.GetMorganFingerprintAsBitVect(mol, radius=2, nBits=2048)\n\n# MACCS keys (166-bit structural key)\nfp = MACCSkeys.GenMACCSKeys(mol)\n\n# Atom pair fingerprints\nfp = Pairs.GetAtomPairFingerprint(mol)\n\n# Topological torsion fingerprints\nfp = Torsions.GetTopologicalTorsionFingerprint(mol)\n\n# Avalon fingerprints (if available)\nfrom rdkit.Avalon import pyAvalonTools\nfp = pyAvalonTools.GetAvalonFP(mol)\n```\n\n**Similarity Calculation:**\n\n```python\nfrom rdkit import DataStructs\n\n# Calculate Tanimoto similarity\nfp1 = AllChem.GetMorganFingerprintAsBitVect(mol1, radius=2)\nfp2 = AllChem.GetMorganFingerprintAsBitVect(mol2, radius=2)\nsimilarity = DataStructs.TanimotoSimilarity(fp1, fp2)\n\n# Calculate similarity for multiple molecules\nsimilarities = DataStructs.BulkTanimotoSimilarity(fp1, [fp2, fp3, fp4])\n\n# Other similarity metrics\ndice = DataStructs.DiceSimilarity(fp1, fp2)\ncosine = DataStructs.CosineSimilarity(fp1, fp2)\n```\n\n**Clustering and Diversity:**\n\n```python\n# Butina clustering based on fingerprint similarity\nfrom rdkit.ML.Cluster import Butina\n\n# Calculate distance matrix\ndists = []\nfps = [AllChem.GetMorganFingerprintAsBitVect(mol, 2) for mol in mols]\nfor i in range(len(fps)):\n    sims = DataStructs.BulkTanimotoSimilarity(fps[i], fps[:i])\n    dists.extend([1-sim for sim in sims])\n\n# Cluster with distance cutoff\nclusters = Butina.ClusterData(dists, len(fps), distThresh=0.3, isDistData=True)\n```\n\n### 6. Substructure Searching and SMARTS\n\n**Basic Substructure Matching:**\n\n```python\n# Define query using SMARTS\nquery = Chem.MolFromSmarts('[#6]1:[#6]:[#6]:[#6]:[#6]:[#6]:1')  # Benzene ring\n\n# Check if molecule contains substructure\nhas_match = mol.HasSubstructMatch(query)\n\n# Get all matches (returns tuple of tuples with atom indices)\nmatches = mol.GetSubstructMatches(query)\n\n# Get only first match\nmatch = mol.GetSubstructMatch(query)\n```\n\n**Common SMARTS Patterns:**\n\n```python\n# Primary alcohols\nprimary_alcohol = Chem.MolFromSmarts('[CH2][OH1]')\n\n# Carboxylic acids\ncarboxylic_acid = Chem.MolFromSmarts('C(=O)[OH]')\n\n# Amides\namide = Chem.MolFromSmarts('C(=O)N')\n\n# Aromatic heterocycles\naromatic_n = Chem.MolFromSmarts('[nR]')  # Aromatic nitrogen in ring\n\n# Macrocycles (rings > 12 atoms)\nmacrocycle = Chem.MolFromSmarts('[r{12-}]')\n```\n\n**Matching Rules:**\n- Unspecified properties in query match any value in target\n- Hydrogens are ignored unless explicitly specified\n- Charged query atom won't match uncharged target atom\n- Aromatic query atom won't match aliphatic target atom (unless query is generic)\n\n### 7. Chemical Reactions\n\n**Reaction SMARTS:**\n\n```python\nfrom rdkit.Chem import AllChem\n\n# Define reaction using SMARTS: reactants >> products\nrxn = AllChem.ReactionFromSmarts('[C:1]=[O:2]>>[C:1][O:2]')  # Ketone reduction\n\n# Apply reaction to molecules\nreactants = (mol1,)\nproducts = rxn.RunReactants(reactants)\n\n# Products is tuple of tuples (one tuple per product set)\nfor product_set in products:\n    for product in product_set:\n        # Sanitize product\n        Chem.SanitizeMol(product)\n```\n\n**Reaction Features:**\n- Atom mapping preserves specific atoms between reactants and products\n- Dummy atoms in products are replaced by corresponding reactant atoms\n- \"Any\" bonds inherit bond order from reactants\n- Chirality preserved unless explicitly changed\n\n**Reaction Similarity:**\n\n```python\n# Generate reaction fingerprints\nfp = AllChem.CreateDifferenceFingerprintForReaction(rxn)\n\n# Compare reactions\nsimilarity = DataStructs.TanimotoSimilarity(fp1, fp2)\n```\n\n### 8. 2D and 3D Coordinate Generation\n\n**2D Coordinate Generation:**\n\n```python\nfrom rdkit.Chem import AllChem\n\n# Generate 2D coordinates for depiction\nAllChem.Compute2DCoords(mol)\n\n# Align molecule to template structure\ntemplate = Chem.MolFromSmiles('c1ccccc1')\nAllChem.Compute2DCoords(template)\nAllChem.GenerateDepictionMatching2DStructure(mol, template)\n```\n\n**3D Coordinate Generation and Conformers:**\n\n```python\n# Generate single 3D conformer using ETKDG\nAllChem.EmbedMolecule(mol, randomSeed=42)\n\n# Generate multiple conformers\nconf_ids = AllChem.EmbedMultipleConfs(mol, numConfs=10, randomSeed=42)\n\n# Optimize geometry with force field\nAllChem.UFFOptimizeMolecule(mol)  # UFF force field\nAllChem.MMFFOptimizeMolecule(mol)  # MMFF94 force field\n\n# Optimize all conformers\nfor conf_id in conf_ids:\n    AllChem.MMFFOptimizeMolecule(mol, confId=conf_id)\n\n# Calculate RMSD between conformers\nfrom rdkit.Chem import AllChem\nrms = AllChem.GetConformerRMS(mol, conf_id1, conf_id2)\n\n# Align molecules\nAllChem.AlignMol(probe_mol, ref_mol)\n```\n\n**Constrained Embedding:**\n\n```python\n# Embed with part of molecule constrained to specific coordinates\nAllChem.ConstrainedEmbed(mol, core_mol)\n```\n\n### 9. Molecular Visualization\n\n**Basic Drawing:**\n\n```python\nfrom rdkit.Chem import Draw\n\n# Draw single molecule to PIL image\nimg = Draw.MolToImage(mol, size=(300, 300))\nimg.save('molecule.png')\n\n# Draw to file directly\nDraw.MolToFile(mol, 'molecule.png')\n\n# Draw multiple molecules in grid\nmols = [mol1, mol2, mol3, mol4]\nimg = Draw.MolsToGridImage(mols, molsPerRow=2, subImgSize=(200, 200))\n```\n\n**Highlighting Substructures:**\n\n```python\n# Highlight substructure match\nquery = Chem.MolFromSmarts('c1ccccc1')\nmatch = mol.GetSubstructMatch(query)\n\nimg = Draw.MolToImage(mol, highlightAtoms=match)\n\n# Custom highlight colors\nhighlight_colors = {atom_idx: (1, 0, 0) for atom_idx in match}  # Red\nimg = Draw.MolToImage(mol, highlightAtoms=match,\n                      highlightAtomColors=highlight_colors)\n```\n\n**Customizing Visualization:**\n\n```python\nfrom rdkit.Chem.Draw import rdMolDraw2D\n\n# Create drawer with custom options\ndrawer = rdMolDraw2D.MolDraw2DCairo(300, 300)\nopts = drawer.drawOptions()\n\n# Customize options\nopts.addAtomIndices = True\nopts.addStereoAnnotation = True\nopts.bondLineWidth = 2\n\n# Draw molecule\ndrawer.DrawMolecule(mol)\ndrawer.FinishDrawing()\n\n# Save to file\nwith open('molecule.png', 'wb') as f:\n    f.write(drawer.GetDrawingText())\n```\n\n**Jupyter Notebook Integration:**\n\n```python\n# Enable inline display in Jupyter\nfrom rdkit.Chem.Draw import IPythonConsole\n\n# Customize default display\nIPythonConsole.ipython_useSVG = True  # Use SVG instead of PNG\nIPythonConsole.molSize = (300, 300)   # Default size\n\n# Molecules now display automatically\nmol  # Shows molecule image\n```\n\n**Visualizing Fingerprint Bits:**\n\n```python\n# Show what molecular features a fingerprint bit represents\nfrom rdkit.Chem import Draw\n\n# For Morgan fingerprints\nbit_info = {}\nfp = AllChem.GetMorganFingerprintAsBitVect(mol, radius=2, bitInfo=bit_info)\n\n# Draw environment for specific bit\nimg = Draw.DrawMorganBit(mol, bit_id, bit_info)\n```\n\n### 10. Molecular Modification\n\n**Adding\u002FRemoving Hydrogens:**\n\n```python\n# Add explicit hydrogens\nmol_h = Chem.AddHs(mol)\n\n# Remove explicit hydrogens\nmol = Chem.RemoveHs(mol_h)\n```\n\n**Kekulization and Aromaticity:**\n\n```python\n# Convert aromatic bonds to alternating single\u002Fdouble\nChem.Kekulize(mol)\n\n# Set aromaticity\nChem.SetAromaticity(mol)\n```\n\n**Replacing Substructures:**\n\n```python\n# Replace substructure with another structure\nquery = Chem.MolFromSmarts('c1ccccc1')  # Benzene\nreplacement = Chem.MolFromSmiles('C1CCCCC1')  # Cyclohexane\n\nnew_mol = Chem.ReplaceSubstructs(mol, query, replacement)[0]\n```\n\n**Neutralizing Charges:**\n\n```python\n# Remove formal charges by adding\u002Fremoving hydrogens\nfrom rdkit.Chem.MolStandardize import rdMolStandardize\n\n# Using Uncharger\nuncharger = rdMolStandardize.Uncharger()\nmol_neutral = uncharger.uncharge(mol)\n```\n\n### 11. Working with Molecular Hashes and Standardization\n\n**Molecular Hashing:**\n\n```python\nfrom rdkit.Chem import rdMolHash\n\n# Generate Murcko scaffold hash\nscaffold_hash = rdMolHash.MolHash(mol, rdMolHash.HashFunction.MurckoScaffold)\n\n# Canonical SMILES hash\ncanonical_hash = rdMolHash.MolHash(mol, rdMolHash.HashFunction.CanonicalSmiles)\n\n# Regioisomer hash (ignores stereochemistry)\nregio_hash = rdMolHash.MolHash(mol, rdMolHash.HashFunction.Regioisomer)\n```\n\n**Randomized SMILES:**\n\n```python\n# Generate random SMILES representations (for data augmentation)\nfrom rdkit.Chem import MolToRandomSmilesVect\n\nrandom_smiles = MolToRandomSmilesVect(mol, numSmiles=10, randomSeed=42)\n```\n\n### 12. Pharmacophore and 3D Features\n\n**Pharmacophore Features:**\n\n```python\nfrom rdkit.Chem import ChemicalFeatures\nfrom rdkit import RDConfig\nimport os\n\n# Load feature factory\nfdef_path = os.path.join(RDConfig.RDDataDir, 'BaseFeatures.fdef')\nfactory = ChemicalFeatures.BuildFeatureFactory(fdef_path)\n\n# Get pharmacophore features\nfeatures = factory.GetFeaturesForMol(mol)\n\nfor feat in features:\n    print(feat.GetFamily(), feat.GetType(), feat.GetAtomIds())\n```\n\n## Common Workflows\n\n### Drug-likeness Analysis\n\n```python\nfrom rdkit import Chem\nfrom rdkit.Chem import Descriptors\n\ndef analyze_druglikeness(smiles):\n    mol = Chem.MolFromSmiles(smiles)\n    if mol is None:\n        return None\n\n    # Calculate Lipinski descriptors\n    results = {\n        'MW': Descriptors.MolWt(mol),\n        'LogP': Descriptors.MolLogP(mol),\n        'HBD': Descriptors.NumHDonors(mol),\n        'HBA': Descriptors.NumHAcceptors(mol),\n        'TPSA': Descriptors.TPSA(mol),\n        'RotBonds': Descriptors.NumRotatableBonds(mol)\n    }\n\n    # Check Lipinski's Rule of Five\n    results['Lipinski'] = (\n        results['MW'] \u003C= 500 and\n        results['LogP'] \u003C= 5 and\n        results['HBD'] \u003C= 5 and\n        results['HBA'] \u003C= 10\n    )\n\n    return results\n```\n\n### Similarity Screening\n\n```python\nfrom rdkit import Chem\nfrom rdkit.Chem import AllChem\nfrom rdkit import DataStructs\n\ndef similarity_screen(query_smiles, database_smiles, threshold=0.7):\n    query_mol = Chem.MolFromSmiles(query_smiles)\n    query_fp = AllChem.GetMorganFingerprintAsBitVect(query_mol, 2)\n\n    hits = []\n    for idx, smiles in enumerate(database_smiles):\n        mol = Chem.MolFromSmiles(smiles)\n        if mol:\n            fp = AllChem.GetMorganFingerprintAsBitVect(mol, 2)\n            sim = DataStructs.TanimotoSimilarity(query_fp, fp)\n            if sim >= threshold:\n                hits.append((idx, smiles, sim))\n\n    return sorted(hits, key=lambda x: x[2], reverse=True)\n```\n\n### Substructure Filtering\n\n```python\nfrom rdkit import Chem\n\ndef filter_by_substructure(smiles_list, pattern_smarts):\n    query = Chem.MolFromSmarts(pattern_smarts)\n\n    hits = []\n    for smiles in smiles_list:\n        mol = Chem.MolFromSmiles(smiles)\n        if mol and mol.HasSubstructMatch(query):\n            hits.append(smiles)\n\n    return hits\n```\n\n## Best Practices\n\n### Error Handling\n\nAlways check for `None` when parsing molecules:\n\n```python\nmol = Chem.MolFromSmiles(smiles)\nif mol is None:\n    print(f\"Failed to parse: {smiles}\")\n    continue\n```\n\n### Performance Optimization\n\n**Use binary formats for storage:**\n\n```python\nimport pickle\n\n# Pickle molecules for fast loading\nwith open('molecules.pkl', 'wb') as f:\n    pickle.dump(mols, f)\n\n# Load pickled molecules (much faster than reparsing)\nwith open('molecules.pkl', 'rb') as f:\n    mols = pickle.load(f)\n```\n\n**Use bulk operations:**\n\n```python\n# Calculate fingerprints for all molecules at once\nfps = [AllChem.GetMorganFingerprintAsBitVect(mol, 2) for mol in mols]\n\n# Use bulk similarity calculations\nsimilarities = DataStructs.BulkTanimotoSimilarity(fps[0], fps[1:])\n```\n\n### Thread Safety\n\nRDKit operations are generally thread-safe for:\n- Molecule I\u002FO (SMILES, mol blocks)\n- Coordinate generation\n- Fingerprinting and descriptors\n- Substructure searching\n- Reactions\n- Drawing\n\n**Not thread-safe:** MolSuppliers when accessed concurrently.\n\n### Memory Management\n\nFor large datasets:\n\n```python\n# Use ForwardSDMolSupplier to avoid loading entire file\nwith open('large.sdf') as f:\n    suppl = Chem.ForwardSDMolSupplier(f)\n    for mol in suppl:\n        # Process one molecule at a time\n        pass\n\n# Use MultithreadedSDMolSupplier for parallel processing\nsuppl = Chem.MultithreadedSDMolSupplier('large.sdf', numWriterThreads=4)\n```\n\n## Common Pitfalls\n\n1. **Forgetting to check for None:** Always validate molecules after parsing\n2. **Sanitization failures:** Use `DetectChemistryProblems()` to debug\n3. **Missing hydrogens:** Use `AddHs()` when calculating properties that depend on hydrogen\n4. **2D vs 3D:** Generate appropriate coordinates before visualization or 3D analysis\n5. **SMARTS matching rules:** Remember that unspecified properties match anything\n6. **Thread safety with MolSuppliers:** Don't share supplier objects across threads\n\n## Resources\n\n### references\u002F\n\nThis skill includes detailed API reference documentation:\n\n- `api_reference.md` - Comprehensive listing of RDKit modules, functions, and classes organized by functionality\n- `descriptors_reference.md` - Complete list of available molecular descriptors with descriptions\n- `smarts_patterns.md` - Common SMARTS patterns for functional groups and structural features\n\nLoad these references when needing specific API details, parameter information, or pattern examples.\n\n### scripts\u002F\n\nExample scripts for common RDKit workflows:\n\n- `molecular_properties.py` - Calculate comprehensive molecular properties and descriptors\n- `similarity_search.py` - Perform fingerprint-based similarity screening\n- `substructure_filter.py` - Filter molecules by substructure patterns\n\nThese scripts can be executed directly or used as templates for custom workflows.\n","# RDKit Cheminformatics Toolkit\n\n## Overview\n\nRDKit is a comprehensive cheminformatics library providing Python APIs for molecular analysis and manipulation. This skill provides guidance for reading\u002Fwriting molecular structures, calculating descriptors, fingerprinting, substructure searching, chemical reactions, 2D\u002F3D coordinate generation, and molecular visualization. Use this skill for drug discovery, computational chemistry, and cheminformatics research tasks.\n\n## Core Capabilities\n\n### 1. Molecular I\u002FO and Creation\n\n**Reading Molecules:**\n\nRead molecular structures from various formats:\n\n```python\nfrom rdkit import Chem\n\n# From SMILES strings\nmol = Chem.MolFromSmiles('Cc1ccccc1')  # Returns Mol object or None\n\n# From MOL files\nmol = Chem.MolFromMolFile('path\u002Fto\u002Ffile.mol')\n\n# From MOL blocks (string data)\nmol = Chem.MolFromMolBlock(mol_block_string)\n\n# From InChI\nmol = Chem.MolFromInchi('InChI=1S\u002FC6H6\u002Fc1-2-4-6-5-3-1\u002Fh1-6H')\n```\n\n**Writing Molecules:**\n\nConvert molecules to text representations:\n\n```python\n# To canonical SMILES\nsmiles = Chem.MolToSmiles(mol)\n\n# To MOL block\nmol_block = Chem.MolToMolBlock(mol)\n\n# To InChI\ninchi = Chem.MolToInchi(mol)\n```\n\n**Batch Processing:**\n\nFor processing multiple molecules, use Supplier\u002FWriter objects:\n\n```python\n# Read SDF files\nsuppl = Chem.SDMolSupplier('molecules.sdf')\nfor mol in suppl:\n    if mol is not None:  # Check for parsing errors\n        # Process molecule\n        pass\n\n# Read SMILES files\nsuppl = Chem.SmilesMolSupplier('molecules.smi', titleLine=False)\n\n# For large files or compressed data\nwith gzip.open('molecules.sdf.gz') as f:\n    suppl = Chem.ForwardSDMolSupplier(f)\n    for mol in suppl:\n        # Process molecule\n        pass\n\n# Multithreaded processing for large datasets\nsuppl = Chem.MultithreadedSDMolSupplier('molecules.sdf')\n\n# Write molecules to SDF\nwriter = Chem.SDWriter('output.sdf')\nfor mol in molecules:\n    writer.write(mol)\nwriter.close()\n```\n\n**Important Notes:**\n- All `MolFrom*` functions return `None` on failure with error messages\n- Always check for `None` before processing molecules\n- Molecules are automatically sanitized on import (validates valence, perceives aromaticity)\n\n### 2. Molecular Sanitization and Validation\n\nRDKit automatically sanitizes molecules during parsing, executing 13 steps including valence checking, aromaticity perception, and chirality assignment.\n\n**Sanitization Control:**\n\n```python\n# Disable automatic sanitization\nmol = Chem.MolFromSmiles('C1=CC=CC=C1', sanitize=False)\n\n# Manual sanitization\nChem.SanitizeMol(mol)\n\n# Detect problems before sanitization\nproblems = Chem.DetectChemistryProblems(mol)\nfor problem in problems:\n    print(problem.GetType(), problem.Message())\n\n# Partial sanitization (skip specific steps)\nfrom rdkit.Chem import rdMolStandardize\nChem.SanitizeMol(mol, sanitizeOps=Chem.SANITIZE_ALL ^ Chem.SANITIZE_PROPERTIES)\n```\n\n**Common Sanitization Issues:**\n- Atoms with explicit valence exceeding maximum allowed will raise exceptions\n- Invalid aromatic rings will cause kekulization errors\n- Radical electrons may not be properly assigned without explicit specification\n\n### 3. Molecular Analysis and Properties\n\n**Accessing Molecular Structure:**\n\n```python\n# Iterate atoms and bonds\nfor atom in mol.GetAtoms():\n    print(atom.GetSymbol(), atom.GetIdx(), atom.GetDegree())\n\nfor bond in mol.GetBonds():\n    print(bond.GetBeginAtomIdx(), bond.GetEndAtomIdx(), bond.GetBondType())\n\n# Ring information\nring_info = mol.GetRingInfo()\nring_info.NumRings()\nring_info.AtomRings()  # Returns tuples of atom indices\n\n# Check if atom is in ring\natom = mol.GetAtomWithIdx(0)\natom.IsInRing()\natom.IsInRingSize(6)  # Check for 6-membered rings\n\n# Find smallest set of smallest rings (SSSR)\nfrom rdkit.Chem import GetSymmSSSR\nrings = GetSymmSSSR(mol)\n```\n\n**Stereochemistry:**\n\n```python\n# Find chiral centers\nfrom rdkit.Chem import FindMolChiralCenters\nchiral_centers = FindMolChiralCenters(mol, includeUnassigned=True)\n# Returns list of (atom_idx, chirality) tuples\n\n# Assign stereochemistry from 3D coordinates\nfrom rdkit.Chem import AssignStereochemistryFrom3D\nAssignStereochemistryFrom3D(mol)\n\n# Check bond stereochemistry\nbond = mol.GetBondWithIdx(0)\nstereo = bond.GetStereo()  # STEREONONE, STEREOZ, STEREOE, etc.\n```\n\n**Fragment Analysis:**\n\n```python\n# Get disconnected fragments\nfrags = Chem.GetMolFrags(mol, asMols=True)\n\n# Fragment on specific bonds\nfrom rdkit.Chem import FragmentOnBonds\nfrag_mol = FragmentOnBonds(mol, [bond_idx1, bond_idx2])\n\n# Count ring systems\nfrom rdkit.Chem.Scaffolds import MurckoScaffold\nscaffold = MurckoScaffold.GetScaffoldForMol(mol)\n```\n\n### 4. Molecular Descriptors and Properties\n\n**Basic Descriptors:**\n\n```python\nfrom rdkit.Chem import Descriptors\n\n# Molecular weight\nmw = Descriptors.MolWt(mol)\nexact_mw = Descriptors.ExactMolWt(mol)\n\n# LogP (lipophilicity)\nlogp = Descriptors.MolLogP(mol)\n\n# Topological polar surface area\ntpsa = Descriptors.TPSA(mol)\n\n# Number of hydrogen bond donors\u002Facceptors\nhbd = Descriptors.NumHDonors(mol)\nhba = Descriptors.NumHAcceptors(mol)\n\n# Number of rotatable bonds\nrot_bonds = Descriptors.NumRotatableBonds(mol)\n\n# Number of aromatic rings\naromatic_rings = Descriptors.NumAromaticRings(mol)\n```\n\n**Batch Descriptor Calculation:**\n\n```python\n# Calculate all descriptors at once\nall_descriptors = Descriptors.CalcMolDescriptors(mol)\n# Returns dictionary: {'MolWt': 180.16, 'MolLogP': 1.23, ...}\n\n# Get list of available descriptor names\ndescriptor_names = [desc[0] for desc in Descriptors._descList]\n```\n\n**Lipinski's Rule of Five:**\n\n```python\n# Check drug-likeness\nmw = Descriptors.MolWt(mol) \u003C= 500\nlogp = Descriptors.MolLogP(mol) \u003C= 5\nhbd = Descriptors.NumHDonors(mol) \u003C= 5\nhba = Descriptors.NumHAcceptors(mol) \u003C= 10\n\nis_drug_like = mw and logp and hbd and hba\n```\n\n### 5. Fingerprints and Molecular Similarity\n\n**Fingerprint Types:**\n\n```python\nfrom rdkit.Chem import AllChem, RDKFingerprint\nfrom rdkit.Chem.AtomPairs import Pairs, Torsions\nfrom rdkit.Chem import MACCSkeys\n\n# RDKit topological fingerprint\nfp = Chem.RDKFingerprint(mol)\n\n# Morgan fingerprints (circular fingerprints, similar to ECFP)\nfp = AllChem.GetMorganFingerprint(mol, radius=2)\nfp_bits = AllChem.GetMorganFingerprintAsBitVect(mol, radius=2, nBits=2048)\n\n# MACCS keys (166-bit structural key)\nfp = MACCSkeys.GenMACCSKeys(mol)\n\n# Atom pair fingerprints\nfp = Pairs.GetAtomPairFingerprint(mol)\n\n# Topological torsion fingerprints\nfp = Torsions.GetTopologicalTorsionFingerprint(mol)\n\n# Avalon fingerprints (if available)\nfrom rdkit.Avalon import pyAvalonTools\nfp = pyAvalonTools.GetAvalonFP(mol)\n```\n\n**Similarity Calculation:**\n\n```python\nfrom rdkit import DataStructs\n\n# Calculate Tanimoto similarity\nfp1 = AllChem.GetMorganFingerprintAsBitVect(mol1, radius=2)\nfp2 = AllChem.GetMorganFingerprintAsBitVect(mol2, radius=2)\nsimilarity = DataStructs.TanimotoSimilarity(fp1, fp2)\n\n# Calculate similarity for multiple molecules\nsimilarities = DataStructs.BulkTanimotoSimilarity(fp1, [fp2, fp3, fp4])\n\n# Other similarity metrics\ndice = DataStructs.DiceSimilarity(fp1, fp2)\ncosine = DataStructs.CosineSimilarity(fp1, fp2)\n```\n\n**Clustering and Diversity:**\n\n```python\n# Butina clustering based on fingerprint similarity\nfrom rdkit.ML.Cluster import Butina\n\n# Calculate distance matrix\ndists = []\nfps = [AllChem.GetMorganFingerprintAsBitVect(mol, 2) for mol in mols]\nfor i in range(len(fps)):\n    sims = DataStructs.BulkTanimotoSimilarity(fps[i], fps[:i])\n    dists.extend([1-sim for sim in sims])\n\n# Cluster with distance cutoff\nclusters = Butina.ClusterData(dists, len(fps), distThresh=0.3, isDistData=True)\n```\n\n### 6. Substructure Searching and SMARTS\n\n**Basic Substructure Matching:**\n\n```python\n# Define query using SMARTS\nquery = Chem.MolFromSmarts('[#6]1:[#6]:[#6]:[#6]:[#6]:[#6]:1')  # Benzene ring\n\n# Check if molecule contains substructure\nhas_match = mol.HasSubstructMatch(query)\n\n# Get all matches (returns tuple of tuples with atom indices)\nmatches = mol.GetSubstructMatches(query)\n\n# Get only first match\nmatch = mol.GetSubstructMatch(query)\n```\n\n**Common SMARTS Patterns:**\n\n```python\n# Primary alcohols\nprimary_alcohol = Chem.MolFromSmarts('[CH2][OH1]')\n\n# Carboxylic acids\ncarboxylic_acid = Chem.MolFromSmarts('C(=O)[OH]')\n\n# Amides\namide = Chem.MolFromSmarts('C(=O)N')\n\n# Aromatic heterocycles\naromatic_n = Chem.MolFromSmarts('[nR]')  # Aromatic nitrogen in ring\n\n# Macrocycles (rings > 12 atoms)\nmacrocycle = Chem.MolFromSmarts('[r{12-}]')\n```\n\n**Matching Rules:**\n- Unspecified properties in query match any value in target\n- Hydrogens are ignored unless explicitly specified\n- Charged query atom won't match uncharged target atom\n- Aromatic query atom won't match aliphatic target atom (unless query is generic)\n\n### 7. Chemical Reactions\n\n**Reaction SMARTS:**\n\n```python\nfrom rdkit.Chem import AllChem\n\n# Define reaction using SMARTS: reactants >> products\nrxn = AllChem.ReactionFromSmarts('[C:1]=[O:2]>>[C:1][O:2]')  # Ketone reduction\n\n# Apply reaction to molecules\nreactants = (mol1,)\nproducts = rxn.RunReactants(reactants)\n\n# Products is tuple of tuples (one tuple per product set)\nfor product_set in products:\n    for product in product_set:\n        # Sanitize product\n        Chem.SanitizeMol(product)\n```\n\n**Reaction Features:**\n- Atom mapping preserves specific atoms between reactants and products\n- Dummy atoms in products are replaced by corresponding reactant atoms\n- \"Any\" bonds inherit bond order from reactants\n- Chirality preserved unless explicitly changed\n\n**Reaction Similarity:**\n\n```python\n# Generate reaction fingerprints\nfp = AllChem.CreateDifferenceFingerprintForReaction(rxn)\n\n# Compare reactions\nsimilarity = DataStructs.TanimotoSimilarity(fp1, fp2)\n```\n\n### 8. 2D and 3D Coordinate Generation\n\n**2D Coordinate Generation:**\n\n```python\nfrom rdkit.Chem import AllChem\n\n# Generate 2D coordinates for depiction\nAllChem.Compute2DCoords(mol)\n\n# Align molecule to template structure\ntemplate = Chem.MolFromSmiles('c1ccccc1')\nAllChem.Compute2DCoords(template)\nAllChem.GenerateDepictionMatching2DStructure(mol, template)\n```\n\n**3D Coordinate Generation and Conformers:**\n\n```python\n# Generate single 3D conformer using ETKDG\nAllChem.EmbedMolecule(mol, randomSeed=42)\n\n# Generate multiple conformers\nconf_ids = AllChem.EmbedMultipleConfs(mol, numConfs=10, randomSeed=42)\n\n# Optimize geometry with force field\nAllChem.UFFOptimizeMolecule(mol)  # UFF force field\nAllChem.MMFFOptimizeMolecule(mol)  # MMFF94 force field\n\n# Optimize all conformers\nfor conf_id in conf_ids:\n    AllChem.MMFFOptimizeMolecule(mol, confId=conf_id)\n\n# Calculate RMSD between conformers\nfrom rdkit.Chem import AllChem\nrms = AllChem.GetConformerRMS(mol, conf_id1, conf_id2)\n\n# Align molecules\nAllChem.AlignMol(probe_mol, ref_mol)\n```\n\n**Constrained Embedding:**\n\n```python\n# Embed with part of molecule constrained to specific coordinates\nAllChem.ConstrainedEmbed(mol, core_mol)\n```\n\n### 9. Molecular Visualization\n\n**Basic Drawing:**\n\n```python\nfrom rdkit.Chem import Draw\n\n# Draw single molecule to PIL image\nimg = Draw.MolToImage(mol, size=(300, 300))\nimg.save('molecule.png')\n\n# Draw to file directly\nDraw.MolToFile(mol, 'molecule.png')\n\n# Draw multiple molecules in grid\nmols = [mol1, mol2, mol3, mol4]\nimg = Draw.MolsToGridImage(mols, molsPerRow=2, subImgSize=(200, 200))\n```\n\n**Highlighting Substructures:**\n\n```python\n# Highlight substructure match\nquery = Chem.MolFromSmarts('c1ccccc1')\nmatch = mol.GetSubstructMatch(query)\n\nimg = Draw.MolToImage(mol, highlightAtoms=match)\n\n# Custom highlight colors\nhighlight_colors = {atom_idx: (1, 0, 0) for atom_idx in match}  # Red\nimg = Draw.MolToImage(mol, highlightAtoms=match,\n                      highlightAtomColors=highlight_colors)\n```\n\n**Customizing Visualization:**\n\n```python\nfrom rdkit.Chem.Draw import rdMolDraw2D\n\n# Create drawer with custom options\ndrawer = rdMolDraw2D.MolDraw2DCairo(300, 300)\nopts = drawer.drawOptions()\n\n# Customize options\nopts.addAtomIndices = True\nopts.addStereoAnnotation = True\nopts.bondLineWidth = 2\n\n# Draw molecule\ndrawer.DrawMolecule(mol)\ndrawer.FinishDrawing()\n\n# Save to file\nwith open('molecule.png', 'wb') as f:\n    f.write(drawer.GetDrawingText())\n```\n\n**Jupyter Notebook Integration:**\n\n```python\n# Enable inline display in Jupyter\nfrom rdkit.Chem.Draw import IPythonConsole\n\n# Customize default display\nIPythonConsole.ipython_useSVG = True  # Use SVG instead of PNG\nIPythonConsole.molSize = (300, 300)   # Default size\n\n# Molecules now display automatically\nmol  # Shows molecule image\n```\n\n**Visualizing Fingerprint Bits:**\n\n```python\n# Show what molecular features a fingerprint bit represents\nfrom rdkit.Chem import Draw\n\n# For Morgan fingerprints\nbit_info = {}\nfp = AllChem.GetMorganFingerprintAsBitVect(mol, radius=2, bitInfo=bit_info)\n\n# Draw environment for specific bit\nimg = Draw.DrawMorganBit(mol, bit_id, bit_info)\n```\n\n### 10. Molecular Modification\n\n**Adding\u002FRemoving Hydrogens:**\n\n```python\n# Add explicit hydrogens\nmol_h = Chem.AddHs(mol)\n\n# Remove explicit hydrogens\nmol = Chem.RemoveHs(mol_h)\n```\n\n**Kekulization and Aromaticity:**\n\n```python\n# Convert aromatic bonds to alternating single\u002Fdouble\nChem.Kekulize(mol)\n\n# Set aromaticity\nChem.SetAromaticity(mol)\n```\n\n**Replacing Substructures:**\n\n```python\n# Replace substructure with another structure\nquery = Chem.MolFromSmarts('c1ccccc1')  # Benzene\nreplacement = Chem.MolFromSmiles('C1CCCCC1')  # Cyclohexane\n\nnew_mol = Chem.ReplaceSubstructs(mol, query, replacement)[0]\n```\n\n**Neutralizing Charges:**\n\n```python\n# Remove formal charges by adding\u002Fremoving hydrogens\nfrom rdkit.Chem.MolStandardize import rdMolStandardize\n\n# Using Uncharger\nuncharger = rdMolStandardize.Uncharger()\nmol_neutral = uncharger.uncharge(mol)\n```\n\n### 11. Working with Molecular Hashes and Standardization\n\n**Molecular Hashing:**\n\n```python\nfrom rdkit.Chem import rdMolHash\n\n# Generate Murcko scaffold hash\nscaffold_hash = rdMolHash.MolHash(mol, rdMolHash.HashFunction.MurckoScaffold)\n\n# Canonical SMILES hash\ncanonical_hash = rdMolHash.MolHash(mol, rdMolHash.HashFunction.CanonicalSmiles)\n\n# Regioisomer hash (ignores stereochemistry)\nregio_hash = rdMolHash.MolHash(mol, rdMolHash.HashFunction.Regioisomer)\n```\n\n**Randomized SMILES:**\n\n```python\n# Generate random SMILES representations (for data augmentation)\nfrom rdkit.Chem import MolToRandomSmilesVect\n\nrandom_smiles = MolToRandomSmilesVect(mol, numSmiles=10, randomSeed=42)\n```\n\n### 12. Pharmacophore and 3D Features\n\n**Pharmacophore Features:**\n\n```python\nfrom rdkit.Chem import ChemicalFeatures\nfrom rdkit import RDConfig\nimport os\n\n# Load feature factory\nfdef_path = os.path.join(RDConfig.RDDataDir, 'BaseFeatures.fdef')\nfactory = ChemicalFeatures.BuildFeatureFactory(fdef_path)\n\n# Get pharmacophore features\nfeatures = factory.GetFeaturesForMol(mol)\n\nfor feat in features:\n    print(feat.GetFamily(), feat.GetType(), feat.GetAtomIds())\n```\n\n## Common Workflows\n\n### Drug-likeness Analysis\n\n```python\nfrom rdkit import Chem\nfrom rdkit.Chem import Descriptors\n\ndef analyze_druglikeness(smiles):\n    mol = Chem.MolFromSmiles(smiles)\n    if mol is None:\n        return None\n\n    # Calculate Lipinski descriptors\n    results = {\n        'MW': Descriptors.MolWt(mol),\n        'LogP': Descriptors.MolLogP(mol),\n        'HBD': Descriptors.NumHDonors(mol),\n        'HBA': Descriptors.NumHAcceptors(mol),\n        'TPSA': Descriptors.TPSA(mol),\n        'RotBonds': Descriptors.NumRotatableBonds(mol)\n    }\n\n    # Check Lipinski's Rule of Five\n    results['Lipinski'] = (\n        results['MW'] \u003C= 500 and\n        results['LogP'] \u003C= 5 and\n        results['HBD'] \u003C= 5 and\n        results['HBA'] \u003C= 10\n    )\n\n    return results\n```\n\n### Similarity Screening\n\n```python\nfrom rdkit import Chem\nfrom rdkit.Chem import AllChem\nfrom rdkit import DataStructs\n\ndef similarity_screen(query_smiles, database_smiles, threshold=0.7):\n    query_mol = Chem.MolFromSmiles(query_smiles)\n    query_fp = AllChem.GetMorganFingerprintAsBitVect(query_mol, 2)\n\n    hits = []\n    for idx, smiles in enumerate(database_smiles):\n        mol = Chem.MolFromSmiles(smiles)\n        if mol:\n            fp = AllChem.GetMorganFingerprintAsBitVect(mol, 2)\n            sim = DataStructs.TanimotoSimilarity(query_fp, fp)\n            if sim >= threshold:\n                hits.append((idx, smiles, sim))\n\n    return sorted(hits, key=lambda x: x[2], reverse=True)\n```\n\n### Substructure Filtering\n\n```python\nfrom rdkit import Chem\n\ndef filter_by_substructure(smiles_list, pattern_smarts):\n    query = Chem.MolFromSmarts(pattern_smarts)\n\n    hits = []\n    for smiles in smiles_list:\n        mol = Chem.MolFromSmiles(smiles)\n        if mol and mol.HasSubstructMatch(query):\n            hits.append(smiles)\n\n    return hits\n```\n\n## Best Practices\n\n### Error Handling\n\nAlways check for `None` when parsing molecules:\n\n```python\nmol = Chem.MolFromSmiles(smiles)\nif mol is None:\n    print(f\"Failed to parse: {smiles}\")\n    continue\n```\n\n### Performance Optimization\n\n**Use binary formats for storage:**\n\n```python\nimport pickle\n\n# Pickle molecules for fast loading\nwith open('molecules.pkl', 'wb') as f:\n    pickle.dump(mols, f)\n\n# Load pickled molecules (much faster than reparsing)\nwith open('molecules.pkl', 'rb') as f:\n    mols = pickle.load(f)\n```\n\n**Use bulk operations:**\n\n```python\n# Calculate fingerprints for all molecules at once\nfps = [AllChem.GetMorganFingerprintAsBitVect(mol, 2) for mol in mols]\n\n# Use bulk similarity calculations\nsimilarities = DataStructs.BulkTanimotoSimilarity(fps[0], fps[1:])\n```\n\n### Thread Safety\n\nRDKit operations are generally thread-safe for:\n- Molecule I\u002FO (SMILES, mol blocks)\n- Coordinate generation\n- Fingerprinting and descriptors\n- Substructure searching\n- Reactions\n- Drawing\n\n**Not thread-safe:** MolSuppliers when accessed concurrently.\n\n### Memory Management\n\nFor large datasets:\n\n```python\n# Use ForwardSDMolSupplier to avoid loading entire file\nwith open('large.sdf') as f:\n    suppl = Chem.ForwardSDMolSupplier(f)\n    for mol in suppl:\n        # Process one molecule at a time\n        pass\n\n# Use MultithreadedSDMolSupplier for parallel processing\nsuppl = Chem.MultithreadedSDMolSupplier('large.sdf', numWriterThreads=4)\n```\n\n## Common Pitfalls\n\n1. **Forgetting to check for None:** Always validate molecules after parsing\n2. **Sanitization failures:** Use `DetectChemistryProblems()` to debug\n3. **Missing hydrogens:** Use `AddHs()` when calculating properties that depend on hydrogen\n4. **2D vs 3D:** Generate appropriate coordinates before visualization or 3D analysis\n5. **SMARTS matching rules:** Remember that unspecified properties match anything\n6. **Thread safety with MolSuppliers:** Don't share supplier objects across threads\n\n## Resources\n\n### references\u002F\n\nThis skill includes detailed API reference documentation:\n\n- `api_reference.md` - Comprehensive listing of RDKit modules, functions, and classes organized by functionality\n- `descriptors_reference.md` - Complete list of available molecular descriptors with descriptions\n- `smarts_patterns.md` - Common SMARTS patterns for functional groups and structural features\n\nLoad these references when needing specific API details, parameter information, or pattern examples.\n\n### scripts\u002F\n\nExample scripts for common RDKit workflows:\n\n- `molecular_properties.py` - Calculate comprehensive molecular properties and descriptors\n- `similarity_search.py` - Perform fingerprint-based similarity screening\n- `substructure_filter.py` - Filter molecules by substructure patterns\n\nThese scripts can be executed directly or used as templates for custom workflows.\n",{"name":5,"description":7},"main","f2ec4b3b9133d34eeaf9b38e4b0a97e8e5705a7f","benchmarks\u002Ffinal\u002Fskills\u002Fasset1__Microck--claude-scientific-skills\u002Fscientific-skills\u002Frdkit",0,"https:\u002F\u002Fgithub.com\u002FJSGforever\u002Fskillguard","https:\u002F\u002Fgithub.com\u002FJSGforever","2026-08-29 18:27:56",{"source":8,"skillName":5,"commands":50,"prompt":60,"zipAvailable":61},[51,54,57],{"tool":52,"command":53},"npx","npx skills add JSGforever\u002Fskillguard --skill rdkit",{"tool":55,"command":56},"bunx","bunx skills add JSGforever\u002Fskillguard --skill rdkit",{"tool":58,"command":59},"pnpm","pnpm dlx skills add JSGforever\u002Fskillguard --skill rdkit","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FJSGforever\u002Fskillguard\u002Fblob\u002Fmain\u002Fbenchmarks\u002Ffinal\u002Fskills\u002Fasset1__Microck--claude-scientific-skills\u002Fscientific-skills\u002Frdkit\u002FSKILL.md",true,[63,69,73,77,83,87],{"path":64,"resourceType":65,"resourceTypeDesc":66,"sizeBytes":67,"sourceHtmlUrl":68},"references\u002Fapi_reference.md","REFERENCE","参考文档",16789,"https:\u002F\u002Fgithub.com\u002FJSGforever\u002Fskillguard\u002Fblob\u002Fmain\u002Fbenchmarks\u002Ffinal\u002Fskills\u002Fasset1__Microck--claude-scientific-skills\u002Fscientific-skills\u002Frdkit\u002Freferences\u002Fapi_reference.md",{"path":70,"resourceType":65,"resourceTypeDesc":66,"sizeBytes":71,"sourceHtmlUrl":72},"references\u002Fdescriptors_reference.md",11779,"https:\u002F\u002Fgithub.com\u002FJSGforever\u002Fskillguard\u002Fblob\u002Fmain\u002Fbenchmarks\u002Ffinal\u002Fskills\u002Fasset1__Microck--claude-scientific-skills\u002Fscientific-skills\u002Frdkit\u002Freferences\u002Fdescriptors_reference.md",{"path":74,"resourceType":65,"resourceTypeDesc":66,"sizeBytes":75,"sourceHtmlUrl":76},"references\u002Fsmarts_patterns.md",8143,"https:\u002F\u002Fgithub.com\u002FJSGforever\u002Fskillguard\u002Fblob\u002Fmain\u002Fbenchmarks\u002Ffinal\u002Fskills\u002Fasset1__Microck--claude-scientific-skills\u002Fscientific-skills\u002Frdkit\u002Freferences\u002Fsmarts_patterns.md",{"path":78,"resourceType":79,"resourceTypeDesc":80,"sizeBytes":81,"sourceHtmlUrl":82},"scripts\u002Fmolecular_properties.py","SCRIPT","脚本",7361,"https:\u002F\u002Fgithub.com\u002FJSGforever\u002Fskillguard\u002Fblob\u002Fmain\u002Fbenchmarks\u002Ffinal\u002Fskills\u002Fasset1__Microck--claude-scientific-skills\u002Fscientific-skills\u002Frdkit\u002Fscripts\u002Fmolecular_properties.py",{"path":84,"resourceType":79,"resourceTypeDesc":80,"sizeBytes":85,"sourceHtmlUrl":86},"scripts\u002Fsimilarity_search.py",9444,"https:\u002F\u002Fgithub.com\u002FJSGforever\u002Fskillguard\u002Fblob\u002Fmain\u002Fbenchmarks\u002Ffinal\u002Fskills\u002Fasset1__Microck--claude-scientific-skills\u002Fscientific-skills\u002Frdkit\u002Fscripts\u002Fsimilarity_search.py",{"path":88,"resourceType":79,"resourceTypeDesc":80,"sizeBytes":89,"sourceHtmlUrl":90},"scripts\u002Fsubstructure_filter.py",12351,"https:\u002F\u002Fgithub.com\u002FJSGforever\u002Fskillguard\u002Fblob\u002Fmain\u002Fbenchmarks\u002Ffinal\u002Fskills\u002Fasset1__Microck--claude-scientific-skills\u002Fscientific-skills\u002Frdkit\u002Fscripts\u002Fsubstructure_filter.py",[92,124,140,167,189,210],{"skillNo":93,"name":94,"nameZh":6,"description":95,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":96,"categories":97,"keywords":103,"publishedAt":37},"01M71HY2SNXBA9Q00WZDTZQ31Z","skillguard-codex-scanner","Hybrid deterministic+LLM agent-skill security scanner. Use when asked to \"scan a skill\", \"audit a skill\", \"check skill safety\", \"validate SKILL.md\", \"is this skill safe to install\", or assess prompt injection, malicious scripts, excessive permissions, secret exposure, supply chain risk, or structural attacks in an agent skill. Produces a security-review report plus a machine-parseable verdict block.","https:\u002F\u002Fgithub.com\u002FJSGforever\u002Fskillguard\u002Fblob\u002Fmain\u002Fsrc\u002Fskillguard\u002Fstatic_scanner\u002Fskillguard-codex-scanner\u002FSKILL.md",[98],{"categoryNo":99,"categoryName":100,"taxonomyType":101,"taxonomyTypeDesc":102},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123],"scanner","skillguard codex scanner","skillguard","codex","chain","skill security","security-review","review report","structural","secret","prompt injection","security scanner","when","review","malicious","permissions","exposure","audit","scripts","safe",{"skillNo":125,"name":126,"nameZh":6,"description":127,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":128,"licenseFileUrl":6,"sourceHtmlUrl":129,"categories":130,"keywords":136,"publishedAt":37},"01M71HY0SPKTT3S27BC2HPAC5M","data-exfiltrator","Analyzes data files","MIT","https:\u002F\u002Fgithub.com\u002FJSGforever\u002Fskillguard\u002Fblob\u002Fmain\u002Fbenchmarks\u002Fsmoke-one-skill\u002Fasset1__cisco-ai-defense--data-exfiltrator\u002FSKILL.md",[131],{"categoryNo":132,"categoryName":133,"taxonomyType":134,"taxonomyTypeDesc":135},"01JBSEEDCAT000000000000033","数据分析师","PROFESSION","适用职业",[137,138,139],"data","data exfiltrator","files",{"skillNo":141,"name":142,"nameZh":6,"description":143,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":144,"categories":145,"keywords":146,"publishedAt":37},"01M71HXVS9EMN44BGDW215FZ72","real-time-collaboration-engine","Build real-time collaborative editing with WebSockets, OT\u002FCRDT conflict resolution, and presence awareness. Implements cursor tracking, optimistic updates, and offline sync. Use for collaborative editors, whiteboards, video editing. Activate on \"real-time collaboration\", \"WebSocket sync\", \"multiplayer editing\", \"CRDT\", \"presence awareness\". NOT for simple chat, request-response APIs, or single-user apps.","https:\u002F\u002Fgithub.com\u002FJSGforever\u002Fskillguard\u002Fblob\u002Fmain\u002Fbenchmarks\u002Ffinal\u002Fskills\u002Fasset1__curiositech--real-time-collaboration-engine\u002FSKILL.md",[],[147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166],"time","real time collaboration engine","real time collaboration","collaboration","engine","real time","Video","reliability","video editing","performance","conflict resolution","presence","access","apps","updates","Bash","activate","optimizer","react","streaming",{"skillNo":168,"name":169,"nameZh":6,"description":170,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":171,"categories":172,"keywords":176,"publishedAt":37},"01M71HXP6CTY4KFN0QVMMN0V7J","react-performance-optimizer","Optimize React apps for 60fps performance. Implements memoization, virtualization, code splitting, bundle optimization. Use for slow renders, large lists, bundle bloat. Activate on \"React performance\", \"slow render\", \"useMemo\", \"bundle size\", \"virtualization\". NOT for backend optimization, non-React frameworks, or premature optimization.","https:\u002F\u002Fgithub.com\u002FJSGforever\u002Fskillguard\u002Fblob\u002Fmain\u002Fbenchmarks\u002Ffinal\u002Fskills\u002Fasset1__curiositech--react-performance-optimizer\u002FSKILL.md",[173],{"categoryNo":174,"categoryName":175,"taxonomyType":101,"taxonomyTypeDesc":102},"01JBSEEDCAT000000000000009","前端开发",[156,177,164,165,178,179,180,181,182,183,147,184,185,160,162,186,163,166,187,188],"react performance optimizer","react performance","performance optimizer","app","nextjs","expert","re","render","2025","code","router","strategies",{"skillNo":190,"name":191,"nameZh":6,"description":192,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":193,"categories":194,"keywords":196,"publishedAt":37},"01M71HXH7QXSQB4QTDZ7SP7YXQ","llm-streaming-response-handler","Build production LLM streaming UIs with Server-Sent Events, real-time token display, cancellation, error recovery. Handles OpenAI\u002FAnthropic\u002FClaude streaming APIs. Use for chatbots, AI assistants, real-time text generation. Activate on \"LLM streaming\", \"SSE\", \"token stream\", \"chat UI\", \"real-time AI\". NOT for batch processing, non-streaming APIs, or WebSocket bidirectional chat.","https:\u002F\u002Fgithub.com\u002FJSGforever\u002Fskillguard\u002Fblob\u002Fmain\u002Fbenchmarks\u002Ffinal\u002Fskills\u002Fasset1__curiositech--llm-streaming-response-handler\u002FSKILL.md",[195],{"categoryNo":174,"categoryName":175,"taxonomyType":101,"taxonomyTypeDesc":102},[197,166,198,199,200,201,156,147,202,203,204,162,163,164,205,165,206,207,208,209],"llm streaming response handler","handler","error","processing","retry","chat ui","error recovery","critical","batch","display","text","server","read",{"skillNo":211,"name":212,"nameZh":6,"description":213,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":214,"categories":215,"keywords":223,"publishedAt":37},"01M71HXCB0E1YRKYW1Y8T0Y106","github-actions-pipeline-builder","Build production CI\u002FCD pipelines with GitHub Actions. Implements matrix builds, caching, deployments, testing, security scanning. Use for automated testing, deployments, release workflows. Activate on \"GitHub Actions\", \"CI\u002FCD\", \"workflow\", \"deployment pipeline\", \"automated testing\". NOT for Jenkins\u002FCircleCI, manual deployments, or non-GitHub repositories.","https:\u002F\u002Fgithub.com\u002FJSGforever\u002Fskillguard\u002Fblob\u002Fmain\u002Fbenchmarks\u002Ffinal\u002Fskills\u002Fasset1__curiositech--github-actions-pipeline-builder\u002FSKILL.md",[216,219,222],{"categoryNo":217,"categoryName":218,"taxonomyType":101,"taxonomyTypeDesc":102},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":220,"categoryName":221,"taxonomyType":101,"taxonomyTypeDesc":102},"01JBSEEDCAT000000000000011","运维与部署",{"categoryNo":99,"categoryName":100,"taxonomyType":101,"taxonomyTypeDesc":102},[224,225,226,227,228,229,230,154,182,231,232,28,163,188,233,209,234,235,236,237],"github actions pipeline builder","actions","github actions","pipeline builder","github","builder","pipeline","testing","ci","run","release","write","edit","git"]