1 package org.lcsim.recon.cluster.util;
2
3 import java.util.List;
4 import org.lcsim.spacegeom.PrincipalAxesLineFitter;
5 import org.lcsim.event.CalorimeterHit;
6 import org.lcsim.geometry.IDDecoder;
7 import org.lcsim.util.fourvec.Lorentz4Vector;
8 import org.lcsim.util.fourvec.Momentum4Vector;
9 import org.lcsim.event.Cluster;
10 import org.lcsim.event.base.ClusterPropertyCalculator;
11
12
13
14
15
16
17
18 public class FixedConeClusterPropertyCalculator implements ClusterPropertyCalculator
19 {
20 private IDDecoder _decoder;
21 private Lorentz4Vector _vec;
22
23 private double _width;
24 private double[] _layerEnergy;
25 private double _clusterEnergy;
26 private double[] _layerWidth;
27 private double[] _centroid;
28 private double[] _directionCosines;
29 private double _samplingFraction;
30 private CalorimeterHit _hottestCell;
31 private double _highestCellEnergy;
32 private boolean _isEndCap;
33 private boolean _isNorth;
34 private double _chisq = 99999.;
35 private int layers;
36 private double _itheta;
37 private double _iphi;
38
39
40
41
42 public FixedConeClusterPropertyCalculator()
43 {
44 layers = 100;
45 }
46
47 public void calculateProperties(Cluster cluster) {
48 calculateProperties(cluster.getCalorimeterHits());
49 }
50
51 public void calculateProperties(List<CalorimeterHit> hits)
52 {
53 _vec = calculateVec(hits);
54 _layerEnergy = new double[layers];
55 _layerWidth = new double[layers];
56
57 double[][] points = new double[3][hits.size()];
58 int npoints=0;
59 _highestCellEnergy = 0.;
60
61 for(CalorimeterHit h : hits )
62 {
63 _decoder = h.getIDDecoder();
64 _decoder.setID(h.getCellID());
65 double e = h.getCorrectedEnergy();
66 if (e>_highestCellEnergy)
67 {
68 _highestCellEnergy = e;
69 _hottestCell = h;
70
71
72
73 }
74
75 double dtheta=_vec.theta() - _decoder.getTheta();
76 double dphi=_vec.phi() - _decoder.getPhi();
77
78 if (dphi>Math.PI)
79 {
80 dphi-=2.*Math.PI;
81 }
82 if (dphi<-Math.PI)
83 {
84 dphi+=2.*Math.PI;
85 }
86 double dRw=(dtheta*dtheta + dphi*dphi)*e;
87 _width+=dRw;
88
89 _layerEnergy[_decoder.getLayer()]+=e;
90 _clusterEnergy+=e;
91
92 _layerWidth[_decoder.getLayer()]+=dRw;
93
94 points[0][npoints] = _decoder.getX();
95 points[1][npoints] = _decoder.getY();
96 points[2][npoints] = _decoder.getZ();
97 npoints++;
98 }
99
100 _width /= _clusterEnergy;
101 for(int i=0; i<layers; ++i)
102 {
103 _layerWidth[i]/=_clusterEnergy;
104 }
105
106
107 PrincipalAxesLineFitter lf = new PrincipalAxesLineFitter();
108 lf.fit(points);
109 _centroid = lf.centroid();
110 _directionCosines = lf.dircos();
111 double dr = Math.sqrt( (_centroid[0]+_directionCosines[0])*(_centroid[0]+_directionCosines[0]) +
112 (_centroid[1]+_directionCosines[1])*(_centroid[1]+_directionCosines[1]) +
113 (_centroid[2]+_directionCosines[2])*(_centroid[2]+_directionCosines[2]) ) -
114 Math.sqrt( (_centroid[0])*(_centroid[0]) +
115 (_centroid[1])*(_centroid[1]) +
116 (_centroid[2])*(_centroid[2]) ) ;
117 double sign = 1.;
118 if(dr < 0.)sign = -1.;
119 _itheta = Math.acos(_directionCosines[2]);
120 _iphi = Math.atan2(_directionCosines[1],_directionCosines[0]);
121
122
123
124 }
125
126
127
128
129
130
131 public Lorentz4Vector calculateVec(List<CalorimeterHit> hits)
132 {
133 Lorentz4Vector sum = new Momentum4Vector();
134 double[] sums = {0.,0.,0.};
135 double wtsum = 0.;
136 for(int i=0;i<hits.size();i++)
137 {
138 CalorimeterHit hit = hits.get(i);
139 double[] pos = new double[3];
140 _decoder = hit.getIDDecoder();
141 _decoder.setID(hit.getCellID());
142 pos[0] = _decoder.getX();
143 pos[1] = _decoder.getY();
144 pos[2] = _decoder.getZ();
145 double wt = hit.getCorrectedEnergy();
146 wtsum += wt;
147 for(int j=0;j<3;j++)
148 {
149 sums[j] += wt*pos[j];
150 }
151 }
152 sum.plusEquals(new Momentum4Vector(sums[0], sums[1], sums[2], wtsum));
153 return sum;
154 }
155
156
157
158
159
160
161 public double width()
162 {
163 return _width;
164 }
165
166
167
168
169
170
171 public Lorentz4Vector vector()
172 {
173 return _vec;
174 }
175
176
177
178
179
180
181
182
183
184
185
186 public double layerEnergy(int layer)
187 {
188 return _layerEnergy[layer];
189 }
190
191
192
193
194
195
196 public double[] layerEnergies()
197 {
198 return _layerEnergy;
199 }
200
201
202
203
204
205
206
207 public double clusterEnergy()
208 {
209 return _clusterEnergy;
210 }
211
212
213
214
215
216
217 public double highestCellEnergy()
218 {
219 return _highestCellEnergy;
220 }
221
222
223
224
225
226
227 public CalorimeterHit hottestCell()
228 {
229 return _hottestCell;
230 }
231
232
233
234
235
236
237 public double layerWidth(int layer)
238 {
239 return _layerWidth[layer];
240 }
241
242
243
244
245
246
247 public double[] centroid()
248 {
249 return _centroid;
250 }
251
252
253
254
255
256
257 public double[] directionCosines()
258 {
259 return _directionCosines;
260 }
261
262
263
264
265
266
267
268 public boolean isEndCap()
269 {
270 return _isEndCap;
271 }
272
273
274
275
276
277
278
279 public boolean isNorth()
280 {
281 return _isNorth;
282 }
283
284 public void setChisq(double chisq)
285 {
286 _chisq = chisq;
287 }
288
289 public double chisq()
290 {
291 return _chisq;
292 }
293 public double[] getPosition()
294 {
295 return _centroid;
296 }
297 public double[] getPositionError()
298 {
299 double[] positionError = {0.,0.,0.,0.,0.,0.};
300 return positionError;
301 }
302 public double getIPhi()
303 {
304 return _iphi;
305 }
306 public double getITheta()
307 {
308 return _itheta;
309 }
310 public double[] getDirectionError()
311 {
312 double[] directionError = {0.,0.,0.,0.,0.,0.};
313 return directionError;
314 }
315 public double[] getShapeParameters()
316 {
317 double[] shapeParameters = {0.,0.,0.,0.,0.,0.};
318 shapeParameters[0] = _width;
319 return shapeParameters;
320 }
321
322
323 }
324