1 package org.lcsim.event.base;
2
3 import hep.physics.event.BaseEvent;
4
5 import java.util.ArrayList;
6 import java.util.Collection;
7 import java.util.Date;
8 import java.util.HashMap;
9 import java.util.IdentityHashMap;
10 import java.util.List;
11 import java.util.Map;
12 import java.util.Set;
13
14 import org.lcsim.conditions.ConditionsManager;
15 import org.lcsim.conditions.ConditionsManager.ConditionsNotFoundException;
16 import org.lcsim.event.EventHeader;
17 import org.lcsim.event.Hit;
18 import org.lcsim.event.MCParticle;
19 import org.lcsim.geometry.Detector;
20 import org.lcsim.geometry.IDDecoder;
21 import org.lcsim.geometry.util.BaseIDDecoder;
22 import org.lcsim.geometry.util.IDDescriptor;
23 import org.lcsim.lcio.LCIOConstants;
24 import org.lcsim.lcio.LCIOUtil;
25
26
27
28
29
30
31 public class BaseLCSimEvent extends BaseEvent implements EventHeader {
32
33 private class MetaData implements LCMetaData {
34
35 private transient IDDecoder dec;
36 private int flags;
37 private Map<String, float[]> floatMap;
38 private Map<String, int[]> intMap;
39 private final String name;
40 private Map<String, String[]> stringMap;
41 private final Class type;
42
43 MetaData(final String name, final Class type, final int flags, final Map intMap, final Map floatMap,
44 final Map stringMap) {
45 this.name = name;
46 this.type = type;
47 this.flags = flags;
48 this.intMap = intMap;
49 this.floatMap = floatMap;
50 this.stringMap = stringMap;
51 }
52
53 MetaData(final String name, final Class type, final int flags, final String readoutName) {
54 this.name = name;
55 this.type = type;
56 this.flags = flags;
57 if (readoutName != null) {
58 this.getStringParameters().put(READOUT_NAME, new String[] {readoutName});
59 }
60 }
61
62
63
64
65
66
67 private IDDecoder createIDDecoderFromCellIDEncoding() {
68 final String[] cellIdEncoding = this.getStringParameters().get("CellIDEncoding");
69 IDDecoder result = null;
70 if (cellIdEncoding != null) {
71 result = new BaseIDDecoder();
72 try {
73 final IDDescriptor desc = new IDDescriptor(cellIdEncoding[0]);
74 result.setIDDescription(desc);
75 } catch (final IDDescriptor.IDException x) {
76 throw new RuntimeException(x);
77 }
78 }
79 return result;
80 }
81
82 public org.lcsim.geometry.IDDecoder findIDDecoder() {
83
84
85 String readoutName = name;
86 if (stringMap != null) {
87 final String[] names = stringMap.get(READOUT_NAME);
88 if (names != null && names.length >= 1) {
89 readoutName = names[0];
90 }
91 }
92
93
94 org.lcsim.geometry.IDDecoder result = null;
95 try {
96 result = BaseLCSimEvent.this.getDetector().getDecoder(readoutName);
97 } catch (final RuntimeException x) {
98 }
99
100
101 if (result == null) {
102 result = this.createIDDecoderFromCellIDEncoding();
103 }
104
105
106
107
108
109
110 return result;
111 }
112
113 @Override
114 public EventHeader getEvent() {
115 return BaseLCSimEvent.this;
116 }
117
118 @Override
119 public int getFlags() {
120 return flags;
121 }
122
123 @Override
124 public Map<String, float[]> getFloatParameters() {
125 if (floatMap == null) {
126 floatMap = new HashMap<String, float[]>();
127 }
128 return floatMap;
129 }
130
131 @Override
132 public org.lcsim.geometry.IDDecoder getIDDecoder() {
133 if (dec == null) {
134 dec = this.findIDDecoder();
135 }
136 return dec;
137 }
138
139 @Override
140 public Map<String, int[]> getIntegerParameters() {
141 if (intMap == null) {
142 intMap = new HashMap<String, int[]>();
143 }
144 return intMap;
145 }
146
147 @Override
148 public String getName() {
149 return name;
150 }
151
152 @Override
153 public Map<String, String[]> getStringParameters() {
154 if (stringMap == null) {
155 stringMap = new HashMap<String, String[]>();
156 }
157 return stringMap;
158 }
159
160 @Override
161 public Class getType() {
162 return type;
163 }
164
165 @Override
166 public boolean isSubset() {
167 return LCIOUtil.bitTest(flags, LCIOConstants.BITSubset);
168 }
169
170 @Override
171 public boolean isTransient() {
172 return LCIOUtil.bitTest(flags, LCIOConstants.BITTransient);
173 }
174
175 @Override
176 public void setSubset(final boolean isSubset) {
177 flags = LCIOUtil.bitSet(flags, LCIOConstants.BITSubset, isSubset);
178 }
179
180 @Override
181 public void setTransient(final boolean isTransient) {
182 flags = LCIOUtil.bitSet(flags, LCIOConstants.BITTransient, isTransient);
183 }
184 }
185
186 private static final int NANO_SECONDS = 1000000;
187 public static final String READOUT_NAME = "ReadoutName";
188 private final ConditionsManager conditionsManager = ConditionsManager.defaultInstance();
189
190 private final String detectorName;
191 private final Map<String, float[]> floatParameters = new HashMap<String, float[]>();
192 private final Map<String, int[]> intParameters = new HashMap<String, int[]>();
193 private final Map<String, String[]> stringParameters = new HashMap<String, String[]>();
194
195 private final Map<List, LCMetaData> metaDataMap = new IdentityHashMap<List, LCMetaData>();
196
197
198 public BaseLCSimEvent(final int run, final int event, final String detectorName) {
199 this(run, event, detectorName, System.currentTimeMillis() * NANO_SECONDS);
200 }
201
202 public BaseLCSimEvent(final int run, final int event, final String detectorName, final long timeStamp) {
203 super(run, event, timeStamp);
204 this.detectorName = detectorName;
205 try {
206 conditionsManager.setDetector(detectorName, run);
207 } catch (final ConditionsNotFoundException x) {
208 throw new RuntimeException(x);
209 }
210 }
211
212 public BaseLCSimEvent(final int run, final int event, final String detectorName, final long timeStamp,
213 final boolean triggerConditionsUpdate) {
214 super(run, event, timeStamp);
215 this.detectorName = detectorName;
216 if (triggerConditionsUpdate) {
217 try {
218 conditionsManager.setDetector(detectorName, run);
219 } catch (final ConditionsNotFoundException x) {
220 throw new RuntimeException(x);
221 }
222 }
223 }
224
225 @Override
226 public <T> List<List<T>> get(final Class<T> type) {
227 final List<List<T>> result = new ArrayList<List<T>>();
228 for (final Map.Entry<List, LCMetaData> entry : metaDataMap.entrySet()) {
229 if (type.isAssignableFrom(entry.getValue().getType())) {
230 result.add(entry.getKey());
231 }
232 }
233 return result;
234 }
235
236 @Override
237 public <T> List<T> get(final Class<T> type, final String name) {
238 return (List<T>) this.get(name);
239 }
240
241 @Override
242 public Detector getDetector() {
243 return conditionsManager.getCachedConditions(Detector.class, "compact.xml").getCachedData();
244 }
245
246 @Override
247 public String getDetectorName() {
248 return detectorName;
249 }
250
251 @Override
252 public Map<String, float[]> getFloatParameters() {
253 return floatParameters;
254 }
255
256 @Override
257 public Map<String, int[]> getIntegerParameters() {
258 return intParameters;
259
260 }
261
262 @Override
263 public Set<List> getLists() {
264 return metaDataMap.keySet();
265 }
266
267 @Override
268 public List<MCParticle> getMCParticles() {
269 return this.get(MCParticle.class, MC_PARTICLES);
270 }
271
272 @Override
273 public Collection<LCMetaData> getMetaData() {
274 return metaDataMap.values();
275 }
276
277 @Override
278 public LCMetaData getMetaData(final List x) {
279 return metaDataMap.get(x);
280 }
281
282 @Override
283 public Map<String, String[]> getStringParameters() {
284 return stringParameters;
285 }
286
287 @Override
288 public float getWeight() {
289 return 1.0f;
290 }
291
292 @Override
293 public boolean hasCollection(final Class type) {
294 for (final LCMetaData meta : metaDataMap.values()) {
295 if (type.isAssignableFrom(meta.getType())) {
296 return true;
297 }
298 }
299 return false;
300 }
301
302 @Override
303 public boolean hasCollection(final Class type, final String name) {
304 if (!this.hasItem(name)) {
305 return false;
306 }
307 final Object collection = this.get(name);
308 if (!(collection instanceof List)) {
309 return false;
310 }
311 return type.isAssignableFrom(metaDataMap.get(collection).getType());
312 }
313
314 @Override
315 public boolean hasItem(final String name) {
316 return super.keys().contains(name);
317 }
318
319 @Override
320 public void put(final String name, final List collection, final Class type, final int flags) {
321 this.put(name, collection, type, flags, null);
322 }
323
324 @Override
325 public void put(final String name, final List collection, final Class type, final int flags, final Map intMap,
326 final Map floatMap, final Map stringMap) {
327 super.put(name, collection);
328 final LCMetaData meta = new MetaData(name, type, flags, intMap, floatMap, stringMap);
329 metaDataMap.put(collection, meta);
330 }
331
332 @Override
333 public void put(final String name, final List collection, final Class type, final int flags,
334 final String readoutName) {
335 super.put(name, collection);
336
337 final LCMetaData meta = new MetaData(name, type, flags, readoutName);
338 metaDataMap.put(collection, meta);
339
340 this.setCollectionMetaData(collection, type, meta);
341 }
342
343 @Override
344 public void put(final String name, final Object component) {
345
346 if (this.hasItem(name)) {
347 throw new IllegalArgumentException("An item called " + name + " already exists in the event.");
348 }
349 super.put(name, component);
350 if (component instanceof List) {
351 final List list = (List) component;
352 Class type = list.isEmpty() ? Object.class : list.get(0).getClass();
353 for (final Object o : list) {
354 if (!type.isAssignableFrom(o.getClass())) {
355 type = Object.class;
356 }
357 }
358 metaDataMap.put(list, new MetaData(name, type, 0, null));
359 }
360 }
361
362
363
364
365 @Override
366 public void remove(final String name) {
367 final Object collection = this.get(name);
368 if (collection instanceof List) {
369 metaDataMap.remove(collection);
370 }
371 super.keys().remove(name);
372 }
373
374 private void setCollectionMetaData(final List collection, final Class type, final LCMetaData meta) {
375
376 if (Hit.class.isAssignableFrom(type)) {
377 for (final Object o : collection) {
378 final Hit hit = (Hit) o;
379 if (hit.getMetaData() == null) {
380 ((Hit) o).setMetaData(meta);
381 }
382 }
383 }
384 }
385
386 @Override
387 public String toString() {
388 return "Run " + this.getRunNumber() + " Event " + this.getEventNumber() + " ("
389 + new Date(this.getTimeStamp() / NANO_SECONDS) + ") Detector: " + detectorName;
390 }
391 }