Rapid Similarity Searching of Large Molecule Files

Problem

You want to perform rapid 2D similarity search on large molecule files.

Ingredients

Difficulty level

🌶️ 🌶️

Download

Download code

makefastfp.py to generate binary fast fingerprint files

See also the Usage (makefastfp) subsection.

Download code

searchfastfp.py to search binary fast fingerprint files

See also the Usage (searchfastfp) subsection.

Source Code

makefastfp
#!/usr/bin/env python3
# (C) 2026 Cadence Design Systems, Inc. (Cadence)
# All rights reserved.
# TERMS FOR USE OF SAMPLE CODE The software below ("Sample Code") is
# provided to current licensees or subscribers of Cadence products or
# SaaS offerings (each a "Customer").
# Customer is hereby permitted to use, copy, and modify the Sample Code,
# subject to these terms. Cadence claims no rights to Customer's
# modifications. Modification of Sample Code is at Customer's sole and
# exclusive risk. Sample Code may require Customer to have a then
# current license or subscription to the applicable Cadence offering.
# THE SAMPLE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED.  OPENEYE DISCLAIMS ALL WARRANTIES, INCLUDING, BUT
# NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. In no event shall Cadence be
# liable for any damages or liability in connection with the Sample Code
# or its use.

"""Generate a fingerprint file for fast fingerprint search."""

import argparse
import datetime
import multiprocessing
import os
import sys
from pathlib import Path

import humanize
from openeye import oechem, oegraphsim
from rich.console import Console
from rich_argparse import HelpPreviewAction, RichHelpFormatter

__SCRIPT_NAME__ = Path(__file__).absolute().stem
__SCRIPT_DESC__ = "Generate a fingerprint file for fast fingerprint search."
__SCRIPT_TOOLKITS__ = ["oechem", "oegraphsim"]
__SCRIPT_KEYWORDS__ = ["fingerprints", "similarity"]
__SCRIPT_CATEGORIES__ = ["cheminformatics"]


def parse_options() -> argparse.Namespace:
    """Set up command line options."""
    parser = argparse.ArgumentParser(
        add_help=True,
        formatter_class=RichHelpFormatter,
        description="[yellow]" + __SCRIPT_DESC__ + "[/yellow]",
    )

    io_group = parser.add_argument_group("Input/output options")
    io_group.add_argument(
        "--mol",
        type=str,
        required=True,
        metavar="MOL-FILE",
        help="input molecule file",
    )
    io_group.add_argument(
        "--fp-database",
        type=str,
        required=True,
        metavar="BINARY-FILE",
        help="output fingerprint database file (.fpbin)",
    )

    fp_group = parser.add_argument_group("Fingerprint generation options")
    fp_group.add_argument(
        "--fp-type",
        type=str,
        default="tree",
        choices=["tree", "circular", "path"],
        help="fingerprint type (default: %(default)s)",
    )
    fp_group.add_argument(
        "--fp-size",
        type=int,
        default=4096,
        choices=[512, 1024, 2048, 4096, 8192],
        help="fingerprint size (default: %(default)s)",
    )

    parser.add_argument(
        "--num-processors",
        type=int,
        default=multiprocessing.cpu_count() - 1,
        metavar="N",
        help="number of processors (default: %(default)s)",
    )
    parser.add_argument("--help-image", action=HelpPreviewAction)
    parser.add_argument(
        "--save-console-svg",
        default=False,
        action="store_true",
        help=f"run command and capture console output in {__SCRIPT_NAME__}.svg file",
    )
    return parser.parse_args()


