Skip to main content

MolSymPy

Python License PyPI

MolSymPy is an open-source Python package for molecular symmetry analysis in atomistic simulations. It is built natively on top of the Atomic Simulation Environment (ASE) and operates directly on ase.Atoms objects, enabling seamless integration with atomistic simulation workflows.

Features

  • Geometric idealization — project nearly-symmetric structures onto their exact symmetry elements and orient the molecular frame by aligning principal and secondary symmetry axes with the Cartesian coordinate system.
  • Point group detection — identify molecular point groups in Schoenflies notation, including the two infinite-order linear groups (C∞v and D∞h).
  • Symmetry-inequivalent atoms — determine symmetry-inequivalent atoms using a path-compressed union-find algorithm operating on the complete symmetry permutation map.
  • Reference database — companion collection of molecular and atomic-cluster geometries spanning the principal point groups, available in both raw and idealized forms.

Performance-critical routines are accelerated through Numba just-in-time compilation, providing efficient execution with no compilation requirements at install time.

Installation

pip install molsympy

Requirements: Python ≥ 3.10, NumPy ≥ 1.24, Numba ≥ 0.61, ASE ≥ 3.22.

Quick start

Point group detection

from ase.build import molecule
from molsympy import get_point_group

cyclopropane = molecule('C3H6_D3h')
print(get_point_group(cyclopropane)) #D3h

Symmetry-inequivalent atoms

from molsympy.collections import symmetrized
from molsympy import get_inequivalent

mol = symmetrized['C3h_1']
unique, parent = get_inequivalent(mol, geom_tol=0.05, eigen_tol=0.01)
print(unique)    # [0, 1, 2, 9, 10]
print(parent)    # [0, 1, 2, 1, 0, 2, 1, 0, 2, 9, 10, 9, 10, 9, 10]

Symmetrization

from molsympy.collections import unsymmetrized
from molsympy import symmetrize

atoms_U = unsymmetrized['C0v_1']     # unsymmetrized ase.Atoms
print(atoms_U.positions)             # [[-1.332400e-02  1.132466e+00  8.276000e-03]
                                     #  [ 2.311000e-03 -1.915900e-02  1.929000e-03]
                                     #  [-2.780300e-02  2.198949e+00  1.415400e-02]]
atoms_S = symmetrize(atoms_U)        # symmetrize ase.Atoms
print(atoms_S.positions)             # [[ 0.          0.         -0.55714544]
                                     #  [ 0.          0.          0.59460318]
                                     #  [ 0.          0.         -1.62374292]]

Symmetry candidates (subgroup fan-out)

from ase.build import molecule
from molsympy import generate_symmetry_candidates

benzene = molecule('C6H6')                    # D6h
for s in generate_symmetry_candidates(benzene):
    # Access Atom object with s.mol
    print(s.pg, s.rmsd)                       # D6h 1.6032259480710427e-07, D3h 1.4451283412026997e-07, ...

API reference

get_point_group(mol, geom_tol=0.05, eigen_tol=None) → str

Determine the point group of a molecule.

Parameter Type Description
mol ase.Atoms Input molecule.
geom_tol float Geometric tolerance in Å (default 0.05).
eigen_tol float | None Relative tolerance for moment-of-inertia eigenvalues. Estimated automatically when None.

Returns the Schoenflies symbol as a string (e.g. "C2v", "D3h", "Oh").


symmetrize(mol, geom_tol=0.05, eigen_tol=None) → ase.Atoms

Project a nearly-symmetric structure onto exact point-group symmetry.

Each set of symmetry-equivalent atoms (SEA) is handled by projecting a representative atom onto the symmetry element that fixes it, then mapping the remaining SEA members via the stored matrix representation of the connecting symmetry operation.


get_inequivalent(mol, geom_tol=0.3, eigen_tol=None) → (np.ndarray, np.ndarray)

Find symmetry-inequivalent atoms.

Returns (unique, parent) where unique contains one representative index per equivalence class and parent[i] is the representative of atom i.


is_planar(mol, geom_tol=0.05) → bool

Check whether all atoms lie in a common plane.


generate_symmetry_candidates(mol, geom_tol=0.05, eigen_tol=None, sort_by=0) → list[SymmetryResult]

Generate symmetry-consistent geometries for all subgroups compatible with the detected point group.

Each SymmetryResult contains:

  • mol — the symmetrized ase.Atoms object
  • pg — the Schoenflies symbol
  • rmsd — RMSD (Å) between original and symmetrized structure

