def build_mol_dat(MOL, mollist, n, stoichs, symnums, jobs, foundlist, select, mdtype='auto'): """ Builds reac1.dat, reac2.dat, prod1.dat etc """ mol = mollist[n - 1] atoms, measure, angles, found, msg = MOL.cart2zmat(mol, select) #mollist[n-1] = mol.split('_')[0] if mdtype.lower() == 'auto': MOL.MDTAU, jobs = prepare_mdtau(len(angles), jobs) if mdtype: log.info(msg) zmatstring = MOL.build(n, mol, jobs, found, angles, atoms, measure) zmat = MOL.typemol + str(n) + '.dat' io.write_file(zmatstring, zmat) stoichs.append(MOL.stoich) symnums.append(MOL.symnum) foundlist.append(found) return mollist, angles, atoms, jobs, foundlist, stoichs, symnums
def write_chemkin_polynomial(mol, zpe, xyz, freqs, deltaH, parameters): """ A driver to perform all operations to write NASA polynomial in chemkin format. Assumes quantum chemistry calculation is performed. """ messpfinput = 'pf.inp' messpfoutput = 'pf.log' name = mol.formula tag = parameters['qcmethod'] inp = get_pf_input(mol, tag, zpe, xyz, freqs) io.write_file(inp, messpfinput) msg = 'Running {0} to generate partition function.\n'.format( parameters['messpf']) msg += io.execute([parameters['messpf'], messpfinput]) msg += 'Running thermp .\n' inp = get_thermp_input(mol.formula, deltaH) msg = run_thermp(inp, 'thermp.dat', messpfoutput, parameters['thermp']) msg += 'Running pac99.\n' msg += run_pac99(name) msg += 'Converting to chemkin format.\n' chemkinfile = name + '.ckin' msg += 'Writing chemking file {0}.\n'.format(chemkinfile) try: msg += write_chemkin_file(deltaH, tag, name, chemkinfile) except: "Failed to write polynomials" 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 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_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 write_anharm_inp(readfile='reac1_l1.log', writefile='anharm.inp', anlevel='ignore'): """ Writes Guassian input to a file given an EStokTP G09 output file name INPUT: readfile - EStokTP output file to read (reac1_l1.log) writefile - name of Gaussian input file to write """ zmat = gauss_anharm_inp(readfile, anlevel) io.write_file(zmat, writefile) return
def build_well_dat(MOL, mol, n, jobs, restartts): if n == 'ts': atoms, measure, angles, found, msg = MOL.cart2zmat('ts') else: atoms, measure, angles, found, msg = MOL.cart2zmat(mol) zmatstring = MOL.build(n, mol, jobs, found, angles, atoms, measure, restartts) log.info(zmatstring) zmat = MOL.typemol + '.dat' io.write_file(zmatstring, zmat) return angles, atoms
def build_molpro(dic, theory, basisset): """ Builds a Guassian optimization inputfile for a molecule INPUT: dic - dictionary for the molecule theory - theory we want to optimize with basisset- basis set we want to optimize with OUPUT: None (but an inputfile now exists with name <stoich>.inp) """ molp = 'memory, 200 ,m\nnosym\ngeometry={angstrom\n' meths = ['ccsdt', 'ccsd(t)', 'ccsd', 'm062x', 'b3lyp'] bases = ['cc-pvqz', 'cc-pvtz', 'cc-pvdz', '6-311+g(d,p)', '6-31+g(d,p)'] zmat = 'none' if theory.lower().lstrip('r') in dic['g09']: for j in range(len(bases)): if bases[j] in dic['g09'][theory.lower().lstrip('r')]: if zmat in dic['g09'][theory.lower().lstrip('r')][bases[j]]: zmat = dic['g09'][theory.lower().lstrip('r')][ bases[j]]['zmat'] if zmat == 'none': for i in range(len(meths)): if meths[i] in dic['g09']: for j in range(len(bases)): if bases[j] in dic['g09'][meths[i]]: if 'zmat' in dic['g09'][meths[i]][bases[j]]: zmat = dic['g09'][meths[i]][bases[j]]['zmat'] zmat1 = '\n'.join(zmat.split('Variables:')[0].split('\n')[2:]) zmat2 = '}\n' for line in zmat.split('Variables:')[1].split('\n')[1:-1]: zmat2 += line.split()[0] + ' = ' + line.split()[1] + '\n' molp += zmat1 + zmat2 spin = 1 / 2. * (dic['mult'] - 1) * 2 molp += '\nSET,SPIN= ' + str(spin) + '\n\n' if spin == 0: molp += '!closed shell input\nbasis=' + basisset + '\nhf\n' + theory.lower( ) + '\noptg\nENERGY=energy' else: if 'ccsd' in theory.lower() or 'cisd' in theory.lower( ) or 'hf' in theory.lower() or 'mp' in theory.lower(): molp += '!open shell input\nbasis=' + basisset + '\nhf\nu' + theory.lower( ) + '\noptg\nENERGY=energy' else: molp += '!open shell input\nbasis=' + basisset + '\nuhf\n' + theory.lower( ) + '\noptg\nENERGY=energy' io.write_file(molp, dic['stoich'] + '.inp') return
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 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 write_isomers_list(listfile): """ Writes a file containing the isomers of the species in a given list. The filename for the list is required as the input. The filename of the new file is returned. """ import iotools as io slist = io.read_list(listfile) newlist = '' for s in slist: isomers = get_isomers(s) for isomer in isomers: newlist += '{}\n'.format(isomer) newfilename = listfile.split('.')[0] + '_isomers.txt' io.write_file(newlist,filename=newfilename) return newfilename
def execute_gaussian(inp, exe='g09'): """ Runs gaussian calculation. """ from subprocess import Popen, PIPE process = Popen([exe, inp], stdout=PIPE, stderr=PIPE) out, err = process.communicate() if err is None or err == '': msg = 'Run {0} {1}: Success.'.format(exe, inp) else: errstr = """ERROR in "{0}"\n STDOUT:\n{1}\n STDERR:\n{2}""".format(inp, out, err) errfile = inp + '.err' io.write_file(errstr, errfile) msg = 'Run {0} {1}: Failed, see "{2}"'.format(exe, inp, io.get_path(errfile)) return msg
def build_gauss(dic, theory, basisset): """ Builds a Guassian optimization inputfile for a molecule INPUT: dic - dictionary for the molecule theory - theory we want to optimize with basisset- basis set we want to optimize with OUPUT: None (but an inputfile now exists with name <stoich>.inp) """ gauss = '%Mem=25GB\n%nproc=8\n' gauss += '#P ' + theory.lstrip('R').lstrip( 'U' ) + '/' + basisset + ' opt=internal int=ultrafine scf=verytight nosym\n' gauss += '\nEnergy for HeatForm\n\n' meths = ['ccsdt', 'ccsd(t)', 'ccsd', 'm062x', 'b3lyp'] bases = ['cc-pvqz', 'cc-pvtz', 'cc-pvdz', '6-311+g(d,p)', '6-31+g(d,p)'] zmat = 'none' if theory.lower().lstrip('r') in dic['g09']: for j in range(len(bases)): if bases[j] in dic['g09'][theory.lower().lstrip('r')]: if zmat in dic['g09'][theory.lower().lstrip('r')][bases[j]]: zmat = dic['g09'][theory.lower().lstrip('r')][ bases[j]]['zmat'] if zmat == 'none': for i in range(len(meths)): if meths[i] in dic['g09']: for j in range(len(bases)): if bases[j] in dic['g09'][meths[i]]: if 'zmat' in dic['g09'][meths[i]][bases[j]]: zmat = dic['g09'][meths[i]][bases[j]]['zmat'] if zmat == 'none': import obtools as ob mol = ob.get_mol(dic['_id']) zmat = ob.get_zmat(mol) gauss += str(dic['charge']) + ' ' + str(dic['mult']) + '\n' gauss += zmat.lstrip('\n') io.write_file(gauss, dic['stoich'] + '.inp') return
def execute(inp, exe,outputfile=None): """ Executes a calculation for a given input file inp and executable exe. """ from subprocess import Popen, PIPE process = Popen([exe, inp], stdout=PIPE, stderr=PIPE) out, err = process.communicate() if outputfile: io.write_file(out,outputfile) if err is None or err == '': msg = 'Run {0} {1}: Success.\n'.format(exe, inp) else: errstr = """ERROR in "{0}"\n STDOUT:\n{1}\n STDERR:\n{2}""".format(inp, out, err) errfile = inp + '.err' io.write_file(errstr, errfile) msg = 'Run {0} {1}: Failed, see "{2}"\n'.format(exe, inp, io.get_path(errfile)) return msg
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 run_thermp(thermpinput, thermpfile='thermp.dat', pffile='pf.log', thermpexe='thermp'): """ Runs thermp.exe Requires pf.dat and thermp.dat files to be present linus /tcghome/sjk/gen/aux_me/therm/thermp.exe """ import iotools as io msg = '' io.write_file(thermpinput, thermpfile) if not io.check_file(thermpfile, 1): return "{0} file not found.\n".format(thermpfile) pfdat = pffile.replace('log', 'dat') io.mv(pffile, pfdat) if io.check_file(pfdat, 1): msg += io.execute(thermpexe) else: msg += "{0} file not found.\n".format(pffile) return msg
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_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 execute_mopac(inp, exe='mopac'): """ Runs mopac calculation. Mopac is a fortran code that does not return an error code but writes error to stderr. If there is no error stderr = None or '' For some keyword errors, still no stderr or stdout is provided, so additional checks are required. """ from subprocess import Popen, PIPE import iotools as io # subprocess.call([mopacexe, inp]) process = Popen([exe, inp], stdout=PIPE, stderr=PIPE) out, err = process.communicate() if err is None or err == '': msg = 'Run {0} {1}: Success.'.format(exe, inp) else: errstr = """ERROR in {0}\n STDOUT:\n{1}\n STDERR:\n{2}""".format(inp, out, err) errfile = inp + '.err' io.write_file(errstr, errfile) msg = 'Run {0} {1}: Failed, see {2}\n'.format(exe, inp, errfile) return msg
def parse_output(s, smilesname, write=False): package = get_output_package(s) if type(s) is list: lines = s s = ''.join(lines) elif type(s) is str: lines = s.splitlines() else: print("First parameter in parse_output should be a string or list of strings") d = {} [theory,calculation,xyz,basis] = ['na']*4 nbasis = 0 energy = 0 energies = {} hrmfreqs = [] anhrmfreqs = [] parsed = False if package == 'nwchem': theory = get_nwchem_theory(s) calculation = get_nwchem_calculation(s) xyz = get_nwchem_xyz(lines) basisinfo = get_nwchem_basis(lines) basis = basisinfo['basis'] nbasis = basisinfo['number of basis functions'] energies = get_nwchem_energies(lines) energy = energies[theory] hrmfreqs = get_nwchem_frequencies(lines) parsed = True elif package == 'molpro': theory, energy = pa.molpro_energy(s) parsed = True elif package == 'gaussian': theory, energy = pa.gaussian_energy(s) parsed = True if parsed: if write: fname = smilesname + '.xyz' io.write_file(xyz, fname) fname = smilesname + '.ene' io.write_file(str(energy), fname) if len(hrmfreqs) > 0: fname = smilesname + '.hrm' io.write_file('\n'.join(str(x) for x in hrmfreqs), fname ) if len(anhrmfreqs) > 0: fname = smilesname + '.anhrm' io.write_file('\n'.join(str(x) for x in hrmfreqs), fname) d = {package: {calculation: {theory: {basis:{ 'number of basis functions':nbasis, 'energy':energy, 'geometry':{ 'xyz':xyz, 'harmonic frequencies' : hrmfreqs}}}}}} if calculation == 'geometry optimization': for key,value in energies.iteritems(): if key is not theory: d[package][calculation][theory][basis]['geometry'].update({ 'single point':{key:{basis:{'number of basis functions':nbasis,'energy':value}}}}) if write: fname = '{0}_{1}.ene'.format(theory,smilesname) io.write_file(str(energy), fname) return d
def build_files(args, paths, ists=False, nodes=1, restartts=False): """ Runs the build functions for reacn.dat, prodn.dat, theory.dat, and estoktp.dat Requirements: QTC, Openbabel, Pybel (OR prepared cartesian coordinate files) and x2z """ import sys sys.path.insert(0, paths['qtc']) global io, ob import patools as pa import iotools as io import obtools as ob build_subdirs() os.chdir('./data') stoichs = [] symnums = [] mdtype = args.mdtype if not 'MdTau' in args.jobs: mdtype = '' #Create Read, Prod, and TS objects from parameters params = (args.nsamps, args.abcd, nodes, args.interval, args.nsteps, args.XYZ, args.xyzstart, mdtype) Reac = build.MOL(paths, params, 'reac', args.reactype) Prod = build.MOL(paths, params, 'prod') params = (args.nsamps, args.abcd, nodes, args.interval, args.nsteps, args.XYZ, args.xyzstart, mdtype) TS = build.MOL(paths, params, 'ts', args.reactype) reacs = args.reacs prods = args.prods key = set_keys(args.reactype) i, j, k = 0, 0, 0 TSprops = [0, 0, [], [], [], '', 0] #charge, spin, angles, atoms, sort, bond, babs foundlist = [] #Build reacn.dat for i, reac in enumerate(reacs, start=1): msg = 'Building reac{:g}.dat'.format(i) log.debug(msg) args.reacs, angles, atoms, args.jobs, foundlist, stoichs, symnums = build_mol_dat( Reac, reacs, i, stoichs, symnums, args.jobs, foundlist, args.select[i - 1], mdtype) TSprops = prep_reacs4TS(Reac, reac, i, key, angles, atoms, Reac.sort, TSprops, args.reactype, paths) nsamps = Reac.nsamps msg = 'Completed' log.info(msg) #Build prodn.dat for j, prod in enumerate(prods, start=1): msg = 'Building prod{:g}.dat'.format(j) log.debug(msg) args.prods, angles, atoms, args.jobs, foundlist, stoichs, symnums = build_mol_dat( Prod, prods, j, stoichs, symnums, args.jobs, foundlist, args.select[i + j - 1], mdtype) msg = 'Completed' log.info(msg) #Build TS, wellr, and wellp.dat tstype = ['ts', 'wellr', 'wellp'] tss = ['false', args.wellr.lower(), args.wellp.lower()] if args.reactype: tss[0] = 'true' TS.ijk = Reac.ijk TS.sort = TSprops[4] TS.bond = TSprops[5] TS.babs = TSprops[6] for k in range(3): if tss[k] and tss[k] != 'false': if k == 1 and 'true' in args.wellr.lower(): if len(args.reacs) > 1: spin = 0 reac1 = args.reacs[0].split('_m') if len(reac1) > 1: spin += (float(reac1[1]) - 1) / 2 reac2 = args.reacs[1].split('_m') if len(reac2) > 1: spin += (float(reac2[1]) - 1) / 2 else: spin = 0 reac3 = reac1[0] + '.' + reac2[0] if spin: reac3 += '_m' + str(int(2 * spin + 1)) log.info('Building {} '.format(reac3)) angles, atoms = build_well_dat(Reac, reac3, 3, args.jobs, restartts) else: log.info( 'Two reactants are required when finding a reactant well' ) elif k == 2 and (args.reactype.lower() == 'addition_well' or args.reactype.lower() == 'isomerization_well'): if io.check_file('prod1.dat'): msg = 'moving prod1.dat to wellp.dat for {} reaction'.format( args.reactype.lower()) log.info(msg) io.mv('prod1.dat', 'wellp.dat') j = 0 args.prods = [] msg = 'Completed' log.info(msg) elif k == 2 and 'true' in args.wellp.lower(): if len(args.prods) > 1: spin = 0 prod1 = args.prods[0].split('_m') if len(prod1) > 1: spin += (float(prod1[1]) - 1) / 2 prod2 = args.prods[1].split('_m') if len(prod2) > 1: spin += (float(prod2[1]) - 1) / 2 else: spin = 0 prod3 = prod1[0] + '.' + prod2[0] if spin: prod3 += '_m' + str(int(2 * spin + 1)) log.info('Building {} '.format(prod3)) angles, atoms = build_well_dat(Prod, prod3, 4, args.jobs, restartts) else: log.info( 'Two products are required when finding a product well' ) else: msg = 'Building ' + tstype[k] + '.dat' log.debug(msg) TS.charge = TSprops[0] TS.mult = int(2. * TSprops[1] + 1) TS.symnum = ' 1' if k == 0: if 'geomdir' in args.XYZ and io.check_file( '../geomdir/ts.xyz'): angles, atoms = build_well_dat(TS, args.reactype, 'ts', args.jobs, restartts) else: zmatstring = TS.build(tstype[k], args.reactype, args.jobs, False, TSprops[2], TSprops[3], restartts) zmat = tstype[k] + '.dat' io.write_file(zmatstring, zmat) else: params = ('1', args.abcd, nodes, args.interval, args.nsteps, 'False', 'start', 'MdTau' in args.jobs) TS = build.MOL(paths, params, 'ts') TS.charge = TSprops[0] TS.mult = int(2. * TSprops[1] + 1) TS.symnum = ' 1' zmatstring = TS.build(tstype[k], args.reactype, args.jobs, False, TSprops[2]) zmat = tstype[k] + '.dat' io.write_file(zmatstring, zmat) msg = 'Completed' log.info(msg) mol = reac[0] #Builds me_head.dat if args.reactype: msg = 'Building me_head.dat' log.debug(msg) if args.mehead: if io.check_file('../' + args.mehead): headstring = io.read_file('../' + args.mehead) elif io.check_file(args.me_head): headstring = io.read_file(args.mehead) else: headstring = build.build_mehead() else: headstring = build.build_mehead() io.write_file(headstring, 'me_head.dat') msg = 'Completed' log.info(msg) #Builds theory.dat msg = 'Building theory.dat' log.debug(msg) theostring = build.build_theory(args.meths, tss, args.zedoptions, args.oneoptions, args.adiabatic) io.write_file(theostring, 'theory.dat') msg = 'Completed' log.info(msg) #Builds estoktp.dat to restart at any step msg = 'Building estoktp.dat' log.debug(msg) jobs = update_jobs(args.jobs, args.restart) params = (stoichs, args.reactype, args.coresh, args.coresl, args.meml, args.memh, args.esoptions) eststring = build.build_estoktp(params, jobs, i, j, tss, args.xyzstart, foundlist, ists) io.write_file(eststring, 'estoktp.dat') msg = 'Completed' log.info(msg) os.chdir('..') return stoichs, symnums
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(inputfile, outputfile, configfile=''): torspath = os.path.dirname(os.path.realpath(sys.argv[0])) if configfile == '': configfile = torspath + os.path.sep + 'configfile.txt' args = config.ARGS(inputfile) Config = config.CONFIG(configfile, outputfile) paths = Config.path_dic() paths['torsscan'] = torspath sys.path.insert(0, es.get_paths(paths, 'bin')) sys.path.insert(0, es.get_paths(paths, 'qtc')) sys.path.insert(0, es.get_paths(paths, 'torsscan')) log.info(random_cute_animal()) ##### Build and Run EStokTP ###### #################################### global io, ob import obtools as ob import iotools as io import tctools as tc import shutil symnums = [] samps = None if args.restart < 8: index = 0 if "Opt" in args.jobs and args.restart < 1: alljobs = args.jobs args.jobs = ["Opt"] es.run_level0(args, paths) args.restart = 1 args.jobs = alljobs if "1dTau" in args.jobs and args.restart < 4: logging.info("========\nBEGIN LEVEL 1 and 1DHR\n========\n") alljobs = args.jobs negvals = True attempt = 0 while (negvals and attempt < 3): attempt += 1 args.jobs = ["Opt_1", "1dTau"] negvals = False if attempt == 1 and args.restart == 3: pass else: stoichs, symnums = es.build_files(args, paths) es.execute(paths, args.nodes[0]) if io.check_file('output/estoktp.out'): shutil.copy('output/estoktp.out', 'output/estoktp_l1.out') args.restart = 3 for i in range(len(args.reacs)): lowene = 0.0 lowenefile = None if io.check_file('me_files/reac' + str(i + 1) + '_hr.me'): hr = io.read_file('me_files/reac' + str(i + 1) + '_hr.me') hr = hr.split('Rotor') startkey = 'Potential' for j, rotor in enumerate(hr[1:]): pot = rotor.split(startkey)[1] pot = pot.splitlines()[1] for k, ene in enumerate(pot.split()): if float(ene) - lowene < -0.1: lowene = float(ene) lowenefile = 'hr_geoms/geom_isp' + str( i + 1).zfill(2) + '_hr' + str( j + 1).zfill(2) + '_hpt' + str( k + 1).zfill(2) + '.xyz' if lowenefile: xyz = io.read_file(lowenefile) logging.info(xyz) slabel = ob.get_slabel(ob.get_mol(xyz)) if slabel.split('_m')[0] == ob.get_slabel( args.reacs[i]).split('_m')[0]: negvals = True if io.check_file('data/ts.dat') and i == 0: if 'isomerization' in args.reactype.lower(): tsfile = io.read_file('data/ts.dat') ijk = tsfile.split('ji ki')[1].split()[:3] ijk.append( tsfile.split('ireact2')[1].split('\n') [1].split()[-1]) xyz = xyz.splitlines() xyz[int(ijk[0]) + 1] = '2 ' + xyz[int(ijk[0]) + 1] xyz[int(ijk[1]) + 1] = '3 ' + xyz[int(ijk[1]) + 1] xyz[int(ijk[2]) + 1] = '4 ' + xyz[int(ijk[2]) + 1] xyz[int(ijk[3]) + 1] = '1 ' + xyz[int(ijk[3]) + 1] xyz = '\n'.join(xyz) else: ijk = io.read_file('data/ts.dat').split( 'ksite')[1].split()[:3] xyz = xyz.splitlines() xyz[int(ijk[0]) + 1] = '2 ' + xyz[int(ijk[0]) + 1] xyz[int(ijk[1]) + 1] = '1 ' + xyz[int(ijk[1]) + 1] xyz[int(ijk[2]) + 1] = '3 ' + xyz[int(ijk[2]) + 1] xyz = '\n'.join(xyz) slabel = ob.get_smiles_filename( ob.get_slabel(args.reacs[i])) io.mkdir('geomdir') io.write_file(xyz, 'geomdir/' + slabel + '.xyz') args.restart = 1 args.XYZ = 'geomdir' args.xyzstart = '0' log.warning( 'Lower configuration found in 1dTau. Restarting at Level1. Saved geometry to {}' .format(slabel + '.xyz')) else: log.warning( 'Lower configuration found in 1dTau. But has different smiles: {} vs. {}' .format(slabel, ob.get_slabel(args.reacs[i]))) for l in range(len(args.prods)): lowene = 0. lowenefile = None if io.check_file('me_files/prod' + str(l + 1) + '_hr.me'): hr = io.read_file('me_files/prod' + str(l + 1) + '_hr.me') hr = hr.split('Rotor') startkey = 'Potential' for j, rotor in enumerate(hr[1:]): pot = rotor.split(startkey)[1] pot = pot.splitlines()[1] for k, ene in enumerate(pot.split()): if float(ene) - lowene < -0.1: lowene = float(ene) lowenefile = 'hr_geoms/geom_isp' + str( i + l + 2).zfill(2) + '_hr' + str( j + 1).zfill(2) + '_hpt' + str( k + 1).zfill(2) + '.xyz' if lowenefile: xyz = io.read_file(lowenefile) slabel = ob.get_slabel(ob.get_mol(xyz)) if slabel.split('_m')[0] == ob.get_slabel( args.prods[l]).split('_m')[0]: negvals = True slabel = ob.get_smiles_filename( ob.get_slabel(args.prods[l])) io.mkdir('geomdir') io.write_file(xyz, 'geomdir/' + slabel + '.xyz') args.restart = 1 args.XYZ = 'geomdir' args.xyzstart = '0' log.warning( 'Lower configuration found in 1dTau. Restarting at Level1. Saved geometry to {}' .format(slabel + '.xyz')) else: log.warning( 'Lower configuration found in 1dTau. But has different smiles: {} vs. {}' .format(slabel, ob.get_slabel(args.prods[l]))) if args.reactype.lower() in [ 'addition', 'abstraction', 'isomerization', 'addition_well', 'isomerization_well' ]: lowene = 0. lowenefile = None if io.check_file('me_files/ts_hr.me'): hr = io.read_file('me_files/ts_hr.me') hr = hr.split('Rotor') startkey = 'Potential' for j, rotor in enumerate(hr[1:]): pot = rotor.split(startkey)[1] pot = pot.splitlines()[1] for k, ene in enumerate(pot.split()): if float(ene) - lowene < -0.1: lowene = float(ene) lowenefile = 'hr_geoms/geom_isp00_hr' + str( j + 1).zfill(2) + '_hpt' + str( k + 1).zfill(2) + '.xyz' if lowenefile: xyz = io.read_file(lowenefile) negvals = True io.mkdir('geomdir') io.write_file(xyz, 'geomdir/ts.xyz') args.restart = 1 args.XYZ = 'geomdir' args.xyzstart = '0' log.warning( 'Lower configuration found in 1dTau. Restarting at Level1. Saved geometry to ts.xyz' ) if args.wellp and args.wellp.lower() != 'false': lowene = 0. lowenefile = None if io.check_file('me_files/wellp_hr.me'): hr = io.read_file('me_files/wellp_hr.me') hr = hr.split('Rotor') startkey = 'Potential' for j, rotor in enumerate(hr[1:]): pot = rotor.split(startkey)[1] pot = pot.splitlines()[1] for k, ene in enumerate(pot.split()): if float(ene) - lowene < -0.1: lowene = float(ene) lowenefile = 'hr_geoms/geom_isp06_hr' + str( j + 1).zfill(2) + '_hpt' + str( k + 1).zfill(2) + '.xyz' if lowenefile: xyz = io.read_file(lowenefile) negvals = True io.mkdir('geomdir') io.write_file(xyz, 'geomdir/wellp.xyz') args.restart = 1 args.XYZ = 'geomdir' args.xyzstart = '0' log.warning( 'Lower configuration found in 1dTau. Restarting at Level1. Saved geometry to wellp.xyz' ) if args.wellr and args.wellr.lower() != 'false': lowene = 0. lowenefile = None if io.check_file('me_files/wellr_hr.me'): hr = io.read_file('me_files/wellr_hr.me') hr = hr.split('Rotor') startkey = 'Potential' for j, rotor in enumerate(hr[1:]): pot = rotor.split(startkey)[1] pot = pot.splitlines()[1] for k, ene in enumerate(pot.split()): if float(ene) - lowene < -0.1: lowene = float(ene) lowenefile = 'hr_geoms/geom_isp05_hr' + str( j + 1).zfill(2) + '_hpt' + str( k + 1).zfill(2) + '.xyz' if lowenefile: xyz = io.read_file(lowenefile) negvals = True io.mkdir('geomdir') io.write_file(xyz, 'geomdir/wellr.xyz') args.restart = 1 args.XYZ = 'geomdir' args.xyzstart = '0' log.warning( 'Lower configuration found in 1dTau. Restarting at Level1. Saved geometry to wellr.xyz' ) args.jobs = alljobs elif "Opt_1" in args.jobs and args.restart < 2: log.info("========\nBEGIN LEVEL 1\n========\n") alljobs = args.jobs args.jobs = ["Opt_1"] stoichs, symnums = es.build_files(args, paths) es.execute(paths, args.nodes[0]) if io.check_file('output/estoktp.out'): shutil.copy('output/estoktp.out', 'output/estoktp_l1.out') args.jobs = alljobs args.restart = 2 if args.anharm.lower() != 'false' and 'd' not in args.nodes[0]: import thermo log.info("========\nBEGIN VPT2\n========\n") optlevel, anlevel = thermo.get_anlevel(args.anharm, args.meths) for n, reac in enumerate(args.reacs): typ = 'reac' natom = ob.get_natom(reac) if natom > 2: mult = ob.get_mult(reac) if io.check_file('me_files/' + typ + str(n + 1) + '_fr.me'): if not 'Anh' in io.read_file('me_files/' + typ + str(n + 1) + '_fr.me'): anfr, fr1, anx, fr2, fr3, _ = thermo.get_anharm( typ, str(n + 1), natom, args.nodes[0], anlevel, args.anovrwrt, reac, optlevel.split('/'), paths) lines = io.read_file('me_files/' + typ + str(n + 1) + '_fr.me') io.write_file( lines, 'me_files/' + typ + str(n + 1) + '_harm.me') lines = fr1 + fr2.split( 'End' )[0] + fr3 + '\n !************************************\n' io.write_file( lines, 'me_files/' + typ + str(n + 1) + '_fr.me') for n, prod in enumerate(args.prods): typ = 'prod' natom = ob.get_natom(prod) if natom > 2: mult = ob.get_mult(prod) if io.check_file('me_files/' + typ + str(n + 1) + '_fr.me'): if not 'Anh' in io.read_file('me_files/' + typ + str(n + 1) + '_fr.me'): anfr, fr1, anx, fr2, fr3, _ = thermo.get_anharm( typ, str(n + 1), natom, args.nodes[0], anlevel, args.anovrwrt, prod, optlevel.split('/'), paths) lines = io.read_file('me_files/' + typ + str(n + 1) + '_fr.me') io.write_file( lines, 'me_files/' + typ + str(n + 1) + '_harm.me') lines = fr1 + fr2.split( 'End' )[0] + fr3 + '\n !************************************\n' io.write_file( lines, 'me_files/' + typ + str(n + 1) + '_fr.me') if args.reactype and io.check_file('geoms/tsgta_l1.xyz'): typ = 'ts' mol = io.read_file('geoms/tsgta_l1.xyz') ts = ob.get_mol(mol) natom = ob.get_natom(ts) mult = ob.get_mult(ts) if io.check_file('me_files/ts_fr.me'): if not 'Anh' in io.read_file('me_files/ts_fr.me'): anfr, fr1, anx, fr2, fr3, _ = thermo.get_anharm( typ, str(n + 1), natom, args.nodes[0], anlevel, args.anovrwrt, 'ts', optlevel.split('/'), paths) lines = io.read_file('me_files/' + typ + '_fr.me') io.write_file(lines, 'me_files/' + typ + '_harm.me') lines = fr1 + fr2.split( 'End' )[0] + fr3 + '\n End\n !************************************\n' io.write_file(lines, 'me_files/' + typ + '_fr.me') log.info("========\nBEGIN MDHR, HL\n========\n") if 'kTP' in args.jobs: alljobs = args.jobs args.jobs = [] for job in alljobs: if job != 'kTP': args.jobs.append(job) stoichs, symnums = es.build_files(args, paths) es.execute(paths, args.nodes[0]) if io.check_file('me_files/ts_en.me'): tsen = float(io.read_file('me_files/ts_en.me')) tsen += float(io.read_file('me_files/ts_zpe.me')) reacen = 0 proden = 0 for i, reac in enumerate(args.reacs): if io.check_file('me_files/reac{}_en.me'.format(i + 1)): reacen += float( io.read_file('me_files/reac{}_en.me'.format(i + 1))) reacen += float( io.read_file('me_files/reac{}_zpe.me'.format(i + 1))) if args.reactype.lower( ) == 'addition_well' or args.reactype.lower( ) == 'isomerization_well': if io.check_file('me_files/wellp_en.me'): proden += float(io.read_file('me_files/wellp_en.me')) proden += float(io.read_file('me_files/wellp_zpe.me')) else: for i, prod in enumerate(args.prods): if io.check_file('me_files/prod{}_en.me'.format(i + 1)): proden += float( io.read_file( 'me_files/prod{}_en.me'.format(i + 1))) proden += float( io.read_file( 'me_files/prod{}_zpe.me'.format(i + 1))) if tsen <= reacen or tsen <= proden: log.info('Well Depth is negative. NoTunnel is turned on') if args.esoptions: args.esoptions += ',NoTunnel' else: args.esoptions = 'NoTunnel' log.info("========\nBEGIN kTP\n========\n") args.jobs = alljobs restart = 7 stoichs, symnums = es.build_files(args, paths) es.execute(paths, args.nodes[0]) else: stoichs, symnums = es.build_files(args, paths) es.execute(paths, args.nodes[0]) if ("1dTau" in args.jobs or 'MdTau' in args.jobs): for i in range(len(args.reacs)): es.check_hrs(i + 1, 'reac') for i in range(len(args.prods)): es.check_hrs(i + 1, 'prod') es.me_file_abs_path() if args.restart == 10: io.execute([paths['bin'] + os.path.sep + 'mess', 'me_ktp.inp']) if args.reactype and io.check_file('rate.out'): import me_parser #initialize the class in which to store the results data = me_parser.paper() data.reactions = [] # set some constants, depending upon whether the rate coefficients are to be used for CHEMKIN or something else. data.T0 = 1.0 data.R = 1.987 # cal/mol-K. Note that PLOG formalism requires Ea in cal/mol-K! data.N_avo = 6.0221415E23 #convert bimolecular rate coefficients from cm^3/sec to cm^3/mol/s # set the minimum and maximum temperature #data.Tmin = 600.0 #data.Tmax = 1200.0 # read me.out file from the command line me_dot_out = 'rate.out' if io.check_file(me_dot_out): lines = io.read_file(me_dot_out, True) if len(lines) < 2: log.info('rate.out is empty') ## copy new plog executable to the path of the source file #path = os.path.abspath(os.path.dirname(me_dot_out)) # #command = 'cp /home/elliott/bin/dsarrfit.x_cfg ' + path #log.info( command) #os.system(command) # parse results for the temperature, pressure, and names of channels me_parser.get_temp_pres(data, lines) # parse results for the pdep rate constants me_parser.get_pdep_k(data, lines) # fit the results to PLOG expressions me_parser.fit_pdep( data, nonlin_fit=False ) #replace <True> with <False> if you don't want to use the nonlinear solver (not recommended) # print the resulting PLOG expressions to file me_parser.print_plog(data, me_dot_out) # plot the results: dashed line = single PLOG, solid line = double PLOG #me_parser.plot_reactant(data, me_dot_out, show_plot=False, save_plot=True) ####### Parse results ######### ######################################## import results rs = results.RESULTS(args, paths) args.hlen = rs.get_hlen() args.optlevel = rs.optlevel args.enlevel = rs.enlevel args.taulevel = rs.taulevel if args.parseall.lower() == 'true' or args.alltherm.lower() == 'true': rs.get_results() ####### Build and run thermo ######### ######################################## import thermo rs.thermo = False if args.alltherm.lower() == 'true': rs.thermo = True args.symnums = symnums rs.dH0, rs.dH298, rs.hfbases, rs.anfreqs, rs.anxmat = thermo.run( args, paths, rs.d) if args.parseall.lower() == 'true': rs.get_thermo_results() return