Skip to main content

molfp logo

molfp

Interpretable molecular fingerprints with SHAP-driven chemical explanations.

A native Python/RDKit library that computes 30 molecular fingerprint types (13 2D + 9 3D + 8 graph-based) and provides built-in tools for interpretation, visualization, collision detection, activity cliff analysis, bioactivity profiling, and SHAP-based feature explanation — capabilities not found in any other fingerprint library.

Install

pip install molfp

Quick Start

import molfp

# Compute fingerprints — versatile input (str, list, Series, DataFrame)
fp = molfp.maccs("CCO")                        # single → list of 166 ints
fps = molfp.ecfp4(["CCO", "c1ccccc1"])         # batch → numpy (2, 1024)
fps = molfp.ecfp4(df, n_bits=2048, n_jobs=-1)  # DataFrame with auto-detected SMILES column

# All 30 types
molfp.available()
# ['maccs', 'ecfp4', 'pubchem', 'substructure', 'substructure_count',
#  'klekota_roth', 'klekota_roth_count', 'estate', 'atompairs2d',
#  'atompairs2d_count', 'rdk', 'rdk_ext', 'rdk_graphonly',
#  'atompairs3d', 'atompairs3d_count', 'usr', 'usrcat',
#  'autocorr3d', 'rdf', 'morse', 'whim', 'getaway',
#  'graph_standard', 'graph_distance', 'graph_line', 'graph_fragment',
#  'graph_standard_enriched', 'graph_distance_enriched',
#  'graph_line_enriched', 'graph_fragment_enriched']

Molecule Visualization

2D Structure Drawing

Draw molecules with optional fingerprint bit highlighting. Works in Jupyter, Colab, and Streamlit.

# Single molecule
molfp.draw("CC(=O)Oc1ccccc1C(=O)O")

# Grid of molecules
molfp.draw(smiles_list, legends=["Aspirin", "Caffeine", ...], mols_per_row=3)

# Highlight atoms that trigger specific fingerprint bits
molfp.draw("CC(=O)Oc1ccccc1C(=O)O", highlight_bits=[88, 143, 162], fp_type="maccs")
2D molecule grid 2D with fingerprint bit highlighting
Molecule grid with labels Fingerprint bit highlighting

3D Interactive Viewer

Interactive 3D viewer using py3Dmol. Auto-detects environment (Jupyter, Colab, Streamlit).

# Interactive 3D viewer
molfp.view3d("CN1C=NC2=C1C(=O)N(C(=O)N2C)C")

# Different styles: stick, sphere, line, ball_and_stick
molfp.view3d("CC(=O)Oc1ccccc1C(=O)O", style="ball_and_stick", spin=True)

Uses adaptive conformer optimization (MMFF94) to generate optimized 3D structures automatically.

3D interactive viewer in Jupyter notebook

Features

30 Fingerprint Types

2D Fingerprints (13 types)

Type Bits Function
MACCS Keys 166 molfp.maccs()
ECFP4 (Morgan r=2) 1024 molfp.ecfp4()
PubChem/CACTVS 881 molfp.pubchem()
SubstructureFP 307 molfp.substructure()
Substructure Count 307 molfp.substructure_count()
Klekota-Roth 4860 molfp.klekota_roth()
Klekota-Roth Count 4860 molfp.klekota_roth_count()
E-State 79 molfp.estate()
AtomPairs2D 780 molfp.atompairs2d()
AtomPairs2D Count 780 molfp.atompairs2d_count()
RDKit path-based 1024 molfp.rdk()
RDKit Extended 1024 molfp.rdk_ext()
RDKit GraphOnly 1024 molfp.rdk_graphonly()

3D Fingerprints (9 types)

Type Dims Function
3D Atom Pairs 780 molfp.atompairs3d()
3D Atom Pairs Count 780 molfp.atompairs3d_count()
USR 12 molfp.usr()
USRCAT 60 molfp.usrcat()
3D Autocorrelation 80 molfp.autocorr3d()
RDF 210 molfp.rdf()
MORSE 224 molfp.morse()
WHIM 114 molfp.whim()
GETAWAY 273 molfp.getaway()

3D fingerprints use adaptive conformer optimization with MMFF94, where iteration counts are estimated from molecular complexity via a regression model trained on 1,420 FDA-approved drugs.

Graph Fingerprints (8 types)

Type Dims Function
Graph Standard 298 molfp.compute_batch(smiles, "graph_standard")
Graph Distance (3D) 286 molfp.compute_batch(smiles, "graph_distance")
Graph Line 714 molfp.compute_batch(smiles, "graph_line")
Graph Fragment 510 molfp.compute_batch(smiles, "graph_fragment")
Graph Standard Enriched 5,242 molfp.compute_batch(smiles, "graph_standard_enriched")
Graph Distance Enriched 5,230 molfp.compute_batch(smiles, "graph_distance_enriched")
Graph Line Enriched 12,250 molfp.compute_batch(smiles, "graph_line_enriched")
Graph Fragment Enriched 5,454 molfp.compute_batch(smiles, "graph_fragment_enriched")

