def molpro_hessian(lines): startkey = 'Force Constants (Second Derivatives of the Energy)' endkey = 'Atomic Masses' lines = lines.splitlines() sline = io.get_line_number(startkey, lines=lines) eline = io.get_line_number(endkey, lines=lines) if sline < 0: return '' hess = '' for line in lines[sline + 1:eline - 2]: hessline = '' for val in line.split(): if 'G' in val: if 'GX' in val: add = 1 val = val.replace('GX', '') elif 'GY' in val: add = 2 val = val.replace('GY', '') else: add = 3 val = val.replace('GZ', '') val = str((int(val) - 1) * 3 + add) hessline += '\t' + val hess += hessline + '\n' return hess
def gaussian_hessian(lines): startkey = 'Force constants in Cartesian coordinates:' endkey = 'Force constants in internal coordinates:' lines = lines.split('Harmonic vibro-rotational analysis')[-1] lines = lines.splitlines() sline = io.get_line_number(startkey, lines=lines) eline = io.get_line_number(endkey, lines=lines) if sline < 0: return '' hess = '\n'.join(lines[sline + 1:eline]).replace('D', 'E') return hess
def gaussian_freqs(lines): """ Return harmonic frequencies. """ nfreq = gaussian_nfreq(lines) freqs = [] lines = lines.splitlines() key = 'Fundamental Bands (DE w.r.t. Ground State)' iline = io.get_line_number(key, lines=lines) if iline > 0: for i in range(nfreq): iline += 1 line = lines[iline] cols = line.split() freqs.append(cols[-5]) else: lines = '\n'.join(lines) kw = 'Frequencies -- (.+)' freqlines = re.findall(kw, lines) freqs = [] k = 0 if len(freqlines) > 0: freqs = [''] * nfreq for i in range(len(freqlines)): tokens = freqlines[i].split() for j in range(len(tokens)): freqs[k] = tokens[j] k += 1 if k == nfreq: break return freqs
def get_mopac_xyz(lines): """ Returns xyz string from mopac output lines. >>> s = io.read_file('test/input.out') >>> print get_mopac_xyz(s) 5 <BLANKLINE> C 0.0000 -0.0000 0.0000 H 1.0870 -0.0000 0.0000 H -0.3623 1.0248 0.0000 H -0.3624 -0.5124 0.8875 H -0.3624 -0.5124 -0.8875 <BLANKLINE> """ import iotools as io if type(lines) == str: lines = lines.splitlines() natom = get_mopac_natom(lines) keyword = "ORIENTATION OF MOLECULE IN FORCE CALCULATION" xyzline = io.get_line_number(keyword, lines=lines) + 4 xyz = '{0}\n'.format(natom) comment = '\n' xyz += comment for i in range(natom): xyz += ' '.join(lines[xyzline + i].split()[1:]) + '\n' return xyz
def get_nwchem_basis(inp, filename=False): """ ------------------------------------------------------------------------------ Tag Description Shells Functions and Types ---------------- ------------------------------ ------ --------------------- C aug-cc-pvdz 9 23 4s3p2d H aug-cc-pvdz 5 9 3s2p """ if filename: lines = io.read_file(inp,aslines=True) else: if type(inp) is str: lines = inp.splitlines() else: lines = inp key = 'Tag Description Shells Functions and Types' i = io.get_line_number(key,lines,getlastone=True) basis = [] nbasis = 0 for line in lines[i+2:]: items = line.split() if len(items) == 5: basis.append(items[1]) nbasis += int(items[-2]) else: break if len(set(basis)) > 1: basis = set(basis) basis = '_'.join(basis) else: basis = basis[0] return {'basis': basis,'number of basis functions': nbasis}
def get_nwchem_energies(inp, filename=False): if filename: lines = io.read_file(inp,aslines=True) else: if type(inp) is str: lines = inp.splitlines() else: lines = inp nwdict = { 'nre' : 'Effective nuclear repulsion energy (a.u.)', 'scf' : 'Total SCF energy', 'mp2' : 'Total MP2 energy', 'mp3' : 'Total MP3 energy', 'ccsd' : 'CCSD total energy / hartree', 'ccsd(t)' : 'CCSD(T) total energy / hartree', 'ccsd(2)_t' : 'CCSD(2)_T total energy / hartree', 'ccsd(2)' : 'CCSD(2) total energy / hartree', 'ccsdt' : 'CCSDT total energy / hartree', 'ccsdt(2)_q' : 'CCSDT(2)_Q total energy / hartree', 'ccsdtq' : 'CCSDTQ total energy / hartree' } energies={} # energies = {'unit':'hartree'} for key,value in nwdict.iteritems(): i = io.get_line_number(value,lines=lines,getlastone=True) if i >= 0: try: energies[key] = float(lines[i].split()[-1]) except: print('Cannot parse {0}'.format(value)) return energies
def get_nwchem_xyz(inp,filename=False): """ Returns geometry in xyz format by parsing NWChem output file. Sample output: Output coordinates in angstroms (scale by 1.889725989 to convert to a.u.) No. Tag Charge X Y Z ---- ---------------- ---------- -------------- -------------- -------------- 1 C 6.0000 0.00000000 0.00000000 0.00000922 2 H 1.0000 0.00000000 0.00000000 1.09304166 3 H 1.0000 0.00000000 -0.94660523 -0.54652544 4 H 1.0000 0.00000000 0.94660523 -0.54652544 """ if filename: lines = io.read_file(inp,aslines=True) else: if type(inp) is str: lines = inp.splitlines() else: lines = inp keyword = 'No. Tag Charge X Y Z' n = io.get_line_number(keyword, lines, getlastone=True) geolines = '' natom = 0 for line in lines[n+2:]: items = line.split() if len(items) == 6: geolines += '{0} {1} {2} {3}\n'.format(items[1],items[3], items[4], items[5]) natom += 1 else: break xyz = '{0}\nParsed by QTC from NWChem output file\n{1}'.format(natom, geolines) return xyz
def get_gaussian_basis(lines): """ Standard basis: CC-pVDZ (5D, 7F) """ import iotools as io if type(lines) == str: lines = lines.splitlines() keyword = 'Standard basis:' n = io.get_line_number(keyword, lines=lines) return int(lines[n].split()[2])
def get_gaussian_natom(lines): """ NAtoms= 30 NQM= 30 NQMF= 0 NMMI= 0 NMMIF= 0 """ import iotools as io if type(lines) == str: lines = lines.splitlines() keyword = 'NAtoms=' n = io.get_line_number(keyword, lines=lines) return int(lines[n].split()[1])
def gaussian_natom(s): """ NAtoms= 30 NQM= 30 NQMF= 0 NMMI= 0 NMMIF= 0 """ from . import iotools as io if isinstance(s, str): lines = s.splitlines() keyword = 'NAtoms=' n = io.get_line_number(keyword, lines=lines) return int(lines[n].split()[1])
def gaussian_rotconstscent(lines): startkey = 'Effective Rotational Constants' lines = lines.splitlines() sline = io.get_line_number(startkey, lines=lines) if sline < 0: return '' rotlines = lines[sline + 4:sline + 7] constants = [] for line in rotlines: constants.append(line.split()[1]) return constants
def get_mopac_deltaH(lines): """ Return delta H in kcal/mol from mopac output. >>> s = io.read_file('test/input.out') >>> print get_mopac_deltaH(s) -13.02534 """ if type(lines) == str: lines = lines.splitlines() keyword = 'FINAL HEAT OF FORMATION' n = io.get_line_number(keyword, lines=lines) return float(lines[n].split()[5])
def get_mopac_zpe(lines): """ Return zero point energy in kcal/mol from mopac output. >>> s = io.read_file('test/input.out') >>> print get_mopac_zpe(s) 28.481 """ if type(lines) == str: lines = lines.splitlines() keyword = 'ZERO POINT ENERGY' n = io.get_line_number(keyword, lines=lines) return float(lines[n].split()[3])
def get_gaussian_fundamentals(s,nfreq=None): """ Parses harmonic and anharmonic frequencies from gaussian log file. Input: s: String containing the log file output. nfreq : number of vibrational frequencies Returns: If successful: Numpy 2D array of size: nfreq x 2 1st column for harmonic frequencies in cm-1 2nd column for anharmonic frequencies in cm-1 else: A string showing the error. Portion of the relevant output: Fundamental Bands (DE w.r.t. Ground State) 1(1) 3106.899 2957.812 -0.042978 -0.008787 -0.008920 2(1) 3106.845 2959.244 -0.042969 -0.008924 -0.008782 3(1) 3082.636 2934.252 -0.043109 -0.008543 -0.008705 4(1) 3082.581 2935.702 -0.043101 -0.008709 -0.008539 5(1) 3028.430 2918.529 -0.048859 -0.008796 -0.008794 6(1) 3026.064 2926.301 -0.048438 -0.008788 -0.008785 7(1) 1477.085 1438.911 -0.044573 -0.001097 -0.007855 8(1) 1477.063 1439.122 -0.044576 -0.007858 -0.001089 9(1) 1474.346 1432.546 -0.043241 0.000678 -0.007062 10(1) 1474.318 1432.981 -0.043245 -0.007065 0.000691 11(1) 1410.843 1377.548 -0.028060 -0.016937 -0.016944 12(1) 1387.532 1356.818 -0.027083 -0.016001 -0.016001 13(1) 1205.022 1177.335 -0.029813 -0.010333 -0.011188 14(1) 1204.977 1177.775 -0.029806 -0.011191 -0.010328 15(1) 1011.453 988.386 -0.037241 -0.014274 -0.014270 16(1) 821.858 814.503 -0.025712 -0.008603 -0.010446 17(1) 821.847 814.500 -0.025693 -0.010449 -0.008599 18(1) 317.554 296.967 -0.035184 -0.010866 -0.010861 Overtones (DE w.r.t. Ground State) """ if nfreq is None: nfreq = get_gaussian_nfreq(s) freqs = np.zeros((nfreq,2)) lines = s.splitlines() key = 'Fundamental Bands (DE w.r.t. Ground State)' iline = io.get_line_number(key,lines=lines) if iline < 0: return 'Not found: {0}'.format(key) for i in range(nfreq): iline += 1 line = lines[iline] cols = line.split() freqs[i,:] = [float(cols[1]),float(cols[2])] return freqs[freqs[:,0].argsort()]
def get_mopac_natom(lines): """ Return the number of atoms from mopac output >>> s = io.read_file('test/input.out') >>> print get_mopac_natom(s) 5 """ import iotools as io if type(lines) == str: lines = lines.splitlines() keyword = 'Empirical Formula' n = io.get_line_number(keyword, lines=lines) natom = int(lines[n].split()[-2]) return natom
def gaussian_vibrot(lines): startkey = 'Vibro-Rot alpha Matrix (in cm^-1)' ndof = gaussian_nfreq(lines) lines = lines.splitlines() sline = io.get_line_number(startkey, lines=lines) if sline < 0: return '' lines = lines[sline + 3:sline + 3 + ndof] for i in range(len(lines)): if ')' in lines[i]: lines[i] = lines[i].split(')')[1] if ndof < 2: lines[i] = '\t'.join(lines[i].split()[:-1]) mat = '\n'.join(lines).split('---------------')[0] return mat
def gaussian_rotdists(lines): startkey = 'Quartic Centrifugal Distortion Constants Tau Prime' endkey = 'Asymmetric Top Reduction' lines = lines.splitlines() sline = io.get_line_number(startkey, lines=lines) if sline < 0: return '' lines = lines[sline + 3:sline + 9] distlines = [] for line in lines: splitline = line.split() if splitline[0] == 'TauP': distlines.append('\t'.join(splitline[1:3])) else: break constants = '\n'.join(distlines).replace('D', 'e') return constants
def get_gaussian_xyz(lines,optimized=True): """ Input orientation: --------------------------------------------------------------------- Center Atomic Atomic Coordinates (Angstroms) Number Number Type X Y Z --------------------------------------------------------------------- 1 1 0 0.000000 0.000000 0.122819 2 1 0 0.000000 0.000000 0.877181 --------------------------------------------------------------------- """ import iotools as io if type(lines) == str: lines = lines.splitlines() natom = get_gaussian_natom(lines) keyword = 'Input orientation:' n = io.get_line_number(keyword, lines=lines,getlastone=optimized) #for i in range(n): return
def get_gaussian_zpve(s): """ Parses zero-point vibrational energy from gaussian log file. Input: s: String containing the log file output. Returns: If successful: Float, zpve in kcal/mol else: A string showing the error. Portion of the relevant output: Zero-point vibrational energy 194497.1 (Joules/Mol) 46.48591 (Kcal/Mol) """ key = "Zero-point vibrational energy" lines = s.splitlines() iline = io.get_line_number(key,lines=lines) if iline < 0: return 'Not found: {0}'.format(key) iline += 1 line = lines[iline] return float(line.split()[0])
def get_gaussian_xmatrix(s,nfreq): """ Parses X matrix from Gaussian log file. Input: s: String containing the log file output. nfreq : number of vibrational frequencies Returns: If successful: Numpy 2D array of size: nfreq x nfreq Only lower half triangle is filled. Unit of the elements is cm-1. else: A string showing the error. Portion of the relevant output: X matrix of Anharmonic Constants (cm-1) 1 2 3 4 5 1 -16.952 2 -20.275 -16.791 3 -68.264 -19.750 -17.403 4 -19.762 -67.602 -20.866 -17.232 5 -39.101 -38.921 -40.903 -40.724 -9.467 6 -40.164 -39.960 -39.582 -39.374 -37.734 7 -3.979 -8.048 -3.791 -7.530 4.360 8 -8.117 -3.911 -7.606 -3.720 4.345 9 -5.530 -9.506 -4.745 -9.316 -0.471 10 -9.552 -5.430 -9.359 -4.641 -0.441 11 -3.195 -3.073 -0.553 -0.426 11.081 12 -3.864 -3.746 -5.117 -4.998 2.696 13 -1.869 -3.005 -1.758 -1.604 -1.937 14 -3.070 -1.768 -1.671 -1.662 -1.899 15 1.427 1.429 1.853 1.856 0.340 16 -2.443 -2.611 -2.489 -3.468 -2.054 17 -2.798 -2.340 -3.661 -2.385 -2.062 18 0.189 0.483 1.107 1.390 1.489 6 7 8 9 10 6 -9.394 7 -9.658 -4.966 8 -9.649 -3.176 -4.942 9 -10.774 -2.897 -2.061 -3.149 10 -10.737 -2.054 -2.842 -0.368 -3.127 11 7.094 -2.539 -2.509 -2.613 -2.570 12 6.172 -0.754 -0.714 -2.250 -2.202 13 -1.744 -4.336 -4.722 -3.153 -3.462 14 -1.707 -4.716 -4.248 -3.466 -3.078 15 0.219 -1.347 -1.343 -1.539 -1.537 16 -1.895 -1.989 -2.795 -5.621 -6.255 17 -1.915 -2.837 -1.935 -6.357 -5.550 18 0.433 -1.192 -1.110 -0.335 -0.089 11 12 13 14 15 11 -7.155 12 -18.994 -3.594 13 -5.621 -3.171 -1.575 14 -5.555 -3.100 0.450 -1.551 15 -7.109 -4.660 -4.614 -4.605 -5.489 16 -1.602 -0.998 -4.504 1.095 -2.827 17 -1.560 -0.941 1.012 -4.392 -2.819 18 1.778 -0.412 -5.035 -4.808 1.097 16 17 18 16 2.460 17 7.634 2.481 18 8.273 8.287 -13.180 Resonance Analysis """ xmat = np.zeros((nfreq,nfreq)) lines = s.splitlines() key = 'X matrix of Anharmonic Constants (cm-1)' key2 = 'Total Anharmonic X Matrix (in cm^-1)' iline = io.get_line_number(key,lines=lines) if iline > 0: iline += 1 else: iline = io.get_line_number(key2,lines=lines) iline += 2 line = lines[iline] if iline < 0: return 'Not found: {0}'.format(key) while line.strip(): cols = line.split() icol = int(cols[0])-1 for irow in range(icol,nfreq): iline += 1 line = lines[iline] cols = line.split() ncol = len(cols) - 1 xmat[irow,icol:icol+ncol] = [float(num.replace('D','E')) for num in cols[1:]] iline += 1 line = lines[iline] return xmat