View Javadoc

1   package org.lcsim.lcio;
2   
3   import java.io.IOException;
4   import java.util.ArrayList;
5   import java.util.List;
6   import java.util.Set;
7   import java.util.HashSet;
8   import java.util.Collections;
9   import hep.io.sio.SIOInputStream;
10  import hep.io.sio.SIOOutputStream;
11  import hep.io.sio.SIORef;
12  import org.lcsim.event.CalorimeterHit;
13  import org.lcsim.event.Cluster;
14  
15  /**
16   * 
17   * @author tonyj
18   */
19  public class SIOCluster implements Cluster
20  {
21      private final static double[] dummy = new double[6];
22      private int type;
23      private float energy;
24      private float energyError;
25      private double raw_energy;
26      private double[] position;
27      private double[] positionError;
28      private float theta;
29      private float phi;
30      private double[] directionError;
31      private double[] shape;
32      private List<Cluster> clusters;
33      private List<CalorimeterHit> calorimeterHits;
34      private double[] hitContributions;
35      private double[] subdetectorEnergies;
36      private List<SIORef> tempHits;
37      private List<SIORef> tempClusters;
38  
39      SIOCluster(SIOInputStream in, int flag, int version) throws IOException
40      {
41          type = in.readInt();
42          energy = in.readFloat();
43          if (version > 1051)
44          {
45              energyError = in.readFloat();
46          }
47          position = new double[3];
48          for (int i = 0; i < 3; i++)
49              position[i] = in.readFloat();
50          positionError = new double[6];
51          for (int i = 0; i < 6; i++)
52              positionError[i] = in.readFloat();
53  
54          theta = in.readFloat();
55          phi = in.readFloat();
56          directionError = new double[3];
57          for (int i = 0; i < 3; i++)
58              directionError[i] = in.readFloat();
59  
60          int nShape;
61          if (version > 1002)
62          {
63              nShape = in.readInt();
64          }
65          else
66          {
67              nShape = 6;
68          }
69          shape = new double[nShape];
70          for (int i = 0; i < nShape; i++)
71          {
72              shape[i] = in.readFloat();
73          }
74  
75          if (version > 1002)
76          {
77              int nPid = in.readInt();
78              // this.particleIDs = new ArrayList(nPid);
79              // for (int i=0; i<nPid; i++)
80              // {
81              // ParticleID id = new SIOParticleID(in,owner,flag,major,minor);
82              // particleIDs.add(id);
83              // }
84          }
85          else
86          {
87              // read 3 dummy floats
88              float[] particleType = new float[3];
89              particleType[0] = in.readFloat();
90              particleType[1] = in.readFloat();
91              particleType[2] = in.readFloat();
92          }
93  
94          int nClust = in.readInt();
95          tempClusters = new ArrayList<SIORef>(nClust);
96          clusters = null;
97          for (int i = 0; i < nClust; i++)
98          {
99              tempClusters.add(in.readPntr());
100         }
101         if ((flag & (1 << LCIOConstants.CLBIT_HITS)) != 0)
102         {
103             int n = in.readInt();
104             tempHits = new ArrayList<SIORef>(n);
105             calorimeterHits = null;
106             this.hitContributions = new double[n];
107             for (int i = 0; i < n; i++)
108             {
109                 tempHits.add(in.readPntr());
110                 hitContributions[i] = in.readFloat();
111             }
112         }
113         int nEnergies = in.readInt();
114         subdetectorEnergies = new double[nEnergies];
115         for (int i = 0; i < nEnergies; i++)
116         {
117             subdetectorEnergies[i] = in.readFloat();
118         }
119         in.readPTag(this);
120     }
121 
122     public List<CalorimeterHit> getCalorimeterHits()
123     {
124         if (calorimeterHits == null && tempHits != null)
125         {
126             calorimeterHits = new ArrayList(tempHits.size());
127             for (SIORef ref : tempHits)
128             {
129                 calorimeterHits.add((CalorimeterHit) ref.getObject());
130             }
131             tempHits.clear();
132             tempHits = null;
133         }
134         if (calorimeterHits == null)
135             return Collections.EMPTY_LIST;
136         else
137             return calorimeterHits;
138     }
139 
140     public List<Cluster> getClusters()
141     {
142         if (clusters == null && tempClusters != null)
143         {
144             clusters = new ArrayList(tempClusters.size());
145             for (SIORef ref : tempClusters)
146             {
147                 clusters.add((Cluster) ref.getObject());
148             }
149             tempClusters.clear();
150             tempClusters = null;
151         }
152         return clusters;
153     }
154 
155     public double[] getDirectionError()
156     {
157         return directionError;
158     }
159 
160     /** Return corrected cluster energy */
161     public double getEnergy()
162     {
163         return energy;
164     }
165 
166     public double getEnergyError()
167     {
168         return energyError;
169     }
170 
171     public double[] getHitContributions()
172     {
173         return hitContributions;
174     }
175 
176     public double getIPhi()
177     {
178         return phi;
179     }
180 
181     public double getITheta()
182     {
183         return theta;
184     }
185 
186     public double[] getPosition()
187     {
188         return position;
189     }
190 
191     public double[] getPositionError()
192     {
193         return positionError;
194     }
195 
196     public double[] getShape()
197     {
198         return shape;
199     }
200 
201     public double[] getSubdetectorEnergies()
202     {
203         return subdetectorEnergies;
204     }
205 
206     /**
207      * Set the subdetector energy contributions
208      * @param energies
209      */
210     public void setSubdetectorEnergies(double[] energies)
211     {
212     	subdetectorEnergies = energies;
213     }
214 
215     public int getType()
216     {
217         return type;
218     }
219 
220     static void write(Cluster cluster, SIOOutputStream out, int flag) throws IOException
221     {
222         out.writeInt(cluster.getType());
223         out.writeFloat((float) cluster.getEnergy());
224         out.writeFloat((float) cluster.getEnergyError());
225         double[] p = cluster.getPosition();
226         if (p == null)
227             p = dummy;
228         for (int i = 0; i < 3; i++)
229             out.writeFloat((float) p[i]);
230         p = cluster.getPositionError();
231         if (p == null)
232             p = dummy;
233         for (int i = 0; i < 6; i++)
234             out.writeFloat((float) p[i]);
235         out.writeFloat((float) cluster.getITheta());
236         out.writeFloat((float) cluster.getIPhi());
237         p = cluster.getDirectionError();
238         if (p == null)
239             p = dummy;
240         for (int i = 0; i < 3; i++)
241             out.writeFloat((float) p[i]);
242 
243         p = cluster.getShape();
244         if (p == null)
245         {
246             out.writeInt(0);
247         }
248         else
249         {
250             out.writeInt(p.length);
251             for (int i = 0; i < p.length; i++)
252             {
253                 out.writeFloat((float) p[i]);
254             }
255         }
256 
257         out.writeInt(0);
258         // List pids = cluster.getParticleIDs() ;
259         // out.writeInt( pids.size());
260         // for (Iterator iter = pids.iterator(); iter.hasNext();)
261         // {
262         // ParticleID pid = (ParticleID) iter.next();
263         // SIOParticleID.write(pid,out);
264         // }
265 
266         List<Cluster> clusters = cluster.getClusters();
267         out.writeInt(clusters.size());
268         for (Cluster c : clusters)
269         {
270             out.writePntr(c);
271         }
272 
273         if ((flag & (1 << LCIOConstants.CLBIT_HITS)) != 0)
274         {
275             List<CalorimeterHit> calorimeterHits = cluster.getCalorimeterHits();
276             double[] hitContributions = cluster.getHitContributions();
277             out.writeInt(calorimeterHits.size());
278             int ii = 0;
279             for (CalorimeterHit hit : calorimeterHits)
280             {
281                 out.writePntr(hit);
282                 out.writeFloat((float) hitContributions[ii++]);
283             }
284         }
285         p = cluster.getSubdetectorEnergies();
286         if (p == null)
287         {
288             out.writeInt(0);
289         }
290         else
291         {
292             out.writeInt(p.length);
293             for (int i = 0; i < p.length; i++)
294             {
295                 out.writeFloat((float) p[i]);
296             }
297         }
298         out.writePTag(cluster);
299     }
300 
301     /**
302      * Return the number of hits comprising the cluster, including hits in subclusters, as per
303      * interface. Hits belonging to more than one cluster/subcluster should be counted only once.
304      */
305     public int getSize()
306     {
307         Set<CalorimeterHit> hitSet = new HashSet<CalorimeterHit>(this.getCalorimeterHits());
308         for (Cluster clus : this.getClusters())
309         {
310             hitSet.addAll(clus.getCalorimeterHits());
311         }
312 
313         // cleanup and return
314         int size = hitSet.size();
315         hitSet.clear();
316         return size;
317     }
318 
319     /**
320      * Return the sum of the raw energies from the hits in the cluster
321      */
322     public double getRawEnergy()
323     {
324         if (raw_energy > 0)
325             return raw_energy;
326 
327         Set<CalorimeterHit> hitSet = new HashSet<CalorimeterHit>(this.getCalorimeterHits());
328         for (Cluster clus : this.getClusters())
329         {
330             hitSet.addAll(clus.getCalorimeterHits());
331         }
332 
333         for (CalorimeterHit hit : hitSet)
334         {
335             raw_energy += hit.getRawEnergy();
336         }
337         return raw_energy;
338     }
339 
340     public int getParticleId() {
341         return 0;
342     }
343 }