Пример #1
0
    def _read_optimized_geometry(self):
        """
        Parses optimized XYZ coordinates. If not present, parses optimized Z-matrix.
        """
        header_pattern = r"\*+\s+OPTIMIZATION\s+CONVERGED\s+\*+\s+\*+\s+Coordinates \(Angstroms\)\s+ATOM\s+X\s+Y\s+Z"
        table_pattern = r"\s+\d+\s+\w+\s+([\d\-\.]+)\s+([\d\-\.]+)\s+([\d\-\.]+)"
        footer_pattern = r"\s+Z-matrix Print:"

        parsed_optimized_geometry = read_table_pattern(
            self.text, header_pattern, table_pattern, footer_pattern)
        if parsed_optimized_geometry == [] or None:
            self.data["optimized_geometry"] = []
            header_pattern = r"^\s+\*+\s+OPTIMIZATION CONVERGED\s+\*+\s+\*+\s+Z-matrix\s+Print:\s+\$molecule\s+[\d\-]+\s+[\d\-]+\n"
            table_pattern = r"\s*(\w+)(?:\s+(\d+)\s+([\d\-\.]+)(?:\s+(\d+)\s+([\d\-\.]+)(?:\s+(\d+)\s+([\d\-\.]+))*)*)*(?:\s+0)*"
            footer_pattern = r"^\$end\n"

            self.data["optimized_zmat"] = read_table_pattern(
                self.text, header_pattern, table_pattern, footer_pattern)
        else:
            self.data["optimized_geometry"] = process_parsed_coords(
                parsed_optimized_geometry[0])
            if self.data.get('charge') != None:
                self.data["molecule_from_optimized_geometry"] = Molecule(
                    species=self.data.get('species'),
                    coords=self.data.get('optimized_geometry'),
                    charge=self.data.get('charge'),
                    spin_multiplicity=self.data.get('multiplicity'))
Пример #2
0
    def _parse_node_opt_trajectory(self):
        self.data["opt_trajectory_energies"] = dict()
        self.data["opt_trajectory_gradrms"] = dict()

        header_pattern = r"\s*converged\n\s*opt-summary [0-9]+"
        body_pattern = r"\s*Node: ([0-9]+) Opt step: [0-9]+ E: ([\.\-0-9]+) predE: [\.\-0-9]+ ratio: [\.\-0-9]+ gradrms: ([\.0-9]+) ss: [\-\.0-9]+ DMAX: ([\.0-9]+)"
        footer_pattern = r""
        temp_opt_trajectories = read_table_pattern(
            self.text,
            header_pattern=header_pattern,
            row_pattern=body_pattern,
            footer_pattern=footer_pattern)

        for table in temp_opt_trajectories:
            energies = list()
            grads = list()
            node_num = int(table[0][0])
            if node_num not in self.data["opt_trajectory_energies"]:
                self.data["opt_trajectory_energies"][node_num] = list()
            if node_num not in self.data["opt_trajectory_gradrms"]:
                self.data["opt_trajectory_gradrms"][node_num] = list()
            for row in table:
                energies.append(float(row[1]))
                grads.append(float(row[2]))

            self.data["opt_trajectory_energies"][node_num].append(energies)
            self.data["opt_trajectory_gradrms"][node_num].append(grads)
Пример #3
0
 def read_molecule(string):
     charge = None
     spin_mult = None
     patterns = {
         "read": r"^\s*\$molecule\n\s*(read)",
         "charge": r"^\s*\$molecule\n\s*(\d+)\s+\d",
         "spin_mult": r"^\s*\$molecule\n\s*\d+\s*(\d)"
     }
     matches = read_pattern(string, patterns)
     if "read" in matches.keys():
         return "read"
     if "charge" in matches.keys():
         charge = float(matches["charge"][0][0])
     if "spin_mult" in matches.keys():
         spin_mult = int(matches["spin_mult"][0][0])
     header = r"^\s*\$molecule\n\s*\d\s*\d"
     row = r"\s*((?i)[a-z]+)\s+([\d\-\.]+)\s+([\d\-\.]+)\s+([\d\-\.]+)"
     footer = r"^\$end"
     mol_table = read_table_pattern(string,
                                    header_pattern=header,
                                    row_pattern=row,
                                    footer_pattern=footer)
     species = [val[0] for val in mol_table[0]]
     coords = [[float(val[1]), float(val[2]),
                float(val[3])] for val in mol_table[0]]
     mol = Molecule(species=species,
                    coords=coords,
                    charge=charge,
                    spin_multiplicity=spin_mult)
     return mol
