예제 #1
0
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
예제 #2
0
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
예제 #3
0
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
예제 #4
0
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))
예제 #5
0
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))