Process the event and put new data products into it.
135 {
136 if (!event.
exists(input_track_coll_name_, input_tracks_passname_)) {
137 ldmx_log(error) << "Unable to find (one) collection named "
138 << input_track_coll_name_ << "_" << input_tracks_passname_;
139 return;
140 }
141 if (!event.
exists(input_ecal_coll_name_, input_ecal_passname_)) {
142 ldmx_log(error) << "Unable to find (one) collection named "
143 << input_ecal_coll_name_ << "_" << input_ecal_passname_;
144 return;
145 }
146 if (!event.
exists(input_hcal_coll_name_, input_hcal_passname_)) {
147 ldmx_log(error) << "Unable to find (one) collection named "
148 << input_hcal_coll_name_ << "_" << input_hcal_passname_;
149 return;
150 }
151
153 input_hcal_coll_name_, input_hcal_passname_);
155 input_track_coll_name_, input_tracks_passname_);
156
157 const auto ecal_clusters =
158 use_existing_ecal_clusters_
159 ? getEcalClusters(event, input_ecal_coll_name_, input_ecal_passname_)
160 : event.getCollection<ldmx::CaloCluster>(input_ecal_coll_name_,
161 input_ecal_passname_);
162
163 std::vector<ldmx::PFCandidate> pf_cands;
164
165 if (!single_particle_) {
166
167
168
169
170
171
172
173
174
175
176
177
178
179 std::map<int, std::vector<int> > tk_calo_map;
180 std::map<int, std::vector<int> > calo_tk_map;
181 std::map<std::pair<int, int>, float> tk_em_dist;
182
183 for (int i = 0; i < tracks.size(); i++) {
184 const auto& tk = tracks[i];
185 const std::vector<float> xyz = tk.getPosition();
186 const std::vector<double> pxyz = tk.getMomentum();
187 const float p = sqrt(pow(pxyz[0], 2) + pow(pxyz[1], 2) + pow(pxyz[2], 2));
188
189 for (int j = 0; j < ecal_clusters.size(); j++) {
190 const auto& ecal = ecal_clusters[j];
191
192 const float ecal_clus_z = ecal.getCentroidZ();
193 const float tk_x_at_clus =
194 xyz[0] +
195 pxyz[0] / pxyz[2] * (ecal_clus_z - xyz[2]);
196 const float tk_y_at_clus =
197 xyz[1] + pxyz[1] / pxyz[2] * (ecal_clus_z - xyz[2]);
198 float dist = hypot((tk_x_at_clus - ecal.getCentroidX()) /
199 std::max(1.0, ecal.getRMSX()),
200 (tk_y_at_clus - ecal.getCentroidY()) /
201 std::max(1.0, ecal.getRMSY()));
202 tk_em_dist[{i, j}] = dist;
203 bool is_match =
204 (dist < 2) && (ecal.getEnergy() > 0.3 * p &&
205 ecal.getEnergy() < 2 * p);
206
207 if (is_match) {
208 if (tk_calo_map.count(i))
209 tk_calo_map[i].push_back(j);
210 else
211 tk_calo_map[i] = {j};
212 if (calo_tk_map.count(j))
213 calo_tk_map[j].push_back(i);
214 else
215 calo_tk_map[j] = {i};
216 }
217 }
218 }
219
220
221 std::map<int, std::vector<int> > em_had_calo_map;
222 std::map<std::pair<int, int>, float> em_had_dist;
223 for (int i = 0; i < ecal_clusters.size(); i++) {
224 const auto& ecal = ecal_clusters[i];
225 for (int j = 0; j < hcal_clusters.size(); j++) {
226 const auto& hcal = hcal_clusters[j];
227
228 const float x_at_h_clus =
229 ecal.getCentroidX() +
230 ecal.getDXDZ() * (hcal.getCentroidZ() -
231 ecal.getCentroidZ());
232 const float y_at_h_clus =
233 ecal.getCentroidY() +
234 ecal.getDYDZ() * (hcal.getCentroidZ() - ecal.getCentroidZ());
235 float dist = sqrt(
236 pow(x_at_h_clus - hcal.getCentroidX(), 2) /
237 std::max(1.0, pow(hcal.getRMSX(), 2) + pow(ecal.getRMSX(), 2)) +
238 pow(y_at_h_clus - hcal.getCentroidY(), 2) /
239 std::max(1.0, pow(hcal.getRMSY(), 2) + pow(ecal.getRMSY(), 2)));
240 em_had_dist[{i, j}] = dist;
241 bool is_match = (dist < 5);
242 if (is_match) {
243 if (em_had_calo_map.count(i))
244 em_had_calo_map[i].push_back(j);
245 else
246 em_had_calo_map[i] = {j};
247 }
248 }
249 }
250
251
252
253 std::map<int, std::vector<int> > tk_had_calo_map;
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270 std::vector<bool> tk_is_em_linked(tracks.size(), false);
271 std::vector<bool> em_is_tk_linked(ecal_clusters.size(), false);
272 std::map<int, int> tk_em_pairs{};
273 for (int i = 0; i < tracks.size(); i++) {
274 if (tk_calo_map.count(i)) {
275
276 for (int em_idx : tk_calo_map[i]) {
277 if (!em_is_tk_linked[em_idx]) {
278 em_is_tk_linked[em_idx] = true;
279 tk_is_em_linked[i] = true;
280 tk_em_pairs[i] = em_idx;
281 break;
282 }
283 }
284 }
285 }
286
287
288 std::vector<bool> em_is_had_linked(ecal_clusters.size(), false);
289 std::vector<bool> had_is_em_linked(hcal_clusters.size(), false);
290 std::map<int, int> em_had_pairs{};
291 for (int i = 0; i < ecal_clusters.size(); i++) {
292 if (em_had_calo_map.count(i)) {
293
294 for (int had_idx : em_had_calo_map[i]) {
295 if (!had_is_em_linked[had_idx]) {
296 had_is_em_linked[had_idx] = true;
297 em_is_had_linked[i] = true;
298 em_had_pairs[i] = had_idx;
299 break;
300 }
301 }
302 }
303 }
304
305
306
307
308
309
310
311
312
313
314
315 for (int i = 0; i < tracks.size(); i++) {
317 fillCandTrack(cand, tracks[i]);
318
319 cand.setTrackIndex(i);
320 if (!tk_is_em_linked[i]) {
321
322 } else {
323 fillCandEMCalo(cand, ecal_clusters[tk_em_pairs[i]]);
324 cand.setEcalIndex(tk_em_pairs[i]);
325 if (em_is_had_linked[tk_em_pairs[i]]) {
326
327 fillCandHadCalo(cand, hcal_clusters[em_had_pairs[tk_em_pairs[i]]]);
328 }
329
330 }
331 pf_cands.push_back(cand);
332 }
333
334
335
336 for (int i = 0; i < ecal_clusters.size(); i++) {
337
338 if (em_is_tk_linked[i]) continue;
340 fillCandEMCalo(cand, ecal_clusters[i]);
341 cand.setEcalIndex(i);
342 if (em_is_had_linked[tk_em_pairs[i]]) {
343 fillCandHadCalo(cand, hcal_clusters[em_had_pairs[i]]);
344
345 } else {
346
347 }
348 pf_cands.push_back(cand);
349 }
350 std::vector<ldmx::PFCandidate> had_only;
351 for (int i = 0; i < hcal_clusters.size(); i++) {
352 if (had_is_em_linked[i]) continue;
354 fillCandHadCalo(cand, hcal_clusters[i]);
355 cand.setHcalIndex(i);
356
357 pf_cands.push_back(cand);
358 }
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430 } else {
431
433 int pid = 0;
434 if (tracks.size()) {
435 fillCandTrack(pf, tracks[0]);
436 pid += 1;
437 }
438 if (ecal_clusters.size()) {
439 fillCandEMCalo(pf, ecal_clusters[0]);
440 pid += 2;
441 }
442 if (hcal_clusters.size()) {
443 fillCandHadCalo(pf, hcal_clusters[0]);
444 pid += 4;
445 }
446 pf.setPID(pid);
447 pf.setEnergy(pf.getEcalEnergy() + pf.getHcalEnergy());
448 pf_cands.push_back(pf);
449 }
450
451 event.
add(output_coll_name_, pf_cands);
452}
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.
void add(const std::string &collectionName, T &obj)
Adds an object to the event bus.
Represents a reconstructed particle.
Represents a simulated tracker hit in the simulation.