Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
ConsolidatedPFParticleAnalysisTemplate_module.cc
Go to the documentation of this file.
1
7#include "art/Framework/Core/EDAnalyzer.h"
8#include "art/Framework/Core/ModuleMacros.h"
9
10#include "lardataobj/RecoBase/PFParticle.h"
11#include "lardataobj/RecoBase/Shower.h"
12#include "lardataobj/RecoBase/Track.h"
13
14#include <string>
15
16//------------------------------------------------------------------------------------------------------------------------------------------
17
18namespace lar_pandora {
19
23 class ConsolidatedPFParticleAnalysisTemplate : public art::EDAnalyzer {
24 public:
25 typedef art::Handle<std::vector<recob::PFParticle>> PFParticleHandle;
26 typedef std::map<size_t, art::Ptr<recob::PFParticle>> PFParticleIdMap;
27 typedef std::vector<art::Ptr<recob::PFParticle>> PFParticleVector;
28 typedef std::vector<art::Ptr<recob::Track>> TrackVector;
29 typedef std::vector<art::Ptr<recob::Shower>> ShowerVector;
30
36 ConsolidatedPFParticleAnalysisTemplate(fhicl::ParameterSet const& pset);
37
43 void reconfigure(fhicl::ParameterSet const& pset);
44
50 void analyze(const art::Event& evt);
51
52 private:
59 void GetPFParticleIdMap(const PFParticleHandle& pfParticleHandle,
60 PFParticleIdMap& pfParticleMap);
61
68 void PrintOutScores(const art::Event& evt, const PFParticleHandle& pfParticleHandle) const;
69
77 void GetFinalStatePFParticleVectors(const PFParticleIdMap& pfParticleMap,
78 PFParticleVector& crParticles,
79 PFParticleVector& nuParticles);
80
90 void CollectTracksAndShowers(const PFParticleVector& particles,
91 const PFParticleHandle& pfParticleHandle,
92 const art::Event& evt,
93 TrackVector& tracks,
94 ShowerVector& showers);
95
96 std::string m_pandoraLabel;
97 std::string m_trackLabel;
98 std::string m_showerLabel;
100 };
101
103
104} // namespace lar_pandora
105
106//------------------------------------------------------------------------------------------------------------------------------------------
107// implementation follows
108
109#include "art/Framework/Principal/Event.h"
110#include "art/Framework/Principal/Handle.h"
111#include "art/Framework/Services/Registry/ServiceHandle.h"
112#include "art_root_io/TFileDirectory.h"
113#include "art_root_io/TFileService.h"
114#include "canvas/Persistency/Common/FindManyP.h"
115#include "fhiclcpp/ParameterSet.h"
116#include "messagefacility/MessageLogger/MessageLogger.h"
117
118#include "lardataobj/RecoBase/PFParticleMetadata.h"
119
120#include "Pandora/PdgTable.h"
121
122#include <iostream>
123
124namespace lar_pandora {
125
127 fhicl::ParameterSet const& pset)
128 : art::EDAnalyzer(pset)
129 {
130 this->reconfigure(pset);
131 }
132
133 //------------------------------------------------------------------------------------------------------------------------------------------
134
135 void ConsolidatedPFParticleAnalysisTemplate::reconfigure(fhicl::ParameterSet const& pset)
136 {
137 m_pandoraLabel = pset.get<std::string>("PandoraLabel");
138 m_trackLabel = pset.get<std::string>("TrackLabel");
139 m_showerLabel = pset.get<std::string>("ShowerLabel");
140 m_printOutScores = pset.get<bool>("PrintOutScores", true);
141 }
142
143 //------------------------------------------------------------------------------------------------------------------------------------------
144
146 {
147 // Collect the PFParticles from the event
148 PFParticleHandle pfParticleHandle;
149 evt.getByLabel(m_pandoraLabel, pfParticleHandle);
150
151 if (!pfParticleHandle.isValid()) {
152 mf::LogDebug("ConsolidatedPFParticleAnalysisTemplate")
153 << " Failed to find the PFParticles." << std::endl;
154 return;
155 }
156
157 // Produce a map of the PFParticle IDs for fast navigation through the hierarchy
158 PFParticleIdMap pfParticleMap;
159 this->GetPFParticleIdMap(pfParticleHandle, pfParticleMap);
160
162 if (m_printOutScores) this->PrintOutScores(evt, pfParticleHandle);
163
164 // Produce two PFParticle vectors containing final-state particles:
165 // 1. Particles identified as cosmic-rays - recontructed under cosmic-hypothesis
166 // 2. Daughters of the neutrino PFParticle - reconstructed under the neutrino hypothesis
167 std::vector<art::Ptr<recob::PFParticle>> crParticles;
168 std::vector<art::Ptr<recob::PFParticle>> nuParticles;
169 this->GetFinalStatePFParticleVectors(pfParticleMap, crParticles, nuParticles);
170
171 // Use as required!
172 // -----------------------------
173 // What follows is an example showing how one might access the reconstructed neutrino final-state tracks and showers
174
175 // These are the vectors to hold the tracks and showers for the final-states of the reconstructed neutrino
176 std::vector<art::Ptr<recob::Track>> tracks;
177 std::vector<art::Ptr<recob::Shower>> showers;
178 this->CollectTracksAndShowers(nuParticles, pfParticleHandle, evt, tracks, showers);
179
180 // Print a summary of the consolidated event
181 std::cout << "Consolidated event summary:" << std::endl;
182 std::cout << " - Number of primary cosmic-ray PFParticles : " << crParticles.size()
183 << std::endl;
184 std::cout << " - Number of neutrino final-state PFParticles : " << nuParticles.size()
185 << std::endl;
186 std::cout << " ... of which are track-like : " << tracks.size() << std::endl;
187 std::cout << " ... of which are showers-like : " << showers.size() << std::endl;
188 }
189
190 //------------------------------------------------------------------------------------------------------------------------------------------
191
193 const PFParticleHandle& pfParticleHandle,
194 PFParticleIdMap& pfParticleMap)
195 {
196 for (unsigned int i = 0; i < pfParticleHandle->size(); ++i) {
197 const art::Ptr<recob::PFParticle> pParticle(pfParticleHandle, i);
198 if (!pfParticleMap.insert(PFParticleIdMap::value_type(pParticle->Self(), pParticle)).second) {
199 throw cet::exception("ConsolidatedPFParticleAnalysisTemplate")
200 << " Unable to get PFParticle ID map, the input PFParticle collection has repeat IDs!";
201 }
202 }
203 }
204
205 //------------------------------------------------------------------------------------------------------------------------------------------
206
208 const art::Event& evt,
209 const PFParticleHandle& pfParticleHandle) const
210 {
211 // Get the associations between PFParticles and larpandoraobj::PFParticleMetadata
212 art::FindManyP<larpandoraobj::PFParticleMetadata> pfPartToMetadataAssoc(
213 pfParticleHandle, evt, m_pandoraLabel);
214
215 for (unsigned int i = 0; i < pfParticleHandle->size(); ++i) {
216 const std::vector<art::Ptr<larpandoraobj::PFParticleMetadata>>& pfParticleMetadataList(
217 pfPartToMetadataAssoc.at(i));
218 if (!pfParticleMetadataList.empty()) {
219 const art::Ptr<recob::PFParticle> pParticle(pfParticleHandle, i);
220 for (unsigned int j = 0; j < pfParticleMetadataList.size(); ++j) {
221 const art::Ptr<larpandoraobj::PFParticleMetadata>& pfParticleMetadata(
222 pfParticleMetadataList.at(j));
223 const larpandoraobj::PFParticleMetadata::PropertiesMap& pfParticlePropertiesMap(
224 pfParticleMetadata->GetPropertiesMap());
225 if (!pfParticlePropertiesMap.empty())
226 std::cout << " Found PFParticle " << pParticle->Self() << " with: " << std::endl;
227 for (larpandoraobj::PFParticleMetadata::PropertiesMap::const_iterator it =
228 pfParticlePropertiesMap.begin();
229 it != pfParticlePropertiesMap.end();
230 ++it)
231 std::cout << " - " << it->first << " = " << it->second << std::endl;
232 }
233 }
234 }
235 }
236
237 //------------------------------------------------------------------------------------------------------------------------------------------
238
240 const PFParticleIdMap& pfParticleMap,
241 PFParticleVector& crParticles,
242 PFParticleVector& nuParticles)
243 {
244 for (PFParticleIdMap::const_iterator it = pfParticleMap.begin(); it != pfParticleMap.end();
245 ++it) {
246 const art::Ptr<recob::PFParticle> pParticle(it->second);
247
248 // Only look for primary particles
249 if (!pParticle->IsPrimary()) continue;
250
251 // Check if this particle is identified as the neutrino
252 const int pdg(pParticle->PdgCode());
253 const bool isNeutrino(std::abs(pdg) == pandora::NU_E || std::abs(pdg) == pandora::NU_MU ||
254 std::abs(pdg) == pandora::NU_TAU);
255
256 // All non-neutrino primary particles are reconstructed under the cosmic hypothesis
257 if (!isNeutrino) {
258 crParticles.push_back(pParticle);
259 continue;
260 }
261
262 // ATTN. We are filling nuParticles under the assumption that there is only one reconstructed neutrino identified per event.
263 // If this is not the case please handle accordingly
264 if (!nuParticles.empty()) {
265 throw cet::exception("ConsolidatedPFParticleAnalysisTemplate")
266 << " This event contains multiple reconstructed neutrinos!";
267 }
268
269 // Add the daughters of the neutrino PFParticle to the nuPFParticles vector
270 for (const size_t daughterId : pParticle->Daughters()) {
271 if (pfParticleMap.find(daughterId) == pfParticleMap.end())
272 throw cet::exception("ConsolidatedPFParticleAnalysisTemplate")
273 << " Invalid PFParticle collection!";
274
275 nuParticles.push_back(pfParticleMap.at(daughterId));
276 }
277 }
278 }
279
280 //------------------------------------------------------------------------------------------------------------------------------------------
281
283 const PFParticleVector& particles,
284 const PFParticleHandle& pfParticleHandle,
285 const art::Event& evt,
286 TrackVector& tracks,
287 ShowerVector& showers)
288 {
289 // Get the associations between PFParticles and tracks/showers from the event
290 art::FindManyP<recob::Track> pfPartToTrackAssoc(pfParticleHandle, evt, m_trackLabel);
291 art::FindManyP<recob::Shower> pfPartToShowerAssoc(pfParticleHandle, evt, m_showerLabel);
292
293 for (const art::Ptr<recob::PFParticle>& pParticle : particles) {
294 const std::vector<art::Ptr<recob::Track>> associatedTracks(
295 pfPartToTrackAssoc.at(pParticle.key()));
296 const std::vector<art::Ptr<recob::Shower>> associatedShowers(
297 pfPartToShowerAssoc.at(pParticle.key()));
298 const unsigned int nTracks(associatedTracks.size());
299 const unsigned int nShowers(associatedShowers.size());
300
301 // Check if the PFParticle has no associated tracks or showers
302 if (nTracks == 0 && nShowers == 0) {
303 mf::LogDebug("ConsolidatedPFParticleAnalysisTemplate")
304 << " No tracks or showers were associated to PFParticle " << pParticle->Self()
305 << std::endl;
306 continue;
307 }
308
309 // Check if there is an associated track
310 if (nTracks == 1 && nShowers == 0) {
311 tracks.push_back(associatedTracks.front());
312 continue;
313 }
314
315 // Check if there is an associated shower
316 if (nTracks == 0 && nShowers == 1) {
317 showers.push_back(associatedShowers.front());
318 continue;
319 }
320
321 throw cet::exception("ConsolidatedPFParticleAnalysisTemplate")
322 << " There were " << nTracks << " tracks and " << nShowers
323 << " showers associated with PFParticle " << pParticle->Self();
324 }
325 }
326
327} //namespace lar_pandora
std::string m_trackLabel
The label for the track producer from PFParticles.
void PrintOutScores(const art::Event &evt, const PFParticleHandle &pfParticleHandle) const
Print out scores in PFParticleMetadata.
bool m_printOutScores
Option to investigate the associations to scores for PFParticles.
std::string m_showerLabel
The label for the shower producer from PFParticles.
void GetPFParticleIdMap(const PFParticleHandle &pfParticleHandle, PFParticleIdMap &pfParticleMap)
Produce a mapping from PFParticle ID to the art ptr to the PFParticle itself for fast navigation.
void CollectTracksAndShowers(const PFParticleVector &particles, const PFParticleHandle &pfParticleHandle, const art::Event &evt, TrackVector &tracks, ShowerVector &showers)
Collect associated tracks and showers to particles in an input particle vector.
void reconfigure(fhicl::ParameterSet const &pset)
Configure memeber variables using FHiCL parameters.
void GetFinalStatePFParticleVectors(const PFParticleIdMap &pfParticleMap, PFParticleVector &crParticles, PFParticleVector &nuParticles)
Produce a mapping from PFParticle ID to the art ptr to the PFParticle itself for fast navigation.