def main() -> int:
    """Generate a binary fingerprint file for fast fingerprint search."""
    args = parse_options()

    console = Console(record=args.save_console_svg)
    num_processors: int = max(1, min(args.num_processors, multiprocessing.cpu_count()))

    if Path(args.fp_database).suffix != ".fpbin":
        oechem.OEThrow.Fatal(
            "Fingerprint database file should have '.fpbin' file extension!"
        )

    idx_fname = oechem.OEGetMolDatabaseIdxFileName(args.mol)

    if not Path(idx_fname).exists() and not oechem.OECreateMolDatabaseIdx(args.mol):
        oechem.OEThrow.Warning(f"Unable to create {idx_fname} molecule index file")

    console.print(f"Using {Path(idx_fname).name} index molecule file")

    mol_db = oechem.OEMolDatabase()
    if not mol_db.Open(args.mol):
        oechem.OEThrow.Fatal("Cannot open molecule database file!")
        return os.EX_DATAERR

    fp_type = _get_fp_type(args)
    if fp_type is None:
        oechem.OEThrow.Fatal(f"Unsupported fingerprint type: {args.fp_type}")
        return os.EX_DATAERR

    console.print(
        f"Using fingerprint type {fp_type.GetFPTypeString()}", highlight=False
    )

    opts = oegraphsim.OECreateFastFPDatabaseOptions(fp_type)
    opts.SetNumProcessors(num_processors)
    dots = oechem.OEDots(100000, 1000, "fingerprints")
    opts.SetTracer(dots)

    console.print(f"Generating fingerprints with {opts.GetNumProcessors()} threads")

    timer = oechem.OEWallTimer()
    if not oegraphsim.OECreateFastFPDatabaseFile(args.fp_database, args.mol, opts):
        oechem.OEThrow.Fatal("Cannot create fingerprint database file!")

    delta = datetime.timedelta(seconds=timer.Elapsed())
    console.print(
        f"[blue]{humanize.precisedelta(delta)}[/blue] to generate {humanize.intcomma(mol_db.GetMaxMolIdx())} fingerprints"
    )

    if args.save_console_svg:
        console.save_svg(f"{__SCRIPT_NAME__}.svg", title="output")
    return os.EX_OK


def _get_fp_type(args: argparse.Namespace) -> oegraphsim.OEFPTypeBase | None:
    """Return the fingerprint type object for the given name."""
    match args.fp_type:
        case "tree":
            return oegraphsim.OEGetTreeFPType(
                args.fp_size,
                0,
                4,
                oegraphsim.OEFPAtomType_DefaultTreeAtom,
                oegraphsim.OEFPBondType_DefaultTreeBond,
            )

        case "circular":
            return oegraphsim.OEGetCircularFPType(
                args.fp_size,
                0,
                5,
                oegraphsim.OEFPAtomType_DefaultCircularAtom,
                oegraphsim.OEFPBondType_DefaultCircularBond,
            )
        case "path":
            return oegraphsim.OEGetPathFPType(
                args.fp_size,
                0,
                5,
                oegraphsim.OEFPAtomType_DefaultPathAtom,
                oegraphsim.OEFPBondType_DefaultPathBond,
            )

    return None


setattr(main, "__SCRIPT_NAME__", __SCRIPT_NAME__)
setattr(main, "__SCRIPT_DESC__", __SCRIPT_DESC__)
setattr(main, "__SCRIPT_TOOLKITS__", __SCRIPT_TOOLKITS__)
setattr(main, "__SCRIPT_KEYWORDS__", __SCRIPT_KEYWORDS__)
setattr(main, "__SCRIPT_CATEGORIES__", __SCRIPT_CATEGORIES__)

if __name__ == "__main__":
    sys.exit(main())
searchfastfp
#!/usr/bin/env python3
# (C) 2026 Cadence Design Systems, Inc. (Cadence)
# All rights reserved.
# TERMS FOR USE OF SAMPLE CODE The software below ("Sample Code") is
# provided to current licensees or subscribers of Cadence products or
# SaaS offerings (each a "Customer").
# Customer is hereby permitted to use, copy, and modify the Sample Code,
# subject to these terms. Cadence claims no rights to Customer's
# modifications. Modification of Sample Code is at Customer's sole and
# exclusive risk. Sample Code may require Customer to have a then
# current license or subscription to the applicable Cadence offering.
# THE SAMPLE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED.  OPENEYE DISCLAIMS ALL WARRANTIES, INCLUDING, BUT
# NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. In no event shall Cadence be
# liable for any damages or liability in connection with the Sample Code
# or its use.

"""Search a fast fingerprint database for similar molecules."""

import argparse
import datetime
import os
import sys
from pathlib import Path

import humanize
import rich.table
from openeye import oechem, oegraphsim
from rich.console import Console
from rich_argparse import HelpPreviewAction, RichHelpFormatter

__SCRIPT_NAME__ = Path(__file__).absolute().stem
__SCRIPT_DESC__ = "Search a fast fingerprint database for similar molecules."
__SCRIPT_TOOLKITS__ = ["oechem", "oegraphsim"]
__SCRIPT_KEYWORDS__ = ["fingerprints", "similarity", "search"]
__SCRIPT_CATEGORIES__ = ["cheminformatics"]


