Process the event and put new data products into it.
100 {
101 if (!event.
exists(inputTrackCollName_))
return;
102 if (!event.
exists(inputEcalCollName_))
return;
103 if (!event.
exists(inputHcalCollName_))
return;
104
105 const auto ecalClusters =
107 const auto hcalClusters =
109 const auto tracks =
111
112 std::vector<ldmx::PFCandidate> pfCands;
113
114 if (!singleParticle_) {
115
116
117
118
119
120
121
122
123
124
125
126
127
128 std::map<int, std::vector<int> > tkCaloMap;
129 std::map<int, std::vector<int> > caloTkMap;
130 std::map<std::pair<int, int>, float> tkEMDist;
131
132 for (int i = 0; i < tracks.size(); i++) {
133 const auto& tk = tracks[i];
134 const std::vector<float> xyz = tk.getPosition();
135 const std::vector<double> pxyz = tk.getMomentum();
136 const float p = sqrt(pow(pxyz[0], 2) + pow(pxyz[1], 2) + pow(pxyz[2], 2));
137
138 for (int j = 0; j < ecalClusters.size(); j++) {
139 const auto& ecal = ecalClusters[j];
140
141 const float ecalClusZ = ecal.getCentroidZ();
142 const float tkXAtClus =
143 xyz[0] + pxyz[0] / pxyz[2] * (ecalClusZ - xyz[2]);
144 const float tkYAtClus =
145 xyz[1] + pxyz[1] / pxyz[2] * (ecalClusZ - xyz[2]);
146 float dist = hypot(
147 (tkXAtClus - ecal.getCentroidX()) / std::max(1.0, ecal.getRMSX()),
148 (tkYAtClus - ecal.getCentroidY()) / std::max(1.0, ecal.getRMSY()));
149 tkEMDist[{i, j}] = dist;
150 bool isMatch =
151 (dist < 2) && (ecal.getEnergy() > 0.3 * p &&
152 ecal.getEnergy() < 2 * p);
153
154 if (isMatch) {
155 if (tkCaloMap.count(i))
156 tkCaloMap[i].push_back(j);
157 else
158 tkCaloMap[i] = {j};
159 if (caloTkMap.count(j))
160 caloTkMap[j].push_back(i);
161 else
162 caloTkMap[j] = {i};
163 }
164 }
165 }
166
167
168 std::map<int, std::vector<int> > emHadCaloMap;
169 std::map<std::pair<int, int>, float> EMHadDist;
170 for (int i = 0; i < ecalClusters.size(); i++) {
171 const auto& ecal = ecalClusters[i];
172 for (int j = 0; j < hcalClusters.size(); j++) {
173 const auto& hcal = hcalClusters[j];
174
175 const float xAtHClus =
176 ecal.getCentroidX() +
177 ecal.getDXDZ() * (hcal.getCentroidZ() -
178 ecal.getCentroidZ());
179 const float yAtHClus =
180 ecal.getCentroidY() +
181 ecal.getDYDZ() * (hcal.getCentroidZ() - ecal.getCentroidZ());
182 float dist = sqrt(
183 pow(xAtHClus - hcal.getCentroidX(), 2) /
184 std::max(1.0, pow(hcal.getRMSX(), 2) + pow(ecal.getRMSX(), 2)) +
185 pow(yAtHClus - hcal.getCentroidY(), 2) /
186 std::max(1.0, pow(hcal.getRMSY(), 2) + pow(ecal.getRMSY(), 2)));
187 EMHadDist[{i, j}] = dist;
188 bool isMatch = (dist < 5);
189 if (isMatch) {
190 if (emHadCaloMap.count(i))
191 emHadCaloMap[i].push_back(j);
192 else
193 emHadCaloMap[i] = {j};
194 }
195 }
196 }
197
198
199
200 std::map<int, std::vector<int> > tkHadCaloMap;
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217 std::vector<bool> tkIsEMLinked(tracks.size(), false);
218 std::vector<bool> EMIsTkLinked(ecalClusters.size(), false);
219 std::map<int, int> tkEMPairs{};
220 for (int i = 0; i < tracks.size(); i++) {
221 if (tkCaloMap.count(i)) {
222
223 for (int em_idx : tkCaloMap[i]) {
224 if (!EMIsTkLinked[em_idx]) {
225 EMIsTkLinked[em_idx] = true;
226 tkIsEMLinked[i] = true;
227 tkEMPairs[i] = em_idx;
228 break;
229 }
230 }
231 }
232 }
233
234
235 std::vector<bool> EMIsHadLinked(ecalClusters.size(), false);
236 std::vector<bool> HadIsEMLinked(hcalClusters.size(), false);
237 std::map<int, int> EMHadPairs{};
238 for (int i = 0; i < ecalClusters.size(); i++) {
239 if (emHadCaloMap.count(i)) {
240
241 for (int had_idx : emHadCaloMap[i]) {
242 if (!HadIsEMLinked[had_idx]) {
243 HadIsEMLinked[had_idx] = true;
244 EMIsHadLinked[i] = true;
245 EMHadPairs[i] = had_idx;
246 break;
247 }
248 }
249 }
250 }
251
252
253
254
255
256
257
258
259
260
261
262 for (int i = 0; i < tracks.size(); i++) {
264 fillCandTrack(cand, tracks[i]);
265
266 if (!tkIsEMLinked[i]) {
267
268 } else {
269 fillCandEMCalo(cand, ecalClusters[tkEMPairs[i]]);
270 if (EMIsHadLinked[tkEMPairs[i]]) {
271
272 fillCandHadCalo(cand, hcalClusters[EMHadPairs[tkEMPairs[i]]]);
273 }
274
275 }
276 pfCands.push_back(cand);
277 }
278
279
280
281 for (int i = 0; i < ecalClusters.size(); i++) {
282
283 if (EMIsTkLinked[i]) continue;
284
286 fillCandEMCalo(cand, ecalClusters[i]);
287 if (EMIsHadLinked[tkEMPairs[i]]) {
288 fillCandHadCalo(cand, hcalClusters[EMHadPairs[i]]);
289
290 } else {
291
292 }
293 pfCands.push_back(cand);
294 }
295 std::vector<ldmx::PFCandidate> hadOnly;
296 for (int i = 0; i < hcalClusters.size(); i++) {
297 if (HadIsEMLinked[i]) continue;
299 fillCandHadCalo(cand, hcalClusters[i]);
300
301 pfCands.push_back(cand);
302 }
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374 } else {
375
377 int pid = 0;
378 if (tracks.size()) {
379 fillCandTrack(pf, tracks[0]);
380 pid += 1;
381 }
382 if (ecalClusters.size()) {
383 fillCandEMCalo(pf, ecalClusters[0]);
384 pid += 2;
385 }
386 if (hcalClusters.size()) {
387 fillCandHadCalo(pf, hcalClusters[0]);
388 pid += 4;
389 }
390 pf.setPID(pid);
391 pf.setEnergy(pf.getEcalEnergy() + pf.getHcalEnergy());
392 pfCands.push_back(pf);
393 }
394
395 event.add(outputCollName_, pfCands);
396}
bool exists(const std::string &name, const std::string &passName="", bool unique=true) const
Check for the existence of an object or collection with the given name and pass name in the event.
Stores cluster information from the ECal.
Represents a reconstructed particle.
Represents a simulated tracker hit in the simulation.