mirror of
https://github.com/nwchemgit/nwchem.git
synced 2026-07-21 06:25:21 -04:00
171 lines
5.2 KiB
Python
Executable file
171 lines
5.2 KiB
Python
Executable file
#!/usr/bin/env python
|
|
"""
|
|
nwchem_tddft_spectrum.py - Extract the tddft data from an NWChem output
|
|
file and plot it in the form of a absorption
|
|
spectrum.
|
|
|
|
Usage:
|
|
nwchem_tddft_spectrum.py (options) (files)
|
|
|
|
Options:
|
|
-a value Use value as the Gaussian exponent to generate the plot
|
|
(default=10000)
|
|
-b Print both spectra
|
|
-h Print this help
|
|
-s Print the singlet spectrum (default)
|
|
-t Print the triplet spectrum
|
|
-o Print the open-shell spectrum
|
|
-u value Use value as the units. Must be in [h,eV,kcal/mol]; default eV
|
|
|
|
Send any errors or additions to Rick Muller, rmuller@sandia.gov.
|
|
"""
|
|
|
|
defaults = {
|
|
'alpha' : 10000,
|
|
'plot_singlet': True,
|
|
'plot_triplet': False,
|
|
'plot_unrestricted': False,
|
|
'plot_zeros': False, # Show zero oscillator strengths as slight negative blips
|
|
'units': 'eV',
|
|
}
|
|
|
|
from pylab import *
|
|
|
|
def parse_nwchem_output(fname):
|
|
import re
|
|
from pprint import pprint
|
|
singlet_pat = re.compile(r'\s+Root\s+\d+\s+singlet')
|
|
triplet_pat = re.compile(r'\s+Root\s+\d+\s+triplet')
|
|
unrestricted_pat = re.compile(r'\s+Root\s+\d')
|
|
singlets = []
|
|
triplets = []
|
|
unrestricted = []
|
|
f = open(fname)
|
|
while 1:
|
|
line = f.readline()
|
|
if not line: break
|
|
if singlet_pat.search(line):
|
|
energy,osc,trans_mom = parse_element(line,f)
|
|
singlets.append((energy,osc))
|
|
if triplet_pat.search(line):
|
|
energy,osc,trans_mom = parse_element(line,f)
|
|
triplets.append((energy,osc))
|
|
if unrestricted_pat.search(line):
|
|
energy,osc,trans_mom = parse_element(line,f)
|
|
unrestricted.append((energy,osc))
|
|
#pprint(singlets)
|
|
#pprint(triplets)
|
|
return singlets,triplets,unrestricted
|
|
|
|
def parse_element(line,f):
|
|
import re
|
|
oscillator_pat = re.compile(r'\s+Oscillator')
|
|
words = line.split()
|
|
try:
|
|
energy = float(words[4])
|
|
except:
|
|
energy = float(words[3])
|
|
line = f.readline() # skip ----
|
|
line = f.readline()
|
|
words = line.split()
|
|
try:
|
|
txyz = float(words[3]),float(words[5]),float(words[7])
|
|
except:
|
|
txyz = (0,0,0)
|
|
line = f.readline()
|
|
words = line.split()
|
|
while None == oscillator_pat.search(line):
|
|
line = f.readline()
|
|
words = line.split()
|
|
try:
|
|
osc = float(words[3])
|
|
except:
|
|
osc = 0
|
|
return energy,osc,txyz
|
|
|
|
def to_plot(data,**kwargs):
|
|
alpha = kwargs.get('alpha',defaults['alpha'])
|
|
plot_zeros = kwargs.get('plot_zeros',defaults['plot_zeros'])
|
|
abmin_floor = kwargs.get('abmin',0.001)
|
|
|
|
Emin = min(E for E,ab in data)
|
|
Emax = max(E for E,ab in data)
|
|
abmin = min([0] + [ab for E,ab in data if ab > 0])
|
|
abmin = max(abmin,abmin_floor)
|
|
Edel = Emax-Emin
|
|
Es = linspace(Emin-Edel/10.,Emax+Edel/10.,2000)
|
|
Spectrum = zeros(Es.shape,'d')
|
|
for E,ab in data:
|
|
if ab > 0:
|
|
Spectrum += ab*exp(-alpha*(Es-E)**2)
|
|
elif plot_zeros:
|
|
Spectrum -= abmin*exp(-alpha*(Es-E)**2)
|
|
return Es,Spectrum
|
|
|
|
def nwchem_tddft_spectrum(fname,**kwargs):
|
|
from os.path import basename
|
|
thetitle = kwargs.get('title',basename(fname))
|
|
units = kwargs.get('units',defaults['units'])
|
|
assert units in ['h','eV','ev','kcal/mol','kcm']
|
|
if units in ['eV','ev']:
|
|
conv = 27.211
|
|
elif units in ['kcal/mol','kcm']:
|
|
conv = 627.51
|
|
else:
|
|
conv = 1.0 # h
|
|
singlet,triplet,unrestricted = parse_nwchem_output(fname)
|
|
if thetitle: title(thetitle)
|
|
if kwargs['plot_singlet']:
|
|
Es0,Spectrum0 = to_plot(singlet,**kwargs)
|
|
plot(Es0*conv,Spectrum0,label='sing')
|
|
if kwargs['plot_triplet']:
|
|
Es1,Spectrum1 = to_plot(triplet,**kwargs)
|
|
plot(Es1*conv,Spectrum1,label='trip')
|
|
if kwargs['plot_unrestricted']:
|
|
Es1,Spectrum1 = to_plot(unrestricted,**kwargs)
|
|
plot(Es1*conv,Spectrum1,label='open')
|
|
legend()
|
|
xlabel('Energy (%s)' % units)
|
|
ylabel('Oscillator Strength')
|
|
if fname.endswith('.out'):
|
|
oname = fname.replace('.out','.png')
|
|
else:
|
|
oname = fname + ".png"
|
|
savefig(oname)
|
|
show()
|
|
return
|
|
|
|
if __name__ == '__main__':
|
|
from getopt import getopt
|
|
opts,args = getopt(sys.argv[1:],'hstoa:b')
|
|
kwargs = defaults
|
|
for key,val in opts:
|
|
if key == '-a':
|
|
kwargs['alpha'] = float(val)
|
|
if key == '-b':
|
|
kwargs['plot_singlet'] = True
|
|
kwargs['plot_triplet'] = True
|
|
kwargs['plot_unrestricted'] = False
|
|
if key == '-s':
|
|
kwargs['plot_singlet'] = True
|
|
kwargs['plot_triplet'] = False
|
|
kwargs['plot_unrestricted'] = False
|
|
if key == '-t':
|
|
kwargs['plot_singlet'] = False
|
|
kwargs['plot_triplet'] = True
|
|
kwargs['plot_unrestricted'] = False
|
|
if key == '-o':
|
|
kwargs['plot_singlet'] = False
|
|
kwargs['plot_triplet'] = False
|
|
kwargs['plot_unrestricted'] = True
|
|
if key == '-h':
|
|
print(__doc__)
|
|
sys.exit()
|
|
if len(args) == 0:
|
|
print(__doc__)
|
|
sys.exit()
|
|
for fname in args:
|
|
nwchem_tddft_spectrum(fname,**kwargs)
|
|
|
|
|
|
|