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