Purity_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: Purity
3 // Module Type: analyzer
4 // File: Purity_module.cc
5 //
6 // Generated at Wed Aug 2 13:55:30 2017 by Andrea Scarpelli
7 //(andrea.scarpelli@cern.ch) using artmod
8 // from cetpkgsupport v1_11_00.
9 // Analyzer for purity measurements in protodunedp (and 3x1x1 prototype)
10 //TODO: GainView to be configured from service
11 //TODO: Stitch to multiple tracks (more than 2)
12 //TODO: generalization to multiple TPCs
13 //TODO: calibration factor!
14 //
15 ////////////////////////////////////////////////////////////////////////
16 
24 #include "fhiclcpp/ParameterSet.h"
26 #include "art_root_io/TFileService.h"
28 #include "canvas/Persistency/Common/FindManyP.h"
29 
41 
42 #include "TTree.h"
43 #include "TH1.h"
44 #include "TH2.h"
45 #include "TInterpreter.h"
46 #include "TROOT.h"
47 #include "TMath.h"
48 
49 #include <cstring>
50 #include <string>
51 #include <iostream>
52 #include <string>
53 #include <vector>
54 #include <map>
55 #include <fstream>
56 #include <stdio.h>
57 #include <math.h> /* acos */
58 
59 
60 namespace pdunedp
61 {
62  struct bHitInfo;
63  class Purity;
64 }
65 
67 {
68  bHitInfo(size_t i, double x, double e, int w) :
69  Index(i), dE(e), dx(x), wire(w)
70  { }
71  size_t Index;
72  double dE, dx;
73  int wire;
74 };
75 
77 public:
78 
79  struct Config{
80  using Name = fhicl::Name;
82 
84  Name("CalorimetryAlg"), Comment("Used to calculate electrons from ADC area.")
85  };
86 
87  fhicl::Atom<art::InputTag> CalWireModuleLabel{
88  Name ("CalWireModuleLabel"), Comment("Calwire data product name")
89  };
90 
92  Name ("HitModuleLabel"), Comment("Hit data product name")
93  };
94 
95  fhicl::Atom<art::InputTag> ClusterModuleLabel{
96  Name ("ClusterModuleLabel"), Comment("Cluster data product name")
97  };
98 
99  fhicl::Atom<art::InputTag> TrackModuleLabel{
100  Name ("TrackModuleLabel"), Comment("Track data product name")
101  };
102 
104  Name ("TotalGain"), Comment("Total Gain of the detector") //<---TODO insert it form service
105  };
106 
108  Name ("EnergyCut"), Comment("Cut over the event energy")
109  };
110 
112  Name ("Length"), Comment("minimal length to define a mip")
113  };
114 
116  Name("StitchAngle"), Comment("Max. stitching angle")
117  };
118 
119  fhicl::Atom<double>StitchDistance{
120  Name("StitchDistance"), Comment("Max. stitching distance")
121  };
122 
124  Name("VolCut"), Comment("Volume Cut to select a going trougth muon")
125  };
126 
128  Name("NumOfBins"), Comment("Number of histogram for the purity analysis")
129  };
130 
132  Name("ADCtoCharge"), Comment("...")
133  };
135  Name("MinDx"), Comment("...")
136  };
137  }; // end struct
138 
140 
141  explicit Purity(Parameters const & config);
142 
143  Purity(Purity const &) = delete;
144  Purity(Purity &&) = delete;
145  Purity & operator = (Purity const &) = delete;
146  Purity & operator = (Purity &&) = delete;
147 
148  // Required functions.
149  void analyze(art::Event const & e) override;
150  void MakeDataProduct();
151  void beginJob() override;
152  void endJob() override;
153  void Clear();
154  void FillEventHitsTree(std::vector<recob::Hit> hits);
155  double GetCharge(std::vector<recob::Hit> hits);
156  double GetCharge(const std::vector<art::Ptr<recob::Hit> > hits);
157  bool IsCrossing(TVector3 Start, TVector3 End);
158  bool StitchTracks(recob::Track Track1, recob::Track Track2, TVector3 & Edge1, TVector3 & Edge2);
159  void Make_dEdx(std::vector< double > & dEdx, std::vector< double > & range,
160  const std::vector< pdunedp::bHitInfo > & hits, recob::Track mip, int Flip, unsigned int plane);
161  void FillTajectoryGraph(std::map<size_t, recob::Track > MipCandidate,
162  art::FindManyP<recob::Hit> HitsTrk);
163  void FillPurityHist(recob::Track track, std::vector<art::Ptr<recob::Hit>> hits);
164  void FindMipInfo(recob::Track mip, std::vector<art::Ptr<recob::Hit>> vhits,
165  const std::vector<const recob::TrackHitMeta*, std::allocator<const recob::TrackHitMeta*> > vmeta);
166  double GetCorrectedCharge(recob::Track trk, double charge, unsigned int plane);
167  double GetCorrection(recob::Track trk, unsigned int plane);
168 
169 
170 private:
173 
178 
179  double fTotalGain;
180  double fECut;
181  double fLength;
182  double fStitchAngle; double fStitchDistance;
183  std::vector<double> fVolCut; int fNumOfBins;
184  double fADCtoCharge;
185  double fMinDx;
186 
187  int Events=0; int SkipEvents=0; int BadEvents=0;
188  int fRun; int fSubRun; int fEvent;
189  int fNtotHits, fNtotTracks, fNHitsTrack;
190  int fTrkNum; int fNumOfMips;
191  int fMipNum; int fMipIndex;
192  int fPlane; int fIndex;
193 
195  int fEndTick;
199 
200  double fTrackLength; double fChi2Ndof;
201  double fHitsCharge; //in fC
202  double fTrackCharge; //in fC
203  double fHitsTrackCharge; //in fC
204  double fMipCharge, fMipLength, fMipPhi, fMipTheta; int fNHitsMip;
205  double fCosX; double fCosY; double fCosZ;
206  double fSpacePointX; double fSpacePointY; double fSpacePointZ;
207  double fSummedADC; double fSummedADC_corrected;
208  double fADCIntegral_corrected; double fADCIntegral; double fADCPeak; double fADCPeak_corrected; double fCorrectedCharge; double fCharge;
209  double fDrift; int fWire; double fCorrection; double fdQds;
210  double fdEdx; double fRange;
211  int fBin;
212 
213  double fSummedCharge; int fEntries;
214 
215  //double fElectronsToGeV;
217  double fElectronCharge = 1.60217662e-4; //in fC
218  double fMipChargeCm = 10; //in fC/cm
219 
220  std::map< size_t, std::vector< pdunedp::bHitInfo >[3] > fTrk2InfoMap; // hits info sorted by views
221  std::map<size_t, recob::Track > TrackList;
222 
223  std::map<int, int> goodevents;
224 
225  TTree *fTree; TTree *fTreeTrk; TTree *fTreeMip; TTree *fTreeHitsMip; TTree *fTreeCalib;
226  TTree *fTreeHits; TTree *fTreePurity; TTree *fTreePurityMean;
227 
228  TH1D *htbin[3][100]; TH1D *htbin_singlehits[3][100]; TH1D *htbin_num[3][100];
229  TH2D *hTrkTrajectory_0; TH2D *hTrkTrajectory_1;
230 };//end class
231 
232 pdunedp::Purity::Purity(Parameters const & config) : EDAnalyzer(config),
233  fCalorimetryAlg(config().CalorimetryAlg()),
234  fCalWireModuleLabel(config().CalWireModuleLabel()),
235  fHitModuleLabel(config().HitModuleLabel()),
236  fClusterModuleLabel(config().ClusterModuleLabel()),
237  fTrackModuleLabel(config().TrackModuleLabel()),
238  fTotalGain(config().TotalGain()),
239  fECut(config().EnergyCut()),
240  fLength(config().Length()),
241  fStitchAngle(config().StitchAngle()),
242  fStitchDistance(config().StitchDistance()),
243  fVolCut(config().VolCut()),
244  fNumOfBins(config().NumOfBins()),
245  fADCtoCharge(config().ADCtoCharge()),
246  fMinDx(config().MinDx())
247 {
248  this->MakeDataProduct();
249 }
250 
252  fADCToElectrons = 1./dp->ElectronsToADC();
253  //auto simChannelExtract = &*art::ServiceHandle<detsim::DPhaseSimChannelExtractService>();
254  //fTotalGain = simChannelExtract->GainPerView()*2;
255 }
256 
258 
259  //Tfile Services
261 
262  //one entry for every event
263  fTree = tfs->make<TTree>("Event", "LAr purity analysis information");
264  fTree->Branch("fRun", &fRun,"fRun/I");
265  fTree->Branch("fSubRun", &fSubRun,"fSubRun/I");
266  fTree->Branch("fEvent", &fEvent, "fEvent/I");
267  fTree->Branch("fNtotHits", &fNtotHits, "fNtotHits/I");
268  fTree->Branch("fNtotTracks", &fNtotTracks, "fNtotTracks/I");
269  fTree->Branch("fNumOfMips", &fNumOfMips, "fNumOfMips/I");
270  fTree->Branch("fHitsCharge", &fHitsCharge, "fHitsCharge/D");
271  fTree->Branch("fHitsTrackCharge", &fHitsTrackCharge, "fHitsTrackCharge/D");
272 
273  //branch for purity measuremtns usign mips: one entry per mip
274  fTreeHits =tfs->make<TTree>("HitsEvent","Info on hits in event");
275  fTreeHits->Branch("fRun", &fRun,"fRun/I");
276  fTreeHits->Branch("fSubRun", &fSubRun,"fSubRun/I");
277  fTreeHits->Branch("fEvent", &fEvent, "fEvent/I");
278  fTreeHits->Branch("fPlane", &fPlane, "fPlane/I");
279  fTreeHits->Branch("fADCIntegral", &fADCIntegral, "fADCIntegral/D");
280  fTreeHits->Branch("fChargeIntegral", &fChargeIntegral, "fChargeIntegral/D");
281  fTreeHits->Branch("fPeakAmplitude", &fPeakAmplitude, "fPeakAmplitude/D");
282  fTreeHits->Branch("fSummedADC", &fSummedADC, "fSummedADC/D");
283  fTreeHits->Branch("fGodnessOfFit", &fGodnessOfFit, "fGodnessOfFit/D");
284  fTreeHits->Branch("fDrift", &fDrift, "fDrift/D");
285  fTreeHits->Branch("fWire", &fWire, "fWire/I");
286  fTreeHits->Branch("fStartTick", &fStartTick, "fStartTick/I");
287  fTreeHits->Branch("fEndTick", &fEndTick, "fEndTick/I");
288 
289  //one entry for every track
290  fTreeTrk = tfs->make<TTree>("TrkInfo", "Information on tracks");
291  fTreeTrk->Branch("fRun", &fRun,"fRun/I");
292  fTreeTrk->Branch("fSubRun", &fSubRun,"fSubRun/I");
293  fTreeTrk->Branch("fEvent", &fEvent, "fEvent/I");
294  fTreeTrk->Branch("fTrkNum", &fTrkNum, "fTrkNum/I");
295  fTreeTrk->Branch("fChi2Ndof", &fChi2Ndof, "fChi2Ndof/D");
296  fTreeTrk->Branch("fTrackLength", &fTrackLength, "fTrackLength/D");
297  fTreeTrk->Branch("fTrackCharge", &fTrackCharge, "fTrackCharge/D");
298  fTreeTrk->Branch("fNHitsTrack", &fNHitsTrack, "fNHitsTrack/I");
299 
300  //one entry for every selected mip (stitched mips are considered separately)
301  fTreeMip = tfs->make<TTree>("MipInfo", "Information on mips");
302  fTreeMip->Branch("fRun", &fRun,"fRun/I");
303  fTreeMip->Branch("fSubRun", &fSubRun,"fSubRun/I");
304  fTreeMip->Branch("fEvent", &fEvent, "fEvent/I");
305  fTreeMip->Branch("fMipIndex", &fMipIndex, "fMipIndex/I");
306  fTreeMip->Branch("fMipNum", &fMipNum, "fMipNum/I");
307  fTreeMip->Branch("fMipCharge", &fMipCharge, "fMipcharge/D");
308  fTreeMip->Branch("fMipLength", &fMipLength, "fMipLength/D");
309  fTreeMip->Branch("fMipLength", &fMipLength, "fMipLength/D");
310  fTreeMip->Branch("fMipPhi", &fMipPhi, "fMipPhi/D");
311  fTreeMip->Branch("fMipTheta", &fMipTheta, "fMipTheta/D");
312  fTreeMip->Branch("fNHitsMip", &fNHitsMip, "fNHitsMip/I");
313 
314  //branch for purity measuremtns usign mips: one entry per mip
315  fTreeHitsMip =tfs->make<TTree>("HitsMip","Info hits in mips");
316  fTreeHitsMip->Branch("fRun", &fRun,"fRun/I");
317  fTreeHitsMip->Branch("fSubRun", &fSubRun,"fSubRun/I");
318  fTreeHitsMip->Branch("fEvent", &fEvent, "fEvent/I");
319  fTreeHitsMip->Branch("fMipIndex", &fMipIndex, "fMipIndex/I");
320  fTreeHitsMip->Branch("fMipNum", &fMipNum, "fMipNum/I");
321  fTreeHitsMip->Branch("fPlane", &fPlane, "fPlane/I");
322  fTreeHitsMip->Branch("fCosX", &fCosX, "fCosX/D");
323  fTreeHitsMip->Branch("fCosY", &fCosY, "fCosY/D");
324  fTreeHitsMip->Branch("fCosZ", &fCosZ, "fCosZ/D");
325  fTreeHitsMip->Branch("fADCIntegral", &fADCIntegral, "fADCIntegral/D");
326  fTreeHitsMip->Branch("fADCIntegral_corrected", &fADCIntegral_corrected, "fADCIntegral_corrected/D");
327  fTreeHitsMip->Branch("fADCPeak", &fADCPeak, "fADCPeak/D");
328  fTreeHitsMip->Branch("fADCPeak_corrected", &fADCPeak_corrected, "fADCPeak_corrected/D");
329  fTreeHitsMip->Branch("fCorrection", &fCorrection, "fCorrection/D");
330  fTreeHitsMip->Branch("fSummedADC", &fSummedADC, "fSummedADC/D");
331  fTreeHitsMip->Branch("fSummedADC_corrected", &fSummedADC_corrected, "fSummedADC_corrected/D");
332  fTreeHitsMip->Branch("fCharge", &fCharge, "fCharge/D");
333  fTreeHitsMip->Branch("fCorrectedCharge", &fCorrectedCharge, "fCorrectedCharge/D");
334  fTreeHitsMip->Branch("fDrift", &fDrift, "fDrift/D");
335  fTreeHitsMip->Branch("fStartTick", &fStartTick, "fStartTick/I");
336  fTreeHitsMip->Branch("fEndTick", &fEndTick, "fEndTick/I");
337  fTreeHitsMip->Branch("fWire", &fWire, "fWire/I");
338  fTreeHitsMip->Branch("fSpacePointX", &fSpacePointX, "fSpacePointX/D");
339  fTreeHitsMip->Branch("fSpacePointY", &fSpacePointY, "fSpacePointY/D");
340  fTreeHitsMip->Branch("fSpacePointZ", &fSpacePointZ, "fSpacePointZ/D");
341  fTreeHitsMip->Branch("fdQds", &fdQds, "fdQds/D");
342 
343  fTreeCalib = tfs->make<TTree>("Calibration", "dE/dx info");
344  fTreeCalib->Branch("fRun", &fRun, "fRun/I");
345  fTreeCalib->Branch("fSubRun", &fSubRun,"fSubRun/I");
346  fTreeCalib->Branch("fEvent", &fEvent, "fEvent/I");
347  fTreeCalib->Branch("fIndex", &fIndex, "fIndex/I");//
348  fTreeCalib->Branch("fdEdx", &fdEdx, "fdEdx/D");
349  fTreeCalib->Branch("fRange", &fRange, "fRange/D");
350  fTreeCalib->Branch("fPlane", &fPlane, "fPlane/I");
351 
352  //fill branch with purity measurements
353  fTreePurity =tfs->make<TTree>("PurityHit","Corrected charge for purity analysis");
354  fTreePurity->Branch("fRun", &fRun,"fRun/I");
355  fTreePurity->Branch("fSubRun", &fSubRun,"fSubRun/I");
356  fTreePurity->Branch("fEvent", &fEvent, "fEvent/I");
357  fTreePurity->Branch("fPlane", &fPlane, "fPlane/I");
358  fTreePurity->Branch("fCharge", &fCharge, "fCharge/D");
359  fTreePurity->Branch("fDrift", &fDrift, "fDrift/D");
360  fTreePurity->Branch("fBin", &fBin, "fBin/I");
361  fTreePurity->Branch("fMipIndex", &fMipIndex, "fMipIndex/I");
362 
363  fTreePurityMean =tfs->make<TTree>("PurityMean","Summed values for every drift bin");
364  fTreePurityMean->Branch("fRun", &fRun,"fRun/I");
365  fTreePurityMean->Branch("fSubRun", &fSubRun,"fSubRun/I");
366  fTreePurityMean->Branch("fEvent", &fEvent, "fEvent/I");
367  fTreePurityMean->Branch("fPlane", &fPlane, "fPlane/I");
368  fTreePurityMean->Branch("fBin", &fBin, "fBin/I");
369  fTreePurityMean->Branch("fSummedCharge", &fSummedCharge, "fSummedCharge/D");
370  fTreePurityMean->Branch("fEntries", &fEntries, "fEntries/I");
371 
372  //TODO<<--Generalize these histograms to different geometries
373  hTrkTrajectory_0 = tfs->make<TH2D>("hTrkTrajectory_0", "Selected mips hit position view 0;Channel;Ticks", 320, 0, 319, 1667, 0, 1666);
374  hTrkTrajectory_1 = tfs->make<TH2D>("hTrkTrajectory_1", "Selected mips hit position view 1;Channel;Ticks", 960, 0, 959, 1667, 0, 1666);
375 
376  for(int plane = 0; plane < (int)geom->Nplanes(0); plane++){
377  for (int nb=0; nb <fNumOfBins; nb++){
378  std::string histname_singlehits = "histname_singlehits"+std::to_string(nb)+"_view"+std::to_string(plane);
379  std::string histname_average = "histname_average"+std::to_string(nb)+"_view"+std::to_string(plane);
380  std::string histname_num = "histname_numhits"+std::to_string(nb)+"_view"+std::to_string(plane);
381 
382  htbin_singlehits[plane][nb] = tfs->make<TH1D>(histname_singlehits.c_str(), ";Single hits charge distribution (fC)", 100, 0, 200);
383  htbin[plane][nb] = tfs->make<TH1D>(histname_average.c_str(), ";Average charge (fC)", 100, 0, 200);
384  htbin_num[plane][nb] = tfs->make<TH1D>(histname_num.c_str(), ";Number of bins per track", 100, 0, 200);
385  }
386  }
387 }
388 
390  fRun = e.run();
391  fSubRun = e.subRun();
392  fEvent = e.id().event(); Events++;
393 
394  Clear();
395 
396  //Require data product handles
397  auto CalwireHandle = e.getValidHandle<std::vector<recob::Wire> >(fCalWireModuleLabel);
398  auto HitHandle = e.getValidHandle<std::vector<recob::Hit> >(fHitModuleLabel);
399  auto ClusterHandle = e.getValidHandle<std::vector<recob::Cluster> >(fClusterModuleLabel);
400  auto TrackHandle = e.getValidHandle<std::vector<recob::Track> >(fTrackModuleLabel);
401 
402  //check data products exists
403  if(!CalwireHandle || !HitHandle || !ClusterHandle || !TrackHandle){
404  BadEvents++;
405  return;
406  }
407 
408  //first selection of data based on ADC counts (separate energetic showers)
409  float SumWireADC=0;
410  for(auto const& Calwire : *CalwireHandle){
411  for(float ADC : Calwire.Signal()){
412  SumWireADC += ADC;
413  }
414  }
415  float Edep = SumWireADC*fADCToElectrons*fElectronCharge;
416  float Efrac = Edep/(fMipChargeCm*350*fTotalGain);
417  mf::LogVerbatim("pdunedp::Purity")<< "Energy: " << Edep << " " << Efrac;
418  if(Efrac > fECut){
419  mf::LogVerbatim("pdunedp::Purity") << "Too much energy energy deposited! Not a mip";
420  SkipEvents++;
421  return;
422  }
423 
424  //Get Hits charge
425  fNtotHits = HitHandle->size();
426  fHitsCharge = GetCharge(*HitHandle);
427 
428  FillEventHitsTree(*HitHandle);
429 
430  fNtotTracks = (int)TrackHandle->size();
431  if(fNtotTracks == 0){
432  mf::LogVerbatim("pdunedp::Purity") << "Event has no 3D tracks";
433  SkipEvents++;
434  return;
435  }
436 
437  art::FindManyP< recob::Hit > HitsFromTrack(TrackHandle, e, fTrackModuleLabel);
438  art::FindManyP< recob::Hit, recob::TrackHitMeta > TrackHitMeta(TrackHandle, e, fTrackModuleLabel);
439 
440  double ChargeTrk=0;
441  //int skippedTrk=0;
442  for(size_t t=0; t<(size_t)fNtotTracks; t++){
443  //retrive information for every track (not mip selected yet)
444  auto track = TrackHandle->at(t);
445  TrackList[t] = track;
446  fTrackLength = track.Length();
447  fChi2Ndof = track.Chi2PerNdof();
448  fNHitsTrack = HitsFromTrack.at(t).size();
449  fTrkNum = (int)t;
450  fTrackCharge = GetCharge(HitsFromTrack.at(t));
451  ChargeTrk+= GetCharge(HitsFromTrack.at(t));
452  fTreeTrk->Fill();
453  }
454  fHitsTrackCharge = ChargeTrk; //<-- Sum charge from all event
455 
456  std::map<size_t, recob::Track > fMipCandidate;
457  /*Try to select mips. Particle passing trougth the detector (Selecting a fiducial
458  volume to keep into account the inefficiencies of the lems ).
459  Tracks that doesn't meet the criteria of crossing the detector after a first pass
460  are stitched togheter and the crossing criteria are evaluated again.
461  Stitch is done only on two consecuitve tracks. TODO: Stitch more than two tracks*/
462 
464  for(It = TrackList.begin(); It !=TrackList.end(); It++){
465  //first check if the track is already inside the candidate vector
466  if (fMipCandidate.find(It->first) != fMipCandidate.end()){
467  continue;
468  }
469 
470  TVector3 Start = (It->second).Vertex<TVector3>(); TVector3 End = (It->second).End<TVector3>();
471  if(!IsCrossing(Start, End) && (TrackList.size() > 1)){
472  //It is not crossing, let's see if it can be stitched to something else
473  for(std::map<size_t, recob::Track >::iterator It2=TrackList.begin(); It2!=TrackList.end(); It2++){
474  if(It->first == It2->first){ continue; }
475  TVector3 newStart; TVector3 newEnd;
476  if(!StitchTracks(It->second, It2->second, newStart, newEnd)){
477  continue; //Not stitching: continue searcing
478  }else{
479  if(IsCrossing(newStart, newEnd)){
480  fMipCandidate[It->first] = It->second;
481  fMipCandidate[It2->first] = It2->second;
482  }else{
483  break; //Stop the loop: we stitched and still not crossing...
484  }
485  }
486  }//end while
487  }else if(!IsCrossing(Start, End) && (TrackList.size() == 1)){
488  continue;
489  }else{
490  fMipCandidate[It->first] = It->second;
491  }
492  }
493 
494  if(!fMipCandidate.size()){
495  mf::LogVerbatim("pdunedp::Purity") << "No mips selected! ";
496  SkipEvents++;
497  return;
498  }
499  //print the list of mips:
500  mf::LogVerbatim("pdunedp::Purity") << "List of mips candidates in event " << fEvent;
501  size_t num=0;
502  for(std::map<size_t, recob::Track >::iterator mip = fMipCandidate.begin(); mip !=fMipCandidate.end(); mip++){
503  mf::LogVerbatim("pdunedp::Purity") << "Track: " << mip->first;
504  fMipNum = (int)num++;
505  fMipIndex = (int)mip->first;
506  fMipCharge = GetCharge(HitsFromTrack.at(mip->first));
507  fMipLength = (mip->second).Length();
508  fMipPhi = (mip->second).Phi(); //polar angle
509  fMipTheta = (mip->second).Theta(); //Azimutal angle
510  fNHitsMip = (int)HitsFromTrack.at(mip->first).size();
511  auto vhit = TrackHitMeta.at(mip->first);
512  auto vmeta = TrackHitMeta.data(mip->first);
513  FindMipInfo(mip->second, vhit, vmeta);
514  FillPurityHist(mip->second, HitsFromTrack.at(mip->first));
515  fTreeMip->Fill();
516  }
517 
518  for (auto const & trkEntry : fTrk2InfoMap)
519  {
520  //check flip
521  int Flip = 0; // tag track if it is reconstructed in the opposite direction
522  if (fMipCandidate[trkEntry.first].End().Z() < fMipCandidate[trkEntry.first].Vertex().Z()){ Flip = 1; }
523 
524  for(unsigned int plane=0; plane < geom->Nplanes(0); plane++){ //TODO<<--Extend to different geometries
525  std::vector< double > dEdx, range;
526  auto const & info = trkEntry.second;
527  Make_dEdx(dEdx, range, info[plane], fMipCandidate[trkEntry.first], Flip, plane);
528  for (size_t i = 0; i < dEdx.size(); ++i){
529  fdEdx = dEdx[i];
530  fPlane = plane;
531  fIndex = trkEntry.first;
532  fRange = range[i];
533  fTreeCalib->Fill();
534  }
535  }
536  }
537 
538  FillTajectoryGraph(fMipCandidate, HitsFromTrack);
540  fTree->Fill();
541 }//end analyzer
542 
544  //It returns the uncalibrated charge in the detector given a list of hits (summed on both views)
545  if(!hits.size()){ return 0.0;}
546 
547  double charge=0;
548  for(auto const hit : hits){
549  //unsigned short plane = hit->WireID().Plane;
550  double dqadc = hit->Integral();
551  if (!std::isnormal(dqadc) || (dqadc < 0)) continue;
552  //charge += dqadc*fCalorimetryAlg.ElectronsFromADCArea(dqadc, plane)*fElectronCharge;
553  charge+= dqadc*fADCtoCharge;
554  }
555  return charge;
556 }
557 
558 double pdunedp::Purity::GetCharge(std::vector<recob::Hit> hits){
559  //It returns the uncalibrated charge in the detector given a list of hits (summed on both views)
560  if(!hits.size()){ return 0.0;}
561 
562  double charge=0;
563  for(auto hit : hits){
564  //unsigned short plane = hit.WireID().Plane;
565  double dqadc = hit.Integral();
566  if (!std::isnormal(dqadc) || (dqadc < 0)) continue;
567  //charge += dqadc*fCalorimetryAlg.ElectronsFromADCArea(dqadc, plane)*fElectronCharge;
568  charge+= dqadc*fADCtoCharge;
569  }
570  return charge;
571 }
572 
573 void pdunedp::Purity::FillEventHitsTree(std::vector<recob::Hit> hits){
574  //Fill a tree with additionals informations about the Event
575  if(!hits.size()){ return;}
576 
577  for(auto hit : hits){
578  unsigned short plane = hit.WireID().Plane;
579  int wire = hit.WireID().Wire;
580  double dqadc = hit.Integral();
581  double tdrift = hit.PeakTime();
582  if (!std::isnormal(dqadc) || (dqadc < 0)) continue;
583  double dq = dqadc*fADCtoCharge;
584 
585  fPlane = plane;
586  fStartTick = hit.StartTick();
587  fEndTick = hit.EndTick();
588  fADCIntegral = dqadc;
589  fPeakAmplitude = hit.PeakAmplitude();
590  fSummedADC = hit.SummedADC();
591  fGodnessOfFit= hit.GoodnessOfFit();
592  fChargeIntegral = dq;
593  fDrift = tdrift;
594  fWire = wire;
595  fTreeHits->Fill();
596  }
597  return;
598 }
599 
600 bool pdunedp::Purity::StitchTracks(recob::Track Track1, recob::Track Track2, TVector3 & Edge1, TVector3 & Edge2){
601  //Attempt to sticth two tracks togheter. return the non stitched verteces of the two tracks.
602  // mf::LogVerbatim("pdunedp::Purity") << "Doing Stitch";
603  bool Stitch = false;
604 
605  double Dx = sqrt(pow(Track1.End().X()-Track2.Vertex().X(),2) + pow(Track1.End().Y()-Track2.Vertex().Y(),2)+pow(Track1.End().Z()-Track2.Vertex().Z(),2));
606  double Angle= (180.0/3.14159)*Track1.EndDirection<TVector3>().Angle(Track2.VertexDirection<TVector3>());
607  int Criteria = 1;
608 
609  if(Dx > sqrt(pow(Track1.End().X()-Track2.End().X(),2) + pow(Track1.End().Y()-Track2.End().Y(),2) + pow(Track1.End().Z()-Track2.End().Z(),2)))
610  {
611  Dx= sqrt(pow(Track1.End().X()-Track2.End().X(),2) + pow(Track1.End().Y()-Track2.End().Y(),2) + pow(Track1.End().Z()-Track2.End().Z(),2));
612  Angle = 180. - (180.0/3.14159)*Track1.EndDirection<TVector3>().Angle(Track2.EndDirection<TVector3>());
613  Criteria= 2;
614  }
615 
616  if(Dx > sqrt(pow(Track1.Vertex().X()-Track2.End().X(),2) + pow(Track1.Vertex().Y()-Track2.End().Y(),2) + pow(Track1.Vertex().Z()-Track2.End().Z(),2)))
617  {
618  Dx = sqrt(pow(Track1.Vertex().X()-Track2.End().X(),2) + pow(Track1.Vertex().Y()-Track2.End().Y(),2) + pow(Track1.Vertex().Z()-Track2.End().Z(),2));
619  Angle = (180.0/3.14159)*Track1.VertexDirection<TVector3>().Angle(Track2.EndDirection<TVector3>());
620  Criteria = 3;
621  }
622 
623  if(Dx > sqrt(pow(Track1.Vertex().X()-Track2.Vertex().X(),2) + pow(Track1.Vertex().Y()-Track2.Vertex().Y(),2) + pow(Track1.Vertex().Z()-Track2.Vertex().Z(),2)))
624  {
625  Dx = sqrt(pow(Track1.Vertex().X()-Track2.Vertex().X(),2) + pow(Track1.Vertex().Y()-Track2.Vertex().Y(),2) + pow(Track1.Vertex().Z()-Track2.Vertex().Z(),2));
626  Angle = 180. - (180.0/3.14159)*Track1.VertexDirection<TVector3>().Angle(Track2.VertexDirection<TVector3>());
627  Criteria = 4;
628  }
629 
630  //check the stitching criteria
631  if( (fStitchAngle > Angle) && (fStitchDistance > Dx)){
632  Stitch = true;
633  switch (Criteria) {
634  case 1:
635  Edge1 = Track1.Vertex<TVector3>(); Edge2 = Track2.End<TVector3>();
636  break;
637  case 2:
638  Edge1 = Track1.Vertex<TVector3>(); Edge2 = Track2.Vertex<TVector3>();
639  break;
640  case 3:
641  Edge1 = Track1.End<TVector3>(); Edge2 = Track2.Vertex<TVector3>();
642  break;
643  case 4:
644  Edge1 = Track1.End<TVector3>(); Edge2 = Track2.End<TVector3>();
645  break;
646  default:
647  mf::LogError("pdunedp::Purity") << "Unknown error!";
648  break;
649  }
650  }
651  return Stitch;
652 }
653 
654 bool pdunedp::Purity::IsCrossing(TVector3 Start, TVector3 End){
655  bool isCrossing = false;
656  //define the boundaries (for the moment consider only 1 TPC) //<--TODO Generalisaztion to Multiple TPCs
657  double vtx[3] = {0, 0, 150}; //<<--TODO Generalisaztion
659  geo::TPCID idtpc = geom->FindTPCAtPosition(vtx);
660  if (geom->HasTPC(idtpc)) // <----Assuming there is only one TPC
661  {
662  /*
663  const geo::TPCGeo& tpcgeo = geom->GetElement(idtpc);
664  double minx = tpcgeo.MinX() + fVolCut[0]; double maxx = tpcgeo.MaxX() - fVolCut[1];
665  double miny = tpcgeo.MinY() + fVolCut[2]; double maxy = tpcgeo.MaxY() - fVolCut[3];
666  double minz = tpcgeo.MinZ() + fVolCut[4]; double maxz = tpcgeo.MaxZ() - fVolCut[5];
667 
668  //check if both start and end are both outside the fiducial volume (in at least one direction )
669  if( ( ((minx > Start.X()) || (maxx < Start.X()))
670  || ((miny > Start.Y()) || (maxy < Start.Y()))
671  || ((minz > Start.Z()) || (maxz < Start.Z())) ) //condiotion on start
672  &&( ((minx > End.X() ) || (maxx < End.X() ))
673  || ((miny > End.Y() ) || (maxy < End.Y() ))
674  || ((minz > End.Z() ) || (maxz < End.Z() )) ) //condiotion on end
675  ){
676  isCrossing=true;
677  }else{
678  isCrossing=false;
679  }
680  //from the point of view of X only particles that goes trougth the whole detector can be
681  //considered particles on trigger (check all the possible cases)
682  TVector3 Diff = Start-End;
683  double ProjX = fabs(Diff.Unit().X());
684  if( acos(1./ProjX) < 30*(TMath::Pi()/180) ){ //<<-- only on very vertical tracks
685  if((maxx < Start.X())||(maxx < End.X())){
686  if((minx < Start.X())||(minx < End.X()))
687  isCrossing=false;
688  }
689  if((minx > Start.X())||(minx > End.X())){
690  if((maxx > Start.X())||(maxx > End.X()))
691  isCrossing=false;
692  }
693  }
694  //Mips must be above certain length (for not be confused with random hadronic processes)
695  if( (Diff).Mag() < fLength){
696  isCrossing=false;
697  }
698  */
699 
700  //Cuts used for the purity analysis: vertical track, from anode to cathode contained within some fiducial volume in z
701  //boundaries are minx -50 maxx +50
702  // miny -50 maxy +50
703  // minz 0 maxz +300
704  const geo::TPCGeo& tpcgeo = geom->GetElement(idtpc);
705  double minx = tpcgeo.MinX() + fVolCut[0]; double maxx = tpcgeo.MaxX() - fVolCut[1];
706  double minz = tpcgeo.MinZ() + fVolCut[4]; double maxz = tpcgeo.MaxZ() - fVolCut[5];
707 
708  //first cut is applied on the length
709  if( (End-Start).Mag() > fLength ){
710 
711  //check if the track is flipped on Z
712  if( (End.Z() - Start.Z()) > 0 ){
713  if( Start.Z() > minz && End.Z() < maxz){
714  //check if the track is flipped on X
715  if(End.X() > Start.X()){
716  if((Start.X() <= minx && End.X() >= maxx)){
717  isCrossing = true;
718  }
719  }else if(End.X() < Start.X()){
720  if((End.X() <= minx && Start.X() >= maxx)){
721  isCrossing = true;
722  }
723  }
724  }
725  }else if((End.Z() - Start.Z()) < 0){
726  if( End.Z() > minz && Start.Z() < maxz){
727  //check if the track is flipped on X
728  if(End.X() > Start.X()){
729  if((Start.X() <= minx && End.X() >= maxx)){
730  isCrossing = true;
731  }
732  }else if(End.X() < Start.X()){
733  if((End.X() <= minx && Start.X() >= maxx)){
734  isCrossing = true;
735  }
736  }
737  }
738  }else{
739  mf::LogError("pdunedp::Purity") << "Track starts and ends in the same Z coordinate";
740  }
741  }//end fLength
742  }//end has tpc
743  return isCrossing;
744 }
745 
746 void pdunedp::Purity::FillTajectoryGraph(std::map<size_t, recob::Track > MipCandidate,
747  art::FindManyP<recob::Hit> HitsTrk){
748  //Merge the 2D hit position view in a single graph to evaluate defects in mip selection
749  //<<--TODO Generic geometry
751  for(It = MipCandidate.begin(); It !=MipCandidate.end(); It++){
752  auto hits = HitsTrk.at(It->first);
753  if(!hits.size()){ continue; }
754  for(auto const hit : hits){
755  unsigned short plane = hit->WireID().Plane;
756  switch (plane) {
757  case 0:
758  hTrkTrajectory_0->Fill(hit->WireID().Wire, hit->PeakTime());
759  break;
760  case 1:
761  hTrkTrajectory_1->Fill(hit->WireID().Wire, hit->PeakTime());
762  break;
763  default:
764  mf::LogError("pdunedp::Purity") << "Invalid Plane;";
765  break;
766  }
767  }
768  }
769  return;
770 }
771 
773  const std::vector<const recob::TrackHitMeta*, std::allocator<const recob::TrackHitMeta*> > vmeta){
774  /*This function is intended to caluclate the most important quantities from a mip
775  and fill a tree for further analysis. There will be an entry for every hit in the mip.
776  Stitched mips are considered independently. T0 is assumed to be 0, as consequence of
777  the selection done*/
778 
779  if(!vhits.size()){return;}
780  for(size_t h =0; h< vhits.size(); h++){
781  unsigned int plane= vhits[h]->WireID().Plane;
782  int wire= vhits[h]->WireID().Wire;
783  //double pitch = geom->WirePitch(vhits[h]->View());
784  double dQadc = vhits[h]->Integral();
785  if (!std::isnormal(dQadc) || (dQadc < 0)) continue;
786  size_t idx = vmeta[h]->Index();
787  double dx = vmeta[h]->Dx();
788 
789  auto TrajPoint3D = mip.TrajectoryPoint(idx);
790 
791  double dQ = dQadc*fADCtoCharge;
792  fTrk2InfoMap[fMipIndex][plane].emplace_back(idx, dx, dQ, wire);
793 
794  TVector3 Dir = mip.Vertex<TVector3>() - mip.End<TVector3>();
795  //Direction cosines of the track
796  double CosX = 1./Dir.Unit().X();
797  double CosY = 1./Dir.Unit().Y();
798  double CosZ = 1./Dir.Unit().Z();
799 
800  double dQ_corr = GetCorrectedCharge(mip, dQ, plane);
801  double PeakTime = vhits[h]->PeakTime();
802 
803  //Fill Purity tree
804  fWire = wire;
805  fPlane = plane;
806  fCosX = CosX;
807  fCosY = CosY;
808  fCosZ = CosZ;
809  fADCIntegral_corrected = GetCorrectedCharge(mip, dQadc, plane); //corrected value
810  fADCPeak = vhits[h]->PeakAmplitude();
811  fADCPeak_corrected = GetCorrectedCharge(mip, vhits[h]->PeakAmplitude(), plane);//corrected value
812  fSummedADC = vhits[h]->SummedADC();
813  fSummedADC_corrected = GetCorrectedCharge(mip, fSummedADC, plane);//corrected value
814  fADCIntegral = dQadc;
815  fCharge = dQ;
816  fCorrectedCharge = dQ_corr;
817  fCorrection = dQ_corr/dQ;
818  fSpacePointX = TrajPoint3D.position.X();
819  fSpacePointY = TrajPoint3D.position.Y();
820  fSpacePointZ = TrajPoint3D.position.Z();
821  if(dx>0){
822  fdQds = dQ/dx;
823  }
824  fDrift = PeakTime;
825  fStartTick = vhits[h]->StartTick();
826  fEndTick = vhits[h]->EndTick();
827  fTreeHitsMip->Fill();
828  }
829  return;
830 }
831 
832 void pdunedp::Purity::Make_dEdx(std::vector< double > & dEdx, std::vector< double > & range,
833  const std::vector< pdunedp::bHitInfo > & hits, recob::Track mip, int Flip, unsigned int plane){
834  if (!hits.size()) return;
835 
836  dEdx.clear(); range.clear();
837 
838  double rmax = mip.Length();
839 
840  int i0 = hits.size() - 1; int i1 = -1; int di = -1;
841  if (Flip) {i0 = 0; i1 = hits.size(); di = 1;}
842 
843  double de = 0.0;
844  double dx = 0.0;
845  double r0 = 0.0; double r1 = 0.0; double r = 0.0;
846 
847  double minDx = 0.1; // can be a parameter
848 
849  while ((i0 != i1) && (r < rmax))
850  {
851  dx = 0.0; de = 0.0;
852  while ((i0 != i1) && (dx <= minDx))
853  {
854  de += hits[i0].dE;
855  dx += hits[i0].dx;
856  i0 += di;
857  }
858 
859  r0 = r1;
860  r1 += dx;
861  r = 0.5 * (r0 + r1);
862 
863  if ((de > 0.0) && (dx > 0.0) && (r < rmax))
864  {
865  dEdx.push_back(de/dx);
866  range.push_back(r*GetCorrection(mip, plane));
867  }
868  }
869  return;
870 }
871 
873  /*Function intended to read the hits from a track and fill the histograms that can be
874  used for further purity analysis*/
875  mf::LogVerbatim("pdunedp::Purity") << "Start purity for track: " << fMipIndex;
876 
877  //determine the size (in ticks of each bin)
878  for(int pl=0; pl<(int)geom->Nplanes(0); pl++){
879  int TicksPerBin = detProp.NumberTimeSamples()/fNumOfBins;
880 
881  double charge[100]; double num[100];
882  for (int nb=0; nb<fNumOfBins; nb++){ charge[nb]=0; num[nb] =0; } //init the charge bins to 0
883 
884  if(!hits.size()){
885  mf::LogError("pdunedp::Purity") << "The track has no hit associated!";
886  return;
887  }
888  int nfound =0; int nstart; int nstop;
889 
890  for (size_t nh=0; nh<hits.size(); nh++){
891 
892  double dqadc = hits[nh]->Integral(); //ADCxticks
893  double htime = hits[nh]->PeakTime(); //ticks
894  unsigned short plane = hits[nh]->WireID().Plane;
895  if(plane != pl) {continue;}
896  //double conv = fCalorimetryAlg.ElectronsFromADCArea(dqadc, plane)*fElectronCharge;
897  double conv = fADCtoCharge;
898  double dq = dqadc*conv;
899  dq = GetCorrectedCharge(track, dq, plane);
900 
901  //dq = GetCorrectedCharge(track, dq, plane); //corrected charge wrt to the track angle
902 
903  if (nh==0){
904  nstart=0;
905  nstop=fNumOfBins;
906  }
907  if (nh>0){
908  nstart=std::max(0,nfound-5);
909  nstop =std::min(nfound+5,fNumOfBins);
910  }
911 
912  for(int nb=nstart; nb<nstop; nb++) {
913  double tmin=TicksPerBin*nb;
914  double tmax=TicksPerBin*(nb+1);
915  //mf::LogVerbatim("pdunedp::Purity") << "nb " << nb << " " << tmin << " " <<tmax;
916 
917  if ( (htime>=tmin) && (htime<tmax) ){
918  htbin_singlehits[pl][nb]->Fill (dq);
919  fBin = nb;
920  fCharge = dq;
921  fPlane = pl;
922  fTreePurity->Fill();
923  charge[nb]+=dq;
924  num[nb]++;
925  //mf::LogVerbatim("pdunedp::Purity") << "charge" << charge[nb];
926  nfound=nb;
927  //mf::LogVerbatim("pdunedp::Purity") << "nfound" << nb;
928 
929  }
930  } //close loop on time bins
931  } //close loop on hit on tracks
932 
933  // fill histograms for fit
934  //select first and last time interval with charge deposition >0
935  int ilast=-1000;
936  int ifirst=1000;
937 
938  for (int nb=0; nb<fNumOfBins; nb++) {
939  if (charge[nb]>0 && num[nb] >0) {
940  //mf::LogVerbatim("pdunedp::Purity") << "nb " << nb << " Norm: " << charge[nb];
941  if (nb<ifirst) ifirst=nb;
942  if (nb>ilast) ilast=nb;
943  }
944  }
945 
946  //mf::LogVerbatim("pdunedp::Purity") << "first: " << ifirst << " last " << ilast;
947 
948  for (int nb=0; nb<ilast-ifirst-1; nb++){
949  mf::LogVerbatim("pdunedp::Purity") << "plane " << pl << " nb " << nb+ifirst+1<< " charge bin " << charge[nb+ifirst+1]/num[nb+ifirst+1];
950  //htbin_norm[nb]->Fill(charge[nb+ifirst+1]/charge[ifirst+1]); //fill the bin with charge normalized to first bin
951  htbin[pl][nb]->Fill( charge[nb+ifirst+1]/num[nb+ifirst+1] );
952  htbin_num[pl][nb]->Fill( num[nb+ifirst+1] );
953  }
954 
955  /*
956  for (int nb=0; nb<ilast-ifirst; nb++){
957  //mf::LogVerbatim("pdunedp::Purity") << "nb " << nb+ifirst+1<< " Norm: " << charge[ifirst+1] << " charge bin " << charge[nb+ifirst+1];
958  htbin_corr[nb]->Fill( charge[nb+ifirst]*angle_corr ); //fill the bin with charge normalized to first bin
959  }
960  */
961  }
962  return;
963 }
964 
965 double pdunedp::Purity::GetCorrectedCharge(recob::Track trk, double charge, unsigned int plane){
966  /*Returns the corrected charge value corrected for the angle between the track direction and the wire pitch*/
967  double angle =0.;
968  double charge_corr =0.;
969 
970  switch (plane) {
971  case 0:
972  angle = atan( fabs( (trk.End().X()-trk.Vertex().X())/(trk.End().Y()-trk.Vertex().Y()) ) );
973  break;
974  case 1:
975  angle = atan( fabs( (trk.End().X()-trk.Vertex().X())/(trk.End().Z()-trk.Vertex().Z()) ) );
976  break;
977  default:
978  mf::LogError("pdunedp::Purity") << "Invalid plane number!";
979  break;
980  }
981  if(fabs(cos(angle))>0.){ charge_corr = charge*fabs(cos(angle)); }
982  return charge_corr;
983 }
984 
985 double pdunedp::Purity::GetCorrection(recob::Track trk, unsigned int plane){
986  /*Returns the corrected charge value corrected for the angle between the track direction and the wire pitch*/
987  double angle =0.;
988  double correction =0.;
989 
990  switch (plane) {
991  case 0:
992  angle = atan( fabs( (trk.End().X()-trk.Vertex().X())/(trk.End().Y()-trk.Vertex().Y()) ) );
993  break;
994  case 1:
995  angle = atan( fabs( (trk.End().X()-trk.Vertex().X())/(trk.End().Z()-trk.Vertex().Z()) ) );
996  break;
997  default:
998  mf::LogError("pdunedp::Purity") << "Invalid plane number!";
999  break;
1000  }
1001  if(fabs(cos(angle))>0.){ correction = fabs(cos(angle)); }
1002  return correction;
1003 }
1004 
1006  TrackList.clear();
1007  fTrk2InfoMap.clear();
1008 }
1009 
1011  mf::LogVerbatim("pdunedp::Purity") << "====== Run " << fRun << " summary ======";
1012  mf::LogVerbatim("pdunedp::Purity") << "Total Events: " << Events;
1013  mf::LogVerbatim("pdunedp::Purity") << "Bad Events: " << BadEvents;
1014  mf::LogVerbatim("pdunedp::Purity") << "Skipped Events: " << SkipEvents;
1015  mf::LogVerbatim("pdunedp::Purity") << "selected Events: " << Events-BadEvents-SkipEvents <<" \nList: ";
1016  for(std::map<int, int>::iterator goodevent = goodevents.begin(); goodevent != goodevents.end(); goodevent++){
1017  mf::LogVerbatim("pdunedp::Purity") << "SubRun: " << goodevent->first << " Event: " << goodevent->second ; //<----write this list on file (?)
1018  }
1019  mf::LogVerbatim("pdunedp::Purity") << "===========================";
1020 
1021 }
1022 
def analyze(root, level, gtrees, gbranches, doprint)
Definition: rootstat.py:69
intermediate_table::iterator iterator
Store parameters for running LArG4.
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
float Length(const PFPStruct &pfp)
Definition: PFPUtils.cxx:3303
static constexpr double nb
Definition: Units.h:81
void FindMipInfo(recob::Track mip, std::vector< art::Ptr< recob::Hit >> vhits, const std::vector< const recob::TrackHitMeta *, std::allocator< const recob::TrackHitMeta * > > vmeta)
CryostatGeo const & GetElement(geo::CryostatID const &cryoid) const
bool IsCrossing(TVector3 Start, TVector3 End)
std::map< size_t, recob::Track > TrackList
std::string string
Definition: nybbler.cc:12
constexpr T pow(T x)
Definition: pow.h:72
double MinX() const
Returns the world x coordinate of the start of the box.
Definition: BoxBoundedGeo.h:88
Geometry information for a single TPC.
Definition: TPCGeo.h:38
struct vector vector
ChannelGroupService::Name Name
calo::CalorimetryAlg fCalorimetryAlg
Class to keep data related to recob::Hit associated with recob::Track.
Vector_t VertexDirection() const
Definition: Track.h:132
art::InputTag fClusterModuleLabel
double MaxX() const
Returns the world x coordinate of the end of the box.
Definition: BoxBoundedGeo.h:91
TTree * fTreePurityMean
Data related to recob::Hit associated with recob::Track.The purpose is to collect several variables t...
Definition: TrackHitMeta.h:43
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
unsigned int Index
void beginJob() override
art framework interface to geometry description
TH1D * htbin_singlehits[3][100]
double GetCharge(std::vector< recob::Hit > hits)
geo::TPCID FindTPCAtPosition(double const worldLoc[3]) const
Returns the ID of the TPC at specified location.
art::InputTag fCalWireModuleLabel
std::map< int, int > goodevents
double dEdx(float dqdx, float Efield)
Definition: doAna.cpp:21
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wire planes in the specified TPC.
double fSummedADC_corrected
const double e
double Length(size_t p=0) const
Access to various track properties.
Definition: Track.h:167
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
art::InputTag fTrackModuleLabel
TH1D * htbin_num[3][100]
void beginJob()
Definition: Breakpoints.cc:14
static Config * config
Definition: config.cpp:1054
void FillTajectoryGraph(std::map< size_t, recob::Track > MipCandidate, art::FindManyP< recob::Hit > HitsTrk)
void FillPurityHist(recob::Track track, std::vector< art::Ptr< recob::Hit >> hits)
Point_t const & Vertex() const
Definition: Track.h:124
double GetCorrection(recob::Track trk, unsigned int plane)
Purity(Parameters const &config)
double MinZ() const
Returns the world z coordinate of the start of the box.
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
Definition: DataViewImpl.h:441
void analyze(art::Event const &e) override
TrajectoryPoint_t TrajectoryPoint(size_t i) const
Access to i-th TrajectoryPoint or its Flags.
Definition: Track.h:117
SubRunNumber_t subRun() const
Definition: DataViewImpl.cc:78
RunNumber_t run() const
Definition: DataViewImpl.cc:71
static int max(int a, int b)
The data type to uniquely identify a TPC.
Definition: geo_types.h:386
art::ServiceHandle< geo::Geometry > geom
double GetCorrectedCharge(recob::Track trk, double charge, unsigned int plane)
Detector simulation of raw signals on wires.
void FillEventHitsTree(std::vector< recob::Hit > hits)
std::vector< double > fVolCut
double fADCIntegral_corrected
bool HasTPC(geo::TPCID const &tpcid) const
Returns whether we have the specified TPC.
Declaration of signal hit object.
#define Comment
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
void End(void)
Definition: gXSecComp.cxx:210
Vector_t EndDirection() const
Definition: Track.h:133
double MaxZ() const
Returns the world z coordinate of the end of the box.
void Make_dEdx(std::vector< double > &dEdx, std::vector< double > &range, const std::vector< pdunedp::bHitInfo > &hits, recob::Track mip, int Flip, unsigned int plane)
Provides recob::Track data product.
double fADCPeak_corrected
void endJob() override
EventNumber_t event() const
Definition: EventID.h:116
Point_t const & End() const
Definition: Track.h:125
bool StitchTracks(recob::Track Track1, recob::Track Track2, TVector3 &Edge1, TVector3 &Edge2)
Declaration of basic channel signal object.
list x
Definition: train.py:276
TH1D * htbin[3][100]
bHitInfo(size_t i, double x, double e, int w)
art::InputTag fHitModuleLabel
std::map< size_t, std::vector< pdunedp::bHitInfo >[3] > fTrk2InfoMap
std::string to_string(ModuleType const mt)
Definition: ModuleType.h:34
EventID id() const
Definition: Event.cc:34
#define Start
Definition: config.cpp:1229
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
Definition: Track.h:49
static TemplateFilterFactory::AutoRegister< FilterLength > fLength("length")