Enriched variants add Morgan environment hashes, functional group membership, and neighbor type counts per atom. Base variants use atom-level properties only (type, degree, charge, hybridization, aromaticity, ring).

Versatile Input Handling

Every fingerprint function accepts any of these input types:

molfp.ecfp4("c1ccccc1")                  # single SMILES → list
molfp.ecfp4(["CCO", "c1ccccc1"])          # list → numpy array
molfp.ecfp4(pd.Series(["CCO", "c1c..."]))  # Series → numpy array
molfp.ecfp4(df, column="SMILES")           # DataFrame → numpy array (auto-detects column)

Bit-Level Explainability

Map each ON bit to the atoms/bonds that triggered it — across all 13 2D FP types:

molfp.explain("CC(=O)Oc1ccccc1C(=O)O", "ecfp4")
# {11: [(1, 1)], 33: [(0, 0)], 64: [(6, 1), (7, 1)], ...}
# bit 64 → center atoms 6 and 7 at radius 1

Chemical Annotation

Human-readable names for every fingerprint bit:

molfp.annotate("substructure", 83)
# {'name': 'Carboxylic_acid', 'smarts': '[CX3...](=[OX1])...', 'category': 'functional_group'}

molfp.annotate("pubchem", 9)
# {'description': 'Element count: C >= 2', 'category': 'element_count'}

SHAP Interpretation with Chemical Meaning

One call: fingerprint → model → SHAP → chemical annotation → per-class SAR:

result = molfp.interpret(smiles, activities, fp_type="maccs", metric="pchembl")

# Per-class drivers with present/absent effect:
# ACTIVE:
#   ↑ present  methyl group (-CH3)     SHAP +0.004  (freq 23% vs 19%)
#   ↓ present  oxygen atom             SHAP -0.003  (freq 13% vs 17%)

Additional functions for molecule-level analysis:

# Explain a single molecule's prediction
molfp.interpret_molecule(smiles, interpretation_result)

# Compare two molecules' structural differences by importance
molfp.compare_molecules(smiles_a, smiles_b, interpretation_result)

Hash Collision Detection

Detect when different substructures hash to the same bit:

molfp.detect_collisions("c1ccccc1", "ecfp4", n_bits=256)
# {63: [2360741695, 3976623167]}  → 2 hashes collided at bit 63

molfp.collision_rate(smiles_list, "ecfp4", n_bits=1024)
# {'collision_rate': 0.027, 'collided_bits': 15, ...}

Activity Cliff Detection

Find structurally similar molecules with large activity differences:

cliffs = molfp.activity_cliffs(smiles, activities, "maccs",
                                sim_threshold=0.8, activity_threshold=2.0)

Bioactivity Class Profiling

Classify molecules, analyze intra/inter-class similarity, find enriched bits:

labels = molfp.classify(pchembl_values, metric="pchembl")
result = molfp.class_similarity(smiles, labels, "maccs")
enriched = molfp.enriched_bits(smiles, labels, "maccs")

Structure Standardization

Desalt, neutralize, canonicalize tautomers, deduplicate by InChIKey:

molfp.standardize_smiles("CC(=O)Oc1ccccc1C(=O)[O-].[Na+]")
# → "CC(=O)Oc1ccccc1C(=O)O"  (desalted + neutralized)

result = molfp.preprocess(smiles_list)
# n_input: 1000 → n_after_standardization: 985 → n_after_deduplication: 923

Distance Functions

Vectorized Tanimoto, Dice, Cosine, Sokal-Michener, Russel-Rao:

molfp.tanimoto(fp_a, fp_b)           # single pair → float
molfp.pairwise(X, metric="tanimoto") # (N, N_bits) → (N, N) matrix (vectorized)

scikit-learn Compatible

All 30 FP types as sklearn transformers with Pipeline, GridSearchCV, and FeatureUnion support:

from sklearn.pipeline import make_pipeline
from sklearn.ensemble import RandomForestClassifier

pipe = make_pipeline(
    molfp.ECFPTransformer(n_bits=2048, n_jobs=-1),
    RandomForestClassifier()
)
pipe.fit(smiles_train, y_train)

Sparse Matrix & Parallelism

molfp.klekota_roth(smiles_list, sparse=True, n_jobs=-1)
# → scipy.sparse.csr_matrix, 97% memory savings for KR 4860-bit FPs

Consensus Fingerprints

Build optimal fusion fingerprints from multiple types using mutual information:

molfp.fuse(smiles, activities, ["ecfp4", "maccs", "pubchem"])

Feature Selection

Standalone functions that work with any fingerprint or graph feature output:

# Remove constant/near-constant features (no labels needed)
result = molfp.remove_low_variance(X, threshold=0.01)
X_clean = result["X"]  # filtered matrix

# Select top-k features by mutual information (requires labels)
result = molfp.select_features(X, y, k=500, threshold=0.01)
X_selected = result["X"]       # (n_samples, 500)
result["indices"]               # original column indices
result["scores"]                # mutual information scores

