예제 #1
0
def makeTimeSeriesContainer(station, interval, tz, records, decodeInfo):
    global timezones
    sdf = SimpleDateFormat("ddMMMyyyy, HH:mm")
    if dssTimezone:
        if not timezones["DSS"]:
            timezones["DSS"] = TimeZone.getTimeZone(
                tzInfo[dssTimezone]["JAVA"])
        sdf.setTimeZone(timezones["DSS"])
    else:
        sdf.setTimeZone(timezones["USGS"])
    dd, decodeInfo = decodeInfo
    cal = Calendar.getInstance()
    t = HecTime()
    tsc = TimeSeriesContainer()
    tsc.interval = interval
    times = []
    values = []
    tsc.quality = None
    factor = decodeInfo["DSS_FACTOR"]
    for j in range(len(records)):
        millis, value = records[j]
        cal.setTimeInMillis(millis)
        t.set(sdf.format(cal.getTime()))
        times.append(t.value())
        try:
            values.append(float(value) * factor)
        except:
            values.append(Constants.UNDEFINED)
    tsc.times = times
    tsc.values = values
    tsc.startTime = times[0]
    tsc.endTime = times[-1]
    tsc.numberValues = len(values)
    tsc.timeZoneID = sdf.getTimeZone().getID()
    tsc.timeZoneRawOffset = sdf.getTimeZone().getRawOffset()
    return tsc
예제 #2
0
def makeTimeSeriesContainer(tsData, timeZone, pathname=None):
    '''
	Construct a TimeSeriesContainer object from a python dictionary that was
	created from a single "time-series" returned from the CWMS RADAR web
	service
	'''
    #---------------#
    # initial setup #
    #---------------#
    tsc = None
    try:
        tz = TimeZone.getTimeZone(timeZone)
        sdf8601 = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX")
        sdfHecTime = SimpleDateFormat("ddMMMyyyy, HH:mm")
        cal = Calendar.getInstance()
        for obj in sdf8601, sdfHecTime, cal:
            obj.setTimeZone(tz)
        ht = HecTime()
        times, values, qualities = [], [], []
        #------------------#
        # process the data #
        #------------------#
        if tsData.has_key("regular-interval-values"):
            #----------------------------------------#
            # regular time series (a lot to process) #
            #----------------------------------------#
            rts = tsData["regular-interval-values"]
            intvlStr = rts["interval"]
            unit = rts["unit"].split()[0]
            if intvlStr.startswith("PT"):
                intvlNum, intvlUnit = int(intvlStr[2:-1]), intvlStr[-1]
                try:
                    factor, field = {
                        "M": (1, Calendar.MINUTE),
                        "H": (60, Calendar.HOUR_OF_DAY)
                    }[intvlUnit]
                except KeyError:
                    raise Exception("Unexpected interval: %s" % intvlStr)
            else:
                intvlNum, intvlUnit = int(intvlStr[1:-1]), intvlStr[-1]
                try:
                    factor, field = {
                        "Y": (1440 * 365, Calendar.YEAR),
                        "M": (1440 * 30, Calendar.MONTH),
                        "D": (1440, Calendar.DATE)
                    }[intvlUnit]
                except KeyError:
                    raise Exception("Unexpected interval: %s" % intvlStr)
            intvl = intvlNum * factor
            segmentCount = rts["segment-count"]
            cal.setTimeInMillis(
                sdf8601.parse(rts["segments"][0]["first-time"]).getTime())
            for i in range(segmentCount):
                for j in range(rts["segments"][i]["value-count"]):
                    ht.set(sdfHecTime.format(cal.getTimeInMillis()))
                    v, q = rts["segments"][i]["values"][j]
                    times.append(ht.value())
                    values.append(v)
                    qualities.append(q)
                    cal.add(field, intvlNum)
                if i < segmentCount - 1:
                    nextBegin = sdf8601.parse(
                        rts["segments"][i + 1]["first-time"]).getTime()
                    time = cal.getTimeInMillis()
                    while time < nextBegin:
                        ht.set(sdfHecTime.format(time))
                        times.append(ht.value())
                        values.append(Constants.UNDEFINED)
                        qualities.append(0)
                        cal.add(field, intvlNum)
                        time = cal.getTimeInMillis()
        elif tsData.has_key("irregular-interval-values"):
            #------------------------------#
            # irregular time series (easy) #
            #------------------------------#
            its = tsData["irregular-interval-values"]
            unit = its["unit"].split()[0]
            intvl = 0
            for t, v, q in its["values"]:
                ht.set(sdfHecTime.format(sdf8601.parse(t)))
                times.append(ht.value())
                values.append(v)
                qualities.append(q)
        else:
            raise Exception("Time series has no values")
        #--------------------------------------------------#
        # code common to regular and irregular time series #
        #--------------------------------------------------#
        tsc = TimeSeriesContainer()
        tsc.times = times
        tsc.values = values
        tsc.quality = qualities
        tsc.numberValues = len(times)
        tsc.startTime = times[0]
        tsc.endTime = times[-1]
        tsc.interval = intvl
        tsc.units = unit
        tsc.timeZoneID = timeZone
        tsc.timeZoneRawOffset = tz.getRawOffset()

        name = tsData["name"]
        loc, param, paramType, intv, dur, ver = name.split(".")
        if pathname:
            #---------------------------#
            # use pathname if specified #
            #---------------------------#
            A, B, C, D, E, F = 1, 2, 3, 4, 5, 6
            parts = pathname.split("/")
            parts[D] = ''
            tsc.fullName = "/".join(parts)
            tsc.watershed = parts[A]
            try:
                tsc.location, tsc.subLocation = parts[B].split("-", 1)
            except:
                tsc.location = parts[B]
            try:
                tsc.parameter, tsc.subParameter = parts[C].split("-", 1)
            except:
                tsc.parameter = parts[C]
            try:
                tsc.version, tsc.subVersion = parts[F].split("-", 1)
            except:
                tsc.version = parts[F]
        else:
            #--------------------------------------#
            # no pathname, use CWMS time series id #
            #--------------------------------------#
            try:
                tsc.location, tsc.subLocation = loc.split("-", 1)
            except:
                tsc.location = loc
            try:
                tsc.parameter, tsc.subParameter = param.split("-", 1)
            except:
                tsc.parameter = param
            try:
                tsc.version, tsc.subVersion = ver.split("-", 1)
            except:
                tsc.version = ver
        tsc.type = {
            "Total": "PER-CUM",
            "Max": "PER-MAX",
            "Min": "PER-MIN",
            "Const": "INST-VAL",
            "Ave": "PER-AVER",
            "Inst": ("INST-VAL", "INST-CUM")[param.startswith("Precip")]
        }[paramType]
    except:
        output(traceback.format_exc())
    return tsc
