def generateYearsArray(start_year, end_year, **kwargs):
    first_year = asDatetime(start_year)
    last_year = asDatetime(end_year)
    interval = relativedelta(years=int(kwargs.get('interval', 1)))
    date_format = kwargs.get('date_format', None)
    as_numpy = kwargs.get('as_numpy', True)

    years = []
    date = first_year
    if date_format in (datetime, object, 'object'):
        while date <= last_year:
            years.append(date)
            date += interval
        dtype = 'object'
        as_numpy = False

    elif date_format in (int, 'int'):
        while date <= last_year:
            years.append(date.year)
            date += interval
        dtype = 'i2'

    else:
        if date_format is None: date_format = '%Y'
        while date <= last_year:
            years.append(date.strftime(date_format))
            date += interval
        dtype = '|S%d' % len(years[0])

    if as_numpy: return N.array(years, dtype=dtype)
    else: return tuple(years)
 def listDates(self, interval_start, interval_end, interval=None):
     if interval is None: _interval = self.interval
     else: _interval = interval
     dates = []
     date = asDatetime(interval_start)
     while date <= asDatetime(interval_end):
         dates.append(date)
         date = monthsInterval(date, _interval)
     return tuple(dates)
 def listDates(self, interval_start, interval_end, interval=None):
     if interval is None: num_days = relativedelta(days=self.interval)
     else: num_days = relativedelta(days=interval)
     dates = []
     date = asDatetime(interval_start)
     while date <= asDatetime(interval_end):
         dates.append(date)
         date += num_days
     return tuple(dates)
    def setTimeSpan(self, iter_start, iter_end):
        if isinstance(iter_start, (list, tuple)) and len(iter_start) == 2:
            iter_start = (iter_start[0], iter_start[1],
                          lastDayOfMonth(*iter_start))
        self.iter_start = asDatetime(iter_start)

        if isinstance(iter_end, (list, tuple)) and len(iter_end) == 2:
            iter_end = (iter_end[0], iter_end[1], lastDayOfMonth(*iter_end))
        self.iter_end = asDatetime(iter_end)
Beispiel #5
0
def generateHoursArray(first_hour, last_hour):
    hour = asDatetime(first_hour)
    last_hour = asDatetime(last_hour)
    interval = relativedelta(hours=1)
    hours = []
    while hour <= last_hour:
        int_date = (hour.year * 1000000) + (hour.month * 10000)
        int_date += (hour.day * 100) + hour.hour
        hours.append(int_date)
        hour += interval
    return N.array(hours, dtype='i4')
Beispiel #6
0
 def _validTimes(self, start_time, end_time):
     """ returns tuple containing index of start_time and index of end_time
     """
     if start_time is None or start_time == ':':
         if end_time is None: return self.base_time, self.base_time
         elif end_time == ':': return self.base_time, self.last_time
         return self.base_time, asDatetime(end_time)
     else:
         _start_time = asDatetime(start_time)
         if end_time is None: return _start_time, _start_time 
         elif end_time == ':': return _start_time, self.last_time
         return _start_time, asDatetime(end_time)
Beispiel #7
0
 def _indexForTime(_time):
     date_time = asDatetime(_time)
     years = date_time.year - self.base_time.year
     months = years * 12
     if date_time.month != 12: months -= (12 - date_time.month)
     if self.base_time.month != 1: months -= self.base_time.month - 1
     return months
    def __call__(self, date, stats_matrix, data):
        num_hours = len(data)
        front_cushion = self.cushions[0]
        end_index = num_hours - self.cushions[1]
        self.detected = []
        if self.isvalid is None:
            self.isvalid = [True for item in data]
            has_valid_data = True
        else:
            has_valid_data = self.hasValidData()

        if not has_valid_data: return
        # detect all sequences ... don't use filters for now
        detected = self.detector(data, 0, end_index)
        if len(detected) == 0: return

        # validate against Period of Record
        stats = stats_matrix[asDatetime(date).month]
        mean = stats[3]
        stddev = stats[5]

        for severity in self.severities:
            num_stddevs = self.stddevs[severity]
            limit = mean + (num_stddevs * stddev)

            for value, length, end_index in detected:
                if end_index < front_cushion: continue
                if length > limit and self.isvalid[end_index]:
                    end_hour = self.hourFromIndex(end_index)
                    detail = (severity, 'seq', end_hour, value, length, limit,
                              num_stddevs)
                    self._capture(end_index, detail)
