Source code for cosymlib.symmetry

from wfnsympy import WfnSympy
from symgroupy import Symgroupy
import numpy as np


def _get_key_symgroup(label, center, central_atom, connectivity, multi, connect_thresh):
    group_key = label.lower()
    center_key = ' '.join(['{:10.8f}'.format(n) for n in center]) if center is not None else None
    connectivity_key = np.array2string(np.array(connectivity), precision=10) if connectivity is not None else None
    multi_key = int(multi)
    central_atom_key = int(central_atom)
    connect_thresh_key = '{:10.8f}'.format(connect_thresh)
    return group_key, center_key, central_atom_key, connectivity_key, multi_key, connect_thresh_key


def _get_key_wfnsym(group, vector_axis1, vector_axis2, center, alpha_occupancy, beta_occupancy):
    group_key = group.lower()
    vec1_key = ' '.join(['{:10.8f}'.format(n) for n in vector_axis1]) if vector_axis1 is not None else None
    vec2_key = ' '.join(['{:10.8f}'.format(n) for n in vector_axis2]) if vector_axis2 is not None else None
    center_key = ' '.join(['{:10.8f}'.format(n) for n in center]) if center is not None else None
    alpha_occupancy_key = ' '.join(['{:10.8f}'.format(n) for n in alpha_occupancy]) if alpha_occupancy is not None else None
    beta_occupancy_key = ' '.join(['{:10.8f}'.format(n) for n in beta_occupancy]) if beta_occupancy is not None else None
    return group_key, vec1_key, vec2_key, center_key, alpha_occupancy_key, beta_occupancy_key


