chematic
A cheminformatics library for Python, Rust, and the browser.
Cheminformatics that's fast by default, safe by design.
Pure Rust · Zero C/C++ · Python · WebAssembly · Live Demo
| chematic | RDKit (Python) | RDKit.js (WASM) | |
|---|---|---|---|
| Get started | pip install chematic |
conda / cmake required | no Python bindings |
| Browser bundle | 719 KB | not available | ~30 MB (~42× larger) |
| Batch fingerprints | ~78 µs/mol (2–3× faster) | ~160–235 µs/mol | — |
| Memory safety | compiler-enforced (Rust) | C++ | C++ |
| Build from source | cargo build only |
cmake + clang + Boost | Emscripten SDK |
All numbers are reproducible — see benchmark details.
WASM sizes: chematic 719 KB · RDKit.js ~30 MB · Indigo WASM ~40 MB
Feature maturity at a glance:
| Feature | Status |
|---|---|
| SMILES / SMARTS / fingerprints / descriptors | Stable |
| 3D conformer generation (DG + MMFF94) | Experimental |
| pKa / ADMET | Rule-based screening (not for clinical use) |
| IUPAC name generation | Partial (25+ classes) |
| Pure-Rust InChI | Approximate (enable native-inchi feature for exact) |
What you get
$ python -c "import chematic; print(chematic.from_smiles('CC(=O)Oc1ccccc1C(=O)O').describe())"
Molecular weight 180.2 Da, formula C9H8O4.
LogP 1.31 (mildly lipophilic), TPSA 63.6 Ų.
HBD 1, HBA 3, 3 rotatable bond(s), 1 aromatic ring(s).
Drug-likeness: no Lipinski rule-of-5 violations. likely orally bioavailable (passes Veber criteria).
QED 0.56 (0 = non-drug-like, 1 = ideal).
Structural alerts: Brenk alert.
One pip install. No RDKit, no conda, no C compiler. Works in Python, Rust, the browser, and AI agents.
# HTML report — self-contained, opens in any browser and renders in Jupyter
mols = [chematic.from_smiles(s) for s in smiles_list]
report = chematic.report(mols, names=compound_names)
report.save("report.html") # or: display(report) in Jupyter
# Side-by-side comparison
cmp = chematic.compare(aspirin, ibuprofen, names=("Aspirin", "Ibuprofen"))
cmp.save("compare.html")
Common Use Cases
| Scenario | How chematic helps |
|---|---|
| HTML report | chematic.report(mols, output="report.html") — self-contained compound grid, no server needed |
| Drug screening | 190+ descriptors, ADMET, PAINS/Brenk, QED — batch over thousands of compounds |
| Molecule search | ECFP4/MACCS fingerprints, Tanimoto, LSH approximate nearest-neighbour |
| AI agent / MCP | Built-in MCP server — Claude Desktop can call chemistry tools directly |
| Browser app | 719 KB WASM bundle, zero backend required, React/Vue/Svelte ready |
| Jupyter notebook | mol renders SVG inline; descriptors_df() returns a pandas DataFrame |
| Batch analysis | Rayon-parallel descriptor/fingerprint/3D pipelines; SDF/CSV in, CSV out |
| Rust server | Pure-Rust crates with no C/C++ toolchain; Axum/Actix compatible |
Full worked examples → Use cases
When to use chematic
Use chematic if:
- You want chemistry in the browser (WASM, 719 KB, no server required)
- You need a pure Rust stack with no C++ toolchain dependencies
- You deploy to environments where
pip install rdkitis impractical (Cloudflare Workers, Lambda, embedded) - You build AI agents and want native MCP tool integration
- You process molecules in batch at high throughput (ECFP4: 2–3× faster than RDKit, Rayon-parallel)
- You want
pip install chematicto just work — anywhere, no compiler needed
Use RDKit if:
- You need maximum ecosystem compatibility and 20+ years of production validation
- You need publication-quality 3D structures with ML-assisted torsion corrections (RDKit's ETKDGv3)
- You need bit-exact standard InChI without enabling the
native-inchifeature - You depend on community plugins written against the RDKit Python API
Quick Start
Installation
# Python — no C/C++ compiler required
pip install chematic
# Rust
cargo add chematic --features "smiles,perception,chem,3d,fp"
# JavaScript/TypeScript
npm install @kent-tokyo/chematic
Python
import chematic
mol = chematic.from_smiles("CC(=O)Oc1ccccc1C(=O)O") # aspirin
# In Jupyter, type `mol` in a cell — 2D structure renders automatically
mol
# Access 190+ descriptors as properties
print(mol.mw, mol.logp, mol.tpsa) # 180.16 1.31 63.6
print(mol.lipinski_passes, mol.pains_passes) # True True
# Substructure search
mol.has_substructure("[OH]") # True
mol.find_matches("[CX3](https://github.com/kent-tokyo/chematic/blob/main/=O)O") # → [[1, 2, 3], [7, 8, 9]]
# Natural-language summary (one paragraph)
print(mol.describe())
# Structured Markdown report — paste into LLM, Jupyter, or save as .md
print(mol.review())
# → # Molecular Review\n## Structure\n## Physical Properties\n## Drug-likeness\n## ADMET...
# Structural diff between two molecules
ibuprofen = chematic.from_smiles("CC(C)Cc1ccc(CC(C)C(=O)O)cc1")
d = mol.diff(ibuprofen) # {"summary": "+C7, -O2. ΔLogP +2.75 ...", "delta_mw": 66.1, ...}
# Batch processing — parallel, numpy-ready
fps = chematic.bulk.ecfp4(["CCO", "c1ccccc1", "CC(=O)O"]) # (3, 2048) uint8
# One-liner DataFrame
df = chematic.descriptors_df(["CCO", "c1ccccc1", "CC(=O)O"])
df[["mw", "logp", "tpsa", "qed"]]
For Rust and JavaScript/TypeScript examples, see the documentation.
Migrating from RDKit
chematic.rdkit_compat provides a lightweight RDKit-compatible subset so existing scripts port with minimal changes:
from chematic import rdkit_compat as Chem
from chematic.rdkit_compat import Descriptors, rdMolDescriptors, DataStructs
mol = Chem.MolFromSmiles("CC(=O)Oc1ccccc1C(=O)O")
Descriptors.MolWt(mol) # 180.16
fp = rdMolDescriptors.GetMorganFingerprintAsBitVect(mol, 2, nBits=2048)
DataStructs.TanimotoSimilarity(fp, fp) # 1.0
It is not a full RDKit clone, and unsupported options fail loudly. See the RDKit compatibility guide for the compatibility matrix, differential-validation results vs RDKit, and runnable examples.
Diagnostics
import chematic
chematic.doctor()
# chematic v0.4.30
# Python 3.12.x | darwin arm64
#
# Descriptor accuracy (benchmark 2026-07-17, v0.4.30 vs RDKit 2026.03.3):
# MW / HBA / HBD / ARC 100% (4,999-mol ChEMBL subset)
# TPSA 100% within ±0.1 Ų
# LogP (Crippen) 100%* (max Δ = 1.1×10⁻¹³)
# Stereocenter count 99.96% (legacy) / 98.6% (new CIP FindPotentialStereo)
# CIP R/S label 96.30% vs modern rdCIPLabeler (96.83% vs legacy)
# ...
For AI / LLM Developers
chematic ships a native MCP (Model Context Protocol) server — the first cheminformatics library with built-in AI agent integration.
// Claude Desktop (~/.config/claude/claude_desktop_config.json)
{
"mcpServers": {
"chematic": { "command": "chematic-mcp" }
}
}
20 chemistry tools are callable from any MCP-compatible agent (full list in the
chematic-mcp README):
| Tool | What it does |
|---|---|
name_to_smiles |
Resolve "aspirin", "caffeine", … to SMILES via PubChem (the only tool that makes a network call) |
calc_properties |
MW, exact mass, Crippen LogP, TPSA, HBD, HBA, rotatable bonds, QED |
smarts_match |
Substructure search |
pains_check / brenk_check |
Flag assay interference or reactive groups |
generate_3d |
3D coordinates via rule-based placement + DREIDING force-field minimization |
find_mcs |
Maximum common substructure |
| + 13 more | ecfp4, tanimoto, canonical_smiles, admet_profile, boiled_egg, sa_score, lipinski_check, retrosynthesis, smiles_to_moljson, moljson_to_smiles, representation_router, molecule_context_pack, parse_smiles |
Transport: stdio (JSON-RPC 2.0 over stdin/stdout) only. Runs as a local process; there is no hosted Remote MCP endpoint, no authentication, and no public service SLA — a remote-ready refactor is under consideration but not implemented.
Why Pure Rust?
Fast
Rust's zero-cost abstractions and ownership model eliminate overhead at the source.
chematic's ECFP4 fingerprint batch pipeline runs at ~78 µs/mol on a diverse
molecule corpus — 2–3× faster than RDKit's Python API on the same hardware, via
Rayon parallelism across all CPU cores. No GIL, no interpreter overhead, no FFI
call overhead hidden inside a _sys crate.
Safe
chematic's own ~15,000 lines of Rust contain ~6 unsafe blocks, all confined to the
optional native-inchi FFI layer (below). No C++ heap corruptions. No segfaults from
malformed SMILES input. No platform-specific build failures from -sys crates. The
compiler enforces memory safety at every call site chematic itself wrote.
The
native-inchifeature is the single opt-in exception — it vendors the IUPAC InChI C library (v1.07.5) for bit-exact standard InChI. All other chematic crates stay FFI-free and unsafe-free. This count is chematic's own source only, not its dependency tree — the optionaldepictfeature (SVG/PDF/EPS rendering) pulls in a font/image-rendering stack (resvg/usvg/rustybuzz/tiny-skia/zune-jpeg) that is not unsafe-free; see the comparison table footnote below for a measured count.
Anywhere
Pure Rust compiles to wasm32-unknown-unknown natively — no Emscripten, no cmake,
no clang. The npm package @kent-tokyo/chematic is 719 KB gzip — ~42× smaller
than RDKit.js. One codebase runs on Linux, macOS, Windows, and in every browser.
Benchmarks & Validation
| Metric | Result | Corpus |
|---|---|---|
| ECFP4 throughput | ~78 µs/mol (2–3× vs RDKit, diverse corpus) | 5,000-mol ChEMBL subset |
| HBA / HBD / aromatic ring count | 100% RDKit agreement | 4,999-mol ChEMBL subset |
| TPSA | 100% RDKit agreement within ±0.1 Ų | 4,999-mol ChEMBL subset |
| LogP (Crippen) | 100% RDKit agreement* | 4,999-mol ChEMBL subset |
| Stereocenter count | 99.96% vs legacy†; 98.6% vs new CIP | 4,999-mol ChEMBL subset |
| CIP R/S label agreement | 96.30% vs modern rdCIPLabeler‡; 96.83% vs legacy |
5,000-mol ChEMBL subset |
| WASM bundle | 719 KB gzip | — |
*LogP max Δ = 1.1×10⁻¹³ across 4,999 molecules — within float64 rounding error.
†Stereocenter count: ~99.96% vs legacy CalcNumAtomStereoCenters (a handful of molecules where chematic matches FindPotentialStereo and legacy under-counts); ~98.6% vs new-CIP FindPotentialStereo (cage/bridgehead molecules where both chematic and legacy correctly return fewer than the new oracle). chematic is calibrated between both extremes. This measures whether an atom is flagged as a stereocenter, not whether its R/S label is correct — see the next row.
‡CIP R/S label agreement measures, for atoms both oracles agree are stereocenters, whether the assigned R/S descriptor matches — a stricter, separate check from stereocenter count agreement above. This row is chematic's default assign_cip() path. The separate chematic-cip engine now reaches 99.38% raw / 99.64% oracle-stable (Milestone 4 gate closed) and is reachable opt-in via assign_cip_with_mode(mol, CipMode::Accurate) (Rust), Mol.cip_stereo(mode="accurate") (Python), or cip_assignments_accurate_json (WASM) — see docs/cip_accurate_rfc.md. No default path changed; this row's 96.30% is unaffected.
All numbers are reproducible with the scripts in this repo.
Full history → benchmarks/ · Methodology → validation/
Comparison with Other Cheminformatics Libraries
| Feature | chematic | RDKit (rdkit-sys) | OpenBabel FFI | RDKit.js (WASM) |
|---|---|---|---|---|
| C/C++ dependencies | None (default)† | Extensive C++ | Extensive C++ | C++ via Emscripten |
| WASM binary size | ~1.9 MB (719 KB gzip) | N/A (no WASM) | N/A (no WASM) | ~30 MB |
| Build requirement | cargo build only |
cmake + clang | cmake + clang | Emscripten SDK |
| WASM target support | Full (native) | No | No | Yes (Emscripten) |
| Python bindings | Yes (pip install chematic, PyO3) |
Yes (rdkit-sys) | Yes | No |
| Unsafe Rust | None in own crates‡ | Extensive | Extensive | N/A |
| Feature | chematic | RDKit (rdkit-sys) | OpenBabel FFI | RDKit.js (WASM) |
|---|---|---|---|---|
| OpenSMILES parser | Full | Full | Full | Full |
| SMILES writer / canonical | Yes | Yes | Yes | Yes |
| Kekulization | 4-pass (incl. Edmonds' blossom) | Yes | Yes | Yes |
| Ring perception (SSSR) | Yes + iterative augmentation | Yes | Yes | Yes |
| SDF/MOL V2000+V3000 + SD fields | Yes | Yes | Yes | Yes |
| Tripos MOL2 format | Yes (parser + writer) | Yes | Yes | No |
| 2D depiction (SVG, CPK colors, PDF, EPS) | Yes | Yes | Yes | Yes |
| ECFP/FCFP fingerprints (2/4/6) | All variants + bitvec | Yes | Yes | Yes |
| AtomPair / Torsion / MACCS FP | Yes | Yes | Yes | Yes |
| MAP4 fingerprint | Yes (Minervini 2020) | No (external pkg) | No | No |
| Molecular descriptors | 190+ descriptor values (71 functions; MQN×42, BCUT2D, autocorr2d return multi-value arrays) | ~30 | ~20 | ~30 |
| Topological descriptors | Yes (Petitjean, Hosoya Z, ECI, Moran, Geary) | Partial | Partial | No |
| BRICS / RECAP fragmentation | Yes | Yes | No | Yes |
| Murcko scaffold | Yes | Yes | No | Yes |
| Tautomer normalisation | Yes | Yes | No | Yes |
| MCS | Yes | Yes | No | Yes |
| Stereoisomer enumeration | Yes | Yes | No | Yes |
| CIP stereo (R/S, E/Z) detail | Yes (per-atom JSON) | Yes | Yes | Yes |
Allene cumulated stereo (C=C=C) |
Yes (@/@@, round-trip stable) |
Yes | Partial | No |
| 3D coordinate generation | Yes (DG + MMFF94/DREIDING + L-BFGS) | Yes (ETKDG) | Yes | Yes |
| 3D shape descriptors (PMI/NPR/USR/…) | Yes | Yes | No | Yes |
| 3D GETAWAY descriptors (HATS-matrix) | Yes (19-dim; whim_getaway_combined 29-dim) |
Yes | No | No |
| MMFF94 force field (all 7 energy terms) | Yes | Yes | Yes | No |
| UFF force field (metals, organometallics) | Yes | No | Yes | No |
| AutoDock PDBQT format (parse + write) | Yes (docking pipeline ready) | Via Python API | Yes | No |
| SDF with partial charges | Yes (write_sdf_with_charges) |
Yes | Yes | No |
| MaxMin / Butina diversity picking | Yes | Yes | No | No |
| Reaction SMILES/SMIRKS | Yes | Yes | Yes | Yes |
| InChI / InChIKey | Yes — pure-Rust + IUPAC-exact via native-inchi |
C lib required | C lib required | C lib required |
| pKa prediction | Yes (15 SMARTS rules) | No | No | No |
| ADMET profile (BBB/Caco-2/hERG/CYP3A4) | Yes + BOILED-Egg | Partial | No | Partial |
| MCP server (AI agent API) | Yes — 20 tools incl. Name→SMILES (stdio only) | No | No | No |
| IUPAC name generation | Yes (25+ classes) | No | No | Partial |
| Name → SMILES (PubChem proxy) | Yes (name_to_smiles MCP tool) |
No | No | No |
| Maintenance (2026) | Active | Active | Minimal | Active |
† Default build only. The optional native-inchi feature adds a C-compiler dependency for the vendored IUPAC InChI C library (v1.07.5). This is about C/C++ FFI specifically — the depict feature below pulls in pure-Rust rendering crates, so it doesn't add a C compiler dependency even though it isn't unsafe-free (see ‡).
‡ chematic's own ~15,000 lines of Rust: unsafe-free outside native-inchi's ~6 FFI blocks (see "Safe" above) — a real, verifiable claim about code chematic wrote, and categorically different from RDKit/OpenBabel's C++ FFI unsafe (uncheckable by any compiler at that boundary) even where the raw count is comparable. It is not true of the full dependency tree: the optional depict feature (SVG/PDF/EPS rendering) pulls in resvg/usvg/rustybuzz/tiny-skia/zune-jpeg, pure-Rust crates that are themselves not unsafe-free — measured directly (unsafe fn/impl/trait/{ openings): tiny-skia 151, zune-jpeg 79, rustybuzz 14, image 8, fontdb 3, tiny-skia-path 3 (258 total in this set alone). chematic-py (pip install chematic) and the npm package both depend on chematic-depict directly, so this applies to both real-world install paths, not just an edge case.
JavaScript / TypeScript (WebAssembly)
719 KB gzip — ~42× smaller than RDKit.js. No Emscripten, no cmake. Drop-in for browser or Node.js.
npm install @kent-tokyo/chematic
import init, { parse_smiles, get_descriptors_json, tanimoto_ecfp4,
generate_3d_minimized_pdb, enumerate_stereo_isomers_json,
maxmin_picks_ecfp4_json } from '@kent-tokyo/chematic';
await init();
const mol = parse_smiles('CC(=O)Oc1ccccc1C(=O)O'); // aspirin
console.log(mol.molecular_weight(), mol.qed(), mol.lipinski_passes());
// All descriptors as a JSON object
const desc = JSON.parse(get_descriptors_json(mol));
// Fingerprint similarity
const caffeine = parse_smiles('Cn1cnc2c1c(=O)n(c(=O)n2C)C');
console.log(tanimoto_ecfp4(mol, caffeine)); // 0.26
// 3D coordinates, stereoisomers, diversity picking
const pdb = generate_3d_minimized_pdb(mol);
const isomers = JSON.parse(enumerate_stereo_isomers_json(parse_smiles('C(F)(Cl)Br')));
const picks = JSON.parse(maxmin_picks_ecfp4_json('["CC","c1ccccc1","CCO","CCCC"]', 2));
130+ exported functions cover descriptors, fingerprints, 3D geometry, reactions, diversity picking, and SDF round-trips. See the full WASM API reference for all exports.
Crate Reference
| Crate | Description | Tests |
|---|---|---|
chematic-core |
Atom, Bond, Molecule, Element, kekulization (no deps); mutable add/remove_atom/bond, fragments(), is_connected(), formula_with_isotopes, validate_valence; StereoGroup/StereoGroupKind |
71 |
chematic-smiles |
OpenSMILES parser, writer, canonical SMILES; stereo parity correction (pre-solves RDKit #8775 — @/@@ auto-flipped on odd permutations); allene cumulated double bond stereo (C=C=C @/@@, round-trip stable) |
109 |
chematic-perception |
SSSR, Hückel aromaticity + antiaromaticity (4n+2 rule), apply_aromaticity, aromatize/kekulize_inplace, assign_stereo_from_2d, assign_ez_from_2d, cip_ez_descriptor; zero-order/dative bonds excluded from ring perception |
101 |
chematic-mol |
MOL/SDF V2000+V3000 (R/W with 2D coords, +partial charge writing), CML (R/W), CDXML (R); SdfRecord with coords+props; MDL RXN R/W; V3000 stereo-group COLLECTION R/W; AutoDock PDBQT (parse + write); ChemicalJSON (parse_cjson/write_cjson, Avogadro/MolSSI format) |
130 |
chematic-depict |
2D SVG (CPK colors, highlighting, grid), DepictData, detect_crossings, render_svg_with_metadata, reaction SVG; PDF output (depict_pdf/depict_pdf_opts via svg2pdf); EPS output (depict_eps/depict_eps_opts, pure Rust); tiny_skia PNG is optional png feature (default on, disabled for WASM) |
64 |
chematic-chem |
190+ descriptor values (71 functions), tautomers, scaffold, BRICS, QED, standardize, CIP; pKa prediction (15 SMARTS rules); ADMET profile (BBB/Caco-2/hERG/CYP3A4); HBA 100% RDKit agreement (4 999 / 4 999 mol benchmark); TPSA 100% ±0.1 Ų / LogP 100%* / HBD 100% / stereocenter count 99.96% (legacy) / 98.6% (new CIP) vs RDKit (4,999-mol ChEMBL); CIP R/S label agreement 96.30% (default), 99.64% oracle-stable via opt-in CipMode::Accurate (5,000-mol ChEMBL, see docs/cip_accurate_rfc.md); topological descriptors (petitjean_index, graph_diameter, graph_radius, graph_eccentricities, eccentric_connectivity_index, hosoya_index, moran_autocorr, geary_autocorr); schultz_mti, gutman_mti, vabc (Bondi radii vdW volume), gravitational_index; clean_stereo_groups() in standardize |
662 |
chematic-fp |
ECFP2/4/6, FCFP4/6, MACCS, TopoPF, AtomPair, Torsion, Layered, Pattern, Pharmacophore, Reaction, MAP4 (Minervini 2020, not in RDKit) — Tanimoto/Dice; bulk similarity | 185 |
chematic-ff |
MMFF94 all 7 terms (Halgren 1996): Bond/Angle/Torsion/vdW/Elec + OOP (117 entries) + Stretch-Bend (282 entries); steepest-descent + L-BFGS optimizer, torsion scan, energy breakdown; DREIDING typing; UFF (metals/organometallics: Zn, Fe, Cu, …) | 98 |
chematic-smarts |
SMARTS, VF2, MCS with chirality matching; SmartsCache (LRU compilation cache, 5–20×); named_pattern() library (20 functional group patterns); atom map :N in SMARTS ([O;D1;H0:3] — stored as metadata, not a match criterion); [kN] ring-size primitive; VF2 early-exit when query > target atom count; find_matches_with_rings — share SSSR across multi-pattern batches |
142 |
chematic-3d |
3D coordinate generation, distance geometry constraints, ETKDG KB (40 torsion patterns, adaptive noise), force-field minimization, shape descriptors, ConformerEnsemble with RMSD pruning, PDB/XYZ; GETAWAY HATS-matrix (full 19-dim implementation); whim_getaway_combined() now 29-dim |
265 |
chematic-rxn |
Reaction SMILES/SMIRKS, run_reactants/run_reactants_strict; retro_disconnect() — 60 retro-SMIRKS templates (AmideBond/Ester/Ether/CNBond/CCBond/CSBond) + SA Score ranking; parity-aware @/@@ SMIRKS stereo filtering; E/Z double-bond stereo filtering in run_reactants (ez_stereo_outward, smirks_ez_stereo_ok) |
137 |
chematic-inchi |
InChI/InChIKey: pure-Rust approximation (WASM) + IUPAC-standard via native-inchi feature (vendored C lib 1.07.5, bit-exact); parse_inchi reader |
96 (+16*) |
chematic-wasm |
130+ WASM exports — npm: @kent-tokyo/chematic v0.4.30 (~1.9 MB, 719 KB gzip); pKa/ADMET/BBB/Caco-2/hERG/CYP3A4; smiles_to_pdbqt, minimize_uff_json |
211 |
chematic-iupac |
Local IUPAC name generation — 25+ compound classes: alkanes, cycloalkanes, alkenes/alkynes, alcohols, amines, halides, aldehydes, ketones, acids, esters, amides, piperidine, morpholine, piperazine, naphthalene, sulfides | 47 |
chematic-mcp |
MCP (Model Context Protocol) server — AI agent integration; 20 tools: parse_smiles, calc_properties, ecfp4, tanimoto, smarts_match, canonical_smiles, find_mcs, generate_3d, pains_check, brenk_check, sa_score, admet_profile, boiled_egg, lipinski_check, name_to_smiles, retrosynthesis, smiles_to_moljson, moljson_to_smiles, representation_router, molecule_context_pack | 31 |
chematic-py |
PyO3 Python bindings (pip install chematic); 300+ API endpoints: from_smiles(), Mol.descriptors(), Mol.minimize_dreiding(), from_cxsmiles(), from_rxn_file()/to_rxn_file(), parse_sdf_with_coords(), Mol.ring_families(), tanimoto_matrix(), iter_sdf(), SimilarityIndex; mol.to_pdf()/mol.to_eps() (depict); from_cjson()/mol.to_cjson() (ChemicalJSON); mol.schultz_mti, mol.gutman_mti, mol.vabc, mol.gravitational_index; bulk.substructure_match(smarts, mols) (parallel VF2 on pre-parsed Mol objects); mol.describe() (LLM/MCP-ready natural-language summary); mol.diff(other) (element + descriptor diff); Sprint 18–27 coverage |
300+ |
chematic-ewald |
PME Ewald summation, B-spline interpolation (cubic, phase-corrected) | 16 |
chematic |
Umbrella crate with feature flags (all sub-crates, incl. iupac, inchi) |
1 |
cargo test --workspace --lib --quiet # 2,366 tests, all passing
cargo test -p chematic-inchi --features native-inchi --test standard_inchi # +16 IUPAC-exact InChI tests
Recent Development (v0.4.x Era)
v0.4.30 (2026-07-17): chematic-cip opt-in wired to every surface, SMARTS [rN] fix, new RDKit-parity aromaticity engine, 5 stereo-metadata bug fixes
chematic-smarts: fixed[rN](ring-size SMARTS, e.g.[r5]/[r6]) being wrongly aliased to[kN]'s any-ring semantics — RDKit's real[rN]means "this atom's smallest ring is exactly size N", a materially different predicate (confirmed empirically: on a fusion atom shared between a 5-ring and 6-ring, RDKit's[k6]matches but[r6]doesn't). No ring-model change —[rN]now has its ownMinRingSizeprimitive computed from chematic's existing SSSR. SMARTS match-set agreement vs RDKit 96.9% → 99.93% on a 5,000-molecule corpus, 0 regressions; seedocs/rdkit_compat.md's "SMARTS-R0"/"SMARTS-R1" entries- Milestone 5A: opt-in access to the accurate engine from every public surface —
chematic_chem::assign_cip_with_mode(mol, CipMode::Accurate)(Rust),Mol.cip_stereo(mode="accurate")+Mol.cip_stereo_unresolved()(Python),cip_assignments_accurate_json/cip_unresolved_json(WASM). Every default (assign_cip(),cip_stereo(), the un-suffixed WASM functions) is unchanged — this is additive only, not a default switch; seedocs/cip_accurate_rfc.md's Milestone 5A entry for the merge semantics (accurate tetrahedral R/S + legacy E/Z, since the accurate engine doesn't compute bond stereo) and the "never guess" contract (ties/budget-outs surface explicitly, never silently backfilled) - Milestone 4 gate closed: 99.64% oracle-stable agreement (raw 99.38%, 4160/4186) on a full-corpus, representation-stability-stratified score — the last residual (11 phosphorus cyclophosphazene rows) turned out to be an oracle instability (RDKit's own labels change under a chemically-neutral Kekulé respelling of the identical molecule), not a chematic defect; the 15-row Rule 5 cage family remains deferred, unaffected by this gate
- The accurate engine (a provenance-carrying, sphere-by-sphere digraph comparator — Rules 1a/1b/2 — plus RDKit-compatible MANCUDE fractional atomic numbers for aromatic ring stereocenters) is available through the opt-in APIs above but is not yet the default implementation behind
assign_cip() - Found and fixed a real ~10-14x perf regression (SSSR misused for a boolean ring-bond check, replaced with an O(V+E) bridge-edge DFS); CI Criterion-gate bootstrap fix; a Criterion-gate reliability finding (pseudo-replication, #70) — process-level redesign (independent process-run observations, two-stage screening, same-binary null control) landed. Follow-up (#117) fixed two further, more specific bugs found via real CI runs: Stage 1's 3-block sign-test could structurally never fail (replaced with a pure magnitude-routing screen, threshold chosen from an offline evaluation against 28 historical no-op runs) and Stage 2's sign-test was independently magnitude-blind to small build/codegen variance (fixed with a combined sign-test + practical-effect-threshold gate). The gate stays non-required; the same-binary null control's blind spot to cross-binary codegen variance is a known, reported, not-yet-fixed gap
- Milestone 4A:
CipCode::LowerR/LowerS— Rule 5 (pseudoasymmetry), scoped to 2 verified-independent rows; a three-armed symmetric-cage family (15 rows) was found to be provably unreachable by this pairwise architecture and deferred as Milestone 4A-2 (needs symmetry/automorphism detection) - Milestone 4A-0: re-froze the residual fresh at 34 rows and mechanically classified 100% of it (0 unexplained) — 15 Rule 5/pseudoasymmetry (the 4A-2 cage family), 8 Rule 4 candidate (positively confirmed via a structural-identity check, not inferred), 11 phosphorus (9 comparator-bug "wrong" + 2 genuinely-tied)
chematic-perception: new opt-inassign_aromaticity_rdkit_parity_experimental/apply_aromaticity_rdkit_parity_experimental— a source-verified port of RDKit's actual aromaticity algorithm, 100.0000% atom/bond agreement with real RDKit on 4,999/5,000 comparable molecules. Not wired into the default path (RdkitLike/Huckelunchanged); default-promotion is blocked on a pre-existing, unrelated canonical-SMILES-writer sensitivity, not this engine- Fixed 5 instances of the same missing-metadata-copy bug (a
MoleculeBuilderrebuild not callingcopy_stereo_groups_from/copy_stereo_from/copy_bond_directions_from), each silently droppingstereo_neighbor_orderor worse:apply_kekule(P0),enumerate_stereoisomers(could silently flip a newly-assigned stereocenter's CIP code),transfer_hydrogen_aromatic/clone_mol(now deleted, replaced byMolecule::clone),transfer_hydrogen, andinvert_stereocenter(which turned out to be a functional no-op on plain@/@@SMILES input, a separate and more severe bug) chematic-smiles: consolidated aromatic bond-direction stashing across all 3 parser bond-creation paths (chain-edge/ring-closure/branch-attachment) into one shared helper — fixes a canonical-round-trip representation instability (4,994/5,000 → 5,000/5,000 stable); does not fixassign_ez's pre-existing blindness to this side channel (tracked as follow-up)- Full-corpus accuracy on the experimental CIP engine 96.68% → 99.38% raw / 99.64% oracle-stable vs modern RDKit
rdCIPLabeler(0 regressions) — seedocs/cip_accurate_rfc.mdfor the full milestone history - Benchmarks refreshed (
benchmarks/2026-07-17.md, Apple M4): the previous ECFP4 throughput headline (3.6 µs/mol, 5–14× vs RDKit) does not reproduce on a clean remeasurement — updated to today's measured numbers (~78 µs/mol / 2–3× on a diverse corpus) throughout this README anddocs/; descriptor accuracy numbers reproduce cleanly
v0.4.29 (2026-07-10): Kabsch rotation bug fix + SDF V3000/CDXML write, Avalon FP, O3A
chematic-3d: fixedalign_coords's Kabsch rotation computed in the wrong direction — was giving grossly inflated RMSD for any non-pure-translation alignment (live on v0.4.28 across crates.io/PyPI/npm before this patch);correspondence_searchfor O3A atom correspondencechematic-mol: SDF V3000 write wiring; CDXML writechematic-fp: Avalon fingerprint
v0.4.28 (2026-07-09): SMARTS perf, registry re-sync
chematic-smarts: existence-check short-circuit —bulk.substructure_search2.2× faster than RDKit- No git tag had been pushed for v0.4.23–v0.4.27 (crates.io stayed current via manual
cargo publish, but PyPI/npm/GitHub Releases fell behind) — this release re-syncs all three registries
v0.4.27 (2026-07-04): Descriptor fixes, RWMol/FCFP, veridict CI gates
chematic-chem:kappa1-3,balaban_j,labute_asa,bcut2d,hall_kier_alphadescriptor fixeschematic-fp:useFeatures=TrueFCFPchematic-mol: RWMol in-place editing- CI: veridict-based performance/Criterion/accuracy-drift regression gates; integration-test CI coverage gap fix
v0.4.26 (2026-06-29): E/Z stereo transfer in reactions + validation Sprint 6/7
chematic-rxn: reaction products now preserve//\double-bond geometry from reactants inrun_reactants()(previously lost on transformation)- Validation: canonical SMILES differential validation vs RDKit (Sprint 6); SMARTS/aromaticity differential tests + I/O compatibility (rdkit_compat Sprint 7); root-caused remaining RDKit canonical divergence to aromaticity round-trip, not Morgan ranks
v0.4.25 (2026-06-29): chematic.rdkit_compat layer
chematic-py: RDKit API compatibility surface (Sprints 1–5) — MorganbitInfo, Fingerprint/Mol/Atom/Bond/RingInfo compatibility, differential tests against RDKit; streamingSDMolSupplier/SDWriter/Mol.GetPropchematic-perception:AromaticityAlgorithm::RdkitLike— Se/Te chalcogen aromaticity matching RDKit's model
v0.4.24 (2026-06-29): CIP Rule 5, bridgehead/rotatable-bonds/TPSA/MR to 100%, HDF fingerprints
chematic-chem: CIP Rule 5 stereo tie-breaking (stereocenters 99.8% → 99.98% vs RDKit); bridgehead detection 98.5% → 100%; rotatable bonds 99.1% → 100%; TPSA 100%; molar refractivity 97.5% → 100% (3-ring XOR augmentation) — all on the 5,000-mol ChEMBL corpuschematic-py:bulk.descriptors_array()columnar numpy output; true-streaming SDF (SdfFileReader/iter_sdf_batched);screen()compound-filter workflow- LLM/RAG: representation router (
to_llm_text,best_representation), molecule context pack, Hyper-Dimensional Fingerprints (HDF) — training-free dense molecular vectors
v0.4.23 (2026-06-26): LogP 96.5% → 99.7%
chematic-chem:crippen_anchor_setsfixed to useuniquify: false, so symmetric triple bonds (internal alkynes) yield both VF2 match orientations instead of one falling back to the generic[#6]value
v0.4.22 (2026-06-26): CITATION.cff + chematic.doctor()
chematic-py:doctor()self-diagnostic; Reliability-by-Feature matrix added to README
v0.4.21 (2026-06-25): HTML/Markdown reporting for LLM/Jupyter
chematic-py:chematic.report()self-contained HTML compound grid,chematic.compare(),mol.review()Markdown analysis- Docs:
benchmarks//validation/reproducible accuracy history
v0.4.20 (2026-06-25): ETKDG torsion KB 44 → 80 rules, mol.describe()/diff()
chematic-3d: chair/envelope ring conformations for 6/5-membered aliphatic rings; SMARTS-based torsion rules as a high-precision pre-check layerchematic-py:mol.describe()/mol.diff(other)for LLM/MCP agents;bulk.generate_3d/tanimoto_matrix/standardize
v0.4.19 (2026-06-23): PDF/EPS output, ChemicalJSON, new descriptors, WASM −38.5%
chematic-depict:depict_pdf()/depict_eps()— PDF and EPS output; pure Rust, no external toolschematic-mol: ChemicalJSON —parse_cjson()/write_cjson()for Avogadro2 / MolSSI interopchematic-chem: 4 new descriptors —schultz_mti(),gutman_mti(),vabc()(Bondi vdW volume),gravitational_index()chematic-3d: Spectrophores 3D fingerprints (pharmacophore shell encoding)chematic-py:mol.to_pdf(),mol.to_eps(),mol.to_cjson(),from_cjson();bulk.substructure_match(smarts, mols)parallel VF2;estate_all()andring_bundlein bulk- WASM bundle: 819 → 504 KB gzip (−38.5%) —
tiny_skiamade optional, inline SHA-256,opt-level="z" lto=true codegen-units=1
v0.4.18 (2026-06-23): Python API expansion + benchmark docs
chematic-py: Jupyter auto-display — writingmolin a cell renders 2D structure via_repr_svg_();mol.has_substructure(smarts),mol.find_matches(smarts);from_smiles_list(),descriptors_df()chematic-chem:chi_all()— all 10 Hall-Kier connectivity indices in a single pass;cns_mpo_from_parts();pains_passes_and_matches()/brenk_passes_and_matches()— combined pass/match in one scan- Docs: benc
No comments yet
Be the first to share your take.