Beispiel #9
0
 def _indexForTime(_time):
     delta = asDatetime(_time) - self.base_time
     hours = (delta.days * 24) + (delta.seconds / 3600)
     indx = hours / interval
     over = hours % interval
     if over > 0: return indx + 1
     else: return indx
    def __call__(self, date, stats_matrix, data, isvalid=None):
        num_hours = len(data)
        start_index = self.cushions[0] - 1
        end_index = (num_hours - self.cushions[1]) + 1
        self.detected = []
        if self.isvalid is None:
            self.isvalid = [True for item in data]
            has_valid_data = True
        else:
            has_valid_data = self.hasValidData()

        if not has_valid_data: return
        # detect any spikes ... don't use filters for now
        detected = self.detector(data, start_index, end_index)
        if len(detected) == 0: return

        # validate against Period of Record for the month
        stats = stats_matrix[asDatetime(date).month]
        mean = stats[3]
        stddev = stats[5]

        for severity in self.severities:
            num_stddevs = self.stddevs[severity]
            limit = mean + (num_stddevs * stddev)

            for spike, indx, value in detected:
                magnitude = min(abs(spike[0]), abs(spike[1]))
                if magnitude > limit and self.isvalid[indx]:
                    hour = self.hourFromIndex(indx)
                    detail = (severity, 'spk', hour, value, spike, limit,
                              num_stddevs)
                    self._capture(indx, detail)
 def index(self, date_time):
     _date_time = asDatetime(date_time)
     if _date_time == self.base_time: return 0
     delta = _date_time - self.base_time
     hours = (delta.days * 24) + (delta.seconds / 3600)
     if (hours % self.interval) == 0: return hours / self.interval
     else: return (hours + self.interval) / self.interval
    def __init__(self,
                 time_series,
                 start_time=None,
                 end_time=None,
                 interval=None,
                 duration=None):
        """ handles instances of the TimeSeriesData class or it's
            subclassses
        """
        if start_time is None: iter_start = time_series.common_start_time
        else: iter_start = asDatetime(start_time)
        if end_time is None: iter_end = time_series.common_end_time
        else: iter_end = asDatetime(end_time)
        if interval is None: interval = time_series.interval
        if duration is None: duration = time_series.interval

        self.iterator = timeIterator(time_series.frequency, iter_start,
                                     iter_end, interval, duration)
def generateHoursArray(start_hour, end_hour, **kwargs):
    first_hour = asDatetime(start_hour)
    last_hour = asDatetime(end_hour)
    interval = relativedelta(hours=int(kwargs.get('interval', 1)))
    date_format = kwargs.get('date_format', None)
    as_numpy = kwargs.get('as_numpy', True)

    hours = []
    hour = first_hour
    if date_format in (datetime, object, 'object'):
        while hour <= last_hour:
            hours.append(hour)
            hour += interval
        dtype = 'object'
        as_numpy = False

    elif date_format in (int, 'int'):
        while hour <= last_hour:
            hours.append((hour.year * 1000000) + (hour.month * 10000) +
                         (hour.day * 100) + hour.hour)
            hour += interval
        dtype = N.dtype(int)

    elif date_format == 'tuple':
        while hour <= last_hour:
            hours.append((hour.year, hour.month, hour.day, hour.hour))
            hour += interval
        dtype = N.dtype({
            'names': ['year', 'month', 'day', 'hour'],
            'formats': ['i2', 'i2', 'i2', 'i2']
        })

    else:
        if date_format is None: date_format = '%Y-%m-%d-%H'
        while hour <= last_hour:
            hours.append(hour.strftime(date_format))
            hour += interval
        dtype = '|S%d' % len(hours[0])

    if as_numpy: return N.array(hours, dtype=dtype)
    else: return tuple(hours)
    def __init__(self,
                 time_series,
                 start_time=None,
                 end_time=None,
                 interval=None,
                 duration=None):
        """ handles instances of the MultiTimeSeries class or it's
            subclassses
        """
        #TODO : handle 2D arrays
        if start_time is None: iter_start = time_series.common_start_time
        else: iter_start = asDatetime(start_time)
        if end_time is None: iter_end = time_series.common_end_time
        else: iter_end = asDatetime(end_time)
        if interval is None: interval = time_series.interval
        if duration is None: duration = time_series.interval

        self.dataset_names = time_series.dataset_names
        self.indexers = time_series.indexers
        self.iterator = timeIterator(time_series.frequency, iter_start,
                                     iter_end, interval, duration)
