1
2
3
4
5
6
7
8
9 package org.lcsim.cal.calib;
10
11 import Jama.Matrix;
12 import hep.aida.ITree;
13 import hep.physics.vec.Hep3Vector;
14 import java.util.List;
15 import org.lcsim.event.CalorimeterHit;
16 import org.lcsim.event.Cluster;
17 import org.lcsim.event.EventHeader;
18 import org.lcsim.event.MCParticle;
19 import org.lcsim.geometry.IDDecoder;
20 import org.lcsim.geometry.subdetector.CylindricalCalorimeter;
21 import org.lcsim.geometry.subdetector.CylindricalEndcapCalorimeter;
22 import org.lcsim.recon.cluster.fixedcone.FixedConeClusterer;
23 import org.lcsim.recon.cluster.fixedcone.FixedConeClusterer.FixedConeDistanceMetric;
24 import org.lcsim.util.Driver;
25 import org.lcsim.util.aida.AIDA;
26
27 import static java.lang.Math.abs;
28 import static java.lang.Math.sqrt;
29 import org.lcsim.conditions.ConditionsManager;
30 import org.lcsim.conditions.ConditionsManager.ConditionsSetNotFoundException;
31 import org.lcsim.conditions.ConditionsSet;
32
33
34
35
36
37 public class SamplingFractionAnalysisDriver extends Driver
38 {
39 private ConditionsSet _cond;
40 private CollectionManager _collectionmanager = CollectionManager.defaultInstance();
41
42
43
44
45
46 private double[][] _acc = new double[3][3];
47 private double[] _vec = new double[3];
48
49
50
51 private FixedConeClusterer _fcc;
52
53 private AIDA aida = AIDA.defaultInstance();
54 private ITree _tree;
55
56 private boolean _initialized = false;
57 private boolean _debug = false;
58
59
60
61 boolean skipFirstLayer = false;
62 int firstEmStartLayer = 0;
63 int secondEmStartLayer = 20;
64
65 double emCalInnerRadius = 0.;
66 double emCalInnerZ = 0.;
67
68
69 public SamplingFractionAnalysisDriver()
70 {
71 _tree = aida.tree();
72 }
73
74
75 protected void process(EventHeader event)
76 {
77 super.process(event);
78
79
80 String[] det = {"EMBarrel","EMEndcap"};
81
82
83
84
85
86
87
88
89 if(!_initialized)
90 {
91 ConditionsManager mgr = ConditionsManager.defaultInstance();
92 try
93 {
94 _cond = mgr.getConditions("CalorimeterCalibration");
95 }
96 catch(ConditionsSetNotFoundException e)
97 {
98 System.out.println("ConditionSet CalorimeterCalibration not found for detector "+mgr.getDetector());
99 System.out.println("Please check that this properties file exists for this detector ");
100 }
101 double radius = .5;
102 double seed = 0.;
103 double minE = .05;
104 _fcc = new FixedConeClusterer(radius, seed, minE, FixedConeDistanceMetric.DPHIDTHETA);
105
106
107
108 CylindricalCalorimeter calsubBarrel = (CylindricalCalorimeter)event.getDetector().getSubdetectors().get(det[0]);
109
110 if(calsubBarrel.getLayering().getLayer(0).getSlices().get(0).isSensitive())
111 {
112 skipFirstLayer = true;
113 firstEmStartLayer += 1;
114 secondEmStartLayer += 1;
115 }
116
117
118
119
120
121
122
123
124
125
126
127
128 emCalInnerRadius = calsubBarrel.getInnerRadius();
129
130 CylindricalEndcapCalorimeter calsubEndcap = (CylindricalEndcapCalorimeter)event.getDetector().getSubdetectors().get(det[1]);
131 emCalInnerZ = abs(calsubEndcap.getZMin());
132 if(skipFirstLayer) System.out.println("processing "+event.getDetectorName()+" with an em calorimeter with a massless first gap");
133 System.out.println("Calorimeter bounds: r= "+emCalInnerRadius+ " z= "+emCalInnerZ);
134 System.out.println("initialized...");
135
136 _initialized = true;
137 }
138
139
140 List<MCParticle> mcparts = event.getMCParticles();
141 MCParticle mcpart = mcparts.get(mcparts.size()-1);
142 String particleType = mcpart.getType().getName();
143 double mcEnergy = mcpart.getEnergy();
144 long mcIntegerEnergy = Math.round(mcEnergy);
145 boolean meV = false;
146 if(mcEnergy<.99)
147 {
148 mcIntegerEnergy = Math.round(mcEnergy*1000);
149 meV = true;
150 }
151
152 _tree.mkdirs(particleType);
153 _tree.cd(particleType);
154 _tree.mkdirs(mcIntegerEnergy+(meV ? "_MeV": "_GeV"));
155 _tree.cd(mcIntegerEnergy+(meV ? "_MeV": "_GeV"));
156
157
158
159
160 Hep3Vector endpoint = mcpart.getEndPoint();
161
162 double radius = sqrt(endpoint.x()*endpoint.x()+endpoint.y()*endpoint.y());
163 double z = endpoint.z();
164
165
166 boolean doit = true;
167 if(radius<emCalInnerRadius && abs(z) < emCalInnerZ) doit = false;
168 if(doit)
169 {
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200 String processedHitsName = _cond.getString("ProcessedHitsCollectionName");
201 List<CalorimeterHit> hitsToCluster = _collectionmanager.getList(processedHitsName);
202
203 if(_debug) System.out.println("clustering "+hitsToCluster.size()+" hits");
204
205
206
207
208
209
210
211 List<Cluster> clusters = _fcc.createClusters(hitsToCluster);
212 if(_debug) System.out.println("found "+clusters.size()+" clusters");
213 aida.histogram1D("number of found clusters", 10, -0.5, 9.5).fill(clusters.size());
214 for(Cluster c : clusters)
215 {
216
217 aida.cloud1D("cluster energy for all clusters").fill(c.getEnergy());
218 }
219
220
221
222 if(clusters.size()>0)
223 {
224 Cluster c = clusters.get(0);
225
226 aida.cloud1D("Highest energy cluster energy").fill(c.getEnergy());
227 aida.cloud1D("Highest energy cluster number of cells").fill(c.getCalorimeterHits().size());
228
229 double clusterEnergy = c.getEnergy();
230 double mcMass = mcpart.getType().getMass();
231
232 double expectedEnergy = sqrt(mcEnergy*mcEnergy - mcMass*mcMass);
233
234 aida.cloud1D("measured - predicted energy").fill(clusterEnergy - expectedEnergy);
235
236
237
238
239
240
241 List<CalorimeterHit> hits = c.getCalorimeterHits();
242 double[] vals = new double[3];
243 double clusterRawEnergy = 0.;
244 for(CalorimeterHit hit : hits)
245 {
246 long id = hit.getCellID();
247 IDDecoder decoder = hit.getIDDecoder();
248 decoder.setID(id);
249 int layer = decoder.getLayer();
250 String detectorName = decoder.getSubdetector().getName();
251 int type = 0;
252 if(detectorName.startsWith("EM"))
253 {
254 if(layer>=firstEmStartLayer && layer<secondEmStartLayer)
255 {
256 type = 0;
257 }
258 else
259 {
260 type = 1;
261 }
262 }
263 if(detectorName.startsWith("HAD"))
264 {
265 type = 2;
266 }
267 clusterRawEnergy += hit.getRawEnergy();
268 vals[type] += hit.getRawEnergy();
269 }
270
271
272 for(int j=0; j<3; ++j)
273 {
274 _vec[j] += expectedEnergy*vals[j];
275 for(int k=0; k<3; ++k)
276 {
277 _acc[j][k] += vals[j]*vals[k];
278 }
279 }
280 }
281
282
283
284 event.put("Found Clusters",clusters);
285 }
286 _tree.cd("/");
287 }
288
289 protected void endOfData()
290 {
291 System.out.println("done! endOfData.");
292
293 Matrix A = new Matrix(_acc, 3, 3);
294 A.print(6,4);
295 Matrix b = new Matrix(3,1);
296 for(int i=0; i<3; ++i)
297 {
298 b.set(i,0,_vec[i]);
299 }
300 b.print(6,4);
301 try
302 {
303 Matrix x = A.solve(b);
304 x.print(6, 4);
305 System.out.println("SamplingFractions: "+ (skipFirstLayer ? "1., ":"")+1./x.get(0,0)+ ", " + 1./x.get(1,0)+", "+1./x.get(2,0));
306 }
307 catch(Exception e)
308 {
309 e.printStackTrace();
310 System.out.println("try reducing dimensionality...");
311 Matrix Ap = new Matrix(_acc, 2, 2);
312 Ap.print(6,4);
313 Matrix bp = new Matrix(2,1);
314 for(int i=0; i<2; ++i)
315 {
316 bp.set(i,0,_vec[i]);
317 }
318 bp.print(6,4);
319 try
320 {
321 Matrix x = Ap.solve(bp);
322 x.print(6, 4);
323 }
324 catch(Exception e2)
325 {
326 e2.printStackTrace();
327 }
328 }
329 }
330 }