Пример #4
0
    def _read_mulliken(self):
        """
        Parses Mulliken charges. Also parses spins given an unrestricted SCF.
        """
        if self.data.get('unrestricted', []):
            header_pattern = r"\-+\s+Ground-State Mulliken Net Atomic Charges\s+Atom\s+Charge \(a\.u\.\)\s+Spin\s\(a\.u\.\)\s+\-+"
            table_pattern = r"\s+\d+\s\w+\s+([\d\-\.]+)\s+([\d\-\.]+)"
            footer_pattern = r"\s\s\-+\s+Sum of atomic charges"
        else:
            header_pattern = r"\-+\s+Ground-State Mulliken Net Atomic Charges\s+Atom\s+Charge \(a\.u\.\)\s+\-+"
            table_pattern = r"\s+\d+\s\w+\s+([\d\-\.]+)"
            footer_pattern = r"\s\s\-+\s+Sum of atomic charges"

        temp_mulliken = read_table_pattern(self.text, header_pattern,
                                           table_pattern, footer_pattern)
        real_mulliken = []
        for one_mulliken in temp_mulliken:
            if self.data.get('unrestricted', []):
                temp = np.zeros(shape=(len(one_mulliken), 2))
                for ii, entry in enumerate(one_mulliken):
                    temp[ii, 0] = float(entry[0])
                    temp[ii, 1] = float(entry[1])
            else:
                temp = np.zeros(len(one_mulliken))
                for ii, entry in enumerate(one_mulliken):
                    temp[ii] = float(entry[0])
            real_mulliken += [temp]

        self.data["Mulliken"] = real_mulliken
Пример #5
0
    def _read_SCF(self):
        """
        Parses both old and new SCFs.
        """
        if self.data.get('using_GEN_SCFMAN', []):
            if "SCF_failed_to_converge" in self.data.get("errors"):
                footer_pattern = r"^\s*gen_scfman_exception: SCF failed to converge"
            else:
                footer_pattern = r"^\s*\-+\n"
            header_pattern = r"^\s*\-+\s+Cycle\s+Energy\s+(?:(?:DIIS)*\s+[Ee]rror)*(?:RMS Gradient)*\s+\-+(?:\s*\-+\s+OpenMP\s+Integral\s+computing\s+Module\s+(?:Release:\s+version\s+[\d\-\.]+\,\s+\w+\s+[\d\-\.]+\, Q-Chem Inc\. Pittsburgh\s+)*\-+)*\n"
            table_pattern = r"(?:\s*Nonlocal correlation = [\d\-\.]+e[\d\-]+)*(?:\s*Inaccurate integrated density:\n\s+Number of electrons\s+=\s+[\d\-\.]+\n\s+Numerical integral\s+=\s+[\d\-\.]+\n\s+Relative error\s+=\s+[\d\-\.]+\s+\%\n)*\s*\d+\s+([\d\-\.]+)\s+([\d\-\.]+)e([\d\-\.\+]+)(?:\s+Convergence criterion met)*(?:\s+Preconditoned Steepest Descent)*(?:\s+Roothaan Step)*(?:\s+(?:Normal\s+)*BFGS [Ss]tep)*(?:\s+LineSearch Step)*(?:\s+Line search: overstep)*(?:\s+Descent step)*"
        else:
            if "SCF_failed_to_converge" in self.data.get("errors"):
                footer_pattern = r"^\s*\d+\s*[\d\-\.]+\s+[\d\-\.]+E[\d\-\.]+\s+Convergence\s+failure\n"
            else:
                footer_pattern = r"^\s*\-+\n"
            header_pattern = r"^\s*\-+\s+Cycle\s+Energy\s+DIIS Error\s+\-+\n"
            table_pattern = r"(?:\s*Inaccurate integrated density:\n\s+Number of electrons\s+=\s+[\d\-\.]+\n\s+Numerical integral\s+=\s+[\d\-\.]+\n\s+Relative error\s+=\s+[\d\-\.]+\s+\%\n)*\s*\d+\s*([\d\-\.]+)\s+([\d\-\.]+)E([\d\-\.\+]+)(?:\s*\n\s*cpu\s+[\d\-\.]+\swall\s+[\d\-\.]+)*(?:\nin dftxc\.C, eleTot sum is:[\d\-\.]+, tauTot is\:[\d\-\.]+)*(?:\s+Convergence criterion met)*(?:\s+Done RCA\. Switching to DIIS)*(?:\n\s*Warning: not using a symmetric Q)*(?:\nRecomputing EXC\s*[\d\-\.]+\s*[\d\-\.]+\s*[\d\-\.]+(?:\s*\nRecomputing EXC\s*[\d\-\.]+\s*[\d\-\.]+\s*[\d\-\.]+)*)*"

        temp_scf = read_table_pattern(self.text, header_pattern, table_pattern,
                                      footer_pattern)
        real_scf = []
        for one_scf in temp_scf:
            temp = np.zeros(shape=(len(one_scf), 2))
            for ii, entry in enumerate(one_scf):
                temp[ii, 0] = float(entry[0])
                temp[ii, 1] = float(entry[1]) * 10**float(entry[2])
            real_scf += [temp]

        self.data["SCF"] = real_scf
