$npx -y skills add LeonChaoX/qinyan-academic-skills --skill datamolPythonic wrapper around RDKit with simplified interface and sensible defaults. Preferred for standard drug discovery including SMILES parsing, standardization, descriptors, fingerprints, clustering, 3D conformers, parallel processing. Returns native rdkit.Chem.Mol objects. For ad
| 1 | # Datamol Cheminformatics Skill |
| 2 | |
| 3 | ## Overview |
| 4 | |
| 5 | Datamol is a Python library that provides a lightweight, Pythonic abstraction layer over RDKit for molecular cheminformatics. Simplify complex molecular operations with sensible defaults, efficient parallelization, and modern I/O capabilities. All molecular objects are native `rdkit.Chem.Mol` instances, ensuring full compatibility with the RDKit ecosystem. |
| 6 | |
| 7 | **Key capabilities**: |
| 8 | - Molecular format conversion (SMILES, SELFIES, InChI) |
| 9 | - Structure standardization and sanitization |
| 10 | - Molecular descriptors and fingerprints |
| 11 | - 3D conformer generation and analysis |
| 12 | - Clustering and diversity selection |
| 13 | - Scaffold and fragment analysis |
| 14 | - Chemical reaction application |
| 15 | - Visualization and alignment |
| 16 | - Batch processing with parallelization |
| 17 | - Cloud storage support via fsspec |
| 18 | |
| 19 | ## Installation and Setup |
| 20 | |
| 21 | Guide users to install datamol: |
| 22 | |
| 23 | ```bash |
| 24 | uv pip install datamol |
| 25 | ``` |
| 26 | |
| 27 | **Import convention**: |
| 28 | ```python |
| 29 | import datamol as dm |
| 30 | ``` |
| 31 | |
| 32 | ## Core Workflows |
| 33 | |
| 34 | ### 1. Basic Molecule Handling |
| 35 | |
| 36 | **Creating molecules from SMILES**: |
| 37 | ```python |
| 38 | import datamol as dm |
| 39 | |
| 40 | # Single molecule |
| 41 | mol = dm.to_mol("CCO") # Ethanol |
| 42 | |
| 43 | # From list of SMILES |
| 44 | smiles_list = ["CCO", "c1ccccc1", "CC(=O)O"] |
| 45 | mols = [dm.to_mol(smi) for smi in smiles_list] |
| 46 | |
| 47 | # Error handling |
| 48 | mol = dm.to_mol("invalid_smiles") # Returns None |
| 49 | if mol is None: |
| 50 | print("Failed to parse SMILES") |
| 51 | ``` |
| 52 | |
| 53 | **Converting molecules to SMILES**: |
| 54 | ```python |
| 55 | # Canonical SMILES |
| 56 | smiles = dm.to_smiles(mol) |
| 57 | |
| 58 | # Isomeric SMILES (includes stereochemistry) |
| 59 | smiles = dm.to_smiles(mol, isomeric=True) |
| 60 | |
| 61 | # Other formats |
| 62 | inchi = dm.to_inchi(mol) |
| 63 | inchikey = dm.to_inchikey(mol) |
| 64 | selfies = dm.to_selfies(mol) |
| 65 | ``` |
| 66 | |
| 67 | **Standardization and sanitization** (always recommend for user-provided molecules): |
| 68 | ```python |
| 69 | # Sanitize molecule |
| 70 | mol = dm.sanitize_mol(mol) |
| 71 | |
| 72 | # Full standardization (recommended for datasets) |
| 73 | mol = dm.standardize_mol( |
| 74 | mol, |
| 75 | disconnect_metals=True, |
| 76 | normalize=True, |
| 77 | reionize=True |
| 78 | ) |
| 79 | |
| 80 | # For SMILES strings directly |
| 81 | clean_smiles = dm.standardize_smiles(smiles) |
| 82 | ``` |
| 83 | |
| 84 | ### 2. Reading and Writing Molecular Files |
| 85 | |
| 86 | Refer to `references/io_module.md` for comprehensive I/O documentation. |
| 87 | |
| 88 | **Reading files**: |
| 89 | ```python |
| 90 | # SDF files (most common in chemistry) |
| 91 | df = dm.read_sdf("compounds.sdf", mol_column='mol') |
| 92 | |
| 93 | # SMILES files |
| 94 | df = dm.read_smi("molecules.smi", smiles_column='smiles', mol_column='mol') |
| 95 | |
| 96 | # CSV with SMILES column |
| 97 | df = dm.read_csv("data.csv", smiles_column="SMILES", mol_column="mol") |
| 98 | |
| 99 | # Excel files |
| 100 | df = dm.read_excel("compounds.xlsx", sheet_name=0, mol_column="mol") |
| 101 | |
| 102 | # Universal reader (auto-detects format) |
| 103 | df = dm.open_df("file.sdf") # Works with .sdf, .csv, .xlsx, .parquet, .json |
| 104 | ``` |
| 105 | |
| 106 | **Writing files**: |
| 107 | ```python |
| 108 | # Save as SDF |
| 109 | dm.to_sdf(mols, "output.sdf") |
| 110 | # Or from DataFrame |
| 111 | dm.to_sdf(df, "output.sdf", mol_column="mol") |
| 112 | |
| 113 | # Save as SMILES file |
| 114 | dm.to_smi(mols, "output.smi") |
| 115 | |
| 116 | # Excel with rendered molecule images |
| 117 | dm.to_xlsx(df, "output.xlsx", mol_columns=["mol"]) |
| 118 | ``` |
| 119 | |
| 120 | **Remote file support** (S3, GCS, HTTP): |
| 121 | ```python |
| 122 | # Read from cloud storage |
| 123 | df = dm.read_sdf("s3://bucket/compounds.sdf") |
| 124 | df = dm.read_csv("https://example.com/data.csv") |
| 125 | |
| 126 | # Write to cloud storage |
| 127 | dm.to_sdf(mols, "s3://bucket/output.sdf") |
| 128 | ``` |
| 129 | |
| 130 | ### 3. Molecular Descriptors and Properties |
| 131 | |
| 132 | Refer to `references/descriptors_viz.md` for detailed descriptor documentation. |
| 133 | |
| 134 | **Computing descriptors for a single molecule**: |
| 135 | ```python |
| 136 | # Get standard descriptor set |
| 137 | descriptors = dm.descriptors.compute_many_descriptors(mol) |
| 138 | # Returns: {'mw': 46.07, 'logp': -0.03, 'hbd': 1, 'hba': 1, |
| 139 | # 'tpsa': 20.23, 'n_aromatic_atoms': 0, ...} |
| 140 | ``` |
| 141 | |
| 142 | **Batch descriptor computation** (recommended for datasets): |
| 143 | ```python |
| 144 | # Compute for all molecules in parallel |
| 145 | desc_df = dm.descriptors.batch_compute_many_descriptors( |
| 146 | mols, |
| 147 | n_jobs=-1, # Use all CPU cores |
| 148 | progress=True # Show progress bar |
| 149 | ) |
| 150 | ``` |
| 151 | |
| 152 | **Specific descriptors**: |
| 153 | ```python |
| 154 | # Aromaticity |
| 155 | n_aromatic = dm.descriptors.n_aromatic_atoms(mol) |
| 156 | aromatic_ratio = dm.descriptors.n_aromatic_atoms_proportion(mol) |
| 157 | |
| 158 | # Stereochemistry |
| 159 | n_stereo = dm.descriptors.n_stereo_centers(mol) |
| 160 | n_unspec = dm.descriptors.n_stereo_centers_unspecified(mol) |
| 161 | |
| 162 | # Flexibility |
| 163 | n_rigid = dm.descriptors.n_rigid_bonds(mol) |
| 164 | ``` |
| 165 | |
| 166 | **Drug-likeness filtering (Lipinski's Rule of Five)**: |
| 167 | ```python |
| 168 | # Filter compounds |
| 169 | def is_druglike(mol): |
| 170 | desc = dm.descriptors.compute_many_descriptors(mol) |
| 171 | return ( |
| 172 | desc['mw'] <= 500 and |
| 173 | desc['logp'] <= 5 and |
| 174 | desc['hbd'] <= 5 and |
| 175 | desc['hba'] <= 10 |
| 176 | ) |
| 177 | |
| 178 | druglike_mols = [mol for mol in mo |