def check_hrs(n, typ): """ Checks MC geoms to make sure they are the same inchii as the starting species """ import sys import iotools as io msg = 'Checking me_files/{1}{0}_hr.me'.format(str(n), typ) filename = 'data/' + typ + str(n) + '.dat' nrotors = 0 md = False if io.check_file(filename): data = io.read_file(filename) tmp = data.split('nhind') if len(tmp) > 2: nrotors = tmp[1].split('\n')[1] if len(tmp) > 3: md = True data = '' filename = 'me_files/' + typ + str(n) + '_hr.me' if io.check_file(filename): data = io.read_file(filename) else: msg = '\nNo hr me_file found' log.error(msg) return if md: if 'MultiRotor' in data: msg = '\nMDTau successfully completed' log.info(msg) else: msg = '\nMD scan incomplete' log.error(msg) filename = 'me_files/' + typ + str(n) + '_1dhr.me' if io.check_file(filename): data = io.read_file(filename) else: msg += '\nNo 1dhr me_file found' log.error(msg) return data = data.split('Rotor') ncomplete = len(data) - 1 msg = '\n{0} out of {1} rotors successfully scanned'.format( str(ncomplete), nrotors) if int(nrotors) == ncomplete: msg = '\n1DTau has completed successfully' else: msg = '\nScan incomplete' log.error(msg) log.info(msg) return
def run_gaussian(s, exe='g09', template='gaussian_template.txt', mult=None, overwrite=False): """ Runs gaussian calculation """ mol = ob.get_mol(s, make3D=True) if mult is None: mult = ob.get_multiplicity(mol) tmp = io.read_file(template) inptext = get_gaussian_input(mol, tmp, mult) prefix = ob.get_smiles_filename(s) inpfile = prefix + '.g09' outfile = prefix + '_gaussian.log' command = [exe, inpfile, outfile] if io.check_file(outfile, timeout=1): if overwrite: msg = 'Overwriting previous calculation "{0}"\n'.format(io.get_path(outfile)) run = True else: msg = 'Skipping calculation, found "{0}"\n'.format(io.get_path(outfile)) run = False else: run = True if run: if not io.check_file(inpfile, timeout=1) or overwrite: io.write_file(inptext, inpfile) if io.check_file(inpfile, timeout=1): msg = io.execute(command) if io.check_file(outfile, timeout=1): msg += ' Output file: "{0}"\n'.format(io.get_path(outfile)) else: msg = 'Failed, cannot find input file "{0}"\n'.format(io.get_path(inpfile)) return msg
def run_mopac(s, exe='mopac', template='mopac_template.txt', mult=None, overwrite=False): """ Runs mopac, returns a string specifying the status of the calculation. mopac inp inp.out Mopac always writes the log file into a file with .out extension """ mol = ob.get_mol(s, make3D=True) if mult is None: mult = ob.get_multiplicity(mol) tmp = io.read_file(template) inptext = get_input(mol, tmp, mult) prefix = ob.get_smiles_filename(s) inpfile = prefix + '.mop' outfile = prefix + '.out' command = [exe, inpfile] if io.check_file(outfile, timeout=1): if overwrite: msg = 'Overwriting previous calculation "{0}"\n'.format(io.get_path(outfile)) run = True else: msg = 'Skipping calculation, found "{0}"\n'.format(io.get_path(outfile)) run = False else: run = True if run: if not io.check_file(inpfile, timeout=1) or overwrite: io.write_file(inptext, inpfile) if io.check_file(inpfile, timeout=1): msg = io.execute(command) if io.check_file(outfile, timeout=1): msg += 'Output file: "{0}"\n'.format(io.get_path(outfile)) else: msg = 'Failed, cannot find input file "{0}"\n'.format(io.get_path(inpfile)) return msg
def parse_qclog_cclib(qclog,anharmonic=False): xyz = None freqs = None zpe = None deltaH = None xmat = None afreqs = None msg ='' if io.check_file(qclog, 1): s = io.read_file(qclog, aslines=False) else: msg = 'File not found: "{0}"\n'.format(io.get_path(qclog)) return msg,xyz,freqs,zpe,deltaH,afreqs,xmat if check_output(s): if cclib: ccdata = parse_cclib(qclog) xyz = ccdata.writexyz() try: freqs = ccdata.vibfreqs freqs = get_listofstrings(freqs) nfreq = len(freqs) except AttributeError: pass try: deltaH = ccdata.enthalpy except AttributeError: pass if anharmonic: xmat = ccdata.vibanharms afreqs = get_gaussian_fundamentals(s, nfreq)[:,1] afreqs = get_listofstrings(afreqs) else: msg = 'Failed job: "{0}"\n'.format(io.get_path(qclog)) return msg,xyz,freqs,zpe,deltaH,afreqs,xmat
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 run_molpro(s, exe='molpro', template='molpro_template.txt', mult=None, overwrite=False): """ Runs molpro, returns a string specifying the status of the calculation. TODO """ mol = ob.get_mol(s, make3D=True) if mult is None: mult = ob.get_multiplicity(mol) tmp = io.read_file(template) inptext = get_input(mol, tmp, mult) prefix = ob.get_smiles_filename(s) inpfile = prefix + '.nw' outfile = prefix + '_nwchem.log' command = [exe, inpfile] if io.check_file(outfile, timeout=1): if overwrite: msg = 'Overwriting previous calculation "{0}"\n'.format(io.get_path(outfile)) run = True else: msg = 'Skipping calculation, found "{0}"\n'.format(io.get_path(outfile)) run = False else: run = True if run: if not io.check_file(inpfile, timeout=1) or overwrite: io.write_file(inptext, inpfile) if io.check_file(inpfile, timeout=1): msg = io.execute(command,stdoutfile=outfile,merge=True) if io.check_file(outfile, timeout=1): msg += ' Output file: "{0}"\n'.format(io.get_path(outfile)) else: msg = 'Failed, cannot find input file "{0}"\n'.format(io.get_path(inpfile)) return msg
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 gauss_xmat(filename, natoms): """ Retrieves the anharmonic constant matrix from Gaussian logfile INPUTS: filename - name of gaussian logfile natoms - number of atoms in molecule OUTPUT: xmat - anharmonic constant matrix (nmode by nmode) """ full = io.read_file(filename) nmodes = 3*natoms-6 lines = full.split('X matrix')[1].split('Resonance')[0] lines = lines.split('\n') del lines[0] del lines[-1] xmat = np.zeros((nmodes, nmodes)) rangemod = 1 if nmodes % 5 == 0: rangemod = 0 marker = 0 for m in range(0, nmodes/5+rangemod): length = nmodes - m * 5 a = np.array(lines[marker+1:marker+length+1]) for i in range(length): for j in range(0, len(a[i].split())-1): xmat[m*5 + i, m*5 + j] = a[i].split()[j+1] xmat[m*5 + j, m*5 + i] = a[i].split()[j+1] marker += length+1 return xmat
def loop(**kw): """Loop the stream and yield packets""" if "targetPids" in kw: skipPids = set(range(1 << 13)) - set(kw.pop("targetPids")) else: skipPids = set(kw.pop("skipPids", tuple())) # Prepare the file / udp if "path" in kw: read = iotools.read_file(kw["path"]) elif "ip" in kw and "port" in kw: read = iotools.read_udp(kw["ip"], kw["port"]) else: Exception(RFMT % "Not enough parameters given\n" "Give either a file path or an ip and a port") # Start loop while True: try: sync = read(1)[0] except IndexError: break if sync != 0x47: raise Exception("Sync should be 0x47, it is 0x%x" % sync) flagsAndPid = read(2) pid = ((flagsAndPid[0] & 0x1F) << 8) + flagsAndPid[1] if pid in skipPids: read(185) continue yield b"\x47" + flagsAndPid + read(185)
def gauss_anharm_inp(filename, anlevel): """ Forms the Gaussian input file for anharmonic frequency computation following an EStokTP level 1 computation on a molecule INPUT: filename - EStokTP output file to read (reac1_l1.log) OUTPUT: zmat - lines for entire guassian input file (not just the zmat part, its poorly named) """ full = io.read_file(filename) full = full.split('Z-matrix:') zmat = full[0].split('***************************')[2].replace('*', '') zmat = zmat.split('Will')[0] zmat = ' ' + zmat.lstrip() zmat += full[0].split('-------------------------------------------')[3].replace( '-', '').replace('-', '').replace('-', '').replace('\n ', '') if not anlevel == 'ignore': zmat = zmat.split('#')[0] + ' # ' + anlevel + \ ' opt = internal ' + zmat.split('#')[2] zmat += '# scf=verytight nosym Freq=Anharmonic Freq=Vibrot\n' zmat += '\nAnharmonic computation\n' zmat += full[1].split(' Variables:')[0] zmat += 'Variables:\n' zmat = zmat.replace('Charge = ', '') zmat = zmat.replace('Multiplicity =', '') varis = full[1].split('Optimized Parameters')[1].split( '--------------------------------------')[1] varis = varis.split('\n') del varis[0] del varis[-1] for var in varis: var = var.split() zmat += ' ' + var[1] + '\t' + var[2] + '\n' return zmat
def get_nwchem_frequencies(inp, filename=False, minfreq=10): """ (Projected Frequencies expressed in cm-1) 1 2 3 4 5 6 P.Frequency 0.00 0.00 0.00 0.00 0.00 0.00 1 0.00000 0.11409 0.07801 0.21786 0.00000 0.00000 2 -0.00312 0.00000 0.00000 0.00000 0.00172 0.25797 3 -0.01627 0.00000 0.00000 0.00000 0.25748 -0.00191 4 0.00000 -0.45282 -0.30962 0.65355 0.00000 0.00000 5 0.57079 0.00000 0.00000 0.00000 0.03802 0.26467 6 -0.01627 0.00000 0.00000 0.00000 0.25748 -0.00191 7 0.00000 0.79511 -0.30961 0.00000 0.00000 0.00000 8 -0.29008 0.00000 0.00000 0.00000 -0.01644 0.25462 9 0.48076 0.00000 0.00000 0.00000 0.28892 0.00389 10 0.00000 0.00000 0.85326 0.00000 0.00000 0.00000 11 -0.29008 0.00000 0.00000 0.00000 -0.01644 0.25462 12 -0.51329 0.00000 0.00000 0.00000 0.22603 -0.00771 7 8 9 10 11 12 P.Frequency 498.18 1406.65 1406.83 3103.34 3292.00 3292.33 1 -0.12950 0.00000 0.00000 0.00000 0.00000 0.00000 2 0.00000 0.00000 0.08818 0.00000 -0.09484 0.00000 3 0.00000 -0.08818 0.00000 -0.00009 0.00000 -0.09484 4 0.51400 0.00000 0.00000 0.00000 0.00000 0.00000 5 0.00000 0.00000 -0.77117 0.00000 -0.01518 0.00000 6 0.00000 -0.07120 0.00000 -0.57437 0.00000 0.76857 7 0.51398 0.00000 0.00000 0.00000 0.00000 0.00000 8 0.00000 -0.36472 -0.13940 0.49839 0.57222 0.33868 9 0.00000 0.56060 0.36475 0.28770 0.33914 0.18033 10 0.51398 0.00000 0.00000 0.00000 0.00000 0.00000 11 0.00000 0.36472 -0.13940 -0.49839 0.57222 -0.33868 12 0.00000 0.56060 -0.36475 0.28770 -0.33914 0.18033 """ if filename: lines = io.read_file(inp,aslines=True) else: if type(inp) is str: lines = inp.splitlines() else: lines = inp key = 'P.Frequency' nums = io.get_line_numbers(key,lines) freqs = [] if nums is not -1: for num in nums: line = lines[num] for item in line.split()[1:]: freq = float(item) if freq > minfreq: freqs.append(freq) return freqs
def get_nwchem_calculation(inp, filename=False): if filename: inp = io.read_file(inp,aslines=False) if 'Optimization converged' in inp: calc = 'geometry optimization' elif 'P.Frequency' in inp: calc = 'frequency analysis' else: calc = 'single point' return calc
def check_geoms(qtc, name, nsamps): """ Checks MC geoms to make sure they are the same inchii as the starting species """ import sys sys.path.insert(0, qtc) import iotools as io import obtools as ob msg = 'Checking level0 geometries' log.debug(msg) n = 2 filename = 'geoms/' + name + '_' + '1'.zfill(n) + '.xyz' lowfilename = filename coords = io.read_file(filename) lowcoords = coords mol = ob.get_mol(coords) inchi = ob.get_inchi_key(mol) energy = float(coords.split('\n')[1]) for i in range(2, int(nsamps) + 1): filename = 'geoms/' + name + '_' + '{}'.format(i).zfill(n) + '.xyz' log.info(filename) if io.check_file(filename): coords = io.read_file(filename) mol = ob.get_mol(coords) if inchi == ob.get_inchi_key(mol): if float(coords.split('\n')[1]) < energy: energy = float(coords.split('\n')[1]) log.info('Lower energy of {:.2f} found in {}'.format( energy, filename)) lowcoords = coords lowfilename = filename else: log.info( 'Connectivity change after torsional optimization. (InChI mismatch) in {}.' .format(filename)) io.cp(lowfilename, 'torsopt.xyz') #io.write_file("\n".join(lowcoords.split("\n")),'geom.xyz') io.write_file("\n".join(lowcoords.split("\n")[2:]), 'geom.xyz') msg = '\nMonte Carlo sampling successfully found geom.xyz!\n' log.info(msg) return lowfilename
def get_results(self): msg = printheader() d = {} for i,reac in enumerate(self.args.reacs, start=1): lines = '' if io.check_file('geoms/reac' + str(i) + '_l1.log'): lines = io.read_file('geoms/reac' + str(i) + '_l1.log') lines2 = '' if io.check_file('me_files/reac' + str(i) + '_fr.me'): lines2 = io.read_file('me_files/reac' + str(i) + '_fr.me') if lines: printstr, d[reac] = self.parse(i, reac, lines, lines2) msg += printstr else: log.warning('No geom for ' + reac + ' in geoms/reac' + str(i) + '_l1.log') for j,prod in enumerate(self.args.prods, start=1): lines = '' if io.check_file('geoms/prod' + str(i) + '_l1.log'): lines = io.read_file('geoms/prod' + str(j) + '_l1.log') lines2 = '' if io.check_file('me_files/reac' + str(j) + '_fr.me'): lines2 = io.read_file('me_files/prod' + str(j) + '_fr.me') if lines: printstr, d[prod] = self.parse(i+j-1, prod, lines, lines2) msg += printstr else: log.warning('No geom for ' + prod + ' in geoms/prod' + str(j) + '_l1.log') #if args.nTS > 0: # lines = io.read_file('geoms/tsgta_l1.log') # printstr += ts_parse(0,lines) # if args.nTS > 1: # lines = io.read_file('geoms/wellr_l1.log') # printstr += ts_parse(1,lines) # if args.nTS > 2: # lines = io.read_file('geoms/wellp_l1.log') # printstr += ts_parse(2,lines) log.info(msg) self.d = d return
def run_extrapolation(s, parameters): lines = io.read_file(parameters['qctemplate'],aslines=True) smilesname = ob.get_smiles_filename(s) filename = smilesname + '_cbs.ene' qcdir = parameters['qcdirectory'] directories = [] msg = '' for line in lines: if 'directories=' in line: exec(line) ndir = len(directories) energies=[0.]*ndir for i, edir in enumerate(directories): efile = io.join_path(*[edir,smilesname+'.ene']) if io.check_file(efile,verbose=True): energies[i] = float(io.read_file(efile, aslines=False)) print('Reading energy from {0} = {1}'.format(edir,energies[i])) for line in lines: if 'energy=' in line: energy = 0 exec(line) print('Extrapolation based on formula: {0}'.format(line)) print('Extrapolated energy = {0}'.format(energy)) if 'filename=' in line: exec(line) if len(directories) < 1: print('You have to specifies directories as a list in the template file') if energy: msg += 'Extrapolation successful' if parameters['writefiles']: if qcdir: filename = io.join_path(*[qcdir,filename]) io.write_file(str(energy), filename) msg += 'Extrapolation enegy file {0}'.format(filename) else: msg += 'Extrapolation failed' return msg
def get_hlen(self): hlen = [] msg = '' for i in range(len(self.args.reacs)): if io.check_file('me_files/reac'+str(i+1) + '_en.me'): hlen.append(float(io.read_file('me_files/reac'+str(i+1) + '_en.me'))) for meth in self.args.meths: if 'hlevel' in meth: self.enlevel = '{}/{}'.format(meth[1],meth[2]) else: msg += 'No energy found for reac{:g}\n'.format(i+1) for i in range(len(self.args.prods)): if io.check_file('me_files/prod'+str(i+1) + '_en.me'): hlen.append(float(io.read_file('me_files/prod'+str(i+1) + '_en.me'))) else: msg += 'No energy found for prod{:g}\n'.format(i+1) if self.args.reactype: if io.check_file('me_files/ts_en.me'): hlen.append(float(io.read_file('me_files/ts_en.me'))) else: msg += 'No energy found for ts\n' if self.args.wellr and self.args.wellr.lower() != 'false': if io.check_file('me_files/wellr_en.me'): hlen.append(float(io.read_file('me_files/wellr_en.me'))) else: msg += 'No energy found for wellr\n' if self.args.wellp and self.args.wellp.lower() != 'false': if io.check_file('me_files/wellp_en.me'): hlen.append(float(io.read_file('me_files/wellp_en.me'))) else: msg += 'No energy found for wellp\n' log.warning(msg) self.hlen = hlen return hlen
def me_file_abs_path(): """ Replaces relative path in mdhr file with absolute path """ import iotools as io if io.check_file('me_files/reac1_hr.me'): lines = io.read_file('me_files/reac1_hr.me') if "PotentialEnergySurface[kcal/mol]" in lines: before, after = lines.split("PotentialEnergySurface[kcal/mol]") after = after.split('\n') after[0] = after[0].replace('./', io.pwd() + '/') lines = before + "PotentialEnergySurface[kcal/mol]" + '\n'.join( after) io.write_file(lines, 'me_files/reac1_hr.me') return
def getenergy_fromlogfile(logfile, theory): """ Returns by default final energy solved for in logfile, or the energy corresponding to a given method in logfile """ lines = io.read_file(logfile) prog = getprog_fromlogfile(lines) if prog == 'g09': return pa.gaussian_energy(lines)[1] elif prog == 'molpro': return pa.molpro_energy(lines)[1] elif prog == None: return pa.molpro_energy(lines)[1] print 'no energy found for this molecule, please use -e to manually set it' return
def run(s): """ A driver function to run quantum chemistry and thermochemistry calculations based on command line options: --qcmethod --qccode """ import qctools as qc import obtools as ob import tctools as tc import iotools as io mol = ob.get_mol(s) mult = ob.get_multiplicity(mol) dirpath = ob.get_unique_path(mol, method=_qcmethod, mult=mult) groupsfile = 'new.groups' io.mkdir(dirpath) cwd = io.pwd() if _runthermo: if io.check_file(groupsfile): io.cp(groupsfile, dirpath) if not io.check_file(groupsfile, 1): print 'Could not copy new.groups file to target directory {0}'.format( dirpath) return -1 else: print 'new.groups file required in working directory' return -1 if io.check_dir(dirpath, 1): io.cd(dirpath) else: print 'I/O error, {0} directory not found'.format(dirpath) return -1 if _runqc: if _qccode == 'mopac': outstr = qc.run_mopac(s, mopacexe=_mopacexe, method=_qcmethod, mult=mult) outfile = outstr.split(' : ')[0] if _runthermo: lines = io.read_file(outfile, aslines=True) xyz = qc.get_mopac_xyz(lines) freqs = qc.get_mopac_freq(lines) zpe = qc.get_mopac_zpe(lines) deltaH = qc.get_mopac_deltaH(lines) get_chemkin_polynomial(mol, _qcmethod, zpe, xyz, freqs, deltaH) io.cd(cwd) return outstr
def run(s, template, parameters, mult=None): """ Runs nwchem, returns a string specifying the status of the calculation. nwchem inp.nw > nw.log NWChem writes output and error to stdout. Generates .db (a binary file to restart a job) and .movecs (scf wavefunction) files in the run directory. Generates many junk files in a scratch directory. If scratch is not specified, these junk files are placed in the run directory. """ package = parameters['qcpackage'] overwrite = parameters['overwrite'] mol = ob.get_mol(s, make3D=True) msg = '' if mult is None: mult = ob.get_multiplicity(mol) else: ob.set_mult(mol, mult) tmp = io.read_file(template) inptext = get_input(mol, tmp) prefix = ob.get_smiles_filename(s) + '_' + package inpfile = prefix + '.inp' outfile = prefix + '.out' if io.check_file(outfile, timeout=1): if overwrite: msg = 'Overwriting previous calculation "{0}"\n'.format(io.get_path(outfile)) run = True else: msg = 'Skipping calculation, found "{0}"\n'.format(io.get_path(outfile)) run = False else: run = True if run: if not io.check_file(inpfile, timeout=1) or overwrite: io.write_file(inptext, inpfile) if io.check_file(inpfile, timeout=1): if package == 'extrapolation': run_extrapolation(s, parameters) elif package == 'nwchem': command = [parameters['qcexe'], inpfile] msg += io.execute(command,stdoutfile=outfile,merge=True) else: command = [parameters['qcexe'], inpfile, outfile] msg = io.execute(command) if io.check_file(outfile, timeout=1): msg += ' Output file: "{0}"\n'.format(io.get_path(outfile)) else: msg += 'Failed, cannot find input file "{0}"\n'.format(io.get_path(inpfile)) return msg
def parse_qclog_as_dict(qclog,qccode='gaussian',anharmonic=False): xyz = None freqs = None zpe = None deltaH = None xmat = None afreqs = None basis = None method = None msg ='' if io.check_file(qclog, 1): s = io.read_file(qclog, aslines=False) else: msg = 'File not found: "{0}"\n'.format(io.get_path(qclog)) return msg,xyz,freqs,zpe,deltaH,afreqs,xmat lines = s.splitlines() if check_output(s): try: if qccode == 'gaussian': mol = ob.get_gaussian_mol(qclog) zpe = mol.energy if cclib: ccdata = parse_cclib(qclog) xyz = ccdata.writexyz() freqs = ccdata.vibfreqs freqs = get_listofstrings(freqs) nfreq = len(freqs) deltaH = ccdata.enthalpy if anharmonic: xmat = ccdata.vibanharms afreqs = get_gaussian_fundamentals(s, nfreq)[:,1] afreqs = get_listofstrings(afreqs) elif qccode == 'mopac': xyz = get_mopac_xyz(lines) freqs = get_mopac_freq(lines) freqs = get_listofstrings(freqs) zpe = get_mopac_zpe(lines) deltaH = get_mopac_deltaH(lines) except: msg = 'Parsing failed for "{0}"\n'.format(io.get_path(qclog)) return msg,xyz,freqs,zpe,deltaH,afreqs,xmat else: msg = 'Failed job: "{0}"\n'.format(io.get_path(qclog)) return msg,xyz,freqs,zpe,deltaH,afreqs,xmat
def get_output_package(out,filename=False): """ Returns the name of qc package if the calculations is succesful. Returns None if failed or unknown package. """ if filename: out = io.read_file(out,aslines=False) if "Normal termination of Gaussian" in out: p = 'gaussian' elif "== MOPAC DONE ==" in out: p = 'mopac' elif "Straatsma" in out: p = 'nwchem' elif "Variable memory released" in out: p = 'molpro' else: p = None return p
def get_freqs(filename): """ Pulls the frequencies out from EStokTP me output file INPUT: filename - name of EStokTP output file (reac1_fr.me or reac1_unpfr.me) OUTPUT: freqs - frequencies obtained from output file order - in case the frequencies were reordered when sorting, keeps track of which index of freqs corresponds to which normal mode """ full = io.read_file(filename) full = full.strip('\n') full = full.split('[1/cm]')[1].split('Zero')[0] full = full.split() nfreqs = full[0] freqs = full[1:] # [freq=float(freq) for freq in freqs] freqs = np.array(list(map(float, freqs))) a = freqs.argsort()[::-1] freqs = np.sort(freqs)[::-1] return freqs.tolist(), a.tolist()
def get_nwchem_theory(inp, filename=False): if filename: inp = io.read_file(inp,aslines=False) nwdict = { 0 :{'nre' : 'Effective nuclear repulsion energy (a.u.)'}, 1 :{'scf' : 'Total SCF energy'}, 2 :{'mp2' : 'Total MP2 energy'}, 3 :{'mp3' : 'Total MP3 energy'}, 4 :{'ccsd' : 'CCSD total energy / hartree'}, 5 :{'ccsd(t)' : 'CCSD(T) total energy / hartree'}, 6 :{'ccsd(2)_t' : 'CCSD(2)_T total energy / hartree'}, 7 :{'ccsd(2)' : 'CCSD(2) total energy / hartree'}, 8 :{'ccsdt' : 'CCSDT total energy / hartree'}, 9 :{'ccsdt(2)_q' : 'CCSDT(2)_Q total energy / hartree'}, 10 :{'ccsdtq' : 'CCSDTQ total energy / hartree'} } theory = 'unknown' for i in range(10,-1,-1): if nwdict[i].values()[0] in inp: theory = nwdict[i].keys()[0] break return theory
def run_nwchem(s, exe='nwchem', template='nwchem_template.txt', mult=None, overwrite=False): """ Runs nwchem, returns a string specifying the status of the calculation. nwchem inp.nw > nw.log NWChem writes output and error to stdout. Generates .db (a binary file to restart a job) and .movecs (scf wavefunction) files in the run directory. Generates many junk files in a scratch directory. If scratch is not specified, these junk files are placed in the run directory. """ mol = ob.get_mol(s, make3D=True) if mult is None: mult = ob.get_multiplicity(mol) tmp = io.read_file(template) inptext = get_input(mol, tmp) prefix = ob.get_smiles_filename(s) inpfile = prefix + '.nw' outfile = prefix + '_nwchem.log' command = [exe, inpfile] if io.check_file(outfile, timeout=1): if overwrite: msg = 'Overwriting previous calculation "{0}"\n'.format(io.get_path(outfile)) run = True else: msg = 'Skipping calculation, found "{0}"\n'.format(io.get_path(outfile)) run = False else: run = True if run: if not io.check_file(inpfile, timeout=1) or overwrite: io.write_file(inptext, inpfile) if io.check_file(inpfile, timeout=1): msg = io.execute(command,stdoutfile=outfile,merge=True) if io.check_file(outfile, timeout=1): msg += ' Output file: "{0}"\n'.format(io.get_path(outfile)) else: msg = 'Failed, cannot find input file "{0}"\n'.format(io.get_path(inpfile)) return msg
def run(s): """ A driver function to run quantum chemistry and thermochemistry calculations based on command line options: --qcmethod --qcpackage """ global parameters runqc = parameters['runqc'] parseqc = parameters['parseqc'] runthermo = parameters['runthermo'] runanharmonic = parameters['anharmonic'] msg = "***************************************\n" msg += "{0}\n".format(s) mult = ob.get_mult(s) mol = ob.get_mol(s) smilesname = ob.get_smiles_filename(s) smilesdir = ob.get_smiles_path(mol, mult, method='', basis='', geopath='') qcdirectory = io.join_path(*[smilesdir, parameters['qcdirectory']]) qctemplate = io.get_path(parameters['qctemplate']) qcpackage = parameters['qcpackage'] qcscript = io.get_path(parameters['qcscript']) qclog = smilesname + '_' + qcpackage + '.out' xyzpath = parameters['xyzpath'] xyzfile = None if xyzpath: if io.check_file(xyzpath): xyzfile = xyzpath elif io.check_file(io.join_path(*(smilesdir, xyzpath))): xyzfile = io.join_path(*(smilesdir, xyzpath)) elif io.check_dir(xyzpath): try: xyzfile = next(io.find_files(xyzpath, '*.xyz')) except StopIteration: msg += "xyz file not found in {0}".format(xyzpath) elif io.check_dir(io.join_path(*(smilesdir, xyzpath))): xyzpath = io.join_path(*(smilesdir, xyzpath)) try: xyzfile = next(io.find_files(xyzpath, '*.xyz')) except StopIteration: msg += "xyz file not found in {0}".format(xyzpath) else: msg += "xyz path not found {0}".format(xyzpath) return msg if xyzfile: msg += "Using xyz file in '{0}'\n".format(xyzfile) xyz = io.read_file(xyzfile) coords = ob.get_coordinates_array(xyz) mol = ob.set_xyz(mol, coords) print(msg) msg = '' io.mkdir(qcdirectory) cwd = io.pwd() if io.check_dir(qcdirectory, 1): io.cd(qcdirectory) msg += "cd '{0}'\n".format(qcdirectory) else: msg += ('I/O error, {0} directory not found.\n'.format(qcdirectory)) return -1 print(msg) msg = '' available_packages = [ 'nwchem', 'molpro', 'mopac', 'gaussian', 'extrapolation' ] if runqc: if qcpackage in available_packages: print('Running {0}'.format(qcpackage)) msg += qc.run(s, qctemplate, parameters, mult) elif qcpackage == 'qcscript': msg += "Running qcscript...\n" geofile = smilesname + '.geo' geo = ob.get_geo(mol) io.write_file(geo, geofile) if io.check_file(geofile, 1): msg += qc.run_qcscript(qcscript, qctemplate, geofile, mult) else: msg = '{0} package not implemented\n'.format(qcpackage) msg += 'Available packages are {0}'.format(available_packages) exit(msg) print(msg) msg = '' if parseqc: if io.check_file(qclog, timeout=1, verbose=False): out = io.read_file(qclog, aslines=False) d = qc.parse_output(out, smilesname, parameters['writefiles']) pprint(d) if runthermo: groupstext = tc.get_new_groups() io.write_file(groupstext, 'new.groups') msg += "Parsing qc logfile '{0}'\n".format(io.get_path(qclog)) newmsg, xyz, freqs, zpe, deltaH, afreqs, xmat = qc.parse_qclog( qclog, qcpackage, anharmonic=runanharmonic) msg += newmsg if xyz is not None: msg += "Optimized xyz in Angstroms:\n{0} \n".format(xyz) else: runthermo = False if freqs is not None: msg += "Harmonic frequencies in cm-1:\n {0} \n".format(freqs) else: runthermo = False if afreqs: msg += "Anharmonic frequencies in cm-1:\n {0}\n".format(afreqs) else: runanharmonic = False if zpe: msg += 'ZPE = {0} kcal/mol\n'.format(zpe) else: runthermo = False if deltaH is not None: msg += 'deltaH = {0} kcal/mol\n'.format(deltaH) else: runthermo = False if xmat is not None: msg += 'Xmat = {0} kcal/mol\n'.format(xmat) else: runanharmonic = False if runthermo: msg += tc.write_chemkin_polynomial(mol, zpe, xyz, freqs, deltaH, parameters) io.cd(cwd) print(msg) return
def main(mol, logfile='geoms/reac1_l1.log', E=9999.9, basis='auto', theory='auto/', db='tempdb', prog='auto'): basis = basis.split() #AUTO SET NONUSERDEFINED PARAMETRS## if is_auto(prog): prog = pa.get_prog(io.read_file(logfile)) if is_auto(mol): mol = getname_fromdirname() if is_auto(theory) and io.check_file(logfile): theory = gettheory_fromlogfile(logfile) theory += '/' theory += getbasisset_fromlogfile(logfile) theory, basisset = theory.split('/') if is_auto(E): E = getenergy_fromlogfile(logfile, theory) basprint = 'manually select basis' atomlist = get_atomlist(mol) basisselection = 0 if is_auto(basis[0]): basis = select_basis(atomlist) basisselection += 1 basprint = 'automatically generate basis' elif basis[0] == 'basis.dat': basis = io.read_file('basis.dat').split() basprint = 'read basis from basis.dat' lines = ( '\n-------------------------------------------------\n\n' + 'HEAT OF FORMATION FOR: ' + mol + '\n at ' + theory + '/' + basisset + '\n\n-------------------------------------------------\n\nYou have chosen to ' + basprint + '\n\nBasis is: ' + ', '.join(basis)) print lines for bas in basis: atomlist.extend(get_atomlist(bas)) #################################### #COMPUTE Atomlist, stoichlist, matrix, and coefficients atomlist = list(set(atomlist)) stoich = get_stoich(mol, atomlist) mat = form_mat(basis, atomlist) for i in range(5): if np.linalg.det(mat) != 0: break print 'Matrix is singular -- select new basis' atomlist = get_atomlist(mol) basis = select_basis(atomlist, basisselection) basisselection += 1 print('\n\nBasis is: ' + ', '.join(basis)) for bas in basis: atomlist.extend(get_atomlist(bas)) atomlist = list(set(atomlist)) stoich = get_stoich(mol, atomlist) mat = form_mat(basis, atomlist) print mat clist = comp_coeff(mat, stoich) ###################################################### ###PRINT STUFF OUT lines = '\n ' + mol + '\t\t' + '\t'.join(basis) for i in range(len(mat)): lines += '\n' + atomlist[i] + ' ' lines += str(stoich[i]) + ' \t' for el in mat[i]: lines += str(el) + '\t' lines += '\n\nCoefficients are: ' for co in clist: lines += str(co) + ' ' print lines + '\n' print check(clist, basis, stoich, atomlist) ################## #COMPUTE AND PRINT delH### E = comp_energy(mol, basis, clist, E, theory, basisset, prog) lines = '\n delHf(0K)' lines += '\nA.U. \t' for e in E[:1]: lines += str(e) + '\t' lines += '\nkJ \t' for e in E[:1]: lines += str(e / .00038088) + '\t' lines += '\nkcal \t' for e in E[:1]: lines += str(e * 627.503) + '\t' lines += '\n\n-------------------------------------------------\n\n' print lines ########################## return E[0] * 627.503
def get_gaussian_zmat(filename): """ Forms a zmat from a gaussian logfile """ lines = io.read_file(filename) return pa.gaussian_zmat(lines)
def getbasisset_fromlogfile(logfile): """ returns basisset used in logfile """ lines = io.read_file(logfile) return pa.basisset(lines)