Skip to content

Commit

Permalink
Merge pull request #36 from sgoodlett/sgoodlett
Browse files Browse the repository at this point in the history
Tests and CI updates. Also Ih fix
  • Loading branch information
nlk36701 authored Nov 20, 2024
2 parents 99aa8cf + aaba50c commit 07f6b5e
Show file tree
Hide file tree
Showing 151 changed files with 1,187 additions and 326 deletions.
17 changes: 15 additions & 2 deletions .github/workflows/workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@ jobs:
strategy:
matrix:
cfg:
- conda-env: base
python-version: 3.8
- conda-env: base
python-version: 3.9
- conda-env: base
python-version: "3.10"
- conda-env: base
python-version: "3.11"
- conda-env: base
python-version: "3.12"
- conda-env: base
python-version: "3.13"
env:
PYVER: ${{ matrix.cfg.python-version }}
CONDA_ENV: ${{ matrix.cfg.conda-env }}
Expand All @@ -36,3 +40,12 @@ jobs:
pytest --cov="molsym" --color=yes --cov-report=xml test/
- name: Upload Coverage to Codecov
uses: codecov/codecov-action@v2
with:
directory: ./coverage/reports/
env_vars: OS,PYTHON
fail_ci_if_error: false
files: ./coverage.xml
flags: unittests
name: codecov-umbrella
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true
Empty file modified LICENSE.txt
100644 → 100755
Empty file.
Empty file modified PsiCon_2023.ipynb
100644 → 100755
Empty file.
6 changes: 3 additions & 3 deletions README.md
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
</a>
</td>
<td align="center">
<a href=https://codecov.io/gh/CCQC/MolSym>
<img src=https://codecov.io/gh/CCQC/MolSym/branch/main/graph/badge.svg?token=NQDJ0QYLB0>
<a href=https://codecov.io/gh/NASymmetry/MolSym>
<img src=https://codecov.io/gh/NASymmetry/MolSym/branch/main/graph/badge.svg?token=NQDJ0QYLB0>
</a>
</td>
</tr>
Expand All @@ -42,7 +42,7 @@ Create a new conda environment with:

`conda create -n "NameYourEnvironment" python=3.X`

MolSym is tested with Python 3.8, 3.9, and 3.10 but should work for more recent versions as well.
MolSym is tested with Python 3.9-3.13, but should work for more recent versions and some older versions as well.

`git clone git@github.com:NASymmetry/MolSym.git`

Expand Down
5 changes: 0 additions & 5 deletions acetylene.xyz

This file was deleted.

5 changes: 3 additions & 2 deletions base.yaml
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
name: test
channels:
- defaults
- conda-forge
- psi4
dependencies:
# Base
- numpy
- numpy>=2.0.0
- python
- qcelemental
- qcelemental>=0.28.0
#- psi4
- pytest
- pytest-cov
Expand Down
Empty file modified docs/Makefile
100644 → 100755
Empty file.
Empty file modified docs/SI/irrep_mats_SI.pdf
100644 → 100755
Empty file.
19 changes: 19 additions & 0 deletions docs/_templates/class.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{{ fullname | escape | underline}}

{{ module }}

{{ objname }}

{% block attributes %} {% if attributes %} .. rubric:: Attributes

{% for item in attributes %}
~{{ fullname }}.{{ item }}

{%- endfor %} {% endif %} {% endblock %}

{% block methods %} {% if methods %} .. rubric:: Methods

{% for item in methods %}
{%- if item != '__init__' %} ~{{ fullname }}.{{ item }} {%- endif -%}

