-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser_eom.py
More file actions
223 lines (206 loc) · 9.09 KB
/
parser_eom.py
File metadata and controls
223 lines (206 loc) · 9.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
#########################################################
# THIS PROGRAM GENERATES A "JSON" FILE #
# (WITH SOCS, ENERGIES, SPIN AND ORBITAL ANGULAR #
# MOMENTUMS OF ALL THE STATES) FROM THE EOM Q-CHEM #
# OUTPUT. #
#########################################################
__author__ = 'Sven Kähler'
import sys, re, string
import numpy as np
import json
from decimal import Decimal
# flag for extra print
print_intermediates = False
# open EOM output file_ms_notnull
lowestEtargetState = False
if len(sys.argv) == 3:
targetState = sys.argv[2]
else:
lowestEtargetState = True
unsortStateList = []
stateList = []
with open(sys.argv[1], 'r') as f:
contents = f.readlines()
# regular expression defitions
eomRe = re.compile(r'\s+Solving for EOM(?:IP|EA)-CCSD(?:\/MP2)? (\w[\d\'\w]*) transitions\.')
eomStateRe = re.compile(r'\s+EOM(?:IP|EA) transition')
symLabelRe = re.compile(r'(\d+/[A-B][\d\'\w]*)')
eomStateEnergyRe = re.compile(r'\s+Total energy = (-?\d+\.\d*) a\.u\.')
realValueRe = re.compile(r'(-?\d+\.\d*)')
statePropRe = re.compile(r'\s+Excited state properties for EOM(?:IP|EA)-(?:CCSD|MP2) transition (\d+/\w[\d\'\w]*)')
stateAngMomRe = re.compile(r'\s+Angular momentum \(a\.u\.\) against gauge origin\:')
stateAngMomVecRe = re.compile(r'\s+\(X (-?\d+\.\d+)i, Y (-?\d+\.\d+)i, Z (-?\d+\.\d+)i\)')
totalAngMomRe = re.compile(r'\s+<S\^2> = (\d+\.\d+)')
transPropRe = re.compile(r'Start computing the transition properties')
stateARe = re.compile(r' State A: eom(?:ip|ea)_(?:ccsd|mp2)/(?:a|b): (\d+/\w[\d\'\w]*)')
stateBRe = re.compile(r' State B: eom(?:ip|ea)_(?:ccsd|mp2)/(?:a|b): (\d+/\w[\d\'\w]*)')
transAngMomRe = re.compile(r' Transition angular momentum against gauge origin \(a\.u\.\)\:')
transAngMomVecABRe = re.compile(r'\s*A->B: \(X (-?\d\.\d+)i, Y (-?\d\.\d+)i, Z (-?\d\.\d+)i\)')
transAngMomVecBARe = re.compile(r'\s*B->A: \(X (-?\d\.\d+)i, Y (-?\d\.\d+)i, Z (-?\d\.\d+)i\)')
socTransitionABRe = re.compile(r' A(Ket)->B(Bra) transition SO matrices')
socTransitionBARe = re.compile(r' B(Ket)->A(Bra) transition SO matrices')
aveTransSOCRe = re.compile(r'\s*Arithmetically averaged transition SO matrices')
mfSOCRe = re.compile(r'\s*Mean-field SO \(cm-1\)')
oneelSOCRe = re.compile(r'\s*One-electron SO \(cm-1\)')
matElemRe = re.compile(r'\s*Actual matrix elements:')
indexKetRowRe = re.compile(r'(?:\s*\|Sz=(-?\d\.\d+)>)+')
socMatElemRe = re.compile(r'\s+<Sz=(-?\d\.\d+)\|(?:\(-?\d+\.\d+,-?\d+\.\d+\))+')
complexPairRe = re.compile(r'\((-?\d+\.\d+),(-?\d+\.\d+)\)')
indexBraRe = re.compile(r'\s+<Sz=(-?\d\.\d+)|')
transPropDivRe = re.compile(r'\s+---+')
# initialize lists for captured properties
eomStates = []
eomStateLabels = []
eomStateEnergies = []
eomStateEnergiesDict = {}
eomStateTotalAngMomDict = {}
eomStateAngMomVecs = []
eomStateAngMomVecsDict = {}
eomTransAngMomVecDict = {}
eomAveTransSOCDict = {}
nEOMStates = 0
foundEOM = False
foundState = False
foundEOMprop = False
foundStateEOMProp = False
foundStateAngMom = False
foundEOMtransProp = False
foundALabel = False
foundBLabel = False
foundStateA = False
foundStateB = False
foundTransAngMom = False
foundTransSOCAB = False
foundTransSOCBA = False
foundAveTransSOC = False
foundMatElem = False
foundMFSOC = False
found1elSOC = False
def printFoundStatePropMessage():
print("found eom prop")
print("eomStateLabels and eomStateEnergies should be complete")
print("eomStateLabels:")
print(str(eomStateLabels))
print("eomStateEnergies:")
print(str(eomStateEnergies))
print("eomStateEnergiesDict:")
print(str(eomStateEnergiesDict))
def printFoundTransPropMessage():
print("found trans prop")
print("stateAngMomVecsDict should be complete")
print("eomStateAngMomVecsDict:")
print(str(eomStateAngMomVecsDict))
# iteratre through file_ms_notnull search for state properties and start of transtion properties section
for line in contents:
if eomRe.match(line):
foundEOM = True
foundState = False
foundStateEOMProp = False
# when EOM section of output found look excited state and symmetry label
if foundEOM:
if eomStateRe.match(line):
match = eomStateRe.match(line)
symLabel = re.findall(symLabelRe, line)[0]
eomStateLabels.append(re.findall(symLabelRe, line))
nEOMStates = nEOMStates + 1
foundState = True
# when excited state information found, search for excitation energy
if foundState:
if eomStateEnergyRe.match(line):
energy_list = [float(energy) for energy in re.findall(realValueRe, line)]
eomStateEnergies.append(energy_list)
eomStateEnergiesDict[symLabel] = energy_list
if statePropRe.match(line):
symLabel = re.findall(symLabelRe, line)[0]
if(not foundStateEOMProp and print_intermediates):
printFoundStatePropMessage()
foundStateEOMProp = True
if (foundStateEOMProp and stateAngMomRe.match(line)):
foundStateAngMom = True
if (foundStateAngMom and stateAngMomVecRe.match(line)):
foundStateAngMom = False
eomStateAngMomVecs.append(re.findall(realValueRe, line))
eomStateAngMomVecsDict[symLabel] = re.findall(realValueRe, line)
# when EOM section found (not in SCF or MP2/CCSD) look for total spin angular momenta
if (foundStateEOMProp and totalAngMomRe.match(line)):
eomStateTotalAngMomDict[symLabel] = float(re.findall(realValueRe, line)[0])
if (transPropRe.match(line)):
if (not foundEOMtransProp and print_intermediates):
printFoundTransPropMessage()
foundEOMtransProp = True
break;
foundState = False
for line in contents:
if stateARe.match(line):
symLabelA = re.findall(symLabelRe, line)[0]
foundALabel = True
foundStateA = True
if stateBRe.match(line):
symLabelB = re.findall(symLabelRe, line)[0]
foundBLabel = True
foundStateB = True
if (foundStateA and foundStateB):
if transAngMomRe.match(line):
foundTransAngMom = True
if (foundTransAngMom and transAngMomVecABRe.match(line)):
transAngMomVecAB = [Decimal(i) for i in re.findall(realValueRe, line)]
if (foundTransAngMom and transAngMomVecBARe.match(line)):
transAngMomVecBA = [Decimal(i) for i in re.findall(realValueRe, line)]
if (oneelSOCRe.match(line)):
found1elSOC = True
foundMFSOC = False
if (mfSOCRe.match(line)):
foundMFSOC = True
found1elSOC = False
if (aveTransSOCRe.match(line)):
foundAveTransSOC = True;
if (foundAveTransSOC and matElemRe.match(line)):
foundMatElem = True;
if (foundMatElem and indexKetRowRe.match(line)):
ketIndices = re.findall(realValueRe, line)
if found1elSOC:
oneelSOCElems = []
oneelSOCColIndices = []
if foundMFSOC:
mfSOCElems = []
mfSOCColIndices = []
if (foundMatElem and found1elSOC and socMatElemRe.match(line)):
match = indexBraRe.match(line)
oneelSOCColIndices.extend(re.findall(realValueRe, match.group()))
oneelSOCElems.append(re.findall(complexPairRe, line))
if (foundMatElem and foundMFSOC and socMatElemRe.match(line)):
match = indexBraRe.match(line)
mfSOCColIndices.extend(re.findall(realValueRe, match.group()))
mfSOCElems.append([complex(float(p[0]),float(p[1])) for p in re.findall(complexPairRe, line)])
# once end of transition properties section reached, process parsed properties:
# average AB and BA angular momentum transition vector
# save both, angular momemta and spin-orbit couplings to dictionaries
if (transPropDivRe.match(line)):
foundALabel = False
foundBLabel = False
foundStateA = False
foundStateB = False
foundMatElem = False
foundAveTransSOC = False
foundTransAngMom = False
aveTransAngMomVec = np.array(
[complex(0.,(ab-ba)/Decimal(2)) for ab,ba in zip(transAngMomVecAB,transAngMomVecBA)])
eomTransAngMomVecDict[symLabelA + "_" + symLabelB] = aveTransAngMomVec
eomAveTransSOCDict[symLabelA + "_" + symLabelB] = np.matrix(mfSOCElems)
def matrix_to_string_list(matrix):
return [[str(elem) for elem in line] for line in matrix.tolist()]
# prepare data for json export - convert complex numbers to strings and matrices and vectors to lists
eomTransAngMomListDict = {x : [str(elem) for elem in list(y)] for x, y in eomTransAngMomVecDict.items()}
eomAveTransSOCListDict = {x : matrix_to_string_list(y) for x, y in eomAveTransSOCDict.items()}
output_dict = {
"stateEnergiesDict" : eomStateEnergiesDict,
"stateTotalAngMomDict" : eomStateTotalAngMomDict,
"transAngMomListDict" : eomTransAngMomListDict,
"aveTransSOCListDict" : eomAveTransSOCListDict
}
outfile_name = sys.argv[1] + ".json"
with open(outfile_name, 'w') as f:
json.dump(output_dict, f,
separators=(',', ':'),
sort_keys=True,
indent=4)