Beispiel #1
0
 def testFindScanStepsTZVP(self):
     # this file starts with an optimized structure, so only one step for the first step
     scan_file = os.path.join(DATA_DIR, "check_gauss",
                              "pet_dimer_scan_neg_tzvp.log")
     gausslog_contents = process_gausslog_file(scan_file,
                                               collect_scan_steps=True)
     scan_dict = gausslog_contents[SCAN_DICT]
     good_scan_dict = {
         '179.9999': -1603.87812457,
         '169.9999': -1603.877835,
         '159.9999': -1603.87700572,
         '149.9999': -1603.87590461,
         '139.9999': -1603.87484789,
         '129.9999': -1603.87417888,
         '119.9998': -1603.87415467,
         '109.9998': -1603.87485973,
         '99.9998': -1603.87614613,
         '89.9998': -1603.87767359,
         '79.9998': -1603.87898846,
         '69.9998': -1603.87971082,
         '59.9999': -1603.87952259,
         '49.9999': -1603.87835992,
         '39.9999': -1603.87628773,
         '29.9999': -1603.87366776,
         '19.9999': -1603.87107387,
         '9.9999': -1603.86908504,
         '-0.0001': -1603.86813326
     }
     self.assertTrue(len(scan_dict) == len(good_scan_dict))
     for scan_idx, scan_val in scan_dict.items():
         self.assertAlmostEqual(scan_val, good_scan_dict[scan_idx])
Beispiel #2
0
 def testFindScanStepsSVP(self):
     # this file has optimization at every step, including the first
     scan_file = os.path.join(DATA_DIR, "check_gauss",
                              "pet_dimer_scan_neg.log")
     gausslog_contents = process_gausslog_file(scan_file,
                                               collect_scan_steps=True)
     scan_dict = gausslog_contents[SCAN_DICT]
     good_scan_dict = {
         '179.9999': -1602.04394884,
         '169.9999': -1602.04365179,
         '159.9999': -1602.04281467,
         '149.9999': -1602.04166748,
         '139.9999': -1602.04051593,
         '129.9999': -1602.03972339,
         '119.9998': -1602.03957399,
         '109.9998': -1602.04019963,
         '99.9998': -1602.04146383,
         '89.9998': -1602.04303797,
         '79.9998': -1602.04447086,
         '69.9998': -1602.04537614,
         '59.9999': -1602.04542364,
         '49.9999': -1602.04440237,
         '39.9999': -1602.04234975,
         '29.9999': -1602.03968177,
         '19.9999': -1602.03698555,
         '9.9999': -1602.03489267,
         '-0.0002': -1602.03389705
     }
     self.assertTrue(len(scan_dict) == len(good_scan_dict))
     for scan_idx, scan_val in scan_dict.items():
         self.assertAlmostEqual(scan_val, good_scan_dict[scan_idx])
Beispiel #3
0
 def testRemoveConvErr(self):
     # sometimes Gaussian ignore convergence error stating:
     #     "Optimization completed on the basis of negligible forces."
     # in those cases, let's also ignore the error and change the error flag to false
     gausslog_loc = os.path.join(SUB_DATA_DIR,
                                 "tieg5pdc2tsc_ts_ircr_opt.log")
     gausslog_content = process_gausslog_file(gausslog_loc,
                                              find_dih=True,
                                              find_converg=True)
     self.assertTrue("False" in gausslog_content[CONVERG_ERR])
     self.assertAlmostEqual(gausslog_content[CONVERG], 1.5711111111111113)
