Source code for exatomic.nbo.output

# -*- coding: utf-8 -*-
# Copyright (c) 2015-2022, Exa Analytics Development Team
# Distributed under the terms of the Apache License 2.0
"""
exnbo Output Editor
####################################
"""
import re
import numpy as np
import pandas as pd
from io import StringIO
from .editor import Editor
#from exatomic.exa.util.units import Length
from exatomic.core.orbital import Orbital


csv_args = {'delim_whitespace': True}


[docs]class Output(Editor): """Parser for NBO output.""" _to_universe = Editor.to_universe
[docs] def to_universe(self): raise NotImplementedError('This editor has no parse_atom method.')
[docs] def parse_nao(self): _re_nao_start = 'NAO Atom No lang Type(AO) Occupancy' _re_nao_stop01 = ' Summary of Natural Population Analysis' _re_nao_stop02 = 'low occupancy.*core orbitals found on' _re_nao_stop03 = 'electrons found in the effective core potential' found = self.find(_re_nao_start, _re_nao_stop01) regex = self.regex(_re_nao_stop02, _re_nao_stop03, keys_only=True) starts = [i[0] + 2 for i in found[_re_nao_start]] stops = [i[0] for i in found[_re_nao_stop01]] if regex[_re_nao_stop03]: stops = regex[_re_nao_stop03] elif regex[_re_nao_stop02]: keys = regex[_re_nao_stop02] stops = [keys[0]] + keys[2::2] dfs = [] spins = [-1, 0, 1] #nrcol = len(self[starts[0]].replace("( ", "(").split()) + 1 #for (lno, col), start, stop, spin in zip(found[_re_nao_start], starts, stops, spins): for (_, col), start, stop, spin in zip(found[_re_nao_start], starts, stops, spins): columns = col.split() lines = [line.replace("( ", "(") for line in self[start:stop]] dfs.append(pd.read_csv(StringIO('\n'.join(lines)), names=columns, **csv_args)) dfs[-1]['spin'] = spin df = pd.concat(dfs).reset_index(drop=True) split = df['Type(AO)'].str.extract('([A-z]{3})\((.*)\)', expand=False) split.columns = ['type', 'ao'] del df['Type(AO)'] self.nao = pd.concat([df, split], axis=1)
[docs] def parse_nbo(self): pass
[docs] def parse_nlmo(self): pass
def __init__(self, *args, **kwargs): super(Output, self).__init__(*args, **kwargs)
[docs]class MOMatrix(Editor): """ The NBO code has the ability to dump any orbital transformation it performs such as the NBOAO, NLMOAO, etc. As long as it is in the AO basis, it is possible to add this momatrix to a corresponding universe's momatrix and view these orbitals. """ _to_universe = Editor.to_universe
[docs] def to_universe(self): raise NotImplementedError('This editor has no parse_atom method.')
[docs] def parse_momatrix(self, nbas, nmo=None, column=None, os=False, nbo6=False): """ Requires the number of basis functions in this matrix. """ column = 'coef' if column is None else column nmo = nbas if nmo is None else nmo start = 0 while start < len(self): try: float(self[start].split()[0]) break except: start += 1 ncol = len(self[start].split()) if nbas <= ncol: nrows = ncol occrows = ncol else: add = 1 if nbas % ncol else 0 nrows = nbas * (nmo // ncol + add) occrows = nbas // ncol + add # This code is repetitive with the beta spin parsing below # generalize for i in rnage(2): etc. etc. stop = start + nrows occstart = stop occstop = occstart + occrows coef = self.pandas_dataframe(start, stop, range(ncol) ).stack().reset_index(drop=True) occvec = self.pandas_dataframe(occstart, occstop, range(ncol) ).stack().reset_index(drop=True) orbital = np.repeat(range(nbas), nmo) chi = np.tile(range(nbas), nmo) self.momatrix = pd.DataFrame.from_dict({'orbital': orbital, 'chi': chi, column: coef, 'frame': 0}) self.orbital = Orbital.from_occupation_vector(occvec) self.occupation_vector = {column: occvec} if os: start = self.regex('BETA SPIN', start=stop, keys_only=True, flags=re.IGNORECASE)[0] + 1 start = start + stop stop = start + nrows occstart = stop occstop = occstart + occrows beta = self.pandas_dataframe(start, stop, range(ncol) ).stack().reset_index(drop=True) betaocc = self.pandas_dataframe(occstart, occstop, range(ncol), ).stack().reset_index(drop=True) self.momatrix['coef1'] = beta betaorb = Orbital.from_occupation_vector(betaocc) self.orbital = pd.concat([self.orbital, betaorb]).reset_index(drop=True) self.occupation_vector[column + '1'] = betaocc
def __init__(self, *args, **kwargs): super(MOMatrix, self).__init__(*args, **kwargs)