def input_gen_gauss(self, charge=None, spin_multiplicity=None, title=None, functional='HF', basis_set='6-31G(d)', route_parameters=SUGGESTED_route_parameters, input_parameters=None, link0_parameters=None, dieze_tag='#P', gen_basis=None): ginobj_mono_a = GaussianInput(self.mono_a, charge, spin_multiplicity, title, functional, basis_set, route_parameters, input_parameters, link0_parameters, dieze_tag, gen_basis) ginobj_mono_b = GaussianInput(self.mono_a, charge, spin_multiplicity, title, functional, basis_set, route_parameters, input_parameters, link0_parameters, dieze_tag, gen_basis) dimer_sites = self.mono_a.sites + self.mono_b.sites dimer_pmgmol = Molecule.from_sites(dimer_sites) ginobj_dimer = GaussianInput(dimer_pmgmol, charge, spin_multiplicity, title, functional, basis_set, route_parameters, input_parameters, link0_parameters, dieze_tag, gen_basis) return ginobj_mono_a.to_string( cart_coords=True), ginobj_mono_b.to_string( cart_coords=True), ginobj_dimer.to_string(cart_coords=True)
def test_init(self): mol = Molecule(["C", "H", "H", "H", "H"], self.coords) gau = GaussianInput(mol, charge=1, route_parameters={"SP": "", "SCF": "Tight"}) self.assertEqual(gau.spin_multiplicity, 2) mol = Molecule(["C", "H", "H", "H", "H"], self.coords, charge=-1) gau = GaussianInput(mol, route_parameters={"SP": "", "SCF": "Tight"}) self.assertEqual(gau.spin_multiplicity, 2) self.assertRaises(ValueError, GaussianInput, mol, spin_multiplicity=1)
def test_no_molecule(self): """Test that we can write output files without a geometry""" # Note that we must manually specify charge with self.assertRaises(ValueError): GaussianInput(None) # Makes a file without geometry input_file = GaussianInput(None, charge=0, spin_multiplicity=2) input_str = input_file.to_string().strip() self.assertTrue(input_str.endswith("0 2"))
def MakesGauInputs(mol_file, dihed_atoms_file, w, num_conform=19): """ Creates Gaussian input files in its own folder for mol_file structues that freezes the central angle at iterations of 180/num_conform degrees. This function requires Gaussian output file of molecule in question and file with dihedral atoms to be in the current working directory. """ molecule_name = mol_file.split('/')[-1][:-12] mol_pymat = Molecule.from_file(mol_file) molecule = pmgmol_to_rdmol(mol_pymat)[0] with open(dihed_atoms_file, 'r') as fn: data = fn.readlines() dihedral1 = data[0].split(',')[0] dihedral2 = data[0].split(',')[1] d1atom1_num = int(dihedral1.split()[0]) d1atom2_num = int(dihedral1.split()[1]) d1atom3_num = int(dihedral1.split()[2]) d1atom4_num = int(dihedral1.split()[3]) phi = np.linspace(start=0, stop=180, num=num_conform) for P in phi: dir_name = "{}/{}_{:.0f}deg/".format(os.getcwd(), molecule_name, P) os.mkdir(dir_name) file_name = "{}/{}_{:.0f}deg".format(dir_name, molecule_name, P) SetDihedralDeg(molecule.GetConformer(), d1atom1_num, d1atom2_num, d1atom3_num, d1atom4_num, P) with open(dir_name + "temp.xyz", 'w+') as fout: fout.write(str(MolToXYZBlock(molecule))) mol = Molecule.from_file(dir_name + 'temp.xyz') os.remove(dir_name + 'temp.xyz') gau = GaussianInput(mol=mol, charge=0, spin_multiplicity=1, functional='uLC-wPBE', basis_set='cc-pVDZ', route_parameters={ "iop(3/107={}, 3/108={})".format(w, w): "", "opt": "modredundant" }, link0_parameters={ '%mem': '5GB', '%chk': '{}.chk'.format(file_name.split('/')[-1]) }) gjf_file = gau.write_file(dir_name + 'temp.gjf') with open(dir_name + 'temp.gjf') as temp: lines = temp.readlines() os.remove(dir_name + 'temp.gjf') with open(file_name + '.gjf', 'w') as gjf: gjf.writelines([item for item in lines[:-2]]) gjf.write("D * {} {} * F\n\n".format(d1atom2_num + 1, d1atom3_num + 1)) print( "Torsion Gaussian input files for {} finsihed!".format(molecule_name))
def generate_gjf(in_fn, out_dir, functional='LC-wHPBE', basis_set='TZVP', charge=0, calculation='opt', omega=None, oldchk=None): """ Convert an individually inputted xyz file to a gjf Gaussian input file """ mol = Molecule.from_file(in_fn) mol.perturb(0.1) mol_name = in_fn.split('/')[-1][:14] link0_parameters = {'%mem': '5GB', '%chk': '{}.chk'.format(calculation)} route_parameters = { calculation: '', 'SCF': '(MaxCycle=250)', 'Int': '(Grid=Ultrafine)' } if calculation == 'tddft': route_parameters = {'TD(NStates=5, 50-50)': ''} if omega is not None: route_parameters["iop(3/107={}, 3/108={})".format(omega, omega)] = '' if oldchk: link0_parameters['%oldchk'] = '{}.chk'.format(oldchk) route_parameters['Geom'] = 'AllCheck' gau = GaussianInput(mol=mol, charge=charge, functional=functional, basis_set=basis_set, route_parameters=route_parameters, link0_parameters=link0_parameters) gjf_file = gau.write_file('{}/{}.gjf'.format(out_dir, calculation)) return gjf_file
def write_mol(mol, filename): """ Write a molecule to a file based on file extension. For example, anything ending in a "xyz" is assumed to be a XYZ file. Supported formats include xyz, Gaussian input (gjf|g03|g09|com|inp), and pymatgen's JSON serialized molecules. Args: mol (Molecule/IMolecule): Molecule to write filename (str): A filename to write to. """ fname = os.path.basename(filename) if fnmatch(fname.lower(), "*.xyz*"): return XYZ(mol).write_file(filename) elif any([ fnmatch(fname.lower(), "*.{}*".format(r)) for r in ["gjf", "g03", "g09", "com", "inp"] ]): return GaussianInput(mol).write_file(filename) elif fnmatch(fname, "*.json*") or fnmatch(fname, "*.mson*"): with zopen(filename, "wt") as f: return f.write(str2unicode(json.dumps(mol, cls=MontyEncoder))) else: m = re.search("\.(pdb|mol|mdl|sdf|sd|ml2|sy2|mol2|cml|mrv)", filename.lower()) if m: return BabelMolAdaptor(mol).write_file(filename, m.group(1)) raise ValueError("Unrecognized file extension!")
def write_gau_input(species, coords, iframe, jobname="run_gau", **kwargs): """ write a gaussian input file """ path = kwargs["path"] functional = kwargs["functional"] basis_set = kwargs["basis_set"] nprocs = kwargs["nprocs"] # get first letter of atom name => element species = [specie[0] for specie in species] # convert nm to angstrom coords = np.array(coords) * 10 # build Molecule and Gaussian object mol = mg.Molecule(species, coords, validate_proximity=True) ginp = GaussianInput( mol, charge=0, title="Written by gro2qm - snapshot %d" % iframe, functional=functional, basis_set=basis_set, route_parameters={"pop": "(MK, MBS)"}, link0_parameters={"%nprocs": nprocs}, dieze_tag="#" ) basename = "gau_%05d" % iframe ginp.write_file(os.path.join(path, basename + ".com"), cart_coords=True) mol.to(fmt="xyz", filename=os.path.join(path, basename + ".xyz")) return "sbatch -J snap_%05d %s %s.com" % (iframe, jobname, basename)
def test_no_molecule_func_bset_charge_mult(self): """ Test that we can write inputs files without a geometry, functional, basis set, charge or multiplicity (mainly for postprocessing jobs where this info is read from .chk) """ gau_str = "#P chkbasis geom=allcheck guess=(only,read) pop=naturalorbital\n" gau_str += "\n" gau_str += "Restart" input_file = GaussianInput( None, charge=None, spin_multiplicity=None, functional=None, basis_set=None, route_parameters={ "chkbasis": None, "geom": "allcheck", "guess": { "only": None, "read": None }, "pop": "naturalorbital", }, ) input_str = input_file.to_string().strip() self.assertEqual(input_str, gau_str)
def test_no_molecule(self): """Test that we can write input files without a geometry""" # Makes a file without geometry input_file = GaussianInput(None, charge=0, spin_multiplicity=2) input_str = input_file.to_string().strip() self.assertTrue(input_str.endswith("0 2"))
def MakesGauInputs(fn,w): """ Convert an individually imputted xyz file to a gjf Gaussian input file """ mol = Molecule.from_file(fn) mol_name = fn.split('/')[-1][:-12] gau = GaussianInput(mol=mol,charge=0,spin_multiplicity=1,functional='uLC-wPBE',basis_set='cc-pVDZ', route_parameters={"iop(3/107={}, 3/108={})".format(w,w):"","opt":"modredundant"}, link0_parameters={'%mem':'5GB','%chk':'{}.chk'.format(mol_name)}) gjf_file = gau.write_file('{}.gjf'.format(fn.split('.')[0])) return gjf_file
def better_guess(cls, gaussian_cmd, input_file, output_file, stderr_file='stderr.txt', backup=True, cart_coords=True): orig_input = GaussianInput.from_file(input_file) yield (GaussianJob(gaussian_cmd=gaussian_cmd, input_file=input_file, output_file=output_file, stderr_file=stderr_file, suffix='.guess1', backup=backup)) if GaussianErrorHandler.activate_better_guess: # TODO: check why it comes here only if the lower job is not # failing and not in the else condition # continue only if other corrections are invalid or failed lower_output = GaussianOutput(output_file) if len(lower_output.errors) == 0: # if the calculation at the lower level of theory succeeded if not filter(os.listdir('.'), '*.[Cc][Hh][Kk]'): raise FileNotFoundError( 'Missing checkpoint file. Required ' 'to read initial guesses') gin = GaussianInput( mol=None, charge=orig_input.charge, spin_multiplicity=orig_input.spin_multiplicity, title=orig_input.title, functional=orig_input.functional, basis_set=orig_input.basis_set, route_parameters=lower_output.route_parameters, input_parameters=orig_input.input_parameters, link0_parameters=orig_input.link0_parameters, dieze_tag=orig_input.dieze_tag, gen_basis=orig_input.gen_basis) gin.route_parameters['Guess'] = 'Read' gin.route_parameters['Geom'] = 'Checkpoint' gin.write_file(input_file, cart_coords=cart_coords) yield (GaussianJob(gaussian_cmd=gaussian_cmd, input_file=input_file, output_file=output_file, stderr_file=stderr_file, suffix='.guess2', backup=backup)) else: logger.info('Failed to generate a better initial guess') else: logger.info('Calculation completed normally without having to ' 'generate a better initial guess')
def setUp(self): coords = [[0.000000, 0.000000, 0.000000], [0.000000, 0.000000, 1.089000], [1.026719, 0.000000, -0.363000], [-0.513360, -0.889165, -0.363000], [-0.513360, 0.889165, -0.363000]] self.coords = coords mol = Molecule(["C", "H", "H", "H", "H"], coords) self.gau = GaussianInput( mol, route_parameters={'SP': "", "SCF": "Tight"}, input_parameters={"EPS": 12})
def gauss_in_gen(name, mol, type, func, basis, charge, spin, route_params, link0_params): mol_in = GaussianInput( mol, charge=charge, spin_multiplicity=spin, functional=func, basis_set=basis, route_parameters=route_params, link0_parameters=link0_params, ) fn = '{}_{}.gjf'.format(name, type) mol_in.write_file(filename=fn, cart_coords=True) return fn
def XYZtoGJF(xyz_fn, out_dir, functional, basis_set, charge=0): """ Convert an individually imputted xyz file to a gjf Gaussian input file """ mol = Molecule.from_file(xyz_fn) mol_name = xyz_fn.split('/')[-1].split('.')[0] gau = GaussianInput(mol=mol, charge=charge, functional=functional, basis_set=basis_set, route_parameters={"opt": ""}, link0_parameters={ '%mem': '5GB', '%chk': '{}.chk'.format(mol_name) }) gjf_file = gau.write_file('{}/{}.gjf'.format(out_dir, mol_name)) return gjf_file
def XYZtoGJF(fn): """ Convert an individually imputted xyz file to a gjf Gaussian input file """ mol = Molecule.from_file(fn) gau = GaussianInput(mol=mol, charge=0, spin_multiplicity=1, functional='PM6', basis_set='', route_parameters={'': ''}, link0_parameters={ '%mem': '5GB', '%nproc': '1', '%chk': '{}.chk'.format(fn.split('.')[0]) }) gjf_file = gau.write_file('{}.gjf'.format(fn.split('.')[0])) return gjf_file
def test_gen_basis(self): gau_str = """#N B3LYP/Gen Pseudo=Read Test 0 1 C H 1 B1 H 1 B2 2 A2 H 1 B3 2 A3 3 D3 H 1 B4 2 A4 4 D4 B1=1.089000 B2=1.089000 A2=109.471221 B3=1.089000 A3=109.471213 D3=120.000017 B4=1.089000 A4=109.471213 D4=119.999966 C 0 6-31G(d,p) **** H 0 6-31G **** """ mol = Molecule(["C", "H", "H", "H", "H"], self.coords) gen_basis = "C 0\n6-31G(d,p)\n****\nH 0\n6-31G\n****" gau = GaussianInput( mol, functional="B3LYP", gen_basis=gen_basis, dieze_tag="#N", route_parameters={"Pseudo": "Read"}, title="Test", ) self.assertEqual(gau.to_string(cart_coords=False), gau_str)
def gen_input(self, step_size, nrings, maxnbq, height=1.7, normaldirection=0, charge=None, spin_multiplicity=None, title=None, functional='HF', basis_set='6-31G(d)', route_parameters=None, input_parameters=None, link0_parameters=None, dieze_tag='#P', gen_basis=None): """ this will return two lists of gauss input string, xticks, xnumbers, pt_idx(ring idx) for plotting pts are cart coords for bqs return None if failed one problem is if the number of ghost atoms cannot be too large, so the param maxnbq is introduced as the max number of ghost atoms that is allowed to show in one input file for other param docs see nics_line_scan_path and pymatgen.io.gassian """ pts, pt_idx, xnumbers, xticks = self.nics_line_scan_path( step_size, nrings, height, normaldirection) sigma_mol_msites = self.nics_sigma_structure(normal_idx=1 - normaldirection) sigma_pmgmol = Molecule.from_sites(sigma_mol_msites) total_pmgmol = self.omol.pmgmol chunksize = maxnbq total_ginobj = GaussianInput(total_pmgmol, charge, spin_multiplicity, title, functional, basis_set, route_parameters, input_parameters, link0_parameters, dieze_tag, gen_basis) sigma_ginobj = GaussianInput(sigma_pmgmol, charge, spin_multiplicity, title, functional, basis_set, route_parameters, input_parameters, link0_parameters, dieze_tag, gen_basis) total_outs_list = [] sigma_outs_list = [] if len(pts) > maxnbq: pts_sep_list = [ pts[i * chunksize:(i + 1) * chunksize] for i in range((len(pts) + chunksize - 1) // chunksize) ] for idx in range(len(pts_sep_list)): total_outs = total_ginobj.to_string(cart_coords=True) total_outs = self.add_bqlines(total_outs, pts_sep_list[idx]) sigma_outs = sigma_ginobj.to_string(cart_coords=True) sigma_outs = self.add_bqlines(sigma_outs, pts_sep_list[idx]) total_outs_list.append(total_outs) sigma_outs_list.append(sigma_outs) else: # is this redundant? total_outs = total_ginobj.to_string(cart_coords=True) total_outs = self.add_bqlines(total_outs, pts) sigma_outs = sigma_ginobj.to_string(cart_coords=True) sigma_outs = self.add_bqlines(sigma_outs, pts) total_outs_list.append(total_outs) sigma_outs_list.append(sigma_outs) return sigma_outs_list, total_outs_list, xticks, xnumbers, pt_idx, pts
def calculate_properties(rin, directory): with cd(directory): # found that the relax often crashed or didn't finish, so will restart # the calculation in these cases try: rout = GaussianOutput('relax.log') if not rout.properly_terminated: logging.info('restarting {}'.format(directory)) route = rout.route route['integral'] = '(acc2e=12)' rout.to_input('relax.com', cart_coords=True, route_parameters=route) os.system('g09 < relax.com > relax.log') except IOError: # relaxation hasn't been run yet logging.info('started processing {}'.format(directory)) rin.write_file('relax.com', cart_coords=True) os.system('g09 < relax.com > relax.log') except IndexError, AttributeError: # the relax calculation used the wrong header, fix this and restart rin = GaussianInput.from_file('relax.com') rin.route_parameters['integral'] = '(acc2e=12)' rin.write_file('relax.com', cart_coords=True) os.system('g09 < relax.com > relax.log') rout = GaussianOutput('relax.log') if not rout.properly_terminated: logging.error( '{} relaxation did not terminate correctly'.format(directory)) return 0 # do the TD-DFT calculation tdin = GaussianInput(rout.final_structure, charge=0, title=rin.title, functional=functional, spin_multiplicity=1, basis_set=basis_set, dieze_tag=dieze_tag, link0_parameters=link0, route_parameters=td_params) td_done = False if os.path.isfile('td.log'): tdout = GaussianOutput('td.log') if tdout.properly_terminated: td_done = True if not td_done: tdin.write_file('td.com', cart_coords=True) os.system('g09 < td.com > td.log') tdout = GaussianOutput('td.log') if not tdout.properly_terminated: logging.error( '{} TD-DFT did not terminate correctly'.format(directory)) return 0 # do the TD-DFT calculation w. Tamm-Dancoff approx tdain = GaussianInput(rout.final_structure, charge=0, title=rin.title, spin_multiplicity=1, functional=functional, basis_set=basis_set, dieze_tag=dieze_tag, link0_parameters=link0, route_parameters=tda_params) tda_done = False if os.path.isfile('tda.log'): tdaout = GaussianOutput('tda.log') if tdaout.properly_terminated: tda_done = True if not tda_done: tdain.write_file('tda.com', cart_coords=True) os.system('g09 < tda.com > tda.log') tdaout = GaussianOutput('tda.log') if not tdaout.properly_terminated: logging.error( '{} TDA-DFT did not terminate correctly'.format(directory)) return 0 # add the dummy atoms for the NICS(1)_zz calculations mol_nics = rout.final_structure mol_nics = add_dummy_atoms(mol_nics, six_mem_a) mol_nics = add_dummy_atoms(mol_nics, six_mem_b) mol_nics = add_dummy_atoms(mol_nics, five_mem_a) mol_nics = add_dummy_atoms(mol_nics, five_mem_b) # run NICS on the ground state and triplet state nicssin = GaussianInput(mol_nics, charge=0, title=rin.title, spin_multiplicity=1, functional=functional, basis_set=basis_set, dieze_tag=dieze_tag, link0_parameters=link0, route_parameters=nmr_params) nicssin.write_file('nics_singlet.com', cart_coords=True) # work around as pymatgen does not allow Bq as an element os.system("sed -i 's/X-Bq0+/Bq/g' nics_singlet.com") os.system('g09 < nics_singlet.com > nics_singlet.log') # can't have NICS job completion check due to above mentioned pmg bug nicstin = GaussianInput(mol_nics, charge=0, title=rin.title, spin_multiplicity=3, functional=functional, basis_set=basis_set, dieze_tag=dieze_tag, link0_parameters=link0, route_parameters=nmr_params) nicstin.write_file('nics_triplet.com', cart_coords=True) os.system("sed -i 's/X-Bq0+/Bq/g' nics_triplet.com") os.system('g09 < nics_triplet.com > nics_triplet.log')