def collect_output_scan_steps(check_file_list):
    """
    Looks for scan values in one or more files.
    Current functionality: returns one scan, or combines two scans if they search in opposite directions
    :param check_file_list:
    :return: a 2D numpy array with the scan values and energy differences in kcal/mol
    """
    scan_arrays = []
    for fname in check_file_list:
        log_content = process_gausslog_file(fname, collect_scan_steps=True)
        if len(log_content[SCAN_DICT]) > 0:
            scan_arrays.append(
                np.array(list(log_content[SCAN_DICT].items()), dtype=float))
    num_arrays = len(scan_arrays)
    # if only one scan file, return it
    if num_arrays == 1:
        return_array = scan_arrays[0]
    elif num_arrays == 0:
        raise InvalidDataError("No scan information found.")
    elif num_arrays == 2:
        first_array = scan_arrays[0]
        second_array = scan_arrays[1]
        first_diff = process_scan_array(first_array)
        second_diff = process_scan_array(second_array)
        # check if the first entry is in common, as for scan in two directions
        if abs(first_array[0][0] - second_array[0][0]) < 0.002:
            if first_diff < 0 < second_diff:
                first_array = np.flip(first_array, 0)
                return_array = np.vstack((first_array[:-1, :], second_array))
            elif first_diff > 0 > second_diff:
                second_array = np.flip(second_array, 0)
                return_array = np.vstack((second_array[:-1, :], first_array))
            else:
                raise InvalidDataError(
                    "Check how the scans are to be combined.")
        else:
            raise InvalidDataError(
                "The program cannot currently handle these files. Check input, and if correct, "
                "please open an issue on github.")
    # convert dict to array
    else:
        raise InvalidDataError(
            "The program can't yet handle this number of files. Please open an issue."
        )
    # find lowest energy and convert to differences in kcal/mol
    min_e = np.min(return_array[:, 1])
    return_array[:, 1] = (return_array[:, 1] - min_e) * EHPART_TO_KCAL_MOL
    return return_array
Beispiel #5
0
 def testOneFileMissingDihedralInfo(self):
     # testing for some specific problem encountered: when there is a freq only job (no opt) there is no
     #     dihedral info (which caused trouble when tried to compare it) and also prevented finding the
     #     convergence. Thus, checking that this specific error is resolved with the expected warning.
     current_file_list = [
         "tieg5ipatse_ts_ircf_opt_noeg.log",
         "tieg5ipatse_ts_noeg_reacta.log", "tieg5ipatse_ts_noeg_reactc.log"
     ]
     full_info_dict = {}
     check_list = []
     gausslog_loc = os.path.join(SUB_DATA_DIR, current_file_list[0])
     with capture_stderr(process_gausslog_file,
                         gausslog_loc,
                         find_dih=True,
                         find_converg=True) as output:
         self.assertTrue(
             "Requested dihedral data not found for file: tieg5ipatse_ts_ircf_opt_noeg.log"
             in output)
     for gausslog_fname in current_file_list:
         if gausslog_fname == "":
             continue
         gausslog_loc = os.path.join(SUB_DATA_DIR, gausslog_fname)
         gausslog_content = process_gausslog_file(gausslog_loc,
                                                  find_dih=True,
                                                  find_converg=True)
         full_info_dict[gausslog_fname] = gausslog_content
         if gausslog_content[CONVERG_ERR]:
             check_list.append(gausslog_fname)
     self.assertTrue(full_info_dict[current_file_list[0]][DIHES] is None)
     self.assertTrue(
         full_info_dict[current_file_list[1]][DIHES] is not None)
     self.assertFalse(full_info_dict[current_file_list[0]][TS])
     self.assertTrue(full_info_dict[current_file_list[0]][CONVERG_ERR])
     self.assertTrue(full_info_dict[current_file_list[1]][CONVERG_ERR])
     self.assertEqual(len(check_list), 3)
     list_of_conf_lists = compare_gausslog_info(full_info_dict, 5)
     self.assertEqual(len(list_of_conf_lists), 3)
     winner_str, warn_files_str = print_results(full_info_dict,
                                                list_of_conf_lists,
                                                False,
                                                True,
                                                print_winners=False)
     warn_files_list = warn_files_str.split('\n')
     self.assertEqual(len(warn_files_list), 4)
