1
2
3
4
5
6 package org.lcsim.cal.calib;
7
8 import static java.lang.Math.sqrt;
9 import hep.aida.ITree;
10
11 import java.util.List;
12
13 import org.lcsim.conditions.ConditionsManager;
14 import org.lcsim.conditions.ConditionsSet;
15 import org.lcsim.conditions.ConditionsManager.ConditionsSetNotFoundException;
16 import org.lcsim.event.CalorimeterHit;
17 import org.lcsim.event.Cluster;
18 import org.lcsim.event.EventHeader;
19 import org.lcsim.event.MCParticle;
20 import org.lcsim.geometry.IDDecoder;
21 import org.lcsim.recon.cluster.fixedcone.FixedConeClusterer;
22 import org.lcsim.util.Driver;
23 import org.lcsim.util.aida.AIDA;
24
25 import Jama.Matrix;
26 import java.util.HashMap;
27 import java.util.Map;
28 import org.lcsim.event.ReconstructedParticle;
29 import org.lcsim.event.SimCalorimeterHit;
30
31
32
33
34
35 public class PandoraPfoSamplingFractionAnalysislDriver extends Driver
36 {
37
38 private ConditionsSet _cond;
39 private CollectionManager _collectionmanager = CollectionManager.defaultInstance();
40
41
42
43
44
45 private double[][] _acc = new double[3][3];
46 private double[] _vec = new double[3];
47
48
49 private FixedConeClusterer _fcc;
50 private AIDA aida = AIDA.defaultInstance();
51 private ITree _tree;
52 private boolean _initialized = false;
53 private boolean _debug = false;
54 private double[] _ecalLayering;
55 boolean _useFirstLayer;
56
57 boolean _isHcalDigital = false;
58
59
60
61
62 public PandoraPfoSamplingFractionAnalysislDriver()
63 {
64 _tree = aida.tree();
65 }
66
67 protected void process(EventHeader event)
68 {
69
70 if (!_initialized) {
71 ConditionsManager mgr = ConditionsManager.defaultInstance();
72 try {
73 _cond = mgr.getConditions("CalorimeterCalibration");
74 } catch (ConditionsSetNotFoundException e) {
75 System.out.println("ConditionSet CalorimeterCalibration not found for detector " + mgr.getDetector());
76 System.out.println("Please check that this properties file exists for this detector ");
77 }
78
79 _ecalLayering = _cond.getDoubleArray("ECalLayering");
80 _useFirstLayer = _cond.getDouble("IsFirstEmLayerSampling") == 1.;
81
82 ConditionsSet hcalProperties = mgr.getConditions("SamplingFractions/HcalBarrel");
83
84 _isHcalDigital = hcalProperties.getBoolean("digital");
85 System.out.println("HCal is " + (_isHcalDigital == true ? "" : "not") + " read out digitally");
86
87 System.out.println("initialized...");
88
89 _initialized = true;
90 }
91
92
93 List<MCParticle> mcparts = event.getMCParticles();
94
95 MCParticle mcpart = null;
96
97 for (MCParticle myMCP : mcparts) {
98 if (myMCP.getGeneratorStatus() == MCParticle.FINAL_STATE) {
99 if (mcpart == null) {
100 mcpart = myMCP;
101 } else if (mcpart.getEnergy() < myMCP.getEnergy()) {
102 mcpart = myMCP;
103 }
104 }
105 }
106 if (mcpart != null) {
107 String particleType = mcpart.getType().getName();
108 double mcEnergy = mcpart.getEnergy();
109 long mcIntegerEnergy = Math.round(mcEnergy);
110 boolean meV = false;
111 if (mcEnergy < .99) {
112 mcIntegerEnergy = Math.round(mcEnergy * 1000);
113 meV = true;
114 }
115
116
117
118
119 Map<Long, SimCalorimeterHit> simCalHitMap = new HashMap<Long, SimCalorimeterHit>();
120
121 List<List<SimCalorimeterHit>> collections = event.get(SimCalorimeterHit.class);
122 for (List<SimCalorimeterHit> collection : collections) {
123 for (SimCalorimeterHit hit : collection) {
124 simCalHitMap.put(hit.getCellID(), hit);
125 }
126 }
127
128 _tree.mkdirs(particleType);
129 _tree.cd(particleType);
130 _tree.mkdirs(mcIntegerEnergy + (meV ? "_MeV" : "_GeV"));
131 _tree.cd(mcIntegerEnergy + (meV ? "_MeV" : "_GeV"));
132
133 if (mcpart.getSimulatorStatus().isDecayedInCalorimeter()) {
134 List<ReconstructedParticle> rpCollection = event.get(ReconstructedParticle.class, "PandoraPFOCollection");
135 if (_debug) {
136 System.out.println("found " + rpCollection.size() + " ReconstructedParticles");
137 }
138
139
140 if (rpCollection.size() == 1) {
141
142 for (ReconstructedParticle p : rpCollection) {
143 if (_debug) {
144 System.out.println(" energy " + p.getEnergy());
145 }
146 }
147
148 ReconstructedParticle p = rpCollection.get(0);
149 List<Cluster> clusters = p.getClusters();
150 if (_debug) {
151 System.out.println("found " + clusters.size() + " clusters");
152 }
153 aida.histogram1D("number of found clusters", 10, -0.5, 9.5).fill(clusters.size());
154
155 if (clusters.size() > 0) {
156 int nHCalHits = 0;
157 for (Cluster c : clusters) {
158 aida.cloud1D("Highest energy cluster energy").fill(c.getEnergy());
159 aida.cloud1D("Highest energy cluster number of cells").fill(c.getCalorimeterHits().size());
160
161 double clusterEnergy = c.getEnergy();
162 double mcMass = mcpart.getType().getMass();
163
164 double expectedEnergy = mcEnergy;
165
166 if (mcpart.getPDGID() == 2212 || mcpart.getPDGID() == 2112) {
167 expectedEnergy = mcEnergy - mcMass;
168 }
169
170 aida.cloud1D("measured - predicted energy").fill(clusterEnergy - expectedEnergy);
171
172
173
174
175
176
177 List<CalorimeterHit> hits = c.getCalorimeterHits();
178 double[] vals = new double[4];
179 double clusterEnergySum = 0.;
180 double rawEnergySum = 0.;
181 for (CalorimeterHit hit : hits) {
182 long id = hit.getCellID();
183 IDDecoder decoder = hit.getIDDecoder();
184 decoder.setID(id);
185 SimCalorimeterHit simHit = simCalHitMap.get(id);
186 double rawEnergy = simHit.getRawEnergy();
187 double correctedEnergy = hit.getCorrectedEnergy();
188 int layer = decoder.getLayer();
189 String detectorName = decoder.getSubdetector().getName();
190
191 int caltype = 0;
192
193 if (detectorName.toUpperCase().startsWith("ECAL")) {
194 for (int i = 1; i < _ecalLayering.length + 1; ++i) {
195 if (layer >= _ecalLayering[i - 1]) {
196 caltype = i - 1;
197 }
198 }
199 }
200
201 if (detectorName.toUpperCase().startsWith("HCAL")) {
202 caltype = 3;
203 nHCalHits += 1;
204 }
205
206 clusterEnergy += hit.getCorrectedEnergy();
207
208 vals[caltype] += rawEnergy;
209 }
210 if (_isHcalDigital == true) {
211 vals[3] = nHCalHits;
212 }
213 if (_debug) {
214 System.out.println("vals: " + vals[0] + " " + vals[1] + " " + vals[2] + " " + vals[3]);
215 }
216
217
218 for (int j = 0; j < 3; ++j) {
219 _vec[j] += expectedEnergy * vals[j + 1];
220 for (int k = 0; k < 3; ++k) {
221 _acc[j][k] += vals[j + 1] * vals[k + 1];
222 }
223 }
224 }
225 }
226 }
227
228
229
230
231
232 }
233 }
234 _tree.cd("/");
235 }
236
237 protected void endOfData()
238 {
239 System.out.println("done! endOfData.");
240
241 Matrix A = new Matrix(_acc, 3, 3);
242 A.print(6, 4);
243 Matrix b = new Matrix(3, 1);
244 for (int i = 0; i < 3; ++i) {
245 b.set(i, 0, _vec[i]);
246 }
247 b.print(6, 4);
248 try {
249 Matrix x = A.solve(b);
250 x.print(6, 4);
251 System.out.println("SamplingFractions: " + 1. / x.get(0, 0) + ", " + 1. / x.get(1, 0) + ", " + 1. / x.get(2, 0));
252 } catch (Exception e) {
253 e.printStackTrace();
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271 }
272 }
273
274 public void setDebug(boolean debug)
275 {
276 _debug = debug;
277 }
278 }