Mercurial > templog
comparison py/utils.py @ 571:ccfaa4351fd8
scale integrate by delay time
namedtuple for StepIntegrator
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Wed, 11 Nov 2015 21:58:38 +0800 |
parents | afe2eb17723e |
children | 02aff9ff8d24 |
comparison
equal
deleted
inserted
replaced
570:afe2eb17723e | 571:ccfaa4351fd8 |
---|---|
5 import select | 5 import select |
6 import logging | 6 import logging |
7 import binascii | 7 import binascii |
8 import json | 8 import json |
9 import datetime | 9 import datetime |
10 import collections | |
10 | 11 |
11 D = logging.debug | 12 D = logging.debug |
12 L = logging.info | 13 L = logging.info |
13 W = logging.warning | 14 W = logging.warning |
14 E = logging.error | 15 E = logging.error |
170 if self(): | 171 if self(): |
171 L(msg + " (log interval %s)" % str(self.limit)) | 172 L(msg + " (log interval %s)" % str(self.limit)) |
172 else: | 173 else: |
173 D(msg) | 174 D(msg) |
174 | 175 |
176 Period = collections.namedtuple('Period', 'start end') | |
175 class StepIntegrator(object): | 177 class StepIntegrator(object): |
176 """ | 178 """ |
177 Takes on/off events and a monotonically increasing timefn. Returns the integral | 179 Takes on/off events and a monotonically increasing timefn. Returns the integral |
178 of (now-limittime, now) over those events. | 180 of (now-limittime, now) over those events. |
179 | 181 |
208 >>> t = 170 | 210 >>> t = 170 |
209 >>> print(s.integrate()) | 211 >>> print(s.integrate()) |
210 0 | 212 0 |
211 """ | 213 """ |
212 def __init__(self, timefn, limittime): | 214 def __init__(self, timefn, limittime): |
213 # _on_periods is a list of [[start, end]]. End is None if still on | 215 # _on_periods is a list of [period]. End is None if still on |
214 self._on_periods = [] | 216 self._on_periods = [] |
215 self._timefn = timefn | 217 self._timefn = timefn |
216 self._limittime = limittime | 218 self._limittime = limittime |
217 | 219 |
218 def set_limit(self, limittime): | 220 def set_limit(self, limittime): |
219 if self._limittime == limittime: | 221 if self._limittime == limittime: |
220 return | 222 return |
221 self._limittime = limittime | 223 self._limittime = limittime |
222 self.trim() | 224 self._trim() |
223 | 225 |
224 def turn(self, value): | 226 def turn(self, value): |
225 if not self._on_periods: | 227 if not self._on_periods: |
226 if value: | 228 if value: |
227 self._on_periods.append([self._timefn(), None]) | 229 self._on_periods.append(Period(self._timefn(), None)) |
228 return | 230 return |
229 | 231 |
230 # state hasn't changed | 232 # state hasn't changed |
231 on_now = (self._on_periods[-1][1] is None) | 233 on_now = (self._on_periods[-1].end is None) |
232 if value == on_now: | 234 if value == on_now: |
233 return | 235 return |
234 | 236 |
235 if value: | 237 if value: |
236 self._on_periods.append([self._timefn(), None]) | 238 self._on_periods.append(Period(self._timefn(), None)) |
237 else: | 239 else: |
238 self._on_periods[-1][1] = self._timefn() | 240 self._on_periods[-1] = self._on_periods[-1]._replace(end = self._timefn()) |
239 | 241 |
240 def _trim(self): | 242 def _trim(self): |
241 begin = self._timefn() - self._limittime | 243 begin = self._timefn() - self._limittime |
242 # shortcut, first start is after begin | 244 # shortcut, first start is after begin |
243 if not self._on_periods or self._on_periods[0][0] >= begin: | 245 if not self._on_periods or self._on_periods[0].start >= begin: |
244 return | 246 return |
245 | 247 |
246 new_periods = [] | 248 new_periods = [] |
247 for s, e in self._on_periods: | 249 for s, e in self._on_periods: |
248 if s == e: | 250 if s == e: |
249 continue | 251 continue |
250 elif s >= begin: | 252 elif s >= begin: |
251 new_periods.append([s,e]) | 253 new_periods.append(Period(s,e)) |
252 elif e is not None and e < begin: | 254 elif e is not None and e < begin: |
253 continue | 255 continue |
254 else: | 256 else: |
255 new_periods.append([begin, e]) | 257 new_periods.append(Period(begin, e)) |
256 self._on_periods = new_periods | 258 self._on_periods = new_periods |
257 | 259 |
258 def integrate(self): | 260 def integrate(self): |
259 self._trim() | 261 self._trim() |
260 tot = 0 | 262 tot = 0 |