LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
LArPandoraHelper.cxx
Go to the documentation of this file.
1 
9 
15 #include "cetlib_except/exception.h"
17 
33 
37 
38 #include "Objects/ParticleFlowObject.h"
39 #include "Pandora/PandoraInternal.h"
40 #include "Pandora/PdgTable.h"
41 
42 #include <iostream>
43 #include <limits>
44 
45 namespace lar_pandora {
46 
48  const std::string& label,
49  WireVector& wireVector)
50  {
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 
71  const std::string& label,
72  HitVector& hitVector)
73  {
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 
94  const std::string& label,
95  PFParticleVector& particleVector)
96  {
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 
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 
130  const std::string& label,
131  SpacePointVector& spacePointVector,
132  SpacePointsToHits& spacePointsToHits,
133  HitsToSpacePoints& hitsToSpacePoints)
134  {
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 
160  const std::string& label,
161  ClusterVector& clusterVector,
162  ClustersToHits& clustersToHits)
163  {
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 
191  const std::string& label,
192  PFParticleVector& particleVector,
193  PFParticlesToSpacePoints& particlesToSpacePoints)
194  {
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 
223  const std::string& label,
224  PFParticleVector& particleVector,
225  PFParticlesToClusters& particlesToClusters)
226  {
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  {
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 
289  const std::string& label,
290  ShowerVector& showerVector,
291  PFParticlesToShowers& particlesToShowers)
292  {
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 
320  const std::string& label,
321  TrackVector& trackVector,
322  PFParticlesToTracks& particlesToTracks)
323  {
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 
351  const std::string& label,
352  TrackVector& trackVector,
353  TracksToHits& tracksToHits)
354  {
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 
382  const std::string& label,
383  ShowerVector& showerVector,
384  ShowersToHits& showersToHits)
385  {
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 
413  const std::string& label,
414  SeedVector& seedVector,
415  PFParticlesToSeeds& particlesToSeeds)
416  {
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 
444  const std::string& label,
445  SeedVector& seedVector,
446  SeedsToHits& seedsToHits)
447  {
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 
477  const std::string& label,
478  VertexVector& vertexVector,
479  PFParticlesToVertices& particlesToVertices)
480  {
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 
731  const std::string& label,
732  CosmicTagVector& cosmicTagVector,
733  TracksToCosmicTags& tracksToCosmicTags)
734  {
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 
754  const std::string& label,
755  T0Vector& t0Vector,
756  PFParticlesToT0s& particlesToT0s)
757  {
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 
780  const std::string& label,
781  SimChannelVector& simChannelVector,
782  bool& areSimChannelsValid)
783  {
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 
807  const std::string& label,
808  MCParticleVector& particleVector)
809  {
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  {
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 
861  const std::string& label,
862  MCTruthToMCParticles& truthToParticles,
863  MCParticlesToMCTruth& particlesToTruth)
864  {
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 =
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
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 
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>
1118  const std::string& label,
1119  const std::vector<art::Ptr<T>>& inputVector,
1120  HitVector& associatedHits,
1121  const pandora::IntVector* const indexVector)
1122  {
1123 
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 
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 
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 
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 
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 
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 
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 
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&,
1468  HitVector&,
1469  const pandora::IntVector* const);
1470 
1471  template void LArPandoraHelper::GetAssociatedHits(const art::Event&,
1472  const std::string&,
1474  HitVector&,
1475  const pandora::IntVector* const);
1476 
1477 } // namespace lar_pandora
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 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. ...
std::map< art::Ptr< recob::Hit >, art::Ptr< simb::MCParticle > > HitsToMCParticles
int PdgCode() const
Definition: MCParticle.h:213
static void BuildPFParticleMap(const PFParticleVector &particleVector, PFParticleMap &particleMap)
Build particle maps for reconstructed particles.
std::map< int, art::Ptr< sim::SimChannel > > SimChannelMap
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...
size_t Self() const
Returns the index of this particle.
Definition: PFParticle.h:88
std::map< art::Ptr< recob::PFParticle >, ClusterVector > PFParticlesToClusters
static bool IsNeutrino(const art::Ptr< recob::PFParticle > particle)
Determine whether a particle has been reconstructed as a neutrino.
int Mother() const
Definition: MCParticle.h:214
Declaration of signal hit object.
std::map< art::Ptr< simb::MCParticle >, art::Ptr< simb::MCTruth > > MCParticlesToMCTruth
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 CollectWires(const art::Event &evt, const std::string &label, WireVector &wireVector)
Collect the reconstructed wires from the ART event record.
constexpr auto abs(T v)
Returns the absolute value of the argument.
static bool IsShower(const art::Ptr< recob::PFParticle > particle)
Determine whether a particle has been reconstructed as shower-like.
int PdgCode() const
Return the type of particle as a PDG ID.
Definition: PFParticle.h:79
std::vector< art::Ptr< recob::Shower > > ShowerVector
intermediate_table::const_iterator const_iterator
int NParticles() const
Definition: MCTruth.h:75
std::vector< int > IntVector
std::vector< art::Ptr< anab::CosmicTag > > CosmicTagVector
Cluster finding and building.
float energy
energy from the particle with this trackID [MeV]
Definition: SimChannel.h:29
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...
std::map< art::Ptr< recob::PFParticle >, TrackVector > PFParticlesToTracks
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. ATTN: This function is needed as accessing generator (opposed to Geant4) level MCParticles requires use of MCTruth block.
std::map< art::Ptr< recob::PFParticle >, VertexVector > PFParticlesToVertices
std::map< int, art::Ptr< recob::PFParticle > > PFParticleMap
int TrackId() const
Definition: MCParticle.h:211
std::map< art::Ptr< recob::Track >, CosmicTagVector > TracksToCosmicTags
int TDCtick_t
Type representing a TDC tick.
Definition: RawTypes.h:25
std::map< int, art::Ptr< simb::MCParticle > > MCParticleMap
std::map< art::Ptr< recob::Hit >, TrackIDEVector > HitsToTrackIDEs
bool isValid() const noexcept
Definition: Handle.h:203
TFile f
Definition: plotHisto.C:6
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 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.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:289
std::vector< art::Ptr< recob::Seed > > SeedVector
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 bool IsVisible(const art::Ptr< simb::MCParticle > particle)
Determine whether a particle is visible (i.e. long-lived charged particle)
std::map< art::Ptr< recob::PFParticle >, MetadataVector > PFParticlesToMetadata
void hits()
Definition: readHits.C:15
std::map< art::Ptr< recob::PFParticle >, T0Vector > PFParticlesToT0s
std::map< art::Ptr< recob::PFParticle >, ShowerVector > PFParticlesToShowers
std::vector< simb::MCParticle > RawMCParticleVector
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...
Metadata associated to PFParticles.
std::map< art::Ptr< simb::MCParticle >, HitVector > MCParticlesToHits
std::map< art::Ptr< recob::PFParticle >, SeedVector > PFParticlesToSeeds
long seed
Definition: chem4.cc:67
std::vector< art::Ptr< recob::PFParticle > > PFParticleVector
size_t Parent() const
Definition: PFParticle.h:92
std::map< art::Ptr< recob::Cluster >, HitVector > ClustersToHits
std::map< art::Ptr< recob::Shower >, HitVector > ShowersToHits
std::map< art::Ptr< simb::MCTruth >, MCParticleVector > MCTruthToMCParticles
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.
key_type key() const noexcept
Definition: Ptr.h:166
std::vector< art::Ptr< recob::SpacePoint > > SpacePointVector
static art::Ptr< recob::Track > GetPrimaryTrack(const PFParticlesToTracks &particlesToTracks, const art::Ptr< recob::PFParticle > particle)
Return the primary track associated with a PFParticle.
std::map< art::Ptr< recob::PFParticle >, HitVector > PFParticlesToHits
std::vector< sim::TrackIDE > TrackIDEs(TDC_t startTDC, TDC_t endTDC) const
Returns energies collected for each track within a time interval.
Definition: SimChannel.cxx:217
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.
float energyFrac
fraction of hit energy from the particle with this trackID
Definition: SimChannel.h:28
std::map< art::Ptr< recob::Hit >, art::Ptr< recob::SpacePoint > > HitsToSpacePoints
std::vector< art::Ptr< simb::MCParticle > > MCParticleVector
std::vector< sim::TrackIDE > TrackIDEVector
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.
Provides recob::Track data product.
bool IsPrimary() const
Returns whether the particle is the root of the flow.
Definition: PFParticle.h:82
static void SelectFinalStatePFParticles(const PFParticleVector &inputParticles, PFParticleVector &outputParticles)
Select final-state reconstructed particles from a list of all reconstructed particles.
std::vector< art::Ptr< recob::Track > > TrackVector
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.
std::map< art::Ptr< recob::PFParticle >, SpacePointVector > PFParticlesToSpacePoints
Declaration of cluster object.
std::map< art::Ptr< recob::Track >, HitVector > TracksToHits
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.
float PeakTimeMinusRMS(float sigmas=+1.) const
Returns a time sigmas RMS away from the peak time.
Definition: Hit.h:290
static void CollectPFParticles(const art::Event &evt, const std::string &label, PFParticleVector &particleVector)
Collect the reconstructed PFParticles from the ART event record.
static void CollectHits(const art::Event &evt, const std::string &label, HitVector &hitVector)
Collect the reconstructed Hits from the ART event record.
Detector simulation of raw signals on wires.
DaughterMode
DaughterMode enumeration.
const simb::MCParticle & GetParticle(int i) const
Definition: MCTruth.h:76
static void SelectNeutrinoPFParticles(const PFParticleVector &inputParticles, PFParticleVector &outputParticles)
Select reconstructed neutrino particles from a list of all reconstructed particles.
raw::ChannelID_t Channel() const
Returns the readout channel this object describes.
Definition: SimChannel.h:323
std::vector< art::Ptr< recob::Hit > > HitVector
int trackID
Geant4 supplied trackID.
Definition: SimChannel.h:27
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
std::vector< art::Ptr< sim::SimChannel > > SimChannelVector
std::vector< art::Ptr< recob::Wire > > WireVector
std::map< art::Ptr< recob::Hit >, art::Ptr< recob::PFParticle > > HitsToPFParticles
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
static bool IsTrack(const art::Ptr< recob::PFParticle > particle)
Determine whether a particle has been reconstructed as track-like.
std::vector< art::Ptr< recob::Vertex > > VertexVector
Declaration of basic channel signal object.
size_type get(size_type i, reference item, data_reference data) const
Definition: FindManyP.h:453
std::vector< art::Ptr< recob::Cluster > > ClusterVector
float PeakTimePlusRMS(float sigmas=+1.) const
Returns a time sigmas RMS away from the peak time.
Definition: Hit.h:285
static int GetGeneration(const PFParticleMap &particleMap, const art::Ptr< recob::PFParticle > daughterParticle)
Return the generation of this particle (first generation if primary)
TCEvent evt
Definition: DataStructs.cxx:8
std::vector< art::Ptr< anab::T0 > > T0Vector
Float_t e
Definition: plot.C:35
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.
std::map< art::Ptr< recob::Seed >, art::Ptr< recob::Hit > > SeedsToHits
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 void CollectMCParticles(const art::Event &evt, const std::string &label, MCParticleVector &particleVector)
Collect a vector of MCParticle objects from the ART event record.
Float_t track
Definition: plot.C:35
helper function for LArPandoraInterface producer module
Ionization energy from a Geant4 track.
Definition: SimChannel.h:26
raw::ChannelID_t Channel() const
ID of the readout channel the hit was extracted from.
Definition: Hit.h:268
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...
Definition: fwd.h:26
art framework interface to geometry description
static bool IsFinalState(const PFParticleMap &particleMap, const art::Ptr< recob::PFParticle > daughterParticle)
Determine whether a particle has been reconstructed as a final-state particle.
std::map< art::Ptr< recob::SpacePoint >, art::Ptr< recob::Hit > > SpacePointsToHits
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
static larpandoraobj::PFParticleMetadata GetPFParticleMetadata(const pandora::ParticleFlowObject *const pPfo)
Get metadata associated to a PFO.
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 void BuildMCParticleMap(const MCParticleVector &particleVector, MCParticleMap &particleMap)
Build particle maps for true particles.
vertex reconstruction