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