Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
HierarchyValidationAlgorithm.cc
Go to the documentation of this file.
1
10
12
15
16using namespace pandora;
17
18namespace lar_content
19{
20
22 m_event{-1},
23 m_detector{"dune_fd_hd"},
24 m_writeTree{false},
25 m_foldToPrimaries{false},
26 m_foldDynamic{false},
27 m_foldToLeadingShowers{false},
28 m_validateEvent{false},
29 m_validateMC{false},
30 m_minPurity{0.8f},
31 m_minCompleteness{0.65f}
32{
33}
34
35//------------------------------------------------------------------------------------------------------------------------------------------
36
38{
39 if (m_writeTree)
40 {
41 PANDORA_MONITORING_API(SaveTree(this->GetPandora(), m_treename.c_str(), m_filename.c_str(), "UPDATE"));
42 }
43}
44
45//------------------------------------------------------------------------------------------------------------------------------------------
46
48{
49 ++m_event;
50 const CaloHitList *pCaloHitList(nullptr);
51 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, m_caloHitListName, pCaloHitList));
52 const MCParticleList *pMCParticleList(nullptr);
53 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*this, pMCParticleList));
54 const PfoList *pPfoList(nullptr);
55 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, m_pfoListName, pPfoList));
56
59 foldParameters.m_foldToTier = true;
60 else if (m_foldDynamic)
61 foldParameters.m_foldDynamic = true;
63 foldParameters.m_foldToLeadingShowers = true;
65 LArHierarchyHelper::FillMCHierarchy(*pMCParticleList, *pCaloHitList, foldParameters, mcHierarchy);
67 LArHierarchyHelper::FillRecoHierarchy(*pPfoList, foldParameters, recoHierarchy);
69 LArHierarchyHelper::MatchInfo matchInfo(mcHierarchy, recoHierarchy, quality);
71 matchInfo.Print(mcHierarchy);
72
73#ifdef MONITORING
75 this->EventValidation(matchInfo);
76 else if (m_validateMC)
77 this->MCValidation(matchInfo);
78#endif
79
80 return STATUS_CODE_SUCCESS;
81}
82
83//------------------------------------------------------------------------------------------------------------------------------------------
84
85#ifdef MONITORING
86void HierarchyValidationAlgorithm::EventValidation(const LArHierarchyHelper::MatchInfo &matchInfo) const
87{
88 if (m_writeTree)
89 {
90 int interaction{0};
91 MCParticleList rootMCParticles;
92 matchInfo.GetRootMCParticles(rootMCParticles);
93
94 const LArHierarchyHelper::RecoHierarchy &recoHierarchy{matchInfo.GetRecoHierarchy()};
95 PfoList rootPfos;
96 recoHierarchy.GetRootPfos(rootPfos);
97 std::map<const LArHierarchyHelper::RecoHierarchy::Node *, const ParticleFlowObject *> recoNodeToRootMap;
98 for (const ParticleFlowObject *const pRoot : rootPfos)
99 {
101 recoHierarchy.GetFlattenedNodes(pRoot, nodes);
102 for (const LArHierarchyHelper::RecoHierarchy::Node *pNode : nodes)
103 recoNodeToRootMap[pNode] = pRoot;
104 }
105
106 std::set<const pandora::ParticleFlowObject *> matchedRecoSliceRoots;
107 for (const MCParticle *const pRoot : rootMCParticles)
108 {
109 const LArHierarchyHelper::MCMatchesVector &matches{matchInfo.GetMatches(pRoot)};
110
111 MCParticleList primaries;
112 for (const LArHierarchyHelper::MCMatches &match : matches)
113 {
114 const LArHierarchyHelper::MCHierarchy::Node *pMCNode{match.GetMC()};
115 if (pMCNode->GetHierarchyTier() == 1)
116 {
117 const MCParticle *const pLeadingMC{pMCNode->GetLeadingMCParticle()};
118 primaries.emplace_back(pLeadingMC);
119 }
120 }
122 const InteractionDescriptor descriptor{LArInteractionTypeHelper::GetInteractionDescriptor(primaries)};
123
124 const int isCC{descriptor.IsCC()};
125 const int isQE{descriptor.IsQE()};
126 const int isResonant{descriptor.IsResonant()};
127 const int isDIS{descriptor.IsDIS()};
128 const int isCoherent{descriptor.IsCoherent()};
129 const int isNuMu{descriptor.IsMuonNeutrino()};
130 const int isNuE{descriptor.IsElectronNeutrino()};
131 const int nPiZero{static_cast<int>(descriptor.GetNumPiZero())};
132 const int nPiPlus{static_cast<int>(descriptor.GetNumPiPlus())};
133 const int nPiMinus{static_cast<int>(descriptor.GetNumPiMinus())};
134 const int nPhotons{static_cast<int>(descriptor.GetNumPhotons())};
135 const int nProtons{static_cast<int>(descriptor.GetNumProtons())};
136
137 std::set<const LArHierarchyHelper::MCHierarchy::Node *> trackNodeSet, showerNodeSet;
138 int nGoodTrackMatches{0}, nGoodShowerMatches{0};
139 int nGoodMatches{0}, nPoorMatches{0}, nUnmatched{0};
140 int nGoodTier1Matches{0}, nTier1Nodes{0};
141 int nGoodTier1TrackMatches{0}, nTier1TrackNodes{0};
142 int nGoodTier1ShowerMatches{0}, nTier1ShowerNodes{0};
143 int hasLeadingMuon{0}, hasLeadingElectron{0}, isLeadingLeptonCorrect{0};
144 for (const LArHierarchyHelper::MCMatches &mcMatch : matches)
145 {
146 const LArHierarchyHelper::MCHierarchy::Node *pNode{mcMatch.GetMC()};
147
148 for (const LArHierarchyHelper::RecoHierarchy::Node *pReco : mcMatch.GetRecoMatches())
149 matchedRecoSliceRoots.insert(recoNodeToRootMap[pReco]);
150
151 const int nReco{static_cast<int>(mcMatch.GetRecoMatches().size())};
152 const bool isQuality{mcMatch.IsQuality(matchInfo.GetQualityCuts())};
153 if (nReco == 1 && isQuality)
154 ++nGoodMatches;
155 else if (nReco >= 1)
156 ++nPoorMatches;
157 else
158 ++nUnmatched;
159 if (pNode->GetHierarchyTier() == 1)
160 {
161 ++nTier1Nodes;
162 if (nReco == 1 && isQuality)
163 ++nGoodTier1Matches;
164 }
165
166 const int pdg{std::abs(pNode->GetParticleId())};
167 if (pNode->IsLeadingLepton())
168 {
169 if (pdg == MU_MINUS)
170 hasLeadingMuon = 1;
171 else if (pdg == E_MINUS)
172 hasLeadingElectron = 1;
173 isLeadingLeptonCorrect = nReco == 1 ? 1 : 0;
174 }
175
176 if (pdg == PHOTON || pdg == E_MINUS)
177 {
178 showerNodeSet.insert(pNode);
179 if (nReco == 1 && isQuality)
180 {
181 ++nGoodShowerMatches;
182 if (pNode->GetHierarchyTier() == 1)
183 ++nGoodTier1ShowerMatches;
184 }
185 if (pNode->GetHierarchyTier() == 1)
186 ++nTier1ShowerNodes;
187 }
188 else
189 {
190 trackNodeSet.insert(pNode);
191 if (nReco == 1 && isQuality)
192 {
193 ++nGoodTrackMatches;
194 if (pNode->GetHierarchyTier() == 1)
195 ++nGoodTier1TrackMatches;
196 }
197 if (pNode->GetHierarchyTier() == 1)
198 ++nTier1TrackNodes;
199 }
200 }
201
202 const int nNodes{static_cast<int>(matchInfo.GetNMCNodes(pRoot))};
203 const int nTrackNodes{static_cast<int>(trackNodeSet.size())}, nShowerNodes{static_cast<int>(showerNodeSet.size())};
204 const int nRecoSlices{static_cast<int>(matchedRecoSliceRoots.size())};
205 const CartesianVector &trueVertex{pRoot->GetVertex()};
206 float vtxDx{std::numeric_limits<float>::max()};
207 float vtxDy{std::numeric_limits<float>::max()};
208 float vtxDz{std::numeric_limits<float>::max()};
209 float vtxDr{std::numeric_limits<float>::max()};
210 const int isFiducial{LArVertexHelper::IsInFiducialVolume(this->GetPandora(), trueVertex, m_detector)};
211
212 for (const ParticleFlowObject *pRootPfo : matchedRecoSliceRoots)
213 {
214 const CartesianVector &recoVertex{LArPfoHelper::GetVertex(pRootPfo)->GetPosition()};
215 const float dx{recoVertex.GetX() - trueVertex.GetX()};
216 const float dy{recoVertex.GetY() - trueVertex.GetY()};
217 const float dz{recoVertex.GetZ() - trueVertex.GetZ()};
218 const float dr{std::sqrt(dx * dx + dy * dy + dz * dz)};
219 if (dr < vtxDr)
220 {
221 vtxDx = dx;
222 vtxDy = dy;
223 vtxDz = dz;
224 vtxDr = dr;
225 }
226 }
227
228 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "event", m_event));
229 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "interaction", interaction));
230 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nRecoSlices", nRecoSlices));
231 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "isCC", isCC));
232 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "isQE", isQE));
233 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "isResonant", isResonant));
234 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "isDIS", isDIS));
235 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "isCoherent", isCoherent));
236 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "isNuMu", isNuMu));
237 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "isNuE", isNuE));
238 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nPiZero", nPiZero));
239 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nPiPlus", nPiPlus));
240 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nPiMinus", nPiMinus));
241 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nPhotons", nPhotons));
242 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nProtons", nProtons));
243 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "isFiducial", isFiducial));
244 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "vtxDx", vtxDx));
245 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "vtxDy", vtxDy));
246 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "vtxDz", vtxDz));
247 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "vtxDr", vtxDr));
248 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nGoodMatches", nGoodMatches));
249 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nPoorMatches", nPoorMatches));
250 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nUnmatched", nUnmatched));
251 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nNodes", nNodes));
252 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nGoodTier1Matches", nGoodTier1Matches));
253 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nTier1Nodes", nTier1Nodes));
254 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nGoodTrackMatches", nGoodTrackMatches));
255 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nGoodShowerMatches", nGoodShowerMatches));
256 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nTrackNodes", nTrackNodes));
257 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nShowerNodes", nShowerNodes));
258 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nGoodTier1TrackMatches", nGoodTier1TrackMatches));
259 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nTier1TrackNodes", nTier1TrackNodes));
260 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nGoodTier1ShowerMatches", nGoodTier1ShowerMatches));
261 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nTier1ShowerNodes", nTier1ShowerNodes));
262 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "hasLeadingMuon", hasLeadingMuon));
263 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "hasLeadingElectron", hasLeadingElectron));
264 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "isLeadingLeptonCorrect", isLeadingLeptonCorrect));
265 PANDORA_MONITORING_API(FillTree(this->GetPandora(), m_treename.c_str()));
266 ++interaction;
267 }
268 }
269}
270
271//------------------------------------------------------------------------------------------------------------------------------------------
272
273void HierarchyValidationAlgorithm::MCValidation(const LArHierarchyHelper::MatchInfo &matchInfo) const
274{
275 if (m_writeTree)
276 {
277 int interaction{0};
278 MCParticleList rootMCParticles;
279 matchInfo.GetRootMCParticles(rootMCParticles);
280 PfoList rootPfos;
281 const LArHierarchyHelper::RecoHierarchy &recoHierarchy{matchInfo.GetRecoHierarchy()};
282 recoHierarchy.GetRootPfos(rootPfos);
283 std::map<const LArHierarchyHelper::RecoHierarchy::Node *, const ParticleFlowObject *> recoNodeToRootMap;
284 for (const ParticleFlowObject *const pRoot : rootPfos)
285 {
287 recoHierarchy.GetFlattenedNodes(pRoot, nodes);
288 for (const LArHierarchyHelper::RecoHierarchy::Node *pNode : nodes)
289 recoNodeToRootMap[pNode] = pRoot;
290 }
291
292 for (const MCParticle *const pRoot : rootMCParticles)
293 {
294 MCParticleList primaries;
295 for (const LArHierarchyHelper::MCMatches &matches : matchInfo.GetMatches(pRoot))
296 {
297 const LArHierarchyHelper::MCHierarchy::Node *pMCNode{matches.GetMC()};
298 if (pMCNode->GetHierarchyTier() == 1)
299 {
300 const MCParticle *const pLeadingMC{pMCNode->GetLeadingMCParticle()};
301 primaries.emplace_back(pLeadingMC);
302 }
303 }
305 const InteractionDescriptor descriptor{LArInteractionTypeHelper::GetInteractionDescriptor(primaries)};
306
307 for (const LArHierarchyHelper::MCMatches &matches : matchInfo.GetMatches(pRoot))
308 {
309 const LArHierarchyHelper::MCHierarchy::Node *pMCNode{matches.GetMC()};
310 const int isTestBeam{pMCNode->IsTestBeamParticle() ? 1 : 0};
311 const int isCosmicRay{!isTestBeam && pMCNode->IsCosmicRay() ? 1 : 0};
312 const int isNeutrinoInt{!(isTestBeam || isCosmicRay) ? 1 : 0};
313 const int mcId{pMCNode->GetId()};
314 const int pdg{pMCNode->GetParticleId()};
315 const int tier{pMCNode->GetHierarchyTier()};
316 const int mcHits{static_cast<int>(pMCNode->GetCaloHits().size())};
317 const int isLeadingLepton{pMCNode->IsLeadingLepton() ? 1 : 0};
318
319 const MCParticle *const pLeadingMC{pMCNode->GetLeadingMCParticle()};
320 const MCParticleList &parentList{pLeadingMC->GetParentList()};
321 const int isElectron{std::abs(pLeadingMC->GetParticleId()) == E_MINUS ? 1 : 0};
322 const int hasMuonParent{parentList.size() == 1 && std::abs(parentList.front()->GetParticleId()) == MU_MINUS ? 1 : 0};
323 const int isMichel{isElectron && hasMuonParent && LArMCParticleHelper::IsDecay(pLeadingMC) ? 1 : 0};
324 const float mcMomentum{pLeadingMC->GetMomentum().GetMagnitude()};
325
326 const LArHierarchyHelper::RecoHierarchy::NodeVector &nodeVector{matches.GetRecoMatches()};
327 const int nMatches{static_cast<int>(nodeVector.size())};
328 IntVector recoSliceIdVector, recoIdVector, nRecoHitsVector, nSharedHitsVector;
329 FloatVector purityVector, completenessVector;
330 FloatVector purityAdcVector, completenessAdcVector;
331 FloatVector purityVectorU, purityVectorV, purityVectorW, completenessVectorU, completenessVectorV, completenessVectorW;
332 FloatVector purityAdcVectorU, purityAdcVectorV, purityAdcVectorW, completenessAdcVectorU, completenessAdcVectorV, completenessAdcVectorW;
333 const CartesianVector &trueVertex{pLeadingMC->GetVertex()};
334 float vtxDx{0.f}, vtxDy{0.f}, vtxDz{0.f}, vtxDr{0.f};
335
336 const int isCC{descriptor.IsCC()};
337 const int isQE{descriptor.IsQE()};
338 const int isResonant{descriptor.IsResonant()};
339 const int isDIS{descriptor.IsDIS()};
340 const int isCoherent{descriptor.IsCoherent()};
341 const int isNuMu{descriptor.IsMuonNeutrino()};
342 const int isNuE{descriptor.IsElectronNeutrino()};
343 const int nPiZero{static_cast<int>(descriptor.GetNumPiZero())};
344 const int nPiPlus{static_cast<int>(descriptor.GetNumPiPlus())};
345 const int nPiMinus{static_cast<int>(descriptor.GetNumPiMinus())};
346 const int nPhotons{static_cast<int>(descriptor.GetNumPhotons())};
347 const int nProtons{static_cast<int>(descriptor.GetNumProtons())};
348
349 for (const LArHierarchyHelper::RecoHierarchy::Node *pRecoNode : nodeVector)
350 {
351 const int sliceId{static_cast<int>(
352 std::distance(rootPfos.begin(), std::find(rootPfos.begin(), rootPfos.end(), recoNodeToRootMap[pRecoNode])))};
353 recoSliceIdVector.emplace_back(sliceId);
354 recoIdVector.emplace_back(pRecoNode->GetParticleId());
355 nRecoHitsVector.emplace_back(static_cast<int>(pRecoNode->GetCaloHits().size()));
356 nSharedHitsVector.emplace_back(static_cast<int>(matches.GetSharedHits(pRecoNode)));
357 purityVector.emplace_back(matches.GetPurity(pRecoNode));
358 completenessVector.emplace_back(matches.GetCompleteness(pRecoNode));
359 purityAdcVector.emplace_back(matches.GetPurity(pRecoNode, true));
360 completenessAdcVector.emplace_back(matches.GetCompleteness(pRecoNode, true));
361 purityVectorU.emplace_back(matches.GetPurity(pRecoNode, TPC_VIEW_U));
362 purityVectorV.emplace_back(matches.GetPurity(pRecoNode, TPC_VIEW_V));
363 purityVectorW.emplace_back(matches.GetPurity(pRecoNode, TPC_VIEW_W));
364 completenessVectorU.emplace_back(matches.GetCompleteness(pRecoNode, TPC_VIEW_U));
365 completenessVectorV.emplace_back(matches.GetCompleteness(pRecoNode, TPC_VIEW_V));
366 completenessVectorW.emplace_back(matches.GetCompleteness(pRecoNode, TPC_VIEW_W));
367 purityAdcVectorU.emplace_back(matches.GetPurity(pRecoNode, TPC_VIEW_U, true));
368 purityAdcVectorV.emplace_back(matches.GetPurity(pRecoNode, TPC_VIEW_V, true));
369 purityAdcVectorW.emplace_back(matches.GetPurity(pRecoNode, TPC_VIEW_W, true));
370 completenessAdcVectorU.emplace_back(matches.GetCompleteness(pRecoNode, TPC_VIEW_U, true));
371 completenessAdcVectorV.emplace_back(matches.GetCompleteness(pRecoNode, TPC_VIEW_V, true));
372 completenessAdcVectorW.emplace_back(matches.GetCompleteness(pRecoNode, TPC_VIEW_W, true));
373 if (nMatches > 0)
374 {
375 const CartesianVector recoVertex{LArPfoHelper::GetVertex(pRecoNode->GetLeadingPfo())->GetPosition()};
376 vtxDx = recoVertex.GetX() - trueVertex.GetX();
377 vtxDy = recoVertex.GetY() - trueVertex.GetY();
378 vtxDz = recoVertex.GetZ() - trueVertex.GetZ();
379 vtxDr = std::sqrt(vtxDx * vtxDx + vtxDy * vtxDy + vtxDz * vtxDz);
380 }
381 }
382
383 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "event", m_event));
384 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "interaction", interaction));
385 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "mcId", mcId));
386 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "mcPDG", pdg));
387 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "mcTier", tier));
388 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "mcNHits", mcHits));
389 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "mcMomentum", mcMomentum));
390 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "isNuInteration", isNeutrinoInt));
391 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "isCosmicRay", isCosmicRay));
392 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "isTestBeam", isTestBeam));
393 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "isLeadingLepton", isLeadingLepton));
394 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "isMichel", isMichel));
395 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nMatches", nMatches));
396 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "recoSliceIdVector", &recoSliceIdVector));
397 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "recoIdVector", &recoIdVector));
398 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nRecoHitsVector", &nRecoHitsVector));
399 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nSharedHitsVector", &nSharedHitsVector));
400 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "purityVector", &purityVector));
401 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "completenessVector", &completenessVector));
402 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "purityAdcVector", &purityAdcVector));
403 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "completenessAdcVector", &completenessAdcVector));
404 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "purityVectorU", &purityVectorU));
405 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "purityVectorV", &purityVectorV));
406 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "purityVectorW", &purityVectorW));
407 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "completenessVectorU", &completenessVectorU));
408 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "completenessVectorV", &completenessVectorV));
409 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "completenessVectorW", &completenessVectorW));
410 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "purityAdcVectorU", &purityAdcVectorU));
411 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "purityAdcVectorV", &purityAdcVectorV));
412 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "purityAdcVectorW", &purityAdcVectorW));
413 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "completenessAdcVectorU", &completenessAdcVectorU));
414 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "completenessAdcVectorV", &completenessAdcVectorV));
415 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "completenessAdcVectorW", &completenessAdcVectorW));
416 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "vtxDx", vtxDx));
417 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "vtxDy", vtxDy));
418 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "vtxDz", vtxDz));
419 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "vtxDr", vtxDr));
420 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "isCC", isCC));
421 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "isQE", isQE));
422 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "isResonant", isResonant));
423 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "isDIS", isDIS));
424 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "isCoherent", isCoherent));
425 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "isNuMu", isNuMu));
426 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "isNuE", isNuE));
427 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nPiZero", nPiZero));
428 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nPiPlus", nPiPlus));
429 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nPiMinus", nPiMinus));
430 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nPhotons", nPhotons));
431 PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treename.c_str(), "nProtons", nProtons));
432 PANDORA_MONITORING_API(FillTree(this->GetPandora(), m_treename.c_str()));
433 }
434 ++interaction;
435 }
436 }
437}
438#endif
439
440//------------------------------------------------------------------------------------------------------------------------------------------
441
443{
444 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "CaloHitListName", m_caloHitListName));
445 if (m_caloHitListName.empty())
446 m_caloHitListName = "CaloHitList2D";
447 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "PfoListName", m_pfoListName));
448 if (m_pfoListName.empty())
449 m_pfoListName = "RecreatedPfos";
450
451 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "Detector", m_detector));
452
453 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ValidateEvent", m_validateEvent));
454 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ValidateMC", m_validateMC));
455
456 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "WriteTree", m_writeTree));
457 if (m_writeTree)
458 {
459 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "FileName", m_filename));
460 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "TreeName", m_treename));
462 {
463 std::cout << "Error: WriteTree requested but no tree names found" << std::endl;
464 return STATUS_CODE_NOT_FOUND;
465 }
466 else if (m_validateEvent && m_validateMC)
467 {
468 std::cout << "Error: Both event-level and MC-level validation requested simulataneously" << std::endl;
469 return STATUS_CODE_INVALID_PARAMETER;
470 }
471 }
472
473 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "FoldToPrimaries", m_foldToPrimaries));
474 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "FoldDynamic", m_foldDynamic));
476 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "FoldToLeadingShowers", m_foldToLeadingShowers));
477
478 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinPurity", m_minPurity));
479 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinCompleteness", m_minCompleteness));
480
481 return STATUS_CODE_SUCCESS;
482}
483
484} // namespace lar_content
Grouping of header files for many classes of use in particle flow algorithms.
#define PANDORA_MONITORING_API(command)
Header file for the hierarchy validation algorithm.
Header file for the interaction type helper class.
Header file for the vertex helper class.
#define PANDORA_RETURN_RESULT_IF_AND_IF(StatusCode1, StatusCode2, Operator, Command)
Definition StatusCodes.h:31
#define PANDORA_RETURN_RESULT_IF(StatusCode1, Operator, Command)
Definition StatusCodes.h:19
std::vector< float > FloatVector
Definition Validation.h:14
static pandora::StatusCode GetCurrentList(const pandora::Algorithm &algorithm, const T *&pT)
Get the current list.
static pandora::StatusCode GetList(const pandora::Algorithm &algorithm, const std::string &listName, const T *&pT)
Get a named list.
pandora::StatusCode Run()
Run the algorithm.
float m_minPurity
Minimum purity to tag a node as being of good quality.
std::string m_treename
The name of the ROOT tree to write.
bool m_validateEvent
Whether to validate at the level of an event.
std::string m_filename
The name of the ROOT file to write.
bool m_validateMC
Whether to validate at the level of MC nodes.
float m_minCompleteness
Minimum completeness to tag a node as being of good quality.
bool m_foldToLeadingShowers
Whether or not to fold the hierarchy back to leading shower particles.
bool m_foldToPrimaries
Whether or not to fold the hierarchy back to primary particles.
bool m_writeTree
Whether or not to output validation information to a ROOT file.
std::string m_caloHitListName
Name of input calo hit list.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
bool m_foldDynamic
Whether or not to fold the hierarchy dynamically.
bool IsCC() const
Whether or not the interaction is CC.
bool m_foldToTier
Whether or not to apply folding based on particle tier.
bool m_foldDynamic
Whether or not to use process and topological information to make folding decisions.
bool m_foldToLeadingShowers
Whether or not to fold shower children to the leading shower particle.
void Print(const MCHierarchy &mcHierarchy) const
Prints information about which reco nodes are matched to the MC nodes, information about hit sharing,...
void GetRootMCParticles(pandora::MCParticleList &rootMCParticles) const
Retrieve the root MC particles of the interaction hierarchies.
unsigned int GetNMCNodes(const pandora::MCParticle *const pRoot) const
Retrieve the number of MC nodes available to match.
const MCMatchesVector & GetMatches(const pandora::MCParticle *const pRoot) const
Retrieve the vector of matches (this will include null matches - i.e. MC nodes with no corresponding ...
const RecoHierarchy & GetRecoHierarchy() const
Retrieve the reco hierarchy used for the matching.
const QualityCuts & GetQualityCuts() const
Retrieve the quality cuts for matching.
void GetRootPfos(pandora::PfoList &rootPfos) const
Retrieve the root particle flow objects of the interaction hierarchies.
static void MatchHierarchies(MatchInfo &matchInfo)
Finds the matches between reconstructed and MC hierarchies.
static void FillRecoHierarchy(const pandora::PfoList &pfoList, const FoldingParameters &foldParameters, RecoHierarchy &hierarchy)
Fill a reconstructed hierarchy based on the specified folding criteria (see RecoHierarchy::FillHierar...
std::vector< MCMatches > MCMatchesVector
static void FillMCHierarchy(const pandora::MCParticleList &mcParticleList, const pandora::CaloHitList &caloHitList, const FoldingParameters &foldParameters, MCHierarchy &hierarchy)
Fill an MC hierarchy based on the specified folding criteria (see MCHierarchy::FillHierarchy for deta...
static InteractionDescriptor GetInteractionDescriptor(const pandora::MCParticleList &mcPrimaryList)
Get the interaction descriptor of an event.
static bool SortByMomentum(const pandora::MCParticle *const pLhs, const pandora::MCParticle *const pRhs)
Sort mc particles by their momentum.
static bool IsDecay(const pandora::MCParticle *const pMCParticle)
Check whether or not an MC particle comes from a decay process.
static const pandora::Vertex * GetVertex(const pandora::ParticleFlowObject *const pPfo)
Get the pfo vertex.
static bool IsInFiducialVolume(const pandora::Pandora &pandora, const pandora::CartesianVector &vertex, const std::string &detector)
Determine if a vertex is within a detector's fiducial volume. This throws a STATUS_CODE_INVALID_PARAM...
CartesianVector class.
float GetX() const
Get the cartesian x coordinate.
MCParticle class.
Definition MCParticle.h:26
const MCParticleList & GetParentList() const
Get list of parents of mc particle.
Definition MCParticle.h:299
ParticleFlowObject class.
const Pandora & GetPandora() const
Get the associated pandora instance.
Definition Process.h:116
const CartesianVector & GetPosition() const
Get the vertex position.
Definition Vertex.h:103
static StatusCode ReadValue(const TiXmlHandle &xmlHandle, const std::string &xmlElementName, T &t)
Read a value from an xml element.
Definition XmlHelper.h:136
MANAGED_CONTAINER< const MCParticle * > MCParticleList
std::vector< int > IntVector
MANAGED_CONTAINER< const CaloHit * > CaloHitList
StatusCode
The StatusCode enum.
MANAGED_CONTAINER< const ParticleFlowObject * > PfoList