Electron-configuration-based molecular fingerprints for transition metal complexes.
Combine ligand topology with the metal's electron configuration into a single vector for classification, regression, similarity, and visualization.
Standard fingerprints (ECFP/Morgan) describe organic molecules well but ignore
what makes a coordination compound distinctive: the metal centre and the
geometry of its coordination sphere. electrum is a hybrid fingerprint
built from two complementary channels:
| Channel | What it encodes | How |
|---|---|---|
| Ligand topology | the atoms and bonds around the metal | graph-based Morgan (ECFP-style) hashing, with stereochemistry |
| Metal identity | the metal's electronics | its ground-state electron configuration as a fixed vector |
The two are concatenated into one array, giving the ligand environment and the periodic/electronic character of the metal in a single representation.
electrum fingerprint
┌───────────────────────────────┬──────────────────────┐
│ ligand topology bits (n_bits) │ electron config (86) │
└───────────────────────────────┴──────────────────────┘
What's new in this rewrite. A graph-based Morgan engine (monoatomic ligands such as halides are now captured), full coordination stereochemistry — cis/trans, fac/mer and Δ/Λ handedness — and a generated electron-configuration metal channel that reproduces the published encoding exactly. Ships with an
electrumcommand-line tool; the original engine is kept aselectrum.legacy.
pip install electrum-fp # distribution name; imported as `electrum`Or from source:
git clone https://github.com/TheFreiLab/electrum
cd electrum
pip install -e .from electrum import calculate_fingerprint
# A connected coordination complex (dative bonds + optional stereo).
# The metal is auto-detected from the graph.
fp = calculate_fingerprint("Cl[Pt@SP1](Cl)([NH3])[NH3]", radius=2, n_bits=1024)
print(fp.shape) # (1024 + 86,)You can also use the original disconnected form (ligand SMILES joined by .
plus a metal symbol):
fp = calculate_fingerprint("Cc1ccccc1.Cl.Cl", metal="Rh", radius=2, n_bits=512)Or straight from a 3D structure (.xyz block or file):
from electrum import calculate_fingerprint_from_xyz, xyz_to_smiles
smiles = xyz_to_smiles("complex.xyz") # 3D -> connected SMILES
fp = calculate_fingerprint_from_xyz("complex.xyz") # 3D -> fingerprintThe XYZ path perceives bonds from the coordinates (see
electrum/xyz.py); it assumes the file carries explicit
hydrogens and a known total charge (comment line or total_charge=), targets a
single classical metal centre, and produces a stereo-free SMILES (coordination
stereochemistry is not yet carried through this route). On the CLI:
electrum complex.xyz.
import numpy as np
from electrum import calculate_fingerprint as fp
cisplatin = fp("Cl[Pt@SP1](Cl)([NH3])[NH3]") # Cl cis to Cl
transplatin = fp("Cl[Pt@SP2](Cl)([NH3])[NH3]") # Cl trans to Cl
np.array_equal(cisplatin, transplatin) # -> FalseSame metal, same ligand set — only the geometry differs, and electrum tells
them apart. Geometry is written with the SMILES descriptors @SP (square-planar),
@OH (octahedral) and @TB (trigonal-bipyramidal); see
Stereochemistry for how it becomes features.
flowchart TB
IN["SMILES or molecule"] --> PARSE["① parse and sanitize<br/>(tolerates dative bonds, odd valences)"]
PARSE --> MORGAN
PARSE --> STEREO
PARSE -->|"metal: given or auto-detected"| EC
subgraph TOPOBLK["topological block — n_bits"]
direction TB
MORGAN["② Morgan / ECFP<br/>radius r, includeChirality"] --> MBITS["fold every atom identifier<br/>bit = id mod n_bits"]
STEREO["③ each non-tetrahedral centre →<br/>geometry + trans pairs + Δ/Λ sign<br/>→ hashed feature"] --> SBITS["fold each feature<br/>bit = hash mod n_bits"]
end
subgraph METALBLK["metal block — 86"]
EC["④ ground-state<br/>electron configuration"]
end
MBITS --> CAT(["⑤ concatenate"])
SBITS --> CAT
EC --> CAT
CAT --> OUT["electrum fingerprint<br/>length = n_bits + 86"]
electrum encodes stereochemistry in two ways, depending on where it lives:
| Kind | Example | Mechanism |
|---|---|---|
| Tetrahedral R/S, double-bond E/Z | L- vs D-amino-acid ligand | baked into the Morgan atom identifiers (includeChirality) |
| cis/trans, fac/mer | cisplatin vs transplatin | a trans-pair feature |
| Δ/Λ handedness | Δ- vs Λ-[Co(en)₃]³⁺ | a handedness sign on that feature |
The trans-pair trick. What separates cisplatin from transplatin is which ligands sit opposite each other:
cisplatin → trans pairs { (Cl,N), (Cl,N) }
transplatin → trans pairs { (Cl,Cl), (N,N) } ← different → different bits
Each ligand in a pair is named by its Morgan identifier (not its position), so the feature is canonical — any SMILES writing of the same isomer gives the same bits. The per-stereocentre pipeline:
flowchart LR
A["SMILES with<br/>@SP / @OH / @TB"] --> B["RDKit perceives<br/>the geometry"]
B --> C["recover trans pairs<br/>(ligands ~180° apart)"]
B --> G["compute handedness<br/>sign (Δ/Λ)"]
C --> D["describe each donor by its<br/>Morgan identifier"]
D --> E["canonical signature:<br/>(metal, geometry, {trans pairs}, Δ/Λ)"]
G --> E
E --> F["hash → set bit(s)"]
Δ/Λ handedness. Trans pairs are achiral, so the Δ and Λ enantiomers of a
tris-chelate ([Ru(bpy)₃]²⁺, [Co(en)₃]³⁺) share them. electrum adds a handedness
sign: order the donors by a canonical (graph-based) ranking, then take the sign of
the scalar triple product of the top mutually-cis triple. It flips between
enantiomers, vanishes for planar centres, and works even when all donors are
identical. Geometry tables are derived once from 3D references (see
electrum/stereo.py); disable with include_handedness=False.
Installing the package also installs an electrum command:
# single complex -> CSV on stdout (metal auto-detected)
electrum "Cl[Pt@SP1](Cl)([NH3])[NH3]"
# batch from a CSV, writing to a file
electrum --input complexes.csv --smiles-column smiles --metal-column metal -o fps.csv
# stream SMILES on stdin, 512 bits, tab-separated, ligand-only
cat smiles.txt | electrum --bits 512 --no-metal -f tsvOutput is CSV (or TSV via -f tsv): an id column followed by bit_*
(topological) and ec_* (electron-configuration) columns. Options mirror the
Python API — --radius, --bits, --metal, --counts, --engine,
--no-metal/--no-stereo/--no-chirality/--no-handedness. Unparseable SMILES are reported and
skipped unless --strict is given. Run electrum --help for the full list.
| Function | Description |
|---|---|
electrum.calculate_fingerprint(smiles, metal=None, radius=2, n_bits=1024, ...) |
Fingerprint one complex |
electrum.calculate_fingerprints(smiles_list, metals_list=None, ...) |
Batch version |
electrum.metals.metal_vector(symbol) |
The 86-bit electron-configuration vector |
electrum.legacy.calculate_fingerprint(...) |
The original SMILES-hash engine (for reproducibility) |
Key options: include_chirality, include_stereo, include_handedness,
include_metal, counts.
Stereochemistry is only encoded when it is specified in the input — via
SMILES descriptors (@/@@ for R/S, /,\ for E/Z, @SP/@OH/@TB for
coordination geometry) or perceived from 3D coordinates. Known gaps:
- Atropisomerism / axial chirality (e.g. BINAP): RDKit does not perceive
atropisomers from SMILES or from an embedded 3D structure in the current
version — the stereo only exists when read from a mol-block/SDF with wedge
bonds — and Morgan ignores it. So biaryl axial chirality is not captured
today. (The building blocks exist —
STEREOATROPCW/CCW— so this can be added once mol-block input is in scope.) - High coordination numbers (CN 7–9) — pentagonal bipyramidal, square antiprism, etc. (common for lanthanides/actinides): RDKit does not perceive these geometries, so their stereochemistry is not encoded.
- The metal electron-configuration channel covers H–Rn (86 bits); elements from Fr onward are not represented.
If you use electrum, please cite:
@Article{D5DD00145E,
author = "Orsi, Markus and Frei, Angelo",
title = "ELECTRUM: an electron configuration-based universal metal fingerprint for transition metal compounds",
journal = "Digital Discovery",
year = "2025",
volume = "4",
issue = "12",
pages = "3567-3577",
publisher = "RSC",
doi = "10.1039/D5DD00145E"
}Released under the MIT License.

