Skip to main content

Improved fingerprints for the OpenEye Toolkits

Project description

OEFP

High-performance molecular fingerprints for the OpenEye Toolkits.

OEFP generates RDKit-compatible Morgan and topological Atom Pair fingerprints from OpenEye molecules, stores them in compact C++ containers, and compares them with fast scalar and batch kernels. It also provides raw Morgan and topological Atom Pair descriptor rows plus a schema-backed Mordred-compatible descriptor surface. Python bindings are built with SWIG, so openeye.oechem molecules pass directly into C++ without serialization.

OEFP currently supports dense binary, sparse binary, and sparse counted fingerprint containers; scalar comparison; query-to-batch comparison; cdist; SciPy-compatible condensed pdist; columnar descriptor batches; and Arrow/Parquet interchange for schema-backed descriptor rows.

Try it out:

pip install oefp

Usage

Here are a few examples of using oefp.

Python

from openeye import oechem
import oefp

mol = oechem.OEGraphMol()
oechem.OESmilesToMol(mol, "CC(=O)OC1=CC=CC=C1C(=O)O")  # aspirin

# Generate an RDKit-compatible Morgan fingerprint.
fp = oefp.morgan_fingerprint(mol, radius=2, num_bits=2048)
print(fp.popcount)
print(fp.words[:4])

# Compare fingerprints.
score = oefp.compare(fp, fp, oefp.Metric.tanimoto())
print(score)

Use reusable generators when applying the same options to many molecules:

from openeye import oechem
import oefp

smiles = ["c1ccccc1", "c1ccc(O)cc1", "CC(=O)O"]
mols = []
for smi in smiles:
    mol = oechem.OEGraphMol()
    oechem.OESmilesToMol(mol, smi)
    mols.append(mol)

generator = oefp.MorganGenerator(radius=2, num_bits=2048)
fps = [generator.fingerprint(mol) for mol in mols]

batch = oefp.OEFPBatch.from_fingerprints(fps)
distances = oefp.pdist(batch, oefp.Metric.jaccard())

Generate sparse and counted fingerprints:

folded_count = oefp.morgan_count_fingerprint(mol)
sparse_binary = oefp.morgan_sparse_fingerprint(mol)
atom_pair_count = oefp.atom_pair_sparse_count_fingerprint(mol)

print(folded_count.indices[:5])
print(folded_count.counts[:5])
print(sparse_binary.indices[:5])
print(atom_pair_count.total_count)

Inspect Morgan bit provenance:

result = oefp.morgan_fingerprint_with_mapping(mol)
print(result.fingerprint.popcount)
print(result.mapping.bit_info())

Import and export OpenEye fingerprints:

from openeye import oechem, oegraphsim
import oefp

mol = oechem.OEGraphMol()
oechem.OESmilesToMol(mol, "CCO")

oe_fp = oegraphsim.OEFingerPrint()
oegraphsim.OEMakeCircularFP(oe_fp, mol)

fp = oefp.from_openeye_fingerprint(oe_fp)
round_tripped = oefp.to_openeye_fingerprint(fp)
print(oegraphsim.OETanimoto(oe_fp, round_tripped))

Work with Mordred-compatible named descriptors:

from openeye import oechem
import oefp

mol = oechem.OEGraphMol()
oechem.OESmilesToMol(mol, "CCO")

row = oefp.mordred_descriptors(mol)
schema = row.schema

print(schema.schema_id)
print(row["MW"])
print(row["GeomDiameter"])  # None unless the input already has 3D coordinates.

requires_3d = [
    definition.name
    for definition in schema.definitions
    if definition.prerequisites & oefp.DESCRIPTOR_PREREQUISITE_COORDINATES_3D
]
print(len(requires_3d))

Descriptor calculation never generates 2D or 3D coordinates implicitly. When a descriptor requires coordinates that the input molecule does not already have, that descriptor value remains missing (None in Python).

C++

#include <oefp/oefp.h>
#include <oechem.h>
#include <iostream>

int main() {
    OEChem::OEGraphMol mol_a;
    OEChem::OEGraphMol mol_b;
    OEChem::OESmilesToMol(mol_a, "c1ccccc1");
    OEChem::OESmilesToMol(mol_b, "c1ccc(O)cc1");

    OEFP::MorganGenerator generator;
    OEFP::OEFP fp_a = generator.Fingerprint(mol_a);
    OEFP::OEFP fp_b = generator.Fingerprint(mol_b);

    double score = OEFP::Compare(fp_a, fp_b, OEFP::Metric::Tanimoto());
    std::cout << score << "\n";

    return 0;
}

Supported Fingerprints

Family Outputs Notes
Morgan Folded binary, folded count, sparse binary, sparse count Bit mapping is available for all Morgan outputs
Topological Atom Pair Folded binary, folded count, sparse binary, sparse count Uses connectivity distances; legacy atom_pair_* names remain compatibility aliases
OpenEye OEFingerPrint import/export Numeric type metadata is preserved when available

Supported Descriptors

Family Output Notes
Morgan Raw counted integer-key descriptors Uses unfurled Morgan environment identifiers
Topological Atom Pair Raw counted string-key descriptors Uses graph shortest-path distances and requires no coordinate generation
Distance Atom Pair Reserved Requires existing 3D coordinates and is not implemented yet
Mordred-compatible Schema-backed named descriptor rows Full Mordred 1.2.0 schema with implemented values filled and unsupported or unavailable values left missing

Mordred-compatible descriptors use local Mordred and RDKit source as the reference truth. Descriptor definitions include source metadata, group labels, serialized parameters, value type, description, and prerequisite bitmaps. Coordinate prerequisites are declarative only: OEFP descriptor calculators do not invoke conformer generation.

