1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 __author__ = "Nickolas Fotopoulos <nickolas.fotopoulos@ligo.org>"
18
19 import collections
20
21 import numpy as np
22
23 from lal import rate
24
26 """
27 This class is a histogram with a bounded size such that as new
28 elements come in, old elements are removed in chronological order.
29 The timestamp is retained only so that some rough idea of live time
30 is retained and so that we can enforce monotonicity.
31 """
33 self.bins = bins
34 self.max_len = max_len
35
36 self.timestamps = collections.deque()
37 self.counts = np.zeros(len(bins), dtype=int)
38 self._hist_ind = collections.deque()
39 if hasattr(bins, "volumes"):
40 self._volumes = bins.volumes()
41 else:
42 self._volumes = bins.upper() - bins.lower()
43
45 """
46 Return the current number of elements in the histogram.
47 """
48 return len(self._hist_ind)
49
51 """
52 Remove the oldest element from the histogram.
53 """
54 self.counts[self._hist_ind.popleft()] -= 1
55 self.timestamps.popleft()
56
57 - def update(self, timestamp, stat):
58 """
59 Push the stat's bin onto the queue and update the histogram.
60 """
61 if len(self) and timestamp < self.timestamps[-1]:
62 raise ValueError, "timestamp non-monotonic: %s" % str(timestamp)
63 ind = self.bins[stat]
64 self.counts[ind] += 1
65 while len(self) >= self.max_len:
66 self._flush_oldest()
67 self._hist_ind.append(ind)
68 self.timestamps.append(timestamp)
69
71 """
72 Return the fraction of events with stats than stat. This is formally
73 the survival function (sf), which is 1 - CDF(stat).
74 """
75
76 ind = self.bins[stat]
77 return self.counts[ind:].sum() / len(self)
78
80 """
81 Return the PDF at stat.
82 """
83 ind = self.bins[stat]
84 return float(self.counts[ind]) / self._volumes[ind] / len(self)
85
87 """
88 Return the CDF of the stat. (To get the "CDF from the right", see get_sf().)
89 """
90
91 ind = self.bins[stat]
92 return self.counts[:ind + 1].sum() / len(self)
93
94
96 return self.timestamps[0]
97