def ts_search(gs_dict): """ Perform ts scan of the bond getting broken""" reactant = gs_dict['reac'] charged = True # hard coded for mogens # find atoms to move during scan. smarts_bond = Chem.MolFromSmarts('[CX4;H0;R]-[CX4;H1;R]') reactant_rdkit_mol = reactant.get_rdkit_mol() atom_idx = reactant_rdkit_mol.GetSubstructMatch(smarts_bond) orca_tsscan = {'method': 'pm3', 'basis': '', 'opt': 'opt', 'geom scan': 'B {} {} = 1.5, 3.5, 12'.format(*atom_idx), 'mem': '8GB', 'cpus': 1} # run ts guess run ts_qmmol = QMMol() name = reactant.label.split('_')[0] + '_ts' ts_qmmol.add_conformer(reactant.write_xyz(to_file=False), fmt='xyz', label=name, charged_fragments=charged, set_initial=True) ts_qmmol.calc = ORCA(parameters=orca_tsscan) ts_conf = ts_qmmol.conformers[0] ts_conf.conf_calculate(quantities=['ts_guess', 'ts_guess_energy']) # update ts_qmmol, hack since i can't set calc on conf. # please fix this. # Run real TS optimization ts_param = {'method': 'pm3', 'basis': '', 'opt': 'ts,calcall,noeigentest', 'freq': 'freq', 'nproc': 1, 'mem': '8GB'} ts_qmmol.calc = Gaussian(parameters=ts_param) ts_conf = ts_qmmol.conformers[0] ts_conf.conf_calculate(quantities=['energy', 'frequencies', 'intensities', 'normal_coordinates', 'structure'], keep_files=True) ts_conf = ts_qmmol.conformers[0] gs_dict['ts'] = ts_conf gs_dict['ts_energy'] = ts_conf.results['energy'] gs_dict['correct_ts'] = ts_test(ts_conf) return gs_dict
def ts_scan(prod, name, chrg, mult, xcontrol_name): """ scan for transition state """ charged = True # hard coded for mogens # create conformers ts_qmmol = QMMol() ts_qmmol.add_conformer(prod.write_xyz(to_file=False), fmt='xyz', label=name, charged_fragments=charged, set_initial=True) xtb_params = { 'method': 'gfn2', 'opt': 'opt', 'cpus': 1, 'input': '../' + str(xcontrol_name) } ts_qmmol.calc = xTB(parameters=xtb_params) ts_conf = ts_qmmol.conformers[0] #ts_conf.conf_calculate(quantities=['energy', 'structure'], keep_files=True) #ts_conf.conf_calculate(quantities=['energy'], keep_files=True) ts_conf.conf_calculate(quantities=['energy', 'ts_guess'], keep_files=True)
def gs_conformer_search(name, rdkit_conf, chrg, mult, cpus): """ ground state conformer search """ charged = True # hard coded for mogens # create conformers qmmol = QMMol() qmmol.add_conformer(rdkit_conf, fmt='rdkit', label=name, charged_fragments=charged, set_initial=True) # find #-- rot bond. mol = qmmol.get_rdkit_mol() triple_smart = '[c]:[c]-[CH0]#[CH0]' extra_rot_bond = int(len(mol.GetSubstructMatches(Chem.MolFromSmarts(triple_smart))) / 2) # print compute number of conformers to find rot_bonds = len(RotatableBonds(qmmol.initial_conformer.get_rdkit_mol())) + extra_rot_bond num_confs = 5 + 5*rot_bonds qmmol.create_random_conformers(threads=cpus, num_confs=num_confs) xtb_params = {'method': 'gfn2', 'opt': 'opt', 'cpus': 1} qmmol.calc = xTB(parameters=xtb_params) qmmol.optimize(num_procs=cpus, keep_files=False) # Get most stable conformer. If most stable conformer # not identical to initial conf try second lowest. initial_smi = Chem.MolToSmiles(Chem.RemoveHs(qmmol.initial_conformer.get_rdkit_mol())) low_energy_conf = qmmol.nlowest(1)[0] conf_smi = Chem.MolToSmiles(Chem.RemoveHs(low_energy_conf.get_rdkit_mol())) i = 1 while initial_smi != conf_smi: low_energy_conf = qmmol.nlowest(i+1)[-1] conf_smi = Chem.MolToSmiles(Chem.RemoveHs(low_energy_conf.get_rdkit_mol())) i += 1 if len(qmmol.conformers) < i: sys.exit('no conformers match the initial input') return low_energy_conf
def gs_conformer_search(name, rdkit_conf, chrg, mult, cpus): """ ground state conformer search """ charged = True # hard coded for mogens # create conformers qmmol = QMMol() qmmol.add_conformer(rdkit_conf, fmt='rdkit', label=name, charged_fragments=charged, set_initial=True) rot_bonds = len(RotatableBonds(qmmol.initial_conformer.get_rdkit_mol())) num_confs = 5 + 5*rot_bonds qmmol.create_random_conformers(threads=cpus, num_confs=num_confs) xtb_params = {'method': 'gfn2', 'opt': 'opt', 'cpus': 1} qmmol.calc = xTB(parameters=xtb_params) qmmol.optimize(num_procs=cpus, keep_files=False) # Get most stable conformer. If most stable conformer # not identical to initial conf try second lowest. initial_smi = Chem.MolToSmiles(Chem.RemoveHs(qmmol.initial_conformer.get_rdkit_mol())) try: low_energy_conf = qmmol.nlowest(1)[0] conf_smi = Chem.MolToSmiles(Chem.RemoveHs(low_energy_conf.get_rdkit_mol())) except: conf_smi = 'wrong' i = 1 while initial_smi != conf_smi: low_energy_conf = qmmol.nlowest(i+1)[-1] conf_smi = Chem.MolToSmiles(Chem.RemoveHs(low_energy_conf.get_rdkit_mol())) i += 1 if len(qmmol.conformers) < i: sys.exit('no conformers match the initial input') return low_energy_conf
def pm3opt(gs_dict): """ Run Gaussian PM3 calculations on low energy xTB structures """ charged = True # hardcoded for this project. xtb_reactant = gs_dict['xtb_reac'] xtb_product = gs_dict['xtb_prod'] pm3_param = {'method': 'pm6', 'basis': '', 'opt': 'opt', 'nproc': 1, 'mem': '4GB'} for reac_prod, conf in [('reac', xtb_reactant), ('prod', xtb_product)]: qmmol = QMMol() name = conf.label qmmol.add_conformer(conf.write_xyz(to_file=False), fmt='xyz', label=name, charged_fragments=charged, set_initial=True) qmmol.calc = Gaussian(parameters=pm3_param) qmconf = qmmol.conformers[0] qmconf.conf_calculate(quantities=['energy', 'structure'], keep_files=False) qmconf = qmmol.conformers[0] if reac_prod == 'reac': reac_conf = qmconf reac_energy = qmconf.results['energy'] if reac_prod == 'prod': prod_conf = qmconf prod_energy = qmconf.results['energy'] gs_dict['pm3_reac'] = reac_conf gs_dict['pm3_prod'] = prod_conf gs_dict['pm3_storage'] = (prod_energy - reac_energy) * 627.503 return gs_dict