Пример #6
0
 def _read_species_and_inital_geometry(self):
     """
     Parses species and initial geometry.
     """
     header_pattern = r"Standard Nuclear Orientation \(Angstroms\)\s+I\s+Atom\s+X\s+Y\s+Z\s+-+"
     table_pattern = r"\s*\d+\s+([a-zA-Z]+)\s*([\d\-\.]+)\s*([\d\-\.]+)\s*([\d\-\.]+)\s*"
     footer_pattern = r"\s*-+"
     temp_geom = read_table_pattern(self.text, header_pattern,
                                    table_pattern, footer_pattern)
     if temp_geom == None or len(temp_geom) == 0:
         self.data["species"] = None
         self.data["initial_geometry"] = None
         self.data["initial_molecule"] = None
     else:
         temp_geom = temp_geom[0]
         species = []
         geometry = np.zeros(shape=(len(temp_geom), 3), dtype=float)
         for ii, entry in enumerate(temp_geom):
             species += [entry[0]]
             for jj in range(3):
                 geometry[ii, jj] = float(entry[jj + 1])
         self.data["species"] = species
         self.data["initial_geometry"] = geometry
         self.data["initial_molecule"] = Molecule(
             species=species,
             coords=geometry,
             charge=self.data.get('charge'),
             spin_multiplicity=self.data.get('multiplicity'))
Пример #7
0
 def read_opt(string):
     patterns = {
         "CONSTRAINT": r"^\s*CONSTRAINT",
         "FIXED": r"^\s*FIXED",
         "DUMMY": r"^\s*DUMMY",
         "CONNECT": r"^\s*CONNECT"
     }
     opt_matches = read_pattern(string, patterns)
     opt_sections = [key for key in opt_matches.keys()]
     opt = {}
     if "CONSTRAINT" in opt_sections:
         c_header = r"^\s*CONSTRAINT\n"
         c_row = r"(\w.*)\n"
         c_footer = r"^\s*ENDCONSTRAINT\n"
         c_table = read_table_pattern(string,
                                      header_pattern=c_header,
                                      row_pattern=c_row,
                                      footer_pattern=c_footer)
         opt["CONSTRAINT"] = [val[0] for val in c_table[0]]
     if "FIXED" in opt_sections:
         f_header = r"^\s*FIXED\n"
         f_row = r"(\w.*)\n"
         f_footer = r"^\s*ENDFIXED\n"
         f_table = read_table_pattern(string,
                                      header_pattern=f_header,
                                      row_pattern=f_row,
                                      footer_pattern=f_footer)
         opt["FIXED"] = [val[0] for val in f_table[0]]
     if "DUMMY" in opt_sections:
         d_header = r"^\s*DUMMY\n"
         d_row = r"(\w.*)\n"
         d_footer = r"^\s*ENDDUMMY\n"
         d_table = read_table_pattern(string,
                                      header_pattern=d_header,
                                      row_pattern=d_row,
                                      footer_pattern=d_footer)
         opt["DUMMY"] = [val[0] for val in d_table[0]]
     if "CONNECT" in opt_sections:
         cc_header = r"^\s*CONNECT\n"
         cc_row = r"(\w.*)\n"
         cc_footer = r"^\s*ENDCONNECT\n"
         cc_table = read_table_pattern(string,
                                       header_pattern=cc_header,
                                       row_pattern=cc_row,
                                       footer_pattern=cc_footer)
         opt["CONNECT"] = [val[0] for val in cc_table[0]]
     return opt