Beispiel #6
0
 def testTSInfo(self):
     goodvibes_helper_folder = os.path.join(DATA_DIR, 'goodvibes_helper')
     file_list = [
         "co_gas.log", "hcoch3_gas.log", "tieg5ipatse_ts.log", "water.log",
         "h_gas_stable_t.log"
     ]
     full_info_dict = {}
     check_list = []
     for fname in file_list:
         gausslog_loc = os.path.join(goodvibes_helper_folder, fname)
         gausslog_content = process_gausslog_file(gausslog_loc,
                                                  find_dih=True,
                                                  find_converg=True)
         full_info_dict[fname] = gausslog_content
         if gausslog_content[CONVERG_ERR]:
             check_list.append(fname)
     for fname in file_list:
         if fname == "tieg5ipatse_ts.log":
             self.assertTrue(full_info_dict[fname][TS])
         else:
             self.assertFalse(full_info_dict[fname][TS])
Beispiel #7
0
def main(argv=None):
    print(
        f"Running GaussianWrangler script gausslog_unique version {__version__}"
    )
    # Read input
    args, ret = parse_cmdline(argv)
    if ret != GOOD_RET or args is None:
        return ret

    # Read template and data files
    try:
        gausslog_files = []
        missing_files = []
        log_info = {}

        # check input
        if args.max_diff:
            args.max_diff = float(args.max_diff)
            if not args.energy and not args.gibbs:
                args.enthalpy = True

        # check that we have files
        with open(args.list) as f:
            for line in f:
                fname = line.strip()
                if len(fname) == 0:
                    continue
                # check that each log file can be found
                if os.path.isfile(fname):
                    gausslog_files.append(fname)
                else:
                    missing_files.append(fname)
            if len(missing_files) > 0:
                raise IOError(
                    "Could not find the following file(s) listed in '{}':\n    "
                    "{}".format(args.list,
                                '\n    '.join(sorted(set(missing_files)))))
            if len(gausslog_files) < 2:
                raise InvalidDataError(
                    "This program expects at least two files to compare to determine if they "
                    "have the same conformation. Check input.")

        # get the data from the files
        for gausslog_file in gausslog_files:
            gausslog_content = process_gausslog_file(gausslog_file,
                                                     find_dih=True,
                                                     find_converg=True)
            log_info[os.path.basename(gausslog_file)] = gausslog_content

        # process data from files
        list_of_conf_lists = compare_gausslog_info(log_info, args.tol)
        winner_str, warn_files_str = print_results(log_info,
                                                   list_of_conf_lists,
                                                   args.enthalpy, args.energy,
                                                   args.max_diff,
                                                   args.out_fname)
        if len(warn_files_str) > 0:
            warning("Check convergence of file(s):" + warn_files_str)

    except IOError as e:
        warning("Problems reading file:", e)
        return IO_ERROR
    except (InvalidDataError, UnicodeDecodeError) as e:
        warning("Problems reading data:", e)
        return INVALID_DATA
    except ValueError as e:
        warning(e.args[0])
        return INVALID_DATA
    return GOOD_RET  # success
