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
Installing and Loading
INSTALL ducksmiles FROM community;
LOAD ducksmiles;
Example
-- Parse SMILES and get molecular formula
SELECT mol_formula('CCO');
-- C2H6O
-- Calculate molecular weight
SELECT round(mol_weight('c1ccccc1'), 2);
-- 78.11
-- Wildman-Crippen LogP and molar refractivity (match RDKit)
SELECT round(logp_crippen('CCO'), 4), round(mol_mr('c1ccccc1'), 3);
-- -0.0014, 26.442
-- QED drug-likeness score (RDKit Chem.QED, weights_mean)
SELECT round(qed('CC(=O)Oc1ccccc1C(=O)O'), 3);
-- 0.550 (aspirin)
-- 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
-- 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');
About ducksmiles
Cheminformatics toolkit for DuckDB - analyze molecular structures directly from SQL without leaving your database. Pure Rust implementation with no external chemistry library dependencies (no RDKit required).
Supported Formats:
- 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):
- 21 structural-profile functions: fragments, formal charge, hydrogen and bond counts, ring membership, elemental counts, fractions, isotope-aware heavy-atom mass and mean heavy-atom degree. A pinned RDKit 2025.09.6 reference suite checks 4,510 inputs; this is finite-corpus validation, not a guarantee of full RDKit parser/sanitizer equivalence.
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 RDKitChem.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()(Morgan/ECFP-style, radius 2 / 2048-bit default) andmaccs_keys()(167-bit MACCS). Morgan bit positions are not claimed to be identical to RDKit's MorganGenerator.- 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 asymmetrictversky_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).
Added Functions
| function_name | function_type | description | comment | examples |
|---|---|---|---|---|
| add_hydrogens | scalar | NULL | NULL | |
| admet_json | scalar | NULL | NULL | |
| asymmetric_bit | scalar | NULL | NULL | |
| bedroc | scalar | NULL | NULL | |
| braun_blanquet_bit | scalar | NULL | NULL | |
| canonical_smiles | scalar | NULL | NULL | |
| cosine_bit | scalar | NULL | NULL | |
| dice_bit | scalar | NULL | NULL | |
| dock | scalar | NULL | NULL | |
| druglikeness_pass | scalar | NULL | NULL | |
| enrichment_factor | scalar | NULL | NULL | |
| fraction_csp3 | scalar | NULL | NULL | |
| fragment_parent | scalar | NULL | NULL | |
| generic_scaffold | scalar | NULL | NULL | |
| inchi_charge | scalar | NULL | NULL | |
| inchi_connections | scalar | NULL | NULL | |
| inchi_formula | scalar | NULL | NULL | |
| inchi_has_stereo | scalar | NULL | NULL | |
| inchi_hydrogens | scalar | NULL | NULL | |
| inchi_is_standard | scalar | NULL | NULL | |
| inchi_is_valid | scalar | NULL | NULL | |
| inchi_num_stereo_centers | scalar | NULL | NULL | |
| inchi_skeleton_match | scalar | NULL | NULL | |
| inchi_stereo_bond | scalar | NULL | NULL | |
| inchi_stereo_tetrahedral | scalar | NULL | NULL | |
| inchi_version | scalar | NULL | NULL | |
| inchikey_connectivity | scalar | NULL | NULL | |
| inchikey_is_valid | scalar | NULL | NULL | |
| inchikey_protonation | scalar | NULL | NULL | |
| inchikey_stereo | scalar | NULL | NULL | |
| kulczynski_bit | scalar | NULL | NULL | |
| largest_fragment | scalar | NULL | NULL | |
| lipinski_violations | scalar | NULL | NULL | |
| logp_crippen | scalar | NULL | NULL | |
| maccs_keys | scalar | NULL | NULL | |
| mcconnaughey_bit | scalar | NULL | NULL | |
| mcs_json | scalar | NULL | NULL | |
| mcs_smarts | scalar | NULL | NULL | |
| mol_aromatic_fraction | scalar | NULL | NULL | |
| mol_block_atoms_json | scalar | NULL | NULL | |
| mol_block_bonds_json | scalar | NULL | NULL | |
| mol_block_centroid_x | scalar | NULL | NULL | |
| mol_block_centroid_y | scalar | NULL | NULL | |
| mol_block_centroid_z | scalar | NULL | NULL | |
| mol_block_formula | scalar | NULL | NULL | |
| mol_block_has_3d | scalar | NULL | NULL | |
| mol_block_json | scalar | NULL | NULL | |
| mol_block_max_x | scalar | NULL | NULL | |
| mol_block_max_y | scalar | NULL | NULL | |
| mol_block_max_z | scalar | NULL | NULL | |
| mol_block_min_x | scalar | NULL | NULL | |
| mol_block_min_y | scalar | NULL | NULL | |
| mol_block_min_z | scalar | NULL | NULL | |
| mol_block_name | scalar | NULL | NULL | |
| mol_block_num_atoms | scalar | NULL | NULL | |
| mol_block_num_bonds | scalar | NULL | NULL | |
| mol_block_properties_json | scalar | NULL | NULL | |
| mol_block_property | scalar | NULL | NULL | |
| mol_block_radius_of_gyration | scalar | NULL | NULL | |
| mol_block_weight | scalar | NULL | NULL | |
| mol_exact_mass | scalar | NULL | NULL | |
| mol_formal_charge | scalar | NULL | NULL | |
| mol_formula | scalar | NULL | NULL | |
| mol_has_substructure | scalar | NULL | NULL | |
| mol_hash | scalar | NULL | NULL | |
| mol_hash_methods | scalar | NULL | NULL | |
| mol_heavy_atom_mass | scalar | NULL | NULL | |
| mol_heteroatom_fraction | scalar | NULL | NULL | |
| mol_is_valid | scalar | NULL | NULL | |
| mol_largest_ring_size | scalar | NULL | NULL | |
| mol_mean_degree | scalar | NULL | NULL | |
| mol_mr | scalar | NULL | NULL | |
| mol_num_aromatic_atoms | scalar | NULL | NULL | |
| mol_num_aromatic_bonds | scalar | NULL | NULL | |
| mol_num_atoms | scalar | NULL | NULL | |
| mol_num_bonds | scalar | NULL | NULL | |
| mol_num_carbons | scalar | NULL | NULL | |
| mol_num_double_bonds | scalar | NULL | NULL | |
| mol_num_explicit_h | scalar | NULL | NULL | |
| mol_num_fragments | scalar | NULL | NULL | |
| mol_num_halogens | scalar | NULL | NULL | |
| mol_num_implicit_h | scalar | NULL | NULL | |
| mol_num_nitrogens | scalar | NULL | NULL | |
| mol_num_oxygens | scalar | NULL | NULL | |
| mol_num_ring_atoms | scalar | NULL | NULL | |
| mol_num_ring_bonds | scalar | NULL | NULL | |
| mol_num_single_bonds | scalar | NULL | NULL | |
| mol_num_total_h | scalar | NULL | NULL | |
| mol_num_triple_bonds | scalar | NULL | NULL | |
| mol_substructure_count | scalar | NULL | NULL | |
| mol_substructure_matches_json | scalar | NULL | NULL | |
| mol_weight | scalar | NULL | NULL | |
| morgan_fp_bits | scalar | NULL | NULL | |
| murcko_scaffold | scalar | NULL | NULL | |
| neutralize_charges | scalar | NULL | NULL | |
| normalize_smiles | scalar | NULL | NULL | |
| num_aliphatic_carbocycles | scalar | NULL | NULL | |
| num_aliphatic_heterocycles | scalar | NULL | NULL | |
| num_aliphatic_rings | scalar | NULL | NULL | |
| num_aromatic_carbocycles | scalar | NULL | NULL | |
| num_aromatic_heterocycles | scalar | NULL | NULL | |
| num_aromatic_rings | scalar | NULL | NULL | |
| num_h_acceptors | scalar | NULL | NULL | |
| num_h_donors | scalar | NULL | NULL | |
| num_heteroatoms | scalar | NULL | NULL | |
| num_rotatable_bonds | scalar | NULL | NULL | |
| num_saturated_carbocycles | scalar | NULL | NULL | |
| num_saturated_heterocycles | scalar | NULL | NULL | |
| num_saturated_rings | scalar | NULL | NULL | |
| pdb_to_pdbqt | scalar | NULL | NULL | |
| prepare_receptor | scalar | NULL | NULL | |
| qed | scalar | NULL | NULL | |
| ring_count | scalar | NULL | NULL | |
| ring_systems_json | scalar | NULL | NULL | |
| roc_auc | scalar | NULL | NULL | |
| russel_bit | scalar | NULL | NULL | |
| scaffold_network_json | scalar | NULL | NULL | |
| sdf_count | scalar | NULL | NULL | |
| sdf_properties_json | scalar | NULL | NULL | |
| sdf_property | scalar | NULL | NULL | |
| selfies_is_valid | scalar | NULL | NULL | |
| selfies_to_smiles | scalar | NULL | NULL | |
| smiles_to_pdbqt | scalar | NULL | NULL | |
| smiles_to_selfies | scalar | NULL | NULL | |
| sokal_bit | scalar | NULL | NULL | |
| strip_salts | scalar | NULL | NULL | |
| structural_alert_count | scalar | NULL | NULL | |
| structural_alerts_json | scalar | NULL | NULL | |
| structure_atom_count | scalar | NULL | NULL | |
| structure_centroid_x | scalar | NULL | NULL | |
| structure_centroid_y | scalar | NULL | NULL | |
| structure_centroid_z | scalar | NULL | NULL | |
| structure_chain_count | scalar | NULL | NULL | |
| structure_max_x | scalar | NULL | NULL | |
| structure_max_y | scalar | NULL | NULL | |
| structure_max_z | scalar | NULL | NULL | |
| structure_min_x | scalar | NULL | NULL | |
| structure_min_y | scalar | NULL | NULL | |
| structure_min_z | scalar | NULL | NULL | |
| structure_model_count | scalar | NULL | NULL | |
| structure_radius_of_gyration | scalar | NULL | NULL | |
| structure_residue_count | scalar | NULL | NULL | |
| tanimoto_bit | scalar | NULL | NULL | |
| tpsa | scalar | NULL | NULL | |
| tversky_bit | scalar | NULL | NULL |
Overloaded Functions
This extension does not add any function overloads.
Added Types
This extension does not add any types.
Added Settings
This extension does not add any settings.