def test_from_file(self): filepath = os.path.join(test_dir, 'MethylPyrrolidine_drawn.gjf') gau = GaussianInput.from_file(filepath) self.assertEqual(gau.molecule.composition.formula, "H11 C5 N1") self.assertIn("opt", gau.route_parameters) self.assertEqual(gau.route_parameters["geom"], "connectivity") self.assertEqual(gau.functional, "b3lyp") self.assertEqual(gau.basis_set, "6-311+g(d,p)") filepath = os.path.join(test_dir, "g305_hb.txt") with open(filepath) as f: txt = f.read() toks = txt.split("--link1--") for i, t in enumerate(toks): lines = t.strip().split("\n") lines = [l.strip() for l in lines] gau = GaussianInput.from_string("\n".join(lines)) self.assertIsNotNone(gau.molecule) if i == 0: mol = gau.molecule ans = """Full Formula (H4 O2) Reduced Formula: H2O Charge = 0, Spin Mult = 1 Sites (6) 0 O 0.000000 0.000000 0.000000 1 O 0.000000 0.000000 2.912902 2 H 0.892596 0.000000 -0.373266 3 H 0.143970 0.000219 0.964351 4 H -0.582554 0.765401 3.042783 5 H -0.580711 -0.766761 3.043012""" self.assertEqual(str(mol), ans)
def test_from_string(self): gau_str = """%mem=5000000 %chk=filename # mp2/6-31g* scf=direct SIH4+ H2---SIH2+ CS //MP2(full)/6-31G* MP2=-290.9225259 1,2 Si X,1,1. H,1,R1,2,HALF1 H,1,R1,2,HALF1,3,180.,0 X,1,1.,2,90.,3,90.,0 X,1,1.,5,THETA,2,180.,0 H,1,R3,6,HALF3,5,0.,0 H,1,R4,6,HALF3,7,180.,0 R1=1.47014 R3=1.890457 R4=1.83514 HALF1=60.633314 THETA=10.35464 HALF3=11.861807""" gau = GaussianInput.from_string(gau_str) self.assertEqual("X3SiH4", gau.molecule.composition.reduced_formula)
def test_str_and_from_string(self): ans = """#P HF/6-31G(d) SCF=Tight SP H4 C1 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 EPS=12 """ self.assertEqual(str(self.gau), ans) gau = GaussianInput.from_string(ans) self.assertEqual(gau.functional, 'HF') self.assertEqual(gau.input_parameters['EPS'], '12')
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 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 test_str_and_from_string(self): ans = """#P HF/6-31G(d) SCF=Tight SP H4 C1 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 EPS=12 """ self.assertEqual(str(self.gau), ans) gau = GaussianInput.from_string(ans) self.assertEqual(gau.functional, "HF") self.assertEqual(gau.input_parameters["EPS"], "12")
def test_multiple_paramaters(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.inp") route = { "test": None, "integral": { "grid": "UltraFine" }, "opt": { "Z-Matrix": None, "maxcycles": "80", "tight": None }, } gin = GaussianInput.from_file(filepath) self.assertEqual(gin.dieze_tag, "#n") self.assertEqual(gin.functional, "B3LYP") self.assertEqual(gin.basis_set, "6-31+G**") self.assertEqual(gin.route_parameters, route) self.assertEqual(gin.title, "L-cysteine neutral") self.assertEqual(gin.charge, 0) self.assertEqual(gin.spin_multiplicity, 1)
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 parse_file(filename): with open(filename) as f: txt = f.read() toks = txt.split("--link1--") for t in toks: try: lines = t.strip().split("\n") lines = [l.strip() for l in lines] gau = GaussianInput.from_string("\n".join(lines)) yield (gau.molecule, gau.charge, gau.spin_multiplicity) except: print("error in {}".format(t))
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 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_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 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) link0_parameters = { '%mem': '5GB', '%chk': '{}.chk'.format(calculation) } route_parameters = { calculation: '', 'SCF': '(MaxCycle=250)', 'Int': '(Grid=SuperFine)' } 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 test_multiple_paramaters(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.inp") route = {"test": None, "integral": {"grid": "UltraFine"}, "opt": {"Z-Matrix": None, "maxcycles": "80", "tight": None}} gin = GaussianInput.from_file(filepath) self.assertEqual(gin.dieze_tag, "#n") self.assertEqual(gin.functional, "B3LYP") self.assertEqual(gin.basis_set, "6-31+G**") self.assertEqual(gin.route_parameters, route) self.assertEqual(gin.title, "L-cysteine neutral") self.assertEqual(gin.charge, 0) self.assertEqual(gin.spin_multiplicity, 1)
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!")
'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 data_to_write = [] db = TinyDB(os.path.join('..', 'data', 'structures.json')) systems = list(db.all()) done = 0 for i, system in enumerate(systems): input_file = GaussianInput.from_dict(system['input']) directory = input_file.title tar_name = '{}.tar.gz'.format(directory) tar_file = os.path.abspath(os.path.join('..', 'data', 'calculations', tar_name)) if os.path.isfile(tar_file): # extract the data in a temp directory to avoid clobbering any data with tempdir() as tmp_dir: shutil.copy(tar_file, tmp_dir) data = extract_data_from_tar_file(tar_name) if not data: print('{} did not finish correctly, skipping'.format(directory)) continue data.update({'x_sub': system['x_sub'], 'y_sub': system['y_sub'], 'z_sub': system['z_sub'], 'nx': system['nx'], 'ny': system['ny'], 'title': system['title']}) data_to_write.append(data)
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')
tda_params = {'integral': '(acc2e=12)', 'tda': '(50-50)', 'guess': 'read'} nmr_params = {'integral': '(acc2e=12)', 'guess': 'read', 'nmr': ''} # define the rings used to calculate NICS six_mem_a = [0, 1, 2, 3, 4, 5] six_mem_b = [1, 2, 6, 7, 8, 9] five_mem_a = [0, 1, 9, 13, 12] five_mem_b = [2, 3, 10, 11, 6] index = int(sys.argv[1]) # use absolute path so we don't loose track of the db when changing directory db = TinyDB(os.path.abspath('structures.json')) query = Query() compound = db.get(query.index == index) rin = GaussianInput.from_dict(compound['input']) directory = rin.title 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)'
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
'title': ginp.title, 'index': index}) ############################################ # generate substituted pyridine structures # ############################################ # need to consider that nx positions 2 and 3 are incompatible # with substitutional sites z and y, respectively and ny # position 3 is incompatible with substitional site x # # the other important note is that we need to substitute the atoms from the # highest site_id downwards, otherwise the order and index of the atoms will # change gin = GaussianInput.from_file(os.path.join('..', 'templates', 'input-template.com')) gin.route_parameters['integral'] = '(acc2e=12)' # hack to get round pmg bug print "generating pyridine substituted structures..." for nx, ny, x_sub, y_sub, z_sub in itertools.product(nx_sites, ny_sites, subs, subs, subs): mol = copy.deepcopy(gin) # if there are any clashes then skip the structure if ((x_sub[0] and ny[0] == 3) or (y_sub[0] and nx[0] == 3) or (z_sub[0] and nx[0] == 2)): continue # make a list of the substitutions and sort from highest to lowest site_id # this list includes the H atoms next to the N we introduce in to the rings sub_list = []
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] molecule = pmgmol_to_rdmol(Molecule.from_file(mol_file))[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) file_name = "{}/{}_{:.0f}deg".format(dir_name, molecule_name, P) os.mkdir(dir_name) SetDihedralDeg(molecule.GetConformer(), d1atom1_num, d1atom2_num, d1atom3_num, d1atom4_num, P) print( sys.getsizeof( SetDihedralDeg(molecule.GetConformer(), d1atom1_num, d1atom2_num, d1atom3_num, d1atom4_num, P))) with open(dir_name + "temp.xyz", 'w+') as fn: fn.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('{}.chk'.format( file_name.split('/')[-1])) }) gjf_file = gau.write_file(dir_name + 'temp.gjf') (dir_name + 'temp.gjf').close() 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))