Current conformance scope is explicit: Morgan chirality, Atom Pair chirality, and Distance Atom Pair generation raise ValueError or NotImplementedError until those paths have dedicated RDKit parity coverage. Topological Atom Pair uses only the molecular connectivity graph; it does not require 2D coordinates.

Installation

Install OpenEye Toolkits first:

pip install --extra-index-url https://pypi.anaconda.org/openeye/simple openeye-toolkits

Install OEFP:

pip install oefp

Build from Source

Set the OpenEye C++ SDK path:

export OPENEYE_ROOT=/path/to/openeye/sdk

Build the C++ library and Python bindings:

cmake --preset debug
cmake --build build-debug

Install the Python package in editable mode:

pip install --config-settings editable_mode=compat -e python/

The editable_mode=compat flag keeps the package on a traditional editable path that works with compiled SWIG extension modules.

Tests

C++ tests:

cmake --build build-debug --target oefp_tests
ctest --test-dir build-debug --output-on-failure

Python tests:

PYTHONPATH=python python -m pytest tests/python -q

RDKit is required for conformance tests but is not a runtime dependency.

Documentation

Build the Sphinx documentation:

python -m pip install -r docs/requirements.txt
make -C docs html

Open the local build:

open docs/_build/html/index.html

The documentation includes installation, quickstart, Python API notes, C++ API reference generation through Doxygen, and release build guidance.

Benchmarks

Run the RDKit generation and dense pdist benchmark:

PYTHONPATH=python python benchmarks/benchmark_rdkit_generation.py \
  --max-mols 1500 \
  --trials 7 \
  --warmup 1 \
  --pdist-size 400 \
  --generation-max-ratio 1.10 \
  --atom-pair-generation-max-ratio 1.10

Run the optional C++ guardrail against a local oecluster checkout:

cmake -S . -B build-bench \
  -DOEFP_BUILD_BENCHMARKS=ON \
  -DOEFP_OECLUSTER_SOURCE_DIR=/path/to/oecluster
cmake --build build-bench --target oefp_oecluster_fingerprint_benchmark
./build-bench/benchmarks/oefp_oecluster_fingerprint_benchmark 512 0 256

Tools

Tool Purpose
CMake C++ build system
SWIG Python bindings
scikit-build-core Python wheel build backend
cmake-openeye OpenEye CMake discovery and SWIG helpers
vrzn Version synchronization
pytest Python tests
Sphinx Documentation

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

oefp-0.2.6-cp310-abi3-win_amd64.whl (11.2 MB view details)

Uploaded CPython 3.10+Windows x86-64

oefp-0.2.6-cp310-abi3-manylinux_2_34_aarch64.whl (1.7 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.34+ ARM64

oefp-0.2.6-cp310-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (1.8 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.24+ x86-64manylinux: glibc 2.28+ x86-64

oefp-0.2.6-cp310-abi3-macosx_15_0_arm64.whl (962.0 kB view details)

Uploaded CPython 3.10+macOS 15.0+ ARM64

File details

Details for the file oefp-0.2.6-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: oefp-0.2.6-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 11.2 MB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for oefp-0.2.6-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 135ee970cccb97c1038823f0b79ca67d9f9f0f00386cda1678336dfd41eabaad
MD5 9513c64563909d6228cb1da53bf021c5
BLAKE2b-256 a79448e65b60bc0799d627f25c196f50e270ab5dfc63561dab838a27cf40b9ac

See more details on using hashes here.

Provenance

The following attestation bundles were made for oefp-0.2.6-cp310-abi3-win_amd64.whl:

Publisher: build-wheels.yml on scott-arne/oefp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file oefp-0.2.6-cp310-abi3-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for oefp-0.2.6-cp310-abi3-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 add2a9c3fda2b487d238f4c37e258f2f7e26b721a0b8414a9025a1aff0bd1acf
MD5 c9776d598c3f2fef84e7f51498089026
BLAKE2b-256 7a597b809fd619f067ff52cf7960fe3ab925a3d4ebf3d9a25e885e104a4d09fe

See more details on using hashes here.

Provenance

The following attestation bundles were made for oefp-0.2.6-cp310-abi3-manylinux_2_34_aarch64.whl:

Publisher: build-wheels.yml on scott-arne/oefp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file oefp-0.2.6-cp310-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for oefp-0.2.6-cp310-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 82f82dea1a83ce0bf6a93c9b8462f809abc80d93b1ce0c89c37b74fdd28f8d17
MD5 8def627dd54d3005b17aabdf6dd62bc7
BLAKE2b-256 f48ac69ecf6eeb6829d68f7005c6e7b22807661cd1f975832730e24c3466b799

See more details on using hashes here.

Provenance

The following attestation bundles were made for oefp-0.2.6-cp310-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl:

Publisher: build-wheels.yml on scott-arne/oefp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file oefp-0.2.6-cp310-abi3-macosx_15_0_arm64.whl.

File metadata

  • Download URL: oefp-0.2.6-cp310-abi3-macosx_15_0_arm64.whl
  • Upload date:
  • Size: 962.0 kB
  • Tags: CPython 3.10+, macOS 15.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for oefp-0.2.6-cp310-abi3-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 ad09a5f1b6b762c14cda4648487a9f79807c05b1f8584f7909ca8b6a2d08a682
MD5 1e28c49af013e84dc14a3bd017da8dd4
BLAKE2b-256 28b9847f378196c354f8c6dfbcfa5f135923b4c95bc1efd287086aae0ba6a3a2

See more details on using hashes here.

Provenance

The following attestation bundles were made for oefp-0.2.6-cp310-abi3-macosx_15_0_arm64.whl:

Publisher: build-wheels.yml on scott-arne/oefp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page