def generateDaysArray(start_date, end_date, **kwargs):
    first_date = asDatetime(start_date)
    last_date = asDatetime(end_date)
    interval = relativedelta(days=int(kwargs.get('interval', 1)))
    date_format = kwargs.get('date_format', None)
    as_numpy = kwargs.get('as_numpy', True)

    days = []
    date = first_date
    if date_format in (datetime, object, 'object'):
        while date <= last_date:
            days.append(date)
            date += interval
        dtype = 'object'
        as_numpy = False

    elif date_format in (int, 'int'):
        while date <= date_hour:
            days.append((date.year * 10000) + (date.month * 100) + date.day)
            date += interval
        dtype = int

    elif date_format == 'tuple':
        while date <= last_date:
            days.append((date.year, date.month, date.day))
            date += interval
        dtype = N.dtype({
            'names': ['year', 'month', 'day'],
            'formats': ['i2', 'i2', 'i2']
        })

    else:
        if date_format is None: date_format = '%Y-%m-%d'
        while date <= last_date:
            days.append(date.strftime(date_format))
            date += interval
        dtype = '|S%d' % len(days[0])

    if as_numpy: return N.array(days, dtype=dtype)
    else: return tuple(days)
    def index(self, date_time):
        _date_time = asDatetime(date_time)
        _base_time = self.base_time
        if _date_time.year == _base_time.year\
        and _date_time.month == _base_time.month:
            return 0

        _interval = self.interval
        # index may be negative if date_time is earlier than base_time
        years = _date_time.year - _base_time.year
        if years == 0:  # both in same year
            months = _date_time.month - _base_time.month
        else:  # different years
            months = (years * 12) + (_date_time.month - _base_time.month)
        if (months % _interval) == 0: return months / _interval
        else: return (months + _interval) / _interval
Beispiel #17
0
def getStationData(factory, station, _date_, dataset_name, cushion=0):
    _datetime_ = asDatetime(_date_)
    start_time = (_datetime_ - relativedelta(days=1)) + relativedelta(hours=8)
    end_time = _datetime_ + relativedelta(hours=7)
    if cushion != 0:
        start_time -= relativedelta(hours=cushion)
        end_time += relativedelta(hours=cushion)

    start_time = dateAsTuple(start_time, True)
    end_time = dateAsTuple(end_time, True)
    ucan = HourlyDataConnection(days_per_request=1)
    _start_date_, _end_date_, data =\
    ucan.getData(station, dataset_name, start_time, end_time)
    data = N.array(data)
    data[N.where(N.isinf(data))] = N.nan
    return datetime(*_start_date_), datetime(*_end_date_), data