Пример #8
0
    def _parse_input_values(self):
        header_pattern = r"#=+#\n#\|.+\[92m\s+Parsed GSM Keys : Values.+\[0m\s+\|#\n#=+#"
        table_pattern = r"(?P<key>[A-Za-z_]+)\s+(?P<value>[A-Za-z0-9\[\]_\.\-]+)\s*\n"
        footer_pattern = r"\-+"

        temp_inputs = read_table_pattern(self.text, header_pattern,
                                         table_pattern, footer_pattern)

        if temp_inputs is None or len(temp_inputs) == 0:
            self.data["inputs"] = dict()
        else:
            self.data["inputs"] = dict()
            temp_inputs = temp_inputs[0]

            for row in temp_inputs:
                key = row["key"]
                value = row["value"]

                if value == "True":  # Deal with bools
                    self.data["inputs"][key] = True
                elif value == "False":
                    self.data["inputs"][key] = False
                elif value.startswith("[") and value.endswith(
                        "]"):  # Deal with lists
                    val = value[1:-1].split(", ")
                    try:  # ints
                        val = [int(v) for v in val]
                        self.data["inputs"][key] = val
                    except ValueError:
                        self.data["inputs"][key] = val
                else:
                    # int
                    is_int = True
                    is_float = True
                    val = value
                    try:
                        val = int(value)
                    except ValueError:
                        is_int = False
                    if is_int:
                        self.data["inputs"][key] = val
                        continue
                    else:
                        try:
                            val = float(value)
                        except ValueError:
                            is_float = False

                    if is_float:
                        self.data["inputs"][key] = val
                        continue
                    else:
                        self.data["inputs"][key] = value

        if "charge" not in self.data["inputs"]:
            self.data["inputs"]["charge"] = 0
Пример #9
0
 def read_rem(string):
     header = r"^\s*\$rem"
     row = r"\s*([a-zA-Z\_]+)\s*=?\s*(\S+)"
     footer = r"^\s*\$end"
     rem_table = read_table_pattern(string,
                                    header_pattern=header,
                                    row_pattern=row,
                                    footer_pattern=footer)
     rem = {key: val for key, val in rem_table[0]}
     return rem
Пример #10
0
    def _read_frequency_data(self):
        """
        Parses frequencies, enthalpy, entropy, and mode vectors.
        """
        temp_dict = read_pattern(
            self.text, {
                "frequencies":
                r"\s*Frequency:\s+([\d\-\.]+)(?:\s+([\d\-\.]+)(?:\s+([\d\-\.]+))*)*",
                "enthalpy":
                r"\s*Total Enthalpy:\s+([\d\-\.]+)\s+kcal/mol",
                "entropy":
                r"\s*Total Entropy:\s+([\d\-\.]+)\s+cal/mol\.K"
            })

        if temp_dict.get('enthalpy') == None:
            self.data['enthalpy'] = []
        else:
            self.data['enthalpy'] = float(temp_dict.get('enthalpy')[0][0])

        if temp_dict.get('entropy') == None:
            self.data['entropy'] = None
        else:
            self.data['entropy'] = float(temp_dict.get('entropy')[0][0])

        if temp_dict.get('frequencies') == None:
            self.data['frequencies'] = None
        else:
            temp_freqs = [
                value for entry in temp_dict.get('frequencies')
                for value in entry
            ]
            freqs = np.zeros(len(temp_freqs) - temp_freqs.count('None'))
            for ii, entry in enumerate(temp_freqs):
                if entry != 'None':
                    freqs[ii] = float(entry)
            self.data['frequencies'] = freqs

            header_pattern = r"\s*Raman Active:\s+[YESNO]+\s+(?:[YESNO]+\s+)*X\s+Y\s+Z\s+(?:X\s+Y\s+Z\s+)*"
            table_pattern = r"\s*[a-zA-Z][a-zA-Z\s]\s*([\d\-\.]+)\s*([\d\-\.]+)\s*([\d\-\.]+)\s*(?:([\d\-\.]+)\s*([\d\-\.]+)\s*([\d\-\.]+)\s*(?:([\d\-\.]+)\s*([\d\-\.]+)\s*([\d\-\.]+))*)*"
            footer_pattern = r"TransDip\s+[\d\-\.]+\s*[\d\-\.]+\s*[\d\-\.]+\s*(?:[\d\-\.]+\s*[\d\-\.]+\s*[\d\-\.]+\s*)*"
            temp_freq_mode_vecs = read_table_pattern(
                self.text, header_pattern, table_pattern, footer_pattern)
            freq_mode_vecs = np.zeros(
                shape=(len(freqs), len(temp_freq_mode_vecs[0]), 3))

            for ii, triple_FMV in enumerate(temp_freq_mode_vecs):
                for jj, line in enumerate(triple_FMV):
                    for kk, entry in enumerate(line):
                        if entry != 'None':
                            freq_mode_vecs[int(ii * 3 + math.floor(kk / 3)),
                                           jj, kk % 3] = float(entry)

            self.data["frequency_mode_vectors"] = freq_mode_vecs