def check_convergence(check_file_list, step_converg, last_step, best_conv,
                      all_steps_to_stdout):
    """
    Reads a Gaussian output file to check convergence
    :param all_steps_to_stdout: Boolean to print convergence to standard out
    :param check_file_list: list of file names
    :param step_converg: boolean; if True, capture convergence of each step. If false, only the final convergence.
    :param last_step: None or int; if int, the last step number to check for convergence
    :param best_conv: Boolean; if true, print ten steps with the best convergence
    :return: nothing: either saves a file or prints to stdout
    """
    fname_str_length = 36
    conv_str_length = 11
    for fname in check_file_list:
        if len(os.path.basename(fname)) > fname_str_length:
            fname_str_length = len(os.path.basename(fname))

    print(
        f"{F_NAME:{fname_str_length}} {CONVERG:{conv_str_length}} {CONVERG_ERR}"
    )
    if step_converg:
        headers = STEP_CONVERG_HEADERS
    else:
        headers = FINAL_CONVERG_HEADERS
    for fname in check_file_list:
        log_content = process_gausslog_file(fname,
                                            find_converg=True,
                                            find_step_converg=step_converg,
                                            last_step_to_read=last_step)
        log_content[F_NAME] = os.path.basename(fname)
        if step_converg:
            # all_steps_to_stdout doesn't need an out_fname, but doesn't hurt either
            if last_step:
                out_fname = sys.stdout
            else:
                out_fname = create_out_fname(fname,
                                             prefix='',
                                             suffix='_conv_steps',
                                             ext='.csv')

            # create list of dicts for each step, for all step_converg options
            step_list = []
            for step_num in log_content[CONVERG_STEP_DICT].keys():
                # not sure necessary to make this new dict, but it is fast enough and clearer for next steps
                step_list.append({
                    F_NAME:
                    log_content[F_NAME],
                    STEP_NUM:
                    step_num,
                    ENERGY:
                    log_content[CONVERG_STEP_DICT][step_num][ENERGY],
                    MAX_FORCE:
                    log_content[CONVERG_STEP_DICT][step_num][MAX_FORCE],
                    RMS_FORCE:
                    log_content[CONVERG_STEP_DICT][step_num][RMS_FORCE],
                    MAX_DISPL:
                    log_content[CONVERG_STEP_DICT][step_num][MAX_DISPL],
                    RMS_DISPL:
                    log_content[CONVERG_STEP_DICT][step_num][RMS_DISPL],
                    CONVERG:
                    log_content[CONVERG_STEP_DICT][step_num][CONVERG],
                    CONVERG_ERR:
                    log_content[CONVERG_STEP_DICT][step_num][CONVERG_ERR],
                })

            # different output depending on which step_converg option
            if last_step or best_conv:
                if len(step_list) == 0:
                    print("No convergence data found for file: {}".format(
                        log_content[F_NAME]))
                    continue
                sorted_by_converg = sorted(step_list, key=itemgetter(CONVERG))
                if last_step:
                    print(
                        "Steps sorted by convergence to step number {} for file: {}"
                        .format(last_step, log_content[F_NAME]))
                    stop_step = last_step
                else:
                    print(
                        "Best (up to 10) steps sorted by convergence for file: {}"
                        .format(log_content[F_NAME]))
                    stop_step = 10
                print("    StepNum  Convergence")
                for print_num, step_dict in enumerate(sorted_by_converg):
                    if print_num == stop_step:
                        # break this for, and go to next file if there is one
                        break
                    print("    {:7} {:10.3f}".format(step_dict[STEP_NUM],
                                                     step_dict[CONVERG]))
            elif all_steps_to_stdout:
                # print all steps to stdout, not sorted by convergence
                print("Convergence of all steps for file: {}".format(
                    log_content[F_NAME]))
                print("    StepNum  Convergence")
                for step_dict in step_list:
                    print("    {:7} {:10.3f}".format(step_dict[STEP_NUM],
                                                     step_dict[CONVERG]))
            else:
                # save all steps, not sorted by convergence
                print(
                    f"{log_content[F_NAME]:{fname_str_length}} {step_list[-1][CONVERG]:{conv_str_length}.4f} "
                    f"{step_list[-1][CONVERG_ERR]}")
                write_csv(step_list,
                          out_fname,
                          headers,
                          extrasaction="ignore",
                          round_digits=6)
                # also make plots of step versus convergence
                create_convergence_plots(out_fname, step_list)
        else:
            # this is the printing for final termination step only (not step_converg)
            fname = log_content[headers[0]]
            print(
                f"{fname:{fname_str_length}} {log_content[headers[1]]:{conv_str_length}.4f} "
                f"{log_content[headers[2]]}")