Skip to content
asadPublic

Repository files navigation

SMSD Pro

SMSD Pro™

Substructure and MCS search for chemical graphs

Maven Central PyPI Licence Release

SMSD Pro provides substructure search and maximum common substructure (MCS) search for C++, Java and Python, with the same search model in each language. Every result states whether the search completed, proved its optimum or stopped at its timeout, and maps atoms by their zero-based indices in the input molecules.

  • C++: a header-only C++17 library.
  • Java: a library and command-line tool for CDK 2.13 molecules, running on Java 8 or later.
  • Python: a binding to the native library that accepts RDKit molecules when RDKit is installed and converts Open Babel molecules.

Installation

Language Package Requirements
Python smsd on PyPI Python 3.9 or later (wheels for CPython 3.14); RDKit optional
Java com.bioinceptionlabs:smsd (library) and com.bioinceptionlabs:smsd-cli (command-line tool) on Maven Central Java 8 or later; CDK 2.13
C++ Header-only library in cpp/include A C++17 compiler

Release files are on the GitHub releases page. The installation guide covers platform requirements, downloads and source builds.

Quick start

Each example finds benzene in phenol, then computes their MCS. Run the commands from the repository root.

C++

Save this as example.cpp:

#include <smsd/smsd.hpp>
#include <iostream>

int main() {
    const auto query = smsd::parseSMILES("c1ccccc1");      // benzene
    const auto target = smsd::parseSMILES("c1ccc(O)cc1");  // phenol
    const bool embedded = !smsd::Substructure::find(query).match(target).matches.empty();
    const auto result = smsd::MCS::find(query).match(target);
    if (!embedded || !result.optimal || result.matches.empty()
            || result.matches.front().atomMapping.size() != 6) {
        return 1;
    }
    std::cout << "MCS atoms: " << result.matches.front().atomMapping.size() << '\n';
    return 0;
}
c++ -std=c++17 -O2 -pthread -I cpp/include example.cpp -o example
./example

See the C++ module and the C++ guide.

Java

Build and install the library and the command-line tool into the local Maven repository:

mvn -f java/pom.xml install

Maven projects can then use the library, which brings only the CDK modules it needs:

<dependency>
  <groupId>com.bioinceptionlabs</groupId>
  <artifactId>smsd</artifactId>
  <version>8.0.0</version>
</dependency>

In Gradle, write implementation("com.bioinceptionlabs:smsd:8.0.0"). The example below also parses SMILES, which needs org.openscience.cdk:cdk-smiles:2.13; the Java module lists the optional additions and the smsd-cli artefact. Save this as QuickStart.java:

import com.bioinception.smsd.core.MCS;
import com.bioinception.smsd.core.SearchResult;
import com.bioinception.smsd.core.Substructure;
import org.openscience.cdk.interfaces.IAtomContainer;
import org.openscience.cdk.silent.SilentChemObjectBuilder;
import org.openscience.cdk.smiles.SmilesParser;

public class QuickStart {
    public static void main(String[] args) throws Exception {
        SmilesParser parser = new SmilesParser(SilentChemObjectBuilder.getInstance());
        IAtomContainer query = parser.parseSmiles("c1ccccc1");      // benzene
        IAtomContainer target = parser.parseSmiles("c1ccc(O)cc1");  // phenol
        boolean embedded = Substructure.find(query).match(target).found();
        SearchResult result = MCS.find(query).withTimeout(1000).match(target);
        if (!embedded || !result.optimal() || !result.found()
                || result.matches().get(0).atomCount() != 6) {
            throw new IllegalStateException("Expected a proved six-atom match");
        }
        System.out.println("MCS atoms: " + result.matches().get(0).atomCount());
    }
}

Compile with Java 25 and run on Java 8 or later, here against the self-contained JAR of the build, which includes CDK and cdk-smiles:

javac --release 8 -cp java/cli/target/smsd-cli-8.0.0-jar-with-dependencies.jar QuickStart.java
java -cp "java/cli/target/smsd-cli-8.0.0-jar-with-dependencies.jar:." QuickStart

With a Java 8 compiler, omit --release 8. On Windows, separate the classpath entries with ; instead of :. The Java module shows atom mappings for CDK containers, and the Java guide covers the full API.

Python

Build and install the package from the checkout:

python -m pip install -e .
import smsd

query = "c1ccccc1"       # benzene
target = "c1ccc(O)cc1"   # phenol
assert smsd.Substructure.find(query).match(target).found
result = smsd.MCS.find(query).match(target)
assert result.optimal and result.best.atom_count == 6
print("MCS atoms:", result.best.atom_count)

See the Python package, the Python guide and the Python examples.

Screening

