BeamExample_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: BeamExample
3 // Plugin Type: analyzer (art v2_07_03)
4 // File: BeamExample_module.cc
5 //
6 // Author: Leigh Whitehead using cetskelgen
7 //
8 // Example module that will access PFParticle objects tagged as beam
9 // particles by Pandora. A lot of useful information about these
10 // objects is stored in art via associations. These complex links
11 // are encapsulated by the ProtoDUNEPFParticleUtils class used here
12 // to simplify the process
13 //
14 ////////////////////////////////////////////////////////////////////////
15 
22 #include "art_root_io/TFileService.h"
24 #include "canvas/Persistency/Common/FindManyP.h"
25 #include "fhiclcpp/ParameterSet.h"
27 
38 
43 #include "dune/Protodune/singlephase/DataUtils/ProtoDUNEDataUtils.h"
44 
45 namespace protoana {
46  class BeamExample;
47 }
48 
49 
51 public:
52 
53  explicit BeamExample(fhicl::ParameterSet const & p);
54  // The compiler-generated destructor is fine for non-base
55  // classes without bare pointers or other resource use.
56 
57  // Plugins should not be copied or assigned.
58  BeamExample(BeamExample const &) = delete;
59  BeamExample(BeamExample &&) = delete;
60  BeamExample & operator = (BeamExample const &) = delete;
61  BeamExample & operator = (BeamExample &&) = delete;
62 
63  virtual void beginJob() override;
64  virtual void endJob() override;
65 
66  // Required functions.
67  void analyze(art::Event const & e) override;
68 
69 private:
70 
71  // fcl parameters
77  bool fVerbose;
78 
80 
81 };
82 
83 
85  :
86  EDAnalyzer(p),
87  fCalorimetryTag(p.get<std::string>("CalorimetryTag")),
88  fTrackerTag(p.get<std::string>("TrackerTag")),
89  fShowerTag(p.get<std::string>("ShowerTag")),
90  fPFParticleTag(p.get<std::string>("PFParticleTag")),
91  fGeneratorTag(p.get<std::string>("GeneratorTag")),
92  fVerbose(p.get<bool>("Verbose")),
93  dataUtil(p.get<fhicl::ParameterSet>("DataUtils"))
94 {
95 
96 }
97 
99 {
100 
101 }
102 
104 {
105 
106  bool beamTriggerEvent = false;
107  // If this event is MC then we can check what the true beam particle is
108  if(!evt.isRealData()){
109  // Get the truth utility to help us out
111  // Firstly we need to get the list of MCTruth objects from the generator. The standard protoDUNE
112  // simulation has fGeneratorTag = "generator"
113  auto mcTruths = evt.getValidHandle<std::vector<simb::MCTruth>>(fGeneratorTag);
114  // mcTruths is basically a pointer to an std::vector of simb::MCTruth objects. There should only be one
115  // of these, so we pass the first element into the function to get the good particle
116  const simb::MCParticle* geantGoodParticle = truthUtil.GetGeantGoodParticle((*mcTruths)[0],evt);
117  if(geantGoodParticle != 0x0){
118  std::cout << "Found GEANT particle corresponding to the good particle with pdg = " << geantGoodParticle->PdgCode() << std::endl;
119  }
120  }
121  else{
122  // For data we can see if this event comes from a beam trigger
123  beamTriggerEvent = dataUtil.IsBeamTrigger(evt);
124  if(beamTriggerEvent){
125  std::cout << "This data event has a beam trigger" << std::endl;
126  }
127  }
128 
129  /*
130  // Now we want to access the output from Pandora. This comes in the form of particle flow objects (recob::PFParticle).
131  // The primary PFParticles are those we want to consider and these PFParticles then have a hierarchy of daughters that
132  // describe the whole interaction of a given primary particle
133  //
134  // / daughter track
135  // /
136  // primary track /
137  // ---------------- ---- daughter track
138  // \
139  // /\-
140  // /\\-- daughter shower
141  //
142  // The above primary PFParticle will have links to three daughter particles, two track-like and one shower-like
143  */
144 
145  // Get the PFParticle utility
147 
148  // Get all of the PFParticles, by default from the "pandora" product
149  auto recoParticles = evt.getValidHandle<std::vector<recob::PFParticle>>(fPFParticleTag);
150 
151  // We'd like to find the beam particle. Pandora tries to do this for us, so let's use the PFParticle utility
152  // to look for it. Pandora reconstructs slices containing one (or sometimes more) primary PFParticles. These
153  // are tagged as either beam or cosmic for ProtoDUNE. This function automatically considers only those
154  // PFParticles considered as primary
155  std::vector<const recob::PFParticle*> beamParticles = pfpUtil.GetPFParticlesFromBeamSlice(evt,fPFParticleTag);
156 
157  if(beamParticles.size() == 0){
158  std::cerr << "We found no beam particles for this event... moving on" << std::endl;
159  return;
160  }
161 
162  // We can now look at these particles
163  for(const recob::PFParticle* particle : beamParticles){
164 
165  // "particle" is the pointer to our beam particle. The recob::Track or recob::Shower object
166  // of this particle might be more helpful. These return null pointers if not track-like / shower-like
167  const recob::Track* thisTrack = pfpUtil.GetPFParticleTrack(*particle,evt,fPFParticleTag,fTrackerTag);
168  const recob::Shower* thisShower = pfpUtil.GetPFParticleShower(*particle,evt,fPFParticleTag,fShowerTag);
169  if(thisTrack != 0x0) std::cout << "Beam particle is track-like" << std::endl;
170  if(thisShower != 0x0) std::cout << "Beam particle is shower-like" << std::endl;
171 
172  // Find the particle vertex. We need the tracker tag here because we need to do a bit of
173  // additional work if the PFParticle is track-like to find the vertex.
174  const TVector3 vtx = pfpUtil.GetPFParticleVertex(*particle,evt,fPFParticleTag,fTrackerTag);
175 
176  // Now we can look for the interaction point of the particle if one exists, i.e where the particle
177  // scatters off an argon nucleus. Shower-like objects won't have an interaction point, so we can
178  // check this by making sure we get a sensible position
179  const TVector3 interactionVtx = pfpUtil.GetPFParticleSecondaryVertex(*particle,evt,fPFParticleTag,fTrackerTag);
180 
181  // Let's get the daughter PFParticles... we can do this simply without the utility
182  for(const int daughterID : particle->Daughters()){
183  // Daughter ID is the element of the original recoParticle vector
184  const recob::PFParticle *daughterParticle = &(recoParticles->at(daughterID));
185  std::cout << "Daughter " << daughterID << " has " << daughterParticle->NumDaughters() << " daughters" << std::endl;
186  }
187 
188  // For actually studying the objects, it is easier to have the daughters in their track and shower forms.
189  // We can use the utility to get a vector of track-like and a vector of shower-like daughters
190  const std::vector<const recob::Track*> trackDaughters = pfpUtil.GetPFParticleDaughterTracks(*particle,evt,fPFParticleTag,fTrackerTag);
191  const std::vector<const recob::Shower*> showerDaughters = pfpUtil.GetPFParticleDaughterShowers(*particle,evt,fPFParticleTag,fShowerTag);
192  std::cout << "Beam particle has " << trackDaughters.size() << " track-like daughters and " << showerDaughters.size() << " shower-like daughters." << std::endl;
193 
194  // At this point we have access to the primary particle track or shower, plus the track and shower daughters of this event.
195  // For other information that can be extracted from the PFParticle objects please see the ProtoDUNEPFParticleUtils header file
196  // /dunetpc/dune/ProtoDUNE/Analysis/ProtoDUNEPFParticleUtils.h
197 
198  }
199 
200 }
201 
203 {
204 
205 }
206 
208 
BeamExample & operator=(BeamExample const &)=delete
int NumDaughters() const
Returns the number of daughter particles flowing from this one.
Definition: PFParticle.h:89
const simb::MCParticle * GetGeantGoodParticle(const simb::MCTruth &genTruth, const art::Event &evt) const
BeamExample(fhicl::ParameterSet const &p)
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
void analyze(art::Event const &e) override
const TVector3 GetPFParticleVertex(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, const std::string trackLabel) const
Function to find the interaction vertex of a primary PFParticle.
STL namespace.
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.h:25
Particle class.
virtual void beginJob() override
bool isRealData() const
const double e
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
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.
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
Definition: DataViewImpl.h:441
p
Definition: test.py:223
const std::vector< const recob::PFParticle * > GetPFParticlesFromBeamSlice(art::Event const &evt, const std::string particleLabel) const
Return the pointers for the PFParticles in the beam slice. Returns an empty vector is no beam slice w...
Declaration of signal hit object.
Hierarchical representation of particle flow.
Definition: PFParticle.h:44
const std::vector< const recob::Shower * > GetPFParticleDaughterShowers(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, const std::string showerLabel) const
Get the daughter showers from the PFParticle.
Provides recob::Track data product.
const TVector3 GetPFParticleSecondaryVertex(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, const std::string trackLabel) const
Function to find the secondary interaction vertex of a primary PFParticle.
TCEvent evt
Definition: DataStructs.cxx:7
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
int bool
Definition: qglobal.h:345
const std::vector< const recob::Track * > GetPFParticleDaughterTracks(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, const std::string trackLabel) const
Get the daughter tracks from the PFParticle.
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
virtual void endJob() override
QTextStream & endl(QTextStream &s)
bool IsBeamTrigger(art::Event const &evt) const
protoana::ProtoDUNEDataUtils dataUtil