RegCNNAna_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////////////////////
2 // Class: RegCNNAna
3 // Module Type: analyzer
4 // File: RegCNNAna_module.cc for analyzing CNN and Standard Reco. results
5 // Author: Ilsoo Seong - iseong@uci.edu
6 // Wenjie Wu - wenjieww@uci.edu
7 ////////////////////////////////////////////////////////////////////////////////////////////////
8 
9 #ifndef regcnnana_module
10 #define regcnnana_module
11 
12 //STL
13 #include <limits>
14 #include <string>
15 #include <vector>
16 #include <algorithm>
17 //ROOT
18 #include "TTree.h"
19 #include "TBranch.h"
20 #include "TMath.h"
21 //ART
26 #include "fhiclcpp/ParameterSet.h"
28 #include "art_root_io/TFileService.h"
29 #include "art_root_io/TFileDirectory.h"
31 //LArSoft
44 //DUNE
52 
53 const int kMax = 1000;
54 
55 namespace myana {
56  class RegCNNAna;
57 }
58 
60 {
61  public:
62 
63  explicit RegCNNAna(fhicl::ParameterSet const& pset);
64  virtual ~RegCNNAna();
65  void beginJob() override;
66  void endJob() override;
67  void beginSubRun(const art::SubRun& sr) override;
68  void endSubRun(const art::SubRun& sr) override;
69 
70  void analyze(art::Event const& evt) override;
71  void reconfigure(fhicl::ParameterSet const& p);
72  void reset();
73 
74  private:
75 
78  detinfo::DetectorPropertiesData const& detProp,
79  const art::Event& event);
80 
81  /**
82  * @brief Converts deposited charge into energy by converting to number of electrons and correcting for average recombination
83  *
84  * @param charge the deposited charge
85  *
86  * @return the reconstructed deposited energy
87  */
88  double CalculateEnergyFromCharge(const double charge);
89  std::vector<std::pair<const simb::MCParticle*, double> > get_sortedMCParticle(
90  std::unordered_map<const simb::MCParticle*, double> mcEMap);
91 
92  TTree* fTree;
93  int ievt;
96  float regcnn_vertex[3];
97  float regcnn_dir[3];
100 
101  // MC truth
102  int InDet;
103  int FidCut;
105  int nhits;
110  double nueng_truth[kMax];
116  // number of final state particles
117  int nPizero[kMax];
118  int nPion[kMax];
120  int nProton[kMax];
121 
122  double ErecoNu;
123  double RecoLepEnNu;
124  double RecoHadEnNu;
127 
138 
149 
150  // uncorrected hadronic energy
154  // calo. energy from shower
157 
158  calo::CalorimetryAlg fCalorimetryAlg; ///< the calorimetry algorithm
175  double fRecombFactor; ///< the average reccombination factor
176 
179 
180 };
181 
183  EDAnalyzer (pset),
184  fCalorimetryAlg (pset.get<fhicl::ParameterSet>("CalorimetryAlg"))
185 {
186  this->reconfigure(pset);
187 }
188 
190 {
191 }
192 
194 {
195  fMCGenModuleLabel = pset.get<std::string>("MCGenModuleLabel");
196  fRegCNNModuleLabel = pset.get<std::string>("RegCNNModuleLabel");
197  fRegCNNResultLabel = pset.get<std::string>("RegCNNResultLabel");
198  fRegCNNProngModuleLabel = pset.get<std::string>("RegCNNProngModuleLabel");
199  fRegCNNProngResultLabel = pset.get<std::string>("RegCNNProngResultLabel");
200  fRegCNNDirModuleLabel = pset.get<std::string>("RegCNNDirModuleLabel");
201  fRegCNNDirResultLabel = pset.get<std::string>("RegCNNDirResultLabel");
202  fHitsModuleLabel = pset.get<std::string>("HitsModuleLabel");
203  fEnergyRecoNuLabel = pset.get<std::string>("EnergyRecoNuLabel");
204  fTrackToHitLabel = pset.get<std::string>("TrackToHitLabel");
205  fShowerToHitLabel = pset.get<std::string>("ShowerToHitLabel");
206  fParticleLabel = pset.get<std::string>("ParticleLabel");
207  fTrackLabel = pset.get<std::string>("TrackLabel");
208  fTrackLabelDir = pset.get<std::string>("TrackLabelDir");
209  fShowerLabel = pset.get<std::string>("ShowerLabel");
210  fShowerLabelDir = pset.get<std::string>("ShowerLabelDir");
211  fRecombFactor = pset.get<double>("RecombFactor");
212 }
213 
216 
217  fTree = tfs->make<TTree>("anatree", "anatree");
218  fTree->Branch("ievent", &ievt, "ievent/I");
219  fTree->Branch("InDet", &InDet, "InDet/I");
220  fTree->Branch("FidCut", &FidCut, "FidCut/I");
221  fTree->Branch("MuTrackCont", &mutrk_contain, "MuTrackCont/I");
222  fTree->Branch("CNNEnergy", &regcnn_energy, "CNNEnergy/F");
223  fTree->Branch("CNNLepEnergy", &regcnn_prong_energy, "CNNLepEnergy/F");
224  fTree->Branch("CNNVertex", regcnn_vertex, "CNNVertex[3]/F");
225  fTree->Branch("CNNDir", regcnn_dir, "CNNDir[3]/F");
226  fTree->Branch("CNNDirDiff", &regcnn_dir_diff, "CNNDirDiff/F");
227  fTree->Branch("CNNNueDirDiff", &regcnn_nue_dir_diff, "CNNNueDirDiff/F");
228 
229  // MC truth
230  fTree->Branch("NuTruthN", &nu_truth_N, "NuTruthN/I");
231  fTree->Branch("NuEngTruth", nueng_truth, "NuEngTruth[NuTruthN]/D");
232  fTree->Branch("NuPDGTruth", nupdg_truth, "NuPDGTruth[NuTruthN]/I");
233  fTree->Branch("NuModeTruth", numode_truth, "NuModeTruth[NuTruthN]/I");
234  fTree->Branch("NuCCNCTruth", nuccnc_truth, "NuCCNCTruth[NuTruthN]/I");
235  fTree->Branch("NuVtxXTruth", nuvtxx_truth, "NuVtxXTruth[NuTruthN]/D");
236  fTree->Branch("NuVtxYTruth", nuvtxy_truth, "NuVtxYTruth[NuTruthN]/D");
237  fTree->Branch("NuVtxZTruth", nuvtxz_truth, "NuVtxZTruth[NuTruthN]/D");
238  // lepton truth
239  fTree->Branch("LepPDGTruth", lepPDG_truth, "LepPDGTruth[NuTruthN]/I");
240  fTree->Branch("LepEngTruth", lepEng_truth, "LepEngTruth[NuTruthN]/D");
241  fTree->Branch("nProtonTruth", nProton, "nProtonTruth[NuTruthN]/I");
242  fTree->Branch("nPionTruth", nPion, "nPionTruth[NuTruthN]/I");
243  fTree->Branch("nPizeroTruth", nPizero, "nPizeroTruth[NuTruthN]/I");
244  fTree->Branch("nNeutronTruth", nNeutron, "nNeutronTruth[NuTruthN]/I");
245 
246  // Reco. from DUNE, energy
247  fTree->Branch("NHits", &nhits, "NHits/I");
248  fTree->Branch("ErecoNu", &ErecoNu, "ErecoNu/D");
249  fTree->Branch("RecoLepEnNu", &RecoLepEnNu, "RecoLepEnNu/D");
250  fTree->Branch("RecoHadEnNu", &RecoHadEnNu, "RecoHadEnNu/D");
251  fTree->Branch("RecoMethodNu", &RecoMethodNu, "RecoMethodNu/I");
252  fTree->Branch("RecoTrackMomMethod", &RecoTrackMomMethod, "RecoTrackMomMethod/I");
253  fTree->Branch("RecoMuTrackLength", &RecoMuTrackLength, "RecoMuTrackLength/D");
254  fTree->Branch("UncorrectedHadEn", &fUncorrectedHadEn, "UncorrectedHadEn/D");
255  fTree->Branch("UncorrectedMuMomMCS", &fUncorrectedMuMomMCS, "UncorrectedMuMomMCS/D");
256  fTree->Branch("UncorrectedElectronEnergy", &fUncorrectedElectronEnergy, "UncorrectedElectronEnergy/D");
257  fTree->Branch("UncorrectedHadEnFromShw", &fUncorrectedHadEnFromShw, "UncorrectedHadEnFromShw/D");
258 
259  // direction
260  fTree->Branch("n_track_pad", &n_track_pad, "n_track_pad/I");
261  fTree->Branch("track_id", track_id, "track_id[n_track_pad]/I");
262  fTree->Branch("all_track_true_pdg", all_track_true_pdg, "all_track_true_pdg[n_track_pad]/I");
263  fTree->Branch("all_track_true_pdg_mom", all_track_true_pdg_mom, "all_track_true_pdg_mom[n_track_pad]/I");
264  fTree->Branch("all_track_px", all_track_px, "all_track_px[n_track_pad]/D");
265  fTree->Branch("all_track_py", all_track_py, "all_track_py[n_track_pad]/D");
266  fTree->Branch("all_track_pz", all_track_pz, "all_track_pz[n_track_pad]/D");
267  fTree->Branch("all_track_true_px", all_track_true_px, "all_track_true_px[n_track_pad]/D");
268  fTree->Branch("all_track_true_py", all_track_true_py, "all_track_true_py[n_track_pad]/D");
269  fTree->Branch("all_track_true_pz", all_track_true_pz, "all_track_true_pz[n_track_pad]/D");
270 
271  fTree->Branch("n_showers", &n_showers, "n_showers/I");
272  fTree->Branch("shower_id", shower_id, "shower_id[n_showers]/I");
273  fTree->Branch("all_shower_true_pdg", all_shower_true_pdg, "all_shower_true_pdg[n_showers]/I");
274  fTree->Branch("all_shower_true_pdg_mom", all_shower_true_pdg_mom, "all_shower_true_pdg_mom[n_showers]/I");
275  fTree->Branch("all_shower_px", all_shower_px, "all_shower_px[n_showers]/D");
276  fTree->Branch("all_shower_py", all_shower_py, "all_shower_py[n_showers]/D");
277  fTree->Branch("all_shower_pz", all_shower_pz, "all_shower_pz[n_showers]/D");
278  fTree->Branch("all_shower_true_px", all_shower_true_px, "all_shower_true_px[n_showers]/D");
279  fTree->Branch("all_shower_true_py", all_shower_true_py, "all_shower_true_py[n_showers]/D");
280  fTree->Branch("all_shower_true_pz", all_shower_true_pz, "all_shower_true_pz[n_showers]/D");
281 }
282 
284 }
285 
287 {
288  this->reset();
289  ievt = evt.id().event();
290  bool isMC = !evt.isRealData();
291 
292  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService>()->DataFor(evt);
293  auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService>()->DataFor(evt, clockData);
294  // Get the highestChargeShower of current event and then the associated hits of that shower
295  // Get lepton charge from shower hits and event charge from event hits
296  // Get hadronic charge by the subtraction of lepton charge from event charge
297  // Get hadronic energy from hadronic charge
298  art::Ptr<recob::Shower> highestChargeShower(this->GetHighestChargeShower(clockData, detProp, evt));
299  if (!highestChargeShower.isAvailable() || highestChargeShower.isNull()) {
300  mf::LogWarning("RegCNNAna")<<" Cannot access the electron shower which is needed for this energy reconstruction method.\n"
301  <<"Set default value"<<std::endl;
302  } else {
303  const std::vector<art::Ptr<recob::Hit> > electronHits(dune_ana::DUNEAnaHitUtils::GetHitsOnPlane(dune_ana::DUNEAnaShowerUtils::GetHits(highestChargeShower, evt, fShowerToHitLabel), 2));
304  const double electronObservedCharge(dune_ana::DUNEAnaHitUtils::LifetimeCorrectedTotalHitCharge(clockData, detProp, electronHits));
305  fUncorrectedElectronEnergy = this->CalculateEnergyFromCharge(electronObservedCharge);
306  const std::vector<art::Ptr<recob::Hit> > eventHits(dune_ana::DUNEAnaHitUtils::GetHitsOnPlane(dune_ana::DUNEAnaEventUtils::GetHits(evt, fHitsModuleLabel), 2));
307  const double eventObservedCharge(dune_ana::DUNEAnaHitUtils::LifetimeCorrectedTotalHitCharge(clockData, detProp, eventHits));
308  const double hadronicObservedCharge(eventObservedCharge-electronObservedCharge);
309  fUncorrectedHadEnFromShw = this->CalculateEnergyFromCharge(hadronicObservedCharge);
310  }
311 
312  // Get the longest track of current event and then the associated hits of that track
313  // Get lepton charge from track hits and event charge from event hits
314  // Get hadronic charge by the subtraction of lepton charge from event charge
315  // Get hadronic energy from hadronic charge
316  // Compare hadronic energy to true energy, get calibrated parameters: grad and interception
317  art::Ptr<recob::Track> longestTrack(this->GetLongestTrack(evt));
318  if (!longestTrack.isAvailable() || longestTrack.isNull()) {
319  mf::LogWarning("RegCNNAna")<<" Cannot access the muon track which is needed for this energy reconstruction method.\n"
320  <<"Set default value"<<std::endl;
321  } else {
322  const std::vector<art::Ptr<recob::Hit> > muonHits(dune_ana::DUNEAnaHitUtils::GetHitsOnPlane(dune_ana::DUNEAnaTrackUtils::GetHits(longestTrack, evt, fTrackToHitLabel), 2));
323  const double leptonObservedCharge(dune_ana::DUNEAnaHitUtils::LifetimeCorrectedTotalHitCharge(clockData, detProp, muonHits));
324  const std::vector<art::Ptr<recob::Hit> > eventHits(dune_ana::DUNEAnaHitUtils::GetHitsOnPlane(dune_ana::DUNEAnaEventUtils::GetHits(evt, fHitsModuleLabel), 2));
325  const double eventObservedCharge(dune_ana::DUNEAnaHitUtils::LifetimeCorrectedTotalHitCharge(clockData, detProp, eventHits));
326  const double hadronicObservedCharge(eventObservedCharge-leptonObservedCharge);
327  fUncorrectedHadEn = this->CalculateEnergyFromCharge(hadronicObservedCharge);
328  RecoMuTrackLength = longestTrack->Length();
329  trkf::TrackMomentumCalculator TrackMomCalc;
330  fUncorrectedMuMomMCS = TrackMomCalc.GetMomentumMultiScatterChi2(longestTrack);
331  std::cout<<"track length :"<<RecoMuTrackLength<<", uncorrectedMuMomMCS :"<<fUncorrectedMuMomMCS<<std::endl;
332  }
333 
334  // * MC truth information
335  std::vector<art::Ptr<simb::MCTruth> > mclist;
336  if (isMC){
337  auto mctruthListHandle = evt.getHandle< std::vector<simb::MCTruth> >(fMCGenModuleLabel);
338  if (mctruthListHandle)
339  art::fill_ptr_vector(mclist, mctruthListHandle);
340  }
341 
342  // Get the hits out of the event record
343  std::vector<art::Ptr<recob::Hit> > hits;
344  auto hitHandle = evt.getHandle<std::vector<recob::Hit> >(fHitsModuleLabel);
345  if (hitHandle)
346  art::fill_ptr_vector(hits, hitHandle);
347 
348  const sim::ParticleList& trueParticles = particleinventory->ParticleList();
349 
350  // Get the pandoratrack out of the event record
351  std::vector<art::Ptr<recob::Track> > trackDir;
352  auto trackHandleDir = evt.getHandle<std::vector<recob::Track> >(fTrackLabelDir);
353  if (trackHandleDir)
354  art::fill_ptr_vector(trackDir, trackHandleDir);
355  art::FindManyP<recob::Hit> fmtrkDir(trackHandleDir, evt, fTrackLabelDir);
356 
357  if (trackHandleDir.isValid()) {
358  n_track_pad = trackDir.size();
359  for (int itrack= 0; itrack< n_track_pad; ++itrack) {
360  art::Ptr<recob::Track> ptrack = trackDir.at(itrack);
361  track_id[itrack] = ptrack->ID();
362  all_track_px[itrack] = ptrack->VertexDirection().X();
363  all_track_py[itrack] = ptrack->VertexDirection().Y();
364  all_track_pz[itrack] = ptrack->VertexDirection().Z();
365 
366  if (fmtrkDir.isValid()) {
367  std::vector<art::Ptr<recob::Hit> > vhit = fmtrkDir.at(itrack);
368  std::unordered_map<const simb::MCParticle*, double> mcEMap;
369  for (size_t ihit= 0; ihit< vhit.size(); ++ihit) {
370  std::vector<sim::TrackIDE> trackIDs = backtracker->HitToTrackIDEs(clockData, vhit[ihit]);
371  for (size_t e= 0; e< trackIDs.size(); ++e) {
372  mcEMap[particleinventory->TrackIdToParticle_P(trackIDs[e].trackID)] += trackIDs[e].energy;
373  }
374  }
375  std::vector<std::pair<const simb::MCParticle*, double> > trkTrue = get_sortedMCParticle(mcEMap);
376  if (trkTrue.size()> 0) {
377  all_track_true_pdg[itrack] = trkTrue[0].first->PdgCode();
378  all_track_true_pdg_mom[itrack] = trkTrue[0].first->Mother()==0 ? -1 : trueParticles[trkTrue[0].first->Mother()]->PdgCode();
379  TVector3 v3_true(trkTrue[0].first->Momentum().Vect());
380  all_track_true_px[itrack] = v3_true.X();
381  all_track_true_py[itrack] = v3_true.Y();
382  all_track_true_pz[itrack] = v3_true.Z();
383  }
384  } // end of fmtrkDir
385  } // end of n_track_pad
386  } // end of trackHandleDir
387 
388  // Get the emshower out of the event record
389  std::vector<art::Ptr<recob::Shower> > showersDir;
390  auto showerHandleDir = evt.getHandle<std::vector<recob::Shower> >(fShowerLabelDir);
391  if (showerHandleDir)
392  art::fill_ptr_vector(showersDir, showerHandleDir);
393  art::FindManyP<recob::Hit> fmshDir(showerHandleDir, evt, fShowerLabelDir);
394 
395  if (showerHandleDir.isValid()) {
396  n_showers = showersDir.size();
397  for (int ishower= 0; ishower< n_showers; ++ishower) {
398  art::Ptr<recob::Shower> emshower = showersDir.at(ishower);
399  shower_id[ishower] = emshower->ID();
400  all_shower_px[ishower] = emshower->Direction().X();
401  all_shower_py[ishower] = emshower->Direction().Y();
402  all_shower_pz[ishower] = emshower->Direction().Z();
403 
404  if (fmshDir.isValid()) {
405  std::vector<art::Ptr<recob::Hit> > vhit = fmshDir.at(ishower);
406  std::unordered_map<const simb::MCParticle*, double> mcEMap;
407  for (size_t ihit= 0; ihit< vhit.size(); ++ihit) {
408  std::vector<sim::TrackIDE> trackIDs = backtracker->HitToTrackIDEs(clockData, vhit[ihit]);
409  for (size_t e= 0; e< trackIDs.size(); ++e) {
410  mcEMap[particleinventory->TrackIdToParticle_P(trackIDs[e].trackID)] += trackIDs[e].energy;
411  }
412  }
413  std::vector<std::pair<const simb::MCParticle*, double> > shwTrue = get_sortedMCParticle(mcEMap);
414  if (shwTrue.size()> 0) {
415  all_shower_true_pdg[ishower] = shwTrue[0].first->PdgCode();
416  all_shower_true_pdg_mom[ishower] = shwTrue[0].first->Mother()==0 ? -1 : trueParticles[shwTrue[0].first->Mother()]->PdgCode();
417  TVector3 v3_true(shwTrue[0].first->Momentum().Vect());
418  all_shower_true_px[ishower] = v3_true.X();
419  all_shower_true_py[ishower] = v3_true.Y();
420  all_shower_true_pz[ishower] = v3_true.Z();
421  }
422  } // end of fmshDir
423  } // end of n_showers
424  } // end of showerHandleDir
425 
426 
427  // Get DUNE energy Reco
428  auto engrecoHandle = evt.getHandle<dune::EnergyRecoOutput>(fEnergyRecoNuLabel);
429 
430  // Get RegCNN Results
431 
432  // neutrino energy
434  auto cnnresultListHandle = evt.getHandle<std::vector<cnn::RegCNNResult>>(itag1);
435 
436  // lepton energy
438  auto RegCnnProngResultListHandle = evt.getHandle<std::vector<cnn::RegCNNResult>>(itag2);
439 
440  // lepton direction
442  auto RegCnnDirResultListHandle = evt.getHandle<std::vector<cnn::RegCNNResult> >(itag3);
443 
444  //std::vector<art::Ptr<cnn::Result> > cnnlist;
445  // auto cnnresultListHandle2 = evt.getHandle<std::vector<cnn::RegCNNResult>>(fRegCNNModuleLabel);
446  //if (cnnresultListHandle2)
447  // art::fill_ptr_vector(cnnlist, cnnresultListHandle2);
448 
449  // Get Truth information
450  if (mclist.size()>0) {
451  int neutrino_i = 0;
452  for(size_t iList = 0; (iList < mclist.size()) && (neutrino_i < kMax) ; ++iList) {
453  if (mclist[iList]->NeutrinoSet()) {
454  const simb::MCNeutrino &nu = mclist[iList]->GetNeutrino();
455 
456  nueng_truth[neutrino_i] = nu.Nu().Momentum().E();
457  nupdg_truth[neutrino_i] = nu.Nu().PdgCode();
458  nuccnc_truth[neutrino_i] = nu.CCNC();
459  numode_truth[neutrino_i] = nu.Mode();
460 
461  lepEng_truth[neutrino_i] = nu.Lepton().E();
462  lepPDG_truth[neutrino_i] = nu.Lepton().PdgCode();
463 
464  nuvtxx_truth[neutrino_i] = nu.Nu().Vx();
465  nuvtxy_truth[neutrino_i] = nu.Nu().Vy();
466  nuvtxz_truth[neutrino_i] = nu.Nu().Vz();
467 
468  // Now we want to do some final state particle counting
469  // We need an instance of the backtracker to find the number of simulated hits for each track
470  // Loop over all of the particles
471  for (auto const thisPart : particleinventory->MCTruthToParticles_Ps(mclist[iList])) {
472  const simb::MCParticle& part = *thisPart;
473  int pdg = part.PdgCode();
474  // Make sure this is a final state particle
475  if (part.StatusCode() != 1) {
476  continue;
477  }
478  // Make sure this particle is a daughter of the neutrino
479  if (part.Mother() != 0) {
480  continue;
481  }
482  // GENIE has some fake particles for energy conservation - eg nuclear binding energy. Ignore these
483  if (pdg > 2000000000) {
484  continue;
485  }
486  // Also don't care about nuclear recoils
487  if (pdg > 1000000) {
488  continue;
489  }
490  switch(abs(pdg)) {
491  case 111 : ++nPizero[neutrino_i]; break;
492  case 211 : ++nPion[neutrino_i]; break;
493  case 2112 : ++nNeutron[neutrino_i]; break;
494  case 2212 : ++nProton[neutrino_i]; break;
495  default : break;
496  }
497  } // end of loop over all of the particles
498 
499  neutrino_i++;
500 
501  } // end of existing valid neutrino
502  } // end of loop over neutrinos
503 
504  nu_truth_N = neutrino_i;
505 
506  } // end of if mclist.size()>0
507 
508  // Get Hit information
509  nhits = hits.size();
510  InDet = 0;
511  if (hits.size()>0)
512  {
513  bool fid_flag = false;
514  for(size_t iHit = 0; iHit < hits.size(); ++iHit)
515  {
516  art::Ptr<recob::Hit> hit = hits.at(iHit);
517  float peakT = hit->PeakTime();
518  //unsigned int channel = hit->Channel();
519  unsigned int plane = hit->WireID().Plane;
520  unsigned int wire = hit->WireID().Wire;
521  unsigned int tpc = hit->WireID().TPC;
522  // for dunefd 1x2x6
523  if (peakT > 4482.) fid_flag = true;
524  if (plane == 2){
525  if (tpc < 4 && wire < 5) fid_flag = true;
526  if (tpc > 19 && wire > 474) fid_flag = true;
527  }
528  if (fid_flag) break;
529  }
530  if (!fid_flag) InDet = 1;
531  }
532 
533  //cut with true vertex in fiducial volume
534  FidCut = 0;
535  if (nu_truth_N>0){
536  if(fabs(nuvtxx_truth[0]) < 310. && fabs(nuvtxy_truth[0]) < 550. && nuvtxz_truth[0] > 50. && nuvtxz_truth[0] < 1250.) FidCut = 1;
537  if (fabs(nupdg_truth[0])==14) {
538  mutrk_contain = engrecoHandle->longestTrackContained; // 1 = contained, 0 = exiting, -1 = not set
539  }
540  }
541 
542  // Get RecoE from DUNE
543  if (!engrecoHandle.failedToGet())
544  {
545  ErecoNu = engrecoHandle->fNuLorentzVector.E();
546  RecoLepEnNu = engrecoHandle->fLepLorentzVector.E();
547  RecoHadEnNu = engrecoHandle->fHadLorentzVector.E();
548  RecoMethodNu = engrecoHandle->recoMethodUsed; // 1 = longest reco track + hadronic, 2 = reco shower with highest charge + hadronic, 3 = all hit charges, -1 = not set
549  RecoTrackMomMethod = engrecoHandle->trackMomMethod; // 1 = range, 0 = MCS, -1 = not set
550  std::cout<< "EnergyReco: "<<ErecoNu << std::endl;
551  }
552 
553  // Get RegCNN Results
554  if (!cnnresultListHandle.failedToGet())
555  {
556  if (!cnnresultListHandle->empty())
557  {
558  const std::vector<float>& v = (*cnnresultListHandle)[0].fOutput;
559  regcnn_energy = v[0];
560  for (unsigned int ii = 0; ii < 3; ii++){
561  regcnn_vertex[ii] = v[ii];
562  }
563  }
564  }
565 
566  if (!RegCnnProngResultListHandle.failedToGet())
567  {
568  if (!RegCnnProngResultListHandle->empty())
569  {
570  const std::vector<float>& v = (*RegCnnProngResultListHandle)[0].fOutput;
571  regcnn_prong_energy = v[0];
572  }
573  }
574 
575  if (!RegCnnDirResultListHandle.failedToGet()) {
576  if (!RegCnnDirResultListHandle->empty()) {
577  const std::vector<float>& v = (*RegCnnDirResultListHandle)[0].fOutput;
578  for (unsigned int i= 0; i< v.size(); ++i) {
579  regcnn_dir[i] = v[i];
580  }
581  }
582  }
583 
584  if (regcnn_dir[0]!=-99999 && track_id[0]!=-99999) {
585  for (int itrack= 0; itrack< n_track_pad; ++itrack) {
586  if (track_id[itrack]==0) {
587  double norm_regcnn_dir = TMath::Sqrt(regcnn_dir[0]*regcnn_dir[0]+
588  regcnn_dir[1]*regcnn_dir[1]+
589  regcnn_dir[2]*regcnn_dir[2]);
590  double norm_true_dir = TMath::Sqrt(all_track_true_px[itrack]*all_track_true_px[itrack]+
591  all_track_true_py[itrack]*all_track_true_py[itrack]+
592  all_track_true_pz[itrack]*all_track_true_pz[itrack]);
593  double dot = regcnn_dir[0]*all_track_true_px[itrack]+
594  regcnn_dir[1]*all_track_true_py[itrack]+
595  regcnn_dir[2]*all_track_true_pz[itrack];
596  double cosTheta = dot/norm_regcnn_dir/norm_true_dir;
597  regcnn_dir_diff = TMath::ACos(cosTheta)*180./TMath::Pi();
598  }
599  }
600  }
601 
602  if (regcnn_dir[0]!=-99999 && shower_id[0]!=-99999) {
603  for (int ishower= 0; ishower< n_showers; ++ishower) {
604  if (shower_id[ishower]==0) {
605  double norm_regcnn_dir = TMath::Sqrt(regcnn_dir[0]*regcnn_dir[0]+
606  regcnn_dir[1]*regcnn_dir[1]+
607  regcnn_dir[2]*regcnn_dir[2]);
608  double norm_true_dir = TMath::Sqrt(all_shower_true_px[ishower]*all_shower_true_px[ishower]+
609  all_shower_true_py[ishower]*all_shower_true_py[ishower]+
610  all_shower_true_pz[ishower]*all_shower_true_pz[ishower]);
611  double dot = regcnn_dir[0]*all_shower_true_px[ishower]+
612  regcnn_dir[1]*all_shower_true_py[ishower]+
613  regcnn_dir[2]*all_shower_true_pz[ishower];
614  double cosTheta = dot/norm_regcnn_dir/norm_true_dir;
615  regcnn_nue_dir_diff = TMath::ACos(cosTheta)*180./TMath::Pi();
616  }
617  }
618  }
619 
620  // fill entry
621  fTree->Fill();
622  return;
623 }
624 
626 }
627 
629 }
630 
632 {
633  // set default to nonsense value
634  ievt = -9999;
635  mutrk_contain = -999;
636  regcnn_energy = -99999;
637  regcnn_prong_energy = -99999;
638  ErecoNu = -99999;
639  RecoLepEnNu = -99999;
640  RecoHadEnNu = -99999;
641  RecoMethodNu = -99999;
642  RecoTrackMomMethod = -99999;
643 
644  fUncorrectedHadEn = -99999;
645  RecoMuTrackLength = -99999;
646  fUncorrectedMuMomMCS = -99999;
648  fUncorrectedHadEnFromShw = -99999;
649 
650  for (int ii = 0; ii < 3; ii++){
651  regcnn_vertex[ii] = -99999;
652  regcnn_dir[ii] = -99999;
653  }
654  regcnn_dir_diff = -99999;
655  regcnn_nue_dir_diff = -99999;
656 
657  nu_truth_N = 0;
658  n_track_pad = 0;
659  n_showers = 0;
660  for (int ii = 0; ii < kMax; ++ii)
661  {
662  nupdg_truth[ii] = -99999;
663  numode_truth[ii] = -99999;
664  nuccnc_truth[ii] = -99999;
665  nueng_truth[ii] = -99999;
666  lepPDG_truth[ii] = -99999;
667  lepEng_truth[ii] = -99999;
668  nuvtxx_truth[ii] = -99999;
669  nuvtxy_truth[ii] = -99999;
670  nuvtxz_truth[ii] = -99999;
671  nProton[ii] = 0;
672  nPion[ii] = 0;
673  nPizero[ii] = 0;
674  nNeutron[ii] = 0;
675 
676  track_id[ii] = -99999;
677  all_track_true_pdg[ii] = -99999;
678  all_track_true_pdg_mom[ii] = -99999;
679  all_track_px[ii] = -99999;
680  all_track_py[ii] = -99999;
681  all_track_pz[ii] = -99999;
682  all_track_true_px[ii] = -99999;
683  all_track_true_py[ii] = -99999;
684  all_track_true_pz[ii] = -99999;
685 
686  shower_id[ii] = -99999;
687  all_shower_true_pdg[ii] = -99999;
688  all_shower_true_pdg_mom[ii] = -99999;
689  all_shower_px[ii] = -99999;
690  all_shower_py[ii] = -99999;
691  all_shower_pz[ii] = -99999;
692  all_shower_true_px[ii] = -99999;
693  all_shower_true_py[ii] = -99999;
694  all_shower_true_pz[ii] = -99999;
695  }
696 }
697 
698 
699 //-----------------------------------------------------------------------------------------------------------------------------------------
700 
702 {
704  const std::vector<art::Ptr<recob::Track> > tracks(dune_ana::DUNEAnaEventUtils::GetTracks(event, fTrackLabel));
705  if (0 == tracks.size())
706  return pTrack;
707 
708  double longestLength(std::numeric_limits<double>::lowest());
709  for (unsigned int iTrack = 0; iTrack < tracks.size(); ++iTrack)
710  {
711  const double length(tracks[iTrack]->Length());
712  if (length-longestLength > std::numeric_limits<double>::epsilon())
713  {
714  longestLength = length;
715  pTrack = tracks[iTrack];
716  }
717  }
718 
719  /***********************
720  // get all PFParticles first, and then get tracks by looping all the PFParticles
721  art::Ptr<recob::Track> pTrack(art::Ptr<recob::Track>(art::ProductID("nullTrack")));
722  // Get all PFParticles
723  const std::vector<art::Ptr<recob::PFParticle>> particles = dune_ana::DUNEAnaEventUtils::GetPFParticles(event, fParticleLabel);
724  if (0 == particles.size())
725  return pTrack;
726 
727  double longestLength(std::numeric_limits<double>::lowest());
728  for (const art::Ptr<recob::PFParticle> &particle : particles) {
729 // Get the track if this particle is track-like
730 if (dune_ana::DUNEAnaPFParticleUtils::IsTrack(particle, event, fParticleLabel, fTrackLabel)) {
731 const art::Ptr<recob::Track> trk = dune_ana::DUNEAnaPFParticleUtils::GetTrack(particle, event, fParticleLabel, fTrackLabel);
732 const double length(trk->Length());
733 if (length-longestLength > std::numeric_limits<double>::epsilon()) {
734 longestLength = length;
735 pTrack = trk;
736 }
737 }
738 } // end of PFParticles
739  ************************/
740 
741  return pTrack;
742 }
743 
744 //-----------------------------------------------------------------------------------------------------------------------------------------
745 
747  detinfo::DetectorPropertiesData const& detProp,
748  const art::Event &event)
749 {
751  const std::vector<art::Ptr<recob::Shower> > showers(dune_ana::DUNEAnaEventUtils::GetShowers(event, fShowerLabel));
752  if (0 == showers.size())
753  return pShower;
754 
755  double maxCharge(std::numeric_limits<double>::lowest());
756  for (unsigned int iShower = 0; iShower < showers.size(); ++iShower)
757  {
758  const std::vector<art::Ptr<recob::Hit> > showerHits(dune_ana::DUNEAnaHitUtils::GetHitsOnPlane(dune_ana::DUNEAnaShowerUtils::GetHits(showers[iShower],
759  event,fShowerToHitLabel),2));
760  const double showerCharge(dune_ana::DUNEAnaHitUtils::LifetimeCorrectedTotalHitCharge(clockData, detProp, showerHits));
761  if (showerCharge-maxCharge > std::numeric_limits<double>::epsilon())
762  {
763  maxCharge = showerCharge;
764  pShower = showers[iShower];
765  }
766  }
767 
768  /*************************
769  // get all PFParticles first, and then get tracks by looping all the PFParticles
770  art::Ptr<recob::Shower> pShower(art::Ptr<recob::Shower>(art::ProductID("nullShower")));
771  // Get all PFParticles
772  const std::vector<art::Ptr<recob::PFParticle>> particles = dune_ana::DUNEAnaEventUtils::GetPFParticles(event, fParticleLabel);
773  if (0 == particles.size())
774  return pShower;
775 
776  double maxCharge(std::numeric_limits<double>::lowest());
777  for (const art::Ptr<recob::PFParticle> &particle : particles) {
778 // Get the shower if this particle is shower-like
779 if (dune_ana::DUNEAnaPFParticleUtils::IsShower(particle, event, fParticleLabel, fShowerLabel)) {
780 const art::Ptr<recob::Shower> shower = dune_ana::DUNEAnaPFParticleUtils::GetShower(particle, event, fParticleLabel, fShowerLabel);
781 const std::vector<art::Ptr<recob::Hit> > showerHits(dune_ana::DUNEAnaHitUtils::GetHitsOnPlane(dune_ana::DUNEAnaShowerUtils::GetHits(shower, event, fShowerToHitLabel), 2));
782 const double showerCharge(dune_ana::DUNEAnaHitUtils::LifetimeCorrectedTotalHitCharge(showerHits));
783 if (showerCharge-maxCharge > std::numeric_limits<double>::epsilon()) {
784 maxCharge = showerCharge;
785 pShower = shower;
786 }
787 }
788 } // end of PFParticles
789  ************************/
790 
791  return pShower;
792 }
793 
794 //-----------------------------------------------------------------------------------------------------------------------------------------
795 
797 {
799 }
800 
801 std::vector<std::pair<const simb::MCParticle*, double> >
802 myana::RegCNNAna::get_sortedMCParticle(std::unordered_map<const simb::MCParticle*, double> mcEMap) {
803  std::vector<std::pair<const simb::MCParticle*, double> > outVec;
804  double total_E = 0;
805  for (std::pair<const simb::MCParticle*, double> const& p: mcEMap) {
806  outVec.push_back(p);
807  total_E += p.second;
808  }
809  std::sort(outVec.begin(), outVec.end(), [](std::pair<const simb::MCParticle*, double> a, std::pair<const simb::MCParticle*, double> b){return a.second > b.second;});
810  if (abs(total_E) < 1e-6) {total_E = 1;} // protect agains zero division
811  for (std::pair<const simb::MCParticle*, double> & p: outVec) {
812  p.second /= total_E;
813  }
814 
815  return outVec;
816 }
817 
819 
820 #endif // regcnnana_module
double E(const int i=0) const
Definition: MCParticle.h:233
float Length(const PFPStruct &pfp)
Definition: PFPUtils.cxx:3303
Utility containing helpful functions for end users to access information about Hits.
int PdgCode() const
Definition: MCParticle.h:212
int CCNC() const
Definition: MCNeutrino.h:148
std::string fParticleLabel
double fRecombFactor
the average reccombination factor
double all_shower_true_px[kMax]
double GetMomentumMultiScatterChi2(art::Ptr< recob::Track > const &trk)
std::vector< sim::TrackIDE > HitToTrackIDEs(detinfo::DetectorClocksData const &clockData, recob::Hit const &hit) const
Utility containing helpful functions for end users to access information about Tracks.
Handle< PROD > getHandle(SelectorBase const &) const
Definition: DataViewImpl.h:382
std::string string
Definition: nybbler.cc:12
const simb::MCParticle * TrackIdToParticle_P(int id) const
geo::WireID WireID() const
Definition: Hit.h:233
int Mother() const
Definition: MCParticle.h:213
calo::CalorimetryAlg fCalorimetryAlg
the calorimetry algorithm
const simb::MCParticle & Nu() const
Definition: MCNeutrino.h:146
art::Ptr< recob::Shower > GetHighestChargeShower(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, const art::Event &event)
std::vector< std::pair< const simb::MCParticle *, double > > get_sortedMCParticle(std::unordered_map< const simb::MCParticle *, double > mcEMap)
double all_shower_true_pz[kMax]
Vector_t VertexDirection() const
Definition: Track.h:132
static std::vector< art::Ptr< recob::Hit > > GetHits(const art::Event &evt, const std::string &label)
Get the hits from the event.
std::vector< const simb::MCParticle * > MCTruthToParticles_Ps(art::Ptr< simb::MCTruth > const &mct) const
int all_track_true_pdg[kMax]
void beginJob() override
int StatusCode() const
Definition: MCParticle.h:211
const int kMax
RegCNNAna(fhicl::ParameterSet const &pset)
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:580
std::string fRegCNNModuleLabel
std::string fTrackToHitLabel
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.h:25
static std::vector< art::Ptr< recob::Hit > > GetHits(const art::Ptr< recob::Track > &pTrack, const art::Event &evt, const std::string &label)
Get the hits associated with the track.
art framework interface to geometry description
double nuvtxy_truth[kMax]
void reconfigure(fhicl::ParameterSet const &p)
double all_track_true_py[kMax]
double nueng_truth[kMax]
double ElectronsFromADCArea(double area, unsigned short plane) const
bool isRealData() const
T abs(T value)
static std::vector< art::Ptr< recob::Track > > GetTracks(const art::Event &evt, const std::string &label)
Get the tracks from the event. This function shouldn&#39;t be used as the basis of an analysis...
constexpr double kGeVToElectrons
23.6eV per ion pair, 1e9 eV/GeV
const double e
double Length(size_t p=0) const
Access to various track properties.
Definition: Track.h:167
const simb::MCParticle & Lepton() const
Definition: MCNeutrino.h:147
double lepEng_truth[kMax]
double nuvtxx_truth[kMax]
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
int all_track_true_pdg_mom[kMax]
Utility containing helpful functions for end users to access information about Showers.
double all_track_pz[kMax]
double all_shower_pz[kMax]
const double a
T get(std::string const &key) const
Definition: ParameterSet.h:271
int all_shower_true_pdg[kMax]
std::string fTrackLabel
bool isNull() const noexcept
Definition: Ptr.h:173
Utility containing helpful functions for end users to access information about PFParticles.
p
Definition: test.py:223
std::string fRegCNNProngModuleLabel
std::string fRegCNNDirModuleLabel
Utility containing helpful functions for end users to access products from events.
const TVector3 & Direction() const
Definition: Shower.h:189
static double LifetimeCorrectedTotalHitCharge(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, const std::vector< art::Ptr< recob::Hit > > &hits)
get the total hit charge, corrected for lifetime
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:493
std::string fShowerLabel
Detector simulation of raw signals on wires.
const sim::ParticleList & ParticleList() const
std::string fMCGenModuleLabel
RegCNNResult for RegCNN modified from Result.h.
double Vx(const int i=0) const
Definition: MCParticle.h:221
art::ServiceHandle< cheat::BackTrackerService > backtracker
std::string fShowerToHitLabel
int ID() const
Definition: Track.h:198
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:218
Declaration of signal hit object.
double all_track_py[kMax]
double fUncorrectedElectronEnergy
static std::vector< art::Ptr< recob::Hit > > GetHits(const art::Ptr< recob::Shower > &pShower, const art::Event &evt, const std::string &label)
Get the hits associated with the shower.
Contains all timing reference information for the detector.
void endJob() override
double all_track_true_pz[kMax]
double all_shower_px[kMax]
const TLorentzVector & Momentum(const int i=0) const
Definition: MCParticle.h:220
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
Provides recob::Track data product.
art::Ptr< recob::Track > GetLongestTrack(const art::Event &event)
double Vz(const int i=0) const
Definition: MCParticle.h:223
std::string fRegCNNDirResultLabel
bool isAvailable() const
Definition: Ptr.h:204
static bool * b
Definition: config.cpp:1043
double CalculateEnergyFromCharge(const double charge)
Converts deposited charge into energy by converting to number of electrons and correcting for average...
int all_shower_true_pdg_mom[kMax]
EventNumber_t event() const
Definition: EventID.h:116
std::string fRegCNNResultLabel
Declaration of basic channel signal object.
void beginSubRun(const art::SubRun &sr) override
double all_shower_py[kMax]
std::string fHitsModuleLabel
static std::vector< art::Ptr< recob::Shower > > GetShowers(const art::Event &evt, const std::string &label)
Get the showers from the event. This function shouldn&#39;t be used as the basis of an analysis...
std::string fTrackLabelDir
std::string fEnergyRecoNuLabel
TCEvent evt
Definition: DataStructs.cxx:7
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
Definition: Ptr.h:297
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:406
double nuvtxz_truth[kMax]
static constexpr double sr
Definition: Units.h:166
Event generator information.
Definition: MCNeutrino.h:18
double all_track_px[kMax]
int Mode() const
Definition: MCNeutrino.h:149
void endSubRun(const art::SubRun &sr) override
std::string fShowerLabelDir
int ID() const
Definition: Shower.h:187
double all_track_true_px[kMax]
art::ServiceHandle< cheat::ParticleInventoryService > particleinventory
double all_shower_true_py[kMax]
EventID id() const
Definition: Event.cc:34
double Vy(const int i=0) const
Definition: MCParticle.h:222
std::string fRegCNNProngResultLabel
QTextStream & endl(QTextStream &s)
Event finding and building.
static std::vector< art::Ptr< recob::Hit > > GetHitsOnPlane(const std::vector< art::Ptr< recob::Hit >> &hits, const geo::PlaneID::PlaneID_t planeID)
Get all hits on a specific plane.
void analyze(art::Event const &evt) override