Beispiel #1
0
 def loadNetworkAttribute(self, filename):
     if self.networkCode is None:
         raise Exception("Cannot load Network att without network code")
     if self.stationList is None:
         raise Exception("Cannot load Network att without station list")
     try:
         na = NetworkAttributes(self.networkCode, filename)
         self.nat = na
     except Exception as e:
         raise e
Beispiel #2
0
    def convert(self, fdo, keepcomments=False, atFront=True):
        if self.filename is None:
            raise Exception(
                "You should pre-load a tab file before before converting.")

        ## Obtain additional attribute classes if needed
        if not self.nat:
            self.nat = NetworkAttributes(self.networkCode, None)
        if not self.sat:
            self.sat = StationAttributes(self.networkCode, self.stationList,
                                         None)
        if not self.sma:
            self.sma = StationMappings(self.networkCode, self.stationList,
                                       None)

        # Parse in again the station lines and network header by the additional classes
        print("Pre-Parsing Station/Network lines ... ", file=sys.stderr)
        fd = open(self.filename)
        for line in fd:
            line = line.strip()
            if not line or line[0] == "#":
                continue
            items = line.split()
            if len(items) <= 5:
                self.nat.parseNetworkLine(items)
            elif len(items) <= 12:
                self.sma.parseStationLine(items)
                self.sat.parseStationLine(items)
        fd.close()

        fd = open(self.filename)
        oldcode = ""  # Station code of the last printed line
        last = ""  # Type of the last printed line
        print("Converting ... ", file=sys.stderr)
        for line in fd:
            line = line.strip()
            if not line or line[0] == "#":
                if last == "l" or last == "a" or last == "h": fdo.write("\n")
                if keepcomments: fdo.write(line + "\n")
                last = "c"
                continue
            items = line.split()
            if len(items) <= 5:
                self.__convertHeader__(line, fdo)
                last = "h"
                if (atFront):
                    fdo.write("\n")
                    self.sma.dump(fdo, None)
                    self.sat.dump(fdo, None)
                    last = "a"
                    fdo.write("\n")
            elif len(items) <= 12:
                if (last == "l"
                        and items[0].strip() != oldcode) or last == "h":
                    fdo.write("\n")
                oldcode = self.__convertLine__(line, fdo, atFront)
                last = "l"
                pass
            else:
                print("input at %s" % line, file=sys.stderr)
        fd.close()
