diff --git a/extensions/ducksmiles/description.yml b/extensions/ducksmiles/description.yml index 34e9a6211..7ddd8737a 100644 --- a/extensions/ducksmiles/description.yml +++ b/extensions/ducksmiles/description.yml @@ -1,7 +1,7 @@ extension: name: ducksmiles - description: Cheminformatics toolkit for DuckDB - SMILES, InChI, MOL/SDF, PDB, SELFIES, Wildman-Crippen LogP, Morgan/ECFP fingerprints, and Tanimoto similarity from SQL - version: 0.4.0 + description: Cheminformatics toolkit for DuckDB - SMILES, InChI, MOL/SDF, PDB, SELFIES; descriptors (LogP, TPSA, QED), Morgan/MACCS fingerprints + similarity, drug-likeness/toxicophore filters, and a native in-silico docking pipeline, from SQL + version: 0.5.0 language: C++ build: cmake license: MIT @@ -10,7 +10,7 @@ extension: repo: github: nkwork9999/duckSMILES - ref: 51c796e9340e70c0ff8592771782916954fb4b08 + ref: 96c85cc2c895e5fdaecb3e2e30009d1201fa5103 docs: hello_world: | @@ -22,21 +22,32 @@ docs: SELECT round(mol_weight('c1ccccc1'), 2); -- 78.11 - -- Wildman-Crippen LogP (matches RDKit) - SELECT round(logp_crippen('CCO'), 4); - -- -0.0014 + -- Wildman-Crippen LogP and molar refractivity (match RDKit) + SELECT round(logp_crippen('CCO'), 4), round(mol_mr('c1ccccc1'), 3); + -- -0.0014, 26.442 - -- Morgan/ECFP fingerprint as 2048-bit BLOB (ECFP4 default) - SELECT bit_count(CAST(morgan_fp_bits('CC(=O)Oc1ccccc1C(=O)O') AS BIT)); - -- 26 (aspirin popcount) + -- QED drug-likeness score (RDKit Chem.QED, weights_mean) + SELECT round(qed('CC(=O)Oc1ccccc1C(=O)O'), 3); + -- 0.550 (aspirin) - -- Tanimoto similarity between two fingerprint BLOBs (no CAST AS BIT needed) + -- Drug-likeness rule panels + toxicophore alerts + SELECT lipinski_violations('CC(=O)Oc1ccccc1C(=O)O'), + druglikeness_pass('CC(=O)Oc1ccccc1C(=O)O', 'veber'), + structural_alerts_json('O=Cc1ccccc1'); + -- 0, 1, ["aldehyde","aldehyde_any"] + + -- Morgan/ECFP fingerprint + similarity between two BLOBs SELECT round(tanimoto_bit(morgan_fp_bits('CCO'), morgan_fp_bits('CCN')), 4); -- 0.3333 - -- Validate and extract InChI layers - SELECT inchi_formula('InChI=1S/C2H4O2/c1-2(3)4/h1H3,(H,3,4)'); - -- C2H4O2 + -- In-silico docking: SMILES ligand vs PDB receptor -> ranked poses (JSON) + SELECT dock('CCO', :receptor_pdb, 1.7,0.2,0.5, 8,8,8, 20, 42); + + -- Retrospective virtual-screening enrichment over a docked, labelled library + SELECT roc_auc(list(score), list(is_active)), + enrichment_factor(list(score), list(is_active), 0.01), + bedroc(list(score), list(is_active), 20.0) + FROM docked_library; -- Convert SMILES to SELFIES (ML-friendly notation) SELECT smiles_to_selfies('CCO'); @@ -47,32 +58,52 @@ docs: library dependencies (no RDKit required). **Supported Formats:** - - SMILES: Molecular validation, formula, weight, atom/bond counts, LogP - - InChI/InChIKey: Layer extraction, stereochemistry detection, skeleton matching - - MOL/SDF: V2000/V3000 block parsing, molecule counting - - PDB/CIF/XYZ: Protein structure analysis (atom, chain, residue, model counts) - - SELFIES: Bidirectional SMILES-SELFIES conversion for ML pipelines - - **39 scalar SQL functions** for molecular property extraction, format conversion, - structural comparison, and physicochemical property prediction. Ideal for - cheminformatics datasets, drug discovery pipelines, and molecular ML feature - engineering. - - **LogP:** `logp_crippen()` implements the Wildman-Crippen atom-contribution - method (110 SMARTS patterns, 68 atom types) and matches RDKit's - `Crippen.MolLogP` exactly for small molecules. - - **Morgan / ECFP fingerprint:** `morgan_fp_bits()` ports RDKit's MorganGenerator - (layered BFS + hash_combine + dead-atom dedup) to Rust and returns a fixed-width - bit vector as `BLOB`. Defaults to ECFP4 (radius=2, 2048 bit); 3-arg overload - `morgan_fp_bits(smi, radius, n_bits)` exposes full control. - - **Tanimoto similarity:** `tanimoto_bit(BLOB, BLOB) -> DOUBLE` computes - `popcount(a & b) / popcount(a | b)` directly on raw BLOB bytes (no - `CAST AS BIT` round-trip), processing 8 bytes at a time via `count_ones()` - so it lowers to POPCNT on x86_64 / CNT on aarch64. Mismatched lengths raise - a clear `InvalidInputException`; empty-vs-empty returns `0.0` (RDKit - convention). The SQL-level `bit_count(a & b)::DOUBLE / bit_count(a | b)` - is still available and produces bit-exact identical results. - - **Architecture:** Rust (core logic, 5 crates) + C++ (DuckDB integration via FFI) + - SMILES: validation, formula, weight, atom/bond counts, canonicalization, aromaticity + - InChI/InChIKey: layer extraction, stereochemistry detection, skeleton matching + - MOL/SDF: V2000/V3000 block parsing, 3D geometry, molecule counting + - PDB/CIF/XYZ: protein structure analysis (atom, chain, residue, model counts) + - SELFIES: bidirectional SMILES-SELFIES conversion for ML pipelines + + **130+ scalar SQL functions** for molecular property extraction, format conversion, + structural comparison, fingerprinting, similarity search, drug-likeness / + toxicophore filtering, and structure-based virtual screening. + + **Descriptors (RDKit-faithful ports):** + - `logp_crippen()` / `mol_mr()` - Wildman-Crippen LogP and molar refractivity. + - `tpsa()` - Ertl topological polar surface area. + - `qed()` - QED drug-likeness (Bickerton 2012), a port of RDKit `Chem.QED`. + - Lipinski set: `num_h_donors()`, `num_h_acceptors()`, `num_rotatable_bonds()`, + `fraction_csp3()`, `num_heteroatoms()`, and the full ring-count descriptor family. + + **Fingerprints & similarity:** + - `morgan_fp_bits()` (RDKit MorganGenerator, ECFP4 / 2048-bit default) and + `maccs_keys()` (167-bit MACCS). + - Full bit-fingerprint similarity family over raw BLOBs, faithful to RDKit + `DataStructs/BitOps.cpp`: `tanimoto_bit`, `dice_bit`, `cosine_bit`, `kulczynski_bit`, + `sokal_bit`, `mcconnaughey_bit`, `asymmetric_bit`, `braun_blanquet_bit`, + `russel_bit`, and asymmetric `tversky_bit(a, b, alpha, beta)`. + + **Structure tools:** SMARTS substructure search/counting, Bemis-Murcko and generic + scaffolds, scaffold networks, ring-system extraction, maximum common substructure + (MCS), and MolHash standardization. + + **Drug-likeness & toxicophore filtering:** + - `admet_json()` - a full report: descriptors plus six drug-likeness rule panels. + - `druglikeness_pass(smiles, rule)` for Lipinski, Veber, Ghose, Egan, Muegge and + Lead-likeness; `lipinski_violations()` for the Rule-of-Five count. + - `structural_alerts_json()` / `structural_alert_count()` over a curated + Brenk / PAINS reactive-group toxicophore catalogue. + + **In-silico docking pipeline (structure-based virtual screening, end-to-end in SQL):** + - `smiles_to_pdbqt()` - 3D conformer generation (distance geometry + an L-BFGS- + minimised lite force field with aromatic-ring planarity) emitted as PDBQT. + - `prepare_receptor(pdb, ph)` - pH-dependent protonation states + polar-hydrogen + addition, so the receptor can donate H-bonds. + - `dock(smiles, pdb, cx, cy, cz, sx, sy, sz, n_runs, seed [, ph])` - flexible + torsion-tree docking with an AutoDock-Vina-style scoring function and 3D affinity + maps; returns ranked poses with coordinates as JSON. + - Retrospective-validation harness: `roc_auc`, `enrichment_factor(fraction)`, + `bedroc(alpha)` to measure how well a docked library enriches known actives. + + **Architecture:** Rust (core logic, zero external chemistry crates) + C++ (DuckDB + integration via FFI).