1 package org.djutils.stats.summarizers;
2
3 import java.util.Calendar;
4
5 import org.djutils.exceptions.Throw;
6
7
8
9
10
11
12
13
14
15
16
17
18
19 public class TimestampWeightedTally implements TimestampTallyInterface
20 {
21
22 private static final long serialVersionUID = 20200228L;
23
24
25 private WeightedTally wrappedWeightedTally;
26
27
28 private double startTime = Double.NaN;
29
30
31 private double elapsedTime = Double.NaN;
32
33
34 private double lastTimestamp = Double.NaN;
35
36
37 private double lastValue = Double.NaN;
38
39
40 private boolean active = false;
41
42
43
44
45
46 public TimestampWeightedTally(final String description)
47 {
48 this.wrappedWeightedTally = new WeightedTally(description);
49 initialize();
50 }
51
52
53 @Override
54 public void initialize()
55 {
56 synchronized (this.wrappedWeightedTally.semaphore)
57 {
58 this.wrappedWeightedTally.initialize();
59 this.startTime = Double.NaN;
60 this.elapsedTime = 0.0;
61 this.lastTimestamp = Double.NaN;
62 this.lastValue = 0.0;
63 this.active = true;
64 }
65 }
66
67
68 @Override
69 public final boolean isActive()
70 {
71 return this.active;
72 }
73
74
75 @Override
76 public final void endObservations(final Number timestamp)
77 {
78 ingest(timestamp, this.lastValue);
79 this.active = false;
80 }
81
82
83 @Override
84 public void endObservations(final Calendar timestamp)
85 {
86 endObservations(timestamp.getTimeInMillis());
87 }
88
89
90
91
92
93 public double getLastValue()
94 {
95 return this.lastValue;
96 }
97
98
99
100
101
102
103
104 public double ingest(final Calendar timestamp, final double value)
105 {
106 Throw.whenNull(timestamp, "timestamp object may not be null");
107 return ingest(timestamp.getTimeInMillis(), value);
108 }
109
110
111
112
113
114
115
116 public double ingest(final Number timestamp, final double value)
117 {
118 Throw.whenNull(timestamp, "timestamp object may not be null");
119 Throw.when(Double.isNaN(value), IllegalArgumentException.class, "value may not be NaN");
120 double timestampDouble = timestamp.doubleValue();
121 Throw.when(Double.isNaN(timestampDouble), IllegalArgumentException.class, "timestamp may not be NaN");
122 Throw.when(timestampDouble < (this.elapsedTime + this.startTime), IllegalArgumentException.class,
123 "times not offered in ascending order. Last time was " + (this.elapsedTime + this.startTime)
124 + ", new timestamp was " + timestampDouble);
125
126 synchronized (this.wrappedWeightedTally.semaphore)
127 {
128
129 if ((Double.isNaN(this.lastTimestamp) || timestampDouble > this.lastTimestamp) && this.active)
130 {
131 if (Double.isNaN(this.startTime))
132 {
133 this.startTime = timestampDouble;
134 this.elapsedTime = 0.0;
135 }
136 else
137 {
138 double deltaTime = timestampDouble - this.lastTimestamp;
139 this.elapsedTime += deltaTime;
140 this.wrappedWeightedTally.ingest(deltaTime, this.lastValue);
141 }
142 this.lastTimestamp = timestampDouble;
143 }
144 this.lastValue = value;
145 return value;
146 }
147 }
148
149
150 @Override
151 public final String getDescription()
152 {
153 return this.wrappedWeightedTally.getDescription();
154 }
155
156
157 @Override
158 public final long getN()
159 {
160 return this.wrappedWeightedTally.getN();
161 }
162
163
164 @Override
165 public final double getMax()
166 {
167 return this.wrappedWeightedTally.getMax();
168 }
169
170
171 @Override
172 public final double getMin()
173 {
174 return this.wrappedWeightedTally.getMin();
175 }
176
177
178 @Override
179 public final double getWeightedSampleMean()
180 {
181 return this.wrappedWeightedTally.getWeightedSampleMean();
182 }
183
184
185 @Override
186 public final double getWeightedSampleStDev()
187 {
188 return this.wrappedWeightedTally.getWeightedSampleStDev();
189 }
190
191
192 @Override
193 public final double getWeightedPopulationStDev()
194 {
195 return this.wrappedWeightedTally.getWeightedPopulationStDev();
196 }
197
198
199 @Override
200 public final double getWeightedSampleVariance()
201 {
202 return this.wrappedWeightedTally.getWeightedSampleVariance();
203 }
204
205
206 @Override
207 public final double getWeightedPopulationVariance()
208 {
209 return this.wrappedWeightedTally.getWeightedPopulationVariance();
210 }
211
212
213 @Override
214 public final double getWeightedSum()
215 {
216 return this.wrappedWeightedTally.getWeightedSum();
217 }
218
219
220 @Override
221 @SuppressWarnings("checkstyle:designforextension")
222 public String toString()
223 {
224 return this.wrappedWeightedTally.toString();
225 }
226
227 }