Cheminformatics and CPU numerical analytics for DuckDB - molecular formats, descriptors, fingerprints, similarity, regression, statistical inference, experimental design, time series, reliability and model evaluation from SQL
Compatibility Matrix
This table covers all DuckDB releases that have not reached end-of-life, including LTS releases, and shows the 2 most recent patch releases of each. Older patch releases are not listed, but the extension may be available for them as well.
| Platform | 1.4.4 | 1.4.5 | 1.5.5 | 1.5.6 | 2.0.0 |
|---|---|---|---|---|---|
| Linux AMD64 | |||||
| Linux ARM64 | |||||
| macOS AMD64 | |||||
| macOS ARM64 | |||||
| Windows AMD64 | |||||
| Windows ARM64 | |||||
| WebAssembly |
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;
-- CPU PCA on a numeric matrix, returning versioned JSON
SELECT chem_pca([[1.0,2.0],[2.0,4.0],[3.0,6.0]], [1.0,0.0]);
-- 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
418 SQL overloads, including the existing 151 molecular overloads and 267 CPU analytics functions. Molecular methods cover property extraction, format conversion, structural comparison, fingerprinting, similarity search, drug-likeness / toxicophore filtering, and structure-based virtual screening.
Function descriptions, meaningful argument names, runnable examples and
categories are discoverable through duckdb_functions() for every overload.
Filter with list_contains(categories, 'ducksmiles') after loading the extension.
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.
Mass context and native graphs:
formula_exact_mass()parses supported flat formulas strictly.adduct_neutral_mass()andadduct_precursor_mz()perform versioned arithmetic for 29 explicit adduct labels, including signed electron corrections.mol_graph_json()exports a versioned native atom/bond graph in input order with explicit hydrogen vertices, isotope, charge and raw stereo tokens. This sidecar is not pretrained-model tensors or full RDKit sanitization.- Unsupported or malformed inputs return NULL.
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.
CPU numerical analytics:
- 267 functions for descriptive/inferential statistics, regression, mixed/latent models, IRT/SEM, causal evaluation, experimental design, quality/reliability, time series, functional preprocessing, numeric text analysis and spatial models.
- Numeric matrices and ordered parameter lists; versioned JSON results, reusable fitted models, and NULL for invalid or resource-limited inputs. No GPU or Python runtime is required. Existing molecular methods remain available.
- Complete SQL examples, parameter contracts, validation evidence and remaining gaps are in the README. These are bounded partial method contracts; full JMP equivalence is not claimed.
The new bounded CPU methods include censored regression, estimated spatial covariance, static SVG histograms/box plots and ordered categorical ML with saved prediction. JMP default Lasso, sandwich inference and full plot options remain explicitly incomplete in the source README.
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.