Beispiel #3
0
class TabConverter:
    def __init__(self, networkCode):
        self.__fmt__ = None
        self.takeSugestions = None

        self.filename = None

        self.networkCode = networkCode
        self.stationList = None

        self.nat = None
        self.sat = None
        self.sma = None
        self.inst = None
        self.defaultEpoch = parseDate("1980/001")

        self.start = 0
        self.code = 0
        self.description = 0
        self.datalogger = 0
        self.sensor = 0
        self.channel = 0
        self.gaind = 0
        self.longitude = 0
        self.latitude = 0
        self.elevation = 0
        self.end = 0
        self.depth = 0
        self.orientation = 0

        ## default dates
        self.startDate = parseDate("1980/001")
        self.endDate = parseDate(None)

    def loadStationMapping(self, filename):
        if self.networkCode is None:
            raise Exception("Cannot load Station mapping without network code")
        if self.stationList is None:
            raise Exception("Cannot load Station mapping without station list")

        try:
            sm = StationMappings(self.networkCode, self.stationList, filename)
            self.sma = sm
        except Exception as e:
            raise e

    def loadStationAttribute(self, filename):
        if self.networkCode is None:
            raise Exception("Cannot load Station att without network code")
        if self.stationList is None:
            raise Exception("Cannot load Station att without station list")

        try:
            sa = StationAttributes(self.networkCode, self.stationList,
                                   filename)
            self.sat = sa
        except Exception as e:
            raise e

    def loadNetworkAttribute(self, filename):
        if self.networkCode is None:
            raise Exception("Cannot load Network att without network code")
        if self.stationList is None:
            raise Exception("Cannot load Network att without station list")
        try:
            na = NetworkAttributes(self.networkCode, filename)
            self.nat = na
        except Exception as e:
            raise e

    def loadInstrumentsFile(self, filename, filterFolder):
        tab = Tab(filterFolder=filterFolder)
        tab.digest(filename)
        if tab.i:
            self.inst = tab.i

    def __fmtline__(self):
        if not self.__fmt__:
            fmt = "Sl: "
            fmt += "%%-%ds" % self.code
            fmt += " %%-%ds" % self.description
            fmt += " %%-%ds" % self.datalogger
            fmt += " %%-%ds" % self.sensor
            fmt += " %%-%ds" % self.channel
            fmt += " %%-%ds" % self.orientation
            fmt += " %%-%ds" % self.latitude
            fmt += " %%-%ds" % self.longitude
            fmt += " %%-%ds" % self.elevation
            fmt += " %%-%ds" % self.depth
            fmt += " %%-%ds" % self.start
            fmt += " %%-%ds" % self.end
            self.__fmt__ = fmt

        return self.__fmt__

    def __analyseLine__(self, items):
        inputLine = " ".join(items)
        if len(items) < 4:
            raise Exception("Invalid items count on line %s" % inputLine)

        if len(items) <= 5:
            netCode = items[2]
            if netCode != self.networkCode:
                raise Exception(
                    "Tab file (%s) doesn't match class (%s) -- %s" %
                    (netCode, self.networkCode, inputLine))
            return [None, None, None]
        else:
            if len(items) < 6:
                raise Exception("Invalid Station line %s" % inputLine)

            stationCode = items.pop(0)
            code = len(stationCode)
            self.code = max(self.code, code)

            description = len(quote(hummanStr(items.pop(0))))
            self.description = max(self.description, description)

            datalogger = len(items.pop(0))
            self.datalogger = max(self.datalogger, datalogger)

            sensor = len(items.pop(0))
            self.sensor = max(self.sensor, sensor)

            # Gain
            gaind = items.pop(0)
            if float(gaind) != 1.0:
                self.datalogger = max(self.datalogger, datalogger + len(gaind))

            channel = len(items.pop(0))
            self.channel = max(self.channel, channel)

            latitude = len(items.pop(0))
            self.latitude = max(self.latitude, latitude)

            longitude = len(items.pop(0))
            self.longitude = max(self.longitude, longitude)

            elevation = len(items.pop(0))
            self.elevation = max(self.elevation, elevation)

            #Orientation
            depth = items.pop(0)
            try:
                float(depth)
                orientation = "ZNE"
            except:
                orientation = "Z"
                (depth, a1, a2) = depth.split("/")

                a1n = float(a1)
                a2n = float(a2)

                orientation += "1"
                if a1n != 0.0: orientation += "(0.0,%s)" % a1

                orientation += "2"
                if a2n != 90.0: orientation += "(0.0,%s)" % a1

            orientation = len(orientation)
            self.orientation = max(self.orientation, orientation)

            depth = len(depth)
            self.depth = max(self.depth, depth)

            # Start
            try:
                start = parseDate(items.pop(0))
                self.start = max(self.start, len(formatDate(start)))
            except:
                raise Exception("Invalid Station line start date %s" %
                                inputLine)

            # End
            try:
                end = parseDate(items.pop(0))
            except:
                end = parseDate("")
                pass
            self.end = max(self.end, len(formatDate(end)))

            return [stationCode, start, end]

    def preload(self, filename, takeSugestions):
        self.takeSugestions = takeSugestions
        sugestedStart = datetime.now()
        sugestedEnd = self.defaultEpoch
        stationList = []

        error = []

        # Some initialization
        if self.filename is not None:
            raise Exception(
                "Cannot pre-load two different files (current one is %s)" %
                self.filename)

        print("Analysing ... ", file=sys.stderr)
        fd = open(filename)
        for line in fd:
            line = line.strip()
            if not line or line[0] == "#": continue

            try:
                (stationCode, start, end) = self.__analyseLine__(line.split())
            except Exception as e:
                error.append(str(e))
                continue

            if not stationCode: continue
            if stationCode not in stationList:
                stationList.append(stationCode)

            sugestedStart = min(sugestedStart, start)
            if end and sugestedEnd:
                sugestedEnd = max(sugestedEnd, end)
            else:
                sugestedEnd = None
        fd.close()

        if len(error):
            raise Exception("\n".join(error))

        print(" Loaded %d different stations" % len(stationList),
              file=sys.stderr)
        if takeSugestions:
            print(" Taking suggestion start date of %s " %
                  formatDate(self.startDate),
                  file=sys.stderr)
            self.startDate = sugestedStart
            print(" Taking suggestion end date of %s " %
                  formatDate(self.endDate),
                  file=sys.stderr)
            self.endDate = sugestedEnd

        self.filename = filename
        self.stationList = stationList
        print("Done.", file=sys.stderr)

    def __convertHeader__(self, line, fdo):

        # Split line
        items = line.split()

        if not self.takeSugestions:
            if self.nat.hasStart:
                print(" Using start from attribute.", file=sys.stderr)
                self.startDate = self.nat.startDate
            if self.nat.hasEnd:
                print(" Using end from attribute.", file=sys.stderr)
                self.endDate = self.nat.endDate

        nCode = items[2].strip()
        if nCode != self.networkCode:
            raise Exception("Wrong network code found: %s != %s" %
                            (self.networkCode, nCode))

        fdo.write(
            "Nw: %s %s %s" %
            (nCode, formatDate(self.startDate), formatDate(self.endDate)) +
            "\n")

        self.nat.dump(fdo)

    def __convertLine__(self, line, fdo, atFront):
        lnfmt = self.__fmtline__()

        # Split line
        items = line.split()

        try:
            code = items.pop(0)
        except Exception as e:
            raise Exception("Missing Code on %s" % line)

        if code not in self.stationList:
            raise Exception("Unknow station code $s" % code)

        try:
            hummanStr(items.pop(0))
        except Exception as e:
            raise Exception("Missing Gain on %s" % line)

        try:
            datalogger = items.pop(0)
        except Exception as e:
            raise Exception("Missing Datalogger on %s" % line)

        try:
            sensor = items.pop(0)
        except Exception as e:
            raise Exception("Missing Sensor on %s" % line)

        try:
            gaind = items.pop(0)
            if float(gaind) != 1.0:
                if not self.inst:
                    raise Exception(
                        "Instrument database needed to convert gain")
                try:
                    dte = self.inst.dls[str(datalogger).split("%")[0]]
                except Exception as e:
                    print(e, file=sys.stderr)
                    raise Exception("Datalogger %s not found" %
                                    str(datalogger).split("%")[0])
                datalogger += "%%%s" % (float(dte.gain) * float(gaind))
                print(
                    " Converting gain multiplier to real gain using instrument DB on %s"
                    % code,
                    file=sys.stderr)
        except Exception as e:
            raise Exception("Missing Gain on %s (%s)" % (line, str(e)))

        try:
            channel = items.pop(0)
        except Exception as e:
            raise Exception("Missing Channel on %s" % line)

        try:
            latitude = items.pop(0)
        except Exception as e:
            raise Exception("Missing Latitude on %s" % line)

        try:
            longitude = items.pop(0)
        except Exception as e:
            raise Exception("Missing Longitude on %s" % line)
        try:
            elevation = items.pop(0)
        except Exception as e:
            raise Exception("Missing Elevation on %s" % line)

        try:
            depth = items.pop(0)
        except Exception as e:
            raise Exception("Missing Depth on %s" % line)

        #Orientation
        try:
            float(depth)
            orientation = "ZNE"
        except:
            orientation = "Z"
            (depth, a1, a2) = depth.split("/")

            a1n = float(a1)
            if a1n == 0.0:
                orientation += "1"
            else:
                orientation += "1(0.0,%s)" % a1

            a2n = float(a2)
            if a2n == 90.0:
                orientation += "2"
            else:
                orientation += "2(0.0,%s)" % a2

        # Start
        try:
            start = items.pop(0)
        except Exception:
            raise Exception("Missing Start on %s" % line)

        try:
            start = parseDate(start)
        except Exception as e:
            raise Exception("Invalide Start date: %s (%s) on %s" %
                            (start, e, line))

        #End
        try:
            end = items.pop(0)
        except:
            end = ""

        try:
            end = parseDate(end)
        except Exception as e:
            raise Exception("Invalide End date: %s (%s) on %s" %
                            (end, e, line))

        [place, country] = self.sat.parseStationLine(line.split())
        description = "%s/%s" % (place, country)

        ## Prepare necessary output
        if not atFront:
            self.sma.dump(fdo, code)
            self.sat.dump(fdo, code)

        for (start, end) in self.sma.getMappings(code, start, end):
            fdo.write(lnfmt %
                      (code, quote(description), datalogger, sensor, channel,
                       orientation, latitude, longitude, elevation, depth,
                       formatDate(start), formatDate(end)) + "\n")

        return code

    def convert(self, fdo, keepcomments=False, atFront=True):
        if self.filename is None:
            raise Exception(
                "You should pre-load a tab file before before converting.")

        ## Obtain additional attribute classes if needed
        if not self.nat:
            self.nat = NetworkAttributes(self.networkCode, None)
        if not self.sat:
            self.sat = StationAttributes(self.networkCode, self.stationList,
                                         None)
        if not self.sma:
            self.sma = StationMappings(self.networkCode, self.stationList,
                                       None)

        # Parse in again the station lines and network header by the additional classes
        print("Pre-Parsing Station/Network lines ... ", file=sys.stderr)
        fd = open(self.filename)
        for line in fd:
            line = line.strip()
            if not line or line[0] == "#":
                continue
            items = line.split()
            if len(items) <= 5:
                self.nat.parseNetworkLine(items)
            elif len(items) <= 12:
                self.sma.parseStationLine(items)
                self.sat.parseStationLine(items)
        fd.close()

        fd = open(self.filename)
        oldcode = ""  # Station code of the last printed line
        last = ""  # Type of the last printed line
        print("Converting ... ", file=sys.stderr)
        for line in fd:
            line = line.strip()
            if not line or line[0] == "#":
                if last == "l" or last == "a" or last == "h": fdo.write("\n")
                if keepcomments: fdo.write(line + "\n")
                last = "c"
                continue
            items = line.split()
            if len(items) <= 5:
                self.__convertHeader__(line, fdo)
                last = "h"
                if (atFront):
                    fdo.write("\n")
                    self.sma.dump(fdo, None)
                    self.sat.dump(fdo, None)
                    last = "a"
                    fdo.write("\n")
            elif len(items) <= 12:
                if (last == "l"
                        and items[0].strip() != oldcode) or last == "h":
                    fdo.write("\n")
                oldcode = self.__convertLine__(line, fdo, atFront)
                last = "l"
                pass
            else:
                print("input at %s" % line, file=sys.stderr)
        fd.close()