Molecular Graph Representations for Deep Learning

Convert molecules to atom/bond feature matrices for graph neural networks (GCN, GAT, MPNN, etc.). Framework-agnostic core with optional PyTorch Geometric and DGL converters.

# Convert to graph — returns NumPy arrays (no DL framework needed)
g = molfp.mol_graph("c1ccccc1")                      # type="standard" (default)
g = molfp.mol_graph("c1ccccc1", type="distance")     # complete graph with 3D distances
g = molfp.mol_graph("c1ccccc1", type="line")          # bonds as nodes
g = molfp.mol_graph("c1ccccc1", type="fragment")      # functional groups as nodes
g = molfp.mol_graph("c1ccccc1", enriched=True)        # enriched atom features (432 dims)

# g["atom_features"]  → numpy (n_nodes, n_features)
# g["edge_index"]     → numpy (2, n_edges)
# g["edge_features"]  → numpy (n_edges, n_edge_features)

# Batch conversion
graphs = molfp.mol_graph(["CCO", "c1ccccc1", "CC(=O)O"])

# PyTorch Geometric (requires: pip install torch torch_geometric)
data = molfp.to_pyg(g, y=1)                          # single graph → Data
loader = molfp.graphs_to_pyg(graphs, y=labels, batch_size=32)  # → DataLoader

# DGL (requires: pip install dgl torch)
dgl_graph = molfp.to_dgl(g)

# Feature inspection
molfp.atom_feature_names()  # ['atom_type_C', 'atom_type_N', ..., 'is_aromatic', 'in_ring']
molfp.edge_feature_names()  # ['bond_type_single', ..., 'is_conjugated', 'in_ring', ...]

Atom features (20 dims): atom type (one-hot, 10), degree, formal charge, num Hs, hybridization (one-hot, 5), is aromatic, in ring.

Edge features (12 dims): bond type (one-hot, 4), is conjugated, in ring, stereo (one-hot, 6).

Graph Vectors for scikit-learn

# Fixed-length vectors from any graph type
X = molfp.graph_vectors(smiles, type="standard", enriched=True)

# sklearn pipeline
from sklearn.pipeline import make_pipeline
from sklearn.ensemble import RandomForestClassifier
pipe = make_pipeline(molfp.GraphTransformer(enriched=True, type="standard"), RandomForestClassifier())
pipe.fit(smiles_train, y_train)

Collision Handling

Hashed fingerprints (ECFP4, RDK, AtomPairs) fold substructures into fixed-length vectors via modulo, causing hash collisions that corrupt SHAP attributions.

# Detect collisions
molfp.detect_collisions("c1ccccc1", "ecfp4", n_bits=1024)

# Remove colliding bits from feature matrix
result = molfp.remove_collisions(X, smiles, "ecfp4", 1024)

# Collision-free mode (multi-hash Bloom filter approach)
fps = molfp.ecfp4(smiles, collision_free=True)  # works on all 8 hashed FPs

# Collision-aware SHAP interpretation
result = molfp.interpret(smiles, activities, fp_type="ecfp4", collision_aware=True)

Scaffold Analysis

Extract Murcko/generic scaffolds with chemical names from ~130 common ring systems. Scaffold-aware train/test splitting prevents data leakage in QSAR.

molfp.scaffold("CC(=O)Oc1ccccc1C(=O)O")
# {"murcko": "c1ccccc1", "generic": "C1CCCCC1", "name": "Benzene"}

# Scaffold fingerprint — binary membership matrix
result = molfp.scaffold_fingerprint(smiles)

# Scaffold-aware split (no scaffold leakage)
result = molfp.scaffold_split(smiles, test_size=0.2)
train_idx, test_idx = result["train_idx"], result["test_idx"]

License

MIT

Metadata

Release files for molfp 0.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for molfp 0.3.1
File Size Uploaded
molfp-0.3.1.tar.gz 110.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for molfp 0.3.1
File Interpreter ABI Platform
molfp-0.3.1-py3-none-any.whl Python 3 none any Details

Total release size: 208.1 kB

Release files / molfp-0.3.1.tar.gz

Download URL molfp-0.3.1.tar.gz
Size 110.4 kB
Tags Source
SHA-256 checksum
How to use checksums
c3d59c5421c8bdd7fe8f536044804f92ae03b3758c498f08de69bdf00f066754
BLAKE2b-256 checksum
How to use checksums
cd7dcae946842138dadfe6765830fc28f237770c227bb01b99e10b0215cfdee2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.

Transparency log

Release files / molfp-0.3.1-py3-none-any.whl

Download URL molfp-0.3.1-py3-none-any.whl
Size 97.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0c3cef9321a6a6c505cc7045214158bfc999f0f12a731b88c44cc033078ee851
BLAKE2b-256 checksum
How to use checksums
fd9ee08c3f811b40b5770dd7487e9911fb74b0a34f07b0ee1504d9884d62d2f0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

This release

0.3.1 This release

2 release files

0.3.0

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page