:py:mod:`pemtk.sym.symHarm` =========================== .. py:module:: pemtk.sym.symHarm .. autoapi-nested-parse:: Class for determining and handling symmetrized harmonics. 23/03/22 v2 - Switched to nested dicts for coeffs, now all in self.coeffs[dtype]. 24/02/22 v1 in development. - For early dev work see http://localhost:8888/lab/workspaces/symm/tree/python/chem/tools/symmetrized_harmonics_libmsym_tests_160122.ipynb - For class dev see http://localhost:8888/lab/workspaces/symm/tree/python/chem/tools/symmetrized_harmonics_PEMtk-dev_240222.ipynb TODO - Data to dicts? Currently have multiple self.coeffXX attribs. - Interface/convert to matrix elements for ePSproc use. Module Contents --------------- Classes ~~~~~~~ .. autoapisummary:: pemtk.sym.symHarm.symHarm Attributes ~~~~~~~~~~ .. autoapisummary:: pemtk.sym.symHarm.xrFlag .. py:data:: xrFlag :value: True .. py:class:: symHarm(PG='Cs', lmax=4, llist=None, dims=['C', 'h', 'mu', 'l', 'm']) Class to set and manipulate symmetrized harmonics. Main symmetry routine uses [libmsym](https://github.com/mcodev31/libmsym), code adapted from https://github.com/mcodev31/libmsym/issues/21 Background ---------- Symmetrized (or generalised) harmonics, which essentially provide correctly symmetrized functions for a given irreducible representation, $\Gamma$, be defined by linear combinations of spherical harmonics \cite{Altmann1963a,Altmann1965,Chandra1987}: \begin{equation} X_{hl}^{\Gamma\mu*}(\theta,\phi)=\sum_{\lambda}b_{hl\lambda}^{\Gamma\mu}Y_{l,\lambda}(\theta,\phi)\label{eq:symm-harmonics} \end{equation} where: - $\Gamma$ is an irreducible representation, - ($l$, $\lambda$) define the usual spherical harmonic indicies (rank, order) - $b_{hl\lambda}^{\Gamma\mu}$ are symmetrization coefficients, - index $\mu$ allows for indexing of degenerate components, - $h$ indexe cases where multiple components are required with all other quantum numbers identical. The exact form of these coefficients will depend on the point-group of the system, see, e.g. \cite{Chandra1987,Reid1994}. Method ------ - Point-groups, character table generation and symmetrization (computing $b_{hl\lambda}^{\Gamma\mu}$ parameters) is handled by [libmsym](https://github.com/mcodev31/libmsym) (based on https://github.com/mcodev31/libmsym/issues/21). - Supported point groups: Ci, Cs, Cnv, Dn, Dnh, Dnd, Td, O, Oh, I and Ih - Routines have been tested with libmsym v0.2.2, March 2022 (last commit https://github.com/mcodev31/libmsym/commit/c99470376270db4ec4c925b952fa722e011377d6). - Spherical harmonic expansions and conversions (real, imaginary, normalization etc.) and basic ploting (2D maps) are handled by [pySHtools](https://shtools.oca.eu). - Routines have been tested with v4.5 and 4.9 (current March 2022). - TODO: Interface to PEMtk/ePSproc for other plotters and handling routines. - TODO: some hardcoded labelling to fix, also incorrect in places ("character" instead of "irrep") .. rubric:: Examples >>> # Compute params for Td, lmax=4 >>> xlm = symHarm('Td',4) >>> # Print charater table >>> xlm.printCharacterTable() >>> # Display table of params >>> xlm.displayXlm() >>> # Plot functions >>> xlm.plotXlm() .. py:method:: set_lm_basis() Set basis functions for each (element, l, m). .. py:method:: set_basis(element, l, m, n, name) Set basis function for a given (element, n, l, m,). .. py:method:: calcSymHarmonics() Compute symmetrized harmonic coeffs for point group up to lmax. .. py:method:: directProduct(terms) Compute direct products for a list of terms (symmetries/species/irreps). .. py:method:: directProductDipole(terms) Compute direct products for a list of terms (symmetries/species/irreps), and include dipole terms. .. py:method:: directProductContinuum(terms, disp=True) Compute direct products for a list of terms (symmetries/species/irreps), and include dipole terms. Similar to directProductDipole, but additionally loops over all irreps to determine valid photoionization combinations, i.e. allowed continuum symmetries for the given cases. .. py:method:: scatSym(symIon, pdInput='allowed', disp=True) Add scattering symmetry column to self.continuum['allowed']['PD']. scatSym = continuum x ion (per ePS definition) 19/02/24 v1 .. py:method:: toePSproc(dimMap={'C': 'Cont', 'h': 'it', 'mu': 'muX'}, dataType='BLM') Wrap toePSproc method. .. py:method:: toePSman(scatSym=None, contSym=None) Wrap toePSman method. .. py:method:: toePSmanPD() Wrap toePSmanPD method. .. py:method:: getIrreps() Get irrep labels from libmsym repr. Quick hack to grab labels from self.ctx.character_table.symmetry_species objects, should be a better way. For source, see https://github.com/mcodev31/libmsym/blob/c99470376270db4ec4c925b952fa722e011377d6/bindings/python/libmsym/libmsym.py#L65 .. py:method:: getSymOps() Get symmetry operation labels from libmsym repr. Quick hack to grab labels from self.ctx.character_table.symmetry_operations objects, should be a better way. For source, see https://github.com/mcodev31/libmsym/blob/c99470376270db4ec4c925b952fa722e011377d6/bindings/python/libmsym/libmsym.py#L65 .. py:method:: setCharTablePD() Generate character table & convert to Pandas DataFrame. .. py:method:: setCoeffsPD(key='libmsym', dtype='real') Convert raw list output to Pandas DataFrame. :param key: Key for self.coeffs[key] :type key: str, optional, default = 'libmsym' :param dtype: Key for self.coeffs[key][dtype] :type dtype: str, optional, default = 'real' .. py:method:: setCoeffsSH(absM=True) Convert symmertrized harmonics to SHtools object, and convert type to complex. :param absM: Use absM values from input coeff labels? May need to force abs(M) for libmsym results? Or double up +/-M terms? :type absM: bool, optional, default = True .. rubric:: Notes - Are sign convensions consistent? - Looks like +m in libmsym output == symmetric case (same sign for +/-m). - And -m is antisym case. - Now fixed above (hopefully) by setting -m term as mSign*clmC.coeffs[1,l,m]] - Could also be Condon-Shortley phase, have INCLUDED it here (see https://shtools.oca.eu/shtools/public/complex-spherical-harmonics.html#condon-shortley-phase-factor) - Current version seems to match Chandra 1987 & Boiko et. al. 2006 for some tested Td cases, more testing required. Sources: -
Boiko, D.L., Féron, P. and Besnard, P. (2006) ‘Simple method to obtain symmetry harmonics of point groups’, The Journal of Chemical Physics, 125(9), p. 094104. doi:10.1063/1.2338040.
-
Chandra, N. (1987) ‘Photoelectron spectroscopic studies of polyatomic molecules. I. Theory’, Journal of Physics B: Atomic and Molecular Physics, 20(14), pp. 3405–3415. doi:10.1088/0022-3700/20/14/013.
.. py:method:: setCoeffsXR(stack=True) Convert coeffs from PD DataFrame to Xarray Dataset. :param stack: If True, try and use default stacking, {'inds':self.dims[1:3], 'LM':self.dims[3:]}. If False, don't stack. If dict, try and stack with specified dict mapping. :type stack: dict, bool, optional, default = True .. py:method:: printCharacterTable(returnPD=False) Print character table with species & degen using Pandas :param returnPD: Return PD object instead of display() if True. :type returnPD: bool, optional, default = False :rtype: Empty unless returnPD = True set. .. py:method:: displayXlm(names='longnames', YlmType='real', setCols='l', dropLevels=[], returnPD=False, sticky=False, symFilter=False, symFilterChannel='Target') Print table of values from Pandas Dataframe self.coeffs['DF']['real'], with specified labels (from self.coeffs['DF']['real'].attrs['indexes']). :param names: Labels to use in printed table, from self.coeffs['DF']['real'].attrs['indexes'] :type names: str, optional, default = 'longnames' :param YlmType: - 'real' show real harmonic coeffs, from self.coeffs['DF']['real'] - 'comp' show complex harmonic coeffs, from self.coeffs['DF']['comp'] :type YlmType: str, optional, default = 'real' :param setCols: Set which label to use for display. Set via self.coeffsDF.unstack(level=setCols). Note this level must be in the DataFrame index, and there is currently no error checking. :type setCols: str, optional, default = 'l' :param dropLevels: Drop levels specified from displayed table. :type dropLevels: str or list of strings, default = [] :param returnPD: Return PD object instead of display() if True. :type returnPD: bool, optional, default = False :param sticky: Apply "sticky" index styler to displayed table. (If supported by Pandas version.) :type sticky: bool, optional, default = False :param symFilter: If True, apply filter from symFilterChannel. :type symFilter: bool, optional, default = False :param symFilterChannel: Try and filter output based on allowed symmetries. This requires self.continuum to be set, and to match a column name for filtering. E.g. 'Target' will filter the Xlm table from self.continuum['allowed']['PD']['Target'] symmetries. TODO: allow use of short names here, currently only filters on output names. :type symFilterChannel: str, optional, default = None :rtype: Empty unless returnPD = True set. .. py:method:: plotXlm(pType='real', gridlmax=20, syms=None, **kwargs) Quick plot of Xlm by symmetry using SHtools grid.plot(). Parameters ---------- pType : str, optional, default = 'real' Plot type as key (for self.coeffs['SH'][pType]). Default cases are 'real' or 'comp' types (complex harmonics) gridlmax : int or None, optional, default = 20 Used by SHtools clm.expand() routine to define gridding. Use SHtools defaults if set to None (== lmax of distribution) syms : str or list, default = None Symmetry groups self.coeffs['SH'][pType][sym] to plot. Defaults to all syms, as defined by self.coeffs['SH'][pType].keys() **kwargs : optional args passed to SHtools grid.plot(**kwargs) Notes ----- - Gridding is defined automatically by clm.expand() routine, pass lmax=int as a proxy to override defaults TODO: For more control with subselection etc. needs bridging with other plotting tools (BLMplot etc.).