Substructure and MCS Search for Chemical Graphs
SMSD provides substructure and maximum common substructure (MCS) search for Java, C++ and Python. It also includes fingerprints, molecular standardisation, stereo handling, depiction and R-group decomposition. Java integrates with CDK 2.13; C++ is a header-only C++17 library; Python binds the native library and supports optional RDKit integration.
The current GitHub release is 7.2.2. It supports Java 8 or later, fixes CML/PDB input and preserves UTF-8 CLI JSON. Downloads include Java packages, C++ headers, Python wheels and native installers for Windows, macOS and Linux. Python 7.2.2 is also on PyPI; Maven Central publication remains pending.
The current source introduces a breaking search API change. Use MCS for
maximum common substructure and Substructure for molecule or SMARTS queries.
Both prepare a reusable query and return mappings with completion and stopping
status. The examples below require a source build.
| Search | C++ and Java | Python |
|---|---|---|
| One result | match(target) |
match(target) |
| All embeddings, with a limit | matchAll(target, limit) |
match_all(target, limit) |
| A collection of targets | matchMany(targets) |
match_many(targets) |
| MCS objectives | MCIS or MCES; connected or disconnected fragments | Same |
MCIS preserves edges and non-edges and maximises atoms, then bonds. MCES selects compatible common edges and maximises bonds, then incident atoms. See the examples for chemistry, fragments and search limits, and the benchmark guide for measuring the source API.
| Package | Requirements |
|---|---|
| Java library or portable CLI | Java 8 or later; Java 25 LTS preferred |
| Windows MSI | Windows AMD64; includes Java 25 LTS |
| macOS DMG | macOS arm64; includes Java 25 LTS |
| Linux DEB | Debian-compatible Linux AMD64; includes Java 25 LTS |
| Windows Python wheel | CPython 3.14, AMD64, Windows 10 or later |
| macOS Python wheel | CPython 3.14, arm64, macOS 26 or later |
| Linux Python wheel | CPython 3.14, x86_64, glibc 2.28 or later |
| C++ library | C++17 compiler |
The MSI, DMG and DEB install the terminal Java CLI. Python wheels install the Python package separately. Windows and macOS installers are unsigned; the macOS application has an ad-hoc signature. See installer instructions for installation, launcher paths and platform details.
Download the JAR with its dependencies, then run it:
curl -LO https://github.com/asad/SMSD/releases/download/v7.2.2/smsd-7.2.2-jar-with-dependencies.jar
java -jar smsd-7.2.2-jar-with-dependencies.jar --version
java -jar smsd-7.2.2-jar-with-dependencies.jar \
--Q SMI --q "c1ccccc1" --T SMI --t "c1ccc(O)cc1" --json -This searches for benzene in phenol. Add --mode mcs for MCS search, or use
--help for all options. The CLI also reads MOL, MOL2, CML and PDB files and
supports SDF batch targets. See the Java guide.
Use these Maven coordinates for 7.2.2:
<dependency>
<groupId>com.bioinceptionlabs</groupId>
<artifactId>smsd</artifactId>
<version>7.2.2</version>
</dependency>Until 7.2.2 is available on Maven Central, install it from this source checkout
with mvn -f java/pom.xml install using Java 25. The example below uses the
unreleased prepared-query API; build the current source checkout with mvn -f java/pom.xml package -DskipTests first.
Save this as MCSExample.java:
import com.bioinception.smsd.core.MCS;
import com.bioinception.smsd.core.SearchResult;
import com.bioinception.smsd.core.Substructure;
import java.util.Map;
import org.openscience.cdk.interfaces.IAtomContainer;
import org.openscience.cdk.silent.SilentChemObjectBuilder;
import org.openscience.cdk.smiles.SmilesParser;
public class MCSExample {
public static void main(String[] args) throws Exception {
SmilesParser parser = new SmilesParser(SilentChemObjectBuilder.getInstance());
IAtomContainer query = parser.parseSmiles("c1ccccc1");
IAtomContainer target = parser.parseSmiles("c1ccc(O)cc1");
SearchResult result = MCS.find(query).withTimeout(1000).match(target);
if (!result.optimal() || !result.found()
|| result.matches().get(0).atomCount() != 6
|| !Substructure.find(query).match(target).found()) {
throw new IllegalStateException("Expected a proven six-atom benzene match");
}
SearchResult.Match match = result.matches().get(0);
for (Map.Entry<Integer, Integer> pair : match.atomMapping().entrySet()) {
System.out.println(query.getAtom(pair.getKey()).getSymbol() + " -> "
+ target.getAtom(pair.getValue()).getSymbol());
}
System.out.println("Common fragment: " + match.toSmiles(query));
}
}Compile with Java 25 and run on Java 8 or later:
javac --release 8 -cp java/target/smsd-7.2.2-jar-with-dependencies.jar MCSExample.java
java -cp "java/target/smsd-7.2.2-jar-with-dependencies.jar:." MCSExampleWhen compiling with Java 8, omit --release 8. On Windows, use
"java/target/smsd-7.2.2-jar-with-dependencies.jar;." as the classpath.
See the Java module for CDK container examples.
The examples use the current source API, which replaces the search entry
points in release 7.2.2. Build from source to use MCS and Substructure.
Install Python 7.2.2 from PyPI:
python -m pip install smsd==7.2.2
python -c "import smsd; print(smsd.__version__)"You can also download the matching wheel from the
GitHub release and install
that file with python -m pip install.
import smsd
query = "c1ccccc1"
target = "c1ccc(O)cc1"
assert smsd.Substructure.find(query).match(target).found
result = smsd.MCS.find(query).match(target)
assert result.best.atom_count == 6
print(result.best.atom_count, result.optimal)Release wheels use CPU and OpenMP. Optional CUDA and Apple Metal support requires a suitable source build. See Python installation and examples and the Python API guide.
Save this as example.cpp in a source checkout:
#include <smsd/smsd.hpp>
int main() {
auto query = smsd::parseSMILES("c1ccccc1");
auto target = smsd::parseSMILES("c1ccc(O)cc1");
const auto result = smsd::MCS::find(query).match(target);
return result.optimal && result.matches.front().atomMapping.size() == 6 ? 0 : 1;
}c++ -std=c++17 -Icpp/include example.cpp -o example
./exampleSee the C++ module and C++ API guide for chemistry options, file formats and integration.
Use Java 25, a C++17 compiler and a supported Python environment:
git clone https://github.com/asad/SMSD.git
cd SMSD
mvn -f java/pom.xml clean verify
cmake -S cpp -B build/cpp -DCMAKE_BUILD_TYPE=Release \
-DSMSD_BUILD_METAL=OFF -DSMSD_BUILD_CUDA=OFF
cmake --build build/cpp --config Release --parallel 4
python -m pip install -e .Each module has its own instructions: Java, C++ and Python. The installation guide covers prerequisites.
The release includes Linux arm64 and AMD64 Docker image archives. Select the architecture matching your Docker host:
SMSD_DOCKER_ARCH=arm64 # use amd64 for an x86_64 Docker host
gh release download v7.2.2 --repo asad/SMSD --dir downloads \
--pattern "smsd-7.2.2-docker-linux-${SMSD_DOCKER_ARCH}.tar.gz"
docker load --input "downloads/smsd-7.2.2-docker-linux-${SMSD_DOCKER_ARCH}.tar.gz"
docker run --rm "smsd:7.2.2-linux-${SMSD_DOCKER_ARCH}" --versionSee the release Docker guide for checksums and search commands.
| Guide | Contents |
|---|---|
| Java API | CDK containers, search, fingerprints and CLI |
| Python API | Native graphs, RDKit integration and bindings |
| C++ API | Header-only library and chemistry options |
| Examples | Feature examples and search contracts |
| Installation | Platform requirements and source builds |
| Native installers | MSI, DMG and DEB installation |
| Release notes | Changes in 7.2.2 |
| Changelog | Versioned API and behaviour changes |
| Publishing | GitHub, PyPI and Maven Central publication |
The release also includes a complete Java API reference. Search budgets limit work; a returned MCS mapping can be a valid result without proving global optimality. Atom mappings use zero-based input indices.
Java 7.2.2 passed its full suite on Java 8 and 25; Python tests passed on macOS, Linux and Windows. See validation results for exact platforms, counts and installer checks.
Benchmark results retain their measured versions, hardware and matching policies. They were not rerun for 7.2.2. See benchmark instructions to reproduce them.
Check the standalone Python, Java and C++ examples with the current SMSD source built and installed, a JDK and GCC or Clang. Install RDKit to include its integration examples:
python scripts/check_examples.py \
--jar java/target/smsd-7.2.2-jar-with-dependencies.jar \
--report build/example-check.jsonUse --languages python to check only Python. Each example runs in a separate
temporary directory; the report lists failures and missing optional dependencies.
SMSD is distributed under the Apache License 2.0. Retain the NOTICE, licence and copyright notices when redistributing. Bundled dependencies include their own licence notices.
If you use SMSD 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.
Syed Asad Rahman — BioInception PVT LTD
Copyright (c) 2018-2026 BioInception PVT LTD. Algorithm Copyright (c) 2009-2026 Syed Asad Rahman.