Rank a library by ECFP4 similarity, then search it by substructure as a prepared corpus; the search can use every core:

import smsd

library = ["CC(=O)Oc1ccccc1", "OC(=O)c1ccccc1O", "CC(=O)Nc1ccc(O)cc1", "c1ccccc1"]
ranked = smsd.batch_similarity("CC(=O)Oc1ccccc1C(=O)O", library)  # aspirin
corpus = smsd.TargetCorpus.from_smiles(library)
corpus.prewarm()
acids = smsd.Substructure.smarts("C(=O)[OX2H1]").match_many(corpus, num_threads=0)
print([library[i] for i, _ in ranked][:2], sum(r.found for r in acids))

The Python examples screen a library of 2,744 molecules and filter by MCS similarity before computing the MCS.

Command line

The Java build also produces the command-line tool, as a self-contained JAR:

java -jar java/cli/target/smsd-cli-8.0.0-jar-with-dependencies.jar \
  --Q SMI --q "c1ccccc1" --T SMI --t "c1ccc(O)cc1" --json -

This runs a substructure search; add --mode mcs for MCS search, and use --help to list every option. The tool also reads MOL, MOL2, CML and PDB files, and SDF files as batch targets.

Features

  • Substructure search with molecule or SMARTS queries, as non-induced (default) or induced embeddings.
  • MCS search for the maximum common induced subgraph (MCIS) or the maximum common edge subgraph (MCES), connected or as disconnected fragments, with optional atom weights.
  • Chemistry options for bond order, aromaticity, formal charge, isotopes, ring membership, stereo and tautomers.
  • Prepared queries that can be searched against many targets, in turn or on several threads.
  • Fingerprints for screening: circular (ECFP and FCFP), path, topological-torsion and structural-key fingerprints, including the 166 MACCS keys, configured once with FingerprintOptions (rings, ring sizes, R/S and E/Z, fragments, Murcko framework) and giving the same bits in C++, Java and Python. Batch searches can use every processor core, and C++ source builds can screen by MCS similarity on CUDA or Apple Metal.
  • Utilities, including R-group decomposition, MOL and SDF input, SVG depiction (C++ and Python) and molecular standardisation (Java).

Search calls

MCS and Substructure prepare a reusable query and offer the same calls:

Call C++ and Java Python
Best match for one target match(target) match(target)
All optimal MCS mappings, or all substructure embeddings, up to a limit (default 1,000) matchAll(target, limit) match_all(target, limit)
Independent searches over a collection of targets matchMany(targets) match_many(targets)

MCS defaults to a connected MCIS. Without atom weights, MCIS maximises mapped atoms, then bonds; MCES maximises common bonds, then their atoms. A search that reaches its timeout can still return a valid mapping, so check the completion and optimality flags before treating it as a proved optimum.

Documentation

Guide Contents
Installation Platform requirements, downloads and source builds
C++ guide Header-only library, chemistry options and file input
Java guide CDK molecules, search, fingerprints, R-groups and the command-line tool
Python guide Search, results, chemistry options and RDKit integration
Python examples Fingerprints, screening, depiction, layout, stereo, files and R-groups
Search algorithms Search guarantees, result semantics and differences between the languages
Benchmarks How to run the benchmarks and report results
Validation record Release checks for 8.0.0
Release notes Highlights, downloads and upgrade notes for 8.0.0
Changelog Changes in 8.0.0

The Java guide explains how to generate the Javadoc reference.

Licence

SMSD Pro is released under the Apache License 2.0. The same terms apply to academic and commercial use, with no fee or registration. Redistributions must include the LICENSE and NOTICE files and retain the copyright notices; the NOTICE file also sets out the trademark terms. Bundled dependencies carry their own licence notices. The Java CLI JAR with dependencies, the portable CLI archive and the Docker image bundle CDK under the LGPL-2.1; for the runtimes that Python wheels can bundle, see the LLVM OpenMP, GCC OpenMP and Microsoft C++ and OpenMP notices.

Citation

If you use SMSD Pro in research, please cite:

Rahman SA. SMSD Pro: Coverage-Driven, Tautomer-Aware Maximum Common Substructure Search. ChemRxiv, 2026. DOI: 10.26434/chemrxiv.15001534/v1

Rahman SA, Bashton M, Holliday GL, Schrader R, Thornton JM. Small Molecule Subgraph Detector (SMSD) toolkit. Journal of Cheminformatics, 1:12, 2009. DOI: 10.1186/1758-2946-1-12

Citation metadata is available in CITATION.cff.

Copyright (c) 2018-2026 BioInception PVT LTD. Algorithm Copyright (c) 2009-2026 Syed Asad Rahman.

Releases

Packages

Used by

Contributors

Languages