def getStationPrecip(factory, station, _date_, cushion=0, test_run=False):
    _datetime_ = asDatetime(_date_)
    start_time = _datetime_ - ONE_DAY + relativedelta(hours=7)
    end_time = _datetime_ + relativedelta(hours=7)
    if cushion != 0:
        start_time -= relativedelta(hours=cushion)
        end_time += relativedelta(hours=cushion)

    if test_run:
        if station['sid'] == STATION_CACHE['sid']:
            data = STATION_CACHE['data']
            dates = STATION_CACHE['dates']
        else:
            # hourly data file must already exist
            filepath = factory.getFilepathForUcanid(station['ucanid'], 'hours')
            if not os.path.exists(filepath):
                print SKIP_MSG % station
                print 'Hourly data file does not exist : %s' % filepath
                return None
            manager = HDF5DataFileManager(filepath, 'r')
            data = manager.getData('pcpn.value')
            STATION_CACHE['data'] = data
            dates = manager.getData('pcpn.date')
            STATION_CACHE['dates'] = dates
            STATION_CACHE['sid'] = station['sid']

        _start_time = dateAsInt(start_time, True)
        _end_time = dateAsInt(end_time, True)
        indexes = N.where((dates > (_start_time - 1)) & (dates < _end_time))
        if len(indexes[0]) > 0: return data[indexes]
        return None

    else:
        start_time = dateAsTuple(start_time, True)
        end_time = dateAsTuple(end_time, True)
        ucan = HourlyDataConnection(days_per_request=1)
        _start_date_, _end_date_, precip =\
        ucan.getData(station, 'pcpn', start_time, end_time)
        precip = N.array(precip)
        precip[N.where(N.isinf(precip))] = N.nan
        return precip
    def __call__(self, date, stats_matrix, data):
        start_index = self.cushions[0]
        num_hours = len(data)
        end_index = num_hours - self.cushions[1]
        self.detected = []
        if self.isvalid is None:
            self.isvalid = [True for item in data]

        # validate against physical extremes
        missing_ = self._validate_(date, data, start_index, end_index)
        if not self.hasValidData(): return missing_

        # needed for validatation against Period of Record for the month
        stats = stats_matrix[asDatetime(date).month]
        mean = stats[3]
        stddev = stats[5]

        for severity in self.severities:
            num_stddevs = self.stddevs[severity]
            upper_limit = mean + (num_stddevs * stddev)
            lower_limit = mean - (num_stddevs * stddev)

            indx = start_index
            while indx < end_index:
                if self.isvalid[indx]:
                    value = data[indx]
                    if value > upper_limit:
                        hour = self.hourFromIndex(indx)
                        detail = (severity, 'exts', hour, value, upper_limit,
                                  num_stddevs)
                        self._capture(indx, detail)
                    elif value < lower_limit:
                        detail = (severity, 'exts', hour, value, lower_limit,
                                  -num_stddevs)
                        self._capture(indx, detail)
                indx += 1

        return missing_
    def __init__(self, *data_info):
        """
        Multiple dataset time series.
        
        All datasets must be the same frequency and interval.

        Arguments
        ---------
            data_info : information tuples, one for each dataset
                        (name, data, base_time, data_attrs)
                name : name of dataset
                data : numpy array containing data
                base_time : date of first item in array
                data_attrs : data attributes dictionary
                    as a minimum it should have the following:
                    value_type : The type of data in the time series data set.
                         'linear' indicates linear data (i.e. data linearly
                                  increases or decrease from one value to
                                  another to the decimal precision of the 
                                  software).
                         'discrete' is similar to 'linear' except thot
                                    values may only be whole numbers.
                         'direction' indicates data consisting spherical
                                     compass directions (i.e. values from 0 to
                                     360 valid).
                          The defualt is 'linear'.
                          If a tuple/list is passed, the first item must
                          be the type, followed by the lower value limit,
                          then the upper value limit)
                    missing : value that indicates missing data
                    frequency : frequency of the data (i.e. 'hour','day',etc.)
                                Default is 'hour'.
                    interval : number of time units between entries in the
                               data array. Default is 1.
        """
        #TODO : handle 2D arrays

        frequency = str(data_info[0][-1].get('frequency', 'hour'))
        self.frequency = frequency
        interval = int(data_info[0][-1].get('interval', 1))
        self.interval = interval

        if frequency == 'hour':

            def _relativeDelta(interval):
                return relativedelta(hours=interval)
        elif frequency == 'day':

            def _relativeDelta(interval):
                return relativedelta(days=interval)
        elif frequency == 'month':

            def _relativeDelta(interval):
                return relativedelta(months=interval)
        elif frequency == 'year':

            def _relativeDelta(interval):
                return relativedelta(years=interval)
        else:
            raise KeyError, 'Unsupported data frequency : %s' % frequency
        self.relativeDelta = _relativeDelta

        self.base_times = {}
        self.value_types = {}
        self.datasets = {}
        self.dataset_names = []
        self.indexers = {}
        self.lower_limits = {}
        self.upper_limits = {}
        self.missing_values = {}

        common_start_time = datetime.now()
        common_end_time = datetime(1000, 1, 1)

        for name, data, base_time, data_attrs in data_info:
            self.dataset_names.append(name)
            self.datasets[name] = data
            self.base_times[name] = _base_time = asDatetime(base_time)
            common_start_time = max(common_start_time, _base_time)

            elapsed_time = (len(data) - 1) * self.interval
            last_time = _base_time + self.relativeDelta(elapsed_time)
            common_end_time = min(common_end_time, last_time)

            value_type = data_attrs.get('value_type', None)
            if isinstance(value_type, (tuple, list)):
                self.value_types[name] = value_type[0]
                self.lower_limits[name] = value_type[1]
                self.upper_limits[name] = value_type[2]
            else:
                self.value_types[name] = value_type
                self.lower_limits[name] = N.NINF
                self.upper_limits[name] = N.inf

            missing = data_attrs.get('missing', None)
            if missing is None:
                if data.dtype.kind == 'i': missing = -32768
                elif data.dtype.kind == 'f':
                    if len(N.where(N.isinf(data))) > 0: missing = N.inf
                    else: missing = N.nan
            self.missing_values[name] = missing

            self.indexers[name] = timeIndexer(frequency, _base_time, interval)

        self.common_start_time = common_start_time
        self.common_end_time = common_end_time

        if self.frequency == 'hour':

            def _asDatetime(_time):
                if isinstance(_time, datetime): return _time
                elif isinstance(_time, (tuple, list)): return datetime(*_time)
                else:
                    return datetime(_time / 1000000, (_time / 10000) % 100,
                                    (_time / 100) % 100, _time % 100)

            def _indexForTime(_time):
                delta = asDatetime(_time) - self.base_time
                hours = (delta.days * 24) + (delta.seconds / 3600)
                indx = hours / interval
                over = hours % interval
                if over > 0: return indx + 1
                else: return indx

            def _relativeDelta(hours):
                return relativedelta(hours=hours)

            def _timeAsString(_time):
                return _time.strftime('%Y-%m-%d:%H')

            def _timeAtIndex(indx):
                return self.base_time + relativedelta(hours=indx * interval)

        elif self.frequency == 'day':

            def _asDatetime(_time):
                if isinstance(_time, datetime): return _time
                if isinstance(_time, (tuple, list)): return datetime(*_time)
                else:
                    return datetime(_time / 10000, (_time / 100) % 100,
                                    _time % 100)

            def _indexForTime(_time):
                indx = (asDatetime(_time) - self.base_time).days / interval
                over = (asDatetime(_time) - self.base_time).days % interval
                if over > 0: return indx + 1
                else: return indx

            def _relativeDelta(days):
                return relativedelta(days=days)

            def _timeAsString(_time):
                return _time.strftime('%Y-%m-%d')

            def _timeAtIndex(indx):
                return self.base_time + relativedelta(days=indx * interval)

        elif self.frequency == 'month':

            def _asDatetime(_time):
                if isinstance(_time, datetime): return _time
                if isinstance(_time, (tuple, list)): return datetime(*_time)
                else: return datetime(_time / 100, _time % 100, 1)

            def _indexForTime(_time):
                date_time = asDatetime(_time)
                years = date_time.year - self.base_time.year
                months = years * 12
                if date_time.month != 12: months -= (12 - date_time.month)
                if self.base_time.month != 1:
                    months -= self.base_time.month - 1
                return months

            def _relativeDelta(months):
                return relativedelta(months=months)

            def _timeAsString(_time):
                return _time.strftime('%Y-%m')

            def _timeAtIndex(indx):
                return self.base_time + relativedelta(months=indx * interval)

        elif self.frequency == 'year':

            def _asDatetime(_time):
                if isinstance(_time, datetime): return _time
                if isinstance(_time, (tuple, list)): return datetime(*_time)
                else: return datetime(_time / 100, _time % 100, 1)

            def _indexForTime(_time):
                return asDatetime(_time).year - self.base_time.year

            def _relativeDelta(years):
                return relativedelta(years=years)

            def _timeAsString(_time):
                return _time.strftime('%Y')

            def _timeAtIndex(indx):
                return self.base_time + relativedelta(years=indx * interval)

        else:
            raise KeyError, 'Unsupported data frequency : %s' % self.frequency

        self.asDatetime = _asDatetime
        self.indexForTime = _indexForTime
        self.relativeDelta = _relativeDelta
        self.timeAsString = _timeAsString
        self.timeAtIndex = _timeAtIndex

        self.generator = dateArrayGenerator(self.frequency)
 def index(self, date_time):
     _date_time = asDatetime(date_time)
     if _date_time == self.base_time: return 0
     delta = _date_time - self.base_time
     if (delta.days % self.interval) == 0: return delta.days / self.interval
     else: return (delta.days + self.interval) / self.interval
    # check to see if dewpt already exists and deal with it
    gen_dewpt = True
    if 'dewpt' in manager.listGroups():
        if replace_existing: manager.deleteGroup('dewpt')
        else: gen_dewpt = False

    if gen_dewpt:
        (rhum_data,rhum_attrs),(temp_data,temp_attrs) = \
        manager.getData(('rhum.value','temp.value'),True)
        rhum_data = factory.transformData('rhum', rhum_data, False)
        print rhum_data
        temp_data = factory.transformData('temp', temp_data, False)
        print ' '
        print temp_data
        temp_start_hour = asDatetime(temp_attrs['first_hour'])

        dewpt_start_hour, dewpt_end_hour, dewpt_data = \
        generateDewpointArray(rhum_data, asDatetime(rhum_attrs['first_hour']),
                              temp_data, temp_start_hour, 'F')

        print ' '
        print dewpt_data
        factory.createHourlyDataGroup(manager, 'dewpt', dewpt_data,
                                      dewpt_start_hour, dewpt_end_hour,
                                      units=temp_attrs['units'],
                                      min=N.nanmin(dewpt_data),
                                      max=N.nanmax(dewpt_data), missing=-32768)

    else:
        dewpt_data, dewpt_attrs = manager.getData('dewpt.value',True)
 def __init__(self, base_time, interval):
     self.base_time = asDatetime(base_time)
     self.interval = interval
