1 package org.lcsim.util;
2
3 import java.io.PrintStream;
4 import java.util.ArrayList;
5 import java.util.List;
6 import java.util.Random;
7 import java.util.logging.Level;
8 import java.util.logging.Logger;
9
10 import org.lcsim.conditions.ConditionsManager;
11 import org.lcsim.event.EventHeader;
12 import org.lcsim.geometry.Detector;
13
14
15
16
17
18
19
20
21
22
23
24
25 public class Driver {
26
27
28
29 public final static int HLEVEL_DEFAULT = -1;
30 public final static int HLEVEL_OFF = 0;
31 public final static int HLEVEL_NORMAL = 1;
32 public final static int HLEVEL_HIGH = 3;
33 public final static int HLEVEL_FULL = 5;
34
35 private static Driver mother = new MotherOfAllDrivers();
36 private final List<Driver> subDrivers = new ArrayList<Driver>();
37 private Driver parent = mother;
38 private int histogramLevel = HLEVEL_DEFAULT;
39 private Random random;
40 private final String driverName;
41 private int nEvents;
42 private long nNanos;
43
44
45
46
47 public Driver() {
48 this(null);
49 }
50
51 Driver(String name) {
52 if (name == null || name.length() == 0) {
53 String id = getClass().getName();
54 int pos = id.lastIndexOf('.');
55 driverName = id.substring(pos < 0 ? 0 : pos + 1);
56 } else {
57 driverName = name;
58 }
59 }
60
61
62
63
64
65 public void add(Driver driver) {
66 subDrivers.add(driver);
67 driver.parent = this;
68 }
69
70
71
72
73
74 public void remove(Driver driver) {
75 subDrivers.remove(driver);
76 driver.parent = mother;
77 }
78
79
80
81
82 public List<Driver> drivers() {
83 return subDrivers;
84 }
85
86
87
88
89
90 public boolean contains(Driver driver) {
91 return subDrivers.contains(driver);
92 }
93
94
95
96
97 public Logger getLogger() {
98
99 return Logger.getLogger(getClass().getName());
100 }
101
102
103
104
105 public String getName() {
106 return driverName;
107 }
108
109 String pathToMother() {
110 return parent.pathToMother() + "." + driverName;
111 }
112
113
114
115
116 public int getHistogramLevel() {
117 return histogramLevel <= HLEVEL_DEFAULT ? parent.getHistogramLevel() : histogramLevel;
118 }
119
120
121
122
123 public void setHistogramLevel(int level) {
124 histogramLevel = level;
125 }
126
127 public ConditionsManager getConditionsManager() {
128 return parent.getConditionsManager();
129 }
130
131
132
133
134 protected void suspend() {
135 for (Driver driver : subDrivers)
136 driver.suspend();
137 }
138
139
140
141
142 protected void resume() {
143 for (Driver driver : subDrivers)
144 driver.resume();
145 }
146
147
148
149
150 protected void endOfData() {
151 for (Driver driver : subDrivers)
152 driver.endOfData();
153 }
154
155
156
157
158 protected void startOfData() {
159 for (Driver driver : subDrivers)
160 driver.startOfData();
161 }
162
163
164
165
166
167
168 protected void detectorChanged(Detector detector) {
169 for (Driver driver : subDrivers)
170 driver.detectorChanged(detector);
171 }
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186 protected void process(EventHeader event) {
187 processChildren(event);
188 }
189
190
191
192
193 public void clearStatistics() {
194 nEvents = 0;
195 nNanos = 0;
196 }
197
198
199
200
201 public void printStatistics(PrintStream out) {
202 printStatistics(out, 0, 0);
203 }
204
205 private void printStatistics(PrintStream out, int indent, long parentNanos) {
206 printStatisticsLine(out, indent, getName(), nEvents, nNanos, parentNanos);
207 if (!subDrivers.isEmpty()) {
208 int nIndent = indent + 1;
209 long self = nNanos;
210 for (Driver driver : subDrivers) {
211 driver.printStatistics(out, nIndent, nNanos);
212 self -= driver.nNanos;
213 }
214 printStatisticsLine(out, nIndent, "*self", nEvents, self, nNanos);
215 }
216 }
217
218 private static void printStatisticsLine(PrintStream out, int indent, String name, int nEvents, long time, long parentTime) {
219 out.print(formatName(indent, name, 40));
220 out.print(' ');
221 out.print(nEvents);
222 out.print(' ');
223 out.printf(formatTime(time));
224 if (parentTime > 0) {
225 out.print(' ');
226 out.printf("%3.1f", 100. * time / parentTime);
227 out.print('%');
228 }
229 out.println();
230 }
231
232 private static String formatName(int indent, String name, int width) {
233 StringBuilder builder = new StringBuilder();
234 for (int i = 0; i < indent; i++)
235 builder.append(" ");
236 builder.append(name);
237 if (builder.length() > width)
238 builder.setLength(width);
239 else
240 for (int i = builder.length(); i < width; i++)
241 builder.append(' ');
242 return builder.toString();
243 }
244
245 private static String formatTime(long nanos) {
246 String unit = "ms";
247 double time = nanos / 1000000.;
248 if (time > 1000) {
249 time /= 1000;
250 unit = "s";
251 }
252 java.util.Formatter formatter = new java.util.Formatter();
253 formatter.format("%3.3g", time);
254 formatter.format("%s", unit);
255 return formatter.toString();
256 }
257
258 void doProcess(EventHeader event) {
259 nEvents++;
260 long start = System.nanoTime();
261 process(event);
262 long stop = System.nanoTime();
263 nNanos += (stop - start);
264 }
265
266
267
268
269 public void processChildren(EventHeader event) {
270 for (Driver driver : subDrivers)
271 driver.doProcess(event);
272 }
273
274 public Random getRandom() {
275 return random == null ? parent.getRandom() : random;
276 }
277
278
279
280
281
282
283 public void setRandom(Random random) {
284 this.random = random;
285 }
286
287 public void setLogLevel(String logLevel) {
288 this.getLogger().setLevel(Level.parse(logLevel));
289 }
290
291
292
293 private static class MotherOfAllDrivers extends Driver {
294 private Random random = new Random();
295
296 MotherOfAllDrivers() {
297 super("TOP");
298 }
299
300 public Random getRandom() {
301 return random;
302 }
303
304 public int getHistogramLevel() {
305 return 0;
306 }
307
308 public ConditionsManager getConditionsManager() {
309 return ConditionsManager.defaultInstance();
310 }
311
312 String pathToMother() {
313 return getName();
314 }
315 }
316
317
318
319
320 public static class NextEventException extends RuntimeException {
321 public NextEventException() {
322 super("Next Event");
323 }
324 }
325
326
327
328
329 public static class AbortRunException extends RuntimeException {
330 public AbortRunException() {
331 super("Abort Run");
332 }
333 }
334 }