1 package org.lcsim.cal.calib;
2 import java.util.List;
3 import java.util.ArrayList;
4 import org.lcsim.event.EventHeader;
5 import org.lcsim.geometry.subdetector.CylindricalCalorimeter;
6 import org.lcsim.event.CalorimeterHit;
7 import org.lcsim.util.Driver;
8 import org.lcsim.util.aida.AIDA;
9 import hep.aida.ITree;
10
11 import static java.lang.Math.sqrt;
12 import java.text.DecimalFormat;
13 import java.util.Calendar;
14 import java.util.Date;
15 import java.util.GregorianCalendar;
16 import org.lcsim.conditions.ConditionsManager;
17 import org.lcsim.conditions.ConditionsManager.ConditionsSetNotFoundException;
18 import org.lcsim.conditions.ConditionsSet;
19 import org.lcsim.event.Cluster;
20 import org.lcsim.geometry.IDDecoder;
21 import org.lcsim.recon.emid.hmatrix.HMatrix;
22 import org.lcsim.recon.emid.hmatrix.HMatrixTask;
23 import org.lcsim.recon.emid.hmatrix.HMatrixBuilder;
24 import org.lcsim.recon.emid.hmatrix.HMatrixConditionsConverter;
25 import org.lcsim.math.chisq.ChisqProb;
26 import org.lcsim.math.moments.CentralMomentsCalculator;
27 import org.lcsim.recon.cluster.fixedcone.FixedConeClusterer;
28 import org.lcsim.recon.cluster.fixedcone.FixedConeClusterer.FixedConeDistanceMetric;
29
30
31
32
33 public class EMClusterID extends Driver
34 {
35 private AIDA aida = AIDA.defaultInstance();
36 private ITree _tree;
37 private boolean _initialized;
38 private ConditionsSet _cond;
39 private String _detName;
40 private HMatrixTask _task;
41 private int _nLayers;
42
43 private HMatrixBuilder _hmb;
44 private HMatrix _hmx;
45
46
47 private int _nmeas;
48
49
50 double[] _vals;
51
52
53 double[] _layerMapping;
54
55 private DecimalFormat _myFormatter = new DecimalFormat("#.###");
56
57 private boolean _debug = true;
58
59
60 private String _fileLocation = "default.hmx";
61
62 public EMClusterID()
63 {
64 this(HMatrixTask.ANALYZE);
65
66 }
67
68 public EMClusterID(HMatrixTask task)
69 {
70 _tree = aida.tree();
71 _task = task;
72
73 if(task==HMatrixTask.ANALYZE)
74 {
75
76 getConditionsManager().registerConditionsConverter(new HMatrixConditionsConverter());
77 }
78
79 }
80
81 protected void process(EventHeader event)
82 {
83 super.process(event);
84
85
86
87
88 String[] det = {"EMBarrel","EMEndcap"};
89 String[] hitsToGet = {"EcalBarrHits","EcalEndcapHits"};
90
91 if(!_initialized)
92 {
93 ConditionsManager mgr = ConditionsManager.defaultInstance();
94 try
95 {
96 _cond = mgr.getConditions("HMatrix");
97 }
98 catch(ConditionsSetNotFoundException e)
99 {
100 System.out.println("ConditionSet HMatrix not found for detector "+mgr.getDetector());
101 System.out.println("Please check that this properties file exists for this detector ");
102 }
103
104 String detectorNameFromFile = _cond.getString("detectorName");
105 if(!detectorNameFromFile.equals(event.getDetectorName()))
106 {
107 System.out.println("detector name from HMatrix.properties: "+detectorNameFromFile +" detector name from event "+event.getDetectorName());
108 throw new RuntimeException("detector name mismatch in HMatrix!");
109 }
110
111 _nmeas = _cond.getInt("measurementDimension");
112
113 _vals = new double[_nmeas];
114
115
116 _fileLocation = event.getDetectorName()+"_"+_fileLocation+"_"+_nmeas+".hmx";
117
118
119 _layerMapping = _cond.getDoubleArray(_nmeas+"layerMapping");
120
121
122
123
124
125
126 CylindricalCalorimeter calsub = (CylindricalCalorimeter)event.getDetector().getSubdetectors().get(det[0]);
127 _nLayers = calsub.getLayering().getLayerCount();
128 if(_nLayers != _layerMapping.length)
129 {
130 System.out.println("found "+_nLayers+" layers in the "+det[0]);
131 throw new RuntimeException("layer number mismatch in EMCalorimeter!");
132 }
133
134
135 int key = 0;
136 if(_task==HMatrixTask.ANALYZE)
137 {
138
139 _hmx = getConditionsManager().getCachedConditions(HMatrix.class, "LongitudinalHMatrix"+_nmeas+".hmx").getCachedData();
140 }
141 else if(_task==HMatrixTask.BUILD)
142 {
143 _hmb = new HMatrixBuilder(_nmeas,key);
144 }
145 _detName = event.getDetectorName();
146
147
148 _initialized = true;
149 }
150
151 List<Cluster> photons = new ArrayList<Cluster>();
152 for(int j=0; j<det.length; ++j)
153 {
154 List<CalorimeterHit> collection = event.get(CalorimeterHit.class,hitsToGet[j]);
155
156
157 double radius = 0.5;
158 double seed = 0.;
159 double minE = 0.05;
160
161
162 FixedConeClusterer fcc = new FixedConeClusterer(radius, seed, minE, FixedConeDistanceMetric.DPHIDTHETA);
163
164 List<Cluster> clusters = fcc.createClusters(collection);
165
166 int minHitsInCluster = 20;
167
168
169 event.put(hitsToGet[j]+"Clusters ",clusters);
170
171 int nGoodClusters = 0;
172 for (Cluster cluster : clusters)
173 {
174 int ncells = cluster.getCalorimeterHits().size();
175 double energy = cluster.getEnergy();
176
177 if(ncells > minHitsInCluster)
178 {
179 nGoodClusters++;
180
181 aida.cloud1D("Number of cells in cluster").fill(ncells);
182 aida.cloud2D("Number of cells in cluster vs cluster energy").fill(energy, ncells);
183
184 aida.cloud2D("Hottest cell in cluster vs cluster energy").fill(energy,hottestCellEnergy(cluster));
185
186 aida.cloud1D("ClusterCorrected energy").fill(energy);
187
188 double[] layerE = layerFractionalEnergies(cluster);
189
190 for(int i=0; i<layerE.length; ++i)
191 {
192 if(_layerMapping[i] != -1)
193 {
194 _vals[(int)_layerMapping[i]] += layerE[i];
195
196 aida.cloud2D("Fractional Energy vs physical Layer").fill(i,layerE[i]);
197 aida.cloud2D("Fractional Energy vs mapped Layer").fill(_layerMapping[i],layerE[i]);
198
199 }
200 }
201
202 for(int i=0; i<_vals.length; ++i)
203 {
204 aida.cloud1D("Fractional Energy for mapped Layer "+i).fill(_vals[i]);
205 for(int k=i+1; k<_vals.length; ++k)
206 {
207 aida.cloud2D("Fractional Energy "+i+" vs "+k).fill(_vals[i], _vals[k]);
208 }
209 }
210
211
212 if (_task==HMatrixTask.BUILD)
213 {
214 _hmb.accumulate(_vals);
215 }
216 if (_task==HMatrixTask.ANALYZE)
217 {
218 double chisq = _hmx.chisquared(_vals);
219 aida.cloud1D("Chisq").fill(chisq);
220 aida.cloud2D("Chisq vs energy").fill(energy,chisq);
221 if(chisq<500)
222 {
223 aida.cloud1D("Chisq(<500)").fill(chisq);
224 aida.cloud2D("Chisq (<500) vs energy").fill(energy,chisq);
225 }
226 aida.cloud1D("Chisq Probability").fill(ChisqProb.gammq(_nmeas,chisq));
227
228 double chisqD = _hmx.chisquaredDiagonal(_vals);
229 aida.cloud1D("ChisqD").fill(chisqD);
230 aida.cloud2D("ChisqD vs energy").fill(energy,chisqD);
231
232 double chisqDProb = ChisqProb.gammq(_nmeas,chisqD);
233 if(chisqDProb<.0000000001) chisqDProb = 0.0000000001;
234 aida.cloud1D("ChisqD Probability").fill(chisqDProb);
235 aida.cloud1D("log10 ChisqDProb").fill(Math.log10(chisqDProb));
236 }
237 double[] pos = cluster.getPosition();
238 aida.cloud2D("centroid x vs y").fill(pos[0], pos[1]);
239 aida.cloud1D("centroid radius").fill( sqrt(pos[0]*pos[0] + pos[1]*pos[1]) );
240
241
242
243 for(int i=0; i<_vals.length; ++i)
244 {
245 _vals[i]=0.;
246 }
247 }
248 }
249 aida.cloud1D(det[j]+ "number of found clusters (above hits threshold)").fill(nGoodClusters);
250 }
251 event.put("photons",photons);
252 }
253
254 private double[] layerFractionalEnergies(Cluster clus)
255 {
256
257 double[] layerEnergies = new double[_nLayers];
258 double clusterEnergy = 0.;
259 List<CalorimeterHit> hits = clus.getCalorimeterHits();
260 for(CalorimeterHit hit : hits)
261 {
262 IDDecoder decoder = hit.getIDDecoder();
263 decoder.setID(hit.getCellID());
264 double e = hit.getCorrectedEnergy();
265 int layer = decoder.getLayer();
266
267 clusterEnergy+=e;
268 layerEnergies[layer]+=e;
269 }
270 for(int i=0; i<_nLayers; ++i)
271 {
272 layerEnergies[i]/=clusterEnergy;
273
274 }
275
276 return layerEnergies;
277 }
278
279 private double hottestCellEnergy(Cluster clus)
280 {
281 double hottestCellEnergy = 0.;
282 List<CalorimeterHit> hits = clus.getCalorimeterHits();
283
284 for(CalorimeterHit hit : hits)
285 {
286 double e = hit.getCorrectedEnergy();
287 if(e>hottestCellEnergy) hottestCellEnergy=e;
288 }
289
290 return hottestCellEnergy;
291 }
292
293 protected void endOfData()
294 {
295 if (_task==HMatrixTask.BUILD)
296 {
297 _hmb.validate();
298 _hmb.write(_fileLocation,commentForHMatrix());
299 }
300 }
301
302 public void setHMatrixFileLocation(String filename)
303 {
304 _fileLocation = filename;
305 }
306
307 private String commentForHMatrix()
308 {
309 Calendar cal = new GregorianCalendar();
310 Date date = new Date();
311 cal.setTime(date);
312 DecimalFormat formatter = new DecimalFormat("00");
313 String day = formatter.format(cal.get(Calendar.DAY_OF_MONTH));
314 String month = formatter.format(cal.get(Calendar.MONTH)+1);
315 String myDate =cal.get(Calendar.YEAR)+month+day;
316 return _detName+" "+myDate+" "+System.getProperty("user.name");
317 }
318 }