sort_by=0 sorts by group size (descending) then RMSD (ascending); sort_by=1 sorts by RMSD first.

Reference database

MolSymPy ships a companion database of molecular and atomic-cluster geometries indexed by point group:

from molsympy.collections import symmetrized, unsymmetrized

# Lists of molecule IDs
print(unsymmetrized.names)         #['C0v_1', 'C0v_2', …, 'Td_3']
print(symmetrized.names)           #['C0v_1', 'C0v_2', …, 'Td_3']
# Equivalent lists asking for molecular formulas (alphabetical order):
print(unsymmetrized.formulas)      # ['AgC68N4H76O4', 'AuC18P2N6H24', …, 'ZrSi7C24H52']
print(symmetrized.formulas)        # ['AgC68N4H76O4', 'AuC18P2N6H24', …, 'ZrSi7C24H52']
# ASE Atoms objects can be called from their molecule IDs or molecular formulas:
mol1 = symmetrized['C3h_1']
mol2 = symmetrized['C6H6O3']

The two collections are:

Object Content
symmetrized Idealized geometries with exact point-group symmetry
unsymmetrized Raw geometries with slight numerical distortions

Lookup by molecular formula

Every structure in the database can also be retrieved by its molecular formula. The key and the formula are interchangeable in all collection operations:

from molsympy.collections import symmetrized, unsymmetrized

# These two calls return the same structure
atoms = unsymmetrized['C0v_1']
atoms = unsymmetrized['CNH']     # equivalent

# Works with both collections
mol_u = unsymmetrized['H2O']     # same as unsymmetrized['C2v_1']
mol_s = symmetrized['H2O']       # same as symmetrized['C2v_1']

# List all available formulas
print(unsymmetrized.formulas)    # ['AgC68N4H76O4', 'AuC18P2N6H24', …, 'ZrSi7C24H52']

The formula stored for each entry is the one embedded in the .npz database. Each structure carries exactly one formula alias; looking up by key always works regardless of whether a formula is defined.

Examples

The examples/ directory contains standalone, runnable scripts for each feature shown above:

Script Description
1_get_point_group.py Detect the point group of a molecule.
2_get_inequivalent.py Find symmetry-inequivalent atoms.
3_symmetrize.py Symmetrize a distorted structure.
4_generate_symmetry_candidates.py Generate symmetry candidates for all compatible subgroups.
database_example.py Access the reference database by key or molecular formula.

License

MIT — see LICENSE.

Authors

  • Sebastian Hernandez-Gutierrez — Departamento de Física Aplicada, Cinvestav-IPN, Mérida, México
  • Diego Roman-Montalvo — Departamento de Física Aplicada, Cinvestav-IPN, Mérida, México
  • Gabriel Merino — Departamento de Física Aplicada, Cinvestav-IPN, Mérida, México
  • Filiberto Ortiz-Chi — Secihti-Departamento de Física Aplicada, Cinvestav-IPN, Mérida, México

If you use MolSymPy in your research, please cite the associated manuscript

Download files

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

Source Distribution

molsympy-0.1.4.tar.gz (31.4 MB view details)

Uploaded Source

Built Distribution

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

molsympy-0.1.4-py3-none-any.whl (270.2 kB view details)

Uploaded Python 3

File details

Details for the file molsympy-0.1.4.tar.gz.

File metadata

  • Download URL: molsympy-0.1.4.tar.gz
  • Upload date:
  • Size: 31.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for molsympy-0.1.4.tar.gz
Algorithm Hash digest
SHA256 a45f677e952f98d42c60e2ec9ee7f765944591052c669037727a5431705cc214
MD5 2bc0f1dc11534aef908f4579bac73b12
BLAKE2b-256 88da2c012f0c93773e7d4b90118072465b5a556610587bc595f6c5976bf8431f

See more details on using hashes here.

File details

Details for the file molsympy-0.1.4-py3-none-any.whl.

File metadata

  • Download URL: molsympy-0.1.4-py3-none-any.whl
  • Upload date:
  • Size: 270.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for molsympy-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 36825aecf7a59897cd16659fc191a7167704d82f4f37236a32c86cd6eeb317e6
MD5 7bce5989af33d8e9fae7a2198a6bf874
BLAKE2b-256 a7616a814e2a2e3f4e652279e873a823bea36c5442a087ea465fd906ddfdb9ee

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.5

2 files

This release

0.1.4 This release

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page