Parse the standard ADF output file.

def _parse_adf_output(self):
        """
        Parse the standard ADF output file.
        """
        numerical_freq_patt = re.compile(
            r"\s+\*\s+F\sR\sE\sQ\sU\sE\sN\sC\sI\sE\sS\s+\*")
        analytic_freq_patt = re.compile(
            r"\s+\*\s+F\sR\sE\sQ\sU\sE\sN\sC\sY\s+A\sN\sA\sL\sY\sS\sI\sS\s+\*")
        freq_on_patt = re.compile(r"Vibrations\sand\sNormal\sModes\s+\*+.*\*+")
        freq_off_patt = re.compile(r"List\sof\sAll\sFrequencies:")
        mode_patt = re.compile(r"\s+(\d+)\.([A-Za-z]+)\s+(.*)")
        coord_patt = re.compile(r"\s+(\d+)\s+([A-Za-z]+)" + 6 * r"\s+([0-9\.-]+)")
        coord_on_patt = re.compile(r"\s+\*\s+R\sU\sN\s+T\sY\sP\sE\s:\sFREQUENCIES\s+\*")
        parse_freq = False
        parse_mode = False
        nnext = 0
        nstrike = 0
        sites = []

        self.frequencies = []
        self.normal_modes = []

        if self.final_structure is None:
            find_structure = True
            parse_coord = False
            natoms = 0
        else:
            find_structure = False
            parse_coord = False
            natoms = self.final_structure.num_sites

        with open(self.filename, "r") as f:
            for line in f:
                if self.run_type == "NumericalFreq" and find_structure:
                    if not parse_coord:
                        m = coord_on_patt.search(line)
                        if m:
                            parse_coord = True
                    else:
                        m = coord_patt.search(line)
                        if m:
                            sites.append(
                                [m.group(2), list(map(float, m.groups()[2:5]))])
                            nstrike += 1
                        elif nstrike > 0:
                            find_structure = False
                            self.final_structure = self._sites_to_mol(sites)
                            natoms = self.final_structure.num_sites

                elif self.freq_type is None:
                    if numerical_freq_patt.search(line):
                        self.freq_type = "Numerical"
                    elif analytic_freq_patt.search(line):
                        self.freq_type = "Analytical"
                        self.run_type = "AnalyticalFreq"

                elif freq_on_patt.search(line):
                    parse_freq = True

                elif parse_freq:
                    if freq_off_patt.search(line):
                        break
                    el = line.strip().split()
                    if 1 <= len(el) <= 3 and line.find(".") != -1:
                        nnext = len(el)
                        parse_mode = True
                        parse_freq = False
                        self.frequencies.extend(map(float, el))
                        for i in range(nnext):
                            self.normal_modes.append([])

                elif parse_mode:
                    m = mode_patt.search(line)
                    if m:
                        v = list(chunks(map(float, m.group(3).split()), 3))
                        if len(v) != nnext:
                            raise AdfOutputError("Odd Error!")
                        for i, k in enumerate(range(-nnext, 0, 1)):
                            self.normal_modes[k].extend(v[i])
                        if int(m.group(1)) == natoms:
                            parse_freq = True
                            parse_mode = False
        if isinstance(self.final_structure, list):
            self.final_structure = self._sites_to_mol(self.final_structure)

        if self.freq_type is not None:
            if len(self.frequencies) != len(self.normal_modes):
                raise AdfOutputError("The number of normal modes is wrong!")
            if len(self.normal_modes[0]) != natoms * 3:
                raise AdfOutputError("The dimensions of the modes are wrong!")