def monthlygen(inputdata, start, local_start): """Internal generator function""" acc = MonthAcc(rain_day_threshold) month_start = start count = 0 while month_start <= stop: count += 1 if count % 12 == 0: logger.info("monthly: %s", month_start.isoformat(' ')) else: logger.debug("monthly: %s", month_start.isoformat(' ')) if local_start.month < 12: local_start = local_start.replace(month=local_start.month+1) else: local_start = local_start.replace( month=1, year=local_start.year+1) month_end = time_zone.local_to_utc(local_start) month_end = time_zone.day_start( month_end, day_end_hour, use_dst=use_dst) acc.reset() for data in inputdata[month_start:month_end]: acc.add_daily(data) new_data = acc.result() if new_data: new_data['start'] = month_start yield new_data month_start = month_end
def dailygen(inputdata): """Internal generator function""" day_start = start count = 0 while day_start <= stop: count += 1 if count % 30 == 0: logger.info("daily: %s", day_start.isoformat(' ')) else: logger.debug("daily: %s", day_start.isoformat(' ')) day_end = day_start + DAY if use_dst: # day might be 23 or 25 hours long day_end = time_zone.day_start( day_end + HOURx3, day_end_hour, use_dst=use_dst) acc.reset() for data in inputdata[day_start:day_end]: acc.add_raw(data) for data in hourly_data[day_start:day_end]: acc.add_hourly(data) new_data = acc.result() if new_data: new_data['start'] = day_start yield new_data day_start = day_end
def rain_day_local(self, data): # compute rain since day start day_end_hour, use_dst = get_day_end_hour(self.context.params) day_start = time_zone.day_start( data['idx'], day_end_hour, use_dst=use_dst) day_start = self.context.calib_data.nearest(day_start) return max( data['rain'] - self.context.calib_data[day_start]['rain'], 0.0)
def generate_monthly(rain_day_threshold, day_end_hour, use_dst, daily_data, monthly_data, process_from): """Generate monthly summaries from daily data.""" start = monthly_data.before(datetime.max) if start is None: start = datetime.min start = daily_data.after(start + SECOND) if process_from: if start: start = min(start, process_from) else: start = process_from if start is None: return start # set start to noon on start of first day of month (local time) local_start = time_zone.utc_to_local(start).replace(tzinfo=None) local_start = local_start.replace(day=1, hour=12, minute=0, second=0) # go back to UTC and get start of day (which might be previous day) start = time_zone.local_to_utc(local_start) start = time_zone.day_start(start, day_end_hour, use_dst=use_dst) del monthly_data[start:] stop = daily_data.before(datetime.max) if stop is None: return None def monthlygen(inputdata, start, local_start): """Internal generator function""" acc = MonthAcc(rain_day_threshold) month_start = start count = 0 while month_start <= stop: count += 1 if count % 12 == 0: logger.info("monthly: %s", month_start.isoformat(' ')) else: logger.debug("monthly: %s", month_start.isoformat(' ')) if local_start.month < 12: local_start = local_start.replace(month=local_start.month+1) else: local_start = local_start.replace( month=1, year=local_start.year+1) month_end = time_zone.local_to_utc(local_start) month_end = time_zone.day_start( month_end, day_end_hour, use_dst=use_dst) acc.reset() for data in inputdata[month_start:month_end]: acc.add_daily(data) new_data = acc.result() if new_data: new_data['start'] = month_start yield new_data month_start = month_end monthly_data.update(monthlygen(daily_data, start, local_start)) return start
def _periodic_due(self, now): # make list of due sections sections = [] # hourly threshold = time_zone.hour_start(now) last_update = self.status.get_datetime('last update', 'hourly') if not last_update or last_update < threshold: sections.append('hourly') # daily threshold = time_zone.day_start(now, self.day_end_hour, use_dst=self.use_dst) last_update = self.status.get_datetime('last update', 'daily') if not last_update or last_update < threshold: sections.append('daily') # 12 hourly threshold = max( threshold, time_zone.day_start(now, (self.day_end_hour + 12) % 24, use_dst=self.use_dst)) last_update = self.status.get_datetime('last update', '12 hourly') if not last_update or last_update < threshold: sections.append('12 hourly') return sections
def generate_daily(day_end_hour, use_dst, calib_data, hourly_data, daily_data, process_from): """Generate daily summaries from calibrated and hourly data.""" start = daily_data.before(datetime.max) if start is None: start = datetime.min start = calib_data.after(start + SECOND) if process_from: if start: start = min(start, process_from) else: start = process_from if start is None: return start # round to start of this day, in local time start = time_zone.day_start(start, day_end_hour, use_dst=use_dst) del daily_data[start:] stop = calib_data.before(datetime.max) acc = DayAcc() def dailygen(inputdata): """Internal generator function""" day_start = start count = 0 while day_start <= stop: count += 1 if count % 30 == 0: logger.info("daily: %s", day_start.isoformat(' ')) else: logger.debug("daily: %s", day_start.isoformat(' ')) day_end = day_start + DAY if use_dst: # day might be 23 or 25 hours long day_end = time_zone.day_start( day_end + HOURx3, day_end_hour, use_dst=use_dst) acc.reset() for data in inputdata[day_start:day_end]: acc.add_raw(data) for data in hourly_data[day_start:day_end]: acc.add_hourly(data) new_data = acc.result() if new_data: new_data['start'] = day_start yield new_data day_start = day_end daily_data.update(dailygen(calib_data)) return start