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 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 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))
from ocelot.schema.conformer import Molecule from ocelot.routines.conformerparser import pmgmol_to_rdmol from ocelot.schema.rdfunc import RdFunc # rdkit is quite tricky in handling nitro groups # see https://github.com/rdkit/rdkit/issues/1979 # and http://www.rdkit.org/docs/RDKit_Book.html#molecular-sanitization m = Molecule.from_file('m.xyz') rm, smiles = pmgmol_to_rdmol(m) RdFunc.draw_mol(rm, 'm.ps') print(rm)