[docs]class Symmetry: """ Symmetry main class :param structure: a geometry, molecule or array type object :type structure: Geometry, Molecule, np.array :param central_atom: central atom position :type central_atom: int :param center: center of symmetry in Cartesian coordinates. By default center is optimized :type center: list :param connect_thresh: Connectivity threshold (Ionic radius is used as reference) :type connect_thresh: float :param multi: Number of symmetry axis to find :type multi: int :param axis: Main symmetry axis (If None, then optimize) :type axis: list :param axis2: secondary symmetry axis (If None, then optimize) :type axis2: list """ def __init__(self, structure, central_atom=0, center=None, connect_thresh=1.2, multi=1, axis=None, axis2=None, ): try: # Interpret as Geometry or molecule self._coordinates = structure.get_positions() self._symbols = structure.get_symbols() self._connectivity = structure.get_connectivity() except AttributeError: # Interpret as numpy array of coordinates or list of lists self._coordinates = structure self._symbols = None self._connectivity = None # If molecule object add electronic structure try: self._electronic_structure = structure.electronic_structure except AttributeError: self._electronic_structure = None self._central_atom = central_atom self._center = center self._connect_thresh = connect_thresh self._multi = multi self._axis = axis self._axis2 = axis2 self._results = {} # Modifier methods
[docs] def set_parameters(self, parameters_dict): """ Set symmetry calculation related parameters :param parameters_dict: parameters in dictionary :type parameters_dict: dict """ for name, value in parameters_dict.items(): setattr(self, '_' + name, value)
def set_electronic_structure(self, electronic_structure): self._electronic_structure = electronic_structure def _get_symgroup_results(self, group): """ # Temporal interface if central_atom is not None: self._central_atom = central_atom self._multi = multi self._center = center self._connect_thresh = connect_thresh """ # Crude calculation call methods key = _get_key_symgroup(group, self._center, self._central_atom, self._connectivity, self._multi, self._connect_thresh) if key not in self._results: self._results[key] = Symgroupy(self._coordinates, group=group, labels=self._symbols, central_atom=self._central_atom, multi=self._multi, center=self._center, connectivity=self._connectivity, connect_thresh=self._connect_thresh, permutation=None) return self._results[key] def _get_wfnsym_results(self, group): if self._electronic_structure is None: raise Exception('Electronic structure not set') key = _get_key_wfnsym(group, self._axis, self._axis2, self._center, self._electronic_structure.alpha_occupancy, self._electronic_structure.beta_occupancy) if key not in self._results: self._results[key] = WfnSympy(coordinates=self._coordinates, symbols=self._symbols, basis=self._electronic_structure.basis, center=self._center, axis=self._axis, axis2=self._axis2, alpha_mo_coeff=self._electronic_structure.coefficients_a, beta_mo_coeff=self._electronic_structure.coefficients_b, group=group.upper(), alpha_occupancy=self._electronic_structure.alpha_occupancy, beta_occupancy=self._electronic_structure.beta_occupancy) return self._results[key] ########################################## # Structure symmetry methods # ##########################################
[docs] def measure(self, label): """ Get symmetry measure :param label: Point group label :type label: str :return: The measure :rtype: float """ return self._get_symgroup_results(label).csm
[docs] def nearest_structure(self, label): """ Get nearest structure :param label: Point group label :type label: str :return: The structure :rtype: Structure """ # TODO: Improve this docstring return self._get_symgroup_results(label).nearest_structure
[docs] def optimum_axis(self, label): """ Get the optimum main symmetry axis :param label: Point group label :type label: str :return: The axis :rtype: list """ return self._get_symgroup_results(label).optimum_axis
[docs] def optimum_permutation(self, label): """ Get the optimum atoms permutation :param label: point group label :return: The permutation :rtype: list """ return self._get_symgroup_results(label).optimum_permutation
[docs] def reference_axis(self, label): """ Get reference axis :param label: point group label :type label: str :return: The axis :rtype: list """ return self._get_symgroup_results(label).reference_axis
[docs] def csm_multi(self, label, multi=1): """ Get symmetry measure of the optimum N axis :param label: point group label :type label: str :param multi: number of axis :type multi: int :return: The measures :rtype: list """ self._multi = multi return self._get_symgroup_results(label).csm_multi
[docs] def axis_multi(self, label, multi=1): """ Get the optimum N axis :param label: point group label :type label: str :param multi: number of axis :type multi: int :return: List of axis :rtype: list """ self._multi = multi return self._get_symgroup_results(label).axis_multi
########################################## # Electronic symmetry methods # ########################################## # TODO: Consider to migrate this methods data to pandas tabular structures def mo_irreducible_representations(self, group): results = self._get_wfnsym_results(group) return {'labels': results.IRLab, 'alpha': results.mo_IRd_a, 'beta': results.mo_IRd_b} def wf_irreducible_representations(self, group): results = self._get_wfnsym_results(group) return {'labels': results.SymLab, 'alpha': results.wf_IRd_a, 'beta': results.wf_IRd_b, 'total': results.wf_IRd} def mo_overlaps(self, group): results = self._get_wfnsym_results(group) return {'labels': results.SymLab, 'alpha': results.mo_SOEVs_a, 'beta': results.mo_SOEVs_b} def wf_overlaps(self, group): results = self._get_wfnsym_results(group) return {'labels': results.SymLab, 'alpha': results.wf_SOEVs_a, 'beta': results.wf_SOEVs_b, 'total': results.wf_SOEVs} def symmetry_matrix(self, group): results = self._get_wfnsym_results(group) return {'labels': results.SymLab, 'matrix': results.SymMat} def wf_measure(self, group): results = self._get_wfnsym_results(group) return {'labels': results.SymLab, 'csm': results.csm_coef, 'grim': results.grim_coef} def wf_ideal_group_table(self, group): results = self._get_wfnsym_results(group) return {'ir_labels' : results.IRLab, 'labels': results.SymLab, 'table': results.ideal_gt} def dens_measure(self, group): results = self._get_wfnsym_results(group) return {'labels': results.SymLab, 'csm': results.csm_dens, 'csm_coef': results.csm_dens_coef, 'self_similarity': results.self_similarity} def axes(self, group): results = self._get_wfnsym_results(group) return {'center' : results.center, 'axis': results.axis, 'axis2': results.axis2} def symmetry_elements(self, group): results = self._get_wfnsym_results(group) return {'SymAxes' : results.SymAxes}