Beispiel #24
0
 def _formatDate(self, date, include_hour):
     date_time = asDatetime(date, True)
     if include_hour: return date_time.strftime('%I %p on %b %d, %Y')
     return date_time.strftime('%b %d, %Y')
Beispiel #25
0
 def _indexForTime(_time):
     indx = (asDatetime(_time) - self.base_time).days / interval
     over = (asDatetime(_time) - self.base_time).days % interval
     if over > 0: return indx + 1
     else: return indx
Beispiel #26
0
 def _indexForTime(_time):
     return asDatetime(_time).year - self.base_time.year
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

metadata = ['sid', 'name', 'active', 'network', 'last_report']

if options.bbox is not None:
    metadata.append('lat')
    metadata.append('lon')
if options.county is not None: metadata.append('county')
if options.state is not None: metadata.append('state')

factory = ObsnetDataFactory(options)
stations = factory.argsToStationData((), options, tuple(metadata))
stations = sorted(stations, key=lambda station: station['name'])

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

verified_stations = []

print '\n Active Stations\n%s' % separator
for station in stations:
    last_hour = asDatetime(station['last_report'], True)
    station['last_hour'] = last_hour.strftime('%b %d, %Y at %I %p')
    delta = base_time - last_hour
    station['num_days'] = delta.days
    verified_stations.append(station)

