Preparing a compound list for similarity search or machine learning means turning structures into numerical features. chematic v1.1.4 speeds up these calculations and lets you receive fingerprints directly as NumPy arrays.

Repeated TPSA reads on the same molecules were about 9–14 times as fast as in the published v1.1.3 package. We start with three compounds, then compare the published Python packages for chematic 1.1.3, chematic 1.1.4, and RDKit 2026.09.1 on identical inputs.

Turn three compounds into a 3 × 2,048 matrix

We use TPSA, a topological polar surface area descriptor, and Morgan fingerprints, which encode local atomic environments as bits. Descriptor calculation and Morgan-based similarity are also covered in the RDKit Python guide.

The inputs are ethanol, aspirin, and caffeine. In a Python virtual environment, save features.py in an empty working directory and run:

python -m pip install "chematic==1.1.4" "numpy==2.5.4"
python features.py
(3, 2048) uint8
[20.23 63.6  61.82]

The first line describes a Morgan feature matrix with three rows, 2,048 columns, and uint8 elements. Each element is 0 or 1. The second line contains TPSA values in Ų in the same compound order.

The core calculation is:

import chematic
import numpy as np

smiles = [
    "CCO",
    "CC(=O)Oc1ccccc1C(=O)O",
    "Cn1cnc2c1c(=O)n(C)c(=O)n2C",
]
molecules = [chematic.from_smiles(s) for s in smiles]
X = np.stack([mol.rdkit_ecfp_config_numpy(2, 2048) for mol in molecules])
tpsa = np.array([mol.rdkit_tpsa for mol in molecules])

rdkit_ecfp_config_numpy(2, 2048) is a new v1.1.4 API for a radius-2, 2,048-bit Morgan fingerprint. np.stack combines the per-molecule arrays into a matrix for similarity calculations or model inputs.

The downloadable script saves the arrays as morgan.npy and tpsa.npy. Its example features.csv retains the row number, compound ID, input SMILES, and TPSA. Each feature row stays attached to its source compound as you move into the next processing step.

Measure the published packages, including SMILES parsing

We timed the workflow that reads a SMILES and calculates both TPSA and a Morgan fingerprint. Slice A contains the first 1,000 records of the public corpus; slice B contains records 5,001–6,000. Both slices were used without filtering.

The table gives milliseconds per 1,000 structures on macOS arm64 with Python 3.13.6. Each published package was installed in a separate environment. We rotated execution order over 21 blocks, took the median of five repeats per block, and report the median across blocks. Timing runs from SMILES parsing through returning both calculation results to Python; NumPy conversion and file saving are outside the timer.

Input v1.1.3 v1.1.4 RDKit 2026.09.1
A 13.21 ms 11.21 ms 95.10 ms
B 12.74 ms 11.20 ms 44.76 ms

The median paired speedup over v1.1.3 was 1.18× on A and 1.10× on B. Paired-bootstrap 95% intervals were 1.13–1.20× and 1.08–1.14× respectively. Against RDKit in the same measurement, the paired speedups were 8.51× on A and 3.98× on B.

TPSA values and Morgan fingerprints agreed across all three packages on all 2,000 structures. We compared every one of the 2,048 fingerprint bits. Morgan uses radius 2, with chirality and count simulation disabled. TPSA follows RDKit’s default setting, excluding S and P contributions.

Reuse calculations on the same molecule

A parsed molecule may be used for filtering, feature preparation, and displaying results. In v1.1.4, calculated values such as TPSA are stored on the molecule and reused by later calls.

Repeated TPSA reads were 8.99× faster than v1.1.3 on A and 14.32× on B. The 95% intervals were 8.66–9.27× and 13.84–14.66× respectively, and v1.1.4 was faster in all 21 blocks on both inputs.

For this measurement, each set of 1,000 molecules was parsed and calculated once before timing. TPSA was then read 50 times per molecule. Parsing and the initial calculation are outside this timer. The earlier table includes parsing, so the two measurements describe different stages of a workflow.

The implementation adds a scalar descriptor cache, used by the TPSA calculation. Regression tests after atom and bond edits cover updating results when a structure changes.

Fingerprint output also converts packed bits into bytes together, replacing the bit-by-bit loop in the Python binding. The binding can then expand those bytes into a NumPy array of zeros and ones.

Measurements ran on October 14, 2026. We provide the benchmark script, all timing observations, and an execution record with hashes for the published wheels, corpus, and example files.