Every machine-learning field needs a representation: a way to turn a thing into numbers that preserve what matters. For images it's pixels, for text it's tokens. For smell, there are two representations in play—sensor-level features (what an e-nose measured, like ΔG/G₀ vectors) and molecule-level features (computed from the molecule's structure). The chemoprint is OpenSmell's molecule-level representation: a 29-dimensional vector of physicochemical properties that lets you compare, cluster, and classify molecules independently of any hardware.

Why Molecule-Level Features?

A sensor trace answers "what does this sample smell like." But most interesting questions are about the molecules: given a SMILES string, is this molecule likely to be pleasant? How similar is it to vanillin? Which of these 10,000 candidates shares odor-space with my target? Structure is the most portable thing in chemistry—two atoms of carbon and six of hydrogen define ethanol in Boston or in Beijing—so a structure-derived vector is the lingua franca of the field. This is also the reason structure-based prediction (Osmo's POM, for instance) can generalize to molecules nobody has ever synthesized.

What the 29 Dimensions Are

The chemoprint condenses a molecule into the physicochemical properties known (and mechanistically expected) to influence odour. Concretely, the categories:

Size & volatility — molecular weight, heavy-atom count, boiling point, vapour pressure. A molecule that can't vaporise can't reach your nose. The "osmogenic" observation that odorous molecules are small (roughly under ~300 Da) is fundamentally a volatility statement.

Lipophilicity — logP (octanol–water partition coefficient), logD. Odorants must partition out of the aqueous olfactory mucus and into the receptor's binding pocket. Lipophilicity governs that transfer, and it correlates with both potency and "molecule-hugging" receptor binding.

Polarity & H-bonding — topological polar surface area (TPSA), H-bond donors and acceptors. Receptors recognise molecules partly through complementary hydrogen bonds; these numbers encode that complementarity.

Electronic properties — polarizability, formal charge. Polarizability controls London dispersion forces—the weak, ubiquitous attraction that dominates small-molecule binding—and has been central to the shape-vs-vibration debate in olfaction.

Topology & shape — rotatable bonds, ring counts, aromatic ratio, chiral centres. Chain length and branching change smell dramatically (ethanol vs. octanol vs. 2-methyl-2-propanol), so the vector must see connectivity and shape, not just an atom census.

This is a curated, normalised subset of the hundreds of descriptors a tool like RDKit can compute. The point of curation is that each dimension is independently meaningful and the vector is small enough to be transparent.

Computing It with RDKit

RDKit is the open-source cheminformatics workhorse (the same library powering OpenSmell's browser toolkit). Computing hundreds of descriptors is one line:

from rdkit import Chem
from rdkit.Chem import Descriptors

mol = Chem.MolFromSmiles("CC(=O)Oc1ccccc1C(=O)O")  # aspirin
for name, fn in Descriptors.descList:
    print(name, fn(mol))

From that pool you select your curated set, handle the pathological edge cases (missing values, salts), and normalise—for the OpenSmell chemoprint, each dimension is scaled to a 0–1 range across a reference corpus so that no single property dominates distance calculations. The result is one fixed-length vector per molecule:

import numpy as np

def chemoprint(smiles: str, names: list[str]) -> np.ndarray:
    mol = Chem.MolFromSmiles(smiles)
    if mol is None:
        return np.zeros(len(names))
    raw = [Descriptors.descList[n][1](mol) for n in names]
    return (np.array(raw) - mins) / (maxs - mins)   # precomputed corpus bounds

What You Can Do With It

  • Similarity search. Euclidean or cosine distance between chemoprints ranks molecules by property similarity. This is the engine behind "find me molecules that smell like this one."
  • Classification. A random forest or MLP on the 29 dims predicts qualitative targets (pleasant/unpleasant, woody/floral) surprisingly well—because the descriptors encode the chemistry that drives perception.
  • Clustering. In the absence of human labels, the chemoprint gives a principled way to group a chemical library before you ever spend money on synthesis or a panel.
from sklearn.ensemble import RandomForestClassifier

X = np.array([chemoprint(s, names) for s in smiles_list])
y = pleasant_labels
clf = RandomForestClassifier(300)
clf.fit(X, y)

Validating a Representation

The cardinal sin is evaluating a representation on molecules that resemble your training set (leakage from shared scaffolds). The right protocol:

  1. Leave-molecule-out cross-validation — hold out whole structures, not random rows.
  2. Scaffold splitting — split by ring system so similar molecules never straddle train/test.
  3. Compare to human judgments — the real test of a smell representation is agreement with pairwise perceptual similarity ratings (that's precisely how the Dravnieks data is used as a benchmark).

Known Limits (Say Them Out Loud)

  • Stereochemistry. Optical isomers can smell completely different—(–)-carvone smells of spearmint, (+)-carvone of caraway—yet they have identical scalar descriptors. Any representation that drops chirality will silently merge compounds humans clearly separate.
  • Mixtures and context. The chemoprint describes an isolated molecule. Real smells are mixtures, and perception shifts with concentration and matrix.
  • The map is not the nose. Physicochemical descriptors correlate with smell because they shape receptor binding—but they are not a theory of the receptor.

Where the Chemoprint Fits

The chemoprint is the molecule half of the representation stack. The sensor half is the feature framework the OpenSmell SDK extracts from raw traces (28 per channel + one selectivity ratio per channel pair + 4 global metrics — 187 dimensions at the canonical six channels). Together they cover both ends: what's in the air, and what the instrument measured. Two representations, one open stack, zero lock-in.

Sources & Further Reading

  • RDKit documentation: https://www.rdkit.org
  • OpenSmell chemoprint reference: https://github.com/opensmell
  • Dravnieks, A. Atlas of Odor Character Profiles (1985).
  • Lee, B. K. et al. Science 381, 999–1006 (2023) — structure-to-perception prediction.