{%- endfor %} {% endif %} {% endblock %}
Empty file modified docs/api.rst
100644 → 100755
Empty file.
2 changes: 1 addition & 1 deletion docs/conf.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
]

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
templates_path = ['docs/_templates']

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
Expand Down
Empty file modified docs/generated/molsym.molecule.rst
100644 → 100755
Empty file.
Empty file modified docs/generated/molsym.pgdetect.flowchart.rst
100644 → 100755
Empty file.
Empty file modified docs/generated/molsym.pgdetect.flowchart_helper.rst
100644 → 100755
Empty file.
Empty file modified docs/generated/molsym.pgdetect.rst
100644 → 100755
Empty file.
Empty file modified docs/generated/molsym.rst
100644 → 100755
Empty file.
Empty file modified docs/generated/molsym.salcs.SymmetryEquivalentIC.rst
100644 → 100755
Empty file.
Empty file modified docs/generated/molsym.salcs.cartesian_coordinates.rst
100644 → 100755
Empty file.
Empty file modified docs/generated/molsym.salcs.function_set.rst
100644 → 100755
Empty file.
Empty file modified docs/generated/molsym.salcs.internal_coordinates.rst
100644 → 100755
Empty file.
Empty file modified docs/generated/molsym.salcs.linear_functions.rst
100644 → 100755
Empty file.
Empty file modified docs/generated/molsym.salcs.projection_op.rst
100644 → 100755
Empty file.
Empty file modified docs/generated/molsym.salcs.rst
100644 → 100755
Empty file.
Empty file modified docs/generated/molsym.salcs.salc.rst
100644 → 100755
Empty file.
Empty file modified docs/generated/molsym.salcs.spherical_harmonics.rst
100644 → 100755
Empty file.
Empty file modified docs/generated/molsym.symmetrize.rst
100644 → 100755
Empty file.
Empty file modified docs/generated/molsym.symtext.Ih_irrep_mats.rst
100644 → 100755
Empty file.
Empty file modified docs/generated/molsym.symtext.character_table.rst
100644 → 100755
Empty file.
Empty file modified docs/generated/molsym.symtext.general_irrep_mats.rst
100644 → 100755
Empty file.
Empty file modified docs/generated/molsym.symtext.goat.rst
100644 → 100755
Empty file.
Empty file modified docs/generated/molsym.symtext.irrep_mats.rst
100644 → 100755
Empty file.
Empty file modified docs/generated/molsym.symtext.linear_helper.rst
100644 → 100755
Empty file.
Empty file modified docs/generated/molsym.symtext.multiplication_table.rst
100644 → 100755
Empty file.
Empty file modified docs/generated/molsym.symtext.point_group.rst
100644 → 100755
Empty file.
Empty file modified docs/generated/molsym.symtext.rst
100644 → 100755
Empty file.
Empty file modified docs/generated/molsym.symtext.symel.rst
100644 → 100755
Empty file.
Empty file modified docs/generated/molsym.symtext.symtext.rst
100644 → 100755
Empty file.
Empty file modified docs/generated/molsym.symtext.symtext_helper.rst
100644 → 100755
Empty file.
Empty file modified docs/generated/molsym.symtools.rst
100644 → 100755
Empty file.
Empty file modified docs/index.md
100644 → 100755
Empty file.
Empty file modified docs/index.rst
100644 → 100755
Empty file.
Empty file modified docs/make.bat
100644 → 100755
Empty file.
21 changes: 20 additions & 1 deletion docs/usage.rst
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,4 +1,23 @@
Usage
=====

How to use MolSym.
MolSym is an open-source Python package for handling molecular symmetry.
Features of MolSym include:

* Point group detection
* Molecule symmetrization
* Symmetry element, irreducible representation, irreducible representation matrices, and character table generation for arbitrary point groups
* Symmetry adapted linear combinations for internal coordinates, Cartesian nuclear coordinates, spherical harmonic basis functions, and Cartesian basis functions

Point Group detection
---------------------


Symmetrization
--------------

Symtext generation
------------------

SALCs
-----
4 changes: 2 additions & 2 deletions environment.yml
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ channels:
- defaults
- conda-forge
dependencies:
- numpy>=1.23.4
- qcelemental >= 0.25.1
- numpy>=2.0.0
- qcelemental >= 0.28.0
- sphinx >= 7.3.7
- sphinx_rtd_theme >= 2.0.0
46 changes: 0 additions & 46 deletions input.py

This file was deleted.

Empty file modified molsym.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file modified molsym/__init__.py
100644 → 100755
Empty file.
93 changes: 91 additions & 2 deletions molsym/molecule.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,42 @@

@dataclass
class Atom():
"""
Dataclass for storing atom information
:param Z: Atomic number of atom.
:param mass: Mass of atom in amu as defined by QCElemental.
:param xyz: Position vector of atom in Cartesian coordinates.
:type Z: int
:type mass: float
:type xyz: NumPy array of shape (3,)
"""
Z:int
mass:float
xyz:np.array

@dataclass
class SEA():
"""
SEA: symmetry equivalent atoms.
SEAs are atoms that can be swapped with no distinguishable change in the molecule.
:param label: Optionally defines rotor type of SEA set (e.g. Single Atom, Linear, Spherical, Regular Polygon, Oblate Symmetric Top, etc.)
:param subset: Sublist of atom indices in molecule that constitute the SEA set
:param axis: Optionally defines possible rotational symmetry vector
:type label: str or None
:type subset: NumPy array of integers
:type axis: NumPy array of shape (3,) or None
"""
label:str
subset:np.array
axis:np.array

class Molecule():
"""
Class dealing with molecule relevant information.
Typically initiated from a QCSchema object.
"""
def __init__(self, atoms, coords, masses) -> None:
self.tol = 1e-5
self.atoms = np.asarray(atoms)
Expand All @@ -29,6 +54,13 @@ def __init__(self, atoms, coords, masses) -> None:

@classmethod
def from_schema(cls, schema):
"""
Class method for constructing a Molecule from a QCSchema object
:param schema: Schema dictionary to be converted to Molecule
:type schema: dict
:rtype: molsym.Molecule
"""
atoms = schema["symbols"]
natoms = len(atoms)
coords = np.reshape(schema["geometry"], (natoms,3))
Expand All @@ -40,6 +72,13 @@ def from_schema(cls, schema):

@classmethod
def from_file(cls, fn):
"""
Class method for constructing a Molecule from an *.xyz file
:param fn: Filename
:type fn: str
:rtype: molsym.Molecule
"""
with open(fn, "r") as lfn:
strang = lfn.read()
strang = "units bohr\n"+strang
Expand All @@ -48,7 +87,14 @@ def from_file(cls, fn):

