def test_scan(self): gau = GaussianOutput(os.path.join(test_dir, "so2_scan.log")) d = gau.read_scan() self.assertAlmostEqual(-548.02102, d["energies"][-1]) self.assertEqual(len(d["coords"]), 1) self.assertEqual(len(d["energies"]), len(gau.energies)) self.assertEqual(len(d["energies"]), 21)
def test_multiple_parameters(self): """ This test makes sure that input files with multi-parameter keywords and route cards with multiple lines can be parsed accurately. """ filepath = os.path.join(test_dir, "l-cysteine.out") route = { "test": None, "integral": { "grid": "UltraFine" }, "opt": { "Z-Matrix": None, "maxcycles": "80", "tight": None }, } gout = GaussianOutput(filepath) self.assertEqual(gout.dieze_tag, "#n") self.assertEqual(gout.functional, "B3LYP") self.assertEqual(gout.basis_set, "6-31+G**") self.assertEqual(gout.route_parameters, route) self.assertEqual(gout.title, "L-cysteine neutral") self.assertEqual(gout.charge, 0) self.assertEqual(gout.spin_multiplicity, 1)
def FindTorsionEnergies(rotdihed_dir, out_dir): """ Iterates through rotdihed_dir and finds energies for each torsion angle for the molecule. It then creates a energy cvs file for the molecule. """ mols = [m for m in os.listdir(rotdihed_dir) if os.path.isdir(os.path.join(rotdihed_dir,m))] for m in mols: mol_name = m.split('.')[0] mpath = os.path.join(rotdihed_dir,m) log_file = [x for x in os.listdir(mpath) if x.endswith('.log')][0] log_path = os.path.join(mpath,log_file) mol = GaussianOutput(log_path) if mol.properly_terminated: normal = 0 with open(log_path) as fn: log = fn.readlines() for line in log: if re.search(' Optimized Parameters',line): normal = 1 break else: continue if normal == 0: print("Error. {} job had a normal termination but did not have optimized parameters.".format(mol_name)) else: normal = 0 print("Error. {} job did not have a normal termination.".format(mol_name)) if normal == 1: energy = mol.final_energy with open('{}/energies.cvs'.format(out_dir),'a') as fout: fout.write(mol_name + ',' + str(energy) + '\n') print("Dihedral rotations energies collected for {}!".format(mol_name))
def assimilate(self, path): """ Assimilate data in a directory path into a ComputedEntry object. Args: path: directory path Returns: ComputedEntry """ try: gaurun = GaussianOutput(path) except Exception as ex: logger.debug("error in {}: {}".format(path, ex)) return None param = {} for p in self._parameters: param[p] = getattr(gaurun, p) data = {} for d in self._data: data[d] = getattr(gaurun, d) if self._inc_structure: entry = ComputedStructureEntry(gaurun.final_structure, gaurun.final_energy, parameters=param, data=data) else: entry = ComputedEntry( gaurun.final_structure.composition, gaurun.final_energy, parameters=param, data=data, ) return entry
def mol_object(log_fn): """ Get pymatgen object in preparation for further processing Returns: A pymatgen object """ try: return GaussianOutput(log_fn) except FileNotFoundError: print("File does not exist: {}".format(log_fn))
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 test_pop(self): gau = GaussianOutput(os.path.join(test_dir, "H2O_gau.out")) self.assertEqual(gau.num_basis_func, 13) self.assertEqual(gau.electrons, (5, 5)) self.assertEqual(gau.is_spin, True) self.assertListEqual(gau.eigenvalues[Spin.down], [-20.55343, -1.35264, -0.72655, -0.54824, -0.49831, 0.20705, 0.30297, 1.10569, 1.16144, 1.16717, 1.20460, 1.38903, 1.67608]) mo = gau.molecular_orbital self.assertEqual(len(mo), 2) # la 6 self.assertEqual(len(mo[Spin.down]), 13) self.assertEqual(len(mo[Spin.down][0]), 3) self.assertEqual(mo[Spin.down][5][0]["1S"], -0.08771) self.assertEqual(mo[Spin.down][5][0]["2PZ"], -0.21625) self.assertListEqual(gau.eigenvectors[Spin.up][:, 5].tolist(), [-0.08771, 0.10840, 0.00000, 0.00000, -0.21625, 1.21165, 0.00000, 0.00000, -0.44481, -0.06348, -1.00532, -0.06348, -1.00532]) self.assertListEqual(gau.atom_basis_labels[0], ["1S", "2S", "2PX", "2PY", "2PZ", "3S", "3PX", "3PY", "3PZ"]) self.assertListEqual(gau.atom_basis_labels[2], ["1S", "2S"]) gau = GaussianOutput(os.path.join(test_dir, "H2O_gau_vib.out")) self.assertEqual(gau.bond_orders[(0, 1)], 0.7582) self.assertEqual(gau.bond_orders[(1, 2)], 0.0002)
def MakeJSON(mol_dir,omega_file,json_file): """ For a molecule rotation directory, mol_dir, this finds the energy, xyz, and degree of rotation and places those into json_file. """ mol_name = str(mol_dir.split('/')[-1]) energy = 0 mol_xyz = 0 try: # if 0 == 0: log_fn = [x for x in os.listdir(mol_dir) if x.endswith('opt_0.log')][0] log_path = os.path.join(mol_dir,log_fn) mol = GaussianOutput(log_path) if mol.properly_terminated: num_electrons = mol.electrons[0] eigens = list(mol.eigenvalues.values())[0] h**o = eigens[num_electrons - 1] * 27.2114 lumo = eigens[num_electrons] * 27.2114 homo_lumo_gap = lumo - h**o pymat_mol = Molecule.from_file(log_path) smi_mol = pmgmol_to_rdmol(pymat_mol)[1] with open(omega_file,'r') as fn: omega_data = fn.readlines()[-2].split()[1] omega = "0{}".format(omega_data.split('.')[1]) normal = 1 else: normal = 0 print("Error. wtuning for did not properly terminate for {}".format(mol_name)) except Exception as e: normal = 0 print("Error. Data NOT collected for {}. Energy calculations for dihedral rotations may not have finished!".format(mol_name)) print(e) if normal == 1: json_data = { "molecule_name" : mol_name, "smiles" : smi_mol, "tuned_omega" : omega, "h**o" : h**o, "lumo" : lumo, "homo_lumo_gap" : homo_lumo_gap } with open(json_file,'w+') as fn: json.dump(json_data, fn) print("Data collected for {}".format(mol_name)) else: pass try: json_file.close() omega_file.close() except: pass
def test_geo_opt(self): """ Test an optimization where no "input orientation" is outputted """ gau = GaussianOutput( os.path.join(test_dir, "acene-n_gaussian09_opt.out")) self.assertAlmostEqual(-1812.58399675, gau.energies[-1]) self.assertEqual(len(gau.structures), 6) # Test the first 3 atom coordinates coords = [[-13.642932, 0.715060, 0.000444], [-13.642932, -0.715060, 0.000444], [-12.444202, 1.416837, 0.000325]] self.assertAlmostEqual(gau.opt_structures[-1].cart_coords[:3].tolist(), coords)
def get_run_folders(molecule_dir, out_dir, nflag=''): mol_name = molecule_dir.split('/')[-1].split('.')[0] opt_log = os.path.join(molecule_dir, 'opt.log') opt_gjf = os.path.join(molecule_dir, 'opt.gjf') freq_gjf = os.path.join(molecule_dir, 'freq.gjf') tddft_gjf = os.path.join(molecule_dir, 'tddft.gjf') tddft_log = os.path.join(molecule_dir, 'tddft.log') if os.path.isfile(tddft_gjf): mol_tddft = GaussianOutput(tddft_log) if mol_tddft.properly_terminated: print("{} TD-DFT terminated normally".format(mol_name)) else: txt_file = os.path.join(out_dir, 'folders_to_run_tddft.txt') with open(txt_file, 'a+') as fn: fn.write(molecule_dir + '\n') return None normal = None if os.path.isfile(opt_log): with open(opt_log) as fn: log_fn = fn.readlines() for line in log_fn: if re.search(' Optimized Parameters', line): last_line = log_fn[-1] if re.search('Normal termination', last_line): if os.path.isfile(freq_gjf): txt_file = os.path.join(out_dir, 'folders_to_run_freq.txt') with open(txt_file, 'a+') as fn: fn.write(molecule_dir + '\n') else: print( "{} is finished optimizing, but there is not freq.gjf file." .format(mol_name)) return None if re.search('Error termination', line): normal = 0 txt_file = os.path.join(out_dir, 'folders_to_run{}.txt'.format(nflag)) with open(txt_file, 'a+') as fn: fn.write(molecule_dir + '\n') print("Error in termination for {}".format(mol_name)) return None else: print("{} does not have an opt.log file.") if os.path.isfile(opt_gjf): print("{} may still be running".format(mol_name)) else: print("Error. {} does not contain a gjf file.".format(mol_name))
def make_json(mol_dir, dihed_atoms_file, json_file): """ For a molecule rotation directory, mol_dir, this finds the energy, xyz, and degree of rotation and places those into json_file. """ mol_name = str(mol_dir.split('/')[-1]) try: log_fn = [x for x in os.listdir(dpath) if x.endswith('deg.log')][0] log_path = os.path.join(dpath, log_fn) except IndexError: print("Error. No log file for {} at {} degrees.".format( mol_name, degree)) return None if check_normal_optimization(log_path): mol = GaussianOutput(log_path) num_electrons = mol.electrons[0] eigens = list(mol.eigenvalues.values())[0] h**o = eigens[num_electrons - 1] * 27.2114 lumo = eigens[num_electrons] * 27.2114 homo_lumo_gap = lumo - h**o energy = mol.final_energy * 27.2114 imol = IMolecule.from_file(log_path) with open(dihed_atoms_file, 'r') as lines: data = lines.readlines() dihedral1 = data[0].split(',')[0] d1atom1_num = int(dihedral1.split()[0]) d1atom2_num = int(dihedral1.split()[1]) d1atom3_num = int(dihedral1.split()[2]) d1atom4_num = int(dihedral1.split()[3]) di_angle = imol.get_dihedral(d1atom1_num, d1atom2_num, d1atom3_num, d1atom4_num) json_data = { "molecule_name": mol_name, "dihedral_angle": di_angle, "energy": energy, "h**o": h**o, "lumo": lumo, "homo_lumo_gap": homo_lumo_gap } write_json(json_data, json_file) print("Data collected for {}".format(mol_name)) else: normal = 0 print("Error. GeomOpt calculation did not properly terminate for {}". format(mol_name))
def make_json(mol_dir, mol_name, json_file): """ For a molecule directory, mol_dir, this finds the energy, xyz, charge, h**o, lumo, homo_lumo_gap, and runtime and places those into json_file. """ # Gather info from log file in mol_dir try: log_fn = [x for x in os.listdir(mol_dir) if x.endswith('.log')][0] log_path = os.path.join(mol_dir, log_fn) mol = GaussianOutput(log_path) if mol.properly_terminated: structure = mol.final_structure xyz = structure.to(fmt="xyz") charge = mol.charge energy = mol.final_energy * 27.2114 num_electrons = mol.electrons[0] eigens = list(mol.eigenvalues.values())[0] h**o = eigens[num_electrons - 1] * 27.2114 lumo = eigens[num_electrons] * 27.2114 homo_lumo_gap = lumo - h**o runtime = runtime_from_log(log_path) normal = 1 else: normal = 0 print("Error. Calculation did not properly terminate for {}".format(mol_name)) except: normal = 0 print("Error. Data NOT collected for {}. Energy calculations may not have finished!".format(mol_name)) # write json file if data was correctly gathered if normal == 1: json_data = { "molecule_name": mol_name, "charge": charge, "structure": xyz, "energy": energy, "h**o": h**o, "lumo": lumo, "homo_lumo_gap": homo_lumo_gap, "runtime": runtime } write_json(json_data, json_file) print("Data collected for {}".format(mol_name))
def read_mol(filename): """ Reads a molecule 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), Gaussian output (.out|and pymatgen's JSON serialized molecules. Using openbabel, many more extensions are supported but requires openbabel to be installed. Args: filename (str): A filename to read from. Returns: A Molecule object. """ fname = os.path.basename(filename) if fnmatch(fname.lower(), "*.xyz*"): return XYZ.from_file(filename).molecule elif any([ fnmatch(fname.lower(), "*.{}*".format(r)) for r in ["gjf", "g03", "g09", "com", "inp"] ]): return GaussianInput.from_file(filename).molecule elif any([ fnmatch(fname.lower(), "*.{}*".format(r)) for r in ["out", "lis", "log"] ]): return GaussianOutput(filename).final_structure elif fnmatch(fname, "*.json*") or fnmatch(fname, "*.mson*"): with zopen(filename) as f: s = json.load(f, cls=MontyDecoder) if type(s) != Molecule: raise IOError("File does not contain a valid serialized " "molecule") return s else: m = re.search("\.(pdb|mol|mdl|sdf|sd|ml2|sy2|mol2|cml|mrv)", filename.lower()) if m: return BabelMolAdaptor.from_file(filename, m.group(1)).pymatgen_mol raise ValueError("Unrecognized file extension!")
def setUp(self): self.gauout = GaussianOutput(os.path.join(test_dir, "methane.log"))
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')
def make_json(mol_dir, json_file, omega_file=None): """ For a molecule directory, mol_dir, this finds the molecule_name, smiles, and tuned omega for the polymer. It then finds the optimized structures, energies, homos, lumos, and runtimes for each degree of rotation and places those into a json_file. """ mol_name = mol_dir.split('/')[-1] xyz_dict, energy_dict, homo_dict, lumo_dict, runtime_dict = {}, {}, {}, {}, {} mol_smiles, omega = None, None if os.path.isfile(omega_file): with open(omega_file, 'r') as fn: try: omega_data = fn.readlines()[-1].split()[1] omega = "0{}".format(omega_data.split('.')[1]) except IndexError: print('Error. wtuning for {} may not have finished'.format( mol_name)) return None deg_folders = [ deg for deg in os.listdir(mol_dir) if os.path.isdir(os.path.join(mol_dir, deg)) ] for deg in deg_folders: dpath = os.path.join(mol_dir, deg) if os.path.isdir(dpath): degree = str((deg.split('_')[-1])[:-3]) try: log_fn = [ x for x in os.listdir(dpath) if x.endswith('deg.log') ][0] log_path = os.path.join(dpath, log_fn) except IndexError: print("Error. No log file for {} at {} degrees.".format( mol_name, degree)) continue if check_normal_optimization(log_path): runtime = runtime_from_log(log_path) mol = IMolecule.from_file(log_path) mol_xyz = mol.to(fmt="xyz") out_mol = GaussianOutput(log_path) num_electrons = out_mol.electrons[0] eigens = list(out_mol.eigenvalues.values())[0] h**o = eigens[num_electrons - 1] * 27.2114 lumo = eigens[num_electrons] * 27.2114 energy = out_mol.final_energy * 27.2114 if mol_smiles is None: mol_smiles = pmgmol_to_rdmol(mol)[1] else: print( "Error. Optimization did not properly terminate for {} at {} degrees." .format(mol_name, degree)) continue xyz_dict[degree] = mol_xyz energy_dict[degree] = energy homo_dict[degree] = h**o lumo_dict[degree] = lumo runtime_dict[degree] = runtime json_data = { # Polymer data "molecule_name": mol_name, "smiles": mol_smiles, "tuned_omega": omega, # Rotation dictionaries "structures": xyz_dict, "energies": energy_dict, "homos": homo_dict, "lumos": lumo_dict, "runtimes": runtime_dict } write_json(json_data, json_file) print("Data collected for {}".format(mol_name))
def test_td(self): gau = GaussianOutput(os.path.join(test_dir, "so2_td.log")) transitions = gau.read_excitation_energies() self.assertEqual(len(transitions), 4) self.assertAlmostEqual(transitions[0], (3.9281, 315.64, 0.0054))
def extract_abs(fn): return GaussianOutput(fn).read_excitation_energies()
def extract_energy(fn): return GaussianOutput(fn).final_energy
def extract_data_from_tar_file(tar_file): with tarfile.open(tar_file, 'r:gz') as tar: tar.extractall() folder = tar_file.replace('.tar.gz', '') with cd(folder): tdout = GaussianOutput('td.log') td_exit = tdout.read_excitation_energies() td_triplet = [e for e in td_exit if 'triplet' in e[3].lower()][0][0] td_singlet = [e for e in td_exit if 'singlet' in e[3].lower()][0][0] tdaout = GaussianOutput('tda.log') tda_exit = tdaout.read_excitation_energies() tda_triplet = [e for e in tda_exit if 'triplet' in e[3].lower()][0][0] tda_singlet = [e for e in tda_exit if 'singlet' in e[3].lower()][0][0] nicssout = GaussianOutput('nics_singlet.log') # occasionally some jobs fail here if not nicssout.properly_terminated: return False nicss_mag = nicssout.read_magnetic_shielding() nicss_six_ring_above = (abs(nicss_mag[-8]['isotropic']) + abs(nicss_mag[-6]['isotropic']))/2 nicss_six_ring_below = (abs(nicss_mag[-7]['isotropic']) + abs(nicss_mag[-5]['isotropic']))/2 nicss_five_ring_above = (abs(nicss_mag[-4]['isotropic']) + abs(nicss_mag[-2]['isotropic']))/2 nicss_five_ring_below = (abs(nicss_mag[-3]['isotropic']) + abs(nicss_mag[-1]['isotropic']))/2 nicstout = GaussianOutput('nics_triplet.log') if not nicstout.properly_terminated: return False nicst_mag = nicstout.read_magnetic_shielding() nicst_six_ring_above = (abs(nicst_mag[-8]['isotropic']) + abs(nicst_mag[-6]['isotropic']))/2 nicst_six_ring_below = (abs(nicst_mag[-7]['isotropic']) + abs(nicst_mag[-5]['isotropic']))/2 nicst_five_ring_above = (abs(nicst_mag[-4]['isotropic']) + abs(nicst_mag[-2]['isotropic']))/2 nicst_five_ring_below = (abs(nicst_mag[-3]['isotropic']) + abs(nicst_mag[-1]['isotropic']))/2 data = {'td_singlet': td_singlet, 'td_triplet': td_triplet, 'tda_singlet': tda_singlet, 'tda_triplet': tda_triplet, 'nicss_six_ring_above': nicss_six_ring_above, 'nicss_six_ring_below': nicss_six_ring_below, 'nicss_five_ring_above': nicss_five_ring_above, 'nicss_five_ring_below': nicss_five_ring_below, 'nicst_six_ring_above': nicst_six_ring_above, 'nicst_six_ring_below': nicst_six_ring_below, 'nicst_five_ring_above': nicst_five_ring_above, 'nicst_five_ring_below': nicst_five_ring_below} return data
name = names_dict.get(mol) if not name: continue print(mol, name) mol_name_path = os.path.join(name_path, name) if not os.path.isdir(mol_name_path): os.mkdir(mol_name_path) gas_opt_dir = os.path.join(mol_path, 'computation', 'gaussian') if os.path.isdir(gas_opt_dir): for zip_file in [ f for f in os.listdir(gas_opt_dir) if f.endswith('.zip') and 'freq' not in f ]: zip_path = os.path.join(gas_opt_dir, zip_file) with ZipFile(zip_path, "r") as target_zip: target_zip.extractall(mol_name_path) log_file = os.path.join(mol_name_path, 'opt_groundState.log') if os.path.isfile(log_file): pmg_mol = GaussianOutput(log_file) num_electrons = pmg_mol.electrons[0] eigens = list(pmg_mol.eigenvalues.values())[0] h**o = eigens[num_electrons - 1] * 27.2114 lumo = eigens[num_electrons] * 27.2114 energy = min(pmg_mol.energies) * 27.2114 master_dict["h**o"][name] = round(h**o, 3) master_dict["lumo"][name] = round(lumo, 3) master_dict["energy"][name] = round(energy, 3) with open("individual_rings_data.json", 'w') as fn: json.dump(master_dict, fn, indent=2)
def test_props(self): gau = self.gauout self.assertEqual(len(gau.energies), 3) self.assertAlmostEqual(gau.energies[-1], -39.9768775602) self.assertEqual(len(gau.structures), 4) for mol in gau.structures: self.assertEqual(mol.formula, "H4 C1") self.assertIn("opt", gau.route_parameters) self.assertEqual("Minimum", gau.stationary_type) self.assertEqual("hf", gau.functional) self.assertEqual("3-21G", gau.basis_set) self.assertEqual(17, gau.num_basis_func) d = gau.as_dict() self.assertEqual(d["input"]["functional"], "hf") self.assertAlmostEqual(d["output"]["final_energy"], -39.9768775602) self.assertEqual(len(gau.cart_forces), 3) self.assertEqual(gau.cart_forces[0][5], 0.009791094) self.assertEqual(gau.cart_forces[0][-1], -0.003263698) self.assertEqual(gau.cart_forces[2][-1], -0.000000032) self.assertEqual(gau.eigenvalues[Spin.up][-1], 1.95586) self.assertEqual(gau.num_basis_func, 17) self.assertEqual(gau.is_spin, False) ch2o_co2 = GaussianOutput(os.path.join(test_dir, "CH2O_CO2.log")) self.assertEqual(len(ch2o_co2.frequencies), 2) self.assertEqual(len(ch2o_co2.frequencies[0]), 6) self.assertEqual(len(ch2o_co2.frequencies[1]), 4) self.assertEqual(ch2o_co2.frequencies[0][0]["frequency"], 1203.1940) self.assertEqual(ch2o_co2.frequencies[0][0]["symmetry"], 'A"') self.assertEqual(ch2o_co2.frequencies[0][3]["IR_intensity"], 60.9575) self.assertEqual(ch2o_co2.frequencies[0][3]["r_mass"], 3.7543) self.assertEqual(ch2o_co2.frequencies[0][4]["f_constant"], 5.4175) self.assertListEqual( ch2o_co2.frequencies[0][1]["mode"], [ 0.15, 0.00, 0.00, -0.26, 0.65, 0.00, -0.26, -0.65, 0.00, -0.08, 0.00, 0.00, ], ) self.assertListEqual( ch2o_co2.frequencies[1][3]["mode"], [0.00, 0.00, 0.88, 0.00, 0.00, -0.33, 0.00, 0.00, -0.33], ) self.assertEqual(ch2o_co2.frequencies[1][3]["symmetry"], "SGU") self.assertEqual(ch2o_co2.eigenvalues[Spin.up][3], -1.18394) h2o = GaussianOutput(os.path.join(test_dir, "H2O_gau_vib.out")) self.assertEqual(len(h2o.frequencies[0]), 3) self.assertEqual(h2o.frequencies[0][0]["frequency"], 1662.8033) self.assertEqual(h2o.frequencies[0][1]["symmetry"], "A'") self.assertEqual(h2o.hessian[0, 0], 0.356872) self.assertEqual(h2o.hessian.shape, (9, 9)) self.assertEqual( h2o.hessian[8, :].tolist(), [ -0.143692e-01, 0.780136e-01, -0.362637e-01, -0.176193e-01, 0.277304e-01, -0.583237e-02, 0.319885e-01, -0.105744e00, 0.420960e-01, ], )
def MakeJSON(mol_dir, json_file, master_json_file): """ For a molecule rotation directory, mol_dir, this finds the energy, xyz, and degree of rotation and places those into json_file. """ mol_name = str(mol_dir.split('/')[-1]) try: log_fn = [x for x in os.listdir(mol_dir) if x.endswith('.log')][0] log_path = os.path.join(mol_dir, log_fn) mol = GaussianOutput(log_path) if mol.properly_terminated: num_electrons = mol.electrons[0] eigens = list(mol.eigenvalues.values())[0] h**o = eigens[num_electrons - 1] * 27.2114 lumo = eigens[num_electrons] * 27.2114 homo_lumo_gap = lumo - h**o energy = mol.final_energy * 27.2114 structure = mol.final_structure mol_xyz = structure.to(fmt="xyz") runtime = runtime_from_log(log_path) functional = mol.functional basis_set = mol.basis_set normal = 1 else: normal = 0 print( "Error. Calculation did not properly terminate for {}".format( mol_name)) print(mol_dir) except: normal = 0 print( "Error. Data NOT collected for {}. Energy calculations may not have finished!" .format(mol_name)) print(mol_dir) try: catpath = os.path.join(mol_dir, 'cation/') log_fn = [x for x in os.listdir(catpath) if x.endswith('.log')][0] log_path = os.path.join(catpath, log_fn) cat = GaussianOutput(log_path) if cat.properly_terminated: cat_energy = cat.final_energy * 27.2114 cnormal = 1 else: cnormal = 0 print( "Error. Calculation did not properly terminate for {} cation with {} and {}" .format(mol_name, functional, basis_set)) print(mol_dir) except: cnormal = 0 print( "Error. Data NOT collected for {} cation. Energy calculations for cation may not have finished!" .format(mol_name)) print(mol_dir) if normal == 1 and cnormal == 1: json_data = { "molecule_name": mol_name, "energy": energy, "cation_energy": cat_energy, "runtime": runtime, "functional": functional, "basis_set": basis_set, "h**o": h**o, "lumo": lumo, "structure": mol_xyz, "homo_lumo_gap": homo_lumo_gap } write_json(json_data, json_file) print("Data collected for {} with {} and {}".format( mol_name, functional, basis_set))