def test_moving_sum(self): """Test moving_sum calculation.""" start_date = datetime(year=2011, month=9, day=6) end_date = datetime(year=2011, month=9, day=8) td_step = timedelta(hours=24) generate_values_kwargs = {'dt_start': start_date, 'dt_stop': end_date, 'td_step': td_step, 'unit': 'AnyUnit', 'value': 1} # Make start_date and end_date tz aware, just as in rain_stats from # adapter start_date = UTC.localize(start_date) end_date = UTC.localize(end_date) moving_sum_kwargs = { 'values': generate_values(**generate_values_kwargs), 'td_window': timedelta(hours=1), 'td_value': td_step, 'start_date_utc': start_date, 'end_date_utc': end_date} # 24 hour data and a 1 hour window, there should be no max_values self.assertEqual(len(moving_sum(**moving_sum_kwargs)), 0) # 3 values of 24 hour data and a 24 hour window, there will be 3 # max_values of 1 each moving_sum_kwargs['td_window'] = timedelta(days=1) self.assertEqual(len(moving_sum(**moving_sum_kwargs)), 3) # if there are more values before and after the window, they are # neglected. generate_values_kwargs['dt_start'] -= timedelta(days=2) generate_values_kwargs['dt_stop'] += timedelta(days=2) moving_sum_kwargs['values'] = generate_values(**generate_values_kwargs) self.assertEqual(len(moving_sum(**moving_sum_kwargs)), 3) # if the values are offset compared to the daterange by # some hours, only 2 values fit within the daterange that is # exactly two calendar days. generate_values_kwargs['dt_start'] -= timedelta(hours=7) generate_values_kwargs['dt_stop'] += timedelta(hours=7) moving_sum_kwargs['values'] = generate_values(**generate_values_kwargs) self.assertEqual(len(moving_sum(**moving_sum_kwargs)), 2) # A 48 hour window should reveal at least the maximum of 2, # which is the sum of two 24 hour values of 1 moving_sum_kwargs['td_window'] = timedelta(days=2) ms = moving_sum(**moving_sum_kwargs) sums = [m['value'] for m in ms] self.assertEqual(max(sums), 2)
def rain_stats(self, values, area_km2, td_window, start_date_utc, end_date_utc): """Calculate stats. Expects utc, returns site timezone datetimes... Sorry.""" logger.debug(('Calculating rain stats for' + 'start=%s, end=%s, td_window=%s') % (start_date_utc, end_date_utc, td_window)) if not values: return { 'td_window': td_window, 'max': None, 'start': None, 'end': None, 't': self._t_to_string(None)} td_value = UNIT_TO_TIMEDELTA[values[0]['unit']] max_values = moving_sum(values, td_window, td_value, start_date_utc, end_date_utc) if max_values: max_value = max(max_values, key=lambda i: i['value']) hours = td_window.days * 24 + td_window.seconds / 3600.0 t = herhalingstijd(hours, area_km2, max_value['value']) else: max_value = {'value': None, 'datetime_start_utc': None, 'datetime_end_utc': None} t = None if max_value['datetime_start_utc'] is not None: datetime_start_site_tz = max_value[ 'datetime_start_utc'].astimezone(self.tz) else: datetime_start_site_tz = None if max_value['datetime_end_utc'] is not None: datetime_end_site_tz = max_value[ 'datetime_end_utc'].astimezone(self.tz) else: datetime_end_site_tz = None return { 'td_window': td_window, 'max': max_value['value'], 'start': datetime_start_site_tz, 'end': datetime_end_site_tz, 't': self._t_to_string(t)}