def parse_options() -> argparse.Namespace:
    """Set up command line options."""
    parser = argparse.ArgumentParser(
        add_help=True,
        formatter_class=RichHelpFormatter,
        description="[yellow]" + __SCRIPT_DESC__ + "[/yellow]",
    )
    io_group = parser.add_argument_group("Input/output options")
    io_group.add_argument(
        "--query",
        type=str,
        required=True,
        metavar="MOL-FILE",
        help="input query molecule file",
    )
    io_group.add_argument(
        "--mol",
        type=str,
        required=True,
        metavar="MOL-FILE",
        help="input molecule database file",
    )
    io_group.add_argument(
        "--fp-database",
        type=str,
        required=True,
        metavar="BINARY-FILE",
        help="input fast fingerprint database file (.fpbin)",
    )
    io_group.add_argument(
        "--hits",
        type=str,
        required=True,
        metavar="MOL-FILE",
        help="output molecule file of similarity search hits",
    )

    search_group = parser.add_argument_group("Search options")
    search_group.add_argument(
        "--num-hits",
        type=int,
        default=10,
        metavar="N",
        help="number of hits to return (default: %(default)s)",
    )
    search_group.add_argument(
        "--cutoff",
        type=float,
        default=0.0,
        metavar="SCORE",
        help="minimum similarity score cutoff (default: %(default)s)",
    )
    search_group.add_argument(
        "--memory-mode",
        type=str,
        default="memory-mapped",
        choices=["memory-mapped", "in-memory"],
        help="memory mode for fingerprint database (default: %(default)s)",
    )

    parser.add_argument("--help-image", action=HelpPreviewAction)
    parser.add_argument(
        "--save-console-svg",
        default=False,
        action="store_true",
        help=f"run command and capture console output in {__SCRIPT_NAME__}.svg file",
    )
    parser.add_argument(
        "--display-top-hits",
        default=False,
        action="store_true",
        help="display top ten hits with scores in console",
    )

    return parser.parse_args()


def main() -> int:
    """Search a fast fingerprint database for similar molecules."""
    args = parse_options()

    console = Console(record=args.save_console_svg)

    timer = oechem.OEWallTimer()

    query: oechem.OEGraphMol = _get_query_molecule(args.query)
    console.print(
        f"Query molecule: {oechem.OEMolToSmiles(query)}", markup=False, highlight=False
    )

    ofs = oechem.oemolostream()
    if not ofs.open(args.hits):
        oechem.OEThrow.Fatal("Cannot open output file!")

    mol_database = oechem.OEMolDatabase()
    if not mol_database.Open(args.mol):
        oechem.OEThrow.Fatal("Cannot open molecule database!")

    timer.Start()
    memory_type = (
        oegraphsim.OEFastFPDatabaseMemoryType_MemoryMapped
        if args.memory_mode == "memory-mapped"
        else oegraphsim.OEFastFPDatabaseMemoryType_InMemory
    )
    fp_database = oegraphsim.OEFastFPDatabase(args.fp_database, memory_type)
    if not fp_database.IsValid():
        oechem.OEThrow.Fatal("Cannot open fingerprint database!")
    num_fingerprints = fp_database.NumFingerPrints()

    if not oegraphsim.OEAreCompatibleDatabases(mol_database, fp_database):
        oechem.OEThrow.Fatal("Databases are not compatible!")

    delta = datetime.timedelta(seconds=timer.Elapsed())
    console.print(
        f"[blue]{humanize.precisedelta(delta)}[/blue] secs to initialize databases"
        f" [blue]{fp_database.GetMemoryTypeString()}[/blue] mode"
    )

    fp_type = fp_database.GetFPTypeBase()
    console.print(
        f"Using fingerprint type {fp_type.GetFPTypeString()}", highlight=False
    )

    opts = oegraphsim.OEFPDatabaseOptions(
        args.num_hits, oegraphsim.OESimMeasure_Tanimoto
    )
    opts.SetCutoff(args.cutoff)

    timer.Start()
    scores = fp_database.GetSortedScores(query, opts)
    delta = datetime.timedelta(seconds=timer.Elapsed())

    console.print(
        f"[blue]{humanize.precisedelta(delta)}[/blue] to search {humanize.intcomma(num_fingerprints)} fingerprints"
    )

    columns = ["score", "smiles"]
    table = rich.table.Table(*columns)

    hit = oechem.OEGraphMol()
    hit_count = 0
    for si in scores:
        if mol_database.GetMolecule(hit, si.GetIdx()):
            oechem.OESetSDData(hit, "Similarity score", f"{si.GetScore():.4f}")
            oechem.OEWriteMolecule(ofs, hit)
            if args.display_top_hits and hit_count < 10:  # noqa: PLR2004
                table.add_row(f"{si.GetScore():.4f}", oechem.OEMolToSmiles(hit))
            hit_count += 1

    if args.display_top_hits:
        console.print(table)

    if args.save_console_svg:
        console.save_svg(f"{__SCRIPT_NAME__}.svg", title="output")
    return os.EX_OK


