ProtoDUNEPFParticleUtils.cxx
Go to the documentation of this file.
3 
7 #include "canvas/Persistency/Common/FindManyP.h"
8 #include "canvas/Persistency/Common/FindOneP.h"
9 
14 
16 
17 }
18 
20 
21 }
22 
23 // Get the number of primary PFParticles
25 
26  // Get the particles
27  auto pfParticles = evt.getValidHandle<std::vector<recob::PFParticle>>(particleLabel);
28 
29  unsigned int nPrimary = 0;
30  for(unsigned int p = 0; p < pfParticles->size(); ++p){
31  if(pfParticles->at(p).IsPrimary()){
32  ++nPrimary;
33  }
34  }
35 
36  return nPrimary;
37 }
38 
39 // Helper to get slice maps and avoid duplicate code
40 const std::map<unsigned int,std::vector<const recob::PFParticle*>> protoana::ProtoDUNEPFParticleUtils::SliceMapHelper(art::Event const &evt, const std::string particleLabel, bool primaryOnly) const{
41 
42  // Get the particles
43  auto pfParticles = evt.getValidHandle<std::vector<recob::PFParticle>>(particleLabel);
44 
45  std::map<unsigned int, std::vector<const recob::PFParticle*>> sliceMap;
46 
47  for(unsigned int p = 0; p < pfParticles->size(); ++p){
48  const recob::PFParticle* particle = &(pfParticles->at(p));
49 
50  // Only the primary particles have the slice association
51  if(primaryOnly && !particle->IsPrimary()) continue;
52 
53  unsigned int thisSlice = GetPFParticleSliceIndex(*particle,evt,particleLabel);
54 
55  if(thisSlice != 9999){
56  sliceMap[thisSlice].push_back(particle);
57  }
58  }
59 
60  return sliceMap;
61 
62 }
63 
64 // Return a map of primary particles grouped by their reconstructed slice. Useful for finding slices with multiple particles
65 const std::map<unsigned int,std::vector<const recob::PFParticle*>> protoana::ProtoDUNEPFParticleUtils::GetPFParticleSliceMap(art::Event const &evt, const std::string particleLabel) const{
66 
67  return SliceMapHelper(evt,particleLabel,true);
68 
69 }
70 
71 // Return a map of all particles grouped by their reconstructed slice.
72 const std::map<unsigned int,std::vector<const recob::PFParticle*>> protoana::ProtoDUNEPFParticleUtils::GetAllPFParticleSliceMap(art::Event const &evt, const std::string particleLabel) const{
73 
74  return SliceMapHelper(evt,particleLabel,false);
75 
76 }
77 
78 // Get the cosmic tag(s) from a given PFParticle
79 std::vector<anab::CosmicTag> protoana::ProtoDUNEPFParticleUtils::GetPFParticleCosmicTag(const recob::PFParticle &particle, art::Event const &evt, std::string particleLabel) const{
80 
81  try{
82  auto recoParticles = evt.getValidHandle<std::vector<recob::PFParticle> >(particleLabel);
83 
84  unsigned int pIndex = particle.Self();
85 
86  std::vector<anab::CosmicTag> pTags;
87 
88  const art::FindManyP<anab::CosmicTag> findCosmicTags(recoParticles,evt,particleLabel);
89  for(unsigned int p = 0; p < findCosmicTags.at(pIndex).size(); ++p){
90  pTags.push_back((*(findCosmicTags.at(pIndex)[p])));
91  }
92 
93  return pTags;
94  }
95  catch(...){
96  return std::vector<anab::CosmicTag>();
97  }
98 }
99 
100 // Get the T0(s) from a given PFParticle
101 std::vector<anab::T0> protoana::ProtoDUNEPFParticleUtils::GetPFParticleT0(const recob::PFParticle &particle, art::Event const &evt, std::string particleLabel) const{
102 
103  return GetPFParticleT0(particle,evt,particleLabel,particleLabel);
104 
105 }
106 
107 std::vector<anab::T0> protoana::ProtoDUNEPFParticleUtils::GetPFParticleT0(const recob::PFParticle &particle, art::Event const &evt, std::string particleLabel, std::string t0Label) const{
108 
109  try{
110  auto recoParticles = evt.getValidHandle<std::vector<recob::PFParticle> >(particleLabel);
111 
112  unsigned int pIndex = particle.Self();
113 
114  std::vector<anab::T0> pT0s;
115 
116  const art::FindManyP<anab::T0> findParticleT0s(recoParticles,evt,t0Label);
117  for(unsigned int p = 0; p < findParticleT0s.at(pIndex).size(); ++p){
118  pT0s.push_back((*(findParticleT0s.at(pIndex)[p])));
119  }
120 
121  return pT0s;
122  }
123  catch(...){
124  return std::vector<anab::T0>();
125  }
126 
127 }
128 
129 // Try to get the slice tagged as beam
130 unsigned short protoana::ProtoDUNEPFParticleUtils::GetBeamSlice(art::Event const &evt, const std::string particleLabel) const{
131 
132  const std::map<unsigned int, std::vector<const recob::PFParticle*>> sliceMap = GetPFParticleSliceMap(evt,particleLabel);
133 
134  for(auto slice : sliceMap){
135  for(auto particle : slice.second){
136  if(IsBeamParticle(*particle,evt,particleLabel)){
137  return slice.first;
138  }
139  }
140  }
141 
142  return 9999;
143 
144 }
145 
146 // Returns pointers for the primary PFParticles in a slice
147 const std::vector<const recob::PFParticle*> protoana::ProtoDUNEPFParticleUtils::GetPFParticlesFromSlice(const unsigned short slice, art::Event const &evt, const std::string particleLabel) const{
148 
149  const std::map<unsigned int, std::vector<const recob::PFParticle*>> sliceMap = GetPFParticleSliceMap(evt,particleLabel);
150 
151  if(sliceMap.find(slice) != sliceMap.end()){
152  return sliceMap.at(slice);
153  }
154  else{
155  return std::vector<const recob::PFParticle*>();
156  }
157 
158 }
159 
160 // Returns pointers for all PFParticles in a slice
161 const std::vector<const recob::PFParticle*> protoana::ProtoDUNEPFParticleUtils::GetAllPFParticlesFromSlice(const unsigned short slice, art::Event const &evt, const std::string particleLabel) const{
162 
163  const std::map<unsigned int, std::vector<const recob::PFParticle*>> sliceMap = GetAllPFParticleSliceMap(evt,particleLabel);
164 
165  if(sliceMap.find(slice) != sliceMap.end()){
166  return sliceMap.at(slice);
167  }
168  else{
169  return std::vector<const recob::PFParticle*>();
170  }
171 
172 }
173 
174 // Return the pointers for the PFParticles in the beam slice
175 const std::vector<const recob::PFParticle*> protoana::ProtoDUNEPFParticleUtils::GetPFParticlesFromBeamSlice(art::Event const &evt, const std::string particleLabel) const{
176 
177  unsigned short beamSlice = GetBeamSlice(evt,particleLabel);
178  return GetPFParticlesFromSlice(beamSlice,evt,particleLabel);
179 }
180 
181 // Access the BDT output used to decide if a slice is beam-like or cosmic-like
183 
184  return FindFloatInMetaData(particle,evt,particleLabel,"TestBeamScore");
185 
186 }
187 
188 // Use the pandora metadata to tell us if this is a beam particle or not
189 bool protoana::ProtoDUNEPFParticleUtils::IsBeamParticle(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const{
190 
191  return FindBoolInMetaData(particle,evt,particleLabel,"IsTestBeam");
192 
193 }
194 
196 
197  std::map<std::string,float> mdMap = GetPFParticleMetaData(particle,evt,particleLabel);
198 
199  if(mdMap.find(entry) != mdMap.end()){
200  return true;
201  }
202  else{
203  return false;
204  }
205 
206 }
207 
209 
210  std::map<std::string,float> mdMap = GetPFParticleMetaData(particle,evt,particleLabel);
211 
212  if(mdMap.find(entry) != mdMap.end()){
213  return mdMap.at(entry);
214  }
215  else{
216  return -999.;
217  }
218 
219 }
220 
221 
222 // Get the reconstructed slice associated with a particle
224 
225  // Perhaps we should use the associations to do this?
226  auto pfParticles = evt.getValidHandle<std::vector<recob::PFParticle>>(particleLabel);
227  const art::FindOneP<recob::Slice> findSlice(pfParticles,evt,particleLabel);
228 
229  const recob::Slice* slice = findSlice.at(particle.Self()).get();
230 
231  return slice;
232 }
233 
234 // Get the reconstructed slice associated with a particle
235 unsigned short protoana::ProtoDUNEPFParticleUtils::GetPFParticleSliceIndex(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const{
236 
237  // Try to use slices if we can
238  try{
239  const recob::Slice* slice = GetPFParticleSlice(particle,evt,particleLabel);
240  return slice->ID();
241  }
242  // Otherwise fall back on metadata
243  catch(...){
244  std::map<std::string,float> mdMap = GetPFParticleMetaData(particle,evt,particleLabel);
245  std::string search = "SliceIndex";
246  if(mdMap.find(search) != mdMap.end()){
247  return static_cast<unsigned short>(mdMap.at(search));
248  }
249  else{
250 // std::cerr << "Object has no slice index... returning 9999" << std::endl;
251  return 9999;
252  }
253  }
254 
255 }
256 
257 // Get all hits from a PFParticle's slice
258 const std::vector<const recob::Hit*> protoana::ProtoDUNEPFParticleUtils::GetPFParticleSliceHits(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const{
259 
260  // Use the slice utility to help us out
262 
263  unsigned short sliceIndex = GetPFParticleSliceIndex(particle,evt,particleLabel);
264  const std::vector<const recob::Hit*> hits = sliceUtil.GetRecoSliceHits(sliceIndex,evt,particleLabel);
265 
266  return hits;
267 }
268 
269 // Get hits from a PFParticle's slice that are not associated to any PFParticle
270 const std::vector<const recob::Hit*> protoana::ProtoDUNEPFParticleUtils::GetPFParticleSliceUnassociatedHits(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const{
271 
272  unsigned short sliceNumber = GetPFParticleSliceIndex(particle,evt,particleLabel);
273  const std::vector<const recob::Hit*> hits = GetPFParticleSliceHits(particle,evt,particleLabel);
274 
275  std::vector<bool> hitUsed(hits.size(),false);
276  std::vector<const recob::Hit*> unassocHits;
277 
278  // We need to iterate through the PFParticles in this slice and get their hits
279  const std::vector<const recob::PFParticle*> slicePFPs = GetAllPFParticlesFromSlice(sliceNumber,evt,particleLabel);
280 
281  for(auto const p : slicePFPs){
282 
283  // We are in the correct slice, so get the hits
284  const std::vector<const recob::Hit*> pfpHits = GetPFParticleHits(*p,evt,particleLabel);
285 
286  std::cout << "Hit vector sizes: " << hits.size() << ", " << pfpHits.size() << std::endl;
287 
288  for(const recob::Hit* h : pfpHits){
289  // Loop through the hit collection from the slice
290  for(unsigned int o = 0; o < hits.size(); ++o){
291  if(fabs(h->Integral() - hits[o]->Integral()) < 1e-5 && fabs(h->PeakTime() - hits[o]->PeakTime()) < 1e-5){
292  hitUsed[o] = true;
293  break;
294  }
295  }
296  }
297  }
298 
299  // Now we can fill our unassociated hits vector
300  for(unsigned int i = 0; i < hits.size(); ++i){
301  if(!hitUsed[i]) unassocHits.push_back(hits[i]);
302  }
303  std::cout << " Number of unassociated hits = " << unassocHits.size() << " of " << hits.size() << std::endl;
304 
305  return unassocHits;
306 }
307 
308 const std::map<std::string,float> protoana::ProtoDUNEPFParticleUtils::GetPFParticleMetaData(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const {
309 
310  // Get the particles
311  auto pfParticles = evt.getValidHandle<std::vector<recob::PFParticle>>(particleLabel);
312  // And their meta data
313  const art::FindManyP<larpandoraobj::PFParticleMetadata> findMetaData(pfParticles,evt,particleLabel);
314 
315  const larpandoraobj::PFParticleMetadata metaData = *((findMetaData.at(particle.Self())).at(0));
316 
317  return metaData.GetPropertiesMap();
318 }
319 
320 // Pandora tags and removes clear cosmics before slicing, so check if this particle is a clear cosmic
321 bool protoana::ProtoDUNEPFParticleUtils::IsClearCosmic(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const{
322 
323  return FindBoolInMetaData(particle,evt,particleLabel,"IsClearCosmic");
324 
325 }
326 
327 // Get all of the clear cosmic ray particles
328 const std::vector<const recob::PFParticle*> protoana::ProtoDUNEPFParticleUtils::GetClearCosmicPFParticles(art::Event const &evt, const std::string particleLabel) const{
329 
330  // Get the particles
331  auto pfParticles = evt.getValidHandle<std::vector<recob::PFParticle>>(particleLabel);
332 
333  std::vector<const recob::PFParticle*> cosmicParticles;
334 
335  for(unsigned int p = 0; p < pfParticles->size(); ++p){
336  const recob::PFParticle* particle = &(pfParticles->at(p));
337 
338  // Only consider primary particles
339  if(!particle->IsPrimary()) continue;
340 
341  if(IsClearCosmic(*particle,evt,particleLabel)){
342  cosmicParticles.push_back(particle);
343  }
344 
345  }
346 
347  return cosmicParticles;
348 
349 }
350 
351 // Function to find the interaction vertex of a primary PFParticle
352 const TVector3 protoana::ProtoDUNEPFParticleUtils::GetPFParticleVertex(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, const std::string trackLabel) const{
353 
354  // Pandora produces associations between PFParticles and recob::Vertex objects
355  auto pfParticles = evt.getValidHandle<std::vector<recob::PFParticle>>(particleLabel);
356  const art::FindManyP<recob::Vertex> findVertices(pfParticles,evt,particleLabel);
357  const std::vector<art::Ptr<recob::Vertex>> vertices = findVertices.at(particle.Self());
358 
359  // What happens next depends on the type of event.
360  // Not primary -> just use the pfparticle vertex
361  // Shower objects -> just use the pfparticle vertex
362  // Cosmics -> use track start point
363  // Beam -> use track start point
364 
365 // std::cout << "PFParticle daughters " << particle.NumDaughters() << std::endl;
366 
367  // Non-primary particle or shower-like primary particle
368  if(!particle.IsPrimary() || !IsPFParticleTracklike(particle,evt,particleLabel,trackLabel)){
369  if(vertices.size() != 0){
370  const recob::Vertex* vtx = (vertices.at(0)).get();
371  return TVector3(vtx->position().X(),vtx->position().Y(),vtx->position().Z());
372  }
373  else{
374  std::cerr << "Non track-like PFParticle has no vertex?! Return default vector" << std::endl;
375  return TVector3();
376  }
377  }
378  else{
379  // Cosmic or track-like beam primary particle
380 
381  const recob::Track* track = GetPFParticleTrack(particle,evt,particleLabel,trackLabel);
382 
383  if(track != 0x0){
384  const TVector3 start(track->Trajectory().Start().X(),track->Trajectory().Start().Y(),track->Trajectory().Start().Z());
385  const TVector3 end(track->Trajectory().End().X(),track->Trajectory().End().Y(),track->Trajectory().End().Z());
386  // Return the most upstream point as some cases where the track is reversed...
387  if(IsBeamParticle(particle,evt,particleLabel)){
388  if(start.Z() < end.Z()) return start;
389  else return end;
390  }
391  // Return the highest point for cosmics
392  else{
393  if(start.Y() > end.Y()) return start;
394  else return end;
395  }
396  }
397  else{
398  std::cerr << "No track found for track-like PFParticle?! Return default vector" << std::endl;
399  return TVector3();
400  }
401 
402  }
403 
404 }
405 
406 // Function to find the secondary interaction vertex of a primary PFParticle
407 const TVector3 protoana::ProtoDUNEPFParticleUtils::GetPFParticleSecondaryVertex(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, const std::string trackLabel) const{
408 
409  // In this case we want to find the end of the track-like PFParticle
410  // To do this, we need to access things via the track
411 
412  // Showers have no secondary vertex
413  if(!IsPFParticleTracklike(particle,evt,particleLabel,trackLabel)){
414  std::cerr << "Shower-like PFParticles have no secondary vertex. Returning default TVector3" << std::endl;
415  return TVector3();
416  }
417 
418  const recob::Track* track = GetPFParticleTrack(particle,evt,particleLabel,trackLabel);
419 
420  // Interaction vertex is the downstream end of the track, or the bottom for cosmics
421  if(track != 0x0){
422  const TVector3 start(track->Trajectory().Start().X(),track->Trajectory().Start().Y(),track->Trajectory().Start().Z());
423  const TVector3 end(track->Trajectory().End().X(),track->Trajectory().End().Y(),track->Trajectory().End().Z());
424 
425  // Return the most downstream point as some cases where the track is reversed...
426  if(IsBeamParticle(particle,evt,particleLabel)){
427  if(start.Z() > end.Z()) return start;
428  else return end;
429  }
430  // Return the lowest point for cosmics
431  else{
432  if(start.Y() < end.Y()) return start;
433  else return end;
434  }
435 
436  }
437  else{
438  std::cerr << "This track-like PFParticle has no associated track. Returning default TVector3" << std::endl;
439  return TVector3();
440  }
441 
442 }
443 
444 // Is the particle track-like?
445 bool protoana::ProtoDUNEPFParticleUtils::IsPFParticleTracklike(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, const std::string trackLabel) const{
446 
447  return (GetPFParticleTrack(particle,evt,particleLabel,trackLabel) != 0x0);
448 
449 }
450 
451 // This is the old and deprecated version of the function
453  std::cerr << "This function is deprecated, please use the version with four arguments." << std::endl;
454  if(abs(particle.PdgCode()) == 11){
455  return false;
456  }
457  else{
458  return true;
459  }
460 }
461 
462 
463 
464 bool protoana::ProtoDUNEPFParticleUtils::IsPFParticleShowerlike(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, const std::string showerLabel) const{
465 
466  return (GetPFParticleShower(particle,evt,particleLabel,showerLabel) != 0x0);
467 
468 }
469 
470 // This is the old and deprecated version of the function
472  return !IsPFParticleTracklike(particle);
473 }
474 
475 // Get the track associated to this particle. Returns a null pointer if not found.
476 const recob::Track* protoana::ProtoDUNEPFParticleUtils::GetPFParticleTrack(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, const std::string trackLabel) const{
477 
478  // Pandora produces associations between PFParticles and recob::Track objects
479  auto particles = evt.getValidHandle<std::vector<recob::PFParticle>>(particleLabel);
480  const art::FindManyP<recob::Track> findTracks(particles,evt,trackLabel);
481  const std::vector<art::Ptr<recob::Track>> pfpTracks = findTracks.at(particle.Self());
482 
483  // Check that the track exists
484  if(pfpTracks.size() != 0){
485  const recob::Track* track = (pfpTracks.at(0)).get();
486  return track;
487  }
488  else{
489 // std::cerr << "No track found, returning null pointer" << std::endl;
490  return nullptr;
491  }
492 
493 }
494 
495 // Get the shower associated to this particle. Returns a null pointer if not found.
496 const recob::Shower* protoana::ProtoDUNEPFParticleUtils::GetPFParticleShower(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, const std::string showerLabel) const{
497 
498  // Pandora produces associations between PFParticles and recob::Track objects
499  auto particles = evt.getValidHandle<std::vector<recob::PFParticle>>(particleLabel);
500  const art::FindManyP<recob::Shower> findShowers(particles,evt,showerLabel);
501  const std::vector<art::Ptr<recob::Shower>> pfpShowers = findShowers.at(particle.Self());
502 
503  // Check that the shower exists
504  if(pfpShowers.size() != 0){
505  const recob::Shower* shw = (pfpShowers.at(0)).get();
506  return shw;
507  }
508  else{
509 // std::cerr << "No shower found, returning null pointer" << std::endl;
510  return nullptr;
511  }
512 
513 }
514 
515 // Get the space points associated to the PFParticle
516 const std::vector<const recob::SpacePoint*> protoana::ProtoDUNEPFParticleUtils::GetPFParticleSpacePoints(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const{
517 
518  // Get the particles and their associations
519  auto particles = evt.getValidHandle<std::vector<recob::PFParticle>>(particleLabel);
520  const art::FindManyP<recob::SpacePoint> findSpacePoints(particles,evt,particleLabel);
521  const std::vector<art::Ptr<recob::SpacePoint>> pfpSpacePoints = findSpacePoints.at(particle.Self());
522 
523  // We don't want the art::Ptr so we need to get rid of it
524  std::vector<const recob::SpacePoint*> sp;
525  for(auto pointer : pfpSpacePoints){
526  sp.push_back(pointer.get());
527  }
528 
529  return sp;
530 }
531 
532 // Get the number of space points
534 
535  return GetPFParticleSpacePoints(particle,evt,particleLabel).size();
536 
537 }
538 
539 // Get the clusters associated to the PFParticle
540 const std::vector<const recob::Cluster*> protoana::ProtoDUNEPFParticleUtils::GetPFParticleClusters(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const{
541 
542  // Get the particles and their associations
543  auto particles = evt.getValidHandle<std::vector<recob::PFParticle>>(particleLabel);
544  const art::FindManyP<recob::Cluster> findClusters(particles,evt,particleLabel);
545  const std::vector<art::Ptr<recob::Cluster>> pfpClusters = findClusters.at(particle.Self());
546 
547  // We don't want the art::Ptr so we need to get rid of it
548  std::vector<const recob::Cluster*> clusters;
549  for(auto pointer : pfpClusters){
550  clusters.push_back(pointer.get());
551  }
552 
553  return clusters;
554 }
555 
556 // Get the number of clusters associated to the PFParticle
557 unsigned int protoana::ProtoDUNEPFParticleUtils::GetNumberPFParticleClusters(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const{
558 
559  return GetPFParticleClusters(particle,evt,particleLabel).size();
560 
561 }
562 
563 // Get the hits associated to the PFParticle
564 const std::vector<const recob::Hit*> protoana::ProtoDUNEPFParticleUtils::GetPFParticleHits(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const{
565 
566  const std::vector<const recob::Cluster*> pfpClusters = GetPFParticleClusters(particle,evt,particleLabel);
567  auto allClusters = evt.getValidHandle<std::vector<recob::Cluster>>(particleLabel);
568  const art::FindManyP<recob::Hit> findHits(allClusters,evt,particleLabel);
569 
570  std::vector<const recob::Hit*> pfpHits;
571 
572  // Store all of the hits in a single vector
573  for(auto cluster : pfpClusters){
574  const std::vector<art::Ptr<recob::Hit>> clusterHits = findHits.at(cluster->ID());
575 // std::cout << "Cluster has " << clusterHits.size() << " hits" << std::endl;
576  for(auto hit : clusterHits){
577  pfpHits.push_back(hit.get());
578  }
579  }
580 
581  return pfpHits;
582 }
583 
584 // Get the hits associated to the PFParticle
585 const std::vector<const recob::Hit*> protoana::ProtoDUNEPFParticleUtils::GetPFParticleHitsFromPlane( const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, unsigned int planeID ) const{
586 
587  const std::vector<const recob::Cluster*> pfpClusters = GetPFParticleClusters(particle,evt,particleLabel);
588  auto allClusters = evt.getValidHandle<std::vector<recob::Cluster>>(particleLabel);
589  const art::FindManyP<recob::Hit> findHits(allClusters,evt,particleLabel);
590 
591  std::vector<const recob::Hit*> pfpHits;
592  if( planeID > 2 ){
593  std::cout << "Please input plane 0, 1, or 2" << std::endl;
594  return pfpHits;
595  }
596 
597  // Store all of the hits in a single vector
598  for(auto cluster : pfpClusters){
599  const std::vector<art::Ptr<recob::Hit>> clusterHits = findHits.at(cluster->ID());
600 // std::cout << "Cluster has " << clusterHits.size() << " hits" << std::endl;
601  for(auto hit : clusterHits){
602  unsigned int thePlane = hit.get()->WireID().asPlaneID().Plane;
603  if( thePlane != planeID ) continue;
604 
605  pfpHits.push_back(hit.get());
606  }
607  }
608 
609  return pfpHits;
610 }
611 
612 const std::vector< art::Ptr< recob::Hit > > protoana::ProtoDUNEPFParticleUtils::GetPFParticleHits_Ptrs(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const{
613 
614  const std::vector<const recob::Cluster*> pfpClusters = GetPFParticleClusters(particle,evt,particleLabel);
615  auto allClusters = evt.getValidHandle<std::vector<recob::Cluster>>(particleLabel);
616  const art::FindManyP<recob::Hit> findHits(allClusters,evt,particleLabel);
617 
618  std::vector< art::Ptr< recob::Hit > > pfpHits;
619 
620  // Store all of the hits in a single vector
621  for(auto cluster : pfpClusters){
622  const std::vector<art::Ptr<recob::Hit>> clusterHits = findHits.at(cluster->ID());
623  for(auto hit : clusterHits){
624  pfpHits.push_back(hit);
625  }
626  }
627 
628  return pfpHits;
629 }
630 
631 const std::vector< art::Ptr< recob::Hit > > protoana::ProtoDUNEPFParticleUtils::GetPFParticleHitsFromPlane_Ptrs(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, size_t planeID) const{
632 
633  const std::vector<const recob::Cluster*> pfpClusters = GetPFParticleClusters(particle,evt,particleLabel);
634  auto allClusters = evt.getValidHandle<std::vector<recob::Cluster>>(particleLabel);
635  const art::FindManyP<recob::Hit> findHits(allClusters,evt,particleLabel);
636 
637  std::vector< art::Ptr< recob::Hit > > pfpHits;
638 
639  // Store all of the hits in a single vector
640  for(auto cluster : pfpClusters){
641  const std::vector<art::Ptr<recob::Hit>> clusterHits = findHits.at(cluster->ID());
642  for(auto hit : clusterHits){
643  size_t thePlane = hit.get()->WireID().asPlaneID().Plane;
644  if( thePlane != planeID ) continue;
645  pfpHits.push_back(hit);
646  }
647  }
648 
649  return pfpHits;
650 }
651 
652 // Get the number of hits
653 unsigned int protoana::ProtoDUNEPFParticleUtils::GetNumberPFParticleHits(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const{
654 
655  return GetPFParticleHits(particle,evt,particleLabel).size();
656 
657 }
658 
659 // Get the total charge from all PFParticle hits
660 const std::vector<double> protoana::ProtoDUNEPFParticleUtils::GetPFParticleHitsCharge(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const {
661 
662  const std::vector<const recob::Hit*> hitvector = GetPFParticleHits(particle, evt, particleLabel);
663 
664  double hitcharge[3] = {0.0, 0.0, 0.0};
665  for(auto hit : hitvector){
666  int hit_plane = (int)hit->WireID().Plane;
667  if(hit_plane < 0) continue;
668  if(hit_plane > 2) continue;
669  //hitcharge[hit_plane] += hit->SummedADC();
670  hitcharge[hit_plane] += hit->Integral();
671  }
672 
673  std::vector<double> hitchargevec;
674  for(int i = 0; i < 3; i++)
675  hitchargevec.push_back(hitcharge[i]);
676 
677  return hitchargevec;
678 }
679 
680 // Get the earliest hit peak time
682 
683  const std::vector<const recob::Hit*> hitvector = GetPFParticleHits(particle, evt, particleLabel);
684 
685  double earliesthittime = 999999.0;
686  for(auto hit : hitvector){
687  if(hit->PeakTime() < earliesthittime)
688  earliesthittime = (double)hit->PeakTime();
689  }
690 
691  return earliesthittime;
692 }
693 
694 // Get the daughter tracks from the PFParticle
695 const std::vector<const recob::Track*> protoana::ProtoDUNEPFParticleUtils::GetPFParticleDaughterTracks(const recob::PFParticle &particle, art::Event const &evt,
696  const std::string particleLabel, const std::string trackLabel) const{
697 
698  // Get the PFParticles
699  auto particles = evt.getValidHandle<std::vector<recob::PFParticle>>(particleLabel);
700 
701  std::vector<const recob::Track*> daughterTracks;
702 
703  // Loop over the daughters
704  for(size_t daughterID : particle.Daughters()){
705  const recob::Track* track = GetPFParticleTrack(particles->at(daughterID),evt,particleLabel,trackLabel);
706  if(track != 0x0){
707  daughterTracks.push_back(track);
708  }
709  }
710 
711  return daughterTracks;
712 
713 }
714 
715 // Get the daughter showers from the PFParticle
716 const std::vector<const recob::Shower*> protoana::ProtoDUNEPFParticleUtils::GetPFParticleDaughterShowers(const recob::PFParticle &particle, art::Event const &evt,
717  const std::string particleLabel, const std::string showerLabel) const{
718 
719  // Get the PFParticles
720  auto particles = evt.getValidHandle<std::vector<recob::PFParticle>>(particleLabel);
721 
722  std::vector<const recob::Shower*> daughterShowers;
723 
724  // Loop over the daughters
725  for(size_t daughterID : particle.Daughters()){
726  const recob::Shower* shower = GetPFParticleShower(particles->at(daughterID),evt,particleLabel,showerLabel);
727  if(shower != 0x0){
728  daughterShowers.push_back(shower);
729  }
730  }
731 
732  return daughterShowers;
733 
734 }
735 
736 
737 
738 
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
const std::vector< size_t > & Daughters() const
Returns the collection of daughter particles.
Definition: PFParticle.h:114
bool IsBeamParticle(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const
Use the pandora metadata to tell us if this is a beam particle or not.
QList< Entry > entry
const std::vector< const recob::PFParticle * > GetAllPFParticlesFromSlice(const unsigned short slice, art::Event const &evt, const std::string particleLabel) const
Get all of the PFParticles from a given slice. Returns an empty vector if the slice number is not val...
std::vector< anab::T0 > GetPFParticleT0(const recob::PFParticle &particle, art::Event const &evt, std::string particleLabel) const
Get the T0(s) from a given PFParticle.
size_t Self() const
Returns the index of this particle.
Definition: PFParticle.h:92
const recob::Shower * GetPFParticleShower(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, const std::string showerLabel) const
Get the shower associated to this particle. Returns a null pointer if not found.
std::string string
Definition: nybbler.cc:12
const recob::TrackTrajectory & Trajectory() const
Access to the stored recob::TrackTrajectory.
Definition: Track.h:98
const std::vector< const recob::Hit * > GetPFParticleSliceUnassociatedHits(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const
For a given PFParticle find its slice and return all those hits not associated to any PFParticle...
bool FindBoolInMetaData(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, const std::string entry) const
Look for entries in the meta data.
const std::vector< const recob::Hit * > GetPFParticleHits(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const
Get the hits associated to the PFParticle.
const TVector3 GetPFParticleVertex(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, const std::string trackLabel) const
Function to find the interaction vertex of a primary PFParticle.
bool IsClearCosmic(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const
Pandora tags and removes clear cosmics before slicing, so check if this particle is a clear cosmic...
unsigned short GetPFParticleSliceIndex(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const
Get the reconstructed slice number associated with a particle.
int PdgCode() const
Return the type of particle as a PDG ID.
Definition: PFParticle.h:83
Cluster finding and building.
const double GetPFParticleEarliestHitPeakTime(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const
Get the earliest hit peak time.
bool IsPFParticleTracklike(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, const std::string trackLabel) const
Is the particle track-like?
bool IsPFParticleShowerlike(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, const std::string showerLabel) const
Is the particle track-like?
Definition of vertex object for LArSoft.
Definition: Vertex.h:35
const std::vector< const recob::Hit * > GetRecoSliceHits(const recob::Slice &slice, art::Event const &evt, const std::string sliceModule) const
const std::vector< art::Ptr< recob::Hit > > GetPFParticleHitsFromPlane_Ptrs(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, size_t planeID) const
T abs(T value)
float FindFloatInMetaData(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, const std::string entry) const
const std::map< std::string, float > GetPFParticleMetaData(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const
Get the metadata associated to a PFParticle from pandora.
const double e
const std::vector< const recob::Cluster * > GetPFParticleClusters(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const
Get the clusters associated to the PFParticle.
Metadata associated to PFParticles.
unsigned short GetBeamSlice(art::Event const &evt, const std::string particleLabel) const
Try to get the slice tagged as beam. Returns 9999 if no beam slice was found.
const std::map< unsigned int, std::vector< const recob::PFParticle * > > GetAllPFParticleSliceMap(art::Event const &evt, const std::string particleLabel) const
Get a map of slice index to all of the PFParticles within it.
const recob::Track * GetPFParticleTrack(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, const std::string trackLabel) const
Get the track associated to this particle. Returns a null pointer if not found.
const PropertiesMap & GetPropertiesMap() const
const recob::Slice * GetPFParticleSlice(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const
Get the reconstructed slice associated with a particle.
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
Definition: DataViewImpl.h:441
p
Definition: test.py:223
const std::map< unsigned int, std::vector< const recob::PFParticle * > > GetPFParticleSliceMap(art::Event const &evt, const std::string particleLabel) const
Get a map of slice index to the primary PFParticles within it.
bool IsPrimary() const
Returns whether the particle is the root of the flow.
Definition: PFParticle.h:86
const std::vector< const recob::PFParticle * > GetPFParticlesFromBeamSlice(art::Event const &evt, const std::string particleLabel) const
Return the pointers for the PFParticles in the beam slice. Returns an empty vector is no beam slice w...
const std::vector< const recob::SpacePoint * > GetPFParticleSpacePoints(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const
Definition: search.py:1
unsigned int GetNumberPFParticleSpacePoints(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const
Get the number of space points.
Detector simulation of raw signals on wires.
const std::vector< double > GetPFParticleHitsCharge(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const
Get the total hit charge for each view.
int ID() const
Definition: Slice.h:29
Hierarchical representation of particle flow.
Definition: PFParticle.h:44
unsigned int GetNumberPFParticleClusters(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const
Get the number of clusters associated to the PFParticle.
const std::vector< const recob::PFParticle * > GetClearCosmicPFParticles(art::Event const &evt, const std::string particleLabel) const
Get all of the clear cosmic ray particles.
std::vector< anab::CosmicTag > GetPFParticleCosmicTag(const recob::PFParticle &particle, art::Event const &evt, std::string particleLabel) const
Get the cosmic tag(s) from a given PFParticle.
const std::vector< const recob::Shower * > GetPFParticleDaughterShowers(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, const std::string showerLabel) const
Get the daughter showers from the PFParticle.
const std::vector< const recob::PFParticle * > GetPFParticlesFromSlice(const unsigned short slice, art::Event const &evt, const std::string particleLabel) const
Get the Primary PFParticles from a given slice. Returns an empty vector if the slice number is not va...
Point_t const & End() const
Returns the position of the last valid point of the trajectory [cm].
Provides recob::Track data product.
const std::vector< art::Ptr< recob::Hit > > GetPFParticleHits_Ptrs(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const
const TVector3 GetPFParticleSecondaryVertex(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, const std::string trackLabel) const
Function to find the secondary interaction vertex of a primary PFParticle.
const std::vector< const recob::Hit * > GetPFParticleHitsFromPlane(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, unsigned int planeID) const
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:48
const std::map< unsigned int, std::vector< const recob::PFParticle * > > SliceMapHelper(art::Event const &evt, const std::string particleLabel, bool primaryOnly) const
Helper to get the slice map and avoid code repetition.
TCEvent evt
Definition: DataStructs.cxx:7
unsigned int GetNumberPrimaryPFParticle(art::Event const &evt, const std::string particleLabel) const
Get the number of primary PFParticles.
Point_t const & Start() const
Returns the position of the first valid point of the trajectory [cm].
const std::vector< const recob::Hit * > GetPFParticleSliceHits(const recob::PFParticle &particlei, art::Event const &evt, const std::string particleLabel) const
For a given PFParticle, return all hits from the slice it comes from.
const std::vector< const recob::Track * > GetPFParticleDaughterTracks(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, const std::string trackLabel) const
Get the daughter tracks from the PFParticle.
float GetBeamCosmicScore(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const
Access the BDT output used to decide if a slice is beam-like or cosmic-like.
unsigned int GetNumberPFParticleHits(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const
Get the number of hits.
const Point_t & position() const
Return vertex 3D position.
Definition: Vertex.h:60
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
Definition: Track.h:49
QTextStream & endl(QTextStream &s)