View Javadoc

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   * A base implementation for EventHeader
28   *
29   * @author Tony Johnson
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           * Make an IDDecoder for this MetaData using the CellIDEncoding parameter.
64           *
65           * @return An IDDecoder made built from the CellIDEncoding.
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              // If the IDDecoder name is explicitly set then use it, otherwise
84              // use the name of the collection itself.
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              // Find the IDDecoder using the Detector.
94              org.lcsim.geometry.IDDecoder result = null;
95              try {
96                  result = BaseLCSimEvent.this.getDetector().getDecoder(readoutName);
97              } catch (final RuntimeException x) {
98              }
99  
100             // Detector lookup failed. Attempt to use the CellIDEncoding collection parameter.
101             if (result == null) {
102                 result = this.createIDDecoderFromCellIDEncoding();
103             }
104 
105             // If both methods failed, then there is a problem.
106             // if (result == null)
107             // throw new RuntimeException("Could not find or create an IDDecoder for the collection: " + name +
108             // ", readout: " + readoutName);
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     /** Creates a new instance of BaseLCSimEvent */
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         // Check if collection exists already which is an error.
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      * Removes a collection from the event.
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         // Set MetaData on collection objects if necessary.
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 }