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