def xyz_to_mol(xyz): if isinstance(xyz, dict): string = xyz_to_xyz_file_format(xyz) elif isinstance(xyz, str): if not xyz[0].isdigit(): atom_num = len(xyz.splitlines()) string = f'{atom_num}\n\n' + xyz else: string = xyz elif os.path.isfile(xyz): string = xyz_to_xyz_file_format(parse_xyz_from_file(xyz)) else: raise ValueError(f'Invalid xyz input, got: {xyz}') molecule = pybel.readstring('xyz', string) mol = Molecule() from_ob_mol(mol, molecule.OBMol) return mol
def check_scan_quality(spc): """ A helper function used to get the status of rotor scans """ for rotor in spc['rotors_dict'].values(): path = rotor['scan_path'] if path: scan_args = parse_scan_args(path) energies, _ = parse_1d_scan_energies(path) invalid, reason, _, actions = scan_quality_check( spc['label'], pivots=rotor['scan'][1:-1], energies=energies, scan_res=scan_args['step_size'], log_file=path) else: rotor['success'] = False rotor['invalidation_reason'] = 'Unknown' continue if not invalid: rotor['success'] = True rotor['symmetry'] = determine_rotor_symmetry( label=spc['label'], pivots=rotor['scan'][1:3], energies=energies)[0] continue if 'change conformer' in actions: print(spc['label'] + ': has a bad conformer orientation according to ' + str(rotor['scan'])) xyz = xyz_to_xyz_file_format(actions['change conformer']) return {'label': spc['label'], 'change conformer': xyz} if 'barrier' in reason: rotor['success'] = False rotor['invalidation_reason'] = reason continue # Otherwise need to come up with troubleshooting methods species_scan_lists = [rotor['scan']] scan_trsh, scan_res = trsh_scan_job(spc['label'], scan_args['step_size'], rotor['scan'], species_scan_lists, actions, path) rotor['trsh_methods'] = [{ 'scan_trsh': scan_trsh, 'scan_res': scan_res }] rotor['archived'].append(rotor['scan_path']) spc['scan'].remove(rotor['scan_path']) return spc
def composite_modify_coords( scan_res: int, arc_zmat: Dict, pivots: Tuple[Tuple[int], Tuple[int]], arc_spc: ARCSpecies, ) -> dict: """ Modify the coordinates two times. Args: scan_res: Number of sampling points for each 1d rotor. arc_zmat: ARC's Z-matrix dictionary. pivots: Atom number representing pivots in the molecule. arc_spc: ARC species. Returns: A dictionary with keys represent dihedral combination and values represent xyz. """ scan_deg = 360 / scan_res xyz_new_dict = dict() for i in range(scan_res): zmat_1 = modify_coords( coords=arc_zmat, indices=pivots[0], new_value=i * scan_deg, modification_type='groups', mol=arc_spc.mol, index=1, output_zmat=True, ) for j in range(scan_res): zmat_2 = modify_coords( coords=zmat_1, indices=pivots[1], new_value=j * scan_deg, modification_type='groups', mol=arc_spc.mol, index=1, output_zmat=True, ) xyz_new_dict[(i, j)] = xyz_to_xyz_file_format(zmat_to_xyz(zmat_2)) return xyz_new_dict
def xyz_to_xyz_file(spc, filename='xyz.txt'): xyz = spc['geom'] with open(os.path.join(spc['directory'], filename), 'w') as f: f.write(xyz_to_xyz_file_format(xyz))
def write_gaussian_input_file(): script = """%chk={name}.chk %mem=300000mb %NProcShared=40 #p opt=(calcfc,noeigentest,maxcycles=120) freq guess=mix uwb97xd def2svp iop(2/9=2000) scf=xqc {name} 0 2 {xyz} """ all_xyz_dict = dict() fingerprint = 0 scan_pts = 45 scan_deg = 360 / scan_pts for grid_search_file_name in os.listdir(psi4_scan_dir): indices_1 = tuple([ int(x) for x in re.search( '_oo_(.*)_n_', grid_search_file_name).group(1).split('_') if x.isnumeric() ]) indices_2 = tuple([ int(x) for x in re.search( '_n_(.*)_coord', grid_search_file_name).group(1).split('_') if x.isnumeric() ]) print('----------------------------') print( f'Considering dihedral combinations: {indices_1} and {indices_2}') with open(psi4_scan_dir + '/' + grid_search_file_name, 'r') as outfile: energy = yaml.load(outfile, Loader=yaml.FullLoader) a = np.zeros((scan_pts, scan_pts)) for k in energy.keys(): a[k[0], k[1]] = energy[k] label = [str(n * scan_deg) for n in range(scan_pts)] df = pd.DataFrame(a, index=label, columns=label) df = df.interpolate(method='linear', axis=0, limit_direction='both').interpolate( method='linear', axis=1, limit_direction='both') g = interpolate.RectBivariateSpline(range(scan_pts), range(scan_pts), df) local_minima_locations = detect_local_minima(df) x0s = (np.array([x, y]) for x, y in zip(local_minima_locations[0], local_minima_locations[1])) res_list = list() for x0 in x0s: res = minimize(run_2d_params, x0=x0, args=g, method='Nelder-Mead', tol=1e-12) res_list.append(res) res_tuple = tuple(res_list) res_result = tuple([(r.x[0], r.x[1], r.fun) for r in res_tuple]) print('Fitted local minima') print(res_result) for r in res_result: new_val_1 = r[0] new_val_2 = r[1] xyz_1_new_dihedral = new_val_1 * scan_deg xyz_2_new_dihedral = new_val_2 * scan_deg xyz_1 = modify_coords( coords=arc_zmat, indices=indices_1, new_value=xyz_1_new_dihedral, modification_type='groups', mol=spc.mol, index=1, output_zmat=True, ) xyz_2 = modify_coords( coords=xyz_1, indices=indices_2, new_value=xyz_2_new_dihedral, modification_type='groups', mol=spc.mol, index=1, output_zmat=True, ) fingerprint += 1 all_xyz_dict[(indices_1, int(round(xyz_1_new_dihedral)), indices_2, int(round(xyz_2_new_dihedral)), fingerprint)] = zmat_to_xyz(xyz_2) non_colliding_xyz = [ xyz for xyz in tuple(all_xyz_dict.values()) if not colliding_atoms(xyz=xyz, threshold=0.65) ] isomorphic_xyz = list() for xyz in tuple(non_colliding_xyz): try: spc_to_check = ARCSpecies(label='check', xyz=xyz, is_ts=False, multiplicity=2, smiles='NCCC(O[O])N(C)C') spc_to_check.mol_from_xyz(xyz) if check_isomorphism(spc.mol, spc_to_check.mol): isomorphic_xyz.append(xyz) except: continue all_xyz_distinct_tuple = cluster_confs_by_rmsd( tuple(isomorphic_xyz)) file_counter = 0 save_batch_size = 200000 batch_folder_counter = 1 for distinct_xyz in all_xyz_distinct_tuple: k = key_by_val(all_xyz_dict, distinct_xyz) indices_1 = k[0] deg_1 = k[1] indices_2 = k[2] deg_2 = k[3] if not file_counter % save_batch_size: batch_foler = 'batch_' + str(batch_folder_counter) if not os.path.exists(save_folder + '/' + batch_foler): os.mkdir(save_folder + '/' + batch_foler) batch_folder_counter += 1 file_counter += 1 xyz_str = xyz_to_xyz_file_format(distinct_xyz) xyz_str = '\n'.join(xyz_str.split('\n')[2:-1]) d1str = "{0:.4g}".format(deg_1) d2str = "{0:.4g}".format(deg_2) d1name = '_'.join([str(elem) for elem in indices_1]) d2name = '_'.join([str(elem) for elem in indices_2]) comb_name_list = [ 'd1', d1name, 'deg1', d1str, 'n', 'd2', d2name, 'deg2', d2str ] comb_name = '_'.join(comb_name_list) g16_file_base_name = str( file_counter) + '_' + ts_name + '_' + comb_name + '_g16' g16_file_path = save_folder + '/' + batch_foler + '/' + g16_file_base_name + '.gjf' with open(g16_file_path, 'wt') as f: f.write(script.format(name=g16_file_base_name, xyz=xyz_str))