Skip to main content

Molecular symmetry detection and symmetrization

Project description

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, get_point_group

atoms = unsymmetrized['C0v_1']   # by point-group key
atoms = unsymmetrized['CNH']     # equivalent: lookup by molecular formula
print(atoms.positions)

sym = symmetrize(atoms)
print(sym.positions)          # Lst of atomic coordinates
print(get_point_group(sym))   # C0v

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):
    print(s.pg, s.rmsd)                         # D6h, D3h, C6h, C6v, ...

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

# List available structures
print(unsymmetrized.names)   # ['C0v_1', 'C0v_2', ..., 'Td_3']
print(symmetrized.names)     # ['C0v_1', 'C0v_2', ..., 'Td_3']

# Load a structure by key  ('<PointGroup>_<index>')
mol_u = unsymmetrized['C3h_1']
mol_s = symmetrized['C3h_1']

# Iterate over all structures in a collection
for name in symmetrized.names:
    atoms = symmetrized[name]

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.

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

Project details


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.3.tar.gz (266.0 kB 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.3-py3-none-any.whl (269.7 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for molsympy-0.1.3.tar.gz
Algorithm Hash digest
SHA256 5e5f73fc337f3938e9bba5f73ff1a1df7255119bba077f131907f34c4eeb3f43
MD5 4ee51820f98d36bd5fa09ef20e9344c2
BLAKE2b-256 9468921abf5d9c2e4be7ea1b9564bc8a013b1d1d80e39079a7d0b4f34a697c09

See more details on using hashes here.

File details

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

File metadata

  • Download URL: molsympy-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 269.7 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.3-py3-none-any.whl
Algorithm Hash digest
SHA256 52a75fac39783ffa5d707a1b8de65488b7b6d893208b60e4e67636d4625dc3c3
MD5 56c326ada5a6d4a3c73f56a0b9da5f49
BLAKE2b-256 54fe44e824e994205c708c8d86a48f36664c8817fdcda676a68e51dea50344f6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page