@classmethod
def from_psi4_schema(cls, schema):
# Schemas coming from Psi4 are different for some reason?
"""
Class method for constructing a Molecule from a QCSchema object generated in Psi4.
Schemas coming from Psi4 are different for some reason?
:param schema: Schema dictionary to be converted to Molecule
:type schema: dict
:rtype: molsym.Molecule
"""
atoms = schema["elem"] # was symbols
natoms = len(atoms)
coords = np.reshape(schema["geom"], (natoms,3)) # was geometry
Expand Down Expand Up @@ -87,27 +133,58 @@ def __eq__(self, other):
return c1 and c2 and c3

def find_com(self):
"""
Get center of mass of molecule.
:return: Center of mass
:rtype: NumPy array of shape (3,)
"""
com = np.zeros(3)
for i in range(self.natoms):
com += self.masses[i]*self.coords[i,:]
return com / sum(self.masses)

def is_at_com(self):
"""
Checks if molecule is at center of mass already.
:rtype: bool
"""
if sum(abs(self.find_com())) < self.tol:
return True
else:
return False

def translate(self, r):
"""
Translates Cartesian positions of all atoms in molecule in place by vector r.
:param r: Translation vector
:type r: NumPy array of shape (3,)
"""
for i in range(self.natoms):
self.coords[i,:] -= r

def transform(self, M):
"""
Transform coordinates of molecule by matrix M and return new molecule.
:param M: Transformation matrix (e.g. rotation, reflection, etc.)
:type M: NumPy array (3,3)
:return: Molecule with transformed atom coordinates
:rtype: molsym.Molecule
"""
new_mol = deepcopy(self)
new_mol.coords = np.dot(new_mol.coords,np.transpose(M))
return new_mol

def distance_matrix(self):
"""
Calculates the interatomic distance matrix as all pairwise distances between atoms.
:return: Interatomic distance matrix
:rtype: NumPy array of shape (self.natoms,self.natoms)
"""
dm = np.zeros((self.natoms,self.natoms))
for i in range(self.natoms):
for j in range(i,self.natoms):
Expand All @@ -116,6 +193,13 @@ def distance_matrix(self):
return dm

def find_SEAs(self):
"""
Find sets of symmetry equivalent atoms.
Permutations of the distance matrix reveal which atoms form symmetry equivalent sets.
:return: List of symmetry equivalent atom sets
:rtype: List[molsym.SEA]
"""
dm = self.distance_matrix()
out = []
for i in range(self.natoms):
Expand Down Expand Up @@ -151,7 +235,12 @@ def find_SEAs(self):
return SEAs

def symmetrize(self, asym_tol=0.05):
# This code might be bad. Consider removing. Interatomic distances ---> Cart. not always well defined
"""
Symmetrizes molecule.
This code might be bad. Consider removing. Interatomic distances ---> Cart. not always well defined
:deprecated:
"""
print("Warning! Using this symmetrize (the one in Molecule) may fail!")
dm = self.distance_matrix()
SEAs = self.find_SEAs()
Expand Down
Empty file modified molsym/pgdetect/__init__.py
100644 → 100755
Empty file.
17 changes: 15 additions & 2 deletions molsym/pgdetect/flowchart.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,25 @@
from .flowchart_helper import *

def find_point_group(mol):
"""
Find the point group of a molecule.
Bases on the algorithm developed by:
Beruski, Otávio; Vidal, Luciano N. Algorithms for computer detection of
symmetry elements in molecular systems, J. Comp. Chem, 2013 doi:10.1002/jcc.23493
Returns a primary and secondary axis in order to define an orienation of the molecule
with resepct to the symmetry elements generated later.
:type mol: molsym.Molecule
:return: Schoenflies point group string, primary axis, and secondary axis
:rtype: (str, NumPy array of shape (3,), NumPy array of shape (3,))
"""

paxis = [0,0,0]
saxis = [0,0,0]
moit = calcmoit(mol)
Ia_mol, Ib_mol, Ic_mol = np.sort(np.linalg.eigh(moit)[0])
# Linear tops
if Ia_mol == 0.0:
if np.isclose(Ia_mol, 0.0, atol=mol.tol):
if isequivalent(mol, mol.transform(inversion_matrix())):
pg = "D0h"
else:
Expand All @@ -32,7 +45,7 @@ def find_point_group(mol):
# Reorienting vectors such that one face is on the z-axis with "pentagon" pointing at the POSITIVE y-axis
phi = (1+np.sqrt(5.0))/2
# Weirdness here, negative or positive???
theta =-np.arccos(phi/np.sqrt(1+(phi**2)))
theta = np.arccos(phi/np.sqrt(1+(phi**2)))
rmat = rotation_matrix(saxis, theta)
paxis = np.dot(rmat, tempaxis)
taxis = np.dot(rmat, paxis)
Expand Down
Loading

0 comments on commit 07f6b5e

Please sign in to comment.