ShowerAnalysis_module.cc
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////
2 // Class: ShowerAnalysis
3 // Module type: analyser
4 // File: ShowerAnalysis_module.cc
5 // Author: Mike Wallbank (m.wallbank@sheffield.ac.uk), April 2016
6 //
7 // Analyser module to evaluate the shower reconstruction performance.
8 // Produces histograms and information within a tree for further
9 // analysis.
10 //////////////////////////////////////////////////////////////////////////
11 
12 // framework includes
16 #include "fhiclcpp/ParameterSet.h"
21 #include "art_root_io/TFileService.h"
22 #include "art_root_io/TFileDirectory.h"
24 #include "canvas/Persistency/Common/FindManyP.h"
25 
26 // LArSoft includes
42 
43 // ROOT
44 #include "TTree.h"
45 #include "TVector3.h"
46 #include "TH1D.h"
47 #include "TH2D.h"
48 #include "TProfile.h"
49 
50 // c++
51 #include <string>
52 
53 namespace showerAna {
54  class ShowerAnalysis;
55  class ShowerParticle;
56 }
57 
59 public:
60 
61  ShowerParticle(); // default constructor
62  ShowerParticle(int id); // standard constructor
63  ShowerParticle(const ShowerParticle& particle); // copy constructor
65 
66  // Setters
67  void SetEnergy(double energy);
68  void SetDepositedEnergy(std::map<int,double> depositedEnergy);
69  void SetDirection(TVector3 direction);
70  void SetStart(TVector3 start);
71  void SetEnd(TVector3 end);
72  void SetPDG(int pdg);
73 
77 
78  // Getters
79  int ID() const { return fID; }
80  int PDG() const { return fPDG; }
81 
82  TVector3 Start() const { return fStart; }
83  TVector3 End() const { return fEnd; }
84  TVector3 Direction() const { return fDirection; }
85  double Energy() const { return fEnergy; }
87  double DepositedEnergy(int plane) const { return fDepositedEnergy.at(plane); }
88 
89  TVector3 ShowerStart() const { return ShowerStart(fLargestShower); }
90  TVector3 ShowerStart(int shower) const { return fShowers.at(shower)->ShowerStart(); }
91  TVector3 ShowerDirection() const { return ShowerDirection(fLargestShower); }
92  TVector3 ShowerDirection(int shower) const { return fShowers.at(shower)->Direction(); }
93  double ShowerEnergy() const { return ShowerEnergy(fLargestShower); }
94  double ShowerEnergy(int shower) const { art::Ptr<recob::Shower> s = fShowers.at(shower); return s->Energy().at(s->best_plane()); }
95  double ShowerdEdx() const { return ShowerdEdx(fLargestShower); }
96  double ShowerdEdx(int shower) const { art::Ptr<recob::Shower> s = fShowers.at(shower); return s->dEdx().at(s->best_plane()); }
97 
98  int NumHits() const { return fHits.size(); }
99  int NumClusters() const { return fClusters.size(); }
100  int NumShowers() const { return fShowers.size(); }
101 
102  int LargestCluster() const { return fLargestCluster; }
103  bool LargestCluster(int cluster) const { return fLargestCluster == cluster; }
104  int LargestShower() const { return fLargestShower; }
105  bool LargestShower(int shower) const { return fLargestShower == shower; }
106 
107  double ClusterCompleteness(int cluster) const { return fClusterTrueHits.at(cluster).size() / (double)fHits.size(); }
108  double ClusterPurity(int cluster) const { return fClusterTrueHits.at(cluster).size() / (double)fClusterHits.at(cluster).size(); }
109  double ShowerCompleteness(int shower) const { return fShowerTrueHits.at(shower).size() / (double)fHits.size(); }
110  double ShowerPurity(int shower) const { return fShowerTrueHits.at(shower).size() / (double)fShowerHits.at(shower).size(); }
111 
112 private:
113 
114  int fID;
115  int fPDG;
116 
117  TVector3 fStart, fEnd, fDirection;
118  double fEnergy;
119  std::map<int,double> fDepositedEnergy;
120 
121  std::vector<art::Ptr<recob::Hit> > fHits;
122  std::vector<art::Ptr<recob::Cluster> > fClusters;
123  std::vector<std::vector<art::Ptr<recob::Hit> > > fClusterHits, fClusterTrueHits;
124  std::vector<art::Ptr<recob::Shower> > fShowers;
125  std::vector<std::vector<art::Ptr<recob::Hit> > > fShowerHits, fShowerTrueHits;
126 
128 
129 };
130 
132  fID = id;
133  fLargestCluster = 0;
134  fLargestShower = 0;
135 }
136 
138  fID = particle.ID();
139  fLargestCluster = 0;
140  fLargestShower = 0;
141 }
142 
144 }
145 
147  fEnergy = energy;
148 }
149 
150 void showerAna::ShowerParticle::SetDepositedEnergy(std::map<int,double> depositedEnergy) {
151  fDepositedEnergy = depositedEnergy;
152 }
153 
156 }
157 
159  fStart = start;
160 }
161 
163  fEnd = end;
164 }
165 
167  fPDG = pdg;
168 }
169 
171  fHits.push_back(hit);
172 }
173 
175  const std::vector<art::Ptr<recob::Hit> >& hits,
176  const std::vector<art::Ptr<recob::Hit> >& trueHits) {
177  fClusters.push_back(cluster);
178  fClusterHits.push_back(hits);
179  fClusterTrueHits.push_back(trueHits);
180  if (hits.size() > fClusterHits[fLargestCluster].size())
181  fLargestCluster = fClusters.size() - 1;
182 }
183 
185  const std::vector<art::Ptr<recob::Hit> >& hits,
186  const std::vector<art::Ptr<recob::Hit> >& trueHits) {
187  fShowers.push_back(shower);
188  fShowerHits.push_back(hits);
189  fShowerTrueHits.push_back(trueHits);
190  if (hits.size() > fShowerHits[fLargestShower].size())
191  fLargestShower = fShowers.size() - 1;
192 }
193 
195  public:
196 
197  ShowerAnalysis(const fhicl::ParameterSet& pset);
198  ~ShowerAnalysis();
199 
200  void analyze(const art::Event& evt);
201 
202  void MakeDataProducts();
203  void FillData(const std::map<int,std::shared_ptr<ShowerParticle> >& particles);
204  void FillPi0Data(const std::map<int,std::shared_ptr<ShowerParticle> >& particles, const std::vector<int>& pi0Decays);
205  int FindTrueParticle(detinfo::DetectorClocksData const& clockData,
206  const std::vector<art::Ptr<recob::Hit> >& hits);
207  int FindParticleID(detinfo::DetectorClocksData const& clockData,
208  const art::Ptr<recob::Hit>& hit);
209  std::vector<art::Ptr<recob::Hit> > FindTrueHits(detinfo::DetectorClocksData const& clockData,
210  const std::vector<art::Ptr<recob::Hit> >& hits, int trueParticle);
211 
212  private:
213 
214  std::string fShowerModuleLabel, fClusterModuleLabel, fHitsModuleLabel;
215 
216  double fElectrondEdx, fPhotondEdx, fElectrondEdxWidth, fPhotondEdxWidth;
217 
222 
223  TTree* fTree;
224 
225  // Showers
226  TH1D *hClusterCompleteness, *hLargestClusterCompleteness, *hClusterPurity, *hLargestClusterPurity;
227  TH2D *hClusterCompletenessEnergy, *hLargestClusterCompletenessEnergy, *hClusterCompletenessDirection, *hLargestClusterCompletenessDirection;
228  TH1D *hShowerCompleteness, *hLargestShowerCompleteness, *hShowerPurity, *hLargestShowerPurity;
229  TH2D *hShowerCompletenessEnergy, *hLargestShowerCompletenessEnergy, *hShowerCompletenessDirection, *hLargestShowerCompletenessDirection;
230  TH1D *hShowerEnergy, *hShowerDepositedEnergy, *hShowerDirection, *hShowerdEdx, *hShowerStart, *hShowerReconstructed, *hNumShowersReconstructed, *hNumShowersReconstructedNonZero;
231  TH2D *hShowerdEdxEnergy, *hNumShowersReconstructedEnergy;
232  TProfile *hShowerReconstructedEnergy, *hShowerdEdxEnergyProfile, *hNumShowersReconstructedEnergyProfile, *hShowerEnergyCompleteness, *hShowerStartEnergy;
233  TH1D *hElectronPull, *hPhotonPull;
234 
235  // Pi0
240 
241 };
242 
244  fShowerModuleLabel = pset.get<std::string>("ShowerModuleLabel");
245  fClusterModuleLabel = pset.get<std::string>("ClusterModuleLabel");
246  fHitsModuleLabel = pset.get<std::string>("HitsModuleLabel");
247  fElectrondEdx = pset.get<double>("ElectrondEdx",2.1);
248  fPhotondEdx = pset.get<double>("PhotondEdx",4.2);
249  fElectrondEdxWidth = pset.get<double>("ElectrondEdxWidth",0.410);
250  fPhotondEdxWidth = pset.get<double>("PhotondEdxWidth",1.217);
251  this->MakeDataProducts();
252 }
253 
255 }
256 
258 
259  // Get showers out of event
260  std::vector<art::Ptr<recob::Shower> > showers;
261  auto showerHandle = evt.getHandle<std::vector<recob::Shower> >(fShowerModuleLabel);
262  if (showerHandle)
263  art::fill_ptr_vector(showers, showerHandle);
264 
265  // Get clusters out of event
266  std::vector<art::Ptr<recob::Cluster> > clusters;
267  auto clusterHandle = evt.getHandle<std::vector<recob::Cluster> >(fClusterModuleLabel);
268  if (clusterHandle)
269  art::fill_ptr_vector(clusters, clusterHandle);
270 
271  // Get hits out of event
272  std::vector<art::Ptr<recob::Hit> > hits;
273  auto hitHandle = evt.getHandle<std::vector<recob::Hit> >(fHitsModuleLabel);
274  if (hitHandle)
275  art::fill_ptr_vector(hits, hitHandle);
276 
277  // Get space points out of event
278  std::vector<art::Ptr<recob::SpacePoint> > spacePoints;
279  auto spacePointHandle = evt.getHandle<std::vector<recob::SpacePoint> >(fShowerModuleLabel);
280  if (spacePointHandle)
281  art::fill_ptr_vector(spacePoints, spacePointHandle);
282 
283  // Get associations out of event
284  art::FindManyP<recob::Hit> fmhc(clusterHandle, evt, fClusterModuleLabel);
285  art::FindManyP<recob::Hit> fmhs(showerHandle, evt, fShowerModuleLabel);
286  art::FindManyP<recob::Hit> fmhsp(spacePointHandle, evt, fShowerModuleLabel);
287 
288  // Map all the true and reconstructed information for each particle
289  std::map<int,std::shared_ptr<ShowerParticle> > particles;
290 
291  // Keep an eye out for pi0s!
292  bool isPi0 = false;
293  std::vector<int> pi0Decays;
294 
295  // Fill true properties
296  const sim::ParticleList& trueParticles = pi_serv->ParticleList();
297  for (sim::ParticleList::const_iterator particleIt = trueParticles.begin(); particleIt != trueParticles.end(); ++particleIt) {
298 
299  const simb::MCParticle* trueParticle = particleIt->second;
300  int mother = trueParticle->Mother();
301  if (mother != 0 and trueParticles.at(mother)->PdgCode() == 111) {
302  isPi0 = true;
303  pi0Decays.push_back(particleIt->first);
304  }
305 
306  std::map<int,double> depositedEnergy;
307  const std::vector<art::Ptr< sim::SimChannel >>& simChannels = bt_serv->SimChannels();
308  for (std::vector<art::Ptr< sim::SimChannel >>::const_iterator channelIt = simChannels.begin(); channelIt != simChannels.end(); ++channelIt) {
309  int plane = geom->View((*channelIt)->Channel());
310  auto const & tdcidemap = (*channelIt)->TDCIDEMap();
311  for (auto const& tdcIt : tdcidemap) {
312  auto const& idevec = tdcIt.second;
313  for (auto const& ideIt : idevec) {
314  if (TMath::Abs(ideIt.trackID) != trueParticle->TrackId())
315  continue;
316  depositedEnergy[plane] += ideIt.energy / 1000;
317  }
318  }
319  }
320 
321  std::shared_ptr<ShowerParticle> particle = std::make_shared<ShowerParticle>(trueParticle->TrackId());
322  particle->SetEnergy(trueParticle->E());
323  particle->SetDepositedEnergy(depositedEnergy);
324  particle->SetDirection(trueParticle->Momentum().Vect().Unit());
325  particle->SetStart(trueParticle->Position().Vect());
326  particle->SetEnd(trueParticle->EndPosition().Vect());
327  particle->SetPDG(trueParticle->PdgCode());
328 
329  particles[particleIt->first] = std::move(particle);
330  }
331 
332  // Fill recon properties
333  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
334  for (std::vector<art::Ptr<recob::Hit> >::iterator hitIt = hits.begin(); hitIt != hits.end(); ++hitIt) {
335  int trueParticle = FindParticleID(clockData, *hitIt);
336  if (particles.count(trueParticle))
337  particles[trueParticle]->AddAssociatedHit(*hitIt);
338  }
339 
340  for (std::vector<art::Ptr<recob::Cluster> >::iterator clusterIt = clusters.begin(); clusterIt != clusters.end(); ++clusterIt) {
341  std::vector<art::Ptr<recob::Hit> > hits = fmhc.at(clusterIt->key());
342  int trueParticle = FindTrueParticle(clockData, hits);
343  std::vector<art::Ptr<recob::Hit> > trueHits = FindTrueHits(clockData, hits, trueParticle);
344  if (particles.count(trueParticle))
345  particles[trueParticle]->AddAssociatedCluster(*clusterIt, hits, trueHits);
346  }
347 
348  for (std::vector<art::Ptr<recob::Shower> >::iterator showerIt = showers.begin(); showerIt != showers.end(); ++showerIt) {
349  std::vector<art::Ptr<recob::Hit> > hits = fmhs.at(showerIt->key());
350  int trueParticle = FindTrueParticle(clockData, hits);
351  std::vector<art::Ptr<recob::Hit> > trueHits = FindTrueHits(clockData, hits, trueParticle);
352  if (particles.count(trueParticle))
353  particles[trueParticle]->AddAssociatedShower(*showerIt, hits, trueHits);
354  }
355 
356  // Fill output data products
357  this->FillData(particles);
358  if (isPi0 and pi0Decays.size() == 2)
359  this->FillPi0Data(particles, pi0Decays);
360 
361  return;
362 
363 }
364 
365 void showerAna::ShowerAnalysis::FillData(const std::map<int,std::shared_ptr<ShowerParticle> >& particles) {
366 
367  // Look at each particle
368  for (std::map<int,std::shared_ptr<ShowerParticle> >::const_iterator particleIt = particles.begin(); particleIt != particles.end(); ++particleIt) {
369 
370  std::shared_ptr<ShowerParticle> particle = particleIt->second;
371 
372  // No point making these plots for particles which don't shower!
373  if (TMath::Abs(particle->PDG()) != 11 and TMath::Abs(particle->PDG()) != 22)
374  continue;
375 
376  // Cluster plots
377  for (int cluster = 0; cluster < particle->NumClusters(); ++cluster) {
378  hClusterCompleteness ->Fill(particle->ClusterCompleteness(cluster));
379  hClusterPurity ->Fill(particle->ClusterPurity(cluster));
380  hClusterCompletenessEnergy ->Fill(particle->Energy(), particle->ClusterCompleteness(cluster));
381  hClusterCompletenessDirection ->Fill(particle->Direction().Angle(TVector3(0,1,0)), particle->ClusterCompleteness(cluster));
382  if (particle->LargestCluster(cluster)) {
383  hLargestClusterCompleteness ->Fill(particle->ClusterCompleteness(cluster));
384  hLargestClusterPurity ->Fill(particle->ClusterPurity(cluster));
385  hLargestClusterCompletenessEnergy ->Fill(particle->Energy(), particle->ClusterCompleteness(cluster));
386  hLargestClusterCompletenessDirection ->Fill(particle->Direction().Angle(TVector3(0,1,0)), particle->ClusterCompleteness(cluster));
387  }
388  }
389 
390  // Shower plots
391  for (int shower = 0; shower < particle->NumShowers(); ++shower) {
392  hShowerCompleteness ->Fill(particle->ShowerCompleteness(shower));
393  hShowerPurity ->Fill(particle->ShowerPurity(shower));
394  hShowerCompletenessEnergy ->Fill(particle->Energy(), particle->ShowerCompleteness(shower));
395  hShowerCompletenessDirection ->Fill(particle->Direction().Angle(TVector3(0,1,0)), particle->ShowerCompleteness(shower));
396  if (particle->LargestShower(shower)) {
397  hLargestShowerCompleteness ->Fill(particle->ShowerCompleteness(shower));
398  hLargestShowerPurity ->Fill(particle->ShowerPurity(shower));
399  hLargestShowerCompletenessEnergy ->Fill(particle->Energy(), particle->ShowerCompleteness(shower));
400  hLargestShowerCompletenessDirection ->Fill(particle->Direction().Angle(TVector3(0,1,0)), particle->ShowerCompleteness(shower));
401  hShowerEnergy ->Fill(particle->ShowerEnergy() / particle->Energy());
402  hShowerDepositedEnergy ->Fill(particle->ShowerEnergy() / particle->DepositedEnergy());
403  hShowerEnergyCompleteness ->Fill(particle->Energy(), particle->ShowerEnergy()/particle->DepositedEnergy());
404  hShowerDirection ->Fill(particle->Direction().Dot(particle->ShowerDirection()));
405  hShowerdEdx ->Fill(particle->ShowerdEdx());
406  if (particle->PDG() == 22) {
407  hShowerStart ->Fill((particle->End() - particle->ShowerStart()).Mag());
408  hShowerStartEnergy ->Fill(particle->Energy(), (particle->End() - particle->ShowerStart()).Mag());
409  }
410  else {
411  hShowerStart ->Fill((particle->Start() - particle->ShowerStart()).Mag());
412  hShowerStartEnergy ->Fill(particle->Energy(), (particle->Start() - particle->ShowerStart()).Mag());
413  }
414  }
415  }
416 
417  hShowerReconstructed->Fill(particle->NumShowers() != 0);
418  hNumShowersReconstructed->Fill(particle->NumShowers());
419  hShowerReconstructedEnergy->Fill(particle->Energy(), particle->NumShowers() != 0);
420  hNumShowersReconstructedEnergy->Fill(particle->Energy(), particle->NumShowers());
421  hNumShowersReconstructedEnergyProfile->Fill(particle->Energy(), particle->NumShowers());
422  if (particle->NumShowers()) {
423  hNumShowersReconstructedNonZero->Fill(particle->NumShowers());
424  hShowerdEdxEnergy->Fill(particle->Energy(), particle->ShowerdEdx());
425  hShowerdEdxEnergyProfile->Fill(particle->Energy(), particle->ShowerdEdx());
426  hElectronPull->Fill((particle->ShowerdEdx() - fElectrondEdx)/fElectrondEdxWidth);
427  hPhotonPull->Fill((particle->ShowerdEdx() - fPhotondEdx)/fPhotondEdxWidth);
428  }
429 
430  }
431 
432  return;
433 
434 }
435 
436 void showerAna::ShowerAnalysis::FillPi0Data(const std::map<int,std::shared_ptr<ShowerParticle> >& particles, const std::vector<int>& pi0Decays) {
437 
438  /// Fill data products related to pi0s
439  /// We only call this function if there are exactly two decay products, so we can assume the decay was pi0 -> gamma gamma
440 
441  std::shared_ptr<ShowerParticle> photon1 = particles.at(pi0Decays.at(0));
442  std::shared_ptr<ShowerParticle> photon2 = particles.at(pi0Decays.at(1));
443 
444  // Make sure there is at least one shower and it was fully reconstructed
445  if (photon1->NumShowers() == 0 or photon2->NumShowers() == 0 or
446  photon1->ShowerStart() == TVector3(0,0,0) or photon2->ShowerStart() == TVector3(0,0,0)) {
447  std::cout << "Event doesn't have enough info for pi0 mass determination" << std::endl;
448  return;
449  }
450 
451  double reconOpeningAngle = TMath::ASin(TMath::Sin(photon1->ShowerDirection().Angle(photon2->ShowerDirection())));
452  double trueOpeningAngle = photon1->Direction().Angle(photon2->Direction());
453 
454  // Reconstruct the pi0 mass
455  double massReconEnergyReconAngle = TMath::Sqrt(4 * photon1->ShowerEnergy() * photon2->ShowerEnergy() * TMath::Power(TMath::Sin(reconOpeningAngle/2),2));
456  double massReconEnergyTrueAngle = TMath::Sqrt(4 * photon1->ShowerEnergy() * photon2->ShowerEnergy() * TMath::Power(TMath::Sin(trueOpeningAngle/2),2));
457  double massTrueEnergyReconAngle = TMath::Sqrt(4 * photon1->Energy() * photon2->Energy() * TMath::Power(TMath::Sin(reconOpeningAngle/2),2));
458  double massTrueEnergyTrueAngle = TMath::Sqrt(4 * photon1->Energy() * photon2->Energy() * TMath::Power(TMath::Sin(trueOpeningAngle/2),2));
459 
460  hPi0MassPeakReconEnergyReconAngle->Fill(massReconEnergyReconAngle);
461  hPi0MassPeakReconEnergyTrueAngle->Fill(massReconEnergyTrueAngle);
462  hPi0MassPeakTrueEnergyReconAngle->Fill(massTrueEnergyReconAngle);
463  hPi0MassPeakTrueEnergyTrueAngle->Fill(massTrueEnergyTrueAngle);
464 
465  return;
466 
467 }
468 
470  const std::vector<art::Ptr<recob::Hit> >& showerHits) {
471 
472  /// Returns the true particle most likely associated with this shower
473 
474  // Make a map of the tracks which are associated with this shower and the charge each contributes
475  std::map<int,double> trackMap;
476  for (std::vector<art::Ptr<recob::Hit> >::const_iterator showerHitIt = showerHits.begin(); showerHitIt != showerHits.end(); ++showerHitIt) {
477  art::Ptr<recob::Hit> hit = *showerHitIt;
478  int trackID = FindParticleID(clockData, hit);
479  trackMap[trackID] += hit->Integral();
480  }
481 
482  // Pick the track with the highest charge as the 'true track'
483  double highestCharge = 0;
484  int showerTrack = 0;
485  for (std::map<int,double>::iterator trackIt = trackMap.begin(); trackIt != trackMap.end(); ++trackIt) {
486  if (trackIt->second > highestCharge) {
487  highestCharge = trackIt->second;
488  showerTrack = trackIt->first;
489  }
490  }
491 
492  return showerTrack;
493 
494 }
495 
497  const art::Ptr<recob::Hit>& hit) {
498 
499  /// Returns the true track ID associated with this hit (if more than one, returns the one with highest energy)
500 
501  double particleEnergy = 0;
502  int likelyTrackID = 0;
503  std::vector<sim::TrackIDE> trackIDs = bt_serv->HitToTrackIDEs(clockData, hit);
504  for (unsigned int idIt = 0; idIt < trackIDs.size(); ++idIt) {
505  if (trackIDs.at(idIt).energy > particleEnergy) {
506  particleEnergy = trackIDs.at(idIt).energy;
507  likelyTrackID = TMath::Abs(trackIDs.at(idIt).trackID);
508  }
509  }
510 
511  return likelyTrackID;
512 
513 }
514 
515 std::vector<art::Ptr<recob::Hit> > showerAna::ShowerAnalysis::FindTrueHits(detinfo::DetectorClocksData const& clockData,
516  const std::vector<art::Ptr<recob::Hit> >& hits, int trueParticle) {
517 
518  std::vector<art::Ptr<recob::Hit> > trueHits;
519  for (std::vector<art::Ptr<recob::Hit> >::const_iterator hitIt = hits.begin(); hitIt != hits.end(); ++hitIt)
520  if (FindParticleID(clockData, *hitIt) == trueParticle)
521  trueHits.push_back(*hitIt);
522 
523  return trueHits;
524 
525 }
526 
528 
529  fTree = tfs->make<TTree>("ShowerAnalysis","ShowerAnalysis");
530 
531  // Cluster
532  hClusterCompleteness = tfs->make<TH1D>("ClusterCompleteness","Completeness of all clusters;Completeness;",101,0,1.01);
533  hLargestClusterCompleteness = tfs->make<TH1D>("LargestClusterCompleteness","Completeness of largest cluster;Completeness;",101,0,1.01);
534  hClusterPurity = tfs->make<TH1D>("ClusterPurity","Purity of all clusters;Purity;",101,0,1.01);
535  hLargestClusterPurity = tfs->make<TH1D>("LargestClusterPurity","Purity of largest cluster;Purity;",101,0,1.01);
536  hClusterCompletenessEnergy = tfs->make<TH2D>("ClusterCompletenessEnergy","Completeness of all clusters vs Energy;Energy (GeV);Completeness;",100,0,10,101,0,1.01);
537  hLargestClusterCompletenessEnergy = tfs->make<TH2D>("LargestClusterCompletenessEnergy","Completeness of largest cluster vs Energy;Energy (GeV);Completeness;",100,0,10,101,0,1.01);
538  hClusterCompletenessDirection = tfs->make<TH2D>("ClusterCompletenessDirection","Completeness of all clusters vs Direction;Direction;Completeness;",100,0,5,101,0,1.01);
539  hLargestClusterCompletenessDirection = tfs->make<TH2D>("LargestClusterCompletenessDirection","Completeness of largest cluster vs Direction;Direction;Completeness;",100,0,5,101,0,1.01);
540 
541  // Shower
542  hShowerCompleteness = tfs->make<TH1D>("ShowerCompleteness","Completeness of all showers;Completeness;",101,0,1.01);
543  hLargestShowerCompleteness = tfs->make<TH1D>("LargestShowerCompleteness","Completeness of largest shower;Completeness;",101,0,1.01);
544  hShowerPurity = tfs->make<TH1D>("ShowerPurity","Purity of all showers;Purity;",101,0,1.01);
545  hLargestShowerPurity = tfs->make<TH1D>("LargestShowerPurity","Purity of largest shower;Purity;",101,0,1.01);
546  hShowerCompletenessEnergy = tfs->make<TH2D>("ShowerCompletenessEnergy","Completeness of all showers vs Energy;Energy (GeV);Completeness;",100,0,10,101,0,1.01);
547  hLargestShowerCompletenessEnergy = tfs->make<TH2D>("LargestShowerCompletenessEnergy","Completeness of largest shower vs Energy;Energy (GeV);Completeness;",100,0,10,101,0,1.01);
548  hShowerCompletenessDirection = tfs->make<TH2D>("ShowerCompletenessDirection","Completeness of all showers vs Direction;Direction;Completeness;",100,0,5,101,0,1.01);
549  hLargestShowerCompletenessDirection = tfs->make<TH2D>("LargestShowerCompletenessDirection","Completeness of largest shower vs Direction;Direction;Completeness;",100,0,5,101,0,1.01);
550  hShowerEnergy = tfs->make<TH1D>("ShowerEnergy","Shower energy;Recon Energy/True Energy;",120,0,1.2);
551  hShowerDepositedEnergy = tfs->make<TH1D>("ShowerDepositedEnergy","Shower deposited energy;Recon Energy/True (Deposited) Energy;",120,0,1.2);
552  hShowerDirection = tfs->make<TH1D>("ShowerDirection","Shower direction;True Direction.(Recon Direction);",202,-1.01,1.01);
553  hShowerdEdx = tfs->make<TH1D>("ShowerdEdx","dEdx of Shower;dE/dx (MeV/cm)",50,0,10);
554  hShowerStart = tfs->make<TH1D>("ShowerStart","Distance from reconstructed shower start to true shower start;True Start - Recon Start (cm);",100,0,20);
555  hShowerReconstructed = tfs->make<TH1D>("ShowerReconstructed","% of showering particles with reconstructed shower",101,0,1.01);
556  hShowerEnergyCompleteness = tfs->make<TProfile>("ShowerEnergyCompleteness","Shower energy completeness vs true deposited energy;True (Deposited) Energy (GeV);Energy Completeness;",100,0,5);
557  hShowerStartEnergy = tfs->make<TProfile>("ShowerStartEnergy","Shower start distance vs true deposited energy;True (Deposited) Energy (GeV);True Start - Recon Start (cm);",100,0,5);
558  hNumShowersReconstructed = tfs->make<TH1D>("NumShowersReconstructed","Number of showers reconstructed for each showering particle;Number of Showers",10,0,10);
559  hNumShowersReconstructedNonZero = tfs->make<TH1D>("NumShowersReconstructedNonZero","Number of showers reconstructed for each showering particle;Number of Showers",9,1,10);
560  for (int n_showers = 0; n_showers < 9; ++n_showers) {
561  hNumShowersReconstructed->GetXaxis()->SetBinLabel(n_showers+1,std::to_string(n_showers).c_str());
562  hNumShowersReconstructedNonZero->GetXaxis()->SetBinLabel(n_showers+1,std::to_string(n_showers+1).c_str());
563  }
564  hNumShowersReconstructed->GetXaxis()->SetBinLabel(10,"9 or more");
565  hNumShowersReconstructedNonZero->GetXaxis()->SetBinLabel(9,"9 or more");
566  hShowerReconstructedEnergy = tfs->make<TProfile>("ShowerReconstructedEnergyProfile","% of showering particles with reconstructed shower vs true energy;True Energy (GeV);Fraction of particles with reconstructed shower;",100,0,5);
567  hNumShowersReconstructedEnergy = tfs->make<TH2D>("NumShowersReconstructedEnergy","Number of showers reconstructed per showering particle vs true energy;True Energy (GeV);Average Number of Showers;",100,0,5,10,0,10);
568  hNumShowersReconstructedEnergyProfile = tfs->make<TProfile>("NumShowersReconstructedEnergyProfile",";True Energy (GeV);Number of Showers;",100,0,5);
569  hShowerdEdxEnergy = tfs->make<TH2D>("ShowerdEdxEnergy","Shower dE/dx vs true energy;True Energy (GeV);dE/dx (MeV/cm);",100,0,5,50,0,10);
570  hShowerdEdxEnergyProfile = tfs->make<TProfile>("ShowerdEdxEnergyProfile",";True Energy (GeV);dE/dx (MeV/cm);",100,0,5);
571  hElectronPull = tfs->make<TH1D>("ElectronPull","Electron pull;Electron pull;",100,-10,10);
572  hPhotonPull = tfs->make<TH1D>("PhotonPull","Photon pull;Photon pull;",100,-10,10);
573 
574  // pi0
575  hPi0MassPeakReconEnergyReconAngle = tfs->make<TH1D>("Pi0MassPeakReconEnergyReconAngle",";Invariant Mass (GeV);",40,0,0.5);
576  hPi0MassPeakTrueEnergyReconAngle = tfs->make<TH1D>("Pi0MassPeakTrueEnergyReconAngle",";Invariant Mass (GeV);",40,0,0.5);
577  hPi0MassPeakReconEnergyTrueAngle = tfs->make<TH1D>("Pi0MassPeakReconEnergyTrueAngle",";Invariant Mass (GeV);",40,0,0.5);
578  hPi0MassPeakTrueEnergyTrueAngle = tfs->make<TH1D>("Pi0MassPeakTrueEnergyTrueAngle",";Invariant Mass (GeV);",40,0,0.5);
579 
580 }
581 
def analyze(root, level, gtrees, gbranches, doprint)
Definition: rootstat.py:69
double E(const int i=0) const
Definition: MCParticle.h:233
int best_plane() const
Definition: Shower.h:200
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
intermediate_table::iterator iterator
const TLorentzVector & Position(const int i=0) const
Definition: MCParticle.h:219
art::ServiceHandle< cheat::ParticleInventoryService > pi_serv
int PdgCode() const
Definition: MCParticle.h:212
double ClusterCompleteness(int cluster) const
void cluster(In first, In last, Out result, Pred *pred)
Definition: NNClusters.h:41
const TLorentzVector & EndPosition() const
Definition: MCParticle.h:225
std::vector< sim::TrackIDE > HitToTrackIDEs(detinfo::DetectorClocksData const &clockData, recob::Hit const &hit) const
Handle< PROD > getHandle(SelectorBase const &) const
Definition: DataViewImpl.h:382
std::string string
Definition: nybbler.cc:12
int Mother() const
Definition: MCParticle.h:213
const std::vector< double > & Energy() const
Definition: Shower.h:195
struct vector vector
int FindParticleID(detinfo::DetectorClocksData const &clockData, const art::Ptr< recob::Hit > &hit)
double ShowerEnergy(int shower) const
std::vector< art::Ptr< recob::Cluster > > fClusters
void FillData(const std::map< int, std::shared_ptr< ShowerParticle > > &particles)
int FindTrueParticle(detinfo::DetectorClocksData const &clockData, const std::vector< art::Ptr< recob::Hit > > &hits)
void SetDirection(TVector3 direction)
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
Definition: Hit.h:224
intermediate_table::const_iterator const_iterator
art::ServiceHandle< art::TFileService > tfs
bool LargestCluster(int cluster) const
Cluster finding and building.
Particle class.
art::ServiceHandle< cheat::BackTrackerService > bt_serv
art framework interface to geometry description
int TrackId() const
Definition: MCParticle.h:210
bool LargestShower(int shower) const
const std::vector< double > & dEdx() const
Definition: Shower.h:203
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
double ShowerPurity(int shower) const
def move(depos, offset)
Definition: depos.py:107
std::vector< std::vector< art::Ptr< recob::Hit > > > fClusterHits
void AddAssociatedCluster(const art::Ptr< recob::Cluster > &cluster, const std::vector< art::Ptr< recob::Hit > > &hits, const std::vector< art::Ptr< recob::Hit > > &trueHits)
T get(std::string const &key) const
Definition: ParameterSet.h:271
std::vector< std::vector< art::Ptr< recob::Hit > > > fShowerHits
ShowerAnalysis(const fhicl::ParameterSet &pset)
TVector3 ShowerDirection(int shower) const
std::vector< std::vector< art::Ptr< recob::Hit > > > fClusterTrueHits
art::ServiceHandle< geo::Geometry > geom
TVector3 ShowerStart(int shower) const
double DepositedEnergy(int plane) const
std::vector< art::Ptr< recob::Shower > > fShowers
View_t View(geo::PlaneID const &pid) const
Returns the view (wire orientation) on the channels of specified TPC plane.
void SetDepositedEnergy(std::map< int, double > depositedEnergy)
Detector simulation of raw signals on wires.
const sim::ParticleList & ParticleList() const
std::vector< art::Ptr< recob::Hit > > fHits
Encapsulate the geometry of a wire.
std::vector< art::Ptr< recob::Hit > > FindTrueHits(detinfo::DetectorClocksData const &clockData, const std::vector< art::Ptr< recob::Hit > > &hits, int trueParticle)
Declaration of signal hit object.
void AddAssociatedHit(const art::Ptr< recob::Hit > &hit)
Encapsulate the construction of a single detector plane.
Contains all timing reference information for the detector.
const TLorentzVector & Momentum(const int i=0) const
Definition: MCParticle.h:220
Provides recob::Track data product.
void FillPi0Data(const std::map< int, std::shared_ptr< ShowerParticle > > &particles, const std::vector< int > &pi0Decays)
const std::vector< art::Ptr< sim::SimChannel > > & SimChannels() const
double ShowerCompleteness(int shower) const
double ClusterPurity(int cluster) const
TCEvent evt
Definition: DataStructs.cxx:7
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
Definition: Ptr.h:297
std::vector< std::vector< art::Ptr< recob::Hit > > > fShowerTrueHits
double ShowerdEdx(int shower) const
void analyze(const art::Event &evt)
std::map< int, double > fDepositedEnergy
std::string to_string(ModuleType const mt)
Definition: ModuleType.h:34
static QCString * s
Definition: config.cpp:1042
QTextStream & endl(QTextStream &s)
void AddAssociatedShower(const art::Ptr< recob::Shower > &shower, const std::vector< art::Ptr< recob::Hit > > &hits, const std::vector< art::Ptr< recob::Hit > > &trueHits)