Пример #11
0
 def read_smx(string):
     header = r"^\s*\$smx"
     row = r"\s*([a-zA-Z\_]+)\s+(\S+)"
     footer = r"^\s*\$end"
     smx_table = read_table_pattern(string,
                                    header_pattern=header,
                                    row_pattern=row,
                                    footer_pattern=footer)
     if smx_table == []:
         print(
             "No valid smx inputs found. Note that there should be no '=' chracters in smx input lines."
         )
         return {}
     else:
         smx = {key: val for key, val in smx_table[0]}
         return smx
Пример #12
0
 def read_pcm(string):
     header = r"^\s*\$pcm"
     row = r"\s*([a-zA-Z\_]+)\s+(\S+)"
     footer = r"^\s*\$end"
     pcm_table = read_table_pattern(string,
                                    header_pattern=header,
                                    row_pattern=row,
                                    footer_pattern=footer)
     if pcm_table == []:
         print(
             "No valid PCM inputs found. Note that there should be no '=' chracters in PCM input lines."
         )
         return {}
     else:
         pcm = {key: val for key, val in pcm_table[0]}
         return pcm
Пример #13
0
    def _read_last_geometry(self):
        """
        Parses the last geometry from an optimization trajectory for use in a new input file.
        """
        header_pattern = r"\s+Optimization\sCycle:\s+" + \
            str(len(self.data.get("energy_trajectory"))) + \
            "\s+Coordinates \(Angstroms\)\s+ATOM\s+X\s+Y\s+Z"
        table_pattern = r"\s+\d+\s+\w+\s+([\d\-\.]+)\s+([\d\-\.]+)\s+([\d\-\.]+)"
        footer_pattern = r"\s+Point Group\:\s+[\d\w]+\s+Number of degrees of freedom\:\s+\d+"

        parsed_last_geometry = read_table_pattern(
            self.text, header_pattern, table_pattern, footer_pattern)
        if parsed_last_geometry == [] or None:
            self.data["last_geometry"] = []
        else:
            self.data["last_geometry"] = process_parsed_coords(
                parsed_last_geometry[0])
            if self.data.get('charge') != None:
                self.data["molecule_from_last_geometry"] = Molecule(
                    species=self.data.get('species'),
                    coords=self.data.get('last_geometry'),
                    charge=self.data.get('charge'),
                    spin_multiplicity=self.data.get('multiplicity'))
