LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
PFParticleMonitoring_module.cc
Go to the documentation of this file.
1 
10 
11 #include "TTree.h"
12 
14 
15 #include <string>
16 
17 //------------------------------------------------------------------------------------------------------------------------------------------
18 
19 namespace lar_pandora
20 {
21 
26 {
27 public:
34 
38  virtual ~PFParticleMonitoring();
39 
40  void beginJob();
41  void endJob();
42  void analyze(const art::Event &evt);
43  void reconfigure(fhicl::ParameterSet const &pset);
44 
45 private:
46 
47  typedef std::set< art::Ptr<recob::PFParticle> > PFParticleSet;
48  typedef std::set< art::Ptr<simb::MCParticle> > MCParticleSet;
49  typedef std::set< art::Ptr<simb::MCTruth> > MCTruthSet;
50 
59  void BuildTrueNeutrinoHitMaps(const MCTruthToMCParticles &truthToParticles, const MCParticlesToHits &trueParticlesToHits,
60  MCTruthToHits &trueNeutrinosToHits, HitsToMCTruth &trueHitsToNeutrinos) const;
61 
70  void BuildRecoNeutrinoHitMaps(const PFParticleMap &recoParticleMap, const PFParticlesToHits &recoParticlesToHits,
71  PFParticlesToHits &recoNeutrinosToHits, HitsToPFParticles &recoHitsToNeutrinos) const;
72 
81  void GetRecoToTrueMatches(const PFParticlesToHits &recoNeutrinosToHits, const HitsToMCTruth &trueHitsToNeutrinos,
82  MCTruthToPFParticles &matchedNeutrinos, MCTruthToHits &matchedNeutrinoHits) const;
83 
94  void GetRecoToTrueMatches(const PFParticlesToHits &recoNeutrinosToHits, const HitsToMCTruth &trueHitsToNeutrinos,
95  MCTruthToPFParticles &matchedNeutrinos, MCTruthToHits &matchedNeutrinoHits, PFParticleSet &recoVeto, MCTruthSet &trueVeto) const;
96 
105  void GetRecoToTrueMatches(const PFParticlesToHits &recoParticlesToHits, const HitsToMCParticles &trueHitsToParticles,
106  MCParticlesToPFParticles &matchedParticles, MCParticlesToHits &matchedHits) const;
107 
118  void GetRecoToTrueMatches(const PFParticlesToHits &recoParticlesToHits, const HitsToMCParticles &trueHitsToParticles,
119  MCParticlesToPFParticles &matchedParticles, MCParticlesToHits &matchedHits, PFParticleSet &recoVeto, MCParticleSet &trueVeto) const;
120 
127  int CountHitsByType(const int view, const HitVector &hitVector) const;
128 
136  void GetStartAndEndPoints(const art::Ptr<simb::MCParticle> trueParticle, int &startT, int &endT) const;
137 
145  double GetLength(const art::Ptr<simb::MCParticle> trueParticle, const int startT, const int endT) const;
146 
147 
148  TTree *m_pRecoTree;
149 
150  int m_run;
151  int m_event;
152  int m_index;
153 
158 
159  int m_mcPdg;
160  int m_mcNuPdg;
166  int m_mcIsCC;
167 
168  int m_pfoPdg;
175 
178  double m_pfoVtxX;
179  double m_pfoVtxY;
180  double m_pfoVtxZ;
181  double m_pfoEndX;
182  double m_pfoEndY;
183  double m_pfoEndZ;
184  double m_pfoDirX;
185  double m_pfoDirY;
186  double m_pfoDirZ;
187  double m_pfoLength;
189 
191  double m_mcVtxX;
192  double m_mcVtxY;
193  double m_mcVtxZ;
194  double m_mcEndX;
195  double m_mcEndY;
196  double m_mcEndZ;
197  double m_mcDirX;
198  double m_mcDirY;
199  double m_mcDirZ;
200  double m_mcEnergy;
201  double m_mcLength;
203 
204  double m_completeness;
205  double m_purity;
206 
207  int m_nMCHits;
210 
214 
218 
222 
225 
228 
229  std::string m_hitfinderLabel;
230  std::string m_trackLabel;
231  std::string m_particleLabel;
232  std::string m_backtrackerLabel;
233  std::string m_geantModuleLabel;
234 
239 
242 };
243 
245 
246 } // namespace lar_pandora
247 
248 //------------------------------------------------------------------------------------------------------------------------------------------
249 // implementation follows
250 
252 #include "fhiclcpp/ParameterSet.h"
258 
263 #include "lardataobj/RecoBase/Hit.h"
275 
276 #include <iostream>
277 
278 namespace lar_pandora
279 {
280 
282 {
283  this->reconfigure(pset);
284 }
285 
286 //------------------------------------------------------------------------------------------------------------------------------------------
287 
289 {
290 }
291 
292 //------------------------------------------------------------------------------------------------------------------------------------------
293 
295 {
296  m_trackLabel = pset.get<std::string>("TrackModule","pandoraTracks");
297  m_particleLabel = pset.get<std::string>("PFParticleModule","pandora");
298  m_hitfinderLabel = pset.get<std::string>("HitFinderModule","gaushit");
299  m_backtrackerLabel = pset.get<std::string>("BackTrackerModule","gaushitTruthMatch");
300  m_geantModuleLabel = pset.get<std::string>("GeantModule","largeant");
301 
302  m_useDaughterPFParticles = pset.get<bool>("UseDaughterPFParticles",false);
303  m_useDaughterMCParticles = pset.get<bool>("UseDaughterMCParticles",true);
304  m_addDaughterPFParticles = pset.get<bool>("AddDaughterPFParticles",true);
305  m_addDaughterMCParticles = pset.get<bool>("AddDaughterMCParticles",true);
306 
307  m_recursiveMatching = pset.get<bool>("RecursiveMatching",false);
308  m_printDebug = pset.get<bool>("PrintDebug",false);
309 }
310 
311 //------------------------------------------------------------------------------------------------------------------------------------------
312 
314 {
315  mf::LogDebug("LArPandora") << " *** PFParticleMonitoring::beginJob() *** " << std::endl;
316 
317  //
319 
320  m_pRecoTree = tfs->make<TTree>("pandora", "LAr Reco vs True");
321  m_pRecoTree->Branch("run", &m_run,"run/I");
322  m_pRecoTree->Branch("event", &m_event,"event/I");
323  m_pRecoTree->Branch("index", &m_index,"index/I");
324  m_pRecoTree->Branch("nMCParticles", &m_nMCParticles, "nMCParticles/I");
325  m_pRecoTree->Branch("nNeutrinoPfos", &m_nNeutrinoPfos, "nNeutrinoPfos/I");
326  m_pRecoTree->Branch("nPrimaryPfos", &m_nPrimaryPfos, "nPrimaryPfos/I");
327  m_pRecoTree->Branch("nDaughterPfos", &m_nDaughterPfos, "nDaughterPfos/I");
328  m_pRecoTree->Branch("mcPdg", &m_mcPdg , "mcPdg/I");
329  m_pRecoTree->Branch("mcNuPdg", &m_mcNuPdg, "mcNuPdg/I");
330  m_pRecoTree->Branch("mcParentPdg", &m_mcParentPdg, "mcParentPdg/I");
331  m_pRecoTree->Branch("mcPrimaryPdg", &m_mcPrimaryPdg, "mcPrimaryPdg/I");
332  m_pRecoTree->Branch("mcIsNeutrino", &m_mcIsNeutrino, "mcIsNeutrino/I");
333  m_pRecoTree->Branch("mcIsPrimary", &m_mcIsPrimary, "mcIsPrimary/I");
334  m_pRecoTree->Branch("mcIsDecay", &m_mcIsDecay, "mcIsDecay/I");
335  m_pRecoTree->Branch("mcIsCC", &m_mcIsCC, "mcIsCC/I");
336  m_pRecoTree->Branch("pfoPdg", &m_pfoPdg, "pfoPdg/I");
337  m_pRecoTree->Branch("pfoNuPdg", &m_pfoNuPdg, "pfoNuPdg/I");
338  m_pRecoTree->Branch("pfoParentPdg", &m_pfoParentPdg, "pfoParentPdg/I");
339  m_pRecoTree->Branch("pfoPrimaryPdg", &m_pfoPrimaryPdg, "pfoPrimaryPdg/I");
340  m_pRecoTree->Branch("pfoIsNeutrino", &m_pfoIsNeutrino, "pfoIsNeutrino/I");
341  m_pRecoTree->Branch("pfoIsPrimary", &m_pfoIsPrimary, "pfoIsPrimary/I");
342  m_pRecoTree->Branch("pfoIsStitched", &m_pfoIsStitched, "pfoIsStitched/I");
343  m_pRecoTree->Branch("pfoTrack", &m_pfoTrack, "pfoTrack/I");
344  m_pRecoTree->Branch("pfoVertex", &m_pfoVertex, "pfoVertex/I");
345  m_pRecoTree->Branch("pfoVtxX", &m_pfoVtxX, "pfoVtxX/D");
346  m_pRecoTree->Branch("pfoVtxY", &m_pfoVtxY, "pfoVtxY/D");
347  m_pRecoTree->Branch("pfoVtxZ", &m_pfoVtxZ, "pfoVtxZ/D");
348  m_pRecoTree->Branch("pfoEndX", &m_pfoEndX, "pfoEndX/D");
349  m_pRecoTree->Branch("pfoEndY", &m_pfoEndY, "pfoEndY/D");
350  m_pRecoTree->Branch("pfoEndZ", &m_pfoEndZ, "pfoEndZ/D");
351  m_pRecoTree->Branch("pfoDirX", &m_pfoDirX, "pfoDirX/D");
352  m_pRecoTree->Branch("pfoDirY", &m_pfoDirY, "pfoDirY/D");
353  m_pRecoTree->Branch("pfoDirZ", &m_pfoDirZ, "pfoDirZ/D");
354  m_pRecoTree->Branch("pfoLength", &m_pfoLength, "pfoLength/D");
355  m_pRecoTree->Branch("pfoStraightLength", &m_pfoStraightLength, "pfoStraightLength/D");
356  m_pRecoTree->Branch("mcVertex", &m_mcVertex, "mcVertex/I");
357  m_pRecoTree->Branch("mcVtxX", &m_mcVtxX, "mcVtxX/D");
358  m_pRecoTree->Branch("mcVtxY", &m_mcVtxY, "mcVtxY/D");
359  m_pRecoTree->Branch("mcVtxZ", &m_mcVtxZ, "mcVtxZ/D");
360  m_pRecoTree->Branch("mcEndX", &m_mcEndX, "mcEndX/D");
361  m_pRecoTree->Branch("mcEndY", &m_mcEndY, "mcEndY/D");
362  m_pRecoTree->Branch("mcEndZ", &m_mcEndZ, "mcEndZ/D");
363  m_pRecoTree->Branch("mcDirX", &m_mcDirX, "mcDirX/D");
364  m_pRecoTree->Branch("mcDirY", &m_mcDirY, "mcDirY/D");
365  m_pRecoTree->Branch("mcDirZ", &m_mcDirZ, "mcDirZ/D");
366  m_pRecoTree->Branch("mcEnergy", &m_mcEnergy, "mcEnergy/D");
367  m_pRecoTree->Branch("mcLength", &m_mcLength, "mcLength/D");
368  m_pRecoTree->Branch("mcStraightLength", &m_mcStraightLength, "mcStraightLength/D");
369  m_pRecoTree->Branch("completeness", &m_completeness, "completeness/D");
370  m_pRecoTree->Branch("purity", &m_purity, "purity/D");
371  m_pRecoTree->Branch("nMCHits", &m_nMCHits, "nMCHits/I");
372  m_pRecoTree->Branch("nPfoHits", &m_nPfoHits, "nPfoHits/I");
373  m_pRecoTree->Branch("nMatchedHits", &m_nMatchedHits, "nMatchedHits/I");
374  m_pRecoTree->Branch("nMCHitsU", &m_nMCHitsU, "nMCHitsU/I");
375  m_pRecoTree->Branch("nMCHitsV", &m_nMCHitsV, "nMCHitsV/I");
376  m_pRecoTree->Branch("nMCHitsW", &m_nMCHitsW, "nMCHitsW/I");
377  m_pRecoTree->Branch("nPfoHitsU", &m_nPfoHitsU, "nPfoHitsU/I");
378  m_pRecoTree->Branch("nPfoHitsV", &m_nPfoHitsV, "nPfoHitsV/I");
379  m_pRecoTree->Branch("nPfoHitsW", &m_nPfoHitsW, "nPfoHitsW/I");
380  m_pRecoTree->Branch("nMatchedHitsU", &m_nMatchedHitsU, "nMatchedHitsU/I");
381  m_pRecoTree->Branch("nMatchedHitsV", &m_nMatchedHitsV, "nMatchedHitsV/I");
382  m_pRecoTree->Branch("nMatchedHitsW", &m_nMatchedHitsW, "nMatchedHitsW/I");
383  m_pRecoTree->Branch("nTrueWithoutRecoHits", &m_nTrueWithoutRecoHits, "nTrueWithoutRecoHits/I");
384  m_pRecoTree->Branch("nRecoWithoutTrueHits", &m_nRecoWithoutTrueHits, "nRecoWithoutTrueHits/I");
385  m_pRecoTree->Branch("spacepointsMinX", &m_spacepointsMinX, "spacepointsMinX/D");
386  m_pRecoTree->Branch("spacepointsMaxX", &m_spacepointsMaxX, "spacepointsMaxX/D");
387 }
388 
389 //------------------------------------------------------------------------------------------------------------------------------------------
390 
392 {
393 }
394 
395 //------------------------------------------------------------------------------------------------------------------------------------------
396 
398 {
399  if (m_printDebug)
400  std::cout << " *** PFParticleMonitoring::analyze(...) *** " << std::endl;
401 
402  m_run = evt.run();
403  m_event = evt.id().event();
404  m_index = 0;
405 
406  m_nMCParticles = 0;
407  m_nNeutrinoPfos = 0;
408  m_nPrimaryPfos = 0;
409  m_nDaughterPfos = 0;
410 
411  m_mcPdg = 0;
412  m_mcNuPdg = 0;
413  m_mcParentPdg = 0;
414  m_mcPrimaryPdg = 0;
415  m_mcIsNeutrino = 0;
416  m_mcIsPrimary = 0;
417  m_mcIsDecay = 0;
418  m_mcIsCC = 0;
419 
420  m_pfoPdg = 0;
421  m_pfoNuPdg = 0;
422  m_pfoParentPdg = 0;
423  m_pfoPrimaryPdg = 0;
424  m_pfoIsNeutrino = 0;
425  m_pfoIsPrimary = 0;
426  m_pfoIsStitched = 0;
427  m_pfoTrack = 0;
428  m_pfoVertex = 0;
429  m_pfoVtxX = 0.0;
430  m_pfoVtxY = 0.0;
431  m_pfoVtxZ = 0.0;
432  m_pfoEndX = 0.0;
433  m_pfoEndY = 0.0;
434  m_pfoEndZ = 0.0;
435  m_pfoDirX = 0.0;
436  m_pfoDirY = 0.0;
437  m_pfoDirZ = 0.0;
438  m_pfoLength = 0.0;
439  m_pfoStraightLength = 0.0;
440 
441  m_mcVertex = 0;
442  m_mcVtxX = 0.0;
443  m_mcVtxY = 0.0;
444  m_mcVtxZ = 0.0;
445  m_mcEndX = 0.0;
446  m_mcEndY = 0.0;
447  m_mcEndZ = 0.0;
448  m_mcDirX = 0.0;
449  m_mcDirY = 0.0;
450  m_mcDirZ = 0.0;
451  m_mcEnergy = 0.0;
452  m_mcLength = 0.0;
453  m_mcStraightLength = 0.0;
454 
455  m_completeness = 0.0;
456  m_purity = 0.0;
457 
458  m_nMCHits = 0;
459  m_nPfoHits = 0;
460  m_nMatchedHits = 0;
461  m_nMCHitsU = 0;
462  m_nMCHitsV = 0;
463  m_nMCHitsW = 0;
464  m_nPfoHitsU = 0;
465  m_nPfoHitsV = 0;
466  m_nPfoHitsW = 0;
467  m_nMatchedHitsU = 0;
468  m_nMatchedHitsV = 0;
469  m_nMatchedHitsW = 0;
470 
473 
474  m_spacepointsMinX = 0.0;
475  m_spacepointsMaxX = 0.0;
476 
477  if (m_printDebug)
478  {
479  std::cout << " Run: " << m_run << std::endl;
480  std::cout << " Event: " << m_event << std::endl;
481  }
482 
483  // Collect Hits
484  // ============
485  HitVector hitVector;
487 
488  if (m_printDebug)
489  std::cout << " Hits: " << hitVector.size() << std::endl;
490 
491  // Collect SpacePoints and SpacePoint <-> Hit Associations
492  // =======================================================
493  SpacePointVector spacePointVector;
494  SpacePointsToHits spacePointsToHits;
495  HitsToSpacePoints hitsToSpacePoints;
496  LArPandoraHelper::CollectSpacePoints(evt, m_particleLabel, spacePointVector, spacePointsToHits, hitsToSpacePoints);
497 
498  if (m_printDebug)
499  std::cout << " SpacePoints: " << spacePointVector.size() << std::endl;
500 
501  // Collect Tracks and PFParticle <-> Track Associations
502  // ====================================================
503  TrackVector recoTrackVector;
504  PFParticlesToTracks recoParticlesToTracks;
505  LArPandoraHelper::CollectTracks(evt, m_trackLabel, recoTrackVector, recoParticlesToTracks);
506 
507  if (m_printDebug)
508  std::cout << " Tracks: " << recoTrackVector.size() << std::endl;
509 
510  // Collect TOs and PFParticle <-> T0 Associations
511  // ==============================================
512  T0Vector t0Vector;
513  PFParticlesToT0s particlesToT0s;
514  LArPandoraHelper::CollectT0s(evt, m_particleLabel, t0Vector, particlesToT0s);
515 
516  // Collect Vertices and PFParticle <-> Vertex Associations
517  // =======================================================
518  VertexVector recoVertexVector;
519  PFParticlesToVertices recoParticlesToVertices;
520  LArPandoraHelper::CollectVertices(evt, m_particleLabel, recoVertexVector, recoParticlesToVertices);
521 
522  if (m_printDebug)
523  std::cout << " Vertices: " << recoVertexVector.size() << std::endl;
524 
525  // Collect PFParticles and match Reco Particles to Hits
526  // ====================================================
527  PFParticleVector recoParticleVector;
528  PFParticleVector recoNeutrinoVector;
529  PFParticlesToHits recoParticlesToHits;
530  HitsToPFParticles recoHitsToParticles;
531 
532  LArPandoraHelper::CollectPFParticles(evt, m_particleLabel, recoParticleVector);
533  LArPandoraHelper::SelectNeutrinoPFParticles(recoParticleVector, recoNeutrinoVector);
534  LArPandoraHelper::BuildPFParticleHitMaps(evt, m_particleLabel, recoParticlesToHits, recoHitsToParticles,
536 
537  if (m_printDebug)
538  {
539  std::cout << " RecoNeutrinos: " << recoNeutrinoVector.size() << std::endl;
540  std::cout << " RecoParticles: " << recoParticleVector.size() << std::endl;
541  }
542 
543  // Collect MCParticles and match True Particles to Hits
544  // ====================================================
545  MCParticleVector trueParticleVector;
546  MCTruthToMCParticles truthToParticles;
547  MCParticlesToMCTruth particlesToTruth;
548  MCParticlesToHits trueParticlesToHits;
549  HitsToMCParticles trueHitsToParticles;
550 
551  if (!evt.isRealData())
552  {
554  LArPandoraHelper::CollectMCParticles(evt, m_geantModuleLabel, truthToParticles, particlesToTruth);
555 
556  LArPandoraHelper::BuildMCParticleHitMaps(evt, m_geantModuleLabel, hitVector, trueParticlesToHits, trueHitsToParticles,
557  (m_useDaughterMCParticles ? (m_addDaughterMCParticles ? LArPandoraHelper::kAddDaughters : LArPandoraHelper::kUseDaughters) : LArPandoraHelper::kIgnoreDaughters));
558 
559  if (trueHitsToParticles.empty())
560  {
561  if (m_backtrackerLabel.empty())
562  throw cet::exception("LArPandora") << " PFParticleMonitoring::analyze - no sim channels found, backtracker module must be set in FHiCL " << std::endl;
563 
565  trueParticlesToHits, trueHitsToParticles,
566  (m_useDaughterMCParticles ? (m_addDaughterMCParticles ? LArPandoraHelper::kAddDaughters : LArPandoraHelper::kUseDaughters) : LArPandoraHelper::kIgnoreDaughters));
567  }
568  }
569 
570  if (m_printDebug)
571  {
572  std::cout << " TrueParticles: " << particlesToTruth.size() << std::endl;
573  std::cout << " TrueEvents: " << truthToParticles.size() << std::endl;
574  std::cout << " MatchedParticles: " << trueParticlesToHits.size() << std::endl;
575  }
576 
577  if (trueParticlesToHits.empty())
578  {
579  m_pRecoTree->Fill();
580  return;
581  }
582 
583  // Build Reco and True Particle Maps (for Parent/Daughter Navigation)
584  // =================================================================
585  MCParticleMap trueParticleMap;
586  PFParticleMap recoParticleMap;
587 
588  LArPandoraHelper::BuildMCParticleMap(trueParticleVector, trueParticleMap);
589  LArPandoraHelper::BuildPFParticleMap(recoParticleVector, recoParticleMap);
590 
591  m_nMCParticles = trueParticlesToHits.size();
592  m_nNeutrinoPfos = 0;
593  m_nPrimaryPfos = 0;
594  m_nDaughterPfos = 0;
595 
596  // Count reconstructed particles
597  for (PFParticleVector::const_iterator iter = recoParticleVector.begin(), iterEnd = recoParticleVector.end(); iter != iterEnd; ++iter)
598  {
599  const art::Ptr<recob::PFParticle> recoParticle = *iter;
600 
601  if (LArPandoraHelper::IsNeutrino(recoParticle))
602  {
603  m_nNeutrinoPfos++;
604  }
605  else if (LArPandoraHelper::IsFinalState(recoParticleMap, recoParticle))
606  {
607  m_nPrimaryPfos++;
608  }
609  else
610  {
611  m_nDaughterPfos++;
612  }
613  }
614 
615  // Match Reco Neutrinos to True Neutrinos
616  // ======================================
617  PFParticlesToHits recoNeutrinosToHits;
618  HitsToPFParticles recoHitsToNeutrinos;
619  HitsToMCTruth trueHitsToNeutrinos;
620  MCTruthToHits trueNeutrinosToHits;
621  this->BuildRecoNeutrinoHitMaps(recoParticleMap, recoParticlesToHits, recoNeutrinosToHits, recoHitsToNeutrinos);
622  this->BuildTrueNeutrinoHitMaps(truthToParticles, trueParticlesToHits, trueNeutrinosToHits, trueHitsToNeutrinos);
623 
624  MCTruthToPFParticles matchedNeutrinos;
625  MCTruthToHits matchedNeutrinoHits;
626  this->GetRecoToTrueMatches(recoNeutrinosToHits, trueHitsToNeutrinos, matchedNeutrinos, matchedNeutrinoHits);
627 
628  for (MCTruthToHits::const_iterator iter = trueNeutrinosToHits.begin(), iterEnd = trueNeutrinosToHits.end(); iter != iterEnd; ++iter)
629  {
630  const art::Ptr<simb::MCTruth> trueEvent = iter->first;
631  const HitVector &trueHitVector = iter->second;
632 
633  if (trueHitVector.empty())
634  continue;
635 
636  if (!trueEvent->NeutrinoSet())
637  continue;
638 
639  const simb::MCNeutrino trueNeutrino(trueEvent->GetNeutrino());
640  const simb::MCParticle trueParticle(trueNeutrino.Nu());
641 
642  m_mcIsCC = ((simb::kCC == trueNeutrino.CCNC()) ? 1 : 0);
643  m_mcPdg = trueParticle.PdgCode();
644  m_mcNuPdg = m_mcPdg;
645  m_mcParentPdg = 0;
646  m_mcPrimaryPdg = 0;
647  m_mcIsNeutrino = 1;
648  m_mcIsPrimary = 0;
649  m_mcIsDecay = 0;
650 
651  m_mcVertex = 1;
652  m_mcVtxX = trueParticle.Vx();
653  m_mcVtxY = trueParticle.Vy();
654  m_mcVtxZ = trueParticle.Vz();
655  m_mcEndX = m_mcVtxX;
656  m_mcEndY = m_mcVtxY;
657  m_mcEndZ = m_mcVtxZ;
658  m_mcDirX = trueParticle.Px() / trueParticle.P();
659  m_mcDirY = trueParticle.Py() / trueParticle.P();
660  m_mcDirZ = trueParticle.Pz() / trueParticle.P();
661  m_mcEnergy = trueParticle.E();
662  m_mcLength = 0.0;
663  m_mcStraightLength = 0.0;
664 
665  m_nMCHits = trueHitVector.size();
666  m_nMCHitsU = this->CountHitsByType(geo::kU, trueHitVector);
667  m_nMCHitsV = this->CountHitsByType(geo::kV, trueHitVector);
668  m_nMCHitsW = this->CountHitsByType(geo::kW, trueHitVector);
669 
670  m_pfoPdg = 0;
671  m_pfoNuPdg = 0;
672  m_pfoParentPdg = 0;
673  m_pfoPrimaryPdg = 0;
674  m_pfoIsNeutrino = 0;
675  m_pfoIsPrimary = 0;
676  m_pfoIsStitched = 0;
677  m_pfoTrack = 0;
678  m_pfoVertex = 0;
679  m_pfoVtxX = 0.0;
680  m_pfoVtxY = 0.0;
681  m_pfoVtxZ = 0.0;
682  m_pfoEndX = 0.0;
683  m_pfoEndY = 0.0;
684  m_pfoEndZ = 0.0;
685  m_pfoDirX = 0.0;
686  m_pfoDirY = 0.0;
687  m_pfoDirZ = 0.0;
688  m_pfoLength = 0.0;
689  m_pfoStraightLength = 0.0;
690 
691  m_nPfoHits = 0;
692  m_nPfoHitsU = 0;
693  m_nPfoHitsV = 0;
694  m_nPfoHitsW = 0;
695 
696  m_nMatchedHits = 0;
697  m_nMatchedHitsU = 0;
698  m_nMatchedHitsV = 0;
699  m_nMatchedHitsW = 0;
700 
703 
704  m_spacepointsMinX = 0.0;
705  m_spacepointsMaxX = 0.0;
706 
707  m_completeness = 0.0;
708  m_purity = 0.0;
709 
710  for (HitVector::const_iterator hIter1 = trueHitVector.begin(), hIterEnd1 = trueHitVector.end(); hIter1 != hIterEnd1; ++hIter1)
711  {
712  if (recoHitsToNeutrinos.find(*hIter1) == recoHitsToNeutrinos.end())
714  }
715 
716  MCTruthToPFParticles::const_iterator pIter1 = matchedNeutrinos.find(trueEvent);
717  if (matchedNeutrinos.end() != pIter1)
718  {
719  const art::Ptr<recob::PFParticle> recoParticle = pIter1->second;
720  m_pfoPdg = recoParticle->PdgCode();
723  m_pfoPrimaryPdg = 0;
724  m_pfoIsNeutrino = 1;
725  m_pfoIsPrimary = 0;
726 
727  if (!LArPandoraHelper::IsNeutrino(recoParticle))
728  std::cout << " Warning: Found neutrino with an invalid PDG code " << std::endl;
729 
730  PFParticlesToHits::const_iterator pIter2 = recoNeutrinosToHits.find(recoParticle);
731  if (recoParticlesToHits.end() != pIter2)
732  {
733  const HitVector &recoHitVector = pIter2->second;
734 
735  for (HitVector::const_iterator hIter2 = recoHitVector.begin(), hIterEnd2 = recoHitVector.end(); hIter2 != hIterEnd2; ++hIter2)
736  {
737  if (trueHitsToNeutrinos.find(*hIter2) == trueHitsToNeutrinos.end())
739  }
740 
741  MCTruthToHits::const_iterator pIter3 = matchedNeutrinoHits.find(trueEvent);
742  if (matchedNeutrinoHits.end() != pIter3)
743  {
744  const HitVector &matchedHitVector = pIter3->second;
745 
746  m_nPfoHits = recoHitVector.size();
747  m_nPfoHitsU = this->CountHitsByType(geo::kU, recoHitVector);
748  m_nPfoHitsV = this->CountHitsByType(geo::kV, recoHitVector);
749  m_nPfoHitsW = this->CountHitsByType(geo::kW, recoHitVector);
750 
751  m_nMatchedHits = matchedHitVector.size();
752  m_nMatchedHitsU = this->CountHitsByType(geo::kU, matchedHitVector);
753  m_nMatchedHitsV = this->CountHitsByType(geo::kV, matchedHitVector);
754  m_nMatchedHitsW = this->CountHitsByType(geo::kW, matchedHitVector);
755 
756  PFParticlesToVertices::const_iterator pIter4 = recoParticlesToVertices.find(recoParticle);
757  if (recoParticlesToVertices.end() != pIter4)
758  {
759  const VertexVector &vertexVector = pIter4->second;
760  if (!vertexVector.empty())
761  {
762  if (vertexVector.size() !=1 && m_printDebug)
763  std::cout << " Warning: Found particle with more than one associated vertex " << std::endl;
764 
765  const art::Ptr<recob::Vertex> recoVertex = *(vertexVector.begin());
766  double xyz[3] = {0.0, 0.0, 0.0} ;
767  recoVertex->XYZ(xyz);
768 
769  m_pfoVertex = 1;
770  m_pfoVtxX = xyz[0];
771  m_pfoVtxY = xyz[1];
772  m_pfoVtxZ = xyz[2];
773  }
774  }
775  }
776  }
777  }
778 
779  m_purity = ((m_nPfoHits == 0) ? 0.0 : static_cast<double>(m_nMatchedHits) / static_cast<double>(m_nPfoHits));
780  m_completeness = ((m_nPfoHits == 0) ? 0.0 : static_cast<double>(m_nMatchedHits) / static_cast<double>(m_nMCHits));
781 
782  if (m_printDebug)
783  std::cout << " MCNeutrino [" << m_index << "]"
784  << " trueNu=" << m_mcNuPdg << ", truePdg=" << m_mcPdg << ", recoNu=" << m_pfoNuPdg << ", recoPdg=" << m_pfoPdg
785  << ", mcHits=" << m_nMCHits << ", pfoHits=" << m_nPfoHits << ", matchedHits=" << m_nMatchedHits
786  << ", availableHits=" << m_nTrueWithoutRecoHits << std::endl;
787 
788  m_pRecoTree->Fill();
789  ++m_index; // Increment index number
790  }
791 
792 
793  // Match Reco Particles to True Particles
794  // ======================================
795  MCParticlesToPFParticles matchedParticles;
796  MCParticlesToHits matchedParticleHits;
797  this->GetRecoToTrueMatches(recoParticlesToHits, trueHitsToParticles, matchedParticles, matchedParticleHits);
798 
799  // Compare true and reconstructed particles
800  for (MCParticlesToHits::const_iterator iter = trueParticlesToHits.begin(), iterEnd = trueParticlesToHits.end(); iter != iterEnd; ++iter)
801  {
802  const art::Ptr<simb::MCParticle> trueParticle = iter->first;
803  const HitVector &trueHitVector = iter->second;
804 
805  if (trueHitVector.empty())
806  continue;
807 
808  m_mcPdg = trueParticle->PdgCode();
809  m_mcNuPdg = 0;
810  m_mcParentPdg = 0;
811  m_mcPrimaryPdg = 0;
812  m_mcIsNeutrino = 0;
813  m_mcIsPrimary = 0;
814  m_mcIsDecay = 0;
815  m_mcIsCC = 0;
816 
817  m_pfoPdg = 0;
818  m_pfoNuPdg = 0;
819  m_pfoParentPdg = 0;
820  m_pfoPrimaryPdg = 0;
821  m_pfoIsNeutrino = 0;
822  m_pfoIsPrimary = 0;
823  m_pfoIsStitched = 0;
824  m_pfoTrack = 0;
825  m_pfoVertex = 0;
826  m_pfoVtxX = 0.0;
827  m_pfoVtxY = 0.0;
828  m_pfoVtxZ = 0.0;
829  m_pfoEndX = 0.0;
830  m_pfoEndY = 0.0;
831  m_pfoEndZ = 0.0;
832  m_pfoDirX = 0.0;
833  m_pfoDirY = 0.0;
834  m_pfoDirZ = 0.0;
835  m_pfoLength = 0.0;
836  m_pfoStraightLength = 0.0;
837 
838  m_mcVertex = 0;
839  m_mcVtxX = 0.0;
840  m_mcVtxY = 0.0;
841  m_mcVtxZ = 0.0;
842  m_mcEndX = 0.0;
843  m_mcEndY = 0.0;
844  m_mcEndZ = 0.0;
845  m_mcDirX = 0.0;
846  m_mcDirY = 0.0;
847  m_mcDirZ = 0.0;
848  m_mcEnergy = 0.0;
849  m_mcLength = 0.0;
850  m_mcStraightLength = 0.0;
851 
852  m_completeness = 0.0;
853  m_purity = 0.0;
854 
855  m_nMCHits = 0;
856  m_nMCHitsU = 0;
857  m_nMCHitsV = 0;
858  m_nMCHitsW = 0;
859 
860  m_nPfoHits = 0;
861  m_nPfoHitsU = 0;
862  m_nPfoHitsV = 0;
863  m_nPfoHitsW = 0;
864 
865  m_nMatchedHits = 0;
866  m_nMatchedHitsU = 0;
867  m_nMatchedHitsV = 0;
868  m_nMatchedHitsW = 0;
869 
872 
873  m_spacepointsMinX = 0.0;
874  m_spacepointsMaxX = 0.0;
875 
876  // Set true properties
877  try
878  {
879  int startT(-1);
880  int endT(-1);
881  this->GetStartAndEndPoints(trueParticle, startT, endT);
882 
883  // vertex and end positions
884  m_mcVertex = 1;
885  m_mcVtxX = trueParticle->Vx(startT);
886  m_mcVtxY = trueParticle->Vy(startT);
887  m_mcVtxZ = trueParticle->Vz(startT);
888  m_mcEndX = trueParticle->Vx(endT);
889  m_mcEndY = trueParticle->Vy(endT);
890  m_mcEndZ = trueParticle->Vz(endT);
891 
892  const double dx(m_mcEndX - m_mcVtxX);
893  const double dy(m_mcEndY - m_mcVtxY);
894  const double dz(m_mcEndZ - m_mcVtxZ);
895 
896  m_mcStraightLength = std::sqrt(dx * dx + dy *dy + dz * dz);
897  m_mcLength = this->GetLength(trueParticle, startT, endT);
898 
899  // energy and momentum
900  const double Ptot(trueParticle->P(startT));
901 
902  if (Ptot > 0.0)
903  {
904  m_mcDirX = trueParticle->Px(startT) / Ptot;
905  m_mcDirY = trueParticle->Py(startT) / Ptot;
906  m_mcDirZ = trueParticle->Pz(startT) / Ptot;
907  m_mcEnergy = trueParticle->E(startT);
908  }
909  }
910  catch (cet::exception &e){
911  }
912 
913  // Get the true parent neutrino
914  MCParticlesToMCTruth::const_iterator nuIter = particlesToTruth.find(trueParticle);
915  if (particlesToTruth.end() == nuIter)
916  throw cet::exception("LArPandora") << " PFParticleMonitoring::analyze --- Found a true particle without any ancestry information ";
917 
918  const art::Ptr<simb::MCTruth> trueEvent = nuIter->second;
919 
920  if (trueEvent->NeutrinoSet())
921  {
922  const simb::MCNeutrino neutrino(trueEvent->GetNeutrino());
923  m_mcNuPdg = neutrino.Nu().PdgCode();
924  m_mcIsCC = ((simb::kCC == neutrino.CCNC()) ? 1 : 0);
925  }
926 
927  // Get the true 'parent' and 'primary' particles
928  try
929  {
930  const art::Ptr<simb::MCParticle> parentParticle(LArPandoraHelper::GetParentMCParticle(trueParticleMap, trueParticle));
931  const art::Ptr<simb::MCParticle> primaryParticle(LArPandoraHelper::GetFinalStateMCParticle(trueParticleMap, trueParticle));
932  m_mcParentPdg = ((parentParticle != trueParticle) ? parentParticle->PdgCode() : 0);
933  m_mcPrimaryPdg = primaryParticle->PdgCode();
934  m_mcIsPrimary = (primaryParticle == trueParticle);
935  m_mcIsDecay = ("Decay" == trueParticle->Process());
936  }
937  catch (cet::exception &e){
938  }
939 
940  // Find min and max X positions of space points
941  bool foundSpacePoints(false);
942 
943  for (HitVector::const_iterator hIter1 = trueHitVector.begin(), hIterEnd1 = trueHitVector.end(); hIter1 != hIterEnd1; ++hIter1)
944  {
945  const art::Ptr<recob::Hit> hit = *hIter1;
946 
947  HitsToSpacePoints::const_iterator hIter2 = hitsToSpacePoints.find(hit);
948  if (hitsToSpacePoints.end() == hIter2)
949  continue;
950 
951  const art::Ptr<recob::SpacePoint> spacepoint = hIter2->second;
952  const double X(spacepoint->XYZ()[0]);
953 
954  if (!foundSpacePoints)
955  {
958  foundSpacePoints = true;
959  }
960  else
961  {
964  }
965  }
966 
967  // Count number of available hits
968  for (HitVector::const_iterator hIter1 = trueHitVector.begin(), hIterEnd1 = trueHitVector.end(); hIter1 != hIterEnd1; ++hIter1)
969  {
970  if (recoHitsToParticles.find(*hIter1) == recoHitsToParticles.end())
972  }
973 
974  // Match true and reconstructed hits
975  m_nMCHits = trueHitVector.size();
976  m_nMCHitsU = this->CountHitsByType(geo::kU, trueHitVector);
977  m_nMCHitsV = this->CountHitsByType(geo::kV, trueHitVector);
978  m_nMCHitsW = this->CountHitsByType(geo::kW, trueHitVector);
979 
980  MCParticlesToPFParticles::const_iterator pIter1 = matchedParticles.find(trueParticle);
981  if (matchedParticles.end() != pIter1)
982  {
983  const art::Ptr<recob::PFParticle> recoParticle = pIter1->second;
984  m_pfoPdg = recoParticle->PdgCode();
985  m_pfoNuPdg = LArPandoraHelper::GetParentNeutrino(recoParticleMap, recoParticle);
986  m_pfoIsPrimary = LArPandoraHelper::IsFinalState(recoParticleMap, recoParticle);
987 
988  const art::Ptr<recob::PFParticle> parentParticle = LArPandoraHelper::GetParentPFParticle(recoParticleMap, recoParticle);
989  m_pfoParentPdg = parentParticle->PdgCode();
990 
991  const art::Ptr<recob::PFParticle> primaryParticle = LArPandoraHelper::GetFinalStatePFParticle(recoParticleMap, recoParticle);
992  m_pfoPrimaryPdg = primaryParticle->PdgCode();
993 
994  PFParticlesToHits::const_iterator pIter2 = recoParticlesToHits.find(recoParticle);
995  if (recoParticlesToHits.end() == pIter2)
996  throw cet::exception("LArPandora") << " PFParticleMonitoring::analyze --- Found a reco particle without any hits ";
997 
998  const HitVector &recoHitVector = pIter2->second;
999 
1000  for (HitVector::const_iterator hIter2 = recoHitVector.begin(), hIterEnd2 = recoHitVector.end(); hIter2 != hIterEnd2; ++hIter2)
1001  {
1002  if (trueHitsToParticles.find(*hIter2) == trueHitsToParticles.end())
1004  }
1005 
1006  MCParticlesToHits::const_iterator pIter3 = matchedParticleHits.find(trueParticle);
1007  if (matchedParticleHits.end() == pIter3)
1008  throw cet::exception("LArPandora") << " PFParticleMonitoring::analyze --- Found a matched true particle without matched hits ";
1009 
1010  const HitVector &matchedHitVector = pIter3->second;
1011 
1012  m_nPfoHits = recoHitVector.size();
1013  m_nPfoHitsU = this->CountHitsByType(geo::kU, recoHitVector);
1014  m_nPfoHitsV = this->CountHitsByType(geo::kV, recoHitVector);
1015  m_nPfoHitsW = this->CountHitsByType(geo::kW, recoHitVector);
1016 
1017  m_nMatchedHits = matchedHitVector.size();
1018  m_nMatchedHitsU = this->CountHitsByType(geo::kU, matchedHitVector);
1019  m_nMatchedHitsV = this->CountHitsByType(geo::kV, matchedHitVector);
1020  m_nMatchedHitsW = this->CountHitsByType(geo::kW, matchedHitVector);
1021 
1022  PFParticlesToVertices::const_iterator pIter4 = recoParticlesToVertices.find(recoParticle);
1023  if (recoParticlesToVertices.end() != pIter4)
1024  {
1025  const VertexVector &vertexVector = pIter4->second;
1026  if (!vertexVector.empty())
1027  {
1028  if (vertexVector.size() !=1 && m_printDebug)
1029  std::cout << " Warning: Found particle with more than one associated vertex " << std::endl;
1030 
1031  const art::Ptr<recob::Vertex> recoVertex = *(vertexVector.begin());
1032  double xyz[3] = {0.0, 0.0, 0.0} ;
1033  recoVertex->XYZ(xyz);
1034 
1035  m_pfoVertex = 1;
1036  m_pfoVtxX = xyz[0];
1037  m_pfoVtxY = xyz[1];
1038  m_pfoVtxZ = xyz[2];
1039  }
1040  }
1041 
1042  PFParticlesToTracks::const_iterator pIter5 = recoParticlesToTracks.find(recoParticle);
1043  if (recoParticlesToTracks.end() != pIter5)
1044  {
1045  const TrackVector &trackVector = pIter5->second;
1046  if (!trackVector.empty())
1047  {
1048  if (trackVector.size() !=1 && m_printDebug)
1049  std::cout << " Warning: Found particle with more than one associated track " << std::endl;
1050 
1051  const art::Ptr<recob::Track> recoTrack = *(trackVector.begin());
1052  const auto &vtxPosition = recoTrack->Vertex();
1053  const auto &endPosition = recoTrack->End();
1054  const auto &vtxDirection = recoTrack->VertexDirection();
1055 
1056  m_pfoTrack = 1;
1057  m_pfoVtxX = vtxPosition.x();
1058  m_pfoVtxY = vtxPosition.y();
1059  m_pfoVtxZ = vtxPosition.z();
1060  m_pfoEndX = endPosition.x();
1061  m_pfoEndY = endPosition.y();
1062  m_pfoEndZ = endPosition.z();
1063  m_pfoDirX = vtxDirection.x();
1064  m_pfoDirY = vtxDirection.y();
1065  m_pfoDirZ = vtxDirection.z();
1066  m_pfoStraightLength = (endPosition - vtxPosition).R();
1067  m_pfoLength = recoTrack->Length();
1068  }
1069  }
1070 
1071  m_pfoIsStitched = (particlesToT0s.end() != particlesToT0s.find(recoParticle));
1072  }
1073 
1074  m_purity = ((m_nPfoHits == 0) ? 0.0 : static_cast<double>(m_nMatchedHits) / static_cast<double>(m_nPfoHits));
1075  m_completeness = ((m_nPfoHits == 0) ? 0.0 : static_cast<double>(m_nMatchedHits) / static_cast<double>(m_nMCHits));
1076 
1077  if (m_printDebug)
1078  std::cout << " MCParticle [" << m_index << "]"
1079  << " trueNu=" << m_mcNuPdg << ", truePdg=" << m_mcPdg << ", recoNu=" << m_pfoNuPdg << ", recoPdg=" << m_pfoPdg
1080  << ", mcHits=" << m_nMCHits << ", pfoHits=" << m_nPfoHits << ", matchedHits=" << m_nMatchedHits
1081  << ", availableHits=" << m_nTrueWithoutRecoHits << std::endl;
1082 
1083  m_pRecoTree->Fill();
1084  ++m_index; // Increment index number
1085  }
1086 }
1087 
1088 //------------------------------------------------------------------------------------------------------------------------------------------
1089 
1090 void PFParticleMonitoring::BuildTrueNeutrinoHitMaps(const MCTruthToMCParticles &truthToParticles, const MCParticlesToHits &trueParticlesToHits,
1091  MCTruthToHits &trueNeutrinosToHits, HitsToMCTruth &trueHitsToNeutrinos) const
1092 {
1093  for (MCTruthToMCParticles::const_iterator iter1 = truthToParticles.begin(), iterEnd1 = truthToParticles.end();
1094  iter1 != iterEnd1; ++iter1)
1095  {
1096  const art::Ptr<simb::MCTruth> trueNeutrino = iter1->first;
1097  const MCParticleVector &trueParticleVector = iter1->second;
1098 
1099  for (MCParticleVector::const_iterator iter2 = trueParticleVector.begin(), iterEnd2 = trueParticleVector.end(); iter2 != iterEnd2; ++iter2)
1100  {
1101  const MCParticlesToHits::const_iterator iter3 = trueParticlesToHits.find(*iter2);
1102  if (trueParticlesToHits.end() == iter3)
1103  continue;
1104 
1105  const HitVector &hitVector = iter3->second;
1106 
1107  for (HitVector::const_iterator iter4 = hitVector.begin(), iterEnd4 = hitVector.end(); iter4 != iterEnd4; ++iter4)
1108  {
1109  const art::Ptr<recob::Hit> hit = *iter4;
1110  trueHitsToNeutrinos[hit] = trueNeutrino;
1111  trueNeutrinosToHits[trueNeutrino].push_back(hit);
1112  }
1113  }
1114  }
1115 }
1116 
1117 //------------------------------------------------------------------------------------------------------------------------------------------
1118 
1119 void PFParticleMonitoring::BuildRecoNeutrinoHitMaps(const PFParticleMap &recoParticleMap, const PFParticlesToHits &recoParticlesToHits,
1120  PFParticlesToHits &recoNeutrinosToHits, HitsToPFParticles &recoHitsToNeutrinos) const
1121 {
1122  for (PFParticleMap::const_iterator iter1 = recoParticleMap.begin(), iterEnd1 = recoParticleMap.end(); iter1 != iterEnd1; ++iter1)
1123  {
1124  const art::Ptr<recob::PFParticle> recoParticle = iter1->second;
1125  const art::Ptr<recob::PFParticle> recoNeutrino = LArPandoraHelper::GetParentPFParticle(recoParticleMap, recoParticle);
1126 
1127  if (!LArPandoraHelper::IsNeutrino(recoNeutrino))
1128  continue;
1129 
1130  const PFParticlesToHits::const_iterator iter2 = recoParticlesToHits.find(recoParticle);
1131  if (recoParticlesToHits.end() == iter2)
1132  continue;
1133 
1134  const HitVector &hitVector = iter2->second;
1135 
1136  for (HitVector::const_iterator iter3 = hitVector.begin(), iterEnd3 = hitVector.end(); iter3 != iterEnd3; ++iter3)
1137  {
1138  const art::Ptr<recob::Hit> hit = *iter3;
1139  recoHitsToNeutrinos[hit] = recoNeutrino;
1140  recoNeutrinosToHits[recoNeutrino].push_back(hit);
1141  }
1142  }
1143 }
1144 
1145 //------------------------------------------------------------------------------------------------------------------------------------------
1146 
1147 void PFParticleMonitoring::GetRecoToTrueMatches(const PFParticlesToHits &recoNeutrinosToHits, const HitsToMCTruth &trueHitsToNeutrinos,
1148  MCTruthToPFParticles &matchedNeutrinos, MCTruthToHits &matchedNeutrinoHits) const
1149 {
1150  PFParticleSet recoVeto; MCTruthSet trueVeto;
1151 
1152  this->GetRecoToTrueMatches(recoNeutrinosToHits, trueHitsToNeutrinos, matchedNeutrinos, matchedNeutrinoHits, recoVeto, trueVeto);
1153 }
1154 
1155 //------------------------------------------------------------------------------------------------------------------------------------------
1156 
1157 void PFParticleMonitoring::GetRecoToTrueMatches(const PFParticlesToHits &recoNeutrinosToHits, const HitsToMCTruth &trueHitsToNeutrinos,
1158  MCTruthToPFParticles &matchedNeutrinos, MCTruthToHits &matchedNeutrinoHits, PFParticleSet &vetoReco, MCTruthSet &vetoTrue) const
1159 {
1160  bool foundMatches(false);
1161 
1162  for (PFParticlesToHits::const_iterator iter1 = recoNeutrinosToHits.begin(), iterEnd1 = recoNeutrinosToHits.end();
1163  iter1 != iterEnd1; ++iter1)
1164  {
1165  const art::Ptr<recob::PFParticle> recoNeutrino = iter1->first;
1166  if (vetoReco.count(recoNeutrino) > 0)
1167  continue;
1168 
1169  const HitVector &hitVector = iter1->second;
1170 
1171  MCTruthToHits truthContributionMap;
1172 
1173  for (HitVector::const_iterator iter2 = hitVector.begin(), iterEnd2 = hitVector.end(); iter2 != iterEnd2; ++iter2)
1174  {
1175  const art::Ptr<recob::Hit> hit = *iter2;
1176 
1177  HitsToMCTruth::const_iterator iter3 = trueHitsToNeutrinos.find(hit);
1178  if (trueHitsToNeutrinos.end() == iter3)
1179  continue;
1180 
1181  const art::Ptr<simb::MCTruth> trueNeutrino = iter3->second;
1182  if (vetoTrue.count(trueNeutrino) > 0)
1183  continue;
1184 
1185  truthContributionMap[trueNeutrino].push_back(hit);
1186  }
1187 
1188  MCTruthToHits::const_iterator mIter = truthContributionMap.end();
1189 
1190  for (MCTruthToHits::const_iterator iter4 = truthContributionMap.begin(), iterEnd4 = truthContributionMap.end();
1191  iter4 != iterEnd4; ++iter4)
1192  {
1193  if ((truthContributionMap.end() == mIter) || (iter4->second.size() > mIter->second.size()))
1194  {
1195  mIter = iter4;
1196  }
1197  }
1198 
1199  if (truthContributionMap.end() != mIter)
1200  {
1201  const art::Ptr<simb::MCTruth> trueNeutrino = mIter->first;
1202 
1203  MCTruthToHits::const_iterator iter5 = matchedNeutrinoHits.find(trueNeutrino);
1204 
1205  if ((matchedNeutrinoHits.end() == iter5) || (mIter->second.size() > iter5->second.size()))
1206  {
1207  matchedNeutrinos[trueNeutrino] = recoNeutrino;
1208  matchedNeutrinoHits[trueNeutrino] = mIter->second;
1209  foundMatches = true;
1210  }
1211  }
1212  }
1213 
1214  if (!foundMatches)
1215  return;
1216 
1217  for (MCTruthToPFParticles::const_iterator pIter = matchedNeutrinos.begin(), pIterEnd = matchedNeutrinos.end();
1218  pIter != pIterEnd; ++pIter)
1219  {
1220  vetoTrue.insert(pIter->first);
1221  vetoReco.insert(pIter->second);
1222  }
1223 
1224  if (m_recursiveMatching)
1225  this->GetRecoToTrueMatches(recoNeutrinosToHits, trueHitsToNeutrinos, matchedNeutrinos, matchedNeutrinoHits, vetoReco, vetoTrue);
1226 }
1227 
1228 //------------------------------------------------------------------------------------------------------------------------------------------
1229 
1230 void PFParticleMonitoring::GetRecoToTrueMatches(const PFParticlesToHits &recoParticlesToHits, const HitsToMCParticles &trueHitsToParticles,
1231  MCParticlesToPFParticles &matchedParticles, MCParticlesToHits &matchedHits) const
1232 {
1233  PFParticleSet recoVeto; MCParticleSet trueVeto;
1234 
1235  this->GetRecoToTrueMatches(recoParticlesToHits, trueHitsToParticles, matchedParticles, matchedHits, recoVeto, trueVeto);
1236 }
1237 
1238 //------------------------------------------------------------------------------------------------------------------------------------------
1239 
1240 void PFParticleMonitoring::GetRecoToTrueMatches(const PFParticlesToHits &recoParticlesToHits, const HitsToMCParticles &trueHitsToParticles,
1241  MCParticlesToPFParticles &matchedParticles, MCParticlesToHits &matchedHits, PFParticleSet &vetoReco, MCParticleSet &vetoTrue) const
1242 {
1243  bool foundMatches(false);
1244 
1245  for (PFParticlesToHits::const_iterator iter1 = recoParticlesToHits.begin(), iterEnd1 = recoParticlesToHits.end();
1246  iter1 != iterEnd1; ++iter1)
1247  {
1248  const art::Ptr<recob::PFParticle> recoParticle = iter1->first;
1249  if (vetoReco.count(recoParticle) > 0)
1250  continue;
1251 
1252  const HitVector &hitVector = iter1->second;
1253 
1254  MCParticlesToHits truthContributionMap;
1255 
1256  for (HitVector::const_iterator iter2 = hitVector.begin(), iterEnd2 = hitVector.end(); iter2 != iterEnd2; ++iter2)
1257  {
1258  const art::Ptr<recob::Hit> hit = *iter2;
1259 
1260  HitsToMCParticles::const_iterator iter3 = trueHitsToParticles.find(hit);
1261  if (trueHitsToParticles.end() == iter3)
1262  continue;
1263 
1264  const art::Ptr<simb::MCParticle> trueParticle = iter3->second;
1265  if (vetoTrue.count(trueParticle) > 0)
1266  continue;
1267 
1268  truthContributionMap[trueParticle].push_back(hit);
1269  }
1270 
1271  MCParticlesToHits::const_iterator mIter = truthContributionMap.end();
1272 
1273  for (MCParticlesToHits::const_iterator iter4 = truthContributionMap.begin(), iterEnd4 = truthContributionMap.end();
1274  iter4 != iterEnd4; ++iter4)
1275  {
1276  if ((truthContributionMap.end() == mIter) || (iter4->second.size() > mIter->second.size()))
1277  {
1278  mIter = iter4;
1279  }
1280  }
1281 
1282  if (truthContributionMap.end() != mIter)
1283  {
1284  const art::Ptr<simb::MCParticle> trueParticle = mIter->first;
1285 
1286  MCParticlesToHits::const_iterator iter5 = matchedHits.find(trueParticle);
1287 
1288  if ((matchedHits.end() == iter5) || (mIter->second.size() > iter5->second.size()))
1289  {
1290  matchedParticles[trueParticle] = recoParticle;
1291  matchedHits[trueParticle] = mIter->second;
1292  foundMatches = true;
1293  }
1294  }
1295  }
1296 
1297  if (!foundMatches)
1298  return;
1299 
1300  for (MCParticlesToPFParticles::const_iterator pIter = matchedParticles.begin(), pIterEnd = matchedParticles.end();
1301  pIter != pIterEnd; ++pIter)
1302  {
1303  vetoTrue.insert(pIter->first);
1304  vetoReco.insert(pIter->second);
1305  }
1306 
1307  if (m_recursiveMatching)
1308  this->GetRecoToTrueMatches(recoParticlesToHits, trueHitsToParticles, matchedParticles, matchedHits, vetoReco, vetoTrue);
1309 }
1310 
1311 //------------------------------------------------------------------------------------------------------------------------------------------
1312 
1313 int PFParticleMonitoring::CountHitsByType(const int view, const HitVector &hitVector) const
1314 {
1315  int nHits(0);
1316 
1317  for (HitVector::const_iterator iter = hitVector.begin(), iterEnd = hitVector.end(); iter != iterEnd; ++iter)
1318  {
1319  const art::Ptr<recob::Hit> hit = *iter;
1320  if (hit->View() == view)
1321  ++nHits;
1322  }
1323 
1324  return nHits;
1325 }
1326 
1327 //------------------------------------------------------------------------------------------------------------------------------------------
1328 
1329 void PFParticleMonitoring::GetStartAndEndPoints(const art::Ptr<simb::MCParticle> particle, int &startT, int &endT) const
1330 {
1332 
1333  bool foundStartPosition(false);
1334 
1335  const int numTrajectoryPoints(static_cast<int>(particle->NumberTrajectoryPoints()));
1336 
1337  for (int nt = 0; nt < numTrajectoryPoints; ++nt)
1338  {
1339  try
1340  {
1341  double pos[3] = {particle->Vx(nt), particle->Vy(nt), particle->Vz(nt)};
1342  unsigned int which_tpc(std::numeric_limits<unsigned int>::max());
1343  unsigned int which_cstat(std::numeric_limits<unsigned int>::max());
1344  theGeometry->PositionToTPC(pos, which_tpc, which_cstat);
1345 
1346  // TODO: Apply fiducial cut due to readout window
1347 
1348  endT = nt;
1349  if (!foundStartPosition)
1350  {
1351  startT = endT;
1352  foundStartPosition = true;
1353  }
1354  }
1355  catch (cet::exception &e){
1356  continue;
1357  }
1358  }
1359 
1360  if (!foundStartPosition)
1361  throw cet::exception("LArPandora");
1362 }
1363 
1364 //------------------------------------------------------------------------------------------------------------------------------------------
1365 
1366 double PFParticleMonitoring::GetLength(const art::Ptr<simb::MCParticle> particle, const int startT, const int endT) const
1367 {
1368  if (endT <= startT)
1369  return 0.0;
1370 
1371  double length(0.0);
1372 
1373  for (int nt = startT; nt < endT; ++nt)
1374  {
1375  const double dx(particle->Vx(nt+1) - particle->Vx(nt));
1376  const double dy(particle->Vy(nt+1) - particle->Vy(nt));
1377  const double dz(particle->Vz(nt+1) - particle->Vz(nt));
1378  length += sqrt(dx * dx + dy * dy + dz * dz);
1379  }
1380 
1381  return length;
1382 }
1383 
1384 } //namespace lar_pandora
double E(const int i=0) const
Definition: MCParticle.h:237
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.
void XYZ(double *xyz) const
Legacy method to access vertex position, preserved to avoid breaking code. Please try to use Vertex::...
Definition: Vertex.cxx:37
unsigned int NumberTrajectoryPoints() const
Definition: MCParticle.h:222
int PdgCode() const
Definition: MCParticle.h:216
std::map< art::Ptr< simb::MCTruth >, HitVector > MCTruthToHits
const simb::MCNeutrino & GetNeutrino() const
Definition: MCTruth.h:74
int CountHitsByType(const int view, const HitVector &hitVector) const
Count the number of reconstructed hits in a given wire plane.
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
double Py(const int i=0) const
Definition: MCParticle.h:235
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< simb::MCTruth >, art::Ptr< recob::PFParticle > > MCTruthToPFParticles
Encapsulate the construction of a single cyostat.
void GetRecoToTrueMatches(const PFParticlesToHits &recoNeutrinosToHits, const HitsToMCTruth &trueHitsToNeutrinos, MCTruthToPFParticles &matchedNeutrinos, MCTruthToHits &matchedNeutrinoHits) const
Perform matching between true and reconstructed neutrino events.
static bool IsNeutrino(const art::Ptr< recob::PFParticle > particle)
Determine whether a particle has been reconstructed as a neutrino.
Planes which measure V.
Definition: geo_types.h:77
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...
double Px(const int i=0) const
Definition: MCParticle.h:234
Vector_t VertexDirection() const
Access to track direction at different points.
Definition: Track.h:135
std::map< int, art::Ptr< simb::MCParticle > > MCParticleMap
int PdgCode() const
Return the type of particle as a PDG ID.
Definition: PFParticle.h:83
geo::View_t View() const
View for the plane of the hit.
Definition: Hit.h:233
std::map< art::Ptr< simb::MCParticle >, art::Ptr< recob::PFParticle > > MCParticlesToPFParticles
bool isRealData() const
Definition: Event.h:83
std::string Process() const
Definition: MCParticle.h:219
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< simb::MCParticle >, art::Ptr< simb::MCTruth > > MCParticlesToMCTruth
void BuildTrueNeutrinoHitMaps(const MCTruthToMCParticles &truthToParticles, const MCParticlesToHits &trueParticlesToHits, MCTruthToHits &trueNeutrinosToHits, HitsToMCTruth &trueHitsToNeutrinos) const
Build mapping from true neutrinos to hits.
std::set< art::Ptr< recob::PFParticle > > PFParticleSet
geo::TPCGeo const & PositionToTPC(geo::Point_t const &point) const
Returns the TPC at specified location.
std::vector< art::Ptr< recob::Track > > TrackVector
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.
std::map< int, art::Ptr< recob::PFParticle > > PFParticleMap
Planes which measure U.
Definition: geo_types.h:76
static void BuildMCParticleHitMaps(const HitVector &hitVector, const SimChannelVector &simChannelVector, HitsToTrackIDEs &hitsToTrackIDEs)
Collect the links from reconstructed hits to their true energy deposits.
double GetLength(const art::Ptr< simb::MCParticle > trueParticle, const int startT, const int endT) const
Find the length of the true particle trajectory through the active region of the detector.
int m_nTrueWithoutRecoHits
True hits which don&#39;t belong to any reconstructed particle - "available".
Int_t max
Definition: plot.C:27
double Length(size_t p=0) const
Access to various track properties.
Definition: Track.h:170
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
void BuildRecoNeutrinoHitMaps(const PFParticleMap &recoParticleMap, const PFParticlesToHits &recoParticlesToHits, PFParticlesToHits &recoNeutrinosToHits, HitsToPFParticles &recoHitsToNeutrinos) const
Build mapping from reconstructed neutrinos to hits.
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:42
Provides recob::Track data product.
std::map< art::Ptr< recob::PFParticle >, T0Vector > PFParticlesToT0s
std::map< art::Ptr< recob::Hit >, art::Ptr< recob::SpacePoint > > HitsToSpacePoints
double P(const int i=0) const
Definition: MCParticle.h:238
T get(std::string const &key) const
Definition: ParameterSet.h:231
std::set< art::Ptr< simb::MCTruth > > MCTruthSet
Point_t const & Vertex() const
Access to track position at different points.
Definition: Track.h:127
bool m_printDebug
switch for print statements (TODO: use message service!)
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
Double_t R
PFParticleMonitoring(fhicl::ParameterSet const &pset)
Constructor.
std::vector< art::Ptr< anab::T0 > > T0Vector
const Double32_t * XYZ() const
Definition: SpacePoint.h:65
EDAnalyzer(Table< Config > const &config)
Definition: EDAnalyzer.h:100
Declaration of cluster object.
static void CollectTracks(const art::Event &evt, const std::string &label, TrackVector &trackVector, PFParticlesToTracks &particlesToTracks)
Collect the reconstructed PFParticles and associated Tracks from the ART event record.
static void CollectPFParticles(const art::Event &evt, const std::string &label, PFParticleVector &particleVector)
Collect the reconstructed PFParticles from the ART event record.
void GetStartAndEndPoints(const art::Ptr< simb::MCParticle > trueParticle, int &startT, int &endT) const
Find the start and end points of the true particle in the active region of detector.
std::vector< art::Ptr< recob::SpacePoint > > SpacePointVector
std::vector< art::Ptr< recob::Hit > > HitVector
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
static void SelectNeutrinoPFParticles(const PFParticleVector &inputParticles, PFParticleVector &outputParticles)
Select reconstructed neutrino particles from a list of all reconstructed particles.
double Vx(const int i=0) const
Definition: MCParticle.h:225
T * make(ARGS...args) const
std::map< art::Ptr< simb::MCParticle >, HitVector > MCParticlesToHits
Utility object to perform functions of association.
Encapsulate the construction of a single detector plane.
Int_t min
Definition: plot.C:26
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
double Pz(const int i=0) const
Definition: MCParticle.h:236
double Vz(const int i=0) const
Definition: MCParticle.h:227
HLT enums.
EventNumber_t event() const
Definition: EventID.h:117
Point_t const & End() const
Access to track position at different points.
Definition: Track.h:128
void reconfigure(fhicl::ParameterSet const &pset)
Planes which measure W (third view for Bo, MicroBooNE, etc).
Definition: geo_types.h:78
bool NeutrinoSet() const
Definition: MCTruth.h:75
TCEvent evt
Definition: DataStructs.cxx:5
Float_t e
Definition: plot.C:34
RunNumber_t run() const
Definition: Event.h:77
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.
Float_t X
Definition: plot.C:39
Event generator information.
Definition: MCNeutrino.h:18
static void CollectMCParticles(const art::Event &evt, const std::string &label, MCParticleVector &particleVector)
Collect a vector of MCParticle objects from the ART event record.
helper function for LArPandoraInterface producer module
std::set< art::Ptr< simb::MCParticle > > MCParticleSet
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
int m_nRecoWithoutTrueHits
Reconstructed hits which don&#39;t belong to any true particle - "missing".
std::map< art::Ptr< recob::Hit >, art::Ptr< simb::MCParticle > > HitsToMCParticles
EventID id() const
Definition: Event.h:56
double Vy(const int i=0) const
Definition: MCParticle.h:226
art framework interface to geometry description
static bool IsFinalState(const PFParticleMap &particleMap, const art::Ptr< recob::PFParticle > daughterParticle)
Determine whether a particle has been reconstructed as a final-state particle.
std::map< art::Ptr< recob::Hit >, art::Ptr< simb::MCTruth > > HitsToMCTruth
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
Encapsulate the construction of a single detector plane.
std::vector< art::Ptr< recob::Vertex > > VertexVector
static void BuildMCParticleMap(const MCParticleVector &particleVector, MCParticleMap &particleMap)
Build particle maps for true particles.