Read a potential energy surface from a gaussian scan calculation.

        Returns:

            A dict: {"energies": [ values ],
                     "coords": {"d1": [ values ], "A2", [ values ], ... }}

            "energies" are the energies of all points of the potential energy
            surface. "coords" are the internal coordinates used to compute the
            potential energy surface and the internal coordinates optimized,
            labelled by their name as defined in the calculation.

def read_scan(self):
        """
        Read a potential energy surface from a gaussian scan calculation.

        Returns:

            A dict: {"energies": [ values ],
                     "coords": {"d1": [ values ], "A2", [ values ], ... }}

            "energies" are the energies of all points of the potential energy
            surface. "coords" are the internal coordinates used to compute the
            potential energy surface and the internal coordinates optimized,
            labelled by their name as defined in the calculation.
        """

        def floatList(l):
            """ return a list of float from a list of string """
            return [float(v) for v in l]

        scan_patt = re.compile(r"^\sSummary of the potential surface scan:")
        optscan_patt = re.compile(r"^\sSummary of Optimized Potential Surface Scan")

        # data dict return
        data = {"energies": list(), "coords": dict()}

        # read in file
        with zopen(self.filename, "r") as f:
            line = f.readline()

            while line != "":
                if optscan_patt.match(line):
                    f.readline()
                    line = f.readline()
                    endScan = False
                    while not endScan:
                        data["energies"] += floatList(float_patt.findall(line))
                        line = f.readline()
                        while not re.search(r"(^\s+(\d+)|^\s-+)", line):
                            icname = line.split()[0].strip()
                            if icname in data["coords"]:
                                data["coords"][icname] += floatList(float_patt.findall(line))
                            else:
                                data["coords"][icname] = floatList(float_patt.findall(line))
                            line = f.readline()
                        if re.search(r"^\s-+", line):
                            endScan = True
                        else:
                            line = f.readline()

                elif scan_patt.match(line):
                    line = f.readline()
                    data["coords"] = {icname: list()
                                      for icname in line.split()[1:-1]}
                    f.readline()
                    line = f.readline()
                    while not re.search(r"^\s-+", line):
                        values = floatList(line.split())
                        data["energies"].append(values[-1])
                        for i, icname in enumerate(data["coords"]):
                            data["coords"][icname].append(values[i+1])
                        line = f.readline()
                else:
                    line = f.readline()

        return data