Пример #14
0
    def _parse_calculation_summary(self):

        header_struct_energies = (
            r"\s*=+\n\s+Structure Energies \(Hartree\)\s+\n\s*=+\n\s+Structure\s+Total\s+"
            + r"Separated\s+Gibbs \(298.15K\)\s*\n\s*=+")
        table_struct_energies = r"\s*([A-Za-z0-9_]+)\s+([\-\.0-9]+)\s+([\-\.0-9]+)\s+([\-\.0-9]+)"
        footer_struct_energies = r"\s*=+"

        temp_struct_energies = read_table_pattern(self.text,
                                                  header_struct_energies,
                                                  table_struct_energies,
                                                  footer_struct_energies)
        if temp_struct_energies is None or len(temp_struct_energies) == 0:
            self.data["output"]["struct_energies"] = None
        else:
            self.data["output"]["struct_energies"] = dict()
            for row in temp_struct_energies[0]:
                struct_name = row[0]
                total_energy = float(row[1])
                separated_energy = float(row[2])
                gibbs = float(row[3])
                self.data["output"]["struct_energies"][struct_name] = {
                    "total": total_energy,
                    "separated": separated_energy,
                    "gibbs": gibbs
                }

        header_complex_energy = (
            r"\s+Complex Energy \(kcal/mol\)\s+\n\s*\-+\n\s*Rxn\s+Er\s+Ep\s+Ets\s+Rxn E\s+Act E"
            + r"\s+frequency\s+Status of IRC\?\s+Path number\s+Approx TS")
        table_complex_energy = (
            r"\s*([0-9]+)\s+([\-\.0-9]+)\s+([\-\.0-9]+)\s+([\-\.0-9]+)\s+([\-\.0-9]+)\s+"
            +
            r"([\-\.0-9]+)\s+([\-\.0-9]+)\s+(Failed|Passed)\s+([0-9]+)\s+(True|False)\s*"
        )
        footer_complex_energy = r"\s*\-+"

        temp_complex_energies = read_table_pattern(self.text,
                                                   header_complex_energy,
                                                   table_complex_energy,
                                                   footer_complex_energy)

        if temp_complex_energies is None or len(temp_complex_energies) == 0:
            self.data["output"]["complex_energies"] = None
        else:
            self.data["output"]["complex_energies"] = list()
            for row in temp_complex_energies[0]:
                if row[7] == "Failed":
                    irc = False
                else:
                    irc = True

                if row[9] == "False":
                    approx_ts = False
                else:
                    approx_ts = True

                self.data["output"]["complex_energies"].append({
                    "reactant":
                    float(row[1]),
                    "product":
                    float(row[2]),
                    "transition_state":
                    float(row[3]),
                    "rxn":
                    float(row[4]),
                    "activation":
                    float(row[5]),
                    "freq_mode":
                    float(row[6]),
                    "irc_succeeded":
                    irc,
                    "path_number":
                    int(row[8]),
                    "approx_ts":
                    approx_ts
                })

        header_sep_energy = (
            r"\s+Inf\. Separated Energy \(kcal/mol\)\s+\n\s*\-+\n\s*Rxn\s+Er\s+Ep\s+Ets\s+Rxn E\s+"
            + r"Act E\s+frequency\s+Status of IRC\?\s+Path number\s+Approx TS")
        table_sep_energy = (
            r"\s*([0-9]+)\s+([\-\.0-9]+)\s+([\-\.0-9]+)\s+([\-\.0-9]+)\s+([\-\.0-9]+)\s+"
            +
            r"([\-\.0-9]+)\s+([\-\.0-9]+)\s+(Failed|Passed)\s+([0-9]+)\s+(True|False)\s*"
        )
        footer_sep_energy = r"\s*\-+"

        temp_sep_energies = read_table_pattern(self.text, header_sep_energy,
                                               table_sep_energy,
                                               footer_sep_energy)
        if temp_sep_energies is None or len(temp_sep_energies) == 0:
            self.data["output"]["separated_energies"] = None
        else:
            self.data["output"]["separated_energies"] = list()
            for row in temp_sep_energies[0]:
                if row[7] == "Failed":
                    irc = False
                else:
                    irc = True

                if row[9] == "False":
                    approx_ts = False
                else:
                    approx_ts = True

                self.data["output"]["separated_energies"].append({
                    "reactant":
                    float(row[1]),
                    "product":
                    float(row[2]),
                    "transition_state":
                    float(row[3]),
                    "rxn":
                    float(row[4]),
                    "activation":
                    float(row[5]),
                    "freq_mode":
                    float(row[6]),
                    "irc_succeeded":
                    irc,
                    "path_number":
                    int(row[8]),
                    "approx_ts":
                    approx_ts
                })

        header_gibbs_energy = (
            r"\s+Gibbs Free Energy at 298\.15K and concentration of 1 mol/liter \(kcal/mol\)\s+\n"
            + r"\s*\-+\n\s*Rxn\s+Gr\s+Gp\s+Gts\s+Rxn G\s+Act G" +
            r"\s+frequency\s+Status of IRC\?\s+Path number\s+Approx TS")
        table_gibbs_energy = (
            r"\s*([0-9]+)\s+([\-\.0-9]+)\s+([\-\.0-9]+)\s+([\-\.0-9]+)\s+([\-\.0-9]+)\s+"
            +
            r"([\-\.0-9]+)\s+([\-\.0-9]+)\s+(Failed|Passed)\s+([0-9]+)\s+(True|False)\s*"
        )
        footer_gibbs_energy = r"\s*\-+"

        temp_gibbs_energies = read_table_pattern(self.text,
                                                 header_gibbs_energy,
                                                 table_gibbs_energy,
                                                 footer_gibbs_energy)
        if temp_gibbs_energies is None or len(temp_gibbs_energies) == 0:
            self.data["output"]["gibbs_energies"] = None
        else:
            self.data["output"]["gibbs_energies"] = list()
            for row in temp_gibbs_energies[0]:
                if row[7] == "Failed":
                    irc = False
                else:
                    irc = True

                if row[9] == "False":
                    approx_ts = False
                else:
                    approx_ts = True

                self.data["output"]["gibbs_energies"].append({
                    "reactant":
                    float(row[1]),
                    "product":
                    float(row[2]),
                    "transition_state":
                    float(row[3]),
                    "rxn":
                    float(row[4]),
                    "activation":
                    float(row[5]),
                    "freq_mode":
                    float(row[6]),
                    "irc_succeeded":
                    irc,
                    "path_number":
                    int(row[8]),
                    "approx_ts":
                    approx_ts
                })

        header_temp_dep = (
            r"\(Celsius\)\s+\(kcal/mol\)\s+\(kcal/mol\)\s+\(s\^\-1.*\)\s+\(s\^\-1.*\)\s+\(unitless\)"
            + r"\s+at t1/2 \(%\)\s+half life\s+\n\-+")
        table_temp_dep = (
            r"\s*([0-9\.\-]+)\s+([0-9\+\-eE\.]+)\s+([0-9\+\-eE\.]+)\s+([0-9\+\-eE\.]+)\s+"
            +
            r"([0-9\+\-eE\.]+)\s+([0-9\+\-eE\.]+)\s+([0-9\+\-eE\.]+)\s+([A-Za-z0-9\.\-\+ ]+)"
        )
        footer_temp_dep = r""

        temp_temp_dep = read_table_pattern(self.text, header_temp_dep,
                                           table_temp_dep, footer_temp_dep)
        if temp_temp_dep is None or len(temp_temp_dep) == 0:
            self.data["output"]["temperature_dependence"] = None
        else:
            self.data["output"]["temperature_dependence"] = dict()
            for row in temp_temp_dep[0]:
                temp = float(row[0])
                self.data["output"]["temperature_dependence"][temp] = {
                    "gibbs_activation": float(row[1]),
                    "gibbs_reaction": float(row[2]),
                    "k_forwards": float(row[3]),
                    "k_reverse": float(row[4]),
                    "log10_keq": float(row[5]),
                    "rct_remaining_t_half": float(row[6]),
                    "half_life": row[7]
                }

        header_diagnostic = r"\s+AutoTS diagnostic report\s+\n\-+\n\s+property\s+value\s+diagnostic passes\n\-+"
        table_diagnostic = r"\s*((?:[A-za-z]+ ?)+)\s*([A-Za-z0-9\-,/ ]+)\s+(Yes|No)"
        footer_diagnostic = r""

        temp_diagnostic = read_table_pattern(self.text, header_diagnostic,
                                             table_diagnostic,
                                             footer_diagnostic)
        if temp_diagnostic is None or len(temp_diagnostic) == 0:
            self.data["diagnostic"] = None
        else:
            self.data["diagnostic"] = dict()
            for row in temp_diagnostic[0]:
                if "Level of theory" in row[0]:
                    continue
                if row[2].strip() == "Yes":
                    passed = True
                else:
                    passed = False

                self.data["diagnostic"][row[0].strip()] = {
                    "value": row[1].strip(),
                    "passed": passed
                }