def _get_query_molecule(filename: str) -> oechem.OEGraphMol:
    ifs = oechem.oemolistream()
    if not ifs.open(filename):
        oechem.OEThrow.Fatal("Cannot open query file!")
    query = oechem.OEGraphMol()
    if not oechem.OEReadMolecule(ifs, query):
        oechem.OEThrow.Fatal("Cannot read query molecule!")
    return query


setattr(main, "__SCRIPT_NAME__", __SCRIPT_NAME__)
setattr(main, "__SCRIPT_DESC__", __SCRIPT_DESC__)
setattr(main, "__SCRIPT_TOOLKITS__", __SCRIPT_TOOLKITS__)
setattr(main, "__SCRIPT_KEYWORDS__", __SCRIPT_KEYWORDS__)
setattr(main, "__SCRIPT_CATEGORIES__", __SCRIPT_CATEGORIES__)

if __name__ == "__main__":
    sys.exit(main())

Solution

In order to solve this problem, two databases are utilized:

See also

This recipe discusses two code examples:

  • Generating Fingerprints section shows how to generate fingerprints and save them into a binary fingerprint file.

  • Searching Fingerprints section illustrates how to perform rapid similarity search using the pre-generated fingerprints.

Generating Fingerprints

In order to accelerate molecule similarity search, fingerprints that encode local features of molecules are generated and stored in a binary file with a .fpbin extension. The following code snippet shows how to generate a binary fingerprint file. See Figure 1 that illustrates the overall process of fingerprint generation.

First, an OEMolDatabase object is initialized with the input molecule filename. The fingerprint type is determined from the --fp-type command-line argument. A binary fingerprint file is then generated by the OECreateFastFPDatabaseFile function. The fingerprint generation is multi-threaded. The number of processors that are utilized can be controlled via the OECreateFastFPDatabaseOptions class. (See also: Performance of fingerprint generation section.)

def main() -> int:
    """Generate a binary fingerprint file for fast fingerprint search."""
    args = parse_options()

    console = Console(record=args.save_console_svg)
    num_processors: int = max(1, min(args.num_processors, multiprocessing.cpu_count()))

    if Path(args.fp_database).suffix != ".fpbin":
        oechem.OEThrow.Fatal(
            "Fingerprint database file should have '.fpbin' file extension!"
        )

    idx_fname = oechem.OEGetMolDatabaseIdxFileName(args.mol)

    if not Path(idx_fname).exists() and not oechem.OECreateMolDatabaseIdx(args.mol):
        oechem.OEThrow.Warning(f"Unable to create {idx_fname} molecule index file")

    console.print(f"Using {Path(idx_fname).name} index molecule file")

    mol_db = oechem.OEMolDatabase()
    if not mol_db.Open(args.mol):
        oechem.OEThrow.Fatal("Cannot open molecule database file!")
        return os.EX_DATAERR

    fp_type = _get_fp_type(args)
    if fp_type is None:
        oechem.OEThrow.Fatal(f"Unsupported fingerprint type: {args.fp_type}")
        return os.EX_DATAERR

    console.print(
        f"Using fingerprint type {fp_type.GetFPTypeString()}", highlight=False
    )

    opts = oegraphsim.OECreateFastFPDatabaseOptions(fp_type)
    opts.SetNumProcessors(num_processors)
    dots = oechem.OEDots(100000, 1000, "fingerprints")
    opts.SetTracer(dots)

    console.print(f"Generating fingerprints with {opts.GetNumProcessors()} threads")

    timer = oechem.OEWallTimer()
    if not oegraphsim.OECreateFastFPDatabaseFile(args.fp_database, args.mol, opts):
        oechem.OEThrow.Fatal("Cannot create fingerprint database file!")

    delta = datetime.timedelta(seconds=timer.Elapsed())
    console.print(
        f"[blue]{humanize.precisedelta(delta)}[/blue] to generate {humanize.intcomma(mol_db.GetMaxMolIdx())} fingerprints"
    )

    if args.save_console_svg:
        console.save_svg(f"{__SCRIPT_NAME__}.svg", title="output")
    return os.EX_OK