예제 #3
0
def put_to_dss(site, dss):
    """Save timeseries to DSS File
    
    Parameters
    ----------
    site: json
        JSON object containing meta data about the site/parameter combination,
        time array and value array
    dss: HecDss DSS file object
        The open DSS file records are written to
    Returns
    -------
    None
    
    Raises
    ------
    Put to DSS exception handled with a message output saying site not saved, but
    continues on trying additional site/parameter combinations
    """
    
    Site = namedtuple(
        'Site',
        site.keys()
    )(**site)
    parameter, unit, data_type, version = usgs_code[Site.code]
    times = [
        HecTime(t, HecTime.MINUTE_GRANULARITY).value()
        for t in Site.times
    ]
    
    timestep_min = None
    for i, t in enumerate(range(len(times) - 1)):
        ts = abs(times[t + 1] - times[t])
        if ts < timestep_min or timestep_min is None:
            timestep_min = ts
    epart = TimeStep().getEPartFromIntervalMinutes(timestep_min)
    # Set the pathname
    pathname = '/{0}/{1}/{2}//{3}/{4}/'.format(ws_name, Site.site_number, parameter, epart, version).upper()
    apart, bpart, cpart, _, _, fpart = pathname.split('/')[1:-1]
    
    container = TimeSeriesContainer()
    container.fullName     = pathname
    container.location     = apart
    container.parameter    = parameter
    container.type         = data_type
    container.version      = version
    container.interval     = timestep_min
    container.units        = unit
    container.times        = times
    container.values       = Site.values
    container.numberValues = len(Site.times)
    container.startTime    = times[0]
    container.endTime      = times[-1]
    container.timeZoneID   = tz
    # container.makeAscending()
    if not TimeSeriesMath.checkTimeSeries(container):
        return 'Site: "{}" not saved to DSS'.format(Site.site_number)
    tsc = TimeSeriesFunctions.snapToRegularInterval(container, epart, "0MIN", "0MIN", "0MIN")
    # Put the data to DSS
    try:
        dss.put(tsc)
    except Exception as ex:
        print(ex)
        return 'Site: "{}" not saved to DSS'.format(Site.site_number)