ProtoDUNEDPAnalCosmicTree_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: ProtoDUNEDPAnalCosmicTree
3 // File: ProtoDUNEDPAnalCosmicTree_module.cc
4 //
5 // Extract protoDUNE useful information, do a firs tpre-selection and save output to a flat tree
6 //
7 // Georgios Christodoulou - georgios.christodoulou at cern.ch
8 //
9 ////////////////////////////////////////////////////////////////////////
10 
17 #include "art_root_io/TFileService.h"
19 #include "canvas/Persistency/Common/FindManyP.h"
20 #include "fhiclcpp/ParameterSet.h"
22 
35 
40 
41 
42 // ROOT includes
43 #include "TTree.h"
44 #include "TFile.h"
45 #include "TString.h"
46 #include "TTimeStamp.h"
47 
48 // C++ Includes
49 #include <fstream>
50 #include <string>
51 #include <sstream>
52 #include <cmath>
53 #include <algorithm>
54 #include <iostream>
55 #include <vector>
56 
57 // Maximum number of beam particles to save
58 const int NMAXCOSMICPARTICLES = 100;
59 
60 namespace protoana {
61  class ProtoDUNEDPAnalCosmicTree;
62 }
63 
64 
66 public:
67 
69 
74 
75  virtual void beginJob() override;
76  virtual void endJob() override;
77 
78  // Required functions.
79  void analyze(art::Event const & evt) override;
80 
81 private:
82 
83  // Helper utility functions
87 
88  // Track momentum algorithm calculates momentum based on track range
90 
91  // Initialise tree variables
92  void Initialise();
93 
94  // Fill cosmics tree
95  void FillCosmicsTree(art::Event const & evt);
96 
97  // fcl parameters
106 
108 
109  // Tree variables
110  int fRun;
111  int fSubRun;
112  int fevent;
113  double fTimeStamp;
115 
116  // Cosmic tree variables
127  //double fcosmicMomentum[NMAXCOSMICPARTICLES];
128  //double fcosmicEndMomentum[NMAXCOSMICPARTICLES];
133 
141 
143 
155 
156 };
157 
158 
160  :
161  EDAnalyzer(p),
162  //dataUtil(p.get<fhicl::ParameterSet>("DataUtils")),
163  fBeamModuleLabel(p.get< art::InputTag >("BeamModuleLabel")),
164  fCalorimetryTag(p.get<std::string>("CalorimetryTag")),
165  fParticleIDTag(p.get<std::string>("ParticleIDTag")),
166  fTrackerTag(p.get<std::string>("TrackerTag")),
167  fShowerTag(p.get<std::string>("ShowerTag")),
168  fPFParticleTag(p.get<std::string>("PFParticleTag")),
169  fGeneratorTag(p.get<std::string>("GeneratorTag")),
170  fMinimumTrackLength(p.get<double>("MinimumTrackLength"))
171 {
172 
173 }
174 
176 
178 
179  fPandoraCosmics = tfs->make<TTree>("PandoraCosmics", "Cosmic tracks reconstructed with Pandora");
180  fPandoraCosmics->Branch("run", &fRun, "run/I");
181  fPandoraCosmics->Branch("subrun", &fSubRun, "subrun/I");
182  fPandoraCosmics->Branch("event", &fevent, "event/I");
183  fPandoraCosmics->Branch("timestamp", &fTimeStamp, "timestamp/D");
184  fPandoraCosmics->Branch("Nactivefembs", &fNactivefembs, "Nactivefembs[5]/I");
185  fPandoraCosmics->Branch("NCOSMICS", &fNCOSMICS, "NCOSMICS/I");
186  fPandoraCosmics->Branch("cosmicIsClear", &fcosmicIsClear, "cosmicIsClear[NCOSMICS]/I");
187  fPandoraCosmics->Branch("cosmicBDTScore", &fcosmicBDTScore, "cosmicBDTScore[NCOSMICS]/D");
188  fPandoraCosmics->Branch("cosmicNHits", &fcosmicNHits, "cosmicNHits[NCOSMICS]/I");
189  fPandoraCosmics->Branch("iscosmictrack", &fiscosmictrack, "iscosmictrack[NCOSMICS]/I");
190  fPandoraCosmics->Branch("iscosmicshower", &fiscosmicshower, "iscosmicshower[NCOSMICS]/I");
191  fPandoraCosmics->Branch("cosmicID", &fcosmicID, "cosmicID[NCOSMICS]/I");
192  fPandoraCosmics->Branch("cosmicTheta", &fcosmicTheta, "cosmicTheta[NCOSMICS]/D");
193  fPandoraCosmics->Branch("cosmicPhi", &fcosmicPhi, "cosmicPhi[NCOSMICS]/D");
194  fPandoraCosmics->Branch("cosmicLength", &fcosmicLength, "cosmicLength[NCOSMICS]/D");
195  //fPandoraCosmics->Branch("cosmicMomentum", &fcosmicMomentum, "cosmicMomentum[NCOSMICS]/D");
196  //fPandoraCosmics->Branch("cosmicEndMomentum", &fcosmicEndMomentum, "cosmicEndMomentum[NCOSMICS]/D");
197  fPandoraCosmics->Branch("cosmicOpeningAngle", &fcosmicOpeningAngle, "cosmicOpeningAngle[NCOSMICS]/D");
198  fPandoraCosmics->Branch("cosmicShowerBestPlane", &fcosmicShowerBestPlane, "cosmicShowerBestPlane[NCOSMICS]/I");
199  fPandoraCosmics->Branch("cosmicEndPosition", &fcosmicEndPosition, "cosmicEndPosition[NCOSMICS][3]/D");
200  fPandoraCosmics->Branch("cosmicStartPosition", &fcosmicStartPosition, "cosmicStartPosition[NCOSMICS][3]/D");
201  fPandoraCosmics->Branch("cosmicEndDirection", &fcosmicEndDirection, "cosmicEndDirection[NCOSMICS][3]/D");
202  fPandoraCosmics->Branch("cosmicStartDirection", &fcosmicStartDirection, "cosmicStartDirection[NCOSMICS][3]/D");
203  fPandoraCosmics->Branch("cosmicMomentumByRangeMuon", &fcosmicMomentumByRangeMuon, "cosmicMomentumByRangeMuon[NCOSMICS]/D");
204  fPandoraCosmics->Branch("cosmicMomentumByRangeProton", &fcosmicMomentumByRangeProton, "cosmicMomentumByRangeProton[NCOSMICS]/D");
205  fPandoraCosmics->Branch("cosmicKineticEnergy", &fcosmicKineticEnergy, "cosmicKineticEnergy[NCOSMICS][3]/D");
206  fPandoraCosmics->Branch("cosmicRange", &fcosmicRange, "cosmicRange[NCOSMICS][3]/D");
207  fPandoraCosmics->Branch("cosmicTrkPitchC", &fcosmicTrkPitchC, "cosmicTrkPitchC[NCOSMICS][3]/D");
208  fPandoraCosmics->Branch("cosmicT0", &fcosmicT0, "cosmicT0[NCOSMICS]/D");
209 
210  fPandoraCosmics->Branch("cosmicPID_Pdg", &fcosmicPID_Pdg, "cosmicPID_Pdg[NCOSMICS][3]/I");
211  fPandoraCosmics->Branch("cosmicPID_Ndf", &fcosmicPID_Ndf, "cosmicPID_Ndf[NCOSMICS][3]/I");
212  fPandoraCosmics->Branch("cosmicPID_MinChi2", &fcosmicPID_MinChi2, "cosmicPID_MinChi2[NCOSMICS][3]/D");
213  fPandoraCosmics->Branch("cosmicPID_DeltaChi2", &fcosmicPID_DeltaChi2, "cosmicPID_DeltaChi2[NCOSMICS][3]/D");
214  fPandoraCosmics->Branch("cosmicPID_Chi2Proton", &fcosmicPID_Chi2Proton, "cosmicPID_Chi2Proton[NCOSMICS][3]/D");
215  fPandoraCosmics->Branch("cosmicPID_Chi2Kaon", &fcosmicPID_Chi2Kaon, "cosmicPID_Chi2Kaon[NCOSMICS][3]/D");
216  fPandoraCosmics->Branch("cosmicPID_Chi2Pion", &fcosmicPID_Chi2Pion, "cosmicPID_Chi2Pion[NCOSMICS][3]/D");
217  fPandoraCosmics->Branch("cosmicPID_Chi2Muon", &fcosmicPID_Chi2Muon, "cosmicPID_Chi2Muon[NCOSMICS][3]/D");
218  fPandoraCosmics->Branch("cosmicPID_MissingE", &fcosmicPID_MissingE, "cosmicPID_MissingE[NCOSMICS][3]/D");
219  fPandoraCosmics->Branch("cosmicPID_MissingEavg", &fcosmicPID_MissingEavg, "cosmicPID_MissingEavg[NCOSMICS][3]/D");
220  fPandoraCosmics->Branch("cosmicPID_PIDA", &fcosmicPID_PIDA, "cosmicPID_PIDA[NCOSMICS][3]/D");
221 
222 }
223 
225 
226  // Initialise tree parameters
227  Initialise();
228 
229  fRun = evt.run();
230  fSubRun = evt.subRun();
231  fevent = evt.id().event();
232  art::Timestamp ts = evt.time();
233  if (ts.timeHigh() == 0){
234  TTimeStamp ts2(ts.timeLow());
235  fTimeStamp = ts2.AsDouble();
236  }
237  else{
238  TTimeStamp ts2(ts.timeHigh(), ts.timeLow());
239  fTimeStamp = ts2.AsDouble();
240  }
241 
242  FillCosmicsTree(evt);
243 
244 }
245 
247 
248 }
249 
251 
252  unsigned int npfParticles = pfpUtil.GetNumberPrimaryPFParticle(evt,fPFParticleTag);
253 
254  if(npfParticles == 0){
255  std::cout << "WARNING::No PfParticles found! Skipping event!" << std::endl;
256  return;
257  }
258 
259  // Do not process more than NMAXCOSMICPARTICLES
260  if(fNCOSMICS > NMAXCOSMICPARTICLES) return;
261 
262  // Get all PFParticles
263  auto recoParticles = evt.getValidHandle<std::vector<recob::PFParticle>>(fPFParticleTag);
264 
265  for(unsigned int i = 0; i < recoParticles->size(); i++){
266  recob::PFParticle* pfparticle = const_cast<recob::PFParticle*>(&(recoParticles->at(i)));
267  //const recob::PFParticle* pfparticle = &(recoParticles->at(i));
268 
269  // Only consider primary particles
270  if(!pfparticle->IsPrimary()) continue;
271 
272  // Do not consider beam particles
273  if(pfpUtil.IsBeamParticle(*pfparticle, evt, fPFParticleTag)) continue;
274 
275  // Get the T0 for this pfParticle
276  std::vector<anab::T0> pfT0vec = pfpUtil.GetPFParticleT0(*pfparticle,evt,fPFParticleTag);
277  //if(pfT0vec.empty()) continue;
278 
279  const recob::Track* thisTrack = pfpUtil.GetPFParticleTrack(*pfparticle,evt,fPFParticleTag,fTrackerTag);
280  const recob::Shower* thisShower = pfpUtil.GetPFParticleShower(*pfparticle,evt,fPFParticleTag,fShowerTag);
281 
282  // Do not save very short cosmic tracks
283  if(thisTrack != 0x0 && thisTrack->Length() < fMinimumTrackLength) continue;
284  if(thisShower != 0x0 && thisShower->Length() < fMinimumTrackLength) continue;
285 
286  // Pandora's BDT beam-cosmic score
288 
289  // NHits associated with this pfParticle
291 
292  if(!pfT0vec.empty())
293  fcosmicT0[fNCOSMICS] = pfT0vec[0].Time();
294 
295  // Check if it is clear cosmic
297 
298  if(thisTrack != 0x0){
301  fcosmicID[fNCOSMICS] = thisTrack->ParticleId();
302  fcosmicTheta[fNCOSMICS] = thisTrack->Theta();
303  fcosmicPhi[fNCOSMICS] = thisTrack->Phi();
304  fcosmicLength[fNCOSMICS] = thisTrack->Length();
305  //fcosmicMomentum[fNCOSMICS] = thisTrack->StartMomentum();
306  //fcosmicEndMomentum[fNCOSMICS] = thisTrack->EndMomentum();
307  fcosmicEndPosition[fNCOSMICS][0] = thisTrack->Trajectory().End().X();
308  fcosmicEndPosition[fNCOSMICS][1] = thisTrack->Trajectory().End().Y();
309  fcosmicEndPosition[fNCOSMICS][2] = thisTrack->Trajectory().End().Z();
310  fcosmicStartPosition[fNCOSMICS][0] = thisTrack->Trajectory().Start().X();
311  fcosmicStartPosition[fNCOSMICS][1] = thisTrack->Trajectory().Start().Y();
312  fcosmicStartPosition[fNCOSMICS][2] = thisTrack->Trajectory().Start().Z();
313  fcosmicEndDirection[fNCOSMICS][0] = thisTrack->Trajectory().EndDirection().X();
314  fcosmicEndDirection[fNCOSMICS][1] = thisTrack->Trajectory().EndDirection().Y();
315  fcosmicEndDirection[fNCOSMICS][2] = thisTrack->Trajectory().EndDirection().Z();
316  fcosmicStartDirection[fNCOSMICS][0] = thisTrack->Trajectory().StartDirection().X();
317  fcosmicStartDirection[fNCOSMICS][1] = thisTrack->Trajectory().StartDirection().Y();
318  fcosmicStartDirection[fNCOSMICS][2] = thisTrack->Trajectory().StartDirection().Z();
319 
322 
323  // Calorimetry
324  std::vector<anab::Calorimetry> calovector = trackUtil.GetRecoTrackCalorimetry(*thisTrack, evt, fTrackerTag, fCalorimetryTag);
325  if(calovector.size() != 3)
326  std::cerr << "WARNING::Calorimetry vector size for cosmic is = " << calovector.size() << std::endl;
327 
328  for(size_t k = 0; k < calovector.size() && k<3; k++){
329  int plane = calovector[k].PlaneID().Plane;
330  if(plane < 0) continue;
331  if(plane > 2) continue;
332  fcosmicKineticEnergy[fNCOSMICS][plane] = calovector[k].KineticEnergy();
333  fcosmicRange[fNCOSMICS][plane] = calovector[k].Range();
334  fcosmicTrkPitchC[fNCOSMICS][plane] = calovector[k].TrkPitchC();
335  }
336 
337  // PID
338  std::vector<anab::ParticleID> pids = trackUtil.GetRecoTrackPID(*thisTrack, evt, fTrackerTag, fParticleIDTag);
339  if(pids.size() != 3)
340  std::cerr << "WARNING::PID vector size for primary is = " << pids.size() << std::endl;
341 
342  for(size_t k = 0; k < pids.size() && k<3; k++){
343  int plane = pids[k].PlaneID().Plane;
344  if(plane < 0) continue;
345  if(plane > 2) continue;
346  fcosmicPID_Pdg[fNCOSMICS][plane] = pids[plane].Pdg();
347  fcosmicPID_Ndf[fNCOSMICS][plane] = pids[plane].Ndf();
348  fcosmicPID_MinChi2[fNCOSMICS][plane] = pids[plane].MinChi2();
349  fcosmicPID_DeltaChi2[fNCOSMICS][plane] = pids[plane].DeltaChi2();
350  fcosmicPID_Chi2Proton[fNCOSMICS][plane] = pids[plane].Chi2Proton();
351  fcosmicPID_Chi2Kaon[fNCOSMICS][plane] = pids[plane].Chi2Kaon();
352  fcosmicPID_Chi2Pion[fNCOSMICS][plane] = pids[plane].Chi2Pion();
353  fcosmicPID_Chi2Muon[fNCOSMICS][plane] = pids[plane].Chi2Muon();
354  fcosmicPID_MissingE[fNCOSMICS][plane] = pids[plane].MissingE();
355  fcosmicPID_MissingEavg[fNCOSMICS][plane] = pids[plane].MissingEavg();
356  fcosmicPID_PIDA[fNCOSMICS][plane] = pids[plane].PIDA();
357  }
358 
359  }
360  else if(thisShower != 0x0){
363 
364  fcosmicID[fNCOSMICS] = thisShower->ID();
365  fcosmicLength[fNCOSMICS] = thisShower->Length();
367  fcosmicOpeningAngle[fNCOSMICS] = thisShower->OpenAngle();
368  fcosmicStartPosition[fNCOSMICS][0] = thisShower->ShowerStart().X();
369  fcosmicStartPosition[fNCOSMICS][1] = thisShower->ShowerStart().Y();
370  fcosmicStartPosition[fNCOSMICS][2] = thisShower->ShowerStart().Z();
371  fcosmicStartDirection[fNCOSMICS][0] = thisShower->Direction().X();
372  fcosmicStartDirection[fNCOSMICS][1] = thisShower->Direction().Y();
373  fcosmicStartDirection[fNCOSMICS][2] = thisShower->Direction().Z();
374  }
375  else{
376  std::cout << "INFO::Cosmic pfParticle is not track or shower. Skip!" << std::endl;
377  continue;
378  }
379 
380  // Increment number of cosmic tracks
381  fNCOSMICS++;
382 
383  }
384 
385  fPandoraCosmics->Fill();
386 
387 }
388 
390 
391  fRun = -999;
392  fSubRun = -999;
393  fevent = -999;
394  fTimeStamp = -999.0;
395  for(int k=0; k < 5; k++)
396  fNactivefembs[k] = -999;
397 
398  // Cosmics tree
399  fNCOSMICS = 0;
400  for(int k=0; k < NMAXCOSMICPARTICLES; k++){
401  fcosmicIsClear[k] = -999;
402  fcosmicNHits[k] = -999;
403  fcosmicBDTScore[k] = -999.0;
404  fiscosmictrack[k] = -999;
405  fiscosmicshower[k] = -999;
406  fcosmicID[k] = -999;
407  fcosmicTheta[k] = -999.0;
408  fcosmicPhi[k] = -999.0;
409  fcosmicLength[k] = -999.0;
410  //fcosmicMomentum[k] = -999.0;
411  //fcosmicEndMomentum[k] = -999.0;
412  fcosmicMomentumByRangeMuon[k] = -999.0;
414  fcosmicT0[k] = -999.0;
415  fcosmicShowerBestPlane[k] = -999.0;
416  fcosmicOpeningAngle[k] = -999.0;
417 
418  for(int l=0; l < 3; l++){
419  fcosmicEndPosition[k][l] = -999.0;
420  fcosmicStartPosition[k][l] = -999.0;
421  fcosmicEndDirection[k][l] = -999.0;
422  fcosmicStartDirection[k][l] = -999.0;
423  fcosmicKineticEnergy[k][l] = -999.0;
424  fcosmicRange[k][l] = -999.0;
425  fcosmicTrkPitchC[k][l] = -999.0;
426 
427  fcosmicPID_Pdg[k][l] = -999.0;
428  fcosmicPID_Ndf[k][l] = -999.0;
429  fcosmicPID_MinChi2[k][l] = -999.0;
430  fcosmicPID_DeltaChi2[k][l] = -999.0;
431  fcosmicPID_Chi2Proton[k][l] = -999.0;
432  fcosmicPID_Chi2Kaon[k][l] = -999.0;
433  fcosmicPID_Chi2Pion[k][l] = -999.0;
434  fcosmicPID_Chi2Muon[k][l] = -999.0;
435  fcosmicPID_MissingE[k][l] = -999.0;
436  fcosmicPID_MissingEavg[k][l] = -999.0;
437  fcosmicPID_PIDA[k][l] = -999.0;
438  }
439  }
440 
441 }
442 
444 
int best_plane() const
Definition: Shower.h:200
const TVector3 & ShowerStart() const
Definition: Shower.h:192
std::vector< anab::ParticleID > GetRecoTrackPID(const recob::Track &track, art::Event const &evt, const std::string trackModule, const std::string pidModule) const
Get the PID from a given track.
constexpr std::uint32_t timeLow() const
Definition: Timestamp.h:29
bool IsBeamParticle(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const
Use the pandora metadata to tell us if this is a beam particle or not.
std::vector< anab::T0 > GetPFParticleT0(const recob::PFParticle &particle, art::Event const &evt, std::string particleLabel) const
Get the T0(s) from a given PFParticle.
const int NMAXCOSMICPARTICLES
double Length() const
Definition: Shower.h:201
int ParticleId() const
Definition: Track.h:171
const recob::Shower * GetPFParticleShower(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, const std::string showerLabel) const
Get the shower associated to this particle. Returns a null pointer if not found.
std::string string
Definition: nybbler.cc:12
const recob::TrackTrajectory & Trajectory() const
Access to the stored recob::TrackTrajectory.
Definition: Track.h:98
std::vector< anab::Calorimetry > GetRecoTrackCalorimetry(const recob::Track &track, art::Event const &evt, const std::string trackModule, const std::string caloModule) const
Get the Calorimetry(s) from a given reco track.
constexpr std::uint32_t timeHigh() const
Definition: Timestamp.h:34
const std::vector< const recob::Hit * > GetPFParticleHits(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const
Get the hits associated to the PFParticle.
bool IsClearCosmic(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const
Pandora tags and removes clear cosmics before slicing, so check if this particle is a clear cosmic...
STL namespace.
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.h:25
Particle class.
static QStrList * l
Definition: config.cpp:1044
ProtoDUNEDPAnalCosmicTree & operator=(ProtoDUNEDPAnalCosmicTree const &)=delete
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
double Phi() const
Definition: Track.h:178
double Length(size_t p=0) const
Access to various track properties.
Definition: Track.h:167
Timestamp time() const
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
double Theta() const
Access to spherical or geographical angles at vertex or at any point.
Definition: Track.h:176
const recob::Track * GetPFParticleTrack(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, const std::string trackLabel) const
Get the track associated to this particle. Returns a null pointer if not found.
double OpenAngle() const
Definition: Shower.h:202
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
Definition: DataViewImpl.h:441
p
Definition: test.py:223
SubRunNumber_t subRun() const
Definition: DataViewImpl.cc:78
bool IsPrimary() const
Returns whether the particle is the root of the flow.
Definition: PFParticle.h:86
const TVector3 & Direction() const
Definition: Shower.h:189
RunNumber_t run() const
Definition: DataViewImpl.cc:71
Vector_t EndDirection() const
Returns the direction of the trajectory at the last point.
Declaration of signal hit object.
Hierarchical representation of particle flow.
Definition: PFParticle.h:44
void analyze(art::Event const &evt) override
Point_t const & End() const
Returns the position of the last valid point of the trajectory [cm].
Provides recob::Track data product.
EventNumber_t event() const
Definition: EventID.h:116
TCEvent evt
Definition: DataStructs.cxx:7
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
unsigned int GetNumberPrimaryPFParticle(art::Event const &evt, const std::string particleLabel) const
Get the number of primary PFParticles.
Vector_t StartDirection() const
Returns the direction of the trajectory at the first point.
Point_t const & Start() const
Returns the position of the first valid point of the trajectory [cm].
int ID() const
Definition: Shower.h:187
float GetBeamCosmicScore(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel) const
Access the BDT output used to decide if a slice is beam-like or cosmic-like.
EventID id() const
Definition: Event.cc:34
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
double GetTrackMomentum(double trkrange, int pdg) const
QTextStream & endl(QTextStream &s)