The generated binary fingerprint file (with .fpbin extension) stores the following information for each molecule:

  • the index of the corresponding molecule in the OEMolDatabase object

  • the bit-vector of the fingerprint

  • the popcount of the fingerprint, i.e., the number of bits that are set in the given fingerprint

../_images/makefastfp.png

Figure 1. Schematic representation of fast fingerprint generation process

Usage (makefastfp)

See Download section to download the script.

> makefastfp --help
../_images/makefastfp-help.svg

The following example shows how to generate a binary fingerprint file for 100,000 molecules from the ChEMBL database chembl_36-100K.ism input file using the default tree fingerprint type:

> makefastfp --mol chembl_36-100K.ism --fp-database chembl_36-100K-tree.fpbin
../_images/makefastfp-01-stdout.svg

The generated .fpbin file stores not only fingerprints but also information about:

  • the endianness of the binary fingerprint file

  • the name of the molecule file to which the fingerprint file corresponds

  • the string representation of the fingerprint type

  • the number of fingerprints in the binary file

This information can be accessed via the OEFastFPDatabaseParams class or by peeking into the fingerprint file:

> head -4 chembl_36-100K-tree.fpbin

LE
chembl_36-100K.ism
Tree,ver=2.0.0,size=4096,bonds=0-4,atype=AtmNum|Arom|Chiral|FCharge|HvyDeg|Hyb,btype=Order
100000

Warning

The fast fingerprint search does not support endianness compatibility for performance reasons. This means that a binary fingerprint file generated on a little-endian computer cannot be searched on a computer that uses big-endian encoding.

--fp-type tree | circular | path
> makefastfp --mol chembl_36-100K.ism --fp-database chembl_36-100K-path.fpbin --fp-type path

GraphSim TK currently only supports the popcount search method for fingerprints with a size that is a multiple of 256. This means that the MACCS key fingerprint type is currently not supported. When customizing other fingerprint types such as tree, circular, or path, the size of the fingerprint must be a multiple of 256.

See also the User-defined Fingerprint section in the GraphSim TK manual.

Searching Fingerprints

The following code example illustrates how to search the binary fingerprint file generated by the previous example. See Figure 2 that illustrates the overall fingerprint search process.

In this example, two databases are utilized:

The correspondence between the two databases is maintained by molecule indexes (see Figure 2). This correspondence can be checked by calling the OEAreCompatibleDatabases function.

After initializing the databases, an OEFPDatabaseOptions object is created that controls how the fingerprint database is searched. For more details about the search options, see the Fingerprint search options section. The OEFastFPDatabase.GetSortedScores method returns an iterator over the calculated similarity scores (OESimScore) in sorted order. Each OESimScore holds a similarity score and the index of the corresponding fingerprint in the database. This index can be used to access the original molecule in the OEMolDatabase object and write the hits into an output molecule file.

