Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
LArPandoraHelper.cxx
Go to the documentation of this file.
1
9
10#include "art/Framework/Principal/Event.h"
11#include "art/Framework/Principal/Handle.h"
12#include "art/Framework/Services/Registry/ServiceHandle.h"
13#include "canvas/Persistency/Common/FindManyP.h"
14#include "canvas/Persistency/Common/FindOneP.h"
15#include "cetlib_except/exception.h"
16#include "messagefacility/MessageLogger/MessageLogger.h"
17
18#include "lardataobj/AnalysisBase/BackTrackerMatchingData.h"
19#include "lardataobj/AnalysisBase/CosmicTag.h"
20#include "lardataobj/AnalysisBase/T0.h"
21#include "lardataobj/RecoBase/Cluster.h"
22#include "lardataobj/RecoBase/Hit.h"
23#include "lardataobj/RecoBase/PFParticle.h"
24#include "lardataobj/RecoBase/PFParticleMetadata.h"
25#include "lardataobj/RecoBase/Seed.h"
26#include "lardataobj/RecoBase/Shower.h"
27#include "lardataobj/RecoBase/Slice.h"
28#include "lardataobj/RecoBase/SpacePoint.h"
29#include "lardataobj/RecoBase/Track.h"
30#include "lardataobj/RecoBase/Vertex.h"
31#include "lardataobj/RecoBase/Wire.h"
32#include "nusimdata/SimulationBase/MCTruth.h"
33
34#include "larcore/Geometry/Geometry.h"
35#include "larcoreobj/SimpleTypesAndConstants/RawTypes.h"
36#include "lardata/DetectorInfoServices/DetectorClocksService.h"
37
40#include "Pandora/PdgTable.h"
41
42#include <iostream>
43#include <limits>
44
45namespace lar_pandora {
46
47 void LArPandoraHelper::CollectWires(const art::Event& evt,
48 const std::string& label,
49 WireVector& wireVector)
50 {
51 art::Handle<std::vector<recob::Wire>> theWires;
52 evt.getByLabel(label, theWires);
53
54 if (!theWires.isValid()) {
55 mf::LogDebug("LArPandora") << " Failed to find wires... " << std::endl;
56 return;
57 }
58 else {
59 mf::LogDebug("LArPandora") << " Found: " << theWires->size() << " Wires " << std::endl;
60 }
61
62 for (unsigned int i = 0; i < theWires->size(); ++i) {
63 const art::Ptr<recob::Wire> wire(theWires, i);
64 wireVector.push_back(wire);
65 }
66 }
67
68 //------------------------------------------------------------------------------------------------------------------------------------------
69
70 void LArPandoraHelper::CollectHits(const art::Event& evt,
71 const std::string& label,
72 HitVector& hitVector)
73 {
74 art::Handle<std::vector<recob::Hit>> theHits;
75 evt.getByLabel(label, theHits);
76
77 if (!theHits.isValid()) {
78 mf::LogDebug("LArPandora") << " Failed to find hits... " << std::endl;
79 return;
80 }
81 else {
82 mf::LogDebug("LArPandora") << " Found: " << theHits->size() << " Hits " << std::endl;
83 }
84
85 for (unsigned int i = 0; i < theHits->size(); ++i) {
86 const art::Ptr<recob::Hit> hit(theHits, i);
87 hitVector.push_back(hit);
88 }
89 }
90
91 //------------------------------------------------------------------------------------------------------------------------------------------
92
93 void LArPandoraHelper::CollectPFParticles(const art::Event& evt,
94 const std::string& label,
95 PFParticleVector& particleVector)
96 {
97 art::Handle<std::vector<recob::PFParticle>> theParticles;
98 evt.getByLabel(label, theParticles);
99
100 if (!theParticles.isValid()) {
101 mf::LogDebug("LArPandora") << " Failed to find particles... " << std::endl;
102 return;
103 }
104 else {
105 mf::LogDebug("LArPandora") << " Found: " << theParticles->size() << " PFParticles "
106 << std::endl;
107 }
108
109 for (unsigned int i = 0; i < theParticles->size(); ++i) {
110 const art::Ptr<recob::PFParticle> particle(theParticles, i);
111 particleVector.push_back(particle);
112 }
113 }
114
115 //------------------------------------------------------------------------------------------------------------------------------------------
116
117 void LArPandoraHelper::CollectSpacePoints(const art::Event& evt,
118 const std::string& label,
119 SpacePointVector& spacePointVector,
120 SpacePointsToHits& spacePointsToHits)
121 {
122 HitsToSpacePoints hitsToSpacePoints;
124 evt, label, spacePointVector, spacePointsToHits, hitsToSpacePoints);
125 }
126
127 //------------------------------------------------------------------------------------------------------------------------------------------
128
129 void LArPandoraHelper::CollectSpacePoints(const art::Event& evt,
130 const std::string& label,
131 SpacePointVector& spacePointVector,
132 SpacePointsToHits& spacePointsToHits,
133 HitsToSpacePoints& hitsToSpacePoints)
134 {
135 art::Handle<std::vector<recob::SpacePoint>> theSpacePoints;
136 evt.getByLabel(label, theSpacePoints);
137
138 if (!theSpacePoints.isValid()) {
139 mf::LogDebug("LArPandora") << " Failed to find spacepoints... " << std::endl;
140 return;
141 }
142 else {
143 mf::LogDebug("LArPandora") << " Found: " << theSpacePoints->size() << " SpacePoints "
144 << std::endl;
145 }
146
147 art::FindOneP<recob::Hit> theHitAssns(theSpacePoints, evt, label);
148 for (unsigned int i = 0; i < theSpacePoints->size(); ++i) {
149 const art::Ptr<recob::SpacePoint> spacepoint(theSpacePoints, i);
150 spacePointVector.push_back(spacepoint);
151 const art::Ptr<recob::Hit> hit = theHitAssns.at(i);
152 spacePointsToHits[spacepoint] = hit;
153 hitsToSpacePoints[hit] = spacepoint;
154 }
155 }
156
157 //------------------------------------------------------------------------------------------------------------------------------------------
158
159 void LArPandoraHelper::CollectClusters(const art::Event& evt,
160 const std::string& label,
161 ClusterVector& clusterVector,
162 ClustersToHits& clustersToHits)
163 {
164 art::Handle<std::vector<recob::Cluster>> theClusters;
165 evt.getByLabel(label, theClusters);
166
167 if (!theClusters.isValid()) {
168 mf::LogDebug("LArPandora") << " Failed to find clusters... " << std::endl;
169 return;
170 }
171 else {
172 mf::LogDebug("LArPandora") << " Found: " << theClusters->size() << " Clusters " << std::endl;
173 }
174
175 art::FindManyP<recob::Hit> theHitAssns(theClusters, evt, label);
176 for (unsigned int i = 0; i < theClusters->size(); ++i) {
177 const art::Ptr<recob::Cluster> cluster(theClusters, i);
178 clusterVector.push_back(cluster);
179
180 const std::vector<art::Ptr<recob::Hit>> hits = theHitAssns.at(i);
181 for (unsigned int j = 0; j < hits.size(); ++j) {
182 const art::Ptr<recob::Hit> hit = hits.at(j);
183 clustersToHits[cluster].push_back(hit);
184 }
185 }
186 }
187
188 //------------------------------------------------------------------------------------------------------------------------------------------
189
190 void LArPandoraHelper::CollectPFParticles(const art::Event& evt,
191 const std::string& label,
192 PFParticleVector& particleVector,
193 PFParticlesToSpacePoints& particlesToSpacePoints)
194 {
195 art::Handle<std::vector<recob::PFParticle>> theParticles;
196 evt.getByLabel(label, theParticles);
197
198 if (!theParticles.isValid()) {
199 mf::LogDebug("LArPandora") << " Failed to find particles... " << std::endl;
200 return;
201 }
202 else {
203 mf::LogDebug("LArPandora") << " Found: " << theParticles->size() << " PFParticles "
204 << std::endl;
205 }
206
207 art::FindManyP<recob::SpacePoint> theSpacePointAssns(theParticles, evt, label);
208 for (unsigned int i = 0; i < theParticles->size(); ++i) {
209 const art::Ptr<recob::PFParticle> particle(theParticles, i);
210 particleVector.push_back(particle);
211
212 const std::vector<art::Ptr<recob::SpacePoint>> spacepoints = theSpacePointAssns.at(i);
213 for (unsigned int j = 0; j < spacepoints.size(); ++j) {
214 const art::Ptr<recob::SpacePoint> spacepoint = spacepoints.at(j);
215 particlesToSpacePoints[particle].push_back(spacepoint);
216 }
217 }
218 }
219
220 //------------------------------------------------------------------------------------------------------------------------------------------
221
222 void LArPandoraHelper::CollectPFParticles(const art::Event& evt,
223 const std::string& label,
224 PFParticleVector& particleVector,
225 PFParticlesToClusters& particlesToClusters)
226 {
227 art::Handle<std::vector<recob::PFParticle>> theParticles;
228 evt.getByLabel(label, theParticles);
229
230 if (!theParticles.isValid()) {
231 mf::LogDebug("LArPandora") << " Failed to find particles... " << std::endl;
232 return;
233 }
234 else {
235 mf::LogDebug("LArPandora") << " Found: " << theParticles->size() << " PFParticles "
236 << std::endl;
237 }
238
239 art::FindManyP<recob::Cluster> theClusterAssns(theParticles, evt, label);
240 for (unsigned int i = 0; i < theParticles->size(); ++i) {
241 const art::Ptr<recob::PFParticle> particle(theParticles, i);
242 particleVector.push_back(particle);
243
244 const std::vector<art::Ptr<recob::Cluster>> clusters = theClusterAssns.at(i);
245 for (unsigned int j = 0; j < clusters.size(); ++j) {
246 const art::Ptr<recob::Cluster> cluster = clusters.at(j);
247 particlesToClusters[particle].push_back(cluster);
248 }
249 }
250 }
251
252 //------------------------------------------------------------------------------------------------------------------------------------------
253
255 const std::string& label,
256 PFParticleVector& particleVector,
257 PFParticlesToMetadata& particlesToMetadata)
258 {
259 art::Handle<std::vector<recob::PFParticle>> theParticles;
260 evt.getByLabel(label, theParticles);
261
262 if (!theParticles.isValid()) {
263 mf::LogDebug("LArPandora") << " Failed to find particles... " << std::endl;
264 return;
265 }
266 else {
267 mf::LogDebug("LArPandora") << " Found: " << theParticles->size() << " PFParticles "
268 << std::endl;
269 }
270
271 art::FindManyP<larpandoraobj::PFParticleMetadata> theMetadataAssns(theParticles, evt, label);
272 for (unsigned int i = 0; i < theParticles->size(); ++i) {
273 const art::Ptr<recob::PFParticle> particle(theParticles, i);
274 particleVector.push_back(particle);
275
276 const std::vector<art::Ptr<larpandoraobj::PFParticleMetadata>> pfParticleMetadataList =
277 theMetadataAssns.at(i);
278 for (unsigned int j = 0; j < pfParticleMetadataList.size(); ++j) {
279 const art::Ptr<larpandoraobj::PFParticleMetadata> pfParticleMetadata =
280 pfParticleMetadataList.at(j);
281 particlesToMetadata[particle].push_back(pfParticleMetadata);
282 }
283 }
284 }
285
286 //------------------------------------------------------------------------------------------------------------------------------------------
287
288 void LArPandoraHelper::CollectShowers(const art::Event& evt,
289 const std::string& label,
290 ShowerVector& showerVector,
291 PFParticlesToShowers& particlesToShowers)
292 {
293 art::Handle<std::vector<recob::Shower>> theShowers;
294 evt.getByLabel(label, theShowers);
295
296 if (!theShowers.isValid()) {
297 mf::LogDebug("LArPandora") << " Failed to find showers... " << std::endl;
298 return;
299 }
300 else {
301 mf::LogDebug("LArPandora") << " Found: " << theShowers->size() << " Showers " << std::endl;
302 }
303
304 art::FindManyP<recob::PFParticle> theShowerAssns(theShowers, evt, label);
305 for (unsigned int i = 0; i < theShowers->size(); ++i) {
306 const art::Ptr<recob::Shower> shower(theShowers, i);
307 showerVector.push_back(shower);
308
309 const std::vector<art::Ptr<recob::PFParticle>> particles = theShowerAssns.at(i);
310 for (unsigned int j = 0; j < particles.size(); ++j) {
311 const art::Ptr<recob::PFParticle> particle = particles.at(j);
312 particlesToShowers[particle].push_back(shower);
313 }
314 }
315 }
316
317 //------------------------------------------------------------------------------------------------------------------------------------------
318
319 void LArPandoraHelper::CollectTracks(const art::Event& evt,
320 const std::string& label,
321 TrackVector& trackVector,
322 PFParticlesToTracks& particlesToTracks)
323 {
324 art::Handle<std::vector<recob::Track>> theTracks;
325 evt.getByLabel(label, theTracks);
326
327 if (!theTracks.isValid()) {
328 mf::LogDebug("LArPandora") << " Failed to find tracks... " << std::endl;
329 return;
330 }
331 else {
332 mf::LogDebug("LArPandora") << " Found: " << theTracks->size() << " Tracks " << std::endl;
333 }
334
335 art::FindManyP<recob::PFParticle> theTrackAssns(theTracks, evt, label);
336 for (unsigned int i = 0; i < theTracks->size(); ++i) {
337 const art::Ptr<recob::Track> track(theTracks, i);
338 trackVector.push_back(track);
339
340 const std::vector<art::Ptr<recob::PFParticle>> particles = theTrackAssns.at(i);
341 for (unsigned int j = 0; j < particles.size(); ++j) {
342 const art::Ptr<recob::PFParticle> particle = particles.at(j);
343 particlesToTracks[particle].push_back(track);
344 }
345 }
346 }
347
348 //------------------------------------------------------------------------------------------------------------------------------------------
349
350 void LArPandoraHelper::CollectTracks(const art::Event& evt,
351 const std::string& label,
352 TrackVector& trackVector,
353 TracksToHits& tracksToHits)
354 {
355 art::Handle<std::vector<recob::Track>> theTracks;
356 evt.getByLabel(label, theTracks);
357
358 if (!theTracks.isValid()) {
359 mf::LogDebug("LArPandora") << " Failed to find tracks... " << std::endl;
360 return;
361 }
362 else {
363 mf::LogDebug("LArPandora") << " Found: " << theTracks->size() << " Tracks " << std::endl;
364 }
365
366 art::FindManyP<recob::Hit> theHitAssns(theTracks, evt, label);
367 for (unsigned int i = 0; i < theTracks->size(); ++i) {
368 const art::Ptr<recob::Track> track(theTracks, i);
369 trackVector.push_back(track);
370
371 const std::vector<art::Ptr<recob::Hit>> hits = theHitAssns.at(i);
372 for (unsigned int j = 0; j < hits.size(); ++j) {
373 const art::Ptr<recob::Hit> hit = hits.at(j);
374 tracksToHits[track].push_back(hit);
375 }
376 }
377 }
378
379 //------------------------------------------------------------------------------------------------------------------------------------------
380
381 void LArPandoraHelper::CollectShowers(const art::Event& evt,
382 const std::string& label,
383 ShowerVector& showerVector,
384 ShowersToHits& showersToHits)
385 {
386 art::Handle<std::vector<recob::Shower>> theShowers;
387 evt.getByLabel(label, theShowers);
388
389 if (!theShowers.isValid()) {
390 mf::LogDebug("LArPandora") << " Failed to find showers... " << std::endl;
391 return;
392 }
393 else {
394 mf::LogDebug("LArPandora") << " Found: " << theShowers->size() << " Showers " << std::endl;
395 }
396
397 art::FindManyP<recob::Hit> theHitAssns(theShowers, evt, label);
398 for (unsigned int i = 0; i < theShowers->size(); ++i) {
399 const art::Ptr<recob::Shower> shower(theShowers, i);
400 showerVector.push_back(shower);
401
402 const std::vector<art::Ptr<recob::Hit>> hits = theHitAssns.at(i);
403 for (unsigned int j = 0; j < hits.size(); ++j) {
404 const art::Ptr<recob::Hit> hit = hits.at(j);
405 showersToHits[shower].push_back(hit);
406 }
407 }
408 }
409
410 //------------------------------------------------------------------------------------------------------------------------------------------
411
412 void LArPandoraHelper::CollectSeeds(const art::Event& evt,
413 const std::string& label,
414 SeedVector& seedVector,
415 PFParticlesToSeeds& particlesToSeeds)
416 {
417 art::Handle<std::vector<recob::Seed>> theSeeds;
418 evt.getByLabel(label, theSeeds);
419
420 if (!theSeeds.isValid()) {
421 mf::LogDebug("LArPandora") << " Failed to find seeds... " << std::endl;
422 return;
423 }
424 else {
425 mf::LogDebug("LArPandora") << " Found: " << theSeeds->size() << " Seeds " << std::endl;
426 }
427
428 art::FindManyP<recob::PFParticle> theSeedAssns(theSeeds, evt, label);
429 for (unsigned int i = 0; i < theSeeds->size(); ++i) {
430 const art::Ptr<recob::Seed> seed(theSeeds, i);
431 seedVector.push_back(seed);
432
433 const std::vector<art::Ptr<recob::PFParticle>> particles = theSeedAssns.at(i);
434 for (unsigned int j = 0; j < particles.size(); ++j) {
435 const art::Ptr<recob::PFParticle> particle = particles.at(j);
436 particlesToSeeds[particle].push_back(seed);
437 }
438 }
439 }
440
441 //------------------------------------------------------------------------------------------------------------------------------------------
442
443 void LArPandoraHelper::CollectSeeds(const art::Event& evt,
444 const std::string& label,
445 SeedVector& seedVector,
446 SeedsToHits& seedsToHits)
447 {
448 art::Handle<std::vector<recob::Seed>> theSeeds;
449 evt.getByLabel(label, theSeeds);
450
451 if (!theSeeds.isValid()) {
452 mf::LogDebug("LArPandora") << " Failed to find seeds... " << std::endl;
453 return;
454 }
455 else {
456 mf::LogDebug("LArPandora") << " Found: " << theSeeds->size() << " Seeds " << std::endl;
457 }
458
459 art::FindOneP<recob::Hit> theHitAssns(theSeeds, evt, label);
460
461 if (!theHitAssns.isValid()) {
462 mf::LogDebug("LArPandora") << " Failed to find seed associations... " << std::endl;
463 return;
464 }
465
466 for (unsigned int i = 0; i < theSeeds->size(); ++i) {
467 const art::Ptr<recob::Seed> seed(theSeeds, i);
468 seedVector.push_back(seed);
469 const art::Ptr<recob::Hit> hit = theHitAssns.at(i);
470 seedsToHits[seed] = hit;
471 }
472 }
473
474 //------------------------------------------------------------------------------------------------------------------------------------------
475
476 void LArPandoraHelper::CollectVertices(const art::Event& evt,
477 const std::string& label,
478 VertexVector& vertexVector,
479 PFParticlesToVertices& particlesToVertices)
480 {
481 art::Handle<std::vector<recob::Vertex>> theVertices;
482 evt.getByLabel(label, theVertices);
483
484 if (!theVertices.isValid()) {
485 mf::LogDebug("LArPandora") << " Failed to find vertices... " << std::endl;
486 return;
487 }
488 else {
489 mf::LogDebug("LArPandora") << " Found: " << theVertices->size() << " Vertices " << std::endl;
490 }
491
492 art::FindManyP<recob::PFParticle> theVerticesAssns(theVertices, evt, label);
493 for (unsigned int i = 0; i < theVertices->size(); ++i) {
494 const art::Ptr<recob::Vertex> vertex(theVertices, i);
495 vertexVector.push_back(vertex);
496
497 const std::vector<art::Ptr<recob::PFParticle>> particles = theVerticesAssns.at(i);
498 for (unsigned int j = 0; j < particles.size(); ++j) {
499 const art::Ptr<recob::PFParticle> particle = particles.at(j);
500 particlesToVertices[particle].push_back(vertex);
501 }
502 }
503 }
504
505 //------------------------------------------------------------------------------------------------------------------------------------------
506
508 const PFParticleVector& particleVector,
509 const PFParticlesToSpacePoints& particlesToSpacePoints,
510 const SpacePointsToHits& spacePointsToHits,
511 PFParticlesToHits& particlesToHits,
512 HitsToPFParticles& hitsToParticles,
513 const DaughterMode daughterMode)
514 {
515 // Build mapping from particle to particle ID for parent/daughter navigation
516 PFParticleMap particleMap;
517
518 for (PFParticleVector::const_iterator iter1 = particleVector.begin(),
519 iterEnd1 = particleVector.end();
520 iter1 != iterEnd1;
521 ++iter1) {
522 const art::Ptr<recob::PFParticle> particle = *iter1;
523 particleMap[particle->Self()] = particle;
524 }
525
526 // Loop over hits and build mapping between reconstructed final-state particles and reconstructed hits
527 for (PFParticlesToSpacePoints::const_iterator iter1 = particlesToSpacePoints.begin(),
528 iterEnd1 = particlesToSpacePoints.end();
529 iter1 != iterEnd1;
530 ++iter1) {
531 const art::Ptr<recob::PFParticle> thisParticle = iter1->first;
532 const art::Ptr<recob::PFParticle> particle(
533 (kAddDaughters == daughterMode) ?
534 LArPandoraHelper::GetFinalStatePFParticle(particleMap, thisParticle) :
535 thisParticle);
536
537 if ((kIgnoreDaughters == daughterMode) &&
538 !LArPandoraHelper::IsFinalState(particleMap, particle))
539 continue;
540
541 const SpacePointVector& spacePointVector = iter1->second;
542
543 for (SpacePointVector::const_iterator iter2 = spacePointVector.begin(),
544 iterEnd2 = spacePointVector.end();
545 iter2 != iterEnd2;
546 ++iter2) {
547 const art::Ptr<recob::SpacePoint> spacepoint = *iter2;
548
549 SpacePointsToHits::const_iterator iter3 = spacePointsToHits.find(spacepoint);
550 if (spacePointsToHits.end() == iter3)
551 throw cet::exception("LArPandora") << " PandoraCollector::BuildPFParticleHitMaps --- "
552 "Found a space point without an associated hit ";
553
554 const art::Ptr<recob::Hit> hit = iter3->second;
555
556 particlesToHits[particle].push_back(hit);
557 hitsToParticles[hit] = particle;
558 }
559 }
560 }
561
562 //------------------------------------------------------------------------------------------------------------------------------------------
563
565 const PFParticlesToClusters& particlesToClusters,
566 const ClustersToHits& clustersToHits,
567 PFParticlesToHits& particlesToHits,
568 HitsToPFParticles& hitsToParticles,
569 const DaughterMode daughterMode)
570 {
571 // Build mapping from particle to particle ID for parent/daughter navigation
572 PFParticleMap particleMap;
573
574 for (PFParticleVector::const_iterator iter1 = particleVector.begin(),
575 iterEnd1 = particleVector.end();
576 iter1 != iterEnd1;
577 ++iter1) {
578 const art::Ptr<recob::PFParticle> particle = *iter1;
579 particleMap[particle->Self()] = particle;
580 }
581
582 // Loop over hits and build mapping between reconstructed final-state particles and reconstructed hits
583 for (PFParticlesToClusters::const_iterator iter1 = particlesToClusters.begin(),
584 iterEnd1 = particlesToClusters.end();
585 iter1 != iterEnd1;
586 ++iter1) {
587 const art::Ptr<recob::PFParticle> thisParticle = iter1->first;
588 const art::Ptr<recob::PFParticle> particle(
589 (kAddDaughters == daughterMode) ?
590 LArPandoraHelper::GetFinalStatePFParticle(particleMap, thisParticle) :
591 thisParticle);
592
593 if ((kIgnoreDaughters == daughterMode) &&
594 !LArPandoraHelper::IsFinalState(particleMap, particle))
595 continue;
596
597 const ClusterVector& clusterVector = iter1->second;
598 for (ClusterVector::const_iterator iter2 = clusterVector.begin(),
599 iterEnd2 = clusterVector.end();
600 iter2 != iterEnd2;
601 ++iter2) {
602 const art::Ptr<recob::Cluster> cluster = *iter2;
603
604 ClustersToHits::const_iterator iter3 = clustersToHits.find(cluster);
605 if (clustersToHits.end() == iter3)
606 throw cet::exception("LArPandora") << " PandoraCollector::BuildPFParticleHitMaps --- "
607 "Found a space point without an associated hit ";
608
609 const HitVector& hitVector = iter3->second;
610 for (HitVector::const_iterator iter4 = hitVector.begin(), iterEnd4 = hitVector.end();
611 iter4 != iterEnd4;
612 ++iter4) {
613 const art::Ptr<recob::Hit> hit = *iter4;
614
615 particlesToHits[particle].push_back(hit);
616 hitsToParticles[hit] = particle;
617 }
618 }
619 }
620 }
621
622 //------------------------------------------------------------------------------------------------------------------------------------------
623
625 const std::string& label,
626 PFParticlesToHits& particlesToHits,
627 HitsToPFParticles& hitsToParticles,
628 const DaughterMode daughterMode,
629 const bool useClusters)
630 {
632 evt, label, label, particlesToHits, hitsToParticles, daughterMode, useClusters);
633 }
634
635 //------------------------------------------------------------------------------------------------------------------------------------------
636
638 const std::string& label_pfpart,
639 const std::string& label_middle,
640 PFParticlesToHits& particlesToHits,
641 HitsToPFParticles& hitsToParticles,
642 const DaughterMode daughterMode,
643 const bool useClusters)
644 {
645 // Use intermediate clusters
646 if (useClusters) {
647 PFParticleVector particleVector;
648 PFParticlesToClusters particlesToClusters;
649
650 ClusterVector clusterVector;
651 ClustersToHits clustersToHits;
652
653 LArPandoraHelper::CollectPFParticles(evt, label_pfpart, particleVector, particlesToClusters);
654 LArPandoraHelper::CollectClusters(evt, label_middle, clusterVector, clustersToHits);
655
657 particlesToClusters,
658 clustersToHits,
659 particlesToHits,
660 hitsToParticles,
661 daughterMode);
662 }
663
664 // Use intermediate space points
665 else {
666 PFParticleVector particleVector;
667 PFParticlesToSpacePoints particlesToSpacePoints;
668
669 SpacePointVector spacePointVector;
670 SpacePointsToHits spacePointsToHits;
671
673 evt, label_pfpart, particleVector, particlesToSpacePoints);
674 LArPandoraHelper::CollectSpacePoints(evt, label_middle, spacePointVector, spacePointsToHits);
675
677 particlesToSpacePoints,
678 spacePointsToHits,
679 particlesToHits,
680 hitsToParticles,
681 daughterMode);
682 }
683 }
684
685 //------------------------------------------------------------------------------------------------------------------------------------------
686
688 PFParticleVector& outputParticles)
689 {
690 for (PFParticleVector::const_iterator iter = inputParticles.begin(),
691 iterEnd = inputParticles.end();
692 iter != iterEnd;
693 ++iter) {
694 const art::Ptr<recob::PFParticle> particle = *iter;
695
696 if (LArPandoraHelper::IsNeutrino(particle)) outputParticles.push_back(particle);
697 }
698 }
699
700 //------------------------------------------------------------------------------------------------------------------------------------------
701
703 PFParticleVector& outputParticles)
704 {
705 // Build mapping from particle to particle ID for parent/daughter navigation
706 PFParticleMap particleMap;
707
708 for (PFParticleVector::const_iterator iter = inputParticles.begin(),
709 iterEnd = inputParticles.end();
710 iter != iterEnd;
711 ++iter) {
712 const art::Ptr<recob::PFParticle> particle = *iter;
713 particleMap[particle->Self()] = particle;
714 }
715
716 // Select final-state particles
717 for (PFParticleVector::const_iterator iter = inputParticles.begin(),
718 iterEnd = inputParticles.end();
719 iter != iterEnd;
720 ++iter) {
721 const art::Ptr<recob::PFParticle> particle = *iter;
722
723 if (LArPandoraHelper::IsFinalState(particleMap, particle))
724 outputParticles.push_back(particle);
725 }
726 }
727
728 //------------------------------------------------------------------------------------------------------------------------------------------
729
730 void LArPandoraHelper::CollectCosmicTags(const art::Event& evt,
731 const std::string& label,
732 CosmicTagVector& cosmicTagVector,
733 TracksToCosmicTags& tracksToCosmicTags)
734 {
735 art::Handle<std::vector<anab::CosmicTag>> theCosmicTags;
736 evt.getByLabel(label, theCosmicTags);
737
738 if (theCosmicTags.isValid()) {
739 art::FindOneP<recob::Track> theCosmicAssns(
740 theCosmicTags, evt, label); // We assume there is one tag per algorithm
741 for (unsigned int i = 0; i < theCosmicTags->size(); ++i) {
742 const art::Ptr<anab::CosmicTag> cosmicTag(theCosmicTags, i);
743 const art::Ptr<recob::Track> track = theCosmicAssns.at(i);
744 tracksToCosmicTags[track].push_back(
745 cosmicTag); // We assume there could be multiple algorithms
746 cosmicTagVector.push_back(cosmicTag);
747 }
748 }
749 }
750
751 //------------------------------------------------------------------------------------------------------------------------------------------
752
753 void LArPandoraHelper::CollectT0s(const art::Event& evt,
754 const std::string& label,
755 T0Vector& t0Vector,
756 PFParticlesToT0s& particlesToT0s)
757 {
758 art::Handle<std::vector<anab::T0>> theT0s;
759 evt.getByLabel(label, theT0s);
760
761 if (theT0s.isValid()) {
762 art::FindManyP<recob::PFParticle> theAssns(theT0s, evt, label);
763 for (unsigned int i = 0; i < theT0s->size(); ++i) {
764 const art::Ptr<anab::T0> theT0(theT0s, i);
765 t0Vector.push_back(theT0);
766
767 const std::vector<art::Ptr<recob::PFParticle>> particles = theAssns.at(i);
768 for (unsigned int j = 0; j < particles.size(); ++j) {
769 const art::Ptr<recob::PFParticle> theParticle = particles.at(j);
770 particlesToT0s[theParticle].push_back(
771 theT0); // We assume there could be multiple T0s per PFParticle
772 }
773 }
774 }
775 }
776
777 //------------------------------------------------------------------------------------------------------------------------------------------
778
779 void LArPandoraHelper::CollectSimChannels(const art::Event& evt,
780 const std::string& label,
781 SimChannelVector& simChannelVector,
782 bool& areSimChannelsValid)
783 {
784 art::Handle<std::vector<sim::SimChannel>> theSimChannels;
785 evt.getByLabel(label, theSimChannels);
786
787 if (!theSimChannels.isValid()) {
788 mf::LogDebug("LArPandora") << " Failed to find sim channels... " << std::endl;
789 areSimChannelsValid = false;
790 return;
791 }
792 else {
793 mf::LogDebug("LArPandora") << " Found: " << theSimChannels->size() << " SimChannels "
794 << std::endl;
795 areSimChannelsValid = true;
796 }
797
798 for (unsigned int i = 0; i < theSimChannels->size(); ++i) {
799 const art::Ptr<sim::SimChannel> channel(theSimChannels, i);
800 simChannelVector.push_back(channel);
801 }
802 }
803
804 //------------------------------------------------------------------------------------------------------------------------------------------
805
806 void LArPandoraHelper::CollectMCParticles(const art::Event& evt,
807 const std::string& label,
808 MCParticleVector& particleVector)
809 {
810 art::Handle<RawMCParticleVector> theParticles;
811 evt.getByLabel(label, theParticles);
812
813 if (!theParticles.isValid()) {
814 mf::LogDebug("LArPandora") << " Failed to find MC particles... " << std::endl;
815 return;
816 }
817 else {
818 mf::LogDebug("LArPandora") << " Found: " << theParticles->size() << " MC particles "
819 << std::endl;
820 }
821
822 for (unsigned int i = 0; i < theParticles->size(); ++i) {
823 const art::Ptr<simb::MCParticle> particle(theParticles, i);
824 particleVector.push_back(particle);
825 }
826 }
827
828 //------------------------------------------------------------------------------------------------------------------------------------------
829
831 const std::string& label,
832 RawMCParticleVector& particleVector)
833 {
834 art::Handle<std::vector<simb::MCTruth>> mcTruthBlocks;
835 evt.getByLabel(label, mcTruthBlocks);
836
837 if (!mcTruthBlocks.isValid()) {
838 mf::LogDebug("LArPandora") << " Failed to find MC truth blocks from generator... "
839 << std::endl;
840 return;
841 }
842 else {
843 mf::LogDebug("LArPandora") << " Found: " << mcTruthBlocks->size() << " MC truth blocks "
844 << std::endl;
845 }
846
847 if (mcTruthBlocks->size() != 1)
848 throw cet::exception("LArPandora") << " PandoraCollector::CollectGeneratorMCParticles --- "
849 "Unexpected number of MC truth blocks ";
850
851 const art::Ptr<simb::MCTruth> mcTruth(mcTruthBlocks, 0);
852
853 for (int i = 0; i < mcTruth->NParticles(); ++i) {
854 particleVector.push_back(mcTruth->GetParticle(i));
855 }
856 }
857
858 //------------------------------------------------------------------------------------------------------------------------------------------
859
860 void LArPandoraHelper::CollectMCParticles(const art::Event& evt,
861 const std::string& label,
862 MCTruthToMCParticles& truthToParticles,
863 MCParticlesToMCTruth& particlesToTruth)
864 {
865 art::Handle<RawMCParticleVector> theParticles;
866 evt.getByLabel(label, theParticles);
867
868 if (!theParticles.isValid()) {
869 mf::LogDebug("LArPandora") << " Failed to find MC particles... " << std::endl;
870 return;
871 }
872 else {
873 mf::LogDebug("LArPandora") << " Found: " << theParticles->size() << " MC particles "
874 << std::endl;
875 }
876
877 art::FindOneP<simb::MCTruth> theTruthAssns(theParticles, evt, label);
878
879 for (unsigned int i = 0, iEnd = theParticles->size(); i < iEnd; ++i) {
880 const art::Ptr<simb::MCParticle> particle(theParticles, i);
881 const art::Ptr<simb::MCTruth> truth(theTruthAssns.at(i));
882 truthToParticles[truth].push_back(particle);
883 particlesToTruth[particle] = truth;
884 }
885 }
886
887 //------------------------------------------------------------------------------------------------------------------------------------------
888
890 const HitVector& hitVector,
891 const SimChannelVector& simChannelVector,
892 HitsToTrackIDEs& hitsToTrackIDEs)
893 {
894 auto const clock_data =
895 art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
896
897 SimChannelMap simChannelMap;
898
899 for (SimChannelVector::const_iterator iter = simChannelVector.begin(),
900 iterEnd = simChannelVector.end();
901 iter != iterEnd;
902 ++iter) {
903 const art::Ptr<sim::SimChannel> simChannel = *iter;
904 simChannelMap.insert(SimChannelMap::value_type(simChannel->Channel(), simChannel));
905 }
906
907 for (HitVector::const_iterator iter = hitVector.begin(), iterEnd = hitVector.end();
908 iter != iterEnd;
909 ++iter) {
910 const art::Ptr<recob::Hit> hit = *iter;
911
912 SimChannelMap::const_iterator sIter = simChannelMap.find(hit->Channel());
913 if (simChannelMap.end() == sIter) continue; // Hit has no truth information [continue]
914
915 // ATTN: Need to convert TDCtick (integer) to TDC (unsigned integer) before passing to simChannel
916 const raw::TDCtick_t start_tick(clock_data.TPCTick2TDC(hit->PeakTimeMinusRMS()));
917 const raw::TDCtick_t end_tick(clock_data.TPCTick2TDC(hit->PeakTimePlusRMS()));
918 const unsigned int start_tdc((start_tick < 0) ? 0 : start_tick);
919 const unsigned int end_tdc(end_tick);
920
921 if (start_tdc > end_tdc) continue; // Hit undershoots the readout window [continue]
922
923 const art::Ptr<sim::SimChannel> simChannel = sIter->second;
924 const TrackIDEVector trackCollection(simChannel->TrackIDEs(start_tdc, end_tdc));
925
926 if (trackCollection.empty()) continue; // Hit has no truth information [continue]
927
928 for (unsigned int iTrack = 0, iTrackEnd = trackCollection.size(); iTrack < iTrackEnd;
929 ++iTrack) {
930 const sim::TrackIDE trackIDE = trackCollection.at(iTrack);
931 hitsToTrackIDEs[hit].push_back(trackIDE);
932 }
933 }
934 }
935
936 //------------------------------------------------------------------------------------------------------------------------------------------
937
939 const MCTruthToMCParticles& truthToParticles,
940 MCParticlesToHits& particlesToHits,
941 HitsToMCParticles& hitsToParticles,
942 const DaughterMode daughterMode)
943 {
944 // Build mapping between particles and track IDs for parent/daughter navigation
945 MCParticleMap particleMap;
946
947 for (MCTruthToMCParticles::const_iterator iter1 = truthToParticles.begin(),
948 iterEnd1 = truthToParticles.end();
949 iter1 != iterEnd1;
950 ++iter1) {
951 const MCParticleVector& particleVector = iter1->second;
952 for (MCParticleVector::const_iterator iter2 = particleVector.begin(),
953 iterEnd2 = particleVector.end();
954 iter2 != iterEnd2;
955 ++iter2) {
956 const art::Ptr<simb::MCParticle> particle = *iter2;
957 particleMap[particle->TrackId()] = particle;
958 }
959 }
960
961 // Loop over hits and build mapping between reconstructed hits and true particles
962 for (HitsToTrackIDEs::const_iterator iter1 = hitsToTrackIDEs.begin(),
963 iterEnd1 = hitsToTrackIDEs.end();
964 iter1 != iterEnd1;
965 ++iter1) {
966 const art::Ptr<recob::Hit> hit = iter1->first;
967 const TrackIDEVector& trackCollection = iter1->second;
968
969 int bestTrackID(-1);
970 float bestEnergyFrac(0.f);
971
972 for (TrackIDEVector::const_iterator iter2 = trackCollection.begin(),
973 iterEnd2 = trackCollection.end();
974 iter2 != iterEnd2;
975 ++iter2) {
976 const sim::TrackIDE& trackIDE = *iter2;
977 const int trackID(std::abs(trackIDE.trackID)); // TODO: Find out why std::abs is needed
978 const float energyFrac(trackIDE.energyFrac);
979
980 if (energyFrac > bestEnergyFrac) {
981 bestEnergyFrac = energyFrac;
982 bestTrackID = trackID;
983 }
984 }
985
986 if (bestTrackID >= 0) {
987 MCParticleMap::const_iterator iter3 = particleMap.find(bestTrackID);
988 if (particleMap.end() == iter3)
989 throw cet::exception("LArPandora") << " PandoraCollector::BuildMCParticleHitMaps --- "
990 "Found a track ID without an MC Particle ";
991
992 try {
993 const art::Ptr<simb::MCParticle> thisParticle = iter3->second;
994 const art::Ptr<simb::MCParticle> primaryParticle(
995 LArPandoraHelper::GetFinalStateMCParticle(particleMap, thisParticle));
996 const art::Ptr<simb::MCParticle> selectedParticle(
997 (kAddDaughters == daughterMode) ? primaryParticle : thisParticle);
998
999 if ((kIgnoreDaughters == daughterMode) && (selectedParticle != primaryParticle)) continue;
1000
1001 if (!(LArPandoraHelper::IsVisible(selectedParticle))) continue;
1002
1003 particlesToHits[selectedParticle].push_back(hit);
1004 hitsToParticles[hit] = selectedParticle;
1005 }
1006 catch (cet::exception& e) {
1007 }
1008 }
1009 }
1010 }
1011
1012 //------------------------------------------------------------------------------------------------------------------------------------------
1013
1015 const std::string& label,
1016 const HitVector& hitVector,
1017 MCParticlesToHits& particlesToHits,
1018 HitsToMCParticles& hitsToParticles,
1019 const DaughterMode daughterMode)
1020 {
1021 SimChannelVector simChannelVector;
1022 MCTruthToMCParticles truthToParticles;
1023 MCParticlesToMCTruth particlesToTruth;
1024 HitsToTrackIDEs hitsToTrackIDEs;
1025
1026 bool areSimChannelsValid(false);
1027 LArPandoraHelper::CollectSimChannels(evt, label, simChannelVector, areSimChannelsValid);
1028
1029 LArPandoraHelper::CollectMCParticles(evt, label, truthToParticles, particlesToTruth);
1030 LArPandoraHelper::BuildMCParticleHitMaps(evt, hitVector, simChannelVector, hitsToTrackIDEs);
1032 hitsToTrackIDEs, truthToParticles, particlesToHits, hitsToParticles, daughterMode);
1033 }
1034
1035 //------------------------------------------------------------------------------------------------------------------------------------------
1036
1038 const std::string& hitLabel,
1039 const std::string& backtrackLabel,
1040 HitsToTrackIDEs& hitsToTrackIDEs)
1041 {
1042 // Start by getting the collection of Hits
1043 art::Handle<std::vector<recob::Hit>> theHits;
1044 evt.getByLabel(hitLabel, theHits);
1045
1046 if (!theHits.isValid()) {
1047 mf::LogDebug("LArPandora") << " Failed to find hits... " << std::endl;
1048 return;
1049 }
1050
1051 HitVector hitVector;
1052
1053 for (unsigned int i = 0; i < theHits->size(); ++i) {
1054 const art::Ptr<recob::Hit> hit(theHits, i);
1055 hitVector.push_back(hit);
1056 }
1057
1058 // Now get the associations between Hits and MCParticles
1059 std::vector<anab::BackTrackerHitMatchingData const*> backtrackerVector;
1060
1061 MCParticleVector particleVector;
1062
1063 art::FindManyP<simb::MCParticle, anab::BackTrackerHitMatchingData> particles_per_hit(
1064 theHits, evt, backtrackLabel);
1065
1066 if (!particles_per_hit.isValid()) {
1067 mf::LogDebug("LArPandora") << " Failed to find reco-truth matching... " << std::endl;
1068 return;
1069 }
1070
1071 // Now loop over the hits and build a collection of IDEs
1072 for (HitVector::const_iterator iter = hitVector.begin(), iterEnd = hitVector.end();
1073 iter != iterEnd;
1074 ++iter) {
1075 const art::Ptr<recob::Hit> hit = *iter;
1076
1077 particleVector.clear();
1078 backtrackerVector.clear();
1079 particles_per_hit.get(hit.key(), particleVector, backtrackerVector);
1080
1081 for (unsigned int j = 0; j < particleVector.size(); ++j) {
1082 const art::Ptr<simb::MCParticle> particle = particleVector[j];
1083
1084 sim::TrackIDE trackIDE;
1085 trackIDE.trackID = particle->TrackId();
1086 trackIDE.energy = backtrackerVector[j]->energy;
1087 trackIDE.energyFrac = backtrackerVector[j]->ideFraction;
1088
1089 hitsToTrackIDEs[hit].push_back(trackIDE);
1090 }
1091 }
1092 }
1093
1094 //------------------------------------------------------------------------------------------------------------------------------------------
1095
1097 const std::string& truthLabel,
1098 const std::string& hitLabel,
1099 const std::string& backtrackLabel,
1100 MCParticlesToHits& particlesToHits,
1101 HitsToMCParticles& hitsToParticles,
1102 const DaughterMode daughterMode)
1103 {
1104 MCTruthToMCParticles truthToParticles;
1105 MCParticlesToMCTruth particlesToTruth;
1106 HitsToTrackIDEs hitsToTrackIDEs;
1107
1108 LArPandoraHelper::CollectMCParticles(evt, truthLabel, truthToParticles, particlesToTruth);
1109 LArPandoraHelper::BuildMCParticleHitMaps(evt, hitLabel, backtrackLabel, hitsToTrackIDEs);
1111 hitsToTrackIDEs, truthToParticles, particlesToHits, hitsToParticles, daughterMode);
1112 }
1113
1114 //------------------------------------------------------------------------------------------------------------------------------------------
1115
1116 template <typename T>
1117 void LArPandoraHelper::GetAssociatedHits(const art::Event& evt,
1118 const std::string& label,
1119 const std::vector<art::Ptr<T>>& inputVector,
1120 HitVector& associatedHits,
1121 const pandora::IntVector* const indexVector)
1122 {
1123
1124 art::Handle<std::vector<T>> handle;
1125 evt.getByLabel(label, handle);
1126 art::FindManyP<recob::Hit> hitAssoc(handle, evt, label);
1127
1128 if (indexVector != nullptr) {
1129 if (inputVector.size() != indexVector->size())
1130 throw cet::exception("LArPandora") << " PandoraHelper::GetAssociatedHits --- trying to use "
1131 "an index vector not matching input vector";
1132
1133 // If indexVector is filled, sort hits according to trajectory points order
1134 for (int index : (*indexVector)) {
1135 const art::Ptr<T>& element = inputVector.at(index);
1136 const HitVector& hits = hitAssoc.at(element.key());
1137 associatedHits.insert(associatedHits.end(), hits.begin(), hits.end());
1138 }
1139 }
1140 else {
1141 // If indexVector is empty just loop through inputSpacePoints
1142 for (const art::Ptr<T>& element : inputVector) {
1143 const HitVector& hits = hitAssoc.at(element.key());
1144 associatedHits.insert(associatedHits.end(), hits.begin(), hits.end());
1145 }
1146 }
1147 }
1148
1149 //------------------------------------------------------------------------------------------------------------------------------------------
1150
1152 MCParticleMap& particleMap)
1153 {
1154 for (MCParticleVector::const_iterator iter = particleVector.begin(),
1155 iterEnd = particleVector.end();
1156 iter != iterEnd;
1157 ++iter) {
1158 const art::Ptr<simb::MCParticle> particle = *iter;
1159 particleMap[particle->TrackId()] = particle;
1160 particleMap[particle->TrackId()] = particle;
1161 }
1162 }
1163
1164 //------------------------------------------------------------------------------------------------------------------------------------------
1165
1167 PFParticleMap& particleMap)
1168 {
1169 for (PFParticleVector::const_iterator iter = particleVector.begin(),
1170 iterEnd = particleVector.end();
1171 iter != iterEnd;
1172 ++iter) {
1173 const art::Ptr<recob::PFParticle> particle = *iter;
1174 particleMap[particle->Self()] = particle;
1175 }
1176 }
1177
1178 //------------------------------------------------------------------------------------------------------------------------------------------
1179
1180 art::Ptr<recob::PFParticle> LArPandoraHelper::GetParentPFParticle(
1181 const PFParticleMap& particleMap,
1182 const art::Ptr<recob::PFParticle> inputParticle)
1183 {
1184 // Navigate upward through PFO daughter/parent links - return the top-level PF Particle
1185 int primaryTrackID(inputParticle->Self());
1186
1187 if (!inputParticle->IsPrimary()) {
1188 while (1) {
1189 PFParticleMap::const_iterator pIter1 = particleMap.find(primaryTrackID);
1190 if (particleMap.end() == pIter1)
1191 throw cet::exception("LArPandora") << " PandoraCollector::GetParentPFParticle --- Found "
1192 "a PFParticle without a particle ID ";
1193
1194 const art::Ptr<recob::PFParticle> primaryParticle = pIter1->second;
1195 if (primaryParticle->IsPrimary()) break;
1196
1197 primaryTrackID = primaryParticle->Parent();
1198 }
1199 }
1200
1201 PFParticleMap::const_iterator pIter2 = particleMap.find(primaryTrackID);
1202 if (particleMap.end() == pIter2)
1203 throw cet::exception("LArPandora")
1204 << " PandoraCollector::GetParentPFParticle --- Found a PFParticle without a particle ID ";
1205
1206 const art::Ptr<recob::PFParticle> outputParticle = pIter2->second;
1207 return outputParticle;
1208 }
1209
1210 //------------------------------------------------------------------------------------------------------------------------------------------
1211
1213 const PFParticleMap& particleMap,
1214 const art::Ptr<recob::PFParticle> inputParticle)
1215 {
1216 // Navigate upward through PFO daughter/parent links - return the top-level non-neutrino PF Particle
1217 int primaryTrackID(inputParticle->Self());
1218
1219 if (!inputParticle->IsPrimary()) {
1220 int parentTrackID(inputParticle->Parent());
1221
1222 while (1) {
1223 PFParticleMap::const_iterator pIter1 = particleMap.find(parentTrackID);
1224 if (particleMap.end() == pIter1)
1225 throw cet::exception("LArPandora") << " PandoraCollector::GetFinalStatePFParticle --- "
1226 "Found a PFParticle without a particle ID ";
1227
1228 const art::Ptr<recob::PFParticle> parentParticle = pIter1->second;
1229 if (LArPandoraHelper::IsNeutrino(parentParticle)) break;
1230
1231 primaryTrackID = parentTrackID;
1232
1233 if (parentParticle->IsPrimary()) break;
1234
1235 parentTrackID = parentParticle->Parent();
1236 }
1237 }
1238
1239 PFParticleMap::const_iterator pIter2 = particleMap.find(primaryTrackID);
1240 if (particleMap.end() == pIter2)
1241 throw cet::exception("LArPandora") << " PandoraCollector::GetFinalStatePFParticle --- Found "
1242 "a PFParticle without a particle ID ";
1243
1244 const art::Ptr<recob::PFParticle> outputParticle = pIter2->second;
1245 return outputParticle;
1246 }
1247
1248 //------------------------------------------------------------------------------------------------------------------------------------------
1249
1250 art::Ptr<simb::MCParticle> LArPandoraHelper::GetParentMCParticle(
1251 const MCParticleMap& particleMap,
1252 const art::Ptr<simb::MCParticle> inputParticle)
1253 {
1254 // Navigate upward through MC daughter/parent links - return the top-level MC particle
1255 int primaryTrackID(inputParticle->TrackId());
1256 int parentTrackID(inputParticle->Mother());
1257
1258 while (1) {
1259 MCParticleMap::const_iterator pIter1 = particleMap.find(parentTrackID);
1260 if (particleMap.end() == pIter1) break; // Can't find MC Particle for this track ID [break]
1261
1262 const art::Ptr<simb::MCParticle> particle = pIter1->second;
1263
1264 primaryTrackID = parentTrackID;
1265 parentTrackID = particle->Mother();
1266 }
1267
1268 MCParticleMap::const_iterator pIter2 = particleMap.find(primaryTrackID);
1269 if (particleMap.end() == pIter2)
1270 throw cet::exception("LArPandora")
1271 << " PandoraCollector::GetParentMCParticle --- Found a track ID without a MC particle ";
1272
1273 const art::Ptr<simb::MCParticle> outputParticle = pIter2->second;
1274 return outputParticle;
1275 }
1276
1277 //------------------------------------------------------------------------------------------------------------------------------------------
1278
1280 const MCParticleMap& particleMap,
1281 const art::Ptr<simb::MCParticle> inputParticle)
1282 {
1283 // Navigate upward through MC daughter/parent links - collect this particle and all its parents
1284 MCParticleVector mcVector;
1285
1286 int trackID(inputParticle->TrackId());
1287
1288 while (1) {
1289 MCParticleMap::const_iterator pIter = particleMap.find(trackID);
1290 if (particleMap.end() == pIter) break; // Can't find MC Particle for this track ID [break]
1291
1292 const art::Ptr<simb::MCParticle> particle = pIter->second;
1293 mcVector.push_back(particle);
1294
1295 trackID = particle->Mother();
1296 }
1297
1298 // Navigate downward through MC parent/daughter links - return the first long-lived charged particle
1299 for (MCParticleVector::const_reverse_iterator iter = mcVector.rbegin(),
1300 iterEnd = mcVector.rend();
1301 iter != iterEnd;
1302 ++iter) {
1303 const art::Ptr<simb::MCParticle> nextParticle = *iter;
1304
1305 if (LArPandoraHelper::IsVisible(nextParticle)) return nextParticle;
1306 }
1307
1308 throw cet::exception("LArPandora"); // need to catch this exception
1309 }
1310
1311 //------------------------------------------------------------------------------------------------------------------------------------------
1312
1314 const PFParticlesToTracks& particlesToTracks,
1315 const art::Ptr<recob::PFParticle> particle)
1316 {
1317 PFParticlesToTracks::const_iterator tIter = particlesToTracks.find(particle);
1318
1319 if (particlesToTracks.end() == tIter || tIter->second.empty())
1320 throw cet::exception("LArPandora")
1321 << " PandoraCollector::GetPrimaryTrack --- Failed to find associated track ";
1322
1323 if (tIter->second.size() != 1)
1324 throw cet::exception("LArPandora")
1325 << " PandoraCollector::GetPrimaryTrack --- Found more than one associated track ";
1326
1327 const art::Ptr<recob::Track> primaryTrack = *(tIter->second.begin());
1328 return primaryTrack;
1329 }
1330
1331 //------------------------------------------------------------------------------------------------------------------------------------------
1332
1334 const art::Ptr<recob::PFParticle> inputParticle)
1335 {
1336 // Navigate upward through PFO daughter/parent links - return the top-level PF Particle
1337 int nGenerations(0);
1338 int primaryTrackID(inputParticle->Self());
1339
1340 while (1) {
1341 PFParticleMap::const_iterator pIter = particleMap.find(primaryTrackID);
1342 if (particleMap.end() == pIter)
1343 throw cet::exception("LArPandora")
1344 << " PandoraCollector::GetGeneration --- Found a PFParticle without a particle ID ";
1345
1346 ++nGenerations;
1347
1348 const art::Ptr<recob::PFParticle> primaryParticle = pIter->second;
1349 if (primaryParticle->IsPrimary()) break;
1350
1351 primaryTrackID = primaryParticle->Parent();
1352 }
1353
1354 return nGenerations;
1355 }
1356
1357 //------------------------------------------------------------------------------------------------------------------------------------------
1358
1360 const art::Ptr<recob::PFParticle> daughterParticle)
1361 {
1362 art::Ptr<recob::PFParticle> parentParticle =
1363 LArPandoraHelper::GetParentPFParticle(particleMap, daughterParticle);
1364
1365 if (LArPandoraHelper::IsNeutrino(parentParticle)) return parentParticle->PdgCode();
1366
1367 if (parentParticle->IsPrimary()) return 0;
1368
1369 const int parentID(parentParticle->Parent());
1370
1371 PFParticleMap::const_iterator pIter = particleMap.find(parentID);
1372 if (particleMap.end() == pIter)
1373 throw cet::exception("LArPandora")
1374 << " PandoraCollector::GetParentNeutrino --- Found a PFParticle without a particle ID ";
1375
1376 const art::Ptr<recob::PFParticle> neutrinoParticle = pIter->second;
1377 return neutrinoParticle->PdgCode();
1378 }
1379
1380 //------------------------------------------------------------------------------------------------------------------------------------------
1381
1383 const art::Ptr<recob::PFParticle> daughterParticle)
1384 {
1385 if (LArPandoraHelper::IsNeutrino(daughterParticle)) return false;
1386
1387 if (daughterParticle->IsPrimary()) return true;
1388
1389 const int parentID(daughterParticle->Parent());
1390
1391 PFParticleMap::const_iterator pIter = particleMap.find(parentID);
1392 if (particleMap.end() == pIter)
1393 throw cet::exception("LArPandora")
1394 << " PandoraCollector::IsFinalState --- Found a PFParticle without a particle ID ";
1395
1396 const art::Ptr<recob::PFParticle> parentParticle = pIter->second;
1397
1398 if (LArPandoraHelper::IsNeutrino(parentParticle)) return true;
1399
1400 return false;
1401 }
1402
1403 //------------------------------------------------------------------------------------------------------------------------------------------
1404
1405 bool LArPandoraHelper::IsNeutrino(const art::Ptr<recob::PFParticle> particle)
1406 {
1407 const int pdg(particle->PdgCode());
1408
1409 // electron, muon, tau (use Pandora PDG tables)
1410 return ((pandora::NU_E == std::abs(pdg)) || (pandora::NU_MU == std::abs(pdg)) ||
1411 (pandora::NU_TAU == std::abs(pdg)));
1412 }
1413
1414 //------------------------------------------------------------------------------------------------------------------------------------------
1415
1416 bool LArPandoraHelper::IsTrack(const art::Ptr<recob::PFParticle> particle)
1417 {
1418 const int pdg(particle->PdgCode());
1419
1420 // muon, pion, proton, kaon (use Pandora PDG tables)
1421 return ((pandora::MU_MINUS == std::abs(pdg)) || (pandora::PI_PLUS == std::abs(pdg)) ||
1422 (pandora::PROTON == std::abs(pdg)) || (pandora::K_PLUS == std::abs(pdg)));
1423 }
1424
1425 //------------------------------------------------------------------------------------------------------------------------------------------
1426
1427 bool LArPandoraHelper::IsShower(const art::Ptr<recob::PFParticle> particle)
1428 {
1429 const int pdg(particle->PdgCode());
1430
1431 // electron, photon (use Pandora PDG tables)
1432 return ((pandora::E_MINUS == std::abs(pdg)) || (pandora::PHOTON == std::abs(pdg)));
1433 }
1434
1435 //------------------------------------------------------------------------------------------------------------------------------------------
1436
1437 bool LArPandoraHelper::IsVisible(const art::Ptr<simb::MCParticle> particle)
1438 {
1439 // Include long-lived charged particles
1440 const int pdg(particle->PdgCode());
1441
1442 if ((pandora::E_MINUS == std::abs(pdg)) || (pandora::MU_MINUS == std::abs(pdg)) ||
1443 (pandora::PROTON == std::abs(pdg)) || (pandora::PI_PLUS == std::abs(pdg)) ||
1444 (pandora::K_PLUS == std::abs(pdg)) || (pandora::SIGMA_MINUS == std::abs(pdg)) ||
1445 (pandora::SIGMA_PLUS == std::abs(pdg)) || (pandora::HYPERON_MINUS == std::abs(pdg)) ||
1446 (pandora::PHOTON == std::abs(pdg)) || (pandora::NEUTRON == std::abs(pdg)))
1447 return true;
1448
1449 // TODO: What about ions, neutrons, photons? (Have included neutrons and photons for now)
1450
1451 return false;
1452 }
1453
1454 //------------------------------------------------------------------------------------------------------------------------------------------
1455
1456 larpandoraobj::PFParticleMetadata LArPandoraHelper::GetPFParticleMetadata(
1457 const pandora::ParticleFlowObject* const pPfo)
1458 {
1459 return larpandoraobj::PFParticleMetadata(pPfo->GetPropertiesMap());
1460 }
1461
1462 //------------------------------------------------------------------------------------------------------------------------------------------
1463 //------------------------------------------------------------------------------------------------------------------------------------------
1464
1465 template void LArPandoraHelper::GetAssociatedHits(const art::Event&,
1466 const std::string&,
1467 const std::vector<art::Ptr<recob::Cluster>>&,
1468 HitVector&,
1469 const pandora::IntVector* const);
1470
1471 template void LArPandoraHelper::GetAssociatedHits(const art::Event&,
1472 const std::string&,
1473 const std::vector<art::Ptr<recob::SpacePoint>>&,
1474 HitVector&,
1475 const pandora::IntVector* const);
1476
1477} // namespace lar_pandora
helper function for LArPandoraInterface producer module
Header file defining relevant internal typedefs, sort and string conversion functions.
Header file for the particle flow object class.
static void CollectShowers(const art::Event &evt, const std::string &label, ShowerVector &showerVector, PFParticlesToShowers &particlesToShowers)
Collect the reconstructed PFParticles and associated Showers from the ART event record.
static void CollectClusters(const art::Event &evt, const std::string &label, ClusterVector &clusterVector, ClustersToHits &clustersToHits)
Collect the reconstructed Clusters and associated hits from the ART event record.
static void SelectNeutrinoPFParticles(const PFParticleVector &inputParticles, PFParticleVector &outputParticles)
Select reconstructed neutrino particles from a list of all reconstructed particles.
static void CollectHits(const art::Event &evt, const std::string &label, HitVector &hitVector)
Collect the reconstructed Hits from the ART event record.
DaughterMode
DaughterMode enumeration.
static void BuildMCParticleMap(const MCParticleVector &particleVector, MCParticleMap &particleMap)
Build particle maps for true particles.
static larpandoraobj::PFParticleMetadata GetPFParticleMetadata(const pandora::ParticleFlowObject *const pPfo)
Get metadata associated to a PFO.
static void CollectVertices(const art::Event &evt, const std::string &label, VertexVector &vertexVector, PFParticlesToVertices &particlesToVertices)
Collect the reconstructed PFParticles and associated Vertices from the ART event record.
static art::Ptr< simb::MCParticle > GetFinalStateMCParticle(const MCParticleMap &particleMap, const art::Ptr< simb::MCParticle > daughterParticle)
Return the final-state parent particle by navigating up the chain of parent/daughter associations.
static void BuildPFParticleMap(const PFParticleVector &particleVector, PFParticleMap &particleMap)
Build particle maps for reconstructed particles.
static void CollectSeeds(const art::Event &evt, const std::string &label, SeedVector &seedVector, PFParticlesToSeeds &particlesToSeeds)
Collect the reconstructed PFParticles and associated Seeds from the ART event record.
static void CollectPFParticleMetadata(const art::Event &evt, const std::string &label, PFParticleVector &particleVector, PFParticlesToMetadata &particlesToMetadata)
Collect the reconstructed PFParticle Metadata from the ART event record.
static art::Ptr< recob::PFParticle > GetFinalStatePFParticle(const PFParticleMap &particleMap, const art::Ptr< recob::PFParticle > daughterParticle)
Return the final-state parent particle by navigating up the chain of parent/daughter associations.
static void CollectSpacePoints(const art::Event &evt, const std::string &label, SpacePointVector &spacePointVector, SpacePointsToHits &spacePointsToHits)
Collect the reconstructed SpacePoints and associated hits from the ART event record.
static art::Ptr< simb::MCParticle > GetParentMCParticle(const MCParticleMap &particleMap, const art::Ptr< simb::MCParticle > daughterParticle)
Return the top-level parent particle by navigating up the chain of parent/daughter associations.
static void CollectT0s(const art::Event &evt, const std::string &label, T0Vector &t0Vector, PFParticlesToT0s &particlesToT0s)
Collect a vector of T0s from the ART event record.
static void SelectFinalStatePFParticles(const PFParticleVector &inputParticles, PFParticleVector &outputParticles)
Select final-state reconstructed particles from a list of all reconstructed particles.
static bool IsVisible(const art::Ptr< simb::MCParticle > particle)
Determine whether a particle is visible (i.e. long-lived charged particle)
static void GetAssociatedHits(const art::Event &evt, const std::string &label, const std::vector< art::Ptr< T > > &inputVector, HitVector &associatedHits, const pandora::IntVector *const indexVector=nullptr)
Get all hits associated with input clusters.
static void BuildMCParticleHitMaps(const art::Event &evt, const HitVector &hitVector, const SimChannelVector &simChannelVector, HitsToTrackIDEs &hitsToTrackIDEs)
Collect the links from reconstructed hits to their true energy deposits.
static art::Ptr< recob::PFParticle > GetParentPFParticle(const PFParticleMap &particleMap, const art::Ptr< recob::PFParticle > daughterParticle)
Return the top-level parent particle by navigating up the chain of parent/daughter associations.
static bool IsTrack(const art::Ptr< recob::PFParticle > particle)
Determine whether a particle has been reconstructed as track-like.
static void CollectSimChannels(const art::Event &evt, const std::string &label, SimChannelVector &simChannelVector, bool &areSimChannelsValid)
Collect a vector of SimChannel objects from the ART event record.
static void CollectWires(const art::Event &evt, const std::string &label, WireVector &wireVector)
Collect the reconstructed wires from the ART event record.
static int GetParentNeutrino(const PFParticleMap &particleMap, const art::Ptr< recob::PFParticle > daughterParticle)
Return the parent neutrino PDG code (or zero for cosmics) for a given reconstructed particle.
static void CollectPFParticles(const art::Event &evt, const std::string &label, PFParticleVector &particleVector)
Collect the reconstructed PFParticles from the ART event record.
static void CollectCosmicTags(const art::Event &evt, const std::string &label, CosmicTagVector &cosmicTagVector, TracksToCosmicTags &tracksToCosmicTags)
Collect a vector of cosmic tags from the ART event record.
static bool IsFinalState(const PFParticleMap &particleMap, const art::Ptr< recob::PFParticle > daughterParticle)
Determine whether a particle has been reconstructed as a final-state particle.
static void CollectGeneratorMCParticles(const art::Event &evt, const std::string &label, RawMCParticleVector &particleVector)
Collect a vector of MCParticle objects from the generator in the ART event record....
static void CollectTracks(const art::Event &evt, const std::string &label, TrackVector &trackVector, PFParticlesToTracks &particlesToTracks)
Collect the reconstructed PFParticles and associated Tracks from the ART event record.
static bool IsNeutrino(const art::Ptr< recob::PFParticle > particle)
Determine whether a particle has been reconstructed as a neutrino.
static int GetGeneration(const PFParticleMap &particleMap, const art::Ptr< recob::PFParticle > daughterParticle)
Return the generation of this particle (first generation if primary)
static art::Ptr< recob::Track > GetPrimaryTrack(const PFParticlesToTracks &particlesToTracks, const art::Ptr< recob::PFParticle > particle)
Return the primary track associated with a PFParticle.
static void BuildPFParticleHitMaps(const PFParticleVector &particleVector, const PFParticlesToSpacePoints &particlesToSpacePoints, const SpacePointsToHits &spacePointsToHits, PFParticlesToHits &particlesToHits, HitsToPFParticles &hitsToParticles, const DaughterMode daughterMode=kUseDaughters)
Build mapping between PFParticles and Hits using PFParticle/SpacePoint/Hit maps.
static void CollectMCParticles(const art::Event &evt, const std::string &label, MCParticleVector &particleVector)
Collect a vector of MCParticle objects from the ART event record.
static bool IsShower(const art::Ptr< recob::PFParticle > particle)
Determine whether a particle has been reconstructed as shower-like.
ParticleFlowObject class.
const PropertiesMap & GetPropertiesMap() const
Get the map from registered property name to floating point property value.
std::map< art::Ptr< recob::PFParticle >, T0Vector > PFParticlesToT0s
std::vector< art::Ptr< anab::T0 > > T0Vector
std::map< int, art::Ptr< recob::PFParticle > > PFParticleMap
std::vector< art::Ptr< recob::Track > > TrackVector
std::map< int, art::Ptr< simb::MCParticle > > MCParticleMap
std::map< art::Ptr< recob::Seed >, art::Ptr< recob::Hit > > SeedsToHits
std::map< art::Ptr< simb::MCParticle >, art::Ptr< simb::MCTruth > > MCParticlesToMCTruth
std::vector< sim::TrackIDE > TrackIDEVector
std::map< art::Ptr< recob::Hit >, TrackIDEVector > HitsToTrackIDEs
std::vector< art::Ptr< recob::Shower > > ShowerVector
std::map< art::Ptr< recob::PFParticle >, ClusterVector > PFParticlesToClusters
std::vector< art::Ptr< recob::Vertex > > VertexVector
std::map< art::Ptr< recob::PFParticle >, ShowerVector > PFParticlesToShowers
std::vector< simb::MCParticle > RawMCParticleVector
std::vector< art::Ptr< sim::SimChannel > > SimChannelVector
std::map< art::Ptr< simb::MCTruth >, MCParticleVector > MCTruthToMCParticles
std::map< art::Ptr< recob::PFParticle >, SpacePointVector > PFParticlesToSpacePoints
std::vector< art::Ptr< recob::Cluster > > ClusterVector
std::map< art::Ptr< recob::PFParticle >, HitVector > PFParticlesToHits
std::vector< art::Ptr< recob::Hit > > HitVector
std::vector< art::Ptr< recob::PFParticle > > PFParticleVector
std::map< art::Ptr< recob::Shower >, HitVector > ShowersToHits
std::vector< art::Ptr< anab::CosmicTag > > CosmicTagVector
std::vector< art::Ptr< simb::MCParticle > > MCParticleVector
std::map< art::Ptr< recob::PFParticle >, TrackVector > PFParticlesToTracks
std::map< art::Ptr< recob::Track >, HitVector > TracksToHits
std::map< art::Ptr< recob::PFParticle >, MetadataVector > PFParticlesToMetadata
std::map< art::Ptr< recob::SpacePoint >, art::Ptr< recob::Hit > > SpacePointsToHits
std::map< art::Ptr< simb::MCParticle >, HitVector > MCParticlesToHits
std::vector< art::Ptr< recob::SpacePoint > > SpacePointVector
std::map< int, art::Ptr< sim::SimChannel > > SimChannelMap
std::map< art::Ptr< recob::Cluster >, HitVector > ClustersToHits
std::map< art::Ptr< recob::PFParticle >, SeedVector > PFParticlesToSeeds
std::vector< art::Ptr< recob::Seed > > SeedVector
std::map< art::Ptr< recob::Hit >, art::Ptr< recob::PFParticle > > HitsToPFParticles
std::map< art::Ptr< recob::Hit >, art::Ptr< simb::MCParticle > > HitsToMCParticles
std::vector< art::Ptr< recob::Wire > > WireVector
std::map< art::Ptr< recob::PFParticle >, VertexVector > PFParticlesToVertices
std::map< art::Ptr< recob::Hit >, art::Ptr< recob::SpacePoint > > HitsToSpacePoints
std::map< art::Ptr< recob::Track >, CosmicTagVector > TracksToCosmicTags
std::vector< int > IntVector