HashMol3D
HashMol3D is a standard, deterministic 3D molecular geometry identifier for computational chemistry, machine learning, and HPC workflows.
It produces a readable identifier of the form
<Hill formula><state tag>-<geometry hash>
e.g. H2Oq0m1-9a3a21fa2c3b6f0d4cb8acb76a18eccf for neutral singlet water. The trailing
geometry hash is rotation-, translation-, permutation-, and
parity-invariant (matching the invariances of the eigenvalues of the
non-relativistic molecular Hamiltonian), and depends on:
- atomic numbers
- coordinates quantized at a user-specified precision in a canonical frame
- a descriptor version tag
The default method projects the original coordinates into a deterministic
canonical frame, sorts the element-labelled coordinate rows, and hashes that
complete representation. Ordinary geometries use the principal axes of the
Z-weighted gyration tensor. Point-like, linear, symmetric-top, and spherical-
top geometries use intrinsic coordinates or canonical atom anchors, so exact
symmetry does not require a random perturbation. The older canonical labelled
distance-matrix method remains available as method="canonical".
Charge and spin multiplicity live in the readable prefix, not in the hash, so two states of the same geometry share the same hex tail and can be grouped by suffix matching:
H2Oq0m1-9a3a21fa2c3b6f0d4cb8acb76a18eccf # neutral singlet water
H2Oq1m2-9a3a21fa2c3b6f0d4cb8acb76a18eccf # water cation, same geometry → same hex tail
The geometry hash defaults to a fixed length of 32 hex chars (128 bits).
Collision resistance is governed by how many distinct geometries share a
namespace (birthday bound ~ n² / 2^{b+1} for b = 4·length bits), not
by molecule size; the 128-bit default keeps the expected collision count below
one for corpora up to ~10¹⁶ geometries. Pass length= to pin any value in
[1, 64], or call hash_length_for(n_items, target_prob) to size the hash to
your corpus:
from hashmol3d import hash_length_for
hash_length_for(10**9) # -> 23 hex chars for 1e9 items at p=1e-9
hash_molecule(z, coords, length=hash_length_for(10**9))
| distinct geometries | p=1e-6 |
p=1e-9 |
p=1e-12 |
|---|---|---|---|
| 10⁶ | 15 | 18 | 20 |
| 10⁹ | 20 | 23 | 25 |
| 10¹² | 25 | 28 | 30 |
| 10¹⁵ | 30 | 33 | 35 |
(recommended hex length; the default of 32 covers up to ~8·10¹⁴ items at p=1e-9.)
It deliberately does not distinguish enantiomers (which share their Hamiltonian eigenvalues). The reference implementation depends only on NumPy.
Canonical frame method
The default method="frame" normally takes O(N log N) time and O(N) memory
(a 100,000-atom asymmetric system hashes in ~0.3 s where a full distance
matrix would need 80 GB):
hash_molecule(z, coords) # method="frame" is the default
When principal moments are degenerate, the method preserves any isolated
axis and canonically anchors only the ambiguous subspace. Linear and point-
like systems are represented in their intrinsic dimension. Canonically tied
anchors are all evaluated up to a 10,000-candidate budget. Ill-conditioned
or over-budget cases emit UserWarning and use the complete distance method.
The path is visible in result.descriptor (F: versus C:/W:).
For an explicitly distance-based descriptor, use:
hash_molecule(z, coords, method="canonical")
Hashes from different descriptor paths are not comparable; use the same method and descriptor version throughout a corpus.
HashMol3D IDs are stable across machines, reproducible, and ideal for:
- workflow deduplication
- caching
- large QC datasets
- MD conformer tracking
- ML potential datasets
- LLM scientific agents
Install
Using pip
pip install hashmol3d
Using uv
# Install from PyPI
uv pip install hashmol3d
Install from source
# Clone the repository
git clone https://github.com/yourusername/HashMol3D.git
cd HashMol3D
# Create and activate a virtual environment (recommended)
# Using uv:
uv venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Or using standard Python:
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install the package in editable mode
uv pip install -e . # Or: pip install -e .
Usage (CLI)
$ hashmol3d water.xyz
H2Oq0m1-9a3a21fa2c3b6f0d4cb8acb76a18eccf
# Cation with explicit multiplicity — only the prefix changes.
$ hashmol3d -c 1 -m 2 water.xyz
H2Oq1m2-9a3a21fa2c3b6f0d4cb8acb76a18eccf
# Pin a fixed hash length and a coarser precision.
$ hashmol3d -p 1e-3 -l 32 benzene.xyz
# Verbose: also print formula, geometry hash, descriptor, and metadata.
$ hashmol3d -v water.xyz
# Request the labelled distance-matrix method explicitly.
$ hashmol3d --method canonical water.xyz
# Show the package version.
$ hashmol3d --version
Options include -p/--precision, -c/--charge, -m/--multiplicity,
-l/--length, --method, and -v/--verbose. Errors on missing or malformed input go
to stderr with exit code 1 (no Python traceback).
Usage (Python)
import numpy as np
from hashmol3d import hash_molecule
atomic_nums = np.array([8, 1, 1])
coords = np.array(
[
[0.0000, 0.0000, 0.0],
[0.7572, 0.5860, 0.0],
[-0.7572, 0.5860, 0.0],
]
)
res = hash_molecule(atomic_nums, coords)
print(res.hash_str) # H2Oq0m1-9a3a21fa2c3b6f0d4cb8acb76a18eccf
print(res.formula) # H2O
print(res.geometry_hash) # 9a3a21fa2c3b6f0d4cb8acb76a18eccf
print(res.charge, res.multiplicity) # 0 1
All optional arguments are keyword-only: precision, charge,
multiplicity, length, and method.
precision must be a power of ten no greater than 1 Å (1.0, 1e-1,
1e-2, ...). Restricting the grid to powers of ten keeps its descriptor
representation unambiguous and portable.
Or read straight from a file:
from hashmol3d import hash_xyz
print(hash_xyz("water.xyz").hash_str) # H2Oq0m1-9a3a21fa2c3b6f0d4cb8acb76a18eccf
print(hash_xyz("water.xyz", charge=1, multiplicity=2).hash_str)
# H2Oq1m2-9a3a21fa2c3b6f0d4cb8acb76a18eccf
See docs/ for the full
specification,
API reference, and
CLI guide.
Metadata
Release files for hashmol3d 0.9.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| hashmol3d-0.9.3.tar.gz | 33.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hashmol3d-0.9.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 55.1 kB
Release files / hashmol3d-0.9.3.tar.gz
| Download URL | hashmol3d-0.9.3.tar.gz |
|---|---|
| Size | 33.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
454792abc0e94afe50883cdc605c7d88b65410bc5d6726479f767cb0669e985a
|
|
BLAKE2b-256 checksum How to use checksums |
28a08e436e9af848e9ffcbd363ac161420e044c67ea4b3668f8dc4374b721f56
|
| 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 Sep 7, 2026.
Transparency logRelease files / hashmol3d-0.9.3-py3-none-any.whl
| Download URL | hashmol3d-0.9.3-py3-none-any.whl |
|---|---|
| Size | 22.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c5c781f9c078506bb7e926a04363a57991f7e4489a09c41bee84ac371a8226a9
|
|
BLAKE2b-256 checksum How to use checksums |
7e013827cabbe9d290e40fe92dd0b0dbff6eea45fd9bf218ce157041c34abd88
|
| 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 Sep 7, 2026.
Transparency log