def main() -> int:
    """Search a fast fingerprint database for similar molecules."""
    args = parse_options()

    console = Console(record=args.save_console_svg)

    timer = oechem.OEWallTimer()

    query: oechem.OEGraphMol = _get_query_molecule(args.query)
    console.print(
        f"Query molecule: {oechem.OEMolToSmiles(query)}", markup=False, highlight=False
    )

    ofs = oechem.oemolostream()
    if not ofs.open(args.hits):
        oechem.OEThrow.Fatal("Cannot open output file!")

    mol_database = oechem.OEMolDatabase()
    if not mol_database.Open(args.mol):
        oechem.OEThrow.Fatal("Cannot open molecule database!")

    timer.Start()
    memory_type = (
        oegraphsim.OEFastFPDatabaseMemoryType_MemoryMapped
        if args.memory_mode == "memory-mapped"
        else oegraphsim.OEFastFPDatabaseMemoryType_InMemory
    )
    fp_database = oegraphsim.OEFastFPDatabase(args.fp_database, memory_type)
    if not fp_database.IsValid():
        oechem.OEThrow.Fatal("Cannot open fingerprint database!")
    num_fingerprints = fp_database.NumFingerPrints()

    if not oegraphsim.OEAreCompatibleDatabases(mol_database, fp_database):
        oechem.OEThrow.Fatal("Databases are not compatible!")

    delta = datetime.timedelta(seconds=timer.Elapsed())
    console.print(
        f"[blue]{humanize.precisedelta(delta)}[/blue] secs to initialize databases"
        f" [blue]{fp_database.GetMemoryTypeString()}[/blue] mode"
    )

    fp_type = fp_database.GetFPTypeBase()
    console.print(
        f"Using fingerprint type {fp_type.GetFPTypeString()}", highlight=False
    )

    opts = oegraphsim.OEFPDatabaseOptions(
        args.num_hits, oegraphsim.OESimMeasure_Tanimoto
    )
    opts.SetCutoff(args.cutoff)

    timer.Start()
    scores = fp_database.GetSortedScores(query, opts)
    delta = datetime.timedelta(seconds=timer.Elapsed())

    console.print(
        f"[blue]{humanize.precisedelta(delta)}[/blue] to search {humanize.intcomma(num_fingerprints)} fingerprints"
    )

    columns = ["score", "smiles"]
    table = rich.table.Table(*columns)

    hit = oechem.OEGraphMol()
    hit_count = 0
    for si in scores:
        if mol_database.GetMolecule(hit, si.GetIdx()):
            oechem.OESetSDData(hit, "Similarity score", f"{si.GetScore():.4f}")
            oechem.OEWriteMolecule(ofs, hit)
            if args.display_top_hits and hit_count < 10:  # noqa: PLR2004
                table.add_row(f"{si.GetScore():.4f}", oechem.OEMolToSmiles(hit))
            hit_count += 1

    if args.display_top_hits:
        console.print(table)

    if args.save_console_svg:
        console.save_svg(f"{__SCRIPT_NAME__}.svg", title="output")
    return os.EX_OK
../_images/searchfastfp.png

Figure 2. Schematic representation of fast fingerprint search process

Usage (searchfastfp)

See Download section to download the script.

> searchfastfp --help
../_images/searchfastfp-help.svg
> searchfastfp --query caffeine.ism --mol chembl_36-100K.ism --fp-database chembl_36-100K-tree.fpbin --hits hits.ism --display-top-hits
../_images/searchfastfp-01-stdout.svg

Note

When the hits are saved to an .sdf file, the similarity scores are written to each hit with the <Similarity score> tag.

Discussion

Performance of fingerprint generation

The graph below shows the speed of generating 1 million 4096-bit long tree fingerprints using different number of processes. The performance has been benchmarked using m4.10x large AWS instance.

../_images/makefastfp-performance.png

Graph 1. The performance of the multi-threaded fingerprint generation for 1M fingerprints

Fingerprint search options

The OEFastFPDatabase class provides several ways to search fingerprints by utilizing the OEFPDatabaseOptions class:

  • By default, OETanimoto similarity coefficient is used to quantify the degree of resemblance between two fingerprints. However, other built-in similarity coefficients such as OECosine, OEDice, OEEuclidean, OEManhattan, and OETversky can also be used (see also OEFPDatabaseOptions.SetSimFunc method).

    Note

    The current implementation of the fast fingerprint search method does not allow utilizing a user-defined similarity measure. If this is desired the slower fingerprint search implemented in the OEFPDatabase class should be used.

  • By default, the OEFPDatabase.GetSortedScores method returns similarity scores in descending order, i.e., it identifies molecules that are most similar to the query. However, the order can be reversed to identify molecules that are most dissimilar to the query (see also OEFPDatabaseOptions.SetDescendingOrder method).

  • There is no default cut-off value defined for fingerprint search, since a reasonable cut-off value can depend on various parameters such as the fingerprint type, the query molecule, and the similarity measure used. The user can specify a cut-off value for a specific search using the OEFPDatabaseOptions.SetCutOff method.

  • By default, there is no limit on the number of similarity scores returned; however, searching and ordering millions of molecules is not recommended. A reasonable limit can be set by using the OEFPDatabaseOptions.SetLimit method.

See also in OEChem TK manual

Theory

API

See also in GraphSim TK manual

Theory

API