stations = sorted(verified_stations, key=lambda station: station['num_days'])

for station in stations:
    print message % station
Beispiel #28
0
    def __init__(self, name, base_time, data_array, **kwargs):
        """
        Single dataset time series

        Arguments :
            name =  name for data in time series
            base_time = datetime object : Date/time corresponding to the
                        first item in `data_array`.
            data_array = Numpy array of values. If multidemensional, the
                         first dimension must be time.

            kwargs can be used to voverride the default value for the follwing :
              value_type = The type of data values in the time series data set.
                             'linear' indicates linear data (i.e. data linearly
                             increases or decrease from one value to another
                             to the decimal precision of the software).
                             'discrete' is similar to 'linear' except thot
                             values may only be whole numbers.
                             'direction' indicates data consisting spherical
                             compass directions (i.e. values from 0 to 360
                             are valid). The defualt is 'linear'
                             If a tuple/list is passed, the first item must
                             be the type, followed by the lower value limit,
                             then the upper value limit)
              frequency = Frequency of (time units between) items in 
                          `data_array`. Valid values are "hour", "day",
                          "month", "year". Default is 'hour'.
              interval = Number of time units per array node. Default is 1
                         (e.g. increment=2 and frequency='hour' means there
                         are 2 hours between each array index)
              missing_value = Value used for missing items in `data_array`.
                              Defualt is -32768 for integer arrays and
                              N.nan for float arrays.
        """
        #TODO : handle 2D arrays

        self.base_time = asDatetime(base_time)
        self.data_name = name
        self.data = data_array
        self.data_interval = interval = int(kwargs.get('interval', 1))
        self.data_type = pythonDataType(data_array.dtype)
        self.description = kwargs.get('description', '?')
        self.frequency = str(kwargs.get('frequency', 'hour'))
        self.units = kwargs.get('units', 'unknown')

        value_type = kwargs.get('value_type', None)
        if value_type is not None:
            self.value_type = value_type[0]
            self.lower_limit = float(value_type[1])
            self.upper_limit = float(value_type[2])
        else:
            self.value_type = 'linear'
            self.lower_limit = N.NINF
            self.upper_limit = N.inf

        self.missing_value = kwargs.get('missing_value', kwargs.get('missing',
                                        defaultMissingValue(data_array.dtype)))
        if self.missing_value is None:
            errmsg = 'No default missing value for dtype :'
            return ValueError, errmsg % dtype.__class__.__name__

        if self.frequency == 'hour':
            def _asDatetime(_time):
                if isinstance(_time, datetime): return _time
                elif isinstance(_time, (tuple,list)): return datetime(*_time)
                else: return datetime( _time/1000000, (_time/10000) % 100,
                                       (_time/100) % 100, _time % 100 )
            def _indexForTime(_time):
                delta = asDatetime(_time) - self.base_time
                hours = (delta.days * 24) + (delta.seconds / 3600)
                indx = hours / interval
                over = hours % interval
                if over > 0: return indx + 1
                else: return indx
            def _relativeDelta(hours): return relativedelta(hours=hours)
            def _timeAsString(_time): return _time.strftime('%Y-%m-%d:%H')
            def _timeAtIndex(indx):
                return self.base_time + relativedelta(hours=indx*interval)

        elif self.frequency == 'day':
            def _asDatetime(_time):
                if isinstance(_time, datetime): return _time
                if isinstance(_time, (tuple,list)): return datetime(*_time)
                else: return datetime( _time/10000, (_time/100) % 100,
                                       _time % 100 )
            def _indexForTime(_time):
                indx = (asDatetime(_time) - self.base_time).days / interval
                over = (asDatetime(_time) - self.base_time).days % interval
                if over > 0: return indx + 1
                else: return indx
            def _relativeDelta(days): return relativedelta(days=days)
            def _timeAsString(_time): return _time.strftime('%Y-%m-%d')
            def _timeAtIndex(indx):
                return self.base_time + relativedelta(days=indx*interval)

        elif self.frequency == 'month':
            def _asDatetime(_time):
                if isinstance(_time, datetime): return _time
                if isinstance(_time, (tuple,list)): return datetime(*_time)
                else: return datetime( _time/100, _time % 100, 1 )
            def _indexForTime(_time):
                date_time = asDatetime(_time)
                years = date_time.year - self.base_time.year
                months = years * 12
                if date_time.month != 12: months -= (12 - date_time.month)
                if self.base_time.month != 1: months -= self.base_time.month - 1
                return months
            def _relativeDelta(months): return relativedelta(months=months)
            def _timeAsString(_time): return _time.strftime('%Y-%m')
            def _timeAtIndex(indx):
                return self.base_time + relativedelta(months=indx*interval)

        elif self.frequency == 'year':
            def _asDatetime(_time):
                if isinstance(_time, datetime): return _time
                if isinstance(_time, (tuple,list)): return datetime(*_time)
                else: return datetime( _time/100, _time % 100, 1 )
            def _indexForTime(_time):
                return asDatetime(_time).year - self.base_time.year
            def _relativeDelta(years): return relativedelta(years=years)
            def _timeAsString(_time): return _time.strftime('%Y')
            def _timeAtIndex(indx):
                return self.base_time + relativedelta(years=indx*interval)

        else:
            raise KeyError, 'Unsupported data frequency : %s' % self.frequency

        self.asDatetime = _asDatetime
        self.indexForTime = _indexForTime
        self.relativeDelta = _relativeDelta
        self.timeAsString = _timeAsString
        self.timeAtIndex = _timeAtIndex

        elapsed_time = (len(data_array) - 1) * self.data_interval
        self.last_time = self.base_time + self.relativeDelta(elapsed_time)

        self.indexer = timeIndexer(self.frequency, self.base_time,
                                   self.data_interval)
        self.generator = dateArrayGenerator(self.frequency)
Beispiel #29
0
 def getTimeSpan(self, date):
     _time = list(dateAsTuple(date)[:3])
     _time.append(self.first_hour_in_day)
     start_time = asDatetime(_time)
     end_time = start_time + ONE_DAY
     return start_time, end_time
 def setTimeSpan(self, iter_start, iter_end):
     self.iter_start = asDatetime(iter_start)
     self.iter_end = asDatetime(iter_end)